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 Lesser 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 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser 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.
21 * Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
22 * file for a list of people on the GTK+ Team. See the ChangeLog
23 * files for a list of changes. These files are distributed with
24 * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
30 #include "gdk/gdkkeysyms.h"
32 #if defined (GDK_WINDOWING_X11)
34 #elif defined (GDK_WINDOWING_WIN32)
35 #include "win32/gdkwin32.h"
36 #elif defined (GDK_WINDOWING_NANOX)
37 #include "nanox/gdkprivate-nanox.h"
38 #elif defined (GDK_WINDOWING_FB)
39 #include "linux-fb/gdkfb.h"
42 #include "gtkprivate.h"
44 #include "gtksignal.h"
45 #include "gtkwindow.h"
46 #include "gtkwindow-decorate.h"
47 #include "gtkbindings.h"
49 #include "gtkiconfactory.h"
76 PROP_DESTROY_WITH_PARENT,
82 GdkGeometry geometry; /* Last set of geometry hints we set */
86 } GtkWindowLastGeometryInfo;
88 struct _GtkWindowGeometryInfo
90 /* Properties that the app has set on the window
92 GdkGeometry geometry; /* Geometry hints */
94 GtkWidget *widget; /* subwidget to which hints apply */
95 gint width; /* Default size */
97 guint may_shrink : 1; /* one-shot auto_shrink behaviour after set_default_size */
99 GtkWindowLastGeometryInfo last;
110 static void gtk_window_class_init (GtkWindowClass *klass);
111 static void gtk_window_init (GtkWindow *window);
112 static void gtk_window_shutdown (GObject *object);
113 static void gtk_window_destroy (GtkObject *object);
114 static void gtk_window_finalize (GObject *object);
115 static void gtk_window_show (GtkWidget *widget);
116 static void gtk_window_hide (GtkWidget *widget);
117 static void gtk_window_map (GtkWidget *widget);
118 static void gtk_window_unmap (GtkWidget *widget);
119 static void gtk_window_realize (GtkWidget *widget);
120 static void gtk_window_unrealize (GtkWidget *widget);
121 static void gtk_window_size_request (GtkWidget *widget,
122 GtkRequisition *requisition);
123 static void gtk_window_size_allocate (GtkWidget *widget,
124 GtkAllocation *allocation);
125 static gint gtk_window_event (GtkWidget *widget,
127 static gboolean gtk_window_frame_event (GtkWidget *widget,
129 static gint gtk_window_configure_event (GtkWidget *widget,
130 GdkEventConfigure *event);
131 static gint gtk_window_key_press_event (GtkWidget *widget,
133 static gint gtk_window_key_release_event (GtkWidget *widget,
135 static gint gtk_window_enter_notify_event (GtkWidget *widget,
136 GdkEventCrossing *event);
137 static gint gtk_window_leave_notify_event (GtkWidget *widget,
138 GdkEventCrossing *event);
139 static gint gtk_window_focus_in_event (GtkWidget *widget,
140 GdkEventFocus *event);
141 static gint gtk_window_focus_out_event (GtkWidget *widget,
142 GdkEventFocus *event);
143 static gint gtk_window_client_event (GtkWidget *widget,
144 GdkEventClient *event);
145 static void gtk_window_check_resize (GtkContainer *container);
146 static gint gtk_window_focus (GtkWidget *widget,
147 GtkDirectionType direction);
148 static void gtk_window_real_set_focus (GtkWindow *window,
151 static void gtk_window_real_activate_default (GtkWindow *window);
152 static void gtk_window_real_activate_focus (GtkWindow *window);
153 static void gtk_window_move_focus (GtkWindow *window,
154 GtkDirectionType dir);
156 static void gtk_window_move_resize (GtkWindow *window);
157 static gboolean gtk_window_compare_hints (GdkGeometry *geometry_a,
159 GdkGeometry *geometry_b,
161 static void gtk_window_compute_default_size (GtkWindow *window,
164 static void gtk_window_constrain_size (GtkWindow *window,
165 GdkGeometry *geometry,
171 static void gtk_window_compute_hints (GtkWindow *window,
172 GdkGeometry *new_geometry,
174 static gint gtk_window_compute_reposition (GtkWindow *window,
180 static void gtk_window_read_rcfiles (GtkWidget *widget,
181 GdkEventClient *event);
182 static void gtk_window_paint (GtkWidget *widget,
184 static gint gtk_window_expose (GtkWidget *widget,
185 GdkEventExpose *event);
186 static void gtk_window_unset_transient_for (GtkWindow *window);
187 static void gtk_window_transient_parent_realized (GtkWidget *parent,
189 static void gtk_window_transient_parent_unrealized (GtkWidget *parent,
192 static GtkWindowGeometryInfo* gtk_window_get_geometry_info (GtkWindow *window,
196 static GSList *toplevel_list = NULL;
197 static GHashTable *mnemonic_hash_table = NULL;
198 static GtkBinClass *parent_class = NULL;
199 static guint window_signals[LAST_SIGNAL] = { 0 };
201 static void gtk_window_set_property (GObject *object,
205 static void gtk_window_get_property (GObject *object,
212 mnemonic_hash (gconstpointer key)
214 const GtkWindowMnemonic *k;
217 k = (GtkWindowMnemonic *)key;
219 h = (gulong) k->window;
220 h ^= k->keyval << 16;
221 h ^= k->keyval >> 16;
227 mnemonic_equal (gconstpointer a, gconstpointer b)
229 const GtkWindowMnemonic *ka;
230 const GtkWindowMnemonic *kb;
232 ka = (GtkWindowMnemonic *)a;
233 kb = (GtkWindowMnemonic *)b;
236 (ka->window == kb->window) &&
237 (ka->keyval == kb->keyval);
241 gtk_window_get_type (void)
243 static GtkType window_type = 0;
247 static const GtkTypeInfo window_info =
251 sizeof (GtkWindowClass),
252 (GtkClassInitFunc) gtk_window_class_init,
253 (GtkObjectInitFunc) gtk_window_init,
254 /* reserved_1 */ NULL,
255 /* reserved_2 */ NULL,
256 (GtkClassInitFunc) NULL,
259 window_type = gtk_type_unique (gtk_bin_get_type (), &window_info);
266 gtk_window_class_init (GtkWindowClass *klass)
268 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
269 GtkObjectClass *object_class;
270 GtkWidgetClass *widget_class;
271 GtkContainerClass *container_class;
272 GtkBindingSet *binding_set;
274 object_class = (GtkObjectClass*) klass;
275 widget_class = (GtkWidgetClass*) klass;
276 container_class = (GtkContainerClass*) klass;
278 parent_class = gtk_type_class (gtk_bin_get_type ());
280 gobject_class->shutdown = gtk_window_shutdown;
281 gobject_class->finalize = gtk_window_finalize;
283 gobject_class->set_property = gtk_window_set_property;
284 gobject_class->get_property = gtk_window_get_property;
286 object_class->destroy = gtk_window_destroy;
288 widget_class->show = gtk_window_show;
289 widget_class->hide = gtk_window_hide;
290 widget_class->map = gtk_window_map;
291 widget_class->unmap = gtk_window_unmap;
292 widget_class->realize = gtk_window_realize;
293 widget_class->unrealize = gtk_window_unrealize;
294 widget_class->size_request = gtk_window_size_request;
295 widget_class->size_allocate = gtk_window_size_allocate;
296 widget_class->configure_event = gtk_window_configure_event;
297 widget_class->key_press_event = gtk_window_key_press_event;
298 widget_class->key_release_event = gtk_window_key_release_event;
299 widget_class->enter_notify_event = gtk_window_enter_notify_event;
300 widget_class->leave_notify_event = gtk_window_leave_notify_event;
301 widget_class->focus_in_event = gtk_window_focus_in_event;
302 widget_class->focus_out_event = gtk_window_focus_out_event;
303 widget_class->client_event = gtk_window_client_event;
304 widget_class->focus = gtk_window_focus;
306 widget_class->expose_event = gtk_window_expose;
308 container_class->check_resize = gtk_window_check_resize;
310 klass->set_focus = gtk_window_real_set_focus;
311 klass->frame_event = gtk_window_frame_event;
313 klass->activate_default = gtk_window_real_activate_default;
314 klass->activate_focus = gtk_window_real_activate_focus;
315 klass->move_focus = gtk_window_move_focus;
318 g_object_class_install_property (gobject_class,
320 g_param_spec_enum ("type",
322 _("The type of the window"),
323 GTK_TYPE_WINDOW_TYPE,
325 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
328 g_object_class_install_property (gobject_class,
330 g_param_spec_string ("title",
332 _("The title of the window"),
336 g_object_class_install_property (gobject_class,
338 g_param_spec_boolean ("auto_shrink",
340 _("If TRUE, the window automatically shrinks to its size request anytime a resize occurs. Don't use this feature, it makes no sense."),
344 g_object_class_install_property (gobject_class,
346 g_param_spec_boolean ("allow_shrink",
348 _("If TRUE, the window has no mimimum size. Don't use this feature, it makes no sense."),
352 g_object_class_install_property (gobject_class,
354 g_param_spec_boolean ("allow_grow",
356 _("If TRUE, users can expand the window beyond its minimum size."),
360 g_object_class_install_property (gobject_class,
362 g_param_spec_boolean ("modal",
364 _("If TRUE, the window is modal (other windows are not usable while this one is up)."),
368 g_object_class_install_property (gobject_class,
370 g_param_spec_enum ("window_position",
371 _("Window Position"),
372 _("The initial position of the window."),
373 GTK_TYPE_WINDOW_POSITION,
377 g_object_class_install_property (gobject_class,
379 g_param_spec_int ("default_width",
381 _("The default width of the window, or 0 to use the size request."),
387 g_object_class_install_property (gobject_class,
389 g_param_spec_int ("default_height",
391 _("The default height of the windo, or 0 to use the size request."),
397 g_object_class_install_property (gobject_class,
398 PROP_DESTROY_WITH_PARENT,
399 g_param_spec_boolean ("destroy_with_parent",
400 _("Destroy with Parent"),
401 _("If this window should be destroyed when the parent is destroyed,"),
405 /* Style props are set or not */
407 window_signals[SET_FOCUS] =
408 g_signal_newc ("set_focus",
409 G_TYPE_FROM_CLASS (object_class),
411 G_STRUCT_OFFSET (GtkWindowClass, set_focus),
413 gtk_marshal_VOID__OBJECT,
417 window_signals[FRAME_EVENT] =
418 g_signal_newc ("frame_event",
419 G_TYPE_FROM_CLASS(object_class),
421 G_STRUCT_OFFSET(GtkWindowClass, frame_event),
422 _gtk_boolean_handled_accumulator, NULL,
423 gtk_marshal_BOOLEAN__BOXED,
427 window_signals[ACTIVATE_FOCUS] =
428 g_signal_newc ("activate_focus",
429 G_OBJECT_CLASS_TYPE (object_class),
430 G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
431 GTK_SIGNAL_OFFSET (GtkWindowClass, activate_focus),
433 gtk_marshal_VOID__VOID,
437 window_signals[ACTIVATE_DEFAULT] =
438 g_signal_newc ("activate_default",
439 G_OBJECT_CLASS_TYPE (object_class),
440 G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
441 GTK_SIGNAL_OFFSET (GtkWindowClass, activate_default),
443 gtk_marshal_VOID__VOID,
447 window_signals[MOVE_FOCUS] =
448 g_signal_newc ("move_focus",
449 G_OBJECT_CLASS_TYPE (object_class),
450 G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
451 GTK_SIGNAL_OFFSET (GtkWindowClass, move_focus),
453 gtk_marshal_VOID__ENUM,
456 GTK_TYPE_DIRECTION_TYPE);
458 if (!mnemonic_hash_table)
459 mnemonic_hash_table = g_hash_table_new (mnemonic_hash,
466 binding_set = gtk_binding_set_by_class (klass);
468 gtk_binding_entry_add_signal (binding_set, GDK_space, 0,
469 "activate_focus", 0);
471 gtk_binding_entry_add_signal (binding_set, GDK_Return, 0,
472 "activate_default", 0);
474 gtk_binding_entry_add_signal (binding_set, GDK_KP_Enter, 0,
475 "activate_default", 0);
477 gtk_binding_entry_add_signal (binding_set, GDK_Up, 0,
479 GTK_TYPE_DIRECTION_TYPE, GTK_DIR_UP);
480 gtk_binding_entry_add_signal (binding_set, GDK_KP_Up, 0,
482 GTK_TYPE_DIRECTION_TYPE, GTK_DIR_UP);
484 gtk_binding_entry_add_signal (binding_set, GDK_Down, 0,
486 GTK_TYPE_DIRECTION_TYPE, GTK_DIR_DOWN);
487 gtk_binding_entry_add_signal (binding_set, GDK_KP_Down, 0,
489 GTK_TYPE_DIRECTION_TYPE, GTK_DIR_DOWN);
491 gtk_binding_entry_add_signal (binding_set, GDK_Left, 0,
493 GTK_TYPE_DIRECTION_TYPE, GTK_DIR_LEFT);
494 gtk_binding_entry_add_signal (binding_set, GDK_KP_Left, 0,
496 GTK_TYPE_DIRECTION_TYPE, GTK_DIR_LEFT);
498 gtk_binding_entry_add_signal (binding_set, GDK_Right, 0,
500 GTK_TYPE_DIRECTION_TYPE, GTK_DIR_RIGHT);
501 gtk_binding_entry_add_signal (binding_set, GDK_KP_Right, 0,
503 GTK_TYPE_DIRECTION_TYPE, GTK_DIR_RIGHT);
505 gtk_binding_entry_add_signal (binding_set, GDK_Tab, 0,
507 GTK_TYPE_DIRECTION_TYPE, GTK_DIR_TAB_FORWARD);
508 gtk_binding_entry_add_signal (binding_set, GDK_ISO_Left_Tab, 0,
510 GTK_TYPE_DIRECTION_TYPE, GTK_DIR_TAB_FORWARD);
512 gtk_binding_entry_add_signal (binding_set, GDK_Tab, GDK_SHIFT_MASK,
514 GTK_TYPE_DIRECTION_TYPE, GTK_DIR_TAB_BACKWARD);
515 gtk_binding_entry_add_signal (binding_set, GDK_ISO_Left_Tab, GDK_SHIFT_MASK,
517 GTK_TYPE_DIRECTION_TYPE, GTK_DIR_TAB_BACKWARD);
521 gtk_window_init (GtkWindow *window)
523 GTK_WIDGET_UNSET_FLAGS (window, GTK_NO_WINDOW);
524 GTK_WIDGET_SET_FLAGS (window, GTK_TOPLEVEL);
526 GTK_PRIVATE_SET_FLAG (window, GTK_ANCHORED);
528 gtk_container_set_resize_mode (GTK_CONTAINER (window), GTK_RESIZE_QUEUE);
530 window->title = NULL;
531 window->wmclass_name = g_strdup (g_get_prgname ());
532 window->wmclass_class = g_strdup (gdk_progclass);
533 window->wm_role = NULL;
534 window->geometry_info = NULL;
535 window->type = GTK_WINDOW_TOPLEVEL;
536 window->focus_widget = NULL;
537 window->default_widget = NULL;
538 window->resize_count = 0;
539 window->allow_shrink = FALSE;
540 window->allow_grow = TRUE;
541 window->auto_shrink = FALSE;
542 window->handling_resize = FALSE;
543 window->position = GTK_WIN_POS_NONE;
544 window->use_uposition = TRUE;
545 window->modal = FALSE;
546 window->frame = NULL;
547 window->has_frame = FALSE;
548 window->frame_left = 0;
549 window->frame_right = 0;
550 window->frame_top = 0;
551 window->frame_bottom = 0;
552 window->type_hint = GDK_WINDOW_TYPE_HINT_NORMAL;
553 window->gravity = GDK_GRAVITY_NORTH_WEST;
554 window->decorated = TRUE;
555 window->mnemonic_modifier = GDK_MOD1_MASK;
557 gtk_widget_ref (GTK_WIDGET (window));
558 gtk_object_sink (GTK_OBJECT (window));
559 window->has_user_ref_count = TRUE;
560 toplevel_list = g_slist_prepend (toplevel_list, window);
562 gtk_decorated_window_init (window);
564 gtk_signal_connect (GTK_OBJECT (window),
566 GTK_SIGNAL_FUNC (gtk_window_event),
571 gtk_window_set_property (GObject *object,
578 window = GTK_WINDOW (object);
583 window->type = g_value_get_enum (value);
586 gtk_window_set_title (window, g_value_get_string (value));
588 case PROP_AUTO_SHRINK:
589 window->auto_shrink = g_value_get_boolean (value);
590 gtk_widget_queue_resize (GTK_WIDGET (window));
592 case PROP_ALLOW_SHRINK:
593 window->allow_shrink = g_value_get_boolean (value);
594 gtk_widget_queue_resize (GTK_WIDGET (window));
596 case PROP_ALLOW_GROW:
597 window->allow_grow = g_value_get_boolean (value);
598 gtk_widget_queue_resize (GTK_WIDGET (window));
601 gtk_window_set_modal (window, g_value_get_boolean (value));
604 gtk_window_set_position (window, g_value_get_enum (value));
606 case PROP_DEFAULT_WIDTH:
607 gtk_window_set_default_size (window, g_value_get_int (value), -1);
609 case PROP_DEFAULT_HEIGHT:
610 gtk_window_set_default_size (window, -1, g_value_get_int (value));
612 case PROP_DESTROY_WITH_PARENT:
613 gtk_window_set_destroy_with_parent (window, g_value_get_boolean (value));
621 gtk_window_get_property (GObject *object,
628 window = GTK_WINDOW (object);
632 GtkWindowGeometryInfo *info;
634 g_value_set_enum (value, window->type);
637 g_value_set_string (value, window->title);
639 case PROP_AUTO_SHRINK:
640 g_value_set_boolean (value, window->auto_shrink);
642 case PROP_ALLOW_SHRINK:
643 g_value_set_boolean (value, window->allow_shrink);
645 case PROP_ALLOW_GROW:
646 g_value_set_boolean (value, window->allow_grow);
649 g_value_set_boolean (value, window->modal);
652 g_value_set_enum (value, window->position);
654 case PROP_DEFAULT_WIDTH:
655 info = gtk_window_get_geometry_info (window, FALSE);
657 g_value_set_int (value, 0);
659 g_value_set_int (value, info->width);
661 case PROP_DEFAULT_HEIGHT:
662 info = gtk_window_get_geometry_info (window, FALSE);
664 g_value_set_int (value, 0);
666 g_value_set_int (value, info->height);
668 case PROP_DESTROY_WITH_PARENT:
669 g_value_set_boolean (value, window->destroy_with_parent);
672 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
679 * @type: type of window
681 * Creates a new #GtkWindow, which is a toplevel window that can
682 * contain other widgets. Nearly always, the type of the window should
683 * be #GTK_WINDOW_TOPLEVEL. If you're implementing something like a
684 * popup menu from scratch (which is a bad idea, just use #GtkMenu),
685 * you might use #GTK_WINDOW_POPUP. #GTK_WINDOW_POPUP is not for
686 * dialogs, though in some other toolkits dialogs are called "popups."
687 * In GTK+, #GTK_WINDOW_POPUP means a pop-up menu or pop-up tooltip.
688 * Popup windows are not controlled by the window manager.
690 * If you simply want an undecorated window (no window borders), use
691 * gtk_window_set_decorated(), don't use #GTK_WINDOW_POPUP.
693 * Return value: a new #GtkWindow.
696 gtk_window_new (GtkWindowType type)
700 g_return_val_if_fail (type >= GTK_WINDOW_TOPLEVEL && type <= GTK_WINDOW_POPUP, NULL);
702 window = gtk_type_new (GTK_TYPE_WINDOW);
706 return GTK_WIDGET (window);
710 * gtk_window_set_title:
711 * @window: a #GtkWindow
712 * @title: title of the window
714 * Sets the title of the #GtkWindow. The title of a window will be displayed in
715 * its title bar; on the X Window System, the title bar is rendered by the
716 * window manager, so exactly how the title appears to users may vary according
717 * to a user's exact configuration. The title should help a user distinguish
718 * this window from other windows they may have open. A good title might
719 * include the application name and current document filename, for example.
723 gtk_window_set_title (GtkWindow *window,
726 g_return_if_fail (window != NULL);
727 g_return_if_fail (GTK_IS_WINDOW (window));
730 g_free (window->title);
731 window->title = g_strdup (title);
733 if (GTK_WIDGET_REALIZED (window))
735 gdk_window_set_title (GTK_WIDGET (window)->window, window->title);
737 gtk_decorated_window_set_title (window, title);
740 g_object_notify (G_OBJECT (window), "title");
744 * gtk_window_get_title:
745 * @window: a #GtkWindow
747 * Retrieves the title of the window. See gtk_window_set_title().
749 * Return value: the title of the window, or %NULL if none has
750 * been set explicitely. The returned string is owned by the widget
751 * and must not be modified or freed.
753 G_CONST_RETURN gchar *
754 gtk_window_get_title (GtkWindow *window)
756 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
758 return window->title;
762 * gtk_window_set_wmclass:
763 * @window: a #GtkWindow
764 * @wmclass_name: window name hint
765 * @wmclass_class: window class hint
767 * Don't use this function. It sets the X Window System "class" and
768 * "name" hints for a window. According to the ICCCM, you should
769 * always set these to the same value for all windows in an
770 * application, and GTK sets them to that value by default, so calling
771 * this function is sort of pointless. However, you may want to call
772 * gtk_window_set_role() on each window in your application, for the
773 * benefit of the session manager. Setting the role allows the window
774 * manager to restore window positions when loading a saved session.
778 gtk_window_set_wmclass (GtkWindow *window,
779 const gchar *wmclass_name,
780 const gchar *wmclass_class)
782 g_return_if_fail (window != NULL);
783 g_return_if_fail (GTK_IS_WINDOW (window));
785 g_free (window->wmclass_name);
786 window->wmclass_name = g_strdup (wmclass_name);
788 g_free (window->wmclass_class);
789 window->wmclass_class = g_strdup (wmclass_class);
791 if (GTK_WIDGET_REALIZED (window))
792 g_warning ("gtk_window_set_wmclass: shouldn't set wmclass after window is realized!\n");
796 * gtk_window_set_role:
797 * @window: a #GtkWindow
798 * @role: unique identifier for the window to be used when restoring a session
800 * In combination with the window title, the window role allows a
801 * window manager to identify "the same" window when an application is
802 * restarted. So for example you might set the "toolbox" role on your
803 * app's toolbox window, so that when the user restarts their session,
804 * the window manager can put the toolbox back in the same place.
806 * If a window already has a unique title, you don't need to set the
807 * role, since the WM can use the title to identify the window when
808 * restoring the session.
812 gtk_window_set_role (GtkWindow *window,
815 g_return_if_fail (GTK_IS_WINDOW (window));
817 if (role == window->wm_role)
820 g_free (window->wm_role);
821 window->wm_role = g_strdup (role);
823 if (GTK_WIDGET_REALIZED (window))
824 g_warning ("gtk_window_set_role(): shouldn't set role after window is realized!\n");
828 * gtk_window_get_role:
829 * @window: a #GtkWindow
831 * Returns the role of the window. See gtk_window_set_role() for
832 * further explanation.
834 * Return value: the role of the window if set, or %NULL. The
835 * returned is owned by the widget and must not be modified
838 G_CONST_RETURN gchar *
839 gtk_window_get_role (GtkWindow *window)
841 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
843 return window->wm_role;
847 * gtk_window_set_focus:
848 * @window: a #GtkWindow
849 * @focus: widget to be the new focus widget
851 * If @focus is not the current focus widget, and is focusable, emits
852 * the "set_focus" signal to set @focus as the focus widget for the
853 * window. This function is more or less GTK-internal; to focus an
854 * entry widget or the like, you should use gtk_widget_grab_focus()
855 * instead of this function.
859 gtk_window_set_focus (GtkWindow *window,
862 g_return_if_fail (window != NULL);
863 g_return_if_fail (GTK_IS_WINDOW (window));
866 g_return_if_fail (GTK_IS_WIDGET (focus));
867 g_return_if_fail (GTK_WIDGET_CAN_FOCUS (focus));
870 if ((window->focus_widget != focus) ||
871 (focus && !GTK_WIDGET_HAS_FOCUS (focus)))
872 gtk_signal_emit (GTK_OBJECT (window), window_signals[SET_FOCUS], focus);
876 * gtk_window_set_default:
877 * @window: a #GtkWindow
878 * @default_widget: widget to be the default
880 * The default widget is the widget that's activated when the user
881 * presses Enter in a dialog (for example). This function tells a
882 * #GtkWindow about the current default widget; it's really a GTK
883 * internal function and you shouldn't need it. Instead, to change the
884 * default widget, first set the #GTK_CAN_DEFAULT flag on the widget
885 * you'd like to make the default using GTK_WIDGET_SET_FLAGS(), then
886 * call gtk_widget_grab_default() to move the default.
890 gtk_window_set_default (GtkWindow *window,
891 GtkWidget *default_widget)
893 g_return_if_fail (window != NULL);
894 g_return_if_fail (GTK_IS_WINDOW (window));
897 g_return_if_fail (GTK_WIDGET_CAN_DEFAULT (default_widget));
899 if (window->default_widget != default_widget)
901 if (window->default_widget)
903 if (window->focus_widget != window->default_widget ||
904 !GTK_WIDGET_RECEIVES_DEFAULT (window->default_widget))
905 GTK_WIDGET_UNSET_FLAGS (window->default_widget, GTK_HAS_DEFAULT);
906 gtk_widget_queue_draw (window->default_widget);
909 window->default_widget = default_widget;
911 if (window->default_widget)
913 if (window->focus_widget == NULL ||
914 !GTK_WIDGET_RECEIVES_DEFAULT (window->focus_widget))
915 GTK_WIDGET_SET_FLAGS (window->default_widget, GTK_HAS_DEFAULT);
916 gtk_widget_queue_draw (window->default_widget);
922 gtk_window_set_policy (GtkWindow *window,
923 gboolean allow_shrink,
925 gboolean auto_shrink)
927 g_return_if_fail (window != NULL);
928 g_return_if_fail (GTK_IS_WINDOW (window));
930 window->allow_shrink = (allow_shrink != FALSE);
931 window->allow_grow = (allow_grow != FALSE);
932 window->auto_shrink = (auto_shrink != FALSE);
934 g_object_notify (G_OBJECT (window), "allow_shrink");
935 g_object_notify (G_OBJECT (window), "allow_grow");
936 g_object_notify (G_OBJECT (window), "auto_shrink");
938 gtk_widget_queue_resize (GTK_WIDGET (window));
942 gtk_window_add_accel_group (GtkWindow *window,
943 GtkAccelGroup *accel_group)
945 g_return_if_fail (window != NULL);
946 g_return_if_fail (GTK_IS_WINDOW (window));
947 g_return_if_fail (accel_group != NULL);
949 gtk_accel_group_attach (accel_group, GTK_OBJECT (window));
953 gtk_window_remove_accel_group (GtkWindow *window,
954 GtkAccelGroup *accel_group)
956 g_return_if_fail (window != NULL);
957 g_return_if_fail (GTK_IS_WINDOW (window));
958 g_return_if_fail (accel_group != NULL);
960 gtk_accel_group_detach (accel_group, GTK_OBJECT (window));
964 gtk_window_add_mnemonic (GtkWindow *window,
968 GtkWindowMnemonic key;
969 GtkWindowMnemonic *mnemonic;
971 g_return_if_fail (GTK_IS_WINDOW (window));
972 g_return_if_fail (GTK_IS_WIDGET (target));
976 mnemonic = g_hash_table_lookup (mnemonic_hash_table, &key);
980 g_return_if_fail (g_slist_find (mnemonic->targets, target) == NULL);
981 mnemonic->targets = g_slist_prepend (mnemonic->targets, target);
985 mnemonic = g_new (GtkWindowMnemonic, 1);
987 mnemonic->targets = g_slist_prepend (NULL, target);
988 g_hash_table_insert (mnemonic_hash_table, mnemonic, mnemonic);
993 gtk_window_remove_mnemonic (GtkWindow *window,
997 GtkWindowMnemonic key;
998 GtkWindowMnemonic *mnemonic;
1000 g_return_if_fail (GTK_IS_WINDOW (window));
1001 g_return_if_fail (GTK_IS_WIDGET (target));
1003 key.window = window;
1004 key.keyval = keyval;
1005 mnemonic = g_hash_table_lookup (mnemonic_hash_table, &key);
1007 g_return_if_fail (mnemonic && g_slist_find (mnemonic->targets, target) != NULL);
1009 mnemonic->targets = g_slist_remove (mnemonic->targets, target);
1010 if (mnemonic->targets == NULL)
1012 g_hash_table_remove (mnemonic_hash_table, mnemonic);
1018 gtk_window_mnemonic_activate (GtkWindow *window,
1020 GdkModifierType modifier)
1022 GtkWindowMnemonic key;
1023 GtkWindowMnemonic *mnemonic;
1025 GtkWidget *widget, *chosen_widget;
1026 gboolean overloaded;
1028 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
1030 if (window->mnemonic_modifier != (modifier & gtk_accelerator_get_default_mod_mask ()))
1033 key.window = window;
1034 key.keyval = keyval;
1035 mnemonic = g_hash_table_lookup (mnemonic_hash_table, &key);
1041 chosen_widget = NULL;
1042 list = mnemonic->targets;
1045 widget = GTK_WIDGET (list->data);
1047 if (GTK_WIDGET_IS_SENSITIVE (widget) &&
1048 GTK_WIDGET_MAPPED (widget))
1056 chosen_widget = widget;
1058 list = g_slist_next (list);
1063 /* For round robin we put the activated entry on
1064 * the end of the list after activation
1066 mnemonic->targets = g_slist_remove (mnemonic->targets, chosen_widget);
1067 mnemonic->targets = g_slist_append (mnemonic->targets, chosen_widget);
1069 return gtk_widget_mnemonic_activate (chosen_widget, overloaded);
1075 gtk_window_set_mnemonic_modifier (GtkWindow *window,
1076 GdkModifierType modifier)
1078 g_return_if_fail (GTK_IS_WINDOW (window));
1079 g_return_if_fail ((modifier & ~GDK_MODIFIER_MASK) == 0);
1081 window->mnemonic_modifier = modifier;
1085 * gtk_window_get_mnemonic_modifier:
1086 * @window: a #GtkWindow
1088 * Returns the mnemonic modifier for this window. See
1089 * gtk_window_set_mnemonic_modifier().
1091 * Return value: the modifier mask used to activate
1092 * mnemonics on this window.
1095 gtk_window_get_mnemonic_modifier (GtkWindow *window)
1097 g_return_val_if_fail (GTK_IS_WINDOW (window), 0);
1099 return window->mnemonic_modifier;
1103 gtk_window_set_position (GtkWindow *window,
1104 GtkWindowPosition position)
1106 g_return_if_fail (GTK_IS_WINDOW (window));
1108 window->position = position;
1110 g_object_notify (G_OBJECT (window), "window_position");
1114 gtk_window_activate_focus (GtkWindow *window)
1116 g_return_val_if_fail (window != NULL, FALSE);
1117 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
1119 if (window->focus_widget)
1121 if (GTK_WIDGET_IS_SENSITIVE (window->focus_widget))
1122 gtk_widget_activate (window->focus_widget);
1130 gtk_window_activate_default (GtkWindow *window)
1132 g_return_val_if_fail (window != NULL, FALSE);
1133 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
1135 if (window->default_widget && GTK_WIDGET_IS_SENSITIVE (window->default_widget) &&
1136 (!window->focus_widget || !GTK_WIDGET_RECEIVES_DEFAULT (window->focus_widget)))
1138 gtk_widget_activate (window->default_widget);
1141 else if (window->focus_widget)
1143 if (GTK_WIDGET_IS_SENSITIVE (window->focus_widget))
1144 gtk_widget_activate (window->focus_widget);
1152 * gtk_window_set_modal:
1153 * @window: a #GtkWindow
1154 * @modal: whether the window is modal
1156 * Sets a window modal or non-modal. Modal windows prevent interaction
1157 * with other windows in the same application. To keep modal dialogs
1158 * on top of main application windows, use
1159 * gtk_window_set_transient_for() to make the dialog transient for the
1160 * parent; most window managers will then disallow lowering the dialog
1166 gtk_window_set_modal (GtkWindow *window,
1169 g_return_if_fail (window != NULL);
1170 g_return_if_fail (GTK_IS_WINDOW (window));
1172 window->modal = modal != FALSE;
1174 /* adjust desired modality state */
1175 if (GTK_WIDGET_VISIBLE (window) && window->modal)
1176 gtk_grab_add (GTK_WIDGET (window));
1178 gtk_grab_remove (GTK_WIDGET (window));
1180 g_object_notify (G_OBJECT (window), "modal");
1184 * gtk_window_get_modal:
1185 * @window: a #GtkWindow
1187 * Returns whether the window is modal. See gtk_window_set_modal().
1189 * Return value: %TRUE if the window is set to be modal and
1190 * establishes a grab when shown
1193 gtk_window_get_modal (GtkWindow *window)
1195 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
1197 return window->modal;
1201 * gtk_window_list_toplevels:
1203 * Returns a list of all existing toplevel windows. The widgets
1204 * in the list are not individually referenced. If you want
1205 * to iterate through the list and perform actions involving
1206 * callbacks that might destroy the widgets, you MUST call
1207 * g_list_foreach (result, (GFunc)g_object_ref, NULL) first, and
1208 * then unref all the widgets afterwards.
1210 * Return value: list of toplevel widgets
1213 gtk_window_list_toplevels (void)
1218 for (slist = toplevel_list; slist; slist = slist->next)
1219 list = g_list_prepend (list, slist->data);
1225 gtk_window_add_embedded_xid (GtkWindow *window, guint xid)
1227 GList *embedded_windows;
1229 g_return_if_fail (window != NULL);
1230 g_return_if_fail (GTK_IS_WINDOW (window));
1232 embedded_windows = gtk_object_get_data (GTK_OBJECT (window), "gtk-embedded");
1233 if (embedded_windows)
1234 gtk_object_remove_no_notify_by_id (GTK_OBJECT (window),
1235 g_quark_from_static_string ("gtk-embedded"));
1236 embedded_windows = g_list_prepend (embedded_windows,
1237 GUINT_TO_POINTER (xid));
1239 gtk_object_set_data_full (GTK_OBJECT (window), "gtk-embedded",
1242 (GtkDestroyNotify) g_list_free : NULL);
1246 gtk_window_remove_embedded_xid (GtkWindow *window, guint xid)
1248 GList *embedded_windows;
1251 g_return_if_fail (window != NULL);
1252 g_return_if_fail (GTK_IS_WINDOW (window));
1254 embedded_windows = gtk_object_get_data (GTK_OBJECT (window), "gtk-embedded");
1255 if (embedded_windows)
1256 gtk_object_remove_no_notify_by_id (GTK_OBJECT (window),
1257 g_quark_from_static_string ("gtk-embedded"));
1259 node = g_list_find (embedded_windows, GUINT_TO_POINTER (xid));
1262 embedded_windows = g_list_remove_link (embedded_windows, node);
1263 g_list_free_1 (node);
1266 gtk_object_set_data_full (GTK_OBJECT (window),
1267 "gtk-embedded", embedded_windows,
1269 (GtkDestroyNotify) g_list_free : NULL);
1273 _gtk_window_reposition (GtkWindow *window,
1277 GtkWindowGeometryInfo *info;
1279 g_return_if_fail (window != NULL);
1280 g_return_if_fail (GTK_IS_WINDOW (window));
1282 /* keep this in sync with gtk_window_compute_reposition()
1284 if (GTK_WIDGET_REALIZED (window))
1286 info = gtk_window_get_geometry_info (window, TRUE);
1288 if (!(info->last.flags & GDK_HINT_POS))
1290 info->last.flags |= GDK_HINT_POS;
1291 gdk_window_set_geometry_hints (GTK_WIDGET (window)->window,
1292 &info->last.geometry,
1297 gdk_window_move (window->frame, x - window->frame_left, y - window->frame_top);
1299 gdk_window_move (GTK_WIDGET (window)->window, x, y);
1304 gtk_window_shutdown (GObject *object)
1308 g_return_if_fail (GTK_IS_WINDOW (object));
1310 window = GTK_WINDOW (object);
1312 gtk_window_set_focus (window, NULL);
1313 gtk_window_set_default (window, NULL);
1315 G_OBJECT_CLASS (parent_class)->shutdown (object);
1319 parent_destroyed_callback (GtkWindow *parent, GtkWindow *child)
1321 gtk_widget_destroy (GTK_WIDGET (child));
1325 connect_parent_destroyed (GtkWindow *window)
1327 if (window->transient_parent)
1329 gtk_signal_connect (GTK_OBJECT (window->transient_parent),
1331 GTK_SIGNAL_FUNC (parent_destroyed_callback),
1337 disconnect_parent_destroyed (GtkWindow *window)
1339 if (window->transient_parent)
1341 gtk_signal_disconnect_by_func (GTK_OBJECT (window->transient_parent),
1342 GTK_SIGNAL_FUNC (parent_destroyed_callback),
1348 gtk_window_transient_parent_realized (GtkWidget *parent,
1351 if (GTK_WIDGET_REALIZED (window))
1352 gdk_window_set_transient_for (window->window, parent->window);
1356 gtk_window_transient_parent_unrealized (GtkWidget *parent,
1359 if (GTK_WIDGET_REALIZED (window))
1360 gdk_property_delete (window->window,
1361 gdk_atom_intern ("WM_TRANSIENT_FOR", FALSE));
1365 gtk_window_unset_transient_for (GtkWindow *window)
1367 if (window->transient_parent)
1369 gtk_signal_disconnect_by_func (GTK_OBJECT (window->transient_parent),
1370 GTK_SIGNAL_FUNC (gtk_window_transient_parent_realized),
1372 gtk_signal_disconnect_by_func (GTK_OBJECT (window->transient_parent),
1373 GTK_SIGNAL_FUNC (gtk_window_transient_parent_unrealized),
1375 gtk_signal_disconnect_by_func (GTK_OBJECT (window->transient_parent),
1376 GTK_SIGNAL_FUNC (gtk_widget_destroyed),
1377 &window->transient_parent);
1379 if (window->destroy_with_parent)
1380 disconnect_parent_destroyed (window);
1382 window->transient_parent = NULL;
1387 * gtk_window_set_transient_for:
1388 * @window: a #GtkWindow
1389 * @parent: parent window
1391 * Dialog windows should be set transient for the main application
1392 * window they were spawned from. This allows window managers to
1393 * e.g. keep the dialog on top of the main window, or center the
1394 * dialog over the main window. gtk_dialog_new_with_buttons() and
1395 * other convenience functions in GTK+ will sometimes call
1396 * gtk_window_set_transient_for() on your behalf.
1400 gtk_window_set_transient_for (GtkWindow *window,
1403 g_return_if_fail (GTK_IS_WINDOW (window));
1404 g_return_if_fail (parent == NULL || GTK_IS_WINDOW (parent));
1405 g_return_if_fail (window != parent);
1408 if (window->transient_parent)
1410 if (GTK_WIDGET_REALIZED (window) &&
1411 GTK_WIDGET_REALIZED (window->transient_parent) &&
1412 (!parent || !GTK_WIDGET_REALIZED (parent)))
1413 gtk_window_transient_parent_unrealized (GTK_WIDGET (window->transient_parent),
1414 GTK_WIDGET (window));
1416 gtk_window_unset_transient_for (window);
1419 window->transient_parent = parent;
1423 gtk_signal_connect (GTK_OBJECT (parent), "destroy",
1424 GTK_SIGNAL_FUNC (gtk_widget_destroyed),
1425 &window->transient_parent);
1426 gtk_signal_connect (GTK_OBJECT (parent), "realize",
1427 GTK_SIGNAL_FUNC (gtk_window_transient_parent_realized),
1429 gtk_signal_connect (GTK_OBJECT (parent), "unrealize",
1430 GTK_SIGNAL_FUNC (gtk_window_transient_parent_unrealized),
1433 if (window->destroy_with_parent)
1434 connect_parent_destroyed (window);
1436 if (GTK_WIDGET_REALIZED (window) &&
1437 GTK_WIDGET_REALIZED (parent))
1438 gtk_window_transient_parent_realized (GTK_WIDGET (parent),
1439 GTK_WIDGET (window));
1444 * gtk_window_get_transient_for:
1445 * @window: a #GtkWindow
1447 * Fetches the transient parent for this window. See
1448 * gtk_window_set_transient_for().
1450 * Return value: the transient parent for this window, or %NULL
1451 * if no transient parent has been set.
1454 gtk_window_get_transient_for (GtkWindow *window)
1456 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
1458 return window->transient_parent;
1462 * gtk_window_set_type_hint:
1463 * @window: a #GtkWindow
1464 * @hint: the window type
1466 * By setting the type hint for the window, you allow the window
1467 * manager to decorate and handle the window in a way which is
1468 * suitable to the function of the window in your application.
1470 * This function should be called before the window becomes visible.
1472 * gtk_dialog_new_with_buttons() and other convenience functions in GTK+
1473 * will sometimes call gtk_window_set_type_hint() on your behalf.
1477 gtk_window_set_type_hint (GtkWindow *window,
1478 GdkWindowTypeHint hint)
1480 g_return_if_fail (GTK_IS_WINDOW (window));
1481 g_return_if_fail (!GTK_WIDGET_VISIBLE (window));
1482 window->type_hint = hint;
1486 * gtk_window_get_type_hint:
1487 * @window: a #GtkWindow
1489 * Gets the type hint for this window. See gtk_window_set_type_hint().
1491 * Return value: the type hint for @window.
1494 gtk_window_get_type_hint (GtkWindow *window)
1496 g_return_val_if_fail (GTK_IS_WINDOW (window), GDK_WINDOW_TYPE_HINT_NORMAL);
1498 return window->type_hint;
1502 * gtk_window_set_destroy_with_parent:
1503 * @window: a #GtkWindow
1504 * @setting: whether to destroy @window with its transient parent
1506 * If @setting is TRUE, then destroying the transient parent of @window
1507 * will also destroy @window itself. This is useful for dialogs that
1508 * shouldn't persist beyond the lifetime of the main window they're
1509 * associated with, for example.
1512 gtk_window_set_destroy_with_parent (GtkWindow *window,
1515 g_return_if_fail (GTK_IS_WINDOW (window));
1517 if (window->destroy_with_parent == (setting != FALSE))
1520 if (window->destroy_with_parent)
1522 disconnect_parent_destroyed (window);
1526 connect_parent_destroyed (window);
1529 window->destroy_with_parent = setting;
1531 g_object_notify (G_OBJECT (window), "destroy_with_parent");
1535 * gtk_window_get_destroy_with_parent:
1536 * @window: a #GtkWindow
1538 * Returns whether the window will be destroyed with its transient parent. See
1539 * gtk_window_set_destroy_with_parent ().
1541 * Return value: %TRUE if the window will be destroyed with its transient parent.
1544 gtk_window_get_destroy_with_parent (GtkWindow *window)
1546 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
1548 return window->destroy_with_parent;
1551 static GtkWindowGeometryInfo*
1552 gtk_window_get_geometry_info (GtkWindow *window,
1555 GtkWindowGeometryInfo *info;
1557 info = window->geometry_info;
1558 if (!info && create)
1560 info = g_new0 (GtkWindowGeometryInfo, 1);
1564 info->last.width = -1;
1565 info->last.height = -1;
1566 info->widget = NULL;
1568 info->may_shrink = FALSE;
1569 window->geometry_info = info;
1576 * gtk_window_set_geometry_hints:
1577 * @window: a #GtkWindow
1578 * @geometry_widget: widget the geometry hints will be applied to
1579 * @geometry: struct containing geometry information
1580 * @geom_mask: mask indicating which struct fields should be paid attention to
1582 * This function sets up hints about how a window can be resized by
1583 * the user. You can set a minimum and maximum size; allowed resize
1584 * increments (e.g. for xterm, you can only resize by the size of a
1585 * character); aspect ratios; and more. See the #GdkGeometry struct.
1589 gtk_window_set_geometry_hints (GtkWindow *window,
1590 GtkWidget *geometry_widget,
1591 GdkGeometry *geometry,
1592 GdkWindowHints geom_mask)
1594 GtkWindowGeometryInfo *info;
1596 g_return_if_fail (window != NULL);
1598 info = gtk_window_get_geometry_info (window, TRUE);
1601 gtk_signal_disconnect_by_func (GTK_OBJECT (info->widget),
1602 GTK_SIGNAL_FUNC (gtk_widget_destroyed),
1605 info->widget = geometry_widget;
1607 gtk_signal_connect (GTK_OBJECT (geometry_widget), "destroy",
1608 GTK_SIGNAL_FUNC (gtk_widget_destroyed),
1612 info->geometry = *geometry;
1614 info->mask = geom_mask;
1616 gtk_widget_queue_resize (GTK_WIDGET (window));
1620 * gtk_window_set_decorated:
1621 * @window: a #GtkWindow
1622 * @setting: %TRUE to decorate the window
1624 * By default, windows are decorated with a title bar, resize
1625 * controls, etc. Some window managers allow GTK+ to disable these
1626 * decorations, creating a borderless window. If you set the decorated
1627 * property to %FALSE using this function, GTK+ will do its best to
1628 * convince the window manager not to decorate the window.
1632 gtk_window_set_decorated (GtkWindow *window,
1635 g_return_if_fail (GTK_IS_WINDOW (window));
1637 setting = setting != FALSE;
1639 if (setting == window->decorated)
1642 if (GTK_WIDGET (window)->window)
1644 if (window->decorated)
1645 gdk_window_set_decorations (GTK_WIDGET (window)->window,
1648 gdk_window_set_decorations (GTK_WIDGET (window)->window,
1654 * gtk_window_get_decorated:
1655 * @window: a #GtkWindow
1657 * Returns whether the window has been set to have decorations
1658 * such as a title bar via gtk_window_set_decorated().
1660 * Return value: %TRUE if the window has been set to have decorations
1663 gtk_window_get_decorated (GtkWindow *window)
1665 g_return_val_if_fail (GTK_IS_WINDOW (window), TRUE);
1667 return window->decorated;
1671 * gtk_window_set_default_size:
1672 * @window: a #GtkWindow
1673 * @width: width in pixels, 0 to unset, or -1 to leave the width unchanged
1674 * @height: height in pixels, 0 to unset, or -1 to leave the height unchanged
1676 * Sets the default size of a window. If the window's "natural" size
1677 * (its size request) is larger than the default, the default will be
1678 * ignored. So the default size is a minimum initial size. Unlike
1679 * gtk_widget_set_usize(), which sets a size request for a widget and
1680 * thus would keep users from shrinking the window, this function only
1681 * sets the initial size, just as if the user had resized the window
1682 * themselves. Users can still shrink the window again as they
1683 * normally would. Setting a default size of 0 means to use the
1684 * "natural" default size (the size request of the window).
1686 * For more control over a window's initial size and how resizing works,
1687 * investigate gtk_window_set_geometry_hints().
1689 * A useful feature: if you set the "geometry widget" via
1690 * gtk_window_set_geometry_hints(), the default size specified by
1691 * gtk_window_set_default_size() will be the default size of that
1692 * widget, not of the entire window.
1696 gtk_window_set_default_size (GtkWindow *window,
1700 GtkWindowGeometryInfo *info;
1702 g_return_if_fail (GTK_IS_WINDOW (window));
1704 info = gtk_window_get_geometry_info (window, TRUE);
1706 g_object_freeze_notify (G_OBJECT (window));
1709 info->width = width;
1710 g_object_notify (G_OBJECT (window), "default_width");
1711 info->may_shrink = TRUE;
1715 info->height = height;
1716 g_object_notify (G_OBJECT (window), "default_height");
1717 info->may_shrink = TRUE;
1719 g_object_thaw_notify (G_OBJECT (window));
1721 gtk_widget_queue_resize (GTK_WIDGET (window));
1725 * gtk_window_get_default_size:
1726 * @window: a #GtkWindow
1727 * @width: location to store the default width, or %NULL
1728 * @height: location to store the default height, or %NULL
1730 * Gets the default size of the window. A value of 0 for the
1731 * width or height indicates that a default size has not
1732 * been explicitely set for that dimension, so the value
1733 * will be computed from the requisition of the window.
1736 gtk_window_get_default_size (GtkWindow *window,
1740 GtkWindowGeometryInfo *info;
1742 g_return_if_fail (GTK_IS_WINDOW (window));
1744 info = gtk_window_get_geometry_info (window, FALSE);
1747 *width = info ? info->width : 0;
1750 *height = info ? info->height : 0;
1754 gtk_window_destroy (GtkObject *object)
1758 g_return_if_fail (GTK_IS_WINDOW (object));
1760 window = GTK_WINDOW (object);
1762 if (window->transient_parent)
1763 gtk_window_set_transient_for (window, NULL);
1765 if (window->has_user_ref_count)
1767 window->has_user_ref_count = FALSE;
1768 gtk_widget_unref (GTK_WIDGET (window));
1772 gtk_window_group_remove_window (window->group, window);
1774 GTK_OBJECT_CLASS (parent_class)->destroy (object);
1778 gtk_window_mnemonic_hash_remove (gpointer key,
1782 GtkWindowMnemonic *mnemonic = key;
1783 GtkWindow *window = user;
1785 if (mnemonic->window == window)
1787 if (mnemonic->targets)
1789 gchar *name = gtk_accelerator_name (mnemonic->keyval, 0);
1791 g_warning ("mnemonic \"%s\" wasn't removed for widget (%p)",
1792 name, mnemonic->targets->data);
1795 g_slist_free (mnemonic->targets);
1804 gtk_window_finalize (GObject *object)
1808 g_return_if_fail (GTK_IS_WINDOW (object));
1810 window = GTK_WINDOW (object);
1812 toplevel_list = g_slist_remove (toplevel_list, window);
1814 g_free (window->title);
1815 g_free (window->wmclass_name);
1816 g_free (window->wmclass_class);
1817 g_free (window->wm_role);
1819 g_hash_table_foreach_remove (mnemonic_hash_table,
1820 gtk_window_mnemonic_hash_remove,
1822 if (window->geometry_info)
1824 if (window->geometry_info->widget)
1825 gtk_signal_disconnect_by_func (GTK_OBJECT (window->geometry_info->widget),
1826 GTK_SIGNAL_FUNC (gtk_widget_destroyed),
1827 &window->geometry_info->widget);
1828 g_free (window->geometry_info);
1831 G_OBJECT_CLASS (parent_class)->finalize (object);
1835 gtk_window_show (GtkWidget *widget)
1837 GtkWindow *window = GTK_WINDOW (widget);
1838 GtkContainer *container = GTK_CONTAINER (window);
1839 gboolean need_resize;
1841 GTK_WIDGET_SET_FLAGS (widget, GTK_VISIBLE);
1843 need_resize = container->need_resize || !GTK_WIDGET_REALIZED (widget);
1844 container->need_resize = FALSE;
1848 GtkWindowGeometryInfo *info = gtk_window_get_geometry_info (window, TRUE);
1849 GtkAllocation allocation = { 0, 0 };
1850 GdkGeometry new_geometry;
1851 guint width, height, new_flags;
1852 gboolean was_realized;
1854 /* determine default size to initially show the window with */
1855 gtk_widget_size_request (widget, NULL);
1856 gtk_window_compute_default_size (window, &width, &height);
1858 /* save away the last default size for later comparisions */
1859 info->last.width = width;
1860 info->last.height = height;
1862 /* constrain size to geometry */
1863 gtk_window_compute_hints (window, &new_geometry, &new_flags);
1864 gtk_window_constrain_size (window,
1865 &new_geometry, new_flags,
1869 /* and allocate the window */
1870 allocation.width = width;
1871 allocation.height = height;
1872 gtk_widget_size_allocate (widget, &allocation);
1874 was_realized = FALSE;
1875 if (!GTK_WIDGET_REALIZED (widget))
1877 gtk_widget_realize (widget);
1878 was_realized = TRUE;;
1881 /* Must be done after the windows are realized,
1882 * so that the decorations can be read
1884 gtk_decorated_window_calculate_frame_size (window);
1887 gdk_window_resize (widget->window, width, height);
1890 gtk_container_check_resize (container);
1892 gtk_widget_map (widget);
1895 gtk_grab_add (widget);
1899 gtk_window_hide (GtkWidget *widget)
1903 g_return_if_fail (widget != NULL);
1904 g_return_if_fail (GTK_IS_WINDOW (widget));
1906 window = GTK_WINDOW (widget);
1908 GTK_WIDGET_UNSET_FLAGS (widget, GTK_VISIBLE);
1909 gtk_widget_unmap (widget);
1912 gtk_grab_remove (widget);
1916 gtk_window_map (GtkWidget *widget)
1919 GdkWindow *toplevel;
1921 g_return_if_fail (widget != NULL);
1922 g_return_if_fail (GTK_IS_WINDOW (widget));
1924 GTK_WIDGET_SET_FLAGS (widget, GTK_MAPPED);
1926 window = GTK_WINDOW (widget);
1928 if (window->bin.child &&
1929 GTK_WIDGET_VISIBLE (window->bin.child) &&
1930 !GTK_WIDGET_MAPPED (window->bin.child))
1931 gtk_widget_map (window->bin.child);
1934 toplevel = window->frame;
1936 toplevel = widget->window;
1938 if (window->maximize_initially)
1939 gdk_window_maximize (toplevel);
1941 gdk_window_unmaximize (toplevel);
1943 if (window->stick_initially)
1944 gdk_window_stick (toplevel);
1946 gdk_window_unstick (toplevel);
1948 if (window->iconify_initially)
1949 gdk_window_iconify (toplevel);
1951 gdk_window_deiconify (toplevel);
1953 gdk_window_show (widget->window);
1956 gdk_window_show (window->frame);
1960 gtk_window_unmap (GtkWidget *widget)
1964 g_return_if_fail (widget != NULL);
1965 g_return_if_fail (GTK_IS_WINDOW (widget));
1967 window = GTK_WINDOW (widget);
1969 GTK_WIDGET_UNSET_FLAGS (widget, GTK_MAPPED);
1971 gdk_window_withdraw (window->frame);
1973 gdk_window_withdraw (widget->window);
1975 window->use_uposition = TRUE;
1976 window->resize_count = 0;
1977 window->handling_resize = FALSE;
1982 gtk_window_realize (GtkWidget *widget)
1985 GdkWindow *parent_window;
1986 GdkWindowAttr attributes;
1987 gint attributes_mask;
1989 g_return_if_fail (GTK_IS_WINDOW (widget));
1991 window = GTK_WINDOW (widget);
1993 /* ensure widget tree is properly size allocated */
1994 if (widget->allocation.x == -1 &&
1995 widget->allocation.y == -1 &&
1996 widget->allocation.width == 1 &&
1997 widget->allocation.height == 1)
1999 GtkRequisition requisition;
2000 GtkAllocation allocation = { 0, 0, 200, 200 };
2002 gtk_widget_size_request (widget, &requisition);
2003 if (requisition.width || requisition.height)
2005 /* non-empty window */
2006 allocation.width = requisition.width;
2007 allocation.height = requisition.height;
2009 gtk_widget_size_allocate (widget, &allocation);
2011 gtk_container_queue_resize (GTK_CONTAINER (widget));
2013 g_return_if_fail (!GTK_WIDGET_REALIZED (widget));
2016 GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED);
2018 switch (window->type)
2020 case GTK_WINDOW_TOPLEVEL:
2021 attributes.window_type = GDK_WINDOW_TOPLEVEL;
2023 case GTK_WINDOW_POPUP:
2024 attributes.window_type = GDK_WINDOW_TEMP;
2027 g_warning (G_STRLOC": Unknown window type %d!", window->type);
2031 attributes.title = window->title;
2032 attributes.wmclass_name = window->wmclass_name;
2033 attributes.wmclass_class = window->wmclass_class;
2034 attributes.wclass = GDK_INPUT_OUTPUT;
2035 attributes.visual = gtk_widget_get_visual (widget);
2036 attributes.colormap = gtk_widget_get_colormap (widget);
2038 if (window->has_frame)
2040 attributes.width = widget->allocation.width + window->frame_left + window->frame_right;
2041 attributes.height = widget->allocation.height + window->frame_top + window->frame_bottom;
2042 attributes.event_mask = (GDK_EXPOSURE_MASK |
2043 GDK_KEY_PRESS_MASK |
2044 GDK_ENTER_NOTIFY_MASK |
2045 GDK_LEAVE_NOTIFY_MASK |
2046 GDK_FOCUS_CHANGE_MASK |
2047 GDK_STRUCTURE_MASK |
2048 GDK_BUTTON_MOTION_MASK |
2049 GDK_POINTER_MOTION_HINT_MASK |
2050 GDK_BUTTON_PRESS_MASK |
2051 GDK_BUTTON_RELEASE_MASK);
2053 attributes_mask = GDK_WA_VISUAL | GDK_WA_COLORMAP;
2055 window->frame = gdk_window_new (NULL, &attributes, attributes_mask);
2056 gdk_window_set_user_data (window->frame, widget);
2058 attributes.window_type = GDK_WINDOW_CHILD;
2059 attributes.x = window->frame_left;
2060 attributes.y = window->frame_right;
2062 attributes_mask = GDK_WA_X | GDK_WA_Y;
2064 parent_window = window->frame;
2068 attributes_mask = 0;
2069 parent_window = NULL;
2072 attributes.width = widget->allocation.width;
2073 attributes.height = widget->allocation.height;
2074 attributes.event_mask = gtk_widget_get_events (widget);
2075 attributes.event_mask |= (GDK_EXPOSURE_MASK |
2076 GDK_KEY_PRESS_MASK |
2077 GDK_ENTER_NOTIFY_MASK |
2078 GDK_LEAVE_NOTIFY_MASK |
2079 GDK_FOCUS_CHANGE_MASK |
2080 GDK_STRUCTURE_MASK);
2082 attributes_mask |= GDK_WA_VISUAL | GDK_WA_COLORMAP;
2083 attributes_mask |= (window->title ? GDK_WA_TITLE : 0);
2084 attributes_mask |= (window->wmclass_name ? GDK_WA_WMCLASS : 0);
2085 widget->window = gdk_window_new (parent_window, &attributes, attributes_mask);
2086 gdk_window_set_user_data (widget->window, window);
2088 widget->style = gtk_style_attach (widget->style, widget->window);
2089 gtk_style_set_background (widget->style, widget->window, GTK_STATE_NORMAL);
2091 gtk_style_set_background (widget->style, window->frame, GTK_STATE_NORMAL);
2093 /* This is a bad hack to set the window background. */
2094 gtk_window_paint (widget, NULL);
2096 if (window->transient_parent &&
2097 GTK_WIDGET_REALIZED (window->transient_parent))
2098 gdk_window_set_transient_for (widget->window,
2099 GTK_WIDGET (window->transient_parent)->window);
2101 if (window->wm_role)
2102 gdk_window_set_role (widget->window, window->wm_role);
2104 if (!window->decorated)
2105 gdk_window_set_decorations (widget->window, 0);
2107 gdk_window_set_type_hint (widget->window, window->type_hint);
2109 /* transient_for must be set to allow the modal hint */
2110 if (window->transient_parent && window->modal)
2111 gdk_window_set_modal_hint (widget->window, TRUE);
2113 gdk_window_set_modal_hint (widget->window, FALSE);
2117 gtk_window_unrealize (GtkWidget *widget)
2121 g_return_if_fail (widget != NULL);
2122 g_return_if_fail (GTK_IS_WINDOW (widget));
2124 window = GTK_WINDOW (widget);
2128 gdk_window_set_user_data (window->frame, NULL);
2129 gdk_window_destroy (window->frame);
2130 window->frame = NULL;
2133 (* GTK_WIDGET_CLASS (parent_class)->unrealize) (widget);
2137 gtk_window_size_request (GtkWidget *widget,
2138 GtkRequisition *requisition)
2143 g_return_if_fail (widget != NULL);
2144 g_return_if_fail (GTK_IS_WINDOW (widget));
2145 g_return_if_fail (requisition != NULL);
2147 window = GTK_WINDOW (widget);
2148 bin = GTK_BIN (window);
2150 requisition->width = GTK_CONTAINER (window)->border_width * 2;
2151 requisition->height = GTK_CONTAINER (window)->border_width * 2;
2153 if (bin->child && GTK_WIDGET_VISIBLE (bin->child))
2155 GtkRequisition child_requisition;
2157 gtk_widget_size_request (bin->child, &child_requisition);
2159 requisition->width += child_requisition.width;
2160 requisition->height += child_requisition.height;
2165 gtk_window_size_allocate (GtkWidget *widget,
2166 GtkAllocation *allocation)
2169 GtkAllocation child_allocation;
2171 g_return_if_fail (widget != NULL);
2172 g_return_if_fail (GTK_IS_WINDOW (widget));
2173 g_return_if_fail (allocation != NULL);
2175 window = GTK_WINDOW (widget);
2176 widget->allocation = *allocation;
2178 if (window->bin.child && GTK_WIDGET_VISIBLE (window->bin.child))
2180 child_allocation.x = GTK_CONTAINER (window)->border_width;
2181 child_allocation.y = GTK_CONTAINER (window)->border_width;
2182 child_allocation.width =
2183 MAX (1, (gint)allocation->width - child_allocation.x * 2);
2184 child_allocation.height =
2185 MAX (1, (gint)allocation->height - child_allocation.y * 2);
2187 gtk_widget_size_allocate (window->bin.child, &child_allocation);
2190 if (GTK_WIDGET_REALIZED (widget) && window->frame)
2192 gdk_window_resize (window->frame,
2193 allocation->width + window->frame_left + window->frame_right,
2194 allocation->height + window->frame_top + window->frame_bottom);
2199 gtk_window_event (GtkWidget *widget, GdkEvent *event)
2202 gboolean return_val;
2205 g_return_val_if_fail (widget != NULL, FALSE);
2206 g_return_val_if_fail (GTK_IS_WINDOW (widget), FALSE);
2207 g_return_val_if_fail (event != NULL, FALSE);
2209 window = GTK_WINDOW (widget);
2211 if (window->frame && (event->any.window == window->frame))
2213 if ((event->type != GDK_KEY_PRESS) &&
2214 (event->type != GDK_KEY_RELEASE) &&
2215 (event->type != GDK_FOCUS_CHANGE))
2217 gtk_signal_emit_stop_by_name (GTK_OBJECT (widget), "event");
2219 gtk_signal_emit (GTK_OBJECT (widget), window_signals[FRAME_EVENT], event, &return_val);
2224 g_object_unref (event->any.window);
2225 event->any.window = g_object_ref (widget->window);
2233 gtk_window_frame_event (GtkWidget *widget, GdkEvent *event)
2235 GdkEventConfigure *configure_event;
2236 GtkWindow *window = GTK_WINDOW (widget);
2239 switch (event->type)
2242 configure_event = (GdkEventConfigure *)event;
2244 /* Invalidate the decorations */
2247 rect.width = configure_event->width;
2248 rect.height = configure_event->height;
2250 gdk_window_invalidate_rect (window->frame, &rect, FALSE);
2252 /* Pass on the (modified) configure event */
2253 configure_event->width -= window->frame_left + window->frame_right;
2254 configure_event->height -= window->frame_top + window->frame_bottom;
2255 return gtk_window_configure_event (widget, configure_event);
2264 gtk_window_configure_event (GtkWidget *widget,
2265 GdkEventConfigure *event)
2269 g_return_val_if_fail (widget != NULL, FALSE);
2270 g_return_val_if_fail (GTK_IS_WINDOW (widget), FALSE);
2271 g_return_val_if_fail (event != NULL, FALSE);
2273 window = GTK_WINDOW (widget);
2275 /* we got a configure event specifying the new window size and position,
2276 * in principle we have to distinguish 4 cases here:
2277 * 1) the size didn't change and resize_count == 0
2278 * -> the window was merely moved (sometimes not even that)
2279 * 2) the size didn't change and resize_count > 0
2280 * -> we requested a new size, but didn't get it
2281 * 3) the size changed and resize_count > 0
2282 * -> we asked for a new size and we got one
2283 * 4) the size changed and resize_count == 0
2284 * -> we got resized from outside the toolkit, and have to
2285 * accept that size since we don't want to fight neither the
2286 * window manager nor the user
2287 * in the three latter cases we have to reallocate the widget tree,
2288 * which happens in gtk_window_move_resize(), so we set a flag for
2289 * that function and assign the new size. if resize_count > 1,
2290 * we simply do nothing and wait for more configure events.
2293 if (window->resize_count > 0 ||
2294 widget->allocation.width != event->width ||
2295 widget->allocation.height != event->height)
2297 if (window->resize_count > 0)
2298 window->resize_count -= 1;
2300 if (window->resize_count == 0)
2302 window->handling_resize = TRUE;
2304 widget->allocation.width = event->width;
2305 widget->allocation.height = event->height;
2307 gtk_widget_queue_resize (widget);
2315 gtk_window_key_press_event (GtkWidget *widget,
2321 g_return_val_if_fail (widget != NULL, FALSE);
2322 g_return_val_if_fail (GTK_IS_WINDOW (widget), FALSE);
2323 g_return_val_if_fail (event != NULL, FALSE);
2325 window = GTK_WINDOW (widget);
2329 if (window->focus_widget && window->focus_widget != widget &&
2330 GTK_WIDGET_IS_SENSITIVE (window->focus_widget))
2331 handled = gtk_widget_event (window->focus_widget, (GdkEvent*) event);
2334 handled = gtk_window_mnemonic_activate (window,
2339 handled = gtk_accel_groups_activate (GTK_OBJECT (window), event->keyval, event->state);
2341 /* Chain up, invokes binding set */
2342 if (!handled && GTK_WIDGET_CLASS (parent_class)->key_press_event)
2343 handled = GTK_WIDGET_CLASS (parent_class)->key_press_event (widget, event);
2350 gtk_window_real_activate_default (GtkWindow *window)
2352 gtk_window_activate_default (window);
2356 gtk_window_real_activate_focus (GtkWindow *window)
2358 gtk_window_activate_focus (window);
2362 gtk_window_move_focus (GtkWindow *window,
2363 GtkDirectionType dir)
2365 gtk_widget_child_focus (GTK_WIDGET (window), dir);
2367 if (!GTK_CONTAINER (window)->focus_child)
2368 gtk_window_set_focus (window, NULL);
2372 gtk_window_key_release_event (GtkWidget *widget,
2378 g_return_val_if_fail (widget != NULL, FALSE);
2379 g_return_val_if_fail (GTK_IS_WINDOW (widget), FALSE);
2380 g_return_val_if_fail (event != NULL, FALSE);
2382 window = GTK_WINDOW (widget);
2384 if (window->focus_widget &&
2385 window->focus_widget != widget &&
2386 GTK_WIDGET_SENSITIVE (window->focus_widget))
2388 handled = gtk_widget_event (window->focus_widget, (GdkEvent*) event);
2391 if (!handled && GTK_WIDGET_CLASS (parent_class)->key_release_event)
2392 handled = GTK_WIDGET_CLASS (parent_class)->key_release_event (widget, event);
2398 gtk_window_enter_notify_event (GtkWidget *widget,
2399 GdkEventCrossing *event)
2401 g_return_val_if_fail (widget != NULL, FALSE);
2402 g_return_val_if_fail (GTK_IS_WINDOW (widget), FALSE);
2403 g_return_val_if_fail (event != NULL, FALSE);
2409 gtk_window_leave_notify_event (GtkWidget *widget,
2410 GdkEventCrossing *event)
2412 g_return_val_if_fail (widget != NULL, FALSE);
2413 g_return_val_if_fail (GTK_IS_WINDOW (widget), FALSE);
2414 g_return_val_if_fail (event != NULL, FALSE);
2420 gtk_window_focus_in_event (GtkWidget *widget,
2421 GdkEventFocus *event)
2423 GtkWindow *window = GTK_WINDOW (widget);
2424 GdkEventFocus fevent;
2426 /* It appears spurious focus in events can occur when
2427 * the window is hidden. So we'll just check to see if
2428 * the window is visible before actually handling the
2431 if (GTK_WIDGET_VISIBLE (widget))
2433 window->has_focus = TRUE;
2435 if (window->focus_widget &&
2436 window->focus_widget != widget &&
2437 !GTK_WIDGET_HAS_FOCUS (window->focus_widget))
2439 fevent.type = GDK_FOCUS_CHANGE;
2440 fevent.window = window->focus_widget->window;
2443 gtk_widget_event (window->focus_widget, (GdkEvent*) &fevent);
2451 gtk_window_focus_out_event (GtkWidget *widget,
2452 GdkEventFocus *event)
2454 GtkWindow *window = GTK_WINDOW (widget);
2455 GdkEventFocus fevent;
2457 window->has_focus = FALSE;
2459 if (window->focus_widget &&
2460 window->focus_widget != widget &&
2461 GTK_WIDGET_HAS_FOCUS (window->focus_widget))
2463 fevent.type = GDK_FOCUS_CHANGE;
2464 fevent.window = window->focus_widget->window;
2467 gtk_widget_event (window->focus_widget, (GdkEvent*) &fevent);
2473 static GdkAtom atom_rcfiles = GDK_NONE;
2476 gtk_window_read_rcfiles (GtkWidget *widget,
2477 GdkEventClient *event)
2479 GList *embedded_windows;
2481 embedded_windows = gtk_object_get_data (GTK_OBJECT (widget), "gtk-embedded");
2482 if (embedded_windows)
2487 for(i = 0; i < 5; i++)
2489 sev.data_format = 32;
2490 sev.message_type = atom_rcfiles;
2492 while (embedded_windows)
2494 guint xid = GPOINTER_TO_UINT (embedded_windows->data);
2495 gdk_event_send_client_message ((GdkEvent *) &sev, xid);
2496 embedded_windows = embedded_windows->next;
2500 if (gtk_rc_reparse_all ())
2502 /* If the above returned true, some of our RC files are out
2503 * of date, so we need to reset all our widgets. Our other
2504 * toplevel windows will also get the message, but by
2505 * then, the RC file will up to date, so we have to tell
2506 * them now. Also, we have to invalidate cached icons in
2507 * icon sets so they get re-rendered.
2509 GList *list, *toplevels;
2511 _gtk_icon_set_invalidate_caches ();
2513 toplevels = gtk_window_list_toplevels ();
2514 g_list_foreach (toplevels, (GFunc)g_object_ref, NULL);
2516 for (list = toplevels; list; list = list->next)
2518 gtk_widget_reset_rc_styles (list->data);
2519 gtk_widget_unref (list->data);
2521 g_list_free (toplevels);
2526 gtk_window_client_event (GtkWidget *widget,
2527 GdkEventClient *event)
2529 g_return_val_if_fail (widget != NULL, FALSE);
2530 g_return_val_if_fail (GTK_IS_WINDOW (widget), FALSE);
2531 g_return_val_if_fail (event != NULL, FALSE);
2534 atom_rcfiles = gdk_atom_intern("_GTK_READ_RCFILES", FALSE);
2536 if(event->message_type == atom_rcfiles)
2537 gtk_window_read_rcfiles (widget, event);
2543 gtk_window_check_resize (GtkContainer *container)
2547 g_return_if_fail (container != NULL);
2548 g_return_if_fail (GTK_IS_WINDOW (container));
2550 window = GTK_WINDOW (container);
2552 if (GTK_WIDGET_VISIBLE (container))
2553 gtk_window_move_resize (window);
2557 gtk_window_focus (GtkWidget *widget,
2558 GtkDirectionType direction)
2562 GtkContainer *container;
2563 GtkWidget *old_focus_child;
2566 container = GTK_CONTAINER (widget);
2567 window = GTK_WINDOW (widget);
2568 bin = GTK_BIN (widget);
2570 old_focus_child = container->focus_child;
2572 /* We need a special implementation here to deal properly with wrapping
2573 * around in the tab chain without the danger of going into an
2576 if (old_focus_child)
2578 if (gtk_widget_child_focus (old_focus_child, direction))
2582 if (window->focus_widget)
2584 /* Wrapped off the end, clear the focus setting for the toplpevel */
2585 parent = window->focus_widget->parent;
2588 gtk_container_set_focus_child (GTK_CONTAINER (parent), NULL);
2589 parent = GTK_WIDGET (parent)->parent;
2592 gtk_window_set_focus (GTK_WINDOW (container), NULL);
2595 /* Now try to focus the first widget in the window */
2598 if (gtk_widget_child_focus (bin->child, direction))
2606 gtk_window_real_set_focus (GtkWindow *window,
2609 GdkEventFocus event;
2610 gboolean def_flags = 0;
2612 g_return_if_fail (window != NULL);
2613 g_return_if_fail (GTK_IS_WINDOW (window));
2615 if (window->default_widget)
2616 def_flags = GTK_WIDGET_HAS_DEFAULT (window->default_widget);
2618 if (window->focus_widget)
2620 if (GTK_WIDGET_RECEIVES_DEFAULT (window->focus_widget) &&
2621 (window->focus_widget != window->default_widget))
2623 GTK_WIDGET_UNSET_FLAGS (window->focus_widget, GTK_HAS_DEFAULT);
2625 if (window->default_widget)
2626 GTK_WIDGET_SET_FLAGS (window->default_widget, GTK_HAS_DEFAULT);
2629 if (window->has_focus)
2631 event.type = GDK_FOCUS_CHANGE;
2632 event.window = window->focus_widget->window;
2635 gtk_widget_event (window->focus_widget, (GdkEvent*) &event);
2639 window->focus_widget = focus;
2641 if (window->focus_widget)
2643 if (GTK_WIDGET_RECEIVES_DEFAULT (window->focus_widget) &&
2644 (window->focus_widget != window->default_widget))
2646 if (GTK_WIDGET_CAN_DEFAULT (window->focus_widget))
2647 GTK_WIDGET_SET_FLAGS (window->focus_widget, GTK_HAS_DEFAULT);
2649 if (window->default_widget)
2650 GTK_WIDGET_UNSET_FLAGS (window->default_widget, GTK_HAS_DEFAULT);
2653 if (window->has_focus)
2655 event.type = GDK_FOCUS_CHANGE;
2656 event.window = window->focus_widget->window;
2659 gtk_widget_event (window->focus_widget, (GdkEvent*) &event);
2663 if (window->default_widget &&
2664 (def_flags != GTK_WIDGET_FLAGS (window->default_widget)))
2665 gtk_widget_queue_draw (window->default_widget);
2670 /*********************************
2671 * Functions related to resizing *
2672 *********************************/
2675 gtk_window_move_resize (GtkWindow *window)
2678 GtkContainer *container;
2679 GtkWindowGeometryInfo *info;
2680 GtkWindowLastGeometryInfo saved_last_info;
2681 GdkGeometry new_geometry;
2685 gint new_width, new_height;
2686 gboolean need_reposition;
2687 gboolean default_size_changed = FALSE;
2688 gboolean hints_changed = FALSE;
2689 gboolean may_shrink = window->auto_shrink;
2691 g_return_if_fail (GTK_WIDGET_REALIZED (window));
2693 widget = GTK_WIDGET (window);
2694 container = GTK_CONTAINER (widget);
2695 info = gtk_window_get_geometry_info (window, TRUE);
2696 saved_last_info = info->last;
2698 gtk_widget_size_request (widget, NULL);
2699 gtk_window_compute_default_size (window, &new_width, &new_height);
2701 if (info->last.width < 0 ||
2702 info->last.width != new_width ||
2703 info->last.height != new_height)
2705 default_size_changed = TRUE;
2706 may_shrink |= info->may_shrink;
2707 info->last.width = new_width;
2708 info->last.height = new_height;
2710 /* We need to force a reposition in this case
2712 if (window->position == GTK_WIN_POS_CENTER_ALWAYS)
2713 window->use_uposition = TRUE;
2715 info->may_shrink = FALSE;
2717 /* Compute new set of hints for the window
2719 gtk_window_compute_hints (window, &new_geometry, &new_flags);
2720 if (!gtk_window_compare_hints (&info->last.geometry, info->last.flags,
2721 &new_geometry, new_flags))
2723 hints_changed = TRUE;
2724 info->last.geometry = new_geometry;
2725 info->last.flags = new_flags;
2728 /* From the default size and the allocation, figure out the size
2729 * the window should be.
2731 if (!default_size_changed ||
2733 new_width <= widget->allocation.width &&
2734 new_height <= widget->allocation.height))
2736 new_width = widget->allocation.width;
2737 new_height = widget->allocation.height;
2740 /* constrain the window size to the specified geometry */
2741 gtk_window_constrain_size (window,
2742 &new_geometry, new_flags,
2743 new_width, new_height,
2744 &new_width, &new_height);
2746 /* compute new window position if a move is required
2748 need_reposition = gtk_window_compute_reposition (window, new_width, new_height, &x, &y);
2749 if (need_reposition && !(new_flags & GDK_HINT_POS))
2751 new_flags |= GDK_HINT_POS;
2752 hints_changed = TRUE;
2756 /* handle actual resizing:
2757 * - handle reallocations due to configure events
2758 * - figure whether we need to request a new window size
2759 * - handle simple resizes within our widget tree
2760 * - reposition window if neccessary
2762 width = widget->allocation.width;
2763 height = widget->allocation.height;
2765 if (window->handling_resize)
2767 GtkAllocation allocation;
2769 /* if we are just responding to a configure event, which
2770 * might be due to a resize by the window manager, the
2771 * user, or a response to a resizing request we made
2772 * earlier, we go ahead, allocate the new size and we're done
2773 * (see gtk_window_configure_event() for more details).
2776 window->handling_resize = FALSE;
2778 allocation = widget->allocation;
2780 gtk_widget_size_allocate (widget, &allocation);
2781 gtk_widget_queue_draw (widget);
2783 if ((default_size_changed || hints_changed) && (width != new_width || height != new_height))
2785 /* We could be here for two reasons
2786 * 1) We coincidentally got a resize while handling
2788 * 2) Our computation of default_size_changed was completely
2789 * screwed up, probably because one of our children
2790 * is changed requisition during size allocation).
2792 * For 1), we could just go ahead and ask for the
2793 * new size right now, but doing that for 2)
2794 * might well be fighting the user (and can even
2795 * trigger a loop). Since we really don't want to
2796 * do that, we requeue a resize in hopes that
2797 * by the time it gets handled, the child has seen
2798 * the light and is willing to go along with the
2799 * new size. (this happens for the zvt widget, since
2800 * the size_allocate() above will have stored the
2801 * requisition corresponding to the new size in the
2804 * This doesn't buy us anything for 1), but it shouldn't
2805 * hurt us too badly, since it is what would have
2806 * happened if we had gotten the configure event before
2807 * the new size had been set.
2810 if (need_reposition)
2813 gdk_window_move (window->frame, x - window->frame_left, y - window->frame_top);
2815 gdk_window_move (GTK_WIDGET (window)->window, x, y);
2818 /* we have to preserve the values and flags that are used
2819 * for computation of default_size_changed and hints_changed
2821 info->last = saved_last_info;
2823 gtk_widget_queue_resize (widget);
2829 /* Now set hints if necessary
2832 gdk_window_set_geometry_hints (widget->window,
2836 if ((default_size_changed || hints_changed) &&
2837 (width != new_width || height != new_height))
2839 /* given that (width != new_width || height != new_height), we are in one
2840 * of the following situations:
2842 * default_size_changed
2843 * our requisition has changed and we need a different window size,
2844 * so we request it from the window manager.
2846 * !default_size_changed
2847 * the window manager wouldn't assign us the size we requested, in this
2848 * case we don't try to request a new size with every resize.
2850 * !default_size_changed && hints_changed
2851 * the window manager rejects our size, but we have just changed the
2852 * window manager hints, so there's a certain chance our request will
2853 * be honoured this time, so we try again.
2856 /* request a new window size */
2857 if (need_reposition)
2861 gdk_window_move_resize (window->frame,
2862 x - window->frame_left, y - window->frame_top,
2863 new_width + window->frame_left + window->frame_right,
2864 new_height + window->frame_top + window->frame_bottom);
2865 gdk_window_resize (GTK_WIDGET (window)->window, new_width, new_height);
2868 gdk_window_move_resize (GTK_WIDGET (window)->window, x, y, new_width, new_height);
2873 gdk_window_resize (window->frame,
2874 new_width + window->frame_left + window->frame_right,
2875 new_height + window->frame_top + window->frame_bottom);
2876 gdk_window_resize (GTK_WIDGET (window)->window, new_width, new_height);
2878 window->resize_count += 1;
2880 /* we are now awaiting the new configure event in response to our
2881 * resizing request. the configure event will cause a new resize
2882 * with ->handling_resize=TRUE.
2883 * until then, we want to
2884 * - discard expose events
2885 * - coalesce resizes for our children
2886 * - defer any window resizes until the configure event arrived
2887 * to achive this, we queue a resize for the window, but remove its
2888 * resizing handler, so resizing will not be handled from the next
2889 * idle handler but when the configure event arrives.
2891 * FIXME: we should also dequeue the pending redraws here, since
2892 * we handle those ourselves in ->handling_resize==TRUE.
2894 gtk_widget_queue_resize (GTK_WIDGET (container));
2895 if (container->resize_mode == GTK_RESIZE_QUEUE)
2896 gtk_container_dequeue_resize_handler (container);
2900 if (need_reposition)
2903 gdk_window_move (window->frame, x - window->frame_left, y - window->frame_top);
2905 gdk_window_move (widget->window, x, y);
2908 if (container->resize_widgets)
2909 gtk_container_resize_children (GTK_CONTAINER (window));
2913 /* Compare two sets of Geometry hints for equality.
2916 gtk_window_compare_hints (GdkGeometry *geometry_a,
2918 GdkGeometry *geometry_b,
2921 if (flags_a != flags_b)
2924 if ((flags_a & GDK_HINT_MIN_SIZE) &&
2925 (geometry_a->min_width != geometry_b->min_width ||
2926 geometry_a->min_height != geometry_b->min_height))
2929 if ((flags_a & GDK_HINT_MAX_SIZE) &&
2930 (geometry_a->max_width != geometry_b->max_width ||
2931 geometry_a->max_height != geometry_b->max_height))
2934 if ((flags_a & GDK_HINT_BASE_SIZE) &&
2935 (geometry_a->base_width != geometry_b->base_width ||
2936 geometry_a->base_height != geometry_b->base_height))
2939 if ((flags_a & GDK_HINT_ASPECT) &&
2940 (geometry_a->min_aspect != geometry_b->min_aspect ||
2941 geometry_a->max_aspect != geometry_b->max_aspect))
2944 if ((flags_a & GDK_HINT_RESIZE_INC) &&
2945 (geometry_a->width_inc != geometry_b->width_inc ||
2946 geometry_a->height_inc != geometry_b->height_inc))
2949 if ((flags_a & GDK_HINT_WIN_GRAVITY) &&
2950 geometry_a->win_gravity != geometry_b->win_gravity)
2956 /* Compute the default_size for a window. The result will
2957 * be stored in *width and *height. The default size is
2958 * the size the window should have when initially mapped.
2959 * This routine does not attempt to constrain the size
2960 * to obey the geometry hints - that must be done elsewhere.
2963 gtk_window_compute_default_size (GtkWindow *window,
2967 GtkRequisition requisition;
2968 GtkWindowGeometryInfo *info;
2970 gtk_widget_get_child_requisition (GTK_WIDGET (window), &requisition);
2971 *width = requisition.width;
2972 *height = requisition.height;
2974 info = gtk_window_get_geometry_info (window, FALSE);
2976 if (*width == 0 && *height == 0)
2985 *width = info->width > 0 ? info->width : *width;
2986 *height = info->height > 0 ? info->height : *height;
2991 _gtk_window_constrain_size (GtkWindow *window,
2997 GtkWindowGeometryInfo *info;
2999 g_return_if_fail (GTK_IS_WINDOW (window));
3001 info = window->geometry_info;
3004 GdkWindowHints flags = info->last.flags;
3005 GdkGeometry *geometry = &info->last.geometry;
3007 gtk_window_constrain_size (window,
3018 gtk_window_constrain_size (GtkWindow *window,
3019 GdkGeometry *geometry,
3026 gdk_window_constrain_size (geometry, flags, width, height,
3027 new_width, new_height);
3030 /* Compute the set of geometry hints and flags for a window
3031 * based on the application set geometry, and requisiition
3032 * of the window. gtk_widget_size_request() must have been
3036 gtk_window_compute_hints (GtkWindow *window,
3037 GdkGeometry *new_geometry,
3041 GtkWidgetAuxInfo *aux_info;
3043 gint extra_width = 0;
3044 gint extra_height = 0;
3045 GtkWindowGeometryInfo *geometry_info;
3046 GtkRequisition requisition;
3048 g_return_if_fail (GTK_IS_WINDOW (window));
3050 widget = GTK_WIDGET (window);
3052 gtk_widget_get_child_requisition (widget, &requisition);
3053 geometry_info = gtk_window_get_geometry_info (GTK_WINDOW (widget), FALSE);
3055 g_return_if_fail (geometry_info != NULL);
3057 *new_flags = geometry_info->mask;
3058 *new_geometry = geometry_info->geometry;
3060 if (geometry_info->widget)
3062 extra_width = widget->requisition.width - geometry_info->widget->requisition.width;
3063 extra_height = widget->requisition.height - geometry_info->widget->requisition.height;
3069 aux_info = _gtk_widget_get_aux_info (widget, FALSE);
3070 if (aux_info && aux_info->x_set && aux_info->y_set)
3074 *new_flags |= GDK_HINT_POS;
3077 if (*new_flags & GDK_HINT_BASE_SIZE)
3079 new_geometry->base_width += extra_width;
3080 new_geometry->base_height += extra_height;
3082 else if (!(*new_flags & GDK_HINT_MIN_SIZE) &&
3083 (*new_flags & GDK_HINT_RESIZE_INC) &&
3084 ((extra_width != 0) || (extra_height != 0)))
3086 *new_flags |= GDK_HINT_BASE_SIZE;
3088 new_geometry->base_width = extra_width;
3089 new_geometry->base_height = extra_height;
3092 if (*new_flags & GDK_HINT_MIN_SIZE)
3094 if (new_geometry->min_width < 0)
3095 new_geometry->min_width = requisition.width;
3097 new_geometry->min_width += extra_width;
3099 if (new_geometry->min_height < 0)
3100 new_geometry->min_width = requisition.height;
3102 new_geometry->min_height += extra_height;
3104 else if (!window->allow_shrink)
3106 *new_flags |= GDK_HINT_MIN_SIZE;
3108 new_geometry->min_width = requisition.width;
3109 new_geometry->min_height = requisition.height;
3112 if (*new_flags & GDK_HINT_MAX_SIZE)
3114 if (new_geometry->max_width < 0)
3115 new_geometry->max_width = requisition.width;
3117 new_geometry->max_width += extra_width;
3119 if (new_geometry->max_height < 0)
3120 new_geometry->max_width = requisition.height;
3122 new_geometry->max_height += extra_height;
3124 else if (!window->allow_grow)
3126 *new_flags |= GDK_HINT_MAX_SIZE;
3128 new_geometry->max_width = requisition.width;
3129 new_geometry->max_height = requisition.height;
3132 *new_flags |= GDK_HINT_WIN_GRAVITY;
3133 new_geometry->win_gravity = window->gravity;
3136 /* Compute a new position for the window based on a new
3137 * size. *x and *y will be set to the new coordinates. Returns
3138 * TRUE if the window needs to be moved (and thus x and y got
3142 gtk_window_compute_reposition (GtkWindow *window,
3148 GtkWidget *widget = GTK_WIDGET (window);
3149 GtkWindowPosition pos;
3150 GtkWidget *parent_widget;
3151 gboolean needs_move = FALSE;
3153 parent_widget = (GtkWidget*) window->transient_parent;
3155 pos = window->position;
3156 if (pos == GTK_WIN_POS_CENTER_ON_PARENT &&
3157 (parent_widget == NULL ||
3158 !GTK_WIDGET_MAPPED (parent_widget)))
3159 pos = GTK_WIN_POS_NONE;
3163 case GTK_WIN_POS_CENTER:
3164 case GTK_WIN_POS_CENTER_ALWAYS:
3165 if (window->use_uposition)
3167 gint screen_width = gdk_screen_width ();
3168 gint screen_height = gdk_screen_height ();
3170 *x = (screen_width - new_width) / 2;
3171 *y = (screen_height - new_height) / 2;
3176 case GTK_WIN_POS_CENTER_ON_PARENT:
3177 if (window->use_uposition)
3180 gdk_window_get_origin (parent_widget->window,
3183 *x = ox + (parent_widget->allocation.width - new_width) / 2;
3184 *y = oy + (parent_widget->allocation.height - new_height) / 2;
3189 case GTK_WIN_POS_MOUSE:
3190 if (window->use_uposition)
3192 gint screen_width = gdk_screen_width ();
3193 gint screen_height = gdk_screen_height ();
3195 gdk_window_get_pointer (NULL, x, y, NULL);
3196 *x -= new_width / 2;
3197 *y -= new_height / 2;
3198 *x = CLAMP (*x, 0, screen_width - new_width);
3199 *y = CLAMP (*y, 0, screen_height - new_height);
3204 if (window->use_uposition)
3206 GtkWidgetAuxInfo *aux_info = _gtk_widget_get_aux_info (widget, FALSE);
3208 if (aux_info && aux_info->x_set && aux_info->y_set)
3220 GtkWidgetAuxInfo *aux_info = _gtk_widget_get_aux_info (widget, TRUE);
3222 /* we handle necessary window positioning by hand here,
3223 * so we can coalesce the window movement with possible
3224 * resizes to get only one configure event.
3226 aux_info->x_set = TRUE;
3227 aux_info->y_set = TRUE;
3230 window->use_uposition = FALSE;
3236 /***********************
3237 * Redrawing functions *
3238 ***********************/
3241 gtk_window_paint (GtkWidget *widget,
3244 gtk_paint_flat_box (widget->style, widget->window, GTK_STATE_NORMAL,
3245 GTK_SHADOW_NONE, area, widget, "base", 0, 0, -1, -1);
3249 gtk_window_expose (GtkWidget *widget,
3250 GdkEventExpose *event)
3252 g_return_val_if_fail (widget != NULL, FALSE);
3253 g_return_val_if_fail (GTK_IS_WINDOW (widget), FALSE);
3254 g_return_val_if_fail (event != NULL, FALSE);
3256 if (!GTK_WIDGET_APP_PAINTABLE (widget))
3257 gtk_window_paint (widget, &event->area);
3259 if (GTK_WIDGET_CLASS (parent_class)->expose_event)
3260 return GTK_WIDGET_CLASS (parent_class)->expose_event (widget, event);
3266 * gtk_window_set_has_frame:
3267 * @window: a #GtkWindow
3268 * @setting: a boolean
3270 * If this function is called on a window with setting of TRUE, before
3271 * it is realized or showed, it will have a "frame" window around
3272 * widget->window, accessible in window->frame. Using the signal
3273 * frame_event you can recieve all events targeted at the frame.
3275 * This function is used by the linux-fb port to implement managed
3276 * windows, but it could concievably be used by X-programs that
3277 * want to do their own window decorations.
3280 gtk_window_set_has_frame (GtkWindow *window,
3283 g_return_if_fail (window != NULL);
3284 g_return_if_fail (GTK_IS_WINDOW (window));
3285 g_return_if_fail (!GTK_WIDGET_REALIZED (window));
3287 window->has_frame = setting != FALSE;
3291 * gtk_window_get_has_frame:
3292 * @window: a #GtkWindow
3294 * Returns whether the window has a frame window exterior to
3295 * widget->window. See gtk_window_set_has_frame ().
3297 * Return value: %TRUE if a frame has been added to the window
3298 * via gtk_widow_has_frame
3301 gtk_window_get_has_frame (GtkWindow *window)
3303 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
3305 return window->has_frame;
3309 * gtk_window_set_frame_dimensions:
3310 * @window: a #GtkWindow that has a frame
3311 * @left: The width of the left border
3312 * @top: The height of the top border
3313 * @right: The width of the right border
3314 * @bottom: The height of the bottom border
3316 * For windows with frames (see #gtk_window_set_has_frame) this function
3317 * can be used to change the size of the frame border.
3320 gtk_window_set_frame_dimensions (GtkWindow *window,
3326 GtkWidget *widget = GTK_WIDGET (window);
3328 g_return_if_fail (window != NULL);
3329 g_return_if_fail (GTK_IS_WINDOW (window));
3331 if (window->frame_left == left &&
3332 window->frame_top == top &&
3333 window->frame_right == right &&
3334 window->frame_bottom == bottom)
3337 window->frame_left = left;
3338 window->frame_top = top;
3339 window->frame_right = right;
3340 window->frame_bottom = bottom;
3342 if (GTK_WIDGET_REALIZED (widget) && window->frame)
3344 gint width = widget->allocation.width + left + right;
3345 gint height = widget->allocation.height + top + bottom;
3346 gdk_window_resize (window->frame, width, height);
3347 gtk_decorated_window_move_resize_window (window,
3349 widget->allocation.width,
3350 widget->allocation.height);
3355 * gtk_window_present:
3356 * @window: a #GtkWindow
3358 * Presents a window to the user. This may mean raising the window
3359 * in the stacking order, deiconifying it, moving it to the current
3360 * desktop, and/or giving it the keyboard focus, possibly dependent
3361 * on the user's platform, window manager, and preferences.
3363 * If @window is hidden, this function calls gtk_widget_show()
3366 * This function should be used when the user tries to open a window
3367 * that's already open. Say for example the preferences dialog is
3368 * currently open, and the user chooses Preferences from the menu
3369 * a second time; use gtk_window_present() to move the already-open dialog
3370 * where the user can see it.
3374 gtk_window_present (GtkWindow *window)
3378 g_return_if_fail (GTK_IS_WINDOW (window));
3380 widget = GTK_WIDGET (window);
3382 if (GTK_WIDGET_VISIBLE (window))
3384 g_assert (widget->window != NULL);
3386 gdk_window_show (widget->window);
3388 /* note that gdk_window_focus() will also move the window to
3389 * the current desktop, for WM spec compliant window managers.
3391 gdk_window_focus (widget->window,
3392 gtk_get_current_event_time ());
3396 gtk_widget_show (widget);
3401 * gtk_window_iconify:
3402 * @window: a #GtkWindow
3404 * Asks to iconify @window. Note that you shouldn't assume the window
3405 * is definitely iconified afterward, because other entities (e.g. the
3406 * user or window manager) could deiconify it again, or there may not
3407 * be a window manager in which case iconification isn't possible,
3408 * etc. But normally the window will end up iconified. Just don't write
3409 * code that crashes if not.
3411 * It's permitted to call this function before showing a window,
3412 * in which case the window will be iconified before it ever appears
3415 * You can track iconification via the "window_state_event" signal
3420 gtk_window_iconify (GtkWindow *window)
3423 GdkWindow *toplevel;
3425 g_return_if_fail (GTK_IS_WINDOW (window));
3427 widget = GTK_WIDGET (window);
3429 window->iconify_initially = TRUE;
3432 toplevel = window->frame;
3434 toplevel = widget->window;
3436 if (toplevel != NULL)
3437 gdk_window_iconify (toplevel);
3441 * gtk_window_deiconify:
3442 * @window: a #GtkWindow
3444 * Asks to deiconify @window. Note that you shouldn't assume the
3445 * window is definitely deiconified afterward, because other entities
3446 * (e.g. the user or window manager) could iconify it again before
3447 * your code which assumes deiconification gets to run.
3449 * You can track iconification via the "window_state_event" signal
3453 gtk_window_deiconify (GtkWindow *window)
3456 GdkWindow *toplevel;
3458 g_return_if_fail (GTK_IS_WINDOW (window));
3460 widget = GTK_WIDGET (window);
3462 window->iconify_initially = FALSE;
3465 toplevel = window->frame;
3467 toplevel = widget->window;
3469 if (toplevel != NULL)
3470 gdk_window_deiconify (toplevel);
3475 * @window: a #GtkWindow
3477 * Asks to stick @window, which means that it will appear on all user
3478 * desktops. Note that you shouldn't assume the window is definitely
3479 * stuck afterward, because other entities (e.g. the user or window
3480 * manager) could unstick it again, and some window managers do not
3481 * support sticking windows. But normally the window will end up
3482 * stuck. Just don't write code that crashes if not.
3484 * It's permitted to call this function before showing a window.
3486 * You can track stickiness via the "window_state_event" signal
3491 gtk_window_stick (GtkWindow *window)
3494 GdkWindow *toplevel;
3496 g_return_if_fail (GTK_IS_WINDOW (window));
3498 widget = GTK_WIDGET (window);
3500 window->stick_initially = TRUE;
3503 toplevel = window->frame;
3505 toplevel = widget->window;
3507 if (toplevel != NULL)
3508 gdk_window_stick (toplevel);
3512 * gtk_window_unstick:
3513 * @window: a #GtkWindow
3515 * Asks to unstick @window, which means that it will appear on only
3516 * one of the user's desktops. Note that you shouldn't assume the
3517 * window is definitely unstuck afterward, because other entities
3518 * (e.g. the user or window manager) could stick it again. But
3519 * normally the window will end up stuck. Just don't write code that
3522 * You can track stickiness via the "window_state_event" signal
3527 gtk_window_unstick (GtkWindow *window)
3530 GdkWindow *toplevel;
3532 g_return_if_fail (GTK_IS_WINDOW (window));
3534 widget = GTK_WIDGET (window);
3536 window->stick_initially = FALSE;
3539 toplevel = window->frame;
3541 toplevel = widget->window;
3543 if (toplevel != NULL)
3544 gdk_window_unstick (toplevel);
3548 * gtk_window_maximize:
3549 * @window: a #GtkWindow
3551 * Asks to maximize @window, so that it becomes full-screen. Note that
3552 * you shouldn't assume the window is definitely maximized afterward,
3553 * because other entities (e.g. the user or window manager) could
3554 * unmaximize it again, and not all window managers support
3555 * maximization. But normally the window will end up maximized. Just
3556 * don't write code that crashes if not.
3558 * It's permitted to call this function before showing a window,
3559 * in which case the window will be maximized when it appears onscreen
3562 * You can track maximization via the "window_state_event" signal
3567 gtk_window_maximize (GtkWindow *window)
3570 GdkWindow *toplevel;
3572 g_return_if_fail (GTK_IS_WINDOW (window));
3574 widget = GTK_WIDGET (window);
3576 window->maximize_initially = TRUE;
3579 toplevel = window->frame;
3581 toplevel = widget->window;
3583 if (toplevel != NULL)
3584 gdk_window_maximize (toplevel);
3588 * gtk_window_unmaximize:
3589 * @window: a #GtkWindow
3591 * Asks to unmaximize @window. Note that you shouldn't assume the
3592 * window is definitely unmaximized afterward, because other entities
3593 * (e.g. the user or window manager) could maximize it again, and not
3594 * all window managers honor requests to unmaximize. But normally the
3595 * window will end up unmaximized. Just don't write code that crashes
3598 * You can track maximization via the "window_state_event" signal
3603 gtk_window_unmaximize (GtkWindow *window)
3606 GdkWindow *toplevel;
3608 g_return_if_fail (GTK_IS_WINDOW (window));
3610 widget = GTK_WIDGET (window);
3612 window->maximize_initially = FALSE;
3615 toplevel = window->frame;
3617 toplevel = widget->window;
3619 if (toplevel != NULL)
3620 gdk_window_unmaximize (toplevel);
3624 * gtk_window_set_resizeable:
3625 * @window: a #GtkWindow
3626 * @resizeable: %TRUE if the user can resize this window
3628 * Sets whether the user can resize a window. Windows are user resizeable
3632 gtk_window_set_resizeable (GtkWindow *window,
3633 gboolean resizeable)
3635 g_return_if_fail (GTK_IS_WINDOW (window));
3637 gtk_window_set_policy (window, FALSE, resizeable, FALSE);
3641 * gtk_window_get_resizeable:
3642 * @window: a #GtkWindow
3644 * Gets the value set by gtk_window_set_resizeable().
3646 * Return value: %TRUE if the user can resize the window
3649 gtk_window_get_resizeable (GtkWindow *window)
3651 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
3653 /* allow_grow is most likely to indicate the semantic concept we
3654 * mean by "resizeable" (and will be a reliable indicator if
3655 * set_policy() hasn't been called)
3657 return window->allow_grow;
3661 * gtk_window_set_gravity:
3662 * @window: a #GtkWindow
3663 * @gravity: window gravity
3665 * Window gravity defines the "reference point" to be used when
3666 * positioning or resizing a window. Calls to
3667 * gtk_widget_set_uposition() will position a different point on the
3668 * window depending on the window gravity. When the window changes size
3669 * the reference point determined by the window's gravity will stay in
3672 * See #GdkGravity for full details. To briefly summarize,
3673 * #GDK_GRAVITY_NORTH_WEST means that the reference point is the
3674 * northwest (top left) corner of the window
3675 * frame. #GDK_GRAVITY_SOUTH_EAST would be the bottom right corner of
3676 * the frame, and so on. If you want to position the window contents,
3677 * rather than the window manager's frame, #GDK_GRAVITY_STATIC moves
3678 * the reference point to the northwest corner of the #GtkWindow
3681 * The default window gravity is #GDK_GRAVITY_NORTH_WEST.
3685 gtk_window_set_gravity (GtkWindow *window,
3688 g_return_if_fail (GTK_IS_WINDOW (window));
3690 if (gravity != window->gravity)
3692 window->gravity = gravity;
3694 /* gtk_window_move_resize() will adapt gravity
3696 gtk_widget_queue_resize (GTK_WIDGET (window));
3701 * gtk_window_get_gravity:
3702 * @window: a #GtkWindow
3704 * Gets the value set by gtk_window_set_gravity().
3706 * Return value: window gravity
3709 gtk_window_get_gravity (GtkWindow *window)
3711 g_return_val_if_fail (GTK_IS_WINDOW (window), 0);
3713 return window->gravity;
3717 * gtk_window_begin_resize_drag:
3718 * @window: a #GtkWindow
3719 * @button: mouse button that initiated the drag
3720 * @edge: position of the resize control
3721 * @root_x: X position where the user clicked to initiate the drag, in root window coordinates
3722 * @root_y: Y position where the user clicked to initiate the drag
3723 * @timestamp: timestamp from the click event that initiated the drag
3725 * Starts resizing a window. This function is used if an application
3726 * has window resizing controls. When GDK can support it, the resize
3727 * will be done using the standard mechanism for the window manager or
3728 * windowing system. Otherwise, GDK will try to emulate window
3729 * resizing, potentially not all that well, depending on the windowing system.
3733 gtk_window_begin_resize_drag (GtkWindow *window,
3741 GdkWindow *toplevel;
3743 g_return_if_fail (GTK_IS_WINDOW (window));
3744 g_return_if_fail (GTK_WIDGET_VISIBLE (window));
3746 widget = GTK_WIDGET (window);
3749 toplevel = window->frame;
3751 toplevel = widget->window;
3753 gdk_window_begin_resize_drag (toplevel,
3760 * gtk_window_get_frame_dimensions:
3761 * @window: a #GtkWindow
3762 * @left: location to store the width of the frame at the left, or %NULL
3763 * @top: location to store the height of the frame at the top, or %NULL
3764 * @right: location to store the width of the frame at the returns, or %NULL
3765 * @bottom: location to store the height of the frame at the bottom, or %NULL
3767 * Retrieves the dimensions of the frame window for this toplevel.
3768 * See gtk_window_set_has_frame(), gtk_window_set_frame_dimensions().
3771 gtk_window_get_frame_dimensions (GtkWindow *window,
3777 g_return_if_fail (GTK_IS_WINDOW (window));
3780 *left = window->frame_left;
3782 *top = window->frame_top;
3784 *top = window->frame_right;
3786 *top = window->frame_bottom;
3790 * gtk_window_begin_move_drag:
3791 * @window: a #GtkWindow
3792 * @button: mouse button that initiated the drag
3793 * @root_x: X position where the user clicked to initiate the drag, in root window coordinates
3794 * @root_y: Y position where the user clicked to initiate the drag
3795 * @timestamp: timestamp from the click event that initiated the drag
3797 * Starts moving a window. This function is used if an application
3798 * has window movement grips. When GDK can support it, the window movement
3799 * will be done using the standard mechanism for the window manager or
3800 * windowing system. Otherwise, GDK will try to emulate window
3801 * movement, potentially not all that well, depending on the windowing system.
3805 gtk_window_begin_move_drag (GtkWindow *window,
3812 GdkWindow *toplevel;
3814 g_return_if_fail (GTK_IS_WINDOW (window));
3815 g_return_if_fail (GTK_WIDGET_VISIBLE (window));
3817 widget = GTK_WIDGET (window);
3820 toplevel = window->frame;
3822 toplevel = widget->window;
3824 gdk_window_begin_move_drag (toplevel,
3832 gtk_window_group_class_init (GtkWindowGroupClass *klass)
3837 gtk_window_group_get_type (void)
3839 static GtkType window_group_type = 0;
3841 if (!window_group_type)
3843 static const GTypeInfo window_group_info =
3845 sizeof (GtkWindowGroupClass),
3846 NULL, /* base_init */
3847 NULL, /* base_finalize */
3848 (GClassInitFunc) gtk_window_group_class_init,
3849 NULL, /* class_finalize */
3850 NULL, /* class_data */
3851 sizeof (GtkWindowGroup),
3852 16, /* n_preallocs */
3853 (GInstanceInitFunc) NULL,
3856 window_group_type = g_type_register_static (G_TYPE_OBJECT, "GtkWindowGroup", &window_group_info, 0);
3859 return window_group_type;
3863 * gtk_window_group_new:
3865 * Create a new #GtkWindowGroup object. Grabs added with
3866 * gtk_window_grab_add() only affect windows within the
3867 * same #GtkWindowGroup
3872 gtk_window_group_new (void)
3874 return g_object_new (GTK_TYPE_WINDOW_GROUP, NULL);
3878 window_group_cleanup_grabs (GtkWindowGroup *group,
3882 GSList *to_remove = NULL;
3884 tmp_list = group->grabs;
3887 if (gtk_widget_get_toplevel (tmp_list->data) == (GtkWidget*) window)
3888 to_remove = g_slist_prepend (to_remove, g_object_ref (tmp_list->data));
3889 tmp_list = tmp_list->next;
3894 gtk_grab_remove (to_remove->data);
3895 g_object_unref (to_remove->data);
3896 to_remove = g_slist_delete_link (to_remove, to_remove);
3901 * gtk_window_group_add_widget:
3902 * @window_group: a #GtkWindowGroup
3903 * @window: the #GtkWindow to add
3905 * Add a window to a #GtkWindowGroup.
3908 gtk_window_group_add_window (GtkWindowGroup *window_group,
3911 g_return_if_fail (GTK_IS_WINDOW_GROUP (window_group));
3912 g_return_if_fail (GTK_IS_WINDOW (window));
3914 if (window->group != window_group)
3916 g_object_ref (window);
3917 g_object_ref (window_group);
3920 gtk_window_group_remove_window (window->group, window);
3922 window_group_cleanup_grabs (_gtk_window_get_group (NULL), window);
3924 window->group = window_group;
3926 g_object_unref (window);
3931 * gtk_window_group_remove_window:
3932 * @window_group: a #GtkWindowGroup
3933 * @window: the #GtkWindow to remove
3935 * Removes a window from a #GtkWindowGroup.
3938 gtk_window_group_remove_window (GtkWindowGroup *window_group,
3941 g_return_if_fail (GTK_IS_WINDOW_GROUP (window_group));
3942 g_return_if_fail (GTK_IS_WIDGET (window));
3943 g_return_if_fail (window->group == window_group);
3945 g_object_ref (window);
3947 window_group_cleanup_grabs (window_group, window);
3948 window->group = NULL;
3950 g_object_unref (G_OBJECT (window_group));
3951 g_object_unref (window);
3954 /* Return the group for the window or the default group
3957 _gtk_window_get_group (GtkWindow *window)
3959 if (window && window->group)
3960 return window->group;
3963 static GtkWindowGroup *default_group = NULL;
3966 default_group = gtk_window_group_new ();
3968 return default_group;