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_window_real_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_window_real_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 g_return_if_fail (window != NULL);
338 g_return_if_fail (GTK_IS_WINDOW (window));
341 g_return_if_fail (GTK_IS_WIDGET (focus));
342 g_return_if_fail (GTK_WIDGET_CAN_FOCUS (focus));
345 if (window->focus_widget != focus)
346 gtk_signal_emit (GTK_OBJECT (window), window_signals[SET_FOCUS], focus);
350 gtk_window_set_default (GtkWindow *window,
351 GtkWidget *default_widget)
353 g_return_if_fail (window != NULL);
354 g_return_if_fail (GTK_IS_WINDOW (window));
357 g_return_if_fail (GTK_WIDGET_CAN_DEFAULT (default_widget));
359 if (window->default_widget != default_widget)
361 if (window->default_widget)
363 GTK_WIDGET_UNSET_FLAGS (window->default_widget, GTK_HAS_DEFAULT);
364 gtk_widget_draw_default (window->default_widget);
367 window->default_widget = default_widget;
369 if (window->default_widget)
371 GTK_WIDGET_SET_FLAGS (window->default_widget, GTK_HAS_DEFAULT);
372 gtk_widget_draw_default (window->default_widget);
378 gtk_window_set_policy (GtkWindow *window,
383 g_return_if_fail (window != NULL);
384 g_return_if_fail (GTK_IS_WINDOW (window));
386 window->allow_shrink = (allow_shrink != FALSE);
387 window->allow_grow = (allow_grow != FALSE);
388 window->auto_shrink = (auto_shrink != FALSE);
390 gtk_window_set_hints (GTK_WIDGET (window), >K_WIDGET (window)->requisition);
394 gtk_window_add_accel_group (GtkWindow *window,
395 GtkAccelGroup *accel_group)
397 g_return_if_fail (window != NULL);
398 g_return_if_fail (GTK_IS_WINDOW (window));
399 g_return_if_fail (accel_group != NULL);
401 gtk_accel_group_attach (accel_group, GTK_OBJECT (window));
405 gtk_window_remove_accel_group (GtkWindow *window,
406 GtkAccelGroup *accel_group)
408 g_return_if_fail (window != NULL);
409 g_return_if_fail (GTK_IS_WINDOW (window));
410 g_return_if_fail (accel_group != NULL);
412 gtk_accel_group_detach (accel_group, GTK_OBJECT (window));
416 gtk_window_set_position (GtkWindow *window,
417 GtkWindowPosition position)
419 g_return_if_fail (window != NULL);
420 g_return_if_fail (GTK_IS_WINDOW (window));
422 window->position = position;
426 gtk_window_activate_focus (GtkWindow *window)
428 g_return_val_if_fail (window != NULL, FALSE);
429 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
431 if (window->focus_widget)
433 gtk_widget_activate (window->focus_widget);
441 gtk_window_activate_default (GtkWindow *window)
443 g_return_val_if_fail (window != NULL, FALSE);
444 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
446 if (window->default_widget)
448 gtk_widget_activate (window->default_widget);
456 gtk_window_set_modal (GtkWindow *window, gboolean modal)
458 g_return_if_fail (window != NULL);
459 g_return_if_fail (GTK_IS_WINDOW (window));
461 /* If the widget was showed already, adjust it's grab state */
462 if (GTK_WIDGET_VISIBLE(GTK_WIDGET(window)))
464 if (window->modal && !modal)
465 gtk_grab_remove (GTK_WIDGET(window));
466 else if (!window->modal && modal)
467 gtk_grab_add (GTK_WIDGET(window));
470 window->modal = modal;
474 gtk_window_add_embedded_xid (GtkWindow *window, guint xid)
476 GList *embedded_windows;
478 g_return_if_fail (window != NULL);
479 g_return_if_fail (GTK_IS_WINDOW (window));
481 g_print ("add %#x\n", xid);
483 embedded_windows = gtk_object_get_data (GTK_OBJECT (window), "gtk-embedded");
484 if (embedded_windows)
485 gtk_object_remove_no_notify_by_id (GTK_OBJECT (window),
486 g_quark_from_static_string ("gtk-embedded"));
487 embedded_windows = g_list_prepend (embedded_windows,
488 GUINT_TO_POINTER (xid));
490 gtk_object_set_data_full (GTK_OBJECT (window), "gtk-embedded",
493 (GtkDestroyNotify) g_list_free : NULL);
497 gtk_window_remove_embedded_xid (GtkWindow *window, guint xid)
499 GList *embedded_windows;
502 g_return_if_fail (window != NULL);
503 g_return_if_fail (GTK_IS_WINDOW (window));
505 g_print ("remove %#x\n", xid);
507 embedded_windows = gtk_object_get_data (GTK_OBJECT (window), "gtk-embedded");
508 if (embedded_windows)
509 gtk_object_remove_no_notify_by_id (GTK_OBJECT (window),
510 g_quark_from_static_string ("gtk-embedded"));
512 node = g_list_find (embedded_windows, GUINT_TO_POINTER (xid));
515 embedded_windows = g_list_remove_link (embedded_windows, node);
516 g_list_free_1 (node);
519 gtk_object_set_data_full (GTK_OBJECT (window),
520 "gtk-embedded", embedded_windows,
522 (GtkDestroyNotify) g_list_free : NULL);
526 gtk_window_shutdown (GtkObject *object)
530 g_return_if_fail (object != NULL);
531 g_return_if_fail (GTK_IS_WINDOW (object));
533 window = GTK_WINDOW (object);
535 gtk_window_set_focus (window, NULL);
536 gtk_window_set_default (window, NULL);
538 GTK_OBJECT_CLASS (parent_class)->shutdown (object);
542 gtk_window_destroy (GtkObject *object)
544 g_return_if_fail (object != NULL);
545 g_return_if_fail (GTK_IS_WINDOW (object));
547 gtk_container_unregister_toplevel (GTK_CONTAINER (object));
549 GTK_OBJECT_CLASS (parent_class)->destroy (object);
553 gtk_window_finalize (GtkObject *object)
557 g_return_if_fail (object != NULL);
558 g_return_if_fail (GTK_IS_WINDOW (object));
560 window = GTK_WINDOW (object);
561 g_free (window->title);
562 g_free (window->wmclass_name);
563 g_free (window->wmclass_class);
565 GTK_OBJECT_CLASS(parent_class)->finalize (object);
569 gtk_window_show (GtkWidget *widget)
571 g_return_if_fail (widget != NULL);
572 g_return_if_fail (GTK_IS_WINDOW (widget));
574 GTK_WIDGET_SET_FLAGS (widget, GTK_VISIBLE);
575 gtk_container_check_resize (GTK_CONTAINER (widget));
576 gtk_widget_map (widget);
578 if (GTK_WINDOW(widget)->modal)
579 gtk_grab_add(widget);
584 gtk_window_hide (GtkWidget *widget)
586 g_return_if_fail (widget != NULL);
587 g_return_if_fail (GTK_IS_WINDOW (widget));
589 GTK_WIDGET_UNSET_FLAGS (widget, GTK_VISIBLE);
590 gtk_widget_unmap (widget);
592 if (GTK_WINDOW(widget)->modal)
593 gtk_grab_remove(widget);
598 gtk_window_map (GtkWidget *widget)
602 g_return_if_fail (widget != NULL);
603 g_return_if_fail (GTK_IS_WINDOW (widget));
605 GTK_WIDGET_SET_FLAGS (widget, GTK_MAPPED);
607 window = GTK_WINDOW (widget);
609 if (window->bin.child &&
610 GTK_WIDGET_VISIBLE (window->bin.child) &&
611 !GTK_WIDGET_MAPPED (window->bin.child))
612 gtk_widget_map (window->bin.child);
614 gtk_window_set_hints (widget, &widget->requisition);
615 gdk_window_show (widget->window);
619 gtk_window_unmap (GtkWidget *widget)
623 g_return_if_fail (widget != NULL);
624 g_return_if_fail (GTK_IS_WINDOW (widget));
626 GTK_WIDGET_UNSET_FLAGS (widget, GTK_MAPPED);
627 gdk_window_hide (widget->window);
629 window = GTK_WINDOW (widget);
630 window->use_uposition = TRUE;
634 gtk_window_realize (GtkWidget *widget)
637 GdkWindowAttr attributes;
638 gint attributes_mask;
640 g_return_if_fail (widget != NULL);
641 g_return_if_fail (GTK_IS_WINDOW (widget));
643 GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED);
644 window = GTK_WINDOW (widget);
646 switch (window->type)
648 case GTK_WINDOW_TOPLEVEL:
649 attributes.window_type = GDK_WINDOW_TOPLEVEL;
651 case GTK_WINDOW_DIALOG:
652 attributes.window_type = GDK_WINDOW_DIALOG;
654 case GTK_WINDOW_POPUP:
655 attributes.window_type = GDK_WINDOW_TEMP;
659 attributes.title = window->title;
660 attributes.wmclass_name = window->wmclass_name;
661 attributes.wmclass_class = window->wmclass_class;
662 attributes.width = widget->allocation.width;
663 attributes.height = widget->allocation.height;
664 attributes.wclass = GDK_INPUT_OUTPUT;
665 attributes.visual = gtk_widget_get_visual (widget);
666 attributes.colormap = gtk_widget_get_colormap (widget);
667 attributes.event_mask = gtk_widget_get_events (widget);
668 attributes.event_mask |= (GDK_EXPOSURE_MASK |
670 GDK_ENTER_NOTIFY_MASK |
671 GDK_LEAVE_NOTIFY_MASK |
672 GDK_FOCUS_CHANGE_MASK |
675 attributes_mask = GDK_WA_VISUAL | GDK_WA_COLORMAP;
676 attributes_mask |= (window->title ? GDK_WA_TITLE : 0);
677 attributes_mask |= (window->wmclass_name ? GDK_WA_WMCLASS : 0);
679 widget->window = gdk_window_new (NULL, &attributes, attributes_mask);
680 gdk_window_set_user_data (widget->window, window);
682 widget->style = gtk_style_attach (widget->style, widget->window);
683 gtk_style_set_background (widget->style, widget->window, GTK_STATE_NORMAL);
684 gtk_window_paint (widget, NULL);
688 gtk_window_size_request (GtkWidget *widget,
689 GtkRequisition *requisition)
694 g_return_if_fail (widget != NULL);
695 g_return_if_fail (GTK_IS_WINDOW (widget));
696 g_return_if_fail (requisition != NULL);
698 window = GTK_WINDOW (widget);
699 bin = GTK_BIN (window);
701 requisition->width = GTK_CONTAINER (window)->border_width * 2;
702 requisition->height = GTK_CONTAINER (window)->border_width * 2;
704 if (bin->child && GTK_WIDGET_VISIBLE (bin->child))
706 gtk_widget_size_request (bin->child, &bin->child->requisition);
708 requisition->width += bin->child->requisition.width;
709 requisition->height += bin->child->requisition.height;
713 if (!GTK_WIDGET_VISIBLE (window))
714 GTK_CONTAINER (window)->need_resize = TRUE;
719 gtk_window_size_allocate (GtkWidget *widget,
720 GtkAllocation *allocation)
723 GtkAllocation child_allocation;
725 g_return_if_fail (widget != NULL);
726 g_return_if_fail (GTK_IS_WINDOW (widget));
727 g_return_if_fail (allocation != NULL);
729 window = GTK_WINDOW (widget);
730 widget->allocation = *allocation;
732 if (window->bin.child && GTK_WIDGET_VISIBLE (window->bin.child))
734 child_allocation.x = GTK_CONTAINER (window)->border_width;
735 child_allocation.y = GTK_CONTAINER (window)->border_width;
736 child_allocation.width = allocation->width - child_allocation.x * 2;
737 child_allocation.height = allocation->height - child_allocation.y * 2;
739 gtk_widget_size_allocate (window->bin.child, &child_allocation);
744 gtk_window_configure_event (GtkWidget *widget,
745 GdkEventConfigure *event)
748 GtkAllocation allocation;
749 gboolean need_expose = FALSE;
751 g_return_val_if_fail (widget != NULL, FALSE);
752 g_return_val_if_fail (GTK_IS_WINDOW (widget), FALSE);
753 g_return_val_if_fail (event != NULL, FALSE);
755 window = GTK_WINDOW (widget);
757 /* If the window was merely moved, do nothing */
758 if ((widget->allocation.width == event->width) &&
759 (widget->allocation.height == event->height))
761 if (window->resize_count == 0) /* The window was merely moved */
765 /* We asked for a new size, which was rejected, so the
766 * WM sent us a synthetic configure event. We won't
767 * get the expose event we would normally get (since
768 * we have ForgetGravity), so we need to fake it.
775 window->handling_resize = TRUE;
779 allocation.width = event->width;
780 allocation.height = event->height;
782 gtk_widget_size_allocate (widget, &allocation);
784 if (window->bin.child &&
785 GTK_WIDGET_VISIBLE (window->bin.child) &&
786 !GTK_WIDGET_MAPPED (window->bin.child))
787 gtk_widget_map (window->bin.child);
789 if (window->resize_count > 0)
790 window->resize_count -= 1;
795 temp_event.type = GDK_EXPOSE;
796 temp_event.expose.window = widget->window;
797 temp_event.expose.send_event = TRUE;
798 temp_event.expose.area.x = 0;
799 temp_event.expose.area.y = 0;
800 temp_event.expose.area.width = event->width;
801 temp_event.expose.area.height = event->height;
802 temp_event.expose.count = 0;
804 gtk_widget_event (widget, &temp_event);
807 window->handling_resize = FALSE;
813 gtk_window_key_press_event (GtkWidget *widget,
817 GtkDirectionType direction = 0;
820 g_return_val_if_fail (widget != NULL, FALSE);
821 g_return_val_if_fail (GTK_IS_WINDOW (widget), FALSE);
822 g_return_val_if_fail (event != NULL, FALSE);
824 window = GTK_WINDOW (widget);
828 if (window->focus_widget)
830 handled = gtk_widget_event (window->focus_widget, (GdkEvent*) event);
834 handled = gtk_accel_groups_activate (GTK_OBJECT (window), event->keyval, event->state);
838 switch (event->keyval)
841 if (window->focus_widget)
843 gtk_widget_activate (window->focus_widget);
849 if (window->default_widget)
851 gtk_widget_activate (window->default_widget);
854 else if (window->focus_widget)
856 gtk_widget_activate (window->focus_widget);
865 case GDK_ISO_Left_Tab:
866 switch (event->keyval)
869 direction = GTK_DIR_UP;
872 direction = GTK_DIR_DOWN;
875 direction = GTK_DIR_LEFT;
878 direction = GTK_DIR_RIGHT;
881 case GDK_ISO_Left_Tab:
882 if (event->state & GDK_SHIFT_MASK)
883 direction = GTK_DIR_TAB_BACKWARD;
885 direction = GTK_DIR_TAB_FORWARD;
888 direction = GTK_DIR_UP; /* never reached, but makes compiler happy */
891 gtk_container_focus (GTK_CONTAINER (widget), direction);
893 if (!GTK_CONTAINER (window)->focus_child)
894 gtk_window_set_focus (GTK_WINDOW (widget), NULL);
901 if (!handled && GTK_WIDGET_CLASS (parent_class)->key_press_event)
902 handled = GTK_WIDGET_CLASS (parent_class)->key_press_event (widget, event);
908 gtk_window_key_release_event (GtkWidget *widget,
914 g_return_val_if_fail (widget != NULL, FALSE);
915 g_return_val_if_fail (GTK_IS_WINDOW (widget), FALSE);
916 g_return_val_if_fail (event != NULL, FALSE);
918 window = GTK_WINDOW (widget);
920 if (window->focus_widget)
922 handled = gtk_widget_event (window->focus_widget, (GdkEvent*) event);
925 if (!handled && GTK_WIDGET_CLASS (parent_class)->key_release_event)
926 handled = GTK_WIDGET_CLASS (parent_class)->key_release_event (widget, event);
932 gtk_window_enter_notify_event (GtkWidget *widget,
933 GdkEventCrossing *event)
935 g_return_val_if_fail (widget != NULL, FALSE);
936 g_return_val_if_fail (GTK_IS_WINDOW (widget), FALSE);
937 g_return_val_if_fail (event != NULL, FALSE);
943 gtk_window_leave_notify_event (GtkWidget *widget,
944 GdkEventCrossing *event)
946 g_return_val_if_fail (widget != NULL, FALSE);
947 g_return_val_if_fail (GTK_IS_WINDOW (widget), FALSE);
948 g_return_val_if_fail (event != NULL, FALSE);
954 gtk_window_focus_in_event (GtkWidget *widget,
955 GdkEventFocus *event)
958 GdkEventFocus fevent;
960 g_return_val_if_fail (widget != NULL, FALSE);
961 g_return_val_if_fail (GTK_IS_WINDOW (widget), FALSE);
962 g_return_val_if_fail (event != NULL, FALSE);
964 /* It appears spurious focus in events can occur when
965 * the window is hidden. So we'll just check to see if
966 * the window is visible before actually handling the
969 if (GTK_WIDGET_VISIBLE (widget))
971 window = GTK_WINDOW (widget);
972 if (window->focus_widget && !GTK_WIDGET_HAS_FOCUS (window->focus_widget))
974 fevent.type = GDK_FOCUS_CHANGE;
975 fevent.window = window->focus_widget->window;
978 gtk_widget_event (window->focus_widget, (GdkEvent*) &fevent);
986 gtk_window_focus_out_event (GtkWidget *widget,
987 GdkEventFocus *event)
990 GdkEventFocus fevent;
992 g_return_val_if_fail (widget != NULL, FALSE);
993 g_return_val_if_fail (GTK_IS_WINDOW (widget), FALSE);
994 g_return_val_if_fail (event != NULL, FALSE);
996 window = GTK_WINDOW (widget);
997 if (window->focus_widget && GTK_WIDGET_HAS_FOCUS (window->focus_widget))
999 fevent.type = GDK_FOCUS_CHANGE;
1000 fevent.window = window->focus_widget->window;
1003 gtk_widget_event (window->focus_widget, (GdkEvent*) &fevent);
1009 static GdkAtom atom_rcfiles = GDK_NONE;
1012 gtk_window_read_rcfiles (GtkWidget *widget,
1013 GdkEventClient *event)
1015 GList *embedded_windows;
1017 embedded_windows = gtk_object_get_data (GTK_OBJECT (widget), "gtk-embedded");
1018 if (embedded_windows)
1023 for(i = 0; i < 5; i++)
1025 sev.data_format = 32;
1026 sev.message_type = atom_rcfiles;
1028 while (embedded_windows)
1030 guint xid = GPOINTER_TO_UINT (embedded_windows->data);
1031 gdk_event_send_client_message ((GdkEvent *) &sev, xid);
1032 embedded_windows = embedded_windows->next;
1036 if (gtk_rc_reparse_all ())
1038 /* If the above returned true, some of our RC files are out
1039 * of date, so we need to reset all our widgets. Our other
1040 * toplevel windows will also get the message, but by
1041 * then, the RC file will up to date, so we have to tell
1046 toplevels = gtk_container_get_toplevels();
1049 gtk_widget_reset_rc_styles (toplevels->data);
1050 toplevels = toplevels->next;
1056 gtk_window_client_event (GtkWidget *widget,
1057 GdkEventClient *event)
1059 g_return_val_if_fail (widget != NULL, FALSE);
1060 g_return_val_if_fail (GTK_IS_WINDOW (widget), FALSE);
1061 g_return_val_if_fail (event != NULL, FALSE);
1064 atom_rcfiles = gdk_atom_intern("_GTK_READ_RCFILES", FALSE);
1066 if(event->message_type == atom_rcfiles)
1067 gtk_window_read_rcfiles (widget, event);
1073 gtk_window_check_resize (GtkContainer *container)
1077 g_return_if_fail (container != NULL);
1078 g_return_if_fail (GTK_IS_WINDOW (container));
1080 window = GTK_WINDOW (container);
1081 if (!window->handling_resize)
1083 if (GTK_WIDGET_VISIBLE (container))
1084 gtk_window_move_resize (window);
1086 GTK_CONTAINER (window)->need_resize = TRUE;
1090 /* FIXME: we leave container->resize_widgets set under some
1093 gtk_window_move_resize (GtkWindow *window)
1096 GtkContainer *container;
1101 gboolean needed_resize;
1102 gboolean size_changed;
1104 g_return_if_fail (window != NULL);
1105 g_return_if_fail (GTK_IS_WINDOW (window));
1107 widget = GTK_WIDGET (window);
1108 container = GTK_CONTAINER (widget);
1110 /* Remember old size, to know if we have to reset hints */
1111 width = widget->requisition.width;
1112 height = widget->requisition.height;
1113 gtk_widget_size_request (widget, &widget->requisition);
1115 size_changed = ((width != widget->requisition.width) ||
1116 (height != widget->requisition.height));
1120 gboolean saved_use_upos;
1122 saved_use_upos = window->use_uposition;
1123 gtk_window_set_hints (widget, &widget->requisition);
1124 window->use_uposition = saved_use_upos;
1129 width = widget->requisition.width;
1130 height = widget->requisition.height;
1132 if (window->use_uposition)
1133 switch (window->position)
1135 case GTK_WIN_POS_CENTER:
1136 x = (gdk_screen_width () - width) / 2;
1137 y = (gdk_screen_height () - height) / 2;
1138 gtk_widget_set_uposition (widget, x, y);
1140 case GTK_WIN_POS_MOUSE:
1141 gdk_window_get_pointer (NULL, &x, &y, NULL);
1146 screen_width = gdk_screen_width ();
1147 screen_height = gdk_screen_height ();
1151 else if (x > (screen_width - width))
1152 x = screen_width - width;
1156 else if (y > (screen_height - height))
1157 y = screen_height - height;
1159 gtk_widget_set_uposition (widget, x, y);
1163 /* Now, do the resizing */
1165 needed_resize = container->need_resize;
1166 container->need_resize = FALSE;
1168 if ((widget->requisition.width == 0) ||
1169 (widget->requisition.height == 0))
1171 widget->requisition.width = 200;
1172 widget->requisition.height = 200;
1175 if (!GTK_WIDGET_REALIZED (window))
1177 GtkAllocation allocation;
1181 allocation.width = widget->requisition.width;
1182 allocation.height = widget->requisition.height;
1184 gtk_widget_size_allocate (widget, &allocation);
1189 gdk_window_get_geometry (widget->window, NULL, NULL, &width, &height, NULL);
1191 /* As an optimization, we don't try to get a new size from the
1192 * window manager if we asked for the same size last time and
1196 (((window->auto_shrink &&
1197 ((width != widget->requisition.width) ||
1198 (height != widget->requisition.height)))) ||
1199 ((width < widget->requisition.width) ||
1200 (height < widget->requisition.height))))
1202 window->resize_count += 1;
1203 if ((x != -1) && (y != -1))
1204 gdk_window_move_resize (widget->window, x, y,
1205 widget->requisition.width,
1206 widget->requisition.height);
1208 gdk_window_resize (widget->window,
1209 widget->requisition.width,
1210 widget->requisition.height);
1212 else if (needed_resize)
1214 /* The windows contents changed size while it was not
1215 * visible, so reallocate everything, since we didn't
1216 * keep track of what changed
1218 GtkAllocation allocation;
1222 allocation.width = widget->requisition.width;
1223 allocation.height = widget->requisition.height;
1225 gtk_widget_size_allocate (widget, &allocation);
1229 if ((x != -1) && (y != -1))
1230 gdk_window_move (widget->window, x, y);
1232 gtk_container_resize_children (GTK_CONTAINER (window));
1237 gtk_window_real_set_focus (GtkWindow *window,
1240 GdkEventFocus event;
1242 g_return_if_fail (window != NULL);
1243 g_return_if_fail (GTK_IS_WINDOW (window));
1245 if (window->focus_widget)
1247 event.type = GDK_FOCUS_CHANGE;
1248 event.window = window->focus_widget->window;
1251 gtk_widget_event (window->focus_widget, (GdkEvent*) &event);
1254 window->focus_widget = focus;
1256 if (window->focus_widget)
1258 event.type = GDK_FOCUS_CHANGE;
1259 event.window = window->focus_widget->window;
1262 gtk_widget_event (window->focus_widget, (GdkEvent*) &event);
1267 gtk_window_set_hints (GtkWidget *widget,
1268 GtkRequisition *requisition)
1271 GtkWidgetAuxInfo *aux_info;
1275 g_return_if_fail (widget != NULL);
1276 g_return_if_fail (GTK_IS_WINDOW (widget));
1277 g_return_if_fail (requisition != NULL);
1279 if (GTK_WIDGET_REALIZED (widget))
1281 window = GTK_WINDOW (widget);
1287 aux_info = gtk_object_get_data (GTK_OBJECT (widget), "gtk-aux-info");
1288 if (aux_info && (aux_info->x != -1) && (aux_info->y != -1))
1292 flags |= GDK_HINT_POS;
1295 if (!window->allow_shrink)
1296 flags |= GDK_HINT_MIN_SIZE;
1297 if (!window->allow_grow)
1298 flags |= GDK_HINT_MAX_SIZE;
1300 gdk_window_set_hints (widget->window,
1302 requisition->width, requisition->height,
1303 requisition->width, requisition->height,
1306 if (window->use_uposition && (flags & GDK_HINT_POS))
1308 window->use_uposition = FALSE;
1309 gdk_window_move (widget->window, ux, uy);
1315 gtk_window_paint (GtkWidget *widget,
1318 gtk_paint_flat_box (widget->style, widget->window, GTK_STATE_NORMAL,
1319 GTK_SHADOW_NONE, area, widget, "base", 0, 0, -1, -1);
1323 gtk_window_expose (GtkWidget *widget,
1324 GdkEventExpose *event)
1326 g_return_val_if_fail (widget != NULL, FALSE);
1327 g_return_val_if_fail (GTK_IS_WINDOW (widget), FALSE);
1328 g_return_val_if_fail (event != NULL, FALSE);
1330 gtk_window_paint (widget, &event->area);
1332 if (GTK_WIDGET_CLASS (parent_class)->expose_event)
1333 return (* GTK_WIDGET_CLASS (parent_class)->expose_event) (widget, event);
1339 gtk_window_draw (GtkWidget *widget,
1342 gtk_window_paint (widget, area);
1344 if (GTK_WIDGET_CLASS (parent_class)->draw)
1345 (* GTK_WIDGET_CLASS (parent_class)->draw) (widget, area);
1349 gtk_window_style_set (GtkWidget *widget,
1350 GtkStyle *previous_style)
1354 if (GTK_WIDGET_REALIZED (widget) &&
1355 !GTK_WIDGET_NO_WINDOW (widget))
1357 gtk_style_set_background (widget->style, widget->window, widget->state);
1361 area.width = widget->allocation.width;
1362 area.height = widget->allocation.height;
1363 gtk_window_draw(widget, &area);
1365 if (GTK_WIDGET_DRAWABLE (widget))
1366 gdk_window_clear (widget->window);