1 /* GTK - The GIMP Toolkit
2 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
14 * You should have received a copy of the GNU Library General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
22 #include "gdk/gdkkeysyms.h"
24 #include "gtkprivate.h"
26 #include "gtksignal.h"
27 #include "gtkwindow.h"
28 #include "gtkbindings.h"
45 static void gtk_window_class_init (GtkWindowClass *klass);
46 static void gtk_window_init (GtkWindow *window);
47 static void gtk_window_set_arg (GtkObject *object,
50 static void gtk_window_get_arg (GtkObject *object,
53 static void gtk_window_shutdown (GtkObject *object);
54 static void gtk_window_destroy (GtkObject *object);
55 static void gtk_window_finalize (GtkObject *object);
56 static void gtk_window_show (GtkWidget *widget);
57 static void gtk_window_hide (GtkWidget *widget);
58 static void gtk_window_map (GtkWidget *widget);
59 static void gtk_window_unmap (GtkWidget *widget);
60 static void gtk_window_realize (GtkWidget *widget);
61 static void gtk_window_size_request (GtkWidget *widget,
62 GtkRequisition *requisition);
63 static void gtk_window_size_allocate (GtkWidget *widget,
64 GtkAllocation *allocation);
65 static gint gtk_window_configure_event (GtkWidget *widget,
66 GdkEventConfigure *event);
67 static gint gtk_window_key_press_event (GtkWidget *widget,
69 static gint gtk_window_key_release_event (GtkWidget *widget,
71 static gint gtk_window_enter_notify_event (GtkWidget *widget,
72 GdkEventCrossing *event);
73 static gint gtk_window_leave_notify_event (GtkWidget *widget,
74 GdkEventCrossing *event);
75 static gint gtk_window_focus_in_event (GtkWidget *widget,
76 GdkEventFocus *event);
77 static gint gtk_window_focus_out_event (GtkWidget *widget,
78 GdkEventFocus *event);
79 static gint gtk_window_client_event (GtkWidget *widget,
80 GdkEventClient *event);
81 static void gtk_window_check_resize (GtkContainer *container);
82 static void gtk_real_window_set_focus (GtkWindow *window,
84 static void gtk_window_move_resize (GtkWindow *window);
85 static void gtk_window_set_hints (GtkWidget *widget,
86 GtkRequisition *requisition);
88 static void gtk_window_read_rcfiles (GtkWidget *widget,
89 GdkEventClient *event);
90 static void gtk_window_draw (GtkWidget *widget,
92 static void gtk_window_paint (GtkWidget *widget,
94 static gint gtk_window_expose (GtkWidget *widget,
95 GdkEventExpose *event);
96 static void gtk_window_style_set (GtkWidget *widget,
97 GtkStyle *previous_style);
99 static GtkBinClass *parent_class = NULL;
100 static guint window_signals[LAST_SIGNAL] = { 0 };
104 gtk_window_get_type (void)
106 static GtkType window_type = 0;
110 static const GtkTypeInfo window_info =
114 sizeof (GtkWindowClass),
115 (GtkClassInitFunc) gtk_window_class_init,
116 (GtkObjectInitFunc) gtk_window_init,
117 /* reserved_1 */ NULL,
118 /* reserved_2 */ NULL,
119 (GtkClassInitFunc) NULL,
122 window_type = gtk_type_unique (gtk_bin_get_type (), &window_info);
129 gtk_window_class_init (GtkWindowClass *klass)
131 GtkObjectClass *object_class;
132 GtkWidgetClass *widget_class;
133 GtkContainerClass *container_class;
135 object_class = (GtkObjectClass*) klass;
136 widget_class = (GtkWidgetClass*) klass;
137 container_class = (GtkContainerClass*) klass;
139 parent_class = gtk_type_class (gtk_bin_get_type ());
141 gtk_object_add_arg_type ("GtkWindow::type", GTK_TYPE_WINDOW_TYPE, GTK_ARG_READWRITE, ARG_TYPE);
142 gtk_object_add_arg_type ("GtkWindow::title", GTK_TYPE_STRING, GTK_ARG_READWRITE, ARG_TITLE);
143 gtk_object_add_arg_type ("GtkWindow::auto_shrink", GTK_TYPE_BOOL, GTK_ARG_READWRITE, ARG_AUTO_SHRINK);
144 gtk_object_add_arg_type ("GtkWindow::allow_shrink", GTK_TYPE_BOOL, GTK_ARG_READWRITE, ARG_ALLOW_SHRINK);
145 gtk_object_add_arg_type ("GtkWindow::allow_grow", GTK_TYPE_BOOL, GTK_ARG_READWRITE, ARG_ALLOW_GROW);
146 gtk_object_add_arg_type ("GtkWindow::window_position", GTK_TYPE_WINDOW_POSITION, GTK_ARG_READWRITE, ARG_WIN_POS);
148 window_signals[SET_FOCUS] =
149 gtk_signal_new ("set_focus",
152 GTK_SIGNAL_OFFSET (GtkWindowClass, set_focus),
153 gtk_marshal_NONE__POINTER,
157 gtk_object_class_add_signals (object_class, window_signals, LAST_SIGNAL);
159 object_class->set_arg = gtk_window_set_arg;
160 object_class->get_arg = gtk_window_get_arg;
161 object_class->shutdown = gtk_window_shutdown;
162 object_class->destroy = gtk_window_destroy;
163 object_class->finalize = gtk_window_finalize;
165 widget_class->show = gtk_window_show;
166 widget_class->hide = gtk_window_hide;
167 widget_class->map = gtk_window_map;
168 widget_class->unmap = gtk_window_unmap;
169 widget_class->realize = gtk_window_realize;
170 widget_class->size_request = gtk_window_size_request;
171 widget_class->size_allocate = gtk_window_size_allocate;
172 widget_class->configure_event = gtk_window_configure_event;
173 widget_class->key_press_event = gtk_window_key_press_event;
174 widget_class->key_release_event = gtk_window_key_release_event;
175 widget_class->enter_notify_event = gtk_window_enter_notify_event;
176 widget_class->leave_notify_event = gtk_window_leave_notify_event;
177 widget_class->focus_in_event = gtk_window_focus_in_event;
178 widget_class->focus_out_event = gtk_window_focus_out_event;
179 widget_class->client_event = gtk_window_client_event;
180 widget_class->style_set = gtk_window_style_set;
182 widget_class->draw = gtk_window_draw;
183 widget_class->expose_event = gtk_window_expose;
185 container_class->check_resize = gtk_window_check_resize;
187 klass->set_focus = gtk_real_window_set_focus;
191 gtk_window_init (GtkWindow *window)
193 GTK_WIDGET_UNSET_FLAGS (window, GTK_NO_WINDOW);
194 GTK_WIDGET_SET_FLAGS (window, GTK_TOPLEVEL);
196 gtk_container_set_resize_mode (GTK_CONTAINER (window), GTK_RESIZE_QUEUE);
198 window->title = NULL;
199 window->wmclass_name = g_strdup (g_get_prgname ());
200 window->wmclass_class = g_strdup (gdk_progclass);
201 window->type = GTK_WINDOW_TOPLEVEL;
202 window->focus_widget = NULL;
203 window->default_widget = NULL;
204 window->resize_count = 0;
205 window->allow_shrink = FALSE;
206 window->allow_grow = TRUE;
207 window->auto_shrink = FALSE;
208 window->handling_resize = FALSE;
209 window->position = GTK_WIN_POS_NONE;
210 window->use_uposition = TRUE;
211 window->modal = FALSE;
213 gtk_container_register_toplevel (GTK_CONTAINER (window));
217 gtk_window_set_arg (GtkObject *object,
223 window = GTK_WINDOW (object);
228 window->type = GTK_VALUE_ENUM (*arg);
231 gtk_window_set_title (window, GTK_VALUE_STRING (*arg));
233 case ARG_AUTO_SHRINK:
234 window->auto_shrink = (GTK_VALUE_BOOL (*arg) != FALSE);
235 gtk_window_set_hints (GTK_WIDGET (window), >K_WIDGET (window)->requisition);
237 case ARG_ALLOW_SHRINK:
238 window->allow_shrink = (GTK_VALUE_BOOL (*arg) != FALSE);
239 gtk_window_set_hints (GTK_WIDGET (window), >K_WIDGET (window)->requisition);
242 window->allow_grow = (GTK_VALUE_BOOL (*arg) != FALSE);
243 gtk_window_set_hints (GTK_WIDGET (window), >K_WIDGET (window)->requisition);
246 gtk_window_set_position (window, GTK_VALUE_ENUM (*arg));
254 gtk_window_get_arg (GtkObject *object,
260 window = GTK_WINDOW (object);
265 GTK_VALUE_ENUM (*arg) = window->type;
268 GTK_VALUE_STRING (*arg) = g_strdup (window->title);
270 case ARG_AUTO_SHRINK:
271 GTK_VALUE_BOOL (*arg) = window->auto_shrink;
273 case ARG_ALLOW_SHRINK:
274 GTK_VALUE_BOOL (*arg) = window->allow_shrink;
277 GTK_VALUE_BOOL (*arg) = window->allow_grow;
280 GTK_VALUE_ENUM (*arg) = window->position;
283 arg->type = GTK_TYPE_INVALID;
289 gtk_window_new (GtkWindowType type)
293 window = gtk_type_new (gtk_window_get_type ());
297 return GTK_WIDGET (window);
301 gtk_window_set_title (GtkWindow *window,
304 g_return_if_fail (window != NULL);
305 g_return_if_fail (GTK_IS_WINDOW (window));
308 g_free (window->title);
309 window->title = g_strdup (title);
311 if (GTK_WIDGET_REALIZED (window))
312 gdk_window_set_title (GTK_WIDGET (window)->window, window->title);
316 gtk_window_set_wmclass (GtkWindow *window,
317 const gchar *wmclass_name,
318 const gchar *wmclass_class)
320 g_return_if_fail (window != NULL);
321 g_return_if_fail (GTK_IS_WINDOW (window));
323 g_free (window->wmclass_name);
324 window->wmclass_name = g_strdup (wmclass_name);
326 g_free (window->wmclass_class);
327 window->wmclass_class = g_strdup (wmclass_class);
329 if (GTK_WIDGET_REALIZED (window))
330 g_warning ("shouldn't set wmclass after window is realized!\n");
334 gtk_window_set_focus (GtkWindow *window,
337 gtk_signal_emit (GTK_OBJECT (window), window_signals[SET_FOCUS], focus);
341 gtk_window_set_default (GtkWindow *window,
342 GtkWidget *default_widget)
344 g_return_if_fail (window != NULL);
345 g_return_if_fail (GTK_IS_WINDOW (window));
348 g_return_if_fail (GTK_WIDGET_CAN_DEFAULT (default_widget));
350 if (window->default_widget != default_widget)
352 if (window->default_widget)
354 GTK_WIDGET_UNSET_FLAGS (window->default_widget, GTK_HAS_DEFAULT);
355 gtk_widget_draw_default (window->default_widget);
358 window->default_widget = default_widget;
360 if (window->default_widget)
362 GTK_WIDGET_SET_FLAGS (window->default_widget, GTK_HAS_DEFAULT);
363 gtk_widget_draw_default (window->default_widget);
369 gtk_window_set_policy (GtkWindow *window,
374 g_return_if_fail (window != NULL);
375 g_return_if_fail (GTK_IS_WINDOW (window));
377 window->allow_shrink = (allow_shrink != FALSE);
378 window->allow_grow = (allow_grow != FALSE);
379 window->auto_shrink = (auto_shrink != FALSE);
381 gtk_window_set_hints (GTK_WIDGET (window), >K_WIDGET (window)->requisition);
385 gtk_window_add_accel_group (GtkWindow *window,
386 GtkAccelGroup *accel_group)
388 g_return_if_fail (window != NULL);
389 g_return_if_fail (GTK_IS_WINDOW (window));
390 g_return_if_fail (accel_group != NULL);
392 gtk_accel_group_attach (accel_group, GTK_OBJECT (window));
396 gtk_window_remove_accel_group (GtkWindow *window,
397 GtkAccelGroup *accel_group)
399 g_return_if_fail (window != NULL);
400 g_return_if_fail (GTK_IS_WINDOW (window));
401 g_return_if_fail (accel_group != NULL);
403 gtk_accel_group_detach (accel_group, GTK_OBJECT (window));
407 gtk_window_set_position (GtkWindow *window,
408 GtkWindowPosition position)
410 g_return_if_fail (window != NULL);
411 g_return_if_fail (GTK_IS_WINDOW (window));
413 window->position = position;
417 gtk_window_activate_focus (GtkWindow *window)
419 g_return_val_if_fail (window != NULL, FALSE);
420 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
422 if (window->focus_widget)
424 gtk_widget_activate (window->focus_widget);
432 gtk_window_activate_default (GtkWindow *window)
434 g_return_val_if_fail (window != NULL, FALSE);
435 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
437 if (window->default_widget)
439 gtk_widget_activate (window->default_widget);
447 gtk_window_set_modal (GtkWindow *window, gboolean modal)
449 g_return_if_fail (window != NULL);
450 g_return_if_fail (GTK_IS_WINDOW (window));
452 /* If the widget was showed already, adjust it's grab state */
453 if (GTK_WIDGET_VISIBLE(GTK_WIDGET(window)))
455 if (window->modal && !modal)
456 gtk_grab_remove (GTK_WIDGET(window));
457 else if (!window->modal && modal)
458 gtk_grab_add (GTK_WIDGET(window));
461 window->modal = modal;
465 gtk_window_add_embedded_xid (GtkWindow *window, guint xid)
467 GList *embedded_windows;
469 g_return_if_fail (window != NULL);
470 g_return_if_fail (GTK_IS_WINDOW (window));
472 g_print ("add %#x\n", xid);
474 embedded_windows = gtk_object_get_data (GTK_OBJECT (window), "gtk-embedded");
475 if (embedded_windows)
476 gtk_object_remove_no_notify_by_id (GTK_OBJECT (window),
477 g_quark_from_static_string ("gtk-embedded"));
478 embedded_windows = g_list_prepend (embedded_windows,
479 GUINT_TO_POINTER (xid));
481 gtk_object_set_data_full (GTK_OBJECT (window), "gtk-embedded",
484 (GtkDestroyNotify) g_list_free : NULL);
488 gtk_window_remove_embedded_xid (GtkWindow *window, guint xid)
490 GList *embedded_windows;
493 g_return_if_fail (window != NULL);
494 g_return_if_fail (GTK_IS_WINDOW (window));
496 g_print ("remove %#x\n", xid);
498 embedded_windows = gtk_object_get_data (GTK_OBJECT (window), "gtk-embedded");
499 if (embedded_windows)
500 gtk_object_remove_no_notify_by_id (GTK_OBJECT (window),
501 g_quark_from_static_string ("gtk-embedded"));
503 node = g_list_find (embedded_windows, GUINT_TO_POINTER (xid));
506 embedded_windows = g_list_remove_link (embedded_windows, node);
507 g_list_free_1 (node);
510 gtk_object_set_data_full (GTK_OBJECT (window),
511 "gtk-embedded", embedded_windows,
513 (GtkDestroyNotify) g_list_free : NULL);
517 gtk_window_shutdown (GtkObject *object)
521 g_return_if_fail (object != NULL);
522 g_return_if_fail (GTK_IS_WINDOW (object));
524 window = GTK_WINDOW (object);
526 gtk_window_set_focus (window, NULL);
527 gtk_window_set_default (window, NULL);
529 GTK_OBJECT_CLASS (parent_class)->shutdown (object);
533 gtk_window_destroy (GtkObject *object)
535 g_return_if_fail (object != NULL);
536 g_return_if_fail (GTK_IS_WINDOW (object));
538 gtk_container_unregister_toplevel (GTK_CONTAINER (object));
540 GTK_OBJECT_CLASS (parent_class)->destroy (object);
544 gtk_window_finalize (GtkObject *object)
548 g_return_if_fail (object != NULL);
549 g_return_if_fail (GTK_IS_WINDOW (object));
551 window = GTK_WINDOW (object);
552 g_free (window->title);
553 g_free (window->wmclass_name);
554 g_free (window->wmclass_class);
556 GTK_OBJECT_CLASS(parent_class)->finalize (object);
560 gtk_window_show (GtkWidget *widget)
562 g_return_if_fail (widget != NULL);
563 g_return_if_fail (GTK_IS_WINDOW (widget));
565 GTK_WIDGET_SET_FLAGS (widget, GTK_VISIBLE);
566 gtk_container_check_resize (GTK_CONTAINER (widget));
567 gtk_widget_map (widget);
569 if (GTK_WINDOW(widget)->modal)
570 gtk_grab_add(widget);
575 gtk_window_hide (GtkWidget *widget)
577 g_return_if_fail (widget != NULL);
578 g_return_if_fail (GTK_IS_WINDOW (widget));
580 GTK_WIDGET_UNSET_FLAGS (widget, GTK_VISIBLE);
581 gtk_widget_unmap (widget);
583 if (GTK_WINDOW(widget)->modal)
584 gtk_grab_remove(widget);
589 gtk_window_map (GtkWidget *widget)
593 g_return_if_fail (widget != NULL);
594 g_return_if_fail (GTK_IS_WINDOW (widget));
596 GTK_WIDGET_SET_FLAGS (widget, GTK_MAPPED);
598 window = GTK_WINDOW (widget);
600 if (window->bin.child &&
601 GTK_WIDGET_VISIBLE (window->bin.child) &&
602 !GTK_WIDGET_MAPPED (window->bin.child))
603 gtk_widget_map (window->bin.child);
605 gtk_window_set_hints (widget, &widget->requisition);
606 gdk_window_show (widget->window);
610 gtk_window_unmap (GtkWidget *widget)
614 g_return_if_fail (widget != NULL);
615 g_return_if_fail (GTK_IS_WINDOW (widget));
617 GTK_WIDGET_UNSET_FLAGS (widget, GTK_MAPPED);
618 gdk_window_hide (widget->window);
620 window = GTK_WINDOW (widget);
621 window->use_uposition = TRUE;
625 gtk_window_realize (GtkWidget *widget)
628 GdkWindowAttr attributes;
629 gint attributes_mask;
631 g_return_if_fail (widget != NULL);
632 g_return_if_fail (GTK_IS_WINDOW (widget));
634 GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED);
635 window = GTK_WINDOW (widget);
637 switch (window->type)
639 case GTK_WINDOW_TOPLEVEL:
640 attributes.window_type = GDK_WINDOW_TOPLEVEL;
642 case GTK_WINDOW_DIALOG:
643 attributes.window_type = GDK_WINDOW_DIALOG;
645 case GTK_WINDOW_POPUP:
646 attributes.window_type = GDK_WINDOW_TEMP;
650 attributes.title = window->title;
651 attributes.wmclass_name = window->wmclass_name;
652 attributes.wmclass_class = window->wmclass_class;
653 attributes.width = widget->allocation.width;
654 attributes.height = widget->allocation.height;
655 attributes.wclass = GDK_INPUT_OUTPUT;
656 attributes.visual = gtk_widget_get_visual (widget);
657 attributes.colormap = gtk_widget_get_colormap (widget);
658 attributes.event_mask = gtk_widget_get_events (widget);
659 attributes.event_mask |= (GDK_EXPOSURE_MASK |
661 GDK_ENTER_NOTIFY_MASK |
662 GDK_LEAVE_NOTIFY_MASK |
663 GDK_FOCUS_CHANGE_MASK |
666 attributes_mask = GDK_WA_VISUAL | GDK_WA_COLORMAP;
667 attributes_mask |= (window->title ? GDK_WA_TITLE : 0);
668 attributes_mask |= (window->wmclass_name ? GDK_WA_WMCLASS : 0);
670 widget->window = gdk_window_new (NULL, &attributes, attributes_mask);
671 gdk_window_set_user_data (widget->window, window);
673 widget->style = gtk_style_attach (widget->style, widget->window);
674 gtk_style_set_background (widget->style, widget->window, GTK_STATE_NORMAL);
675 gtk_window_paint (widget, NULL);
679 gtk_window_size_request (GtkWidget *widget,
680 GtkRequisition *requisition)
685 g_return_if_fail (widget != NULL);
686 g_return_if_fail (GTK_IS_WINDOW (widget));
687 g_return_if_fail (requisition != NULL);
689 window = GTK_WINDOW (widget);
690 bin = GTK_BIN (window);
692 requisition->width = GTK_CONTAINER (window)->border_width * 2;
693 requisition->height = GTK_CONTAINER (window)->border_width * 2;
695 if (bin->child && GTK_WIDGET_VISIBLE (bin->child))
697 gtk_widget_size_request (bin->child, &bin->child->requisition);
699 requisition->width += bin->child->requisition.width;
700 requisition->height += bin->child->requisition.height;
704 if (!GTK_WIDGET_VISIBLE (window))
705 GTK_CONTAINER (window)->need_resize = TRUE;
710 gtk_window_size_allocate (GtkWidget *widget,
711 GtkAllocation *allocation)
714 GtkAllocation child_allocation;
716 g_return_if_fail (widget != NULL);
717 g_return_if_fail (GTK_IS_WINDOW (widget));
718 g_return_if_fail (allocation != NULL);
720 window = GTK_WINDOW (widget);
721 widget->allocation = *allocation;
723 if (window->bin.child && GTK_WIDGET_VISIBLE (window->bin.child))
725 child_allocation.x = GTK_CONTAINER (window)->border_width;
726 child_allocation.y = GTK_CONTAINER (window)->border_width;
727 child_allocation.width = allocation->width - child_allocation.x * 2;
728 child_allocation.height = allocation->height - child_allocation.y * 2;
730 gtk_widget_size_allocate (window->bin.child, &child_allocation);
735 gtk_window_configure_event (GtkWidget *widget,
736 GdkEventConfigure *event)
739 GtkAllocation allocation;
740 gboolean need_expose = FALSE;
742 g_return_val_if_fail (widget != NULL, FALSE);
743 g_return_val_if_fail (GTK_IS_WINDOW (widget), FALSE);
744 g_return_val_if_fail (event != NULL, FALSE);
746 window = GTK_WINDOW (widget);
748 /* If the window was merely moved, do nothing */
749 if ((widget->allocation.width == event->width) &&
750 (widget->allocation.height == event->height))
752 if (window->resize_count == 0) /* The window was merely moved */
756 /* We asked for a new size, which was rejected, so the
757 * WM sent us a synthetic configure event. We won't
758 * get the expose event we would normally get (since
759 * we have ForgetGravity), so we need to fake it.
766 window->handling_resize = TRUE;
770 allocation.width = event->width;
771 allocation.height = event->height;
773 gtk_widget_size_allocate (widget, &allocation);
775 if (window->bin.child &&
776 GTK_WIDGET_VISIBLE (window->bin.child) &&
777 !GTK_WIDGET_MAPPED (window->bin.child))
778 gtk_widget_map (window->bin.child);
780 if (window->resize_count > 0)
781 window->resize_count -= 1;
786 temp_event.type = GDK_EXPOSE;
787 temp_event.expose.window = widget->window;
788 temp_event.expose.send_event = TRUE;
789 temp_event.expose.area.x = 0;
790 temp_event.expose.area.y = 0;
791 temp_event.expose.area.width = event->width;
792 temp_event.expose.area.height = event->height;
793 temp_event.expose.count = 0;
795 gtk_widget_event (widget, &temp_event);
798 window->handling_resize = FALSE;
804 gtk_window_key_press_event (GtkWidget *widget,
808 GtkDirectionType direction = 0;
811 g_return_val_if_fail (widget != NULL, FALSE);
812 g_return_val_if_fail (GTK_IS_WINDOW (widget), FALSE);
813 g_return_val_if_fail (event != NULL, FALSE);
815 window = GTK_WINDOW (widget);
819 if (window->focus_widget)
821 handled = gtk_widget_event (window->focus_widget, (GdkEvent*) event);
825 handled = gtk_accel_groups_activate (GTK_OBJECT (window), event->keyval, event->state);
829 switch (event->keyval)
832 if (window->focus_widget)
834 gtk_widget_activate (window->focus_widget);
840 if (window->default_widget)
842 gtk_widget_activate (window->default_widget);
845 else if (window->focus_widget)
847 gtk_widget_activate (window->focus_widget);
856 case GDK_ISO_Left_Tab:
857 switch (event->keyval)
860 direction = GTK_DIR_UP;
863 direction = GTK_DIR_DOWN;
866 direction = GTK_DIR_LEFT;
869 direction = GTK_DIR_RIGHT;
872 case GDK_ISO_Left_Tab:
873 if (event->state & GDK_SHIFT_MASK)
874 direction = GTK_DIR_TAB_BACKWARD;
876 direction = GTK_DIR_TAB_FORWARD;
879 direction = GTK_DIR_UP; /* never reached, but makes compiler happy */
882 gtk_container_focus (GTK_CONTAINER (widget), direction);
884 if (!GTK_CONTAINER (window)->focus_child)
885 gtk_window_set_focus (GTK_WINDOW (widget), NULL);
892 if (!handled && GTK_WIDGET_CLASS (parent_class)->key_press_event)
893 handled = GTK_WIDGET_CLASS (parent_class)->key_press_event (widget, event);
899 gtk_window_key_release_event (GtkWidget *widget,
905 g_return_val_if_fail (widget != NULL, FALSE);
906 g_return_val_if_fail (GTK_IS_WINDOW (widget), FALSE);
907 g_return_val_if_fail (event != NULL, FALSE);
909 window = GTK_WINDOW (widget);
911 if (window->focus_widget)
913 handled = gtk_widget_event (window->focus_widget, (GdkEvent*) event);
916 if (!handled && GTK_WIDGET_CLASS (parent_class)->key_release_event)
917 handled = GTK_WIDGET_CLASS (parent_class)->key_release_event (widget, event);
923 gtk_window_enter_notify_event (GtkWidget *widget,
924 GdkEventCrossing *event)
926 g_return_val_if_fail (widget != NULL, FALSE);
927 g_return_val_if_fail (GTK_IS_WINDOW (widget), FALSE);
928 g_return_val_if_fail (event != NULL, FALSE);
934 gtk_window_leave_notify_event (GtkWidget *widget,
935 GdkEventCrossing *event)
937 g_return_val_if_fail (widget != NULL, FALSE);
938 g_return_val_if_fail (GTK_IS_WINDOW (widget), FALSE);
939 g_return_val_if_fail (event != NULL, FALSE);
945 gtk_window_focus_in_event (GtkWidget *widget,
946 GdkEventFocus *event)
949 GdkEventFocus fevent;
951 g_return_val_if_fail (widget != NULL, FALSE);
952 g_return_val_if_fail (GTK_IS_WINDOW (widget), FALSE);
953 g_return_val_if_fail (event != NULL, FALSE);
955 /* It appears spurious focus in events can occur when
956 * the window is hidden. So we'll just check to see if
957 * the window is visible before actually handling the
960 if (GTK_WIDGET_VISIBLE (widget))
962 window = GTK_WINDOW (widget);
963 if (window->focus_widget && !GTK_WIDGET_HAS_FOCUS (window->focus_widget))
965 fevent.type = GDK_FOCUS_CHANGE;
966 fevent.window = window->focus_widget->window;
969 gtk_widget_event (window->focus_widget, (GdkEvent*) &fevent);
977 gtk_window_focus_out_event (GtkWidget *widget,
978 GdkEventFocus *event)
981 GdkEventFocus fevent;
983 g_return_val_if_fail (widget != NULL, FALSE);
984 g_return_val_if_fail (GTK_IS_WINDOW (widget), FALSE);
985 g_return_val_if_fail (event != NULL, FALSE);
987 window = GTK_WINDOW (widget);
988 if (window->focus_widget && GTK_WIDGET_HAS_FOCUS (window->focus_widget))
990 fevent.type = GDK_FOCUS_CHANGE;
991 fevent.window = window->focus_widget->window;
994 gtk_widget_event (window->focus_widget, (GdkEvent*) &fevent);
1000 static GdkAtom atom_rcfiles = GDK_NONE;
1003 gtk_window_read_rcfiles (GtkWidget *widget,
1004 GdkEventClient *event)
1006 GList *embedded_windows;
1008 embedded_windows = gtk_object_get_data (GTK_OBJECT (widget), "gtk-embedded");
1009 if (embedded_windows)
1014 for(i = 0; i < 5; i++)
1016 sev.data_format = 32;
1017 sev.message_type = atom_rcfiles;
1019 while (embedded_windows)
1021 guint xid = GPOINTER_TO_UINT (embedded_windows->data);
1022 gdk_event_send_client_message ((GdkEvent *) &sev, xid);
1023 embedded_windows = embedded_windows->next;
1027 if (gtk_rc_reparse_all ())
1029 /* If the above returned true, some of our RC files are out
1030 * of date, so we need to reset all our widgets. Our other
1031 * toplevel windows will also get the message, but by
1032 * then, the RC file will up to date, so we have to tell
1037 toplevels = gtk_container_get_toplevels();
1040 gtk_widget_reset_rc_styles (toplevels->data);
1041 toplevels = toplevels->next;
1047 gtk_window_client_event (GtkWidget *widget,
1048 GdkEventClient *event)
1050 g_return_val_if_fail (widget != NULL, FALSE);
1051 g_return_val_if_fail (GTK_IS_WINDOW (widget), FALSE);
1052 g_return_val_if_fail (event != NULL, FALSE);
1055 atom_rcfiles = gdk_atom_intern("_GTK_READ_RCFILES", FALSE);
1057 if(event->message_type == atom_rcfiles)
1058 gtk_window_read_rcfiles (widget, event);
1064 gtk_window_check_resize (GtkContainer *container)
1068 g_return_if_fail (container != NULL);
1069 g_return_if_fail (GTK_IS_WINDOW (container));
1071 window = GTK_WINDOW (container);
1072 if (!window->handling_resize)
1074 if (GTK_WIDGET_VISIBLE (container))
1075 gtk_window_move_resize (window);
1077 GTK_CONTAINER (window)->need_resize = TRUE;
1081 /* FIXME: we leave container->resize_widgets set under some
1084 gtk_window_move_resize (GtkWindow *window)
1087 GtkContainer *container;
1092 gboolean needed_resize;
1093 gboolean size_changed;
1095 g_return_if_fail (window != NULL);
1096 g_return_if_fail (GTK_IS_WINDOW (window));
1098 widget = GTK_WIDGET (window);
1099 container = GTK_CONTAINER (widget);
1101 /* Remember old size, to know if we have to reset hints */
1102 width = widget->requisition.width;
1103 height = widget->requisition.height;
1104 gtk_widget_size_request (widget, &widget->requisition);
1106 size_changed = ((width != widget->requisition.width) ||
1107 (height != widget->requisition.height));
1111 gboolean saved_use_upos;
1113 saved_use_upos = window->use_uposition;
1114 gtk_window_set_hints (widget, &widget->requisition);
1115 window->use_uposition = saved_use_upos;
1120 width = widget->requisition.width;
1121 height = widget->requisition.height;
1123 if (window->use_uposition)
1124 switch (window->position)
1126 case GTK_WIN_POS_CENTER:
1127 x = (gdk_screen_width () - width) / 2;
1128 y = (gdk_screen_height () - height) / 2;
1129 gtk_widget_set_uposition (widget, x, y);
1131 case GTK_WIN_POS_MOUSE:
1132 gdk_window_get_pointer (NULL, &x, &y, NULL);
1137 screen_width = gdk_screen_width ();
1138 screen_height = gdk_screen_height ();
1142 else if (x > (screen_width - width))
1143 x = screen_width - width;
1147 else if (y > (screen_height - height))
1148 y = screen_height - height;
1150 gtk_widget_set_uposition (widget, x, y);
1154 /* Now, do the resizing */
1156 needed_resize = container->need_resize;
1157 container->need_resize = FALSE;
1159 if ((widget->requisition.width == 0) ||
1160 (widget->requisition.height == 0))
1162 widget->requisition.width = 200;
1163 widget->requisition.height = 200;
1166 if (!GTK_WIDGET_REALIZED (window))
1168 GtkAllocation allocation;
1172 allocation.width = widget->requisition.width;
1173 allocation.height = widget->requisition.height;
1175 gtk_widget_size_allocate (widget, &allocation);
1180 gdk_window_get_geometry (widget->window, NULL, NULL, &width, &height, NULL);
1182 /* As an optimization, we don't try to get a new size from the
1183 * window manager if we asked for the same size last time and
1187 (((window->auto_shrink &&
1188 ((width != widget->requisition.width) ||
1189 (height != widget->requisition.height)))) ||
1190 ((width < widget->requisition.width) ||
1191 (height < widget->requisition.height))))
1193 window->resize_count += 1;
1194 if ((x != -1) && (y != -1))
1195 gdk_window_move_resize (widget->window, x, y,
1196 widget->requisition.width,
1197 widget->requisition.height);
1199 gdk_window_resize (widget->window,
1200 widget->requisition.width,
1201 widget->requisition.height);
1203 else if (needed_resize)
1205 /* The windows contents changed size while it was not
1206 * visible, so reallocate everything, since we didn't
1207 * keep track of what changed
1209 GtkAllocation allocation;
1213 allocation.width = widget->requisition.width;
1214 allocation.height = widget->requisition.height;
1216 gtk_widget_size_allocate (widget, &allocation);
1220 if ((x != -1) && (y != -1))
1221 gdk_window_move (widget->window, x, y);
1223 gtk_container_resize_children (GTK_CONTAINER (window));
1228 gtk_real_window_set_focus (GtkWindow *window,
1231 GdkEventFocus event;
1233 g_return_if_fail (window != NULL);
1234 g_return_if_fail (GTK_IS_WINDOW (window));
1236 if (focus && !GTK_WIDGET_CAN_FOCUS (focus))
1239 if (window->focus_widget != focus)
1241 if (window->focus_widget)
1243 event.type = GDK_FOCUS_CHANGE;
1244 event.window = window->focus_widget->window;
1247 gtk_widget_event (window->focus_widget, (GdkEvent*) &event);
1250 window->focus_widget = focus;
1252 if (window->focus_widget)
1254 event.type = GDK_FOCUS_CHANGE;
1255 event.window = window->focus_widget->window;
1258 gtk_widget_event (window->focus_widget, (GdkEvent*) &event);
1264 gtk_window_set_hints (GtkWidget *widget,
1265 GtkRequisition *requisition)
1268 GtkWidgetAuxInfo *aux_info;
1272 g_return_if_fail (widget != NULL);
1273 g_return_if_fail (GTK_IS_WINDOW (widget));
1274 g_return_if_fail (requisition != NULL);
1276 if (GTK_WIDGET_REALIZED (widget))
1278 window = GTK_WINDOW (widget);
1284 aux_info = gtk_object_get_data (GTK_OBJECT (widget), "gtk-aux-info");
1285 if (aux_info && (aux_info->x != -1) && (aux_info->y != -1))
1289 flags |= GDK_HINT_POS;
1292 if (!window->allow_shrink)
1293 flags |= GDK_HINT_MIN_SIZE;
1294 if (!window->allow_grow)
1295 flags |= GDK_HINT_MAX_SIZE;
1297 gdk_window_set_hints (widget->window,
1299 requisition->width, requisition->height,
1300 requisition->width, requisition->height,
1303 if (window->use_uposition && (flags & GDK_HINT_POS))
1305 window->use_uposition = FALSE;
1306 gdk_window_move (widget->window, ux, uy);
1312 gtk_window_paint (GtkWidget *widget,
1315 gtk_paint_flat_box (widget->style, widget->window, GTK_STATE_NORMAL,
1316 GTK_SHADOW_NONE, area, widget, "base", 0, 0, -1, -1);
1320 gtk_window_expose (GtkWidget *widget,
1321 GdkEventExpose *event)
1323 g_return_val_if_fail (widget != NULL, FALSE);
1324 g_return_val_if_fail (GTK_IS_WINDOW (widget), FALSE);
1325 g_return_val_if_fail (event != NULL, FALSE);
1327 gtk_window_paint (widget, &event->area);
1329 if (GTK_WIDGET_CLASS (parent_class)->expose_event)
1330 return (* GTK_WIDGET_CLASS (parent_class)->expose_event) (widget, event);
1336 gtk_window_draw (GtkWidget *widget,
1339 gtk_window_paint (widget, area);
1341 if (GTK_WIDGET_CLASS (parent_class)->draw)
1342 (* GTK_WIDGET_CLASS (parent_class)->draw) (widget, area);
1346 gtk_window_style_set (GtkWidget *widget,
1347 GtkStyle *previous_style)
1351 if (GTK_WIDGET_REALIZED (widget) &&
1352 !GTK_WIDGET_NO_WINDOW (widget))
1354 gtk_style_set_background (widget->style, widget->window, widget->state);
1358 area.width = widget->allocation.width;
1359 area.height = widget->allocation.height;
1360 gtk_window_draw(widget, &area);
1362 if (GTK_WIDGET_DRAWABLE (widget))
1363 gdk_window_clear (widget->window);