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/.
29 #include "gtkwindow.h"
36 #include "gtkprivate.h"
37 #include "gtkwindowprivate.h"
38 #include "gtkaccelgroupprivate.h"
39 #include "gtkbindings.h"
40 #include "gtkkeyhash.h"
42 #include "gtkmnemonichash.h"
43 #include "gtkmenubar.h"
44 #include "gtkiconfactory.h"
45 #include "gtkicontheme.h"
46 #include "gtkmarshalers.h"
48 #include "gtkbuildable.h"
49 #include "gtkwidgetprivate.h"
50 #include "gtkcontainerprivate.h"
52 #include "gtktypebuiltins.h"
53 #include "a11y/gtkwindowaccessible.h"
55 #include "deprecated/gtkstyle.h"
57 #ifdef GDK_WINDOWING_X11
64 * @short_description: Toplevel which can contain other widgets
66 * A GtkWindow is a toplevel window which can contain other widgets.
67 * Windows normally have decorations that are under the control
68 * of the windowing system and allow the user to manipulate the window
69 * (resize it, move it, close it,...).
71 * GTK+ also allows windows to have a resize grip (a small area in the lower
72 * right or left corner) which can be clicked to reszie the window. To
73 * control whether a window has a resize grip, use
74 * gtk_window_set_has_resize_grip().
76 * <refsect2 id="GtkWindow-BUILDER-UI">
77 * <title>GtkWindow as GtkBuildable</title>
79 * The GtkWindow implementation of the GtkBuildable interface supports a
80 * custom <tag class="starttag">accel-groups</tag> element, which supports
81 * any number of <tag class="starttag">group</tag> elements representing the
82 * #GtkAccelGroup objects you want to add to your window (synonymous with
83 * gtk_window_add_accel_group().
86 * <title>A UI definition fragment with accel groups</title>
87 * <programlisting><![CDATA[
88 * <object class="GtkWindow">
90 * <group name="accelgroup1"/>
96 * <object class="GtkAccelGroup" id="accelgroup1"/>
97 * ]]></programlisting>
102 typedef struct _GtkDeviceGrabInfo GtkDeviceGrabInfo;
104 struct _GtkWindowPrivate
106 GtkMnemonicHash *mnemonic_hash;
108 GtkWidget *attach_widget;
109 GtkWidget *default_widget;
110 GtkWidget *focus_widget;
111 GtkWindow *transient_parent;
112 GtkWindowGeometryInfo *geometry_info;
113 GtkWindowGroup *group;
115 GtkApplication *application;
117 GdkModifierType mnemonic_modifier;
118 GdkWindowTypeHint gdk_type_hint;
122 GdkWindow *grip_window;
126 gchar *wmclass_class;
130 guint keys_changed_handler;
132 guint32 initial_timestamp;
134 guint16 configure_request_count;
136 /* The following flags are initially TRUE (before a window is mapped).
137 * They cause us to compute a configure request that involves
138 * default-only parameters. Once mapped, we set them to FALSE.
139 * Then we set them to TRUE again on unmap (for position)
140 * and on unrealize (for size).
142 guint need_default_position : 1;
143 guint need_default_size : 1;
145 guint above_initially : 1;
146 guint accept_focus : 1;
147 guint below_initially : 1;
148 guint builder_visible : 1;
149 guint configure_notify_received : 1;
152 guint destroy_with_parent : 1;
153 guint focus_on_map : 1;
154 guint fullscreen_initially : 1;
156 guint has_user_ref_count : 1;
157 guint has_toplevel_focus : 1;
158 guint hide_titlebar_when_maximized : 1;
159 guint iconify_initially : 1; /* gtk_window_iconify() called before realization */
161 guint maximize_initially : 1;
162 guint mnemonics_visible : 1;
163 guint mnemonics_visible_set : 1;
164 guint focus_visible : 1;
166 guint opacity_set : 1;
168 guint reset_type_hint : 1;
170 guint skips_pager : 1;
171 guint skips_taskbar : 1;
172 guint stick_initially : 1;
173 guint transient_parent_group : 1;
174 guint type : 4; /* GtkWindowType */
175 guint type_hint : 3; /* GdkWindowTypeHint if the hint is
176 * one of the original eight. If not,
178 * GDK_WINDOW_TYPE_HINT_NORMAL
181 guint has_resize_grip : 1;
182 guint resize_grip_visible : 1; /* don't use, just for "resize-
183 * grip-visible" notification
185 guint gravity : 5; /* GdkGravity */
212 PROP_DESTROY_WITH_PARENT,
213 PROP_HIDE_TITLEBAR_WHEN_MAXIMIZED,
218 PROP_SKIP_TASKBAR_HINT,
219 PROP_SKIP_PAGER_HINT,
229 PROP_HAS_RESIZE_GRIP,
230 PROP_RESIZE_GRIP_VISIBLE,
232 /* Readonly properties */
234 PROP_HAS_TOPLEVEL_FOCUS,
236 /* Writeonly properties */
239 PROP_MNEMONICS_VISIBLE,
250 guint using_default_icon : 1;
251 guint using_parent_icon : 1;
252 guint using_themed_icon : 1;
256 GdkGeometry geometry; /* Last set of geometry hints we set */
257 GdkWindowHints flags;
258 GdkRectangle configure_request;
259 } GtkWindowLastGeometryInfo;
261 struct _GtkWindowGeometryInfo
263 /* Properties that the app has set on the window
265 GdkGeometry geometry; /* Geometry hints */
267 GtkWidget *widget; /* subwidget to which hints apply */
268 /* from last gtk_window_resize () - if > 0, indicates that
269 * we should resize to this size.
274 /* From last gtk_window_move () prior to mapping -
275 * only used if initial_pos_set
280 /* Default size - used only the FIRST time we map a window,
285 /* whether to use initial_x, initial_y */
286 guint initial_pos_set : 1;
287 /* CENTER_ALWAYS or other position constraint changed since
288 * we sent the last configure request.
290 guint position_constraints_changed : 1;
292 /* if true, default_width, height should be multiplied by the
293 * increments and affect the geometry widget only
295 guint default_is_geometry : 1;
297 /* if true, resize_width, height should be multiplied by the
298 * increments and affect the geometry widget only
300 guint resize_is_geometry : 1;
302 GtkWindowLastGeometryInfo last;
306 struct _GtkDeviceGrabInfo
310 guint block_others : 1;
313 struct _GtkWindowGroupPrivate
316 GSList *device_grabs;
319 static void gtk_window_dispose (GObject *object);
320 static void gtk_window_finalize (GObject *object);
321 static void gtk_window_destroy (GtkWidget *widget);
322 static void gtk_window_show (GtkWidget *widget);
323 static void gtk_window_hide (GtkWidget *widget);
324 static void gtk_window_map (GtkWidget *widget);
325 static void gtk_window_unmap (GtkWidget *widget);
326 static void gtk_window_realize (GtkWidget *widget);
327 static void gtk_window_unrealize (GtkWidget *widget);
328 static void gtk_window_size_allocate (GtkWidget *widget,
329 GtkAllocation *allocation);
330 static gboolean gtk_window_map_event (GtkWidget *widget,
332 static gint gtk_window_configure_event (GtkWidget *widget,
333 GdkEventConfigure *event);
334 static gint gtk_window_key_press_event (GtkWidget *widget,
336 static gint gtk_window_key_release_event (GtkWidget *widget,
338 static gint gtk_window_button_press_event (GtkWidget *widget,
339 GdkEventButton *event);
340 static gint gtk_window_enter_notify_event (GtkWidget *widget,
341 GdkEventCrossing *event);
342 static gint gtk_window_leave_notify_event (GtkWidget *widget,
343 GdkEventCrossing *event);
344 static gint gtk_window_focus_in_event (GtkWidget *widget,
345 GdkEventFocus *event);
346 static gint gtk_window_focus_out_event (GtkWidget *widget,
347 GdkEventFocus *event);
348 static void gtk_window_style_updated (GtkWidget *widget);
349 static gboolean gtk_window_state_event (GtkWidget *widget,
350 GdkEventWindowState *event);
351 static void gtk_window_check_resize (GtkContainer *container);
352 static gint gtk_window_focus (GtkWidget *widget,
353 GtkDirectionType direction);
354 static void gtk_window_move_focus (GtkWidget *widget,
355 GtkDirectionType dir);
356 static void gtk_window_real_set_focus (GtkWindow *window,
358 static void gtk_window_direction_changed (GtkWidget *widget,
359 GtkTextDirection prev_dir);
360 static void gtk_window_state_changed (GtkWidget *widget,
361 GtkStateType previous_state);
363 static void gtk_window_real_activate_default (GtkWindow *window);
364 static void gtk_window_real_activate_focus (GtkWindow *window);
365 static void gtk_window_keys_changed (GtkWindow *window);
366 static gint gtk_window_draw (GtkWidget *widget,
368 static void gtk_window_unset_transient_for (GtkWindow *window);
369 static void gtk_window_transient_parent_realized (GtkWidget *parent,
371 static void gtk_window_transient_parent_unrealized (GtkWidget *parent,
374 static GdkScreen *gtk_window_check_screen (GtkWindow *window);
376 static GtkWindowGeometryInfo* gtk_window_get_geometry_info (GtkWindow *window,
379 static void gtk_window_move_resize (GtkWindow *window);
380 static gboolean gtk_window_compare_hints (GdkGeometry *geometry_a,
382 GdkGeometry *geometry_b,
384 static void gtk_window_constrain_size (GtkWindow *window,
385 GdkGeometry *geometry,
391 static void gtk_window_constrain_position (GtkWindow *window,
396 static void gtk_window_compute_hints (GtkWindow *window,
397 GdkGeometry *new_geometry,
399 static void gtk_window_compute_configure_request (GtkWindow *window,
400 GdkRectangle *request,
401 GdkGeometry *geometry,
404 static void gtk_window_set_default_size_internal (GtkWindow *window,
405 gboolean change_width,
407 gboolean change_height,
409 gboolean is_geometry);
411 static void update_themed_icon (GtkIconTheme *theme,
413 static GList *icon_list_from_theme (GtkWidget *widget,
415 static void gtk_window_realize_icon (GtkWindow *window);
416 static void gtk_window_unrealize_icon (GtkWindow *window);
417 static void resize_grip_create_window (GtkWindow *window);
418 static void resize_grip_destroy_window (GtkWindow *window);
419 static void update_grip_visibility (GtkWindow *window);
421 static void gtk_window_notify_keys_changed (GtkWindow *window);
422 static GtkKeyHash *gtk_window_get_key_hash (GtkWindow *window);
423 static void gtk_window_free_key_hash (GtkWindow *window);
424 static void gtk_window_on_composited_changed (GdkScreen *screen,
426 static void gtk_window_on_theme_variant_changed (GtkSettings *settings,
429 static void gtk_window_set_theme_variant (GtkWindow *window);
431 static GSList *toplevel_list = NULL;
432 static guint window_signals[LAST_SIGNAL] = { 0 };
433 static GList *default_icon_list = NULL;
434 static gchar *default_icon_name = NULL;
435 static guint default_icon_serial = 0;
436 static gboolean disable_startup_notification = FALSE;
437 static gboolean sent_startup_notification = FALSE;
439 static GQuark quark_gtk_embedded = 0;
440 static GQuark quark_gtk_window_key_hash = 0;
441 static GQuark quark_gtk_window_icon_info = 0;
442 static GQuark quark_gtk_buildable_accels = 0;
444 static GtkBuildableIface *parent_buildable_iface;
446 static void gtk_window_set_property (GObject *object,
450 static void gtk_window_get_property (GObject *object,
456 static void gtk_window_buildable_interface_init (GtkBuildableIface *iface);
457 static void gtk_window_buildable_set_buildable_property (GtkBuildable *buildable,
460 const GValue *value);
461 static void gtk_window_buildable_parser_finished (GtkBuildable *buildable,
462 GtkBuilder *builder);
463 static gboolean gtk_window_buildable_custom_tag_start (GtkBuildable *buildable,
466 const gchar *tagname,
467 GMarkupParser *parser,
469 static void gtk_window_buildable_custom_finished (GtkBuildable *buildable,
472 const gchar *tagname,
476 static void gtk_window_get_preferred_width (GtkWidget *widget,
479 static void gtk_window_get_preferred_height (GtkWidget *widget,
483 static void ensure_state_flag_backdrop (GtkWidget *widget);
485 G_DEFINE_TYPE_WITH_CODE (GtkWindow, gtk_window, GTK_TYPE_BIN,
486 G_IMPLEMENT_INTERFACE (GTK_TYPE_BUILDABLE,
487 gtk_window_buildable_interface_init))
490 add_tab_bindings (GtkBindingSet *binding_set,
491 GdkModifierType modifiers,
492 GtkDirectionType direction)
494 gtk_binding_entry_add_signal (binding_set, GDK_KEY_Tab, modifiers,
496 GTK_TYPE_DIRECTION_TYPE, direction);
497 gtk_binding_entry_add_signal (binding_set, GDK_KEY_KP_Tab, modifiers,
499 GTK_TYPE_DIRECTION_TYPE, direction);
503 add_arrow_bindings (GtkBindingSet *binding_set,
505 GtkDirectionType direction)
507 guint keypad_keysym = keysym - GDK_KEY_Left + GDK_KEY_KP_Left;
509 gtk_binding_entry_add_signal (binding_set, keysym, 0,
511 GTK_TYPE_DIRECTION_TYPE, direction);
512 gtk_binding_entry_add_signal (binding_set, keysym, GDK_CONTROL_MASK,
514 GTK_TYPE_DIRECTION_TYPE, direction);
515 gtk_binding_entry_add_signal (binding_set, keypad_keysym, 0,
517 GTK_TYPE_DIRECTION_TYPE, direction);
518 gtk_binding_entry_add_signal (binding_set, keypad_keysym, GDK_CONTROL_MASK,
520 GTK_TYPE_DIRECTION_TYPE, direction);
524 extract_time_from_startup_id (const gchar* startup_id)
526 gchar *timestr = g_strrstr (startup_id, "_TIME");
527 guint32 retval = GDK_CURRENT_TIME;
534 /* Skip past the "_TIME" part */
539 timestamp = g_ascii_strtoull (timestr, &end, 0);
540 if (errno == 0 && end != timestr)
548 startup_id_is_fake (const gchar* startup_id)
550 return strncmp (startup_id, "_TIME", 5) == 0;
554 gtk_window_class_init (GtkWindowClass *klass)
556 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
557 GtkWidgetClass *widget_class;
558 GtkContainerClass *container_class;
559 GtkBindingSet *binding_set;
561 widget_class = (GtkWidgetClass*) klass;
562 container_class = (GtkContainerClass*) klass;
564 quark_gtk_embedded = g_quark_from_static_string ("gtk-embedded");
565 quark_gtk_window_key_hash = g_quark_from_static_string ("gtk-window-key-hash");
566 quark_gtk_window_icon_info = g_quark_from_static_string ("gtk-window-icon-info");
567 quark_gtk_buildable_accels = g_quark_from_static_string ("gtk-window-buildable-accels");
569 gobject_class->dispose = gtk_window_dispose;
570 gobject_class->finalize = gtk_window_finalize;
572 gobject_class->set_property = gtk_window_set_property;
573 gobject_class->get_property = gtk_window_get_property;
575 widget_class->destroy = gtk_window_destroy;
576 widget_class->show = gtk_window_show;
577 widget_class->hide = gtk_window_hide;
578 widget_class->map = gtk_window_map;
579 widget_class->map_event = gtk_window_map_event;
580 widget_class->unmap = gtk_window_unmap;
581 widget_class->realize = gtk_window_realize;
582 widget_class->unrealize = gtk_window_unrealize;
583 widget_class->size_allocate = gtk_window_size_allocate;
584 widget_class->configure_event = gtk_window_configure_event;
585 widget_class->key_press_event = gtk_window_key_press_event;
586 widget_class->key_release_event = gtk_window_key_release_event;
587 widget_class->enter_notify_event = gtk_window_enter_notify_event;
588 widget_class->leave_notify_event = gtk_window_leave_notify_event;
589 widget_class->focus_in_event = gtk_window_focus_in_event;
590 widget_class->button_press_event = gtk_window_button_press_event;
591 widget_class->focus_out_event = gtk_window_focus_out_event;
592 widget_class->focus = gtk_window_focus;
593 widget_class->move_focus = gtk_window_move_focus;
594 widget_class->draw = gtk_window_draw;
595 widget_class->get_preferred_width = gtk_window_get_preferred_width;
596 widget_class->get_preferred_height = gtk_window_get_preferred_height;
597 widget_class->window_state_event = gtk_window_state_event;
598 widget_class->direction_changed = gtk_window_direction_changed;
599 widget_class->state_changed = gtk_window_state_changed;
600 widget_class->style_updated = gtk_window_style_updated;
602 container_class->check_resize = gtk_window_check_resize;
604 klass->set_focus = gtk_window_real_set_focus;
606 klass->activate_default = gtk_window_real_activate_default;
607 klass->activate_focus = gtk_window_real_activate_focus;
608 klass->keys_changed = gtk_window_keys_changed;
610 g_type_class_add_private (gobject_class, sizeof (GtkWindowPrivate));
613 g_object_class_install_property (gobject_class,
615 g_param_spec_enum ("type",
617 P_("The type of the window"),
618 GTK_TYPE_WINDOW_TYPE,
620 GTK_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
622 g_object_class_install_property (gobject_class,
624 g_param_spec_string ("title",
626 P_("The title of the window"),
628 GTK_PARAM_READWRITE));
630 g_object_class_install_property (gobject_class,
632 g_param_spec_string ("role",
634 P_("Unique identifier for the window to be used when restoring a session"),
636 GTK_PARAM_READWRITE));
639 * GtkWindow:startup-id:
641 * The :startup-id is a write-only property for setting window's
642 * startup notification identifier. See gtk_window_set_startup_id()
647 g_object_class_install_property (gobject_class,
649 g_param_spec_string ("startup-id",
651 P_("Unique startup identifier for the window used by startup-notification"),
653 GTK_PARAM_WRITABLE));
655 g_object_class_install_property (gobject_class,
657 g_param_spec_boolean ("resizable",
659 P_("If TRUE, users can resize the window"),
661 GTK_PARAM_READWRITE));
663 g_object_class_install_property (gobject_class,
665 g_param_spec_boolean ("modal",
667 P_("If TRUE, the window is modal (other windows are not usable while this one is up)"),
669 GTK_PARAM_READWRITE));
671 g_object_class_install_property (gobject_class,
673 g_param_spec_enum ("window-position",
674 P_("Window Position"),
675 P_("The initial position of the window"),
676 GTK_TYPE_WINDOW_POSITION,
678 GTK_PARAM_READWRITE));
680 g_object_class_install_property (gobject_class,
682 g_param_spec_int ("default-width",
684 P_("The default width of the window, used when initially showing the window"),
688 GTK_PARAM_READWRITE));
690 g_object_class_install_property (gobject_class,
692 g_param_spec_int ("default-height",
693 P_("Default Height"),
694 P_("The default height of the window, used when initially showing the window"),
698 GTK_PARAM_READWRITE));
700 g_object_class_install_property (gobject_class,
701 PROP_DESTROY_WITH_PARENT,
702 g_param_spec_boolean ("destroy-with-parent",
703 P_("Destroy with Parent"),
704 P_("If this window should be destroyed when the parent is destroyed"),
706 GTK_PARAM_READWRITE));
709 * GtkWindow:hide-titlebar-when-maximized:
711 * Whether the titlebar should be hidden during maximization.
715 g_object_class_install_property (gobject_class,
716 PROP_HIDE_TITLEBAR_WHEN_MAXIMIZED,
717 g_param_spec_boolean ("hide-titlebar-when-maximized",
718 P_("Hide the titlebar during maximization"),
719 P_("If this window's titlebar should be hidden when the window is maximized"),
721 GTK_PARAM_READWRITE));
723 g_object_class_install_property (gobject_class,
725 g_param_spec_object ("icon",
727 P_("Icon for this window"),
729 GTK_PARAM_READWRITE));
732 * GtkWindow:mnemonics-visible:
734 * Whether mnemonics are currently visible in this window.
736 * This property is maintained by GTK+ based on the
737 * #GtkSettings:gtk-auto-mnemonics setting and user input,
738 * and should not be set by applications.
742 g_object_class_install_property (gobject_class,
743 PROP_MNEMONICS_VISIBLE,
744 g_param_spec_boolean ("mnemonics-visible",
745 P_("Mnemonics Visible"),
746 P_("Whether mnemonics are currently visible in this window"),
748 GTK_PARAM_READWRITE));
751 * GtkWindow:focus-visible:
753 * Whether 'focus rectangles' are currently visible in this window.
755 * This property is maintained by GTK+ based on the
756 * #GtkSettings:gtk-visible-focus setting and user input
757 * and should not be set by applications.
761 g_object_class_install_property (gobject_class,
763 g_param_spec_boolean ("focus-visible",
765 P_("Whether focus rectangles are currently visible in this window"),
767 GTK_PARAM_READWRITE));
770 * GtkWindow:icon-name:
772 * The :icon-name property specifies the name of the themed icon to
773 * use as the window icon. See #GtkIconTheme for more details.
777 g_object_class_install_property (gobject_class,
779 g_param_spec_string ("icon-name",
781 P_("Name of the themed icon for this window"),
783 GTK_PARAM_READWRITE));
785 g_object_class_install_property (gobject_class,
787 g_param_spec_object ("screen",
789 P_("The screen where this window will be displayed"),
791 GTK_PARAM_READWRITE));
793 g_object_class_install_property (gobject_class,
795 g_param_spec_boolean ("is-active",
797 P_("Whether the toplevel is the current active window"),
799 GTK_PARAM_READABLE));
801 g_object_class_install_property (gobject_class,
802 PROP_HAS_TOPLEVEL_FOCUS,
803 g_param_spec_boolean ("has-toplevel-focus",
804 P_("Focus in Toplevel"),
805 P_("Whether the input focus is within this GtkWindow"),
807 GTK_PARAM_READABLE));
809 g_object_class_install_property (gobject_class,
811 g_param_spec_enum ("type-hint",
813 P_("Hint to help the desktop environment understand what kind of window this is and how to treat it."),
814 GDK_TYPE_WINDOW_TYPE_HINT,
815 GDK_WINDOW_TYPE_HINT_NORMAL,
816 GTK_PARAM_READWRITE));
818 g_object_class_install_property (gobject_class,
819 PROP_SKIP_TASKBAR_HINT,
820 g_param_spec_boolean ("skip-taskbar-hint",
822 P_("TRUE if the window should not be in the task bar."),
824 GTK_PARAM_READWRITE));
826 g_object_class_install_property (gobject_class,
827 PROP_SKIP_PAGER_HINT,
828 g_param_spec_boolean ("skip-pager-hint",
830 P_("TRUE if the window should not be in the pager."),
832 GTK_PARAM_READWRITE));
834 g_object_class_install_property (gobject_class,
836 g_param_spec_boolean ("urgency-hint",
838 P_("TRUE if the window should be brought to the user's attention."),
840 GTK_PARAM_READWRITE));
843 * GtkWindow:accept-focus:
845 * Whether the window should receive the input focus.
849 g_object_class_install_property (gobject_class,
851 g_param_spec_boolean ("accept-focus",
853 P_("TRUE if the window should receive the input focus."),
855 GTK_PARAM_READWRITE));
858 * GtkWindow:focus-on-map:
860 * Whether the window should receive the input focus when mapped.
864 g_object_class_install_property (gobject_class,
866 g_param_spec_boolean ("focus-on-map",
868 P_("TRUE if the window should receive the input focus when mapped."),
870 GTK_PARAM_READWRITE));
873 * GtkWindow:decorated:
875 * Whether the window should be decorated by the window manager.
879 g_object_class_install_property (gobject_class,
881 g_param_spec_boolean ("decorated",
883 P_("Whether the window should be decorated by the window manager"),
885 GTK_PARAM_READWRITE));
888 * GtkWindow:deletable:
890 * Whether the window frame should have a close button.
894 g_object_class_install_property (gobject_class,
896 g_param_spec_boolean ("deletable",
898 P_("Whether the window frame should have a close button"),
900 GTK_PARAM_READWRITE));
903 * GtkWindow:has-resize-grip
905 * Whether the window has a corner resize grip.
907 * Note that the resize grip is only shown if the window is
908 * actually resizable and not maximized. Use
909 * #GtkWindow:resize-grip-visible to find out if the resize
910 * grip is currently shown.
914 g_object_class_install_property (gobject_class,
915 PROP_HAS_RESIZE_GRIP,
916 g_param_spec_boolean ("has-resize-grip",
918 P_("Specifies whether the window should have a resize grip"),
920 GTK_PARAM_READWRITE));
923 * GtkWindow:resize-grip-visible:
925 * Whether a corner resize grip is currently shown.
929 g_object_class_install_property (gobject_class,
930 PROP_RESIZE_GRIP_VISIBLE,
931 g_param_spec_boolean ("resize-grip-visible",
932 P_("Resize grip is visible"),
933 P_("Specifies whether the window's resize grip is visible."),
935 GTK_PARAM_READABLE));
941 * The window gravity of the window. See gtk_window_move() and #GdkGravity for
942 * more details about window gravity.
946 g_object_class_install_property (gobject_class,
948 g_param_spec_enum ("gravity",
950 P_("The window gravity of the window"),
952 GDK_GRAVITY_NORTH_WEST,
953 GTK_PARAM_READWRITE));
957 * GtkWindow:transient-for:
959 * The transient parent of the window. See gtk_window_set_transient_for() for
960 * more details about transient windows.
964 g_object_class_install_property (gobject_class,
966 g_param_spec_object ("transient-for",
967 P_("Transient for Window"),
968 P_("The transient parent of the dialog"),
970 GTK_PARAM_READWRITE| G_PARAM_CONSTRUCT));
973 * GtkWindow:attached-to:
975 * The widget to which this window is attached.
976 * See gtk_window_set_attached_to().
978 * Examples of places where specifying this relation is useful are
979 * for instance a #GtkMenu created by a #GtkComboBox, a completion
980 * popup window created by #GtkEntry or a typeahead search entry
981 * created by #GtkTreeView.
985 g_object_class_install_property (gobject_class,
987 g_param_spec_object ("attached-to",
988 P_("Attached to Widget"),
989 P_("The widget where the window is attached"),
991 GTK_PARAM_READWRITE | G_PARAM_CONSTRUCT));
996 * The requested opacity of the window. See gtk_window_set_opacity() for
997 * more details about window opacity.
1001 g_object_class_install_property (gobject_class,
1003 g_param_spec_double ("opacity",
1004 P_("Opacity for Window"),
1005 P_("The opacity of the window, from 0 to 1"),
1009 GTK_PARAM_READWRITE));
1011 /* Style properties.
1013 gtk_widget_class_install_style_property (widget_class,
1014 g_param_spec_int ("resize-grip-width",
1015 P_("Width of resize grip"),
1016 P_("Width of resize grip"),
1017 0, G_MAXINT, 16, GTK_PARAM_READWRITE));
1019 gtk_widget_class_install_style_property (widget_class,
1020 g_param_spec_int ("resize-grip-height",
1021 P_("Height of resize grip"),
1022 P_("Height of resize grip"),
1023 0, G_MAXINT, 16, GTK_PARAM_READWRITE));
1027 * GtkWindow:application:
1029 * The #GtkApplication associated with the window.
1031 * The application will be kept alive for at least as long as it
1032 * has any windows associated with it (see g_application_hold()
1033 * for a way to keep it alive without windows).
1035 * Normally, the connection between the application and the window
1036 * will remain until the window is destroyed, but you can explicitly
1037 * remove it by setting the ::application property to %NULL.
1041 g_object_class_install_property (gobject_class,
1043 g_param_spec_object ("application",
1044 P_("GtkApplication"),
1045 P_("The GtkApplication for the window"),
1046 GTK_TYPE_APPLICATION,
1047 GTK_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
1049 window_signals[SET_FOCUS] =
1050 g_signal_new (I_("set-focus"),
1051 G_TYPE_FROM_CLASS (gobject_class),
1053 G_STRUCT_OFFSET (GtkWindowClass, set_focus),
1055 _gtk_marshal_VOID__OBJECT,
1060 * GtkWindow::activate-focus:
1061 * @window: the window which received the signal
1063 * The ::activate-focus signal is a
1064 * <link linkend="keybinding-signals">keybinding signal</link>
1065 * which gets emitted when the user activates the currently
1066 * focused widget of @window.
1068 window_signals[ACTIVATE_FOCUS] =
1069 g_signal_new (I_("activate-focus"),
1070 G_TYPE_FROM_CLASS (gobject_class),
1071 G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
1072 G_STRUCT_OFFSET (GtkWindowClass, activate_focus),
1074 _gtk_marshal_VOID__VOID,
1079 * GtkWindow::activate-default:
1080 * @window: the window which received the signal
1082 * The ::activate-default signal is a
1083 * <link linkend="keybinding-signals">keybinding signal</link>
1084 * which gets emitted when the user activates the default widget
1087 window_signals[ACTIVATE_DEFAULT] =
1088 g_signal_new (I_("activate-default"),
1089 G_TYPE_FROM_CLASS (gobject_class),
1090 G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
1091 G_STRUCT_OFFSET (GtkWindowClass, activate_default),
1093 _gtk_marshal_VOID__VOID,
1098 * GtkWindow::keys-changed:
1099 * @window: the window which received the signal
1101 * The ::keys-changed signal gets emitted when the set of accelerators
1102 * or mnemonics that are associated with @window changes.
1104 window_signals[KEYS_CHANGED] =
1105 g_signal_new (I_("keys-changed"),
1106 G_TYPE_FROM_CLASS (gobject_class),
1108 G_STRUCT_OFFSET (GtkWindowClass, keys_changed),
1110 _gtk_marshal_VOID__VOID,
1118 binding_set = gtk_binding_set_by_class (klass);
1120 gtk_binding_entry_add_signal (binding_set, GDK_KEY_space, 0,
1121 "activate-focus", 0);
1122 gtk_binding_entry_add_signal (binding_set, GDK_KEY_KP_Space, 0,
1123 "activate-focus", 0);
1125 gtk_binding_entry_add_signal (binding_set, GDK_KEY_Return, 0,
1126 "activate-default", 0);
1127 gtk_binding_entry_add_signal (binding_set, GDK_KEY_ISO_Enter, 0,
1128 "activate-default", 0);
1129 gtk_binding_entry_add_signal (binding_set, GDK_KEY_KP_Enter, 0,
1130 "activate-default", 0);
1132 add_arrow_bindings (binding_set, GDK_KEY_Up, GTK_DIR_UP);
1133 add_arrow_bindings (binding_set, GDK_KEY_Down, GTK_DIR_DOWN);
1134 add_arrow_bindings (binding_set, GDK_KEY_Left, GTK_DIR_LEFT);
1135 add_arrow_bindings (binding_set, GDK_KEY_Right, GTK_DIR_RIGHT);
1137 add_tab_bindings (binding_set, 0, GTK_DIR_TAB_FORWARD);
1138 add_tab_bindings (binding_set, GDK_CONTROL_MASK, GTK_DIR_TAB_FORWARD);
1139 add_tab_bindings (binding_set, GDK_SHIFT_MASK, GTK_DIR_TAB_BACKWARD);
1140 add_tab_bindings (binding_set, GDK_CONTROL_MASK | GDK_SHIFT_MASK, GTK_DIR_TAB_BACKWARD);
1142 gtk_widget_class_set_accessible_type (widget_class, GTK_TYPE_WINDOW_ACCESSIBLE);
1146 gtk_window_init (GtkWindow *window)
1148 GtkWindowPrivate *priv;
1150 window->priv = G_TYPE_INSTANCE_GET_PRIVATE (window,
1153 priv = window->priv;
1155 gtk_widget_set_has_window (GTK_WIDGET (window), TRUE);
1156 _gtk_widget_set_is_toplevel (GTK_WIDGET (window), TRUE);
1158 _gtk_widget_set_anchored (GTK_WIDGET (window), TRUE);
1160 gtk_container_set_resize_mode (GTK_CONTAINER (window), GTK_RESIZE_QUEUE);
1163 priv->wmclass_name = g_strdup (g_get_prgname ());
1164 priv->wmclass_class = g_strdup (gdk_get_program_class ());
1165 priv->wm_role = NULL;
1166 priv->geometry_info = NULL;
1167 priv->type = GTK_WINDOW_TOPLEVEL;
1168 priv->focus_widget = NULL;
1169 priv->default_widget = NULL;
1170 priv->configure_request_count = 0;
1171 priv->resizable = TRUE;
1172 priv->configure_notify_received = FALSE;
1173 priv->position = GTK_WIN_POS_NONE;
1174 priv->need_default_size = TRUE;
1175 priv->need_default_position = TRUE;
1176 priv->modal = FALSE;
1177 priv->gdk_type_hint = GDK_WINDOW_TYPE_HINT_NORMAL;
1178 priv->gravity = GDK_GRAVITY_NORTH_WEST;
1179 priv->decorated = TRUE;
1180 priv->mnemonic_modifier = GDK_MOD1_MASK;
1181 priv->screen = gdk_screen_get_default ();
1183 priv->accept_focus = TRUE;
1184 priv->focus_on_map = TRUE;
1185 priv->deletable = TRUE;
1186 priv->type_hint = GDK_WINDOW_TYPE_HINT_NORMAL;
1187 priv->opacity = 1.0;
1188 priv->startup_id = NULL;
1189 priv->initial_timestamp = GDK_CURRENT_TIME;
1190 priv->has_resize_grip = TRUE;
1191 priv->mnemonics_visible = TRUE;
1192 priv->focus_visible = TRUE;
1194 g_object_ref_sink (window);
1195 priv->has_user_ref_count = TRUE;
1196 toplevel_list = g_slist_prepend (toplevel_list, window);
1199 g_signal_connect (priv->screen, "composited-changed",
1200 G_CALLBACK (gtk_window_on_composited_changed), window);
1202 #ifdef GDK_WINDOWING_X11
1203 g_signal_connect (gtk_settings_get_for_screen (priv->screen),
1204 "notify::gtk-application-prefer-dark-theme",
1205 G_CALLBACK (gtk_window_on_theme_variant_changed), window);
1210 gtk_window_set_property (GObject *object,
1212 const GValue *value,
1215 GtkWindow *window = GTK_WINDOW (object);
1216 GtkWindowPrivate *priv = window->priv;
1221 priv->type = g_value_get_enum (value);
1224 gtk_window_set_title (window, g_value_get_string (value));
1227 gtk_window_set_role (window, g_value_get_string (value));
1229 case PROP_STARTUP_ID:
1230 gtk_window_set_startup_id (window, g_value_get_string (value));
1232 case PROP_RESIZABLE:
1233 gtk_window_set_resizable (window, g_value_get_boolean (value));
1236 gtk_window_set_modal (window, g_value_get_boolean (value));
1239 gtk_window_set_position (window, g_value_get_enum (value));
1241 case PROP_DEFAULT_WIDTH:
1242 gtk_window_set_default_size_internal (window,
1243 TRUE, g_value_get_int (value),
1246 case PROP_DEFAULT_HEIGHT:
1247 gtk_window_set_default_size_internal (window,
1249 TRUE, g_value_get_int (value), FALSE);
1251 case PROP_DESTROY_WITH_PARENT:
1252 gtk_window_set_destroy_with_parent (window, g_value_get_boolean (value));
1254 case PROP_HIDE_TITLEBAR_WHEN_MAXIMIZED:
1255 gtk_window_set_hide_titlebar_when_maximized (window, g_value_get_boolean (value));
1258 gtk_window_set_icon (window,
1259 g_value_get_object (value));
1261 case PROP_ICON_NAME:
1262 gtk_window_set_icon_name (window, g_value_get_string (value));
1265 gtk_window_set_screen (window, g_value_get_object (value));
1267 case PROP_TYPE_HINT:
1268 gtk_window_set_type_hint (window,
1269 g_value_get_enum (value));
1271 case PROP_SKIP_TASKBAR_HINT:
1272 gtk_window_set_skip_taskbar_hint (window,
1273 g_value_get_boolean (value));
1275 case PROP_SKIP_PAGER_HINT:
1276 gtk_window_set_skip_pager_hint (window,
1277 g_value_get_boolean (value));
1279 case PROP_URGENCY_HINT:
1280 gtk_window_set_urgency_hint (window,
1281 g_value_get_boolean (value));
1283 case PROP_ACCEPT_FOCUS:
1284 gtk_window_set_accept_focus (window,
1285 g_value_get_boolean (value));
1287 case PROP_FOCUS_ON_MAP:
1288 gtk_window_set_focus_on_map (window,
1289 g_value_get_boolean (value));
1291 case PROP_DECORATED:
1292 gtk_window_set_decorated (window, g_value_get_boolean (value));
1294 case PROP_DELETABLE:
1295 gtk_window_set_deletable (window, g_value_get_boolean (value));
1298 gtk_window_set_gravity (window, g_value_get_enum (value));
1300 case PROP_TRANSIENT_FOR:
1301 gtk_window_set_transient_for (window, g_value_get_object (value));
1303 case PROP_ATTACHED_TO:
1304 gtk_window_set_attached_to (window, g_value_get_object (value));
1307 gtk_window_set_opacity (window, g_value_get_double (value));
1309 case PROP_HAS_RESIZE_GRIP:
1310 gtk_window_set_has_resize_grip (window, g_value_get_boolean (value));
1312 case PROP_APPLICATION:
1313 gtk_window_set_application (window, g_value_get_object (value));
1315 case PROP_MNEMONICS_VISIBLE:
1316 gtk_window_set_mnemonics_visible (window, g_value_get_boolean (value));
1318 case PROP_FOCUS_VISIBLE:
1319 gtk_window_set_focus_visible (window, g_value_get_boolean (value));
1322 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1328 gtk_window_get_property (GObject *object,
1333 GtkWindow *window = GTK_WINDOW (object);
1334 GtkWindowPrivate *priv = window->priv;
1338 GtkWindowGeometryInfo *info;
1340 g_value_set_enum (value, priv->type);
1343 g_value_set_string (value, priv->wm_role);
1346 g_value_set_string (value, priv->title);
1348 case PROP_RESIZABLE:
1349 g_value_set_boolean (value, priv->resizable);
1352 g_value_set_boolean (value, priv->modal);
1355 g_value_set_enum (value, priv->position);
1357 case PROP_DEFAULT_WIDTH:
1358 info = gtk_window_get_geometry_info (window, FALSE);
1360 g_value_set_int (value, -1);
1362 g_value_set_int (value, info->default_width);
1364 case PROP_DEFAULT_HEIGHT:
1365 info = gtk_window_get_geometry_info (window, FALSE);
1367 g_value_set_int (value, -1);
1369 g_value_set_int (value, info->default_height);
1371 case PROP_DESTROY_WITH_PARENT:
1372 g_value_set_boolean (value, priv->destroy_with_parent);
1374 case PROP_HIDE_TITLEBAR_WHEN_MAXIMIZED:
1375 g_value_set_boolean (value, priv->hide_titlebar_when_maximized);
1378 g_value_set_object (value, gtk_window_get_icon (window));
1380 case PROP_ICON_NAME:
1381 g_value_set_string (value, gtk_window_get_icon_name (window));
1384 g_value_set_object (value, priv->screen);
1386 case PROP_IS_ACTIVE:
1387 g_value_set_boolean (value, priv->is_active);
1389 case PROP_HAS_TOPLEVEL_FOCUS:
1390 g_value_set_boolean (value, priv->has_toplevel_focus);
1392 case PROP_TYPE_HINT:
1393 g_value_set_enum (value, priv->type_hint);
1395 case PROP_SKIP_TASKBAR_HINT:
1396 g_value_set_boolean (value,
1397 gtk_window_get_skip_taskbar_hint (window));
1399 case PROP_SKIP_PAGER_HINT:
1400 g_value_set_boolean (value,
1401 gtk_window_get_skip_pager_hint (window));
1403 case PROP_URGENCY_HINT:
1404 g_value_set_boolean (value,
1405 gtk_window_get_urgency_hint (window));
1407 case PROP_ACCEPT_FOCUS:
1408 g_value_set_boolean (value,
1409 gtk_window_get_accept_focus (window));
1411 case PROP_FOCUS_ON_MAP:
1412 g_value_set_boolean (value,
1413 gtk_window_get_focus_on_map (window));
1415 case PROP_DECORATED:
1416 g_value_set_boolean (value, gtk_window_get_decorated (window));
1418 case PROP_DELETABLE:
1419 g_value_set_boolean (value, gtk_window_get_deletable (window));
1422 g_value_set_enum (value, gtk_window_get_gravity (window));
1424 case PROP_TRANSIENT_FOR:
1425 g_value_set_object (value, gtk_window_get_transient_for (window));
1427 case PROP_ATTACHED_TO:
1428 g_value_set_object (value, gtk_window_get_attached_to (window));
1431 g_value_set_double (value, gtk_window_get_opacity (window));
1433 case PROP_HAS_RESIZE_GRIP:
1434 g_value_set_boolean (value, priv->has_resize_grip);
1436 case PROP_RESIZE_GRIP_VISIBLE:
1437 g_value_set_boolean (value, gtk_window_resize_grip_is_visible (window));
1439 case PROP_APPLICATION:
1440 g_value_set_object (value, gtk_window_get_application (window));
1442 case PROP_MNEMONICS_VISIBLE:
1443 g_value_set_boolean (value, priv->mnemonics_visible);
1445 case PROP_FOCUS_VISIBLE:
1446 g_value_set_boolean (value, priv->focus_visible);
1449 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1455 gtk_window_buildable_interface_init (GtkBuildableIface *iface)
1457 parent_buildable_iface = g_type_interface_peek_parent (iface);
1458 iface->set_buildable_property = gtk_window_buildable_set_buildable_property;
1459 iface->parser_finished = gtk_window_buildable_parser_finished;
1460 iface->custom_tag_start = gtk_window_buildable_custom_tag_start;
1461 iface->custom_finished = gtk_window_buildable_custom_finished;
1465 gtk_window_buildable_set_buildable_property (GtkBuildable *buildable,
1466 GtkBuilder *builder,
1468 const GValue *value)
1470 GtkWindow *window = GTK_WINDOW (buildable);
1471 GtkWindowPrivate *priv = window->priv;
1473 if (strcmp (name, "visible") == 0 && g_value_get_boolean (value))
1474 priv->builder_visible = TRUE;
1476 parent_buildable_iface->set_buildable_property (buildable, builder, name, value);
1480 gtk_window_buildable_parser_finished (GtkBuildable *buildable,
1481 GtkBuilder *builder)
1483 GtkWindow *window = GTK_WINDOW (buildable);
1484 GtkWindowPrivate *priv = window->priv;
1488 if (priv->builder_visible)
1489 gtk_widget_show (GTK_WIDGET (buildable));
1491 accels = g_object_get_qdata (G_OBJECT (buildable), quark_gtk_buildable_accels);
1492 for (l = accels; l; l = l->next)
1494 object = gtk_builder_get_object (builder, l->data);
1497 g_warning ("Unknown accel group %s specified in window %s",
1498 (const gchar*)l->data, gtk_buildable_get_name (buildable));
1501 gtk_window_add_accel_group (GTK_WINDOW (buildable),
1502 GTK_ACCEL_GROUP (object));
1506 g_object_set_qdata (G_OBJECT (buildable), quark_gtk_buildable_accels, NULL);
1508 parent_buildable_iface->parser_finished (buildable, builder);
1514 } GSListSubParserData;
1517 window_start_element (GMarkupParseContext *context,
1518 const gchar *element_name,
1519 const gchar **names,
1520 const gchar **values,
1525 GSListSubParserData *data = (GSListSubParserData*)user_data;
1527 if (strcmp (element_name, "group") == 0)
1529 for (i = 0; names[i]; i++)
1531 if (strcmp (names[i], "name") == 0)
1532 data->items = g_slist_prepend (data->items, g_strdup (values[i]));
1535 else if (strcmp (element_name, "accel-groups") == 0)
1538 g_warning ("Unsupported tag type for GtkWindow: %s\n",
1543 static const GMarkupParser window_parser =
1545 window_start_element
1549 gtk_window_buildable_custom_tag_start (GtkBuildable *buildable,
1550 GtkBuilder *builder,
1552 const gchar *tagname,
1553 GMarkupParser *parser,
1556 GSListSubParserData *parser_data;
1558 if (parent_buildable_iface->custom_tag_start (buildable, builder, child,
1559 tagname, parser, data))
1562 if (strcmp (tagname, "accel-groups") == 0)
1564 parser_data = g_slice_new0 (GSListSubParserData);
1565 parser_data->items = NULL;
1566 parser_data->object = G_OBJECT (buildable);
1568 *parser = window_parser;
1569 *data = parser_data;
1577 gtk_window_buildable_custom_finished (GtkBuildable *buildable,
1578 GtkBuilder *builder,
1580 const gchar *tagname,
1583 GSListSubParserData *data;
1585 parent_buildable_iface->custom_finished (buildable, builder, child,
1586 tagname, user_data);
1588 if (strcmp (tagname, "accel-groups") != 0)
1591 data = (GSListSubParserData*)user_data;
1593 g_object_set_qdata_full (G_OBJECT (buildable), quark_gtk_buildable_accels,
1594 data->items, (GDestroyNotify) g_slist_free);
1596 g_slice_free (GSListSubParserData, data);
1601 * @type: type of window
1603 * Creates a new #GtkWindow, which is a toplevel window that can
1604 * contain other widgets. Nearly always, the type of the window should
1605 * be #GTK_WINDOW_TOPLEVEL. If you're implementing something like a
1606 * popup menu from scratch (which is a bad idea, just use #GtkMenu),
1607 * you might use #GTK_WINDOW_POPUP. #GTK_WINDOW_POPUP is not for
1608 * dialogs, though in some other toolkits dialogs are called "popups".
1609 * In GTK+, #GTK_WINDOW_POPUP means a pop-up menu or pop-up tooltip.
1610 * On X11, popup windows are not controlled by the <link
1611 * linkend="gtk-X11-arch">window manager</link>.
1613 * If you simply want an undecorated window (no window borders), use
1614 * gtk_window_set_decorated(), don't use #GTK_WINDOW_POPUP.
1616 * Return value: a new #GtkWindow.
1619 gtk_window_new (GtkWindowType type)
1621 GtkWindowPrivate *priv;
1624 g_return_val_if_fail (type >= GTK_WINDOW_TOPLEVEL && type <= GTK_WINDOW_POPUP, NULL);
1626 window = g_object_new (GTK_TYPE_WINDOW, NULL);
1627 priv = window->priv;
1631 return GTK_WIDGET (window);
1635 * gtk_window_set_title:
1636 * @window: a #GtkWindow
1637 * @title: title of the window
1639 * Sets the title of the #GtkWindow. The title of a window will be
1640 * displayed in its title bar; on the X Window System, the title bar
1641 * is rendered by the <link linkend="gtk-X11-arch">window
1642 * manager</link>, so exactly how the title appears to users may vary
1643 * according to a user's exact configuration. The title should help a
1644 * user distinguish this window from other windows they may have
1645 * open. A good title might include the application name and current
1646 * document filename, for example.
1650 gtk_window_set_title (GtkWindow *window,
1653 GtkWindowPrivate *priv;
1657 g_return_if_fail (GTK_IS_WINDOW (window));
1659 priv = window->priv;
1660 widget = GTK_WIDGET (window);
1662 new_title = g_strdup (title);
1663 g_free (priv->title);
1664 priv->title = new_title;
1666 if (gtk_widget_get_realized (widget))
1668 gdk_window_set_title (gtk_widget_get_window (widget),
1672 g_object_notify (G_OBJECT (window), "title");
1676 * gtk_window_get_title:
1677 * @window: a #GtkWindow
1679 * Retrieves the title of the window. See gtk_window_set_title().
1681 * Return value: the title of the window, or %NULL if none has
1682 * been set explicitely. The returned string is owned by the widget
1683 * and must not be modified or freed.
1686 gtk_window_get_title (GtkWindow *window)
1688 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
1690 return window->priv->title;
1694 * gtk_window_set_wmclass:
1695 * @window: a #GtkWindow
1696 * @wmclass_name: window name hint
1697 * @wmclass_class: window class hint
1699 * Don't use this function. It sets the X Window System "class" and
1700 * "name" hints for a window. According to the ICCCM, you should
1701 * always set these to the same value for all windows in an
1702 * application, and GTK+ sets them to that value by default, so calling
1703 * this function is sort of pointless. However, you may want to call
1704 * gtk_window_set_role() on each window in your application, for the
1705 * benefit of the session manager. Setting the role allows the window
1706 * manager to restore window positions when loading a saved session.
1710 gtk_window_set_wmclass (GtkWindow *window,
1711 const gchar *wmclass_name,
1712 const gchar *wmclass_class)
1714 GtkWindowPrivate *priv;
1716 g_return_if_fail (GTK_IS_WINDOW (window));
1718 priv = window->priv;
1720 g_free (priv->wmclass_name);
1721 priv->wmclass_name = g_strdup (wmclass_name);
1723 g_free (priv->wmclass_class);
1724 priv->wmclass_class = g_strdup (wmclass_class);
1726 if (gtk_widget_get_realized (GTK_WIDGET (window)))
1727 g_warning ("gtk_window_set_wmclass: shouldn't set wmclass after window is realized!\n");
1731 * gtk_window_set_role:
1732 * @window: a #GtkWindow
1733 * @role: unique identifier for the window to be used when restoring a session
1735 * This function is only useful on X11, not with other GTK+ targets.
1737 * In combination with the window title, the window role allows a
1738 * <link linkend="gtk-X11-arch">window manager</link> to identify "the
1739 * same" window when an application is restarted. So for example you
1740 * might set the "toolbox" role on your app's toolbox window, so that
1741 * when the user restarts their session, the window manager can put
1742 * the toolbox back in the same place.
1744 * If a window already has a unique title, you don't need to set the
1745 * role, since the WM can use the title to identify the window when
1746 * restoring the session.
1750 gtk_window_set_role (GtkWindow *window,
1753 GtkWindowPrivate *priv;
1756 g_return_if_fail (GTK_IS_WINDOW (window));
1758 priv = window->priv;
1760 new_role = g_strdup (role);
1761 g_free (priv->wm_role);
1762 priv->wm_role = new_role;
1764 if (gtk_widget_get_realized (GTK_WIDGET (window)))
1765 gdk_window_set_role (gtk_widget_get_window (GTK_WIDGET (window)),
1768 g_object_notify (G_OBJECT (window), "role");
1772 * gtk_window_set_startup_id:
1773 * @window: a #GtkWindow
1774 * @startup_id: a string with startup-notification identifier
1776 * Startup notification identifiers are used by desktop environment to
1777 * track application startup, to provide user feedback and other
1778 * features. This function changes the corresponding property on the
1779 * underlying GdkWindow. Normally, startup identifier is managed
1780 * automatically and you should only use this function in special cases
1781 * like transferring focus from other processes. You should use this
1782 * function before calling gtk_window_present() or any equivalent
1783 * function generating a window map event.
1785 * This function is only useful on X11, not with other GTK+ targets.
1790 gtk_window_set_startup_id (GtkWindow *window,
1791 const gchar *startup_id)
1793 GtkWindowPrivate *priv;
1796 g_return_if_fail (GTK_IS_WINDOW (window));
1798 priv = window->priv;
1799 widget = GTK_WIDGET (window);
1801 g_free (priv->startup_id);
1802 priv->startup_id = g_strdup (startup_id);
1804 if (gtk_widget_get_realized (widget))
1806 GdkWindow *gdk_window;
1807 guint32 timestamp = extract_time_from_startup_id (priv->startup_id);
1809 gdk_window = gtk_widget_get_window (widget);
1811 #ifdef GDK_WINDOWING_X11
1812 if (timestamp != GDK_CURRENT_TIME && GDK_IS_X11_WINDOW(gdk_window))
1813 gdk_x11_window_set_user_time (gdk_window, timestamp);
1816 /* Here we differentiate real and "fake" startup notification IDs,
1817 * constructed on purpose just to pass interaction timestamp
1819 if (startup_id_is_fake (priv->startup_id))
1820 gtk_window_present_with_time (window, timestamp);
1823 gdk_window_set_startup_id (gdk_window,
1826 /* If window is mapped, terminate the startup-notification too */
1827 if (gtk_widget_get_mapped (widget) &&
1828 !disable_startup_notification)
1829 gdk_notify_startup_complete_with_id (priv->startup_id);
1833 g_object_notify (G_OBJECT (window), "startup-id");
1837 * gtk_window_get_role:
1838 * @window: a #GtkWindow
1840 * Returns the role of the window. See gtk_window_set_role() for
1841 * further explanation.
1843 * Return value: the role of the window if set, or %NULL. The
1844 * returned is owned by the widget and must not be modified
1848 gtk_window_get_role (GtkWindow *window)
1850 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
1852 return window->priv->wm_role;
1856 * gtk_window_set_focus:
1857 * @window: a #GtkWindow
1858 * @focus: (allow-none): widget to be the new focus widget, or %NULL to unset
1859 * any focus widget for the toplevel window.
1861 * If @focus is not the current focus widget, and is focusable, sets
1862 * it as the focus widget for the window. If @focus is %NULL, unsets
1863 * the focus widget for this window. To set the focus to a particular
1864 * widget in the toplevel, it is usually more convenient to use
1865 * gtk_widget_grab_focus() instead of this function.
1868 gtk_window_set_focus (GtkWindow *window,
1871 GtkWindowPrivate *priv;
1874 g_return_if_fail (GTK_IS_WINDOW (window));
1876 priv = window->priv;
1880 g_return_if_fail (GTK_IS_WIDGET (focus));
1881 g_return_if_fail (gtk_widget_get_can_focus (focus));
1885 gtk_widget_grab_focus (focus);
1888 /* Clear the existing focus chain, so that when we focus into
1889 * the window again, we start at the beginnning.
1891 GtkWidget *widget = priv->focus_widget;
1894 while ((parent = gtk_widget_get_parent (widget)))
1897 gtk_container_set_focus_child (GTK_CONTAINER (widget), NULL);
1901 _gtk_window_internal_set_focus (window, NULL);
1906 _gtk_window_internal_set_focus (GtkWindow *window,
1909 GtkWindowPrivate *priv;
1911 g_return_if_fail (GTK_IS_WINDOW (window));
1913 priv = window->priv;
1915 if ((priv->focus_widget != focus) ||
1916 (focus && !gtk_widget_has_focus (focus)))
1917 g_signal_emit (window, window_signals[SET_FOCUS], 0, focus);
1921 * gtk_window_set_default:
1922 * @window: a #GtkWindow
1923 * @default_widget: (allow-none): widget to be the default, or %NULL to unset the
1924 * default widget for the toplevel.
1926 * The default widget is the widget that's activated when the user
1927 * presses Enter in a dialog (for example). This function sets or
1928 * unsets the default widget for a #GtkWindow about. When setting
1929 * (rather than unsetting) the default widget it's generally easier to
1930 * call gtk_widget_grab_focus() on the widget. Before making a widget
1931 * the default widget, you must set the #GTK_CAN_DEFAULT flag on the
1932 * widget you'd like to make the default using GTK_WIDGET_SET_FLAGS().
1935 gtk_window_set_default (GtkWindow *window,
1936 GtkWidget *default_widget)
1938 GtkWindowPrivate *priv;
1940 g_return_if_fail (GTK_IS_WINDOW (window));
1942 priv = window->priv;
1945 g_return_if_fail (gtk_widget_get_can_default (default_widget));
1947 if (priv->default_widget != default_widget)
1949 GtkWidget *old_default_widget = NULL;
1952 g_object_ref (default_widget);
1954 if (priv->default_widget)
1956 old_default_widget = priv->default_widget;
1958 if (priv->focus_widget != priv->default_widget ||
1959 !gtk_widget_get_receives_default (priv->default_widget))
1960 _gtk_widget_set_has_default (priv->default_widget, FALSE);
1962 gtk_widget_queue_draw (priv->default_widget);
1965 priv->default_widget = default_widget;
1967 if (priv->default_widget)
1969 if (priv->focus_widget == NULL ||
1970 !gtk_widget_get_receives_default (priv->focus_widget))
1971 _gtk_widget_set_has_default (priv->default_widget, TRUE);
1973 gtk_widget_queue_draw (priv->default_widget);
1976 if (old_default_widget)
1977 g_object_notify (G_OBJECT (old_default_widget), "has-default");
1981 g_object_notify (G_OBJECT (default_widget), "has-default");
1982 g_object_unref (default_widget);
1988 * gtk_window_get_default_widget:
1989 * @window: a #GtkWindow
1991 * Returns the default widget for @window. See gtk_window_set_default()
1994 * Returns: (transfer none): the default widget, or %NULL if there is none.
1999 gtk_window_get_default_widget (GtkWindow *window)
2001 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
2003 return window->priv->default_widget;
2007 handle_keys_changed (gpointer data)
2009 GtkWindow *window = GTK_WINDOW (data);
2010 GtkWindowPrivate *priv = window->priv;
2012 if (priv->keys_changed_handler)
2014 g_source_remove (priv->keys_changed_handler);
2015 priv->keys_changed_handler = 0;
2018 g_signal_emit (window, window_signals[KEYS_CHANGED], 0);
2024 gtk_window_notify_keys_changed (GtkWindow *window)
2026 GtkWindowPrivate *priv = window->priv;
2028 if (!priv->keys_changed_handler)
2029 priv->keys_changed_handler = gdk_threads_add_idle (handle_keys_changed, window);
2033 * gtk_window_add_accel_group:
2034 * @window: window to attach accelerator group to
2035 * @accel_group: a #GtkAccelGroup
2037 * Associate @accel_group with @window, such that calling
2038 * gtk_accel_groups_activate() on @window will activate accelerators
2042 gtk_window_add_accel_group (GtkWindow *window,
2043 GtkAccelGroup *accel_group)
2045 g_return_if_fail (GTK_IS_WINDOW (window));
2046 g_return_if_fail (GTK_IS_ACCEL_GROUP (accel_group));
2048 _gtk_accel_group_attach (accel_group, G_OBJECT (window));
2049 g_signal_connect_object (accel_group, "accel-changed",
2050 G_CALLBACK (gtk_window_notify_keys_changed),
2051 window, G_CONNECT_SWAPPED);
2052 gtk_window_notify_keys_changed (window);
2056 * gtk_window_remove_accel_group:
2057 * @window: a #GtkWindow
2058 * @accel_group: a #GtkAccelGroup
2060 * Reverses the effects of gtk_window_add_accel_group().
2063 gtk_window_remove_accel_group (GtkWindow *window,
2064 GtkAccelGroup *accel_group)
2066 g_return_if_fail (GTK_IS_WINDOW (window));
2067 g_return_if_fail (GTK_IS_ACCEL_GROUP (accel_group));
2069 g_signal_handlers_disconnect_by_func (accel_group,
2070 gtk_window_notify_keys_changed,
2072 _gtk_accel_group_detach (accel_group, G_OBJECT (window));
2073 gtk_window_notify_keys_changed (window);
2076 static GtkMnemonicHash *
2077 gtk_window_get_mnemonic_hash (GtkWindow *window,
2080 GtkWindowPrivate *private = window->priv;
2082 if (!private->mnemonic_hash && create)
2083 private->mnemonic_hash = _gtk_mnemonic_hash_new ();
2085 return private->mnemonic_hash;
2089 * gtk_window_add_mnemonic:
2090 * @window: a #GtkWindow
2091 * @keyval: the mnemonic
2092 * @target: the widget that gets activated by the mnemonic
2094 * Adds a mnemonic to this window.
2097 gtk_window_add_mnemonic (GtkWindow *window,
2101 g_return_if_fail (GTK_IS_WINDOW (window));
2102 g_return_if_fail (GTK_IS_WIDGET (target));
2104 _gtk_mnemonic_hash_add (gtk_window_get_mnemonic_hash (window, TRUE),
2106 gtk_window_notify_keys_changed (window);
2110 * gtk_window_remove_mnemonic:
2111 * @window: a #GtkWindow
2112 * @keyval: the mnemonic
2113 * @target: the widget that gets activated by the mnemonic
2115 * Removes a mnemonic from this window.
2118 gtk_window_remove_mnemonic (GtkWindow *window,
2122 g_return_if_fail (GTK_IS_WINDOW (window));
2123 g_return_if_fail (GTK_IS_WIDGET (target));
2125 _gtk_mnemonic_hash_remove (gtk_window_get_mnemonic_hash (window, TRUE),
2127 gtk_window_notify_keys_changed (window);
2131 * gtk_window_mnemonic_activate:
2132 * @window: a #GtkWindow
2133 * @keyval: the mnemonic
2134 * @modifier: the modifiers
2136 * Activates the targets associated with the mnemonic.
2138 * Returns: %TRUE if the activation is done.
2141 gtk_window_mnemonic_activate (GtkWindow *window,
2143 GdkModifierType modifier)
2145 GtkWindowPrivate *priv;
2147 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
2149 priv = window->priv;
2151 if (priv->mnemonic_modifier == (modifier & gtk_accelerator_get_default_mod_mask ()))
2153 GtkMnemonicHash *mnemonic_hash = gtk_window_get_mnemonic_hash (window, FALSE);
2155 return _gtk_mnemonic_hash_activate (mnemonic_hash, keyval);
2162 * gtk_window_set_mnemonic_modifier:
2163 * @window: a #GtkWindow
2164 * @modifier: the modifier mask used to activate
2165 * mnemonics on this window.
2167 * Sets the mnemonic modifier for this window.
2170 gtk_window_set_mnemonic_modifier (GtkWindow *window,
2171 GdkModifierType modifier)
2173 GtkWindowPrivate *priv;
2175 g_return_if_fail (GTK_IS_WINDOW (window));
2176 g_return_if_fail ((modifier & ~GDK_MODIFIER_MASK) == 0);
2178 priv = window->priv;
2180 priv->mnemonic_modifier = modifier;
2181 gtk_window_notify_keys_changed (window);
2185 * gtk_window_get_mnemonic_modifier:
2186 * @window: a #GtkWindow
2188 * Returns the mnemonic modifier for this window. See
2189 * gtk_window_set_mnemonic_modifier().
2191 * Return value: the modifier mask used to activate
2192 * mnemonics on this window.
2195 gtk_window_get_mnemonic_modifier (GtkWindow *window)
2197 g_return_val_if_fail (GTK_IS_WINDOW (window), 0);
2199 return window->priv->mnemonic_modifier;
2203 * gtk_window_set_position:
2204 * @window: a #GtkWindow.
2205 * @position: a position constraint.
2207 * Sets a position constraint for this window. If the old or new
2208 * constraint is %GTK_WIN_POS_CENTER_ALWAYS, this will also cause
2209 * the window to be repositioned to satisfy the new constraint.
2212 gtk_window_set_position (GtkWindow *window,
2213 GtkWindowPosition position)
2215 GtkWindowPrivate *priv;
2217 g_return_if_fail (GTK_IS_WINDOW (window));
2219 priv = window->priv;
2221 if (position == GTK_WIN_POS_CENTER_ALWAYS ||
2222 priv->position == GTK_WIN_POS_CENTER_ALWAYS)
2224 GtkWindowGeometryInfo *info;
2226 info = gtk_window_get_geometry_info (window, TRUE);
2228 /* this flag causes us to re-request the CENTER_ALWAYS
2229 * constraint in gtk_window_move_resize(), see
2230 * comment in that function.
2232 info->position_constraints_changed = TRUE;
2234 gtk_widget_queue_resize_no_redraw (GTK_WIDGET (window));
2237 priv->position = position;
2239 g_object_notify (G_OBJECT (window), "window-position");
2243 * gtk_window_activate_focus:
2244 * @window: a #GtkWindow
2246 * Activates the current focused widget within the window.
2248 * Return value: %TRUE if a widget got activated.
2251 gtk_window_activate_focus (GtkWindow *window)
2253 GtkWindowPrivate *priv;
2255 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
2257 priv = window->priv;
2259 if (priv->focus_widget && gtk_widget_is_sensitive (priv->focus_widget))
2260 return gtk_widget_activate (priv->focus_widget);
2266 * gtk_window_get_focus:
2267 * @window: a #GtkWindow
2269 * Retrieves the current focused widget within the window.
2270 * Note that this is the widget that would have the focus
2271 * if the toplevel window focused; if the toplevel window
2272 * is not focused then <literal>gtk_widget_has_focus (widget)</literal> will
2273 * not be %TRUE for the widget.
2275 * Return value: (transfer none): the currently focused widget, or %NULL if there is none.
2278 gtk_window_get_focus (GtkWindow *window)
2280 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
2282 return window->priv->focus_widget;
2286 * gtk_window_activate_default:
2287 * @window: a #GtkWindow
2289 * Activates the default widget for the window, unless the current
2290 * focused widget has been configured to receive the default action
2291 * (see gtk_widget_set_receives_default()), in which case the
2292 * focused widget is activated.
2294 * Return value: %TRUE if a widget got activated.
2297 gtk_window_activate_default (GtkWindow *window)
2299 GtkWindowPrivate *priv;
2301 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
2303 priv = window->priv;
2305 if (priv->default_widget && gtk_widget_is_sensitive (priv->default_widget) &&
2306 (!priv->focus_widget || !gtk_widget_get_receives_default (priv->focus_widget)))
2307 return gtk_widget_activate (priv->default_widget);
2308 else if (priv->focus_widget && gtk_widget_is_sensitive (priv->focus_widget))
2309 return gtk_widget_activate (priv->focus_widget);
2315 * gtk_window_set_modal:
2316 * @window: a #GtkWindow
2317 * @modal: whether the window is modal
2319 * Sets a window modal or non-modal. Modal windows prevent interaction
2320 * with other windows in the same application. To keep modal dialogs
2321 * on top of main application windows, use
2322 * gtk_window_set_transient_for() to make the dialog transient for the
2323 * parent; most <link linkend="gtk-X11-arch">window managers</link>
2324 * will then disallow lowering the dialog below the parent.
2329 gtk_window_set_modal (GtkWindow *window,
2332 GtkWindowPrivate *priv;
2335 g_return_if_fail (GTK_IS_WINDOW (window));
2337 priv = window->priv;
2339 modal = modal != FALSE;
2340 if (priv->modal == modal)
2343 priv->modal = modal;
2344 widget = GTK_WIDGET (window);
2346 /* adjust desired modality state */
2347 if (gtk_widget_get_realized (widget))
2350 gdk_window_set_modal_hint (gtk_widget_get_window (widget), TRUE);
2352 gdk_window_set_modal_hint (gtk_widget_get_window (widget), FALSE);
2355 if (gtk_widget_get_visible (widget))
2358 gtk_grab_add (widget);
2360 gtk_grab_remove (widget);
2363 g_object_notify (G_OBJECT (window), "modal");
2367 * gtk_window_get_modal:
2368 * @window: a #GtkWindow
2370 * Returns whether the window is modal. See gtk_window_set_modal().
2372 * Return value: %TRUE if the window is set to be modal and
2373 * establishes a grab when shown
2376 gtk_window_get_modal (GtkWindow *window)
2378 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
2380 return window->priv->modal;
2384 * gtk_window_list_toplevels:
2386 * Returns a list of all existing toplevel windows. The widgets
2387 * in the list are not individually referenced. If you want
2388 * to iterate through the list and perform actions involving
2389 * callbacks that might destroy the widgets, you <emphasis>must</emphasis> call
2390 * <literal>g_list_foreach (result, (GFunc)g_object_ref, NULL)</literal> first, and
2391 * then unref all the widgets afterwards.
2393 * Return value: (element-type GtkWidget) (transfer container): list of toplevel widgets
2396 gtk_window_list_toplevels (void)
2401 for (slist = toplevel_list; slist; slist = slist->next)
2402 list = g_list_prepend (list, slist->data);
2408 remove_attach_widget (GtkWindow *window)
2410 GtkWindowPrivate *priv = window->priv;
2412 if (priv->attach_widget)
2414 _gtk_widget_remove_attached_window (priv->attach_widget, window);
2416 g_object_unref (priv->attach_widget);
2417 priv->attach_widget = NULL;
2422 gtk_window_dispose (GObject *object)
2424 GtkWindow *window = GTK_WINDOW (object);
2426 gtk_window_set_focus (window, NULL);
2427 gtk_window_set_default (window, NULL);
2429 remove_attach_widget (GTK_WINDOW (object));
2431 G_OBJECT_CLASS (gtk_window_parent_class)->dispose (object);
2435 parent_destroyed_callback (GtkWindow *parent, GtkWindow *child)
2437 gtk_widget_destroy (GTK_WIDGET (child));
2441 connect_parent_destroyed (GtkWindow *window)
2443 GtkWindowPrivate *priv = window->priv;
2445 if (priv->transient_parent)
2447 g_signal_connect (priv->transient_parent,
2449 G_CALLBACK (parent_destroyed_callback),
2455 disconnect_parent_destroyed (GtkWindow *window)
2457 GtkWindowPrivate *priv = window->priv;
2459 if (priv->transient_parent)
2461 g_signal_handlers_disconnect_by_func (priv->transient_parent,
2462 parent_destroyed_callback,
2468 gtk_window_transient_parent_realized (GtkWidget *parent,
2471 if (gtk_widget_get_realized (window))
2472 gdk_window_set_transient_for (gtk_widget_get_window (window),
2473 gtk_widget_get_window (parent));
2477 gtk_window_transient_parent_unrealized (GtkWidget *parent,
2480 if (gtk_widget_get_realized (window))
2481 gdk_property_delete (gtk_widget_get_window (window),
2482 gdk_atom_intern_static_string ("WM_TRANSIENT_FOR"));
2486 gtk_window_transient_parent_screen_changed (GtkWindow *parent,
2490 gtk_window_set_screen (window, parent->priv->screen);
2494 gtk_window_unset_transient_for (GtkWindow *window)
2496 GtkWindowPrivate *priv = window->priv;
2498 if (priv->transient_parent)
2500 g_signal_handlers_disconnect_by_func (priv->transient_parent,
2501 gtk_window_transient_parent_realized,
2503 g_signal_handlers_disconnect_by_func (priv->transient_parent,
2504 gtk_window_transient_parent_unrealized,
2506 g_signal_handlers_disconnect_by_func (priv->transient_parent,
2507 gtk_window_transient_parent_screen_changed,
2509 g_signal_handlers_disconnect_by_func (priv->transient_parent,
2510 gtk_widget_destroyed,
2511 &priv->transient_parent);
2513 if (priv->destroy_with_parent)
2514 disconnect_parent_destroyed (window);
2516 priv->transient_parent = NULL;
2518 if (priv->transient_parent_group)
2520 priv->transient_parent_group = FALSE;
2521 gtk_window_group_remove_window (priv->group,
2528 * gtk_window_set_transient_for:
2529 * @window: a #GtkWindow
2530 * @parent: (allow-none): parent window, or %NULL
2532 * Dialog windows should be set transient for the main application
2533 * window they were spawned from. This allows <link
2534 * linkend="gtk-X11-arch">window managers</link> to e.g. keep the
2535 * dialog on top of the main window, or center the dialog over the
2536 * main window. gtk_dialog_new_with_buttons() and other convenience
2537 * functions in GTK+ will sometimes call
2538 * gtk_window_set_transient_for() on your behalf.
2540 * Passing %NULL for @parent unsets the current transient window.
2542 * On Windows, this function puts the child window on top of the parent,
2543 * much as the window manager would have done on X.
2546 gtk_window_set_transient_for (GtkWindow *window,
2549 GtkWindowPrivate *priv;
2551 g_return_if_fail (GTK_IS_WINDOW (window));
2552 g_return_if_fail (parent == NULL || GTK_IS_WINDOW (parent));
2553 g_return_if_fail (window != parent);
2555 priv = window->priv;
2557 if (priv->transient_parent)
2559 if (gtk_widget_get_realized (GTK_WIDGET (window)) &&
2560 gtk_widget_get_realized (GTK_WIDGET (priv->transient_parent)) &&
2561 (!parent || !gtk_widget_get_realized (GTK_WIDGET (parent))))
2562 gtk_window_transient_parent_unrealized (GTK_WIDGET (priv->transient_parent),
2563 GTK_WIDGET (window));
2565 gtk_window_unset_transient_for (window);
2568 priv->transient_parent = parent;
2572 g_signal_connect (parent, "destroy",
2573 G_CALLBACK (gtk_widget_destroyed),
2574 &priv->transient_parent);
2575 g_signal_connect (parent, "realize",
2576 G_CALLBACK (gtk_window_transient_parent_realized),
2578 g_signal_connect (parent, "unrealize",
2579 G_CALLBACK (gtk_window_transient_parent_unrealized),
2581 g_signal_connect (parent, "notify::screen",
2582 G_CALLBACK (gtk_window_transient_parent_screen_changed),
2585 gtk_window_set_screen (window, parent->priv->screen);
2587 if (priv->destroy_with_parent)
2588 connect_parent_destroyed (window);
2590 if (gtk_widget_get_realized (GTK_WIDGET (window)) &&
2591 gtk_widget_get_realized (GTK_WIDGET (parent)))
2592 gtk_window_transient_parent_realized (GTK_WIDGET (parent),
2593 GTK_WIDGET (window));
2595 if (parent->priv->group)
2597 gtk_window_group_add_window (parent->priv->group, window);
2598 priv->transient_parent_group = TRUE;
2604 * gtk_window_get_transient_for:
2605 * @window: a #GtkWindow
2607 * Fetches the transient parent for this window. See
2608 * gtk_window_set_transient_for().
2610 * Return value: (transfer none): the transient parent for this window, or %NULL
2611 * if no transient parent has been set.
2614 gtk_window_get_transient_for (GtkWindow *window)
2616 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
2618 return window->priv->transient_parent;
2622 * gtk_window_set_attached_to:
2623 * @window: a #GtkWindow
2624 * @attach_widget (allow-none): a #GtkWidget, or %NULL
2626 * Marks @window as attached to @attach_widget. This creates a logical binding
2627 * between the window and the widget it belongs to, which is used by GTK+ to
2628 * propagate information such as styling or accessibility to @window as if it
2629 * was a children of @attach_widget.
2631 * Examples of places where specifying this relation is useful are for instance
2632 * a #GtkMenu created by a #GtkComboBox, a completion popup window
2633 * created by #GtkEntry or a typeahead search entry created by #GtkTreeView.
2635 * Note that this function should not be confused with
2636 * gtk_window_set_transient_for(), which specifies a window manager relation
2637 * between two toplevels instead.
2639 * Passing %NULL for @attach_widget detaches the window.
2644 gtk_window_set_attached_to (GtkWindow *window,
2645 GtkWidget *attach_widget)
2647 GtkWindowPrivate *priv;
2649 g_return_if_fail (GTK_IS_WINDOW (window));
2650 g_return_if_fail (GTK_WIDGET (window) != attach_widget);
2652 priv = window->priv;
2654 remove_attach_widget (window);
2656 priv->attach_widget = attach_widget;
2658 if (priv->attach_widget)
2660 _gtk_widget_add_attached_window (priv->attach_widget, window);
2662 g_object_ref_sink (priv->attach_widget);
2665 /* Update the style, as the widget path might change. */
2666 gtk_widget_reset_style (GTK_WIDGET (window));
2670 * gtk_window_get_attached_to:
2671 * @window: a #GtkWindow
2673 * Fetches the attach widget for this window. See
2674 * gtk_window_set_attached_to().
2676 * Return value: (transfer none): the widget where the window is attached,
2677 * or %NULL if the window is not attached to any widget.
2682 gtk_window_get_attached_to (GtkWindow *window)
2684 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
2686 return window->priv->attach_widget;
2690 * gtk_window_set_opacity:
2691 * @window: a #GtkWindow
2692 * @opacity: desired opacity, between 0 and 1
2694 * Request the windowing system to make @window partially transparent,
2695 * with opacity 0 being fully transparent and 1 fully opaque. (Values
2696 * of the opacity parameter are clamped to the [0,1] range.) On X11
2697 * this has any effect only on X screens with a compositing manager
2698 * running. See gtk_widget_is_composited(). On Windows it should work
2701 * Note that setting a window's opacity after the window has been
2702 * shown causes it to flicker once on Windows.
2707 gtk_window_set_opacity (GtkWindow *window,
2710 GtkWindowPrivate *priv;
2712 g_return_if_fail (GTK_IS_WINDOW (window));
2714 priv = window->priv;
2718 else if (opacity > 1.0)
2721 priv->opacity_set = TRUE;
2722 priv->opacity = opacity;
2724 if (gtk_widget_get_realized (GTK_WIDGET (window)))
2725 gdk_window_set_opacity (gtk_widget_get_window (GTK_WIDGET (window)),
2730 * gtk_window_get_opacity:
2731 * @window: a #GtkWindow
2733 * Fetches the requested opacity for this window. See
2734 * gtk_window_set_opacity().
2736 * Return value: the requested opacity for this window.
2741 gtk_window_get_opacity (GtkWindow *window)
2743 g_return_val_if_fail (GTK_IS_WINDOW (window), 0.0);
2745 return window->priv->opacity;
2749 * gtk_window_get_application:
2750 * @window: a #GtkWindow
2752 * Gets the #GtkApplication associated with the window (if any).
2754 * Return value: (transfer none): a #GtkApplication, or %NULL
2759 gtk_window_get_application (GtkWindow *window)
2761 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
2763 return window->priv->application;
2767 gtk_window_release_application (GtkWindow *window)
2769 if (window->priv->application)
2771 GtkApplication *application;
2773 /* steal reference into temp variable */
2774 application = window->priv->application;
2775 window->priv->application = NULL;
2777 gtk_application_remove_window (application, window);
2778 g_object_unref (application);
2783 * gtk_window_set_application:
2784 * @window: a #GtkWindow
2785 * @application: (allow-none): a #GtkApplication, or %NULL
2787 * Sets or unsets the #GtkApplication associated with the window.
2789 * The application will be kept alive for at least as long as the window
2795 gtk_window_set_application (GtkWindow *window,
2796 GtkApplication *application)
2798 GtkWindowPrivate *priv;
2800 g_return_if_fail (GTK_IS_WINDOW (window));
2802 priv = window->priv;
2803 if (priv->application != application)
2805 gtk_window_release_application (window);
2807 priv->application = application;
2809 if (priv->application != NULL)
2811 g_object_ref (priv->application);
2813 gtk_application_add_window (priv->application, window);
2816 g_object_notify (G_OBJECT (window), "application");
2821 * gtk_window_set_type_hint:
2822 * @window: a #GtkWindow
2823 * @hint: the window type
2825 * By setting the type hint for the window, you allow the window
2826 * manager to decorate and handle the window in a way which is
2827 * suitable to the function of the window in your application.
2829 * This function should be called before the window becomes visible.
2831 * gtk_dialog_new_with_buttons() and other convenience functions in GTK+
2832 * will sometimes call gtk_window_set_type_hint() on your behalf.
2836 gtk_window_set_type_hint (GtkWindow *window,
2837 GdkWindowTypeHint hint)
2839 GtkWindowPrivate *priv;
2841 g_return_if_fail (GTK_IS_WINDOW (window));
2842 g_return_if_fail (!gtk_widget_get_mapped (GTK_WIDGET (window)));
2844 priv = window->priv;
2846 if (hint < GDK_WINDOW_TYPE_HINT_DROPDOWN_MENU)
2847 priv->type_hint = hint;
2849 priv->type_hint = GDK_WINDOW_TYPE_HINT_NORMAL;
2851 priv->reset_type_hint = TRUE;
2852 priv->gdk_type_hint = hint;
2856 * gtk_window_get_type_hint:
2857 * @window: a #GtkWindow
2859 * Gets the type hint for this window. See gtk_window_set_type_hint().
2861 * Return value: the type hint for @window.
2864 gtk_window_get_type_hint (GtkWindow *window)
2866 g_return_val_if_fail (GTK_IS_WINDOW (window), GDK_WINDOW_TYPE_HINT_NORMAL);
2868 return window->priv->gdk_type_hint;
2872 * gtk_window_set_skip_taskbar_hint:
2873 * @window: a #GtkWindow
2874 * @setting: %TRUE to keep this window from appearing in the task bar
2876 * Windows may set a hint asking the desktop environment not to display
2877 * the window in the task bar. This function sets this hint.
2882 gtk_window_set_skip_taskbar_hint (GtkWindow *window,
2885 GtkWindowPrivate *priv;
2887 g_return_if_fail (GTK_IS_WINDOW (window));
2889 priv = window->priv;
2891 setting = setting != FALSE;
2893 if (priv->skips_taskbar != setting)
2895 priv->skips_taskbar = setting;
2896 if (gtk_widget_get_realized (GTK_WIDGET (window)))
2897 gdk_window_set_skip_taskbar_hint (gtk_widget_get_window (GTK_WIDGET (window)),
2898 priv->skips_taskbar);
2899 g_object_notify (G_OBJECT (window), "skip-taskbar-hint");
2904 * gtk_window_get_skip_taskbar_hint:
2905 * @window: a #GtkWindow
2907 * Gets the value set by gtk_window_set_skip_taskbar_hint()
2909 * Return value: %TRUE if window shouldn't be in taskbar
2914 gtk_window_get_skip_taskbar_hint (GtkWindow *window)
2916 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
2918 return window->priv->skips_taskbar;
2922 * gtk_window_set_skip_pager_hint:
2923 * @window: a #GtkWindow
2924 * @setting: %TRUE to keep this window from appearing in the pager
2926 * Windows may set a hint asking the desktop environment not to display
2927 * the window in the pager. This function sets this hint.
2928 * (A "pager" is any desktop navigation tool such as a workspace
2929 * switcher that displays a thumbnail representation of the windows
2935 gtk_window_set_skip_pager_hint (GtkWindow *window,
2938 GtkWindowPrivate *priv;
2940 g_return_if_fail (GTK_IS_WINDOW (window));
2942 priv = window->priv;
2944 setting = setting != FALSE;
2946 if (priv->skips_pager != setting)
2948 priv->skips_pager = setting;
2949 if (gtk_widget_get_realized (GTK_WIDGET (window)))
2950 gdk_window_set_skip_pager_hint (gtk_widget_get_window (GTK_WIDGET (window)),
2952 g_object_notify (G_OBJECT (window), "skip-pager-hint");
2957 * gtk_window_get_skip_pager_hint:
2958 * @window: a #GtkWindow
2960 * Gets the value set by gtk_window_set_skip_pager_hint().
2962 * Return value: %TRUE if window shouldn't be in pager
2967 gtk_window_get_skip_pager_hint (GtkWindow *window)
2969 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
2971 return window->priv->skips_pager;
2975 * gtk_window_set_urgency_hint:
2976 * @window: a #GtkWindow
2977 * @setting: %TRUE to mark this window as urgent
2979 * Windows may set a hint asking the desktop environment to draw
2980 * the users attention to the window. This function sets this hint.
2985 gtk_window_set_urgency_hint (GtkWindow *window,
2988 GtkWindowPrivate *priv;
2990 g_return_if_fail (GTK_IS_WINDOW (window));
2992 priv = window->priv;
2994 setting = setting != FALSE;
2996 if (priv->urgent != setting)
2998 priv->urgent = setting;
2999 if (gtk_widget_get_realized (GTK_WIDGET (window)))
3000 gdk_window_set_urgency_hint (gtk_widget_get_window (GTK_WIDGET (window)),
3002 g_object_notify (G_OBJECT (window), "urgency-hint");
3007 * gtk_window_get_urgency_hint:
3008 * @window: a #GtkWindow
3010 * Gets the value set by gtk_window_set_urgency_hint()
3012 * Return value: %TRUE if window is urgent
3017 gtk_window_get_urgency_hint (GtkWindow *window)
3019 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
3021 return window->priv->urgent;
3025 * gtk_window_set_accept_focus:
3026 * @window: a #GtkWindow
3027 * @setting: %TRUE to let this window receive input focus
3029 * Windows may set a hint asking the desktop environment not to receive
3030 * the input focus. This function sets this hint.
3035 gtk_window_set_accept_focus (GtkWindow *window,
3038 GtkWindowPrivate *priv;
3040 g_return_if_fail (GTK_IS_WINDOW (window));
3042 priv = window->priv;
3044 setting = setting != FALSE;
3046 if (priv->accept_focus != setting)
3048 priv->accept_focus = setting;
3049 if (gtk_widget_get_realized (GTK_WIDGET (window)))
3050 gdk_window_set_accept_focus (gtk_widget_get_window (GTK_WIDGET (window)),
3051 priv->accept_focus);
3052 g_object_notify (G_OBJECT (window), "accept-focus");
3057 * gtk_window_get_accept_focus:
3058 * @window: a #GtkWindow
3060 * Gets the value set by gtk_window_set_accept_focus().
3062 * Return value: %TRUE if window should receive the input focus
3067 gtk_window_get_accept_focus (GtkWindow *window)
3069 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
3071 return window->priv->accept_focus;
3075 * gtk_window_set_focus_on_map:
3076 * @window: a #GtkWindow
3077 * @setting: %TRUE to let this window receive input focus on map
3079 * Windows may set a hint asking the desktop environment not to receive
3080 * the input focus when the window is mapped. This function sets this
3086 gtk_window_set_focus_on_map (GtkWindow *window,
3089 GtkWindowPrivate *priv;
3091 g_return_if_fail (GTK_IS_WINDOW (window));
3093 priv = window->priv;
3095 setting = setting != FALSE;
3097 if (priv->focus_on_map != setting)
3099 priv->focus_on_map = setting;
3100 if (gtk_widget_get_realized (GTK_WIDGET (window)))
3101 gdk_window_set_focus_on_map (gtk_widget_get_window (GTK_WIDGET (window)),
3102 priv->focus_on_map);
3103 g_object_notify (G_OBJECT (window), "focus-on-map");
3108 * gtk_window_get_focus_on_map:
3109 * @window: a #GtkWindow
3111 * Gets the value set by gtk_window_set_focus_on_map().
3113 * Return value: %TRUE if window should receive the input focus when
3119 gtk_window_get_focus_on_map (GtkWindow *window)
3121 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
3123 return window->priv->focus_on_map;
3127 * gtk_window_set_destroy_with_parent:
3128 * @window: a #GtkWindow
3129 * @setting: whether to destroy @window with its transient parent
3131 * If @setting is %TRUE, then destroying the transient parent of @window
3132 * will also destroy @window itself. This is useful for dialogs that
3133 * shouldn't persist beyond the lifetime of the main window they're
3134 * associated with, for example.
3137 gtk_window_set_destroy_with_parent (GtkWindow *window,
3140 GtkWindowPrivate *priv;
3142 g_return_if_fail (GTK_IS_WINDOW (window));
3144 priv = window->priv;
3146 if (priv->destroy_with_parent == (setting != FALSE))
3149 if (priv->destroy_with_parent)
3151 disconnect_parent_destroyed (window);
3155 connect_parent_destroyed (window);
3158 priv->destroy_with_parent = setting;
3160 g_object_notify (G_OBJECT (window), "destroy-with-parent");
3164 * gtk_window_get_destroy_with_parent:
3165 * @window: a #GtkWindow
3167 * Returns whether the window will be destroyed with its transient parent. See
3168 * gtk_window_set_destroy_with_parent ().
3170 * Return value: %TRUE if the window will be destroyed with its transient parent.
3173 gtk_window_get_destroy_with_parent (GtkWindow *window)
3175 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
3177 return window->priv->destroy_with_parent;
3181 * gtk_window_set_hide_titlebar_when_maximized:
3182 * @window: a #GtkWindow
3183 * @setting: whether to hide the titlebar when @window is maximized
3185 * If @setting is %TRUE, then @window will request that it's titlebar
3186 * should be hidden when maximized.
3187 * This is useful for windows that don't convey any information other
3188 * than the application name in the titlebar, to put the available
3189 * screen space to better use. If the underlying window system does not
3190 * support the request, the setting will not have any effect.
3195 gtk_window_set_hide_titlebar_when_maximized (GtkWindow *window,
3198 g_return_if_fail (GTK_IS_WINDOW (window));
3200 #ifdef GDK_WINDOWING_X11
3202 GdkWindow *gdk_window;
3204 gdk_window = gtk_widget_get_window (GTK_WIDGET (window));
3206 if (GDK_IS_X11_WINDOW (gdk_window))
3207 gdk_x11_window_set_hide_titlebar_when_maximized (gdk_window, setting);
3211 window->priv->hide_titlebar_when_maximized = setting;
3212 g_object_notify (G_OBJECT (window), "hide-titlebar-when-maximized");
3216 * gtk_window_get_hide_titlebar_when_maximized:
3217 * @window: a #GtkWindow
3219 * Returns whether the window has requested to have its titlebar hidden
3220 * when maximized. See gtk_window_set_hide_titlebar_when_maximized ().
3222 * Return value: %TRUE if the window has requested to have its titlebar
3223 * hidden when maximized
3228 gtk_window_get_hide_titlebar_when_maximized (GtkWindow *window)
3230 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
3232 return window->priv->hide_titlebar_when_maximized;
3235 static GtkWindowGeometryInfo*
3236 gtk_window_get_geometry_info (GtkWindow *window,
3239 GtkWindowPrivate *priv = window->priv;
3240 GtkWindowGeometryInfo *info;
3242 info = priv->geometry_info;
3243 if (!info && create)
3245 info = g_new0 (GtkWindowGeometryInfo, 1);
3247 info->default_width = -1;
3248 info->default_height = -1;
3249 info->resize_width = -1;
3250 info->resize_height = -1;
3251 info->initial_x = 0;
3252 info->initial_y = 0;
3253 info->initial_pos_set = FALSE;
3254 info->default_is_geometry = FALSE;
3255 info->position_constraints_changed = FALSE;
3256 info->last.configure_request.x = 0;
3257 info->last.configure_request.y = 0;
3258 info->last.configure_request.width = -1;
3259 info->last.configure_request.height = -1;
3260 info->widget = NULL;
3262 priv->geometry_info = info;
3269 * gtk_window_set_geometry_hints:
3270 * @window: a #GtkWindow
3271 * @geometry_widget: (allow-none): widget the geometry hints will be applied to or %NULL
3272 * @geometry: (allow-none): struct containing geometry information or %NULL
3273 * @geom_mask: mask indicating which struct fields should be paid attention to
3275 * This function sets up hints about how a window can be resized by
3276 * the user. You can set a minimum and maximum size; allowed resize
3277 * increments (e.g. for xterm, you can only resize by the size of a
3278 * character); aspect ratios; and more. See the #GdkGeometry struct.
3282 gtk_window_set_geometry_hints (GtkWindow *window,
3283 GtkWidget *geometry_widget,
3284 GdkGeometry *geometry,
3285 GdkWindowHints geom_mask)
3287 GtkWindowGeometryInfo *info;
3289 g_return_if_fail (GTK_IS_WINDOW (window));
3290 g_return_if_fail (geometry_widget == NULL || GTK_IS_WIDGET (geometry_widget));
3292 info = gtk_window_get_geometry_info (window, TRUE);
3295 g_signal_handlers_disconnect_by_func (info->widget,
3296 gtk_widget_destroyed,
3299 info->widget = geometry_widget;
3301 g_signal_connect (geometry_widget, "destroy",
3302 G_CALLBACK (gtk_widget_destroyed),
3306 info->geometry = *geometry;
3308 /* We store gravity in priv->gravity not in the hints. */
3309 info->mask = geom_mask & ~(GDK_HINT_WIN_GRAVITY);
3311 if (geom_mask & GDK_HINT_WIN_GRAVITY)
3313 gtk_window_set_gravity (window, geometry->win_gravity);
3316 gtk_widget_queue_resize_no_redraw (GTK_WIDGET (window));
3320 * gtk_window_set_decorated:
3321 * @window: a #GtkWindow
3322 * @setting: %TRUE to decorate the window
3324 * By default, windows are decorated with a title bar, resize
3325 * controls, etc. Some <link linkend="gtk-X11-arch">window
3326 * managers</link> allow GTK+ to disable these decorations, creating a
3327 * borderless window. If you set the decorated property to %FALSE
3328 * using this function, GTK+ will do its best to convince the window
3329 * manager not to decorate the window. Depending on the system, this
3330 * function may not have any effect when called on a window that is
3331 * already visible, so you should call it before calling gtk_widget_show().
3333 * On Windows, this function always works, since there's no window manager
3338 gtk_window_set_decorated (GtkWindow *window,
3341 GtkWindowPrivate *priv;
3342 GdkWindow *gdk_window;
3344 g_return_if_fail (GTK_IS_WINDOW (window));
3346 priv = window->priv;
3348 setting = setting != FALSE;
3350 if (setting == priv->decorated)
3353 priv->decorated = setting;
3355 gdk_window = gtk_widget_get_window (GTK_WIDGET (window));
3358 if (priv->decorated)
3359 gdk_window_set_decorations (gdk_window,
3362 gdk_window_set_decorations (gdk_window,
3366 g_object_notify (G_OBJECT (window), "decorated");
3370 * gtk_window_get_decorated:
3371 * @window: a #GtkWindow
3373 * Returns whether the window has been set to have decorations
3374 * such as a title bar via gtk_window_set_decorated().
3376 * Return value: %TRUE if the window has been set to have decorations
3379 gtk_window_get_decorated (GtkWindow *window)
3381 g_return_val_if_fail (GTK_IS_WINDOW (window), TRUE);
3383 return window->priv->decorated;
3387 * gtk_window_set_deletable:
3388 * @window: a #GtkWindow
3389 * @setting: %TRUE to decorate the window as deletable
3391 * By default, windows have a close button in the window frame. Some
3392 * <link linkend="gtk-X11-arch">window managers</link> allow GTK+ to
3393 * disable this button. If you set the deletable property to %FALSE
3394 * using this function, GTK+ will do its best to convince the window
3395 * manager not to show a close button. Depending on the system, this
3396 * function may not have any effect when called on a window that is
3397 * already visible, so you should call it before calling gtk_window_show().
3399 * On Windows, this function always works, since there's no window manager
3405 gtk_window_set_deletable (GtkWindow *window,
3408 GtkWindowPrivate *priv;
3409 GdkWindow *gdk_window;
3411 g_return_if_fail (GTK_IS_WINDOW (window));
3413 priv = window->priv;
3415 setting = setting != FALSE;
3417 if (setting == priv->deletable)
3420 priv->deletable = setting;
3422 gdk_window = gtk_widget_get_window (GTK_WIDGET (window));
3425 if (priv->deletable)
3426 gdk_window_set_functions (gdk_window,
3429 gdk_window_set_functions (gdk_window,
3430 GDK_FUNC_ALL | GDK_FUNC_CLOSE);
3433 g_object_notify (G_OBJECT (window), "deletable");
3437 * gtk_window_get_deletable:
3438 * @window: a #GtkWindow
3440 * Returns whether the window has been set to have a close button
3441 * via gtk_window_set_deletable().
3443 * Return value: %TRUE if the window has been set to have a close button
3448 gtk_window_get_deletable (GtkWindow *window)
3450 g_return_val_if_fail (GTK_IS_WINDOW (window), TRUE);
3452 return window->priv->deletable;
3455 static GtkWindowIconInfo*
3456 get_icon_info (GtkWindow *window)
3458 return g_object_get_qdata (G_OBJECT (window), quark_gtk_window_icon_info);
3462 free_icon_info (GtkWindowIconInfo *info)
3464 g_free (info->icon_name);
3465 g_slice_free (GtkWindowIconInfo, info);
3469 static GtkWindowIconInfo*
3470 ensure_icon_info (GtkWindow *window)
3472 GtkWindowIconInfo *info;
3474 info = get_icon_info (window);
3478 info = g_slice_new0 (GtkWindowIconInfo);
3479 g_object_set_qdata_full (G_OBJECT (window),
3480 quark_gtk_window_icon_info,
3482 (GDestroyNotify)free_icon_info);
3489 icon_list_from_theme (GtkWidget *widget,
3494 GtkIconTheme *icon_theme;
3499 icon_theme = gtk_icon_theme_get_for_screen (gtk_widget_get_screen (widget));
3501 sizes = gtk_icon_theme_get_icon_sizes (icon_theme, name);
3504 for (i = 0; sizes[i]; i++)
3507 * We need an EWMH extension to handle scalable icons
3508 * by passing their name to the WM. For now just use a
3512 icon = gtk_icon_theme_load_icon (icon_theme, name,
3515 icon = gtk_icon_theme_load_icon (icon_theme, name,
3518 list = g_list_append (list, icon);
3528 gtk_window_realize_icon (GtkWindow *window)
3530 GtkWindowPrivate *priv = window->priv;
3532 GtkWindowIconInfo *info;
3533 GdkWindow *gdk_window;
3536 widget = GTK_WIDGET (window);
3537 gdk_window = gtk_widget_get_window (widget);
3539 g_return_if_fail (gdk_window != NULL);
3541 /* no point setting an icon on override-redirect */
3542 if (priv->type == GTK_WINDOW_POPUP)
3547 info = ensure_icon_info (window);
3552 info->using_default_icon = FALSE;
3553 info->using_parent_icon = FALSE;
3554 info->using_themed_icon = FALSE;
3556 icon_list = info->icon_list;
3558 /* Look up themed icon */
3559 if (icon_list == NULL && info->icon_name)
3561 icon_list = icon_list_from_theme (widget, info->icon_name);
3563 info->using_themed_icon = TRUE;
3566 /* Inherit from transient parent */
3567 if (icon_list == NULL && priv->transient_parent)
3569 icon_list = ensure_icon_info (priv->transient_parent)->icon_list;
3571 info->using_parent_icon = TRUE;
3574 /* Inherit from default */
3575 if (icon_list == NULL)
3577 icon_list = default_icon_list;
3579 info->using_default_icon = TRUE;
3582 /* Look up themed icon */
3583 if (icon_list == NULL && default_icon_name)
3585 icon_list = icon_list_from_theme (widget, default_icon_name);
3586 info->using_default_icon = TRUE;
3587 info->using_themed_icon = TRUE;
3590 info->realized = TRUE;
3592 gdk_window_set_icon_list (gtk_widget_get_window (widget), icon_list);
3594 if (info->using_themed_icon)
3596 GtkIconTheme *icon_theme;
3598 g_list_free_full (icon_list, g_object_unref);
3600 icon_theme = gtk_icon_theme_get_for_screen (gtk_widget_get_screen (GTK_WIDGET (window)));
3601 g_signal_connect (icon_theme, "changed",
3602 G_CALLBACK (update_themed_icon), window);
3607 gtk_window_unrealize_icon (GtkWindow *window)
3609 GtkWindowIconInfo *info;
3611 info = get_icon_info (window);
3616 if (info->using_themed_icon)
3618 GtkIconTheme *icon_theme;
3620 icon_theme = gtk_icon_theme_get_for_screen (gtk_widget_get_screen (GTK_WIDGET (window)));
3622 g_signal_handlers_disconnect_by_func (icon_theme, update_themed_icon, window);
3625 /* We don't clear the properties on the window, just figure the
3626 * window is going away.
3629 info->realized = FALSE;
3634 * gtk_window_set_icon_list:
3635 * @window: a #GtkWindow
3636 * @list: (element-type GdkPixbuf): list of #GdkPixbuf
3638 * Sets up the icon representing a #GtkWindow. The icon is used when
3639 * the window is minimized (also known as iconified). Some window
3640 * managers or desktop environments may also place it in the window
3641 * frame, or display it in other contexts.
3643 * gtk_window_set_icon_list() allows you to pass in the same icon in
3644 * several hand-drawn sizes. The list should contain the natural sizes
3645 * your icon is available in; that is, don't scale the image before
3646 * passing it to GTK+. Scaling is postponed until the last minute,
3647 * when the desired final size is known, to allow best quality.
3649 * By passing several sizes, you may improve the final image quality
3650 * of the icon, by reducing or eliminating automatic image scaling.
3652 * Recommended sizes to provide: 16x16, 32x32, 48x48 at minimum, and
3653 * larger images (64x64, 128x128) if you have them.
3655 * See also gtk_window_set_default_icon_list() to set the icon
3656 * for all windows in your application in one go.
3658 * Note that transient windows (those who have been set transient for another
3659 * window using gtk_window_set_transient_for()) will inherit their
3660 * icon from their transient parent. So there's no need to explicitly
3661 * set the icon on transient windows.
3664 gtk_window_set_icon_list (GtkWindow *window,
3667 GtkWindowIconInfo *info;
3669 g_return_if_fail (GTK_IS_WINDOW (window));
3671 info = ensure_icon_info (window);
3673 if (info->icon_list == list) /* check for NULL mostly */
3676 g_list_foreach (list,
3677 (GFunc) g_object_ref, NULL);
3679 g_list_free_full (info->icon_list, g_object_unref);
3681 info->icon_list = g_list_copy (list);
3683 g_object_notify (G_OBJECT (window), "icon");
3685 gtk_window_unrealize_icon (window);
3687 if (gtk_widget_get_realized (GTK_WIDGET (window)))
3688 gtk_window_realize_icon (window);
3690 /* We could try to update our transient children, but I don't think
3691 * it's really worth it. If we did it, the best way would probably
3692 * be to have children connect to notify::icon-list
3697 * gtk_window_get_icon_list:
3698 * @window: a #GtkWindow
3700 * Retrieves the list of icons set by gtk_window_set_icon_list().
3701 * The list is copied, but the reference count on each
3702 * member won't be incremented.
3704 * Return value: (element-type GdkPixbuf) (transfer container): copy of window's icon list
3707 gtk_window_get_icon_list (GtkWindow *window)
3709 GtkWindowIconInfo *info;
3711 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
3713 info = get_icon_info (window);
3716 return g_list_copy (info->icon_list);
3722 * gtk_window_set_icon:
3723 * @window: a #GtkWindow
3724 * @icon: (allow-none): icon image, or %NULL
3726 * Sets up the icon representing a #GtkWindow. This icon is used when
3727 * the window is minimized (also known as iconified). Some window
3728 * managers or desktop environments may also place it in the window
3729 * frame, or display it in other contexts.
3731 * The icon should be provided in whatever size it was naturally
3732 * drawn; that is, don't scale the image before passing it to
3733 * GTK+. Scaling is postponed until the last minute, when the desired
3734 * final size is known, to allow best quality.
3736 * If you have your icon hand-drawn in multiple sizes, use
3737 * gtk_window_set_icon_list(). Then the best size will be used.
3739 * This function is equivalent to calling gtk_window_set_icon_list()
3740 * with a 1-element list.
3742 * See also gtk_window_set_default_icon_list() to set the icon
3743 * for all windows in your application in one go.
3746 gtk_window_set_icon (GtkWindow *window,
3751 g_return_if_fail (GTK_IS_WINDOW (window));
3752 g_return_if_fail (icon == NULL || GDK_IS_PIXBUF (icon));
3757 list = g_list_append (list, icon);
3759 gtk_window_set_icon_list (window, list);
3765 update_themed_icon (GtkIconTheme *icon_theme,
3768 g_object_notify (G_OBJECT (window), "icon");
3770 gtk_window_unrealize_icon (window);
3772 if (gtk_widget_get_realized (GTK_WIDGET (window)))
3773 gtk_window_realize_icon (window);
3777 * gtk_window_set_icon_name:
3778 * @window: a #GtkWindow
3779 * @name: (allow-none): the name of the themed icon
3781 * Sets the icon for the window from a named themed icon. See
3782 * the docs for #GtkIconTheme for more details.
3784 * Note that this has nothing to do with the WM_ICON_NAME
3785 * property which is mentioned in the ICCCM.
3790 gtk_window_set_icon_name (GtkWindow *window,
3793 GtkWindowIconInfo *info;
3796 g_return_if_fail (GTK_IS_WINDOW (window));
3798 info = ensure_icon_info (window);
3800 if (g_strcmp0 (info->icon_name, name) == 0)
3803 tmp = info->icon_name;
3804 info->icon_name = g_strdup (name);
3807 g_list_free_full (info->icon_list, g_object_unref);
3808 info->icon_list = NULL;
3810 update_themed_icon (NULL, window);
3812 g_object_notify (G_OBJECT (window), "icon-name");
3816 * gtk_window_get_icon_name:
3817 * @window: a #GtkWindow
3819 * Returns the name of the themed icon for the window,
3820 * see gtk_window_set_icon_name().
3822 * Returns: the icon name or %NULL if the window has
3828 gtk_window_get_icon_name (GtkWindow *window)
3830 GtkWindowIconInfo *info;
3832 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
3834 info = ensure_icon_info (window);
3836 return info->icon_name;
3840 * gtk_window_get_icon:
3841 * @window: a #GtkWindow
3843 * Gets the value set by gtk_window_set_icon() (or if you've
3844 * called gtk_window_set_icon_list(), gets the first icon in
3847 * Return value: (transfer none): icon for window
3850 gtk_window_get_icon (GtkWindow *window)
3852 GtkWindowIconInfo *info;
3854 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
3856 info = get_icon_info (window);
3857 if (info && info->icon_list)
3858 return GDK_PIXBUF (info->icon_list->data);
3863 /* Load pixbuf, printing warning on failure if error == NULL
3866 load_pixbuf_verbosely (const char *filename,
3869 GError *local_err = NULL;
3872 pixbuf = gdk_pixbuf_new_from_file (filename, &local_err);
3880 g_warning ("Error loading icon from file '%s':\n\t%s",
3881 filename, local_err->message);
3882 g_error_free (local_err);
3890 * gtk_window_set_icon_from_file:
3891 * @window: a #GtkWindow
3892 * @filename: (type filename): location of icon file
3893 * @err: (allow-none): location to store error, or %NULL.
3895 * Sets the icon for @window.
3896 * Warns on failure if @err is %NULL.
3898 * This function is equivalent to calling gtk_window_set_icon()
3899 * with a pixbuf created by loading the image from @filename.
3901 * Returns: %TRUE if setting the icon succeeded.
3906 gtk_window_set_icon_from_file (GtkWindow *window,
3907 const gchar *filename,
3910 GdkPixbuf *pixbuf = load_pixbuf_verbosely (filename, err);
3914 gtk_window_set_icon (window, pixbuf);
3915 g_object_unref (pixbuf);
3924 * gtk_window_set_default_icon_list:
3925 * @list: (element-type GdkPixbuf) (transfer container): a list of #GdkPixbuf
3927 * Sets an icon list to be used as fallback for windows that haven't
3928 * had gtk_window_set_icon_list() called on them to set up a
3929 * window-specific icon list. This function allows you to set up the
3930 * icon for all windows in your app at once.
3932 * See gtk_window_set_icon_list() for more details.
3936 gtk_window_set_default_icon_list (GList *list)
3940 if (list == default_icon_list)
3943 /* Update serial so we don't used cached pixmaps/masks
3945 default_icon_serial++;
3947 g_list_foreach (list,
3948 (GFunc) g_object_ref, NULL);
3950 g_list_free_full (default_icon_list, g_object_unref);
3952 default_icon_list = g_list_copy (list);
3954 /* Update all toplevels */
3955 toplevels = gtk_window_list_toplevels ();
3956 tmp_list = toplevels;
3957 while (tmp_list != NULL)
3959 GtkWindowIconInfo *info;
3960 GtkWindow *w = tmp_list->data;
3962 info = get_icon_info (w);
3963 if (info && info->using_default_icon)
3965 gtk_window_unrealize_icon (w);
3966 if (gtk_widget_get_realized (GTK_WIDGET (w)))
3967 gtk_window_realize_icon (w);
3970 tmp_list = tmp_list->next;
3972 g_list_free (toplevels);
3976 * gtk_window_set_default_icon:
3979 * Sets an icon to be used as fallback for windows that haven't
3980 * had gtk_window_set_icon() called on them from a pixbuf.
3985 gtk_window_set_default_icon (GdkPixbuf *icon)
3989 g_return_if_fail (GDK_IS_PIXBUF (icon));
3991 list = g_list_prepend (NULL, icon);
3992 gtk_window_set_default_icon_list (list);
3997 * gtk_window_set_default_icon_name:
3998 * @name: the name of the themed icon
4000 * Sets an icon to be used as fallback for windows that haven't
4001 * had gtk_window_set_icon_list() called on them from a named
4002 * themed icon, see gtk_window_set_icon_name().
4007 gtk_window_set_default_icon_name (const gchar *name)
4012 /* Update serial so we don't used cached pixmaps/masks
4014 default_icon_serial++;
4016 g_free (default_icon_name);
4017 default_icon_name = g_strdup (name);
4019 g_list_free_full (default_icon_list, g_object_unref);
4020 default_icon_list = NULL;
4022 /* Update all toplevels */
4023 toplevels = gtk_window_list_toplevels ();
4024 tmp_list = toplevels;
4025 while (tmp_list != NULL)
4027 GtkWindowIconInfo *info;
4028 GtkWindow *w = tmp_list->data;
4030 info = get_icon_info (w);
4031 if (info && info->using_default_icon && info->using_themed_icon)
4033 gtk_window_unrealize_icon (w);
4034 if (gtk_widget_get_realized (GTK_WIDGET (w)))
4035 gtk_window_realize_icon (w);
4038 tmp_list = tmp_list->next;
4040 g_list_free (toplevels);
4044 * gtk_window_get_default_icon_name:
4046 * Returns the fallback icon name for windows that has been set
4047 * with gtk_window_set_default_icon_name(). The returned
4048 * string is owned by GTK+ and should not be modified. It
4049 * is only valid until the next call to
4050 * gtk_window_set_default_icon_name().
4052 * Returns: the fallback icon name for windows
4057 gtk_window_get_default_icon_name (void)
4059 return default_icon_name;
4063 * gtk_window_set_default_icon_from_file:
4064 * @filename: (type filename): location of icon file
4065 * @err: (allow-none): location to store error, or %NULL.
4067 * Sets an icon to be used as fallback for windows that haven't
4068 * had gtk_window_set_icon_list() called on them from a file
4069 * on disk. Warns on failure if @err is %NULL.
4071 * Returns: %TRUE if setting the icon succeeded.
4076 gtk_window_set_default_icon_from_file (const gchar *filename,
4079 GdkPixbuf *pixbuf = load_pixbuf_verbosely (filename, err);
4083 gtk_window_set_default_icon (pixbuf);
4084 g_object_unref (pixbuf);
4093 * gtk_window_get_default_icon_list:
4095 * Gets the value set by gtk_window_set_default_icon_list().
4096 * The list is a copy and should be freed with g_list_free(),
4097 * but the pixbufs in the list have not had their reference count
4100 * Return value: (element-type GdkPixbuf) (transfer container): copy of default icon list
4103 gtk_window_get_default_icon_list (void)
4105 return g_list_copy (default_icon_list);
4109 gtk_window_set_default_size_internal (GtkWindow *window,
4110 gboolean change_width,
4112 gboolean change_height,
4114 gboolean is_geometry)
4116 GtkWindowGeometryInfo *info;
4118 g_return_if_fail (change_width == FALSE || width >= -1);
4119 g_return_if_fail (change_height == FALSE || height >= -1);
4121 info = gtk_window_get_geometry_info (window, TRUE);
4123 g_object_freeze_notify (G_OBJECT (window));
4125 info->default_is_geometry = is_geometry != FALSE;
4135 info->default_width = width;
4137 g_object_notify (G_OBJECT (window), "default-width");
4148 info->default_height = height;
4150 g_object_notify (G_OBJECT (window), "default-height");
4153 g_object_thaw_notify (G_OBJECT (window));
4155 gtk_widget_queue_resize_no_redraw (GTK_WIDGET (window));
4159 * gtk_window_set_default_size:
4160 * @window: a #GtkWindow
4161 * @width: width in pixels, or -1 to unset the default width
4162 * @height: height in pixels, or -1 to unset the default height
4164 * Sets the default size of a window. If the window's "natural" size
4165 * (its size request) is larger than the default, the default will be
4166 * ignored. More generally, if the default size does not obey the
4167 * geometry hints for the window (gtk_window_set_geometry_hints() can
4168 * be used to set these explicitly), the default size will be clamped
4169 * to the nearest permitted size.
4171 * Unlike gtk_widget_set_size_request(), which sets a size request for
4172 * a widget and thus would keep users from shrinking the window, this
4173 * function only sets the initial size, just as if the user had
4174 * resized the window themselves. Users can still shrink the window
4175 * again as they normally would. Setting a default size of -1 means to
4176 * use the "natural" default size (the size request of the window).
4178 * For more control over a window's initial size and how resizing works,
4179 * investigate gtk_window_set_geometry_hints().
4181 * For some uses, gtk_window_resize() is a more appropriate function.
4182 * gtk_window_resize() changes the current size of the window, rather
4183 * than the size to be used on initial display. gtk_window_resize() always
4184 * affects the window itself, not the geometry widget.
4186 * The default size of a window only affects the first time a window is
4187 * shown; if a window is hidden and re-shown, it will remember the size
4188 * it had prior to hiding, rather than using the default size.
4190 * Windows can't actually be 0x0 in size, they must be at least 1x1, but
4191 * passing 0 for @width and @height is OK, resulting in a 1x1 default size.
4194 gtk_window_set_default_size (GtkWindow *window,
4198 g_return_if_fail (GTK_IS_WINDOW (window));
4199 g_return_if_fail (width >= -1);
4200 g_return_if_fail (height >= -1);
4202 gtk_window_set_default_size_internal (window, TRUE, width, TRUE, height, FALSE);
4206 * gtk_window_set_default_geometry:
4207 * @window: a #GtkWindow
4208 * @width: width in resize increments, or -1 to unset the default width
4209 * @height: height in resize increments, or -1 to unset the default height
4211 * Like gtk_window_set_default_size(), but @width and @height are interpreted
4212 * in terms of the base size and increment set with
4213 * gtk_window_set_geometry_hints.
4218 gtk_window_set_default_geometry (GtkWindow *window,
4222 g_return_if_fail (GTK_IS_WINDOW (window));
4223 g_return_if_fail (width >= -1);
4224 g_return_if_fail (height >= -1);
4226 gtk_window_set_default_size_internal (window, TRUE, width, TRUE, height, TRUE);
4230 * gtk_window_get_default_size:
4231 * @window: a #GtkWindow
4232 * @width: (out) (allow-none): location to store the default width, or %NULL
4233 * @height: (out) (allow-none): location to store the default height, or %NULL
4235 * Gets the default size of the window. A value of -1 for the width or
4236 * height indicates that a default size has not been explicitly set
4237 * for that dimension, so the "natural" size of the window will be
4242 gtk_window_get_default_size (GtkWindow *window,
4246 GtkWindowGeometryInfo *info;
4248 g_return_if_fail (GTK_IS_WINDOW (window));
4250 info = gtk_window_get_geometry_info (window, FALSE);
4253 *width = info ? info->default_width : -1;
4256 *height = info ? info->default_height : -1;
4260 * gtk_window_resize:
4261 * @window: a #GtkWindow
4262 * @width: width in pixels to resize the window to
4263 * @height: height in pixels to resize the window to
4265 * Resizes the window as if the user had done so, obeying geometry
4266 * constraints. The default geometry constraint is that windows may
4267 * not be smaller than their size request; to override this
4268 * constraint, call gtk_widget_set_size_request() to set the window's
4269 * request to a smaller value.
4271 * If gtk_window_resize() is called before showing a window for the
4272 * first time, it overrides any default size set with
4273 * gtk_window_set_default_size().
4275 * Windows may not be resized smaller than 1 by 1 pixels.
4279 gtk_window_resize (GtkWindow *window,
4283 GtkWindowGeometryInfo *info;
4285 g_return_if_fail (GTK_IS_WINDOW (window));
4286 g_return_if_fail (width > 0);
4287 g_return_if_fail (height > 0);
4289 info = gtk_window_get_geometry_info (window, TRUE);
4291 info->resize_width = width;
4292 info->resize_height = height;
4293 info->resize_is_geometry = FALSE;
4295 gtk_widget_queue_resize_no_redraw (GTK_WIDGET (window));
4299 * gtk_window_resize_to_geometry:
4300 * @window: a #GtkWindow
4301 * @width: width in resize increments to resize the window to
4302 * @height: height in resize increments to resize the window to
4304 * Like gtk_window_resize(), but @width and @height are interpreted
4305 * in terms of the base size and increment set with
4306 * gtk_window_set_geometry_hints.
4311 gtk_window_resize_to_geometry (GtkWindow *window,
4315 GtkWindowGeometryInfo *info;
4317 g_return_if_fail (GTK_IS_WINDOW (window));
4318 g_return_if_fail (width > 0);
4319 g_return_if_fail (height > 0);
4321 info = gtk_window_get_geometry_info (window, TRUE);
4323 info->resize_width = width;
4324 info->resize_height = height;
4325 info->resize_is_geometry = TRUE;
4327 gtk_widget_queue_resize_no_redraw (GTK_WIDGET (window));
4331 * gtk_window_get_size:
4332 * @window: a #GtkWindow
4333 * @width: (out) (allow-none): return location for width, or %NULL
4334 * @height: (out) (allow-none): return location for height, or %NULL
4336 * Obtains the current size of @window. If @window is not onscreen,
4337 * it returns the size GTK+ will suggest to the <link
4338 * linkend="gtk-X11-arch">window manager</link> for the initial window
4339 * size (but this is not reliably the same as the size the window
4340 * manager will actually select). The size obtained by
4341 * gtk_window_get_size() is the last size received in a
4342 * #GdkEventConfigure, that is, GTK+ uses its locally-stored size,
4343 * rather than querying the X server for the size. As a result, if you
4344 * call gtk_window_resize() then immediately call
4345 * gtk_window_get_size(), the size won't have taken effect yet. After
4346 * the window manager processes the resize request, GTK+ receives
4347 * notification that the size has changed via a configure event, and
4348 * the size of the window gets updated.
4350 * Note 1: Nearly any use of this function creates a race condition,
4351 * because the size of the window may change between the time that you
4352 * get the size and the time that you perform some action assuming
4353 * that size is the current size. To avoid race conditions, connect to
4354 * "configure-event" on the window and adjust your size-dependent
4355 * state to match the size delivered in the #GdkEventConfigure.
4357 * Note 2: The returned size does <emphasis>not</emphasis> include the
4358 * size of the window manager decorations (aka the window frame or
4359 * border). Those are not drawn by GTK+ and GTK+ has no reliable
4360 * method of determining their size.
4362 * Note 3: If you are getting a window size in order to position
4363 * the window onscreen, there may be a better way. The preferred
4364 * way is to simply set the window's semantic type with
4365 * gtk_window_set_type_hint(), which allows the window manager to
4366 * e.g. center dialogs. Also, if you set the transient parent of
4367 * dialogs with gtk_window_set_transient_for() window managers
4368 * will often center the dialog over its parent window. It's
4369 * much preferred to let the window manager handle these
4370 * things rather than doing it yourself, because all apps will
4371 * behave consistently and according to user prefs if the window
4372 * manager handles it. Also, the window manager can take the size
4373 * of the window decorations/border into account, while your
4374 * application cannot.
4376 * In any case, if you insist on application-specified window
4377 * positioning, there's <emphasis>still</emphasis> a better way than
4378 * doing it yourself - gtk_window_set_position() will frequently
4379 * handle the details for you.
4383 gtk_window_get_size (GtkWindow *window,
4389 g_return_if_fail (GTK_IS_WINDOW (window));
4391 if (width == NULL && height == NULL)
4394 if (gtk_widget_get_mapped (GTK_WIDGET (window)))
4396 w = gdk_window_get_width (gtk_widget_get_window (GTK_WIDGET (window)));
4397 h = gdk_window_get_height (gtk_widget_get_window (GTK_WIDGET (window)));
4401 GdkRectangle configure_request;
4403 gtk_window_compute_configure_request (window,
4407 w = configure_request.width;
4408 h = configure_request.height;
4419 * @window: a #GtkWindow
4420 * @x: X coordinate to move window to
4421 * @y: Y coordinate to move window to
4423 * Asks the <link linkend="gtk-X11-arch">window manager</link> to move
4424 * @window to the given position. Window managers are free to ignore
4425 * this; most window managers ignore requests for initial window
4426 * positions (instead using a user-defined placement algorithm) and
4427 * honor requests after the window has already been shown.
4429 * Note: the position is the position of the gravity-determined
4430 * reference point for the window. The gravity determines two things:
4431 * first, the location of the reference point in root window
4432 * coordinates; and second, which point on the window is positioned at
4433 * the reference point.
4435 * By default the gravity is #GDK_GRAVITY_NORTH_WEST, so the reference
4436 * point is simply the @x, @y supplied to gtk_window_move(). The
4437 * top-left corner of the window decorations (aka window frame or
4438 * border) will be placed at @x, @y. Therefore, to position a window
4439 * at the top left of the screen, you want to use the default gravity
4440 * (which is #GDK_GRAVITY_NORTH_WEST) and move the window to 0,0.
4442 * To position a window at the bottom right corner of the screen, you
4443 * would set #GDK_GRAVITY_SOUTH_EAST, which means that the reference
4444 * point is at @x + the window width and @y + the window height, and
4445 * the bottom-right corner of the window border will be placed at that
4446 * reference point. So, to place a window in the bottom right corner
4447 * you would first set gravity to south east, then write:
4448 * <literal>gtk_window_move (window, gdk_screen_width () - window_width,
4449 * gdk_screen_height () - window_height)</literal> (note that this
4450 * example does not take multi-head scenarios into account).
4452 * The Extended Window Manager Hints specification at <ulink
4453 * url="http://www.freedesktop.org/Standards/wm-spec">
4454 * http://www.freedesktop.org/Standards/wm-spec</ulink> has a
4455 * nice table of gravities in the "implementation notes" section.
4457 * The gtk_window_get_position() documentation may also be relevant.
4460 gtk_window_move (GtkWindow *window,
4464 GtkWindowGeometryInfo *info;
4467 g_return_if_fail (GTK_IS_WINDOW (window));
4469 widget = GTK_WIDGET (window);
4471 info = gtk_window_get_geometry_info (window, TRUE);
4473 if (gtk_widget_get_mapped (widget))
4475 GtkAllocation allocation;
4477 gtk_widget_get_allocation (widget, &allocation);
4479 /* we have now sent a request with this position
4480 * with currently-active constraints, so toggle flag.
4482 info->position_constraints_changed = FALSE;
4484 /* we only constrain if mapped - if not mapped,
4485 * then gtk_window_compute_configure_request()
4486 * will apply the constraints later, and we
4487 * don't want to lose information about
4488 * what position the user set before then.
4489 * i.e. if you do a move() then turn off POS_CENTER
4490 * then show the window, your move() will work.
4492 gtk_window_constrain_position (window,
4493 allocation.width, allocation.height,
4496 /* Note that this request doesn't go through our standard request
4497 * framework, e.g. doesn't increment configure_request_count,
4498 * doesn't set info->last, etc.; that's because
4499 * we don't save the info needed to arrive at this same request
4502 * To gtk_window_move_resize(), this will end up looking exactly
4503 * the same as the position being changed by the window
4506 gdk_window_move (gtk_widget_get_window (GTK_WIDGET (window)), x, y);
4510 /* Save this position to apply on mapping */
4511 info->initial_x = x;
4512 info->initial_y = y;
4513 info->initial_pos_set = TRUE;
4518 * gtk_window_get_position:
4519 * @window: a #GtkWindow
4520 * @root_x: (out) (allow-none): eturn location for X coordinate of
4521 * gravity-determined reference point, or %NULL
4522 * @root_y: (out) (allow-none): return location for Y coordinate of
4523 * gravity-determined reference point, or %NULL
4525 * This function returns the position you need to pass to
4526 * gtk_window_move() to keep @window in its current position.
4527 * This means that the meaning of the returned value varies with
4528 * window gravity. See gtk_window_move() for more details.
4530 * If you haven't changed the window gravity, its gravity will be
4531 * #GDK_GRAVITY_NORTH_WEST. This means that gtk_window_get_position()
4532 * gets the position of the top-left corner of the window manager
4533 * frame for the window. gtk_window_move() sets the position of this
4534 * same top-left corner.
4536 * gtk_window_get_position() is not 100% reliable because the X Window System
4537 * does not specify a way to obtain the geometry of the
4538 * decorations placed on a window by the window manager.
4539 * Thus GTK+ is using a "best guess" that works with most
4542 * Moreover, nearly all window managers are historically broken with
4543 * respect to their handling of window gravity. So moving a window to
4544 * its current position as returned by gtk_window_get_position() tends
4545 * to result in moving the window slightly. Window managers are
4546 * slowly getting better over time.
4548 * If a window has gravity #GDK_GRAVITY_STATIC the window manager
4549 * frame is not relevant, and thus gtk_window_get_position() will
4550 * always produce accurate results. However you can't use static
4551 * gravity to do things like place a window in a corner of the screen,
4552 * because static gravity ignores the window manager decorations.
4554 * If you are saving and restoring your application's window
4555 * positions, you should know that it's impossible for applications to
4556 * do this without getting it somewhat wrong because applications do
4557 * not have sufficient knowledge of window manager state. The Correct
4558 * Mechanism is to support the session management protocol (see the
4559 * "GnomeClient" object in the GNOME libraries for example) and allow
4560 * the window manager to save your window sizes and positions.
4565 gtk_window_get_position (GtkWindow *window,
4569 GtkWindowPrivate *priv;
4571 GdkWindow *gdk_window;
4573 g_return_if_fail (GTK_IS_WINDOW (window));
4575 priv = window->priv;
4576 widget = GTK_WIDGET (window);
4577 gdk_window = gtk_widget_get_window (widget);
4579 if (priv->gravity == GDK_GRAVITY_STATIC)
4581 if (gtk_widget_get_mapped (widget))
4583 /* This does a server round-trip, which is sort of wrong;
4584 * but a server round-trip is inevitable for
4585 * gdk_window_get_frame_extents() in the usual
4586 * NorthWestGravity case below, so not sure what else to
4587 * do. We should likely be consistent about whether we get
4588 * the client-side info or the server-side info.
4590 gdk_window_get_origin (gdk_window, root_x, root_y);
4594 GdkRectangle configure_request;
4596 gtk_window_compute_configure_request (window,
4600 *root_x = configure_request.x;
4601 *root_y = configure_request.y;
4606 GdkRectangle frame_extents;
4611 if (gtk_widget_get_mapped (widget))
4613 gdk_window_get_frame_extents (gdk_window, &frame_extents);
4614 x = frame_extents.x;
4615 y = frame_extents.y;
4616 gtk_window_get_size (window, &w, &h);
4620 /* We just say the frame has 0 size on all sides.
4621 * Not sure what else to do.
4623 gtk_window_compute_configure_request (window,
4626 x = frame_extents.x;
4627 y = frame_extents.y;
4628 w = frame_extents.width;
4629 h = frame_extents.height;
4632 switch (priv->gravity)
4634 case GDK_GRAVITY_NORTH:
4635 case GDK_GRAVITY_CENTER:
4636 case GDK_GRAVITY_SOUTH:
4637 /* Find center of frame. */
4638 x += frame_extents.width / 2;
4639 /* Center client window on that point. */
4643 case GDK_GRAVITY_SOUTH_EAST:
4644 case GDK_GRAVITY_EAST:
4645 case GDK_GRAVITY_NORTH_EAST:
4646 /* Find right edge of frame */
4647 x += frame_extents.width;
4648 /* Align left edge of client at that point. */
4655 switch (priv->gravity)
4657 case GDK_GRAVITY_WEST:
4658 case GDK_GRAVITY_CENTER:
4659 case GDK_GRAVITY_EAST:
4660 /* Find center of frame. */
4661 y += frame_extents.height / 2;
4662 /* Center client window there. */
4665 case GDK_GRAVITY_SOUTH_WEST:
4666 case GDK_GRAVITY_SOUTH:
4667 case GDK_GRAVITY_SOUTH_EAST:
4668 /* Find south edge of frame */
4669 y += frame_extents.height;
4670 /* Place bottom edge of client there */
4685 * gtk_window_reshow_with_initial_size:
4686 * @window: a #GtkWindow
4688 * Hides @window, then reshows it, resetting the
4689 * default size and position of the window. Used
4690 * by GUI builders only.
4693 gtk_window_reshow_with_initial_size (GtkWindow *window)
4697 g_return_if_fail (GTK_IS_WINDOW (window));
4699 widget = GTK_WIDGET (window);
4701 gtk_widget_hide (widget);
4702 gtk_widget_unrealize (widget);
4703 gtk_widget_show (widget);
4707 gtk_window_destroy (GtkWidget *widget)
4709 GtkWindow *window = GTK_WINDOW (widget);
4710 GtkWindowPrivate *priv = window->priv;
4712 gtk_window_release_application (window);
4714 toplevel_list = g_slist_remove (toplevel_list, window);
4716 if (priv->transient_parent)
4717 gtk_window_set_transient_for (window, NULL);
4719 remove_attach_widget (GTK_WINDOW (widget));
4721 /* frees the icons */
4722 gtk_window_set_icon_list (window, NULL);
4724 if (priv->has_user_ref_count)
4726 priv->has_user_ref_count = FALSE;
4727 g_object_unref (window);
4731 gtk_window_group_remove_window (priv->group, window);
4733 gtk_window_free_key_hash (window);
4735 GTK_WIDGET_CLASS (gtk_window_parent_class)->destroy (widget);
4739 gtk_window_finalize (GObject *object)
4741 GtkWindow *window = GTK_WINDOW (object);
4742 GtkWindowPrivate *priv = window->priv;
4743 GtkMnemonicHash *mnemonic_hash;
4745 g_free (priv->title);
4746 g_free (priv->wmclass_name);
4747 g_free (priv->wmclass_class);
4748 g_free (priv->wm_role);
4749 gtk_window_release_application (window);
4751 mnemonic_hash = gtk_window_get_mnemonic_hash (window, FALSE);
4753 _gtk_mnemonic_hash_free (mnemonic_hash);
4755 if (priv->geometry_info)
4757 if (priv->geometry_info->widget)
4758 g_signal_handlers_disconnect_by_func (priv->geometry_info->widget,
4759 gtk_widget_destroyed,
4760 &priv->geometry_info->widget);
4761 g_free (priv->geometry_info);
4764 if (priv->keys_changed_handler)
4766 g_source_remove (priv->keys_changed_handler);
4767 priv->keys_changed_handler = 0;
4771 g_signal_handlers_disconnect_by_func (priv->screen,
4772 gtk_window_on_composited_changed, window);
4774 g_free (priv->startup_id);
4776 #ifdef GDK_WINDOWING_X11
4777 g_signal_handlers_disconnect_by_func (gtk_settings_get_default (),
4778 gtk_window_on_theme_variant_changed,
4782 G_OBJECT_CLASS (gtk_window_parent_class)->finalize (object);
4786 gtk_window_show (GtkWidget *widget)
4788 GtkWindow *window = GTK_WINDOW (widget);
4789 GtkWindowPrivate *priv = window->priv;
4790 GtkContainer *container = GTK_CONTAINER (window);
4791 gboolean need_resize;
4794 if (!gtk_widget_is_toplevel (GTK_WIDGET (widget)))
4796 GTK_WIDGET_CLASS (gtk_window_parent_class)->show (widget);
4800 _gtk_widget_set_visible_flag (widget, TRUE);
4802 need_resize = _gtk_container_get_need_resize (container) || !gtk_widget_get_realized (widget);
4803 _gtk_container_set_need_resize (container, FALSE);
4807 GtkWindowGeometryInfo *info = gtk_window_get_geometry_info (window, TRUE);
4808 GtkAllocation allocation = { 0, 0 };
4809 GdkRectangle configure_request;
4810 GdkGeometry new_geometry;
4812 gboolean was_realized;
4814 /* We are going to go ahead and perform this configure request
4815 * and then emulate a configure notify by going ahead and
4816 * doing a size allocate. Sort of a synchronous
4817 * mini-copy of gtk_window_move_resize() here.
4819 gtk_window_compute_configure_request (window,
4824 /* We update this because we are going to go ahead
4825 * and gdk_window_resize() below, rather than
4828 info->last.configure_request.width = configure_request.width;
4829 info->last.configure_request.height = configure_request.height;
4831 /* and allocate the window - this is normally done
4832 * in move_resize in response to configure notify
4834 allocation.width = configure_request.width;
4835 allocation.height = configure_request.height;
4836 gtk_widget_size_allocate (widget, &allocation);
4838 /* Then we guarantee we have a realize */
4839 was_realized = FALSE;
4840 if (!gtk_widget_get_realized (widget))
4842 gtk_widget_realize (widget);
4843 was_realized = TRUE;
4846 /* We only send configure request if we didn't just finish
4847 * creating the window; if we just created the window
4848 * then we created it with widget->allocation anyhow.
4851 gdk_window_move_resize (gtk_widget_get_window (widget),
4852 configure_request.x,
4853 configure_request.y,
4854 configure_request.width,
4855 configure_request.height);
4858 gtk_container_check_resize (container);
4860 gtk_widget_map (widget);
4862 /* Try to make sure that we have some focused widget
4864 #ifdef GDK_WINDOWING_X11
4865 is_plug = GDK_IS_X11_WINDOW (gtk_widget_get_window (widget)) &&
4866 GTK_IS_PLUG (window);
4870 if (!priv->focus_widget && !is_plug)
4871 gtk_window_move_focus (widget, GTK_DIR_TAB_FORWARD);
4874 gtk_grab_add (widget);
4878 gtk_window_hide (GtkWidget *widget)
4880 GtkWindow *window = GTK_WINDOW (widget);
4881 GtkWindowPrivate *priv = window->priv;
4883 if (!gtk_widget_is_toplevel (GTK_WIDGET (widget)))
4885 GTK_WIDGET_CLASS (gtk_window_parent_class)->hide (widget);
4889 _gtk_widget_set_visible_flag (widget, FALSE);
4890 gtk_widget_unmap (widget);
4893 gtk_grab_remove (widget);
4897 gtk_window_map (GtkWidget *widget)
4900 GtkWindow *window = GTK_WINDOW (widget);
4901 GtkWindowPrivate *priv = window->priv;
4902 GdkWindow *gdk_window;
4903 gboolean auto_mnemonics;
4904 GtkPolicyType visible_focus;
4906 if (!gtk_widget_is_toplevel (widget))
4908 GTK_WIDGET_CLASS (gtk_window_parent_class)->map (widget);
4912 gtk_widget_set_mapped (widget, TRUE);
4914 child = gtk_bin_get_child (&(window->bin));
4916 gtk_widget_get_visible (child) &&
4917 !gtk_widget_get_mapped (child))
4918 gtk_widget_map (child);
4920 gdk_window = gtk_widget_get_window (widget);
4922 if (priv->maximize_initially)
4923 gdk_window_maximize (gdk_window);
4925 gdk_window_unmaximize (gdk_window);
4927 if (priv->stick_initially)
4928 gdk_window_stick (gdk_window);
4930 gdk_window_unstick (gdk_window);
4932 if (priv->iconify_initially)
4933 gdk_window_iconify (gdk_window);
4935 gdk_window_deiconify (gdk_window);
4937 if (priv->fullscreen_initially)
4938 gdk_window_fullscreen (gdk_window);
4940 gdk_window_unfullscreen (gdk_window);
4942 gdk_window_set_keep_above (gdk_window, priv->above_initially);
4944 gdk_window_set_keep_below (gdk_window, priv->below_initially);
4946 if (priv->type == GTK_WINDOW_TOPLEVEL)
4948 gtk_window_set_theme_variant (window);
4949 gtk_window_set_hide_titlebar_when_maximized (window,
4950 priv->hide_titlebar_when_maximized);
4953 /* No longer use the default settings */
4954 priv->need_default_size = FALSE;
4955 priv->need_default_position = FALSE;
4957 if (priv->reset_type_hint)
4959 /* We should only reset the type hint when the application
4960 * used gtk_window_set_type_hint() to change the hint.
4961 * Some applications use X directly to change the properties;
4962 * in that case, we shouldn't overwrite what they did.
4964 gdk_window_set_type_hint (gdk_window, priv->gdk_type_hint);
4965 priv->reset_type_hint = FALSE;
4968 gdk_window_show (gdk_window);
4970 if (priv->grip_window)
4971 gdk_window_show (priv->grip_window);
4973 if (!disable_startup_notification)
4975 /* Do we have a custom startup-notification id? */
4976 if (priv->startup_id != NULL)
4978 /* Make sure we have a "real" id */
4979 if (!startup_id_is_fake (priv->startup_id))
4980 gdk_notify_startup_complete_with_id (priv->startup_id);
4982 g_free (priv->startup_id);
4983 priv->startup_id = NULL;
4985 else if (!sent_startup_notification)
4987 sent_startup_notification = TRUE;
4988 gdk_notify_startup_complete ();
4992 /* if auto-mnemonics is enabled and mnemonics visible is not already set
4993 * (as in the case of popup menus), then hide mnemonics initially
4995 g_object_get (gtk_widget_get_settings (widget),
4996 "gtk-auto-mnemonics", &auto_mnemonics,
4997 "gtk-visible-focus", &visible_focus,
5000 if (auto_mnemonics && !priv->mnemonics_visible_set)
5001 gtk_window_set_mnemonics_visible (window, FALSE);
5003 /* inherit from transient parent, so that a dialog that is
5004 * opened via keynav shows focus initially
5006 if (priv->transient_parent)
5007 gtk_window_set_focus_visible (window, gtk_window_get_focus_visible (priv->transient_parent));
5009 gtk_window_set_focus_visible (window, visible_focus == GTK_POLICY_ALWAYS);
5011 ensure_state_flag_backdrop (widget);
5015 gtk_window_map_event (GtkWidget *widget,
5018 if (!gtk_widget_get_mapped (widget))
5020 /* we should be be unmapped, but are getting a MapEvent, this may happen
5021 * to toplevel XWindows if mapping was intercepted by a window manager
5022 * and an unmap request occoured while the MapRequestEvent was still
5023 * being handled. we work around this situaiton here by re-requesting
5024 * the window being unmapped. more details can be found in:
5025 * http://bugzilla.gnome.org/show_bug.cgi?id=316180
5027 gdk_window_hide (gtk_widget_get_window (widget));
5033 gtk_window_unmap (GtkWidget *widget)
5035 GtkWindow *window = GTK_WINDOW (widget);
5036 GtkWindowPrivate *priv = window->priv;
5038 GtkWindowGeometryInfo *info;
5039 GdkWindow *gdk_window;
5040 GdkWindowState state;
5042 if (!gtk_widget_is_toplevel (GTK_WIDGET (widget)))
5044 GTK_WIDGET_CLASS (gtk_window_parent_class)->unmap (widget);
5048 gdk_window = gtk_widget_get_window (widget);
5050 gtk_widget_set_mapped (widget, FALSE);
5051 gdk_window_withdraw (gdk_window);
5053 priv->configure_request_count = 0;
5054 priv->configure_notify_received = FALSE;
5056 /* on unmap, we reset the default positioning of the window,
5057 * so it's placed again, but we don't reset the default
5058 * size of the window, so it's remembered.
5060 priv->need_default_position = TRUE;
5062 info = gtk_window_get_geometry_info (window, FALSE);
5065 info->initial_pos_set = FALSE;
5066 info->position_constraints_changed = FALSE;
5069 state = gdk_window_get_state (gdk_window);
5070 priv->iconify_initially = (state & GDK_WINDOW_STATE_ICONIFIED) != 0;
5071 priv->maximize_initially = (state & GDK_WINDOW_STATE_MAXIMIZED) != 0;
5072 priv->stick_initially = (state & GDK_WINDOW_STATE_STICKY) != 0;
5073 priv->above_initially = (state & GDK_WINDOW_STATE_ABOVE) != 0;
5074 priv->below_initially = (state & GDK_WINDOW_STATE_BELOW) != 0;
5076 child = gtk_bin_get_child (&(window->bin));
5078 gtk_widget_unmap (child);
5081 /* (Note: Replace "size" with "width" or "height". Also, the request
5082 * mode is honoured.)
5083 * For selecting the default window size, the following conditions
5084 * should hold (in order of importance):
5085 * - the size is not below the minimum size
5086 * Windows cannot be resized below their minimum size, so we must
5087 * ensure we don't do that either.
5088 * - the size is not above the natural size
5089 * It seems weird to allocate more than this in an initial guess.
5090 * - the size does not exceed that of a maximized window
5091 * We want to see the whole window after all.
5092 * (Note that this may not be possible to achieve due to imperfect
5093 * information from the windowing system.)
5096 /* We use these for now to not make windows too big by accident. Note
5097 * that we still clamp these numbers by screen size. Also note that
5098 * minimum size still overrides this. So keep your windows small! :)
5100 #define MAX_DEFAULT_WINDOW_WIDTH 640
5101 #define MAX_DEFAULT_WINDOW_HEIGHT 480
5104 gtk_window_guess_default_size (GtkWindow *window,
5108 GtkWidget *widget = GTK_WIDGET (window);
5110 int minimum, natural;
5112 screen = gtk_widget_get_screen (widget);
5114 *width = gdk_screen_get_width (screen);
5115 *height = gdk_screen_get_height (screen);
5117 if (*width >= *height)
5120 *width = MIN (*width, MAX_DEFAULT_WINDOW_WIDTH);
5121 *height = MIN (*height, MAX_DEFAULT_WINDOW_HEIGHT);
5126 *width = MIN (*width, MAX_DEFAULT_WINDOW_HEIGHT);
5127 *height = MIN (*height, MAX_DEFAULT_WINDOW_WIDTH);
5130 if (gtk_widget_get_request_mode (widget) == GTK_SIZE_REQUEST_WIDTH_FOR_HEIGHT)
5132 gtk_widget_get_preferred_height (widget, &minimum, &natural);
5133 *height = MAX (minimum, MIN (*height, natural));
5135 gtk_widget_get_preferred_width_for_height (widget, *height, &minimum, &natural);
5136 *width = MAX (minimum, MIN (*width, natural));
5138 else /* GTK_SIZE_REQUEST_HEIGHT_FOR_WIDTH or CONSTANT_SIZE */
5140 gtk_widget_get_preferred_width (widget, &minimum, &natural);
5141 *width = MAX (minimum, MIN (*width, natural));
5143 gtk_widget_get_preferred_height_for_width (widget, *width, &minimum, &natural);
5144 *height = MAX (minimum, MIN (*height, natural));
5149 gtk_window_realize (GtkWidget *widget)
5151 GtkAllocation allocation;
5153 GdkWindow *parent_window;
5154 GdkWindow *gdk_window;
5155 GdkWindowAttr attributes;
5156 gint attributes_mask;
5157 GtkWindowPrivate *priv;
5158 GtkStyleContext *context;
5160 window = GTK_WINDOW (widget);
5161 priv = window->priv;
5163 gtk_widget_get_allocation (widget, &allocation);
5165 if (gtk_widget_get_parent_window (widget))
5167 gtk_container_set_resize_mode (GTK_CONTAINER (widget), GTK_RESIZE_PARENT);
5169 gtk_widget_set_realized (widget, TRUE);
5171 attributes.x = allocation.x;
5172 attributes.y = allocation.y;
5173 attributes.width = allocation.width;
5174 attributes.height = allocation.height;
5175 attributes.window_type = GDK_WINDOW_CHILD;
5177 attributes.event_mask = gtk_widget_get_events (widget) | GDK_EXPOSURE_MASK | GDK_STRUCTURE_MASK;
5179 attributes.visual = gtk_widget_get_visual (widget);
5180 attributes.wclass = GDK_INPUT_OUTPUT;
5182 attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL;
5184 gdk_window = gdk_window_new (gtk_widget_get_parent_window (widget),
5185 &attributes, attributes_mask);
5186 gtk_widget_set_window (widget, gdk_window);
5187 gdk_window_set_user_data (gdk_window, widget);
5189 gtk_style_context_set_background (gtk_widget_get_style_context (widget), gdk_window);
5191 gdk_window_enable_synchronized_configure (gdk_window);
5195 gtk_container_set_resize_mode (GTK_CONTAINER (window), GTK_RESIZE_QUEUE);
5197 /* ensure widget tree is properly size allocated */
5198 if (allocation.x == -1 &&
5199 allocation.y == -1 &&
5200 allocation.width == 1 &&
5201 allocation.height == 1)
5207 gtk_window_guess_default_size (window, &allocation.width, &allocation.height);
5208 if (allocation.width == 0 || allocation.height == 0)
5210 /* non-empty window */
5211 allocation.width = 200;
5212 allocation.height = 200;
5214 gtk_widget_size_allocate (widget, &allocation);
5216 _gtk_container_queue_resize (GTK_CONTAINER (widget));
5218 g_return_if_fail (!gtk_widget_get_realized (widget));
5221 gtk_widget_set_realized (widget, TRUE);
5225 case GTK_WINDOW_TOPLEVEL:
5226 attributes.window_type = GDK_WINDOW_TOPLEVEL;
5228 case GTK_WINDOW_POPUP:
5229 attributes.window_type = GDK_WINDOW_TEMP;
5232 g_warning (G_STRLOC": Unknown window type %d!", priv->type);
5236 attributes.title = priv->title;
5237 attributes.wmclass_name = priv->wmclass_name;
5238 attributes.wmclass_class = priv->wmclass_class;
5239 attributes.wclass = GDK_INPUT_OUTPUT;
5240 attributes.visual = gtk_widget_get_visual (widget);
5242 attributes_mask = 0;
5243 parent_window = gtk_widget_get_root_window (widget);
5245 gtk_widget_get_allocation (widget, &allocation);
5246 attributes.width = allocation.width;
5247 attributes.height = allocation.height;
5248 attributes.event_mask = gtk_widget_get_events (widget);
5249 attributes.event_mask |= (GDK_EXPOSURE_MASK |
5250 GDK_KEY_PRESS_MASK |
5251 GDK_KEY_RELEASE_MASK |
5252 GDK_ENTER_NOTIFY_MASK |
5253 GDK_LEAVE_NOTIFY_MASK |
5254 GDK_FOCUS_CHANGE_MASK |
5255 GDK_STRUCTURE_MASK);
5256 attributes.type_hint = priv->type_hint;
5258 attributes_mask |= GDK_WA_VISUAL | GDK_WA_TYPE_HINT;
5259 attributes_mask |= (priv->title ? GDK_WA_TITLE : 0);
5260 attributes_mask |= (priv->wmclass_name ? GDK_WA_WMCLASS : 0);
5262 gdk_window = gdk_window_new (parent_window, &attributes, attributes_mask);
5263 gtk_widget_set_window (widget, gdk_window);
5265 if (priv->opacity_set)
5266 gdk_window_set_opacity (gdk_window, priv->opacity);
5268 gdk_window_enable_synchronized_configure (gdk_window);
5270 gdk_window_set_user_data (gdk_window, window);
5272 context = gtk_widget_get_style_context (widget);
5273 gtk_style_context_set_background (context, gdk_window);
5276 if (priv->transient_parent &&
5277 gtk_widget_get_realized (GTK_WIDGET (priv->transient_parent)))
5278 gdk_window_set_transient_for (gdk_window,
5279 gtk_widget_get_window (GTK_WIDGET (priv->transient_parent)));
5282 gdk_window_set_role (gdk_window, priv->wm_role);
5284 if (!priv->decorated)
5285 gdk_window_set_decorations (gdk_window, 0);
5287 if (!priv->deletable)
5288 gdk_window_set_functions (gdk_window, GDK_FUNC_ALL | GDK_FUNC_CLOSE);
5290 if (gtk_window_get_skip_pager_hint (window))
5291 gdk_window_set_skip_pager_hint (gdk_window, TRUE);
5293 if (gtk_window_get_skip_taskbar_hint (window))
5294 gdk_window_set_skip_taskbar_hint (gdk_window, TRUE);
5296 if (gtk_window_get_accept_focus (window))
5297 gdk_window_set_accept_focus (gdk_window, TRUE);
5299 gdk_window_set_accept_focus (gdk_window, FALSE);
5301 if (gtk_window_get_focus_on_map (window))
5302 gdk_window_set_focus_on_map (gdk_window, TRUE);
5304 gdk_window_set_focus_on_map (gdk_window, FALSE);
5307 gdk_window_set_modal_hint (gdk_window, TRUE);
5309 gdk_window_set_modal_hint (gdk_window, FALSE);
5311 if (priv->startup_id)
5313 #ifdef GDK_WINDOWING_X11
5314 if (GDK_IS_X11_WINDOW (gdk_window))
5316 guint32 timestamp = extract_time_from_startup_id (priv->startup_id);
5317 if (timestamp != GDK_CURRENT_TIME)
5318 gdk_x11_window_set_user_time (gdk_window, timestamp);
5321 if (!startup_id_is_fake (priv->startup_id))
5322 gdk_window_set_startup_id (gdk_window, priv->startup_id);
5325 #ifdef GDK_WINDOWING_X11
5326 if (priv->initial_timestamp != GDK_CURRENT_TIME)
5328 if (GDK_IS_X11_WINDOW (gdk_window))
5329 gdk_x11_window_set_user_time (gdk_window, priv->initial_timestamp);
5333 gtk_window_set_application (window, gtk_window_get_application (window));
5336 gtk_window_realize_icon (window);
5338 if (priv->has_resize_grip)
5339 resize_grip_create_window (window);
5343 gtk_window_unrealize (GtkWidget *widget)
5345 GtkWindow *window = GTK_WINDOW (widget);
5346 GtkWindowPrivate *priv = window->priv;
5347 GtkWindowGeometryInfo *info;
5349 /* On unrealize, we reset the size of the window such
5350 * that we will re-apply the default sizing stuff
5351 * next time we show the window.
5353 * Default positioning is reset on unmap, instead of unrealize.
5355 priv->need_default_size = TRUE;
5356 info = gtk_window_get_geometry_info (window, FALSE);
5359 info->resize_width = -1;
5360 info->resize_height = -1;
5361 info->last.configure_request.x = 0;
5362 info->last.configure_request.y = 0;
5363 info->last.configure_request.width = -1;
5364 info->last.configure_request.height = -1;
5365 /* be sure we reset geom hints on re-realize */
5366 info->last.flags = 0;
5370 gtk_window_unrealize_icon (window);
5372 if (priv->grip_window != NULL)
5373 resize_grip_destroy_window (window);
5375 GTK_WIDGET_CLASS (gtk_window_parent_class)->unrealize (widget);
5378 static GtkJunctionSides
5379 get_grip_junction (GtkWidget *widget)
5381 if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_LTR)
5382 return GTK_JUNCTION_CORNER_BOTTOMRIGHT;
5384 return GTK_JUNCTION_CORNER_BOTTOMLEFT;
5388 get_drag_edge (GtkWidget *widget,
5389 GdkWindowEdge *edge)
5391 GtkWindowPrivate *priv = GTK_WINDOW (widget)->priv;
5392 gboolean hresizable;
5393 gboolean vresizable;
5394 GtkTextDirection dir;
5395 GtkWindowGeometryInfo *info;
5400 info = priv->geometry_info;
5403 GdkWindowHints flags = info->last.flags;
5404 GdkGeometry *geometry = &info->last.geometry;
5406 if ((flags & GDK_HINT_MIN_SIZE) && (flags & GDK_HINT_MAX_SIZE))
5408 hresizable = geometry->min_width < geometry->max_width;
5409 vresizable = geometry->min_height < geometry->max_height;
5413 dir = gtk_widget_get_direction (widget);
5415 if (hresizable && vresizable)
5416 *edge = dir == GTK_TEXT_DIR_LTR ? GDK_WINDOW_EDGE_SOUTH_EAST : GDK_WINDOW_EDGE_SOUTH_WEST;
5417 else if (hresizable)
5418 *edge = dir == GTK_TEXT_DIR_LTR ? GDK_WINDOW_EDGE_EAST : GDK_WINDOW_EDGE_WEST;
5419 else if (vresizable)
5420 *edge = GDK_WINDOW_EDGE_SOUTH;
5428 set_grip_cursor (GtkWindow *window)
5430 GtkWidget *widget = GTK_WIDGET (window);
5431 GtkWindowPrivate *priv = window->priv;
5433 if (priv->grip_window == NULL)
5436 if (gtk_widget_is_sensitive (widget))
5439 GdkDisplay *display;
5440 GdkCursorType cursor_type;
5443 cursor_type = GDK_LEFT_PTR;
5445 if (get_drag_edge (widget, &edge))
5449 case GDK_WINDOW_EDGE_EAST:
5450 cursor_type = GDK_RIGHT_SIDE;
5452 case GDK_WINDOW_EDGE_SOUTH_EAST:
5453 cursor_type = GDK_BOTTOM_RIGHT_CORNER;
5455 case GDK_WINDOW_EDGE_SOUTH:
5456 cursor_type = GDK_BOTTOM_SIDE;
5458 case GDK_WINDOW_EDGE_SOUTH_WEST:
5459 cursor_type = GDK_BOTTOM_LEFT_CORNER;
5461 case GDK_WINDOW_EDGE_WEST:
5462 cursor_type = GDK_LEFT_SIDE;
5468 display = gtk_widget_get_display (widget);
5469 cursor = gdk_cursor_new_for_display (display, cursor_type);
5470 gdk_window_set_cursor (priv->grip_window, cursor);
5471 g_object_unref (cursor);
5474 gdk_window_set_cursor (priv->grip_window, NULL);
5478 set_grip_shape (GtkWindow *window)
5480 GtkWindowPrivate *priv = window->priv;
5481 cairo_region_t *region;
5482 cairo_surface_t *surface;
5484 double width, height;
5486 if (priv->grip_window == NULL)
5489 width = gdk_window_get_width (priv->grip_window);
5490 height = gdk_window_get_height (priv->grip_window);
5491 surface = cairo_image_surface_create (CAIRO_FORMAT_A1, width, height);
5493 cr = cairo_create (surface);
5494 cairo_set_source_rgba (cr, 0.0, 0.0, 0.0, 0.0);
5496 cairo_set_source_rgba (cr, 0.0, 0.0, 0.0, 1.0);
5497 if (get_grip_junction (GTK_WIDGET (window)) & GTK_JUNCTION_CORNER_BOTTOMRIGHT)
5499 cairo_move_to (cr, width, 0.0);
5500 cairo_line_to (cr, width, height);
5501 cairo_line_to (cr, 0.0, height);
5505 cairo_move_to (cr, 0.0, 0.0);
5506 cairo_line_to (cr, width, height);
5507 cairo_line_to (cr, 0.0, height);
5509 cairo_close_path (cr);
5512 region = gdk_cairo_region_create_from_surface (surface);
5513 cairo_surface_destroy (surface);
5515 gdk_window_shape_combine_region (priv->grip_window, region, 0, 0);
5516 cairo_region_destroy (region);
5520 set_grip_position (GtkWindow *window)
5522 GtkWindowPrivate *priv = window->priv;
5525 if (priv->grip_window == NULL)
5528 gtk_window_get_resize_grip_area (window, &rect);
5529 gdk_window_raise (priv->grip_window);
5530 gdk_window_move_resize (priv->grip_window,
5532 rect.width, rect.height);
5536 gtk_window_size_allocate (GtkWidget *widget,
5537 GtkAllocation *allocation)
5539 GtkWindow *window = GTK_WINDOW (widget);
5540 GtkAllocation child_allocation;
5544 gtk_widget_set_allocation (widget, allocation);
5546 if (gtk_widget_get_realized (widget))
5548 /* If it's not a toplevel we're embedded, we need to resize the window's
5549 * window and skip the grip.
5551 if (!gtk_widget_is_toplevel (widget))
5553 gdk_window_move_resize (gtk_widget_get_window (widget),
5554 allocation->x, allocation->y,
5555 allocation->width, allocation->height);
5559 update_grip_visibility (window);
5560 set_grip_position (window);
5564 child = gtk_bin_get_child (&(window->bin));
5565 if (child && gtk_widget_get_visible (child))
5567 border_width = gtk_container_get_border_width (GTK_CONTAINER (window));
5568 child_allocation.x = border_width;
5569 child_allocation.y = border_width;
5570 child_allocation.width =
5571 MAX (1, (gint)allocation->width - child_allocation.x * 2);
5572 child_allocation.height =
5573 MAX (1, (gint)allocation->height - child_allocation.y * 2);
5575 gtk_widget_size_allocate (child, &child_allocation);
5580 gtk_window_configure_event (GtkWidget *widget,
5581 GdkEventConfigure *event)
5583 GtkAllocation allocation;
5584 GtkWindow *window = GTK_WINDOW (widget);
5585 GtkWindowPrivate *priv = window->priv;
5586 gboolean expected_reply = priv->configure_request_count > 0;
5588 if (!gtk_widget_is_toplevel (GTK_WIDGET (widget)))
5590 if (GTK_WIDGET_CLASS (gtk_window_parent_class)->configure_event)
5591 return GTK_WIDGET_CLASS (gtk_window_parent_class)->configure_event (widget, event);
5593 gdk_window_configure_finished (gtk_widget_get_window (widget));
5597 /* priv->configure_request_count incremented for each
5598 * configure request, and decremented to a min of 0 for
5599 * each configure notify.
5601 * All it means is that we know we will get at least
5602 * priv->configure_request_count more configure notifies.
5603 * We could get more configure notifies than that; some
5604 * of the configure notifies we get may be unrelated to
5605 * the configure requests. But we will get at least
5606 * priv->configure_request_count notifies.
5609 if (priv->configure_request_count > 0)
5611 priv->configure_request_count -= 1;
5612 gdk_window_thaw_toplevel_updates_libgtk_only (gtk_widget_get_window (widget));
5615 /* As an optimization, we avoid a resize when possible.
5617 * The only times we can avoid a resize are:
5618 * - we know only the position changed, not the size
5619 * - we know we have made more requests and so will get more
5620 * notifies and can wait to resize when we get them
5622 gtk_widget_get_allocation (widget, &allocation);
5623 if (!expected_reply &&
5624 (allocation.width == event->width &&
5625 allocation.height == event->height))
5627 gdk_window_configure_finished (gtk_widget_get_window (widget));
5632 * If we do need to resize, we do that by:
5633 * - filling in widget->allocation with the new size
5634 * - setting configure_notify_received to TRUE
5635 * for use in gtk_window_move_resize()
5636 * - queueing a resize, leading to invocation of
5637 * gtk_window_move_resize() in an idle handler
5641 priv->configure_notify_received = TRUE;
5643 allocation.width = event->width;
5644 allocation.height = event->height;
5645 gtk_widget_set_allocation (widget, &allocation);
5647 gdk_window_invalidate_rect (gtk_widget_get_window (widget), NULL, FALSE); // XXX - What was this for again?
5649 _gtk_container_queue_resize (GTK_CONTAINER (widget));
5655 gtk_window_state_event (GtkWidget *widget,
5656 GdkEventWindowState *event)
5658 update_grip_visibility (GTK_WINDOW (widget));
5660 if (event->changed_mask & GDK_WINDOW_STATE_FOCUSED)
5661 ensure_state_flag_backdrop (widget);
5667 gtk_window_direction_changed (GtkWidget *widget,
5668 GtkTextDirection prev_dir)
5670 GtkWindow *window = GTK_WINDOW (widget);
5672 set_grip_cursor (window);
5673 set_grip_position (window);
5674 set_grip_shape (window);
5678 gtk_window_state_changed (GtkWidget *widget,
5679 GtkStateType previous_state)
5681 GtkWindow *window = GTK_WINDOW (widget);
5683 update_grip_visibility (window);
5687 gtk_window_style_updated (GtkWidget *widget)
5689 GtkWindow *window = GTK_WINDOW (widget);
5690 GtkWindowPrivate *priv = window->priv;
5693 GTK_WIDGET_CLASS (gtk_window_parent_class)->style_updated (widget);
5695 if (priv->grip_window != NULL && gtk_window_get_resize_grip_area (window, &rect))
5697 gdk_window_move_resize (priv->grip_window,
5699 rect.width, rect.height);
5701 set_grip_shape (window);
5702 gtk_widget_queue_resize (widget);
5707 resize_grip_create_window (GtkWindow *window)
5710 GtkWindowPrivate *priv;
5711 GdkWindowAttr attributes;
5712 gint attributes_mask;
5714 GdkRGBA transparent = {0, 0, 0, 0};
5716 priv = window->priv;
5717 widget = GTK_WIDGET (window);
5719 g_return_if_fail (gtk_widget_get_realized (widget));
5720 g_return_if_fail (priv->grip_window == NULL);
5722 gtk_window_get_resize_grip_area (window, &rect);
5724 attributes.x = rect.x;
5725 attributes.y = rect.y;
5726 attributes.width = rect.width;
5727 attributes.height = rect.height;
5728 attributes.window_type = GDK_WINDOW_CHILD;
5729 attributes.wclass = GDK_INPUT_OUTPUT;
5730 attributes.event_mask = gtk_widget_get_events (widget) |
5732 GDK_BUTTON_PRESS_MASK;
5734 attributes_mask = GDK_WA_X | GDK_WA_Y;
5736 priv->grip_window = gdk_window_new (gtk_widget_get_window (widget),
5739 gdk_window_set_background_rgba (priv->grip_window, &transparent);
5741 gdk_window_set_user_data (priv->grip_window, widget);
5743 gdk_window_raise (priv->grip_window);
5745 set_grip_shape (window);
5746 update_grip_visibility (window);
5750 resize_grip_destroy_window (GtkWindow *window)
5752 GtkWindowPrivate *priv = window->priv;
5754 gdk_window_set_user_data (priv->grip_window, NULL);
5755 gdk_window_destroy (priv->grip_window);
5756 priv->grip_window = NULL;
5757 update_grip_visibility (window);
5761 * gtk_window_set_has_resize_grip:
5762 * @window: a #GtkWindow
5763 * @value: %TRUE to allow a resize grip
5765 * Sets whether @window has a corner resize grip.
5767 * Note that the resize grip is only shown if the window
5768 * is actually resizable and not maximized. Use
5769 * gtk_window_resize_grip_is_visible() to find out if the
5770 * resize grip is currently shown.
5775 gtk_window_set_has_resize_grip (GtkWindow *window,
5778 GtkWidget *widget = GTK_WIDGET (window);
5779 GtkWindowPrivate *priv = window->priv;
5781 value = value != FALSE;
5783 if (value != priv->has_resize_grip)
5785 priv->has_resize_grip = value;
5786 gtk_widget_queue_draw (widget);
5788 if (gtk_widget_get_realized (widget) &&
5789 gtk_widget_is_toplevel (GTK_WIDGET (widget)))
5791 if (priv->has_resize_grip && priv->grip_window == NULL)
5792 resize_grip_create_window (window);
5793 else if (!priv->has_resize_grip && priv->grip_window != NULL)
5794 resize_grip_destroy_window (window);
5797 g_object_notify (G_OBJECT (window), "has-resize-grip");
5802 update_grip_visibility (GtkWindow *window)
5804 GtkWindowPrivate *priv = window->priv;
5807 val = gtk_window_resize_grip_is_visible (window);
5809 if (priv->grip_window != NULL)
5813 gdk_window_show (priv->grip_window);
5814 set_grip_cursor (window);
5818 gdk_window_hide (priv->grip_window);
5822 if (priv->resize_grip_visible != val)
5824 priv->resize_grip_visible = val;
5826 g_object_notify (G_OBJECT (window), "resize-grip-visible");
5831 * gtk_window_resize_grip_is_visible:
5832 * @window: a #GtkWindow
5834 * Determines whether a resize grip is visible for the specified window.
5836 * Returns: %TRUE if a resize grip exists and is visible
5841 gtk_window_resize_grip_is_visible (GtkWindow *window)
5844 GtkWindowPrivate *priv;
5847 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
5849 priv = window->priv;
5850 widget = GTK_WIDGET (window);
5852 if (priv->type == GTK_WINDOW_POPUP)
5855 if (!priv->resizable)
5858 if (!gtk_widget_is_toplevel (GTK_WIDGET (widget)))
5861 if (gtk_widget_get_realized (widget))
5863 GdkWindowState state;
5865 state = gdk_window_get_state (gtk_widget_get_window (widget));
5867 if (state & GDK_WINDOW_STATE_MAXIMIZED || state & GDK_WINDOW_STATE_FULLSCREEN)
5871 if (!get_drag_edge (widget, &edge))
5874 return window->priv->has_resize_grip;
5878 * gtk_window_get_has_resize_grip:
5879 * @window: a #GtkWindow
5881 * Determines whether the window may have a resize grip.
5883 * Returns: %TRUE if the window has a resize grip
5888 gtk_window_get_has_resize_grip (GtkWindow *window)
5890 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
5892 return window->priv->has_resize_grip;
5896 * gtk_window_get_resize_grip_area:
5897 * @window: a #GtkWindow
5898 * @rect: (out): a pointer to a #GdkRectangle which we should store
5899 * the resize grip area
5901 * If a window has a resize grip, this will retrieve the grip
5902 * position, width and height into the specified #GdkRectangle.
5904 * Returns: %TRUE if the resize grip's area was retrieved
5909 gtk_window_get_resize_grip_area (GtkWindow *window,
5912 GtkWidget *widget = GTK_WIDGET (window);
5913 GtkAllocation allocation;
5917 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
5919 if (!window->priv->has_resize_grip)
5922 gtk_widget_get_allocation (widget, &allocation);
5924 gtk_widget_style_get (widget,
5925 "resize-grip-width", &grip_width,
5926 "resize-grip-height", &grip_height,
5929 if (grip_width > allocation.width)
5930 grip_width = allocation.width;
5932 if (grip_height > allocation.height)
5933 grip_height = allocation.height;
5935 rect->width = grip_width;
5936 rect->height = grip_height;
5937 rect->y = allocation.y + allocation.height - grip_height;
5939 if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_LTR)
5940 rect->x = allocation.x + allocation.width - grip_width;
5942 rect->x = allocation.x;
5947 /* the accel_key and accel_mods fields of the key have to be setup
5948 * upon calling this function. it'll then return whether that key
5949 * is at all used as accelerator, and if so will OR in the
5950 * accel_flags member of the key.
5953 _gtk_window_query_nonaccels (GtkWindow *window,
5955 GdkModifierType accel_mods)
5957 GtkWindowPrivate *priv;
5959 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
5961 priv = window->priv;
5963 /* movement keys are considered locked accels */
5966 static const guint bindings[] = {
5967 GDK_KEY_space, GDK_KEY_KP_Space, GDK_KEY_Return, GDK_KEY_ISO_Enter, GDK_KEY_KP_Enter, GDK_KEY_Up, GDK_KEY_KP_Up, GDK_KEY_Down, GDK_KEY_KP_Down,
5968 GDK_KEY_Left, GDK_KEY_KP_Left, GDK_KEY_Right, GDK_KEY_KP_Right, GDK_KEY_Tab, GDK_KEY_KP_Tab, GDK_KEY_ISO_Left_Tab,
5972 for (i = 0; i < G_N_ELEMENTS (bindings); i++)
5973 if (bindings[i] == accel_key)
5977 /* mnemonics are considered locked accels */
5978 if (accel_mods == priv->mnemonic_modifier)
5980 GtkMnemonicHash *mnemonic_hash = gtk_window_get_mnemonic_hash (window, FALSE);
5981 if (mnemonic_hash && _gtk_mnemonic_hash_lookup (mnemonic_hash, accel_key))
5989 * gtk_window_propagate_key_event:
5990 * @window: a #GtkWindow
5991 * @event: a #GdkEventKey
5993 * Propagate a key press or release event to the focus widget and
5994 * up the focus container chain until a widget handles @event.
5995 * This is normally called by the default ::key_press_event and
5996 * ::key_release_event handlers for toplevel windows,
5997 * however in some cases it may be useful to call this directly when
5998 * overriding the standard key handling for a toplevel window.
6000 * Return value: %TRUE if a widget in the focus chain handled the event.
6005 gtk_window_propagate_key_event (GtkWindow *window,
6008 GtkWindowPrivate *priv;
6009 gboolean handled = FALSE;
6010 GtkWidget *widget, *focus;
6012 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
6014 priv = window->priv;
6015 widget = GTK_WIDGET (window);
6017 focus = priv->focus_widget;
6019 g_object_ref (focus);
6022 focus && focus != widget &&
6023 gtk_widget_get_toplevel (focus) == widget)
6027 if (gtk_widget_is_sensitive (focus))
6028 handled = gtk_widget_event (focus, (GdkEvent*) event);
6030 parent = gtk_widget_get_parent (focus);
6032 g_object_ref (parent);
6034 g_object_unref (focus);
6040 g_object_unref (focus);
6046 gtk_window_key_press_event (GtkWidget *widget,
6049 GtkWindow *window = GTK_WINDOW (widget);
6050 gboolean handled = FALSE;
6052 /* handle mnemonics and accelerators */
6054 handled = gtk_window_activate_key (window, event);
6056 /* handle focus widget key events */
6058 handled = gtk_window_propagate_key_event (window, event);
6060 /* Chain up, invokes binding set */
6062 handled = GTK_WIDGET_CLASS (gtk_window_parent_class)->key_press_event (widget, event);
6068 gtk_window_key_release_event (GtkWidget *widget,
6071 GtkWindow *window = GTK_WINDOW (widget);
6072 gboolean handled = FALSE;
6074 /* handle focus widget key events */
6076 handled = gtk_window_propagate_key_event (window, event);
6078 /* Chain up, invokes binding set */
6080 handled = GTK_WIDGET_CLASS (gtk_window_parent_class)->key_release_event (widget, event);
6086 gtk_window_button_press_event (GtkWidget *widget,
6087 GdkEventButton *event)
6089 GtkWindowPrivate *priv = GTK_WINDOW (widget)->priv;
6092 if (event->window == priv->grip_window)
6094 if (get_drag_edge (widget, &edge))
6095 gdk_window_begin_resize_drag_for_device (gtk_widget_get_window (widget),
6097 gdk_event_get_device ((GdkEvent *) event),
6110 gtk_window_real_activate_default (GtkWindow *window)
6112 gtk_window_activate_default (window);
6116 gtk_window_real_activate_focus (GtkWindow *window)
6118 gtk_window_activate_focus (window);
6122 gtk_window_enter_notify_event (GtkWidget *widget,
6123 GdkEventCrossing *event)
6129 gtk_window_leave_notify_event (GtkWidget *widget,
6130 GdkEventCrossing *event)
6136 do_focus_change (GtkWidget *widget,
6140 GdkDeviceManager *device_manager;
6143 g_object_ref (widget);
6145 device_manager = gdk_display_get_device_manager (gtk_widget_get_display (widget));
6146 devices = gdk_device_manager_list_devices (device_manager, GDK_DEVICE_TYPE_MASTER);
6147 devices = g_list_concat (devices, gdk_device_manager_list_devices (device_manager, GDK_DEVICE_TYPE_SLAVE));
6148 devices = g_list_concat (devices, gdk_device_manager_list_devices (device_manager, GDK_DEVICE_TYPE_FLOATING));
6150 for (d = devices; d; d = d->next)
6152 GdkDevice *dev = d->data;
6155 if (gdk_device_get_source (dev) != GDK_SOURCE_KEYBOARD)
6158 /* Skip non-master keyboards that haven't
6159 * selected for events from this window
6161 window = gtk_widget_get_window (widget);
6162 if (gdk_device_get_device_type (dev) != GDK_DEVICE_TYPE_MASTER &&
6163 window && !gdk_window_get_device_events (window, dev))
6166 fevent = gdk_event_new (GDK_FOCUS_CHANGE);
6168 fevent->focus_change.type = GDK_FOCUS_CHANGE;
6169 fevent->focus_change.window = window;
6171 g_object_ref (window);
6172 fevent->focus_change.in = in;
6173 gdk_event_set_device (fevent, dev);
6175 gtk_widget_send_focus_change (widget, fevent);
6177 gdk_event_free (fevent);
6180 g_list_free (devices);
6181 g_object_unref (widget);
6185 maybe_set_mnemonics_visible (GtkWindow *window)
6188 GdkDeviceManager *device_manager;
6190 device_manager = gdk_display_get_device_manager (gtk_widget_get_display (GTK_WIDGET (window)));
6191 devices = gdk_device_manager_list_devices (device_manager, GDK_DEVICE_TYPE_MASTER);
6193 for (d = devices; d; d = d->next)
6195 GdkDevice *dev = d->data;
6197 if (gdk_device_get_source (dev) == GDK_SOURCE_MOUSE)
6199 GdkModifierType mask;
6201 gdk_device_get_state (dev, gtk_widget_get_window (GTK_WIDGET (window)),
6203 if (window->priv->mnemonic_modifier == (mask & gtk_accelerator_get_default_mod_mask ()))
6205 gtk_window_set_mnemonics_visible (window, TRUE);
6211 g_list_free (devices);
6215 gtk_window_focus_in_event (GtkWidget *widget,
6216 GdkEventFocus *event)
6218 GtkWindow *window = GTK_WINDOW (widget);
6219 gboolean auto_mnemonics;
6221 /* It appears spurious focus in events can occur when
6222 * the window is hidden. So we'll just check to see if
6223 * the window is visible before actually handling the
6226 if (gtk_widget_get_visible (widget))
6228 _gtk_window_set_has_toplevel_focus (window, TRUE);
6229 _gtk_window_set_is_active (window, TRUE);
6231 g_object_get (gtk_widget_get_settings (widget),
6232 "gtk-auto-mnemonics", &auto_mnemonics, NULL);
6234 maybe_set_mnemonics_visible (window);
6241 gtk_window_focus_out_event (GtkWidget *widget,
6242 GdkEventFocus *event)
6244 GtkWindow *window = GTK_WINDOW (widget);
6245 gboolean auto_mnemonics;
6247 _gtk_window_set_has_toplevel_focus (window, FALSE);
6248 _gtk_window_set_is_active (window, FALSE);
6250 /* set the mnemonic-visible property to false */
6251 g_object_get (gtk_widget_get_settings (widget),
6252 "gtk-auto-mnemonics", &auto_mnemonics, NULL);
6254 gtk_window_set_mnemonics_visible (window, FALSE);
6260 gtk_window_check_resize (GtkContainer *container)
6262 /* If the window is not toplevel anymore than it's embedded somewhere,
6263 * so handle it like a normal window */
6264 if (!gtk_widget_is_toplevel (GTK_WIDGET (container)))
6265 GTK_CONTAINER_CLASS (gtk_window_parent_class)->check_resize (container);
6266 else if (gtk_widget_get_visible (GTK_WIDGET (container)))
6267 gtk_window_move_resize (GTK_WINDOW (container));
6271 gtk_window_focus (GtkWidget *widget,
6272 GtkDirectionType direction)
6274 GtkWindowPrivate *priv;
6277 GtkContainer *container;
6279 GtkWidget *old_focus_child;
6282 if (!gtk_widget_is_toplevel (GTK_WIDGET (widget)))
6283 return GTK_WIDGET_CLASS (gtk_window_parent_class)->focus (widget, direction);
6285 container = GTK_CONTAINER (widget);
6286 window = GTK_WINDOW (widget);
6287 priv = window->priv;
6288 bin = GTK_BIN (widget);
6290 old_focus_child = gtk_container_get_focus_child (container);
6292 /* We need a special implementation here to deal properly with wrapping
6293 * around in the tab chain without the danger of going into an
6296 if (old_focus_child)
6298 if (gtk_widget_child_focus (old_focus_child, direction))
6302 if (priv->focus_widget)
6304 if (direction == GTK_DIR_LEFT ||
6305 direction == GTK_DIR_RIGHT ||
6306 direction == GTK_DIR_UP ||
6307 direction == GTK_DIR_DOWN)
6312 /* Wrapped off the end, clear the focus setting for the toplpevel */
6313 parent = gtk_widget_get_parent (priv->focus_widget);
6316 gtk_container_set_focus_child (GTK_CONTAINER (parent), NULL);
6317 parent = gtk_widget_get_parent (parent);
6320 gtk_window_set_focus (GTK_WINDOW (container), NULL);
6323 /* Now try to focus the first widget in the window */
6324 child = gtk_bin_get_child (bin);
6327 if (gtk_widget_child_focus (child, direction))
6335 gtk_window_move_focus (GtkWidget *widget,
6336 GtkDirectionType dir)
6338 if (!gtk_widget_is_toplevel (GTK_WIDGET (widget)))
6340 GTK_WIDGET_CLASS (gtk_window_parent_class)->move_focus (widget, dir);
6344 gtk_widget_child_focus (widget, dir);
6346 if (! gtk_container_get_focus_child (GTK_CONTAINER (widget)))
6347 gtk_window_set_focus (GTK_WINDOW (widget), NULL);
6351 gtk_window_real_set_focus (GtkWindow *window,
6354 GtkWindowPrivate *priv = window->priv;
6355 GtkWidget *old_focus = priv->focus_widget;
6356 gboolean had_default = FALSE;
6357 gboolean focus_had_default = FALSE;
6358 gboolean old_focus_had_default = FALSE;
6362 g_object_ref (old_focus);
6363 g_object_freeze_notify (G_OBJECT (old_focus));
6364 old_focus_had_default = gtk_widget_has_default (old_focus);
6368 g_object_ref (focus);
6369 g_object_freeze_notify (G_OBJECT (focus));
6370 focus_had_default = gtk_widget_has_default (focus);
6373 if (priv->default_widget)
6374 had_default = gtk_widget_has_default (priv->default_widget);
6376 if (priv->focus_widget)
6378 if (gtk_widget_get_receives_default (priv->focus_widget) &&
6379 (priv->focus_widget != priv->default_widget))
6381 _gtk_widget_set_has_default (priv->focus_widget, FALSE);
6382 gtk_widget_queue_draw (priv->focus_widget);
6384 if (priv->default_widget)
6385 _gtk_widget_set_has_default (priv->default_widget, TRUE);
6388 priv->focus_widget = NULL;
6390 if (priv->has_focus)
6391 do_focus_change (old_focus, FALSE);
6393 g_object_notify (G_OBJECT (old_focus), "is-focus");
6396 /* The above notifications may have set a new focus widget,
6397 * if so, we don't want to override it.
6399 if (focus && !priv->focus_widget)
6401 priv->focus_widget = focus;
6403 if (gtk_widget_get_receives_default (priv->focus_widget) &&
6404 (priv->focus_widget != priv->default_widget))
6406 if (gtk_widget_get_can_default (priv->focus_widget))
6407 _gtk_widget_set_has_default (priv->focus_widget, TRUE);
6409 if (priv->default_widget)
6410 _gtk_widget_set_has_default (priv->default_widget, FALSE);
6413 if (priv->has_focus)
6414 do_focus_change (priv->focus_widget, TRUE);
6416 g_object_notify (G_OBJECT (priv->focus_widget), "is-focus");
6419 /* If the default widget changed, a redraw will have been queued
6420 * on the old and new default widgets by gtk_window_set_default(), so
6421 * we only have to worry about the case where it didn't change.
6422 * We'll sometimes queue a draw twice on the new widget but that
6425 if (priv->default_widget &&
6426 (had_default != gtk_widget_has_default (priv->default_widget)))
6427 gtk_widget_queue_draw (priv->default_widget);
6431 if (old_focus_had_default != gtk_widget_has_default (old_focus))
6432 gtk_widget_queue_draw (old_focus);
6434 g_object_thaw_notify (G_OBJECT (old_focus));
6435 g_object_unref (old_focus);
6439 if (focus_had_default != gtk_widget_has_default (focus))
6440 gtk_widget_queue_draw (focus);
6442 g_object_thaw_notify (G_OBJECT (focus));
6443 g_object_unref (focus);
6449 gtk_window_get_preferred_width (GtkWidget *widget,
6457 window = GTK_WINDOW (widget);
6458 child = gtk_bin_get_child (GTK_BIN (window));
6460 border_width = gtk_container_get_border_width (GTK_CONTAINER (window));
6461 *minimum_size = border_width * 2;
6462 *natural_size = border_width * 2;
6464 if (child && gtk_widget_get_visible (child))
6466 gint child_min, child_nat;
6467 gtk_widget_get_preferred_width (child, &child_min, &child_nat);
6469 *minimum_size += child_min;
6470 *natural_size += child_nat;
6475 gtk_window_get_preferred_height (GtkWidget *widget,
6483 window = GTK_WINDOW (widget);
6484 child = gtk_bin_get_child (GTK_BIN (window));
6486 border_width = gtk_container_get_border_width (GTK_CONTAINER (window));
6487 *minimum_size = border_width * 2;
6488 *natural_size = border_width * 2;
6490 if (child && gtk_widget_get_visible (child))
6492 gint child_min, child_nat;
6493 gtk_widget_get_preferred_height (child, &child_min, &child_nat);
6495 *minimum_size += child_min;
6496 *natural_size += child_nat;
6502 * _gtk_window_unset_focus_and_default:
6503 * @window: a #GtkWindow
6504 * @widget: a widget inside of @window
6506 * Checks whether the focus and default widgets of @window are
6507 * @widget or a descendent of @widget, and if so, unset them.
6510 _gtk_window_unset_focus_and_default (GtkWindow *window,
6514 GtkWindowPrivate *priv = window->priv;
6518 g_object_ref (window);
6519 g_object_ref (widget);
6521 parent = gtk_widget_get_parent (widget);
6522 if (gtk_container_get_focus_child (GTK_CONTAINER (parent)) == widget)
6524 child = priv->focus_widget;
6526 while (child && child != widget)
6527 child = gtk_widget_get_parent (child);
6529 if (child == widget)
6530 gtk_window_set_focus (GTK_WINDOW (window), NULL);
6533 child = priv->default_widget;
6535 while (child && child != widget)
6536 child = gtk_widget_get_parent (child);
6538 if (child == widget)
6539 gtk_window_set_default (window, NULL);
6541 g_object_unref (widget);
6542 g_object_unref (window);
6545 /*********************************
6546 * Functions related to resizing *
6547 *********************************/
6550 geometry_size_to_pixels (GdkGeometry *geometry,
6555 gint base_width = 0;
6556 gint base_height = 0;
6558 gint min_height = 0;
6560 gint height_inc = 1;
6562 if (flags & GDK_HINT_BASE_SIZE)
6564 base_width = geometry->base_width;
6565 base_height = geometry->base_height;
6567 if (flags & GDK_HINT_MIN_SIZE)
6569 min_width = geometry->min_width;
6570 min_height = geometry->min_height;
6572 if (flags & GDK_HINT_RESIZE_INC)
6574 width_inc = geometry->width_inc;
6575 height_inc = geometry->height_inc;
6579 *width = MAX (*width * width_inc + base_width, min_width);
6581 *height = MAX (*height * height_inc + base_height, min_height);
6584 /* This function doesn't constrain to geometry hints */
6586 gtk_window_compute_configure_request_size (GtkWindow *window,
6587 GdkGeometry *geometry,
6592 GtkWindowPrivate *priv = window->priv;
6593 GtkWindowGeometryInfo *info;
6596 * - we've done a size request
6599 info = gtk_window_get_geometry_info (window, FALSE);
6601 if (priv->need_default_size)
6603 gtk_window_guess_default_size (window, width, height);
6605 /* If window is empty so requests 0, default to random nonzero size */
6606 if (*width == 0 && *height == 0)
6612 /* Override with default size */
6616 if (info->default_width > 0)
6617 *width = info->default_width;
6618 if (info->default_height > 0)
6619 *height = info->default_height;
6621 if (info->default_is_geometry)
6622 geometry_size_to_pixels (geometry, flags,
6623 info->default_width > 0 ? width : NULL,
6624 info->default_height > 0 ? height : NULL);
6629 GtkAllocation allocation;
6631 gtk_widget_get_allocation (GTK_WIDGET (window), &allocation);
6633 /* Default to keeping current size */
6634 *width = allocation.width;
6635 *height = allocation.height;
6638 /* Override any size with gtk_window_resize() values */
6641 if (info->resize_width > 0)
6642 *width = info->resize_width;
6643 if (info->resize_height > 0)
6644 *height = info->resize_height;
6646 if (info->resize_is_geometry)
6647 geometry_size_to_pixels (geometry, flags,
6648 info->resize_width > 0 ? width : NULL,
6649 info->resize_height > 0 ? height : NULL);
6652 /* Don't ever request zero width or height, its not supported by
6653 gdk. The size allocation code will round it to 1 anyway but if
6654 we do it then the value returned from this function will is
6655 not comparable to the size allocation read from the GtkWindow. */
6656 *width = MAX (*width, 1);
6657 *height = MAX (*height, 1);
6660 static GtkWindowPosition
6661 get_effective_position (GtkWindow *window)
6663 GtkWindowPrivate *priv = window->priv;
6664 GtkWindowPosition pos = priv->position;
6666 if (pos == GTK_WIN_POS_CENTER_ON_PARENT &&
6667 (priv->transient_parent == NULL ||
6668 !gtk_widget_get_mapped (GTK_WIDGET (priv->transient_parent))))
6669 pos = GTK_WIN_POS_NONE;
6675 get_center_monitor_of_window (GtkWindow *window)
6677 /* We could try to sort out the relative positions of the monitors and
6678 * stuff, or we could just be losers and assume you have a row
6679 * or column of monitors.
6681 return gdk_screen_get_n_monitors (gtk_window_check_screen (window)) / 2;
6685 get_monitor_containing_pointer (GtkWindow *window)
6689 GdkScreen *window_screen;
6690 GdkScreen *pointer_screen;
6691 GdkDisplay *display;
6692 GdkDeviceManager *device_manager;
6695 window_screen = gtk_window_check_screen (window);
6696 display = gdk_screen_get_display (window_screen);
6697 device_manager = gdk_display_get_device_manager (display);
6698 pointer = gdk_device_manager_get_client_pointer (device_manager);
6700 gdk_device_get_position (pointer,
6704 if (pointer_screen == window_screen)
6705 monitor_num = gdk_screen_get_monitor_at_point (pointer_screen, px, py);
6713 center_window_on_monitor (GtkWindow *window,
6719 GdkRectangle monitor;
6722 monitor_num = get_monitor_containing_pointer (window);
6724 if (monitor_num == -1)
6725 monitor_num = get_center_monitor_of_window (window);
6727 gdk_screen_get_monitor_workarea (gtk_window_check_screen (window),
6728 monitor_num, &monitor);
6730 *x = (monitor.width - w) / 2 + monitor.x;
6731 *y = (monitor.height - h) / 2 + monitor.y;
6733 /* Be sure we aren't off the monitor, ignoring _NET_WM_STRUT
6734 * and WM decorations.
6748 if (extent > clamp_extent)
6750 *base = clamp_base + clamp_extent/2 - extent/2;
6751 else if (*base < clamp_base)
6753 else if (*base + extent > clamp_base + clamp_extent)
6754 *base = clamp_base + clamp_extent - extent;
6758 clamp_window_to_rectangle (gint *x,
6762 const GdkRectangle *rect)
6764 #ifdef DEBUGGING_OUTPUT
6765 g_print ("%s: %+d%+d %dx%d: %+d%+d: %dx%d", G_STRFUNC, rect->x, rect->y, rect->width, rect->height, *x, *y, w, h);
6768 /* If it is too large, center it. If it fits on the monitor but is
6769 * partially outside, move it to the closest edge. Do this
6770 * separately in x and y directions.
6772 clamp (x, w, rect->x, rect->width);
6773 clamp (y, h, rect->y, rect->height);
6774 #ifdef DEBUGGING_OUTPUT
6775 g_print (" ==> %+d%+d: %dx%d\n", *x, *y, w, h);
6781 gtk_window_compute_configure_request (GtkWindow *window,
6782 GdkRectangle *request,
6783 GdkGeometry *geometry,
6786 GtkWindowPrivate *priv = window->priv;
6787 GdkGeometry new_geometry;
6790 GtkWindowPosition pos;
6791 GtkWidget *parent_widget;
6792 GtkWindowGeometryInfo *info;
6796 screen = gtk_window_check_screen (window);
6798 gtk_window_compute_hints (window, &new_geometry, &new_flags);
6799 gtk_window_compute_configure_request_size (window,
6800 &new_geometry, new_flags,
6803 gtk_window_constrain_size (window,
6804 &new_geometry, new_flags,
6808 parent_widget = (GtkWidget*) priv->transient_parent;
6810 pos = get_effective_position (window);
6811 info = gtk_window_get_geometry_info (window, FALSE);
6813 /* by default, don't change position requested */
6816 x = info->last.configure_request.x;
6817 y = info->last.configure_request.y;
6826 if (priv->need_default_position)
6829 /* FIXME this all interrelates with window gravity.
6830 * For most of them I think we want to set GRAVITY_CENTER.
6832 * Not sure how to go about that.
6836 /* here we are only handling CENTER_ALWAYS
6837 * as it relates to default positioning,
6838 * where it's equivalent to simply CENTER
6840 case GTK_WIN_POS_CENTER_ALWAYS:
6841 case GTK_WIN_POS_CENTER:
6842 center_window_on_monitor (window, w, h, &x, &y);
6845 case GTK_WIN_POS_CENTER_ON_PARENT:
6847 GtkAllocation allocation;
6848 GdkWindow *gdk_window;
6850 GdkRectangle monitor;
6853 g_assert (gtk_widget_get_mapped (parent_widget)); /* established earlier */
6855 gdk_window = gtk_widget_get_window (parent_widget);
6857 if (gdk_window != NULL)
6858 monitor_num = gdk_screen_get_monitor_at_window (screen,
6863 gdk_window_get_origin (gdk_window,
6866 gtk_widget_get_allocation (parent_widget, &allocation);
6867 x = ox + (allocation.width - w) / 2;
6868 y = oy + (allocation.height - h) / 2;
6870 /* Clamp onto current monitor, ignoring _NET_WM_STRUT and
6871 * WM decorations. If parent wasn't on a monitor, just
6874 if (monitor_num >= 0)
6876 gdk_screen_get_monitor_geometry (screen, monitor_num, &monitor);
6877 clamp_window_to_rectangle (&x, &y, w, h, &monitor);
6882 case GTK_WIN_POS_MOUSE:
6884 gint screen_width = gdk_screen_get_width (screen);
6885 gint screen_height = gdk_screen_get_height (screen);
6887 GdkRectangle monitor;
6888 GdkDisplay *display;
6889 GdkDeviceManager *device_manager;
6891 GdkScreen *pointer_screen;
6894 display = gdk_screen_get_display (screen);
6895 device_manager = gdk_display_get_device_manager (display);
6896 pointer = gdk_device_manager_get_client_pointer (device_manager);
6898 gdk_device_get_position (pointer,
6902 if (pointer_screen == screen)
6903 monitor_num = gdk_screen_get_monitor_at_point (screen, px, py);
6909 x = CLAMP (x, 0, screen_width - w);
6910 y = CLAMP (y, 0, screen_height - h);
6912 /* Clamp onto current monitor, ignoring _NET_WM_STRUT and
6913 * WM decorations. Don't try to figure out what's going
6914 * on if the mouse wasn't inside a monitor.
6916 if (monitor_num >= 0)
6918 gdk_screen_get_monitor_geometry (screen, monitor_num, &monitor);
6919 clamp_window_to_rectangle (&x, &y, w, h, &monitor);
6927 } /* if (priv->need_default_position) */
6929 if (priv->need_default_position && info &&
6930 info->initial_pos_set)
6932 x = info->initial_x;
6933 y = info->initial_y;
6934 gtk_window_constrain_position (window, w, h, &x, &y);
6940 request->height = h;
6943 *geometry = new_geometry;
6949 gtk_window_constrain_position (GtkWindow *window,
6955 GtkWindowPrivate *priv = window->priv;
6957 /* See long comments in gtk_window_move_resize()
6958 * on when it's safe to call this function.
6960 if (priv->position == GTK_WIN_POS_CENTER_ALWAYS)
6962 gint center_x, center_y;
6964 center_window_on_monitor (window, new_width, new_height, ¢er_x, ¢er_y);
6972 gtk_window_move_resize (GtkWindow *window)
6976 * First we determine whether any information has changed that would
6977 * cause us to revise our last configure request. If we would send
6978 * a different configure request from last time, then
6979 * configure_request_size_changed = TRUE or
6980 * configure_request_pos_changed = TRUE. configure_request_size_changed
6981 * may be true due to new hints, a gtk_window_resize(), or whatever.
6982 * configure_request_pos_changed may be true due to gtk_window_set_position()
6983 * or gtk_window_move().
6985 * If the configure request has changed, we send off a new one. To
6986 * ensure GTK+ invariants are maintained (resize queue does what it
6987 * should), we go ahead and size_allocate the requested size in this
6990 * If the configure request has not changed, we don't ever resend
6991 * it, because it could mean fighting the user or window manager.
6994 * To prepare the configure request, we come up with a base size/pos:
6995 * - the one from gtk_window_move()/gtk_window_resize()
6996 * - else default_width, default_height if we haven't ever
6998 * - else the size request if we haven't ever been mapped,
6999 * as a substitute default size
7000 * - else the current size of the window, as received from
7001 * configure notifies (i.e. the current allocation)
7003 * If GTK_WIN_POS_CENTER_ALWAYS is active, we constrain
7004 * the position request to be centered.
7006 GtkWindowPrivate *priv = window->priv;
7007 GtkAllocation allocation;
7009 GtkContainer *container;
7010 GtkWindowGeometryInfo *info;
7011 GdkGeometry new_geometry;
7012 GdkWindow *gdk_window;
7014 GdkRectangle new_request;
7015 gboolean configure_request_size_changed;
7016 gboolean configure_request_pos_changed;
7017 gboolean hints_changed; /* do we need to send these again */
7018 GtkWindowLastGeometryInfo saved_last_info;
7020 widget = GTK_WIDGET (window);
7022 gdk_window = gtk_widget_get_window (widget);
7023 container = GTK_CONTAINER (widget);
7024 info = gtk_window_get_geometry_info (window, TRUE);
7026 configure_request_size_changed = FALSE;
7027 configure_request_pos_changed = FALSE;
7029 gtk_window_compute_configure_request (window, &new_request,
7030 &new_geometry, &new_flags);
7032 /* This check implies the invariant that we never set info->last
7033 * without setting the hints and sending off a configure request.
7035 * If we change info->last without sending the request, we may
7038 if (info->last.configure_request.x != new_request.x ||
7039 info->last.configure_request.y != new_request.y)
7040 configure_request_pos_changed = TRUE;
7042 if ((info->last.configure_request.width != new_request.width ||
7043 info->last.configure_request.height != new_request.height))
7044 configure_request_size_changed = TRUE;
7046 hints_changed = FALSE;
7048 if (!gtk_window_compare_hints (&info->last.geometry, info->last.flags,
7049 &new_geometry, new_flags))
7051 hints_changed = TRUE;
7054 /* Position Constraints
7055 * ====================
7057 * POS_CENTER_ALWAYS is conceptually a constraint rather than
7058 * a default. The other POS_ values are used only when the
7059 * window is shown, not after that.
7061 * However, we can't implement a position constraint as
7062 * "anytime the window size changes, center the window"
7063 * because this may well end up fighting the WM or user. In
7064 * fact it gets in an infinite loop with at least one WM.
7066 * Basically, applications are in no way in a position to
7067 * constrain the position of a window, with one exception:
7068 * override redirect windows. (Really the intended purpose
7069 * of CENTER_ALWAYS anyhow, I would think.)
7071 * So the way we implement this "constraint" is to say that when WE
7072 * cause a move or resize, i.e. we make a configure request changing
7073 * window size, we recompute the CENTER_ALWAYS position to reflect
7074 * the new window size, and include it in our request. Also, if we
7075 * just turned on CENTER_ALWAYS we snap to center with a new
7076 * request. Otherwise, if we are just NOTIFIED of a move or resize
7077 * done by someone else e.g. the window manager, we do NOT send a
7078 * new configure request.
7080 * For override redirect windows, this works fine; all window
7081 * sizes are from our configure requests. For managed windows,
7082 * it is at least semi-sane, though who knows what the
7083 * app author is thinking.
7086 /* This condition should be kept in sync with the condition later on
7087 * that determines whether we send a configure request. i.e. we
7088 * should do this position constraining anytime we were going to
7089 * send a configure request anyhow, plus when constraints have
7092 if (configure_request_pos_changed ||
7093 configure_request_size_changed ||
7095 info->position_constraints_changed)
7097 /* We request the constrained position if:
7098 * - we were changing position, and need to clamp
7099 * the change to the constraint
7100 * - we're changing the size anyway
7101 * - set_position() was called to toggle CENTER_ALWAYS on
7104 gtk_window_constrain_position (window,
7110 /* Update whether we need to request a move */
7111 if (info->last.configure_request.x != new_request.x ||
7112 info->last.configure_request.y != new_request.y)
7113 configure_request_pos_changed = TRUE;
7115 configure_request_pos_changed = FALSE;
7119 if (priv->type == GTK_WINDOW_TOPLEVEL)
7121 int notify_x, notify_y;
7123 /* this is the position from the last configure notify */
7124 gdk_window_get_position (widget->window, ¬ify_x, ¬ify_y);
7126 g_message ("--- %s ---\n"
7127 "last : %d,%d\t%d x %d\n"
7128 "this : %d,%d\t%d x %d\n"
7129 "alloc : %d,%d\t%d x %d\n"
7131 "resize: \t%d x %d\n"
7132 "size_changed: %d pos_changed: %d hints_changed: %d\n"
7133 "configure_notify_received: %d\n"
7134 "configure_request_count: %d\n"
7135 "position_constraints_changed: %d\n",
7136 priv->title ? priv->title : "(no title)",
7137 info->last.configure_request.x,
7138 info->last.configure_request.y,
7139 info->last.configure_request.width,
7140 info->last.configure_request.height,
7146 widget->allocation.width,
7147 widget->allocation.height,
7148 widget->requisition.width,
7149 widget->requisition.height,
7151 info->resize_height,
7152 configure_request_pos_changed,
7153 configure_request_size_changed,
7155 priv->configure_notify_received,
7156 priv->configure_request_count,
7157 info->position_constraints_changed);
7161 saved_last_info = info->last;
7162 info->last.geometry = new_geometry;
7163 info->last.flags = new_flags;
7164 info->last.configure_request = new_request;
7166 /* need to set PPosition so the WM will look at our position,
7167 * but we don't want to count PPosition coming and going as a hints
7168 * change for future iterations. So we saved info->last prior to
7172 /* Also, if the initial position was explicitly set, then we always
7173 * toggle on PPosition. This makes gtk_window_move(window, 0, 0)
7177 /* Also, we toggle on PPosition if GTK_WIN_POS_ is in use and
7178 * this is an initial map
7181 if ((configure_request_pos_changed ||
7182 info->initial_pos_set ||
7183 (priv->need_default_position &&
7184 get_effective_position (window) != GTK_WIN_POS_NONE)) &&
7185 (new_flags & GDK_HINT_POS) == 0)
7187 new_flags |= GDK_HINT_POS;
7188 hints_changed = TRUE;
7191 /* Set hints if necessary
7194 gdk_window_set_geometry_hints (gdk_window,
7198 gtk_widget_get_allocation (widget, &allocation);
7200 /* handle resizing/moving and widget tree allocation
7202 if (priv->configure_notify_received)
7204 /* If we have received a configure event since
7205 * the last time in this function, we need to
7206 * accept our new size and size_allocate child widgets.
7207 * (see gtk_window_configure_event() for more details).
7209 * 1 or more configure notifies may have been received.
7210 * Also, configure_notify_received will only be TRUE
7211 * if all expected configure notifies have been received
7212 * (one per configure request), as an optimization.
7215 priv->configure_notify_received = FALSE;
7217 /* gtk_window_configure_event() filled in widget->allocation */
7218 gtk_widget_size_allocate (widget, &allocation);
7220 set_grip_position (window);
7221 update_grip_visibility (window);
7223 gdk_window_process_updates (gdk_window, TRUE);
7225 gdk_window_configure_finished (gdk_window);
7227 /* If the configure request changed, it means that
7229 * 1) coincidentally changed hints or widget properties
7230 * impacting the configure request before getting
7231 * a configure notify, or
7232 * 2) some broken widget is changing its size request
7233 * during size allocation, resulting in
7234 * a false appearance of changed configure request.
7236 * For 1), we could just go ahead and ask for the
7237 * new size right now, but doing that for 2)
7238 * might well be fighting the user (and can even
7239 * trigger a loop). Since we really don't want to
7240 * do that, we requeue a resize in hopes that
7241 * by the time it gets handled, the child has seen
7242 * the light and is willing to go along with the
7243 * new size. (this happens for the zvt widget, since
7244 * the size_allocate() above will have stored the
7245 * requisition corresponding to the new size in the
7248 * This doesn't buy us anything for 1), but it shouldn't
7249 * hurt us too badly, since it is what would have
7250 * happened if we had gotten the configure event before
7251 * the new size had been set.
7254 if (configure_request_size_changed ||
7255 configure_request_pos_changed)
7257 /* Don't change the recorded last info after all, because we
7258 * haven't actually updated to the new info yet - we decided
7259 * to postpone our configure request until later.
7261 info->last = saved_last_info;
7263 gtk_widget_queue_resize_no_redraw (widget); /* migth recurse for GTK_RESIZE_IMMEDIATE */
7266 return; /* Bail out, we didn't really process the move/resize */
7268 else if ((configure_request_size_changed || hints_changed) &&
7269 (allocation.width != new_request.width || allocation.height != new_request.height))
7272 /* We are in one of the following situations:
7273 * A. configure_request_size_changed
7274 * our requisition has changed and we need a different window size,
7275 * so we request it from the window manager.
7276 * B. !configure_request_size_changed && hints_changed
7277 * the window manager rejects our size, but we have just changed the
7278 * window manager hints, so there's a chance our request will
7279 * be honoured this time, so we try again.
7281 * However, if the new requisition is the same as the current allocation,
7282 * we don't request it again, since we won't get a ConfigureNotify back from
7283 * the window manager unless it decides to change our requisition. If
7284 * we don't get the ConfigureNotify back, the resize queue will never be run.
7287 /* Now send the configure request */
7288 if (configure_request_pos_changed)
7290 gdk_window_move_resize (gdk_window,
7291 new_request.x, new_request.y,
7292 new_request.width, new_request.height);
7294 else /* only size changed */
7296 gdk_window_resize (gdk_window,
7297 new_request.width, new_request.height);
7300 if (priv->type == GTK_WINDOW_POPUP)
7302 GtkAllocation allocation;
7304 /* Directly size allocate for override redirect (popup) windows. */
7307 allocation.width = new_request.width;
7308 allocation.height = new_request.height;
7310 gtk_widget_size_allocate (widget, &allocation);
7312 gdk_window_process_updates (gdk_window, TRUE);
7314 if (gtk_container_get_resize_mode (container) == GTK_RESIZE_QUEUE)
7315 gtk_widget_queue_draw (widget);
7319 /* Increment the number of have-not-yet-received-notify requests */
7320 priv->configure_request_count += 1;
7321 gdk_window_freeze_toplevel_updates_libgtk_only (gdk_window);
7323 /* for GTK_RESIZE_QUEUE toplevels, we are now awaiting a new
7324 * configure event in response to our resizing request.
7325 * the configure event will cause a new resize with
7326 * ->configure_notify_received=TRUE.
7327 * until then, we want to
7328 * - discard expose events
7329 * - coalesce resizes for our children
7330 * - defer any window resizes until the configure event arrived
7331 * to achieve this, we queue a resize for the window, but remove its
7332 * resizing handler, so resizing will not be handled from the next
7333 * idle handler but when the configure event arrives.
7335 * FIXME: we should also dequeue the pending redraws here, since
7336 * we handle those ourselves upon ->configure_notify_received==TRUE.
7338 if (gtk_container_get_resize_mode (container) == GTK_RESIZE_QUEUE)
7340 gtk_widget_queue_resize_no_redraw (widget);
7341 _gtk_container_dequeue_resize_handler (container);
7347 /* Handle any position changes.
7349 if (configure_request_pos_changed)
7351 gdk_window_move (gdk_window,
7352 new_request.x, new_request.y);
7355 /* And run the resize queue.
7357 gtk_container_resize_children (container);
7360 /* We have now processed a move/resize since the last position
7361 * constraint change, setting of the initial position, or resize.
7362 * (Not resetting these flags here can lead to infinite loops for
7363 * GTK_RESIZE_IMMEDIATE containers)
7365 info->position_constraints_changed = FALSE;
7366 info->initial_pos_set = FALSE;
7367 info->resize_width = -1;
7368 info->resize_height = -1;
7371 /* Compare two sets of Geometry hints for equality.
7374 gtk_window_compare_hints (GdkGeometry *geometry_a,
7376 GdkGeometry *geometry_b,
7379 if (flags_a != flags_b)
7382 if ((flags_a & GDK_HINT_MIN_SIZE) &&
7383 (geometry_a->min_width != geometry_b->min_width ||
7384 geometry_a->min_height != geometry_b->min_height))
7387 if ((flags_a & GDK_HINT_MAX_SIZE) &&
7388 (geometry_a->max_width != geometry_b->max_width ||
7389 geometry_a->max_height != geometry_b->max_height))
7392 if ((flags_a & GDK_HINT_BASE_SIZE) &&
7393 (geometry_a->base_width != geometry_b->base_width ||
7394 geometry_a->base_height != geometry_b->base_height))
7397 if ((flags_a & GDK_HINT_ASPECT) &&
7398 (geometry_a->min_aspect != geometry_b->min_aspect ||
7399 geometry_a->max_aspect != geometry_b->max_aspect))
7402 if ((flags_a & GDK_HINT_RESIZE_INC) &&
7403 (geometry_a->width_inc != geometry_b->width_inc ||
7404 geometry_a->height_inc != geometry_b->height_inc))
7407 if ((flags_a & GDK_HINT_WIN_GRAVITY) &&
7408 geometry_a->win_gravity != geometry_b->win_gravity)
7415 _gtk_window_constrain_size (GtkWindow *window,
7421 GtkWindowPrivate *priv;
7422 GtkWindowGeometryInfo *info;
7424 g_return_if_fail (GTK_IS_WINDOW (window));
7426 priv = window->priv;
7428 info = priv->geometry_info;
7431 GdkWindowHints flags = info->last.flags;
7432 GdkGeometry *geometry = &info->last.geometry;
7434 gtk_window_constrain_size (window,
7445 gtk_window_constrain_size (GtkWindow *window,
7446 GdkGeometry *geometry,
7453 gdk_window_constrain_size (geometry, flags, width, height,
7454 new_width, new_height);
7457 /* Compute the set of geometry hints and flags for a window
7458 * based on the application set geometry, and requisition
7459 * of the window. gtk_widget_get_preferred_size() must have been
7463 gtk_window_compute_hints (GtkWindow *window,
7464 GdkGeometry *new_geometry,
7467 GtkWindowPrivate *priv = window->priv;
7469 gint extra_width = 0;
7470 gint extra_height = 0;
7471 GtkWindowGeometryInfo *geometry_info;
7472 GtkRequisition requisition;
7474 widget = GTK_WIDGET (window);
7476 gtk_widget_get_preferred_size (widget, &requisition, NULL);
7477 geometry_info = gtk_window_get_geometry_info (GTK_WINDOW (widget), FALSE);
7481 *new_flags = geometry_info->mask;
7482 *new_geometry = geometry_info->geometry;
7489 if (geometry_info && geometry_info->widget)
7491 /* If the geometry widget is set, then the hints really apply to that
7492 * widget. This is pretty much meaningless unless the window layout
7493 * is such that the rest of the window adds fixed size borders to
7494 * the geometry widget. Our job is to figure the size of the borders;
7495 * We do that by asking how big the toplevel would be if the
7496 * geometry widget was *really big*.
7499 * |AAAAAAAAA | At small sizes, the minimum sizes of widgets
7500 * |GGGGG B| in the border can confuse things
7506 * |AAAAAAAAA | When the geometry widget is large, things are
7507 * |GGGGGGGGGGB| clearer.
7512 #define TEMPORARY_SIZE 10000 /* 10,000 pixels should be bigger than real widget sizes */
7513 GtkRequisition requisition;
7514 int current_width, current_height;
7516 _gtk_widget_override_size_request (geometry_info->widget,
7517 TEMPORARY_SIZE, TEMPORARY_SIZE,
7518 ¤t_width, ¤t_height);
7519 gtk_widget_get_preferred_size (widget,
7520 &requisition, NULL);
7521 _gtk_widget_restore_size_request (geometry_info->widget,
7522 current_width, current_height);
7524 extra_width = requisition.width - TEMPORARY_SIZE;
7525 extra_height = requisition.height - TEMPORARY_SIZE;
7527 if (extra_width < 0 || extra_height < 0)
7529 g_warning("Toplevel size doesn't seem to directly depend on the "
7530 "size of the geometry widget from gtk_window_set_geometry_hints(). "
7531 "The geometry widget might not be in the window, or it might not "
7532 "be packed into the window appropriately");
7533 extra_width = MAX(extra_width, 0);
7534 extra_height = MAX(extra_height, 0);
7536 #undef TEMPORARY_SIZE
7539 /* We don't want to set GDK_HINT_POS in here, we just set it
7540 * in gtk_window_move_resize() when we want the position
7544 if (*new_flags & GDK_HINT_BASE_SIZE)
7546 new_geometry->base_width += extra_width;
7547 new_geometry->base_height += extra_height;
7551 /* For simplicity, we always set the base hint, even when we
7552 * don't expect it to have any visible effect.
7553 * (Note: geometry_size_to_pixels() depends on this.)
7555 *new_flags |= GDK_HINT_BASE_SIZE;
7557 new_geometry->base_width = extra_width;
7558 new_geometry->base_height = extra_height;
7560 /* As for X, if BASE_SIZE is not set but MIN_SIZE is set, then the
7561 * base size is the minimum size */
7562 if (*new_flags & GDK_HINT_MIN_SIZE)
7564 if (new_geometry->min_width > 0)
7565 new_geometry->base_width += new_geometry->min_width;
7566 if (new_geometry->min_height > 0)
7567 new_geometry->base_height += new_geometry->min_height;
7571 /* Please use a good size for unresizable widgets, not the minimum one. */
7572 if (!priv->resizable)
7573 gtk_window_guess_default_size (window, &requisition.width, &requisition.height);
7575 if (*new_flags & GDK_HINT_MIN_SIZE)
7577 if (new_geometry->min_width < 0)
7578 new_geometry->min_width = requisition.width;
7580 new_geometry->min_width = MAX (requisition.width, new_geometry->min_width + extra_width);
7582 if (new_geometry->min_height < 0)
7583 new_geometry->min_height = requisition.height;
7585 new_geometry->min_height = MAX (requisition.height, new_geometry->min_height + extra_height);
7589 *new_flags |= GDK_HINT_MIN_SIZE;
7591 new_geometry->min_width = requisition.width;
7592 new_geometry->min_height = requisition.height;
7595 if (*new_flags & GDK_HINT_MAX_SIZE)
7597 if (new_geometry->max_width < 0)
7598 new_geometry->max_width = requisition.width;
7600 new_geometry->max_width += extra_width;
7602 if (new_geometry->max_height < 0)
7603 new_geometry->max_height = requisition.height;
7605 new_geometry->max_height += extra_height;
7607 else if (!priv->resizable)
7609 *new_flags |= GDK_HINT_MAX_SIZE;
7611 new_geometry->max_width = requisition.width;
7612 new_geometry->max_height = requisition.height;
7615 *new_flags |= GDK_HINT_WIN_GRAVITY;
7616 new_geometry->win_gravity = priv->gravity;
7619 /***********************
7620 * Redrawing functions *
7621 ***********************/
7624 gtk_window_draw (GtkWidget *widget,
7627 GtkWindowPrivate *priv = GTK_WINDOW (widget)->priv;
7628 GtkStyleContext *context;
7629 gboolean ret = FALSE;
7631 context = gtk_widget_get_style_context (widget);
7633 if (!gtk_widget_get_app_paintable (widget) &&
7634 gtk_cairo_should_draw_window (cr, gtk_widget_get_window (widget)))
7636 gtk_style_context_save (context);
7638 gtk_style_context_add_class (context, GTK_STYLE_CLASS_BACKGROUND);
7639 gtk_render_background (context, cr, 0, 0,
7640 gtk_widget_get_allocated_width (widget),
7641 gtk_widget_get_allocated_height (widget));
7643 gtk_style_context_restore (context);
7646 if (GTK_WIDGET_CLASS (gtk_window_parent_class)->draw)
7647 ret = GTK_WIDGET_CLASS (gtk_window_parent_class)->draw (widget, cr);
7649 if (priv->grip_window &&
7650 gtk_cairo_should_draw_window (cr, priv->grip_window))
7654 gtk_style_context_save (context);
7657 gtk_cairo_transform_to_window (cr, widget, priv->grip_window);
7658 gtk_window_get_resize_grip_area (GTK_WINDOW (widget), &rect);
7660 gtk_style_context_add_class (context, GTK_STYLE_CLASS_GRIP);
7661 gtk_style_context_set_junction_sides (context, get_grip_junction (widget));
7662 gtk_render_handle (context, cr, 0, 0, rect.width, rect.height);
7665 gtk_style_context_restore (context);
7672 * gtk_window_present:
7673 * @window: a #GtkWindow
7675 * Presents a window to the user. This may mean raising the window
7676 * in the stacking order, deiconifying it, moving it to the current
7677 * desktop, and/or giving it the keyboard focus, possibly dependent
7678 * on the user's platform, window manager, and preferences.
7680 * If @window is hidden, this function calls gtk_widget_show()
7683 * This function should be used when the user tries to open a window
7684 * that's already open. Say for example the preferences dialog is
7685 * currently open, and the user chooses Preferences from the menu
7686 * a second time; use gtk_window_present() to move the already-open dialog
7687 * where the user can see it.
7689 * If you are calling this function in response to a user interaction,
7690 * it is preferable to use gtk_window_present_with_time().
7694 gtk_window_present (GtkWindow *window)
7696 gtk_window_present_with_time (window, GDK_CURRENT_TIME);
7700 * gtk_window_present_with_time:
7701 * @window: a #GtkWindow
7702 * @timestamp: the timestamp of the user interaction (typically a
7703 * button or key press event) which triggered this call
7705 * Presents a window to the user in response to a user interaction.
7706 * If you need to present a window without a timestamp, use
7707 * gtk_window_present(). See gtk_window_present() for details.
7712 gtk_window_present_with_time (GtkWindow *window,
7715 GtkWindowPrivate *priv;
7717 GdkWindow *gdk_window;
7719 g_return_if_fail (GTK_IS_WINDOW (window));
7721 priv = window->priv;
7722 widget = GTK_WIDGET (window);
7724 if (gtk_widget_get_visible (widget))
7726 gdk_window = gtk_widget_get_window (widget);
7728 g_assert (gdk_window != NULL);
7730 gdk_window_show (gdk_window);
7732 /* Translate a timestamp of GDK_CURRENT_TIME appropriately */
7733 if (timestamp == GDK_CURRENT_TIME)
7735 #ifdef GDK_WINDOWING_X11
7736 if (GDK_IS_X11_WINDOW(gdk_window))
7738 GdkDisplay *display;
7740 display = gtk_widget_get_display (GTK_WIDGET (window));
7741 timestamp = gdk_x11_display_get_user_time (display);
7745 timestamp = gtk_get_current_event_time ();
7748 gdk_window_focus (gdk_window, timestamp);
7752 priv->initial_timestamp = timestamp;
7753 gtk_widget_show (widget);
7758 * gtk_window_iconify:
7759 * @window: a #GtkWindow
7761 * Asks to iconify (i.e. minimize) the specified @window. Note that
7762 * you shouldn't assume the window is definitely iconified afterward,
7763 * because other entities (e.g. the user or <link
7764 * linkend="gtk-X11-arch">window manager</link>) could deiconify it
7765 * again, or there may not be a window manager in which case
7766 * iconification isn't possible, etc. But normally the window will end
7767 * up iconified. Just don't write code that crashes if not.
7769 * It's permitted to call this function before showing a window,
7770 * in which case the window will be iconified before it ever appears
7773 * You can track iconification via the "window-state-event" signal
7778 gtk_window_iconify (GtkWindow *window)
7780 GtkWindowPrivate *priv;
7782 GdkWindow *toplevel;
7784 g_return_if_fail (GTK_IS_WINDOW (window));
7786 priv = window->priv;
7787 widget = GTK_WIDGET (window);
7789 priv->iconify_initially = TRUE;
7791 toplevel = gtk_widget_get_window (widget);
7793 if (toplevel != NULL)
7794 gdk_window_iconify (toplevel);
7798 * gtk_window_deiconify:
7799 * @window: a #GtkWindow
7801 * Asks to deiconify (i.e. unminimize) the specified @window. Note
7802 * that you shouldn't assume the window is definitely deiconified
7803 * afterward, because other entities (e.g. the user or <link
7804 * linkend="gtk-X11-arch">window manager</link>) could iconify it
7805 * again before your code which assumes deiconification gets to run.
7807 * You can track iconification via the "window-state-event" signal
7811 gtk_window_deiconify (GtkWindow *window)
7813 GtkWindowPrivate *priv;
7815 GdkWindow *toplevel;
7817 g_return_if_fail (GTK_IS_WINDOW (window));
7819 priv = window->priv;
7820 widget = GTK_WIDGET (window);
7822 priv->iconify_initially = FALSE;
7824 toplevel = gtk_widget_get_window (widget);
7826 if (toplevel != NULL)
7827 gdk_window_deiconify (toplevel);
7832 * @window: a #GtkWindow
7834 * Asks to stick @window, which means that it will appear on all user
7835 * desktops. Note that you shouldn't assume the window is definitely
7836 * stuck afterward, because other entities (e.g. the user or <link
7837 * linkend="gtk-X11-arch">window manager</link>) could unstick it
7838 * again, and some window managers do not support sticking
7839 * windows. But normally the window will end up stuck. Just don't
7840 * write code that crashes if not.
7842 * It's permitted to call this function before showing a window.
7844 * You can track stickiness via the "window-state-event" signal
7849 gtk_window_stick (GtkWindow *window)
7851 GtkWindowPrivate *priv;
7853 GdkWindow *toplevel;
7855 g_return_if_fail (GTK_IS_WINDOW (window));
7857 priv = window->priv;
7858 widget = GTK_WIDGET (window);
7860 priv->stick_initially = TRUE;
7862 toplevel = gtk_widget_get_window (widget);
7864 if (toplevel != NULL)
7865 gdk_window_stick (toplevel);
7869 * gtk_window_unstick:
7870 * @window: a #GtkWindow
7872 * Asks to unstick @window, which means that it will appear on only
7873 * one of the user's desktops. Note that you shouldn't assume the
7874 * window is definitely unstuck afterward, because other entities
7875 * (e.g. the user or <link linkend="gtk-X11-arch">window
7876 * manager</link>) could stick it again. But normally the window will
7877 * end up stuck. Just don't write code that crashes if not.
7879 * You can track stickiness via the "window-state-event" signal
7884 gtk_window_unstick (GtkWindow *window)
7886 GtkWindowPrivate *priv;
7888 GdkWindow *toplevel;
7890 g_return_if_fail (GTK_IS_WINDOW (window));
7892 priv = window->priv;
7893 widget = GTK_WIDGET (window);
7895 priv->stick_initially = FALSE;
7897 toplevel = gtk_widget_get_window (widget);
7899 if (toplevel != NULL)
7900 gdk_window_unstick (toplevel);
7904 * gtk_window_maximize:
7905 * @window: a #GtkWindow
7907 * Asks to maximize @window, so that it becomes full-screen. Note that
7908 * you shouldn't assume the window is definitely maximized afterward,
7909 * because other entities (e.g. the user or <link
7910 * linkend="gtk-X11-arch">window manager</link>) could unmaximize it
7911 * again, and not all window managers support maximization. But
7912 * normally the window will end up maximized. Just don't write code
7913 * that crashes if not.
7915 * It's permitted to call this function before showing a window,
7916 * in which case the window will be maximized when it appears onscreen
7919 * You can track maximization via the "window-state-event" signal
7924 gtk_window_maximize (GtkWindow *window)
7926 GtkWindowPrivate *priv;
7928 GdkWindow *toplevel;
7930 g_return_if_fail (GTK_IS_WINDOW (window));
7932 priv = window->priv;
7933 widget = GTK_WIDGET (window);
7935 priv->maximize_initially = TRUE;
7937 toplevel = gtk_widget_get_window (widget);
7939 if (toplevel != NULL)
7940 gdk_window_maximize (toplevel);
7944 * gtk_window_unmaximize:
7945 * @window: a #GtkWindow
7947 * Asks to unmaximize @window. Note that you shouldn't assume the
7948 * window is definitely unmaximized afterward, because other entities
7949 * (e.g. the user or <link linkend="gtk-X11-arch">window
7950 * manager</link>) could maximize it again, and not all window
7951 * managers honor requests to unmaximize. But normally the window will
7952 * end up unmaximized. Just don't write code that crashes if not.
7954 * You can track maximization via the "window-state-event" signal
7959 gtk_window_unmaximize (GtkWindow *window)
7961 GtkWindowPrivate *priv;
7963 GdkWindow *toplevel;
7965 g_return_if_fail (GTK_IS_WINDOW (window));
7967 priv = window->priv;
7968 widget = GTK_WIDGET (window);
7970 priv->maximize_initially = FALSE;
7972 toplevel = gtk_widget_get_window (widget);
7974 if (toplevel != NULL)
7975 gdk_window_unmaximize (toplevel);
7979 * gtk_window_fullscreen:
7980 * @window: a #GtkWindow
7982 * Asks to place @window in the fullscreen state. Note that you
7983 * shouldn't assume the window is definitely full screen afterward,
7984 * because other entities (e.g. the user or <link
7985 * linkend="gtk-X11-arch">window manager</link>) could unfullscreen it
7986 * again, and not all window managers honor requests to fullscreen
7987 * windows. But normally the window will end up fullscreen. Just
7988 * don't write code that crashes if not.
7990 * You can track the fullscreen state via the "window-state-event" signal
7996 gtk_window_fullscreen (GtkWindow *window)
7998 GtkWindowPrivate *priv;
8000 GdkWindow *toplevel;
8002 g_return_if_fail (GTK_IS_WINDOW (window));
8004 priv = window->priv;
8005 widget = GTK_WIDGET (window);
8007 priv->fullscreen_initially = TRUE;
8009 toplevel = gtk_widget_get_window (widget);
8011 if (toplevel != NULL)
8012 gdk_window_fullscreen (toplevel);
8016 * gtk_window_unfullscreen:
8017 * @window: a #GtkWindow
8019 * Asks to toggle off the fullscreen state for @window. Note that you
8020 * shouldn't assume the window is definitely not full screen
8021 * afterward, because other entities (e.g. the user or <link
8022 * linkend="gtk-X11-arch">window manager</link>) could fullscreen it
8023 * again, and not all window managers honor requests to unfullscreen
8024 * windows. But normally the window will end up restored to its normal
8025 * state. Just don't write code that crashes if not.
8027 * You can track the fullscreen state via the "window-state-event" signal
8033 gtk_window_unfullscreen (GtkWindow *window)
8036 GdkWindow *toplevel;
8037 GtkWindowPrivate *priv;
8039 g_return_if_fail (GTK_IS_WINDOW (window));
8041 priv = window->priv;
8042 widget = GTK_WIDGET (window);
8044 priv->fullscreen_initially = FALSE;
8046 toplevel = gtk_widget_get_window (widget);
8048 if (toplevel != NULL)
8049 gdk_window_unfullscreen (toplevel);
8053 * gtk_window_set_keep_above:
8054 * @window: a #GtkWindow
8055 * @setting: whether to keep @window above other windows
8057 * Asks to keep @window above, so that it stays on top. Note that
8058 * you shouldn't assume the window is definitely above afterward,
8059 * because other entities (e.g. the user or <link
8060 * linkend="gtk-X11-arch">window manager</link>) could not keep it above,
8061 * and not all window managers support keeping windows above. But
8062 * normally the window will end kept above. Just don't write code
8063 * that crashes if not.
8065 * It's permitted to call this function before showing a window,
8066 * in which case the window will be kept above when it appears onscreen
8069 * You can track the above state via the "window-state-event" signal
8072 * Note that, according to the <ulink
8073 * url="http://www.freedesktop.org/Standards/wm-spec">Extended Window
8074 * Manager Hints</ulink> specification, the above state is mainly meant
8075 * for user preferences and should not be used by applications e.g. for
8076 * drawing attention to their dialogs.
8081 gtk_window_set_keep_above (GtkWindow *window,
8085 GtkWindowPrivate *priv;
8086 GdkWindow *toplevel;
8088 g_return_if_fail (GTK_IS_WINDOW (window));
8090 priv = window->priv;
8091 widget = GTK_WIDGET (window);
8093 priv->above_initially = setting != FALSE;
8095 priv->below_initially = FALSE;
8097 toplevel = gtk_widget_get_window (widget);
8099 if (toplevel != NULL)
8100 gdk_window_set_keep_above (toplevel, setting);
8104 * gtk_window_set_keep_below:
8105 * @window: a #GtkWindow
8106 * @setting: whether to keep @window below other windows
8108 * Asks to keep @window below, so that it stays in bottom. Note that
8109 * you shouldn't assume the window is definitely below afterward,
8110 * because other entities (e.g. the user or <link
8111 * linkend="gtk-X11-arch">window manager</link>) could not keep it below,
8112 * and not all window managers support putting windows below. But
8113 * normally the window will be kept below. Just don't write code
8114 * that crashes if not.
8116 * It's permitted to call this function before showing a window,
8117 * in which case the window will be kept below when it appears onscreen
8120 * You can track the below state via the "window-state-event" signal
8123 * Note that, according to the <ulink
8124 * url="http://www.freedesktop.org/Standards/wm-spec">Extended Window
8125 * Manager Hints</ulink> specification, the above state is mainly meant
8126 * for user preferences and should not be used by applications e.g. for
8127 * drawing attention to their dialogs.
8132 gtk_window_set_keep_below (GtkWindow *window,
8136 GtkWindowPrivate *priv;
8137 GdkWindow *toplevel;
8139 g_return_if_fail (GTK_IS_WINDOW (window));
8141 priv = window->priv;
8142 widget = GTK_WIDGET (window);
8144 priv->below_initially = setting != FALSE;
8146 priv->above_initially = FALSE;
8148 toplevel = gtk_widget_get_window (widget);
8150 if (toplevel != NULL)
8151 gdk_window_set_keep_below (toplevel, setting);
8155 * gtk_window_set_resizable:
8156 * @window: a #GtkWindow
8157 * @resizable: %TRUE if the user can resize this window
8159 * Sets whether the user can resize a window. Windows are user resizable
8163 gtk_window_set_resizable (GtkWindow *window,
8166 GtkWindowPrivate *priv;
8168 g_return_if_fail (GTK_IS_WINDOW (window));
8170 priv = window->priv;
8172 resizable = (resizable != FALSE);
8174 if (priv->resizable != resizable)
8176 priv->resizable = (resizable != FALSE);
8178 update_grip_visibility (window);
8180 gtk_widget_queue_resize_no_redraw (GTK_WIDGET (window));
8182 g_object_notify (G_OBJECT (window), "resizable");
8187 * gtk_window_get_resizable:
8188 * @window: a #GtkWindow
8190 * Gets the value set by gtk_window_set_resizable().
8192 * Return value: %TRUE if the user can resize the window
8195 gtk_window_get_resizable (GtkWindow *window)
8197 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
8199 return window->priv->resizable;
8203 * gtk_window_set_gravity:
8204 * @window: a #GtkWindow
8205 * @gravity: window gravity
8207 * Window gravity defines the meaning of coordinates passed to
8208 * gtk_window_move(). See gtk_window_move() and #GdkGravity for
8211 * The default window gravity is #GDK_GRAVITY_NORTH_WEST which will
8212 * typically "do what you mean."
8216 gtk_window_set_gravity (GtkWindow *window,
8219 GtkWindowPrivate *priv;
8221 g_return_if_fail (GTK_IS_WINDOW (window));
8223 priv = window->priv;
8225 if (gravity != priv->gravity)
8227 priv->gravity = gravity;
8229 /* gtk_window_move_resize() will adapt gravity
8231 gtk_widget_queue_resize_no_redraw (GTK_WIDGET (window));
8233 g_object_notify (G_OBJECT (window), "gravity");
8238 * gtk_window_get_gravity:
8239 * @window: a #GtkWindow
8241 * Gets the value set by gtk_window_set_gravity().
8243 * Return value: (transfer none): window gravity
8246 gtk_window_get_gravity (GtkWindow *window)
8248 g_return_val_if_fail (GTK_IS_WINDOW (window), 0);
8250 return window->priv->gravity;
8254 * gtk_window_begin_resize_drag:
8255 * @window: a #GtkWindow
8256 * @button: mouse button that initiated the drag
8257 * @edge: position of the resize control
8258 * @root_x: X position where the user clicked to initiate the drag, in root window coordinates
8259 * @root_y: Y position where the user clicked to initiate the drag
8260 * @timestamp: timestamp from the click event that initiated the drag
8262 * Starts resizing a window. This function is used if an application
8263 * has window resizing controls. When GDK can support it, the resize
8264 * will be done using the standard mechanism for the <link
8265 * linkend="gtk-X11-arch">window manager</link> or windowing
8266 * system. Otherwise, GDK will try to emulate window resizing,
8267 * potentially not all that well, depending on the windowing system.
8271 gtk_window_begin_resize_drag (GtkWindow *window,
8279 GdkWindow *toplevel;
8281 g_return_if_fail (GTK_IS_WINDOW (window));
8282 widget = GTK_WIDGET (window);
8283 g_return_if_fail (gtk_widget_get_visible (widget));
8285 toplevel = gtk_widget_get_window (widget);
8287 gdk_window_begin_resize_drag (toplevel,
8294 * gtk_window_begin_move_drag:
8295 * @window: a #GtkWindow
8296 * @button: mouse button that initiated the drag
8297 * @root_x: X position where the user clicked to initiate the drag, in root window coordinates
8298 * @root_y: Y position where the user clicked to initiate the drag
8299 * @timestamp: timestamp from the click event that initiated the drag
8301 * Starts moving a window. This function is used if an application has
8302 * window movement grips. When GDK can support it, the window movement
8303 * will be done using the standard mechanism for the <link
8304 * linkend="gtk-X11-arch">window manager</link> or windowing
8305 * system. Otherwise, GDK will try to emulate window movement,
8306 * potentially not all that well, depending on the windowing system.
8310 gtk_window_begin_move_drag (GtkWindow *window,
8317 GdkWindow *toplevel;
8319 g_return_if_fail (GTK_IS_WINDOW (window));
8320 widget = GTK_WIDGET (window);
8321 g_return_if_fail (gtk_widget_get_visible (widget));
8323 toplevel = gtk_widget_get_window (widget);
8325 gdk_window_begin_move_drag (toplevel,
8332 * gtk_window_set_screen:
8333 * @window: a #GtkWindow.
8334 * @screen: a #GdkScreen.
8336 * Sets the #GdkScreen where the @window is displayed; if
8337 * the window is already mapped, it will be unmapped, and
8338 * then remapped on the new screen.
8343 gtk_window_set_screen (GtkWindow *window,
8346 GtkWindowPrivate *priv;
8348 GdkScreen *previous_screen;
8349 gboolean was_mapped;
8351 g_return_if_fail (GTK_IS_WINDOW (window));
8352 g_return_if_fail (GDK_IS_SCREEN (screen));
8354 priv = window->priv;
8356 if (screen == priv->screen)
8359 widget = GTK_WIDGET (window);
8361 previous_screen = priv->screen;
8362 was_mapped = gtk_widget_get_mapped (widget);
8365 gtk_widget_unmap (widget);
8366 if (gtk_widget_get_realized (widget))
8367 gtk_widget_unrealize (widget);
8369 gtk_window_free_key_hash (window);
8370 priv->screen = screen;
8371 gtk_widget_reset_rc_styles (widget);
8372 if (screen != previous_screen)
8374 if (previous_screen)
8376 g_signal_handlers_disconnect_by_func (previous_screen,
8377 gtk_window_on_composited_changed, window);
8378 #ifdef GDK_WINDOWING_X11
8379 g_signal_handlers_disconnect_by_func (gtk_settings_get_for_screen (previous_screen),
8380 gtk_window_on_theme_variant_changed, window);
8383 g_signal_connect (screen, "composited-changed",
8384 G_CALLBACK (gtk_window_on_composited_changed), window);
8385 #ifdef GDK_WINDOWING_X11
8386 g_signal_connect (gtk_settings_get_for_screen (screen),
8387 "notify::gtk-application-prefer-dark-theme",
8388 G_CALLBACK (gtk_window_on_theme_variant_changed), window);
8391 _gtk_widget_propagate_screen_changed (widget, previous_screen);
8392 _gtk_widget_propagate_composited_changed (widget);
8394 g_object_notify (G_OBJECT (window), "screen");
8397 gtk_widget_map (widget);
8401 gtk_window_set_theme_variant (GtkWindow *window)
8403 #ifdef GDK_WINDOWING_X11
8404 GdkWindow *gdk_window;
8405 gboolean dark_theme_requested;
8407 g_object_get (gtk_settings_get_for_screen (window->priv->screen),
8408 "gtk-application-prefer-dark-theme", &dark_theme_requested,
8411 gdk_window = gtk_widget_get_window (GTK_WIDGET (window));
8413 if (GDK_IS_X11_WINDOW (gdk_window))
8414 gdk_x11_window_set_theme_variant (gdk_window,
8415 dark_theme_requested ? "dark" : NULL);
8420 gtk_window_on_theme_variant_changed (GtkSettings *settings,
8424 if (window->priv->type == GTK_WINDOW_TOPLEVEL)
8425 gtk_window_set_theme_variant (window);
8429 gtk_window_on_composited_changed (GdkScreen *screen,
8432 gtk_widget_queue_draw (GTK_WIDGET (window));
8434 _gtk_widget_propagate_composited_changed (GTK_WIDGET (window));
8438 gtk_window_check_screen (GtkWindow *window)
8440 GtkWindowPrivate *priv = window->priv;
8443 return priv->screen;
8446 g_warning ("Screen for GtkWindow not set; you must always set\n"
8447 "a screen for a GtkWindow before using the window");
8453 * gtk_window_get_screen:
8454 * @window: a #GtkWindow.
8456 * Returns the #GdkScreen associated with @window.
8458 * Return value: (transfer none): a #GdkScreen.
8463 gtk_window_get_screen (GtkWindow *window)
8465 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
8467 return window->priv->screen;
8471 * gtk_window_is_active:
8472 * @window: a #GtkWindow
8474 * Returns whether the window is part of the current active toplevel.
8475 * (That is, the toplevel window receiving keystrokes.)
8476 * The return value is %TRUE if the window is active toplevel
8477 * itself, but also if it is, say, a #GtkPlug embedded in the active toplevel.
8478 * You might use this function if you wanted to draw a widget
8479 * differently in an active window from a widget in an inactive window.
8480 * See gtk_window_has_toplevel_focus()
8482 * Return value: %TRUE if the window part of the current active window.
8487 gtk_window_is_active (GtkWindow *window)
8489 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
8491 return window->priv->is_active;
8495 * gtk_window_has_toplevel_focus:
8496 * @window: a #GtkWindow
8498 * Returns whether the input focus is within this GtkWindow.
8499 * For real toplevel windows, this is identical to gtk_window_is_active(),
8500 * but for embedded windows, like #GtkPlug, the results will differ.
8502 * Return value: %TRUE if the input focus is within this GtkWindow
8507 gtk_window_has_toplevel_focus (GtkWindow *window)
8509 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
8511 return window->priv->has_toplevel_focus;
8516 * SECTION:gtkwindowgroup
8517 * @Short_description: Limit the effect of grabs
8518 * @Title: GtkWindowGroup
8520 * #GtkWindowGroup objects are referenced by each window in the group,
8521 * so once you have added all windows to a #GtkWindowGroup, you can drop
8522 * the initial reference to the window group with g_object_unref(). If the
8523 * windows in the window group are subsequently destroyed, then they will
8524 * be removed from the window group and drop their references on the window
8525 * group; when all window have been removed, the window group will be
8529 G_DEFINE_TYPE (GtkWindowGroup, gtk_window_group, G_TYPE_OBJECT)
8532 gtk_window_group_init (GtkWindowGroup *group)
8534 group->priv = G_TYPE_INSTANCE_GET_PRIVATE (group,
8535 GTK_TYPE_WINDOW_GROUP,
8536 GtkWindowGroupPrivate);
8540 gtk_window_group_class_init (GtkWindowGroupClass *klass)
8542 g_type_class_add_private (klass, sizeof (GtkWindowGroupPrivate));
8546 * gtk_window_group_new:
8548 * Creates a new #GtkWindowGroup object. Grabs added with
8549 * gtk_grab_add() only affect windows within the same #GtkWindowGroup.
8551 * Return value: a new #GtkWindowGroup.
8554 gtk_window_group_new (void)
8556 return g_object_new (GTK_TYPE_WINDOW_GROUP, NULL);
8560 window_group_cleanup_grabs (GtkWindowGroup *group,
8563 GtkWindowGroupPrivate *priv;
8564 GtkDeviceGrabInfo *info;
8566 GSList *to_remove = NULL;
8570 tmp_list = priv->grabs;
8573 if (gtk_widget_get_toplevel (tmp_list->data) == (GtkWidget*) window)
8574 to_remove = g_slist_prepend (to_remove, g_object_ref (tmp_list->data));
8575 tmp_list = tmp_list->next;
8580 gtk_grab_remove (to_remove->data);
8581 g_object_unref (to_remove->data);
8582 to_remove = g_slist_delete_link (to_remove, to_remove);
8585 tmp_list = priv->device_grabs;
8589 info = tmp_list->data;
8591 if (gtk_widget_get_toplevel (info->widget) == (GtkWidget *) window)
8592 to_remove = g_slist_prepend (to_remove, info);
8594 tmp_list = tmp_list->next;
8599 info = to_remove->data;
8601 gtk_device_grab_remove (info->widget, info->device);
8602 to_remove = g_slist_delete_link (to_remove, to_remove);
8607 * gtk_window_group_add_window:
8608 * @window_group: a #GtkWindowGroup
8609 * @window: the #GtkWindow to add
8611 * Adds a window to a #GtkWindowGroup.
8614 gtk_window_group_add_window (GtkWindowGroup *window_group,
8617 GtkWindowPrivate *priv;
8619 g_return_if_fail (GTK_IS_WINDOW_GROUP (window_group));
8620 g_return_if_fail (GTK_IS_WINDOW (window));
8622 priv = window->priv;
8624 if (priv->group != window_group)
8626 g_object_ref (window);
8627 g_object_ref (window_group);
8630 gtk_window_group_remove_window (priv->group, window);
8632 window_group_cleanup_grabs (gtk_window_get_group (NULL), window);
8634 priv->group = window_group;
8636 g_object_unref (window);
8641 * gtk_window_group_remove_window:
8642 * @window_group: a #GtkWindowGroup
8643 * @window: the #GtkWindow to remove
8645 * Removes a window from a #GtkWindowGroup.
8648 gtk_window_group_remove_window (GtkWindowGroup *window_group,
8651 GtkWindowPrivate *priv;
8653 g_return_if_fail (GTK_IS_WINDOW_GROUP (window_group));
8654 g_return_if_fail (GTK_IS_WINDOW (window));
8655 priv = window->priv;
8656 g_return_if_fail (priv->group == window_group);
8658 g_object_ref (window);
8660 window_group_cleanup_grabs (window_group, window);
8663 g_object_unref (window_group);
8664 g_object_unref (window);
8668 * gtk_window_group_list_windows:
8669 * @window_group: a #GtkWindowGroup
8671 * Returns a list of the #GtkWindows that belong to @window_group.
8673 * Returns: (element-type GtkWindow) (transfer container): A
8674 * newly-allocated list of windows inside the group.
8679 gtk_window_group_list_windows (GtkWindowGroup *window_group)
8681 GList *toplevels, *toplevel, *group_windows;
8683 g_return_val_if_fail (GTK_IS_WINDOW_GROUP (window_group), NULL);
8685 group_windows = NULL;
8686 toplevels = gtk_window_list_toplevels ();
8688 for (toplevel = toplevels; toplevel; toplevel = toplevel->next)
8690 GtkWindow *window = toplevel->data;
8692 if (window_group == window->priv->group)
8693 group_windows = g_list_prepend (group_windows, window);
8696 g_list_free (toplevels);
8698 return g_list_reverse (group_windows);
8702 * gtk_window_get_group:
8703 * @window: (allow-none): a #GtkWindow, or %NULL
8705 * Returns the group for @window or the default group, if
8706 * @window is %NULL or if @window does not have an explicit
8709 * Returns: (transfer none): the #GtkWindowGroup for a window or the default group
8714 gtk_window_get_group (GtkWindow *window)
8716 if (window && window->priv->group)
8717 return window->priv->group;
8720 static GtkWindowGroup *default_group = NULL;
8723 default_group = gtk_window_group_new ();
8725 return default_group;
8730 * gtk_window_has_group:
8731 * @window: a #GtkWindow
8733 * Returns whether @window has an explicit window group.
8735 * Return value: %TRUE if @window has an explicit window group.
8740 gtk_window_has_group (GtkWindow *window)
8742 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
8744 return window->priv->group != NULL;
8748 * gtk_window_group_get_current_grab:
8749 * @window_group: a #GtkWindowGroup
8751 * Gets the current grab widget of the given group,
8752 * see gtk_grab_add().
8754 * Returns: (transfer none): the current grab widget of the group
8759 gtk_window_group_get_current_grab (GtkWindowGroup *window_group)
8761 g_return_val_if_fail (GTK_IS_WINDOW_GROUP (window_group), NULL);
8763 if (window_group->priv->grabs)
8764 return GTK_WIDGET (window_group->priv->grabs->data);
8769 _gtk_window_group_add_grab (GtkWindowGroup *window_group,
8772 GtkWindowGroupPrivate *priv;
8774 priv = window_group->priv;
8775 priv->grabs = g_slist_prepend (priv->grabs, widget);
8779 _gtk_window_group_remove_grab (GtkWindowGroup *window_group,
8782 GtkWindowGroupPrivate *priv;
8784 priv = window_group->priv;
8785 priv->grabs = g_slist_remove (priv->grabs, widget);
8790 _gtk_window_group_add_device_grab (GtkWindowGroup *window_group,
8793 gboolean block_others)
8795 GtkWindowGroupPrivate *priv;
8796 GtkDeviceGrabInfo *info;
8798 priv = window_group->priv;
8800 info = g_slice_new0 (GtkDeviceGrabInfo);
8801 info->widget = widget;
8802 info->device = device;
8803 info->block_others = block_others;
8805 priv->device_grabs = g_slist_prepend (priv->device_grabs, info);
8809 _gtk_window_group_remove_device_grab (GtkWindowGroup *window_group,
8813 GtkWindowGroupPrivate *priv;
8814 GtkDeviceGrabInfo *info;
8815 GSList *list, *node = NULL;
8816 GdkDevice *other_device;
8818 priv = window_group->priv;
8819 other_device = gdk_device_get_associated_device (device);
8820 list = priv->device_grabs;
8826 if (info->widget == widget &&
8827 (info->device == device ||
8828 info->device == other_device))
8841 priv->device_grabs = g_slist_delete_link (priv->device_grabs, node);
8842 g_slice_free (GtkDeviceGrabInfo, info);
8847 * gtk_window_group_get_current_device_grab:
8848 * @window_group: a #GtkWindowGroup
8849 * @device: a #GdkDevice
8851 * Returns the current grab widget for @device, or %NULL if none.
8853 * Returns: (transfer none): The grab widget, or %NULL
8858 gtk_window_group_get_current_device_grab (GtkWindowGroup *window_group,
8861 GtkWindowGroupPrivate *priv;
8862 GtkDeviceGrabInfo *info;
8863 GdkDevice *other_device;
8866 g_return_val_if_fail (GTK_IS_WINDOW_GROUP (window_group), NULL);
8867 g_return_val_if_fail (GDK_IS_DEVICE (device), NULL);
8869 priv = window_group->priv;
8870 list = priv->device_grabs;
8871 other_device = gdk_device_get_associated_device (device);
8878 if (info->device == device ||
8879 info->device == other_device)
8880 return info->widget;
8887 _gtk_window_group_widget_is_blocked_for_device (GtkWindowGroup *window_group,
8891 GtkWindowGroupPrivate *priv;
8892 GtkDeviceGrabInfo *info;
8893 GdkDevice *other_device;
8896 priv = window_group->priv;
8897 other_device = gdk_device_get_associated_device (device);
8898 list = priv->device_grabs;
8905 /* Look for blocking grabs on other device pairs
8906 * that have the passed widget within the GTK+ grab.
8908 if (info->block_others &&
8909 info->device != device &&
8910 info->device != other_device &&
8911 (info->widget == widget ||
8912 gtk_widget_is_ancestor (widget, info->widget)))
8920 Derived from XParseGeometry() in XFree86
8922 Copyright 1985, 1986, 1987,1998 The Open Group
8924 All Rights Reserved.
8926 The above copyright notice and this permission notice shall be included
8927 in all copies or substantial portions of the Software.
8929 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
8930 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
8931 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
8932 IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
8933 OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
8934 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
8935 OTHER DEALINGS IN THE SOFTWARE.
8937 Except as contained in this notice, the name of The Open Group shall
8938 not be used in advertising or otherwise to promote the sale, use or
8939 other dealings in this Software without prior written authorization
8940 from The Open Group.
8945 * XParseGeometry parses strings of the form
8946 * "=<width>x<height>{+-}<xoffset>{+-}<yoffset>", where
8947 * width, height, xoffset, and yoffset are unsigned integers.
8948 * Example: "=80x24+300-49"
8949 * The equal sign is optional.
8950 * It returns a bitmask that indicates which of the four values
8951 * were actually found in the string. For each value found,
8952 * the corresponding argument is updated; for each value
8953 * not found, the corresponding argument is left unchanged.
8956 /* The following code is from Xlib, and is minimally modified, so we
8957 * can track any upstream changes if required. Don't change this
8958 * code. Or if you do, put in a huge comment marking which thing
8963 read_int (gchar *string,
8971 else if (*string == '-')
8977 for (; (*string >= '0') && (*string <= '9'); string++)
8979 result = (result * 10) + (*string - '0');
8991 * Bitmask returned by XParseGeometry(). Each bit tells if the corresponding
8992 * value (x, y, width, height) was found in the parsed string.
8994 #define NoValue 0x0000
8995 #define XValue 0x0001
8996 #define YValue 0x0002
8997 #define WidthValue 0x0004
8998 #define HeightValue 0x0008
8999 #define AllValues 0x000F
9000 #define XNegative 0x0010
9001 #define YNegative 0x0020
9003 /* Try not to reformat/modify, so we can compare/sync with X sources */
9005 gtk_XParseGeometry (const char *string,
9008 unsigned int *width,
9009 unsigned int *height)
9013 unsigned int tempWidth, tempHeight;
9015 char *nextCharacter;
9017 /* These initializations are just to silence gcc */
9023 if ( (string == NULL) || (*string == '\0')) return(mask);
9025 string++; /* ignore possible '=' at beg of geometry spec */
9027 strind = (char *)string;
9028 if (*strind != '+' && *strind != '-' && *strind != 'x') {
9029 tempWidth = read_int(strind, &nextCharacter);
9030 if (strind == nextCharacter)
9032 strind = nextCharacter;
9036 if (*strind == 'x' || *strind == 'X') {
9038 tempHeight = read_int(strind, &nextCharacter);
9039 if (strind == nextCharacter)
9041 strind = nextCharacter;
9042 mask |= HeightValue;
9045 if ((*strind == '+') || (*strind == '-')) {
9046 if (*strind == '-') {
9048 tempX = -read_int(strind, &nextCharacter);
9049 if (strind == nextCharacter)
9051 strind = nextCharacter;
9057 tempX = read_int(strind, &nextCharacter);
9058 if (strind == nextCharacter)
9060 strind = nextCharacter;
9063 if ((*strind == '+') || (*strind == '-')) {
9064 if (*strind == '-') {
9066 tempY = -read_int(strind, &nextCharacter);
9067 if (strind == nextCharacter)
9069 strind = nextCharacter;
9076 tempY = read_int(strind, &nextCharacter);
9077 if (strind == nextCharacter)
9079 strind = nextCharacter;
9085 /* If strind isn't at the end of the string the it's an invalid
9086 geometry specification. */
9088 if (*strind != '\0') return (0);
9094 if (mask & WidthValue)
9096 if (mask & HeightValue)
9097 *height = tempHeight;
9102 * gtk_window_parse_geometry:
9103 * @window: a #GtkWindow
9104 * @geometry: geometry string
9106 * Parses a standard X Window System geometry string - see the
9107 * manual page for X (type 'man X') for details on this.
9108 * gtk_window_parse_geometry() does work on all GTK+ ports
9109 * including Win32 but is primarily intended for an X environment.
9111 * If either a size or a position can be extracted from the
9112 * geometry string, gtk_window_parse_geometry() returns %TRUE
9113 * and calls gtk_window_set_default_size() and/or gtk_window_move()
9114 * to resize/move the window.
9116 * If gtk_window_parse_geometry() returns %TRUE, it will also
9117 * set the #GDK_HINT_USER_POS and/or #GDK_HINT_USER_SIZE hints
9118 * indicating to the window manager that the size/position of
9119 * the window was user-specified. This causes most window
9120 * managers to honor the geometry.
9122 * Note that for gtk_window_parse_geometry() to work as expected, it has
9123 * to be called when the window has its "final" size, i.e. after calling
9124 * gtk_widget_show_all() on the contents and gtk_window_set_geometry_hints()
9127 * #include <gtk/gtk.h>
9130 * fill_with_content (GtkWidget *vbox)
9132 * /* fill with content... */
9136 * main (int argc, char *argv[])
9138 * GtkWidget *window, *vbox;
9139 * GdkGeometry size_hints = {
9140 * 100, 50, 0, 0, 100, 50, 10, 10, 0.0, 0.0, GDK_GRAVITY_NORTH_WEST
9143 * gtk_init (&argc, &argv);
9145 * window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
9146 * vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, FALSE, 0);
9148 * gtk_container_add (GTK_CONTAINER (window), vbox);
9149 * fill_with_content (vbox);
9150 * gtk_widget_show_all (vbox);
9152 * gtk_window_set_geometry_hints (GTK_WINDOW (window),
9155 * GDK_HINT_MIN_SIZE |
9156 * GDK_HINT_BASE_SIZE |
9157 * GDK_HINT_RESIZE_INC);
9161 * if (!gtk_window_parse_geometry (GTK_WINDOW (window), argv[1]))
9162 * fprintf (stderr, "Failed to parse '%s'\n", argv[1]);
9165 * gtk_widget_show_all (window);
9172 * Return value: %TRUE if string was parsed successfully
9175 gtk_window_parse_geometry (GtkWindow *window,
9176 const gchar *geometry)
9178 gint result, x = 0, y = 0;
9182 gboolean size_set, pos_set;
9185 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
9186 g_return_val_if_fail (geometry != NULL, FALSE);
9188 child = gtk_bin_get_child (GTK_BIN (window));
9189 if (!child || !gtk_widget_get_visible (child))
9190 g_warning ("gtk_window_parse_geometry() called on a window with no "
9191 "visible children; the window should be set up before "
9192 "gtk_window_parse_geometry() is called.");
9194 screen = gtk_window_check_screen (window);
9196 result = gtk_XParseGeometry (geometry, &x, &y, &w, &h);
9199 if ((result & WidthValue) || (result & HeightValue))
9201 gtk_window_set_default_size_internal (window,
9202 TRUE, result & WidthValue ? w : -1,
9203 TRUE, result & HeightValue ? h : -1,
9208 gtk_window_get_size (window, (gint *)&w, (gint *)&h);
9210 grav = GDK_GRAVITY_NORTH_WEST;
9212 if ((result & XNegative) && (result & YNegative))
9213 grav = GDK_GRAVITY_SOUTH_EAST;
9214 else if (result & XNegative)
9215 grav = GDK_GRAVITY_NORTH_EAST;
9216 else if (result & YNegative)
9217 grav = GDK_GRAVITY_SOUTH_WEST;
9219 if ((result & XValue) == 0)
9222 if ((result & YValue) == 0)
9225 if (grav == GDK_GRAVITY_SOUTH_WEST ||
9226 grav == GDK_GRAVITY_SOUTH_EAST)
9227 y = gdk_screen_get_height (screen) - h + y;
9229 if (grav == GDK_GRAVITY_SOUTH_EAST ||
9230 grav == GDK_GRAVITY_NORTH_EAST)
9231 x = gdk_screen_get_width (screen) - w + x;
9233 /* we don't let you put a window offscreen; maybe some people would
9234 * prefer to be able to, but it's kind of a bogus thing to do.
9243 if ((result & XValue) || (result & YValue))
9245 gtk_window_set_gravity (window, grav);
9246 gtk_window_move (window, x, y);
9250 if (size_set || pos_set)
9252 /* Set USSize, USPosition hints */
9253 GtkWindowGeometryInfo *info;
9255 info = gtk_window_get_geometry_info (window, TRUE);
9258 info->mask |= GDK_HINT_USER_POS;
9260 info->mask |= GDK_HINT_USER_SIZE;
9267 gtk_window_mnemonic_hash_foreach (guint keyval,
9273 GtkWindowKeysForeachFunc func;
9277 (*info->func) (info->window, keyval, info->window->priv->mnemonic_modifier, TRUE, info->func_data);
9281 _gtk_window_keys_foreach (GtkWindow *window,
9282 GtkWindowKeysForeachFunc func,
9286 GtkMnemonicHash *mnemonic_hash;
9290 GtkWindowKeysForeachFunc func;
9294 info.window = window;
9296 info.func_data = func_data;
9298 mnemonic_hash = gtk_window_get_mnemonic_hash (window, FALSE);
9300 _gtk_mnemonic_hash_foreach (mnemonic_hash,
9301 gtk_window_mnemonic_hash_foreach, &info);
9303 groups = gtk_accel_groups_from_object (G_OBJECT (window));
9306 GtkAccelGroup *group = groups->data;
9309 for (i = 0; i < group->priv->n_accels; i++)
9311 GtkAccelKey *key = &group->priv->priv_accels[i].key;
9314 (*func) (window, key->accel_key, key->accel_mods, FALSE, func_data);
9317 groups = groups->next;
9322 gtk_window_keys_changed (GtkWindow *window)
9324 gtk_window_free_key_hash (window);
9325 gtk_window_get_key_hash (window);
9328 typedef struct _GtkWindowKeyEntry GtkWindowKeyEntry;
9330 struct _GtkWindowKeyEntry
9334 guint is_mnemonic : 1;
9338 window_key_entry_destroy (gpointer data)
9340 g_slice_free (GtkWindowKeyEntry, data);
9344 add_to_key_hash (GtkWindow *window,
9346 GdkModifierType modifiers,
9347 gboolean is_mnemonic,
9350 GtkKeyHash *key_hash = data;
9352 GtkWindowKeyEntry *entry = g_slice_new (GtkWindowKeyEntry);
9354 entry->keyval = keyval;
9355 entry->modifiers = modifiers;
9356 entry->is_mnemonic = is_mnemonic;
9358 /* GtkAccelGroup stores lowercased accelerators. To deal
9359 * with this, if <Shift> was specified, uppercase.
9361 if (modifiers & GDK_SHIFT_MASK)
9363 if (keyval == GDK_KEY_Tab)
9364 keyval = GDK_KEY_ISO_Left_Tab;
9366 keyval = gdk_keyval_to_upper (keyval);
9369 _gtk_key_hash_add_entry (key_hash, keyval, entry->modifiers, entry);
9373 gtk_window_get_key_hash (GtkWindow *window)
9375 GdkScreen *screen = gtk_window_check_screen (window);
9376 GtkKeyHash *key_hash = g_object_get_qdata (G_OBJECT (window), quark_gtk_window_key_hash);
9381 key_hash = _gtk_key_hash_new (gdk_keymap_get_for_display (gdk_screen_get_display (screen)),
9382 (GDestroyNotify)window_key_entry_destroy);
9383 _gtk_window_keys_foreach (window, add_to_key_hash, key_hash);
9384 g_object_set_qdata (G_OBJECT (window), quark_gtk_window_key_hash, key_hash);
9390 gtk_window_free_key_hash (GtkWindow *window)
9392 GtkKeyHash *key_hash = g_object_get_qdata (G_OBJECT (window), quark_gtk_window_key_hash);
9395 _gtk_key_hash_free (key_hash);
9396 g_object_set_qdata (G_OBJECT (window), quark_gtk_window_key_hash, NULL);
9401 * gtk_window_activate_key:
9402 * @window: a #GtkWindow
9403 * @event: a #GdkEventKey
9405 * Activates mnemonics and accelerators for this #GtkWindow. This is normally
9406 * called by the default ::key_press_event handler for toplevel windows,
9407 * however in some cases it may be useful to call this directly when
9408 * overriding the standard key handling for a toplevel window.
9410 * Return value: %TRUE if a mnemonic or accelerator was found and activated.
9415 gtk_window_activate_key (GtkWindow *window,
9418 GtkKeyHash *key_hash;
9419 GtkWindowKeyEntry *found_entry = NULL;
9420 gboolean enable_mnemonics;
9421 gboolean enable_accels;
9423 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
9424 g_return_val_if_fail (event != NULL, FALSE);
9426 key_hash = gtk_window_get_key_hash (window);
9431 GSList *entries = _gtk_key_hash_lookup (key_hash,
9432 event->hardware_keycode,
9434 gtk_accelerator_get_default_mod_mask (),
9437 g_object_get (gtk_widget_get_settings (GTK_WIDGET (window)),
9438 "gtk-enable-mnemonics", &enable_mnemonics,
9439 "gtk-enable-accels", &enable_accels,
9442 for (tmp_list = entries; tmp_list; tmp_list = tmp_list->next)
9444 GtkWindowKeyEntry *entry = tmp_list->data;
9445 if (entry->is_mnemonic)
9447 if (enable_mnemonics)
9449 found_entry = entry;
9455 if (enable_accels && !found_entry)
9457 found_entry = entry;
9462 g_slist_free (entries);
9467 if (found_entry->is_mnemonic)
9469 if (enable_mnemonics)
9470 return gtk_window_mnemonic_activate (window, found_entry->keyval,
9471 found_entry->modifiers);
9476 return gtk_accel_groups_activate (G_OBJECT (window), found_entry->keyval,
9477 found_entry->modifiers);
9485 window_update_has_focus (GtkWindow *window)
9487 GtkWindowPrivate *priv = window->priv;
9488 GtkWidget *widget = GTK_WIDGET (window);
9489 gboolean has_focus = priv->has_toplevel_focus && priv->is_active;
9491 if (has_focus != priv->has_focus)
9493 priv->has_focus = has_focus;
9497 if (priv->focus_widget &&
9498 priv->focus_widget != widget &&
9499 !gtk_widget_has_focus (priv->focus_widget))
9500 do_focus_change (priv->focus_widget, TRUE);
9504 if (priv->focus_widget &&
9505 priv->focus_widget != widget &&
9506 gtk_widget_has_focus (priv->focus_widget))
9507 do_focus_change (priv->focus_widget, FALSE);
9513 * _gtk_window_set_is_active:
9514 * @window: a #GtkWindow
9515 * @is_active: %TRUE if the window is in the currently active toplevel
9517 * Internal function that sets whether the #GtkWindow is part
9518 * of the currently active toplevel window (taking into account inter-process
9522 _gtk_window_set_is_active (GtkWindow *window,
9525 GtkWindowPrivate *priv;
9527 g_return_if_fail (GTK_IS_WINDOW (window));
9529 priv = window->priv;
9531 is_active = is_active != FALSE;
9533 if (is_active != priv->is_active)
9535 priv->is_active = is_active;
9536 window_update_has_focus (window);
9538 g_object_notify (G_OBJECT (window), "is-active");
9543 * _gtk_window_set_is_toplevel:
9544 * @window: a #GtkWindow
9545 * @is_toplevel: %TRUE if the window is still a real toplevel (nominally a
9546 * child of the root window); %FALSE if it is not (for example, for an
9547 * in-process, parented GtkPlug)
9549 * Internal function used by #GtkPlug when it gets parented/unparented by a
9550 * #GtkSocket. This keeps the @window's #GTK_TOPLEVEL flag in sync with the
9551 * global list of toplevel windows.
9554 _gtk_window_set_is_toplevel (GtkWindow *window,
9555 gboolean is_toplevel)
9558 GtkWidget *toplevel;
9560 widget = GTK_WIDGET (window);
9562 if (gtk_widget_is_toplevel (widget))
9563 g_assert (g_slist_find (toplevel_list, window) != NULL);
9565 g_assert (g_slist_find (toplevel_list, window) == NULL);
9567 if (is_toplevel == gtk_widget_is_toplevel (widget))
9572 /* Pass through regular pathways of an embedded toplevel
9573 * to go through unmapping and hiding the widget before
9574 * becomming a toplevel again.
9576 * We remain hidden after becomming toplevel in order to
9577 * avoid problems during an embedded toplevel's dispose cycle
9578 * (When a toplevel window is shown it tries to grab focus again,
9579 * this causes problems while disposing).
9581 gtk_widget_hide (widget);
9583 /* Save the toplevel this widget was previously anchored into before
9584 * propagating a hierarchy-changed.
9586 * Usually this happens by way of gtk_widget_unparent() and we are
9587 * already unanchored at this point, just adding this clause incase
9588 * things happen differently.
9590 toplevel = gtk_widget_get_toplevel (widget);
9591 if (!gtk_widget_is_toplevel (toplevel))
9594 _gtk_widget_set_is_toplevel (widget, TRUE);
9596 /* When a window becomes toplevel after being embedded and anchored
9597 * into another window we need to unset its anchored flag so that
9598 * the hierarchy changed signal kicks in properly.
9600 _gtk_widget_set_anchored (widget, FALSE);
9601 _gtk_widget_propagate_hierarchy_changed (widget, toplevel);
9603 toplevel_list = g_slist_prepend (toplevel_list, window);
9607 _gtk_widget_set_is_toplevel (widget, FALSE);
9608 toplevel_list = g_slist_remove (toplevel_list, window);
9610 _gtk_widget_propagate_hierarchy_changed (widget, widget);
9615 * _gtk_window_set_has_toplevel_focus:
9616 * @window: a #GtkWindow
9617 * @has_toplevel_focus: %TRUE if the in
9619 * Internal function that sets whether the keyboard focus for the
9620 * toplevel window (taking into account inter-process embedding.)
9623 _gtk_window_set_has_toplevel_focus (GtkWindow *window,
9624 gboolean has_toplevel_focus)
9626 GtkWindowPrivate *priv;
9628 g_return_if_fail (GTK_IS_WINDOW (window));
9630 priv = window->priv;
9632 has_toplevel_focus = has_toplevel_focus != FALSE;
9634 if (has_toplevel_focus != priv->has_toplevel_focus)
9636 priv->has_toplevel_focus = has_toplevel_focus;
9637 window_update_has_focus (window);
9639 g_object_notify (G_OBJECT (window), "has-toplevel-focus");
9644 * gtk_window_set_auto_startup_notification:
9645 * @setting: %TRUE to automatically do startup notification
9647 * By default, after showing the first #GtkWindow, GTK+ calls
9648 * gdk_notify_startup_complete(). Call this function to disable
9649 * the automatic startup notification. You might do this if your
9650 * first window is a splash screen, and you want to delay notification
9651 * until after your real main window has been shown, for example.
9653 * In that example, you would disable startup notification
9654 * temporarily, show your splash screen, then re-enable it so that
9655 * showing the main window would automatically result in notification.
9660 gtk_window_set_auto_startup_notification (gboolean setting)
9662 disable_startup_notification = !setting;
9666 * gtk_window_get_window_type:
9667 * @window: a #GtkWindow
9669 * Gets the type of the window. See #GtkWindowType.
9671 * Return value: the type of the window
9676 gtk_window_get_window_type (GtkWindow *window)
9678 g_return_val_if_fail (GTK_IS_WINDOW (window), GTK_WINDOW_TOPLEVEL);
9680 return window->priv->type;
9684 * gtk_window_get_mnemonics_visible:
9685 * @window: a #GtkWindow
9687 * Gets the value of the #GtkWindow:mnemonics-visible property.
9689 * Returns: %TRUE if mnemonics are supposed to be visible
9695 gtk_window_get_mnemonics_visible (GtkWindow *window)
9697 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
9699 return window->priv->mnemonics_visible;
9703 * gtk_window_set_mnemonics_visible:
9704 * @window: a #GtkWindow
9705 * @setting: the new value
9707 * Sets the #GtkWindow:mnemonics-visible property.
9712 gtk_window_set_mnemonics_visible (GtkWindow *window,
9715 GtkWindowPrivate *priv;
9717 g_return_if_fail (GTK_IS_WINDOW (window));
9719 priv = window->priv;
9721 setting = setting != FALSE;
9723 if (priv->mnemonics_visible != setting)
9725 priv->mnemonics_visible = setting;
9726 g_object_notify (G_OBJECT (window), "mnemonics-visible");
9729 priv->mnemonics_visible_set = TRUE;
9733 * gtk_window_get_focus_visible:
9734 * @window: a #GtkWindow
9736 * Gets the value of the #GtkWindow:focus-visible property.
9738 * Returns: %TRUE if 'focus rectangles' are supposed to be visible
9744 gtk_window_get_focus_visible (GtkWindow *window)
9746 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
9748 return window->priv->focus_visible;
9752 * gtk_window_set_focus_visible:
9753 * @window: a #GtkWindow
9754 * @setting: the new value
9756 * Sets the #GtkWindow:focus-visible property.
9761 gtk_window_set_focus_visible (GtkWindow *window,
9764 GtkWindowPrivate *priv;
9766 g_return_if_fail (GTK_IS_WINDOW (window));
9768 priv = window->priv;
9770 setting = setting != FALSE;
9772 if (priv->focus_visible != setting)
9774 priv->focus_visible = setting;
9775 g_object_notify (G_OBJECT (window), "focus-visible");
9780 _gtk_window_get_wmclass (GtkWindow *window,
9781 gchar **wmclass_name,
9782 gchar **wmclass_class)
9784 GtkWindowPrivate *priv = window->priv;
9786 *wmclass_name = priv->wmclass_name;
9787 *wmclass_class = priv->wmclass_class;
9791 * gtk_window_set_has_user_ref_count:
9792 * @window: a #GtkWindow
9793 * @setting: the new value
9795 * Tells GTK+ whether to drop its extra reference to the window
9796 * when gtk_window_destroy() is called.
9798 * This function is only exported for the benefit of language
9799 * bindings which may need to keep the window alive until their
9800 * wrapper object is garbage collected. There is no justification
9801 * for ever calling this function in an application.
9806 gtk_window_set_has_user_ref_count (GtkWindow *window,
9809 g_return_if_fail (GTK_IS_WINDOW (window));
9811 window->priv->has_user_ref_count = setting;
9815 ensure_state_flag_backdrop (GtkWidget *widget)
9818 gboolean window_focused = TRUE;
9820 window = gtk_widget_get_window (widget);
9822 window_focused = gdk_window_get_state (window) & GDK_WINDOW_STATE_FOCUSED;
9824 if (!window_focused)
9825 gtk_widget_set_state_flags (widget, GTK_STATE_FLAG_BACKDROP, FALSE);
9827 gtk_widget_unset_state_flags (widget, GTK_STATE_FLAG_BACKDROP);
9829 gtk_widget_queue_draw (widget);