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/.
33 #include "gdk/gdkkeysyms.h"
37 #include "gtkprivate.h"
39 #include "gtkwindow.h"
40 #include "gtkwindow-decorate.h"
41 #include "gtkbindings.h"
42 #include "gtkkeyhash.h"
44 #include "gtkmnemonichash.h"
45 #include "gtkiconfactory.h"
46 #include "gtkicontheme.h"
47 #include "gtkmarshalers.h"
49 #include "gtkbuildable.h"
52 #ifdef GDK_WINDOWING_X11
81 PROP_DESTROY_WITH_PARENT,
86 PROP_SKIP_TASKBAR_HINT,
97 /* Readonly properties */
99 PROP_HAS_TOPLEVEL_FOCUS,
101 /* Writeonly properties */
110 GdkPixmap *icon_pixmap;
111 GdkPixmap *icon_mask;
114 guint using_default_icon : 1;
115 guint using_parent_icon : 1;
116 guint using_themed_icon : 1;
120 GdkGeometry geometry; /* Last set of geometry hints we set */
121 GdkWindowHints flags;
122 GdkRectangle configure_request;
123 } GtkWindowLastGeometryInfo;
125 struct _GtkWindowGeometryInfo
127 /* Properties that the app has set on the window
129 GdkGeometry geometry; /* Geometry hints */
131 GtkWidget *widget; /* subwidget to which hints apply */
132 /* from last gtk_window_resize () - if > 0, indicates that
133 * we should resize to this size.
138 /* From last gtk_window_move () prior to mapping -
139 * only used if initial_pos_set
144 /* Default size - used only the FIRST time we map a window,
149 /* whether to use initial_x, initial_y */
150 guint initial_pos_set : 1;
151 /* CENTER_ALWAYS or other position constraint changed since
152 * we sent the last configure request.
154 guint position_constraints_changed : 1;
156 /* if true, default_width, height come from gtk_window_parse_geometry,
157 * and thus should be multiplied by the increments and affect the
158 * geometry widget only
160 guint default_is_geometry : 1;
162 GtkWindowLastGeometryInfo last;
165 #define GTK_WINDOW_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GTK_TYPE_WINDOW, GtkWindowPrivate))
167 typedef struct _GtkWindowPrivate GtkWindowPrivate;
169 struct _GtkWindowPrivate
171 GtkMnemonicHash *mnemonic_hash;
173 guint above_initially : 1;
174 guint below_initially : 1;
175 guint fullscreen_initially : 1;
176 guint skips_taskbar : 1;
177 guint skips_pager : 1;
179 guint accept_focus : 1;
180 guint focus_on_map : 1;
182 guint transient_parent_group : 1;
184 guint reset_type_hint : 1;
185 guint opacity_set : 1;
186 guint builder_visible : 1;
188 GdkWindowTypeHint type_hint;
195 static void gtk_window_dispose (GObject *object);
196 static void gtk_window_destroy (GtkObject *object);
197 static void gtk_window_finalize (GObject *object);
198 static void gtk_window_show (GtkWidget *widget);
199 static void gtk_window_hide (GtkWidget *widget);
200 static void gtk_window_map (GtkWidget *widget);
201 static void gtk_window_unmap (GtkWidget *widget);
202 static void gtk_window_realize (GtkWidget *widget);
203 static void gtk_window_unrealize (GtkWidget *widget);
204 static void gtk_window_size_request (GtkWidget *widget,
205 GtkRequisition *requisition);
206 static void gtk_window_size_allocate (GtkWidget *widget,
207 GtkAllocation *allocation);
208 static gint gtk_window_event (GtkWidget *widget,
210 static gboolean gtk_window_map_event (GtkWidget *widget,
212 static gboolean gtk_window_frame_event (GtkWindow *window,
214 static gint gtk_window_configure_event (GtkWidget *widget,
215 GdkEventConfigure *event);
216 static gint gtk_window_key_press_event (GtkWidget *widget,
218 static gint gtk_window_key_release_event (GtkWidget *widget,
220 static gint gtk_window_enter_notify_event (GtkWidget *widget,
221 GdkEventCrossing *event);
222 static gint gtk_window_leave_notify_event (GtkWidget *widget,
223 GdkEventCrossing *event);
224 static gint gtk_window_focus_in_event (GtkWidget *widget,
225 GdkEventFocus *event);
226 static gint gtk_window_focus_out_event (GtkWidget *widget,
227 GdkEventFocus *event);
228 static gint gtk_window_client_event (GtkWidget *widget,
229 GdkEventClient *event);
230 static void gtk_window_check_resize (GtkContainer *container);
231 static gint gtk_window_focus (GtkWidget *widget,
232 GtkDirectionType direction);
233 static void gtk_window_real_set_focus (GtkWindow *window,
236 static void gtk_window_real_activate_default (GtkWindow *window);
237 static void gtk_window_real_activate_focus (GtkWindow *window);
238 static void gtk_window_move_focus (GtkWindow *window,
239 GtkDirectionType dir);
240 static void gtk_window_keys_changed (GtkWindow *window);
241 static void gtk_window_paint (GtkWidget *widget,
243 static gint gtk_window_expose (GtkWidget *widget,
244 GdkEventExpose *event);
245 static void gtk_window_unset_transient_for (GtkWindow *window);
246 static void gtk_window_transient_parent_realized (GtkWidget *parent,
248 static void gtk_window_transient_parent_unrealized (GtkWidget *parent,
251 static GdkScreen *gtk_window_check_screen (GtkWindow *window);
253 static GtkWindowGeometryInfo* gtk_window_get_geometry_info (GtkWindow *window,
256 static void gtk_window_move_resize (GtkWindow *window);
257 static gboolean gtk_window_compare_hints (GdkGeometry *geometry_a,
259 GdkGeometry *geometry_b,
261 static void gtk_window_constrain_size (GtkWindow *window,
262 GdkGeometry *geometry,
268 static void gtk_window_constrain_position (GtkWindow *window,
273 static void gtk_window_compute_hints (GtkWindow *window,
274 GdkGeometry *new_geometry,
276 static void gtk_window_compute_configure_request (GtkWindow *window,
277 GdkRectangle *request,
278 GdkGeometry *geometry,
281 static void gtk_window_set_default_size_internal (GtkWindow *window,
282 gboolean change_width,
284 gboolean change_height,
286 gboolean is_geometry);
288 static void update_themed_icon (GtkIconTheme *theme,
290 static GList *icon_list_from_theme (GtkWidget *widget,
292 static void gtk_window_realize_icon (GtkWindow *window);
293 static void gtk_window_unrealize_icon (GtkWindow *window);
295 static void gtk_window_notify_keys_changed (GtkWindow *window);
296 static GtkKeyHash *gtk_window_get_key_hash (GtkWindow *window);
297 static void gtk_window_free_key_hash (GtkWindow *window);
298 static void gtk_window_on_composited_changed (GdkScreen *screen,
301 static GSList *toplevel_list = NULL;
302 static guint window_signals[LAST_SIGNAL] = { 0 };
303 static GList *default_icon_list = NULL;
304 static gchar *default_icon_name = NULL;
305 static guint default_icon_serial = 0;
306 static gboolean disable_startup_notification = FALSE;
307 static gboolean sent_startup_notification = FALSE;
309 static GQuark quark_gtk_embedded = 0;
310 static GQuark quark_gtk_window_key_hash = 0;
311 static GQuark quark_gtk_window_default_icon_pixmap = 0;
312 static GQuark quark_gtk_window_icon_info = 0;
314 static GtkBuildableIface *parent_buildable_iface;
316 static void gtk_window_set_property (GObject *object,
320 static void gtk_window_get_property (GObject *object,
326 static void gtk_window_buildable_interface_init (GtkBuildableIface *iface);
327 static void gtk_window_buildable_set_buildable_property (GtkBuildable *buildable,
330 const GValue *value);
331 static void gtk_window_buildable_parser_finished (GtkBuildable *buildable,
332 GtkBuilder *builder);
335 G_DEFINE_TYPE_WITH_CODE (GtkWindow, gtk_window, GTK_TYPE_BIN,
336 G_IMPLEMENT_INTERFACE (GTK_TYPE_BUILDABLE,
337 gtk_window_buildable_interface_init))
340 add_tab_bindings (GtkBindingSet *binding_set,
341 GdkModifierType modifiers,
342 GtkDirectionType direction)
344 gtk_binding_entry_add_signal (binding_set, GDK_Tab, modifiers,
346 GTK_TYPE_DIRECTION_TYPE, direction);
347 gtk_binding_entry_add_signal (binding_set, GDK_KP_Tab, modifiers,
349 GTK_TYPE_DIRECTION_TYPE, direction);
353 add_arrow_bindings (GtkBindingSet *binding_set,
355 GtkDirectionType direction)
357 guint keypad_keysym = keysym - GDK_Left + GDK_KP_Left;
359 gtk_binding_entry_add_signal (binding_set, keysym, 0,
361 GTK_TYPE_DIRECTION_TYPE, direction);
362 gtk_binding_entry_add_signal (binding_set, keysym, GDK_CONTROL_MASK,
364 GTK_TYPE_DIRECTION_TYPE, direction);
365 gtk_binding_entry_add_signal (binding_set, keypad_keysym, 0,
367 GTK_TYPE_DIRECTION_TYPE, direction);
368 gtk_binding_entry_add_signal (binding_set, keypad_keysym, GDK_CONTROL_MASK,
370 GTK_TYPE_DIRECTION_TYPE, direction);
374 extract_time_from_startup_id (const gchar* startup_id)
376 gchar *timestr = g_strrstr (startup_id, "_TIME");
377 guint32 retval = GDK_CURRENT_TIME;
384 /* Skip past the "_TIME" part */
387 timestamp = strtoul (timestr, &end, 0);
388 if (end != timestr && errno == 0)
396 startup_id_is_fake (const gchar* startup_id)
398 return strncmp (startup_id, "_TIME", 5) == 0;
402 gtk_window_class_init (GtkWindowClass *klass)
404 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
405 GtkObjectClass *object_class;
406 GtkWidgetClass *widget_class;
407 GtkContainerClass *container_class;
408 GtkBindingSet *binding_set;
410 object_class = (GtkObjectClass*) klass;
411 widget_class = (GtkWidgetClass*) klass;
412 container_class = (GtkContainerClass*) klass;
414 quark_gtk_embedded = g_quark_from_static_string ("gtk-embedded");
415 quark_gtk_window_key_hash = g_quark_from_static_string ("gtk-window-key-hash");
416 quark_gtk_window_default_icon_pixmap = g_quark_from_static_string ("gtk-window-default-icon-pixmap");
417 quark_gtk_window_icon_info = g_quark_from_static_string ("gtk-window-icon-info");
419 gobject_class->dispose = gtk_window_dispose;
420 gobject_class->finalize = gtk_window_finalize;
422 gobject_class->set_property = gtk_window_set_property;
423 gobject_class->get_property = gtk_window_get_property;
425 object_class->destroy = gtk_window_destroy;
427 widget_class->show = gtk_window_show;
428 widget_class->hide = gtk_window_hide;
429 widget_class->map = gtk_window_map;
430 widget_class->map_event = gtk_window_map_event;
431 widget_class->unmap = gtk_window_unmap;
432 widget_class->realize = gtk_window_realize;
433 widget_class->unrealize = gtk_window_unrealize;
434 widget_class->size_request = gtk_window_size_request;
435 widget_class->size_allocate = gtk_window_size_allocate;
436 widget_class->configure_event = gtk_window_configure_event;
437 widget_class->key_press_event = gtk_window_key_press_event;
438 widget_class->key_release_event = gtk_window_key_release_event;
439 widget_class->enter_notify_event = gtk_window_enter_notify_event;
440 widget_class->leave_notify_event = gtk_window_leave_notify_event;
441 widget_class->focus_in_event = gtk_window_focus_in_event;
442 widget_class->focus_out_event = gtk_window_focus_out_event;
443 widget_class->client_event = gtk_window_client_event;
444 widget_class->focus = gtk_window_focus;
446 widget_class->expose_event = gtk_window_expose;
448 container_class->check_resize = gtk_window_check_resize;
450 klass->set_focus = gtk_window_real_set_focus;
451 klass->frame_event = gtk_window_frame_event;
453 klass->activate_default = gtk_window_real_activate_default;
454 klass->activate_focus = gtk_window_real_activate_focus;
455 klass->move_focus = gtk_window_move_focus;
456 klass->keys_changed = gtk_window_keys_changed;
458 g_type_class_add_private (gobject_class, sizeof (GtkWindowPrivate));
461 g_object_class_install_property (gobject_class,
463 g_param_spec_enum ("type",
465 P_("The type of the window"),
466 GTK_TYPE_WINDOW_TYPE,
468 GTK_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
470 g_object_class_install_property (gobject_class,
472 g_param_spec_string ("title",
474 P_("The title of the window"),
476 GTK_PARAM_READWRITE));
478 g_object_class_install_property (gobject_class,
480 g_param_spec_string ("role",
482 P_("Unique identifier for the window to be used when restoring a session"),
484 GTK_PARAM_READWRITE));
487 * GtkWindow:startup-id:
489 * The :startup-id is a write-only property for setting window's
490 * startup notification identifier. See gtk_window_set_startup_id()
495 g_object_class_install_property (gobject_class,
497 g_param_spec_string ("startup-id",
499 P_("Unique startup identifier for the window used by startup-notification"),
501 GTK_PARAM_WRITABLE));
503 g_object_class_install_property (gobject_class,
505 g_param_spec_boolean ("allow-shrink",
507 /* xgettext:no-c-format */
508 P_("If TRUE, the window has no mimimum size. Setting this to TRUE is 99% of the time a bad idea"),
510 GTK_PARAM_READWRITE));
512 g_object_class_install_property (gobject_class,
514 g_param_spec_boolean ("allow-grow",
516 P_("If TRUE, users can expand the window beyond its minimum size"),
518 GTK_PARAM_READWRITE));
520 g_object_class_install_property (gobject_class,
522 g_param_spec_boolean ("resizable",
524 P_("If TRUE, users can resize the window"),
526 GTK_PARAM_READWRITE));
528 g_object_class_install_property (gobject_class,
530 g_param_spec_boolean ("modal",
532 P_("If TRUE, the window is modal (other windows are not usable while this one is up)"),
534 GTK_PARAM_READWRITE));
536 g_object_class_install_property (gobject_class,
538 g_param_spec_enum ("window-position",
539 P_("Window Position"),
540 P_("The initial position of the window"),
541 GTK_TYPE_WINDOW_POSITION,
543 GTK_PARAM_READWRITE));
545 g_object_class_install_property (gobject_class,
547 g_param_spec_int ("default-width",
549 P_("The default width of the window, used when initially showing the window"),
553 GTK_PARAM_READWRITE));
555 g_object_class_install_property (gobject_class,
557 g_param_spec_int ("default-height",
558 P_("Default Height"),
559 P_("The default height of the window, used when initially showing the window"),
563 GTK_PARAM_READWRITE));
565 g_object_class_install_property (gobject_class,
566 PROP_DESTROY_WITH_PARENT,
567 g_param_spec_boolean ("destroy-with-parent",
568 P_("Destroy with Parent"),
569 P_("If this window should be destroyed when the parent is destroyed"),
571 GTK_PARAM_READWRITE));
573 g_object_class_install_property (gobject_class,
575 g_param_spec_object ("icon",
577 P_("Icon for this window"),
579 GTK_PARAM_READWRITE));
582 * GtkWindow:icon-name:
584 * The :icon-name property specifies the name of the themed icon to
585 * use as the window icon. See #GtkIconTheme for more details.
589 g_object_class_install_property (gobject_class,
591 g_param_spec_string ("icon-name",
593 P_("Name of the themed icon for this window"),
595 GTK_PARAM_READWRITE));
597 g_object_class_install_property (gobject_class,
599 g_param_spec_object ("screen",
601 P_("The screen where this window will be displayed"),
603 GTK_PARAM_READWRITE));
605 g_object_class_install_property (gobject_class,
607 g_param_spec_boolean ("is-active",
609 P_("Whether the toplevel is the current active window"),
611 GTK_PARAM_READABLE));
613 g_object_class_install_property (gobject_class,
614 PROP_HAS_TOPLEVEL_FOCUS,
615 g_param_spec_boolean ("has-toplevel-focus",
616 P_("Focus in Toplevel"),
617 P_("Whether the input focus is within this GtkWindow"),
619 GTK_PARAM_READABLE));
621 g_object_class_install_property (gobject_class,
623 g_param_spec_enum ("type-hint",
625 P_("Hint to help the desktop environment understand what kind of window this is and how to treat it."),
626 GDK_TYPE_WINDOW_TYPE_HINT,
627 GDK_WINDOW_TYPE_HINT_NORMAL,
628 GTK_PARAM_READWRITE));
630 g_object_class_install_property (gobject_class,
631 PROP_SKIP_TASKBAR_HINT,
632 g_param_spec_boolean ("skip-taskbar-hint",
634 P_("TRUE if the window should not be in the task bar."),
636 GTK_PARAM_READWRITE));
638 g_object_class_install_property (gobject_class,
639 PROP_SKIP_PAGER_HINT,
640 g_param_spec_boolean ("skip-pager-hint",
642 P_("TRUE if the window should not be in the pager."),
644 GTK_PARAM_READWRITE));
646 g_object_class_install_property (gobject_class,
648 g_param_spec_boolean ("urgency-hint",
650 P_("TRUE if the window should be brought to the user's attention."),
652 GTK_PARAM_READWRITE));
655 * GtkWindow:accept-focus-hint:
657 * Whether the window should receive the input focus.
661 g_object_class_install_property (gobject_class,
663 g_param_spec_boolean ("accept-focus",
665 P_("TRUE if the window should receive the input focus."),
667 GTK_PARAM_READWRITE));
670 * GtkWindow:focus-on-map-hint:
672 * Whether the window should receive the input focus when mapped.
676 g_object_class_install_property (gobject_class,
678 g_param_spec_boolean ("focus-on-map",
680 P_("TRUE if the window should receive the input focus when mapped."),
682 GTK_PARAM_READWRITE));
685 * GtkWindow:decorated:
687 * Whether the window should be decorated by the window manager.
691 g_object_class_install_property (gobject_class,
693 g_param_spec_boolean ("decorated",
695 P_("Whether the window should be decorated by the window manager"),
697 GTK_PARAM_READWRITE));
700 * GtkWindow:deletable:
702 * Whether the window frame should have a close button.
706 g_object_class_install_property (gobject_class,
708 g_param_spec_boolean ("deletable",
710 P_("Whether the window frame should have a close button"),
712 GTK_PARAM_READWRITE));
718 * The window gravity of the window. See gtk_window_move() and #GdkGravity for
719 * more details about window gravity.
723 g_object_class_install_property (gobject_class,
725 g_param_spec_enum ("gravity",
727 P_("The window gravity of the window"),
729 GDK_GRAVITY_NORTH_WEST,
730 GTK_PARAM_READWRITE));
734 * GtkWindow:transient-for:
736 * The transient parent of the window. See gtk_window_set_transient_for() for
737 * more details about transient windows.
741 g_object_class_install_property (gobject_class,
743 g_param_spec_object ("transient-for",
744 P_("Transient for Window"),
745 P_("The transient parent of the dialog"),
747 GTK_PARAM_READWRITE| G_PARAM_CONSTRUCT));
751 * The requested opacity of the window. See gtk_window_set_opacity() for
752 * more details about window opacity.
756 g_object_class_install_property (gobject_class,
758 g_param_spec_double ("opacity",
759 P_("Opacity for Window"),
760 P_("The opacity of the window, from 0 to 1"),
764 GTK_PARAM_READWRITE));
766 window_signals[SET_FOCUS] =
767 g_signal_new (I_("set_focus"),
768 G_TYPE_FROM_CLASS (gobject_class),
770 G_STRUCT_OFFSET (GtkWindowClass, set_focus),
772 _gtk_marshal_VOID__OBJECT,
776 window_signals[FRAME_EVENT] =
777 g_signal_new (I_("frame_event"),
778 G_TYPE_FROM_CLASS (gobject_class),
780 G_STRUCT_OFFSET(GtkWindowClass, frame_event),
781 _gtk_boolean_handled_accumulator, NULL,
782 _gtk_marshal_BOOLEAN__BOXED,
786 window_signals[ACTIVATE_FOCUS] =
787 g_signal_new (I_("activate_focus"),
788 G_TYPE_FROM_CLASS (gobject_class),
789 G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
790 G_STRUCT_OFFSET (GtkWindowClass, activate_focus),
792 _gtk_marshal_VOID__VOID,
796 window_signals[ACTIVATE_DEFAULT] =
797 g_signal_new (I_("activate_default"),
798 G_TYPE_FROM_CLASS (gobject_class),
799 G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
800 G_STRUCT_OFFSET (GtkWindowClass, activate_default),
802 _gtk_marshal_VOID__VOID,
806 window_signals[KEYS_CHANGED] =
807 g_signal_new (I_("keys_changed"),
808 G_TYPE_FROM_CLASS (gobject_class),
810 G_STRUCT_OFFSET (GtkWindowClass, keys_changed),
812 _gtk_marshal_VOID__VOID,
820 binding_set = gtk_binding_set_by_class (klass);
822 gtk_binding_entry_add_signal (binding_set, GDK_space, 0,
823 "activate_focus", 0);
824 gtk_binding_entry_add_signal (binding_set, GDK_KP_Space, 0,
825 "activate_focus", 0);
827 gtk_binding_entry_add_signal (binding_set, GDK_Return, 0,
828 "activate_default", 0);
829 gtk_binding_entry_add_signal (binding_set, GDK_ISO_Enter, 0,
830 "activate_default", 0);
831 gtk_binding_entry_add_signal (binding_set, GDK_KP_Enter, 0,
832 "activate_default", 0);
834 add_arrow_bindings (binding_set, GDK_Up, GTK_DIR_UP);
835 add_arrow_bindings (binding_set, GDK_Down, GTK_DIR_DOWN);
836 add_arrow_bindings (binding_set, GDK_Left, GTK_DIR_LEFT);
837 add_arrow_bindings (binding_set, GDK_Right, GTK_DIR_RIGHT);
839 add_tab_bindings (binding_set, 0, GTK_DIR_TAB_FORWARD);
840 add_tab_bindings (binding_set, GDK_CONTROL_MASK, GTK_DIR_TAB_FORWARD);
841 add_tab_bindings (binding_set, GDK_SHIFT_MASK, GTK_DIR_TAB_BACKWARD);
842 add_tab_bindings (binding_set, GDK_CONTROL_MASK | GDK_SHIFT_MASK, GTK_DIR_TAB_BACKWARD);
846 gtk_window_init (GtkWindow *window)
848 GdkColormap *colormap;
849 GtkWindowPrivate *priv = GTK_WINDOW_GET_PRIVATE (window);
851 GTK_WIDGET_UNSET_FLAGS (window, GTK_NO_WINDOW);
852 GTK_WIDGET_SET_FLAGS (window, GTK_TOPLEVEL);
854 GTK_PRIVATE_SET_FLAG (window, GTK_ANCHORED);
856 gtk_container_set_resize_mode (GTK_CONTAINER (window), GTK_RESIZE_QUEUE);
858 window->title = NULL;
859 window->wmclass_name = g_strdup (g_get_prgname ());
860 window->wmclass_class = g_strdup (gdk_get_program_class ());
861 window->wm_role = NULL;
862 window->geometry_info = NULL;
863 window->type = GTK_WINDOW_TOPLEVEL;
864 window->focus_widget = NULL;
865 window->default_widget = NULL;
866 window->configure_request_count = 0;
867 window->allow_shrink = FALSE;
868 window->allow_grow = TRUE;
869 window->configure_notify_received = FALSE;
870 window->position = GTK_WIN_POS_NONE;
871 window->need_default_size = TRUE;
872 window->need_default_position = TRUE;
873 window->modal = FALSE;
874 window->frame = NULL;
875 window->has_frame = FALSE;
876 window->frame_left = 0;
877 window->frame_right = 0;
878 window->frame_top = 0;
879 window->frame_bottom = 0;
880 window->type_hint = GDK_WINDOW_TYPE_HINT_NORMAL;
881 window->gravity = GDK_GRAVITY_NORTH_WEST;
882 window->decorated = TRUE;
883 window->mnemonic_modifier = GDK_MOD1_MASK;
884 window->screen = gdk_screen_get_default ();
886 priv->accept_focus = TRUE;
887 priv->focus_on_map = TRUE;
888 priv->deletable = TRUE;
889 priv->type_hint = GDK_WINDOW_TYPE_HINT_NORMAL;
891 priv->startup_id = NULL;
893 colormap = _gtk_widget_peek_colormap ();
895 gtk_widget_set_colormap (GTK_WIDGET (window), colormap);
897 g_object_ref_sink (window);
898 window->has_user_ref_count = TRUE;
899 toplevel_list = g_slist_prepend (toplevel_list, window);
901 gtk_decorated_window_init (window);
903 g_signal_connect (window->screen, "composited_changed",
904 G_CALLBACK (gtk_window_on_composited_changed), window);
908 gtk_window_set_property (GObject *object,
915 window = GTK_WINDOW (object);
920 window->type = g_value_get_enum (value);
923 gtk_window_set_title (window, g_value_get_string (value));
926 gtk_window_set_role (window, g_value_get_string (value));
928 case PROP_STARTUP_ID:
929 gtk_window_set_startup_id (window, g_value_get_string (value));
931 case PROP_ALLOW_SHRINK:
932 window->allow_shrink = g_value_get_boolean (value);
933 gtk_widget_queue_resize (GTK_WIDGET (window));
935 case PROP_ALLOW_GROW:
936 window->allow_grow = g_value_get_boolean (value);
937 gtk_widget_queue_resize (GTK_WIDGET (window));
938 g_object_notify (G_OBJECT (window), "resizable");
941 window->allow_grow = g_value_get_boolean (value);
942 gtk_widget_queue_resize (GTK_WIDGET (window));
943 g_object_notify (G_OBJECT (window), "allow-grow");
946 gtk_window_set_modal (window, g_value_get_boolean (value));
949 gtk_window_set_position (window, g_value_get_enum (value));
951 case PROP_DEFAULT_WIDTH:
952 gtk_window_set_default_size_internal (window,
953 TRUE, g_value_get_int (value),
956 case PROP_DEFAULT_HEIGHT:
957 gtk_window_set_default_size_internal (window,
959 TRUE, g_value_get_int (value), FALSE);
961 case PROP_DESTROY_WITH_PARENT:
962 gtk_window_set_destroy_with_parent (window, g_value_get_boolean (value));
965 gtk_window_set_icon (window,
966 g_value_get_object (value));
969 gtk_window_set_icon_name (window, g_value_get_string (value));
972 gtk_window_set_screen (window, g_value_get_object (value));
975 gtk_window_set_type_hint (window,
976 g_value_get_enum (value));
978 case PROP_SKIP_TASKBAR_HINT:
979 gtk_window_set_skip_taskbar_hint (window,
980 g_value_get_boolean (value));
982 case PROP_SKIP_PAGER_HINT:
983 gtk_window_set_skip_pager_hint (window,
984 g_value_get_boolean (value));
986 case PROP_URGENCY_HINT:
987 gtk_window_set_urgency_hint (window,
988 g_value_get_boolean (value));
990 case PROP_ACCEPT_FOCUS:
991 gtk_window_set_accept_focus (window,
992 g_value_get_boolean (value));
994 case PROP_FOCUS_ON_MAP:
995 gtk_window_set_focus_on_map (window,
996 g_value_get_boolean (value));
999 gtk_window_set_decorated (window, g_value_get_boolean (value));
1001 case PROP_DELETABLE:
1002 gtk_window_set_deletable (window, g_value_get_boolean (value));
1005 gtk_window_set_gravity (window, g_value_get_enum (value));
1007 case PROP_TRANSIENT_FOR:
1008 gtk_window_set_transient_for (window, g_value_get_object (value));
1011 gtk_window_set_opacity (window, g_value_get_double (value));
1014 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1020 gtk_window_get_property (GObject *object,
1026 GtkWindowPrivate *priv;
1028 window = GTK_WINDOW (object);
1029 priv = GTK_WINDOW_GET_PRIVATE (window);
1033 GtkWindowGeometryInfo *info;
1035 g_value_set_enum (value, window->type);
1038 g_value_set_string (value, window->wm_role);
1041 g_value_set_string (value, window->title);
1043 case PROP_ALLOW_SHRINK:
1044 g_value_set_boolean (value, window->allow_shrink);
1046 case PROP_ALLOW_GROW:
1047 g_value_set_boolean (value, window->allow_grow);
1049 case PROP_RESIZABLE:
1050 g_value_set_boolean (value, window->allow_grow);
1053 g_value_set_boolean (value, window->modal);
1056 g_value_set_enum (value, window->position);
1058 case PROP_DEFAULT_WIDTH:
1059 info = gtk_window_get_geometry_info (window, FALSE);
1061 g_value_set_int (value, -1);
1063 g_value_set_int (value, info->default_width);
1065 case PROP_DEFAULT_HEIGHT:
1066 info = gtk_window_get_geometry_info (window, FALSE);
1068 g_value_set_int (value, -1);
1070 g_value_set_int (value, info->default_height);
1072 case PROP_DESTROY_WITH_PARENT:
1073 g_value_set_boolean (value, window->destroy_with_parent);
1076 g_value_set_object (value, gtk_window_get_icon (window));
1078 case PROP_ICON_NAME:
1079 g_value_set_string (value, gtk_window_get_icon_name (window));
1082 g_value_set_object (value, window->screen);
1084 case PROP_IS_ACTIVE:
1085 g_value_set_boolean (value, window->is_active);
1087 case PROP_HAS_TOPLEVEL_FOCUS:
1088 g_value_set_boolean (value, window->has_toplevel_focus);
1090 case PROP_TYPE_HINT:
1091 g_value_set_enum (value, priv->type_hint);
1093 case PROP_SKIP_TASKBAR_HINT:
1094 g_value_set_boolean (value,
1095 gtk_window_get_skip_taskbar_hint (window));
1097 case PROP_SKIP_PAGER_HINT:
1098 g_value_set_boolean (value,
1099 gtk_window_get_skip_pager_hint (window));
1101 case PROP_URGENCY_HINT:
1102 g_value_set_boolean (value,
1103 gtk_window_get_urgency_hint (window));
1105 case PROP_ACCEPT_FOCUS:
1106 g_value_set_boolean (value,
1107 gtk_window_get_accept_focus (window));
1109 case PROP_FOCUS_ON_MAP:
1110 g_value_set_boolean (value,
1111 gtk_window_get_focus_on_map (window));
1113 case PROP_DECORATED:
1114 g_value_set_boolean (value, gtk_window_get_decorated (window));
1116 case PROP_DELETABLE:
1117 g_value_set_boolean (value, gtk_window_get_deletable (window));
1120 g_value_set_enum (value, gtk_window_get_gravity (window));
1122 case PROP_TRANSIENT_FOR:
1123 g_value_set_object (value, gtk_window_get_transient_for (window));
1126 g_value_set_double (value, gtk_window_get_opacity (window));
1129 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1135 gtk_window_buildable_interface_init (GtkBuildableIface *iface)
1137 parent_buildable_iface = g_type_interface_peek_parent (iface);
1138 iface->set_buildable_property = gtk_window_buildable_set_buildable_property;
1139 iface->parser_finished = gtk_window_buildable_parser_finished;
1144 gtk_window_buildable_set_buildable_property (GtkBuildable *buildable,
1145 GtkBuilder *builder,
1147 const GValue *value)
1149 GtkWindowPrivate *priv = GTK_WINDOW_GET_PRIVATE (buildable);
1151 if (strcmp (name, "visible") == 0 && g_value_get_boolean (value))
1152 priv->builder_visible = TRUE;
1154 parent_buildable_iface->set_buildable_property (buildable, builder, name, value);
1158 gtk_window_buildable_parser_finished (GtkBuildable *buildable,
1159 GtkBuilder *builder)
1161 GtkWindowPrivate *priv = GTK_WINDOW_GET_PRIVATE (buildable);
1163 if (priv->builder_visible)
1164 gtk_widget_show (GTK_WIDGET (buildable));
1166 parent_buildable_iface->parser_finished (buildable, builder);
1171 * @type: type of window
1173 * Creates a new #GtkWindow, which is a toplevel window that can
1174 * contain other widgets. Nearly always, the type of the window should
1175 * be #GTK_WINDOW_TOPLEVEL. If you're implementing something like a
1176 * popup menu from scratch (which is a bad idea, just use #GtkMenu),
1177 * you might use #GTK_WINDOW_POPUP. #GTK_WINDOW_POPUP is not for
1178 * dialogs, though in some other toolkits dialogs are called "popups".
1179 * In GTK+, #GTK_WINDOW_POPUP means a pop-up menu or pop-up tooltip.
1180 * On X11, popup windows are not controlled by the <link
1181 * linkend="gtk-X11-arch">window manager</link>.
1183 * If you simply want an undecorated window (no window borders), use
1184 * gtk_window_set_decorated(), don't use #GTK_WINDOW_POPUP.
1186 * Return value: a new #GtkWindow.
1189 gtk_window_new (GtkWindowType type)
1193 g_return_val_if_fail (type >= GTK_WINDOW_TOPLEVEL && type <= GTK_WINDOW_POPUP, NULL);
1195 window = g_object_new (GTK_TYPE_WINDOW, NULL);
1197 window->type = type;
1199 return GTK_WIDGET (window);
1203 * gtk_window_set_title:
1204 * @window: a #GtkWindow
1205 * @title: title of the window
1207 * Sets the title of the #GtkWindow. The title of a window will be
1208 * displayed in its title bar; on the X Window System, the title bar
1209 * is rendered by the <link linkend="gtk-X11-arch">window
1210 * manager</link>, so exactly how the title appears to users may vary
1211 * according to a user's exact configuration. The title should help a
1212 * user distinguish this window from other windows they may have
1213 * open. A good title might include the application name and current
1214 * document filename, for example.
1218 gtk_window_set_title (GtkWindow *window,
1223 g_return_if_fail (GTK_IS_WINDOW (window));
1225 new_title = g_strdup (title);
1226 g_free (window->title);
1227 window->title = new_title;
1229 if (GTK_WIDGET_REALIZED (window))
1231 gdk_window_set_title (GTK_WIDGET (window)->window, window->title);
1233 gtk_decorated_window_set_title (window, title);
1236 g_object_notify (G_OBJECT (window), "title");
1240 * gtk_window_get_title:
1241 * @window: a #GtkWindow
1243 * Retrieves the title of the window. See gtk_window_set_title().
1245 * Return value: the title of the window, or %NULL if none has
1246 * been set explicitely. The returned string is owned by the widget
1247 * and must not be modified or freed.
1249 G_CONST_RETURN gchar *
1250 gtk_window_get_title (GtkWindow *window)
1252 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
1254 return window->title;
1258 * gtk_window_set_wmclass:
1259 * @window: a #GtkWindow
1260 * @wmclass_name: window name hint
1261 * @wmclass_class: window class hint
1263 * Don't use this function. It sets the X Window System "class" and
1264 * "name" hints for a window. According to the ICCCM, you should
1265 * always set these to the same value for all windows in an
1266 * application, and GTK+ sets them to that value by default, so calling
1267 * this function is sort of pointless. However, you may want to call
1268 * gtk_window_set_role() on each window in your application, for the
1269 * benefit of the session manager. Setting the role allows the window
1270 * manager to restore window positions when loading a saved session.
1274 gtk_window_set_wmclass (GtkWindow *window,
1275 const gchar *wmclass_name,
1276 const gchar *wmclass_class)
1278 g_return_if_fail (GTK_IS_WINDOW (window));
1280 g_free (window->wmclass_name);
1281 window->wmclass_name = g_strdup (wmclass_name);
1283 g_free (window->wmclass_class);
1284 window->wmclass_class = g_strdup (wmclass_class);
1286 if (GTK_WIDGET_REALIZED (window))
1287 g_warning ("gtk_window_set_wmclass: shouldn't set wmclass after window is realized!\n");
1291 * gtk_window_set_role:
1292 * @window: a #GtkWindow
1293 * @role: unique identifier for the window to be used when restoring a session
1295 * This function is only useful on X11, not with other GTK+ targets.
1297 * In combination with the window title, the window role allows a
1298 * <link linkend="gtk-X11-arch">window manager</link> to identify "the
1299 * same" window when an application is restarted. So for example you
1300 * might set the "toolbox" role on your app's toolbox window, so that
1301 * when the user restarts their session, the window manager can put
1302 * the toolbox back in the same place.
1304 * If a window already has a unique title, you don't need to set the
1305 * role, since the WM can use the title to identify the window when
1306 * restoring the session.
1310 gtk_window_set_role (GtkWindow *window,
1315 g_return_if_fail (GTK_IS_WINDOW (window));
1317 new_role = g_strdup (role);
1318 g_free (window->wm_role);
1319 window->wm_role = new_role;
1321 if (GTK_WIDGET_REALIZED (window))
1322 gdk_window_set_role (GTK_WIDGET (window)->window, window->wm_role);
1324 g_object_notify (G_OBJECT (window), "role");
1328 * gtk_window_set_startup_id:
1329 * @window: a #GtkWindow
1330 * @startup_id: a string with startup-notification identifier
1332 * Startup notification identifiers are used by desktop environment to
1333 * track application startup, to provide user feedback and other
1334 * features. This function changes the corresponding property on the
1335 * underlying GdkWindow. Normally, startup identifier is managed
1336 * automatically and you should only use this function in special cases
1337 * like transferring focus from other processes. You should use this
1338 * function before calling gtk_window_present() or any equivalent
1339 * function generating a window map event.
1341 * This function is only useful on X11, not with other GTK+ targets.
1346 gtk_window_set_startup_id (GtkWindow *window,
1347 const gchar *startup_id)
1349 GtkWindowPrivate *priv = GTK_WINDOW_GET_PRIVATE (window);
1351 g_return_if_fail (GTK_IS_WINDOW (window));
1353 g_free (priv->startup_id);
1354 priv->startup_id = g_strdup (startup_id);
1356 if (GTK_WIDGET_REALIZED (window))
1358 /* Here we differentiate real and "fake" startup notification IDs,
1359 * constructed on purpose just to pass interaction timestamp
1361 if (startup_id_is_fake (priv->startup_id))
1363 guint32 timestamp = extract_time_from_startup_id (priv->startup_id);
1365 gtk_window_present_with_time (window, timestamp);
1369 gdk_window_set_startup_id (GTK_WIDGET (window)->window,
1372 /* If window is mapped, terminate the startup-notification too */
1373 if (GTK_WIDGET_MAPPED (window) && !disable_startup_notification)
1374 gdk_notify_startup_complete_with_id (priv->startup_id);
1378 g_object_notify (G_OBJECT (window), "startup-id");
1382 * gtk_window_get_role:
1383 * @window: a #GtkWindow
1385 * Returns the role of the window. See gtk_window_set_role() for
1386 * further explanation.
1388 * Return value: the role of the window if set, or %NULL. The
1389 * returned is owned by the widget and must not be modified
1392 G_CONST_RETURN gchar *
1393 gtk_window_get_role (GtkWindow *window)
1395 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
1397 return window->wm_role;
1401 * gtk_window_set_focus:
1402 * @window: a #GtkWindow
1403 * @focus: widget to be the new focus widget, or %NULL to unset
1404 * any focus widget for the toplevel window.
1406 * If @focus is not the current focus widget, and is focusable, sets
1407 * it as the focus widget for the window. If @focus is %NULL, unsets
1408 * the focus widget for this window. To set the focus to a particular
1409 * widget in the toplevel, it is usually more convenient to use
1410 * gtk_widget_grab_focus() instead of this function.
1413 gtk_window_set_focus (GtkWindow *window,
1416 g_return_if_fail (GTK_IS_WINDOW (window));
1419 g_return_if_fail (GTK_IS_WIDGET (focus));
1420 g_return_if_fail (GTK_WIDGET_CAN_FOCUS (focus));
1424 gtk_widget_grab_focus (focus);
1427 /* Clear the existing focus chain, so that when we focus into
1428 * the window again, we start at the beginnning.
1430 GtkWidget *widget = window->focus_widget;
1433 while (widget->parent)
1435 widget = widget->parent;
1436 gtk_container_set_focus_child (GTK_CONTAINER (widget), NULL);
1440 _gtk_window_internal_set_focus (window, NULL);
1445 _gtk_window_internal_set_focus (GtkWindow *window,
1448 g_return_if_fail (GTK_IS_WINDOW (window));
1450 if ((window->focus_widget != focus) ||
1451 (focus && !GTK_WIDGET_HAS_FOCUS (focus)))
1452 g_signal_emit (window, window_signals[SET_FOCUS], 0, focus);
1456 * gtk_window_set_default:
1457 * @window: a #GtkWindow
1458 * @default_widget: widget to be the default, or %NULL to unset the
1459 * default widget for the toplevel.
1461 * The default widget is the widget that's activated when the user
1462 * presses Enter in a dialog (for example). This function sets or
1463 * unsets the default widget for a #GtkWindow about. When setting
1464 * (rather than unsetting) the default widget it's generally easier to
1465 * call gtk_widget_grab_focus() on the widget. Before making a widget
1466 * the default widget, you must set the #GTK_CAN_DEFAULT flag on the
1467 * widget you'd like to make the default using GTK_WIDGET_SET_FLAGS().
1470 gtk_window_set_default (GtkWindow *window,
1471 GtkWidget *default_widget)
1473 g_return_if_fail (GTK_IS_WINDOW (window));
1476 g_return_if_fail (GTK_WIDGET_CAN_DEFAULT (default_widget));
1478 if (window->default_widget != default_widget)
1480 GtkWidget *old_default_widget = NULL;
1483 g_object_ref (default_widget);
1485 if (window->default_widget)
1487 old_default_widget = window->default_widget;
1489 if (window->focus_widget != window->default_widget ||
1490 !GTK_WIDGET_RECEIVES_DEFAULT (window->default_widget))
1491 GTK_WIDGET_UNSET_FLAGS (window->default_widget, GTK_HAS_DEFAULT);
1492 gtk_widget_queue_draw (window->default_widget);
1495 window->default_widget = default_widget;
1497 if (window->default_widget)
1499 if (window->focus_widget == NULL ||
1500 !GTK_WIDGET_RECEIVES_DEFAULT (window->focus_widget))
1501 GTK_WIDGET_SET_FLAGS (window->default_widget, GTK_HAS_DEFAULT);
1502 gtk_widget_queue_draw (window->default_widget);
1505 if (old_default_widget)
1506 g_object_notify (G_OBJECT (old_default_widget), "has-default");
1510 g_object_notify (G_OBJECT (default_widget), "has-default");
1511 g_object_unref (default_widget);
1517 * gtk_window_get_default:
1518 * @window: a #GtkWindow
1520 * Returns the default widget for @window. See gtk_window_set_default()
1523 * Returns: the default widget, or %NULL if there is none.
1528 gtk_window_get_default (GtkWindow *window)
1530 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
1532 return window->default_widget;
1536 gtk_window_set_policy (GtkWindow *window,
1537 gboolean allow_shrink,
1538 gboolean allow_grow,
1539 gboolean auto_shrink)
1541 g_return_if_fail (GTK_IS_WINDOW (window));
1543 window->allow_shrink = (allow_shrink != FALSE);
1544 window->allow_grow = (allow_grow != FALSE);
1546 g_object_freeze_notify (G_OBJECT (window));
1547 g_object_notify (G_OBJECT (window), "allow-shrink");
1548 g_object_notify (G_OBJECT (window), "allow-grow");
1549 g_object_notify (G_OBJECT (window), "resizable");
1550 g_object_thaw_notify (G_OBJECT (window));
1552 gtk_widget_queue_resize_no_redraw (GTK_WIDGET (window));
1556 handle_keys_changed (gpointer data)
1560 window = GTK_WINDOW (data);
1562 if (window->keys_changed_handler)
1564 g_source_remove (window->keys_changed_handler);
1565 window->keys_changed_handler = 0;
1568 g_signal_emit (window, window_signals[KEYS_CHANGED], 0);
1574 gtk_window_notify_keys_changed (GtkWindow *window)
1576 if (!window->keys_changed_handler)
1577 window->keys_changed_handler = gdk_threads_add_idle (handle_keys_changed, window);
1581 * gtk_window_add_accel_group:
1582 * @window: window to attach accelerator group to
1583 * @accel_group: a #GtkAccelGroup
1585 * Associate @accel_group with @window, such that calling
1586 * gtk_accel_groups_activate() on @window will activate accelerators
1590 gtk_window_add_accel_group (GtkWindow *window,
1591 GtkAccelGroup *accel_group)
1593 g_return_if_fail (GTK_IS_WINDOW (window));
1594 g_return_if_fail (GTK_IS_ACCEL_GROUP (accel_group));
1596 _gtk_accel_group_attach (accel_group, G_OBJECT (window));
1597 g_signal_connect_object (accel_group, "accel_changed",
1598 G_CALLBACK (gtk_window_notify_keys_changed),
1599 window, G_CONNECT_SWAPPED);
1600 gtk_window_notify_keys_changed (window);
1604 * gtk_window_remove_accel_group:
1605 * @window: a #GtkWindow
1606 * @accel_group: a #GtkAccelGroup
1608 * Reverses the effects of gtk_window_add_accel_group().
1611 gtk_window_remove_accel_group (GtkWindow *window,
1612 GtkAccelGroup *accel_group)
1614 g_return_if_fail (GTK_IS_WINDOW (window));
1615 g_return_if_fail (GTK_IS_ACCEL_GROUP (accel_group));
1617 g_signal_handlers_disconnect_by_func (accel_group,
1618 gtk_window_notify_keys_changed,
1620 _gtk_accel_group_detach (accel_group, G_OBJECT (window));
1621 gtk_window_notify_keys_changed (window);
1624 static GtkMnemonicHash *
1625 gtk_window_get_mnemonic_hash (GtkWindow *window,
1628 GtkWindowPrivate *private = GTK_WINDOW_GET_PRIVATE (window);
1629 if (!private->mnemonic_hash && create)
1630 private->mnemonic_hash = _gtk_mnemonic_hash_new ();
1632 return private->mnemonic_hash;
1636 * gtk_window_add_mnemonic:
1637 * @window: a #GtkWindow
1638 * @keyval: the mnemonic
1639 * @target: the widget that gets activated by the mnemonic
1641 * Adds a mnemonic to this window.
1644 gtk_window_add_mnemonic (GtkWindow *window,
1648 g_return_if_fail (GTK_IS_WINDOW (window));
1649 g_return_if_fail (GTK_IS_WIDGET (target));
1651 _gtk_mnemonic_hash_add (gtk_window_get_mnemonic_hash (window, TRUE),
1653 gtk_window_notify_keys_changed (window);
1657 * gtk_window_remove_mnemonic:
1658 * @window: a #GtkWindow
1659 * @keyval: the mnemonic
1660 * @target: the widget that gets activated by the mnemonic
1662 * Removes a mnemonic from this window.
1665 gtk_window_remove_mnemonic (GtkWindow *window,
1669 g_return_if_fail (GTK_IS_WINDOW (window));
1670 g_return_if_fail (GTK_IS_WIDGET (target));
1672 _gtk_mnemonic_hash_remove (gtk_window_get_mnemonic_hash (window, TRUE),
1674 gtk_window_notify_keys_changed (window);
1678 * gtk_window_mnemonic_activate:
1679 * @window: a #GtkWindow
1680 * @keyval: the mnemonic
1681 * @modifier: the modifiers
1682 * @returns: %TRUE if the activation is done.
1684 * Activates the targets associated with the mnemonic.
1687 gtk_window_mnemonic_activate (GtkWindow *window,
1689 GdkModifierType modifier)
1691 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
1693 if (window->mnemonic_modifier == (modifier & gtk_accelerator_get_default_mod_mask ()))
1695 GtkMnemonicHash *mnemonic_hash = gtk_window_get_mnemonic_hash (window, FALSE);
1697 return _gtk_mnemonic_hash_activate (mnemonic_hash, keyval);
1704 * gtk_window_set_mnemonic_modifier:
1705 * @window: a #GtkWindow
1706 * @modifier: the modifier mask used to activate
1707 * mnemonics on this window.
1709 * Sets the mnemonic modifier for this window.
1712 gtk_window_set_mnemonic_modifier (GtkWindow *window,
1713 GdkModifierType modifier)
1715 g_return_if_fail (GTK_IS_WINDOW (window));
1716 g_return_if_fail ((modifier & ~GDK_MODIFIER_MASK) == 0);
1718 window->mnemonic_modifier = modifier;
1719 gtk_window_notify_keys_changed (window);
1723 * gtk_window_get_mnemonic_modifier:
1724 * @window: a #GtkWindow
1726 * Returns the mnemonic modifier for this window. See
1727 * gtk_window_set_mnemonic_modifier().
1729 * Return value: the modifier mask used to activate
1730 * mnemonics on this window.
1733 gtk_window_get_mnemonic_modifier (GtkWindow *window)
1735 g_return_val_if_fail (GTK_IS_WINDOW (window), 0);
1737 return window->mnemonic_modifier;
1741 * gtk_window_set_position:
1742 * @window: a #GtkWindow.
1743 * @position: a position constraint.
1745 * Sets a position constraint for this window. If the old or new
1746 * constraint is %GTK_WIN_POS_CENTER_ALWAYS, this will also cause
1747 * the window to be repositioned to satisfy the new constraint.
1750 gtk_window_set_position (GtkWindow *window,
1751 GtkWindowPosition position)
1753 g_return_if_fail (GTK_IS_WINDOW (window));
1755 if (position == GTK_WIN_POS_CENTER_ALWAYS ||
1756 window->position == GTK_WIN_POS_CENTER_ALWAYS)
1758 GtkWindowGeometryInfo *info;
1760 info = gtk_window_get_geometry_info (window, TRUE);
1762 /* this flag causes us to re-request the CENTER_ALWAYS
1763 * constraint in gtk_window_move_resize(), see
1764 * comment in that function.
1766 info->position_constraints_changed = TRUE;
1768 gtk_widget_queue_resize_no_redraw (GTK_WIDGET (window));
1771 window->position = position;
1773 g_object_notify (G_OBJECT (window), "window-position");
1777 * gtk_window_activate_focus:
1778 * @window: a #GtkWindow
1780 * Activates the current focused widget within the window.
1782 * Return value: %TRUE if a widget got activated.
1785 gtk_window_activate_focus (GtkWindow *window)
1787 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
1789 if (window->focus_widget && GTK_WIDGET_IS_SENSITIVE (window->focus_widget))
1790 return gtk_widget_activate (window->focus_widget);
1796 * gtk_window_get_focus:
1797 * @window: a #GtkWindow
1799 * Retrieves the current focused widget within the window.
1800 * Note that this is the widget that would have the focus
1801 * if the toplevel window focused; if the toplevel window
1802 * is not focused then <literal>GTK_WIDGET_HAS_FOCUS (widget)</literal> will
1803 * not be %TRUE for the widget.
1805 * Return value: the currently focused widget, or %NULL if there is none.
1808 gtk_window_get_focus (GtkWindow *window)
1810 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
1812 return window->focus_widget;
1816 * gtk_window_activate_default:
1817 * @window: a #GtkWindow
1819 * Activates the default widget for the window, unless the current
1820 * focused widget has been configured to receive the default action
1821 * (see #GTK_RECEIVES_DEFAULT in #GtkWidgetFlags), in which case the
1822 * focused widget is activated.
1824 * Return value: %TRUE if a widget got activated.
1827 gtk_window_activate_default (GtkWindow *window)
1829 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
1831 if (window->default_widget && GTK_WIDGET_IS_SENSITIVE (window->default_widget) &&
1832 (!window->focus_widget || !GTK_WIDGET_RECEIVES_DEFAULT (window->focus_widget)))
1833 return gtk_widget_activate (window->default_widget);
1834 else if (window->focus_widget && GTK_WIDGET_IS_SENSITIVE (window->focus_widget))
1835 return gtk_widget_activate (window->focus_widget);
1841 * gtk_window_set_modal:
1842 * @window: a #GtkWindow
1843 * @modal: whether the window is modal
1845 * Sets a window modal or non-modal. Modal windows prevent interaction
1846 * with other windows in the same application. To keep modal dialogs
1847 * on top of main application windows, use
1848 * gtk_window_set_transient_for() to make the dialog transient for the
1849 * parent; most <link linkend="gtk-X11-arch">window managers</link>
1850 * will then disallow lowering the dialog below the parent.
1855 gtk_window_set_modal (GtkWindow *window,
1858 g_return_if_fail (GTK_IS_WINDOW (window));
1860 modal = modal != FALSE;
1861 if (window->modal == modal)
1864 window->modal = modal;
1866 /* adjust desired modality state */
1867 if (GTK_WIDGET_REALIZED (window))
1869 GtkWidget *widget = GTK_WIDGET (window);
1872 gdk_window_set_modal_hint (widget->window, TRUE);
1874 gdk_window_set_modal_hint (widget->window, FALSE);
1877 if (GTK_WIDGET_VISIBLE (window))
1880 gtk_grab_add (GTK_WIDGET (window));
1882 gtk_grab_remove (GTK_WIDGET (window));
1885 g_object_notify (G_OBJECT (window), "modal");
1889 * gtk_window_get_modal:
1890 * @window: a #GtkWindow
1892 * Returns whether the window is modal. See gtk_window_set_modal().
1894 * Return value: %TRUE if the window is set to be modal and
1895 * establishes a grab when shown
1898 gtk_window_get_modal (GtkWindow *window)
1900 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
1902 return window->modal;
1906 * gtk_window_list_toplevels:
1908 * Returns a list of all existing toplevel windows. The widgets
1909 * in the list are not individually referenced. If you want
1910 * to iterate through the list and perform actions involving
1911 * callbacks that might destroy the widgets, you <emphasis>must</emphasis> call
1912 * <literal>g_list_foreach (result, (GFunc)g_object_ref, NULL)</literal> first, and
1913 * then unref all the widgets afterwards.
1915 * Return value: list of toplevel widgets
1918 gtk_window_list_toplevels (void)
1923 for (slist = toplevel_list; slist; slist = slist->next)
1924 list = g_list_prepend (list, slist->data);
1930 gtk_window_add_embedded_xid (GtkWindow *window, guint xid)
1932 GList *embedded_windows;
1934 g_return_if_fail (GTK_IS_WINDOW (window));
1936 embedded_windows = g_object_get_qdata (G_OBJECT (window), quark_gtk_embedded);
1937 if (embedded_windows)
1938 g_object_steal_qdata (G_OBJECT (window), quark_gtk_embedded);
1939 embedded_windows = g_list_prepend (embedded_windows,
1940 GUINT_TO_POINTER (xid));
1942 g_object_set_qdata_full (G_OBJECT (window), quark_gtk_embedded,
1945 (GDestroyNotify) g_list_free : NULL);
1949 gtk_window_remove_embedded_xid (GtkWindow *window, guint xid)
1951 GList *embedded_windows;
1954 g_return_if_fail (GTK_IS_WINDOW (window));
1956 embedded_windows = g_object_get_qdata (G_OBJECT (window), quark_gtk_embedded);
1957 if (embedded_windows)
1958 g_object_steal_qdata (G_OBJECT (window), quark_gtk_embedded);
1960 node = g_list_find (embedded_windows, GUINT_TO_POINTER (xid));
1963 embedded_windows = g_list_remove_link (embedded_windows, node);
1964 g_list_free_1 (node);
1967 g_object_set_qdata_full (G_OBJECT (window), quark_gtk_embedded,
1970 (GDestroyNotify) g_list_free : NULL);
1974 _gtk_window_reposition (GtkWindow *window,
1978 g_return_if_fail (GTK_IS_WINDOW (window));
1980 gtk_window_move (window, x, y);
1984 gtk_window_dispose (GObject *object)
1986 GtkWindow *window = GTK_WINDOW (object);
1988 gtk_window_set_focus (window, NULL);
1989 gtk_window_set_default (window, NULL);
1991 G_OBJECT_CLASS (gtk_window_parent_class)->dispose (object);
1995 parent_destroyed_callback (GtkWindow *parent, GtkWindow *child)
1997 gtk_widget_destroy (GTK_WIDGET (child));
2001 connect_parent_destroyed (GtkWindow *window)
2003 if (window->transient_parent)
2005 g_signal_connect (window->transient_parent,
2007 G_CALLBACK (parent_destroyed_callback),
2013 disconnect_parent_destroyed (GtkWindow *window)
2015 if (window->transient_parent)
2017 g_signal_handlers_disconnect_by_func (window->transient_parent,
2018 parent_destroyed_callback,
2024 gtk_window_transient_parent_realized (GtkWidget *parent,
2027 if (GTK_WIDGET_REALIZED (window))
2028 gdk_window_set_transient_for (window->window, parent->window);
2032 gtk_window_transient_parent_unrealized (GtkWidget *parent,
2035 if (GTK_WIDGET_REALIZED (window))
2036 gdk_property_delete (window->window,
2037 gdk_atom_intern_static_string ("WM_TRANSIENT_FOR"));
2041 gtk_window_transient_parent_screen_changed (GtkWindow *parent,
2045 gtk_window_set_screen (window, parent->screen);
2049 gtk_window_unset_transient_for (GtkWindow *window)
2051 GtkWindowPrivate *priv = GTK_WINDOW_GET_PRIVATE (window);
2053 if (window->transient_parent)
2055 g_signal_handlers_disconnect_by_func (window->transient_parent,
2056 gtk_window_transient_parent_realized,
2058 g_signal_handlers_disconnect_by_func (window->transient_parent,
2059 gtk_window_transient_parent_unrealized,
2061 g_signal_handlers_disconnect_by_func (window->transient_parent,
2062 gtk_window_transient_parent_screen_changed,
2064 g_signal_handlers_disconnect_by_func (window->transient_parent,
2065 gtk_widget_destroyed,
2066 &window->transient_parent);
2068 if (window->destroy_with_parent)
2069 disconnect_parent_destroyed (window);
2071 window->transient_parent = NULL;
2073 if (priv->transient_parent_group)
2075 priv->transient_parent_group = FALSE;
2076 gtk_window_group_remove_window (window->group,
2083 * gtk_window_set_transient_for:
2084 * @window: a #GtkWindow
2085 * @parent: parent window
2087 * Dialog windows should be set transient for the main application
2088 * window they were spawned from. This allows <link
2089 * linkend="gtk-X11-arch">window managers</link> to e.g. keep the
2090 * dialog on top of the main window, or center the dialog over the
2091 * main window. gtk_dialog_new_with_buttons() and other convenience
2092 * functions in GTK+ will sometimes call
2093 * gtk_window_set_transient_for() on your behalf.
2095 * On Windows, this function puts the child window on top of the parent,
2096 * much as the window manager would have done on X.
2100 gtk_window_set_transient_for (GtkWindow *window,
2103 GtkWindowPrivate *priv = GTK_WINDOW_GET_PRIVATE (window);
2105 g_return_if_fail (GTK_IS_WINDOW (window));
2106 g_return_if_fail (parent == NULL || GTK_IS_WINDOW (parent));
2107 g_return_if_fail (window != parent);
2109 if (window->transient_parent)
2111 if (GTK_WIDGET_REALIZED (window) &&
2112 GTK_WIDGET_REALIZED (window->transient_parent) &&
2113 (!parent || !GTK_WIDGET_REALIZED (parent)))
2114 gtk_window_transient_parent_unrealized (GTK_WIDGET (window->transient_parent),
2115 GTK_WIDGET (window));
2117 gtk_window_unset_transient_for (window);
2120 window->transient_parent = parent;
2124 g_signal_connect (parent, "destroy",
2125 G_CALLBACK (gtk_widget_destroyed),
2126 &window->transient_parent);
2127 g_signal_connect (parent, "realize",
2128 G_CALLBACK (gtk_window_transient_parent_realized),
2130 g_signal_connect (parent, "unrealize",
2131 G_CALLBACK (gtk_window_transient_parent_unrealized),
2133 g_signal_connect (parent, "notify::screen",
2134 G_CALLBACK (gtk_window_transient_parent_screen_changed),
2137 gtk_window_set_screen (window, parent->screen);
2139 if (window->destroy_with_parent)
2140 connect_parent_destroyed (window);
2142 if (GTK_WIDGET_REALIZED (window) &&
2143 GTK_WIDGET_REALIZED (parent))
2144 gtk_window_transient_parent_realized (GTK_WIDGET (parent),
2145 GTK_WIDGET (window));
2149 gtk_window_group_add_window (parent->group, window);
2150 priv->transient_parent_group = TRUE;
2156 * gtk_window_get_transient_for:
2157 * @window: a #GtkWindow
2159 * Fetches the transient parent for this window. See
2160 * gtk_window_set_transient_for().
2162 * Return value: the transient parent for this window, or %NULL
2163 * if no transient parent has been set.
2166 gtk_window_get_transient_for (GtkWindow *window)
2168 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
2170 return window->transient_parent;
2174 * gtk_window_set_opacity:
2175 * @window: a #GtkWindow
2176 * @opacity: desired opacity, between 0 and 1
2178 * Request the windowing system to make @window partially transparent,
2179 * with opacity 0 being fully transparent and 1 fully opaque. (Values
2180 * of the opacity parameter are clamped to the [0,1] range.) On X11
2181 * this has any effect only on X screens with a compositing manager
2182 * running. See gtk_widget_is_composited(). On Windows it should work
2185 * Note that setting a window's opacity after the window has been
2186 * shown causes it to flicker once on Windows.
2191 gtk_window_set_opacity (GtkWindow *window,
2194 GtkWindowPrivate *priv;
2196 g_return_if_fail (GTK_IS_WINDOW (window));
2198 priv = GTK_WINDOW_GET_PRIVATE (window);
2202 else if (opacity > 1.0)
2205 priv->opacity_set = TRUE;
2206 priv->opacity = opacity;
2208 if (GTK_WIDGET_REALIZED (window))
2209 gdk_window_set_opacity (GTK_WIDGET (window)->window, priv->opacity);
2213 * gtk_window_get_opacity:
2214 * @window: a #GtkWindow
2216 * Fetches the requested opacity for this window. See
2217 * gtk_window_set_opacity().
2219 * Return value: the requested opacity for this window.
2224 gtk_window_get_opacity (GtkWindow *window)
2226 GtkWindowPrivate *priv;
2228 g_return_val_if_fail (GTK_IS_WINDOW (window), 0.0);
2230 priv = GTK_WINDOW_GET_PRIVATE (window);
2232 return priv->opacity;
2236 * gtk_window_set_type_hint:
2237 * @window: a #GtkWindow
2238 * @hint: the window type
2240 * By setting the type hint for the window, you allow the window
2241 * manager to decorate and handle the window in a way which is
2242 * suitable to the function of the window in your application.
2244 * This function should be called before the window becomes visible.
2246 * gtk_dialog_new_with_buttons() and other convenience functions in GTK+
2247 * will sometimes call gtk_window_set_type_hint() on your behalf.
2251 gtk_window_set_type_hint (GtkWindow *window,
2252 GdkWindowTypeHint hint)
2254 GtkWindowPrivate *priv;
2256 g_return_if_fail (GTK_IS_WINDOW (window));
2257 g_return_if_fail (!GTK_WIDGET_VISIBLE (window));
2259 priv = GTK_WINDOW_GET_PRIVATE (window);
2261 if (hint < GDK_WINDOW_TYPE_HINT_DROPDOWN_MENU)
2262 window->type_hint = hint;
2264 window->type_hint = GDK_WINDOW_TYPE_HINT_NORMAL;
2266 priv->reset_type_hint = TRUE;
2267 priv->type_hint = hint;
2271 * gtk_window_get_type_hint:
2272 * @window: a #GtkWindow
2274 * Gets the type hint for this window. See gtk_window_set_type_hint().
2276 * Return value: the type hint for @window.
2279 gtk_window_get_type_hint (GtkWindow *window)
2281 GtkWindowPrivate *priv;
2283 g_return_val_if_fail (GTK_IS_WINDOW (window), GDK_WINDOW_TYPE_HINT_NORMAL);
2285 priv = GTK_WINDOW_GET_PRIVATE (window);
2287 return priv->type_hint;
2291 * gtk_window_set_skip_taskbar_hint:
2292 * @window: a #GtkWindow
2293 * @setting: %TRUE to keep this window from appearing in the task bar
2295 * Windows may set a hint asking the desktop environment not to display
2296 * the window in the task bar. This function sets this hint.
2301 gtk_window_set_skip_taskbar_hint (GtkWindow *window,
2304 GtkWindowPrivate *priv;
2306 g_return_if_fail (GTK_IS_WINDOW (window));
2308 priv = GTK_WINDOW_GET_PRIVATE (window);
2310 setting = setting != FALSE;
2312 if (priv->skips_taskbar != setting)
2314 priv->skips_taskbar = setting;
2315 if (GTK_WIDGET_REALIZED (window))
2316 gdk_window_set_skip_taskbar_hint (GTK_WIDGET (window)->window,
2317 priv->skips_taskbar);
2318 g_object_notify (G_OBJECT (window), "skip-taskbar-hint");
2323 * gtk_window_get_skip_taskbar_hint:
2324 * @window: a #GtkWindow
2326 * Gets the value set by gtk_window_set_skip_taskbar_hint()
2328 * Return value: %TRUE if window shouldn't be in taskbar
2333 gtk_window_get_skip_taskbar_hint (GtkWindow *window)
2335 GtkWindowPrivate *priv;
2337 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
2339 priv = GTK_WINDOW_GET_PRIVATE (window);
2341 return priv->skips_taskbar;
2345 * gtk_window_set_skip_pager_hint:
2346 * @window: a #GtkWindow
2347 * @setting: %TRUE to keep this window from appearing in the pager
2349 * Windows may set a hint asking the desktop environment not to display
2350 * the window in the pager. This function sets this hint.
2351 * (A "pager" is any desktop navigation tool such as a workspace
2352 * switcher that displays a thumbnail representation of the windows
2358 gtk_window_set_skip_pager_hint (GtkWindow *window,
2361 GtkWindowPrivate *priv;
2363 g_return_if_fail (GTK_IS_WINDOW (window));
2365 priv = GTK_WINDOW_GET_PRIVATE (window);
2367 setting = setting != FALSE;
2369 if (priv->skips_pager != setting)
2371 priv->skips_pager = setting;
2372 if (GTK_WIDGET_REALIZED (window))
2373 gdk_window_set_skip_pager_hint (GTK_WIDGET (window)->window,
2375 g_object_notify (G_OBJECT (window), "skip-pager-hint");
2380 * gtk_window_get_skip_pager_hint:
2381 * @window: a #GtkWindow
2383 * Gets the value set by gtk_window_set_skip_pager_hint().
2385 * Return value: %TRUE if window shouldn't be in pager
2390 gtk_window_get_skip_pager_hint (GtkWindow *window)
2392 GtkWindowPrivate *priv;
2394 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
2396 priv = GTK_WINDOW_GET_PRIVATE (window);
2398 return priv->skips_pager;
2402 * gtk_window_set_urgency_hint:
2403 * @window: a #GtkWindow
2404 * @setting: %TRUE to mark this window as urgent
2406 * Windows may set a hint asking the desktop environment to draw
2407 * the users attention to the window. This function sets this hint.
2412 gtk_window_set_urgency_hint (GtkWindow *window,
2415 GtkWindowPrivate *priv;
2417 g_return_if_fail (GTK_IS_WINDOW (window));
2419 priv = GTK_WINDOW_GET_PRIVATE (window);
2421 setting = setting != FALSE;
2423 if (priv->urgent != setting)
2425 priv->urgent = setting;
2426 if (GTK_WIDGET_REALIZED (window))
2427 gdk_window_set_urgency_hint (GTK_WIDGET (window)->window,
2429 g_object_notify (G_OBJECT (window), "urgency-hint");
2434 * gtk_window_get_urgency_hint:
2435 * @window: a #GtkWindow
2437 * Gets the value set by gtk_window_set_urgency_hint()
2439 * Return value: %TRUE if window is urgent
2444 gtk_window_get_urgency_hint (GtkWindow *window)
2446 GtkWindowPrivate *priv;
2448 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
2450 priv = GTK_WINDOW_GET_PRIVATE (window);
2452 return priv->urgent;
2456 * gtk_window_set_accept_focus:
2457 * @window: a #GtkWindow
2458 * @setting: %TRUE to let this window receive input focus
2460 * Windows may set a hint asking the desktop environment not to receive
2461 * the input focus. This function sets this hint.
2466 gtk_window_set_accept_focus (GtkWindow *window,
2469 GtkWindowPrivate *priv;
2471 g_return_if_fail (GTK_IS_WINDOW (window));
2473 priv = GTK_WINDOW_GET_PRIVATE (window);
2475 setting = setting != FALSE;
2477 if (priv->accept_focus != setting)
2479 priv->accept_focus = setting;
2480 if (GTK_WIDGET_REALIZED (window))
2481 gdk_window_set_accept_focus (GTK_WIDGET (window)->window,
2482 priv->accept_focus);
2483 g_object_notify (G_OBJECT (window), "accept-focus");
2488 * gtk_window_get_accept_focus:
2489 * @window: a #GtkWindow
2491 * Gets the value set by gtk_window_set_accept_focus().
2493 * Return value: %TRUE if window should receive the input focus
2498 gtk_window_get_accept_focus (GtkWindow *window)
2500 GtkWindowPrivate *priv;
2502 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
2504 priv = GTK_WINDOW_GET_PRIVATE (window);
2506 return priv->accept_focus;
2510 * gtk_window_set_focus_on_map:
2511 * @window: a #GtkWindow
2512 * @setting: %TRUE to let this window receive input focus on map
2514 * Windows may set a hint asking the desktop environment not to receive
2515 * the input focus when the window is mapped. This function sets this
2521 gtk_window_set_focus_on_map (GtkWindow *window,
2524 GtkWindowPrivate *priv;
2526 g_return_if_fail (GTK_IS_WINDOW (window));
2528 priv = GTK_WINDOW_GET_PRIVATE (window);
2530 setting = setting != FALSE;
2532 if (priv->focus_on_map != setting)
2534 priv->focus_on_map = setting;
2535 if (GTK_WIDGET_REALIZED (window))
2536 gdk_window_set_focus_on_map (GTK_WIDGET (window)->window,
2537 priv->focus_on_map);
2538 g_object_notify (G_OBJECT (window), "focus-on-map");
2543 * gtk_window_get_focus_on_map:
2544 * @window: a #GtkWindow
2546 * Gets the value set by gtk_window_set_focus_on_map().
2548 * Return value: %TRUE if window should receive the input focus when
2554 gtk_window_get_focus_on_map (GtkWindow *window)
2556 GtkWindowPrivate *priv;
2558 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
2560 priv = GTK_WINDOW_GET_PRIVATE (window);
2562 return priv->focus_on_map;
2566 * gtk_window_set_destroy_with_parent:
2567 * @window: a #GtkWindow
2568 * @setting: whether to destroy @window with its transient parent
2570 * If @setting is %TRUE, then destroying the transient parent of @window
2571 * will also destroy @window itself. This is useful for dialogs that
2572 * shouldn't persist beyond the lifetime of the main window they're
2573 * associated with, for example.
2576 gtk_window_set_destroy_with_parent (GtkWindow *window,
2579 g_return_if_fail (GTK_IS_WINDOW (window));
2581 if (window->destroy_with_parent == (setting != FALSE))
2584 if (window->destroy_with_parent)
2586 disconnect_parent_destroyed (window);
2590 connect_parent_destroyed (window);
2593 window->destroy_with_parent = setting;
2595 g_object_notify (G_OBJECT (window), "destroy-with-parent");
2599 * gtk_window_get_destroy_with_parent:
2600 * @window: a #GtkWindow
2602 * Returns whether the window will be destroyed with its transient parent. See
2603 * gtk_window_set_destroy_with_parent ().
2605 * Return value: %TRUE if the window will be destroyed with its transient parent.
2608 gtk_window_get_destroy_with_parent (GtkWindow *window)
2610 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
2612 return window->destroy_with_parent;
2615 static GtkWindowGeometryInfo*
2616 gtk_window_get_geometry_info (GtkWindow *window,
2619 GtkWindowGeometryInfo *info;
2621 info = window->geometry_info;
2622 if (!info && create)
2624 info = g_new0 (GtkWindowGeometryInfo, 1);
2626 info->default_width = -1;
2627 info->default_height = -1;
2628 info->resize_width = -1;
2629 info->resize_height = -1;
2630 info->initial_x = 0;
2631 info->initial_y = 0;
2632 info->initial_pos_set = FALSE;
2633 info->default_is_geometry = FALSE;
2634 info->position_constraints_changed = FALSE;
2635 info->last.configure_request.x = 0;
2636 info->last.configure_request.y = 0;
2637 info->last.configure_request.width = -1;
2638 info->last.configure_request.height = -1;
2639 info->widget = NULL;
2641 window->geometry_info = info;
2648 * gtk_window_set_geometry_hints:
2649 * @window: a #GtkWindow
2650 * @geometry_widget: widget the geometry hints will be applied to
2651 * @geometry: struct containing geometry information
2652 * @geom_mask: mask indicating which struct fields should be paid attention to
2654 * This function sets up hints about how a window can be resized by
2655 * the user. You can set a minimum and maximum size; allowed resize
2656 * increments (e.g. for xterm, you can only resize by the size of a
2657 * character); aspect ratios; and more. See the #GdkGeometry struct.
2661 gtk_window_set_geometry_hints (GtkWindow *window,
2662 GtkWidget *geometry_widget,
2663 GdkGeometry *geometry,
2664 GdkWindowHints geom_mask)
2666 GtkWindowGeometryInfo *info;
2668 g_return_if_fail (GTK_IS_WINDOW (window));
2669 g_return_if_fail (geometry_widget == NULL || GTK_IS_WIDGET (geometry_widget));
2671 info = gtk_window_get_geometry_info (window, TRUE);
2674 g_signal_handlers_disconnect_by_func (info->widget,
2675 gtk_widget_destroyed,
2678 info->widget = geometry_widget;
2680 g_signal_connect (geometry_widget, "destroy",
2681 G_CALLBACK (gtk_widget_destroyed),
2685 info->geometry = *geometry;
2687 /* We store gravity in window->gravity not in the hints. */
2688 info->mask = geom_mask & ~(GDK_HINT_WIN_GRAVITY);
2690 if (geom_mask & GDK_HINT_WIN_GRAVITY)
2692 gtk_window_set_gravity (window, geometry->win_gravity);
2695 gtk_widget_queue_resize_no_redraw (GTK_WIDGET (window));
2699 * gtk_window_set_decorated:
2700 * @window: a #GtkWindow
2701 * @setting: %TRUE to decorate the window
2703 * By default, windows are decorated with a title bar, resize
2704 * controls, etc. Some <link linkend="gtk-X11-arch">window
2705 * managers</link> allow GTK+ to disable these decorations, creating a
2706 * borderless window. If you set the decorated property to %FALSE
2707 * using this function, GTK+ will do its best to convince the window
2708 * manager not to decorate the window. Depending on the system, this
2709 * function may not have any effect when called on a window that is
2710 * already visible, so you should call it before calling gtk_window_show().
2712 * On Windows, this function always works, since there's no window manager
2717 gtk_window_set_decorated (GtkWindow *window,
2720 g_return_if_fail (GTK_IS_WINDOW (window));
2722 setting = setting != FALSE;
2724 if (setting == window->decorated)
2727 window->decorated = setting;
2729 if (GTK_WIDGET (window)->window)
2731 if (window->decorated)
2732 gdk_window_set_decorations (GTK_WIDGET (window)->window,
2735 gdk_window_set_decorations (GTK_WIDGET (window)->window,
2739 g_object_notify (G_OBJECT (window), "decorated");
2743 * gtk_window_get_decorated:
2744 * @window: a #GtkWindow
2746 * Returns whether the window has been set to have decorations
2747 * such as a title bar via gtk_window_set_decorated().
2749 * Return value: %TRUE if the window has been set to have decorations
2752 gtk_window_get_decorated (GtkWindow *window)
2754 g_return_val_if_fail (GTK_IS_WINDOW (window), TRUE);
2756 return window->decorated;
2760 * gtk_window_set_deletable:
2761 * @window: a #GtkWindow
2762 * @setting: %TRUE to decorate the window as deletable
2764 * By default, windows have a close button in the window frame. Some
2765 * <link linkend="gtk-X11-arch">window managers</link> allow GTK+ to
2766 * disable this button. If you set the deletable property to %FALSE
2767 * using this function, GTK+ will do its best to convince the window
2768 * manager not to show a close button. Depending on the system, this
2769 * function may not have any effect when called on a window that is
2770 * already visible, so you should call it before calling gtk_window_show().
2772 * On Windows, this function always works, since there's no window manager
2778 gtk_window_set_deletable (GtkWindow *window,
2781 GtkWindowPrivate *priv;
2783 g_return_if_fail (GTK_IS_WINDOW (window));
2785 priv = GTK_WINDOW_GET_PRIVATE (window);
2787 setting = setting != FALSE;
2789 if (setting == priv->deletable)
2792 priv->deletable = setting;
2794 if (GTK_WIDGET (window)->window)
2796 if (priv->deletable)
2797 gdk_window_set_functions (GTK_WIDGET (window)->window,
2800 gdk_window_set_functions (GTK_WIDGET (window)->window,
2801 GDK_FUNC_ALL | GDK_FUNC_CLOSE);
2804 g_object_notify (G_OBJECT (window), "deletable");
2808 * gtk_window_get_deletable:
2809 * @window: a #GtkWindow
2811 * Returns whether the window has been set to have a close button
2812 * via gtk_window_set_deletable().
2814 * Return value: %TRUE if the window has been set to have a close button
2819 gtk_window_get_deletable (GtkWindow *window)
2821 GtkWindowPrivate *priv;
2823 g_return_val_if_fail (GTK_IS_WINDOW (window), TRUE);
2825 priv = GTK_WINDOW_GET_PRIVATE (window);
2827 return priv->deletable;
2830 static GtkWindowIconInfo*
2831 get_icon_info (GtkWindow *window)
2833 return g_object_get_qdata (G_OBJECT (window), quark_gtk_window_icon_info);
2837 free_icon_info (GtkWindowIconInfo *info)
2839 g_free (info->icon_name);
2840 g_slice_free (GtkWindowIconInfo, info);
2844 static GtkWindowIconInfo*
2845 ensure_icon_info (GtkWindow *window)
2847 GtkWindowIconInfo *info;
2849 info = get_icon_info (window);
2853 info = g_slice_new0 (GtkWindowIconInfo);
2854 g_object_set_qdata_full (G_OBJECT (window),
2855 quark_gtk_window_icon_info,
2857 (GDestroyNotify)free_icon_info);
2869 static ScreenIconInfo *
2870 get_screen_icon_info (GdkScreen *screen)
2872 ScreenIconInfo *info = g_object_get_qdata (G_OBJECT (screen),
2873 quark_gtk_window_default_icon_pixmap);
2876 info = g_slice_new0 (ScreenIconInfo);
2877 g_object_set_qdata (G_OBJECT (screen),
2878 quark_gtk_window_default_icon_pixmap, info);
2881 if (info->serial != default_icon_serial)
2885 g_object_remove_weak_pointer (G_OBJECT (info->pixmap), (gpointer*)&info->pixmap);
2886 info->pixmap = NULL;
2891 g_object_remove_weak_pointer (G_OBJECT (info->mask), (gpointer*)&info->mask);
2895 info->serial = default_icon_serial;
2902 get_pixmap_and_mask (GdkWindow *window,
2903 GtkWindowIconInfo *parent_info,
2904 gboolean is_default_list,
2906 GdkPixmap **pmap_return,
2907 GdkBitmap **mask_return)
2909 GdkScreen *screen = gdk_drawable_get_screen (window);
2910 ScreenIconInfo *default_icon_info = get_screen_icon_info (screen);
2911 GdkPixbuf *best_icon;
2915 *pmap_return = NULL;
2916 *mask_return = NULL;
2918 if (is_default_list &&
2919 default_icon_info->pixmap != NULL)
2921 /* Use shared icon pixmap for all windows on this screen.
2923 if (default_icon_info->pixmap)
2924 g_object_ref (default_icon_info->pixmap);
2925 if (default_icon_info->mask)
2926 g_object_ref (default_icon_info->mask);
2928 *pmap_return = default_icon_info->pixmap;
2929 *mask_return = default_icon_info->mask;
2931 else if (parent_info && parent_info->icon_pixmap)
2933 if (parent_info->icon_pixmap)
2934 g_object_ref (parent_info->icon_pixmap);
2935 if (parent_info->icon_mask)
2936 g_object_ref (parent_info->icon_mask);
2938 *pmap_return = parent_info->icon_pixmap;
2939 *mask_return = parent_info->icon_mask;
2943 #define IDEAL_SIZE 48
2945 best_size = G_MAXINT;
2947 tmp_list = icon_list;
2948 while (tmp_list != NULL)
2950 GdkPixbuf *pixbuf = tmp_list->data;
2953 /* average width and height - if someone passes in a rectangular
2954 * icon they deserve what they get.
2956 this = gdk_pixbuf_get_width (pixbuf) + gdk_pixbuf_get_height (pixbuf);
2959 if (best_icon == NULL)
2966 /* icon is better if it's 32 pixels or larger, and closer to
2967 * the ideal size than the current best.
2970 (ABS (best_size - IDEAL_SIZE) <
2971 ABS (this - IDEAL_SIZE)))
2978 tmp_list = tmp_list->next;
2982 gdk_pixbuf_render_pixmap_and_mask_for_colormap (best_icon,
2983 gdk_screen_get_system_colormap (screen),
2988 /* Save pmap/mask for others to use if appropriate */
2991 parent_info->icon_pixmap = *pmap_return;
2992 parent_info->icon_mask = *mask_return;
2994 if (parent_info->icon_pixmap)
2995 g_object_ref (parent_info->icon_pixmap);
2996 if (parent_info->icon_mask)
2997 g_object_ref (parent_info->icon_mask);
2999 else if (is_default_list)
3001 default_icon_info->pixmap = *pmap_return;
3002 default_icon_info->mask = *mask_return;
3004 if (default_icon_info->pixmap)
3005 g_object_add_weak_pointer (G_OBJECT (default_icon_info->pixmap),
3006 (gpointer*)&default_icon_info->pixmap);
3007 if (default_icon_info->mask)
3008 g_object_add_weak_pointer (G_OBJECT (default_icon_info->mask),
3009 (gpointer*)&default_icon_info->mask);
3015 icon_list_from_theme (GtkWidget *widget,
3020 GtkIconTheme *icon_theme;
3025 icon_theme = gtk_icon_theme_get_for_screen (gtk_widget_get_screen (widget));
3027 sizes = gtk_icon_theme_get_icon_sizes (icon_theme, name);
3030 for (i = 0; sizes[i]; i++)
3033 * We need an EWMH extension to handle scalable icons
3034 * by passing their name to the WM. For now just use a
3038 icon = gtk_icon_theme_load_icon (icon_theme, name,
3041 icon = gtk_icon_theme_load_icon (icon_theme, name,
3044 list = g_list_append (list, icon);
3054 gtk_window_realize_icon (GtkWindow *window)
3057 GtkWindowIconInfo *info;
3060 widget = GTK_WIDGET (window);
3062 g_return_if_fail (widget->window != NULL);
3064 /* no point setting an icon on override-redirect */
3065 if (window->type == GTK_WINDOW_POPUP)
3070 info = ensure_icon_info (window);
3075 g_return_if_fail (info->icon_pixmap == NULL);
3076 g_return_if_fail (info->icon_mask == NULL);
3078 info->using_default_icon = FALSE;
3079 info->using_parent_icon = FALSE;
3080 info->using_themed_icon = FALSE;
3082 icon_list = info->icon_list;
3084 /* Look up themed icon */
3085 if (icon_list == NULL && info->icon_name)
3087 icon_list = icon_list_from_theme (widget, info->icon_name);
3089 info->using_themed_icon = TRUE;
3092 /* Inherit from transient parent */
3093 if (icon_list == NULL && window->transient_parent)
3095 icon_list = ensure_icon_info (window->transient_parent)->icon_list;
3097 info->using_parent_icon = TRUE;
3100 /* Inherit from default */
3101 if (icon_list == NULL)
3103 icon_list = default_icon_list;
3105 info->using_default_icon = TRUE;
3108 /* Look up themed icon */
3109 if (icon_list == NULL && default_icon_name)
3111 icon_list = icon_list_from_theme (widget, default_icon_name);
3112 info->using_default_icon = TRUE;
3113 info->using_themed_icon = TRUE;
3116 gdk_window_set_icon_list (widget->window, icon_list);
3118 get_pixmap_and_mask (widget->window,
3119 info->using_parent_icon ? ensure_icon_info (window->transient_parent) : NULL,
3120 info->using_default_icon,
3125 /* This is a slight ICCCM violation since it's a color pixmap not
3126 * a bitmap, but everyone does it.
3128 gdk_window_set_icon (widget->window,
3133 info->realized = TRUE;
3135 if (info->using_themed_icon)
3137 GtkIconTheme *icon_theme;
3139 g_list_foreach (icon_list, (GFunc) g_object_unref, NULL);
3140 g_list_free (icon_list);
3142 icon_theme = gtk_icon_theme_get_for_screen (gtk_widget_get_screen (GTK_WIDGET (window)));
3143 g_signal_connect (icon_theme, "changed",
3144 G_CALLBACK (update_themed_icon), window);
3149 gtk_window_unrealize_icon (GtkWindow *window)
3151 GtkWindowIconInfo *info;
3153 info = get_icon_info (window);
3158 if (info->icon_pixmap)
3159 g_object_unref (info->icon_pixmap);
3161 if (info->icon_mask)
3162 g_object_unref (info->icon_mask);
3164 info->icon_pixmap = NULL;
3165 info->icon_mask = NULL;
3167 if (info->using_themed_icon)
3169 GtkIconTheme *icon_theme;
3171 icon_theme = gtk_icon_theme_get_for_screen (gtk_widget_get_screen (GTK_WIDGET (window)));
3173 g_signal_handlers_disconnect_by_func (icon_theme, update_themed_icon, window);
3176 /* We don't clear the properties on the window, just figure the
3177 * window is going away.
3180 info->realized = FALSE;
3185 * gtk_window_set_icon_list:
3186 * @window: a #GtkWindow
3187 * @list: list of #GdkPixbuf
3189 * Sets up the icon representing a #GtkWindow. The icon is used when
3190 * the window is minimized (also known as iconified). Some window
3191 * managers or desktop environments may also place it in the window
3192 * frame, or display it in other contexts.
3194 * gtk_window_set_icon_list() allows you to pass in the same icon in
3195 * several hand-drawn sizes. The list should contain the natural sizes
3196 * your icon is available in; that is, don't scale the image before
3197 * passing it to GTK+. Scaling is postponed until the last minute,
3198 * when the desired final size is known, to allow best quality.
3200 * By passing several sizes, you may improve the final image quality
3201 * of the icon, by reducing or eliminating automatic image scaling.
3203 * Recommended sizes to provide: 16x16, 32x32, 48x48 at minimum, and
3204 * larger images (64x64, 128x128) if you have them.
3206 * See also gtk_window_set_default_icon_list() to set the icon
3207 * for all windows in your application in one go.
3209 * Note that transient windows (those who have been set transient for another
3210 * window using gtk_window_set_transient_for()) will inherit their
3211 * icon from their transient parent. So there's no need to explicitly
3212 * set the icon on transient windows.
3215 gtk_window_set_icon_list (GtkWindow *window,
3218 GtkWindowIconInfo *info;
3220 g_return_if_fail (GTK_IS_WINDOW (window));
3222 info = ensure_icon_info (window);
3224 if (info->icon_list == list) /* check for NULL mostly */
3227 g_list_foreach (list,
3228 (GFunc) g_object_ref, NULL);
3230 g_list_foreach (info->icon_list,
3231 (GFunc) g_object_unref, NULL);
3233 g_list_free (info->icon_list);
3235 info->icon_list = g_list_copy (list);
3237 g_object_notify (G_OBJECT (window), "icon");
3239 gtk_window_unrealize_icon (window);
3241 if (GTK_WIDGET_REALIZED (window))
3242 gtk_window_realize_icon (window);
3244 /* We could try to update our transient children, but I don't think
3245 * it's really worth it. If we did it, the best way would probably
3246 * be to have children connect to notify::icon-list
3251 * gtk_window_get_icon_list:
3252 * @window: a #GtkWindow
3254 * Retrieves the list of icons set by gtk_window_set_icon_list().
3255 * The list is copied, but the reference count on each
3256 * member won't be incremented.
3258 * Return value: copy of window's icon list
3261 gtk_window_get_icon_list (GtkWindow *window)
3263 GtkWindowIconInfo *info;
3265 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
3267 info = get_icon_info (window);
3270 return g_list_copy (info->icon_list);
3276 * gtk_window_set_icon:
3277 * @window: a #GtkWindow
3278 * @icon: icon image, or %NULL
3280 * Sets up the icon representing a #GtkWindow. This icon is used when
3281 * the window is minimized (also known as iconified). Some window
3282 * managers or desktop environments may also place it in the window
3283 * frame, or display it in other contexts.
3285 * The icon should be provided in whatever size it was naturally
3286 * drawn; that is, don't scale the image before passing it to
3287 * GTK+. Scaling is postponed until the last minute, when the desired
3288 * final size is known, to allow best quality.
3290 * If you have your icon hand-drawn in multiple sizes, use
3291 * gtk_window_set_icon_list(). Then the best size will be used.
3293 * This function is equivalent to calling gtk_window_set_icon_list()
3294 * with a 1-element list.
3296 * See also gtk_window_set_default_icon_list() to set the icon
3297 * for all windows in your application in one go.
3300 gtk_window_set_icon (GtkWindow *window,
3305 g_return_if_fail (GTK_IS_WINDOW (window));
3306 g_return_if_fail (icon == NULL || GDK_IS_PIXBUF (icon));
3311 list = g_list_append (list, icon);
3313 gtk_window_set_icon_list (window, list);
3319 update_themed_icon (GtkIconTheme *icon_theme,
3322 g_object_notify (G_OBJECT (window), "icon");
3324 gtk_window_unrealize_icon (window);
3326 if (GTK_WIDGET_REALIZED (window))
3327 gtk_window_realize_icon (window);
3331 * gtk_window_set_icon_name:
3332 * @window: a #GtkWindow
3333 * @name: the name of the themed icon
3335 * Sets the icon for the window from a named themed icon. See
3336 * the docs for #GtkIconTheme for more details.
3338 * Note that this has nothing to do with the WM_ICON_NAME
3339 * property which is mentioned in the ICCCM.
3344 gtk_window_set_icon_name (GtkWindow *window,
3347 GtkWindowIconInfo *info;
3350 g_return_if_fail (GTK_IS_WINDOW (window));
3352 info = ensure_icon_info (window);
3354 tmp = info->icon_name;
3355 info->icon_name = g_strdup (name);
3358 g_list_foreach (info->icon_list, (GFunc) g_object_unref, NULL);
3359 g_list_free (info->icon_list);
3360 info->icon_list = NULL;
3362 update_themed_icon (NULL, window);
3364 g_object_notify (G_OBJECT (window), "icon-name");
3368 * gtk_window_get_icon_name:
3369 * @window: a #GtkWindow
3371 * Returns the name of the themed icon for the window,
3372 * see gtk_window_set_icon_name().
3374 * Returns: the icon name or %NULL if the window has
3379 G_CONST_RETURN gchar *
3380 gtk_window_get_icon_name (GtkWindow *window)
3382 GtkWindowIconInfo *info;
3384 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
3386 info = ensure_icon_info (window);
3388 return info->icon_name;
3392 * gtk_window_get_icon:
3393 * @window: a #GtkWindow
3395 * Gets the value set by gtk_window_set_icon() (or if you've
3396 * called gtk_window_set_icon_list(), gets the first icon in
3399 * Return value: icon for window
3402 gtk_window_get_icon (GtkWindow *window)
3404 GtkWindowIconInfo *info;
3406 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
3408 info = get_icon_info (window);
3409 if (info && info->icon_list)
3410 return GDK_PIXBUF (info->icon_list->data);
3415 /* Load pixbuf, printing warning on failure if error == NULL
3418 load_pixbuf_verbosely (const char *filename,
3421 GError *local_err = NULL;
3424 pixbuf = gdk_pixbuf_new_from_file (filename, &local_err);
3432 g_warning ("Error loading icon from file '%s':\n\t%s",
3433 filename, local_err->message);
3434 g_error_free (local_err);
3442 * gtk_window_set_icon_from_file:
3443 * @window: a #GtkWindow
3444 * @filename: location of icon file
3445 * @err: location to store error, or %NULL.
3447 * Sets the icon for @window.
3448 * Warns on failure if @err is %NULL.
3450 * This function is equivalent to calling gtk_window_set_icon()
3451 * with a pixbuf created by loading the image from @filename.
3453 * Returns: %TRUE if setting the icon succeeded.
3458 gtk_window_set_icon_from_file (GtkWindow *window,
3459 const gchar *filename,
3462 GdkPixbuf *pixbuf = load_pixbuf_verbosely (filename, err);
3466 gtk_window_set_icon (window, pixbuf);
3467 g_object_unref (pixbuf);
3476 * gtk_window_set_default_icon_list:
3477 * @list: a list of #GdkPixbuf
3479 * Sets an icon list to be used as fallback for windows that haven't
3480 * had gtk_window_set_icon_list() called on them to set up a
3481 * window-specific icon list. This function allows you to set up the
3482 * icon for all windows in your app at once.
3484 * See gtk_window_set_icon_list() for more details.
3488 gtk_window_set_default_icon_list (GList *list)
3492 if (list == default_icon_list)
3495 /* Update serial so we don't used cached pixmaps/masks
3497 default_icon_serial++;
3499 g_list_foreach (list,
3500 (GFunc) g_object_ref, NULL);
3502 g_list_foreach (default_icon_list,
3503 (GFunc) g_object_unref, NULL);
3505 g_list_free (default_icon_list);
3507 default_icon_list = g_list_copy (list);
3509 /* Update all toplevels */
3510 toplevels = gtk_window_list_toplevels ();
3511 tmp_list = toplevels;
3512 while (tmp_list != NULL)
3514 GtkWindowIconInfo *info;
3515 GtkWindow *w = tmp_list->data;
3517 info = get_icon_info (w);
3518 if (info && info->using_default_icon)
3520 gtk_window_unrealize_icon (w);
3521 if (GTK_WIDGET_REALIZED (w))
3522 gtk_window_realize_icon (w);
3525 tmp_list = tmp_list->next;
3527 g_list_free (toplevels);
3531 * gtk_window_set_default_icon:
3534 * Sets an icon to be used as fallback for windows that haven't
3535 * had gtk_window_set_icon() called on them from a pixbuf.
3540 gtk_window_set_default_icon (GdkPixbuf *icon)
3544 g_return_if_fail (GDK_IS_PIXBUF (icon));
3546 list = g_list_prepend (NULL, icon);
3547 gtk_window_set_default_icon_list (list);
3552 * gtk_window_set_default_icon_name:
3553 * @name: the name of the themed icon
3555 * Sets an icon to be used as fallback for windows that haven't
3556 * had gtk_window_set_icon_list() called on them from a named
3557 * themed icon, see gtk_window_set_icon_name().
3562 gtk_window_set_default_icon_name (const gchar *name)
3567 /* Update serial so we don't used cached pixmaps/masks
3569 default_icon_serial++;
3571 g_free (default_icon_name);
3572 default_icon_name = g_strdup (name);
3574 g_list_foreach (default_icon_list,
3575 (GFunc) g_object_unref, NULL);
3577 g_list_free (default_icon_list);
3578 default_icon_list = NULL;
3580 /* Update all toplevels */
3581 toplevels = gtk_window_list_toplevels ();
3582 tmp_list = toplevels;
3583 while (tmp_list != NULL)
3585 GtkWindowIconInfo *info;
3586 GtkWindow *w = tmp_list->data;
3588 info = get_icon_info (w);
3589 if (info && info->using_default_icon && info->using_themed_icon)
3591 gtk_window_unrealize_icon (w);
3592 if (GTK_WIDGET_REALIZED (w))
3593 gtk_window_realize_icon (w);
3596 tmp_list = tmp_list->next;
3598 g_list_free (toplevels);
3602 * gtk_window_set_default_icon_from_file:
3603 * @filename: location of icon file
3604 * @err: location to store error, or %NULL.
3606 * Sets an icon to be used as fallback for windows that haven't
3607 * had gtk_window_set_icon_list() called on them from a file
3608 * on disk. Warns on failure if @err is %NULL.
3610 * Returns: %TRUE if setting the icon succeeded.
3615 gtk_window_set_default_icon_from_file (const gchar *filename,
3618 GdkPixbuf *pixbuf = load_pixbuf_verbosely (filename, err);
3622 gtk_window_set_default_icon (pixbuf);
3623 g_object_unref (pixbuf);
3632 * gtk_window_get_default_icon_list:
3634 * Gets the value set by gtk_window_set_default_icon_list().
3635 * The list is a copy and should be freed with g_list_free(),
3636 * but the pixbufs in the list have not had their reference count
3639 * Return value: copy of default icon list
3642 gtk_window_get_default_icon_list (void)
3644 return g_list_copy (default_icon_list);
3648 gtk_window_set_default_size_internal (GtkWindow *window,
3649 gboolean change_width,
3651 gboolean change_height,
3653 gboolean is_geometry)
3655 GtkWindowGeometryInfo *info;
3657 g_return_if_fail (change_width == FALSE || width >= -1);
3658 g_return_if_fail (change_height == FALSE || height >= -1);
3660 info = gtk_window_get_geometry_info (window, TRUE);
3662 g_object_freeze_notify (G_OBJECT (window));
3664 info->default_is_geometry = is_geometry != FALSE;
3674 info->default_width = width;
3676 g_object_notify (G_OBJECT (window), "default-width");
3687 info->default_height = height;
3689 g_object_notify (G_OBJECT (window), "default-height");
3692 g_object_thaw_notify (G_OBJECT (window));
3694 gtk_widget_queue_resize_no_redraw (GTK_WIDGET (window));
3698 * gtk_window_set_default_size:
3699 * @window: a #GtkWindow
3700 * @width: width in pixels, or -1 to unset the default width
3701 * @height: height in pixels, or -1 to unset the default height
3703 * Sets the default size of a window. If the window's "natural" size
3704 * (its size request) is larger than the default, the default will be
3705 * ignored. More generally, if the default size does not obey the
3706 * geometry hints for the window (gtk_window_set_geometry_hints() can
3707 * be used to set these explicitly), the default size will be clamped
3708 * to the nearest permitted size.
3710 * Unlike gtk_widget_set_size_request(), which sets a size request for
3711 * a widget and thus would keep users from shrinking the window, this
3712 * function only sets the initial size, just as if the user had
3713 * resized the window themselves. Users can still shrink the window
3714 * again as they normally would. Setting a default size of -1 means to
3715 * use the "natural" default size (the size request of the window).
3717 * For more control over a window's initial size and how resizing works,
3718 * investigate gtk_window_set_geometry_hints().
3720 * For some uses, gtk_window_resize() is a more appropriate function.
3721 * gtk_window_resize() changes the current size of the window, rather
3722 * than the size to be used on initial display. gtk_window_resize() always
3723 * affects the window itself, not the geometry widget.
3725 * The default size of a window only affects the first time a window is
3726 * shown; if a window is hidden and re-shown, it will remember the size
3727 * it had prior to hiding, rather than using the default size.
3729 * Windows can't actually be 0x0 in size, they must be at least 1x1, but
3730 * passing 0 for @width and @height is OK, resulting in a 1x1 default size.
3733 gtk_window_set_default_size (GtkWindow *window,
3737 g_return_if_fail (GTK_IS_WINDOW (window));
3738 g_return_if_fail (width >= -1);
3739 g_return_if_fail (height >= -1);
3741 gtk_window_set_default_size_internal (window, TRUE, width, TRUE, height, FALSE);
3745 * gtk_window_get_default_size:
3746 * @window: a #GtkWindow
3747 * @width: location to store the default width, or %NULL
3748 * @height: location to store the default height, or %NULL
3750 * Gets the default size of the window. A value of -1 for the width or
3751 * height indicates that a default size has not been explicitly set
3752 * for that dimension, so the "natural" size of the window will be
3757 gtk_window_get_default_size (GtkWindow *window,
3761 GtkWindowGeometryInfo *info;
3763 g_return_if_fail (GTK_IS_WINDOW (window));
3765 info = gtk_window_get_geometry_info (window, FALSE);
3768 *width = info ? info->default_width : -1;
3771 *height = info ? info->default_height : -1;
3775 * gtk_window_resize:
3776 * @window: a #GtkWindow
3777 * @width: width in pixels to resize the window to
3778 * @height: height in pixels to resize the window to
3780 * Resizes the window as if the user had done so, obeying geometry
3781 * constraints. The default geometry constraint is that windows may
3782 * not be smaller than their size request; to override this
3783 * constraint, call gtk_widget_set_size_request() to set the window's
3784 * request to a smaller value.
3786 * If gtk_window_resize() is called before showing a window for the
3787 * first time, it overrides any default size set with
3788 * gtk_window_set_default_size().
3790 * Windows may not be resized smaller than 1 by 1 pixels.
3794 gtk_window_resize (GtkWindow *window,
3798 GtkWindowGeometryInfo *info;
3800 g_return_if_fail (GTK_IS_WINDOW (window));
3801 g_return_if_fail (width > 0);
3802 g_return_if_fail (height > 0);
3804 info = gtk_window_get_geometry_info (window, TRUE);
3806 info->resize_width = width;
3807 info->resize_height = height;
3809 gtk_widget_queue_resize_no_redraw (GTK_WIDGET (window));
3813 * gtk_window_get_size:
3814 * @window: a #GtkWindow
3815 * @width: return location for width, or %NULL
3816 * @height: return location for height, or %NULL
3818 * Obtains the current size of @window. If @window is not onscreen,
3819 * it returns the size GTK+ will suggest to the <link
3820 * linkend="gtk-X11-arch">window manager</link> for the initial window
3821 * size (but this is not reliably the same as the size the window
3822 * manager will actually select). The size obtained by
3823 * gtk_window_get_size() is the last size received in a
3824 * #GdkEventConfigure, that is, GTK+ uses its locally-stored size,
3825 * rather than querying the X server for the size. As a result, if you
3826 * call gtk_window_resize() then immediately call
3827 * gtk_window_get_size(), the size won't have taken effect yet. After
3828 * the window manager processes the resize request, GTK+ receives
3829 * notification that the size has changed via a configure event, and
3830 * the size of the window gets updated.
3832 * Note 1: Nearly any use of this function creates a race condition,
3833 * because the size of the window may change between the time that you
3834 * get the size and the time that you perform some action assuming
3835 * that size is the current size. To avoid race conditions, connect to
3836 * "configure_event" on the window and adjust your size-dependent
3837 * state to match the size delivered in the #GdkEventConfigure.
3839 * Note 2: The returned size does <emphasis>not</emphasis> include the
3840 * size of the window manager decorations (aka the window frame or
3841 * border). Those are not drawn by GTK+ and GTK+ has no reliable
3842 * method of determining their size.
3844 * Note 3: If you are getting a window size in order to position
3845 * the window onscreen, there may be a better way. The preferred
3846 * way is to simply set the window's semantic type with
3847 * gtk_window_set_type_hint(), which allows the window manager to
3848 * e.g. center dialogs. Also, if you set the transient parent of
3849 * dialogs with gtk_window_set_transient_for() window managers
3850 * will often center the dialog over its parent window. It's
3851 * much preferred to let the window manager handle these
3852 * things rather than doing it yourself, because all apps will
3853 * behave consistently and according to user prefs if the window
3854 * manager handles it. Also, the window manager can take the size
3855 * of the window decorations/border into account, while your
3856 * application cannot.
3858 * In any case, if you insist on application-specified window
3859 * positioning, there's <emphasis>still</emphasis> a better way than
3860 * doing it yourself - gtk_window_set_position() will frequently
3861 * handle the details for you.
3865 gtk_window_get_size (GtkWindow *window,
3871 g_return_if_fail (GTK_IS_WINDOW (window));
3873 if (width == NULL && height == NULL)
3876 if (GTK_WIDGET_MAPPED (window))
3878 gdk_drawable_get_size (GTK_WIDGET (window)->window,
3883 GdkRectangle configure_request;
3885 gtk_window_compute_configure_request (window,
3889 w = configure_request.width;
3890 h = configure_request.height;
3901 * @window: a #GtkWindow
3902 * @x: X coordinate to move window to
3903 * @y: Y coordinate to move window to
3905 * Asks the <link linkend="gtk-X11-arch">window manager</link> to move
3906 * @window to the given position. Window managers are free to ignore
3907 * this; most window managers ignore requests for initial window
3908 * positions (instead using a user-defined placement algorithm) and
3909 * honor requests after the window has already been shown.
3911 * Note: the position is the position of the gravity-determined
3912 * reference point for the window. The gravity determines two things:
3913 * first, the location of the reference point in root window
3914 * coordinates; and second, which point on the window is positioned at
3915 * the reference point.
3917 * By default the gravity is #GDK_GRAVITY_NORTH_WEST, so the reference
3918 * point is simply the @x, @y supplied to gtk_window_move(). The
3919 * top-left corner of the window decorations (aka window frame or
3920 * border) will be placed at @x, @y. Therefore, to position a window
3921 * at the top left of the screen, you want to use the default gravity
3922 * (which is #GDK_GRAVITY_NORTH_WEST) and move the window to 0,0.
3924 * To position a window at the bottom right corner of the screen, you
3925 * would set #GDK_GRAVITY_SOUTH_EAST, which means that the reference
3926 * point is at @x + the window width and @y + the window height, and
3927 * the bottom-right corner of the window border will be placed at that
3928 * reference point. So, to place a window in the bottom right corner
3929 * you would first set gravity to south east, then write:
3930 * <literal>gtk_window_move (window, gdk_screen_width () - window_width,
3931 * gdk_screen_height () - window_height)</literal> (note that this
3932 * example does not take multi-head scenarios into account).
3934 * The Extended Window Manager Hints specification at <ulink
3935 * url="http://www.freedesktop.org/Standards/wm-spec">
3936 * http://www.freedesktop.org/Standards/wm-spec</ulink> has a
3937 * nice table of gravities in the "implementation notes" section.
3939 * The gtk_window_get_position() documentation may also be relevant.
3942 gtk_window_move (GtkWindow *window,
3946 GtkWindowGeometryInfo *info;
3949 g_return_if_fail (GTK_IS_WINDOW (window));
3951 widget = GTK_WIDGET (window);
3953 info = gtk_window_get_geometry_info (window, TRUE);
3955 if (GTK_WIDGET_MAPPED (window))
3957 /* we have now sent a request with this position
3958 * with currently-active constraints, so toggle flag.
3960 info->position_constraints_changed = FALSE;
3962 /* we only constrain if mapped - if not mapped,
3963 * then gtk_window_compute_configure_request()
3964 * will apply the constraints later, and we
3965 * don't want to lose information about
3966 * what position the user set before then.
3967 * i.e. if you do a move() then turn off POS_CENTER
3968 * then show the window, your move() will work.
3970 gtk_window_constrain_position (window,
3971 widget->allocation.width,
3972 widget->allocation.height,
3975 /* Note that this request doesn't go through our standard request
3976 * framework, e.g. doesn't increment configure_request_count,
3977 * doesn't set info->last, etc.; that's because
3978 * we don't save the info needed to arrive at this same request
3981 * To gtk_window_move_resize(), this will end up looking exactly
3982 * the same as the position being changed by the window
3986 /* FIXME are we handling gravity properly for framed windows? */
3988 gdk_window_move (window->frame,
3989 x - window->frame_left,
3990 y - window->frame_top);
3992 gdk_window_move (GTK_WIDGET (window)->window,
3997 /* Save this position to apply on mapping */
3998 info->initial_x = x;
3999 info->initial_y = y;
4000 info->initial_pos_set = TRUE;
4005 * gtk_window_get_position:
4006 * @window: a #GtkWindow
4007 * @root_x: return location for X coordinate of gravity-determined reference point
4008 * @root_y: return location for Y coordinate of gravity-determined reference point
4010 * This function returns the position you need to pass to
4011 * gtk_window_move() to keep @window in its current position. This
4012 * means that the meaning of the returned value varies with window
4013 * gravity. See gtk_window_move() for more details.
4015 * If you haven't changed the window gravity, its gravity will be
4016 * #GDK_GRAVITY_NORTH_WEST. This means that gtk_window_get_position()
4017 * gets the position of the top-left corner of the window manager
4018 * frame for the window. gtk_window_move() sets the position of this
4019 * same top-left corner.
4021 * gtk_window_get_position() is not 100% reliable because the X Window System
4022 * does not specify a way to obtain the geometry of the
4023 * decorations placed on a window by the window manager.
4024 * Thus GTK+ is using a "best guess" that works with most
4027 * Moreover, nearly all window managers are historically broken with
4028 * respect to their handling of window gravity. So moving a window to
4029 * its current position as returned by gtk_window_get_position() tends
4030 * to result in moving the window slightly. Window managers are
4031 * slowly getting better over time.
4033 * If a window has gravity #GDK_GRAVITY_STATIC the window manager
4034 * frame is not relevant, and thus gtk_window_get_position() will
4035 * always produce accurate results. However you can't use static
4036 * gravity to do things like place a window in a corner of the screen,
4037 * because static gravity ignores the window manager decorations.
4039 * If you are saving and restoring your application's window
4040 * positions, you should know that it's impossible for applications to
4041 * do this without getting it somewhat wrong because applications do
4042 * not have sufficient knowledge of window manager state. The Correct
4043 * Mechanism is to support the session management protocol (see the
4044 * "GnomeClient" object in the GNOME libraries for example) and allow
4045 * the window manager to save your window sizes and positions.
4050 gtk_window_get_position (GtkWindow *window,
4056 g_return_if_fail (GTK_IS_WINDOW (window));
4058 widget = GTK_WIDGET (window);
4060 if (window->gravity == GDK_GRAVITY_STATIC)
4062 if (GTK_WIDGET_MAPPED (widget))
4064 /* This does a server round-trip, which is sort of wrong;
4065 * but a server round-trip is inevitable for
4066 * gdk_window_get_frame_extents() in the usual
4067 * NorthWestGravity case below, so not sure what else to
4068 * do. We should likely be consistent about whether we get
4069 * the client-side info or the server-side info.
4071 gdk_window_get_origin (widget->window, root_x, root_y);
4075 GdkRectangle configure_request;
4077 gtk_window_compute_configure_request (window,
4081 *root_x = configure_request.x;
4082 *root_y = configure_request.y;
4087 GdkRectangle frame_extents;
4092 if (GTK_WIDGET_MAPPED (widget))
4095 gdk_window_get_frame_extents (window->frame, &frame_extents);
4097 gdk_window_get_frame_extents (widget->window, &frame_extents);
4098 x = frame_extents.x;
4099 y = frame_extents.y;
4100 gtk_window_get_size (window, &w, &h);
4104 /* We just say the frame has 0 size on all sides.
4105 * Not sure what else to do.
4107 gtk_window_compute_configure_request (window,
4110 x = frame_extents.x;
4111 y = frame_extents.y;
4112 w = frame_extents.width;
4113 h = frame_extents.height;
4116 switch (window->gravity)
4118 case GDK_GRAVITY_NORTH:
4119 case GDK_GRAVITY_CENTER:
4120 case GDK_GRAVITY_SOUTH:
4121 /* Find center of frame. */
4122 x += frame_extents.width / 2;
4123 /* Center client window on that point. */
4127 case GDK_GRAVITY_SOUTH_EAST:
4128 case GDK_GRAVITY_EAST:
4129 case GDK_GRAVITY_NORTH_EAST:
4130 /* Find right edge of frame */
4131 x += frame_extents.width;
4132 /* Align left edge of client at that point. */
4139 switch (window->gravity)
4141 case GDK_GRAVITY_WEST:
4142 case GDK_GRAVITY_CENTER:
4143 case GDK_GRAVITY_EAST:
4144 /* Find center of frame. */
4145 y += frame_extents.height / 2;
4146 /* Center client window there. */
4149 case GDK_GRAVITY_SOUTH_WEST:
4150 case GDK_GRAVITY_SOUTH:
4151 case GDK_GRAVITY_SOUTH_EAST:
4152 /* Find south edge of frame */
4153 y += frame_extents.height;
4154 /* Place bottom edge of client there */
4169 * gtk_window_reshow_with_initial_size:
4170 * @window: a #GtkWindow
4172 * Hides @window, then reshows it, resetting the
4173 * default size and position of the window. Used
4174 * by GUI builders only.
4177 gtk_window_reshow_with_initial_size (GtkWindow *window)
4181 g_return_if_fail (GTK_IS_WINDOW (window));
4183 widget = GTK_WIDGET (window);
4185 gtk_widget_hide (widget);
4186 gtk_widget_unrealize (widget);
4187 gtk_widget_show (widget);
4191 gtk_window_destroy (GtkObject *object)
4193 GtkWindow *window = GTK_WINDOW (object);
4195 toplevel_list = g_slist_remove (toplevel_list, window);
4197 if (window->transient_parent)
4198 gtk_window_set_transient_for (window, NULL);
4200 /* frees the icons */
4201 gtk_window_set_icon_list (window, NULL);
4203 if (window->has_user_ref_count)
4205 window->has_user_ref_count = FALSE;
4206 g_object_unref (window);
4210 gtk_window_group_remove_window (window->group, window);
4212 gtk_window_free_key_hash (window);
4214 GTK_OBJECT_CLASS (gtk_window_parent_class)->destroy (object);
4218 gtk_window_finalize (GObject *object)
4220 GtkWindow *window = GTK_WINDOW (object);
4221 GtkMnemonicHash *mnemonic_hash;
4223 g_free (window->title);
4224 g_free (window->wmclass_name);
4225 g_free (window->wmclass_class);
4226 g_free (window->wm_role);
4228 mnemonic_hash = gtk_window_get_mnemonic_hash (window, FALSE);
4230 _gtk_mnemonic_hash_free (mnemonic_hash);
4232 if (window->geometry_info)
4234 if (window->geometry_info->widget)
4235 g_signal_handlers_disconnect_by_func (window->geometry_info->widget,
4236 gtk_widget_destroyed,
4237 &window->geometry_info->widget);
4238 g_free (window->geometry_info);
4241 if (window->keys_changed_handler)
4243 g_source_remove (window->keys_changed_handler);
4244 window->keys_changed_handler = 0;
4249 g_signal_handlers_disconnect_by_func (window->screen,
4250 gtk_window_on_composited_changed, window);
4253 G_OBJECT_CLASS (gtk_window_parent_class)->finalize (object);
4257 gtk_window_show (GtkWidget *widget)
4259 GtkWindow *window = GTK_WINDOW (widget);
4260 GtkContainer *container = GTK_CONTAINER (window);
4261 gboolean need_resize;
4263 GTK_WIDGET_SET_FLAGS (widget, GTK_VISIBLE);
4265 need_resize = container->need_resize || !GTK_WIDGET_REALIZED (widget);
4266 container->need_resize = FALSE;
4270 GtkWindowGeometryInfo *info = gtk_window_get_geometry_info (window, TRUE);
4271 GtkAllocation allocation = { 0, 0 };
4272 GdkRectangle configure_request;
4273 GdkGeometry new_geometry;
4275 gboolean was_realized;
4277 /* We are going to go ahead and perform this configure request
4278 * and then emulate a configure notify by going ahead and
4279 * doing a size allocate. Sort of a synchronous
4280 * mini-copy of gtk_window_move_resize() here.
4282 gtk_window_compute_configure_request (window,
4287 /* We update this because we are going to go ahead
4288 * and gdk_window_resize() below, rather than
4291 info->last.configure_request.width = configure_request.width;
4292 info->last.configure_request.height = configure_request.height;
4294 /* and allocate the window - this is normally done
4295 * in move_resize in response to configure notify
4297 allocation.width = configure_request.width;
4298 allocation.height = configure_request.height;
4299 gtk_widget_size_allocate (widget, &allocation);
4301 /* Then we guarantee we have a realize */
4302 was_realized = FALSE;
4303 if (!GTK_WIDGET_REALIZED (widget))
4305 gtk_widget_realize (widget);
4306 was_realized = TRUE;
4309 /* Must be done after the windows are realized,
4310 * so that the decorations can be read
4312 gtk_decorated_window_calculate_frame_size (window);
4314 /* We only send configure request if we didn't just finish
4315 * creating the window; if we just created the window
4316 * then we created it with widget->allocation anyhow.
4319 gdk_window_move_resize (widget->window,
4320 configure_request.x,
4321 configure_request.y,
4322 configure_request.width,
4323 configure_request.height);
4326 gtk_container_check_resize (container);
4328 gtk_widget_map (widget);
4330 /* Try to make sure that we have some focused widget
4332 if (!window->focus_widget && !GTK_IS_PLUG (window))
4333 gtk_window_move_focus (window, GTK_DIR_TAB_FORWARD);
4336 gtk_grab_add (widget);
4340 gtk_window_hide (GtkWidget *widget)
4342 GtkWindow *window = GTK_WINDOW (widget);
4344 GTK_WIDGET_UNSET_FLAGS (widget, GTK_VISIBLE);
4345 gtk_widget_unmap (widget);
4348 gtk_grab_remove (widget);
4352 gtk_window_map (GtkWidget *widget)
4354 GtkWindow *window = GTK_WINDOW (widget);
4355 GtkWindowPrivate *priv = GTK_WINDOW_GET_PRIVATE (window);
4356 GdkWindow *toplevel;
4358 GTK_WIDGET_SET_FLAGS (widget, GTK_MAPPED);
4360 if (window->bin.child &&
4361 GTK_WIDGET_VISIBLE (window->bin.child) &&
4362 !GTK_WIDGET_MAPPED (window->bin.child))
4363 gtk_widget_map (window->bin.child);
4366 toplevel = window->frame;
4368 toplevel = widget->window;
4370 if (window->maximize_initially)
4371 gdk_window_maximize (toplevel);
4373 gdk_window_unmaximize (toplevel);
4375 if (window->stick_initially)
4376 gdk_window_stick (toplevel);
4378 gdk_window_unstick (toplevel);
4380 if (window->iconify_initially)
4381 gdk_window_iconify (toplevel);
4383 gdk_window_deiconify (toplevel);
4385 if (priv->fullscreen_initially)
4386 gdk_window_fullscreen (toplevel);
4388 gdk_window_unfullscreen (toplevel);
4390 gdk_window_set_keep_above (toplevel, priv->above_initially);
4392 gdk_window_set_keep_below (toplevel, priv->below_initially);
4394 /* No longer use the default settings */
4395 window->need_default_size = FALSE;
4396 window->need_default_position = FALSE;
4398 if (priv->reset_type_hint)
4400 /* We should only reset the type hint when the application
4401 * used gtk_window_set_type_hint() to change the hint.
4402 * Some applications use X directly to change the properties;
4403 * in that case, we shouldn't overwrite what they did.
4405 gdk_window_set_type_hint (widget->window, priv->type_hint);
4406 priv->reset_type_hint = FALSE;
4409 gdk_window_show (widget->window);
4412 gdk_window_show (window->frame);
4414 if (!disable_startup_notification)
4416 /* Do we have a custom startup-notification id? */
4417 if (priv->startup_id != NULL)
4419 /* Make sure we have a "real" id */
4420 if (!startup_id_is_fake (priv->startup_id))
4421 gdk_notify_startup_complete_with_id (priv->startup_id);
4423 priv->startup_id = NULL;
4425 else if (!sent_startup_notification)
4427 sent_startup_notification = TRUE;
4428 gdk_notify_startup_complete ();
4434 gtk_window_map_event (GtkWidget *widget,
4437 if (!GTK_WIDGET_MAPPED (widget))
4439 /* we should be be unmapped, but are getting a MapEvent, this may happen
4440 * to toplevel XWindows if mapping was intercepted by a window manager
4441 * and an unmap request occoured while the MapRequestEvent was still
4442 * being handled. we work around this situaiton here by re-requesting
4443 * the window being unmapped. more details can be found in:
4444 * http://bugzilla.gnome.org/show_bug.cgi?id=316180
4446 gdk_window_hide (widget->window);
4452 gtk_window_unmap (GtkWidget *widget)
4454 GtkWindow *window = GTK_WINDOW (widget);
4455 GtkWindowPrivate *priv = GTK_WINDOW_GET_PRIVATE (widget);
4456 GtkWindowGeometryInfo *info;
4457 GdkWindowState state;
4459 GTK_WIDGET_UNSET_FLAGS (widget, GTK_MAPPED);
4461 gdk_window_withdraw (window->frame);
4463 gdk_window_withdraw (widget->window);
4465 window->configure_request_count = 0;
4466 window->configure_notify_received = FALSE;
4468 /* on unmap, we reset the default positioning of the window,
4469 * so it's placed again, but we don't reset the default
4470 * size of the window, so it's remembered.
4472 window->need_default_position = TRUE;
4474 info = gtk_window_get_geometry_info (window, FALSE);
4477 info->initial_pos_set = FALSE;
4478 info->position_constraints_changed = FALSE;
4481 state = gdk_window_get_state (widget->window);
4482 window->iconify_initially = (state & GDK_WINDOW_STATE_ICONIFIED) != 0;
4483 window->maximize_initially = (state & GDK_WINDOW_STATE_MAXIMIZED) != 0;
4484 window->stick_initially = (state & GDK_WINDOW_STATE_STICKY) != 0;
4485 priv->above_initially = (state & GDK_WINDOW_STATE_ABOVE) != 0;
4486 priv->below_initially = (state & GDK_WINDOW_STATE_BELOW) != 0;
4490 gtk_window_realize (GtkWidget *widget)
4493 GdkWindow *parent_window;
4494 GdkWindowAttr attributes;
4495 gint attributes_mask;
4496 GtkWindowPrivate *priv;
4498 window = GTK_WINDOW (widget);
4499 priv = GTK_WINDOW_GET_PRIVATE (window);
4501 /* ensure widget tree is properly size allocated */
4502 if (widget->allocation.x == -1 &&
4503 widget->allocation.y == -1 &&
4504 widget->allocation.width == 1 &&
4505 widget->allocation.height == 1)
4507 GtkRequisition requisition;
4508 GtkAllocation allocation = { 0, 0, 200, 200 };
4510 gtk_widget_size_request (widget, &requisition);
4511 if (requisition.width || requisition.height)
4513 /* non-empty window */
4514 allocation.width = requisition.width;
4515 allocation.height = requisition.height;
4517 gtk_widget_size_allocate (widget, &allocation);
4519 _gtk_container_queue_resize (GTK_CONTAINER (widget));
4521 g_return_if_fail (!GTK_WIDGET_REALIZED (widget));
4524 GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED);
4526 switch (window->type)
4528 case GTK_WINDOW_TOPLEVEL:
4529 attributes.window_type = GDK_WINDOW_TOPLEVEL;
4531 case GTK_WINDOW_POPUP:
4532 attributes.window_type = GDK_WINDOW_TEMP;
4535 g_warning (G_STRLOC": Unknown window type %d!", window->type);
4539 attributes.title = window->title;
4540 attributes.wmclass_name = window->wmclass_name;
4541 attributes.wmclass_class = window->wmclass_class;
4542 attributes.wclass = GDK_INPUT_OUTPUT;
4543 attributes.visual = gtk_widget_get_visual (widget);
4544 attributes.colormap = gtk_widget_get_colormap (widget);
4546 if (window->has_frame)
4548 attributes.width = widget->allocation.width + window->frame_left + window->frame_right;
4549 attributes.height = widget->allocation.height + window->frame_top + window->frame_bottom;
4550 attributes.event_mask = (GDK_EXPOSURE_MASK |
4551 GDK_KEY_PRESS_MASK |
4552 GDK_ENTER_NOTIFY_MASK |
4553 GDK_LEAVE_NOTIFY_MASK |
4554 GDK_FOCUS_CHANGE_MASK |
4555 GDK_STRUCTURE_MASK |
4556 GDK_BUTTON_MOTION_MASK |
4557 GDK_POINTER_MOTION_HINT_MASK |
4558 GDK_BUTTON_PRESS_MASK |
4559 GDK_BUTTON_RELEASE_MASK);
4561 attributes_mask = GDK_WA_VISUAL | GDK_WA_COLORMAP;
4563 window->frame = gdk_window_new (gtk_widget_get_root_window (widget),
4564 &attributes, attributes_mask);
4566 if (priv->opacity_set)
4567 gdk_window_set_opacity (window->frame, priv->opacity);
4569 gdk_window_set_user_data (window->frame, widget);
4571 attributes.window_type = GDK_WINDOW_CHILD;
4572 attributes.x = window->frame_left;
4573 attributes.y = window->frame_top;
4575 attributes_mask = GDK_WA_X | GDK_WA_Y;
4577 parent_window = window->frame;
4579 g_signal_connect (window,
4581 G_CALLBACK (gtk_window_event),
4586 attributes_mask = 0;
4587 parent_window = gtk_widget_get_root_window (widget);
4590 attributes.width = widget->allocation.width;
4591 attributes.height = widget->allocation.height;
4592 attributes.event_mask = gtk_widget_get_events (widget);
4593 attributes.event_mask |= (GDK_EXPOSURE_MASK |
4594 GDK_KEY_PRESS_MASK |
4595 GDK_KEY_RELEASE_MASK |
4596 GDK_ENTER_NOTIFY_MASK |
4597 GDK_LEAVE_NOTIFY_MASK |
4598 GDK_FOCUS_CHANGE_MASK |
4599 GDK_STRUCTURE_MASK);
4600 attributes.type_hint = priv->type_hint;
4602 attributes_mask |= GDK_WA_VISUAL | GDK_WA_COLORMAP | GDK_WA_TYPE_HINT;
4603 attributes_mask |= (window->title ? GDK_WA_TITLE : 0);
4604 attributes_mask |= (window->wmclass_name ? GDK_WA_WMCLASS : 0);
4606 widget->window = gdk_window_new (parent_window, &attributes, attributes_mask);
4608 if (!window->has_frame && priv->opacity_set)
4609 gdk_window_set_opacity (widget->window, priv->opacity);
4611 gdk_window_enable_synchronized_configure (widget->window);
4613 gdk_window_set_user_data (widget->window, window);
4615 widget->style = gtk_style_attach (widget->style, widget->window);
4616 gtk_style_set_background (widget->style, widget->window, GTK_STATE_NORMAL);
4618 gtk_style_set_background (widget->style, window->frame, GTK_STATE_NORMAL);
4620 /* This is a bad hack to set the window background. */
4621 gtk_window_paint (widget, NULL);
4623 if (window->transient_parent &&
4624 GTK_WIDGET_REALIZED (window->transient_parent))
4625 gdk_window_set_transient_for (widget->window,
4626 GTK_WIDGET (window->transient_parent)->window);
4628 if (window->wm_role)
4629 gdk_window_set_role (widget->window, window->wm_role);
4631 if (!window->decorated)
4632 gdk_window_set_decorations (widget->window, 0);
4634 if (!priv->deletable)
4635 gdk_window_set_functions (widget->window, GDK_FUNC_ALL | GDK_FUNC_CLOSE);
4637 if (gtk_window_get_skip_pager_hint (window))
4638 gdk_window_set_skip_pager_hint (widget->window, TRUE);
4640 if (gtk_window_get_skip_taskbar_hint (window))
4641 gdk_window_set_skip_taskbar_hint (widget->window, TRUE);
4643 if (gtk_window_get_accept_focus (window))
4644 gdk_window_set_accept_focus (widget->window, TRUE);
4646 gdk_window_set_accept_focus (widget->window, FALSE);
4648 if (gtk_window_get_focus_on_map (window))
4649 gdk_window_set_focus_on_map (widget->window, TRUE);
4651 gdk_window_set_focus_on_map (widget->window, FALSE);
4654 gdk_window_set_modal_hint (widget->window, TRUE);
4656 gdk_window_set_modal_hint (widget->window, FALSE);
4658 if (priv->startup_id)
4660 #ifdef GDK_WINDOWING_X11
4661 guint32 timestamp = extract_time_from_startup_id (priv->startup_id);
4662 if (timestamp != GDK_CURRENT_TIME)
4663 gdk_x11_window_set_user_time (widget->window, timestamp);
4665 if (!startup_id_is_fake (priv->startup_id))
4666 gdk_window_set_startup_id (widget->window, priv->startup_id);
4670 gtk_window_realize_icon (window);
4674 gtk_window_unrealize (GtkWidget *widget)
4677 GtkWindowGeometryInfo *info;
4679 window = GTK_WINDOW (widget);
4681 /* On unrealize, we reset the size of the window such
4682 * that we will re-apply the default sizing stuff
4683 * next time we show the window.
4685 * Default positioning is reset on unmap, instead of unrealize.
4687 window->need_default_size = TRUE;
4688 info = gtk_window_get_geometry_info (window, FALSE);
4691 info->resize_width = -1;
4692 info->resize_height = -1;
4693 info->last.configure_request.x = 0;
4694 info->last.configure_request.y = 0;
4695 info->last.configure_request.width = -1;
4696 info->last.configure_request.height = -1;
4697 /* be sure we reset geom hints on re-realize */
4698 info->last.flags = 0;
4703 gdk_window_set_user_data (window->frame, NULL);
4704 gdk_window_destroy (window->frame);
4705 window->frame = NULL;
4709 gtk_window_unrealize_icon (window);
4711 (* GTK_WIDGET_CLASS (gtk_window_parent_class)->unrealize) (widget);
4715 gtk_window_size_request (GtkWidget *widget,
4716 GtkRequisition *requisition)
4721 window = GTK_WINDOW (widget);
4722 bin = GTK_BIN (window);
4724 requisition->width = GTK_CONTAINER (window)->border_width * 2;
4725 requisition->height = GTK_CONTAINER (window)->border_width * 2;
4727 if (bin->child && GTK_WIDGET_VISIBLE (bin->child))
4729 GtkRequisition child_requisition;
4731 gtk_widget_size_request (bin->child, &child_requisition);
4733 requisition->width += child_requisition.width;
4734 requisition->height += child_requisition.height;
4739 gtk_window_size_allocate (GtkWidget *widget,
4740 GtkAllocation *allocation)
4743 GtkAllocation child_allocation;
4745 window = GTK_WINDOW (widget);
4746 widget->allocation = *allocation;
4748 if (window->bin.child && GTK_WIDGET_VISIBLE (window->bin.child))
4750 child_allocation.x = GTK_CONTAINER (window)->border_width;
4751 child_allocation.y = GTK_CONTAINER (window)->border_width;
4752 child_allocation.width =
4753 MAX (1, (gint)allocation->width - child_allocation.x * 2);
4754 child_allocation.height =
4755 MAX (1, (gint)allocation->height - child_allocation.y * 2);
4757 gtk_widget_size_allocate (window->bin.child, &child_allocation);
4760 if (GTK_WIDGET_REALIZED (widget) && window->frame)
4762 gdk_window_resize (window->frame,
4763 allocation->width + window->frame_left + window->frame_right,
4764 allocation->height + window->frame_top + window->frame_bottom);
4769 gtk_window_event (GtkWidget *widget, GdkEvent *event)
4772 gboolean return_val;
4774 window = GTK_WINDOW (widget);
4776 if (window->frame && (event->any.window == window->frame))
4778 if ((event->type != GDK_KEY_PRESS) &&
4779 (event->type != GDK_KEY_RELEASE) &&
4780 (event->type != GDK_FOCUS_CHANGE))
4782 g_signal_stop_emission_by_name (widget, "event");
4784 g_signal_emit (widget, window_signals[FRAME_EVENT], 0, event, &return_val);
4789 g_object_unref (event->any.window);
4790 event->any.window = g_object_ref (widget->window);
4798 gtk_window_frame_event (GtkWindow *window, GdkEvent *event)
4800 GdkEventConfigure *configure_event;
4803 switch (event->type)
4806 configure_event = (GdkEventConfigure *)event;
4808 /* Invalidate the decorations */
4811 rect.width = configure_event->width;
4812 rect.height = configure_event->height;
4814 gdk_window_invalidate_rect (window->frame, &rect, FALSE);
4816 /* Pass on the (modified) configure event */
4817 configure_event->width -= window->frame_left + window->frame_right;
4818 configure_event->height -= window->frame_top + window->frame_bottom;
4819 return gtk_window_configure_event (GTK_WIDGET (window), configure_event);
4828 gtk_window_configure_event (GtkWidget *widget,
4829 GdkEventConfigure *event)
4831 GtkWindow *window = GTK_WINDOW (widget);
4832 gboolean expected_reply = window->configure_request_count > 0;
4834 /* window->configure_request_count incremented for each
4835 * configure request, and decremented to a min of 0 for
4836 * each configure notify.
4838 * All it means is that we know we will get at least
4839 * window->configure_request_count more configure notifies.
4840 * We could get more configure notifies than that; some
4841 * of the configure notifies we get may be unrelated to
4842 * the configure requests. But we will get at least
4843 * window->configure_request_count notifies.
4846 if (window->configure_request_count > 0)
4848 window->configure_request_count -= 1;
4849 gdk_window_thaw_toplevel_updates_libgtk_only (widget->window);
4852 /* As an optimization, we avoid a resize when possible.
4854 * The only times we can avoid a resize are:
4855 * - we know only the position changed, not the size
4856 * - we know we have made more requests and so will get more
4857 * notifies and can wait to resize when we get them
4860 if (!expected_reply &&
4861 (widget->allocation.width == event->width &&
4862 widget->allocation.height == event->height))
4864 gdk_window_configure_finished (widget->window);
4869 * If we do need to resize, we do that by:
4870 * - filling in widget->allocation with the new size
4871 * - setting configure_notify_received to TRUE
4872 * for use in gtk_window_move_resize()
4873 * - queueing a resize, leading to invocation of
4874 * gtk_window_move_resize() in an idle handler
4878 window->configure_notify_received = TRUE;
4880 widget->allocation.width = event->width;
4881 widget->allocation.height = event->height;
4883 _gtk_container_queue_resize (GTK_CONTAINER (widget));
4888 /* the accel_key and accel_mods fields of the key have to be setup
4889 * upon calling this function. it'll then return whether that key
4890 * is at all used as accelerator, and if so will OR in the
4891 * accel_flags member of the key.
4894 _gtk_window_query_nonaccels (GtkWindow *window,
4896 GdkModifierType accel_mods)
4898 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
4900 /* movement keys are considered locked accels */
4903 static const guint bindings[] = {
4904 GDK_space, GDK_KP_Space, GDK_Return, GDK_ISO_Enter, GDK_KP_Enter, GDK_Up, GDK_KP_Up, GDK_Down, GDK_KP_Down,
4905 GDK_Left, GDK_KP_Left, GDK_Right, GDK_KP_Right, GDK_Tab, GDK_KP_Tab, GDK_ISO_Left_Tab,
4909 for (i = 0; i < G_N_ELEMENTS (bindings); i++)
4910 if (bindings[i] == accel_key)
4914 /* mnemonics are considered locked accels */
4915 if (accel_mods == window->mnemonic_modifier)
4917 GtkMnemonicHash *mnemonic_hash = gtk_window_get_mnemonic_hash (window, FALSE);
4918 if (mnemonic_hash && _gtk_mnemonic_hash_lookup (mnemonic_hash, accel_key))
4926 * gtk_window_propagate_key_event:
4927 * @window: a #GtkWindow
4928 * @event: a #GdkEventKey
4930 * Propagate a key press or release event to the focus widget and
4931 * up the focus container chain until a widget handles @event.
4932 * This is normally called by the default ::key_press_event and
4933 * ::key_release_event handlers for toplevel windows,
4934 * however in some cases it may be useful to call this directly when
4935 * overriding the standard key handling for a toplevel window.
4937 * Return value: %TRUE if a widget in the focus chain handled the event.
4940 gtk_window_propagate_key_event (GtkWindow *window,
4943 gboolean handled = FALSE;
4944 GtkWidget *widget, *focus;
4946 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
4948 widget = GTK_WIDGET (window);
4949 focus = window->focus_widget;
4951 g_object_ref (focus);
4954 focus && focus != widget &&
4955 gtk_widget_get_toplevel (focus) == widget)
4959 if (GTK_WIDGET_IS_SENSITIVE (focus))
4960 handled = gtk_widget_event (focus, (GdkEvent*) event);
4962 parent = focus->parent;
4964 g_object_ref (parent);
4966 g_object_unref (focus);
4972 g_object_unref (focus);
4978 gtk_window_key_press_event (GtkWidget *widget,
4981 GtkWindow *window = GTK_WINDOW (widget);
4982 gboolean handled = FALSE;
4984 /* handle mnemonics and accelerators */
4986 handled = gtk_window_activate_key (window, event);
4988 /* handle focus widget key events */
4990 handled = gtk_window_propagate_key_event (window, event);
4992 /* Chain up, invokes binding set */
4994 handled = GTK_WIDGET_CLASS (gtk_window_parent_class)->key_press_event (widget, event);
5000 gtk_window_key_release_event (GtkWidget *widget,
5003 GtkWindow *window = GTK_WINDOW (widget);
5004 gboolean handled = FALSE;
5006 /* handle focus widget key events */
5008 handled = gtk_window_propagate_key_event (window, event);
5010 /* Chain up, invokes binding set */
5012 handled = GTK_WIDGET_CLASS (gtk_window_parent_class)->key_release_event (widget, event);
5018 gtk_window_real_activate_default (GtkWindow *window)
5020 gtk_window_activate_default (window);
5024 gtk_window_real_activate_focus (GtkWindow *window)
5026 gtk_window_activate_focus (window);
5030 gtk_window_move_focus (GtkWindow *window,
5031 GtkDirectionType dir)
5033 gtk_widget_child_focus (GTK_WIDGET (window), dir);
5035 if (!GTK_CONTAINER (window)->focus_child)
5036 gtk_window_set_focus (window, NULL);
5040 gtk_window_enter_notify_event (GtkWidget *widget,
5041 GdkEventCrossing *event)
5047 gtk_window_leave_notify_event (GtkWidget *widget,
5048 GdkEventCrossing *event)
5054 do_focus_change (GtkWidget *widget,
5057 GdkEvent *fevent = gdk_event_new (GDK_FOCUS_CHANGE);
5059 g_object_ref (widget);
5062 GTK_WIDGET_SET_FLAGS (widget, GTK_HAS_FOCUS);
5064 GTK_WIDGET_UNSET_FLAGS (widget, GTK_HAS_FOCUS);
5066 fevent->focus_change.type = GDK_FOCUS_CHANGE;
5067 fevent->focus_change.window = widget->window;
5069 g_object_ref (widget->window);
5070 fevent->focus_change.in = in;
5072 gtk_widget_event (widget, fevent);
5074 g_object_notify (G_OBJECT (widget), "has-focus");
5076 g_object_unref (widget);
5077 gdk_event_free (fevent);
5081 gtk_window_focus_in_event (GtkWidget *widget,
5082 GdkEventFocus *event)
5084 GtkWindow *window = GTK_WINDOW (widget);
5086 /* It appears spurious focus in events can occur when
5087 * the window is hidden. So we'll just check to see if
5088 * the window is visible before actually handling the
5091 if (GTK_WIDGET_VISIBLE (widget))
5093 _gtk_window_set_has_toplevel_focus (window, TRUE);
5094 _gtk_window_set_is_active (window, TRUE);
5101 gtk_window_focus_out_event (GtkWidget *widget,
5102 GdkEventFocus *event)
5104 GtkWindow *window = GTK_WINDOW (widget);
5106 _gtk_window_set_has_toplevel_focus (window, FALSE);
5107 _gtk_window_set_is_active (window, FALSE);
5112 static GdkAtom atom_rcfiles = GDK_NONE;
5113 static GdkAtom atom_iconthemes = GDK_NONE;
5116 send_client_message_to_embedded_windows (GtkWidget *widget,
5117 GdkAtom message_type)
5119 GList *embedded_windows;
5121 embedded_windows = g_object_get_qdata (G_OBJECT (widget), quark_gtk_embedded);
5122 if (embedded_windows)
5124 GdkEvent *send_event = gdk_event_new (GDK_CLIENT_EVENT);
5127 for (i = 0; i < 5; i++)
5128 send_event->client.data.l[i] = 0;
5129 send_event->client.data_format = 32;
5130 send_event->client.message_type = message_type;
5132 while (embedded_windows)
5134 guint xid = GPOINTER_TO_UINT (embedded_windows->data);
5135 gdk_event_send_client_message_for_display (gtk_widget_get_display (widget), send_event, xid);
5136 embedded_windows = embedded_windows->next;
5139 gdk_event_free (send_event);
5144 gtk_window_client_event (GtkWidget *widget,
5145 GdkEventClient *event)
5149 atom_rcfiles = gdk_atom_intern_static_string ("_GTK_READ_RCFILES");
5150 atom_iconthemes = gdk_atom_intern_static_string ("_GTK_LOAD_ICONTHEMES");
5153 if (event->message_type == atom_rcfiles)
5155 send_client_message_to_embedded_windows (widget, atom_rcfiles);
5156 gtk_rc_reparse_all_for_settings (gtk_widget_get_settings (widget), FALSE);
5159 if (event->message_type == atom_iconthemes)
5161 send_client_message_to_embedded_windows (widget, atom_iconthemes);
5162 _gtk_icon_theme_check_reload (gtk_widget_get_display (widget));
5169 gtk_window_check_resize (GtkContainer *container)
5171 GtkWindow *window = GTK_WINDOW (container);
5173 if (GTK_WIDGET_VISIBLE (container))
5174 gtk_window_move_resize (window);
5178 gtk_window_focus (GtkWidget *widget,
5179 GtkDirectionType direction)
5183 GtkContainer *container;
5184 GtkWidget *old_focus_child;
5187 container = GTK_CONTAINER (widget);
5188 window = GTK_WINDOW (widget);
5189 bin = GTK_BIN (widget);
5191 old_focus_child = container->focus_child;
5193 /* We need a special implementation here to deal properly with wrapping
5194 * around in the tab chain without the danger of going into an
5197 if (old_focus_child)
5199 if (gtk_widget_child_focus (old_focus_child, direction))
5203 if (window->focus_widget)
5205 if (direction == GTK_DIR_LEFT ||
5206 direction == GTK_DIR_RIGHT ||
5207 direction == GTK_DIR_UP ||
5208 direction == GTK_DIR_DOWN)
5213 /* Wrapped off the end, clear the focus setting for the toplpevel */
5214 parent = window->focus_widget->parent;
5217 gtk_container_set_focus_child (GTK_CONTAINER (parent), NULL);
5218 parent = GTK_WIDGET (parent)->parent;
5221 gtk_window_set_focus (GTK_WINDOW (container), NULL);
5224 /* Now try to focus the first widget in the window */
5227 if (gtk_widget_child_focus (bin->child, direction))
5235 gtk_window_real_set_focus (GtkWindow *window,
5238 GtkWidget *old_focus = window->focus_widget;
5239 gboolean had_default = FALSE;
5240 gboolean focus_had_default = FALSE;
5241 gboolean old_focus_had_default = FALSE;
5245 g_object_ref (old_focus);
5246 g_object_freeze_notify (G_OBJECT (old_focus));
5247 old_focus_had_default = GTK_WIDGET_HAS_DEFAULT (old_focus);
5251 g_object_ref (focus);
5252 g_object_freeze_notify (G_OBJECT (focus));
5253 focus_had_default = GTK_WIDGET_HAS_DEFAULT (focus);
5256 if (window->default_widget)
5257 had_default = GTK_WIDGET_HAS_DEFAULT (window->default_widget);
5259 if (window->focus_widget)
5261 if (GTK_WIDGET_RECEIVES_DEFAULT (window->focus_widget) &&
5262 (window->focus_widget != window->default_widget))
5264 GTK_WIDGET_UNSET_FLAGS (window->focus_widget, GTK_HAS_DEFAULT);
5265 gtk_widget_queue_draw (window->focus_widget);
5267 if (window->default_widget)
5268 GTK_WIDGET_SET_FLAGS (window->default_widget, GTK_HAS_DEFAULT);
5271 window->focus_widget = NULL;
5273 if (window->has_focus)
5274 do_focus_change (old_focus, FALSE);
5276 g_object_notify (G_OBJECT (old_focus), "is-focus");
5279 /* The above notifications may have set a new focus widget,
5280 * if so, we don't want to override it.
5282 if (focus && !window->focus_widget)
5284 window->focus_widget = focus;
5286 if (GTK_WIDGET_RECEIVES_DEFAULT (window->focus_widget) &&
5287 (window->focus_widget != window->default_widget))
5289 if (GTK_WIDGET_CAN_DEFAULT (window->focus_widget))
5290 GTK_WIDGET_SET_FLAGS (window->focus_widget, GTK_HAS_DEFAULT);
5292 if (window->default_widget)
5293 GTK_WIDGET_UNSET_FLAGS (window->default_widget, GTK_HAS_DEFAULT);
5296 if (window->has_focus)
5297 do_focus_change (window->focus_widget, TRUE);
5299 g_object_notify (G_OBJECT (window->focus_widget), "is-focus");
5302 /* If the default widget changed, a redraw will have been queued
5303 * on the old and new default widgets by gtk_window_set_default(), so
5304 * we only have to worry about the case where it didn't change.
5305 * We'll sometimes queue a draw twice on the new widget but that
5308 if (window->default_widget &&
5309 (had_default != GTK_WIDGET_HAS_DEFAULT (window->default_widget)))
5310 gtk_widget_queue_draw (window->default_widget);
5314 if (old_focus_had_default != GTK_WIDGET_HAS_DEFAULT (old_focus))
5315 gtk_widget_queue_draw (old_focus);
5317 g_object_thaw_notify (G_OBJECT (old_focus));
5318 g_object_unref (old_focus);
5322 if (focus_had_default != GTK_WIDGET_HAS_DEFAULT (focus))
5323 gtk_widget_queue_draw (focus);
5325 g_object_thaw_notify (G_OBJECT (focus));
5326 g_object_unref (focus);
5331 * _gtk_window_unset_focus_and_default:
5332 * @window: a #GtkWindow
5333 * @widget: a widget inside of @window
5335 * Checks whether the focus and default widgets of @window are
5336 * @widget or a descendent of @widget, and if so, unset them.
5339 _gtk_window_unset_focus_and_default (GtkWindow *window,
5345 g_object_ref (window);
5346 g_object_ref (widget);
5348 if (GTK_CONTAINER (widget->parent)->focus_child == widget)
5350 child = window->focus_widget;
5352 while (child && child != widget)
5353 child = child->parent;
5355 if (child == widget)
5356 gtk_window_set_focus (GTK_WINDOW (window), NULL);
5359 child = window->default_widget;
5361 while (child && child != widget)
5362 child = child->parent;
5364 if (child == widget)
5365 gtk_window_set_default (window, NULL);
5367 g_object_unref (widget);
5368 g_object_unref (window);
5371 /*********************************
5372 * Functions related to resizing *
5373 *********************************/
5375 /* This function doesn't constrain to geometry hints */
5377 gtk_window_compute_configure_request_size (GtkWindow *window,
5381 GtkRequisition requisition;
5382 GtkWindowGeometryInfo *info;
5386 * - we've done a size request
5389 widget = GTK_WIDGET (window);
5391 info = gtk_window_get_geometry_info (window, FALSE);
5393 if (window->need_default_size)
5395 gtk_widget_get_child_requisition (widget, &requisition);
5397 /* Default to requisition */
5398 *width = requisition.width;
5399 *height = requisition.height;
5401 /* If window is empty so requests 0, default to random nonzero size */
5402 if (*width == 0 && *height == 0)
5408 /* Override requisition with default size */
5412 gint base_width = 0;
5413 gint base_height = 0;
5415 gint min_height = 0;
5417 gint height_inc = 1;
5419 if (info->default_is_geometry &&
5420 (info->default_width > 0 || info->default_height > 0))
5422 GdkGeometry geometry;
5425 gtk_window_compute_hints (window, &geometry, &flags);
5427 if (flags & GDK_HINT_BASE_SIZE)
5429 base_width = geometry.base_width;
5430 base_height = geometry.base_height;
5432 if (flags & GDK_HINT_MIN_SIZE)
5434 min_width = geometry.min_width;
5435 min_height = geometry.min_height;
5437 if (flags & GDK_HINT_RESIZE_INC)
5439 width_inc = geometry.width_inc;
5440 height_inc = geometry.height_inc;
5444 if (info->default_width > 0)
5445 *width = MAX (info->default_width * width_inc + base_width, min_width);
5447 if (info->default_height > 0)
5448 *height = MAX (info->default_height * height_inc + base_height, min_height);
5453 /* Default to keeping current size */
5454 *width = widget->allocation.width;
5455 *height = widget->allocation.height;
5458 /* Override any size with gtk_window_resize() values */
5461 if (info->resize_width > 0)
5462 *width = info->resize_width;
5464 if (info->resize_height > 0)
5465 *height = info->resize_height;
5469 static GtkWindowPosition
5470 get_effective_position (GtkWindow *window)
5472 GtkWindowPosition pos = window->position;
5473 if (pos == GTK_WIN_POS_CENTER_ON_PARENT &&
5474 (window->transient_parent == NULL ||
5475 !GTK_WIDGET_MAPPED (window->transient_parent)))
5476 pos = GTK_WIN_POS_NONE;
5482 get_center_monitor_of_window (GtkWindow *window)
5484 /* We could try to sort out the relative positions of the monitors and
5485 * stuff, or we could just be losers and assume you have a row
5486 * or column of monitors.
5488 return gdk_screen_get_n_monitors (gtk_window_check_screen (window)) / 2;
5492 get_monitor_containing_pointer (GtkWindow *window)
5496 GdkScreen *window_screen;
5497 GdkScreen *pointer_screen;
5499 window_screen = gtk_window_check_screen (window);
5500 gdk_display_get_pointer (gdk_screen_get_display (window_screen),
5504 if (pointer_screen == window_screen)
5505 monitor_num = gdk_screen_get_monitor_at_point (pointer_screen, px, py);
5513 center_window_on_monitor (GtkWindow *window,
5519 GdkRectangle monitor;
5522 monitor_num = get_monitor_containing_pointer (window);
5524 if (monitor_num == -1)
5525 monitor_num = get_center_monitor_of_window (window);
5527 gdk_screen_get_monitor_geometry (gtk_window_check_screen (window),
5528 monitor_num, &monitor);
5530 *x = (monitor.width - w) / 2 + monitor.x;
5531 *y = (monitor.height - h) / 2 + monitor.y;
5533 /* Be sure we aren't off the monitor, ignoring _NET_WM_STRUT
5534 * and WM decorations.
5548 if (extent > clamp_extent)
5550 *base = clamp_base + clamp_extent/2 - extent/2;
5551 else if (*base < clamp_base)
5553 else if (*base + extent > clamp_base + clamp_extent)
5554 *base = clamp_base + clamp_extent - extent;
5558 clamp_window_to_rectangle (gint *x,
5562 const GdkRectangle *rect)
5564 #ifdef DEBUGGING_OUTPUT
5565 g_print ("%s: %+d%+d %dx%d: %+d%+d: %dx%d", __FUNCTION__, rect->x, rect->y, rect->width, rect->height, *x, *y, w, h);
5568 /* If it is too large, center it. If it fits on the monitor but is
5569 * partially outside, move it to the closest edge. Do this
5570 * separately in x and y directions.
5572 clamp (x, w, rect->x, rect->width);
5573 clamp (y, h, rect->y, rect->height);
5574 #ifdef DEBUGGING_OUTPUT
5575 g_print (" ==> %+d%+d: %dx%d\n", *x, *y, w, h);
5581 gtk_window_compute_configure_request (GtkWindow *window,
5582 GdkRectangle *request,
5583 GdkGeometry *geometry,
5586 GdkGeometry new_geometry;
5590 GtkWindowPosition pos;
5591 GtkWidget *parent_widget;
5592 GtkWindowGeometryInfo *info;
5596 widget = GTK_WIDGET (window);
5598 screen = gtk_window_check_screen (window);
5600 gtk_widget_size_request (widget, NULL);
5601 gtk_window_compute_configure_request_size (window, (guint *)&w, (guint *)&h);
5603 gtk_window_compute_hints (window, &new_geometry, &new_flags);
5604 gtk_window_constrain_size (window,
5605 &new_geometry, new_flags,
5609 parent_widget = (GtkWidget*) window->transient_parent;
5611 pos = get_effective_position (window);
5612 info = gtk_window_get_geometry_info (window, FALSE);
5614 /* by default, don't change position requested */
5617 x = info->last.configure_request.x;
5618 y = info->last.configure_request.y;
5627 if (window->need_default_position)
5630 /* FIXME this all interrelates with window gravity.
5631 * For most of them I think we want to set GRAVITY_CENTER.
5633 * Not sure how to go about that.
5638 /* here we are only handling CENTER_ALWAYS
5639 * as it relates to default positioning,
5640 * where it's equivalent to simply CENTER
5642 case GTK_WIN_POS_CENTER_ALWAYS:
5643 case GTK_WIN_POS_CENTER:
5644 center_window_on_monitor (window, w, h, &x, &y);
5647 case GTK_WIN_POS_CENTER_ON_PARENT:
5650 GdkRectangle monitor;
5653 g_assert (GTK_WIDGET_MAPPED (parent_widget)); /* established earlier */
5655 if (parent_widget->window != NULL)
5656 monitor_num = gdk_screen_get_monitor_at_window (screen,
5657 parent_widget->window);
5661 gdk_window_get_origin (parent_widget->window,
5664 x = ox + (parent_widget->allocation.width - w) / 2;
5665 y = oy + (parent_widget->allocation.height - h) / 2;
5667 /* Clamp onto current monitor, ignoring _NET_WM_STRUT and
5668 * WM decorations. If parent wasn't on a monitor, just
5671 if (monitor_num >= 0)
5673 gdk_screen_get_monitor_geometry (screen, monitor_num, &monitor);
5674 clamp_window_to_rectangle (&x, &y, w, h, &monitor);
5679 case GTK_WIN_POS_MOUSE:
5681 gint screen_width = gdk_screen_get_width (screen);
5682 gint screen_height = gdk_screen_get_height (screen);
5684 GdkRectangle monitor;
5685 GdkScreen *pointer_screen;
5688 gdk_display_get_pointer (gdk_screen_get_display (screen),
5692 if (pointer_screen == screen)
5693 monitor_num = gdk_screen_get_monitor_at_point (screen, px, py);
5699 x = CLAMP (x, 0, screen_width - w);
5700 y = CLAMP (y, 0, screen_height - h);
5702 /* Clamp onto current monitor, ignoring _NET_WM_STRUT and
5703 * WM decorations. Don't try to figure out what's going
5704 * on if the mouse wasn't inside a monitor.
5706 if (monitor_num >= 0)
5708 gdk_screen_get_monitor_geometry (screen, monitor_num, &monitor);
5709 clamp_window_to_rectangle (&x, &y, w, h, &monitor);
5717 } /* if (window->need_default_position) */
5719 if (window->need_default_position && info &&
5720 info->initial_pos_set)
5722 x = info->initial_x;
5723 y = info->initial_y;
5724 gtk_window_constrain_position (window, w, h, &x, &y);
5730 request->height = h;
5733 *geometry = new_geometry;
5739 gtk_window_constrain_position (GtkWindow *window,
5745 /* See long comments in gtk_window_move_resize()
5746 * on when it's safe to call this function.
5748 if (window->position == GTK_WIN_POS_CENTER_ALWAYS)
5750 gint center_x, center_y;
5752 center_window_on_monitor (window, new_width, new_height, ¢er_x, ¢er_y);
5760 gtk_window_move_resize (GtkWindow *window)
5764 * First we determine whether any information has changed that would
5765 * cause us to revise our last configure request. If we would send
5766 * a different configure request from last time, then
5767 * configure_request_size_changed = TRUE or
5768 * configure_request_pos_changed = TRUE. configure_request_size_changed
5769 * may be true due to new hints, a gtk_window_resize(), or whatever.
5770 * configure_request_pos_changed may be true due to gtk_window_set_position()
5771 * or gtk_window_move().
5773 * If the configure request has changed, we send off a new one. To
5774 * ensure GTK+ invariants are maintained (resize queue does what it
5775 * should), we go ahead and size_allocate the requested size in this
5778 * If the configure request has not changed, we don't ever resend
5779 * it, because it could mean fighting the user or window manager.
5782 * To prepare the configure request, we come up with a base size/pos:
5783 * - the one from gtk_window_move()/gtk_window_resize()
5784 * - else default_width, default_height if we haven't ever
5786 * - else the size request if we haven't ever been mapped,
5787 * as a substitute default size
5788 * - else the current size of the window, as received from
5789 * configure notifies (i.e. the current allocation)
5791 * If GTK_WIN_POS_CENTER_ALWAYS is active, we constrain
5792 * the position request to be centered.
5795 GtkContainer *container;
5796 GtkWindowGeometryInfo *info;
5797 GdkGeometry new_geometry;
5799 GdkRectangle new_request;
5800 gboolean configure_request_size_changed;
5801 gboolean configure_request_pos_changed;
5802 gboolean hints_changed; /* do we need to send these again */
5803 GtkWindowLastGeometryInfo saved_last_info;
5805 widget = GTK_WIDGET (window);
5806 container = GTK_CONTAINER (widget);
5807 info = gtk_window_get_geometry_info (window, TRUE);
5809 configure_request_size_changed = FALSE;
5810 configure_request_pos_changed = FALSE;
5812 gtk_window_compute_configure_request (window, &new_request,
5813 &new_geometry, &new_flags);
5815 /* This check implies the invariant that we never set info->last
5816 * without setting the hints and sending off a configure request.
5818 * If we change info->last without sending the request, we may
5821 if (info->last.configure_request.x != new_request.x ||
5822 info->last.configure_request.y != new_request.y)
5823 configure_request_pos_changed = TRUE;
5825 if ((info->last.configure_request.width != new_request.width ||
5826 info->last.configure_request.height != new_request.height))
5827 configure_request_size_changed = TRUE;
5829 hints_changed = FALSE;
5831 if (!gtk_window_compare_hints (&info->last.geometry, info->last.flags,
5832 &new_geometry, new_flags))
5834 hints_changed = TRUE;
5837 /* Position Constraints
5838 * ====================
5840 * POS_CENTER_ALWAYS is conceptually a constraint rather than
5841 * a default. The other POS_ values are used only when the
5842 * window is shown, not after that.
5844 * However, we can't implement a position constraint as
5845 * "anytime the window size changes, center the window"
5846 * because this may well end up fighting the WM or user. In
5847 * fact it gets in an infinite loop with at least one WM.
5849 * Basically, applications are in no way in a position to
5850 * constrain the position of a window, with one exception:
5851 * override redirect windows. (Really the intended purpose
5852 * of CENTER_ALWAYS anyhow, I would think.)
5854 * So the way we implement this "constraint" is to say that when WE
5855 * cause a move or resize, i.e. we make a configure request changing
5856 * window size, we recompute the CENTER_ALWAYS position to reflect
5857 * the new window size, and include it in our request. Also, if we
5858 * just turned on CENTER_ALWAYS we snap to center with a new
5859 * request. Otherwise, if we are just NOTIFIED of a move or resize
5860 * done by someone else e.g. the window manager, we do NOT send a
5861 * new configure request.
5863 * For override redirect windows, this works fine; all window
5864 * sizes are from our configure requests. For managed windows,
5865 * it is at least semi-sane, though who knows what the
5866 * app author is thinking.
5869 /* This condition should be kept in sync with the condition later on
5870 * that determines whether we send a configure request. i.e. we
5871 * should do this position constraining anytime we were going to
5872 * send a configure request anyhow, plus when constraints have
5875 if (configure_request_pos_changed ||
5876 configure_request_size_changed ||
5878 info->position_constraints_changed)
5880 /* We request the constrained position if:
5881 * - we were changing position, and need to clamp
5882 * the change to the constraint
5883 * - we're changing the size anyway
5884 * - set_position() was called to toggle CENTER_ALWAYS on
5887 gtk_window_constrain_position (window,
5893 /* Update whether we need to request a move */
5894 if (info->last.configure_request.x != new_request.x ||
5895 info->last.configure_request.y != new_request.y)
5896 configure_request_pos_changed = TRUE;
5898 configure_request_pos_changed = FALSE;
5902 if (window->type == GTK_WINDOW_TOPLEVEL)
5904 int notify_x, notify_y;
5906 /* this is the position from the last configure notify */
5907 gdk_window_get_position (widget->window, ¬ify_x, ¬ify_y);
5909 g_message ("--- %s ---\n"
5910 "last : %d,%d\t%d x %d\n"
5911 "this : %d,%d\t%d x %d\n"
5912 "alloc : %d,%d\t%d x %d\n"
5914 "resize: \t%d x %d\n"
5915 "size_changed: %d pos_changed: %d hints_changed: %d\n"
5916 "configure_notify_received: %d\n"
5917 "configure_request_count: %d\n"
5918 "position_constraints_changed: %d\n",
5919 window->title ? window->title : "(no title)",
5920 info->last.configure_request.x,
5921 info->last.configure_request.y,
5922 info->last.configure_request.width,
5923 info->last.configure_request.height,
5929 widget->allocation.width,
5930 widget->allocation.height,
5931 widget->requisition.width,
5932 widget->requisition.height,
5934 info->resize_height,
5935 configure_request_pos_changed,
5936 configure_request_size_changed,
5938 window->configure_notify_received,
5939 window->configure_request_count,
5940 info->position_constraints_changed);
5944 saved_last_info = info->last;
5945 info->last.geometry = new_geometry;
5946 info->last.flags = new_flags;
5947 info->last.configure_request = new_request;
5949 /* need to set PPosition so the WM will look at our position,
5950 * but we don't want to count PPosition coming and going as a hints
5951 * change for future iterations. So we saved info->last prior to
5955 /* Also, if the initial position was explicitly set, then we always
5956 * toggle on PPosition. This makes gtk_window_move(window, 0, 0)
5960 /* Also, we toggle on PPosition if GTK_WIN_POS_ is in use and
5961 * this is an initial map
5964 if ((configure_request_pos_changed ||
5965 info->initial_pos_set ||
5966 (window->need_default_position &&
5967 get_effective_position (window) != GTK_WIN_POS_NONE)) &&
5968 (new_flags & GDK_HINT_POS) == 0)
5970 new_flags |= GDK_HINT_POS;
5971 hints_changed = TRUE;
5974 /* Set hints if necessary
5977 gdk_window_set_geometry_hints (widget->window,
5981 /* handle resizing/moving and widget tree allocation
5983 if (window->configure_notify_received)
5985 GtkAllocation allocation;
5987 /* If we have received a configure event since
5988 * the last time in this function, we need to
5989 * accept our new size and size_allocate child widgets.
5990 * (see gtk_window_configure_event() for more details).
5992 * 1 or more configure notifies may have been received.
5993 * Also, configure_notify_received will only be TRUE
5994 * if all expected configure notifies have been received
5995 * (one per configure request), as an optimization.
5998 window->configure_notify_received = FALSE;
6000 /* gtk_window_configure_event() filled in widget->allocation */
6001 allocation = widget->allocation;
6002 gtk_widget_size_allocate (widget, &allocation);
6004 gdk_window_process_updates (widget->window, TRUE);
6006 gdk_window_configure_finished (widget->window);
6008 /* If the configure request changed, it means that
6010 * 1) coincidentally changed hints or widget properties
6011 * impacting the configure request before getting
6012 * a configure notify, or
6013 * 2) some broken widget is changing its size request
6014 * during size allocation, resulting in
6015 * a false appearance of changed configure request.
6017 * For 1), we could just go ahead and ask for the
6018 * new size right now, but doing that for 2)
6019 * might well be fighting the user (and can even
6020 * trigger a loop). Since we really don't want to
6021 * do that, we requeue a resize in hopes that
6022 * by the time it gets handled, the child has seen
6023 * the light and is willing to go along with the
6024 * new size. (this happens for the zvt widget, since
6025 * the size_allocate() above will have stored the
6026 * requisition corresponding to the new size in the
6029 * This doesn't buy us anything for 1), but it shouldn't
6030 * hurt us too badly, since it is what would have
6031 * happened if we had gotten the configure event before
6032 * the new size had been set.
6035 if (configure_request_size_changed ||
6036 configure_request_pos_changed)
6038 /* Don't change the recorded last info after all, because we
6039 * haven't actually updated to the new info yet - we decided
6040 * to postpone our configure request until later.
6042 info->last = saved_last_info;
6044 gtk_widget_queue_resize_no_redraw (widget); /* migth recurse for GTK_RESIZE_IMMEDIATE */
6047 return; /* Bail out, we didn't really process the move/resize */
6049 else if ((configure_request_size_changed || hints_changed) &&
6050 (widget->allocation.width != new_request.width ||
6051 widget->allocation.height != new_request.height))
6054 /* We are in one of the following situations:
6055 * A. configure_request_size_changed
6056 * our requisition has changed and we need a different window size,
6057 * so we request it from the window manager.
6058 * B. !configure_request_size_changed && hints_changed
6059 * the window manager rejects our size, but we have just changed the
6060 * window manager hints, so there's a chance our request will
6061 * be honoured this time, so we try again.
6063 * However, if the new requisition is the same as the current allocation,
6064 * we don't request it again, since we won't get a ConfigureNotify back from
6065 * the window manager unless it decides to change our requisition. If
6066 * we don't get the ConfigureNotify back, the resize queue will never be run.
6069 /* Now send the configure request */
6070 if (configure_request_pos_changed)
6074 gdk_window_move_resize (window->frame,
6075 new_request.x - window->frame_left,
6076 new_request.y - window->frame_top,
6077 new_request.width + window->frame_left + window->frame_right,
6078 new_request.height + window->frame_top + window->frame_bottom);
6079 gdk_window_resize (widget->window,
6080 new_request.width, new_request.height);
6083 gdk_window_move_resize (widget->window,
6084 new_request.x, new_request.y,
6085 new_request.width, new_request.height);
6087 else /* only size changed */
6090 gdk_window_resize (window->frame,
6091 new_request.width + window->frame_left + window->frame_right,
6092 new_request.height + window->frame_top + window->frame_bottom);
6093 gdk_window_resize (widget->window,
6094 new_request.width, new_request.height);
6097 if (window->type == GTK_WINDOW_POPUP)
6099 GtkAllocation allocation;
6101 /* Directly size allocate for override redirect (popup) windows. */
6104 allocation.width = new_request.width;
6105 allocation.height = new_request.height;
6107 gtk_widget_size_allocate (widget, &allocation);
6109 gdk_window_process_updates (widget->window, TRUE);
6111 if (container->resize_mode == GTK_RESIZE_QUEUE)
6112 gtk_widget_queue_draw (widget);
6116 /* Increment the number of have-not-yet-received-notify requests */
6117 window->configure_request_count += 1;
6118 gdk_window_freeze_toplevel_updates_libgtk_only (widget->window);
6120 /* for GTK_RESIZE_QUEUE toplevels, we are now awaiting a new
6121 * configure event in response to our resizing request.
6122 * the configure event will cause a new resize with
6123 * ->configure_notify_received=TRUE.
6124 * until then, we want to
6125 * - discard expose events
6126 * - coalesce resizes for our children
6127 * - defer any window resizes until the configure event arrived
6128 * to achieve this, we queue a resize for the window, but remove its
6129 * resizing handler, so resizing will not be handled from the next
6130 * idle handler but when the configure event arrives.
6132 * FIXME: we should also dequeue the pending redraws here, since
6133 * we handle those ourselves upon ->configure_notify_received==TRUE.
6135 if (container->resize_mode == GTK_RESIZE_QUEUE)
6137 gtk_widget_queue_resize_no_redraw (widget);
6138 _gtk_container_dequeue_resize_handler (container);
6144 /* Handle any position changes.
6146 if (configure_request_pos_changed)
6150 gdk_window_move (window->frame,
6151 new_request.x - window->frame_left,
6152 new_request.y - window->frame_top);
6155 gdk_window_move (widget->window,
6156 new_request.x, new_request.y);
6159 /* And run the resize queue.
6161 gtk_container_resize_children (container);
6164 /* We have now processed a move/resize since the last position
6165 * constraint change, setting of the initial position, or resize.
6166 * (Not resetting these flags here can lead to infinite loops for
6167 * GTK_RESIZE_IMMEDIATE containers)
6169 info->position_constraints_changed = FALSE;
6170 info->initial_pos_set = FALSE;
6171 info->resize_width = -1;
6172 info->resize_height = -1;
6175 /* Compare two sets of Geometry hints for equality.
6178 gtk_window_compare_hints (GdkGeometry *geometry_a,
6180 GdkGeometry *geometry_b,
6183 if (flags_a != flags_b)
6186 if ((flags_a & GDK_HINT_MIN_SIZE) &&
6187 (geometry_a->min_width != geometry_b->min_width ||
6188 geometry_a->min_height != geometry_b->min_height))
6191 if ((flags_a & GDK_HINT_MAX_SIZE) &&
6192 (geometry_a->max_width != geometry_b->max_width ||
6193 geometry_a->max_height != geometry_b->max_height))
6196 if ((flags_a & GDK_HINT_BASE_SIZE) &&
6197 (geometry_a->base_width != geometry_b->base_width ||
6198 geometry_a->base_height != geometry_b->base_height))
6201 if ((flags_a & GDK_HINT_ASPECT) &&
6202 (geometry_a->min_aspect != geometry_b->min_aspect ||
6203 geometry_a->max_aspect != geometry_b->max_aspect))
6206 if ((flags_a & GDK_HINT_RESIZE_INC) &&
6207 (geometry_a->width_inc != geometry_b->width_inc ||
6208 geometry_a->height_inc != geometry_b->height_inc))
6211 if ((flags_a & GDK_HINT_WIN_GRAVITY) &&
6212 geometry_a->win_gravity != geometry_b->win_gravity)
6219 _gtk_window_constrain_size (GtkWindow *window,
6225 GtkWindowGeometryInfo *info;
6227 g_return_if_fail (GTK_IS_WINDOW (window));
6229 info = window->geometry_info;
6232 GdkWindowHints flags = info->last.flags;
6233 GdkGeometry *geometry = &info->last.geometry;
6235 gtk_window_constrain_size (window,
6246 gtk_window_constrain_size (GtkWindow *window,
6247 GdkGeometry *geometry,
6254 gdk_window_constrain_size (geometry, flags, width, height,
6255 new_width, new_height);
6258 /* Compute the set of geometry hints and flags for a window
6259 * based on the application set geometry, and requisiition
6260 * of the window. gtk_widget_size_request() must have been
6264 gtk_window_compute_hints (GtkWindow *window,
6265 GdkGeometry *new_geometry,
6269 gint extra_width = 0;
6270 gint extra_height = 0;
6271 GtkWindowGeometryInfo *geometry_info;
6272 GtkRequisition requisition;
6274 widget = GTK_WIDGET (window);
6276 gtk_widget_get_child_requisition (widget, &requisition);
6277 geometry_info = gtk_window_get_geometry_info (GTK_WINDOW (widget), FALSE);
6281 *new_flags = geometry_info->mask;
6282 *new_geometry = geometry_info->geometry;
6289 if (geometry_info && geometry_info->widget)
6291 GtkRequisition child_requisition;
6293 /* FIXME: This really isn't right. It gets the min size wrong and forces
6294 * callers to do horrible hacks like set a huge usize on the child requisition
6295 * to get the base size right. We really want to find the answers to:
6297 * - If the geometry widget was infinitely big, how much extra space
6298 * would be needed for the stuff around it.
6300 * - If the geometry widget was infinitely small, how big would the
6301 * window still have to be.
6303 * Finding these answers would be a bit of a mess here. (Bug #68668)
6305 gtk_widget_get_child_requisition (geometry_info->widget, &child_requisition);
6307 extra_width = widget->requisition.width - child_requisition.width;
6308 extra_height = widget->requisition.height - child_requisition.height;
6311 /* We don't want to set GDK_HINT_POS in here, we just set it
6312 * in gtk_window_move_resize() when we want the position
6316 if (*new_flags & GDK_HINT_BASE_SIZE)
6318 new_geometry->base_width += extra_width;
6319 new_geometry->base_height += extra_height;
6321 else if (!(*new_flags & GDK_HINT_MIN_SIZE) &&
6322 (*new_flags & GDK_HINT_RESIZE_INC) &&
6323 ((extra_width != 0) || (extra_height != 0)))
6325 *new_flags |= GDK_HINT_BASE_SIZE;
6327 new_geometry->base_width = extra_width;
6328 new_geometry->base_height = extra_height;
6331 if (*new_flags & GDK_HINT_MIN_SIZE)
6333 if (new_geometry->min_width < 0)
6334 new_geometry->min_width = requisition.width;
6336 new_geometry->min_width += extra_width;
6338 if (new_geometry->min_height < 0)
6339 new_geometry->min_height = requisition.height;
6341 new_geometry->min_height += extra_height;
6343 else if (!window->allow_shrink)
6345 *new_flags |= GDK_HINT_MIN_SIZE;
6347 new_geometry->min_width = requisition.width;
6348 new_geometry->min_height = requisition.height;
6351 if (*new_flags & GDK_HINT_MAX_SIZE)
6353 if (new_geometry->max_width < 0)
6354 new_geometry->max_width = requisition.width;
6356 new_geometry->max_width += extra_width;
6358 if (new_geometry->max_height < 0)
6359 new_geometry->max_height = requisition.height;
6361 new_geometry->max_height += extra_height;
6363 else if (!window->allow_grow)
6365 *new_flags |= GDK_HINT_MAX_SIZE;
6367 new_geometry->max_width = requisition.width;
6368 new_geometry->max_height = requisition.height;
6371 *new_flags |= GDK_HINT_WIN_GRAVITY;
6372 new_geometry->win_gravity = window->gravity;
6375 /***********************
6376 * Redrawing functions *
6377 ***********************/
6380 gtk_window_paint (GtkWidget *widget,
6383 gtk_paint_flat_box (widget->style, widget->window, GTK_STATE_NORMAL,
6384 GTK_SHADOW_NONE, area, widget, "base", 0, 0, -1, -1);
6388 gtk_window_expose (GtkWidget *widget,
6389 GdkEventExpose *event)
6391 if (!GTK_WIDGET_APP_PAINTABLE (widget))
6392 gtk_window_paint (widget, &event->area);
6394 if (GTK_WIDGET_CLASS (gtk_window_parent_class)->expose_event)
6395 return GTK_WIDGET_CLASS (gtk_window_parent_class)->expose_event (widget, event);
6401 * gtk_window_set_has_frame:
6402 * @window: a #GtkWindow
6403 * @setting: a boolean
6405 * (Note: this is a special-purpose function for the framebuffer port,
6406 * that causes GTK+ to draw its own window border. For most applications,
6407 * you want gtk_window_set_decorated() instead, which tells the window
6408 * manager whether to draw the window border.)
6410 * If this function is called on a window with setting of %TRUE, before
6411 * it is realized or showed, it will have a "frame" window around
6412 * @window->window, accessible in @window->frame. Using the signal
6413 * frame_event you can receive all events targeted at the frame.
6415 * This function is used by the linux-fb port to implement managed
6416 * windows, but it could conceivably be used by X-programs that
6417 * want to do their own window decorations.
6421 gtk_window_set_has_frame (GtkWindow *window,
6424 g_return_if_fail (GTK_IS_WINDOW (window));
6425 g_return_if_fail (!GTK_WIDGET_REALIZED (window));
6427 window->has_frame = setting != FALSE;
6431 * gtk_window_get_has_frame:
6432 * @window: a #GtkWindow
6434 * Accessor for whether the window has a frame window exterior to
6435 * @window->window. Gets the value set by gtk_window_set_has_frame ().
6437 * Return value: %TRUE if a frame has been added to the window
6438 * via gtk_window_set_has_frame().
6441 gtk_window_get_has_frame (GtkWindow *window)
6443 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
6445 return window->has_frame;
6449 * gtk_window_set_frame_dimensions:
6450 * @window: a #GtkWindow that has a frame
6451 * @left: The width of the left border
6452 * @top: The height of the top border
6453 * @right: The width of the right border
6454 * @bottom: The height of the bottom border
6456 * (Note: this is a special-purpose function intended for the framebuffer
6457 * port; see gtk_window_set_has_frame(). It will have no effect on the
6458 * window border drawn by the window manager, which is the normal
6459 * case when using the X Window system.)
6461 * For windows with frames (see gtk_window_set_has_frame()) this function
6462 * can be used to change the size of the frame border.
6465 gtk_window_set_frame_dimensions (GtkWindow *window,
6473 g_return_if_fail (GTK_IS_WINDOW (window));
6475 widget = GTK_WIDGET (window);
6477 if (window->frame_left == left &&
6478 window->frame_top == top &&
6479 window->frame_right == right &&
6480 window->frame_bottom == bottom)
6483 window->frame_left = left;
6484 window->frame_top = top;
6485 window->frame_right = right;
6486 window->frame_bottom = bottom;
6488 if (GTK_WIDGET_REALIZED (widget) && window->frame)
6490 gint width = widget->allocation.width + left + right;
6491 gint height = widget->allocation.height + top + bottom;
6492 gdk_window_resize (window->frame, width, height);
6493 gtk_decorated_window_move_resize_window (window,
6495 widget->allocation.width,
6496 widget->allocation.height);
6501 * gtk_window_present:
6502 * @window: a #GtkWindow
6504 * Presents a window to the user. This may mean raising the window
6505 * in the stacking order, deiconifying it, moving it to the current
6506 * desktop, and/or giving it the keyboard focus, possibly dependent
6507 * on the user's platform, window manager, and preferences.
6509 * If @window is hidden, this function calls gtk_widget_show()
6512 * This function should be used when the user tries to open a window
6513 * that's already open. Say for example the preferences dialog is
6514 * currently open, and the user chooses Preferences from the menu
6515 * a second time; use gtk_window_present() to move the already-open dialog
6516 * where the user can see it.
6518 * If you are calling this function in response to a user interaction,
6519 * it is preferable to use gtk_window_present_with_time().
6523 gtk_window_present (GtkWindow *window)
6525 gtk_window_present_with_time (window, GDK_CURRENT_TIME);
6529 * gtk_window_present_with_time:
6530 * @window: a #GtkWindow
6531 * @timestamp: the timestamp of the user interaction (typically a
6532 * button or key press event) which triggered this call
6534 * Presents a window to the user in response to a user interaction.
6535 * If you need to present a window without a timestamp, use
6536 * gtk_window_present(). See gtk_window_present() for details.
6541 gtk_window_present_with_time (GtkWindow *window,
6546 g_return_if_fail (GTK_IS_WINDOW (window));
6548 widget = GTK_WIDGET (window);
6550 if (GTK_WIDGET_VISIBLE (window))
6552 g_assert (widget->window != NULL);
6554 gdk_window_show (widget->window);
6556 /* Translate a timestamp of GDK_CURRENT_TIME appropriately */
6557 if (timestamp == GDK_CURRENT_TIME)
6559 #ifdef GDK_WINDOWING_X11
6560 GdkDisplay *display;
6562 display = gtk_widget_get_display (GTK_WIDGET (window));
6563 timestamp = gdk_x11_display_get_user_time (display);
6565 timestamp = gtk_get_current_event_time ();
6569 gdk_window_focus (widget->window, timestamp);
6573 gtk_widget_show (widget);
6578 * gtk_window_iconify:
6579 * @window: a #GtkWindow
6581 * Asks to iconify (i.e. minimize) the specified @window. Note that
6582 * you shouldn't assume the window is definitely iconified afterward,
6583 * because other entities (e.g. the user or <link
6584 * linkend="gtk-X11-arch">window manager</link>) could deiconify it
6585 * again, or there may not be a window manager in which case
6586 * iconification isn't possible, etc. But normally the window will end
6587 * up iconified. Just don't write code that crashes if not.
6589 * It's permitted to call this function before showing a window,
6590 * in which case the window will be iconified before it ever appears
6593 * You can track iconification via the "window_state_event" signal
6598 gtk_window_iconify (GtkWindow *window)
6601 GdkWindow *toplevel;
6603 g_return_if_fail (GTK_IS_WINDOW (window));
6605 widget = GTK_WIDGET (window);
6607 window->iconify_initially = TRUE;
6610 toplevel = window->frame;
6612 toplevel = widget->window;
6614 if (toplevel != NULL)
6615 gdk_window_iconify (toplevel);
6619 * gtk_window_deiconify:
6620 * @window: a #GtkWindow
6622 * Asks to deiconify (i.e. unminimize) the specified @window. Note
6623 * that you shouldn't assume the window is definitely deiconified
6624 * afterward, because other entities (e.g. the user or <link
6625 * linkend="gtk-X11-arch">window manager</link>) could iconify it
6626 * again before your code which assumes deiconification gets to run.
6628 * You can track iconification via the "window_state_event" signal
6632 gtk_window_deiconify (GtkWindow *window)
6635 GdkWindow *toplevel;
6637 g_return_if_fail (GTK_IS_WINDOW (window));
6639 widget = GTK_WIDGET (window);
6641 window->iconify_initially = FALSE;
6644 toplevel = window->frame;
6646 toplevel = widget->window;
6648 if (toplevel != NULL)
6649 gdk_window_deiconify (toplevel);
6654 * @window: a #GtkWindow
6656 * Asks to stick @window, which means that it will appear on all user
6657 * desktops. Note that you shouldn't assume the window is definitely
6658 * stuck afterward, because other entities (e.g. the user or <link
6659 * linkend="gtk-X11-arch">window manager</link>) could unstick it
6660 * again, and some window managers do not support sticking
6661 * windows. But normally the window will end up stuck. Just don't
6662 * write code that crashes if not.
6664 * It's permitted to call this function before showing a window.
6666 * You can track stickiness via the "window_state_event" signal
6671 gtk_window_stick (GtkWindow *window)
6674 GdkWindow *toplevel;
6676 g_return_if_fail (GTK_IS_WINDOW (window));
6678 widget = GTK_WIDGET (window);
6680 window->stick_initially = TRUE;
6683 toplevel = window->frame;
6685 toplevel = widget->window;
6687 if (toplevel != NULL)
6688 gdk_window_stick (toplevel);
6692 * gtk_window_unstick:
6693 * @window: a #GtkWindow
6695 * Asks to unstick @window, which means that it will appear on only
6696 * one of the user's desktops. Note that you shouldn't assume the
6697 * window is definitely unstuck afterward, because other entities
6698 * (e.g. the user or <link linkend="gtk-X11-arch">window
6699 * manager</link>) could stick it again. But normally the window will
6700 * end up stuck. Just don't write code that crashes if not.
6702 * You can track stickiness via the "window_state_event" signal
6707 gtk_window_unstick (GtkWindow *window)
6710 GdkWindow *toplevel;
6712 g_return_if_fail (GTK_IS_WINDOW (window));
6714 widget = GTK_WIDGET (window);
6716 window->stick_initially = FALSE;
6719 toplevel = window->frame;
6721 toplevel = widget->window;
6723 if (toplevel != NULL)
6724 gdk_window_unstick (toplevel);
6728 * gtk_window_maximize:
6729 * @window: a #GtkWindow
6731 * Asks to maximize @window, so that it becomes full-screen. Note that
6732 * you shouldn't assume the window is definitely maximized afterward,
6733 * because other entities (e.g. the user or <link
6734 * linkend="gtk-X11-arch">window manager</link>) could unmaximize it
6735 * again, and not all window managers support maximization. But
6736 * normally the window will end up maximized. Just don't write code
6737 * that crashes if not.
6739 * It's permitted to call this function before showing a window,
6740 * in which case the window will be maximized when it appears onscreen
6743 * You can track maximization via the "window_state_event" signal
6748 gtk_window_maximize (GtkWindow *window)
6751 GdkWindow *toplevel;
6753 g_return_if_fail (GTK_IS_WINDOW (window));
6755 widget = GTK_WIDGET (window);
6757 window->maximize_initially = TRUE;
6760 toplevel = window->frame;
6762 toplevel = widget->window;
6764 if (toplevel != NULL)
6765 gdk_window_maximize (toplevel);
6769 * gtk_window_unmaximize:
6770 * @window: a #GtkWindow
6772 * Asks to unmaximize @window. Note that you shouldn't assume the
6773 * window is definitely unmaximized afterward, because other entities
6774 * (e.g. the user or <link linkend="gtk-X11-arch">window
6775 * manager</link>) could maximize it again, and not all window
6776 * managers honor requests to unmaximize. But normally the window will
6777 * end up unmaximized. Just don't write code that crashes if not.
6779 * You can track maximization via the "window_state_event" signal
6784 gtk_window_unmaximize (GtkWindow *window)
6787 GdkWindow *toplevel;
6789 g_return_if_fail (GTK_IS_WINDOW (window));
6791 widget = GTK_WIDGET (window);
6793 window->maximize_initially = FALSE;
6796 toplevel = window->frame;
6798 toplevel = widget->window;
6800 if (toplevel != NULL)
6801 gdk_window_unmaximize (toplevel);
6805 * gtk_window_fullscreen:
6806 * @window: a #GtkWindow
6808 * Asks to place @window in the fullscreen state. Note that you
6809 * shouldn't assume the window is definitely full screen afterward,
6810 * because other entities (e.g. the user or <link
6811 * linkend="gtk-X11-arch">window manager</link>) could unfullscreen it
6812 * again, and not all window managers honor requests to fullscreen
6813 * windows. But normally the window will end up fullscreen. Just
6814 * don't write code that crashes if not.
6816 * You can track the fullscreen state via the "window_state_event" signal
6822 gtk_window_fullscreen (GtkWindow *window)
6825 GdkWindow *toplevel;
6826 GtkWindowPrivate *priv;
6828 g_return_if_fail (GTK_IS_WINDOW (window));
6830 widget = GTK_WIDGET (window);
6831 priv = GTK_WINDOW_GET_PRIVATE (window);
6833 priv->fullscreen_initially = TRUE;
6836 toplevel = window->frame;
6838 toplevel = widget->window;
6840 if (toplevel != NULL)
6841 gdk_window_fullscreen (toplevel);
6845 * gtk_window_unfullscreen:
6846 * @window: a #GtkWindow
6848 * Asks to toggle off the fullscreen state for @window. Note that you
6849 * shouldn't assume the window is definitely not full screen
6850 * afterward, because other entities (e.g. the user or <link
6851 * linkend="gtk-X11-arch">window manager</link>) could fullscreen it
6852 * again, and not all window managers honor requests to unfullscreen
6853 * windows. But normally the window will end up restored to its normal
6854 * state. Just don't write code that crashes if not.
6856 * You can track the fullscreen state via the "window_state_event" signal
6862 gtk_window_unfullscreen (GtkWindow *window)
6865 GdkWindow *toplevel;
6866 GtkWindowPrivate *priv;
6868 g_return_if_fail (GTK_IS_WINDOW (window));
6870 widget = GTK_WIDGET (window);
6871 priv = GTK_WINDOW_GET_PRIVATE (window);
6873 priv->fullscreen_initially = FALSE;
6876 toplevel = window->frame;
6878 toplevel = widget->window;
6880 if (toplevel != NULL)
6881 gdk_window_unfullscreen (toplevel);
6885 * gtk_window_set_keep_above:
6886 * @window: a #GtkWindow
6887 * @setting: whether to keep @window above other windows
6889 * Asks to keep @window above, so that it stays on top. Note that
6890 * you shouldn't assume the window is definitely above afterward,
6891 * because other entities (e.g. the user or <link
6892 * linkend="gtk-X11-arch">window manager</link>) could not keep it above,
6893 * and not all window managers support keeping windows above. But
6894 * normally the window will end kept above. Just don't write code
6895 * that crashes if not.
6897 * It's permitted to call this function before showing a window,
6898 * in which case the window will be kept above when it appears onscreen
6901 * You can track the above state via the "window_state_event" signal
6904 * Note that, according to the <ulink
6905 * url="http://www.freedesktop.org/Standards/wm-spec">Extended Window
6906 * Manager Hints</ulink> specification, the above state is mainly meant
6907 * for user preferences and should not be used by applications e.g. for
6908 * drawing attention to their dialogs.
6913 gtk_window_set_keep_above (GtkWindow *window,
6917 GtkWindowPrivate *priv;
6918 GdkWindow *toplevel;
6920 g_return_if_fail (GTK_IS_WINDOW (window));
6922 widget = GTK_WIDGET (window);
6923 priv = GTK_WINDOW_GET_PRIVATE (window);
6925 priv->above_initially = setting != FALSE;
6927 priv->below_initially = FALSE;
6930 toplevel = window->frame;
6932 toplevel = widget->window;
6934 if (toplevel != NULL)
6935 gdk_window_set_keep_above (toplevel, setting);
6939 * gtk_window_set_keep_below:
6940 * @window: a #GtkWindow
6941 * @setting: whether to keep @window below other windows
6943 * Asks to keep @window below, so that it stays in bottom. Note that
6944 * you shouldn't assume the window is definitely below afterward,
6945 * because other entities (e.g. the user or <link
6946 * linkend="gtk-X11-arch">window manager</link>) could not keep it below,
6947 * and not all window managers support putting windows below. But
6948 * normally the window will be kept below. Just don't write code
6949 * that crashes if not.
6951 * It's permitted to call this function before showing a window,
6952 * in which case the window will be kept below when it appears onscreen
6955 * You can track the below state via the "window_state_event" signal
6958 * Note that, according to the <ulink
6959 * url="http://www.freedesktop.org/Standards/wm-spec">Extended Window
6960 * Manager Hints</ulink> specification, the above state is mainly meant
6961 * for user preferences and should not be used by applications e.g. for
6962 * drawing attention to their dialogs.
6967 gtk_window_set_keep_below (GtkWindow *window,
6971 GtkWindowPrivate *priv;
6972 GdkWindow *toplevel;
6974 g_return_if_fail (GTK_IS_WINDOW (window));
6976 widget = GTK_WIDGET (window);
6977 priv = GTK_WINDOW_GET_PRIVATE (window);
6979 priv->below_initially = setting != FALSE;
6981 priv->above_initially = FALSE;
6984 toplevel = window->frame;
6986 toplevel = widget->window;
6988 if (toplevel != NULL)
6989 gdk_window_set_keep_below (toplevel, setting);
6993 * gtk_window_set_resizable:
6994 * @window: a #GtkWindow
6995 * @resizable: %TRUE if the user can resize this window
6997 * Sets whether the user can resize a window. Windows are user resizable
7001 gtk_window_set_resizable (GtkWindow *window,
7004 g_return_if_fail (GTK_IS_WINDOW (window));
7006 gtk_window_set_policy (window, FALSE, resizable, FALSE);
7010 * gtk_window_get_resizable:
7011 * @window: a #GtkWindow
7013 * Gets the value set by gtk_window_set_resizable().
7015 * Return value: %TRUE if the user can resize the window
7018 gtk_window_get_resizable (GtkWindow *window)
7020 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
7022 /* allow_grow is most likely to indicate the semantic concept we
7023 * mean by "resizable" (and will be a reliable indicator if
7024 * set_policy() hasn't been called)
7026 return window->allow_grow;
7030 * gtk_window_set_gravity:
7031 * @window: a #GtkWindow
7032 * @gravity: window gravity
7034 * Window gravity defines the meaning of coordinates passed to
7035 * gtk_window_move(). See gtk_window_move() and #GdkGravity for
7038 * The default window gravity is #GDK_GRAVITY_NORTH_WEST which will
7039 * typically "do what you mean."
7043 gtk_window_set_gravity (GtkWindow *window,
7046 g_return_if_fail (GTK_IS_WINDOW (window));
7048 if (gravity != window->gravity)
7050 window->gravity = gravity;
7052 /* gtk_window_move_resize() will adapt gravity
7054 gtk_widget_queue_resize_no_redraw (GTK_WIDGET (window));
7056 g_object_notify (G_OBJECT (window), "gravity");
7061 * gtk_window_get_gravity:
7062 * @window: a #GtkWindow
7064 * Gets the value set by gtk_window_set_gravity().
7066 * Return value: window gravity
7069 gtk_window_get_gravity (GtkWindow *window)
7071 g_return_val_if_fail (GTK_IS_WINDOW (window), 0);
7073 return window->gravity;
7077 * gtk_window_begin_resize_drag:
7078 * @window: a #GtkWindow
7079 * @button: mouse button that initiated the drag
7080 * @edge: position of the resize control
7081 * @root_x: X position where the user clicked to initiate the drag, in root window coordinates
7082 * @root_y: Y position where the user clicked to initiate the drag
7083 * @timestamp: timestamp from the click event that initiated the drag
7085 * Starts resizing a window. This function is used if an application
7086 * has window resizing controls. When GDK can support it, the resize
7087 * will be done using the standard mechanism for the <link
7088 * linkend="gtk-X11-arch">window manager</link> or windowing
7089 * system. Otherwise, GDK will try to emulate window resizing,
7090 * potentially not all that well, depending on the windowing system.
7094 gtk_window_begin_resize_drag (GtkWindow *window,
7102 GdkWindow *toplevel;
7104 g_return_if_fail (GTK_IS_WINDOW (window));
7105 g_return_if_fail (GTK_WIDGET_VISIBLE (window));
7107 widget = GTK_WIDGET (window);
7110 toplevel = window->frame;
7112 toplevel = widget->window;
7114 gdk_window_begin_resize_drag (toplevel,
7121 * gtk_window_get_frame_dimensions:
7122 * @window: a #GtkWindow
7123 * @left: location to store the width of the frame at the left, or %NULL
7124 * @top: location to store the height of the frame at the top, or %NULL
7125 * @right: location to store the width of the frame at the returns, or %NULL
7126 * @bottom: location to store the height of the frame at the bottom, or %NULL
7128 * (Note: this is a special-purpose function intended for the
7129 * framebuffer port; see gtk_window_set_has_frame(). It will not
7130 * return the size of the window border drawn by the <link
7131 * linkend="gtk-X11-arch">window manager</link>, which is the normal
7132 * case when using a windowing system. See
7133 * gdk_window_get_frame_extents() to get the standard window border
7136 * Retrieves the dimensions of the frame window for this toplevel.
7137 * See gtk_window_set_has_frame(), gtk_window_set_frame_dimensions().
7140 gtk_window_get_frame_dimensions (GtkWindow *window,
7146 g_return_if_fail (GTK_IS_WINDOW (window));
7149 *left = window->frame_left;
7151 *top = window->frame_top;
7153 *right = window->frame_right;
7155 *bottom = window->frame_bottom;
7159 * gtk_window_begin_move_drag:
7160 * @window: a #GtkWindow
7161 * @button: mouse button that initiated the drag
7162 * @root_x: X position where the user clicked to initiate the drag, in root window coordinates
7163 * @root_y: Y position where the user clicked to initiate the drag
7164 * @timestamp: timestamp from the click event that initiated the drag
7166 * Starts moving a window. This function is used if an application has
7167 * window movement grips. When GDK can support it, the window movement
7168 * will be done using the standard mechanism for the <link
7169 * linkend="gtk-X11-arch">window manager</link> or windowing
7170 * system. Otherwise, GDK will try to emulate window movement,
7171 * potentially not all that well, depending on the windowing system.
7175 gtk_window_begin_move_drag (GtkWindow *window,
7182 GdkWindow *toplevel;
7184 g_return_if_fail (GTK_IS_WINDOW (window));
7185 g_return_if_fail (GTK_WIDGET_VISIBLE (window));
7187 widget = GTK_WIDGET (window);
7190 toplevel = window->frame;
7192 toplevel = widget->window;
7194 gdk_window_begin_move_drag (toplevel,
7201 * gtk_window_set_screen:
7202 * @window: a #GtkWindow.
7203 * @screen: a #GdkScreen.
7205 * Sets the #GdkScreen where the @window is displayed; if
7206 * the window is already mapped, it will be unmapped, and
7207 * then remapped on the new screen.
7212 gtk_window_set_screen (GtkWindow *window,
7216 GdkScreen *previous_screen;
7217 gboolean was_mapped;
7219 g_return_if_fail (GTK_IS_WINDOW (window));
7220 g_return_if_fail (GDK_IS_SCREEN (screen));
7222 if (screen == window->screen)
7225 widget = GTK_WIDGET (window);
7227 previous_screen = window->screen;
7228 was_mapped = GTK_WIDGET_MAPPED (widget);
7231 gtk_widget_unmap (widget);
7232 if (GTK_WIDGET_REALIZED (widget))
7233 gtk_widget_unrealize (widget);
7235 gtk_window_free_key_hash (window);
7236 window->screen = screen;
7237 gtk_widget_reset_rc_styles (widget);
7238 if (screen != previous_screen)
7240 g_signal_handlers_disconnect_by_func (previous_screen,
7241 gtk_window_on_composited_changed, window);
7242 g_signal_connect (screen, "composited_changed",
7243 G_CALLBACK (gtk_window_on_composited_changed), window);
7245 _gtk_widget_propagate_screen_changed (widget, previous_screen);
7246 _gtk_widget_propagate_composited_changed (widget);
7248 g_object_notify (G_OBJECT (window), "screen");
7251 gtk_widget_map (widget);
7255 gtk_window_on_composited_changed (GdkScreen *screen,
7258 gtk_widget_queue_draw (GTK_WIDGET (window));
7260 _gtk_widget_propagate_composited_changed (GTK_WIDGET (window));
7264 gtk_window_check_screen (GtkWindow *window)
7267 return window->screen;
7270 g_warning ("Screen for GtkWindow not set; you must always set\n"
7271 "a screen for a GtkWindow before using the window");
7277 * gtk_window_get_screen:
7278 * @window: a #GtkWindow.
7280 * Returns the #GdkScreen associated with @window.
7282 * Return value: a #GdkScreen.
7287 gtk_window_get_screen (GtkWindow *window)
7289 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
7291 return window->screen;
7295 * gtk_window_is_active:
7296 * @window: a #GtkWindow
7298 * Returns whether the window is part of the current active toplevel.
7299 * (That is, the toplevel window receiving keystrokes.)
7300 * The return value is %TRUE if the window is active toplevel
7301 * itself, but also if it is, say, a #GtkPlug embedded in the active toplevel.
7302 * You might use this function if you wanted to draw a widget
7303 * differently in an active window from a widget in an inactive window.
7304 * See gtk_window_has_toplevel_focus()
7306 * Return value: %TRUE if the window part of the current active window.
7311 gtk_window_is_active (GtkWindow *window)
7313 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
7315 return window->is_active;
7319 * gtk_window_has_toplevel_focus:
7320 * @window: a #GtkWindow
7322 * Returns whether the input focus is within this GtkWindow.
7323 * For real toplevel windows, this is identical to gtk_window_is_active(),
7324 * but for embedded windows, like #GtkPlug, the results will differ.
7326 * Return value: %TRUE if the input focus is within this GtkWindow
7331 gtk_window_has_toplevel_focus (GtkWindow *window)
7333 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
7335 return window->has_toplevel_focus;
7339 gtk_window_group_class_init (GtkWindowGroupClass *klass)
7344 gtk_window_group_get_type (void)
7346 static GType window_group_type = 0;
7348 if (!window_group_type)
7350 const GTypeInfo window_group_info =
7352 sizeof (GtkWindowGroupClass),
7353 NULL, /* base_init */
7354 NULL, /* base_finalize */
7355 (GClassInitFunc) gtk_window_group_class_init,
7356 NULL, /* class_finalize */
7357 NULL, /* class_data */
7358 sizeof (GtkWindowGroup),
7359 0, /* n_preallocs */
7360 (GInstanceInitFunc) NULL,
7363 window_group_type = g_type_register_static (G_TYPE_OBJECT, I_("GtkWindowGroup"),
7364 &window_group_info, 0);
7367 return window_group_type;
7371 * gtk_window_group_new:
7373 * Creates a new #GtkWindowGroup object. Grabs added with
7374 * gtk_grab_add() only affect windows within the same #GtkWindowGroup.
7376 * Return value: a new #GtkWindowGroup.
7379 gtk_window_group_new (void)
7381 return g_object_new (GTK_TYPE_WINDOW_GROUP, NULL);
7385 window_group_cleanup_grabs (GtkWindowGroup *group,
7389 GSList *to_remove = NULL;
7391 tmp_list = group->grabs;
7394 if (gtk_widget_get_toplevel (tmp_list->data) == (GtkWidget*) window)
7395 to_remove = g_slist_prepend (to_remove, g_object_ref (tmp_list->data));
7396 tmp_list = tmp_list->next;
7401 gtk_grab_remove (to_remove->data);
7402 g_object_unref (to_remove->data);
7403 to_remove = g_slist_delete_link (to_remove, to_remove);
7408 * gtk_window_group_add_window:
7409 * @window_group: a #GtkWindowGroup
7410 * @window: the #GtkWindow to add
7412 * Adds a window to a #GtkWindowGroup.
7415 gtk_window_group_add_window (GtkWindowGroup *window_group,
7418 g_return_if_fail (GTK_IS_WINDOW_GROUP (window_group));
7419 g_return_if_fail (GTK_IS_WINDOW (window));
7421 if (window->group != window_group)
7423 g_object_ref (window);
7424 g_object_ref (window_group);
7427 gtk_window_group_remove_window (window->group, window);
7429 window_group_cleanup_grabs (gtk_window_get_group (NULL), window);
7431 window->group = window_group;
7433 g_object_unref (window);
7438 * gtk_window_group_remove_window:
7439 * @window_group: a #GtkWindowGroup
7440 * @window: the #GtkWindow to remove
7442 * Removes a window from a #GtkWindowGroup.
7445 gtk_window_group_remove_window (GtkWindowGroup *window_group,
7448 g_return_if_fail (GTK_IS_WINDOW_GROUP (window_group));
7449 g_return_if_fail (GTK_IS_WINDOW (window));
7450 g_return_if_fail (window->group == window_group);
7452 g_object_ref (window);
7454 window_group_cleanup_grabs (window_group, window);
7455 window->group = NULL;
7457 g_object_unref (window_group);
7458 g_object_unref (window);
7462 * gtk_window_group_list_windows:
7463 * @window_group: a #GtkWindowGroup
7465 * Returns a list of the #GtkWindows that belong to @window_group.
7467 * Returns: A newly-allocated list of windows inside the group.
7472 gtk_window_group_list_windows (GtkWindowGroup *window_group)
7474 GList *toplevels, *toplevel, *group_windows;
7476 g_return_val_if_fail (GTK_IS_WINDOW_GROUP (window_group), NULL);
7478 group_windows = NULL;
7479 toplevels = gtk_window_list_toplevels ();
7481 for (toplevel = toplevels; toplevel; toplevel = toplevel->next)
7483 GtkWindow *window = toplevel->data;
7485 if (window_group == window->group)
7486 group_windows = g_list_prepend (group_windows, window);
7489 return g_list_reverse (group_windows);
7493 * gtk_window_get_group:
7494 * @window: a #GtkWindow, or %NULL
7496 * Returns the group for @window or the default group, if
7497 * @window is %NULL or if @window does not have an explicit
7500 * Returns: the #GtkWindowGroup for a window or the default group
7505 gtk_window_get_group (GtkWindow *window)
7507 if (window && window->group)
7508 return window->group;
7511 static GtkWindowGroup *default_group = NULL;
7514 default_group = gtk_window_group_new ();
7516 return default_group;
7520 /* Return the current grab widget of the given group
7523 _gtk_window_group_get_current_grab (GtkWindowGroup *window_group)
7525 if (window_group->grabs)
7526 return GTK_WIDGET (window_group->grabs->data);
7531 Derived from XParseGeometry() in XFree86
7533 Copyright 1985, 1986, 1987,1998 The Open Group
7535 All Rights Reserved.
7537 The above copyright notice and this permission notice shall be included
7538 in all copies or substantial portions of the Software.
7540 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
7541 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
7542 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
7543 IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
7544 OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
7545 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
7546 OTHER DEALINGS IN THE SOFTWARE.
7548 Except as contained in this notice, the name of The Open Group shall
7549 not be used in advertising or otherwise to promote the sale, use or
7550 other dealings in this Software without prior written authorization
7551 from The Open Group.
7556 * XParseGeometry parses strings of the form
7557 * "=<width>x<height>{+-}<xoffset>{+-}<yoffset>", where
7558 * width, height, xoffset, and yoffset are unsigned integers.
7559 * Example: "=80x24+300-49"
7560 * The equal sign is optional.
7561 * It returns a bitmask that indicates which of the four values
7562 * were actually found in the string. For each value found,
7563 * the corresponding argument is updated; for each value
7564 * not found, the corresponding argument is left unchanged.
7567 /* The following code is from Xlib, and is minimally modified, so we
7568 * can track any upstream changes if required. Don't change this
7569 * code. Or if you do, put in a huge comment marking which thing
7574 read_int (gchar *string,
7582 else if (*string == '-')
7588 for (; (*string >= '0') && (*string <= '9'); string++)
7590 result = (result * 10) + (*string - '0');
7602 * Bitmask returned by XParseGeometry(). Each bit tells if the corresponding
7603 * value (x, y, width, height) was found in the parsed string.
7605 #define NoValue 0x0000
7606 #define XValue 0x0001
7607 #define YValue 0x0002
7608 #define WidthValue 0x0004
7609 #define HeightValue 0x0008
7610 #define AllValues 0x000F
7611 #define XNegative 0x0010
7612 #define YNegative 0x0020
7614 /* Try not to reformat/modify, so we can compare/sync with X sources */
7616 gtk_XParseGeometry (const char *string,
7619 unsigned int *width,
7620 unsigned int *height)
7624 unsigned int tempWidth, tempHeight;
7626 char *nextCharacter;
7628 /* These initializations are just to silence gcc */
7634 if ( (string == NULL) || (*string == '\0')) return(mask);
7636 string++; /* ignore possible '=' at beg of geometry spec */
7638 strind = (char *)string;
7639 if (*strind != '+' && *strind != '-' && *strind != 'x') {
7640 tempWidth = read_int(strind, &nextCharacter);
7641 if (strind == nextCharacter)
7643 strind = nextCharacter;
7647 if (*strind == 'x' || *strind == 'X') {
7649 tempHeight = read_int(strind, &nextCharacter);
7650 if (strind == nextCharacter)
7652 strind = nextCharacter;
7653 mask |= HeightValue;
7656 if ((*strind == '+') || (*strind == '-')) {
7657 if (*strind == '-') {
7659 tempX = -read_int(strind, &nextCharacter);
7660 if (strind == nextCharacter)
7662 strind = nextCharacter;
7668 tempX = read_int(strind, &nextCharacter);
7669 if (strind == nextCharacter)
7671 strind = nextCharacter;
7674 if ((*strind == '+') || (*strind == '-')) {
7675 if (*strind == '-') {
7677 tempY = -read_int(strind, &nextCharacter);
7678 if (strind == nextCharacter)
7680 strind = nextCharacter;
7687 tempY = read_int(strind, &nextCharacter);
7688 if (strind == nextCharacter)
7690 strind = nextCharacter;
7696 /* If strind isn't at the end of the string the it's an invalid
7697 geometry specification. */
7699 if (*strind != '\0') return (0);
7705 if (mask & WidthValue)
7707 if (mask & HeightValue)
7708 *height = tempHeight;
7713 * gtk_window_parse_geometry:
7714 * @window: a #GtkWindow
7715 * @geometry: geometry string
7717 * Parses a standard X Window System geometry string - see the
7718 * manual page for X (type 'man X') for details on this.
7719 * gtk_window_parse_geometry() does work on all GTK+ ports
7720 * including Win32 but is primarily intended for an X environment.
7722 * If either a size or a position can be extracted from the
7723 * geometry string, gtk_window_parse_geometry() returns %TRUE
7724 * and calls gtk_window_set_default_size() and/or gtk_window_move()
7725 * to resize/move the window.
7727 * If gtk_window_parse_geometry() returns %TRUE, it will also
7728 * set the #GDK_HINT_USER_POS and/or #GDK_HINT_USER_SIZE hints
7729 * indicating to the window manager that the size/position of
7730 * the window was user-specified. This causes most window
7731 * managers to honor the geometry.
7733 * Note that for gtk_window_parse_geometry() to work as expected, it has
7734 * to be called when the window has its "final" size, i.e. after calling
7735 * gtk_widget_show_all() on the contents and gtk_window_set_geometry_hints()
7738 * #include <gtk/gtk.h>
7741 * fill_with_content (GtkWidget *vbox)
7743 * /* fill with content... */
7747 * main (int argc, char *argv[])
7749 * GtkWidget *window, *vbox;
7750 * GdkGeometry size_hints = {
7751 * 100, 50, 0, 0, 100, 50, 10, 10, 0.0, 0.0, GDK_GRAVITY_NORTH_WEST
7754 * gtk_init (&argc, &argv);
7756 * window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
7757 * vbox = gtk_vbox_new (FALSE, 0);
7759 * gtk_container_add (GTK_CONTAINER (window), vbox);
7760 * fill_with_content (vbox);
7761 * gtk_widget_show_all (vbox);
7763 * gtk_window_set_geometry_hints (GTK_WINDOW (window),
7766 * GDK_HINT_MIN_SIZE |
7767 * GDK_HINT_BASE_SIZE |
7768 * GDK_HINT_RESIZE_INC);
7772 * if (!gtk_window_parse_geometry (GTK_WINDOW (window), argv[1]))
7773 * fprintf (stderr, "Failed to parse '%s'\n", argv[1]);
7776 * gtk_widget_show_all (window);
7783 * Return value: %TRUE if string was parsed successfully
7786 gtk_window_parse_geometry (GtkWindow *window,
7787 const gchar *geometry)
7789 gint result, x = 0, y = 0;
7792 gboolean size_set, pos_set;
7795 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
7796 g_return_val_if_fail (geometry != NULL, FALSE);
7798 screen = gtk_window_check_screen (window);
7800 result = gtk_XParseGeometry (geometry, &x, &y, &w, &h);
7803 if ((result & WidthValue) || (result & HeightValue))
7805 gtk_window_set_default_size_internal (window,
7806 TRUE, result & WidthValue ? w : -1,
7807 TRUE, result & HeightValue ? h : -1,
7812 gtk_window_get_size (window, (gint *)&w, (gint *)&h);
7814 grav = GDK_GRAVITY_NORTH_WEST;
7816 if ((result & XNegative) && (result & YNegative))
7817 grav = GDK_GRAVITY_SOUTH_EAST;
7818 else if (result & XNegative)
7819 grav = GDK_GRAVITY_NORTH_EAST;
7820 else if (result & YNegative)
7821 grav = GDK_GRAVITY_SOUTH_WEST;
7823 if ((result & XValue) == 0)
7826 if ((result & YValue) == 0)
7829 if (grav == GDK_GRAVITY_SOUTH_WEST ||
7830 grav == GDK_GRAVITY_SOUTH_EAST)
7831 y = gdk_screen_get_height (screen) - h + y;
7833 if (grav == GDK_GRAVITY_SOUTH_EAST ||
7834 grav == GDK_GRAVITY_NORTH_EAST)
7835 x = gdk_screen_get_width (screen) - w + x;
7837 /* we don't let you put a window offscreen; maybe some people would
7838 * prefer to be able to, but it's kind of a bogus thing to do.
7847 if ((result & XValue) || (result & YValue))
7849 gtk_window_set_gravity (window, grav);
7850 gtk_window_move (window, x, y);
7854 if (size_set || pos_set)
7856 /* Set USSize, USPosition hints */
7857 GtkWindowGeometryInfo *info;
7859 info = gtk_window_get_geometry_info (window, TRUE);
7862 info->mask |= GDK_HINT_USER_POS;
7864 info->mask |= GDK_HINT_USER_SIZE;
7871 gtk_window_mnemonic_hash_foreach (guint keyval,
7877 GtkWindowKeysForeachFunc func;
7881 (*info->func) (info->window, keyval, info->window->mnemonic_modifier, TRUE, info->func_data);
7885 _gtk_window_keys_foreach (GtkWindow *window,
7886 GtkWindowKeysForeachFunc func,
7890 GtkMnemonicHash *mnemonic_hash;
7894 GtkWindowKeysForeachFunc func;
7898 info.window = window;
7900 info.func_data = func_data;
7902 mnemonic_hash = gtk_window_get_mnemonic_hash (window, FALSE);
7904 _gtk_mnemonic_hash_foreach (mnemonic_hash,
7905 gtk_window_mnemonic_hash_foreach, &info);
7907 groups = gtk_accel_groups_from_object (G_OBJECT (window));
7910 GtkAccelGroup *group = groups->data;
7913 for (i = 0; i < group->n_accels; i++)
7915 GtkAccelKey *key = &group->priv_accels[i].key;
7918 (*func) (window, key->accel_key, key->accel_mods, FALSE, func_data);
7921 groups = groups->next;
7926 gtk_window_keys_changed (GtkWindow *window)
7928 gtk_window_free_key_hash (window);
7929 gtk_window_get_key_hash (window);
7932 typedef struct _GtkWindowKeyEntry GtkWindowKeyEntry;
7934 struct _GtkWindowKeyEntry
7938 guint is_mnemonic : 1;
7942 window_key_entry_destroy (gpointer data)
7944 g_slice_free (GtkWindowKeyEntry, data);
7948 add_to_key_hash (GtkWindow *window,
7950 GdkModifierType modifiers,
7951 gboolean is_mnemonic,
7954 GtkKeyHash *key_hash = data;
7956 GtkWindowKeyEntry *entry = g_slice_new (GtkWindowKeyEntry);
7958 entry->keyval = keyval;
7959 entry->modifiers = modifiers;
7960 entry->is_mnemonic = is_mnemonic;
7962 /* GtkAccelGroup stores lowercased accelerators. To deal
7963 * with this, if <Shift> was specified, uppercase.
7965 if (modifiers & GDK_SHIFT_MASK)
7967 if (keyval == GDK_Tab)
7968 keyval = GDK_ISO_Left_Tab;
7970 keyval = gdk_keyval_to_upper (keyval);
7973 _gtk_key_hash_add_entry (key_hash, keyval, entry->modifiers, entry);
7977 gtk_window_get_key_hash (GtkWindow *window)
7979 GdkScreen *screen = gtk_window_check_screen (window);
7980 GtkKeyHash *key_hash = g_object_get_qdata (G_OBJECT (window), quark_gtk_window_key_hash);
7985 key_hash = _gtk_key_hash_new (gdk_keymap_get_for_display (gdk_screen_get_display (screen)),
7986 (GDestroyNotify)window_key_entry_destroy);
7987 _gtk_window_keys_foreach (window, add_to_key_hash, key_hash);
7988 g_object_set_qdata (G_OBJECT (window), quark_gtk_window_key_hash, key_hash);
7994 gtk_window_free_key_hash (GtkWindow *window)
7996 GtkKeyHash *key_hash = g_object_get_qdata (G_OBJECT (window), quark_gtk_window_key_hash);
7999 _gtk_key_hash_free (key_hash);
8000 g_object_set_qdata (G_OBJECT (window), quark_gtk_window_key_hash, NULL);
8005 * gtk_window_activate_key:
8006 * @window: a #GtkWindow
8007 * @event: a #GdkEventKey
8009 * Activates mnemonics and accelerators for this #GtkWindow. This is normally
8010 * called by the default ::key_press_event handler for toplevel windows,
8011 * however in some cases it may be useful to call this directly when
8012 * overriding the standard key handling for a toplevel window.
8014 * Return value: %TRUE if a mnemonic or accelerator was found and activated.
8017 gtk_window_activate_key (GtkWindow *window,
8020 GtkKeyHash *key_hash;
8021 GtkWindowKeyEntry *found_entry = NULL;
8023 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
8024 g_return_val_if_fail (event != NULL, FALSE);
8026 key_hash = gtk_window_get_key_hash (window);
8030 GSList *entries = _gtk_key_hash_lookup (key_hash,
8031 event->hardware_keycode,
8033 gtk_accelerator_get_default_mod_mask (),
8037 for (tmp_list = entries; tmp_list; tmp_list = tmp_list->next)
8039 GtkWindowKeyEntry *entry = tmp_list->data;
8040 if (entry->is_mnemonic)
8042 found_entry = entry;
8047 if (!found_entry && entries)
8048 found_entry = entries->data;
8050 g_slist_free (entries);
8055 gboolean enable_mnemonics;
8056 gboolean enable_accels;
8058 g_object_get (gtk_widget_get_settings (GTK_WIDGET (window)),
8059 "gtk-enable-mnemonics", &enable_mnemonics,
8060 "gtk-enable-accels", &enable_accels,
8063 if (found_entry->is_mnemonic)
8065 if (enable_mnemonics)
8066 return gtk_window_mnemonic_activate (window, found_entry->keyval,
8067 found_entry->modifiers);
8072 return gtk_accel_groups_activate (G_OBJECT (window), found_entry->keyval,
8073 found_entry->modifiers);
8081 window_update_has_focus (GtkWindow *window)
8083 GtkWidget *widget = GTK_WIDGET (window);
8084 gboolean has_focus = window->has_toplevel_focus && window->is_active;
8086 if (has_focus != window->has_focus)
8088 window->has_focus = has_focus;
8092 if (window->focus_widget &&
8093 window->focus_widget != widget &&
8094 !GTK_WIDGET_HAS_FOCUS (window->focus_widget))
8095 do_focus_change (window->focus_widget, TRUE);
8099 if (window->focus_widget &&
8100 window->focus_widget != widget &&
8101 GTK_WIDGET_HAS_FOCUS (window->focus_widget))
8102 do_focus_change (window->focus_widget, FALSE);
8108 * _gtk_window_set_is_active:
8109 * @window: a #GtkWindow
8110 * @is_active: %TRUE if the window is in the currently active toplevel
8112 * Internal function that sets whether the #GtkWindow is part
8113 * of the currently active toplevel window (taking into account inter-process
8117 _gtk_window_set_is_active (GtkWindow *window,
8120 g_return_if_fail (GTK_IS_WINDOW (window));
8122 is_active = is_active != FALSE;
8124 if (is_active != window->is_active)
8126 window->is_active = is_active;
8127 window_update_has_focus (window);
8129 g_object_notify (G_OBJECT (window), "is-active");
8134 * _gtk_window_set_has_toplevel_focus:
8135 * @window: a #GtkWindow
8136 * @has_toplevel_focus: %TRUE if the in
8138 * Internal function that sets whether the keyboard focus for the
8139 * toplevel window (taking into account inter-process embedding.)
8142 _gtk_window_set_has_toplevel_focus (GtkWindow *window,
8143 gboolean has_toplevel_focus)
8145 g_return_if_fail (GTK_IS_WINDOW (window));
8147 has_toplevel_focus = has_toplevel_focus != FALSE;
8149 if (has_toplevel_focus != window->has_toplevel_focus)
8151 window->has_toplevel_focus = has_toplevel_focus;
8152 window_update_has_focus (window);
8154 g_object_notify (G_OBJECT (window), "has-toplevel-focus");
8159 * gtk_window_set_auto_startup_notification:
8160 * @setting: %TRUE to automatically do startup notification
8162 * By default, after showing the first #GtkWindow, GTK+ calls
8163 * gdk_notify_startup_complete(). Call this function to disable
8164 * the automatic startup notification. You might do this if your
8165 * first window is a splash screen, and you want to delay notification
8166 * until after your real main window has been shown, for example.
8168 * In that example, you would disable startup notification
8169 * temporarily, show your splash screen, then re-enable it so that
8170 * showing the main window would automatically result in notification.
8175 gtk_window_set_auto_startup_notification (gboolean setting)
8177 disable_startup_notification = !setting;
8182 #undef gtk_window_set_icon_from_file
8185 gtk_window_set_icon_from_file (GtkWindow *window,
8186 const gchar *filename,
8189 gchar *utf8_filename = g_locale_to_utf8 (filename, -1, NULL, NULL, err);
8192 if (utf8_filename == NULL)
8195 retval = gtk_window_set_icon_from_file_utf8 (window, utf8_filename, err);
8197 g_free (utf8_filename);
8202 #undef gtk_window_set_default_icon_from_file
8205 gtk_window_set_default_icon_from_file (const gchar *filename,
8208 gchar *utf8_filename = g_locale_to_utf8 (filename, -1, NULL, NULL, err);
8211 if (utf8_filename == NULL)
8214 retval = gtk_window_set_default_icon_from_file_utf8 (utf8_filename, err);
8216 g_free (utf8_filename);
8223 #define __GTK_WINDOW_C__
8224 #include "gtkaliasdef.c"