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/.
31 #include "gdk/gdkkeysyms.h"
34 #include "gtkprivate.h"
36 #include "gtkwindow.h"
37 #include "gtkwindow-decorate.h"
38 #include "gtkbindings.h"
39 #include "gtkkeyhash.h"
41 #include "gtkmnemonichash.h"
42 #include "gtkiconfactory.h"
43 #include "gtkicontheme.h"
45 #include "gtkmarshalers.h"
48 #ifdef GDK_WINDOWING_X11
78 PROP_DESTROY_WITH_PARENT,
83 PROP_SKIP_TASKBAR_HINT,
90 /* Readonly properties */
92 PROP_HAS_TOPLEVEL_FOCUS,
100 GdkPixmap *icon_pixmap;
101 GdkPixmap *icon_mask;
104 guint using_default_icon : 1;
105 guint using_parent_icon : 1;
106 guint using_themed_icon : 1;
110 GdkGeometry geometry; /* Last set of geometry hints we set */
111 GdkWindowHints flags;
112 GdkRectangle configure_request;
113 } GtkWindowLastGeometryInfo;
115 struct _GtkWindowGeometryInfo
117 /* Properties that the app has set on the window
119 GdkGeometry geometry; /* Geometry hints */
121 GtkWidget *widget; /* subwidget to which hints apply */
122 /* from last gtk_window_resize () - if > 0, indicates that
123 * we should resize to this size.
128 /* From last gtk_window_move () prior to mapping -
129 * only used if initial_pos_set
134 /* Default size - used only the FIRST time we map a window,
139 /* whether to use initial_x, initial_y */
140 guint initial_pos_set : 1;
141 /* CENTER_ALWAYS or other position constraint changed since
142 * we sent the last configure request.
144 guint position_constraints_changed : 1;
146 /* if true, default_width, height come from gtk_window_parse_geometry,
147 * and thus should be multiplied by the increments and affect the
148 * geometry widget only
150 guint default_is_geometry : 1;
152 GtkWindowLastGeometryInfo last;
155 #define GTK_WINDOW_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GTK_TYPE_WINDOW, GtkWindowPrivate))
157 typedef struct _GtkWindowPrivate GtkWindowPrivate;
159 struct _GtkWindowPrivate
161 GtkMnemonicHash *mnemonic_hash;
163 guint above_initially : 1;
164 guint below_initially : 1;
165 guint fullscreen_initially : 1;
166 guint skips_taskbar : 1;
167 guint skips_pager : 1;
168 guint accept_focus : 1;
169 guint focus_on_map : 1;
172 static void gtk_window_class_init (GtkWindowClass *klass);
173 static void gtk_window_init (GtkWindow *window);
174 static void gtk_window_dispose (GObject *object);
175 static void gtk_window_destroy (GtkObject *object);
176 static void gtk_window_finalize (GObject *object);
177 static void gtk_window_show (GtkWidget *widget);
178 static void gtk_window_hide (GtkWidget *widget);
179 static void gtk_window_map (GtkWidget *widget);
180 static void gtk_window_unmap (GtkWidget *widget);
181 static void gtk_window_realize (GtkWidget *widget);
182 static void gtk_window_unrealize (GtkWidget *widget);
183 static void gtk_window_size_request (GtkWidget *widget,
184 GtkRequisition *requisition);
185 static void gtk_window_size_allocate (GtkWidget *widget,
186 GtkAllocation *allocation);
187 static gint gtk_window_event (GtkWidget *widget,
189 static gboolean gtk_window_frame_event (GtkWindow *window,
191 static gint gtk_window_configure_event (GtkWidget *widget,
192 GdkEventConfigure *event);
193 static gint gtk_window_key_press_event (GtkWidget *widget,
195 static gint gtk_window_key_release_event (GtkWidget *widget,
197 static gint gtk_window_enter_notify_event (GtkWidget *widget,
198 GdkEventCrossing *event);
199 static gint gtk_window_leave_notify_event (GtkWidget *widget,
200 GdkEventCrossing *event);
201 static gint gtk_window_focus_in_event (GtkWidget *widget,
202 GdkEventFocus *event);
203 static gint gtk_window_focus_out_event (GtkWidget *widget,
204 GdkEventFocus *event);
205 static gint gtk_window_client_event (GtkWidget *widget,
206 GdkEventClient *event);
207 static void gtk_window_check_resize (GtkContainer *container);
208 static gint gtk_window_focus (GtkWidget *widget,
209 GtkDirectionType direction);
210 static void gtk_window_real_set_focus (GtkWindow *window,
213 static void gtk_window_real_activate_default (GtkWindow *window);
214 static void gtk_window_real_activate_focus (GtkWindow *window);
215 static void gtk_window_move_focus (GtkWindow *window,
216 GtkDirectionType dir);
217 static void gtk_window_keys_changed (GtkWindow *window);
218 static void gtk_window_read_rcfiles (GtkWidget *widget,
219 GdkEventClient *event);
220 static void gtk_window_paint (GtkWidget *widget,
222 static gint gtk_window_expose (GtkWidget *widget,
223 GdkEventExpose *event);
224 static void gtk_window_unset_transient_for (GtkWindow *window);
225 static void gtk_window_transient_parent_realized (GtkWidget *parent,
227 static void gtk_window_transient_parent_unrealized (GtkWidget *parent,
230 static GdkScreen *gtk_window_check_screen (GtkWindow *window);
232 static GtkWindowGeometryInfo* gtk_window_get_geometry_info (GtkWindow *window,
235 static void gtk_window_move_resize (GtkWindow *window);
236 static gboolean gtk_window_compare_hints (GdkGeometry *geometry_a,
238 GdkGeometry *geometry_b,
240 static void gtk_window_constrain_size (GtkWindow *window,
241 GdkGeometry *geometry,
247 static void gtk_window_constrain_position (GtkWindow *window,
252 static void gtk_window_compute_hints (GtkWindow *window,
253 GdkGeometry *new_geometry,
255 static void gtk_window_compute_configure_request (GtkWindow *window,
256 GdkRectangle *request,
257 GdkGeometry *geometry,
260 static void gtk_window_set_default_size_internal (GtkWindow *window,
261 gboolean change_width,
263 gboolean change_height,
265 gboolean is_geometry);
267 static void update_themed_icon (GtkIconTheme *theme,
269 static GList *icon_list_from_theme (GtkWidget *widget,
271 static void gtk_window_realize_icon (GtkWindow *window);
272 static void gtk_window_unrealize_icon (GtkWindow *window);
274 static void gtk_window_notify_keys_changed (GtkWindow *window);
275 static GtkKeyHash *gtk_window_get_key_hash (GtkWindow *window);
276 static void gtk_window_free_key_hash (GtkWindow *window);
278 static GSList *toplevel_list = NULL;
279 static GtkBinClass *parent_class = NULL;
280 static guint window_signals[LAST_SIGNAL] = { 0 };
281 static GList *default_icon_list = NULL;
282 static gchar *default_icon_name = NULL;
283 static guint default_icon_serial = 0;
284 static gboolean disable_startup_notification = FALSE;
285 static gboolean sent_startup_notification = FALSE;
287 static void gtk_window_set_property (GObject *object,
291 static void gtk_window_get_property (GObject *object,
298 gtk_window_get_type (void)
300 static GType window_type = 0;
304 static const GTypeInfo window_info =
306 sizeof (GtkWindowClass),
307 NULL, /* base_init */
308 NULL, /* base_finalize */
309 (GClassInitFunc) gtk_window_class_init,
310 NULL, /* class_finalize */
311 NULL, /* class_data */
314 (GInstanceInitFunc) gtk_window_init,
317 window_type = g_type_register_static (GTK_TYPE_BIN, "GtkWindow",
325 add_tab_bindings (GtkBindingSet *binding_set,
326 GdkModifierType modifiers,
327 GtkDirectionType direction)
329 gtk_binding_entry_add_signal (binding_set, GDK_Tab, modifiers,
331 GTK_TYPE_DIRECTION_TYPE, direction);
332 gtk_binding_entry_add_signal (binding_set, GDK_KP_Tab, modifiers,
334 GTK_TYPE_DIRECTION_TYPE, direction);
338 add_arrow_bindings (GtkBindingSet *binding_set,
340 GtkDirectionType direction)
342 guint keypad_keysym = keysym - GDK_Left + GDK_KP_Left;
344 gtk_binding_entry_add_signal (binding_set, keysym, 0,
346 GTK_TYPE_DIRECTION_TYPE, direction);
347 gtk_binding_entry_add_signal (binding_set, keysym, GDK_CONTROL_MASK,
349 GTK_TYPE_DIRECTION_TYPE, direction);
350 gtk_binding_entry_add_signal (binding_set, keypad_keysym, 0,
352 GTK_TYPE_DIRECTION_TYPE, direction);
353 gtk_binding_entry_add_signal (binding_set, keypad_keysym, GDK_CONTROL_MASK,
355 GTK_TYPE_DIRECTION_TYPE, direction);
360 gtk_window_class_init (GtkWindowClass *klass)
362 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
363 GtkObjectClass *object_class;
364 GtkWidgetClass *widget_class;
365 GtkContainerClass *container_class;
366 GtkBindingSet *binding_set;
368 object_class = (GtkObjectClass*) klass;
369 widget_class = (GtkWidgetClass*) klass;
370 container_class = (GtkContainerClass*) klass;
372 parent_class = g_type_class_peek_parent (klass);
374 gobject_class->dispose = gtk_window_dispose;
375 gobject_class->finalize = gtk_window_finalize;
377 gobject_class->set_property = gtk_window_set_property;
378 gobject_class->get_property = gtk_window_get_property;
380 object_class->destroy = gtk_window_destroy;
382 widget_class->show = gtk_window_show;
383 widget_class->hide = gtk_window_hide;
384 widget_class->map = gtk_window_map;
385 widget_class->unmap = gtk_window_unmap;
386 widget_class->realize = gtk_window_realize;
387 widget_class->unrealize = gtk_window_unrealize;
388 widget_class->size_request = gtk_window_size_request;
389 widget_class->size_allocate = gtk_window_size_allocate;
390 widget_class->configure_event = gtk_window_configure_event;
391 widget_class->key_press_event = gtk_window_key_press_event;
392 widget_class->key_release_event = gtk_window_key_release_event;
393 widget_class->enter_notify_event = gtk_window_enter_notify_event;
394 widget_class->leave_notify_event = gtk_window_leave_notify_event;
395 widget_class->focus_in_event = gtk_window_focus_in_event;
396 widget_class->focus_out_event = gtk_window_focus_out_event;
397 widget_class->client_event = gtk_window_client_event;
398 widget_class->focus = gtk_window_focus;
400 widget_class->expose_event = gtk_window_expose;
402 container_class->check_resize = gtk_window_check_resize;
404 klass->set_focus = gtk_window_real_set_focus;
405 klass->frame_event = gtk_window_frame_event;
407 klass->activate_default = gtk_window_real_activate_default;
408 klass->activate_focus = gtk_window_real_activate_focus;
409 klass->move_focus = gtk_window_move_focus;
410 klass->keys_changed = gtk_window_keys_changed;
412 g_type_class_add_private (gobject_class, sizeof (GtkWindowPrivate));
415 g_object_class_install_property (gobject_class,
417 g_param_spec_enum ("type",
419 P_("The type of the window"),
420 GTK_TYPE_WINDOW_TYPE,
422 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
424 g_object_class_install_property (gobject_class,
426 g_param_spec_string ("title",
428 P_("The title of the window"),
432 g_object_class_install_property (gobject_class,
434 g_param_spec_string ("role",
436 P_("Unique identifier for the window to be used when restoring a session"),
440 g_object_class_install_property (gobject_class,
442 g_param_spec_boolean ("allow-shrink",
444 /* xgettext:no-c-format */
445 P_("If TRUE, the window has no mimimum size. Setting this to TRUE is 99% of the time a bad idea"),
449 g_object_class_install_property (gobject_class,
451 g_param_spec_boolean ("allow-grow",
453 P_("If TRUE, users can expand the window beyond its minimum size"),
457 g_object_class_install_property (gobject_class,
459 g_param_spec_boolean ("resizable",
461 P_("If TRUE, users can resize the window"),
465 g_object_class_install_property (gobject_class,
467 g_param_spec_boolean ("modal",
469 P_("If TRUE, the window is modal (other windows are not usable while this one is up)"),
473 g_object_class_install_property (gobject_class,
475 g_param_spec_enum ("window-position",
476 P_("Window Position"),
477 P_("The initial position of the window"),
478 GTK_TYPE_WINDOW_POSITION,
482 g_object_class_install_property (gobject_class,
484 g_param_spec_int ("default-width",
486 P_("The default width of the window, used when initially showing the window"),
492 g_object_class_install_property (gobject_class,
494 g_param_spec_int ("default-height",
495 P_("Default Height"),
496 P_("The default height of the window, used when initially showing the window"),
502 g_object_class_install_property (gobject_class,
503 PROP_DESTROY_WITH_PARENT,
504 g_param_spec_boolean ("destroy-with-parent",
505 P_("Destroy with Parent"),
506 P_("If this window should be destroyed when the parent is destroyed"),
510 g_object_class_install_property (gobject_class,
512 g_param_spec_object ("icon",
514 P_("Icon for this window"),
519 * GtkWindow:icon-name:
521 * The :icon-name property specifies the name of the themed icon to
522 * use as the window icon. See #GtkIconTheme for more details.
526 g_object_class_install_property (gobject_class,
528 g_param_spec_string ("icon-name",
530 P_("Name of the themed icon for this window"),
534 g_object_class_install_property (gobject_class,
536 g_param_spec_object ("screen",
538 P_("The screen where this window will be displayed"),
542 g_object_class_install_property (gobject_class,
544 g_param_spec_boolean ("is-active",
546 P_("Whether the toplevel is the current active window"),
550 g_object_class_install_property (gobject_class,
551 PROP_HAS_TOPLEVEL_FOCUS,
552 g_param_spec_boolean ("has-toplevel-focus",
553 P_("Focus in Toplevel"),
554 P_("Whether the input focus is within this GtkWindow"),
558 g_object_class_install_property (gobject_class,
560 g_param_spec_enum ("type-hint",
562 P_("Hint to help the desktop environment understand what kind of window this is and how to treat it."),
563 GDK_TYPE_WINDOW_TYPE_HINT,
564 GDK_WINDOW_TYPE_HINT_NORMAL,
567 g_object_class_install_property (gobject_class,
568 PROP_SKIP_TASKBAR_HINT,
569 g_param_spec_boolean ("skip-taskbar-hint",
571 P_("TRUE if the window should not be in the task bar."),
575 g_object_class_install_property (gobject_class,
576 PROP_SKIP_PAGER_HINT,
577 g_param_spec_boolean ("skip-pager-hint",
579 P_("TRUE if the window should not be in the pager."),
584 * GtkWindow:accept-focus-hint:
586 * Whether the window should receive the input focus.
590 g_object_class_install_property (gobject_class,
592 g_param_spec_boolean ("accept-focus",
594 P_("TRUE if the window should receive the input focus."),
599 * GtkWindow:focus-on-map-hint:
601 * Whether the window should receive the input focus when mapped.
605 g_object_class_install_property (gobject_class,
607 g_param_spec_boolean ("focus-on-map",
609 P_("TRUE if the window should receive the input focus when mapped."),
614 * GtkWindow:decorated:
616 * Whether the window should be decorated by the window manager.
620 g_object_class_install_property (gobject_class,
622 g_param_spec_boolean ("decorated",
624 P_("Whether the window should be decorated by the window manager"),
631 * The window gravity of the window. See gtk_window_move() and #GdkGravity for
632 * more details about window gravity.
636 g_object_class_install_property (gobject_class,
638 g_param_spec_enum ("gravity",
640 P_("The window gravity of the window"),
642 GDK_GRAVITY_NORTH_WEST,
645 window_signals[SET_FOCUS] =
646 g_signal_new ("set_focus",
647 G_TYPE_FROM_CLASS (gobject_class),
649 G_STRUCT_OFFSET (GtkWindowClass, set_focus),
651 _gtk_marshal_VOID__OBJECT,
655 window_signals[FRAME_EVENT] =
656 g_signal_new ("frame_event",
657 G_TYPE_FROM_CLASS (gobject_class),
659 G_STRUCT_OFFSET(GtkWindowClass, frame_event),
660 _gtk_boolean_handled_accumulator, NULL,
661 _gtk_marshal_BOOLEAN__BOXED,
665 window_signals[ACTIVATE_FOCUS] =
666 g_signal_new ("activate_focus",
667 G_TYPE_FROM_CLASS (gobject_class),
668 G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
669 G_STRUCT_OFFSET (GtkWindowClass, activate_focus),
671 _gtk_marshal_VOID__VOID,
675 window_signals[ACTIVATE_DEFAULT] =
676 g_signal_new ("activate_default",
677 G_TYPE_FROM_CLASS (gobject_class),
678 G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
679 G_STRUCT_OFFSET (GtkWindowClass, activate_default),
681 _gtk_marshal_VOID__VOID,
685 window_signals[MOVE_FOCUS] =
686 g_signal_new ("move_focus",
687 G_TYPE_FROM_CLASS (gobject_class),
688 G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
689 G_STRUCT_OFFSET (GtkWindowClass, move_focus),
691 _gtk_marshal_VOID__ENUM,
694 GTK_TYPE_DIRECTION_TYPE);
696 window_signals[KEYS_CHANGED] =
697 g_signal_new ("keys_changed",
698 G_TYPE_FROM_CLASS (gobject_class),
700 G_STRUCT_OFFSET (GtkWindowClass, keys_changed),
702 _gtk_marshal_VOID__VOID,
710 binding_set = gtk_binding_set_by_class (klass);
712 gtk_binding_entry_add_signal (binding_set, GDK_space, 0,
713 "activate_focus", 0);
714 gtk_binding_entry_add_signal (binding_set, GDK_KP_Space, 0,
715 "activate_focus", 0);
717 gtk_binding_entry_add_signal (binding_set, GDK_Return, 0,
718 "activate_default", 0);
720 gtk_binding_entry_add_signal (binding_set, GDK_KP_Enter, 0,
721 "activate_default", 0);
723 add_arrow_bindings (binding_set, GDK_Up, GTK_DIR_UP);
724 add_arrow_bindings (binding_set, GDK_Down, GTK_DIR_DOWN);
725 add_arrow_bindings (binding_set, GDK_Left, GTK_DIR_LEFT);
726 add_arrow_bindings (binding_set, GDK_Right, GTK_DIR_RIGHT);
728 add_tab_bindings (binding_set, 0, GTK_DIR_TAB_FORWARD);
729 add_tab_bindings (binding_set, GDK_CONTROL_MASK, GTK_DIR_TAB_FORWARD);
730 add_tab_bindings (binding_set, GDK_SHIFT_MASK, GTK_DIR_TAB_BACKWARD);
731 add_tab_bindings (binding_set, GDK_CONTROL_MASK | GDK_SHIFT_MASK, GTK_DIR_TAB_BACKWARD);
735 gtk_window_init (GtkWindow *window)
737 GdkColormap *colormap;
738 GtkWindowPrivate *priv = GTK_WINDOW_GET_PRIVATE (window);
740 GTK_WIDGET_UNSET_FLAGS (window, GTK_NO_WINDOW);
741 GTK_WIDGET_SET_FLAGS (window, GTK_TOPLEVEL);
743 GTK_PRIVATE_SET_FLAG (window, GTK_ANCHORED);
745 gtk_container_set_resize_mode (GTK_CONTAINER (window), GTK_RESIZE_QUEUE);
747 window->title = NULL;
748 window->wmclass_name = g_strdup (g_get_prgname ());
749 window->wmclass_class = g_strdup (gdk_get_program_class ());
750 window->wm_role = NULL;
751 window->geometry_info = NULL;
752 window->type = GTK_WINDOW_TOPLEVEL;
753 window->focus_widget = NULL;
754 window->default_widget = NULL;
755 window->configure_request_count = 0;
756 window->allow_shrink = FALSE;
757 window->allow_grow = TRUE;
758 window->configure_notify_received = FALSE;
759 window->position = GTK_WIN_POS_NONE;
760 window->need_default_size = TRUE;
761 window->need_default_position = TRUE;
762 window->modal = FALSE;
763 window->frame = NULL;
764 window->has_frame = FALSE;
765 window->frame_left = 0;
766 window->frame_right = 0;
767 window->frame_top = 0;
768 window->frame_bottom = 0;
769 window->type_hint = GDK_WINDOW_TYPE_HINT_NORMAL;
770 window->gravity = GDK_GRAVITY_NORTH_WEST;
771 window->decorated = TRUE;
772 window->mnemonic_modifier = GDK_MOD1_MASK;
773 window->screen = gdk_screen_get_default ();
775 priv->accept_focus = TRUE;
776 priv->focus_on_map = TRUE;
778 colormap = _gtk_widget_peek_colormap ();
780 gtk_widget_set_colormap (GTK_WIDGET (window), colormap);
782 g_object_ref (window);
783 gtk_object_sink (GTK_OBJECT (window));
784 window->has_user_ref_count = TRUE;
785 toplevel_list = g_slist_prepend (toplevel_list, window);
787 gtk_decorated_window_init (window);
789 g_signal_connect (window,
791 G_CALLBACK (gtk_window_event),
796 gtk_window_set_property (GObject *object,
803 window = GTK_WINDOW (object);
808 window->type = g_value_get_enum (value);
811 gtk_window_set_title (window, g_value_get_string (value));
814 gtk_window_set_role (window, g_value_get_string (value));
816 case PROP_ALLOW_SHRINK:
817 window->allow_shrink = g_value_get_boolean (value);
818 gtk_widget_queue_resize (GTK_WIDGET (window));
820 case PROP_ALLOW_GROW:
821 window->allow_grow = g_value_get_boolean (value);
822 gtk_widget_queue_resize (GTK_WIDGET (window));
823 g_object_notify (G_OBJECT (window), "resizable");
826 window->allow_grow = g_value_get_boolean (value);
827 gtk_widget_queue_resize (GTK_WIDGET (window));
828 g_object_notify (G_OBJECT (window), "allow_grow");
831 gtk_window_set_modal (window, g_value_get_boolean (value));
834 gtk_window_set_position (window, g_value_get_enum (value));
836 case PROP_DEFAULT_WIDTH:
837 gtk_window_set_default_size_internal (window,
838 TRUE, g_value_get_int (value),
841 case PROP_DEFAULT_HEIGHT:
842 gtk_window_set_default_size_internal (window,
844 TRUE, g_value_get_int (value), FALSE);
846 case PROP_DESTROY_WITH_PARENT:
847 gtk_window_set_destroy_with_parent (window, g_value_get_boolean (value));
850 gtk_window_set_icon (window,
851 g_value_get_object (value));
854 gtk_window_set_icon_name (window, g_value_get_string (value));
857 gtk_window_set_screen (window, g_value_get_object (value));
860 gtk_window_set_type_hint (window,
861 g_value_get_enum (value));
863 case PROP_SKIP_TASKBAR_HINT:
864 gtk_window_set_skip_taskbar_hint (window,
865 g_value_get_boolean (value));
867 case PROP_SKIP_PAGER_HINT:
868 gtk_window_set_skip_pager_hint (window,
869 g_value_get_boolean (value));
871 case PROP_ACCEPT_FOCUS:
872 gtk_window_set_accept_focus (window,
873 g_value_get_boolean (value));
875 case PROP_FOCUS_ON_MAP:
876 gtk_window_set_focus_on_map (window,
877 g_value_get_boolean (value));
880 gtk_window_set_decorated (window, g_value_get_boolean (value));
883 gtk_window_set_gravity (window, g_value_get_enum (value));
891 gtk_window_get_property (GObject *object,
898 window = GTK_WINDOW (object);
902 GtkWindowGeometryInfo *info;
904 g_value_set_enum (value, window->type);
907 g_value_set_string (value, window->wm_role);
910 g_value_set_string (value, window->title);
912 case PROP_ALLOW_SHRINK:
913 g_value_set_boolean (value, window->allow_shrink);
915 case PROP_ALLOW_GROW:
916 g_value_set_boolean (value, window->allow_grow);
919 g_value_set_boolean (value, window->allow_grow);
922 g_value_set_boolean (value, window->modal);
925 g_value_set_enum (value, window->position);
927 case PROP_DEFAULT_WIDTH:
928 info = gtk_window_get_geometry_info (window, FALSE);
930 g_value_set_int (value, -1);
932 g_value_set_int (value, info->default_width);
934 case PROP_DEFAULT_HEIGHT:
935 info = gtk_window_get_geometry_info (window, FALSE);
937 g_value_set_int (value, -1);
939 g_value_set_int (value, info->default_height);
941 case PROP_DESTROY_WITH_PARENT:
942 g_value_set_boolean (value, window->destroy_with_parent);
945 g_value_set_object (value, gtk_window_get_icon (window));
948 g_value_set_string (value, gtk_window_get_icon_name (window));
951 g_value_set_object (value, window->screen);
954 g_value_set_boolean (value, window->is_active);
956 case PROP_HAS_TOPLEVEL_FOCUS:
957 g_value_set_boolean (value, window->has_toplevel_focus);
960 g_value_set_enum (value,
963 case PROP_SKIP_TASKBAR_HINT:
964 g_value_set_boolean (value,
965 gtk_window_get_skip_taskbar_hint (window));
967 case PROP_SKIP_PAGER_HINT:
968 g_value_set_boolean (value,
969 gtk_window_get_skip_pager_hint (window));
971 case PROP_ACCEPT_FOCUS:
972 g_value_set_boolean (value,
973 gtk_window_get_accept_focus (window));
975 case PROP_FOCUS_ON_MAP:
976 g_value_set_boolean (value,
977 gtk_window_get_focus_on_map (window));
980 g_value_set_boolean (value, gtk_window_get_decorated (window));
983 g_value_set_enum (value, gtk_window_get_gravity (window));
986 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
993 * @type: type of window
995 * Creates a new #GtkWindow, which is a toplevel window that can
996 * contain other widgets. Nearly always, the type of the window should
997 * be #GTK_WINDOW_TOPLEVEL. If you're implementing something like a
998 * popup menu from scratch (which is a bad idea, just use #GtkMenu),
999 * you might use #GTK_WINDOW_POPUP. #GTK_WINDOW_POPUP is not for
1000 * dialogs, though in some other toolkits dialogs are called "popups".
1001 * In GTK+, #GTK_WINDOW_POPUP means a pop-up menu or pop-up tooltip.
1002 * On X11, popup windows are not controlled by the <link
1003 * linkend="gtk-X11-arch">window manager</link>.
1005 * If you simply want an undecorated window (no window borders), use
1006 * gtk_window_set_decorated(), don't use #GTK_WINDOW_POPUP.
1008 * Return value: a new #GtkWindow.
1011 gtk_window_new (GtkWindowType type)
1015 g_return_val_if_fail (type >= GTK_WINDOW_TOPLEVEL && type <= GTK_WINDOW_POPUP, NULL);
1017 window = g_object_new (GTK_TYPE_WINDOW, NULL);
1019 window->type = type;
1021 return GTK_WIDGET (window);
1025 * gtk_window_set_title:
1026 * @window: a #GtkWindow
1027 * @title: title of the window
1029 * Sets the title of the #GtkWindow. The title of a window will be
1030 * displayed in its title bar; on the X Window System, the title bar
1031 * is rendered by the <link linkend="gtk-X11-arch">window
1032 * manager</link>, so exactly how the title appears to users may vary
1033 * according to a user's exact configuration. The title should help a
1034 * user distinguish this window from other windows they may have
1035 * open. A good title might include the application name and current
1036 * document filename, for example.
1040 gtk_window_set_title (GtkWindow *window,
1045 g_return_if_fail (GTK_IS_WINDOW (window));
1047 new_title = g_strdup (title);
1048 g_free (window->title);
1049 window->title = new_title;
1051 if (GTK_WIDGET_REALIZED (window))
1053 gdk_window_set_title (GTK_WIDGET (window)->window, window->title);
1055 gtk_decorated_window_set_title (window, title);
1058 g_object_notify (G_OBJECT (window), "title");
1062 * gtk_window_get_title:
1063 * @window: a #GtkWindow
1065 * Retrieves the title of the window. See gtk_window_set_title().
1067 * Return value: the title of the window, or %NULL if none has
1068 * been set explicitely. The returned string is owned by the widget
1069 * and must not be modified or freed.
1071 G_CONST_RETURN gchar *
1072 gtk_window_get_title (GtkWindow *window)
1074 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
1076 return window->title;
1080 * gtk_window_set_wmclass:
1081 * @window: a #GtkWindow
1082 * @wmclass_name: window name hint
1083 * @wmclass_class: window class hint
1085 * Don't use this function. It sets the X Window System "class" and
1086 * "name" hints for a window. According to the ICCCM, you should
1087 * always set these to the same value for all windows in an
1088 * application, and GTK+ sets them to that value by default, so calling
1089 * this function is sort of pointless. However, you may want to call
1090 * gtk_window_set_role() on each window in your application, for the
1091 * benefit of the session manager. Setting the role allows the window
1092 * manager to restore window positions when loading a saved session.
1096 gtk_window_set_wmclass (GtkWindow *window,
1097 const gchar *wmclass_name,
1098 const gchar *wmclass_class)
1100 g_return_if_fail (GTK_IS_WINDOW (window));
1102 g_free (window->wmclass_name);
1103 window->wmclass_name = g_strdup (wmclass_name);
1105 g_free (window->wmclass_class);
1106 window->wmclass_class = g_strdup (wmclass_class);
1108 if (GTK_WIDGET_REALIZED (window))
1109 g_warning ("gtk_window_set_wmclass: shouldn't set wmclass after window is realized!\n");
1113 * gtk_window_set_role:
1114 * @window: a #GtkWindow
1115 * @role: unique identifier for the window to be used when restoring a session
1117 * This function is only useful on X11, not with other GTK+ targets.
1119 * In combination with the window title, the window role allows a
1120 * <link linkend="gtk-X11-arch">window manager</link> to identify "the
1121 * same" window when an application is restarted. So for example you
1122 * might set the "toolbox" role on your app's toolbox window, so that
1123 * when the user restarts their session, the window manager can put
1124 * the toolbox back in the same place.
1126 * If a window already has a unique title, you don't need to set the
1127 * role, since the WM can use the title to identify the window when
1128 * restoring the session.
1132 gtk_window_set_role (GtkWindow *window,
1137 g_return_if_fail (GTK_IS_WINDOW (window));
1139 new_role = g_strdup (role);
1140 g_free (window->wm_role);
1141 window->wm_role = new_role;
1143 if (GTK_WIDGET_REALIZED (window))
1144 gdk_window_set_role (GTK_WIDGET (window)->window, window->wm_role);
1146 g_object_notify (G_OBJECT (window), "role");
1150 * gtk_window_get_role:
1151 * @window: a #GtkWindow
1153 * Returns the role of the window. See gtk_window_set_role() for
1154 * further explanation.
1156 * Return value: the role of the window if set, or %NULL. The
1157 * returned is owned by the widget and must not be modified
1160 G_CONST_RETURN gchar *
1161 gtk_window_get_role (GtkWindow *window)
1163 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
1165 return window->wm_role;
1169 * gtk_window_set_focus:
1170 * @window: a #GtkWindow
1171 * @focus: widget to be the new focus widget, or %NULL to unset
1172 * any focus widget for the toplevel window.
1174 * If @focus is not the current focus widget, and is focusable, sets
1175 * it as the focus widget for the window. If @focus is %NULL, unsets
1176 * the focus widget for this window. To set the focus to a particular
1177 * widget in the toplevel, it is usually more convenient to use
1178 * gtk_widget_grab_focus() instead of this function.
1181 gtk_window_set_focus (GtkWindow *window,
1184 g_return_if_fail (GTK_IS_WINDOW (window));
1187 g_return_if_fail (GTK_IS_WIDGET (focus));
1188 g_return_if_fail (GTK_WIDGET_CAN_FOCUS (focus));
1192 gtk_widget_grab_focus (focus);
1195 /* Clear the existing focus chain, so that when we focus into
1196 * the window again, we start at the beginnning.
1198 GtkWidget *widget = window->focus_widget;
1201 while (widget->parent)
1203 widget = widget->parent;
1204 gtk_container_set_focus_child (GTK_CONTAINER (widget), NULL);
1208 _gtk_window_internal_set_focus (window, NULL);
1213 _gtk_window_internal_set_focus (GtkWindow *window,
1216 g_return_if_fail (GTK_IS_WINDOW (window));
1218 if ((window->focus_widget != focus) ||
1219 (focus && !GTK_WIDGET_HAS_FOCUS (focus)))
1220 g_signal_emit (window, window_signals[SET_FOCUS], 0, focus);
1224 * gtk_window_set_default:
1225 * @window: a #GtkWindow
1226 * @default_widget: widget to be the default, or %NULL to unset the
1227 * default widget for the toplevel.
1229 * The default widget is the widget that's activated when the user
1230 * presses Enter in a dialog (for example). This function sets or
1231 * unsets the default widget for a #GtkWindow about. When setting
1232 * (rather than unsetting) the default widget it's generally easier to
1233 * call gtk_widget_grab_focus() on the widget. Before making a widget
1234 * the default widget, you must set the #GTK_CAN_DEFAULT flag on the
1235 * widget you'd like to make the default using GTK_WIDGET_SET_FLAGS().
1238 gtk_window_set_default (GtkWindow *window,
1239 GtkWidget *default_widget)
1241 g_return_if_fail (GTK_IS_WINDOW (window));
1244 g_return_if_fail (GTK_WIDGET_CAN_DEFAULT (default_widget));
1246 if (window->default_widget != default_widget)
1248 GtkWidget *old_default_widget = NULL;
1251 g_object_ref (default_widget);
1253 if (window->default_widget)
1255 old_default_widget = window->default_widget;
1257 if (window->focus_widget != window->default_widget ||
1258 !GTK_WIDGET_RECEIVES_DEFAULT (window->default_widget))
1259 GTK_WIDGET_UNSET_FLAGS (window->default_widget, GTK_HAS_DEFAULT);
1260 gtk_widget_queue_draw (window->default_widget);
1263 window->default_widget = default_widget;
1265 if (window->default_widget)
1267 if (window->focus_widget == NULL ||
1268 !GTK_WIDGET_RECEIVES_DEFAULT (window->focus_widget))
1269 GTK_WIDGET_SET_FLAGS (window->default_widget, GTK_HAS_DEFAULT);
1270 gtk_widget_queue_draw (window->default_widget);
1273 if (old_default_widget)
1274 g_object_notify (G_OBJECT (old_default_widget), "has_default");
1278 g_object_notify (G_OBJECT (default_widget), "has_default");
1279 g_object_unref (default_widget);
1285 gtk_window_set_policy (GtkWindow *window,
1286 gboolean allow_shrink,
1287 gboolean allow_grow,
1288 gboolean auto_shrink)
1290 g_return_if_fail (GTK_IS_WINDOW (window));
1292 window->allow_shrink = (allow_shrink != FALSE);
1293 window->allow_grow = (allow_grow != FALSE);
1295 g_object_freeze_notify (G_OBJECT (window));
1296 g_object_notify (G_OBJECT (window), "allow_shrink");
1297 g_object_notify (G_OBJECT (window), "allow_grow");
1298 g_object_notify (G_OBJECT (window), "resizable");
1299 g_object_thaw_notify (G_OBJECT (window));
1301 gtk_widget_queue_resize (GTK_WIDGET (window));
1305 handle_keys_changed (gpointer data)
1309 GDK_THREADS_ENTER ();
1310 window = GTK_WINDOW (data);
1312 if (window->keys_changed_handler)
1314 g_source_remove (window->keys_changed_handler);
1315 window->keys_changed_handler = 0;
1318 g_signal_emit (window, window_signals[KEYS_CHANGED], 0);
1319 GDK_THREADS_LEAVE ();
1325 gtk_window_notify_keys_changed (GtkWindow *window)
1327 if (!window->keys_changed_handler)
1328 window->keys_changed_handler = g_idle_add (handle_keys_changed, window);
1332 * gtk_window_add_accel_group:
1333 * @window: window to attach accelerator group to
1334 * @accel_group: a #GtkAccelGroup
1336 * Associate @accel_group with @window, such that calling
1337 * gtk_accel_groups_activate() on @window will activate accelerators
1341 gtk_window_add_accel_group (GtkWindow *window,
1342 GtkAccelGroup *accel_group)
1344 g_return_if_fail (GTK_IS_WINDOW (window));
1345 g_return_if_fail (GTK_IS_ACCEL_GROUP (accel_group));
1347 _gtk_accel_group_attach (accel_group, G_OBJECT (window));
1348 g_signal_connect_object (accel_group, "accel_changed",
1349 G_CALLBACK (gtk_window_notify_keys_changed),
1350 window, G_CONNECT_SWAPPED);
1354 * gtk_window_remove_accel_group:
1355 * @window: a #GtkWindow
1356 * @accel_group: a #GtkAccelGroup
1358 * Reverses the effects of gtk_window_add_accel_group().
1361 gtk_window_remove_accel_group (GtkWindow *window,
1362 GtkAccelGroup *accel_group)
1364 g_return_if_fail (GTK_IS_WINDOW (window));
1365 g_return_if_fail (GTK_IS_ACCEL_GROUP (accel_group));
1367 g_signal_handlers_disconnect_by_func (accel_group,
1368 gtk_window_notify_keys_changed,
1370 _gtk_accel_group_detach (accel_group, G_OBJECT (window));
1373 static GtkMnemonicHash *
1374 gtk_window_get_mnemonic_hash (GtkWindow *window,
1377 GtkWindowPrivate *private = GTK_WINDOW_GET_PRIVATE (window);
1378 if (!private->mnemonic_hash && create)
1379 private->mnemonic_hash = _gtk_mnemonic_hash_new ();
1381 return private->mnemonic_hash;
1385 * gtk_window_add_mnemonic:
1386 * @window: a #GtkWindow
1387 * @keyval: the mnemonic
1388 * @target: the widget that gets activated by the mnemonic
1390 * Adds a mnemonic to this window.
1393 gtk_window_add_mnemonic (GtkWindow *window,
1397 g_return_if_fail (GTK_IS_WINDOW (window));
1398 g_return_if_fail (GTK_IS_WIDGET (target));
1400 _gtk_mnemonic_hash_add (gtk_window_get_mnemonic_hash (window, TRUE),
1402 gtk_window_notify_keys_changed (window);
1406 * gtk_window_remove_mnemonic:
1407 * @window: a #GtkWindow
1408 * @keyval: the mnemonic
1409 * @target: the widget that gets activated by the mnemonic
1411 * Removes a mnemonic from this window.
1414 gtk_window_remove_mnemonic (GtkWindow *window,
1418 g_return_if_fail (GTK_IS_WINDOW (window));
1419 g_return_if_fail (GTK_IS_WIDGET (target));
1421 _gtk_mnemonic_hash_remove (gtk_window_get_mnemonic_hash (window, TRUE),
1423 gtk_window_notify_keys_changed (window);
1427 * gtk_window_mnemonic_activate:
1428 * @window: a #GtkWindow
1429 * @keyval: the mnemonic
1430 * @modifier: the modifiers
1431 * @returns: %TRUE if the activation is done.
1433 * Activates the targets associated with the mnemonic.
1436 gtk_window_mnemonic_activate (GtkWindow *window,
1438 GdkModifierType modifier)
1440 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
1442 if (window->mnemonic_modifier == (modifier & gtk_accelerator_get_default_mod_mask ()))
1444 GtkMnemonicHash *mnemonic_hash = gtk_window_get_mnemonic_hash (window, FALSE);
1446 return _gtk_mnemonic_hash_activate (mnemonic_hash, keyval);
1453 * gtk_window_set_mnemonic_modifier:
1454 * @window: a #GtkWindow
1455 * @modifier: the modifier mask used to activate
1456 * mnemonics on this window.
1458 * Sets the mnemonic modifier for this window.
1461 gtk_window_set_mnemonic_modifier (GtkWindow *window,
1462 GdkModifierType modifier)
1464 g_return_if_fail (GTK_IS_WINDOW (window));
1465 g_return_if_fail ((modifier & ~GDK_MODIFIER_MASK) == 0);
1467 window->mnemonic_modifier = modifier;
1468 gtk_window_notify_keys_changed (window);
1472 * gtk_window_get_mnemonic_modifier:
1473 * @window: a #GtkWindow
1475 * Returns the mnemonic modifier for this window. See
1476 * gtk_window_set_mnemonic_modifier().
1478 * Return value: the modifier mask used to activate
1479 * mnemonics on this window.
1482 gtk_window_get_mnemonic_modifier (GtkWindow *window)
1484 g_return_val_if_fail (GTK_IS_WINDOW (window), 0);
1486 return window->mnemonic_modifier;
1490 * gtk_window_set_position:
1491 * @window: a #GtkWindow.
1492 * @position: a position constraint.
1494 * Sets a position constraint for this window. If the old or new
1495 * constraint is %GTK_WIN_POS_CENTER_ALWAYS, this will also cause
1496 * the window to be repositioned to satisfy the new constraint.
1499 gtk_window_set_position (GtkWindow *window,
1500 GtkWindowPosition position)
1502 g_return_if_fail (GTK_IS_WINDOW (window));
1504 if (position == GTK_WIN_POS_CENTER_ALWAYS ||
1505 window->position == GTK_WIN_POS_CENTER_ALWAYS)
1507 GtkWindowGeometryInfo *info;
1509 info = gtk_window_get_geometry_info (window, TRUE);
1511 /* this flag causes us to re-request the CENTER_ALWAYS
1512 * constraint in gtk_window_move_resize(), see
1513 * comment in that function.
1515 info->position_constraints_changed = TRUE;
1517 gtk_widget_queue_resize (GTK_WIDGET (window));
1520 window->position = position;
1522 g_object_notify (G_OBJECT (window), "window_position");
1526 * gtk_window_activate_focus:
1527 * @window: a #GtkWindow
1529 * Activates the current focused widget within the window.
1531 * Return value: %TRUE if a widget got activated.
1534 gtk_window_activate_focus (GtkWindow *window)
1536 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
1538 if (window->focus_widget && GTK_WIDGET_IS_SENSITIVE (window->focus_widget))
1539 return gtk_widget_activate (window->focus_widget);
1545 * gtk_window_get_focus:
1546 * @window: a #GtkWindow
1548 * Retrieves the current focused widget within the window.
1549 * Note that this is the widget that would have the focus
1550 * if the toplevel window focused; if the toplevel window
1551 * is not focused then <literal>GTK_WIDGET_HAS_FOCUS (widget)</literal> will
1552 * not be %TRUE for the widget.
1554 * Return value: the currently focused widget, or %NULL if there is none.
1557 gtk_window_get_focus (GtkWindow *window)
1559 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
1561 return window->focus_widget;
1565 * gtk_window_activate_default:
1566 * @window: a #GtkWindow
1568 * Activates the default widget for the window, unless the current
1569 * focused widget has been configured to receive the default action
1570 * (see #GTK_RECEIVES_DEFAULT in #GtkWidgetFlags), in which case the
1571 * focused widget is activated.
1573 * Return value: %TRUE if a widget got activated.
1576 gtk_window_activate_default (GtkWindow *window)
1578 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
1580 if (window->default_widget && GTK_WIDGET_IS_SENSITIVE (window->default_widget) &&
1581 (!window->focus_widget || !GTK_WIDGET_RECEIVES_DEFAULT (window->focus_widget)))
1582 return gtk_widget_activate (window->default_widget);
1583 else if (window->focus_widget && GTK_WIDGET_IS_SENSITIVE (window->focus_widget))
1584 return gtk_widget_activate (window->focus_widget);
1590 * gtk_window_set_modal:
1591 * @window: a #GtkWindow
1592 * @modal: whether the window is modal
1594 * Sets a window modal or non-modal. Modal windows prevent interaction
1595 * with other windows in the same application. To keep modal dialogs
1596 * on top of main application windows, use
1597 * gtk_window_set_transient_for() to make the dialog transient for the
1598 * parent; most <link linkend="gtk-X11-arch">window managers</link>
1599 * will then disallow lowering the dialog below the parent.
1604 gtk_window_set_modal (GtkWindow *window,
1607 g_return_if_fail (GTK_IS_WINDOW (window));
1609 modal = modal != FALSE;
1610 if (window->modal == modal)
1613 window->modal = modal;
1615 /* adjust desired modality state */
1616 if (GTK_WIDGET_REALIZED (window))
1618 GtkWidget *widget = GTK_WIDGET (window);
1621 gdk_window_set_modal_hint (widget->window, TRUE);
1623 gdk_window_set_modal_hint (widget->window, FALSE);
1626 if (GTK_WIDGET_VISIBLE (window))
1629 gtk_grab_add (GTK_WIDGET (window));
1631 gtk_grab_remove (GTK_WIDGET (window));
1634 g_object_notify (G_OBJECT (window), "modal");
1638 * gtk_window_get_modal:
1639 * @window: a #GtkWindow
1641 * Returns whether the window is modal. See gtk_window_set_modal().
1643 * Return value: %TRUE if the window is set to be modal and
1644 * establishes a grab when shown
1647 gtk_window_get_modal (GtkWindow *window)
1649 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
1651 return window->modal;
1655 * gtk_window_list_toplevels:
1657 * Returns a list of all existing toplevel windows. The widgets
1658 * in the list are not individually referenced. If you want
1659 * to iterate through the list and perform actions involving
1660 * callbacks that might destroy the widgets, you <emphasis>must</emphasis> call
1661 * <literal>g_list_foreach (result, (GFunc)g_object_ref, NULL)</literal> first, and
1662 * then unref all the widgets afterwards.
1664 * Return value: list of toplevel widgets
1667 gtk_window_list_toplevels (void)
1672 for (slist = toplevel_list; slist; slist = slist->next)
1673 list = g_list_prepend (list, slist->data);
1679 gtk_window_add_embedded_xid (GtkWindow *window, guint xid)
1681 GList *embedded_windows;
1683 g_return_if_fail (GTK_IS_WINDOW (window));
1685 embedded_windows = g_object_get_data (G_OBJECT (window), "gtk-embedded");
1686 if (embedded_windows)
1687 g_object_steal_qdata (G_OBJECT (window),
1688 g_quark_from_static_string ("gtk-embedded"));
1689 embedded_windows = g_list_prepend (embedded_windows,
1690 GUINT_TO_POINTER (xid));
1692 g_object_set_data_full (G_OBJECT (window), "gtk-embedded",
1695 (GDestroyNotify) g_list_free : NULL);
1699 gtk_window_remove_embedded_xid (GtkWindow *window, guint xid)
1701 GList *embedded_windows;
1704 g_return_if_fail (GTK_IS_WINDOW (window));
1706 embedded_windows = g_object_get_data (G_OBJECT (window), "gtk-embedded");
1707 if (embedded_windows)
1708 g_object_steal_qdata (G_OBJECT (window),
1709 g_quark_from_static_string ("gtk-embedded"));
1711 node = g_list_find (embedded_windows, GUINT_TO_POINTER (xid));
1714 embedded_windows = g_list_remove_link (embedded_windows, node);
1715 g_list_free_1 (node);
1718 g_object_set_data_full (G_OBJECT (window), "gtk-embedded",
1721 (GDestroyNotify) g_list_free : NULL);
1725 _gtk_window_reposition (GtkWindow *window,
1729 g_return_if_fail (GTK_IS_WINDOW (window));
1731 gtk_window_move (window, x, y);
1735 gtk_window_dispose (GObject *object)
1737 GtkWindow *window = GTK_WINDOW (object);
1739 gtk_window_set_focus (window, NULL);
1740 gtk_window_set_default (window, NULL);
1742 G_OBJECT_CLASS (parent_class)->dispose (object);
1746 parent_destroyed_callback (GtkWindow *parent, GtkWindow *child)
1748 gtk_widget_destroy (GTK_WIDGET (child));
1752 connect_parent_destroyed (GtkWindow *window)
1754 if (window->transient_parent)
1756 g_signal_connect (window->transient_parent,
1758 G_CALLBACK (parent_destroyed_callback),
1764 disconnect_parent_destroyed (GtkWindow *window)
1766 if (window->transient_parent)
1768 g_signal_handlers_disconnect_by_func (window->transient_parent,
1769 parent_destroyed_callback,
1775 gtk_window_transient_parent_realized (GtkWidget *parent,
1778 if (GTK_WIDGET_REALIZED (window))
1779 gdk_window_set_transient_for (window->window, parent->window);
1783 gtk_window_transient_parent_unrealized (GtkWidget *parent,
1786 if (GTK_WIDGET_REALIZED (window))
1787 gdk_property_delete (window->window,
1788 gdk_atom_intern ("WM_TRANSIENT_FOR", FALSE));
1792 gtk_window_transient_parent_screen_changed (GtkWindow *parent,
1796 gtk_window_set_screen (window, parent->screen);
1800 gtk_window_unset_transient_for (GtkWindow *window)
1802 if (window->transient_parent)
1804 g_signal_handlers_disconnect_by_func (window->transient_parent,
1805 gtk_window_transient_parent_realized,
1807 g_signal_handlers_disconnect_by_func (window->transient_parent,
1808 gtk_window_transient_parent_unrealized,
1810 g_signal_handlers_disconnect_by_func (window->transient_parent,
1811 gtk_window_transient_parent_screen_changed,
1813 g_signal_handlers_disconnect_by_func (window->transient_parent,
1814 gtk_widget_destroyed,
1815 &window->transient_parent);
1817 if (window->destroy_with_parent)
1818 disconnect_parent_destroyed (window);
1820 window->transient_parent = NULL;
1825 * gtk_window_set_transient_for:
1826 * @window: a #GtkWindow
1827 * @parent: parent window
1829 * Dialog windows should be set transient for the main application
1830 * window they were spawned from. This allows <link
1831 * linkend="gtk-X11-arch">window managers</link> to e.g. keep the
1832 * dialog on top of the main window, or center the dialog over the
1833 * main window. gtk_dialog_new_with_buttons() and other convenience
1834 * functions in GTK+ will sometimes call
1835 * gtk_window_set_transient_for() on your behalf.
1837 * On Windows, this function will and put the child window
1838 * on top of the parent, much as the window manager would have
1843 gtk_window_set_transient_for (GtkWindow *window,
1846 g_return_if_fail (GTK_IS_WINDOW (window));
1847 g_return_if_fail (parent == NULL || GTK_IS_WINDOW (parent));
1848 g_return_if_fail (window != parent);
1851 if (window->transient_parent)
1853 if (GTK_WIDGET_REALIZED (window) &&
1854 GTK_WIDGET_REALIZED (window->transient_parent) &&
1855 (!parent || !GTK_WIDGET_REALIZED (parent)))
1856 gtk_window_transient_parent_unrealized (GTK_WIDGET (window->transient_parent),
1857 GTK_WIDGET (window));
1859 gtk_window_unset_transient_for (window);
1862 window->transient_parent = parent;
1866 g_signal_connect (parent, "destroy",
1867 G_CALLBACK (gtk_widget_destroyed),
1868 &window->transient_parent);
1869 g_signal_connect (parent, "realize",
1870 G_CALLBACK (gtk_window_transient_parent_realized),
1872 g_signal_connect (parent, "unrealize",
1873 G_CALLBACK (gtk_window_transient_parent_unrealized),
1875 g_signal_connect (parent, "notify::screen",
1876 G_CALLBACK (gtk_window_transient_parent_screen_changed),
1879 gtk_window_set_screen (window, parent->screen);
1881 if (window->destroy_with_parent)
1882 connect_parent_destroyed (window);
1884 if (GTK_WIDGET_REALIZED (window) &&
1885 GTK_WIDGET_REALIZED (parent))
1886 gtk_window_transient_parent_realized (GTK_WIDGET (parent),
1887 GTK_WIDGET (window));
1892 * gtk_window_get_transient_for:
1893 * @window: a #GtkWindow
1895 * Fetches the transient parent for this window. See
1896 * gtk_window_set_transient_for().
1898 * Return value: the transient parent for this window, or %NULL
1899 * if no transient parent has been set.
1902 gtk_window_get_transient_for (GtkWindow *window)
1904 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
1906 return window->transient_parent;
1910 * gtk_window_set_type_hint:
1911 * @window: a #GtkWindow
1912 * @hint: the window type
1914 * By setting the type hint for the window, you allow the window
1915 * manager to decorate and handle the window in a way which is
1916 * suitable to the function of the window in your application.
1918 * This function should be called before the window becomes visible.
1920 * gtk_dialog_new_with_buttons() and other convenience functions in GTK+
1921 * will sometimes call gtk_window_set_type_hint() on your behalf.
1925 gtk_window_set_type_hint (GtkWindow *window,
1926 GdkWindowTypeHint hint)
1928 g_return_if_fail (GTK_IS_WINDOW (window));
1929 g_return_if_fail (!GTK_WIDGET_VISIBLE (window));
1930 window->type_hint = hint;
1934 * gtk_window_get_type_hint:
1935 * @window: a #GtkWindow
1937 * Gets the type hint for this window. See gtk_window_set_type_hint().
1939 * Return value: the type hint for @window.
1942 gtk_window_get_type_hint (GtkWindow *window)
1944 g_return_val_if_fail (GTK_IS_WINDOW (window), GDK_WINDOW_TYPE_HINT_NORMAL);
1946 return window->type_hint;
1950 * gtk_window_set_skip_taskbar_hint:
1951 * @window: a #GtkWindow
1952 * @setting: %TRUE to keep this window from appearing in the task bar
1954 * Windows may set a hint asking the desktop environment not to display
1955 * the window in the task bar. This function sets this hint.
1960 gtk_window_set_skip_taskbar_hint (GtkWindow *window,
1963 GtkWindowPrivate *priv;
1965 g_return_if_fail (GTK_IS_WINDOW (window));
1967 priv = GTK_WINDOW_GET_PRIVATE (window);
1969 setting = setting != FALSE;
1971 if (priv->skips_taskbar != setting)
1973 priv->skips_taskbar = setting;
1974 if (GTK_WIDGET_REALIZED (window))
1975 gdk_window_set_skip_taskbar_hint (GTK_WIDGET (window)->window,
1976 priv->skips_taskbar);
1977 g_object_notify (G_OBJECT (window), "skip_taskbar_hint");
1982 * gtk_window_get_skip_taskbar_hint:
1983 * @window: a #GtkWindow
1985 * Gets the value set by gtk_window_set_skip_taskbar_hint()
1987 * Return value: %TRUE if window shouldn't be in taskbar
1992 gtk_window_get_skip_taskbar_hint (GtkWindow *window)
1994 GtkWindowPrivate *priv;
1996 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
1998 priv = GTK_WINDOW_GET_PRIVATE (window);
2000 return priv->skips_taskbar;
2004 * gtk_window_set_skip_pager_hint:
2005 * @window: a #GtkWindow
2006 * @setting: %TRUE to keep this window from appearing in the pager
2008 * Windows may set a hint asking the desktop environment not to display
2009 * the window in the pager. This function sets this hint.
2010 * (A "pager" is any desktop navigation tool such as a workspace
2011 * switcher that displays a thumbnail representation of the windows
2017 gtk_window_set_skip_pager_hint (GtkWindow *window,
2020 GtkWindowPrivate *priv;
2022 g_return_if_fail (GTK_IS_WINDOW (window));
2024 priv = GTK_WINDOW_GET_PRIVATE (window);
2026 setting = setting != FALSE;
2028 if (priv->skips_pager != setting)
2030 priv->skips_pager = setting;
2031 if (GTK_WIDGET_REALIZED (window))
2032 gdk_window_set_skip_pager_hint (GTK_WIDGET (window)->window,
2034 g_object_notify (G_OBJECT (window), "skip_pager_hint");
2039 * gtk_window_get_skip_pager_hint:
2040 * @window: a #GtkWindow
2042 * Gets the value set by gtk_window_set_skip_pager_hint().
2044 * Return value: %TRUE if window shouldn't be in pager
2049 gtk_window_get_skip_pager_hint (GtkWindow *window)
2051 GtkWindowPrivate *priv;
2053 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
2055 priv = GTK_WINDOW_GET_PRIVATE (window);
2057 return priv->skips_pager;
2061 * gtk_window_set_accept_focus:
2062 * @window: a #GtkWindow
2063 * @setting: %TRUE to let this window receive input focus
2065 * Windows may set a hint asking the desktop environment not to receive
2066 * the input focus. This function sets this hint.
2071 gtk_window_set_accept_focus (GtkWindow *window,
2074 GtkWindowPrivate *priv;
2076 g_return_if_fail (GTK_IS_WINDOW (window));
2078 priv = GTK_WINDOW_GET_PRIVATE (window);
2080 setting = setting != FALSE;
2082 if (priv->accept_focus != setting)
2084 priv->accept_focus = setting;
2085 if (GTK_WIDGET_REALIZED (window))
2086 gdk_window_set_accept_focus (GTK_WIDGET (window)->window,
2087 priv->accept_focus);
2088 g_object_notify (G_OBJECT (window), "accept_focus");
2093 * gtk_window_get_accept_focus:
2094 * @window: a #GtkWindow
2096 * Gets the value set by gtk_window_set_accept_focus().
2098 * Return value: %TRUE if window should receive the input focus
2103 gtk_window_get_accept_focus (GtkWindow *window)
2105 GtkWindowPrivate *priv;
2107 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
2109 priv = GTK_WINDOW_GET_PRIVATE (window);
2111 return priv->accept_focus;
2115 * gtk_window_set_focus_on_map:
2116 * @window: a #GtkWindow
2117 * @setting: %TRUE to let this window receive input focus on map
2119 * Windows may set a hint asking the desktop environment not to receive
2120 * the input focus when the window is mapped. This function sets this
2126 gtk_window_set_focus_on_map (GtkWindow *window,
2129 GtkWindowPrivate *priv;
2131 g_return_if_fail (GTK_IS_WINDOW (window));
2133 priv = GTK_WINDOW_GET_PRIVATE (window);
2135 setting = setting != FALSE;
2137 if (priv->focus_on_map != setting)
2139 priv->focus_on_map = setting;
2140 if (GTK_WIDGET_REALIZED (window))
2141 gdk_window_set_focus_on_map (GTK_WIDGET (window)->window,
2142 priv->focus_on_map);
2143 g_object_notify (G_OBJECT (window), "focus_on_map");
2148 * gtk_window_get_focus_on_map:
2149 * @window: a #GtkWindow
2151 * Gets the value set by gtk_window_set_focus_on_map().
2153 * Return value: %TRUE if window should receive the input focus when
2159 gtk_window_get_focus_on_map (GtkWindow *window)
2161 GtkWindowPrivate *priv;
2163 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
2165 priv = GTK_WINDOW_GET_PRIVATE (window);
2167 return priv->focus_on_map;
2171 * gtk_window_set_destroy_with_parent:
2172 * @window: a #GtkWindow
2173 * @setting: whether to destroy @window with its transient parent
2175 * If @setting is %TRUE, then destroying the transient parent of @window
2176 * will also destroy @window itself. This is useful for dialogs that
2177 * shouldn't persist beyond the lifetime of the main window they're
2178 * associated with, for example.
2181 gtk_window_set_destroy_with_parent (GtkWindow *window,
2184 g_return_if_fail (GTK_IS_WINDOW (window));
2186 if (window->destroy_with_parent == (setting != FALSE))
2189 if (window->destroy_with_parent)
2191 disconnect_parent_destroyed (window);
2195 connect_parent_destroyed (window);
2198 window->destroy_with_parent = setting;
2200 g_object_notify (G_OBJECT (window), "destroy_with_parent");
2204 * gtk_window_get_destroy_with_parent:
2205 * @window: a #GtkWindow
2207 * Returns whether the window will be destroyed with its transient parent. See
2208 * gtk_window_set_destroy_with_parent ().
2210 * Return value: %TRUE if the window will be destroyed with its transient parent.
2213 gtk_window_get_destroy_with_parent (GtkWindow *window)
2215 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
2217 return window->destroy_with_parent;
2220 static GtkWindowGeometryInfo*
2221 gtk_window_get_geometry_info (GtkWindow *window,
2224 GtkWindowGeometryInfo *info;
2226 info = window->geometry_info;
2227 if (!info && create)
2229 info = g_new0 (GtkWindowGeometryInfo, 1);
2231 info->default_width = -1;
2232 info->default_height = -1;
2233 info->resize_width = -1;
2234 info->resize_height = -1;
2235 info->initial_x = 0;
2236 info->initial_y = 0;
2237 info->initial_pos_set = FALSE;
2238 info->default_is_geometry = FALSE;
2239 info->position_constraints_changed = FALSE;
2240 info->last.configure_request.x = 0;
2241 info->last.configure_request.y = 0;
2242 info->last.configure_request.width = -1;
2243 info->last.configure_request.height = -1;
2244 info->widget = NULL;
2246 window->geometry_info = info;
2253 * gtk_window_set_geometry_hints:
2254 * @window: a #GtkWindow
2255 * @geometry_widget: widget the geometry hints will be applied to
2256 * @geometry: struct containing geometry information
2257 * @geom_mask: mask indicating which struct fields should be paid attention to
2259 * This function sets up hints about how a window can be resized by
2260 * the user. You can set a minimum and maximum size; allowed resize
2261 * increments (e.g. for xterm, you can only resize by the size of a
2262 * character); aspect ratios; and more. See the #GdkGeometry struct.
2266 gtk_window_set_geometry_hints (GtkWindow *window,
2267 GtkWidget *geometry_widget,
2268 GdkGeometry *geometry,
2269 GdkWindowHints geom_mask)
2271 GtkWindowGeometryInfo *info;
2273 g_return_if_fail (GTK_IS_WINDOW (window));
2274 g_return_if_fail (geometry_widget == NULL || GTK_IS_WIDGET (geometry_widget));
2276 info = gtk_window_get_geometry_info (window, TRUE);
2279 g_signal_handlers_disconnect_by_func (info->widget,
2280 gtk_widget_destroyed,
2283 info->widget = geometry_widget;
2285 g_signal_connect (geometry_widget, "destroy",
2286 G_CALLBACK (gtk_widget_destroyed),
2290 info->geometry = *geometry;
2292 /* We store gravity in window->gravity not in the hints. */
2293 info->mask = geom_mask & ~(GDK_HINT_WIN_GRAVITY);
2295 if (geom_mask & GDK_HINT_WIN_GRAVITY)
2297 gtk_window_set_gravity (window, geometry->win_gravity);
2300 gtk_widget_queue_resize (GTK_WIDGET (window));
2304 * gtk_window_set_decorated:
2305 * @window: a #GtkWindow
2306 * @setting: %TRUE to decorate the window
2308 * By default, windows are decorated with a title bar, resize
2309 * controls, etc. Some <link linkend="gtk-X11-arch">window
2310 * managers</link> allow GTK+ to disable these decorations, creating a
2311 * borderless window. If you set the decorated property to %FALSE
2312 * using this function, GTK+ will do its best to convince the window
2313 * manager not to decorate the window. Depending on the system, this
2314 * function may not have any effect when called on a window that is
2315 * already visible, so you should call it before calling gtk_window_show().
2317 * On Windows, this function always works, since there's no window manager
2322 gtk_window_set_decorated (GtkWindow *window,
2325 g_return_if_fail (GTK_IS_WINDOW (window));
2327 setting = setting != FALSE;
2329 if (setting == window->decorated)
2332 window->decorated = setting;
2334 if (GTK_WIDGET (window)->window)
2336 if (window->decorated)
2337 gdk_window_set_decorations (GTK_WIDGET (window)->window,
2340 gdk_window_set_decorations (GTK_WIDGET (window)->window,
2344 g_object_notify (G_OBJECT (window), "decorated");
2348 * gtk_window_get_decorated:
2349 * @window: a #GtkWindow
2351 * Returns whether the window has been set to have decorations
2352 * such as a title bar via gtk_window_set_decorated().
2354 * Return value: %TRUE if the window has been set to have decorations
2357 gtk_window_get_decorated (GtkWindow *window)
2359 g_return_val_if_fail (GTK_IS_WINDOW (window), TRUE);
2361 return window->decorated;
2364 static GtkWindowIconInfo*
2365 get_icon_info (GtkWindow *window)
2367 return g_object_get_data (G_OBJECT (window),
2368 "gtk-window-icon-info");
2372 free_icon_info (GtkWindowIconInfo *info)
2374 g_free (info->icon_name);
2379 static GtkWindowIconInfo*
2380 ensure_icon_info (GtkWindow *window)
2382 GtkWindowIconInfo *info;
2384 info = get_icon_info (window);
2388 info = g_new0 (GtkWindowIconInfo, 1);
2389 g_object_set_data_full (G_OBJECT (window),
2390 "gtk-window-icon-info",
2392 (GDestroyNotify)free_icon_info);
2404 static ScreenIconInfo *
2405 get_screen_icon_info (GdkScreen *screen)
2407 ScreenIconInfo *info = g_object_get_data (G_OBJECT (screen),
2408 "gtk-window-default-icon-pixmap");
2411 info = g_new0 (ScreenIconInfo, 1);
2412 g_object_set_data (G_OBJECT (screen), "gtk-window-default-icon-pixmap", info);
2415 if (info->serial != default_icon_serial)
2419 g_object_remove_weak_pointer (G_OBJECT (info->pixmap), (gpointer*)&info->pixmap);
2420 info->pixmap = NULL;
2425 g_object_remove_weak_pointer (G_OBJECT (info->mask), (gpointer*)&info->mask);
2429 info->serial = default_icon_serial;
2436 get_pixmap_and_mask (GdkWindow *window,
2437 GtkWindowIconInfo *parent_info,
2438 gboolean is_default_list,
2440 GdkPixmap **pmap_return,
2441 GdkBitmap **mask_return)
2443 GdkScreen *screen = gdk_drawable_get_screen (window);
2444 ScreenIconInfo *default_icon_info = get_screen_icon_info (screen);
2445 GdkPixbuf *best_icon;
2449 *pmap_return = NULL;
2450 *mask_return = NULL;
2452 if (is_default_list &&
2453 default_icon_info->pixmap != NULL)
2455 /* Use shared icon pixmap for all windows on this screen.
2457 if (default_icon_info->pixmap)
2458 g_object_ref (default_icon_info->pixmap);
2459 if (default_icon_info->mask)
2460 g_object_ref (default_icon_info->mask);
2462 *pmap_return = default_icon_info->pixmap;
2463 *mask_return = default_icon_info->mask;
2465 else if (parent_info && parent_info->icon_pixmap)
2467 if (parent_info->icon_pixmap)
2468 g_object_ref (parent_info->icon_pixmap);
2469 if (parent_info->icon_mask)
2470 g_object_ref (parent_info->icon_mask);
2472 *pmap_return = parent_info->icon_pixmap;
2473 *mask_return = parent_info->icon_mask;
2477 #define IDEAL_SIZE 48
2479 best_size = G_MAXINT;
2481 tmp_list = icon_list;
2482 while (tmp_list != NULL)
2484 GdkPixbuf *pixbuf = tmp_list->data;
2487 /* average width and height - if someone passes in a rectangular
2488 * icon they deserve what they get.
2490 this = gdk_pixbuf_get_width (pixbuf) + gdk_pixbuf_get_height (pixbuf);
2493 if (best_icon == NULL)
2500 /* icon is better if it's 32 pixels or larger, and closer to
2501 * the ideal size than the current best.
2504 (ABS (best_size - IDEAL_SIZE) <
2505 ABS (this - IDEAL_SIZE)))
2512 tmp_list = tmp_list->next;
2516 gdk_pixbuf_render_pixmap_and_mask_for_colormap (best_icon,
2517 gdk_screen_get_system_colormap (screen),
2522 /* Save pmap/mask for others to use if appropriate */
2525 parent_info->icon_pixmap = *pmap_return;
2526 parent_info->icon_mask = *mask_return;
2528 if (parent_info->icon_pixmap)
2529 g_object_ref (parent_info->icon_pixmap);
2530 if (parent_info->icon_mask)
2531 g_object_ref (parent_info->icon_mask);
2533 else if (is_default_list)
2535 default_icon_info->pixmap = *pmap_return;
2536 default_icon_info->mask = *mask_return;
2538 if (default_icon_info->pixmap)
2539 g_object_add_weak_pointer (G_OBJECT (default_icon_info->pixmap),
2540 (gpointer*)&default_icon_info->pixmap);
2541 if (default_icon_info->mask)
2542 g_object_add_weak_pointer (G_OBJECT (default_icon_info->mask),
2543 (gpointer*)&default_icon_info->mask);
2549 icon_list_from_theme (GtkWidget *widget,
2554 GtkIconTheme *icon_theme;
2559 icon_theme = gtk_icon_theme_get_for_screen (gtk_widget_get_screen (widget));
2561 sizes = gtk_icon_theme_get_icon_sizes (icon_theme, name);
2564 for (i = 0; sizes[i]; i++)
2567 * We need an EWMH extension to handle scalable icons
2568 * by passing their name to the WM. For now just use a
2572 icon = gtk_icon_theme_load_icon (icon_theme, name,
2575 icon = gtk_icon_theme_load_icon (icon_theme, name,
2578 list = g_list_append (list, icon);
2588 gtk_window_realize_icon (GtkWindow *window)
2591 GtkWindowIconInfo *info;
2594 widget = GTK_WIDGET (window);
2596 g_return_if_fail (widget->window != NULL);
2598 /* no point setting an icon on override-redirect */
2599 if (window->type == GTK_WINDOW_POPUP)
2604 info = ensure_icon_info (window);
2609 g_return_if_fail (info->icon_pixmap == NULL);
2610 g_return_if_fail (info->icon_mask == NULL);
2612 info->using_default_icon = FALSE;
2613 info->using_parent_icon = FALSE;
2614 info->using_themed_icon = FALSE;
2616 icon_list = info->icon_list;
2618 /* Look up themed icon */
2619 if (icon_list == NULL && info->icon_name)
2621 icon_list = icon_list_from_theme (widget, info->icon_name);
2623 info->using_themed_icon = TRUE;
2626 /* Inherit from transient parent */
2627 if (icon_list == NULL && window->transient_parent)
2629 icon_list = ensure_icon_info (window->transient_parent)->icon_list;
2631 info->using_parent_icon = TRUE;
2634 /* Inherit from default */
2635 if (icon_list == NULL)
2637 icon_list = default_icon_list;
2639 info->using_default_icon = TRUE;
2642 /* Look up themed icon */
2643 if (icon_list == NULL && default_icon_name)
2645 icon_list = icon_list_from_theme (widget, default_icon_name);
2646 info->using_default_icon = TRUE;
2647 info->using_themed_icon = TRUE;
2650 gdk_window_set_icon_list (widget->window, icon_list);
2652 get_pixmap_and_mask (widget->window,
2653 info->using_parent_icon ? ensure_icon_info (window->transient_parent) : NULL,
2654 info->using_default_icon,
2659 /* This is a slight ICCCM violation since it's a color pixmap not
2660 * a bitmap, but everyone does it.
2662 gdk_window_set_icon (widget->window,
2667 info->realized = TRUE;
2669 if (info->using_themed_icon)
2671 GtkIconTheme *icon_theme;
2673 g_list_foreach (icon_list, (GFunc) g_object_unref, NULL);
2674 g_list_free (icon_list);
2676 icon_theme = gtk_icon_theme_get_for_screen (gtk_widget_get_screen (GTK_WIDGET (window)));
2677 g_signal_connect (icon_theme, "changed",
2678 G_CALLBACK (update_themed_icon), window);
2683 gtk_window_unrealize_icon (GtkWindow *window)
2685 GtkWindowIconInfo *info;
2688 widget = GTK_WIDGET (window);
2690 info = get_icon_info (window);
2695 if (info->icon_pixmap)
2696 g_object_unref (info->icon_pixmap);
2698 if (info->icon_mask)
2699 g_object_unref (info->icon_mask);
2701 info->icon_pixmap = NULL;
2702 info->icon_mask = NULL;
2704 if (info->using_themed_icon)
2706 GtkIconTheme *icon_theme;
2708 icon_theme = gtk_icon_theme_get_for_screen (gtk_widget_get_screen (GTK_WIDGET (window)));
2710 g_signal_handlers_disconnect_by_func (icon_theme, update_themed_icon, window);
2713 /* We don't clear the properties on the window, just figure the
2714 * window is going away.
2717 info->realized = FALSE;
2722 * gtk_window_set_icon_list:
2723 * @window: a #GtkWindow
2724 * @list: list of #GdkPixbuf
2726 * Sets up the icon representing a #GtkWindow. The icon is used when
2727 * the window is minimized (also known as iconified). Some window
2728 * managers or desktop environments may also place it in the window
2729 * frame, or display it in other contexts.
2731 * gtk_window_set_icon_list() allows you to pass in the same icon in
2732 * several hand-drawn sizes. The list should contain the natural sizes
2733 * your icon is available in; that is, don't scale the image before
2734 * passing it to GTK+. Scaling is postponed until the last minute,
2735 * when the desired final size is known, to allow best quality.
2737 * By passing several sizes, you may improve the final image quality
2738 * of the icon, by reducing or eliminating automatic image scaling.
2740 * Recommended sizes to provide: 16x16, 32x32, 48x48 at minimum, and
2741 * larger images (64x64, 128x128) if you have them.
2743 * See also gtk_window_set_default_icon_list() to set the icon
2744 * for all windows in your application in one go.
2746 * Note that transient windows (those who have been set transient for another
2747 * window using gtk_window_set_transient_for()) will inherit their
2748 * icon from their transient parent. So there's no need to explicitly
2749 * set the icon on transient windows.
2752 gtk_window_set_icon_list (GtkWindow *window,
2755 GtkWindowIconInfo *info;
2757 g_return_if_fail (GTK_IS_WINDOW (window));
2759 info = ensure_icon_info (window);
2761 if (info->icon_list == list) /* check for NULL mostly */
2764 g_list_foreach (list,
2765 (GFunc) g_object_ref, NULL);
2767 g_list_foreach (info->icon_list,
2768 (GFunc) g_object_unref, NULL);
2770 g_list_free (info->icon_list);
2772 info->icon_list = g_list_copy (list);
2774 g_object_notify (G_OBJECT (window), "icon");
2776 gtk_window_unrealize_icon (window);
2778 if (GTK_WIDGET_REALIZED (window))
2779 gtk_window_realize_icon (window);
2781 /* We could try to update our transient children, but I don't think
2782 * it's really worth it. If we did it, the best way would probably
2783 * be to have children connect to notify::icon-list
2788 * gtk_window_get_icon_list:
2789 * @window: a #GtkWindow
2791 * Retrieves the list of icons set by gtk_window_set_icon_list().
2792 * The list is copied, but the reference count on each
2793 * member won't be incremented.
2795 * Return value: copy of window's icon list
2798 gtk_window_get_icon_list (GtkWindow *window)
2800 GtkWindowIconInfo *info;
2802 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
2804 info = get_icon_info (window);
2807 return g_list_copy (info->icon_list);
2813 * gtk_window_set_icon:
2814 * @window: a #GtkWindow
2815 * @icon: icon image, or %NULL
2817 * Sets up the icon representing a #GtkWindow. This icon is used when
2818 * the window is minimized (also known as iconified). Some window
2819 * managers or desktop environments may also place it in the window
2820 * frame, or display it in other contexts.
2822 * The icon should be provided in whatever size it was naturally
2823 * drawn; that is, don't scale the image before passing it to
2824 * GTK+. Scaling is postponed until the last minute, when the desired
2825 * final size is known, to allow best quality.
2827 * If you have your icon hand-drawn in multiple sizes, use
2828 * gtk_window_set_icon_list(). Then the best size will be used.
2830 * This function is equivalent to calling gtk_window_set_icon_list()
2831 * with a 1-element list.
2833 * See also gtk_window_set_default_icon_list() to set the icon
2834 * for all windows in your application in one go.
2837 gtk_window_set_icon (GtkWindow *window,
2842 g_return_if_fail (GTK_IS_WINDOW (window));
2843 g_return_if_fail (icon == NULL || GDK_IS_PIXBUF (icon));
2848 list = g_list_append (list, icon);
2850 gtk_window_set_icon_list (window, list);
2856 update_themed_icon (GtkIconTheme *icon_theme,
2859 g_object_notify (G_OBJECT (window), "icon");
2861 gtk_window_unrealize_icon (window);
2863 if (GTK_WIDGET_REALIZED (window))
2864 gtk_window_realize_icon (window);
2868 * gtk_window_set_icon_name:
2869 * @window: a #GtkWindow
2870 * @name: the name of the themed icon
2872 * Sets the icon for the window from a named themed icon. See
2873 * the docs for #GtkIconTheme for more details.
2875 * Note that this has nothing to do with the WM_ICON_NAME
2876 * property which is mentioned in the ICCCM.
2881 gtk_window_set_icon_name (GtkWindow *window,
2884 GtkWindowIconInfo *info;
2887 g_return_if_fail (GTK_IS_WINDOW (window));
2889 info = ensure_icon_info (window);
2891 tmp = info->icon_name;
2892 info->icon_name = g_strdup (name);
2895 g_list_foreach (info->icon_list, (GFunc) g_object_unref, NULL);
2896 g_list_free (info->icon_list);
2897 info->icon_list = NULL;
2899 update_themed_icon (NULL, window);
2901 g_object_notify (G_OBJECT (window), "icon_name");
2905 * gtk_window_get_icon_name:
2906 * @window: a #GtkWindow
2908 * Returns the name of the themed icon for the window,
2909 * see gtk_window_set_icon_name().
2911 * Returns: the icon name or %NULL if the window has
2916 G_CONST_RETURN gchar *
2917 gtk_window_get_icon_name (GtkWindow *window)
2919 GtkWindowIconInfo *info;
2921 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
2923 info = ensure_icon_info (window);
2925 return info->icon_name;
2929 * gtk_window_get_icon:
2930 * @window: a #GtkWindow
2932 * Gets the value set by gtk_window_set_icon() (or if you've
2933 * called gtk_window_set_icon_list(), gets the first icon in
2936 * Return value: icon for window
2939 gtk_window_get_icon (GtkWindow *window)
2941 GtkWindowIconInfo *info;
2943 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
2945 info = get_icon_info (window);
2946 if (info && info->icon_list)
2947 return GDK_PIXBUF (info->icon_list->data);
2952 /* Load pixbuf, printing warning on failure if error == NULL
2955 load_pixbuf_verbosely (const char *filename,
2958 GError *local_err = NULL;
2961 pixbuf = gdk_pixbuf_new_from_file (filename, &local_err);
2969 g_warning ("Error loading icon from file '%s':\n\t%s",
2970 filename, local_err->message);
2971 g_error_free (local_err);
2979 * gtk_window_set_icon_from_file:
2980 * @window: a #GtkWindow
2981 * @filename: location of icon file
2982 * @err: location to store error, or %NULL.
2984 * Sets the icon for @window.
2985 * Warns on failure if @err is %NULL.
2987 * This function is equivalent to calling gtk_window_set_icon()
2988 * with a pixbuf created by loading the image from @filename.
2990 * Returns: %TRUE if setting the icon succeeded.
2995 gtk_window_set_icon_from_file (GtkWindow *window,
2996 const gchar *filename,
2999 GdkPixbuf *pixbuf = load_pixbuf_verbosely (filename, err);
3003 gtk_window_set_icon (window, pixbuf);
3004 g_object_unref (pixbuf);
3013 * gtk_window_set_default_icon_list:
3014 * @list: a list of #GdkPixbuf
3016 * Sets an icon list to be used as fallback for windows that haven't
3017 * had gtk_window_set_icon_list() called on them to set up a
3018 * window-specific icon list. This function allows you to set up the
3019 * icon for all windows in your app at once.
3021 * See gtk_window_set_icon_list() for more details.
3025 gtk_window_set_default_icon_list (GList *list)
3029 if (list == default_icon_list)
3032 /* Update serial so we don't used cached pixmaps/masks
3034 default_icon_serial++;
3036 g_list_foreach (list,
3037 (GFunc) g_object_ref, NULL);
3039 g_list_foreach (default_icon_list,
3040 (GFunc) g_object_unref, NULL);
3042 g_list_free (default_icon_list);
3044 default_icon_list = g_list_copy (list);
3046 /* Update all toplevels */
3047 toplevels = gtk_window_list_toplevels ();
3048 tmp_list = toplevels;
3049 while (tmp_list != NULL)
3051 GtkWindowIconInfo *info;
3052 GtkWindow *w = tmp_list->data;
3054 info = get_icon_info (w);
3055 if (info && info->using_default_icon)
3057 gtk_window_unrealize_icon (w);
3058 if (GTK_WIDGET_REALIZED (w))
3059 gtk_window_realize_icon (w);
3062 tmp_list = tmp_list->next;
3064 g_list_free (toplevels);
3068 * gtk_window_set_default_icon:
3071 * Sets an icon to be used as fallback for windows that haven't
3072 * had gtk_window_set_icon() called on them from a pixbuf.
3077 gtk_window_set_default_icon (GdkPixbuf *icon)
3081 g_return_if_fail (GDK_IS_PIXBUF (icon));
3083 list = g_list_prepend (NULL, icon);
3084 gtk_window_set_default_icon_list (list);
3089 * gtk_window_set_default_icon_name:
3090 * @name: the name of the themed icon
3092 * Sets an icon to be used as fallback for windows that haven't
3093 * had gtk_window_set_icon_list() called on them from a named
3094 * themed icon, see gtk_window_set_icon_name().
3099 gtk_window_set_default_icon_name (const gchar *name)
3104 /* Update serial so we don't used cached pixmaps/masks
3106 default_icon_serial++;
3108 g_free (default_icon_name);
3109 default_icon_name = g_strdup (name);
3111 g_list_foreach (default_icon_list,
3112 (GFunc) g_object_unref, NULL);
3114 g_list_free (default_icon_list);
3115 default_icon_list = NULL;
3117 /* Update all toplevels */
3118 toplevels = gtk_window_list_toplevels ();
3119 tmp_list = toplevels;
3120 while (tmp_list != NULL)
3122 GtkWindowIconInfo *info;
3123 GtkWindow *w = tmp_list->data;
3125 info = get_icon_info (w);
3126 if (info && info->using_default_icon && info->using_themed_icon)
3128 gtk_window_unrealize_icon (w);
3129 if (GTK_WIDGET_REALIZED (w))
3130 gtk_window_realize_icon (w);
3133 tmp_list = tmp_list->next;
3135 g_list_free (toplevels);
3139 * gtk_window_set_default_icon_from_file:
3140 * @filename: location of icon file
3141 * @err: location to store error, or %NULL.
3143 * Sets an icon to be used as fallback for windows that haven't
3144 * had gtk_window_set_icon_list() called on them from a file
3145 * on disk. Warns on failure if @err is %NULL.
3147 * Returns: %TRUE if setting the icon succeeded.
3152 gtk_window_set_default_icon_from_file (const gchar *filename,
3155 GdkPixbuf *pixbuf = load_pixbuf_verbosely (filename, err);
3159 gtk_window_set_default_icon (pixbuf);
3160 g_object_unref (pixbuf);
3169 * gtk_window_get_default_icon_list:
3171 * Gets the value set by gtk_window_set_default_icon_list().
3172 * The list is a copy and should be freed with g_list_free(),
3173 * but the pixbufs in the list have not had their reference count
3176 * Return value: copy of default icon list
3179 gtk_window_get_default_icon_list (void)
3181 return g_list_copy (default_icon_list);
3185 gtk_window_set_default_size_internal (GtkWindow *window,
3186 gboolean change_width,
3188 gboolean change_height,
3190 gboolean is_geometry)
3192 GtkWindowGeometryInfo *info;
3194 g_return_if_fail (change_width == FALSE || width >= -1);
3195 g_return_if_fail (change_height == FALSE || height >= -1);
3197 info = gtk_window_get_geometry_info (window, TRUE);
3199 g_object_freeze_notify (G_OBJECT (window));
3201 info->default_is_geometry = is_geometry != FALSE;
3211 info->default_width = width;
3213 g_object_notify (G_OBJECT (window), "default_width");
3224 info->default_height = height;
3226 g_object_notify (G_OBJECT (window), "default_height");
3229 g_object_thaw_notify (G_OBJECT (window));
3231 gtk_widget_queue_resize (GTK_WIDGET (window));
3235 * gtk_window_set_default_size:
3236 * @window: a #GtkWindow
3237 * @width: width in pixels, or -1 to unset the default width
3238 * @height: height in pixels, or -1 to unset the default height
3240 * Sets the default size of a window. If the window's "natural" size
3241 * (its size request) is larger than the default, the default will be
3242 * ignored. More generally, if the default size does not obey the
3243 * geometry hints for the window (gtk_window_set_geometry_hints() can
3244 * be used to set these explicitly), the default size will be clamped
3245 * to the nearest permitted size.
3247 * Unlike gtk_widget_set_size_request(), which sets a size request for
3248 * a widget and thus would keep users from shrinking the window, this
3249 * function only sets the initial size, just as if the user had
3250 * resized the window themselves. Users can still shrink the window
3251 * again as they normally would. Setting a default size of -1 means to
3252 * use the "natural" default size (the size request of the window).
3254 * For more control over a window's initial size and how resizing works,
3255 * investigate gtk_window_set_geometry_hints().
3257 * For some uses, gtk_window_resize() is a more appropriate function.
3258 * gtk_window_resize() changes the current size of the window, rather
3259 * than the size to be used on initial display. gtk_window_resize() always
3260 * affects the window itself, not the geometry widget.
3262 * The default size of a window only affects the first time a window is
3263 * shown; if a window is hidden and re-shown, it will remember the size
3264 * it had prior to hiding, rather than using the default size.
3266 * Windows can't actually be 0x0 in size, they must be at least 1x1, but
3267 * passing 0 for @width and @height is OK, resulting in a 1x1 default size.
3270 gtk_window_set_default_size (GtkWindow *window,
3274 g_return_if_fail (GTK_IS_WINDOW (window));
3275 g_return_if_fail (width >= -1);
3276 g_return_if_fail (height >= -1);
3278 gtk_window_set_default_size_internal (window, TRUE, width, TRUE, height, FALSE);
3282 * gtk_window_get_default_size:
3283 * @window: a #GtkWindow
3284 * @width: location to store the default width, or %NULL
3285 * @height: location to store the default height, or %NULL
3287 * Gets the default size of the window. A value of -1 for the width or
3288 * height indicates that a default size has not been explicitly set
3289 * for that dimension, so the "natural" size of the window will be
3294 gtk_window_get_default_size (GtkWindow *window,
3298 GtkWindowGeometryInfo *info;
3300 g_return_if_fail (GTK_IS_WINDOW (window));
3302 info = gtk_window_get_geometry_info (window, FALSE);
3305 *width = info ? info->default_width : -1;
3308 *height = info ? info->default_height : -1;
3312 * gtk_window_resize:
3313 * @window: a #GtkWindow
3314 * @width: width in pixels to resize the window to
3315 * @height: height in pixels to resize the window to
3317 * Resizes the window as if the user had done so, obeying geometry
3318 * constraints. The default geometry constraint is that windows may
3319 * not be smaller than their size request; to override this
3320 * constraint, call gtk_widget_set_size_request() to set the window's
3321 * request to a smaller value.
3323 * If gtk_window_resize() is called before showing a window for the
3324 * first time, it overrides any default size set with
3325 * gtk_window_set_default_size().
3327 * Windows may not be resized smaller than 1 by 1 pixels.
3331 gtk_window_resize (GtkWindow *window,
3335 GtkWindowGeometryInfo *info;
3337 g_return_if_fail (GTK_IS_WINDOW (window));
3338 g_return_if_fail (width > 0);
3339 g_return_if_fail (height > 0);
3341 info = gtk_window_get_geometry_info (window, TRUE);
3343 info->resize_width = width;
3344 info->resize_height = height;
3346 gtk_widget_queue_resize (GTK_WIDGET (window));
3350 * gtk_window_get_size:
3351 * @window: a #GtkWindow
3352 * @width: return location for width, or %NULL
3353 * @height: return location for height, or %NULL
3355 * Obtains the current size of @window. If @window is not onscreen,
3356 * it returns the size GTK+ will suggest to the <link
3357 * linkend="gtk-X11-arch">window manager</link> for the initial window
3358 * size (but this is not reliably the same as the size the window
3359 * manager will actually select). The size obtained by
3360 * gtk_window_get_size() is the last size received in a
3361 * #GdkEventConfigure, that is, GTK+ uses its locally-stored size,
3362 * rather than querying the X server for the size. As a result, if you
3363 * call gtk_window_resize() then immediately call
3364 * gtk_window_get_size(), the size won't have taken effect yet. After
3365 * the window manager processes the resize request, GTK+ receives
3366 * notification that the size has changed via a configure event, and
3367 * the size of the window gets updated.
3369 * Note 1: Nearly any use of this function creates a race condition,
3370 * because the size of the window may change between the time that you
3371 * get the size and the time that you perform some action assuming
3372 * that size is the current size. To avoid race conditions, connect to
3373 * "configure_event" on the window and adjust your size-dependent
3374 * state to match the size delivered in the #GdkEventConfigure.
3376 * Note 2: The returned size does <emphasis>not</emphasis> include the
3377 * size of the window manager decorations (aka the window frame or
3378 * border). Those are not drawn by GTK+ and GTK+ has no reliable
3379 * method of determining their size.
3381 * Note 3: If you are getting a window size in order to position
3382 * the window onscreen, there may be a better way. The preferred
3383 * way is to simply set the window's semantic type with
3384 * gtk_window_set_type_hint(), which allows the window manager to
3385 * e.g. center dialogs. Also, if you set the transient parent of
3386 * dialogs with gtk_window_set_transient_for() window managers
3387 * will often center the dialog over its parent window. It's
3388 * much preferred to let the window manager handle these
3389 * things rather than doing it yourself, because all apps will
3390 * behave consistently and according to user prefs if the window
3391 * manager handles it. Also, the window manager can take the size
3392 * of the window decorations/border into account, while your
3393 * application cannot.
3395 * In any case, if you insist on application-specified window
3396 * positioning, there's <emphasis>still</emphasis> a better way than
3397 * doing it yourself - gtk_window_set_position() will frequently
3398 * handle the details for you.
3402 gtk_window_get_size (GtkWindow *window,
3409 g_return_if_fail (GTK_IS_WINDOW (window));
3411 widget = GTK_WIDGET (window);
3413 if (width == NULL && height == NULL)
3416 if (GTK_WIDGET_MAPPED (window))
3418 gdk_drawable_get_size (GTK_WIDGET (window)->window,
3423 GdkRectangle configure_request;
3425 gtk_window_compute_configure_request (window,
3429 w = configure_request.width;
3430 h = configure_request.height;
3441 * @window: a #GtkWindow
3442 * @x: X coordinate to move window to
3443 * @y: Y coordinate to move window to
3445 * Asks the <link linkend="gtk-X11-arch">window manager</link> to move
3446 * @window to the given position. Window managers are free to ignore
3447 * this; most window managers ignore requests for initial window
3448 * positions (instead using a user-defined placement algorithm) and
3449 * honor requests after the window has already been shown.
3451 * Note: the position is the position of the gravity-determined
3452 * reference point for the window. The gravity determines two things:
3453 * first, the location of the reference point in root window
3454 * coordinates; and second, which point on the window is positioned at
3455 * the reference point.
3457 * By default the gravity is #GDK_GRAVITY_NORTH_WEST, so the reference
3458 * point is simply the @x, @y supplied to gtk_window_move(). The
3459 * top-left corner of the window decorations (aka window frame or
3460 * border) will be placed at @x, @y. Therefore, to position a window
3461 * at the top left of the screen, you want to use the default gravity
3462 * (which is #GDK_GRAVITY_NORTH_WEST) and move the window to 0,0.
3464 * To position a window at the bottom right corner of the screen, you
3465 * would set #GDK_GRAVITY_SOUTH_EAST, which means that the reference
3466 * point is at @x + the window width and @y + the window height, and
3467 * the bottom-right corner of the window border will be placed at that
3468 * reference point. So, to place a window in the bottom right corner
3469 * you would first set gravity to south east, then write:
3470 * <literal>gtk_window_move (window, gdk_screen_width () - window_width,
3471 * gdk_screen_height () - window_height)</literal>.
3473 * The Extended Window Manager Hints specification at <ulink
3474 * url="http://www.freedesktop.org/Standards/wm-spec">
3475 * http://www.freedesktop.org/Standards/wm-spec</ulink> has a
3476 * nice table of gravities in the "implementation notes" section.
3478 * The gtk_window_get_position() documentation may also be relevant.
3482 gtk_window_move (GtkWindow *window,
3486 GtkWindowGeometryInfo *info;
3489 g_return_if_fail (GTK_IS_WINDOW (window));
3491 widget = GTK_WIDGET (window);
3493 info = gtk_window_get_geometry_info (window, TRUE);
3495 if (GTK_WIDGET_MAPPED (window))
3497 /* we have now sent a request with this position
3498 * with currently-active constraints, so toggle flag.
3500 info->position_constraints_changed = FALSE;
3502 /* we only constrain if mapped - if not mapped,
3503 * then gtk_window_compute_configure_request()
3504 * will apply the constraints later, and we
3505 * don't want to lose information about
3506 * what position the user set before then.
3507 * i.e. if you do a move() then turn off POS_CENTER
3508 * then show the window, your move() will work.
3510 gtk_window_constrain_position (window,
3511 widget->allocation.width,
3512 widget->allocation.height,
3515 /* Note that this request doesn't go through our standard request
3516 * framework, e.g. doesn't increment configure_request_count,
3517 * doesn't set info->last, etc.; that's because
3518 * we don't save the info needed to arrive at this same request
3521 * To gtk_window_move_resize(), this will end up looking exactly
3522 * the same as the position being changed by the window
3526 /* FIXME are we handling gravity properly for framed windows? */
3528 gdk_window_move (window->frame,
3529 x - window->frame_left,
3530 y - window->frame_top);
3532 gdk_window_move (GTK_WIDGET (window)->window,
3537 /* Save this position to apply on mapping */
3538 info->initial_x = x;
3539 info->initial_y = y;
3540 info->initial_pos_set = TRUE;
3545 * gtk_window_get_position:
3546 * @window: a #GtkWindow
3547 * @root_x: return location for X coordinate of gravity-determined reference p\oint
3548 * @root_y: return location for Y coordinate of gravity-determined reference p\oint
3550 * This function returns the position you need to pass to
3551 * gtk_window_move() to keep @window in its current position. This
3552 * means that the meaning of the returned value varies with window
3553 * gravity. See gtk_window_move() for more details.
3555 * If you haven't changed the window gravity, its gravity will be
3556 * #GDK_GRAVITY_NORTH_WEST. This means that gtk_window_get_position()
3557 * gets the position of the top-left corner of the window manager
3558 * frame for the window. gtk_window_move() sets the position of this
3559 * same top-left corner.
3561 * gtk_window_get_position() is not 100% reliable because the X Window System
3562 * does not specify a way to obtain the geometry of the
3563 * decorations placed on a window by the window manager.
3564 * Thus GTK+ is using a "best guess" that works with most
3567 * Moreover, nearly all window managers are historically broken with
3568 * respect to their handling of window gravity. So moving a window to
3569 * its current position as returned by gtk_window_get_position() tends
3570 * to result in moving the window slightly. Window managers are
3571 * slowly getting better over time.
3573 * If a window has gravity #GDK_GRAVITY_STATIC the window manager
3574 * frame is not relevant, and thus gtk_window_get_position() will
3575 * always produce accurate results. However you can't use static
3576 * gravity to do things like place a window in a corner of the screen,
3577 * because static gravity ignores the window manager decorations.
3579 * If you are saving and restoring your application's window
3580 * positions, you should know that it's impossible for applications to
3581 * do this without getting it somewhat wrong because applications do
3582 * not have sufficient knowledge of window manager state. The Correct
3583 * Mechanism is to support the session management protocol (see the
3584 * "GnomeClient" object in the GNOME libraries for example) and allow
3585 * the window manager to save your window sizes and positions.
3590 gtk_window_get_position (GtkWindow *window,
3596 g_return_if_fail (GTK_IS_WINDOW (window));
3598 widget = GTK_WIDGET (window);
3600 if (window->gravity == GDK_GRAVITY_STATIC)
3602 if (GTK_WIDGET_MAPPED (widget))
3604 /* This does a server round-trip, which is sort of wrong;
3605 * but a server round-trip is inevitable for
3606 * gdk_window_get_frame_extents() in the usual
3607 * NorthWestGravity case below, so not sure what else to
3608 * do. We should likely be consistent about whether we get
3609 * the client-side info or the server-side info.
3611 gdk_window_get_origin (widget->window, root_x, root_y);
3615 GdkRectangle configure_request;
3617 gtk_window_compute_configure_request (window,
3621 *root_x = configure_request.x;
3622 *root_y = configure_request.y;
3627 GdkRectangle frame_extents;
3632 if (GTK_WIDGET_MAPPED (widget))
3635 gdk_window_get_frame_extents (window->frame, &frame_extents);
3637 gdk_window_get_frame_extents (widget->window, &frame_extents);
3638 x = frame_extents.x;
3639 y = frame_extents.y;
3640 gtk_window_get_size (window, &w, &h);
3644 /* We just say the frame has 0 size on all sides.
3645 * Not sure what else to do.
3647 gtk_window_compute_configure_request (window,
3650 x = frame_extents.x;
3651 y = frame_extents.y;
3652 w = frame_extents.width;
3653 h = frame_extents.height;
3656 switch (window->gravity)
3658 case GDK_GRAVITY_NORTH:
3659 case GDK_GRAVITY_CENTER:
3660 case GDK_GRAVITY_SOUTH:
3661 /* Find center of frame. */
3662 x += frame_extents.width / 2;
3663 /* Center client window on that point. */
3667 case GDK_GRAVITY_SOUTH_EAST:
3668 case GDK_GRAVITY_EAST:
3669 case GDK_GRAVITY_NORTH_EAST:
3670 /* Find right edge of frame */
3671 x += frame_extents.width;
3672 /* Align left edge of client at that point. */
3679 switch (window->gravity)
3681 case GDK_GRAVITY_WEST:
3682 case GDK_GRAVITY_CENTER:
3683 case GDK_GRAVITY_EAST:
3684 /* Find center of frame. */
3685 y += frame_extents.height / 2;
3686 /* Center client window there. */
3689 case GDK_GRAVITY_SOUTH_WEST:
3690 case GDK_GRAVITY_SOUTH:
3691 case GDK_GRAVITY_SOUTH_EAST:
3692 /* Find south edge of frame */
3693 y += frame_extents.height;
3694 /* Place bottom edge of client there */
3709 * gtk_window_reshow_with_initial_size:
3710 * @window: a #GtkWindow
3712 * Hides @window, then reshows it, resetting the
3713 * default size and position of the window. Used
3714 * by GUI builders only.
3717 gtk_window_reshow_with_initial_size (GtkWindow *window)
3721 g_return_if_fail (GTK_IS_WINDOW (window));
3723 widget = GTK_WIDGET (window);
3725 gtk_widget_hide (widget);
3726 gtk_widget_unrealize (widget);
3727 gtk_widget_show (widget);
3731 gtk_window_destroy (GtkObject *object)
3733 GtkWindow *window = GTK_WINDOW (object);
3735 toplevel_list = g_slist_remove (toplevel_list, window);
3737 if (window->transient_parent)
3738 gtk_window_set_transient_for (window, NULL);
3740 /* frees the icons */
3741 gtk_window_set_icon_list (window, NULL);
3743 if (window->has_user_ref_count)
3745 window->has_user_ref_count = FALSE;
3746 g_object_unref (window);
3750 gtk_window_group_remove_window (window->group, window);
3752 gtk_window_free_key_hash (window);
3754 GTK_OBJECT_CLASS (parent_class)->destroy (object);
3758 gtk_window_finalize (GObject *object)
3760 GtkWindow *window = GTK_WINDOW (object);
3761 GtkMnemonicHash *mnemonic_hash;
3763 g_free (window->title);
3764 g_free (window->wmclass_name);
3765 g_free (window->wmclass_class);
3766 g_free (window->wm_role);
3768 mnemonic_hash = gtk_window_get_mnemonic_hash (window, FALSE);
3770 _gtk_mnemonic_hash_free (mnemonic_hash);
3772 if (window->geometry_info)
3774 if (window->geometry_info->widget)
3775 g_signal_handlers_disconnect_by_func (window->geometry_info->widget,
3776 gtk_widget_destroyed,
3777 &window->geometry_info->widget);
3778 g_free (window->geometry_info);
3781 if (window->keys_changed_handler)
3783 g_source_remove (window->keys_changed_handler);
3784 window->keys_changed_handler = 0;
3787 G_OBJECT_CLASS (parent_class)->finalize (object);
3791 gtk_window_show (GtkWidget *widget)
3793 GtkWindow *window = GTK_WINDOW (widget);
3794 GtkContainer *container = GTK_CONTAINER (window);
3795 gboolean need_resize;
3797 GTK_WIDGET_SET_FLAGS (widget, GTK_VISIBLE);
3799 need_resize = container->need_resize || !GTK_WIDGET_REALIZED (widget);
3800 container->need_resize = FALSE;
3804 GtkWindowGeometryInfo *info = gtk_window_get_geometry_info (window, TRUE);
3805 GtkAllocation allocation = { 0, 0 };
3806 GdkRectangle configure_request;
3807 GdkGeometry new_geometry;
3809 gboolean was_realized;
3811 /* We are going to go ahead and perform this configure request
3812 * and then emulate a configure notify by going ahead and
3813 * doing a size allocate. Sort of a synchronous
3814 * mini-copy of gtk_window_move_resize() here.
3816 gtk_window_compute_configure_request (window,
3821 /* We update this because we are going to go ahead
3822 * and gdk_window_resize() below, rather than
3825 info->last.configure_request.width = configure_request.width;
3826 info->last.configure_request.height = configure_request.height;
3828 /* and allocate the window - this is normally done
3829 * in move_resize in response to configure notify
3831 allocation.width = configure_request.width;
3832 allocation.height = configure_request.height;
3833 gtk_widget_size_allocate (widget, &allocation);
3835 /* Then we guarantee we have a realize */
3836 was_realized = FALSE;
3837 if (!GTK_WIDGET_REALIZED (widget))
3839 gtk_widget_realize (widget);
3840 was_realized = TRUE;
3843 /* Must be done after the windows are realized,
3844 * so that the decorations can be read
3846 gtk_decorated_window_calculate_frame_size (window);
3848 /* We only send configure request if we didn't just finish
3849 * creating the window; if we just created the window
3850 * then we created it with widget->allocation anyhow.
3853 gdk_window_move_resize (widget->window,
3854 configure_request.x,
3855 configure_request.y,
3856 configure_request.width,
3857 configure_request.height);
3860 gtk_container_check_resize (container);
3862 gtk_widget_map (widget);
3864 /* Try to make sure that we have some focused widget
3866 #ifdef GDK_WINDOWING_X11
3867 if (!window->focus_widget && !GTK_IS_PLUG (window))
3869 if (!window->focus_widget)
3871 gtk_window_move_focus (window, GTK_DIR_TAB_FORWARD);
3874 gtk_grab_add (widget);
3878 gtk_window_hide (GtkWidget *widget)
3880 GtkWindow *window = GTK_WINDOW (widget);
3882 GTK_WIDGET_UNSET_FLAGS (widget, GTK_VISIBLE);
3883 gtk_widget_unmap (widget);
3886 gtk_grab_remove (widget);
3890 gtk_window_map (GtkWidget *widget)
3892 GtkWindow *window = GTK_WINDOW (widget);
3893 GtkWindowPrivate *priv = GTK_WINDOW_GET_PRIVATE (window);
3894 GdkWindow *toplevel;
3896 GTK_WIDGET_SET_FLAGS (widget, GTK_MAPPED);
3898 if (window->bin.child &&
3899 GTK_WIDGET_VISIBLE (window->bin.child) &&
3900 !GTK_WIDGET_MAPPED (window->bin.child))
3901 gtk_widget_map (window->bin.child);
3904 toplevel = window->frame;
3906 toplevel = widget->window;
3908 if (window->maximize_initially)
3909 gdk_window_maximize (toplevel);
3911 gdk_window_unmaximize (toplevel);
3913 if (window->stick_initially)
3914 gdk_window_stick (toplevel);
3916 gdk_window_unstick (toplevel);
3918 if (window->iconify_initially)
3919 gdk_window_iconify (toplevel);
3921 gdk_window_deiconify (toplevel);
3923 if (priv->fullscreen_initially)
3924 gdk_window_fullscreen (toplevel);
3926 gdk_window_unfullscreen (toplevel);
3928 gdk_window_set_keep_above (toplevel, priv->above_initially);
3930 gdk_window_set_keep_below (toplevel, priv->below_initially);
3932 /* No longer use the default settings */
3933 window->need_default_size = FALSE;
3934 window->need_default_position = FALSE;
3936 gdk_window_show (widget->window);
3939 gdk_window_show (window->frame);
3941 if (!disable_startup_notification &&
3942 !sent_startup_notification)
3944 sent_startup_notification = TRUE;
3945 gdk_notify_startup_complete ();
3950 gtk_window_unmap (GtkWidget *widget)
3952 GtkWindow *window = GTK_WINDOW (widget);
3953 GtkWindowPrivate *priv = GTK_WINDOW_GET_PRIVATE (widget);
3954 GtkWindowGeometryInfo *info;
3955 GdkWindowState state;
3957 GTK_WIDGET_UNSET_FLAGS (widget, GTK_MAPPED);
3959 gdk_window_withdraw (window->frame);
3961 gdk_window_withdraw (widget->window);
3963 window->configure_request_count = 0;
3964 window->configure_notify_received = FALSE;
3966 /* on unmap, we reset the default positioning of the window,
3967 * so it's placed again, but we don't reset the default
3968 * size of the window, so it's remembered.
3970 window->need_default_position = TRUE;
3972 info = gtk_window_get_geometry_info (window, FALSE);
3975 info->initial_pos_set = FALSE;
3976 info->position_constraints_changed = FALSE;
3979 state = gdk_window_get_state (widget->window);
3980 window->iconify_initially = state & GDK_WINDOW_STATE_ICONIFIED;
3981 window->maximize_initially = state & GDK_WINDOW_STATE_MAXIMIZED;
3982 window->stick_initially = state & GDK_WINDOW_STATE_STICKY;
3983 priv->above_initially = state & GDK_WINDOW_STATE_ABOVE;
3984 priv->below_initially = state & GDK_WINDOW_STATE_BELOW;
3988 gtk_window_realize (GtkWidget *widget)
3991 GdkWindow *parent_window;
3992 GdkWindowAttr attributes;
3993 gint attributes_mask;
3995 window = GTK_WINDOW (widget);
3997 /* ensure widget tree is properly size allocated */
3998 if (widget->allocation.x == -1 &&
3999 widget->allocation.y == -1 &&
4000 widget->allocation.width == 1 &&
4001 widget->allocation.height == 1)
4003 GtkRequisition requisition;
4004 GtkAllocation allocation = { 0, 0, 200, 200 };
4006 gtk_widget_size_request (widget, &requisition);
4007 if (requisition.width || requisition.height)
4009 /* non-empty window */
4010 allocation.width = requisition.width;
4011 allocation.height = requisition.height;
4013 gtk_widget_size_allocate (widget, &allocation);
4015 _gtk_container_queue_resize (GTK_CONTAINER (widget));
4017 g_return_if_fail (!GTK_WIDGET_REALIZED (widget));
4020 GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED);
4022 switch (window->type)
4024 case GTK_WINDOW_TOPLEVEL:
4025 attributes.window_type = GDK_WINDOW_TOPLEVEL;
4027 case GTK_WINDOW_POPUP:
4028 attributes.window_type = GDK_WINDOW_TEMP;
4031 g_warning (G_STRLOC": Unknown window type %d!", window->type);
4035 attributes.title = window->title;
4036 attributes.wmclass_name = window->wmclass_name;
4037 attributes.wmclass_class = window->wmclass_class;
4038 attributes.wclass = GDK_INPUT_OUTPUT;
4039 attributes.visual = gtk_widget_get_visual (widget);
4040 attributes.colormap = gtk_widget_get_colormap (widget);
4042 if (window->has_frame)
4044 attributes.width = widget->allocation.width + window->frame_left + window->frame_right;
4045 attributes.height = widget->allocation.height + window->frame_top + window->frame_bottom;
4046 attributes.event_mask = (GDK_EXPOSURE_MASK |
4047 GDK_KEY_PRESS_MASK |
4048 GDK_ENTER_NOTIFY_MASK |
4049 GDK_LEAVE_NOTIFY_MASK |
4050 GDK_FOCUS_CHANGE_MASK |
4051 GDK_STRUCTURE_MASK |
4052 GDK_BUTTON_MOTION_MASK |
4053 GDK_POINTER_MOTION_HINT_MASK |
4054 GDK_BUTTON_PRESS_MASK |
4055 GDK_BUTTON_RELEASE_MASK);
4057 attributes_mask = GDK_WA_VISUAL | GDK_WA_COLORMAP;
4059 window->frame = gdk_window_new (gtk_widget_get_root_window (widget),
4060 &attributes, attributes_mask);
4062 gdk_window_set_user_data (window->frame, widget);
4064 attributes.window_type = GDK_WINDOW_CHILD;
4065 attributes.x = window->frame_left;
4066 attributes.y = window->frame_top;
4068 attributes_mask = GDK_WA_X | GDK_WA_Y;
4070 parent_window = window->frame;
4074 attributes_mask = 0;
4075 parent_window = gtk_widget_get_root_window (widget);
4078 attributes.width = widget->allocation.width;
4079 attributes.height = widget->allocation.height;
4080 attributes.event_mask = gtk_widget_get_events (widget);
4081 attributes.event_mask |= (GDK_EXPOSURE_MASK |
4082 GDK_KEY_PRESS_MASK |
4083 GDK_KEY_RELEASE_MASK |
4084 GDK_ENTER_NOTIFY_MASK |
4085 GDK_LEAVE_NOTIFY_MASK |
4086 GDK_FOCUS_CHANGE_MASK |
4087 GDK_STRUCTURE_MASK);
4089 attributes_mask |= GDK_WA_VISUAL | GDK_WA_COLORMAP;
4090 attributes_mask |= (window->title ? GDK_WA_TITLE : 0);
4091 attributes_mask |= (window->wmclass_name ? GDK_WA_WMCLASS : 0);
4093 widget->window = gdk_window_new (parent_window, &attributes, attributes_mask);
4095 gdk_window_enable_synchronized_configure (widget->window);
4097 gdk_window_set_user_data (widget->window, window);
4099 widget->style = gtk_style_attach (widget->style, widget->window);
4100 gtk_style_set_background (widget->style, widget->window, GTK_STATE_NORMAL);
4102 gtk_style_set_background (widget->style, window->frame, GTK_STATE_NORMAL);
4104 /* This is a bad hack to set the window background. */
4105 gtk_window_paint (widget, NULL);
4107 if (window->transient_parent &&
4108 GTK_WIDGET_REALIZED (window->transient_parent))
4109 gdk_window_set_transient_for (widget->window,
4110 GTK_WIDGET (window->transient_parent)->window);
4112 if (window->wm_role)
4113 gdk_window_set_role (widget->window, window->wm_role);
4115 if (!window->decorated)
4116 gdk_window_set_decorations (widget->window, 0);
4118 gdk_window_set_type_hint (widget->window, window->type_hint);
4120 if (gtk_window_get_skip_pager_hint (window))
4121 gdk_window_set_skip_pager_hint (widget->window, TRUE);
4123 if (gtk_window_get_skip_taskbar_hint (window))
4124 gdk_window_set_skip_taskbar_hint (widget->window, TRUE);
4126 if (gtk_window_get_accept_focus (window))
4127 gdk_window_set_accept_focus (widget->window, TRUE);
4129 gdk_window_set_accept_focus (widget->window, FALSE);
4131 if (gtk_window_get_focus_on_map (window))
4132 gdk_window_set_focus_on_map (widget->window, TRUE);
4134 gdk_window_set_focus_on_map (widget->window, FALSE);
4137 gdk_window_set_modal_hint (widget->window, TRUE);
4139 gdk_window_set_modal_hint (widget->window, FALSE);
4142 gtk_window_realize_icon (window);
4146 gtk_window_unrealize (GtkWidget *widget)
4149 GtkWindowGeometryInfo *info;
4151 window = GTK_WINDOW (widget);
4153 /* On unrealize, we reset the size of the window such
4154 * that we will re-apply the default sizing stuff
4155 * next time we show the window.
4157 * Default positioning is reset on unmap, instead of unrealize.
4159 window->need_default_size = TRUE;
4160 info = gtk_window_get_geometry_info (window, FALSE);
4163 info->resize_width = -1;
4164 info->resize_height = -1;
4165 info->last.configure_request.x = 0;
4166 info->last.configure_request.y = 0;
4167 info->last.configure_request.width = -1;
4168 info->last.configure_request.height = -1;
4169 /* be sure we reset geom hints on re-realize */
4170 info->last.flags = 0;
4175 gdk_window_set_user_data (window->frame, NULL);
4176 gdk_window_destroy (window->frame);
4177 window->frame = NULL;
4181 gtk_window_unrealize_icon (window);
4183 (* GTK_WIDGET_CLASS (parent_class)->unrealize) (widget);
4187 gtk_window_size_request (GtkWidget *widget,
4188 GtkRequisition *requisition)
4193 window = GTK_WINDOW (widget);
4194 bin = GTK_BIN (window);
4196 requisition->width = GTK_CONTAINER (window)->border_width * 2;
4197 requisition->height = GTK_CONTAINER (window)->border_width * 2;
4199 if (bin->child && GTK_WIDGET_VISIBLE (bin->child))
4201 GtkRequisition child_requisition;
4203 gtk_widget_size_request (bin->child, &child_requisition);
4205 requisition->width += child_requisition.width;
4206 requisition->height += child_requisition.height;
4211 gtk_window_size_allocate (GtkWidget *widget,
4212 GtkAllocation *allocation)
4215 GtkAllocation child_allocation;
4217 window = GTK_WINDOW (widget);
4218 widget->allocation = *allocation;
4220 if (window->bin.child && GTK_WIDGET_VISIBLE (window->bin.child))
4222 child_allocation.x = GTK_CONTAINER (window)->border_width;
4223 child_allocation.y = GTK_CONTAINER (window)->border_width;
4224 child_allocation.width =
4225 MAX (1, (gint)allocation->width - child_allocation.x * 2);
4226 child_allocation.height =
4227 MAX (1, (gint)allocation->height - child_allocation.y * 2);
4229 gtk_widget_size_allocate (window->bin.child, &child_allocation);
4232 if (GTK_WIDGET_REALIZED (widget) && window->frame)
4234 gdk_window_resize (window->frame,
4235 allocation->width + window->frame_left + window->frame_right,
4236 allocation->height + window->frame_top + window->frame_bottom);
4241 gtk_window_event (GtkWidget *widget, GdkEvent *event)
4244 gboolean return_val;
4246 window = GTK_WINDOW (widget);
4248 if (window->frame && (event->any.window == window->frame))
4250 if ((event->type != GDK_KEY_PRESS) &&
4251 (event->type != GDK_KEY_RELEASE) &&
4252 (event->type != GDK_FOCUS_CHANGE))
4254 g_signal_stop_emission_by_name (widget, "event");
4256 g_signal_emit (widget, window_signals[FRAME_EVENT], 0, event, &return_val);
4261 g_object_unref (event->any.window);
4262 event->any.window = g_object_ref (widget->window);
4270 gtk_window_frame_event (GtkWindow *window, GdkEvent *event)
4272 GdkEventConfigure *configure_event;
4275 switch (event->type)
4278 configure_event = (GdkEventConfigure *)event;
4280 /* Invalidate the decorations */
4283 rect.width = configure_event->width;
4284 rect.height = configure_event->height;
4286 gdk_window_invalidate_rect (window->frame, &rect, FALSE);
4288 /* Pass on the (modified) configure event */
4289 configure_event->width -= window->frame_left + window->frame_right;
4290 configure_event->height -= window->frame_top + window->frame_bottom;
4291 return gtk_window_configure_event (GTK_WIDGET (window), configure_event);
4300 gtk_window_configure_event (GtkWidget *widget,
4301 GdkEventConfigure *event)
4303 GtkWindow *window = GTK_WINDOW (widget);
4304 gboolean expected_reply = window->configure_request_count > 0;
4306 /* window->configure_request_count incremented for each
4307 * configure request, and decremented to a min of 0 for
4308 * each configure notify.
4310 * All it means is that we know we will get at least
4311 * window->configure_request_count more configure notifies.
4312 * We could get more configure notifies than that; some
4313 * of the configure notifies we get may be unrelated to
4314 * the configure requests. But we will get at least
4315 * window->configure_request_count notifies.
4318 if (window->configure_request_count > 0)
4319 window->configure_request_count -= 1;
4321 /* As an optimization, we avoid a resize when possible.
4323 * The only times we can avoid a resize are:
4324 * - we know only the position changed, not the size
4325 * - we know we have made more requests and so will get more
4326 * notifies and can wait to resize when we get them
4329 if (!expected_reply &&
4330 (widget->allocation.width == event->width &&
4331 widget->allocation.height == event->height))
4333 gdk_window_configure_finished (widget->window);
4338 * If we do need to resize, we do that by:
4339 * - filling in widget->allocation with the new size
4340 * - setting configure_notify_received to TRUE
4341 * for use in gtk_window_move_resize()
4342 * - queueing a resize, leading to invocation of
4343 * gtk_window_move_resize() in an idle handler
4347 window->configure_notify_received = TRUE;
4349 widget->allocation.width = event->width;
4350 widget->allocation.height = event->height;
4352 _gtk_container_queue_resize (GTK_CONTAINER (widget));
4357 /* the accel_key and accel_mods fields of the key have to be setup
4358 * upon calling this function. it'll then return whether that key
4359 * is at all used as accelerator, and if so will OR in the
4360 * accel_flags member of the key.
4363 _gtk_window_query_nonaccels (GtkWindow *window,
4365 GdkModifierType accel_mods)
4367 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
4369 /* movement keys are considered locked accels */
4372 static const guint bindings[] = {
4373 GDK_space, GDK_KP_Space, GDK_Return, GDK_KP_Enter, GDK_Up, GDK_KP_Up, GDK_Down, GDK_KP_Down,
4374 GDK_Left, GDK_KP_Left, GDK_Right, GDK_KP_Right, GDK_Tab, GDK_KP_Tab, GDK_ISO_Left_Tab,
4378 for (i = 0; i < G_N_ELEMENTS (bindings); i++)
4379 if (bindings[i] == accel_key)
4383 /* mnemonics are considered locked accels */
4384 if (accel_mods == window->mnemonic_modifier)
4386 GtkMnemonicHash *mnemonic_hash = gtk_window_get_mnemonic_hash (window, FALSE);
4387 if (mnemonic_hash && _gtk_mnemonic_hash_lookup (mnemonic_hash, accel_key))
4395 * gtk_window_propagate_key_event:
4396 * @window: a #GtkWindow
4397 * @event: a #GdkEventKey
4399 * Propagate a key press or release event to the focus widget and
4400 * up the focus container chain until a widget handles @event.
4401 * This is normally called by the default ::key_press_event and
4402 * ::key_release_event handlers for toplevel windows,
4403 * however in some cases it may be useful to call this directly when
4404 * overriding the standard key handling for a toplevel window.
4406 * Return value: %TRUE if a widget in the focus chain handled the event.
4409 gtk_window_propagate_key_event (GtkWindow *window,
4412 gboolean handled = FALSE;
4413 GtkWidget *widget, *focus;
4415 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
4417 widget = GTK_WIDGET (window);
4418 focus = window->focus_widget;
4420 g_object_ref (focus);
4423 focus && focus != widget &&
4424 gtk_widget_get_toplevel (focus) == widget)
4428 if (GTK_WIDGET_IS_SENSITIVE (focus))
4429 handled = gtk_widget_event (focus, (GdkEvent*) event);
4431 parent = focus->parent;
4433 g_object_ref (parent);
4435 g_object_unref (focus);
4441 g_object_unref (focus);
4447 gtk_window_key_press_event (GtkWidget *widget,
4450 GtkWindow *window = GTK_WINDOW (widget);
4451 gboolean handled = FALSE;
4453 /* handle mnemonics and accelerators */
4455 handled = gtk_window_activate_key (window, event);
4457 /* handle focus widget key events */
4459 handled = gtk_window_propagate_key_event (window, event);
4461 /* Chain up, invokes binding set */
4463 handled = GTK_WIDGET_CLASS (parent_class)->key_press_event (widget, event);
4469 gtk_window_key_release_event (GtkWidget *widget,
4472 GtkWindow *window = GTK_WINDOW (widget);
4473 gboolean handled = FALSE;
4475 /* handle focus widget key events */
4477 handled = gtk_window_propagate_key_event (window, event);
4479 /* Chain up, invokes binding set */
4481 handled = GTK_WIDGET_CLASS (parent_class)->key_press_event (widget, event);
4487 gtk_window_real_activate_default (GtkWindow *window)
4489 gtk_window_activate_default (window);
4493 gtk_window_real_activate_focus (GtkWindow *window)
4495 gtk_window_activate_focus (window);
4499 gtk_window_move_focus (GtkWindow *window,
4500 GtkDirectionType dir)
4502 gtk_widget_child_focus (GTK_WIDGET (window), dir);
4504 if (!GTK_CONTAINER (window)->focus_child)
4505 gtk_window_set_focus (window, NULL);
4509 gtk_window_enter_notify_event (GtkWidget *widget,
4510 GdkEventCrossing *event)
4516 gtk_window_leave_notify_event (GtkWidget *widget,
4517 GdkEventCrossing *event)
4523 do_focus_change (GtkWidget *widget,
4526 GdkEvent *fevent = gdk_event_new (GDK_FOCUS_CHANGE);
4528 g_object_ref (widget);
4531 GTK_WIDGET_SET_FLAGS (widget, GTK_HAS_FOCUS);
4533 GTK_WIDGET_UNSET_FLAGS (widget, GTK_HAS_FOCUS);
4535 fevent->focus_change.type = GDK_FOCUS_CHANGE;
4536 fevent->focus_change.window = widget->window;
4538 g_object_ref (widget->window);
4539 fevent->focus_change.in = in;
4541 gtk_widget_event (widget, fevent);
4543 g_object_notify (G_OBJECT (widget), "has_focus");
4545 g_object_unref (widget);
4546 gdk_event_free (fevent);
4550 gtk_window_focus_in_event (GtkWidget *widget,
4551 GdkEventFocus *event)
4553 GtkWindow *window = GTK_WINDOW (widget);
4555 /* It appears spurious focus in events can occur when
4556 * the window is hidden. So we'll just check to see if
4557 * the window is visible before actually handling the
4560 if (GTK_WIDGET_VISIBLE (widget))
4562 _gtk_window_set_has_toplevel_focus (window, TRUE);
4563 _gtk_window_set_is_active (window, TRUE);
4570 gtk_window_focus_out_event (GtkWidget *widget,
4571 GdkEventFocus *event)
4573 GtkWindow *window = GTK_WINDOW (widget);
4575 _gtk_window_set_has_toplevel_focus (window, FALSE);
4576 _gtk_window_set_is_active (window, FALSE);
4581 static GdkAtom atom_rcfiles = GDK_NONE;
4584 gtk_window_read_rcfiles (GtkWidget *widget,
4585 GdkEventClient *event)
4587 GList *embedded_windows;
4589 embedded_windows = g_object_get_data (G_OBJECT (widget), "gtk-embedded");
4590 if (embedded_windows)
4592 GdkEvent *send_event = gdk_event_new (GDK_CLIENT_EVENT);
4595 for (i = 0; i < 5; i++)
4596 send_event->client.data.l[i] = 0;
4597 send_event->client.data_format = 32;
4598 send_event->client.message_type = atom_rcfiles;
4600 while (embedded_windows)
4602 guint xid = GPOINTER_TO_UINT (embedded_windows->data);
4603 gdk_event_send_client_message_for_display (gtk_widget_get_display (widget), send_event, xid);
4604 embedded_windows = embedded_windows->next;
4607 gdk_event_free (send_event);
4610 gtk_rc_reparse_all_for_settings (gtk_widget_get_settings (widget), FALSE);
4614 gtk_window_client_event (GtkWidget *widget,
4615 GdkEventClient *event)
4618 atom_rcfiles = gdk_atom_intern ("_GTK_READ_RCFILES", FALSE);
4620 if (event->message_type == atom_rcfiles)
4621 gtk_window_read_rcfiles (widget, event);
4627 gtk_window_check_resize (GtkContainer *container)
4629 GtkWindow *window = GTK_WINDOW (container);
4631 if (GTK_WIDGET_VISIBLE (container))
4632 gtk_window_move_resize (window);
4636 gtk_window_focus (GtkWidget *widget,
4637 GtkDirectionType direction)
4641 GtkContainer *container;
4642 GtkWidget *old_focus_child;
4645 container = GTK_CONTAINER (widget);
4646 window = GTK_WINDOW (widget);
4647 bin = GTK_BIN (widget);
4649 old_focus_child = container->focus_child;
4651 /* We need a special implementation here to deal properly with wrapping
4652 * around in the tab chain without the danger of going into an
4655 if (old_focus_child)
4657 if (gtk_widget_child_focus (old_focus_child, direction))
4661 if (window->focus_widget)
4663 if (direction == GTK_DIR_LEFT ||
4664 direction == GTK_DIR_RIGHT ||
4665 direction == GTK_DIR_UP ||
4666 direction == GTK_DIR_DOWN)
4671 /* Wrapped off the end, clear the focus setting for the toplpevel */
4672 parent = window->focus_widget->parent;
4675 gtk_container_set_focus_child (GTK_CONTAINER (parent), NULL);
4676 parent = GTK_WIDGET (parent)->parent;
4679 gtk_window_set_focus (GTK_WINDOW (container), NULL);
4682 /* Now try to focus the first widget in the window */
4685 if (gtk_widget_child_focus (bin->child, direction))
4693 gtk_window_real_set_focus (GtkWindow *window,
4696 GtkWidget *old_focus = window->focus_widget;
4697 gboolean had_default = FALSE;
4701 g_object_ref (old_focus);
4702 g_object_freeze_notify (G_OBJECT (old_focus));
4706 g_object_ref (focus);
4707 g_object_freeze_notify (G_OBJECT (focus));
4710 if (window->default_widget)
4711 had_default = GTK_WIDGET_HAS_DEFAULT (window->default_widget);
4713 if (window->focus_widget)
4715 if (GTK_WIDGET_RECEIVES_DEFAULT (window->focus_widget) &&
4716 (window->focus_widget != window->default_widget))
4718 GTK_WIDGET_UNSET_FLAGS (window->focus_widget, GTK_HAS_DEFAULT);
4720 if (window->default_widget)
4721 GTK_WIDGET_SET_FLAGS (window->default_widget, GTK_HAS_DEFAULT);
4724 window->focus_widget = NULL;
4726 if (window->has_focus)
4727 do_focus_change (old_focus, FALSE);
4729 g_object_notify (G_OBJECT (old_focus), "is_focus");
4732 /* The above notifications may have set a new focus widget,
4733 * if so, we don't want to override it.
4735 if (focus && !window->focus_widget)
4737 window->focus_widget = focus;
4739 if (GTK_WIDGET_RECEIVES_DEFAULT (window->focus_widget) &&
4740 (window->focus_widget != window->default_widget))
4742 if (GTK_WIDGET_CAN_DEFAULT (window->focus_widget))
4743 GTK_WIDGET_SET_FLAGS (window->focus_widget, GTK_HAS_DEFAULT);
4745 if (window->default_widget)
4746 GTK_WIDGET_UNSET_FLAGS (window->default_widget, GTK_HAS_DEFAULT);
4749 if (window->has_focus)
4750 do_focus_change (window->focus_widget, TRUE);
4752 g_object_notify (G_OBJECT (window->focus_widget), "is_focus");
4755 /* If the default widget changed, a redraw will have been queued
4756 * on the old and new default widgets by gtk_window_set_default(), so
4757 * we only have to worry about the case where it didn't change.
4758 * We'll sometimes queue a draw twice on the new widget but that
4761 if (window->default_widget &&
4762 (had_default != GTK_WIDGET_HAS_DEFAULT (window->default_widget)))
4763 gtk_widget_queue_draw (window->default_widget);
4767 g_object_thaw_notify (G_OBJECT (old_focus));
4768 g_object_unref (old_focus);
4772 g_object_thaw_notify (G_OBJECT (focus));
4773 g_object_unref (focus);
4778 * _gtk_window_unset_focus_and_default:
4779 * @window: a #GtkWindow
4780 * @widget: a widget inside of @window
4782 * Checks whether the focus and default widgets of @window are
4783 * @widget or a descendent of @widget, and if so, unset them.
4786 _gtk_window_unset_focus_and_default (GtkWindow *window,
4792 g_object_ref (window);
4793 g_object_ref (widget);
4795 if (GTK_CONTAINER (widget->parent)->focus_child == widget)
4797 child = window->focus_widget;
4799 while (child && child != widget)
4800 child = child->parent;
4802 if (child == widget)
4803 gtk_window_set_focus (GTK_WINDOW (window), NULL);
4806 child = window->default_widget;
4808 while (child && child != widget)
4809 child = child->parent;
4811 if (child == widget)
4812 gtk_window_set_default (window, NULL);
4814 g_object_unref (widget);
4815 g_object_unref (window);
4818 /*********************************
4819 * Functions related to resizing *
4820 *********************************/
4822 /* This function doesn't constrain to geometry hints */
4824 gtk_window_compute_configure_request_size (GtkWindow *window,
4828 GtkRequisition requisition;
4829 GtkWindowGeometryInfo *info;
4833 * - we've done a size request
4836 widget = GTK_WIDGET (window);
4838 info = gtk_window_get_geometry_info (window, FALSE);
4840 if (window->need_default_size)
4842 gtk_widget_get_child_requisition (widget, &requisition);
4844 /* Default to requisition */
4845 *width = requisition.width;
4846 *height = requisition.height;
4848 /* If window is empty so requests 0, default to random nonzero size */
4849 if (*width == 0 && *height == 0)
4855 /* Override requisition with default size */
4859 gint base_width = 0;
4860 gint base_height = 0;
4862 gint height_inc = 1;
4864 if (info->default_is_geometry &&
4865 (info->default_width > 0 || info->default_height > 0))
4867 GdkGeometry geometry;
4870 gtk_window_compute_hints (window, &geometry, &flags);
4872 if (flags & GDK_HINT_BASE_SIZE)
4874 base_width = geometry.base_width;
4875 base_height = geometry.base_height;
4877 else if (flags & GDK_HINT_MIN_SIZE)
4879 base_width = geometry.min_width;
4880 base_height = geometry.min_height;
4882 if (flags & GDK_HINT_RESIZE_INC)
4884 width_inc = geometry.width_inc;
4885 height_inc = geometry.height_inc;
4889 if (info->default_width > 0)
4890 *width = info->default_width * width_inc + base_width;
4892 if (info->default_height > 0)
4893 *height = info->default_height * height_inc + base_height;
4898 /* Default to keeping current size */
4899 *width = widget->allocation.width;
4900 *height = widget->allocation.height;
4903 /* Override any size with gtk_window_resize() values */
4906 if (info->resize_width > 0)
4907 *width = info->resize_width;
4909 if (info->resize_height > 0)
4910 *height = info->resize_height;
4914 static GtkWindowPosition
4915 get_effective_position (GtkWindow *window)
4917 GtkWindowPosition pos = window->position;
4918 if (pos == GTK_WIN_POS_CENTER_ON_PARENT &&
4919 (window->transient_parent == NULL ||
4920 !GTK_WIDGET_MAPPED (window->transient_parent)))
4921 pos = GTK_WIN_POS_NONE;
4927 get_center_monitor_of_window (GtkWindow *window)
4929 /* We could try to sort out the relative positions of the monitors and
4930 * stuff, or we could just be losers and assume you have a row
4931 * or column of monitors.
4933 return gdk_screen_get_n_monitors (gtk_window_check_screen (window)) / 2;
4937 get_monitor_containing_pointer (GtkWindow *window)
4941 GdkScreen *window_screen;
4942 GdkScreen *pointer_screen;
4944 window_screen = gtk_window_check_screen (window);
4945 gdk_display_get_pointer (gdk_screen_get_display (window_screen),
4949 if (pointer_screen == window_screen)
4950 monitor_num = gdk_screen_get_monitor_at_point (pointer_screen, px, py);
4958 center_window_on_monitor (GtkWindow *window,
4964 GdkRectangle monitor;
4967 monitor_num = get_monitor_containing_pointer (window);
4969 if (monitor_num == -1)
4970 monitor_num = get_center_monitor_of_window (window);
4972 gdk_screen_get_monitor_geometry (gtk_window_check_screen (window),
4973 monitor_num, &monitor);
4975 *x = (monitor.width - w) / 2 + monitor.x;
4976 *y = (monitor.height - h) / 2 + monitor.y;
4978 /* Be sure we aren't off the monitor, ignoring _NET_WM_STRUT
4979 * and WM decorations.
4988 clamp_window_to_rectangle (gint *x,
4992 const GdkRectangle *rect)
4994 gint outside_w, outside_h;
4996 outside_w = (*x + w) - (rect->x + rect->width);
5000 outside_h = (*y + h) - (rect->y + rect->height);
5004 /* if larger than the screen, center on the screen. */
5006 *x += (rect->x - *x) / 2;
5008 *y += (rect->y - *y) / 2;
5013 gtk_window_compute_configure_request (GtkWindow *window,
5014 GdkRectangle *request,
5015 GdkGeometry *geometry,
5018 GdkGeometry new_geometry;
5022 GtkWindowPosition pos;
5023 GtkWidget *parent_widget;
5024 GtkWindowGeometryInfo *info;
5028 widget = GTK_WIDGET (window);
5030 screen = gtk_window_check_screen (window);
5032 gtk_widget_size_request (widget, NULL);
5033 gtk_window_compute_configure_request_size (window, &w, &h);
5035 gtk_window_compute_hints (window, &new_geometry, &new_flags);
5036 gtk_window_constrain_size (window,
5037 &new_geometry, new_flags,
5041 parent_widget = (GtkWidget*) window->transient_parent;
5043 pos = get_effective_position (window);
5044 info = gtk_window_get_geometry_info (window, TRUE);
5046 /* by default, don't change position requested */
5047 x = info->last.configure_request.x;
5048 y = info->last.configure_request.y;
5050 if (window->need_default_position)
5053 /* FIXME this all interrelates with window gravity.
5054 * For most of them I think we want to set GRAVITY_CENTER.
5056 * Not sure how to go about that.
5061 /* here we are only handling CENTER_ALWAYS
5062 * as it relates to default positioning,
5063 * where it's equivalent to simply CENTER
5065 case GTK_WIN_POS_CENTER_ALWAYS:
5066 case GTK_WIN_POS_CENTER:
5067 center_window_on_monitor (window, w, h, &x, &y);
5070 case GTK_WIN_POS_CENTER_ON_PARENT:
5073 GdkRectangle monitor;
5076 g_assert (GTK_WIDGET_MAPPED (parent_widget)); /* established earlier */
5078 if (parent_widget->window != NULL)
5079 monitor_num = gdk_screen_get_monitor_at_window (screen,
5080 parent_widget->window);
5084 gdk_window_get_origin (parent_widget->window,
5087 x = ox + (parent_widget->allocation.width - w) / 2;
5088 y = oy + (parent_widget->allocation.height - h) / 2;
5090 /* Clamp onto current monitor, ignoring _NET_WM_STRUT and
5091 * WM decorations. If parent wasn't on a monitor, just
5094 if (monitor_num >= 0)
5096 gdk_screen_get_monitor_geometry (screen, monitor_num, &monitor);
5097 clamp_window_to_rectangle (&x, &y, w, h, &monitor);
5102 case GTK_WIN_POS_MOUSE:
5104 gint screen_width = gdk_screen_get_width (screen);
5105 gint screen_height = gdk_screen_get_height (screen);
5107 GdkRectangle monitor;
5108 GdkScreen *pointer_screen;
5111 gdk_display_get_pointer (gdk_screen_get_display (screen),
5115 if (pointer_screen == screen)
5116 monitor_num = gdk_screen_get_monitor_at_point (screen, px, py);
5122 x = CLAMP (x, 0, screen_width - w);
5123 y = CLAMP (y, 0, screen_height - h);
5125 /* Clamp onto current monitor, ignoring _NET_WM_STRUT and
5126 * WM decorations. Don't try to figure out what's going
5127 * on if the mouse wasn't inside a monitor.
5129 if (monitor_num >= 0)
5131 gdk_screen_get_monitor_geometry (screen, monitor_num, &monitor);
5132 clamp_window_to_rectangle (&x, &y, w, h, &monitor);
5140 } /* if (window->need_default_position) */
5142 if (window->need_default_position &&
5143 info->initial_pos_set)
5145 x = info->initial_x;
5146 y = info->initial_y;
5147 gtk_window_constrain_position (window, w, h, &x, &y);
5153 request->height = h;
5156 *geometry = new_geometry;
5162 gtk_window_constrain_position (GtkWindow *window,
5168 /* See long comments in gtk_window_move_resize()
5169 * on when it's safe to call this function.
5171 if (window->position == GTK_WIN_POS_CENTER_ALWAYS)
5173 gint center_x, center_y;
5175 center_window_on_monitor (window, new_width, new_height, ¢er_x, ¢er_y);
5183 gtk_window_move_resize (GtkWindow *window)
5187 * First we determine whether any information has changed that would
5188 * cause us to revise our last configure request. If we would send
5189 * a different configure request from last time, then
5190 * configure_request_size_changed = TRUE or
5191 * configure_request_pos_changed = TRUE. configure_request_size_changed
5192 * may be true due to new hints, a gtk_window_resize(), or whatever.
5193 * configure_request_pos_changed may be true due to gtk_window_set_position()
5194 * or gtk_window_move().
5196 * If the configure request has changed, we send off a new one. To
5197 * ensure GTK+ invariants are maintained (resize queue does what it
5198 * should), we go ahead and size_allocate the requested size in this
5201 * If the configure request has not changed, we don't ever resend
5202 * it, because it could mean fighting the user or window manager.
5205 * To prepare the configure request, we come up with a base size/pos:
5206 * - the one from gtk_window_move()/gtk_window_resize()
5207 * - else default_width, default_height if we haven't ever
5209 * - else the size request if we haven't ever been mapped,
5210 * as a substitute default size
5211 * - else the current size of the window, as received from
5212 * configure notifies (i.e. the current allocation)
5214 * If GTK_WIN_POS_CENTER_ALWAYS is active, we constrain
5215 * the position request to be centered.
5218 GtkContainer *container;
5219 GtkWindowGeometryInfo *info;
5220 GdkGeometry new_geometry;
5222 GdkRectangle new_request;
5223 gboolean configure_request_size_changed;
5224 gboolean configure_request_pos_changed;
5225 gboolean hints_changed; /* do we need to send these again */
5226 GtkWindowLastGeometryInfo saved_last_info;
5228 widget = GTK_WIDGET (window);
5229 container = GTK_CONTAINER (widget);
5230 info = gtk_window_get_geometry_info (window, TRUE);
5232 configure_request_size_changed = FALSE;
5233 configure_request_pos_changed = FALSE;
5235 gtk_window_compute_configure_request (window, &new_request,
5236 &new_geometry, &new_flags);
5238 /* This check implies the invariant that we never set info->last
5239 * without setting the hints and sending off a configure request.
5241 * If we change info->last without sending the request, we may
5244 if (info->last.configure_request.x != new_request.x ||
5245 info->last.configure_request.y != new_request.y)
5246 configure_request_pos_changed = TRUE;
5248 if ((info->last.configure_request.width != new_request.width ||
5249 info->last.configure_request.height != new_request.height))
5250 configure_request_size_changed = TRUE;
5252 hints_changed = FALSE;
5254 if (!gtk_window_compare_hints (&info->last.geometry, info->last.flags,
5255 &new_geometry, new_flags))
5257 hints_changed = TRUE;
5260 /* Position Constraints
5261 * ====================
5263 * POS_CENTER_ALWAYS is conceptually a constraint rather than
5264 * a default. The other POS_ values are used only when the
5265 * window is shown, not after that.
5267 * However, we can't implement a position constraint as
5268 * "anytime the window size changes, center the window"
5269 * because this may well end up fighting the WM or user. In
5270 * fact it gets in an infinite loop with at least one WM.
5272 * Basically, applications are in no way in a position to
5273 * constrain the position of a window, with one exception:
5274 * override redirect windows. (Really the intended purpose
5275 * of CENTER_ALWAYS anyhow, I would think.)
5277 * So the way we implement this "constraint" is to say that when WE
5278 * cause a move or resize, i.e. we make a configure request changing
5279 * window size, we recompute the CENTER_ALWAYS position to reflect
5280 * the new window size, and include it in our request. Also, if we
5281 * just turned on CENTER_ALWAYS we snap to center with a new
5282 * request. Otherwise, if we are just NOTIFIED of a move or resize
5283 * done by someone else e.g. the window manager, we do NOT send a
5284 * new configure request.
5286 * For override redirect windows, this works fine; all window
5287 * sizes are from our configure requests. For managed windows,
5288 * it is at least semi-sane, though who knows what the
5289 * app author is thinking.
5292 /* This condition should be kept in sync with the condition later on
5293 * that determines whether we send a configure request. i.e. we
5294 * should do this position constraining anytime we were going to
5295 * send a configure request anyhow, plus when constraints have
5298 if (configure_request_pos_changed ||
5299 configure_request_size_changed ||
5301 info->position_constraints_changed)
5303 /* We request the constrained position if:
5304 * - we were changing position, and need to clamp
5305 * the change to the constraint
5306 * - we're changing the size anyway
5307 * - set_position() was called to toggle CENTER_ALWAYS on
5310 gtk_window_constrain_position (window,
5316 /* Update whether we need to request a move */
5317 if (info->last.configure_request.x != new_request.x ||
5318 info->last.configure_request.y != new_request.y)
5319 configure_request_pos_changed = TRUE;
5321 configure_request_pos_changed = FALSE;
5325 if (window->type == GTK_WINDOW_TOPLEVEL)
5327 int notify_x, notify_y;
5329 /* this is the position from the last configure notify */
5330 gdk_window_get_position (widget->window, ¬ify_x, ¬ify_y);
5332 g_message ("--- %s ---\n"
5333 "last : %d,%d\t%d x %d\n"
5334 "this : %d,%d\t%d x %d\n"
5335 "alloc : %d,%d\t%d x %d\n"
5337 "resize: \t%d x %d\n"
5338 "size_changed: %d pos_changed: %d hints_changed: %d\n"
5339 "configure_notify_received: %d\n"
5340 "configure_request_count: %d\n"
5341 "position_constraints_changed: %d\n",
5342 window->title ? window->title : "(no title)",
5343 info->last.configure_request.x,
5344 info->last.configure_request.y,
5345 info->last.configure_request.width,
5346 info->last.configure_request.height,
5352 widget->allocation.width,
5353 widget->allocation.height,
5354 widget->requisition.width,
5355 widget->requisition.height,
5357 info->resize_height,
5358 configure_request_pos_changed,
5359 configure_request_size_changed,
5361 window->configure_notify_received,
5362 window->configure_request_count,
5363 info->position_constraints_changed);
5367 saved_last_info = info->last;
5368 info->last.geometry = new_geometry;
5369 info->last.flags = new_flags;
5370 info->last.configure_request = new_request;
5372 /* need to set PPosition so the WM will look at our position,
5373 * but we don't want to count PPosition coming and going as a hints
5374 * change for future iterations. So we saved info->last prior to
5378 /* Also, if the initial position was explicitly set, then we always
5379 * toggle on PPosition. This makes gtk_window_move(window, 0, 0)
5383 /* Also, we toggle on PPosition if GTK_WIN_POS_ is in use and
5384 * this is an initial map
5387 if ((configure_request_pos_changed ||
5388 info->initial_pos_set ||
5389 (window->need_default_position &&
5390 get_effective_position (window) != GTK_WIN_POS_NONE)) &&
5391 (new_flags & GDK_HINT_POS) == 0)
5393 new_flags |= GDK_HINT_POS;
5394 hints_changed = TRUE;
5397 /* Set hints if necessary
5400 gdk_window_set_geometry_hints (widget->window,
5404 /* handle resizing/moving and widget tree allocation
5406 if (window->configure_notify_received)
5408 GtkAllocation allocation;
5410 /* If we have received a configure event since
5411 * the last time in this function, we need to
5412 * accept our new size and size_allocate child widgets.
5413 * (see gtk_window_configure_event() for more details).
5415 * 1 or more configure notifies may have been received.
5416 * Also, configure_notify_received will only be TRUE
5417 * if all expected configure notifies have been received
5418 * (one per configure request), as an optimization.
5421 window->configure_notify_received = FALSE;
5423 /* gtk_window_configure_event() filled in widget->allocation */
5424 allocation = widget->allocation;
5425 gtk_widget_size_allocate (widget, &allocation);
5427 gdk_window_process_all_updates ();
5429 gdk_window_configure_finished (widget->window);
5431 /* If the configure request changed, it means that
5433 * 1) coincidentally changed hints or widget properties
5434 * impacting the configure request before getting
5435 * a configure notify, or
5436 * 2) some broken widget is changing its size request
5437 * during size allocation, resulting in
5438 * a false appearance of changed configure request.
5440 * For 1), we could just go ahead and ask for the
5441 * new size right now, but doing that for 2)
5442 * might well be fighting the user (and can even
5443 * trigger a loop). Since we really don't want to
5444 * do that, we requeue a resize in hopes that
5445 * by the time it gets handled, the child has seen
5446 * the light and is willing to go along with the
5447 * new size. (this happens for the zvt widget, since
5448 * the size_allocate() above will have stored the
5449 * requisition corresponding to the new size in the
5452 * This doesn't buy us anything for 1), but it shouldn't
5453 * hurt us too badly, since it is what would have
5454 * happened if we had gotten the configure event before
5455 * the new size had been set.
5458 if (configure_request_size_changed ||
5459 configure_request_pos_changed)
5461 /* Don't change the recorded last info after all, because we
5462 * haven't actually updated to the new info yet - we decided
5463 * to postpone our configure request until later.
5465 info->last = saved_last_info;
5467 gtk_widget_queue_resize (widget); /* migth recurse for GTK_RESIZE_IMMEDIATE */
5470 return; /* Bail out, we didn't really process the move/resize */
5472 else if ((configure_request_size_changed || hints_changed) &&
5473 (widget->allocation.width != new_request.width ||
5474 widget->allocation.height != new_request.height))
5477 /* We are in one of the following situations:
5478 * A. configure_request_size_changed
5479 * our requisition has changed and we need a different window size,
5480 * so we request it from the window manager.
5481 * B. !configure_request_size_changed && hints_changed
5482 * the window manager rejects our size, but we have just changed the
5483 * window manager hints, so there's a chance our request will
5484 * be honoured this time, so we try again.
5486 * However, if the new requisition is the same as the current allocation,
5487 * we don't request it again, since we won't get a ConfigureNotify back from
5488 * the window manager unless it decides to change our requisition. If
5489 * we don't get the ConfigureNotify back, the resize queue will never be run.
5492 /* Now send the configure request */
5493 if (configure_request_pos_changed)
5497 gdk_window_move_resize (window->frame,
5498 new_request.x - window->frame_left,
5499 new_request.y - window->frame_top,
5500 new_request.width + window->frame_left + window->frame_right,
5501 new_request.height + window->frame_top + window->frame_bottom);
5502 gdk_window_resize (widget->window,
5503 new_request.width, new_request.height);
5506 gdk_window_move_resize (widget->window,
5507 new_request.x, new_request.y,
5508 new_request.width, new_request.height);
5510 else /* only size changed */
5513 gdk_window_resize (window->frame,
5514 new_request.width + window->frame_left + window->frame_right,
5515 new_request.height + window->frame_top + window->frame_bottom);
5516 gdk_window_resize (widget->window,
5517 new_request.width, new_request.height);
5520 /* Increment the number of have-not-yet-received-notify requests */
5521 window->configure_request_count += 1;
5523 /* for GTK_RESIZE_QUEUE toplevels, we are now awaiting a new
5524 * configure event in response to our resizing request.
5525 * the configure event will cause a new resize with
5526 * ->configure_notify_received=TRUE.
5527 * until then, we want to
5528 * - discard expose events
5529 * - coalesce resizes for our children
5530 * - defer any window resizes until the configure event arrived
5531 * to achieve this, we queue a resize for the window, but remove its
5532 * resizing handler, so resizing will not be handled from the next
5533 * idle handler but when the configure event arrives.
5535 * FIXME: we should also dequeue the pending redraws here, since
5536 * we handle those ourselves upon ->configure_notify_received==TRUE.
5538 if (container->resize_mode == GTK_RESIZE_QUEUE)
5540 gtk_widget_queue_resize (widget);
5541 _gtk_container_dequeue_resize_handler (container);
5546 /* Handle any position changes.
5548 if (configure_request_pos_changed)
5552 gdk_window_move (window->frame,
5553 new_request.x - window->frame_left,
5554 new_request.y - window->frame_top);
5557 gdk_window_move (widget->window,
5558 new_request.x, new_request.y);
5561 /* And run the resize queue.
5563 gtk_container_resize_children (container);
5566 /* We have now processed a move/resize since the last position
5567 * constraint change, setting of the initial position, or resize.
5568 * (Not resetting these flags here can lead to infinite loops for
5569 * GTK_RESIZE_IMMEDIATE containers)
5571 info->position_constraints_changed = FALSE;
5572 info->initial_pos_set = FALSE;
5573 info->resize_width = -1;
5574 info->resize_height = -1;
5577 /* Compare two sets of Geometry hints for equality.
5580 gtk_window_compare_hints (GdkGeometry *geometry_a,
5582 GdkGeometry *geometry_b,
5585 if (flags_a != flags_b)
5588 if ((flags_a & GDK_HINT_MIN_SIZE) &&
5589 (geometry_a->min_width != geometry_b->min_width ||
5590 geometry_a->min_height != geometry_b->min_height))
5593 if ((flags_a & GDK_HINT_MAX_SIZE) &&
5594 (geometry_a->max_width != geometry_b->max_width ||
5595 geometry_a->max_height != geometry_b->max_height))
5598 if ((flags_a & GDK_HINT_BASE_SIZE) &&
5599 (geometry_a->base_width != geometry_b->base_width ||
5600 geometry_a->base_height != geometry_b->base_height))
5603 if ((flags_a & GDK_HINT_ASPECT) &&
5604 (geometry_a->min_aspect != geometry_b->min_aspect ||
5605 geometry_a->max_aspect != geometry_b->max_aspect))
5608 if ((flags_a & GDK_HINT_RESIZE_INC) &&
5609 (geometry_a->width_inc != geometry_b->width_inc ||
5610 geometry_a->height_inc != geometry_b->height_inc))
5613 if ((flags_a & GDK_HINT_WIN_GRAVITY) &&
5614 geometry_a->win_gravity != geometry_b->win_gravity)
5621 _gtk_window_constrain_size (GtkWindow *window,
5627 GtkWindowGeometryInfo *info;
5629 g_return_if_fail (GTK_IS_WINDOW (window));
5631 info = window->geometry_info;
5634 GdkWindowHints flags = info->last.flags;
5635 GdkGeometry *geometry = &info->last.geometry;
5637 gtk_window_constrain_size (window,
5648 gtk_window_constrain_size (GtkWindow *window,
5649 GdkGeometry *geometry,
5656 gdk_window_constrain_size (geometry, flags, width, height,
5657 new_width, new_height);
5660 /* Compute the set of geometry hints and flags for a window
5661 * based on the application set geometry, and requisiition
5662 * of the window. gtk_widget_size_request() must have been
5666 gtk_window_compute_hints (GtkWindow *window,
5667 GdkGeometry *new_geometry,
5671 gint extra_width = 0;
5672 gint extra_height = 0;
5673 GtkWindowGeometryInfo *geometry_info;
5674 GtkRequisition requisition;
5676 widget = GTK_WIDGET (window);
5678 gtk_widget_get_child_requisition (widget, &requisition);
5679 geometry_info = gtk_window_get_geometry_info (GTK_WINDOW (widget), FALSE);
5683 *new_flags = geometry_info->mask;
5684 *new_geometry = geometry_info->geometry;
5691 if (geometry_info && geometry_info->widget)
5693 GtkRequisition child_requisition;
5695 /* FIXME: This really isn't right. It gets the min size wrong and forces
5696 * callers to do horrible hacks like set a huge usize on the child requisition
5697 * to get the base size right. We really want to find the answers to:
5699 * - If the geometry widget was infinitely big, how much extra space
5700 * would be needed for the stuff around it.
5702 * - If the geometry widget was infinitely small, how big would the
5703 * window still have to be.
5705 * Finding these answers would be a bit of a mess here. (Bug #68668)
5707 gtk_widget_get_child_requisition (geometry_info->widget, &child_requisition);
5709 extra_width = widget->requisition.width - child_requisition.width;
5710 extra_height = widget->requisition.height - child_requisition.height;
5713 /* We don't want to set GDK_HINT_POS in here, we just set it
5714 * in gtk_window_move_resize() when we want the position
5718 if (*new_flags & GDK_HINT_BASE_SIZE)
5720 new_geometry->base_width += extra_width;
5721 new_geometry->base_height += extra_height;
5723 else if (!(*new_flags & GDK_HINT_MIN_SIZE) &&
5724 (*new_flags & GDK_HINT_RESIZE_INC) &&
5725 ((extra_width != 0) || (extra_height != 0)))
5727 *new_flags |= GDK_HINT_BASE_SIZE;
5729 new_geometry->base_width = extra_width;
5730 new_geometry->base_height = extra_height;
5733 if (*new_flags & GDK_HINT_MIN_SIZE)
5735 if (new_geometry->min_width < 0)
5736 new_geometry->min_width = requisition.width;
5738 new_geometry->min_width += extra_width;
5740 if (new_geometry->min_height < 0)
5741 new_geometry->min_height = requisition.height;
5743 new_geometry->min_height += extra_height;
5745 else if (!window->allow_shrink)
5747 *new_flags |= GDK_HINT_MIN_SIZE;
5749 new_geometry->min_width = requisition.width;
5750 new_geometry->min_height = requisition.height;
5753 if (*new_flags & GDK_HINT_MAX_SIZE)
5755 if (new_geometry->max_width < 0)
5756 new_geometry->max_width = requisition.width;
5758 new_geometry->max_width += extra_width;
5760 if (new_geometry->max_height < 0)
5761 new_geometry->max_height = requisition.height;
5763 new_geometry->max_height += extra_height;
5765 else if (!window->allow_grow)
5767 *new_flags |= GDK_HINT_MAX_SIZE;
5769 new_geometry->max_width = requisition.width;
5770 new_geometry->max_height = requisition.height;
5773 *new_flags |= GDK_HINT_WIN_GRAVITY;
5774 new_geometry->win_gravity = window->gravity;
5777 /***********************
5778 * Redrawing functions *
5779 ***********************/
5782 gtk_window_paint (GtkWidget *widget,
5785 gtk_paint_flat_box (widget->style, widget->window, GTK_STATE_NORMAL,
5786 GTK_SHADOW_NONE, area, widget, "base", 0, 0, -1, -1);
5790 gtk_window_expose (GtkWidget *widget,
5791 GdkEventExpose *event)
5793 if (!GTK_WIDGET_APP_PAINTABLE (widget))
5794 gtk_window_paint (widget, &event->area);
5796 if (GTK_WIDGET_CLASS (parent_class)->expose_event)
5797 return GTK_WIDGET_CLASS (parent_class)->expose_event (widget, event);
5803 * gtk_window_set_has_frame:
5804 * @window: a #GtkWindow
5805 * @setting: a boolean
5807 * (Note: this is a special-purpose function for the framebuffer port,
5808 * that causes GTK+ to draw its own window border. For most applications,
5809 * you want gtk_window_set_decorated() instead, which tells the window
5810 * manager whether to draw the window border.)
5812 * If this function is called on a window with setting of %TRUE, before
5813 * it is realized or showed, it will have a "frame" window around
5814 * @window->window, accessible in @window->frame. Using the signal
5815 * frame_event you can receive all events targeted at the frame.
5817 * This function is used by the linux-fb port to implement managed
5818 * windows, but it could concievably be used by X-programs that
5819 * want to do their own window decorations.
5823 gtk_window_set_has_frame (GtkWindow *window,
5826 g_return_if_fail (GTK_IS_WINDOW (window));
5827 g_return_if_fail (!GTK_WIDGET_REALIZED (window));
5829 window->has_frame = setting != FALSE;
5833 * gtk_window_get_has_frame:
5834 * @window: a #GtkWindow
5836 * Accessor for whether the window has a frame window exterior to
5837 * @window->window. Gets the value set by gtk_window_set_has_frame ().
5839 * Return value: %TRUE if a frame has been added to the window
5840 * via gtk_window_set_has_frame().
5843 gtk_window_get_has_frame (GtkWindow *window)
5845 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
5847 return window->has_frame;
5851 * gtk_window_set_frame_dimensions:
5852 * @window: a #GtkWindow that has a frame
5853 * @left: The width of the left border
5854 * @top: The height of the top border
5855 * @right: The width of the right border
5856 * @bottom: The height of the bottom border
5858 * (Note: this is a special-purpose function intended for the framebuffer
5859 * port; see gtk_window_set_has_frame(). It will have no effect on the
5860 * window border drawn by the window manager, which is the normal
5861 * case when using the X Window system.)
5863 * For windows with frames (see gtk_window_set_has_frame()) this function
5864 * can be used to change the size of the frame border.
5867 gtk_window_set_frame_dimensions (GtkWindow *window,
5875 g_return_if_fail (GTK_IS_WINDOW (window));
5877 widget = GTK_WIDGET (window);
5879 if (window->frame_left == left &&
5880 window->frame_top == top &&
5881 window->frame_right == right &&
5882 window->frame_bottom == bottom)
5885 window->frame_left = left;
5886 window->frame_top = top;
5887 window->frame_right = right;
5888 window->frame_bottom = bottom;
5890 if (GTK_WIDGET_REALIZED (widget) && window->frame)
5892 gint width = widget->allocation.width + left + right;
5893 gint height = widget->allocation.height + top + bottom;
5894 gdk_window_resize (window->frame, width, height);
5895 gtk_decorated_window_move_resize_window (window,
5897 widget->allocation.width,
5898 widget->allocation.height);
5903 * gtk_window_present:
5904 * @window: a #GtkWindow
5906 * Presents a window to the user. This may mean raising the window
5907 * in the stacking order, deiconifying it, moving it to the current
5908 * desktop, and/or giving it the keyboard focus, possibly dependent
5909 * on the user's platform, window manager, and preferences.
5911 * If @window is hidden, this function calls gtk_widget_show()
5914 * This function should be used when the user tries to open a window
5915 * that's already open. Say for example the preferences dialog is
5916 * currently open, and the user chooses Preferences from the menu
5917 * a second time; use gtk_window_present() to move the already-open dialog
5918 * where the user can see it.
5922 gtk_window_present (GtkWindow *window)
5926 g_return_if_fail (GTK_IS_WINDOW (window));
5928 widget = GTK_WIDGET (window);
5930 if (GTK_WIDGET_VISIBLE (window))
5932 g_assert (widget->window != NULL);
5934 gdk_window_show (widget->window);
5936 /* note that gdk_window_focus() will also move the window to
5937 * the current desktop, for WM spec compliant window managers.
5939 #ifdef GDK_WINDOWING_X11
5940 gdk_window_focus (widget->window,
5941 gdk_x11_display_get_user_time (gtk_widget_get_display (widget)));
5943 gdk_window_focus (widget->window,
5944 gtk_get_current_event_time ());
5949 gtk_widget_show (widget);
5954 * gtk_window_iconify:
5955 * @window: a #GtkWindow
5957 * Asks to iconify (i.e. minimize) the specified @window. Note that
5958 * you shouldn't assume the window is definitely iconified afterward,
5959 * because other entities (e.g. the user or <link
5960 * linkend="gtk-X11-arch">window manager</link>) could deiconify it
5961 * again, or there may not be a window manager in which case
5962 * iconification isn't possible, etc. But normally the window will end
5963 * up iconified. Just don't write code that crashes if not.
5965 * It's permitted to call this function before showing a window,
5966 * in which case the window will be iconified before it ever appears
5969 * You can track iconification via the "window_state_event" signal
5974 gtk_window_iconify (GtkWindow *window)
5977 GdkWindow *toplevel;
5979 g_return_if_fail (GTK_IS_WINDOW (window));
5981 widget = GTK_WIDGET (window);
5983 window->iconify_initially = TRUE;
5986 toplevel = window->frame;
5988 toplevel = widget->window;
5990 if (toplevel != NULL)
5991 gdk_window_iconify (toplevel);
5995 * gtk_window_deiconify:
5996 * @window: a #GtkWindow
5998 * Asks to deiconify (i.e. unminimize) the specified @window. Note
5999 * that you shouldn't assume the window is definitely deiconified
6000 * afterward, because other entities (e.g. the user or <link
6001 * linkend="gtk-X11-arch">window manager</link>) could iconify it
6002 * again before your code which assumes deiconification gets to run.
6004 * You can track iconification via the "window_state_event" signal
6008 gtk_window_deiconify (GtkWindow *window)
6011 GdkWindow *toplevel;
6013 g_return_if_fail (GTK_IS_WINDOW (window));
6015 widget = GTK_WIDGET (window);
6017 window->iconify_initially = FALSE;
6020 toplevel = window->frame;
6022 toplevel = widget->window;
6024 if (toplevel != NULL)
6025 gdk_window_deiconify (toplevel);
6030 * @window: a #GtkWindow
6032 * Asks to stick @window, which means that it will appear on all user
6033 * desktops. Note that you shouldn't assume the window is definitely
6034 * stuck afterward, because other entities (e.g. the user or <link
6035 * linkend="gtk-X11-arch">window manager</link>) could unstick it
6036 * again, and some window managers do not support sticking
6037 * windows. But normally the window will end up stuck. Just don't
6038 * write code that crashes if not.
6040 * It's permitted to call this function before showing a window.
6042 * You can track stickiness via the "window_state_event" signal
6047 gtk_window_stick (GtkWindow *window)
6050 GdkWindow *toplevel;
6052 g_return_if_fail (GTK_IS_WINDOW (window));
6054 widget = GTK_WIDGET (window);
6056 window->stick_initially = TRUE;
6059 toplevel = window->frame;
6061 toplevel = widget->window;
6063 if (toplevel != NULL)
6064 gdk_window_stick (toplevel);
6068 * gtk_window_unstick:
6069 * @window: a #GtkWindow
6071 * Asks to unstick @window, which means that it will appear on only
6072 * one of the user's desktops. Note that you shouldn't assume the
6073 * window is definitely unstuck afterward, because other entities
6074 * (e.g. the user or <link linkend="gtk-X11-arch">window
6075 * manager</link>) could stick it again. But normally the window will
6076 * end up stuck. Just don't write code that crashes if not.
6078 * You can track stickiness via the "window_state_event" signal
6083 gtk_window_unstick (GtkWindow *window)
6086 GdkWindow *toplevel;
6088 g_return_if_fail (GTK_IS_WINDOW (window));
6090 widget = GTK_WIDGET (window);
6092 window->stick_initially = FALSE;
6095 toplevel = window->frame;
6097 toplevel = widget->window;
6099 if (toplevel != NULL)
6100 gdk_window_unstick (toplevel);
6104 * gtk_window_maximize:
6105 * @window: a #GtkWindow
6107 * Asks to maximize @window, so that it becomes full-screen. Note that
6108 * you shouldn't assume the window is definitely maximized afterward,
6109 * because other entities (e.g. the user or <link
6110 * linkend="gtk-X11-arch">window manager</link>) could unmaximize it
6111 * again, and not all window managers support maximization. But
6112 * normally the window will end up maximized. Just don't write code
6113 * that crashes if not.
6115 * It's permitted to call this function before showing a window,
6116 * in which case the window will be maximized when it appears onscreen
6119 * You can track maximization via the "window_state_event" signal
6124 gtk_window_maximize (GtkWindow *window)
6127 GdkWindow *toplevel;
6129 g_return_if_fail (GTK_IS_WINDOW (window));
6131 widget = GTK_WIDGET (window);
6133 window->maximize_initially = TRUE;
6136 toplevel = window->frame;
6138 toplevel = widget->window;
6140 if (toplevel != NULL)
6141 gdk_window_maximize (toplevel);
6145 * gtk_window_unmaximize:
6146 * @window: a #GtkWindow
6148 * Asks to unmaximize @window. Note that you shouldn't assume the
6149 * window is definitely unmaximized afterward, because other entities
6150 * (e.g. the user or <link linkend="gtk-X11-arch">window
6151 * manager</link>) could maximize it again, and not all window
6152 * managers honor requests to unmaximize. But normally the window will
6153 * end up unmaximized. Just don't write code that crashes if not.
6155 * You can track maximization via the "window_state_event" signal
6160 gtk_window_unmaximize (GtkWindow *window)
6163 GdkWindow *toplevel;
6165 g_return_if_fail (GTK_IS_WINDOW (window));
6167 widget = GTK_WIDGET (window);
6169 window->maximize_initially = FALSE;
6172 toplevel = window->frame;
6174 toplevel = widget->window;
6176 if (toplevel != NULL)
6177 gdk_window_unmaximize (toplevel);
6181 * gtk_window_fullscreen:
6182 * @window: a #GtkWindow
6184 * Asks to place @window in the fullscreen state. Note that you
6185 * shouldn't assume the window is definitely full screen afterward,
6186 * because other entities (e.g. the user or <link
6187 * linkend="gtk-X11-arch">window manager</link>) could unfullscreen it
6188 * again, and not all window managers honor requests to fullscreen
6189 * windows. But normally the window will end up fullscreen. Just
6190 * don't write code that crashes if not.
6192 * You can track the fullscreen state via the "window_state_event" signal
6198 gtk_window_fullscreen (GtkWindow *window)
6201 GdkWindow *toplevel;
6202 GtkWindowPrivate *priv;
6204 g_return_if_fail (GTK_IS_WINDOW (window));
6206 widget = GTK_WIDGET (window);
6207 priv = GTK_WINDOW_GET_PRIVATE (window);
6209 priv->fullscreen_initially = TRUE;
6212 toplevel = window->frame;
6214 toplevel = widget->window;
6216 if (toplevel != NULL)
6217 gdk_window_fullscreen (toplevel);
6221 * gtk_window_unfullscreen:
6222 * @window: a #GtkWindow
6224 * Asks to toggle off the fullscreen state for @window. Note that you
6225 * shouldn't assume the window is definitely not full screen
6226 * afterward, because other entities (e.g. the user or <link
6227 * linkend="gtk-X11-arch">window manager</link>) could fullscreen it
6228 * again, and not all window managers honor requests to unfullscreen
6229 * windows. But normally the window will end up restored to its normal
6230 * state. Just don't write code that crashes if not.
6232 * You can track the fullscreen state via the "window_state_event" signal
6238 gtk_window_unfullscreen (GtkWindow *window)
6241 GdkWindow *toplevel;
6242 GtkWindowPrivate *priv;
6244 g_return_if_fail (GTK_IS_WINDOW (window));
6246 widget = GTK_WIDGET (window);
6247 priv = GTK_WINDOW_GET_PRIVATE (window);
6249 priv->fullscreen_initially = FALSE;
6252 toplevel = window->frame;
6254 toplevel = widget->window;
6256 if (toplevel != NULL)
6257 gdk_window_unfullscreen (toplevel);
6261 * gtk_window_set_keep_above:
6262 * @window: a #GtkWindow
6263 * @setting: whether to keep @window above other windows
6265 * Asks to keep @window above, so that it stays on top. Note that
6266 * you shouldn't assume the window is definitely above afterward,
6267 * because other entities (e.g. the user or <link
6268 * linkend="gtk-X11-arch">window manager</link>) could not keep it above,
6269 * and not all window managers support keeping windows above. But
6270 * normally the window will end kept above. Just don't write code
6271 * that crashes if not.
6273 * It's permitted to call this function before showing a window,
6274 * in which case the window will be kept above when it appears onscreen
6277 * You can track the above state via the "window_state_event" signal
6280 * Note that, according to the <ulink
6281 * url="http://www.freedesktop.org/Standards/wm-spec">Extended Window
6282 * Manager Hints</ulink> specification, the above state is mainly meant
6283 * for user preferences and should not be used by applications e.g. for
6284 * drawing attention to their dialogs.
6289 gtk_window_set_keep_above (GtkWindow *window,
6293 GtkWindowPrivate *priv;
6294 GdkWindow *toplevel;
6296 g_return_if_fail (GTK_IS_WINDOW (window));
6298 widget = GTK_WIDGET (window);
6299 priv = GTK_WINDOW_GET_PRIVATE (window);
6301 priv->above_initially = setting;
6303 priv->below_initially = FALSE;
6306 toplevel = window->frame;
6308 toplevel = widget->window;
6310 if (toplevel != NULL)
6311 gdk_window_set_keep_above (toplevel, setting);
6315 * gtk_window_set_keep_below:
6316 * @window: a #GtkWindow
6317 * @setting: whether to keep @window below other windows
6319 * Asks to keep @window below, so that it stays in bottom. Note that
6320 * you shouldn't assume the window is definitely below afterward,
6321 * because other entities (e.g. the user or <link
6322 * linkend="gtk-X11-arch">window manager</link>) could not keep it below,
6323 * and not all window managers support putting windows below. But
6324 * normally the window will be kept below. Just don't write code
6325 * that crashes if not.
6327 * It's permitted to call this function before showing a window,
6328 * in which case the window will be kept below when it appears onscreen
6331 * You can track the below state via the "window_state_event" signal
6334 * Note that, according to the <ulink
6335 * url="http://www.freedesktop.org/Standards/wm-spec">Extended Window
6336 * Manager Hints</ulink> specification, the above state is mainly meant
6337 * for user preferences and should not be used by applications e.g. for
6338 * drawing attention to their dialogs.
6343 gtk_window_set_keep_below (GtkWindow *window,
6347 GtkWindowPrivate *priv;
6348 GdkWindow *toplevel;
6350 g_return_if_fail (GTK_IS_WINDOW (window));
6352 widget = GTK_WIDGET (window);
6353 priv = GTK_WINDOW_GET_PRIVATE (window);
6355 priv->below_initially = setting;
6357 priv->above_initially = FALSE;
6360 toplevel = window->frame;
6362 toplevel = widget->window;
6364 if (toplevel != NULL)
6365 gdk_window_set_keep_below (toplevel, setting);
6369 * gtk_window_set_resizable:
6370 * @window: a #GtkWindow
6371 * @resizable: %TRUE if the user can resize this window
6373 * Sets whether the user can resize a window. Windows are user resizable
6377 gtk_window_set_resizable (GtkWindow *window,
6380 g_return_if_fail (GTK_IS_WINDOW (window));
6382 gtk_window_set_policy (window, FALSE, resizable, FALSE);
6386 * gtk_window_get_resizable:
6387 * @window: a #GtkWindow
6389 * Gets the value set by gtk_window_set_resizable().
6391 * Return value: %TRUE if the user can resize the window
6394 gtk_window_get_resizable (GtkWindow *window)
6396 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
6398 /* allow_grow is most likely to indicate the semantic concept we
6399 * mean by "resizable" (and will be a reliable indicator if
6400 * set_policy() hasn't been called)
6402 return window->allow_grow;
6406 * gtk_window_set_gravity:
6407 * @window: a #GtkWindow
6408 * @gravity: window gravity
6410 * Window gravity defines the meaning of coordinates passed to
6411 * gtk_window_move(). See gtk_window_move() and #GdkGravity for
6414 * The default window gravity is #GDK_GRAVITY_NORTH_WEST which will
6415 * typically "do what you mean."
6419 gtk_window_set_gravity (GtkWindow *window,
6422 g_return_if_fail (GTK_IS_WINDOW (window));
6424 if (gravity != window->gravity)
6426 window->gravity = gravity;
6428 /* gtk_window_move_resize() will adapt gravity
6430 gtk_widget_queue_resize (GTK_WIDGET (window));
6432 g_object_notify (G_OBJECT (window), "gravity");
6437 * gtk_window_get_gravity:
6438 * @window: a #GtkWindow
6440 * Gets the value set by gtk_window_set_gravity().
6442 * Return value: window gravity
6445 gtk_window_get_gravity (GtkWindow *window)
6447 g_return_val_if_fail (GTK_IS_WINDOW (window), 0);
6449 return window->gravity;
6453 * gtk_window_begin_resize_drag:
6454 * @window: a #GtkWindow
6455 * @button: mouse button that initiated the drag
6456 * @edge: position of the resize control
6457 * @root_x: X position where the user clicked to initiate the drag, in root window coordinates
6458 * @root_y: Y position where the user clicked to initiate the drag
6459 * @timestamp: timestamp from the click event that initiated the drag
6461 * Starts resizing a window. This function is used if an application
6462 * has window resizing controls. When GDK can support it, the resize
6463 * will be done using the standard mechanism for the <link
6464 * linkend="gtk-X11-arch">window manager</link> or windowing
6465 * system. Otherwise, GDK will try to emulate window resizing,
6466 * potentially not all that well, depending on the windowing system.
6470 gtk_window_begin_resize_drag (GtkWindow *window,
6478 GdkWindow *toplevel;
6480 g_return_if_fail (GTK_IS_WINDOW (window));
6481 g_return_if_fail (GTK_WIDGET_VISIBLE (window));
6483 widget = GTK_WIDGET (window);
6486 toplevel = window->frame;
6488 toplevel = widget->window;
6490 gdk_window_begin_resize_drag (toplevel,
6497 * gtk_window_get_frame_dimensions:
6498 * @window: a #GtkWindow
6499 * @left: location to store the width of the frame at the left, or %NULL
6500 * @top: location to store the height of the frame at the top, or %NULL
6501 * @right: location to store the width of the frame at the returns, or %NULL
6502 * @bottom: location to store the height of the frame at the bottom, or %NULL
6504 * (Note: this is a special-purpose function intended for the
6505 * framebuffer port; see gtk_window_set_has_frame(). It will not
6506 * return the size of the window border drawn by the <link
6507 * linkend="gtk-X11-arch">window manager</link>, which is the normal
6508 * case when using a windowing system. See
6509 * gdk_window_get_frame_extents() to get the standard window border
6512 * Retrieves the dimensions of the frame window for this toplevel.
6513 * See gtk_window_set_has_frame(), gtk_window_set_frame_dimensions().
6516 gtk_window_get_frame_dimensions (GtkWindow *window,
6522 g_return_if_fail (GTK_IS_WINDOW (window));
6525 *left = window->frame_left;
6527 *top = window->frame_top;
6529 *right = window->frame_right;
6531 *bottom = window->frame_bottom;
6535 * gtk_window_begin_move_drag:
6536 * @window: a #GtkWindow
6537 * @button: mouse button that initiated the drag
6538 * @root_x: X position where the user clicked to initiate the drag, in root window coordinates
6539 * @root_y: Y position where the user clicked to initiate the drag
6540 * @timestamp: timestamp from the click event that initiated the drag
6542 * Starts moving a window. This function is used if an application has
6543 * window movement grips. When GDK can support it, the window movement
6544 * will be done using the standard mechanism for the <link
6545 * linkend="gtk-X11-arch">window manager</link> or windowing
6546 * system. Otherwise, GDK will try to emulate window movement,
6547 * potentially not all that well, depending on the windowing system.
6551 gtk_window_begin_move_drag (GtkWindow *window,
6558 GdkWindow *toplevel;
6560 g_return_if_fail (GTK_IS_WINDOW (window));
6561 g_return_if_fail (GTK_WIDGET_VISIBLE (window));
6563 widget = GTK_WIDGET (window);
6566 toplevel = window->frame;
6568 toplevel = widget->window;
6570 gdk_window_begin_move_drag (toplevel,
6577 * gtk_window_set_screen:
6578 * @window: a #GtkWindow.
6579 * @screen: a #GdkScreen.
6581 * Sets the #GdkScreen where the @window is displayed; if
6582 * the window is already mapped, it will be unmapped, and
6583 * then remapped on the new screen.
6588 gtk_window_set_screen (GtkWindow *window,
6592 GdkScreen *previous_screen;
6593 gboolean was_mapped;
6595 g_return_if_fail (GTK_IS_WINDOW (window));
6596 g_return_if_fail (GDK_IS_SCREEN (screen));
6598 if (screen == window->screen)
6601 widget = GTK_WIDGET (window);
6603 previous_screen = window->screen;
6604 was_mapped = GTK_WIDGET_MAPPED (widget);
6607 gtk_widget_unmap (widget);
6608 if (GTK_WIDGET_REALIZED (widget))
6609 gtk_widget_unrealize (widget);
6611 gtk_window_free_key_hash (window);
6612 window->screen = screen;
6613 gtk_widget_reset_rc_styles (widget);
6614 if (screen != previous_screen)
6615 _gtk_widget_propagate_screen_changed (widget, previous_screen);
6616 g_object_notify (G_OBJECT (window), "screen");
6619 gtk_widget_map (widget);
6623 gtk_window_check_screen (GtkWindow *window)
6626 return window->screen;
6629 g_warning ("Screen for GtkWindow not set; you must always set\n"
6630 "a screen for a GtkWindow before using the window");
6636 * gtk_window_get_screen:
6637 * @window: a #GtkWindow.
6639 * Returns the #GdkScreen associated with @window.
6641 * Return value: a #GdkScreen.
6646 gtk_window_get_screen (GtkWindow *window)
6648 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
6650 return window->screen;
6654 * gtk_window_is_active:
6655 * @window: a #GtkWindow
6657 * Returns whether the window is part of the current active toplevel.
6658 * (That is, the toplevel window receiving keystrokes.)
6659 * The return value is %TRUE if the window is active toplevel
6660 * itself, but also if it is, say, a #GtkPlug embedded in the active toplevel.
6661 * You might use this function if you wanted to draw a widget
6662 * differently in an active window from a widget in an inactive window.
6663 * See gtk_window_has_toplevel_focus()
6665 * Return value: %TRUE if the window part of the current active window.
6670 gtk_window_is_active (GtkWindow *window)
6672 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
6674 return window->is_active;
6678 * gtk_window_has_toplevel_focus:
6679 * @window: a #GtkWindow
6681 * Returns whether the input focus is within this GtkWindow.
6682 * For real toplevel windows, this is identical to gtk_window_is_active(),
6683 * but for embedded windows, like #GtkPlug, the results will differ.
6685 * Return value: %TRUE if the input focus is within this GtkWindow
6690 gtk_window_has_toplevel_focus (GtkWindow *window)
6692 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
6694 return window->has_toplevel_focus;
6698 gtk_window_group_class_init (GtkWindowGroupClass *klass)
6703 gtk_window_group_get_type (void)
6705 static GType window_group_type = 0;
6707 if (!window_group_type)
6709 static const GTypeInfo window_group_info =
6711 sizeof (GtkWindowGroupClass),
6712 NULL, /* base_init */
6713 NULL, /* base_finalize */
6714 (GClassInitFunc) gtk_window_group_class_init,
6715 NULL, /* class_finalize */
6716 NULL, /* class_data */
6717 sizeof (GtkWindowGroup),
6718 16, /* n_preallocs */
6719 (GInstanceInitFunc) NULL,
6722 window_group_type = g_type_register_static (G_TYPE_OBJECT, "GtkWindowGroup", &window_group_info, 0);
6725 return window_group_type;
6729 * gtk_window_group_new:
6731 * Creates a new #GtkWindowGroup object. Grabs added with
6732 * gtk_grab_add() only affect windows within the same #GtkWindowGroup.
6734 * Return value: a new #GtkWindowGroup.
6737 gtk_window_group_new (void)
6739 return g_object_new (GTK_TYPE_WINDOW_GROUP, NULL);
6743 window_group_cleanup_grabs (GtkWindowGroup *group,
6747 GSList *to_remove = NULL;
6749 tmp_list = group->grabs;
6752 if (gtk_widget_get_toplevel (tmp_list->data) == (GtkWidget*) window)
6753 to_remove = g_slist_prepend (to_remove, g_object_ref (tmp_list->data));
6754 tmp_list = tmp_list->next;
6759 gtk_grab_remove (to_remove->data);
6760 g_object_unref (to_remove->data);
6761 to_remove = g_slist_delete_link (to_remove, to_remove);
6766 * gtk_window_group_add_window:
6767 * @window_group: a #GtkWindowGroup
6768 * @window: the #GtkWindow to add
6770 * Adds a window to a #GtkWindowGroup.
6773 gtk_window_group_add_window (GtkWindowGroup *window_group,
6776 g_return_if_fail (GTK_IS_WINDOW_GROUP (window_group));
6777 g_return_if_fail (GTK_IS_WINDOW (window));
6779 if (window->group != window_group)
6781 g_object_ref (window);
6782 g_object_ref (window_group);
6785 gtk_window_group_remove_window (window->group, window);
6787 window_group_cleanup_grabs (_gtk_window_get_group (NULL), window);
6789 window->group = window_group;
6791 g_object_unref (window);
6796 * gtk_window_group_remove_window:
6797 * @window_group: a #GtkWindowGroup
6798 * @window: the #GtkWindow to remove
6800 * Removes a window from a #GtkWindowGroup.
6803 gtk_window_group_remove_window (GtkWindowGroup *window_group,
6806 g_return_if_fail (GTK_IS_WINDOW_GROUP (window_group));
6807 g_return_if_fail (GTK_IS_WIDGET (window));
6808 g_return_if_fail (window->group == window_group);
6810 g_object_ref (window);
6812 window_group_cleanup_grabs (window_group, window);
6813 window->group = NULL;
6815 g_object_unref (window_group);
6816 g_object_unref (window);
6819 /* Return the group for the window or the default group
6822 _gtk_window_get_group (GtkWindow *window)
6824 if (window && window->group)
6825 return window->group;
6828 static GtkWindowGroup *default_group = NULL;
6831 default_group = gtk_window_group_new ();
6833 return default_group;
6839 Derived from XParseGeometry() in XFree86
6841 Copyright 1985, 1986, 1987,1998 The Open Group
6843 All Rights Reserved.
6845 The above copyright notice and this permission notice shall be included
6846 in all copies or substantial portions of the Software.
6848 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
6849 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
6850 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
6851 IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
6852 OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
6853 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
6854 OTHER DEALINGS IN THE SOFTWARE.
6856 Except as contained in this notice, the name of The Open Group shall
6857 not be used in advertising or otherwise to promote the sale, use or
6858 other dealings in this Software without prior written authorization
6859 from The Open Group.
6864 * XParseGeometry parses strings of the form
6865 * "=<width>x<height>{+-}<xoffset>{+-}<yoffset>", where
6866 * width, height, xoffset, and yoffset are unsigned integers.
6867 * Example: "=80x24+300-49"
6868 * The equal sign is optional.
6869 * It returns a bitmask that indicates which of the four values
6870 * were actually found in the string. For each value found,
6871 * the corresponding argument is updated; for each value
6872 * not found, the corresponding argument is left unchanged.
6875 /* The following code is from Xlib, and is minimally modified, so we
6876 * can track any upstream changes if required. Don't change this
6877 * code. Or if you do, put in a huge comment marking which thing
6882 read_int (gchar *string,
6890 else if (*string == '-')
6896 for (; (*string >= '0') && (*string <= '9'); string++)
6898 result = (result * 10) + (*string - '0');
6910 * Bitmask returned by XParseGeometry(). Each bit tells if the corresponding
6911 * value (x, y, width, height) was found in the parsed string.
6913 #define NoValue 0x0000
6914 #define XValue 0x0001
6915 #define YValue 0x0002
6916 #define WidthValue 0x0004
6917 #define HeightValue 0x0008
6918 #define AllValues 0x000F
6919 #define XNegative 0x0010
6920 #define YNegative 0x0020
6922 /* Try not to reformat/modify, so we can compare/sync with X sources */
6924 gtk_XParseGeometry (const char *string,
6927 unsigned int *width,
6928 unsigned int *height)
6932 unsigned int tempWidth, tempHeight;
6934 char *nextCharacter;
6936 /* These initializations are just to silence gcc */
6942 if ( (string == NULL) || (*string == '\0')) return(mask);
6944 string++; /* ignore possible '=' at beg of geometry spec */
6946 strind = (char *)string;
6947 if (*strind != '+' && *strind != '-' && *strind != 'x') {
6948 tempWidth = read_int(strind, &nextCharacter);
6949 if (strind == nextCharacter)
6951 strind = nextCharacter;
6955 if (*strind == 'x' || *strind == 'X') {
6957 tempHeight = read_int(strind, &nextCharacter);
6958 if (strind == nextCharacter)
6960 strind = nextCharacter;
6961 mask |= HeightValue;
6964 if ((*strind == '+') || (*strind == '-')) {
6965 if (*strind == '-') {
6967 tempX = -read_int(strind, &nextCharacter);
6968 if (strind == nextCharacter)
6970 strind = nextCharacter;
6976 tempX = read_int(strind, &nextCharacter);
6977 if (strind == nextCharacter)
6979 strind = nextCharacter;
6982 if ((*strind == '+') || (*strind == '-')) {
6983 if (*strind == '-') {
6985 tempY = -read_int(strind, &nextCharacter);
6986 if (strind == nextCharacter)
6988 strind = nextCharacter;
6995 tempY = read_int(strind, &nextCharacter);
6996 if (strind == nextCharacter)
6998 strind = nextCharacter;
7004 /* If strind isn't at the end of the string the it's an invalid
7005 geometry specification. */
7007 if (*strind != '\0') return (0);
7013 if (mask & WidthValue)
7015 if (mask & HeightValue)
7016 *height = tempHeight;
7021 * gtk_window_parse_geometry:
7022 * @window: a #GtkWindow
7023 * @geometry: geometry string
7025 * Parses a standard X Window System geometry string - see the
7026 * manual page for X (type 'man X') for details on this.
7027 * gtk_window_parse_geometry() does work on all GTK+ ports
7028 * including Win32 but is primarily intended for an X environment.
7030 * If either a size or a position can be extracted from the
7031 * geometry string, gtk_window_parse_geometry() returns %TRUE
7032 * and calls gtk_window_set_default_size() and/or gtk_window_move()
7033 * to resize/move the window.
7035 * If gtk_window_parse_geometry() returns %TRUE, it will also
7036 * set the #GDK_HINT_USER_POS and/or #GDK_HINT_USER_SIZE hints
7037 * indicating to the window manager that the size/position of
7038 * the window was user-specified. This causes most window
7039 * managers to honor the geometry.
7041 * Note that for gtk_window_parse_geometry() to work as expected, it has
7042 * to be called when the window has its "final" size, i.e. after calling
7043 * gtk_widget_show_all() on the contents and gtk_window_set_geometry_hints()
7046 * <informalexample><programlisting>
7048 * main (int argc, char *argv[])
7050 * GtkWidget *window, vbox;
7051 * GdkGeometry size_hints;
7053 * gtk_init (&argc, &argv);
7055 * window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
7056 * vbox = gtk_vbox_new (FALSE, 0);
7058 * gtk_container_add (GTK_CONTAINER (window), vbox);
7059 * fill_with_content (vbox);
7060 * gtk_widget_show_all (vbox);
7063 * 100, 50, 0, 0, 100, 50, 10, 10, 0.0, 0.0, GDK_GRAVITY_NORTH_WEST
7066 * gtk_window_set_geometry_hints (GTK_WINDOW (window),
7069 * GDK_HINT_MIN_SIZE |
7070 * GDK_HINT_BASE_SIZE |
7071 * GDK_HINT_RESIZE_INC);
7075 * if (!gtk_window_parse_geometry (GTK_WINDOW (window), argv[1]))
7076 * fprintf (stderr, "Failed to parse '%s'\n", argv[1]);
7079 * gtk_widget_show_all (window);
7084 * </programlisting></informalexample>
7086 * Return value: %TRUE if string was parsed successfully
7089 gtk_window_parse_geometry (GtkWindow *window,
7090 const gchar *geometry)
7095 gboolean size_set, pos_set;
7098 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
7099 g_return_val_if_fail (geometry != NULL, FALSE);
7101 screen = gtk_window_check_screen (window);
7103 result = gtk_XParseGeometry (geometry, &x, &y, &w, &h);
7105 if ((result & WidthValue) == 0 ||
7108 if ((result & HeightValue) == 0 ||
7113 if ((result & WidthValue) || (result & HeightValue))
7115 gtk_window_set_default_size_internal (window, TRUE, w, TRUE, h, TRUE);
7119 gtk_window_get_size (window, &w, &h);
7121 grav = GDK_GRAVITY_NORTH_WEST;
7123 if ((result & XNegative) && (result & YNegative))
7124 grav = GDK_GRAVITY_SOUTH_EAST;
7125 else if (result & XNegative)
7126 grav = GDK_GRAVITY_NORTH_EAST;
7127 else if (result & YNegative)
7128 grav = GDK_GRAVITY_SOUTH_WEST;
7130 if ((result & XValue) == 0)
7133 if ((result & YValue) == 0)
7136 if (grav == GDK_GRAVITY_SOUTH_WEST ||
7137 grav == GDK_GRAVITY_SOUTH_EAST)
7138 y = gdk_screen_get_height (screen) - h + y;
7140 if (grav == GDK_GRAVITY_SOUTH_EAST ||
7141 grav == GDK_GRAVITY_NORTH_EAST)
7142 x = gdk_screen_get_width (screen) - w + x;
7144 /* we don't let you put a window offscreen; maybe some people would
7145 * prefer to be able to, but it's kind of a bogus thing to do.
7154 if ((result & XValue) || (result & YValue))
7156 gtk_window_set_gravity (window, grav);
7157 gtk_window_move (window, x, y);
7161 if (size_set || pos_set)
7163 /* Set USSize, USPosition hints */
7164 GtkWindowGeometryInfo *info;
7166 info = gtk_window_get_geometry_info (window, TRUE);
7169 info->mask |= GDK_HINT_USER_POS;
7171 info->mask |= GDK_HINT_USER_SIZE;
7178 gtk_window_mnemonic_hash_foreach (guint keyval,
7184 GtkWindowKeysForeachFunc func;
7188 (*info->func) (info->window, keyval, info->window->mnemonic_modifier, TRUE, info->func_data);
7192 _gtk_window_keys_foreach (GtkWindow *window,
7193 GtkWindowKeysForeachFunc func,
7197 GtkMnemonicHash *mnemonic_hash;
7201 GtkWindowKeysForeachFunc func;
7205 info.window = window;
7207 info.func_data = func_data;
7209 mnemonic_hash = gtk_window_get_mnemonic_hash (window, FALSE);
7211 _gtk_mnemonic_hash_foreach (mnemonic_hash,
7212 gtk_window_mnemonic_hash_foreach, &info);
7214 groups = gtk_accel_groups_from_object (G_OBJECT (window));
7217 GtkAccelGroup *group = groups->data;
7220 for (i = 0; i < group->n_accels; i++)
7222 GtkAccelKey *key = &group->priv_accels[i].key;
7225 (*func) (window, key->accel_key, key->accel_mods, FALSE, func_data);
7228 groups = groups->next;
7233 gtk_window_keys_changed (GtkWindow *window)
7235 gtk_window_free_key_hash (window);
7236 gtk_window_get_key_hash (window);
7239 typedef struct _GtkWindowKeyEntry GtkWindowKeyEntry;
7241 struct _GtkWindowKeyEntry
7245 gboolean is_mnemonic;
7249 add_to_key_hash (GtkWindow *window,
7251 GdkModifierType modifiers,
7252 gboolean is_mnemonic,
7255 GtkKeyHash *key_hash = data;
7257 GtkWindowKeyEntry *entry = g_new (GtkWindowKeyEntry, 1);
7259 entry->keyval = keyval;
7260 entry->modifiers = modifiers;
7261 entry->is_mnemonic = is_mnemonic;
7263 /* GtkAccelGroup stores lowercased accelerators. To deal
7264 * with this, if <Shift> was specified, uppercase.
7266 if (modifiers & GDK_SHIFT_MASK)
7268 if (keyval == GDK_Tab)
7269 keyval = GDK_ISO_Left_Tab;
7271 keyval = gdk_keyval_to_upper (keyval);
7274 _gtk_key_hash_add_entry (key_hash, keyval, entry->modifiers, entry);
7278 gtk_window_get_key_hash (GtkWindow *window)
7280 GdkScreen *screen = gtk_window_check_screen (window);
7281 GtkKeyHash *key_hash = g_object_get_data (G_OBJECT (window), "gtk-window-key-hash");
7286 key_hash = _gtk_key_hash_new (gdk_keymap_get_for_display (gdk_screen_get_display (screen)),
7287 (GDestroyNotify)g_free);
7288 _gtk_window_keys_foreach (window, add_to_key_hash, key_hash);
7289 g_object_set_data (G_OBJECT (window), "gtk-window-key-hash", key_hash);
7295 gtk_window_free_key_hash (GtkWindow *window)
7297 GtkKeyHash *key_hash = g_object_get_data (G_OBJECT (window), "gtk-window-key-hash");
7300 _gtk_key_hash_free (key_hash);
7301 g_object_set_data (G_OBJECT (window), "gtk-window-key-hash", NULL);
7306 * gtk_window_activate_key:
7307 * @window: a #GtkWindow
7308 * @event: a #GdkEventKey
7310 * Activates mnemonics and accelerators for this #GtkWindow. This is normally
7311 * called by the default ::key_press_event handler for toplevel windows,
7312 * however in some cases it may be useful to call this directly when
7313 * overriding the standard key handling for a toplevel window.
7315 * Return value: %TRUE if a mnemonic or accelerator was found and activated.
7318 gtk_window_activate_key (GtkWindow *window,
7321 GtkKeyHash *key_hash = g_object_get_data (G_OBJECT (window), "gtk-window-key-hash");
7322 GtkWindowKeyEntry *found_entry = NULL;
7326 gtk_window_keys_changed (window);
7327 key_hash = g_object_get_data (G_OBJECT (window), "gtk-window-key-hash");
7332 GSList *entries = _gtk_key_hash_lookup (key_hash,
7333 event->hardware_keycode,
7335 gtk_accelerator_get_default_mod_mask (),
7339 for (tmp_list = entries; tmp_list; tmp_list = tmp_list->next)
7341 GtkWindowKeyEntry *entry = tmp_list->data;
7342 if (entry->is_mnemonic)
7344 found_entry = entry;
7349 if (!found_entry && entries)
7350 found_entry = entries->data;
7352 g_slist_free (entries);
7357 if (found_entry->is_mnemonic)
7358 return gtk_window_mnemonic_activate (window, found_entry->keyval, found_entry->modifiers);
7360 return gtk_accel_groups_activate (G_OBJECT (window), found_entry->keyval, found_entry->modifiers);
7367 window_update_has_focus (GtkWindow *window)
7369 GtkWidget *widget = GTK_WIDGET (window);
7370 gboolean has_focus = window->has_toplevel_focus && window->is_active;
7372 if (has_focus != window->has_focus)
7374 window->has_focus = has_focus;
7378 if (window->focus_widget &&
7379 window->focus_widget != widget &&
7380 !GTK_WIDGET_HAS_FOCUS (window->focus_widget))
7381 do_focus_change (window->focus_widget, TRUE);
7385 if (window->focus_widget &&
7386 window->focus_widget != widget &&
7387 GTK_WIDGET_HAS_FOCUS (window->focus_widget))
7388 do_focus_change (window->focus_widget, FALSE);
7394 * _gtk_window_set_is_active:
7395 * @window: a #GtkWindow
7396 * @is_active: %TRUE if the window is in the currently active toplevel
7398 * Internal function that sets whether the #GtkWindow is part
7399 * of the currently active toplevel window (taking into account inter-process
7403 _gtk_window_set_is_active (GtkWindow *window,
7406 g_return_if_fail (GTK_IS_WINDOW (window));
7408 is_active = is_active != FALSE;
7410 if (is_active != window->is_active)
7412 window->is_active = is_active;
7413 window_update_has_focus (window);
7415 g_object_notify (G_OBJECT (window), "is_active");
7420 * _gtk_window_set_has_toplevel_focus:
7421 * @window: a #GtkWindow
7422 * @has_toplevel_focus: %TRUE if the in
7424 * Internal function that sets whether the keyboard focus for the
7425 * toplevel window (taking into account inter-process embedding.)
7428 _gtk_window_set_has_toplevel_focus (GtkWindow *window,
7429 gboolean has_toplevel_focus)
7431 g_return_if_fail (GTK_IS_WINDOW (window));
7433 has_toplevel_focus = has_toplevel_focus != FALSE;
7435 if (has_toplevel_focus != window->has_toplevel_focus)
7437 window->has_toplevel_focus = has_toplevel_focus;
7438 window_update_has_focus (window);
7440 g_object_notify (G_OBJECT (window), "has_toplevel_focus");
7445 * gtk_window_set_auto_startup_notification:
7446 * @setting: %TRUE to automatically do startup notification
7448 * By default, after showing the first #GtkWindow for each #GdkScreen,
7449 * GTK+ calls gdk_screen_notify_startup_complete(). Call this
7450 * function to disable the automatic startup notification. You might
7451 * do this if your first window is a splash screen, and you want to
7452 * delay notification until after your real main window has been
7453 * shown, for example.
7455 * In that example, you would disable startup notification
7456 * temporarily, show your splash screen, then re-enable it so that
7457 * showing the main window would automatically result in notification.
7462 gtk_window_set_auto_startup_notification (gboolean setting)
7464 disable_startup_notification = !setting;
7469 #undef gtk_window_set_icon_from_file
7472 gtk_window_set_icon_from_file (GtkWindow *window,
7473 const gchar *filename,
7476 gchar *utf8_filename = g_locale_to_utf8 (filename, -1, NULL, NULL, err);
7479 if (utf8_filename == NULL)
7482 retval = gtk_window_set_icon_from_file_utf8 (window, utf8_filename, err);
7484 g_free (utf8_filename);
7489 #undef gtk_window_set_default_icon_from_file
7492 gtk_window_set_default_icon_from_file (const gchar *filename,
7495 gchar *utf8_filename = g_locale_to_utf8 (filename, -1, NULL, NULL, err);
7498 if (utf8_filename == NULL)
7501 retval = gtk_window_set_default_icon_from_file_utf8 (utf8_filename, err);
7503 g_free (utf8_filename);