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"
44 typedef gint (*GtkWindowSignal1) (GtkObject *object,
50 typedef void (*GtkWindowSignal2) (GtkObject *object,
54 static void gtk_window_marshal_signal_2 (GtkObject *object,
58 static void gtk_window_class_init (GtkWindowClass *klass);
59 static void gtk_window_init (GtkWindow *window);
60 static void gtk_window_set_arg (GtkWindow *window,
63 static void gtk_window_get_arg (GtkWindow *window,
66 static void gtk_window_shutdown (GtkObject *object);
67 static void gtk_window_destroy (GtkObject *object);
68 static void gtk_window_finalize (GtkObject *object);
69 static void gtk_window_show (GtkWidget *widget);
70 static void gtk_window_hide (GtkWidget *widget);
71 static void gtk_window_map (GtkWidget *widget);
72 static void gtk_window_unmap (GtkWidget *widget);
73 static void gtk_window_realize (GtkWidget *widget);
74 static void gtk_window_size_request (GtkWidget *widget,
75 GtkRequisition *requisition);
76 static void gtk_window_size_allocate (GtkWidget *widget,
77 GtkAllocation *allocation);
78 static gint gtk_window_expose_event (GtkWidget *widget,
79 GdkEventExpose *event);
80 static gint gtk_window_configure_event (GtkWidget *widget,
81 GdkEventConfigure *event);
82 static gint gtk_window_key_press_event (GtkWidget *widget,
84 static gint gtk_window_key_release_event (GtkWidget *widget,
86 static gint gtk_window_enter_notify_event (GtkWidget *widget,
87 GdkEventCrossing *event);
88 static gint gtk_window_leave_notify_event (GtkWidget *widget,
89 GdkEventCrossing *event);
90 static gint gtk_window_focus_in_event (GtkWidget *widget,
91 GdkEventFocus *event);
92 static gint gtk_window_focus_out_event (GtkWidget *widget,
93 GdkEventFocus *event);
94 static gint gtk_window_client_event (GtkWidget *widget,
95 GdkEventClient *event);
96 static void gtk_window_check_resize (GtkContainer *container);
97 static void gtk_real_window_set_focus (GtkWindow *window,
99 static void gtk_window_move_resize (GtkWindow *window);
100 static void gtk_window_set_hints (GtkWidget *widget,
101 GtkRequisition *requisition);
103 static void gtk_window_read_rcfiles (GtkWidget *widget,
104 GdkEventClient *event);
107 static GtkBinClass *parent_class = NULL;
108 static guint window_signals[LAST_SIGNAL] = { 0 };
112 gtk_window_get_type (void)
114 static GtkType window_type = 0;
118 GtkTypeInfo window_info =
122 sizeof (GtkWindowClass),
123 (GtkClassInitFunc) gtk_window_class_init,
124 (GtkObjectInitFunc) gtk_window_init,
125 (GtkArgSetFunc) gtk_window_set_arg,
126 (GtkArgGetFunc) gtk_window_get_arg,
129 window_type = gtk_type_unique (gtk_bin_get_type (), &window_info);
136 gtk_window_class_init (GtkWindowClass *klass)
138 GtkObjectClass *object_class;
139 GtkWidgetClass *widget_class;
140 GtkContainerClass *container_class;
142 object_class = (GtkObjectClass*) klass;
143 widget_class = (GtkWidgetClass*) klass;
144 container_class = (GtkContainerClass*) klass;
146 parent_class = gtk_type_class (gtk_bin_get_type ());
148 gtk_object_add_arg_type ("GtkWindow::type", GTK_TYPE_WINDOW_TYPE, GTK_ARG_READWRITE, ARG_TYPE);
149 gtk_object_add_arg_type ("GtkWindow::title", GTK_TYPE_STRING, GTK_ARG_READWRITE, ARG_TITLE);
150 gtk_object_add_arg_type ("GtkWindow::auto_shrink", GTK_TYPE_BOOL, GTK_ARG_READWRITE, ARG_AUTO_SHRINK);
151 gtk_object_add_arg_type ("GtkWindow::allow_shrink", GTK_TYPE_BOOL, GTK_ARG_READWRITE, ARG_ALLOW_SHRINK);
152 gtk_object_add_arg_type ("GtkWindow::allow_grow", GTK_TYPE_BOOL, GTK_ARG_READWRITE, ARG_ALLOW_GROW);
153 gtk_object_add_arg_type ("GtkWindow::window_position", GTK_TYPE_WINDOW_POSITION, GTK_ARG_READWRITE, ARG_WIN_POS);
155 window_signals[SET_FOCUS] =
156 gtk_signal_new ("set_focus",
159 GTK_SIGNAL_OFFSET (GtkWindowClass, set_focus),
160 gtk_window_marshal_signal_2,
164 gtk_object_class_add_signals (object_class, window_signals, LAST_SIGNAL);
166 object_class->shutdown = gtk_window_shutdown;
167 object_class->destroy = gtk_window_destroy;
168 object_class->finalize = gtk_window_finalize;
170 widget_class->show = gtk_window_show;
171 widget_class->hide = gtk_window_hide;
172 widget_class->map = gtk_window_map;
173 widget_class->unmap = gtk_window_unmap;
174 widget_class->realize = gtk_window_realize;
175 widget_class->size_request = gtk_window_size_request;
176 widget_class->size_allocate = gtk_window_size_allocate;
177 widget_class->expose_event = gtk_window_expose_event;
178 widget_class->configure_event = gtk_window_configure_event;
179 widget_class->key_press_event = gtk_window_key_press_event;
180 widget_class->key_release_event = gtk_window_key_release_event;
181 widget_class->enter_notify_event = gtk_window_enter_notify_event;
182 widget_class->leave_notify_event = gtk_window_leave_notify_event;
183 widget_class->focus_in_event = gtk_window_focus_in_event;
184 widget_class->focus_out_event = gtk_window_focus_out_event;
185 widget_class->client_event = gtk_window_client_event;
187 container_class->check_resize = gtk_window_check_resize;
189 klass->set_focus = gtk_real_window_set_focus;
193 gtk_window_init (GtkWindow *window)
195 GTK_WIDGET_UNSET_FLAGS (window, GTK_NO_WINDOW);
196 GTK_WIDGET_SET_FLAGS (window, GTK_TOPLEVEL);
198 gtk_container_set_resize_mode (GTK_CONTAINER (window), GTK_RESIZE_QUEUE);
200 window->title = NULL;
201 window->wmclass_name = g_strdup (gdk_progname);
202 window->wmclass_class = g_strdup (gdk_progclass);
203 window->type = GTK_WINDOW_TOPLEVEL;
204 window->focus_widget = NULL;
205 window->default_widget = NULL;
206 window->resize_count = 0;
207 window->allow_shrink = FALSE;
208 window->allow_grow = TRUE;
209 window->auto_shrink = FALSE;
210 window->handling_resize = FALSE;
211 window->position = GTK_WIN_POS_NONE;
212 window->use_uposition = TRUE;
214 gtk_container_register_toplevel (GTK_CONTAINER (window));
218 gtk_window_set_arg (GtkWindow *window,
225 window->type = GTK_VALUE_ENUM (*arg);
228 gtk_window_set_title (window, GTK_VALUE_STRING (*arg));
230 case ARG_AUTO_SHRINK:
231 window->auto_shrink = (GTK_VALUE_BOOL (*arg) != FALSE);
232 gtk_window_set_hints (GTK_WIDGET (window), >K_WIDGET (window)->requisition);
234 case ARG_ALLOW_SHRINK:
235 window->allow_shrink = (GTK_VALUE_BOOL (*arg) != FALSE);
236 gtk_window_set_hints (GTK_WIDGET (window), >K_WIDGET (window)->requisition);
239 window->allow_grow = (GTK_VALUE_BOOL (*arg) != FALSE);
240 gtk_window_set_hints (GTK_WIDGET (window), >K_WIDGET (window)->requisition);
243 gtk_window_position (window, GTK_VALUE_ENUM (*arg));
251 gtk_window_get_arg (GtkWindow *window,
258 GTK_VALUE_ENUM (*arg) = window->type;
261 GTK_VALUE_STRING (*arg) = g_strdup (window->title);
263 case ARG_AUTO_SHRINK:
264 GTK_VALUE_BOOL (*arg) = window->auto_shrink;
266 case ARG_ALLOW_SHRINK:
267 GTK_VALUE_BOOL (*arg) = window->allow_shrink;
270 GTK_VALUE_BOOL (*arg) = window->allow_grow;
273 GTK_VALUE_ENUM (*arg) = window->position;
276 arg->type = GTK_TYPE_INVALID;
282 gtk_window_new (GtkWindowType type)
286 window = gtk_type_new (gtk_window_get_type ());
290 return GTK_WIDGET (window);
294 gtk_window_set_title (GtkWindow *window,
297 g_return_if_fail (window != NULL);
298 g_return_if_fail (GTK_IS_WINDOW (window));
301 g_free (window->title);
302 window->title = g_strdup (title);
304 if (GTK_WIDGET_REALIZED (window))
305 gdk_window_set_title (GTK_WIDGET (window)->window, window->title);
309 gtk_window_set_wmclass (GtkWindow *window,
310 const gchar *wmclass_name,
311 const gchar *wmclass_class)
313 g_return_if_fail (window != NULL);
314 g_return_if_fail (GTK_IS_WINDOW (window));
316 g_free (window->wmclass_name);
317 window->wmclass_name = g_strdup (wmclass_name);
319 g_free (window->wmclass_class);
320 window->wmclass_class = g_strdup (wmclass_class);
322 if (GTK_WIDGET_REALIZED (window))
323 g_warning ("shouldn't set wmclass after window is realized!\n");
327 gtk_window_set_focus (GtkWindow *window,
330 gtk_signal_emit (GTK_OBJECT (window), window_signals[SET_FOCUS], focus);
334 gtk_window_set_default (GtkWindow *window,
335 GtkWidget *default_widget)
337 g_return_if_fail (window != NULL);
338 g_return_if_fail (GTK_IS_WINDOW (window));
341 g_return_if_fail (GTK_WIDGET_CAN_DEFAULT (default_widget));
343 if (window->default_widget != default_widget)
345 if (window->default_widget)
347 GTK_WIDGET_UNSET_FLAGS (window->default_widget, GTK_HAS_DEFAULT);
348 gtk_widget_draw_default (window->default_widget);
351 window->default_widget = default_widget;
353 if (window->default_widget)
355 GTK_WIDGET_SET_FLAGS (window->default_widget, GTK_HAS_DEFAULT);
356 gtk_widget_draw_default (window->default_widget);
362 gtk_window_set_policy (GtkWindow *window,
367 g_return_if_fail (window != NULL);
368 g_return_if_fail (GTK_IS_WINDOW (window));
370 window->allow_shrink = (allow_shrink != FALSE);
371 window->allow_grow = (allow_grow != FALSE);
372 window->auto_shrink = (auto_shrink != FALSE);
374 gtk_window_set_hints (GTK_WIDGET (window), >K_WIDGET (window)->requisition);
378 gtk_window_add_accel_group (GtkWindow *window,
379 GtkAccelGroup *accel_group)
381 g_return_if_fail (window != NULL);
382 g_return_if_fail (GTK_IS_WINDOW (window));
383 g_return_if_fail (accel_group != NULL);
385 gtk_accel_group_attach (accel_group, GTK_OBJECT (window));
389 gtk_window_remove_accel_group (GtkWindow *window,
390 GtkAccelGroup *accel_group)
392 g_return_if_fail (window != NULL);
393 g_return_if_fail (GTK_IS_WINDOW (window));
394 g_return_if_fail (accel_group != NULL);
396 gtk_accel_group_detach (accel_group, GTK_OBJECT (window));
400 gtk_window_position (GtkWindow *window,
401 GtkWindowPosition position)
403 g_return_if_fail (window != NULL);
404 g_return_if_fail (GTK_IS_WINDOW (window));
406 window->position = position;
410 gtk_window_activate_focus (GtkWindow *window)
412 g_return_val_if_fail (window != NULL, FALSE);
413 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
415 if (window->focus_widget)
417 gtk_widget_activate (window->focus_widget);
425 gtk_window_activate_default (GtkWindow *window)
427 g_return_val_if_fail (window != NULL, FALSE);
428 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
430 if (window->default_widget)
432 gtk_widget_activate (window->default_widget);
440 gtk_window_marshal_signal_2 (GtkObject *object,
445 GtkWindowSignal2 rfunc;
447 rfunc = (GtkWindowSignal2) func;
449 (* rfunc) (object, GTK_VALUE_POINTER (args[0]), func_data);
453 gtk_window_shutdown (GtkObject *object)
457 g_return_if_fail (object != NULL);
458 g_return_if_fail (GTK_IS_WINDOW (object));
460 window = GTK_WINDOW (object);
462 gtk_window_set_focus (window, NULL);
463 gtk_window_set_default (window, NULL);
465 GTK_OBJECT_CLASS (parent_class)->shutdown (object);
469 gtk_window_destroy (GtkObject *object)
471 g_return_if_fail (object != NULL);
472 g_return_if_fail (GTK_IS_WINDOW (object));
474 gtk_container_unregister_toplevel (GTK_CONTAINER (object));
476 GTK_OBJECT_CLASS (parent_class)->destroy (object);
480 gtk_window_finalize (GtkObject *object)
484 g_return_if_fail (object != NULL);
485 g_return_if_fail (GTK_IS_WINDOW (object));
487 window = GTK_WINDOW (object);
488 g_free (window->title);
489 g_free (window->wmclass_name);
490 g_free (window->wmclass_class);
492 GTK_OBJECT_CLASS(parent_class)->finalize (object);
496 gtk_window_show (GtkWidget *widget)
498 g_return_if_fail (widget != NULL);
499 g_return_if_fail (GTK_IS_WINDOW (widget));
501 GTK_WIDGET_SET_FLAGS (widget, GTK_VISIBLE);
502 gtk_container_check_resize (GTK_CONTAINER (widget));
503 gtk_widget_map (widget);
507 gtk_window_hide (GtkWidget *widget)
509 g_return_if_fail (widget != NULL);
510 g_return_if_fail (GTK_IS_WINDOW (widget));
512 GTK_WIDGET_UNSET_FLAGS (widget, GTK_VISIBLE);
513 gtk_widget_unmap (widget);
517 gtk_window_map (GtkWidget *widget)
521 g_return_if_fail (widget != NULL);
522 g_return_if_fail (GTK_IS_WINDOW (widget));
524 GTK_WIDGET_SET_FLAGS (widget, GTK_MAPPED);
526 window = GTK_WINDOW (widget);
528 if (window->bin.child &&
529 GTK_WIDGET_VISIBLE (window->bin.child) &&
530 !GTK_WIDGET_MAPPED (window->bin.child))
531 gtk_widget_map (window->bin.child);
533 gtk_window_set_hints (widget, &widget->requisition);
534 gdk_window_show (widget->window);
538 gtk_window_unmap (GtkWidget *widget)
542 g_return_if_fail (widget != NULL);
543 g_return_if_fail (GTK_IS_WINDOW (widget));
545 GTK_WIDGET_UNSET_FLAGS (widget, GTK_MAPPED);
546 gdk_window_hide (widget->window);
548 window = GTK_WINDOW (widget);
549 window->use_uposition = TRUE;
553 gtk_window_realize (GtkWidget *widget)
556 GdkWindowAttr attributes;
557 gint attributes_mask;
559 g_return_if_fail (widget != NULL);
560 g_return_if_fail (GTK_IS_WINDOW (widget));
562 GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED);
563 window = GTK_WINDOW (widget);
565 switch (window->type)
567 case GTK_WINDOW_TOPLEVEL:
568 attributes.window_type = GDK_WINDOW_TOPLEVEL;
570 case GTK_WINDOW_DIALOG:
571 attributes.window_type = GDK_WINDOW_DIALOG;
573 case GTK_WINDOW_POPUP:
574 attributes.window_type = GDK_WINDOW_TEMP;
578 attributes.title = window->title;
579 attributes.wmclass_name = window->wmclass_name;
580 attributes.wmclass_class = window->wmclass_class;
581 attributes.width = widget->allocation.width;
582 attributes.height = widget->allocation.height;
583 attributes.wclass = GDK_INPUT_OUTPUT;
584 attributes.visual = gtk_widget_get_visual (widget);
585 attributes.colormap = gtk_widget_get_colormap (widget);
586 attributes.event_mask = gtk_widget_get_events (widget);
587 attributes.event_mask |= (GDK_EXPOSURE_MASK |
589 GDK_ENTER_NOTIFY_MASK |
590 GDK_LEAVE_NOTIFY_MASK |
591 GDK_FOCUS_CHANGE_MASK |
594 attributes_mask = GDK_WA_VISUAL | GDK_WA_COLORMAP;
595 attributes_mask |= (window->title ? GDK_WA_TITLE : 0);
596 attributes_mask |= (window->wmclass_name ? GDK_WA_WMCLASS : 0);
598 widget->window = gdk_window_new (NULL, &attributes, attributes_mask);
599 gdk_window_set_user_data (widget->window, window);
601 widget->style = gtk_style_attach (widget->style, widget->window);
602 gtk_style_set_background (widget->style, widget->window, GTK_STATE_NORMAL);
606 gtk_window_size_request (GtkWidget *widget,
607 GtkRequisition *requisition)
611 g_return_if_fail (widget != NULL);
612 g_return_if_fail (GTK_IS_WINDOW (widget));
613 g_return_if_fail (requisition != NULL);
615 window = GTK_WINDOW (widget);
617 if (window->bin.child)
619 requisition->width = GTK_CONTAINER (window)->border_width * 2;
620 requisition->height = GTK_CONTAINER (window)->border_width * 2;
622 gtk_widget_size_request (window->bin.child, &window->bin.child->requisition);
624 requisition->width += window->bin.child->requisition.width;
625 requisition->height += window->bin.child->requisition.height;
629 if (!GTK_WIDGET_VISIBLE (window))
630 GTK_CONTAINER (window)->need_resize = TRUE;
635 gtk_window_size_allocate (GtkWidget *widget,
636 GtkAllocation *allocation)
639 GtkAllocation child_allocation;
641 g_return_if_fail (widget != NULL);
642 g_return_if_fail (GTK_IS_WINDOW (widget));
643 g_return_if_fail (allocation != NULL);
645 window = GTK_WINDOW (widget);
646 widget->allocation = *allocation;
648 if (window->bin.child && GTK_WIDGET_VISIBLE (window->bin.child))
650 child_allocation.x = GTK_CONTAINER (window)->border_width;
651 child_allocation.y = GTK_CONTAINER (window)->border_width;
652 child_allocation.width = allocation->width - child_allocation.x * 2;
653 child_allocation.height = allocation->height - child_allocation.y * 2;
655 gtk_widget_size_allocate (window->bin.child, &child_allocation);
660 gtk_window_expose_event (GtkWidget *widget,
661 GdkEventExpose *event)
663 g_return_val_if_fail (widget != NULL, FALSE);
664 g_return_val_if_fail (GTK_IS_WINDOW (widget), FALSE);
665 g_return_val_if_fail (event != NULL, FALSE);
667 if (GTK_WIDGET_DRAWABLE (widget))
668 if (GTK_WIDGET_CLASS (parent_class)->expose_event)
669 return (* GTK_WIDGET_CLASS (parent_class)->expose_event) (widget, event);
675 gtk_window_configure_event (GtkWidget *widget,
676 GdkEventConfigure *event)
679 GtkAllocation allocation;
681 g_return_val_if_fail (widget != NULL, FALSE);
682 g_return_val_if_fail (GTK_IS_WINDOW (widget), FALSE);
683 g_return_val_if_fail (event != NULL, FALSE);
685 window = GTK_WINDOW (widget);
687 /* If the window was merely moved, do nothing */
688 if ((widget->allocation.width == event->width) &&
689 (widget->allocation.height == event->height) &&
690 (window->resize_count == 0))
693 window->handling_resize = TRUE;
697 allocation.width = event->width;
698 allocation.height = event->height;
700 gtk_widget_size_allocate (widget, &allocation);
702 if (window->bin.child &&
703 GTK_WIDGET_VISIBLE (window->bin.child) &&
704 !GTK_WIDGET_MAPPED (window->bin.child))
705 gtk_widget_map (window->bin.child);
707 if (window->resize_count > 0)
708 window->resize_count -= 1;
710 window->handling_resize = FALSE;
716 gtk_window_key_press_event (GtkWidget *widget,
720 GtkDirectionType direction = 0;
723 g_return_val_if_fail (widget != NULL, FALSE);
724 g_return_val_if_fail (GTK_IS_WINDOW (widget), FALSE);
725 g_return_val_if_fail (event != NULL, FALSE);
727 window = GTK_WINDOW (widget);
731 if (window->focus_widget)
733 handled = gtk_widget_event (window->focus_widget, (GdkEvent*) event);
737 handled = gtk_accel_groups_activate (GTK_OBJECT (window), event->keyval, event->state);
741 switch (event->keyval)
744 if (window->focus_widget)
746 gtk_widget_activate (window->focus_widget);
752 if (window->default_widget)
754 gtk_widget_activate (window->default_widget);
757 else if (window->focus_widget)
759 gtk_widget_activate (window->focus_widget);
768 case GDK_ISO_Left_Tab:
769 switch (event->keyval)
772 direction = GTK_DIR_UP;
775 direction = GTK_DIR_DOWN;
778 direction = GTK_DIR_LEFT;
781 direction = GTK_DIR_RIGHT;
784 case GDK_ISO_Left_Tab:
785 if (event->state & GDK_SHIFT_MASK)
786 direction = GTK_DIR_TAB_BACKWARD;
788 direction = GTK_DIR_TAB_FORWARD;
791 direction = GTK_DIR_UP; /* never reached, but makes compiler happy */
794 gtk_container_focus (GTK_CONTAINER (widget), direction);
796 if (!GTK_CONTAINER (window)->focus_child)
797 gtk_window_set_focus (GTK_WINDOW (widget), NULL);
804 if (!handled && GTK_WIDGET_CLASS (parent_class)->key_press_event)
805 handled = GTK_WIDGET_CLASS (parent_class)->key_press_event (widget, event);
811 gtk_window_key_release_event (GtkWidget *widget,
817 g_return_val_if_fail (widget != NULL, FALSE);
818 g_return_val_if_fail (GTK_IS_WINDOW (widget), FALSE);
819 g_return_val_if_fail (event != NULL, FALSE);
821 window = GTK_WINDOW (widget);
823 if (window->focus_widget)
825 handled = gtk_widget_event (window->focus_widget, (GdkEvent*) event);
828 if (!handled && GTK_WIDGET_CLASS (parent_class)->key_release_event)
829 handled = GTK_WIDGET_CLASS (parent_class)->key_release_event (widget, event);
835 gtk_window_enter_notify_event (GtkWidget *widget,
836 GdkEventCrossing *event)
838 g_return_val_if_fail (widget != NULL, FALSE);
839 g_return_val_if_fail (GTK_IS_WINDOW (widget), FALSE);
840 g_return_val_if_fail (event != NULL, FALSE);
846 gtk_window_leave_notify_event (GtkWidget *widget,
847 GdkEventCrossing *event)
849 g_return_val_if_fail (widget != NULL, FALSE);
850 g_return_val_if_fail (GTK_IS_WINDOW (widget), FALSE);
851 g_return_val_if_fail (event != NULL, FALSE);
857 gtk_window_focus_in_event (GtkWidget *widget,
858 GdkEventFocus *event)
861 GdkEventFocus fevent;
863 g_return_val_if_fail (widget != NULL, FALSE);
864 g_return_val_if_fail (GTK_IS_WINDOW (widget), FALSE);
865 g_return_val_if_fail (event != NULL, FALSE);
867 /* It appears spurious focus in events can occur when
868 * the window is hidden. So we'll just check to see if
869 * the window is visible before actually handling the
872 if (GTK_WIDGET_VISIBLE (widget))
874 window = GTK_WINDOW (widget);
875 if (window->focus_widget && !GTK_WIDGET_HAS_FOCUS (window->focus_widget))
877 fevent.type = GDK_FOCUS_CHANGE;
878 fevent.window = window->focus_widget->window;
881 gtk_widget_event (window->focus_widget, (GdkEvent*) &fevent);
889 gtk_window_focus_out_event (GtkWidget *widget,
890 GdkEventFocus *event)
893 GdkEventFocus fevent;
895 g_return_val_if_fail (widget != NULL, FALSE);
896 g_return_val_if_fail (GTK_IS_WINDOW (widget), FALSE);
897 g_return_val_if_fail (event != NULL, FALSE);
899 window = GTK_WINDOW (widget);
900 if (window->focus_widget && GTK_WIDGET_HAS_FOCUS (window->focus_widget))
902 fevent.type = GDK_FOCUS_CHANGE;
903 fevent.window = window->focus_widget->window;
906 gtk_widget_event (window->focus_widget, (GdkEvent*) &fevent);
913 gtk_window_read_rcfiles (GtkWidget *widget,
914 GdkEventClient *event)
918 if (gtk_rc_reparse_all ())
920 toplevels = gdk_window_get_toplevels();
924 gdk_window_get_user_data (toplevels->data, (gpointer *)&widget);
927 gtk_widget_reset_rc_styles (widget);
929 toplevels = toplevels->next;
931 g_list_free (toplevels);
936 gtk_window_client_event (GtkWidget *widget,
937 GdkEventClient *event)
939 static GdkAtom atom_rcfiles = GDK_NONE;
940 g_return_val_if_fail (widget != NULL, FALSE);
941 g_return_val_if_fail (GTK_IS_WINDOW (widget), FALSE);
942 g_return_val_if_fail (event != NULL, FALSE);
945 atom_rcfiles = gdk_atom_intern("_GTK_READ_RCFILES", FALSE);
947 if(event->message_type == atom_rcfiles)
948 gtk_window_read_rcfiles (widget, event);
954 gtk_window_check_resize (GtkContainer *container)
958 g_return_if_fail (container != NULL);
959 g_return_if_fail (GTK_IS_WINDOW (container));
961 window = GTK_WINDOW (container);
962 if (!window->handling_resize)
964 if (GTK_WIDGET_VISIBLE (container))
965 gtk_window_move_resize (window);
967 GTK_CONTAINER (window)->need_resize = TRUE;
971 /* FIXME: we leave container->resize_widgets set under some
974 gtk_window_move_resize (GtkWindow *window)
977 GtkContainer *container;
982 gboolean needed_resize;
984 g_return_if_fail (window != NULL);
985 g_return_if_fail (GTK_IS_WINDOW (window));
987 widget = GTK_WIDGET (window);
988 container = GTK_CONTAINER (widget);
990 /* Remember old size, to know if we have to reset hints */
991 width = widget->requisition.width;
992 height = widget->requisition.height;
993 gtk_widget_size_request (widget, &widget->requisition);
995 if ((width != widget->requisition.width ||
996 height != widget->requisition.height))
998 gboolean saved_use_upos;
1000 saved_use_upos = window->use_uposition;
1001 gtk_window_set_hints (widget, &widget->requisition);
1002 window->use_uposition = saved_use_upos;
1007 width = widget->requisition.width;
1008 height = widget->requisition.height;
1010 if (window->use_uposition)
1011 switch (window->position)
1013 case GTK_WIN_POS_CENTER:
1014 x = (gdk_screen_width () - width) / 2;
1015 y = (gdk_screen_height () - height) / 2;
1016 gtk_widget_set_uposition (widget, x, y);
1018 case GTK_WIN_POS_MOUSE:
1019 gdk_window_get_pointer (NULL, &x, &y, NULL);
1024 screen_width = gdk_screen_width ();
1025 screen_height = gdk_screen_height ();
1029 else if (x > (screen_width - width))
1030 x = screen_width - width;
1034 else if (y > (screen_height - height))
1035 y = screen_height - height;
1037 gtk_widget_set_uposition (widget, x, y);
1041 /* Now, do the resizing */
1043 needed_resize = container->need_resize;
1044 container->need_resize = FALSE;
1046 if ((widget->requisition.width == 0) ||
1047 (widget->requisition.height == 0))
1049 widget->requisition.width = 200;
1050 widget->requisition.height = 200;
1053 if (!GTK_WIDGET_REALIZED (window))
1055 GtkAllocation allocation;
1059 allocation.width = widget->requisition.width;
1060 allocation.height = widget->requisition.height;
1062 gtk_widget_size_allocate (widget, &allocation);
1067 gdk_window_get_geometry (widget->window, NULL, NULL, &width, &height, NULL);
1069 if ((window->auto_shrink &&
1070 ((width != widget->requisition.width) ||
1071 (height != widget->requisition.height))) ||
1072 (width < widget->requisition.width) ||
1073 (height < widget->requisition.height))
1075 window->resize_count += 1;
1076 if ((x != -1) && (y != -1))
1077 gdk_window_move_resize (widget->window, x, y,
1078 widget->requisition.width,
1079 widget->requisition.height);
1081 gdk_window_resize (widget->window,
1082 widget->requisition.width,
1083 widget->requisition.height);
1085 else if (needed_resize)
1087 /* The windows contents changed size while it was not
1088 * visible, so reallocate everything, since we didn't
1089 * keep track of what changed
1091 GtkAllocation allocation;
1095 allocation.width = widget->requisition.width;
1096 allocation.height = widget->requisition.height;
1098 gtk_widget_size_allocate (widget, &allocation);
1102 if ((x != -1) && (y != -1))
1103 gdk_window_move (widget->window, x, y);
1105 gtk_container_resize_children (GTK_CONTAINER (window));
1110 gtk_real_window_set_focus (GtkWindow *window,
1113 GdkEventFocus event;
1115 g_return_if_fail (window != NULL);
1116 g_return_if_fail (GTK_IS_WINDOW (window));
1118 if (focus && !GTK_WIDGET_CAN_FOCUS (focus))
1121 if (window->focus_widget != focus)
1123 if (window->focus_widget)
1125 event.type = GDK_FOCUS_CHANGE;
1126 event.window = window->focus_widget->window;
1129 gtk_widget_event (window->focus_widget, (GdkEvent*) &event);
1132 window->focus_widget = focus;
1134 if (window->focus_widget)
1136 event.type = GDK_FOCUS_CHANGE;
1137 event.window = window->focus_widget->window;
1140 gtk_widget_event (window->focus_widget, (GdkEvent*) &event);
1146 gtk_window_set_hints (GtkWidget *widget,
1147 GtkRequisition *requisition)
1150 GtkWidgetAuxInfo *aux_info;
1154 g_return_if_fail (widget != NULL);
1155 g_return_if_fail (GTK_IS_WINDOW (widget));
1156 g_return_if_fail (requisition != NULL);
1158 if (GTK_WIDGET_REALIZED (widget))
1160 window = GTK_WINDOW (widget);
1166 aux_info = gtk_object_get_data (GTK_OBJECT (widget), "gtk-aux-info");
1167 if (aux_info && (aux_info->x != -1) && (aux_info->y != -1))
1171 flags |= GDK_HINT_POS;
1174 if (!window->allow_shrink)
1175 flags |= GDK_HINT_MIN_SIZE;
1176 if (!window->allow_grow)
1177 flags |= GDK_HINT_MAX_SIZE;
1179 gdk_window_set_hints (widget->window, ux, uy,
1180 requisition->width, requisition->height,
1181 requisition->width, requisition->height,
1184 if (window->use_uposition && (flags & GDK_HINT_POS))
1186 window->use_uposition = FALSE;
1187 gdk_window_move (widget->window, ux, uy);