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 static void gtk_window_class_init (GtkWindowClass *klass);
45 static void gtk_window_init (GtkWindow *window);
46 static void gtk_window_set_arg (GtkObject *object,
49 static void gtk_window_get_arg (GtkObject *object,
52 static void gtk_window_shutdown (GtkObject *object);
53 static void gtk_window_destroy (GtkObject *object);
54 static void gtk_window_finalize (GtkObject *object);
55 static void gtk_window_show (GtkWidget *widget);
56 static void gtk_window_hide (GtkWidget *widget);
57 static void gtk_window_map (GtkWidget *widget);
58 static void gtk_window_unmap (GtkWidget *widget);
59 static void gtk_window_realize (GtkWidget *widget);
60 static void gtk_window_size_request (GtkWidget *widget,
61 GtkRequisition *requisition);
62 static void gtk_window_size_allocate (GtkWidget *widget,
63 GtkAllocation *allocation);
64 static gint gtk_window_expose_event (GtkWidget *widget,
65 GdkEventExpose *event);
66 static gint gtk_window_configure_event (GtkWidget *widget,
67 GdkEventConfigure *event);
68 static gint gtk_window_key_press_event (GtkWidget *widget,
70 static gint gtk_window_key_release_event (GtkWidget *widget,
72 static gint gtk_window_enter_notify_event (GtkWidget *widget,
73 GdkEventCrossing *event);
74 static gint gtk_window_leave_notify_event (GtkWidget *widget,
75 GdkEventCrossing *event);
76 static gint gtk_window_focus_in_event (GtkWidget *widget,
77 GdkEventFocus *event);
78 static gint gtk_window_focus_out_event (GtkWidget *widget,
79 GdkEventFocus *event);
80 static gint gtk_window_client_event (GtkWidget *widget,
81 GdkEventClient *event);
82 static void gtk_window_check_resize (GtkContainer *container);
83 static void gtk_real_window_set_focus (GtkWindow *window,
85 static void gtk_window_move_resize (GtkWindow *window);
86 static void gtk_window_set_hints (GtkWidget *widget,
87 GtkRequisition *requisition);
89 static void gtk_window_read_rcfiles (GtkWidget *widget,
90 GdkEventClient *event);
93 static GtkBinClass *parent_class = NULL;
94 static guint window_signals[LAST_SIGNAL] = { 0 };
98 gtk_window_get_type (void)
100 static GtkType window_type = 0;
104 GtkTypeInfo window_info =
108 sizeof (GtkWindowClass),
109 (GtkClassInitFunc) gtk_window_class_init,
110 (GtkObjectInitFunc) gtk_window_init,
111 /* reserved_1 */ NULL,
112 /* reserved_2 */ NULL,
113 (GtkClassInitFunc) NULL,
116 window_type = gtk_type_unique (gtk_bin_get_type (), &window_info);
123 gtk_window_class_init (GtkWindowClass *klass)
125 GtkObjectClass *object_class;
126 GtkWidgetClass *widget_class;
127 GtkContainerClass *container_class;
129 object_class = (GtkObjectClass*) klass;
130 widget_class = (GtkWidgetClass*) klass;
131 container_class = (GtkContainerClass*) klass;
133 parent_class = gtk_type_class (gtk_bin_get_type ());
135 gtk_object_add_arg_type ("GtkWindow::type", GTK_TYPE_WINDOW_TYPE, GTK_ARG_READWRITE, ARG_TYPE);
136 gtk_object_add_arg_type ("GtkWindow::title", GTK_TYPE_STRING, GTK_ARG_READWRITE, ARG_TITLE);
137 gtk_object_add_arg_type ("GtkWindow::auto_shrink", GTK_TYPE_BOOL, GTK_ARG_READWRITE, ARG_AUTO_SHRINK);
138 gtk_object_add_arg_type ("GtkWindow::allow_shrink", GTK_TYPE_BOOL, GTK_ARG_READWRITE, ARG_ALLOW_SHRINK);
139 gtk_object_add_arg_type ("GtkWindow::allow_grow", GTK_TYPE_BOOL, GTK_ARG_READWRITE, ARG_ALLOW_GROW);
140 gtk_object_add_arg_type ("GtkWindow::window_position", GTK_TYPE_WINDOW_POSITION, GTK_ARG_READWRITE, ARG_WIN_POS);
142 window_signals[SET_FOCUS] =
143 gtk_signal_new ("set_focus",
146 GTK_SIGNAL_OFFSET (GtkWindowClass, set_focus),
147 gtk_marshal_NONE__POINTER,
151 gtk_object_class_add_signals (object_class, window_signals, LAST_SIGNAL);
153 object_class->set_arg = gtk_window_set_arg;
154 object_class->get_arg = gtk_window_get_arg;
155 object_class->shutdown = gtk_window_shutdown;
156 object_class->destroy = gtk_window_destroy;
157 object_class->finalize = gtk_window_finalize;
159 widget_class->show = gtk_window_show;
160 widget_class->hide = gtk_window_hide;
161 widget_class->map = gtk_window_map;
162 widget_class->unmap = gtk_window_unmap;
163 widget_class->realize = gtk_window_realize;
164 widget_class->size_request = gtk_window_size_request;
165 widget_class->size_allocate = gtk_window_size_allocate;
166 widget_class->expose_event = gtk_window_expose_event;
167 widget_class->configure_event = gtk_window_configure_event;
168 widget_class->key_press_event = gtk_window_key_press_event;
169 widget_class->key_release_event = gtk_window_key_release_event;
170 widget_class->enter_notify_event = gtk_window_enter_notify_event;
171 widget_class->leave_notify_event = gtk_window_leave_notify_event;
172 widget_class->focus_in_event = gtk_window_focus_in_event;
173 widget_class->focus_out_event = gtk_window_focus_out_event;
174 widget_class->client_event = gtk_window_client_event;
176 container_class->check_resize = gtk_window_check_resize;
178 klass->set_focus = gtk_real_window_set_focus;
182 gtk_window_init (GtkWindow *window)
184 GTK_WIDGET_UNSET_FLAGS (window, GTK_NO_WINDOW);
185 GTK_WIDGET_SET_FLAGS (window, GTK_TOPLEVEL);
187 gtk_container_set_resize_mode (GTK_CONTAINER (window), GTK_RESIZE_QUEUE);
189 window->title = NULL;
190 window->wmclass_name = g_strdup (gdk_progname);
191 window->wmclass_class = g_strdup (gdk_progclass);
192 window->type = GTK_WINDOW_TOPLEVEL;
193 window->focus_widget = NULL;
194 window->default_widget = NULL;
195 window->resize_count = 0;
196 window->allow_shrink = FALSE;
197 window->allow_grow = TRUE;
198 window->auto_shrink = FALSE;
199 window->handling_resize = FALSE;
200 window->position = GTK_WIN_POS_NONE;
201 window->use_uposition = TRUE;
203 gtk_container_register_toplevel (GTK_CONTAINER (window));
207 gtk_window_set_arg (GtkObject *object,
213 window = GTK_WINDOW (object);
218 window->type = GTK_VALUE_ENUM (*arg);
221 gtk_window_set_title (window, GTK_VALUE_STRING (*arg));
223 case ARG_AUTO_SHRINK:
224 window->auto_shrink = (GTK_VALUE_BOOL (*arg) != FALSE);
225 gtk_window_set_hints (GTK_WIDGET (window), >K_WIDGET (window)->requisition);
227 case ARG_ALLOW_SHRINK:
228 window->allow_shrink = (GTK_VALUE_BOOL (*arg) != FALSE);
229 gtk_window_set_hints (GTK_WIDGET (window), >K_WIDGET (window)->requisition);
232 window->allow_grow = (GTK_VALUE_BOOL (*arg) != FALSE);
233 gtk_window_set_hints (GTK_WIDGET (window), >K_WIDGET (window)->requisition);
236 gtk_window_position (window, GTK_VALUE_ENUM (*arg));
244 gtk_window_get_arg (GtkObject *object,
250 window = GTK_WINDOW (object);
255 GTK_VALUE_ENUM (*arg) = window->type;
258 GTK_VALUE_STRING (*arg) = g_strdup (window->title);
260 case ARG_AUTO_SHRINK:
261 GTK_VALUE_BOOL (*arg) = window->auto_shrink;
263 case ARG_ALLOW_SHRINK:
264 GTK_VALUE_BOOL (*arg) = window->allow_shrink;
267 GTK_VALUE_BOOL (*arg) = window->allow_grow;
270 GTK_VALUE_ENUM (*arg) = window->position;
273 arg->type = GTK_TYPE_INVALID;
279 gtk_window_new (GtkWindowType type)
283 window = gtk_type_new (gtk_window_get_type ());
287 return GTK_WIDGET (window);
291 gtk_window_set_title (GtkWindow *window,
294 g_return_if_fail (window != NULL);
295 g_return_if_fail (GTK_IS_WINDOW (window));
298 g_free (window->title);
299 window->title = g_strdup (title);
301 if (GTK_WIDGET_REALIZED (window))
302 gdk_window_set_title (GTK_WIDGET (window)->window, window->title);
306 gtk_window_set_wmclass (GtkWindow *window,
307 const gchar *wmclass_name,
308 const gchar *wmclass_class)
310 g_return_if_fail (window != NULL);
311 g_return_if_fail (GTK_IS_WINDOW (window));
313 g_free (window->wmclass_name);
314 window->wmclass_name = g_strdup (wmclass_name);
316 g_free (window->wmclass_class);
317 window->wmclass_class = g_strdup (wmclass_class);
319 if (GTK_WIDGET_REALIZED (window))
320 g_warning ("shouldn't set wmclass after window is realized!\n");
324 gtk_window_set_focus (GtkWindow *window,
327 gtk_signal_emit (GTK_OBJECT (window), window_signals[SET_FOCUS], focus);
331 gtk_window_set_default (GtkWindow *window,
332 GtkWidget *default_widget)
334 g_return_if_fail (window != NULL);
335 g_return_if_fail (GTK_IS_WINDOW (window));
338 g_return_if_fail (GTK_WIDGET_CAN_DEFAULT (default_widget));
340 if (window->default_widget != default_widget)
342 if (window->default_widget)
344 GTK_WIDGET_UNSET_FLAGS (window->default_widget, GTK_HAS_DEFAULT);
345 gtk_widget_draw_default (window->default_widget);
348 window->default_widget = default_widget;
350 if (window->default_widget)
352 GTK_WIDGET_SET_FLAGS (window->default_widget, GTK_HAS_DEFAULT);
353 gtk_widget_draw_default (window->default_widget);
359 gtk_window_set_policy (GtkWindow *window,
364 g_return_if_fail (window != NULL);
365 g_return_if_fail (GTK_IS_WINDOW (window));
367 window->allow_shrink = (allow_shrink != FALSE);
368 window->allow_grow = (allow_grow != FALSE);
369 window->auto_shrink = (auto_shrink != FALSE);
371 gtk_window_set_hints (GTK_WIDGET (window), >K_WIDGET (window)->requisition);
375 gtk_window_add_accel_group (GtkWindow *window,
376 GtkAccelGroup *accel_group)
378 g_return_if_fail (window != NULL);
379 g_return_if_fail (GTK_IS_WINDOW (window));
380 g_return_if_fail (accel_group != NULL);
382 gtk_accel_group_attach (accel_group, GTK_OBJECT (window));
386 gtk_window_remove_accel_group (GtkWindow *window,
387 GtkAccelGroup *accel_group)
389 g_return_if_fail (window != NULL);
390 g_return_if_fail (GTK_IS_WINDOW (window));
391 g_return_if_fail (accel_group != NULL);
393 gtk_accel_group_detach (accel_group, GTK_OBJECT (window));
397 gtk_window_position (GtkWindow *window,
398 GtkWindowPosition position)
400 g_return_if_fail (window != NULL);
401 g_return_if_fail (GTK_IS_WINDOW (window));
403 window->position = position;
407 gtk_window_activate_focus (GtkWindow *window)
409 g_return_val_if_fail (window != NULL, FALSE);
410 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
412 if (window->focus_widget)
414 gtk_widget_activate (window->focus_widget);
422 gtk_window_activate_default (GtkWindow *window)
424 g_return_val_if_fail (window != NULL, FALSE);
425 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
427 if (window->default_widget)
429 gtk_widget_activate (window->default_widget);
437 gtk_window_shutdown (GtkObject *object)
441 g_return_if_fail (object != NULL);
442 g_return_if_fail (GTK_IS_WINDOW (object));
444 window = GTK_WINDOW (object);
446 gtk_window_set_focus (window, NULL);
447 gtk_window_set_default (window, NULL);
449 GTK_OBJECT_CLASS (parent_class)->shutdown (object);
453 gtk_window_destroy (GtkObject *object)
455 g_return_if_fail (object != NULL);
456 g_return_if_fail (GTK_IS_WINDOW (object));
458 gtk_container_unregister_toplevel (GTK_CONTAINER (object));
460 GTK_OBJECT_CLASS (parent_class)->destroy (object);
464 gtk_window_finalize (GtkObject *object)
468 g_return_if_fail (object != NULL);
469 g_return_if_fail (GTK_IS_WINDOW (object));
471 window = GTK_WINDOW (object);
472 g_free (window->title);
473 g_free (window->wmclass_name);
474 g_free (window->wmclass_class);
476 GTK_OBJECT_CLASS(parent_class)->finalize (object);
480 gtk_window_show (GtkWidget *widget)
482 g_return_if_fail (widget != NULL);
483 g_return_if_fail (GTK_IS_WINDOW (widget));
485 GTK_WIDGET_SET_FLAGS (widget, GTK_VISIBLE);
486 gtk_container_check_resize (GTK_CONTAINER (widget));
487 gtk_widget_map (widget);
491 gtk_window_hide (GtkWidget *widget)
493 g_return_if_fail (widget != NULL);
494 g_return_if_fail (GTK_IS_WINDOW (widget));
496 GTK_WIDGET_UNSET_FLAGS (widget, GTK_VISIBLE);
497 gtk_widget_unmap (widget);
501 gtk_window_map (GtkWidget *widget)
505 g_return_if_fail (widget != NULL);
506 g_return_if_fail (GTK_IS_WINDOW (widget));
508 GTK_WIDGET_SET_FLAGS (widget, GTK_MAPPED);
510 window = GTK_WINDOW (widget);
512 if (window->bin.child &&
513 GTK_WIDGET_VISIBLE (window->bin.child) &&
514 !GTK_WIDGET_MAPPED (window->bin.child))
515 gtk_widget_map (window->bin.child);
517 gtk_window_set_hints (widget, &widget->requisition);
518 gdk_window_show (widget->window);
522 gtk_window_unmap (GtkWidget *widget)
526 g_return_if_fail (widget != NULL);
527 g_return_if_fail (GTK_IS_WINDOW (widget));
529 GTK_WIDGET_UNSET_FLAGS (widget, GTK_MAPPED);
530 gdk_window_hide (widget->window);
532 window = GTK_WINDOW (widget);
533 window->use_uposition = TRUE;
537 gtk_window_realize (GtkWidget *widget)
540 GdkWindowAttr attributes;
541 gint attributes_mask;
543 g_return_if_fail (widget != NULL);
544 g_return_if_fail (GTK_IS_WINDOW (widget));
546 GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED);
547 window = GTK_WINDOW (widget);
549 switch (window->type)
551 case GTK_WINDOW_TOPLEVEL:
552 attributes.window_type = GDK_WINDOW_TOPLEVEL;
554 case GTK_WINDOW_DIALOG:
555 attributes.window_type = GDK_WINDOW_DIALOG;
557 case GTK_WINDOW_POPUP:
558 attributes.window_type = GDK_WINDOW_TEMP;
562 attributes.title = window->title;
563 attributes.wmclass_name = window->wmclass_name;
564 attributes.wmclass_class = window->wmclass_class;
565 attributes.width = widget->allocation.width;
566 attributes.height = widget->allocation.height;
567 attributes.wclass = GDK_INPUT_OUTPUT;
568 attributes.visual = gtk_widget_get_visual (widget);
569 attributes.colormap = gtk_widget_get_colormap (widget);
570 attributes.event_mask = gtk_widget_get_events (widget);
571 attributes.event_mask |= (GDK_EXPOSURE_MASK |
573 GDK_ENTER_NOTIFY_MASK |
574 GDK_LEAVE_NOTIFY_MASK |
575 GDK_FOCUS_CHANGE_MASK |
578 attributes_mask = GDK_WA_VISUAL | GDK_WA_COLORMAP;
579 attributes_mask |= (window->title ? GDK_WA_TITLE : 0);
580 attributes_mask |= (window->wmclass_name ? GDK_WA_WMCLASS : 0);
582 widget->window = gdk_window_new (NULL, &attributes, attributes_mask);
583 gdk_window_set_user_data (widget->window, window);
585 widget->style = gtk_style_attach (widget->style, widget->window);
586 gtk_style_set_background (widget->style, widget->window, GTK_STATE_NORMAL);
590 gtk_window_size_request (GtkWidget *widget,
591 GtkRequisition *requisition)
595 g_return_if_fail (widget != NULL);
596 g_return_if_fail (GTK_IS_WINDOW (widget));
597 g_return_if_fail (requisition != NULL);
599 window = GTK_WINDOW (widget);
601 if (window->bin.child)
603 requisition->width = GTK_CONTAINER (window)->border_width * 2;
604 requisition->height = GTK_CONTAINER (window)->border_width * 2;
606 gtk_widget_size_request (window->bin.child, &window->bin.child->requisition);
608 requisition->width += window->bin.child->requisition.width;
609 requisition->height += window->bin.child->requisition.height;
613 if (!GTK_WIDGET_VISIBLE (window))
614 GTK_CONTAINER (window)->need_resize = TRUE;
619 gtk_window_size_allocate (GtkWidget *widget,
620 GtkAllocation *allocation)
623 GtkAllocation child_allocation;
625 g_return_if_fail (widget != NULL);
626 g_return_if_fail (GTK_IS_WINDOW (widget));
627 g_return_if_fail (allocation != NULL);
629 window = GTK_WINDOW (widget);
630 widget->allocation = *allocation;
632 if (window->bin.child && GTK_WIDGET_VISIBLE (window->bin.child))
634 child_allocation.x = GTK_CONTAINER (window)->border_width;
635 child_allocation.y = GTK_CONTAINER (window)->border_width;
636 child_allocation.width = allocation->width - child_allocation.x * 2;
637 child_allocation.height = allocation->height - child_allocation.y * 2;
639 gtk_widget_size_allocate (window->bin.child, &child_allocation);
644 gtk_window_expose_event (GtkWidget *widget,
645 GdkEventExpose *event)
647 g_return_val_if_fail (widget != NULL, FALSE);
648 g_return_val_if_fail (GTK_IS_WINDOW (widget), FALSE);
649 g_return_val_if_fail (event != NULL, FALSE);
651 if (GTK_WIDGET_DRAWABLE (widget))
652 if (GTK_WIDGET_CLASS (parent_class)->expose_event)
653 return (* GTK_WIDGET_CLASS (parent_class)->expose_event) (widget, event);
659 gtk_window_configure_event (GtkWidget *widget,
660 GdkEventConfigure *event)
663 GtkAllocation allocation;
665 g_return_val_if_fail (widget != NULL, FALSE);
666 g_return_val_if_fail (GTK_IS_WINDOW (widget), FALSE);
667 g_return_val_if_fail (event != NULL, FALSE);
669 window = GTK_WINDOW (widget);
671 /* If the window was merely moved, do nothing */
672 if ((widget->allocation.width == event->width) &&
673 (widget->allocation.height == event->height) &&
674 (window->resize_count == 0))
677 window->handling_resize = TRUE;
681 allocation.width = event->width;
682 allocation.height = event->height;
684 gtk_widget_size_allocate (widget, &allocation);
686 if (window->bin.child &&
687 GTK_WIDGET_VISIBLE (window->bin.child) &&
688 !GTK_WIDGET_MAPPED (window->bin.child))
689 gtk_widget_map (window->bin.child);
691 if (window->resize_count > 0)
692 window->resize_count -= 1;
694 window->handling_resize = FALSE;
700 gtk_window_key_press_event (GtkWidget *widget,
704 GtkDirectionType direction = 0;
707 g_return_val_if_fail (widget != NULL, FALSE);
708 g_return_val_if_fail (GTK_IS_WINDOW (widget), FALSE);
709 g_return_val_if_fail (event != NULL, FALSE);
711 window = GTK_WINDOW (widget);
715 if (window->focus_widget)
717 handled = gtk_widget_event (window->focus_widget, (GdkEvent*) event);
721 handled = gtk_accel_groups_activate (GTK_OBJECT (window), event->keyval, event->state);
725 switch (event->keyval)
728 if (window->focus_widget)
730 gtk_widget_activate (window->focus_widget);
736 if (window->default_widget)
738 gtk_widget_activate (window->default_widget);
741 else if (window->focus_widget)
743 gtk_widget_activate (window->focus_widget);
752 case GDK_ISO_Left_Tab:
753 switch (event->keyval)
756 direction = GTK_DIR_UP;
759 direction = GTK_DIR_DOWN;
762 direction = GTK_DIR_LEFT;
765 direction = GTK_DIR_RIGHT;
768 case GDK_ISO_Left_Tab:
769 if (event->state & GDK_SHIFT_MASK)
770 direction = GTK_DIR_TAB_BACKWARD;
772 direction = GTK_DIR_TAB_FORWARD;
775 direction = GTK_DIR_UP; /* never reached, but makes compiler happy */
778 gtk_container_focus (GTK_CONTAINER (widget), direction);
780 if (!GTK_CONTAINER (window)->focus_child)
781 gtk_window_set_focus (GTK_WINDOW (widget), NULL);
788 if (!handled && GTK_WIDGET_CLASS (parent_class)->key_press_event)
789 handled = GTK_WIDGET_CLASS (parent_class)->key_press_event (widget, event);
795 gtk_window_key_release_event (GtkWidget *widget,
801 g_return_val_if_fail (widget != NULL, FALSE);
802 g_return_val_if_fail (GTK_IS_WINDOW (widget), FALSE);
803 g_return_val_if_fail (event != NULL, FALSE);
805 window = GTK_WINDOW (widget);
807 if (window->focus_widget)
809 handled = gtk_widget_event (window->focus_widget, (GdkEvent*) event);
812 if (!handled && GTK_WIDGET_CLASS (parent_class)->key_release_event)
813 handled = GTK_WIDGET_CLASS (parent_class)->key_release_event (widget, event);
819 gtk_window_enter_notify_event (GtkWidget *widget,
820 GdkEventCrossing *event)
822 g_return_val_if_fail (widget != NULL, FALSE);
823 g_return_val_if_fail (GTK_IS_WINDOW (widget), FALSE);
824 g_return_val_if_fail (event != NULL, FALSE);
830 gtk_window_leave_notify_event (GtkWidget *widget,
831 GdkEventCrossing *event)
833 g_return_val_if_fail (widget != NULL, FALSE);
834 g_return_val_if_fail (GTK_IS_WINDOW (widget), FALSE);
835 g_return_val_if_fail (event != NULL, FALSE);
841 gtk_window_focus_in_event (GtkWidget *widget,
842 GdkEventFocus *event)
845 GdkEventFocus fevent;
847 g_return_val_if_fail (widget != NULL, FALSE);
848 g_return_val_if_fail (GTK_IS_WINDOW (widget), FALSE);
849 g_return_val_if_fail (event != NULL, FALSE);
851 /* It appears spurious focus in events can occur when
852 * the window is hidden. So we'll just check to see if
853 * the window is visible before actually handling the
856 if (GTK_WIDGET_VISIBLE (widget))
858 window = GTK_WINDOW (widget);
859 if (window->focus_widget && !GTK_WIDGET_HAS_FOCUS (window->focus_widget))
861 fevent.type = GDK_FOCUS_CHANGE;
862 fevent.window = window->focus_widget->window;
865 gtk_widget_event (window->focus_widget, (GdkEvent*) &fevent);
873 gtk_window_focus_out_event (GtkWidget *widget,
874 GdkEventFocus *event)
877 GdkEventFocus fevent;
879 g_return_val_if_fail (widget != NULL, FALSE);
880 g_return_val_if_fail (GTK_IS_WINDOW (widget), FALSE);
881 g_return_val_if_fail (event != NULL, FALSE);
883 window = GTK_WINDOW (widget);
884 if (window->focus_widget && GTK_WIDGET_HAS_FOCUS (window->focus_widget))
886 fevent.type = GDK_FOCUS_CHANGE;
887 fevent.window = window->focus_widget->window;
890 gtk_widget_event (window->focus_widget, (GdkEvent*) &fevent);
897 gtk_window_read_rcfiles (GtkWidget *widget,
898 GdkEventClient *event)
902 if (gtk_rc_reparse_all ())
904 toplevels = gdk_window_get_toplevels();
908 gdk_window_get_user_data (toplevels->data, (gpointer *)&widget);
911 gtk_widget_reset_rc_styles (widget);
913 toplevels = toplevels->next;
915 g_list_free (toplevels);
920 gtk_window_client_event (GtkWidget *widget,
921 GdkEventClient *event)
923 static GdkAtom atom_rcfiles = GDK_NONE;
924 g_return_val_if_fail (widget != NULL, FALSE);
925 g_return_val_if_fail (GTK_IS_WINDOW (widget), FALSE);
926 g_return_val_if_fail (event != NULL, FALSE);
929 atom_rcfiles = gdk_atom_intern("_GTK_READ_RCFILES", FALSE);
931 if(event->message_type == atom_rcfiles)
932 gtk_window_read_rcfiles (widget, event);
938 gtk_window_check_resize (GtkContainer *container)
942 g_return_if_fail (container != NULL);
943 g_return_if_fail (GTK_IS_WINDOW (container));
945 window = GTK_WINDOW (container);
946 if (!window->handling_resize)
948 if (GTK_WIDGET_VISIBLE (container))
949 gtk_window_move_resize (window);
951 GTK_CONTAINER (window)->need_resize = TRUE;
955 /* FIXME: we leave container->resize_widgets set under some
958 gtk_window_move_resize (GtkWindow *window)
961 GtkContainer *container;
966 gboolean needed_resize;
968 g_return_if_fail (window != NULL);
969 g_return_if_fail (GTK_IS_WINDOW (window));
971 widget = GTK_WIDGET (window);
972 container = GTK_CONTAINER (widget);
974 /* Remember old size, to know if we have to reset hints */
975 width = widget->requisition.width;
976 height = widget->requisition.height;
977 gtk_widget_size_request (widget, &widget->requisition);
979 if ((width != widget->requisition.width ||
980 height != widget->requisition.height))
982 gboolean saved_use_upos;
984 saved_use_upos = window->use_uposition;
985 gtk_window_set_hints (widget, &widget->requisition);
986 window->use_uposition = saved_use_upos;
991 width = widget->requisition.width;
992 height = widget->requisition.height;
994 if (window->use_uposition)
995 switch (window->position)
997 case GTK_WIN_POS_CENTER:
998 x = (gdk_screen_width () - width) / 2;
999 y = (gdk_screen_height () - height) / 2;
1000 gtk_widget_set_uposition (widget, x, y);
1002 case GTK_WIN_POS_MOUSE:
1003 gdk_window_get_pointer (NULL, &x, &y, NULL);
1008 screen_width = gdk_screen_width ();
1009 screen_height = gdk_screen_height ();
1013 else if (x > (screen_width - width))
1014 x = screen_width - width;
1018 else if (y > (screen_height - height))
1019 y = screen_height - height;
1021 gtk_widget_set_uposition (widget, x, y);
1025 /* Now, do the resizing */
1027 needed_resize = container->need_resize;
1028 container->need_resize = FALSE;
1030 if ((widget->requisition.width == 0) ||
1031 (widget->requisition.height == 0))
1033 widget->requisition.width = 200;
1034 widget->requisition.height = 200;
1037 if (!GTK_WIDGET_REALIZED (window))
1039 GtkAllocation allocation;
1043 allocation.width = widget->requisition.width;
1044 allocation.height = widget->requisition.height;
1046 gtk_widget_size_allocate (widget, &allocation);
1051 gdk_window_get_geometry (widget->window, NULL, NULL, &width, &height, NULL);
1053 if ((window->auto_shrink &&
1054 ((width != widget->requisition.width) ||
1055 (height != widget->requisition.height))) ||
1056 (width < widget->requisition.width) ||
1057 (height < widget->requisition.height))
1059 window->resize_count += 1;
1060 if ((x != -1) && (y != -1))
1061 gdk_window_move_resize (widget->window, x, y,
1062 widget->requisition.width,
1063 widget->requisition.height);
1065 gdk_window_resize (widget->window,
1066 widget->requisition.width,
1067 widget->requisition.height);
1069 else if (needed_resize)
1071 /* The windows contents changed size while it was not
1072 * visible, so reallocate everything, since we didn't
1073 * keep track of what changed
1075 GtkAllocation allocation;
1079 allocation.width = widget->requisition.width;
1080 allocation.height = widget->requisition.height;
1082 gtk_widget_size_allocate (widget, &allocation);
1086 if ((x != -1) && (y != -1))
1087 gdk_window_move (widget->window, x, y);
1089 gtk_container_resize_children (GTK_CONTAINER (window));
1094 gtk_real_window_set_focus (GtkWindow *window,
1097 GdkEventFocus event;
1099 g_return_if_fail (window != NULL);
1100 g_return_if_fail (GTK_IS_WINDOW (window));
1102 if (focus && !GTK_WIDGET_CAN_FOCUS (focus))
1105 if (window->focus_widget != focus)
1107 if (window->focus_widget)
1109 event.type = GDK_FOCUS_CHANGE;
1110 event.window = window->focus_widget->window;
1113 gtk_widget_event (window->focus_widget, (GdkEvent*) &event);
1116 window->focus_widget = focus;
1118 if (window->focus_widget)
1120 event.type = GDK_FOCUS_CHANGE;
1121 event.window = window->focus_widget->window;
1124 gtk_widget_event (window->focus_widget, (GdkEvent*) &event);
1130 gtk_window_set_hints (GtkWidget *widget,
1131 GtkRequisition *requisition)
1134 GtkWidgetAuxInfo *aux_info;
1138 g_return_if_fail (widget != NULL);
1139 g_return_if_fail (GTK_IS_WINDOW (widget));
1140 g_return_if_fail (requisition != NULL);
1142 if (GTK_WIDGET_REALIZED (widget))
1144 window = GTK_WINDOW (widget);
1150 aux_info = gtk_object_get_data (GTK_OBJECT (widget), "gtk-aux-info");
1151 if (aux_info && (aux_info->x != -1) && (aux_info->y != -1))
1155 flags |= GDK_HINT_POS;
1158 if (!window->allow_shrink)
1159 flags |= GDK_HINT_MIN_SIZE;
1160 if (!window->allow_grow)
1161 flags |= GDK_HINT_MAX_SIZE;
1163 gdk_window_set_hints (widget->window, ux, uy,
1164 requisition->width, requisition->height,
1165 requisition->width, requisition->height,
1168 if (window->use_uposition && (flags & GDK_HINT_POS))
1170 window->use_uposition = FALSE;
1171 gdk_window_move (widget->window, ux, uy);