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, see <http://www.gnu.org/licenses/>.
19 * Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
20 * file for a list of people on the GTK+ Team. See the ChangeLog
21 * files for a list of changes. These files are distributed with
22 * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
27 #include "gtkwindow.h"
34 #include "gtkprivate.h"
35 #include "gtkwindowprivate.h"
36 #include "gtkaccelgroupprivate.h"
37 #include "gtkbindings.h"
38 #include "gtkkeyhash.h"
40 #include "gtkmnemonichash.h"
41 #include "gtkmenubar.h"
42 #include "gtkiconfactory.h"
43 #include "gtkicontheme.h"
44 #include "gtkmarshalers.h"
46 #include "gtkbuildable.h"
47 #include "gtkwidgetprivate.h"
48 #include "gtkcontainerprivate.h"
50 #include "gtkstylecontextprivate.h"
51 #include "gtktypebuiltins.h"
52 #include "a11y/gtkwindowaccessible.h"
54 #include "deprecated/gtkstyle.h"
56 #ifdef GDK_WINDOWING_X11
63 * @short_description: Toplevel which can contain other widgets
65 * A GtkWindow is a toplevel window which can contain other widgets.
66 * Windows normally have decorations that are under the control
67 * of the windowing system and allow the user to manipulate the window
68 * (resize it, move it, close it,...).
70 * GTK+ also allows windows to have a resize grip (a small area in the lower
71 * right or left corner) which can be clicked to reszie the window. To
72 * control whether a window has a resize grip, use
73 * gtk_window_set_has_resize_grip().
75 * <refsect2 id="GtkWindow-BUILDER-UI">
76 * <title>GtkWindow as GtkBuildable</title>
78 * The GtkWindow implementation of the GtkBuildable interface supports a
79 * custom <tag class="starttag">accel-groups</tag> element, which supports
80 * any number of <tag class="starttag">group</tag> elements representing the
81 * #GtkAccelGroup objects you want to add to your window (synonymous with
82 * gtk_window_add_accel_group().
85 * <title>A UI definition fragment with accel groups</title>
86 * <programlisting><![CDATA[
87 * <object class="GtkWindow">
89 * <group name="accelgroup1"/>
95 * <object class="GtkAccelGroup" id="accelgroup1"/>
96 * ]]></programlisting>
101 typedef struct _GtkDeviceGrabInfo GtkDeviceGrabInfo;
103 struct _GtkWindowPrivate
105 GtkMnemonicHash *mnemonic_hash;
107 GtkWidget *attach_widget;
108 GtkWidget *default_widget;
109 GtkWidget *focus_widget;
110 GtkWindow *transient_parent;
111 GtkWindowGeometryInfo *geometry_info;
112 GtkWindowGroup *group;
114 GtkApplication *application;
116 GdkModifierType mnemonic_modifier;
117 GdkWindowTypeHint gdk_type_hint;
121 GdkWindow *grip_window;
125 gchar *wmclass_class;
129 guint keys_changed_handler;
131 guint32 initial_timestamp;
133 guint16 configure_request_count;
135 /* The following flags are initially TRUE (before a window is mapped).
136 * They cause us to compute a configure request that involves
137 * default-only parameters. Once mapped, we set them to FALSE.
138 * Then we set them to TRUE again on unmap (for position)
139 * and on unrealize (for size).
141 guint need_default_position : 1;
142 guint need_default_size : 1;
144 guint above_initially : 1;
145 guint accept_focus : 1;
146 guint below_initially : 1;
147 guint builder_visible : 1;
148 guint configure_notify_received : 1;
151 guint destroy_with_parent : 1;
152 guint focus_on_map : 1;
153 guint fullscreen_initially : 1;
155 guint has_user_ref_count : 1;
156 guint has_toplevel_focus : 1;
157 guint hide_titlebar_when_maximized : 1;
158 guint iconify_initially : 1; /* gtk_window_iconify() called before realization */
160 guint maximize_initially : 1;
161 guint mnemonics_visible : 1;
162 guint mnemonics_visible_set : 1;
163 guint focus_visible : 1;
165 guint opacity_set : 1;
167 guint reset_type_hint : 1;
169 guint skips_pager : 1;
170 guint skips_taskbar : 1;
171 guint stick_initially : 1;
172 guint transient_parent_group : 1;
173 guint type : 4; /* GtkWindowType */
174 guint type_hint : 3; /* GdkWindowTypeHint if the hint is
175 * one of the original eight. If not,
177 * GDK_WINDOW_TYPE_HINT_NORMAL
180 guint has_resize_grip : 1;
181 guint resize_grip_visible : 1; /* don't use, just for "resize-
182 * grip-visible" notification
184 guint gravity : 5; /* GdkGravity */
211 PROP_DESTROY_WITH_PARENT,
212 PROP_HIDE_TITLEBAR_WHEN_MAXIMIZED,
217 PROP_SKIP_TASKBAR_HINT,
218 PROP_SKIP_PAGER_HINT,
228 PROP_HAS_RESIZE_GRIP,
229 PROP_RESIZE_GRIP_VISIBLE,
231 /* Readonly properties */
233 PROP_HAS_TOPLEVEL_FOCUS,
235 /* Writeonly properties */
238 PROP_MNEMONICS_VISIBLE,
249 guint using_default_icon : 1;
250 guint using_parent_icon : 1;
251 guint using_themed_icon : 1;
255 GdkGeometry geometry; /* Last set of geometry hints we set */
256 GdkWindowHints flags;
257 GdkRectangle configure_request;
258 } GtkWindowLastGeometryInfo;
260 struct _GtkWindowGeometryInfo
262 /* Properties that the app has set on the window
264 GdkGeometry geometry; /* Geometry hints */
266 GtkWidget *widget; /* subwidget to which hints apply */
267 /* from last gtk_window_resize () - if > 0, indicates that
268 * we should resize to this size.
273 /* From last gtk_window_move () prior to mapping -
274 * only used if initial_pos_set
279 /* Default size - used only the FIRST time we map a window,
284 /* whether to use initial_x, initial_y */
285 guint initial_pos_set : 1;
286 /* CENTER_ALWAYS or other position constraint changed since
287 * we sent the last configure request.
289 guint position_constraints_changed : 1;
291 /* if true, default_width, height should be multiplied by the
292 * increments and affect the geometry widget only
294 guint default_is_geometry : 1;
296 /* if true, resize_width, height should be multiplied by the
297 * increments and affect the geometry widget only
299 guint resize_is_geometry : 1;
301 GtkWindowLastGeometryInfo last;
305 struct _GtkDeviceGrabInfo
309 guint block_others : 1;
312 struct _GtkWindowGroupPrivate
315 GSList *device_grabs;
318 static void gtk_window_dispose (GObject *object);
319 static void gtk_window_finalize (GObject *object);
320 static void gtk_window_destroy (GtkWidget *widget);
321 static void gtk_window_show (GtkWidget *widget);
322 static void gtk_window_hide (GtkWidget *widget);
323 static void gtk_window_map (GtkWidget *widget);
324 static void gtk_window_unmap (GtkWidget *widget);
325 static void gtk_window_realize (GtkWidget *widget);
326 static void gtk_window_unrealize (GtkWidget *widget);
327 static void gtk_window_size_allocate (GtkWidget *widget,
328 GtkAllocation *allocation);
329 static gboolean gtk_window_map_event (GtkWidget *widget,
331 static gint gtk_window_configure_event (GtkWidget *widget,
332 GdkEventConfigure *event);
333 static gint gtk_window_key_press_event (GtkWidget *widget,
335 static gint gtk_window_key_release_event (GtkWidget *widget,
337 static gint gtk_window_button_press_event (GtkWidget *widget,
338 GdkEventButton *event);
339 static gint gtk_window_enter_notify_event (GtkWidget *widget,
340 GdkEventCrossing *event);
341 static gint gtk_window_leave_notify_event (GtkWidget *widget,
342 GdkEventCrossing *event);
343 static gint gtk_window_focus_in_event (GtkWidget *widget,
344 GdkEventFocus *event);
345 static gint gtk_window_focus_out_event (GtkWidget *widget,
346 GdkEventFocus *event);
347 static void gtk_window_style_updated (GtkWidget *widget);
348 static gboolean gtk_window_state_event (GtkWidget *widget,
349 GdkEventWindowState *event);
350 static void gtk_window_check_resize (GtkContainer *container);
351 static gint gtk_window_focus (GtkWidget *widget,
352 GtkDirectionType direction);
353 static void gtk_window_move_focus (GtkWidget *widget,
354 GtkDirectionType dir);
355 static void gtk_window_real_set_focus (GtkWindow *window,
357 static void gtk_window_direction_changed (GtkWidget *widget,
358 GtkTextDirection prev_dir);
359 static void gtk_window_state_changed (GtkWidget *widget,
360 GtkStateType previous_state);
362 static void gtk_window_real_activate_default (GtkWindow *window);
363 static void gtk_window_real_activate_focus (GtkWindow *window);
364 static void gtk_window_keys_changed (GtkWindow *window);
365 static gint gtk_window_draw (GtkWidget *widget,
367 static void gtk_window_unset_transient_for (GtkWindow *window);
368 static void gtk_window_transient_parent_realized (GtkWidget *parent,
370 static void gtk_window_transient_parent_unrealized (GtkWidget *parent,
373 static GdkScreen *gtk_window_check_screen (GtkWindow *window);
375 static GtkWindowGeometryInfo* gtk_window_get_geometry_info (GtkWindow *window,
378 static void gtk_window_move_resize (GtkWindow *window);
379 static gboolean gtk_window_compare_hints (GdkGeometry *geometry_a,
381 GdkGeometry *geometry_b,
383 static void gtk_window_constrain_size (GtkWindow *window,
384 GdkGeometry *geometry,
390 static void gtk_window_constrain_position (GtkWindow *window,
395 static void gtk_window_compute_hints (GtkWindow *window,
396 GdkGeometry *new_geometry,
398 static void gtk_window_compute_configure_request (GtkWindow *window,
399 GdkRectangle *request,
400 GdkGeometry *geometry,
403 static void gtk_window_set_default_size_internal (GtkWindow *window,
404 gboolean change_width,
406 gboolean change_height,
408 gboolean is_geometry);
410 static void update_themed_icon (GtkIconTheme *theme,
412 static GList *icon_list_from_theme (GtkWidget *widget,
414 static void gtk_window_realize_icon (GtkWindow *window);
415 static void gtk_window_unrealize_icon (GtkWindow *window);
416 static void resize_grip_create_window (GtkWindow *window);
417 static void resize_grip_destroy_window (GtkWindow *window);
418 static void update_grip_visibility (GtkWindow *window);
420 static void gtk_window_notify_keys_changed (GtkWindow *window);
421 static GtkKeyHash *gtk_window_get_key_hash (GtkWindow *window);
422 static void gtk_window_free_key_hash (GtkWindow *window);
423 static void gtk_window_on_composited_changed (GdkScreen *screen,
425 static void gtk_window_on_theme_variant_changed (GtkSettings *settings,
428 static void gtk_window_set_theme_variant (GtkWindow *window);
430 static GSList *toplevel_list = NULL;
431 static guint window_signals[LAST_SIGNAL] = { 0 };
432 static GList *default_icon_list = NULL;
433 static gchar *default_icon_name = NULL;
434 static guint default_icon_serial = 0;
435 static gboolean disable_startup_notification = FALSE;
436 static gboolean sent_startup_notification = FALSE;
438 static GQuark quark_gtk_embedded = 0;
439 static GQuark quark_gtk_window_key_hash = 0;
440 static GQuark quark_gtk_window_icon_info = 0;
441 static GQuark quark_gtk_buildable_accels = 0;
443 static GtkBuildableIface *parent_buildable_iface;
445 static void gtk_window_set_property (GObject *object,
449 static void gtk_window_get_property (GObject *object,
455 static void gtk_window_buildable_interface_init (GtkBuildableIface *iface);
456 static void gtk_window_buildable_set_buildable_property (GtkBuildable *buildable,
459 const GValue *value);
460 static void gtk_window_buildable_parser_finished (GtkBuildable *buildable,
461 GtkBuilder *builder);
462 static gboolean gtk_window_buildable_custom_tag_start (GtkBuildable *buildable,
465 const gchar *tagname,
466 GMarkupParser *parser,
468 static void gtk_window_buildable_custom_finished (GtkBuildable *buildable,
471 const gchar *tagname,
475 static void gtk_window_get_preferred_width (GtkWidget *widget,
478 static void gtk_window_get_preferred_height (GtkWidget *widget,
482 static void ensure_state_flag_backdrop (GtkWidget *widget);
484 G_DEFINE_TYPE_WITH_CODE (GtkWindow, gtk_window, GTK_TYPE_BIN,
485 G_IMPLEMENT_INTERFACE (GTK_TYPE_BUILDABLE,
486 gtk_window_buildable_interface_init))
489 add_tab_bindings (GtkBindingSet *binding_set,
490 GdkModifierType modifiers,
491 GtkDirectionType direction)
493 gtk_binding_entry_add_signal (binding_set, GDK_KEY_Tab, modifiers,
495 GTK_TYPE_DIRECTION_TYPE, direction);
496 gtk_binding_entry_add_signal (binding_set, GDK_KEY_KP_Tab, modifiers,
498 GTK_TYPE_DIRECTION_TYPE, direction);
502 add_arrow_bindings (GtkBindingSet *binding_set,
504 GtkDirectionType direction)
506 guint keypad_keysym = keysym - GDK_KEY_Left + GDK_KEY_KP_Left;
508 gtk_binding_entry_add_signal (binding_set, keysym, 0,
510 GTK_TYPE_DIRECTION_TYPE, direction);
511 gtk_binding_entry_add_signal (binding_set, keysym, GDK_CONTROL_MASK,
513 GTK_TYPE_DIRECTION_TYPE, direction);
514 gtk_binding_entry_add_signal (binding_set, keypad_keysym, 0,
516 GTK_TYPE_DIRECTION_TYPE, direction);
517 gtk_binding_entry_add_signal (binding_set, keypad_keysym, GDK_CONTROL_MASK,
519 GTK_TYPE_DIRECTION_TYPE, direction);
523 extract_time_from_startup_id (const gchar* startup_id)
525 gchar *timestr = g_strrstr (startup_id, "_TIME");
526 guint32 retval = GDK_CURRENT_TIME;
533 /* Skip past the "_TIME" part */
538 timestamp = g_ascii_strtoull (timestr, &end, 0);
539 if (errno == 0 && end != timestr)
547 startup_id_is_fake (const gchar* startup_id)
549 return strncmp (startup_id, "_TIME", 5) == 0;
553 gtk_window_class_init (GtkWindowClass *klass)
555 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
556 GtkWidgetClass *widget_class;
557 GtkContainerClass *container_class;
558 GtkBindingSet *binding_set;
560 widget_class = (GtkWidgetClass*) klass;
561 container_class = (GtkContainerClass*) klass;
563 quark_gtk_embedded = g_quark_from_static_string ("gtk-embedded");
564 quark_gtk_window_key_hash = g_quark_from_static_string ("gtk-window-key-hash");
565 quark_gtk_window_icon_info = g_quark_from_static_string ("gtk-window-icon-info");
566 quark_gtk_buildable_accels = g_quark_from_static_string ("gtk-window-buildable-accels");
568 gobject_class->dispose = gtk_window_dispose;
569 gobject_class->finalize = gtk_window_finalize;
571 gobject_class->set_property = gtk_window_set_property;
572 gobject_class->get_property = gtk_window_get_property;
574 widget_class->destroy = gtk_window_destroy;
575 widget_class->show = gtk_window_show;
576 widget_class->hide = gtk_window_hide;
577 widget_class->map = gtk_window_map;
578 widget_class->map_event = gtk_window_map_event;
579 widget_class->unmap = gtk_window_unmap;
580 widget_class->realize = gtk_window_realize;
581 widget_class->unrealize = gtk_window_unrealize;
582 widget_class->size_allocate = gtk_window_size_allocate;
583 widget_class->configure_event = gtk_window_configure_event;
584 widget_class->key_press_event = gtk_window_key_press_event;
585 widget_class->key_release_event = gtk_window_key_release_event;
586 widget_class->enter_notify_event = gtk_window_enter_notify_event;
587 widget_class->leave_notify_event = gtk_window_leave_notify_event;
588 widget_class->focus_in_event = gtk_window_focus_in_event;
589 widget_class->button_press_event = gtk_window_button_press_event;
590 widget_class->focus_out_event = gtk_window_focus_out_event;
591 widget_class->focus = gtk_window_focus;
592 widget_class->move_focus = gtk_window_move_focus;
593 widget_class->draw = gtk_window_draw;
594 widget_class->get_preferred_width = gtk_window_get_preferred_width;
595 widget_class->get_preferred_height = gtk_window_get_preferred_height;
596 widget_class->window_state_event = gtk_window_state_event;
597 widget_class->direction_changed = gtk_window_direction_changed;
598 widget_class->state_changed = gtk_window_state_changed;
599 widget_class->style_updated = gtk_window_style_updated;
601 container_class->check_resize = gtk_window_check_resize;
603 klass->set_focus = gtk_window_real_set_focus;
605 klass->activate_default = gtk_window_real_activate_default;
606 klass->activate_focus = gtk_window_real_activate_focus;
607 klass->keys_changed = gtk_window_keys_changed;
609 g_type_class_add_private (gobject_class, sizeof (GtkWindowPrivate));
612 g_object_class_install_property (gobject_class,
614 g_param_spec_enum ("type",
616 P_("The type of the window"),
617 GTK_TYPE_WINDOW_TYPE,
619 GTK_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
621 g_object_class_install_property (gobject_class,
623 g_param_spec_string ("title",
625 P_("The title of the window"),
627 GTK_PARAM_READWRITE));
629 g_object_class_install_property (gobject_class,
631 g_param_spec_string ("role",
633 P_("Unique identifier for the window to be used when restoring a session"),
635 GTK_PARAM_READWRITE));
638 * GtkWindow:startup-id:
640 * The :startup-id is a write-only property for setting window's
641 * startup notification identifier. See gtk_window_set_startup_id()
646 g_object_class_install_property (gobject_class,
648 g_param_spec_string ("startup-id",
650 P_("Unique startup identifier for the window used by startup-notification"),
652 GTK_PARAM_WRITABLE));
654 g_object_class_install_property (gobject_class,
656 g_param_spec_boolean ("resizable",
658 P_("If TRUE, users can resize the window"),
660 GTK_PARAM_READWRITE));
662 g_object_class_install_property (gobject_class,
664 g_param_spec_boolean ("modal",
666 P_("If TRUE, the window is modal (other windows are not usable while this one is up)"),
668 GTK_PARAM_READWRITE));
670 g_object_class_install_property (gobject_class,
672 g_param_spec_enum ("window-position",
673 P_("Window Position"),
674 P_("The initial position of the window"),
675 GTK_TYPE_WINDOW_POSITION,
677 GTK_PARAM_READWRITE));
679 g_object_class_install_property (gobject_class,
681 g_param_spec_int ("default-width",
683 P_("The default width of the window, used when initially showing the window"),
687 GTK_PARAM_READWRITE));
689 g_object_class_install_property (gobject_class,
691 g_param_spec_int ("default-height",
692 P_("Default Height"),
693 P_("The default height of the window, used when initially showing the window"),
697 GTK_PARAM_READWRITE));
699 g_object_class_install_property (gobject_class,
700 PROP_DESTROY_WITH_PARENT,
701 g_param_spec_boolean ("destroy-with-parent",
702 P_("Destroy with Parent"),
703 P_("If this window should be destroyed when the parent is destroyed"),
705 GTK_PARAM_READWRITE));
708 * GtkWindow:hide-titlebar-when-maximized:
710 * Whether the titlebar should be hidden during maximization.
714 g_object_class_install_property (gobject_class,
715 PROP_HIDE_TITLEBAR_WHEN_MAXIMIZED,
716 g_param_spec_boolean ("hide-titlebar-when-maximized",
717 P_("Hide the titlebar during maximization"),
718 P_("If this window's titlebar should be hidden when the window is maximized"),
720 GTK_PARAM_READWRITE));
722 g_object_class_install_property (gobject_class,
724 g_param_spec_object ("icon",
726 P_("Icon for this window"),
728 GTK_PARAM_READWRITE));
731 * GtkWindow:mnemonics-visible:
733 * Whether mnemonics are currently visible in this window.
735 * This property is maintained by GTK+ based on the
736 * #GtkSettings:gtk-auto-mnemonics setting and user input,
737 * and should not be set by applications.
741 g_object_class_install_property (gobject_class,
742 PROP_MNEMONICS_VISIBLE,
743 g_param_spec_boolean ("mnemonics-visible",
744 P_("Mnemonics Visible"),
745 P_("Whether mnemonics are currently visible in this window"),
747 GTK_PARAM_READWRITE));
750 * GtkWindow:focus-visible:
752 * Whether 'focus rectangles' are currently visible in this window.
754 * This property is maintained by GTK+ based on the
755 * #GtkSettings:gtk-visible-focus setting and user input
756 * and should not be set by applications.
760 g_object_class_install_property (gobject_class,
762 g_param_spec_boolean ("focus-visible",
764 P_("Whether focus rectangles are currently visible in this window"),
766 GTK_PARAM_READWRITE));
769 * GtkWindow:icon-name:
771 * The :icon-name property specifies the name of the themed icon to
772 * use as the window icon. See #GtkIconTheme for more details.
776 g_object_class_install_property (gobject_class,
778 g_param_spec_string ("icon-name",
780 P_("Name of the themed icon for this window"),
782 GTK_PARAM_READWRITE));
784 g_object_class_install_property (gobject_class,
786 g_param_spec_object ("screen",
788 P_("The screen where this window will be displayed"),
790 GTK_PARAM_READWRITE));
792 g_object_class_install_property (gobject_class,
794 g_param_spec_boolean ("is-active",
796 P_("Whether the toplevel is the current active window"),
798 GTK_PARAM_READABLE));
800 g_object_class_install_property (gobject_class,
801 PROP_HAS_TOPLEVEL_FOCUS,
802 g_param_spec_boolean ("has-toplevel-focus",
803 P_("Focus in Toplevel"),
804 P_("Whether the input focus is within this GtkWindow"),
806 GTK_PARAM_READABLE));
808 g_object_class_install_property (gobject_class,
810 g_param_spec_enum ("type-hint",
812 P_("Hint to help the desktop environment understand what kind of window this is and how to treat it."),
813 GDK_TYPE_WINDOW_TYPE_HINT,
814 GDK_WINDOW_TYPE_HINT_NORMAL,
815 GTK_PARAM_READWRITE));
817 g_object_class_install_property (gobject_class,
818 PROP_SKIP_TASKBAR_HINT,
819 g_param_spec_boolean ("skip-taskbar-hint",
821 P_("TRUE if the window should not be in the task bar."),
823 GTK_PARAM_READWRITE));
825 g_object_class_install_property (gobject_class,
826 PROP_SKIP_PAGER_HINT,
827 g_param_spec_boolean ("skip-pager-hint",
829 P_("TRUE if the window should not be in the pager."),
831 GTK_PARAM_READWRITE));
833 g_object_class_install_property (gobject_class,
835 g_param_spec_boolean ("urgency-hint",
837 P_("TRUE if the window should be brought to the user's attention."),
839 GTK_PARAM_READWRITE));
842 * GtkWindow:accept-focus:
844 * Whether the window should receive the input focus.
848 g_object_class_install_property (gobject_class,
850 g_param_spec_boolean ("accept-focus",
852 P_("TRUE if the window should receive the input focus."),
854 GTK_PARAM_READWRITE));
857 * GtkWindow:focus-on-map:
859 * Whether the window should receive the input focus when mapped.
863 g_object_class_install_property (gobject_class,
865 g_param_spec_boolean ("focus-on-map",
867 P_("TRUE if the window should receive the input focus when mapped."),
869 GTK_PARAM_READWRITE));
872 * GtkWindow:decorated:
874 * Whether the window should be decorated by the window manager.
878 g_object_class_install_property (gobject_class,
880 g_param_spec_boolean ("decorated",
882 P_("Whether the window should be decorated by the window manager"),
884 GTK_PARAM_READWRITE));
887 * GtkWindow:deletable:
889 * Whether the window frame should have a close button.
893 g_object_class_install_property (gobject_class,
895 g_param_spec_boolean ("deletable",
897 P_("Whether the window frame should have a close button"),
899 GTK_PARAM_READWRITE));
902 * GtkWindow:has-resize-grip:
904 * Whether the window has a corner resize grip.
906 * Note that the resize grip is only shown if the window is
907 * actually resizable and not maximized. Use
908 * #GtkWindow:resize-grip-visible to find out if the resize
909 * grip is currently shown.
913 g_object_class_install_property (gobject_class,
914 PROP_HAS_RESIZE_GRIP,
915 g_param_spec_boolean ("has-resize-grip",
917 P_("Specifies whether the window should have a resize grip"),
919 GTK_PARAM_READWRITE));
922 * GtkWindow:resize-grip-visible:
924 * Whether a corner resize grip is currently shown.
928 g_object_class_install_property (gobject_class,
929 PROP_RESIZE_GRIP_VISIBLE,
930 g_param_spec_boolean ("resize-grip-visible",
931 P_("Resize grip is visible"),
932 P_("Specifies whether the window's resize grip is visible."),
934 GTK_PARAM_READABLE));
940 * The window gravity of the window. See gtk_window_move() and #GdkGravity for
941 * more details about window gravity.
945 g_object_class_install_property (gobject_class,
947 g_param_spec_enum ("gravity",
949 P_("The window gravity of the window"),
951 GDK_GRAVITY_NORTH_WEST,
952 GTK_PARAM_READWRITE));
956 * GtkWindow:transient-for:
958 * The transient parent of the window. See gtk_window_set_transient_for() for
959 * more details about transient windows.
963 g_object_class_install_property (gobject_class,
965 g_param_spec_object ("transient-for",
966 P_("Transient for Window"),
967 P_("The transient parent of the dialog"),
969 GTK_PARAM_READWRITE| G_PARAM_CONSTRUCT));
972 * GtkWindow:attached-to:
974 * The widget to which this window is attached.
975 * See gtk_window_set_attached_to().
977 * Examples of places where specifying this relation is useful are
978 * for instance a #GtkMenu created by a #GtkComboBox, a completion
979 * popup window created by #GtkEntry or a typeahead search entry
980 * created by #GtkTreeView.
984 g_object_class_install_property (gobject_class,
986 g_param_spec_object ("attached-to",
987 P_("Attached to Widget"),
988 P_("The widget where the window is attached"),
990 GTK_PARAM_READWRITE | G_PARAM_CONSTRUCT));
995 * The requested opacity of the window. See gtk_window_set_opacity() for
996 * more details about window opacity.
1000 g_object_class_install_property (gobject_class,
1002 g_param_spec_double ("opacity",
1003 P_("Opacity for Window"),
1004 P_("The opacity of the window, from 0 to 1"),
1008 GTK_PARAM_READWRITE));
1010 /* Style properties.
1012 gtk_widget_class_install_style_property (widget_class,
1013 g_param_spec_int ("resize-grip-width",
1014 P_("Width of resize grip"),
1015 P_("Width of resize grip"),
1016 0, G_MAXINT, 16, GTK_PARAM_READWRITE));
1018 gtk_widget_class_install_style_property (widget_class,
1019 g_param_spec_int ("resize-grip-height",
1020 P_("Height of resize grip"),
1021 P_("Height of resize grip"),
1022 0, G_MAXINT, 16, GTK_PARAM_READWRITE));
1026 * GtkWindow:application:
1028 * The #GtkApplication associated with the window.
1030 * The application will be kept alive for at least as long as it
1031 * has any windows associated with it (see g_application_hold()
1032 * for a way to keep it alive without windows).
1034 * Normally, the connection between the application and the window
1035 * will remain until the window is destroyed, but you can explicitly
1036 * remove it by setting the ::application property to %NULL.
1040 g_object_class_install_property (gobject_class,
1042 g_param_spec_object ("application",
1043 P_("GtkApplication"),
1044 P_("The GtkApplication for the window"),
1045 GTK_TYPE_APPLICATION,
1046 GTK_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
1048 window_signals[SET_FOCUS] =
1049 g_signal_new (I_("set-focus"),
1050 G_TYPE_FROM_CLASS (gobject_class),
1052 G_STRUCT_OFFSET (GtkWindowClass, set_focus),
1054 _gtk_marshal_VOID__OBJECT,
1059 * GtkWindow::activate-focus:
1060 * @window: the window which received the signal
1062 * The ::activate-focus signal is a
1063 * <link linkend="keybinding-signals">keybinding signal</link>
1064 * which gets emitted when the user activates the currently
1065 * focused widget of @window.
1067 window_signals[ACTIVATE_FOCUS] =
1068 g_signal_new (I_("activate-focus"),
1069 G_TYPE_FROM_CLASS (gobject_class),
1070 G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
1071 G_STRUCT_OFFSET (GtkWindowClass, activate_focus),
1073 _gtk_marshal_VOID__VOID,
1078 * GtkWindow::activate-default:
1079 * @window: the window which received the signal
1081 * The ::activate-default signal is a
1082 * <link linkend="keybinding-signals">keybinding signal</link>
1083 * which gets emitted when the user activates the default widget
1086 window_signals[ACTIVATE_DEFAULT] =
1087 g_signal_new (I_("activate-default"),
1088 G_TYPE_FROM_CLASS (gobject_class),
1089 G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
1090 G_STRUCT_OFFSET (GtkWindowClass, activate_default),
1092 _gtk_marshal_VOID__VOID,
1097 * GtkWindow::keys-changed:
1098 * @window: the window which received the signal
1100 * The ::keys-changed signal gets emitted when the set of accelerators
1101 * or mnemonics that are associated with @window changes.
1103 window_signals[KEYS_CHANGED] =
1104 g_signal_new (I_("keys-changed"),
1105 G_TYPE_FROM_CLASS (gobject_class),
1107 G_STRUCT_OFFSET (GtkWindowClass, keys_changed),
1109 _gtk_marshal_VOID__VOID,
1117 binding_set = gtk_binding_set_by_class (klass);
1119 gtk_binding_entry_add_signal (binding_set, GDK_KEY_space, 0,
1120 "activate-focus", 0);
1121 gtk_binding_entry_add_signal (binding_set, GDK_KEY_KP_Space, 0,
1122 "activate-focus", 0);
1124 gtk_binding_entry_add_signal (binding_set, GDK_KEY_Return, 0,
1125 "activate-default", 0);
1126 gtk_binding_entry_add_signal (binding_set, GDK_KEY_ISO_Enter, 0,
1127 "activate-default", 0);
1128 gtk_binding_entry_add_signal (binding_set, GDK_KEY_KP_Enter, 0,
1129 "activate-default", 0);
1131 add_arrow_bindings (binding_set, GDK_KEY_Up, GTK_DIR_UP);
1132 add_arrow_bindings (binding_set, GDK_KEY_Down, GTK_DIR_DOWN);
1133 add_arrow_bindings (binding_set, GDK_KEY_Left, GTK_DIR_LEFT);
1134 add_arrow_bindings (binding_set, GDK_KEY_Right, GTK_DIR_RIGHT);
1136 add_tab_bindings (binding_set, 0, GTK_DIR_TAB_FORWARD);
1137 add_tab_bindings (binding_set, GDK_CONTROL_MASK, GTK_DIR_TAB_FORWARD);
1138 add_tab_bindings (binding_set, GDK_SHIFT_MASK, GTK_DIR_TAB_BACKWARD);
1139 add_tab_bindings (binding_set, GDK_CONTROL_MASK | GDK_SHIFT_MASK, GTK_DIR_TAB_BACKWARD);
1141 gtk_widget_class_set_accessible_type (widget_class, GTK_TYPE_WINDOW_ACCESSIBLE);
1145 gtk_window_init (GtkWindow *window)
1147 GtkWindowPrivate *priv;
1149 window->priv = G_TYPE_INSTANCE_GET_PRIVATE (window,
1152 priv = window->priv;
1154 gtk_widget_set_has_window (GTK_WIDGET (window), TRUE);
1155 _gtk_widget_set_is_toplevel (GTK_WIDGET (window), TRUE);
1157 _gtk_widget_set_anchored (GTK_WIDGET (window), TRUE);
1159 gtk_container_set_resize_mode (GTK_CONTAINER (window), GTK_RESIZE_QUEUE);
1162 priv->wmclass_name = g_strdup (g_get_prgname ());
1163 priv->wmclass_class = g_strdup (gdk_get_program_class ());
1164 priv->wm_role = NULL;
1165 priv->geometry_info = NULL;
1166 priv->type = GTK_WINDOW_TOPLEVEL;
1167 priv->focus_widget = NULL;
1168 priv->default_widget = NULL;
1169 priv->configure_request_count = 0;
1170 priv->resizable = TRUE;
1171 priv->configure_notify_received = FALSE;
1172 priv->position = GTK_WIN_POS_NONE;
1173 priv->need_default_size = TRUE;
1174 priv->need_default_position = TRUE;
1175 priv->modal = FALSE;
1176 priv->gdk_type_hint = GDK_WINDOW_TYPE_HINT_NORMAL;
1177 priv->gravity = GDK_GRAVITY_NORTH_WEST;
1178 priv->decorated = TRUE;
1179 priv->mnemonic_modifier = GDK_MOD1_MASK;
1180 priv->screen = gdk_screen_get_default ();
1182 priv->accept_focus = TRUE;
1183 priv->focus_on_map = TRUE;
1184 priv->deletable = TRUE;
1185 priv->type_hint = GDK_WINDOW_TYPE_HINT_NORMAL;
1186 priv->opacity = 1.0;
1187 priv->startup_id = NULL;
1188 priv->initial_timestamp = GDK_CURRENT_TIME;
1189 priv->has_resize_grip = TRUE;
1190 priv->mnemonics_visible = TRUE;
1191 priv->focus_visible = TRUE;
1193 g_object_ref_sink (window);
1194 priv->has_user_ref_count = TRUE;
1195 toplevel_list = g_slist_prepend (toplevel_list, window);
1198 g_signal_connect (priv->screen, "composited-changed",
1199 G_CALLBACK (gtk_window_on_composited_changed), window);
1201 #ifdef GDK_WINDOWING_X11
1202 g_signal_connect (gtk_settings_get_for_screen (priv->screen),
1203 "notify::gtk-application-prefer-dark-theme",
1204 G_CALLBACK (gtk_window_on_theme_variant_changed), window);
1209 gtk_window_set_property (GObject *object,
1211 const GValue *value,
1214 GtkWindow *window = GTK_WINDOW (object);
1215 GtkWindowPrivate *priv = window->priv;
1220 priv->type = g_value_get_enum (value);
1223 gtk_window_set_title (window, g_value_get_string (value));
1226 gtk_window_set_role (window, g_value_get_string (value));
1228 case PROP_STARTUP_ID:
1229 gtk_window_set_startup_id (window, g_value_get_string (value));
1231 case PROP_RESIZABLE:
1232 gtk_window_set_resizable (window, g_value_get_boolean (value));
1235 gtk_window_set_modal (window, g_value_get_boolean (value));
1238 gtk_window_set_position (window, g_value_get_enum (value));
1240 case PROP_DEFAULT_WIDTH:
1241 gtk_window_set_default_size_internal (window,
1242 TRUE, g_value_get_int (value),
1245 case PROP_DEFAULT_HEIGHT:
1246 gtk_window_set_default_size_internal (window,
1248 TRUE, g_value_get_int (value), FALSE);
1250 case PROP_DESTROY_WITH_PARENT:
1251 gtk_window_set_destroy_with_parent (window, g_value_get_boolean (value));
1253 case PROP_HIDE_TITLEBAR_WHEN_MAXIMIZED:
1254 gtk_window_set_hide_titlebar_when_maximized (window, g_value_get_boolean (value));
1257 gtk_window_set_icon (window,
1258 g_value_get_object (value));
1260 case PROP_ICON_NAME:
1261 gtk_window_set_icon_name (window, g_value_get_string (value));
1264 gtk_window_set_screen (window, g_value_get_object (value));
1266 case PROP_TYPE_HINT:
1267 gtk_window_set_type_hint (window,
1268 g_value_get_enum (value));
1270 case PROP_SKIP_TASKBAR_HINT:
1271 gtk_window_set_skip_taskbar_hint (window,
1272 g_value_get_boolean (value));
1274 case PROP_SKIP_PAGER_HINT:
1275 gtk_window_set_skip_pager_hint (window,
1276 g_value_get_boolean (value));
1278 case PROP_URGENCY_HINT:
1279 gtk_window_set_urgency_hint (window,
1280 g_value_get_boolean (value));
1282 case PROP_ACCEPT_FOCUS:
1283 gtk_window_set_accept_focus (window,
1284 g_value_get_boolean (value));
1286 case PROP_FOCUS_ON_MAP:
1287 gtk_window_set_focus_on_map (window,
1288 g_value_get_boolean (value));
1290 case PROP_DECORATED:
1291 gtk_window_set_decorated (window, g_value_get_boolean (value));
1293 case PROP_DELETABLE:
1294 gtk_window_set_deletable (window, g_value_get_boolean (value));
1297 gtk_window_set_gravity (window, g_value_get_enum (value));
1299 case PROP_TRANSIENT_FOR:
1300 gtk_window_set_transient_for (window, g_value_get_object (value));
1302 case PROP_ATTACHED_TO:
1303 gtk_window_set_attached_to (window, g_value_get_object (value));
1306 gtk_window_set_opacity (window, g_value_get_double (value));
1308 case PROP_HAS_RESIZE_GRIP:
1309 gtk_window_set_has_resize_grip (window, g_value_get_boolean (value));
1311 case PROP_APPLICATION:
1312 gtk_window_set_application (window, g_value_get_object (value));
1314 case PROP_MNEMONICS_VISIBLE:
1315 gtk_window_set_mnemonics_visible (window, g_value_get_boolean (value));
1317 case PROP_FOCUS_VISIBLE:
1318 gtk_window_set_focus_visible (window, g_value_get_boolean (value));
1321 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1327 gtk_window_get_property (GObject *object,
1332 GtkWindow *window = GTK_WINDOW (object);
1333 GtkWindowPrivate *priv = window->priv;
1337 GtkWindowGeometryInfo *info;
1339 g_value_set_enum (value, priv->type);
1342 g_value_set_string (value, priv->wm_role);
1345 g_value_set_string (value, priv->title);
1347 case PROP_RESIZABLE:
1348 g_value_set_boolean (value, priv->resizable);
1351 g_value_set_boolean (value, priv->modal);
1354 g_value_set_enum (value, priv->position);
1356 case PROP_DEFAULT_WIDTH:
1357 info = gtk_window_get_geometry_info (window, FALSE);
1359 g_value_set_int (value, -1);
1361 g_value_set_int (value, info->default_width);
1363 case PROP_DEFAULT_HEIGHT:
1364 info = gtk_window_get_geometry_info (window, FALSE);
1366 g_value_set_int (value, -1);
1368 g_value_set_int (value, info->default_height);
1370 case PROP_DESTROY_WITH_PARENT:
1371 g_value_set_boolean (value, priv->destroy_with_parent);
1373 case PROP_HIDE_TITLEBAR_WHEN_MAXIMIZED:
1374 g_value_set_boolean (value, priv->hide_titlebar_when_maximized);
1377 g_value_set_object (value, gtk_window_get_icon (window));
1379 case PROP_ICON_NAME:
1380 g_value_set_string (value, gtk_window_get_icon_name (window));
1383 g_value_set_object (value, priv->screen);
1385 case PROP_IS_ACTIVE:
1386 g_value_set_boolean (value, priv->is_active);
1388 case PROP_HAS_TOPLEVEL_FOCUS:
1389 g_value_set_boolean (value, priv->has_toplevel_focus);
1391 case PROP_TYPE_HINT:
1392 g_value_set_enum (value, priv->type_hint);
1394 case PROP_SKIP_TASKBAR_HINT:
1395 g_value_set_boolean (value,
1396 gtk_window_get_skip_taskbar_hint (window));
1398 case PROP_SKIP_PAGER_HINT:
1399 g_value_set_boolean (value,
1400 gtk_window_get_skip_pager_hint (window));
1402 case PROP_URGENCY_HINT:
1403 g_value_set_boolean (value,
1404 gtk_window_get_urgency_hint (window));
1406 case PROP_ACCEPT_FOCUS:
1407 g_value_set_boolean (value,
1408 gtk_window_get_accept_focus (window));
1410 case PROP_FOCUS_ON_MAP:
1411 g_value_set_boolean (value,
1412 gtk_window_get_focus_on_map (window));
1414 case PROP_DECORATED:
1415 g_value_set_boolean (value, gtk_window_get_decorated (window));
1417 case PROP_DELETABLE:
1418 g_value_set_boolean (value, gtk_window_get_deletable (window));
1421 g_value_set_enum (value, gtk_window_get_gravity (window));
1423 case PROP_TRANSIENT_FOR:
1424 g_value_set_object (value, gtk_window_get_transient_for (window));
1426 case PROP_ATTACHED_TO:
1427 g_value_set_object (value, gtk_window_get_attached_to (window));
1430 g_value_set_double (value, gtk_window_get_opacity (window));
1432 case PROP_HAS_RESIZE_GRIP:
1433 g_value_set_boolean (value, priv->has_resize_grip);
1435 case PROP_RESIZE_GRIP_VISIBLE:
1436 g_value_set_boolean (value, gtk_window_resize_grip_is_visible (window));
1438 case PROP_APPLICATION:
1439 g_value_set_object (value, gtk_window_get_application (window));
1441 case PROP_MNEMONICS_VISIBLE:
1442 g_value_set_boolean (value, priv->mnemonics_visible);
1444 case PROP_FOCUS_VISIBLE:
1445 g_value_set_boolean (value, priv->focus_visible);
1448 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1454 gtk_window_buildable_interface_init (GtkBuildableIface *iface)
1456 parent_buildable_iface = g_type_interface_peek_parent (iface);
1457 iface->set_buildable_property = gtk_window_buildable_set_buildable_property;
1458 iface->parser_finished = gtk_window_buildable_parser_finished;
1459 iface->custom_tag_start = gtk_window_buildable_custom_tag_start;
1460 iface->custom_finished = gtk_window_buildable_custom_finished;
1464 gtk_window_buildable_set_buildable_property (GtkBuildable *buildable,
1465 GtkBuilder *builder,
1467 const GValue *value)
1469 GtkWindow *window = GTK_WINDOW (buildable);
1470 GtkWindowPrivate *priv = window->priv;
1472 if (strcmp (name, "visible") == 0 && g_value_get_boolean (value))
1473 priv->builder_visible = TRUE;
1475 parent_buildable_iface->set_buildable_property (buildable, builder, name, value);
1479 gtk_window_buildable_parser_finished (GtkBuildable *buildable,
1480 GtkBuilder *builder)
1482 GtkWindow *window = GTK_WINDOW (buildable);
1483 GtkWindowPrivate *priv = window->priv;
1487 if (priv->builder_visible)
1488 gtk_widget_show (GTK_WIDGET (buildable));
1490 accels = g_object_get_qdata (G_OBJECT (buildable), quark_gtk_buildable_accels);
1491 for (l = accels; l; l = l->next)
1493 object = gtk_builder_get_object (builder, l->data);
1496 g_warning ("Unknown accel group %s specified in window %s",
1497 (const gchar*)l->data, gtk_buildable_get_name (buildable));
1500 gtk_window_add_accel_group (GTK_WINDOW (buildable),
1501 GTK_ACCEL_GROUP (object));
1505 g_object_set_qdata (G_OBJECT (buildable), quark_gtk_buildable_accels, NULL);
1507 parent_buildable_iface->parser_finished (buildable, builder);
1513 } GSListSubParserData;
1516 window_start_element (GMarkupParseContext *context,
1517 const gchar *element_name,
1518 const gchar **names,
1519 const gchar **values,
1524 GSListSubParserData *data = (GSListSubParserData*)user_data;
1526 if (strcmp (element_name, "group") == 0)
1528 for (i = 0; names[i]; i++)
1530 if (strcmp (names[i], "name") == 0)
1531 data->items = g_slist_prepend (data->items, g_strdup (values[i]));
1534 else if (strcmp (element_name, "accel-groups") == 0)
1537 g_warning ("Unsupported tag type for GtkWindow: %s\n",
1542 static const GMarkupParser window_parser =
1544 window_start_element
1548 gtk_window_buildable_custom_tag_start (GtkBuildable *buildable,
1549 GtkBuilder *builder,
1551 const gchar *tagname,
1552 GMarkupParser *parser,
1555 GSListSubParserData *parser_data;
1557 if (parent_buildable_iface->custom_tag_start (buildable, builder, child,
1558 tagname, parser, data))
1561 if (strcmp (tagname, "accel-groups") == 0)
1563 parser_data = g_slice_new0 (GSListSubParserData);
1564 parser_data->items = NULL;
1565 parser_data->object = G_OBJECT (buildable);
1567 *parser = window_parser;
1568 *data = parser_data;
1576 gtk_window_buildable_custom_finished (GtkBuildable *buildable,
1577 GtkBuilder *builder,
1579 const gchar *tagname,
1582 GSListSubParserData *data;
1584 parent_buildable_iface->custom_finished (buildable, builder, child,
1585 tagname, user_data);
1587 if (strcmp (tagname, "accel-groups") != 0)
1590 data = (GSListSubParserData*)user_data;
1592 g_object_set_qdata_full (G_OBJECT (buildable), quark_gtk_buildable_accels,
1593 data->items, (GDestroyNotify) g_slist_free);
1595 g_slice_free (GSListSubParserData, data);
1600 * @type: type of window
1602 * Creates a new #GtkWindow, which is a toplevel window that can
1603 * contain other widgets. Nearly always, the type of the window should
1604 * be #GTK_WINDOW_TOPLEVEL. If you're implementing something like a
1605 * popup menu from scratch (which is a bad idea, just use #GtkMenu),
1606 * you might use #GTK_WINDOW_POPUP. #GTK_WINDOW_POPUP is not for
1607 * dialogs, though in some other toolkits dialogs are called "popups".
1608 * In GTK+, #GTK_WINDOW_POPUP means a pop-up menu or pop-up tooltip.
1609 * On X11, popup windows are not controlled by the <link
1610 * linkend="gtk-X11-arch">window manager</link>.
1612 * If you simply want an undecorated window (no window borders), use
1613 * gtk_window_set_decorated(), don't use #GTK_WINDOW_POPUP.
1615 * Return value: a new #GtkWindow.
1618 gtk_window_new (GtkWindowType type)
1620 GtkWindowPrivate *priv;
1623 g_return_val_if_fail (type >= GTK_WINDOW_TOPLEVEL && type <= GTK_WINDOW_POPUP, NULL);
1625 window = g_object_new (GTK_TYPE_WINDOW, NULL);
1626 priv = window->priv;
1630 return GTK_WIDGET (window);
1634 * gtk_window_set_title:
1635 * @window: a #GtkWindow
1636 * @title: title of the window
1638 * Sets the title of the #GtkWindow. The title of a window will be
1639 * displayed in its title bar; on the X Window System, the title bar
1640 * is rendered by the <link linkend="gtk-X11-arch">window
1641 * manager</link>, so exactly how the title appears to users may vary
1642 * according to a user's exact configuration. The title should help a
1643 * user distinguish this window from other windows they may have
1644 * open. A good title might include the application name and current
1645 * document filename, for example.
1649 gtk_window_set_title (GtkWindow *window,
1652 GtkWindowPrivate *priv;
1656 g_return_if_fail (GTK_IS_WINDOW (window));
1658 priv = window->priv;
1659 widget = GTK_WIDGET (window);
1661 new_title = g_strdup (title);
1662 g_free (priv->title);
1663 priv->title = new_title;
1665 if (gtk_widget_get_realized (widget))
1667 gdk_window_set_title (gtk_widget_get_window (widget),
1671 g_object_notify (G_OBJECT (window), "title");
1675 * gtk_window_get_title:
1676 * @window: a #GtkWindow
1678 * Retrieves the title of the window. See gtk_window_set_title().
1680 * Return value: the title of the window, or %NULL if none has
1681 * been set explicitely. The returned string is owned by the widget
1682 * and must not be modified or freed.
1685 gtk_window_get_title (GtkWindow *window)
1687 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
1689 return window->priv->title;
1693 * gtk_window_set_wmclass:
1694 * @window: a #GtkWindow
1695 * @wmclass_name: window name hint
1696 * @wmclass_class: window class hint
1698 * Don't use this function. It sets the X Window System "class" and
1699 * "name" hints for a window. According to the ICCCM, you should
1700 * always set these to the same value for all windows in an
1701 * application, and GTK+ sets them to that value by default, so calling
1702 * this function is sort of pointless. However, you may want to call
1703 * gtk_window_set_role() on each window in your application, for the
1704 * benefit of the session manager. Setting the role allows the window
1705 * manager to restore window positions when loading a saved session.
1709 gtk_window_set_wmclass (GtkWindow *window,
1710 const gchar *wmclass_name,
1711 const gchar *wmclass_class)
1713 GtkWindowPrivate *priv;
1715 g_return_if_fail (GTK_IS_WINDOW (window));
1717 priv = window->priv;
1719 g_free (priv->wmclass_name);
1720 priv->wmclass_name = g_strdup (wmclass_name);
1722 g_free (priv->wmclass_class);
1723 priv->wmclass_class = g_strdup (wmclass_class);
1725 if (gtk_widget_get_realized (GTK_WIDGET (window)))
1726 g_warning ("gtk_window_set_wmclass: shouldn't set wmclass after window is realized!\n");
1730 * gtk_window_set_role:
1731 * @window: a #GtkWindow
1732 * @role: unique identifier for the window to be used when restoring a session
1734 * This function is only useful on X11, not with other GTK+ targets.
1736 * In combination with the window title, the window role allows a
1737 * <link linkend="gtk-X11-arch">window manager</link> to identify "the
1738 * same" window when an application is restarted. So for example you
1739 * might set the "toolbox" role on your app's toolbox window, so that
1740 * when the user restarts their session, the window manager can put
1741 * the toolbox back in the same place.
1743 * If a window already has a unique title, you don't need to set the
1744 * role, since the WM can use the title to identify the window when
1745 * restoring the session.
1749 gtk_window_set_role (GtkWindow *window,
1752 GtkWindowPrivate *priv;
1755 g_return_if_fail (GTK_IS_WINDOW (window));
1757 priv = window->priv;
1759 new_role = g_strdup (role);
1760 g_free (priv->wm_role);
1761 priv->wm_role = new_role;
1763 if (gtk_widget_get_realized (GTK_WIDGET (window)))
1764 gdk_window_set_role (gtk_widget_get_window (GTK_WIDGET (window)),
1767 g_object_notify (G_OBJECT (window), "role");
1771 * gtk_window_set_startup_id:
1772 * @window: a #GtkWindow
1773 * @startup_id: a string with startup-notification identifier
1775 * Startup notification identifiers are used by desktop environment to
1776 * track application startup, to provide user feedback and other
1777 * features. This function changes the corresponding property on the
1778 * underlying GdkWindow. Normally, startup identifier is managed
1779 * automatically and you should only use this function in special cases
1780 * like transferring focus from other processes. You should use this
1781 * function before calling gtk_window_present() or any equivalent
1782 * function generating a window map event.
1784 * This function is only useful on X11, not with other GTK+ targets.
1789 gtk_window_set_startup_id (GtkWindow *window,
1790 const gchar *startup_id)
1792 GtkWindowPrivate *priv;
1795 g_return_if_fail (GTK_IS_WINDOW (window));
1797 priv = window->priv;
1798 widget = GTK_WIDGET (window);
1800 g_free (priv->startup_id);
1801 priv->startup_id = g_strdup (startup_id);
1803 if (gtk_widget_get_realized (widget))
1805 GdkWindow *gdk_window;
1806 guint32 timestamp = extract_time_from_startup_id (priv->startup_id);
1808 gdk_window = gtk_widget_get_window (widget);
1810 #ifdef GDK_WINDOWING_X11
1811 if (timestamp != GDK_CURRENT_TIME && GDK_IS_X11_WINDOW(gdk_window))
1812 gdk_x11_window_set_user_time (gdk_window, timestamp);
1815 /* Here we differentiate real and "fake" startup notification IDs,
1816 * constructed on purpose just to pass interaction timestamp
1818 if (startup_id_is_fake (priv->startup_id))
1819 gtk_window_present_with_time (window, timestamp);
1822 gdk_window_set_startup_id (gdk_window,
1825 /* If window is mapped, terminate the startup-notification too */
1826 if (gtk_widget_get_mapped (widget) &&
1827 !disable_startup_notification)
1828 gdk_notify_startup_complete_with_id (priv->startup_id);
1832 g_object_notify (G_OBJECT (window), "startup-id");
1836 * gtk_window_get_role:
1837 * @window: a #GtkWindow
1839 * Returns the role of the window. See gtk_window_set_role() for
1840 * further explanation.
1842 * Return value: the role of the window if set, or %NULL. The
1843 * returned is owned by the widget and must not be modified
1847 gtk_window_get_role (GtkWindow *window)
1849 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
1851 return window->priv->wm_role;
1855 * gtk_window_set_focus:
1856 * @window: a #GtkWindow
1857 * @focus: (allow-none): widget to be the new focus widget, or %NULL to unset
1858 * any focus widget for the toplevel window.
1860 * If @focus is not the current focus widget, and is focusable, sets
1861 * it as the focus widget for the window. If @focus is %NULL, unsets
1862 * the focus widget for this window. To set the focus to a particular
1863 * widget in the toplevel, it is usually more convenient to use
1864 * gtk_widget_grab_focus() instead of this function.
1867 gtk_window_set_focus (GtkWindow *window,
1870 GtkWindowPrivate *priv;
1873 g_return_if_fail (GTK_IS_WINDOW (window));
1875 priv = window->priv;
1879 g_return_if_fail (GTK_IS_WIDGET (focus));
1880 g_return_if_fail (gtk_widget_get_can_focus (focus));
1884 gtk_widget_grab_focus (focus);
1887 /* Clear the existing focus chain, so that when we focus into
1888 * the window again, we start at the beginnning.
1890 GtkWidget *widget = priv->focus_widget;
1893 while ((parent = gtk_widget_get_parent (widget)))
1896 gtk_container_set_focus_child (GTK_CONTAINER (widget), NULL);
1900 _gtk_window_internal_set_focus (window, NULL);
1905 _gtk_window_internal_set_focus (GtkWindow *window,
1908 GtkWindowPrivate *priv;
1910 g_return_if_fail (GTK_IS_WINDOW (window));
1912 priv = window->priv;
1914 if ((priv->focus_widget != focus) ||
1915 (focus && !gtk_widget_has_focus (focus)))
1916 g_signal_emit (window, window_signals[SET_FOCUS], 0, focus);
1920 * gtk_window_set_default:
1921 * @window: a #GtkWindow
1922 * @default_widget: (allow-none): widget to be the default, or %NULL to unset the
1923 * default widget for the toplevel.
1925 * The default widget is the widget that's activated when the user
1926 * presses Enter in a dialog (for example). This function sets or
1927 * unsets the default widget for a #GtkWindow about. When setting
1928 * (rather than unsetting) the default widget it's generally easier to
1929 * call gtk_widget_grab_focus() on the widget. Before making a widget
1930 * the default widget, you must set the #GTK_CAN_DEFAULT flag on the
1931 * widget you'd like to make the default using GTK_WIDGET_SET_FLAGS().
1934 gtk_window_set_default (GtkWindow *window,
1935 GtkWidget *default_widget)
1937 GtkWindowPrivate *priv;
1939 g_return_if_fail (GTK_IS_WINDOW (window));
1941 priv = window->priv;
1944 g_return_if_fail (gtk_widget_get_can_default (default_widget));
1946 if (priv->default_widget != default_widget)
1948 GtkWidget *old_default_widget = NULL;
1951 g_object_ref (default_widget);
1953 if (priv->default_widget)
1955 old_default_widget = priv->default_widget;
1957 if (priv->focus_widget != priv->default_widget ||
1958 !gtk_widget_get_receives_default (priv->default_widget))
1959 _gtk_widget_set_has_default (priv->default_widget, FALSE);
1961 gtk_widget_queue_draw (priv->default_widget);
1964 priv->default_widget = default_widget;
1966 if (priv->default_widget)
1968 if (priv->focus_widget == NULL ||
1969 !gtk_widget_get_receives_default (priv->focus_widget))
1970 _gtk_widget_set_has_default (priv->default_widget, TRUE);
1972 gtk_widget_queue_draw (priv->default_widget);
1975 if (old_default_widget)
1976 g_object_notify (G_OBJECT (old_default_widget), "has-default");
1980 g_object_notify (G_OBJECT (default_widget), "has-default");
1981 g_object_unref (default_widget);
1987 * gtk_window_get_default_widget:
1988 * @window: a #GtkWindow
1990 * Returns the default widget for @window. See gtk_window_set_default()
1993 * Returns: (transfer none): the default widget, or %NULL if there is none.
1998 gtk_window_get_default_widget (GtkWindow *window)
2000 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
2002 return window->priv->default_widget;
2006 handle_keys_changed (gpointer data)
2008 GtkWindow *window = GTK_WINDOW (data);
2009 GtkWindowPrivate *priv = window->priv;
2011 if (priv->keys_changed_handler)
2013 g_source_remove (priv->keys_changed_handler);
2014 priv->keys_changed_handler = 0;
2017 g_signal_emit (window, window_signals[KEYS_CHANGED], 0);
2023 gtk_window_notify_keys_changed (GtkWindow *window)
2025 GtkWindowPrivate *priv = window->priv;
2027 if (!priv->keys_changed_handler)
2028 priv->keys_changed_handler = gdk_threads_add_idle (handle_keys_changed, window);
2032 * gtk_window_add_accel_group:
2033 * @window: window to attach accelerator group to
2034 * @accel_group: a #GtkAccelGroup
2036 * Associate @accel_group with @window, such that calling
2037 * gtk_accel_groups_activate() on @window will activate accelerators
2041 gtk_window_add_accel_group (GtkWindow *window,
2042 GtkAccelGroup *accel_group)
2044 g_return_if_fail (GTK_IS_WINDOW (window));
2045 g_return_if_fail (GTK_IS_ACCEL_GROUP (accel_group));
2047 _gtk_accel_group_attach (accel_group, G_OBJECT (window));
2048 g_signal_connect_object (accel_group, "accel-changed",
2049 G_CALLBACK (gtk_window_notify_keys_changed),
2050 window, G_CONNECT_SWAPPED);
2051 gtk_window_notify_keys_changed (window);
2055 * gtk_window_remove_accel_group:
2056 * @window: a #GtkWindow
2057 * @accel_group: a #GtkAccelGroup
2059 * Reverses the effects of gtk_window_add_accel_group().
2062 gtk_window_remove_accel_group (GtkWindow *window,
2063 GtkAccelGroup *accel_group)
2065 g_return_if_fail (GTK_IS_WINDOW (window));
2066 g_return_if_fail (GTK_IS_ACCEL_GROUP (accel_group));
2068 g_signal_handlers_disconnect_by_func (accel_group,
2069 gtk_window_notify_keys_changed,
2071 _gtk_accel_group_detach (accel_group, G_OBJECT (window));
2072 gtk_window_notify_keys_changed (window);
2075 static GtkMnemonicHash *
2076 gtk_window_get_mnemonic_hash (GtkWindow *window,
2079 GtkWindowPrivate *private = window->priv;
2081 if (!private->mnemonic_hash && create)
2082 private->mnemonic_hash = _gtk_mnemonic_hash_new ();
2084 return private->mnemonic_hash;
2088 * gtk_window_add_mnemonic:
2089 * @window: a #GtkWindow
2090 * @keyval: the mnemonic
2091 * @target: the widget that gets activated by the mnemonic
2093 * Adds a mnemonic to this window.
2096 gtk_window_add_mnemonic (GtkWindow *window,
2100 g_return_if_fail (GTK_IS_WINDOW (window));
2101 g_return_if_fail (GTK_IS_WIDGET (target));
2103 _gtk_mnemonic_hash_add (gtk_window_get_mnemonic_hash (window, TRUE),
2105 gtk_window_notify_keys_changed (window);
2109 * gtk_window_remove_mnemonic:
2110 * @window: a #GtkWindow
2111 * @keyval: the mnemonic
2112 * @target: the widget that gets activated by the mnemonic
2114 * Removes a mnemonic from this window.
2117 gtk_window_remove_mnemonic (GtkWindow *window,
2121 g_return_if_fail (GTK_IS_WINDOW (window));
2122 g_return_if_fail (GTK_IS_WIDGET (target));
2124 _gtk_mnemonic_hash_remove (gtk_window_get_mnemonic_hash (window, TRUE),
2126 gtk_window_notify_keys_changed (window);
2130 * gtk_window_mnemonic_activate:
2131 * @window: a #GtkWindow
2132 * @keyval: the mnemonic
2133 * @modifier: the modifiers
2135 * Activates the targets associated with the mnemonic.
2137 * Returns: %TRUE if the activation is done.
2140 gtk_window_mnemonic_activate (GtkWindow *window,
2142 GdkModifierType modifier)
2144 GtkWindowPrivate *priv;
2146 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
2148 priv = window->priv;
2150 if (priv->mnemonic_modifier == (modifier & gtk_accelerator_get_default_mod_mask ()))
2152 GtkMnemonicHash *mnemonic_hash = gtk_window_get_mnemonic_hash (window, FALSE);
2154 return _gtk_mnemonic_hash_activate (mnemonic_hash, keyval);
2161 * gtk_window_set_mnemonic_modifier:
2162 * @window: a #GtkWindow
2163 * @modifier: the modifier mask used to activate
2164 * mnemonics on this window.
2166 * Sets the mnemonic modifier for this window.
2169 gtk_window_set_mnemonic_modifier (GtkWindow *window,
2170 GdkModifierType modifier)
2172 GtkWindowPrivate *priv;
2174 g_return_if_fail (GTK_IS_WINDOW (window));
2175 g_return_if_fail ((modifier & ~GDK_MODIFIER_MASK) == 0);
2177 priv = window->priv;
2179 priv->mnemonic_modifier = modifier;
2180 gtk_window_notify_keys_changed (window);
2184 * gtk_window_get_mnemonic_modifier:
2185 * @window: a #GtkWindow
2187 * Returns the mnemonic modifier for this window. See
2188 * gtk_window_set_mnemonic_modifier().
2190 * Return value: the modifier mask used to activate
2191 * mnemonics on this window.
2194 gtk_window_get_mnemonic_modifier (GtkWindow *window)
2196 g_return_val_if_fail (GTK_IS_WINDOW (window), 0);
2198 return window->priv->mnemonic_modifier;
2202 * gtk_window_set_position:
2203 * @window: a #GtkWindow.
2204 * @position: a position constraint.
2206 * Sets a position constraint for this window. If the old or new
2207 * constraint is %GTK_WIN_POS_CENTER_ALWAYS, this will also cause
2208 * the window to be repositioned to satisfy the new constraint.
2211 gtk_window_set_position (GtkWindow *window,
2212 GtkWindowPosition position)
2214 GtkWindowPrivate *priv;
2216 g_return_if_fail (GTK_IS_WINDOW (window));
2218 priv = window->priv;
2220 if (position == GTK_WIN_POS_CENTER_ALWAYS ||
2221 priv->position == GTK_WIN_POS_CENTER_ALWAYS)
2223 GtkWindowGeometryInfo *info;
2225 info = gtk_window_get_geometry_info (window, TRUE);
2227 /* this flag causes us to re-request the CENTER_ALWAYS
2228 * constraint in gtk_window_move_resize(), see
2229 * comment in that function.
2231 info->position_constraints_changed = TRUE;
2233 gtk_widget_queue_resize_no_redraw (GTK_WIDGET (window));
2236 priv->position = position;
2238 g_object_notify (G_OBJECT (window), "window-position");
2242 * gtk_window_activate_focus:
2243 * @window: a #GtkWindow
2245 * Activates the current focused widget within the window.
2247 * Return value: %TRUE if a widget got activated.
2250 gtk_window_activate_focus (GtkWindow *window)
2252 GtkWindowPrivate *priv;
2254 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
2256 priv = window->priv;
2258 if (priv->focus_widget && gtk_widget_is_sensitive (priv->focus_widget))
2259 return gtk_widget_activate (priv->focus_widget);
2265 * gtk_window_get_focus:
2266 * @window: a #GtkWindow
2268 * Retrieves the current focused widget within the window.
2269 * Note that this is the widget that would have the focus
2270 * if the toplevel window focused; if the toplevel window
2271 * is not focused then <literal>gtk_widget_has_focus (widget)</literal> will
2272 * not be %TRUE for the widget.
2274 * Return value: (transfer none): the currently focused widget, or %NULL if there is none.
2277 gtk_window_get_focus (GtkWindow *window)
2279 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
2281 return window->priv->focus_widget;
2285 * gtk_window_activate_default:
2286 * @window: a #GtkWindow
2288 * Activates the default widget for the window, unless the current
2289 * focused widget has been configured to receive the default action
2290 * (see gtk_widget_set_receives_default()), in which case the
2291 * focused widget is activated.
2293 * Return value: %TRUE if a widget got activated.
2296 gtk_window_activate_default (GtkWindow *window)
2298 GtkWindowPrivate *priv;
2300 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
2302 priv = window->priv;
2304 if (priv->default_widget && gtk_widget_is_sensitive (priv->default_widget) &&
2305 (!priv->focus_widget || !gtk_widget_get_receives_default (priv->focus_widget)))
2306 return gtk_widget_activate (priv->default_widget);
2307 else if (priv->focus_widget && gtk_widget_is_sensitive (priv->focus_widget))
2308 return gtk_widget_activate (priv->focus_widget);
2314 * gtk_window_set_modal:
2315 * @window: a #GtkWindow
2316 * @modal: whether the window is modal
2318 * Sets a window modal or non-modal. Modal windows prevent interaction
2319 * with other windows in the same application. To keep modal dialogs
2320 * on top of main application windows, use
2321 * gtk_window_set_transient_for() to make the dialog transient for the
2322 * parent; most <link linkend="gtk-X11-arch">window managers</link>
2323 * will then disallow lowering the dialog below the parent.
2328 gtk_window_set_modal (GtkWindow *window,
2331 GtkWindowPrivate *priv;
2334 g_return_if_fail (GTK_IS_WINDOW (window));
2336 priv = window->priv;
2338 modal = modal != FALSE;
2339 if (priv->modal == modal)
2342 priv->modal = modal;
2343 widget = GTK_WIDGET (window);
2345 /* adjust desired modality state */
2346 if (gtk_widget_get_realized (widget))
2349 gdk_window_set_modal_hint (gtk_widget_get_window (widget), TRUE);
2351 gdk_window_set_modal_hint (gtk_widget_get_window (widget), FALSE);
2354 if (gtk_widget_get_visible (widget))
2357 gtk_grab_add (widget);
2359 gtk_grab_remove (widget);
2362 g_object_notify (G_OBJECT (window), "modal");
2366 * gtk_window_get_modal:
2367 * @window: a #GtkWindow
2369 * Returns whether the window is modal. See gtk_window_set_modal().
2371 * Return value: %TRUE if the window is set to be modal and
2372 * establishes a grab when shown
2375 gtk_window_get_modal (GtkWindow *window)
2377 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
2379 return window->priv->modal;
2383 * gtk_window_list_toplevels:
2385 * Returns a list of all existing toplevel windows. The widgets
2386 * in the list are not individually referenced. If you want
2387 * to iterate through the list and perform actions involving
2388 * callbacks that might destroy the widgets, you <emphasis>must</emphasis> call
2389 * <literal>g_list_foreach (result, (GFunc)g_object_ref, NULL)</literal> first, and
2390 * then unref all the widgets afterwards.
2392 * Return value: (element-type GtkWidget) (transfer container): list of toplevel widgets
2395 gtk_window_list_toplevels (void)
2400 for (slist = toplevel_list; slist; slist = slist->next)
2401 list = g_list_prepend (list, slist->data);
2407 remove_attach_widget (GtkWindow *window)
2409 GtkWindowPrivate *priv = window->priv;
2411 if (priv->attach_widget)
2413 _gtk_widget_remove_attached_window (priv->attach_widget, window);
2415 g_object_unref (priv->attach_widget);
2416 priv->attach_widget = NULL;
2421 gtk_window_dispose (GObject *object)
2423 GtkWindow *window = GTK_WINDOW (object);
2425 gtk_window_set_focus (window, NULL);
2426 gtk_window_set_default (window, NULL);
2428 remove_attach_widget (GTK_WINDOW (object));
2430 G_OBJECT_CLASS (gtk_window_parent_class)->dispose (object);
2434 parent_destroyed_callback (GtkWindow *parent, GtkWindow *child)
2436 gtk_widget_destroy (GTK_WIDGET (child));
2440 connect_parent_destroyed (GtkWindow *window)
2442 GtkWindowPrivate *priv = window->priv;
2444 if (priv->transient_parent)
2446 g_signal_connect (priv->transient_parent,
2448 G_CALLBACK (parent_destroyed_callback),
2454 disconnect_parent_destroyed (GtkWindow *window)
2456 GtkWindowPrivate *priv = window->priv;
2458 if (priv->transient_parent)
2460 g_signal_handlers_disconnect_by_func (priv->transient_parent,
2461 parent_destroyed_callback,
2467 gtk_window_transient_parent_realized (GtkWidget *parent,
2470 if (gtk_widget_get_realized (window))
2471 gdk_window_set_transient_for (gtk_widget_get_window (window),
2472 gtk_widget_get_window (parent));
2476 gtk_window_transient_parent_unrealized (GtkWidget *parent,
2479 if (gtk_widget_get_realized (window))
2480 gdk_property_delete (gtk_widget_get_window (window),
2481 gdk_atom_intern_static_string ("WM_TRANSIENT_FOR"));
2485 gtk_window_transient_parent_screen_changed (GtkWindow *parent,
2489 gtk_window_set_screen (window, parent->priv->screen);
2493 gtk_window_unset_transient_for (GtkWindow *window)
2495 GtkWindowPrivate *priv = window->priv;
2497 if (priv->transient_parent)
2499 g_signal_handlers_disconnect_by_func (priv->transient_parent,
2500 gtk_window_transient_parent_realized,
2502 g_signal_handlers_disconnect_by_func (priv->transient_parent,
2503 gtk_window_transient_parent_unrealized,
2505 g_signal_handlers_disconnect_by_func (priv->transient_parent,
2506 gtk_window_transient_parent_screen_changed,
2508 g_signal_handlers_disconnect_by_func (priv->transient_parent,
2509 gtk_widget_destroyed,
2510 &priv->transient_parent);
2512 if (priv->destroy_with_parent)
2513 disconnect_parent_destroyed (window);
2515 priv->transient_parent = NULL;
2517 if (priv->transient_parent_group)
2519 priv->transient_parent_group = FALSE;
2520 gtk_window_group_remove_window (priv->group,
2527 * gtk_window_set_transient_for:
2528 * @window: a #GtkWindow
2529 * @parent: (allow-none): parent window, or %NULL
2531 * Dialog windows should be set transient for the main application
2532 * window they were spawned from. This allows <link
2533 * linkend="gtk-X11-arch">window managers</link> to e.g. keep the
2534 * dialog on top of the main window, or center the dialog over the
2535 * main window. gtk_dialog_new_with_buttons() and other convenience
2536 * functions in GTK+ will sometimes call
2537 * gtk_window_set_transient_for() on your behalf.
2539 * Passing %NULL for @parent unsets the current transient window.
2541 * On Windows, this function puts the child window on top of the parent,
2542 * much as the window manager would have done on X.
2545 gtk_window_set_transient_for (GtkWindow *window,
2548 GtkWindowPrivate *priv;
2550 g_return_if_fail (GTK_IS_WINDOW (window));
2551 g_return_if_fail (parent == NULL || GTK_IS_WINDOW (parent));
2552 g_return_if_fail (window != parent);
2554 priv = window->priv;
2556 if (priv->transient_parent)
2558 if (gtk_widget_get_realized (GTK_WIDGET (window)) &&
2559 gtk_widget_get_realized (GTK_WIDGET (priv->transient_parent)) &&
2560 (!parent || !gtk_widget_get_realized (GTK_WIDGET (parent))))
2561 gtk_window_transient_parent_unrealized (GTK_WIDGET (priv->transient_parent),
2562 GTK_WIDGET (window));
2564 gtk_window_unset_transient_for (window);
2567 priv->transient_parent = parent;
2571 g_signal_connect (parent, "destroy",
2572 G_CALLBACK (gtk_widget_destroyed),
2573 &priv->transient_parent);
2574 g_signal_connect (parent, "realize",
2575 G_CALLBACK (gtk_window_transient_parent_realized),
2577 g_signal_connect (parent, "unrealize",
2578 G_CALLBACK (gtk_window_transient_parent_unrealized),
2580 g_signal_connect (parent, "notify::screen",
2581 G_CALLBACK (gtk_window_transient_parent_screen_changed),
2584 gtk_window_set_screen (window, parent->priv->screen);
2586 if (priv->destroy_with_parent)
2587 connect_parent_destroyed (window);
2589 if (gtk_widget_get_realized (GTK_WIDGET (window)) &&
2590 gtk_widget_get_realized (GTK_WIDGET (parent)))
2591 gtk_window_transient_parent_realized (GTK_WIDGET (parent),
2592 GTK_WIDGET (window));
2594 if (parent->priv->group)
2596 gtk_window_group_add_window (parent->priv->group, window);
2597 priv->transient_parent_group = TRUE;
2603 * gtk_window_get_transient_for:
2604 * @window: a #GtkWindow
2606 * Fetches the transient parent for this window. See
2607 * gtk_window_set_transient_for().
2609 * Return value: (transfer none): the transient parent for this window, or %NULL
2610 * if no transient parent has been set.
2613 gtk_window_get_transient_for (GtkWindow *window)
2615 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
2617 return window->priv->transient_parent;
2621 * gtk_window_set_attached_to:
2622 * @window: a #GtkWindow
2623 * @attach_widget: (allow-none): a #GtkWidget, or %NULL
2625 * Marks @window as attached to @attach_widget. This creates a logical binding
2626 * between the window and the widget it belongs to, which is used by GTK+ to
2627 * propagate information such as styling or accessibility to @window as if it
2628 * was a children of @attach_widget.
2630 * Examples of places where specifying this relation is useful are for instance
2631 * a #GtkMenu created by a #GtkComboBox, a completion popup window
2632 * created by #GtkEntry or a typeahead search entry created by #GtkTreeView.
2634 * Note that this function should not be confused with
2635 * gtk_window_set_transient_for(), which specifies a window manager relation
2636 * between two toplevels instead.
2638 * Passing %NULL for @attach_widget detaches the window.
2643 gtk_window_set_attached_to (GtkWindow *window,
2644 GtkWidget *attach_widget)
2646 GtkStyleContext *context;
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 if (priv->attach_widget == attach_widget)
2657 remove_attach_widget (window);
2659 priv->attach_widget = attach_widget;
2661 if (priv->attach_widget)
2663 _gtk_widget_add_attached_window (priv->attach_widget, window);
2665 g_object_ref (priv->attach_widget);
2668 /* Update the style, as the widget path might change. */
2669 context = gtk_widget_get_style_context (GTK_WIDGET (window));
2670 if (priv->attach_widget)
2671 gtk_style_context_set_parent (context, gtk_widget_get_style_context (priv->attach_widget));
2673 gtk_style_context_set_parent (context, NULL);
2677 * gtk_window_get_attached_to:
2678 * @window: a #GtkWindow
2680 * Fetches the attach widget for this window. See
2681 * gtk_window_set_attached_to().
2683 * Return value: (transfer none): the widget where the window is attached,
2684 * or %NULL if the window is not attached to any widget.
2689 gtk_window_get_attached_to (GtkWindow *window)
2691 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
2693 return window->priv->attach_widget;
2697 * gtk_window_set_opacity:
2698 * @window: a #GtkWindow
2699 * @opacity: desired opacity, between 0 and 1
2701 * Request the windowing system to make @window partially transparent,
2702 * with opacity 0 being fully transparent and 1 fully opaque. (Values
2703 * of the opacity parameter are clamped to the [0,1] range.) On X11
2704 * this has any effect only on X screens with a compositing manager
2705 * running. See gtk_widget_is_composited(). On Windows it should work
2708 * Note that setting a window's opacity after the window has been
2709 * shown causes it to flicker once on Windows.
2714 gtk_window_set_opacity (GtkWindow *window,
2717 GtkWindowPrivate *priv;
2719 g_return_if_fail (GTK_IS_WINDOW (window));
2721 priv = window->priv;
2725 else if (opacity > 1.0)
2728 priv->opacity_set = TRUE;
2729 priv->opacity = opacity;
2731 if (gtk_widget_get_realized (GTK_WIDGET (window)))
2732 gdk_window_set_opacity (gtk_widget_get_window (GTK_WIDGET (window)),
2737 * gtk_window_get_opacity:
2738 * @window: a #GtkWindow
2740 * Fetches the requested opacity for this window. See
2741 * gtk_window_set_opacity().
2743 * Return value: the requested opacity for this window.
2748 gtk_window_get_opacity (GtkWindow *window)
2750 g_return_val_if_fail (GTK_IS_WINDOW (window), 0.0);
2752 return window->priv->opacity;
2756 * gtk_window_get_application:
2757 * @window: a #GtkWindow
2759 * Gets the #GtkApplication associated with the window (if any).
2761 * Return value: (transfer none): a #GtkApplication, or %NULL
2766 gtk_window_get_application (GtkWindow *window)
2768 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
2770 return window->priv->application;
2774 gtk_window_release_application (GtkWindow *window)
2776 if (window->priv->application)
2778 GtkApplication *application;
2780 /* steal reference into temp variable */
2781 application = window->priv->application;
2782 window->priv->application = NULL;
2784 gtk_application_remove_window (application, window);
2785 g_object_unref (application);
2790 * gtk_window_set_application:
2791 * @window: a #GtkWindow
2792 * @application: (allow-none): a #GtkApplication, or %NULL
2794 * Sets or unsets the #GtkApplication associated with the window.
2796 * The application will be kept alive for at least as long as the window
2802 gtk_window_set_application (GtkWindow *window,
2803 GtkApplication *application)
2805 GtkWindowPrivate *priv;
2807 g_return_if_fail (GTK_IS_WINDOW (window));
2809 priv = window->priv;
2810 if (priv->application != application)
2812 gtk_window_release_application (window);
2814 priv->application = application;
2816 if (priv->application != NULL)
2818 g_object_ref (priv->application);
2820 gtk_application_add_window (priv->application, window);
2823 g_object_notify (G_OBJECT (window), "application");
2828 * gtk_window_set_type_hint:
2829 * @window: a #GtkWindow
2830 * @hint: the window type
2832 * By setting the type hint for the window, you allow the window
2833 * manager to decorate and handle the window in a way which is
2834 * suitable to the function of the window in your application.
2836 * This function should be called before the window becomes visible.
2838 * gtk_dialog_new_with_buttons() and other convenience functions in GTK+
2839 * will sometimes call gtk_window_set_type_hint() on your behalf.
2843 gtk_window_set_type_hint (GtkWindow *window,
2844 GdkWindowTypeHint hint)
2846 GtkWindowPrivate *priv;
2848 g_return_if_fail (GTK_IS_WINDOW (window));
2849 g_return_if_fail (!gtk_widget_get_mapped (GTK_WIDGET (window)));
2851 priv = window->priv;
2853 if (hint < GDK_WINDOW_TYPE_HINT_DROPDOWN_MENU)
2854 priv->type_hint = hint;
2856 priv->type_hint = GDK_WINDOW_TYPE_HINT_NORMAL;
2858 priv->reset_type_hint = TRUE;
2859 priv->gdk_type_hint = hint;
2863 * gtk_window_get_type_hint:
2864 * @window: a #GtkWindow
2866 * Gets the type hint for this window. See gtk_window_set_type_hint().
2868 * Return value: the type hint for @window.
2871 gtk_window_get_type_hint (GtkWindow *window)
2873 g_return_val_if_fail (GTK_IS_WINDOW (window), GDK_WINDOW_TYPE_HINT_NORMAL);
2875 return window->priv->gdk_type_hint;
2879 * gtk_window_set_skip_taskbar_hint:
2880 * @window: a #GtkWindow
2881 * @setting: %TRUE to keep this window from appearing in the task bar
2883 * Windows may set a hint asking the desktop environment not to display
2884 * the window in the task bar. This function sets this hint.
2889 gtk_window_set_skip_taskbar_hint (GtkWindow *window,
2892 GtkWindowPrivate *priv;
2894 g_return_if_fail (GTK_IS_WINDOW (window));
2896 priv = window->priv;
2898 setting = setting != FALSE;
2900 if (priv->skips_taskbar != setting)
2902 priv->skips_taskbar = setting;
2903 if (gtk_widget_get_realized (GTK_WIDGET (window)))
2904 gdk_window_set_skip_taskbar_hint (gtk_widget_get_window (GTK_WIDGET (window)),
2905 priv->skips_taskbar);
2906 g_object_notify (G_OBJECT (window), "skip-taskbar-hint");
2911 * gtk_window_get_skip_taskbar_hint:
2912 * @window: a #GtkWindow
2914 * Gets the value set by gtk_window_set_skip_taskbar_hint()
2916 * Return value: %TRUE if window shouldn't be in taskbar
2921 gtk_window_get_skip_taskbar_hint (GtkWindow *window)
2923 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
2925 return window->priv->skips_taskbar;
2929 * gtk_window_set_skip_pager_hint:
2930 * @window: a #GtkWindow
2931 * @setting: %TRUE to keep this window from appearing in the pager
2933 * Windows may set a hint asking the desktop environment not to display
2934 * the window in the pager. This function sets this hint.
2935 * (A "pager" is any desktop navigation tool such as a workspace
2936 * switcher that displays a thumbnail representation of the windows
2942 gtk_window_set_skip_pager_hint (GtkWindow *window,
2945 GtkWindowPrivate *priv;
2947 g_return_if_fail (GTK_IS_WINDOW (window));
2949 priv = window->priv;
2951 setting = setting != FALSE;
2953 if (priv->skips_pager != setting)
2955 priv->skips_pager = setting;
2956 if (gtk_widget_get_realized (GTK_WIDGET (window)))
2957 gdk_window_set_skip_pager_hint (gtk_widget_get_window (GTK_WIDGET (window)),
2959 g_object_notify (G_OBJECT (window), "skip-pager-hint");
2964 * gtk_window_get_skip_pager_hint:
2965 * @window: a #GtkWindow
2967 * Gets the value set by gtk_window_set_skip_pager_hint().
2969 * Return value: %TRUE if window shouldn't be in pager
2974 gtk_window_get_skip_pager_hint (GtkWindow *window)
2976 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
2978 return window->priv->skips_pager;
2982 * gtk_window_set_urgency_hint:
2983 * @window: a #GtkWindow
2984 * @setting: %TRUE to mark this window as urgent
2986 * Windows may set a hint asking the desktop environment to draw
2987 * the users attention to the window. This function sets this hint.
2992 gtk_window_set_urgency_hint (GtkWindow *window,
2995 GtkWindowPrivate *priv;
2997 g_return_if_fail (GTK_IS_WINDOW (window));
2999 priv = window->priv;
3001 setting = setting != FALSE;
3003 if (priv->urgent != setting)
3005 priv->urgent = setting;
3006 if (gtk_widget_get_realized (GTK_WIDGET (window)))
3007 gdk_window_set_urgency_hint (gtk_widget_get_window (GTK_WIDGET (window)),
3009 g_object_notify (G_OBJECT (window), "urgency-hint");
3014 * gtk_window_get_urgency_hint:
3015 * @window: a #GtkWindow
3017 * Gets the value set by gtk_window_set_urgency_hint()
3019 * Return value: %TRUE if window is urgent
3024 gtk_window_get_urgency_hint (GtkWindow *window)
3026 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
3028 return window->priv->urgent;
3032 * gtk_window_set_accept_focus:
3033 * @window: a #GtkWindow
3034 * @setting: %TRUE to let this window receive input focus
3036 * Windows may set a hint asking the desktop environment not to receive
3037 * the input focus. This function sets this hint.
3042 gtk_window_set_accept_focus (GtkWindow *window,
3045 GtkWindowPrivate *priv;
3047 g_return_if_fail (GTK_IS_WINDOW (window));
3049 priv = window->priv;
3051 setting = setting != FALSE;
3053 if (priv->accept_focus != setting)
3055 priv->accept_focus = setting;
3056 if (gtk_widget_get_realized (GTK_WIDGET (window)))
3057 gdk_window_set_accept_focus (gtk_widget_get_window (GTK_WIDGET (window)),
3058 priv->accept_focus);
3059 g_object_notify (G_OBJECT (window), "accept-focus");
3064 * gtk_window_get_accept_focus:
3065 * @window: a #GtkWindow
3067 * Gets the value set by gtk_window_set_accept_focus().
3069 * Return value: %TRUE if window should receive the input focus
3074 gtk_window_get_accept_focus (GtkWindow *window)
3076 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
3078 return window->priv->accept_focus;
3082 * gtk_window_set_focus_on_map:
3083 * @window: a #GtkWindow
3084 * @setting: %TRUE to let this window receive input focus on map
3086 * Windows may set a hint asking the desktop environment not to receive
3087 * the input focus when the window is mapped. This function sets this
3093 gtk_window_set_focus_on_map (GtkWindow *window,
3096 GtkWindowPrivate *priv;
3098 g_return_if_fail (GTK_IS_WINDOW (window));
3100 priv = window->priv;
3102 setting = setting != FALSE;
3104 if (priv->focus_on_map != setting)
3106 priv->focus_on_map = setting;
3107 if (gtk_widget_get_realized (GTK_WIDGET (window)))
3108 gdk_window_set_focus_on_map (gtk_widget_get_window (GTK_WIDGET (window)),
3109 priv->focus_on_map);
3110 g_object_notify (G_OBJECT (window), "focus-on-map");
3115 * gtk_window_get_focus_on_map:
3116 * @window: a #GtkWindow
3118 * Gets the value set by gtk_window_set_focus_on_map().
3120 * Return value: %TRUE if window should receive the input focus when
3126 gtk_window_get_focus_on_map (GtkWindow *window)
3128 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
3130 return window->priv->focus_on_map;
3134 * gtk_window_set_destroy_with_parent:
3135 * @window: a #GtkWindow
3136 * @setting: whether to destroy @window with its transient parent
3138 * If @setting is %TRUE, then destroying the transient parent of @window
3139 * will also destroy @window itself. This is useful for dialogs that
3140 * shouldn't persist beyond the lifetime of the main window they're
3141 * associated with, for example.
3144 gtk_window_set_destroy_with_parent (GtkWindow *window,
3147 GtkWindowPrivate *priv;
3149 g_return_if_fail (GTK_IS_WINDOW (window));
3151 priv = window->priv;
3153 if (priv->destroy_with_parent == (setting != FALSE))
3156 if (priv->destroy_with_parent)
3158 disconnect_parent_destroyed (window);
3162 connect_parent_destroyed (window);
3165 priv->destroy_with_parent = setting;
3167 g_object_notify (G_OBJECT (window), "destroy-with-parent");
3171 * gtk_window_get_destroy_with_parent:
3172 * @window: a #GtkWindow
3174 * Returns whether the window will be destroyed with its transient parent. See
3175 * gtk_window_set_destroy_with_parent ().
3177 * Return value: %TRUE if the window will be destroyed with its transient parent.
3180 gtk_window_get_destroy_with_parent (GtkWindow *window)
3182 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
3184 return window->priv->destroy_with_parent;
3188 * gtk_window_set_hide_titlebar_when_maximized:
3189 * @window: a #GtkWindow
3190 * @setting: whether to hide the titlebar when @window is maximized
3192 * If @setting is %TRUE, then @window will request that it's titlebar
3193 * should be hidden when maximized.
3194 * This is useful for windows that don't convey any information other
3195 * than the application name in the titlebar, to put the available
3196 * screen space to better use. If the underlying window system does not
3197 * support the request, the setting will not have any effect.
3202 gtk_window_set_hide_titlebar_when_maximized (GtkWindow *window,
3205 g_return_if_fail (GTK_IS_WINDOW (window));
3207 #ifdef GDK_WINDOWING_X11
3209 GdkWindow *gdk_window;
3211 gdk_window = gtk_widget_get_window (GTK_WIDGET (window));
3213 if (GDK_IS_X11_WINDOW (gdk_window))
3214 gdk_x11_window_set_hide_titlebar_when_maximized (gdk_window, setting);
3218 window->priv->hide_titlebar_when_maximized = setting;
3219 g_object_notify (G_OBJECT (window), "hide-titlebar-when-maximized");
3223 * gtk_window_get_hide_titlebar_when_maximized:
3224 * @window: a #GtkWindow
3226 * Returns whether the window has requested to have its titlebar hidden
3227 * when maximized. See gtk_window_set_hide_titlebar_when_maximized ().
3229 * Return value: %TRUE if the window has requested to have its titlebar
3230 * hidden when maximized
3235 gtk_window_get_hide_titlebar_when_maximized (GtkWindow *window)
3237 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
3239 return window->priv->hide_titlebar_when_maximized;
3242 static GtkWindowGeometryInfo*
3243 gtk_window_get_geometry_info (GtkWindow *window,
3246 GtkWindowPrivate *priv = window->priv;
3247 GtkWindowGeometryInfo *info;
3249 info = priv->geometry_info;
3250 if (!info && create)
3252 info = g_new0 (GtkWindowGeometryInfo, 1);
3254 info->default_width = -1;
3255 info->default_height = -1;
3256 info->resize_width = -1;
3257 info->resize_height = -1;
3258 info->initial_x = 0;
3259 info->initial_y = 0;
3260 info->initial_pos_set = FALSE;
3261 info->default_is_geometry = FALSE;
3262 info->position_constraints_changed = FALSE;
3263 info->last.configure_request.x = 0;
3264 info->last.configure_request.y = 0;
3265 info->last.configure_request.width = -1;
3266 info->last.configure_request.height = -1;
3267 info->widget = NULL;
3269 priv->geometry_info = info;
3276 * gtk_window_set_geometry_hints:
3277 * @window: a #GtkWindow
3278 * @geometry_widget: (allow-none): widget the geometry hints will be applied to or %NULL
3279 * @geometry: (allow-none): struct containing geometry information or %NULL
3280 * @geom_mask: mask indicating which struct fields should be paid attention to
3282 * This function sets up hints about how a window can be resized by
3283 * the user. You can set a minimum and maximum size; allowed resize
3284 * increments (e.g. for xterm, you can only resize by the size of a
3285 * character); aspect ratios; and more. See the #GdkGeometry struct.
3289 gtk_window_set_geometry_hints (GtkWindow *window,
3290 GtkWidget *geometry_widget,
3291 GdkGeometry *geometry,
3292 GdkWindowHints geom_mask)
3294 GtkWindowGeometryInfo *info;
3296 g_return_if_fail (GTK_IS_WINDOW (window));
3297 g_return_if_fail (geometry_widget == NULL || GTK_IS_WIDGET (geometry_widget));
3299 info = gtk_window_get_geometry_info (window, TRUE);
3302 g_signal_handlers_disconnect_by_func (info->widget,
3303 gtk_widget_destroyed,
3306 info->widget = geometry_widget;
3308 g_signal_connect (geometry_widget, "destroy",
3309 G_CALLBACK (gtk_widget_destroyed),
3313 info->geometry = *geometry;
3315 /* We store gravity in priv->gravity not in the hints. */
3316 info->mask = geom_mask & ~(GDK_HINT_WIN_GRAVITY);
3318 if (geom_mask & GDK_HINT_WIN_GRAVITY)
3320 gtk_window_set_gravity (window, geometry->win_gravity);
3323 gtk_widget_queue_resize_no_redraw (GTK_WIDGET (window));
3327 * gtk_window_set_decorated:
3328 * @window: a #GtkWindow
3329 * @setting: %TRUE to decorate the window
3331 * By default, windows are decorated with a title bar, resize
3332 * controls, etc. Some <link linkend="gtk-X11-arch">window
3333 * managers</link> allow GTK+ to disable these decorations, creating a
3334 * borderless window. If you set the decorated property to %FALSE
3335 * using this function, GTK+ will do its best to convince the window
3336 * manager not to decorate the window. Depending on the system, this
3337 * function may not have any effect when called on a window that is
3338 * already visible, so you should call it before calling gtk_widget_show().
3340 * On Windows, this function always works, since there's no window manager
3345 gtk_window_set_decorated (GtkWindow *window,
3348 GtkWindowPrivate *priv;
3349 GdkWindow *gdk_window;
3351 g_return_if_fail (GTK_IS_WINDOW (window));
3353 priv = window->priv;
3355 setting = setting != FALSE;
3357 if (setting == priv->decorated)
3360 priv->decorated = setting;
3362 gdk_window = gtk_widget_get_window (GTK_WIDGET (window));
3365 if (priv->decorated)
3366 gdk_window_set_decorations (gdk_window,
3369 gdk_window_set_decorations (gdk_window,
3373 g_object_notify (G_OBJECT (window), "decorated");
3377 * gtk_window_get_decorated:
3378 * @window: a #GtkWindow
3380 * Returns whether the window has been set to have decorations
3381 * such as a title bar via gtk_window_set_decorated().
3383 * Return value: %TRUE if the window has been set to have decorations
3386 gtk_window_get_decorated (GtkWindow *window)
3388 g_return_val_if_fail (GTK_IS_WINDOW (window), TRUE);
3390 return window->priv->decorated;
3394 * gtk_window_set_deletable:
3395 * @window: a #GtkWindow
3396 * @setting: %TRUE to decorate the window as deletable
3398 * By default, windows have a close button in the window frame. Some
3399 * <link linkend="gtk-X11-arch">window managers</link> allow GTK+ to
3400 * disable this button. If you set the deletable property to %FALSE
3401 * using this function, GTK+ will do its best to convince the window
3402 * manager not to show a close button. Depending on the system, this
3403 * function may not have any effect when called on a window that is
3404 * already visible, so you should call it before calling gtk_window_show().
3406 * On Windows, this function always works, since there's no window manager
3412 gtk_window_set_deletable (GtkWindow *window,
3415 GtkWindowPrivate *priv;
3416 GdkWindow *gdk_window;
3418 g_return_if_fail (GTK_IS_WINDOW (window));
3420 priv = window->priv;
3422 setting = setting != FALSE;
3424 if (setting == priv->deletable)
3427 priv->deletable = setting;
3429 gdk_window = gtk_widget_get_window (GTK_WIDGET (window));
3432 if (priv->deletable)
3433 gdk_window_set_functions (gdk_window,
3436 gdk_window_set_functions (gdk_window,
3437 GDK_FUNC_ALL | GDK_FUNC_CLOSE);
3440 g_object_notify (G_OBJECT (window), "deletable");
3444 * gtk_window_get_deletable:
3445 * @window: a #GtkWindow
3447 * Returns whether the window has been set to have a close button
3448 * via gtk_window_set_deletable().
3450 * Return value: %TRUE if the window has been set to have a close button
3455 gtk_window_get_deletable (GtkWindow *window)
3457 g_return_val_if_fail (GTK_IS_WINDOW (window), TRUE);
3459 return window->priv->deletable;
3462 static GtkWindowIconInfo*
3463 get_icon_info (GtkWindow *window)
3465 return g_object_get_qdata (G_OBJECT (window), quark_gtk_window_icon_info);
3469 free_icon_info (GtkWindowIconInfo *info)
3471 g_free (info->icon_name);
3472 g_slice_free (GtkWindowIconInfo, info);
3476 static GtkWindowIconInfo*
3477 ensure_icon_info (GtkWindow *window)
3479 GtkWindowIconInfo *info;
3481 info = get_icon_info (window);
3485 info = g_slice_new0 (GtkWindowIconInfo);
3486 g_object_set_qdata_full (G_OBJECT (window),
3487 quark_gtk_window_icon_info,
3489 (GDestroyNotify)free_icon_info);
3496 icon_list_from_theme (GtkWidget *widget,
3501 GtkIconTheme *icon_theme;
3506 icon_theme = gtk_icon_theme_get_for_screen (gtk_widget_get_screen (widget));
3508 sizes = gtk_icon_theme_get_icon_sizes (icon_theme, name);
3511 for (i = 0; sizes[i]; i++)
3514 * We need an EWMH extension to handle scalable icons
3515 * by passing their name to the WM. For now just use a
3519 icon = gtk_icon_theme_load_icon (icon_theme, name,
3522 icon = gtk_icon_theme_load_icon (icon_theme, name,
3525 list = g_list_append (list, icon);
3535 gtk_window_realize_icon (GtkWindow *window)
3537 GtkWindowPrivate *priv = window->priv;
3539 GtkWindowIconInfo *info;
3540 GdkWindow *gdk_window;
3543 widget = GTK_WIDGET (window);
3544 gdk_window = gtk_widget_get_window (widget);
3546 g_return_if_fail (gdk_window != NULL);
3548 /* no point setting an icon on override-redirect */
3549 if (priv->type == GTK_WINDOW_POPUP)
3554 info = ensure_icon_info (window);
3559 info->using_default_icon = FALSE;
3560 info->using_parent_icon = FALSE;
3561 info->using_themed_icon = FALSE;
3563 icon_list = info->icon_list;
3565 /* Look up themed icon */
3566 if (icon_list == NULL && info->icon_name)
3568 icon_list = icon_list_from_theme (widget, info->icon_name);
3570 info->using_themed_icon = TRUE;
3573 /* Inherit from transient parent */
3574 if (icon_list == NULL && priv->transient_parent)
3576 icon_list = ensure_icon_info (priv->transient_parent)->icon_list;
3578 info->using_parent_icon = TRUE;
3581 /* Inherit from default */
3582 if (icon_list == NULL)
3584 icon_list = default_icon_list;
3586 info->using_default_icon = TRUE;
3589 /* Look up themed icon */
3590 if (icon_list == NULL && default_icon_name)
3592 icon_list = icon_list_from_theme (widget, default_icon_name);
3593 info->using_default_icon = TRUE;
3594 info->using_themed_icon = TRUE;
3597 info->realized = TRUE;
3599 gdk_window_set_icon_list (gtk_widget_get_window (widget), icon_list);
3601 if (info->using_themed_icon)
3603 GtkIconTheme *icon_theme;
3605 g_list_free_full (icon_list, g_object_unref);
3607 icon_theme = gtk_icon_theme_get_for_screen (gtk_widget_get_screen (GTK_WIDGET (window)));
3608 g_signal_connect (icon_theme, "changed",
3609 G_CALLBACK (update_themed_icon), window);
3614 gtk_window_unrealize_icon (GtkWindow *window)
3616 GtkWindowIconInfo *info;
3618 info = get_icon_info (window);
3623 if (info->using_themed_icon)
3625 GtkIconTheme *icon_theme;
3627 icon_theme = gtk_icon_theme_get_for_screen (gtk_widget_get_screen (GTK_WIDGET (window)));
3629 g_signal_handlers_disconnect_by_func (icon_theme, update_themed_icon, window);
3632 /* We don't clear the properties on the window, just figure the
3633 * window is going away.
3636 info->realized = FALSE;
3641 * gtk_window_set_icon_list:
3642 * @window: a #GtkWindow
3643 * @list: (element-type GdkPixbuf): list of #GdkPixbuf
3645 * Sets up the icon representing a #GtkWindow. The icon is used when
3646 * the window is minimized (also known as iconified). Some window
3647 * managers or desktop environments may also place it in the window
3648 * frame, or display it in other contexts.
3650 * gtk_window_set_icon_list() allows you to pass in the same icon in
3651 * several hand-drawn sizes. The list should contain the natural sizes
3652 * your icon is available in; that is, don't scale the image before
3653 * passing it to GTK+. Scaling is postponed until the last minute,
3654 * when the desired final size is known, to allow best quality.
3656 * By passing several sizes, you may improve the final image quality
3657 * of the icon, by reducing or eliminating automatic image scaling.
3659 * Recommended sizes to provide: 16x16, 32x32, 48x48 at minimum, and
3660 * larger images (64x64, 128x128) if you have them.
3662 * See also gtk_window_set_default_icon_list() to set the icon
3663 * for all windows in your application in one go.
3665 * Note that transient windows (those who have been set transient for another
3666 * window using gtk_window_set_transient_for()) will inherit their
3667 * icon from their transient parent. So there's no need to explicitly
3668 * set the icon on transient windows.
3671 gtk_window_set_icon_list (GtkWindow *window,
3674 GtkWindowIconInfo *info;
3676 g_return_if_fail (GTK_IS_WINDOW (window));
3678 info = ensure_icon_info (window);
3680 if (info->icon_list == list) /* check for NULL mostly */
3683 g_list_foreach (list,
3684 (GFunc) g_object_ref, NULL);
3686 g_list_free_full (info->icon_list, g_object_unref);
3688 info->icon_list = g_list_copy (list);
3690 g_object_notify (G_OBJECT (window), "icon");
3692 gtk_window_unrealize_icon (window);
3694 if (gtk_widget_get_realized (GTK_WIDGET (window)))
3695 gtk_window_realize_icon (window);
3697 /* We could try to update our transient children, but I don't think
3698 * it's really worth it. If we did it, the best way would probably
3699 * be to have children connect to notify::icon-list
3704 * gtk_window_get_icon_list:
3705 * @window: a #GtkWindow
3707 * Retrieves the list of icons set by gtk_window_set_icon_list().
3708 * The list is copied, but the reference count on each
3709 * member won't be incremented.
3711 * Return value: (element-type GdkPixbuf) (transfer container): copy of window's icon list
3714 gtk_window_get_icon_list (GtkWindow *window)
3716 GtkWindowIconInfo *info;
3718 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
3720 info = get_icon_info (window);
3723 return g_list_copy (info->icon_list);
3729 * gtk_window_set_icon:
3730 * @window: a #GtkWindow
3731 * @icon: (allow-none): icon image, or %NULL
3733 * Sets up the icon representing a #GtkWindow. This icon is used when
3734 * the window is minimized (also known as iconified). Some window
3735 * managers or desktop environments may also place it in the window
3736 * frame, or display it in other contexts.
3738 * The icon should be provided in whatever size it was naturally
3739 * drawn; that is, don't scale the image before passing it to
3740 * GTK+. Scaling is postponed until the last minute, when the desired
3741 * final size is known, to allow best quality.
3743 * If you have your icon hand-drawn in multiple sizes, use
3744 * gtk_window_set_icon_list(). Then the best size will be used.
3746 * This function is equivalent to calling gtk_window_set_icon_list()
3747 * with a 1-element list.
3749 * See also gtk_window_set_default_icon_list() to set the icon
3750 * for all windows in your application in one go.
3753 gtk_window_set_icon (GtkWindow *window,
3758 g_return_if_fail (GTK_IS_WINDOW (window));
3759 g_return_if_fail (icon == NULL || GDK_IS_PIXBUF (icon));
3764 list = g_list_append (list, icon);
3766 gtk_window_set_icon_list (window, list);
3772 update_themed_icon (GtkIconTheme *icon_theme,
3775 g_object_notify (G_OBJECT (window), "icon");
3777 gtk_window_unrealize_icon (window);
3779 if (gtk_widget_get_realized (GTK_WIDGET (window)))
3780 gtk_window_realize_icon (window);
3784 * gtk_window_set_icon_name:
3785 * @window: a #GtkWindow
3786 * @name: (allow-none): the name of the themed icon
3788 * Sets the icon for the window from a named themed icon. See
3789 * the docs for #GtkIconTheme for more details.
3791 * Note that this has nothing to do with the WM_ICON_NAME
3792 * property which is mentioned in the ICCCM.
3797 gtk_window_set_icon_name (GtkWindow *window,
3800 GtkWindowIconInfo *info;
3803 g_return_if_fail (GTK_IS_WINDOW (window));
3805 info = ensure_icon_info (window);
3807 if (g_strcmp0 (info->icon_name, name) == 0)
3810 tmp = info->icon_name;
3811 info->icon_name = g_strdup (name);
3814 g_list_free_full (info->icon_list, g_object_unref);
3815 info->icon_list = NULL;
3817 update_themed_icon (NULL, window);
3819 g_object_notify (G_OBJECT (window), "icon-name");
3823 * gtk_window_get_icon_name:
3824 * @window: a #GtkWindow
3826 * Returns the name of the themed icon for the window,
3827 * see gtk_window_set_icon_name().
3829 * Returns: the icon name or %NULL if the window has
3835 gtk_window_get_icon_name (GtkWindow *window)
3837 GtkWindowIconInfo *info;
3839 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
3841 info = ensure_icon_info (window);
3843 return info->icon_name;
3847 * gtk_window_get_icon:
3848 * @window: a #GtkWindow
3850 * Gets the value set by gtk_window_set_icon() (or if you've
3851 * called gtk_window_set_icon_list(), gets the first icon in
3854 * Return value: (transfer none): icon for window
3857 gtk_window_get_icon (GtkWindow *window)
3859 GtkWindowIconInfo *info;
3861 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
3863 info = get_icon_info (window);
3864 if (info && info->icon_list)
3865 return GDK_PIXBUF (info->icon_list->data);
3870 /* Load pixbuf, printing warning on failure if error == NULL
3873 load_pixbuf_verbosely (const char *filename,
3876 GError *local_err = NULL;
3879 pixbuf = gdk_pixbuf_new_from_file (filename, &local_err);
3887 g_warning ("Error loading icon from file '%s':\n\t%s",
3888 filename, local_err->message);
3889 g_error_free (local_err);
3897 * gtk_window_set_icon_from_file:
3898 * @window: a #GtkWindow
3899 * @filename: (type filename): location of icon file
3900 * @err: (allow-none): location to store error, or %NULL.
3902 * Sets the icon for @window.
3903 * Warns on failure if @err is %NULL.
3905 * This function is equivalent to calling gtk_window_set_icon()
3906 * with a pixbuf created by loading the image from @filename.
3908 * Returns: %TRUE if setting the icon succeeded.
3913 gtk_window_set_icon_from_file (GtkWindow *window,
3914 const gchar *filename,
3917 GdkPixbuf *pixbuf = load_pixbuf_verbosely (filename, err);
3921 gtk_window_set_icon (window, pixbuf);
3922 g_object_unref (pixbuf);
3931 * gtk_window_set_default_icon_list:
3932 * @list: (element-type GdkPixbuf) (transfer container): a list of #GdkPixbuf
3934 * Sets an icon list to be used as fallback for windows that haven't
3935 * had gtk_window_set_icon_list() called on them to set up a
3936 * window-specific icon list. This function allows you to set up the
3937 * icon for all windows in your app at once.
3939 * See gtk_window_set_icon_list() for more details.
3943 gtk_window_set_default_icon_list (GList *list)
3947 if (list == default_icon_list)
3950 /* Update serial so we don't used cached pixmaps/masks
3952 default_icon_serial++;
3954 g_list_foreach (list,
3955 (GFunc) g_object_ref, NULL);
3957 g_list_free_full (default_icon_list, g_object_unref);
3959 default_icon_list = g_list_copy (list);
3961 /* Update all toplevels */
3962 toplevels = gtk_window_list_toplevels ();
3963 tmp_list = toplevels;
3964 while (tmp_list != NULL)
3966 GtkWindowIconInfo *info;
3967 GtkWindow *w = tmp_list->data;
3969 info = get_icon_info (w);
3970 if (info && info->using_default_icon)
3972 gtk_window_unrealize_icon (w);
3973 if (gtk_widget_get_realized (GTK_WIDGET (w)))
3974 gtk_window_realize_icon (w);
3977 tmp_list = tmp_list->next;
3979 g_list_free (toplevels);
3983 * gtk_window_set_default_icon:
3986 * Sets an icon to be used as fallback for windows that haven't
3987 * had gtk_window_set_icon() called on them from a pixbuf.
3992 gtk_window_set_default_icon (GdkPixbuf *icon)
3996 g_return_if_fail (GDK_IS_PIXBUF (icon));
3998 list = g_list_prepend (NULL, icon);
3999 gtk_window_set_default_icon_list (list);
4004 * gtk_window_set_default_icon_name:
4005 * @name: the name of the themed icon
4007 * Sets an icon to be used as fallback for windows that haven't
4008 * had gtk_window_set_icon_list() called on them from a named
4009 * themed icon, see gtk_window_set_icon_name().
4014 gtk_window_set_default_icon_name (const gchar *name)
4019 /* Update serial so we don't used cached pixmaps/masks
4021 default_icon_serial++;
4023 g_free (default_icon_name);
4024 default_icon_name = g_strdup (name);
4026 g_list_free_full (default_icon_list, g_object_unref);
4027 default_icon_list = NULL;
4029 /* Update all toplevels */
4030 toplevels = gtk_window_list_toplevels ();
4031 tmp_list = toplevels;
4032 while (tmp_list != NULL)
4034 GtkWindowIconInfo *info;
4035 GtkWindow *w = tmp_list->data;
4037 info = get_icon_info (w);
4038 if (info && info->using_default_icon && info->using_themed_icon)
4040 gtk_window_unrealize_icon (w);
4041 if (gtk_widget_get_realized (GTK_WIDGET (w)))
4042 gtk_window_realize_icon (w);
4045 tmp_list = tmp_list->next;
4047 g_list_free (toplevels);
4051 * gtk_window_get_default_icon_name:
4053 * Returns the fallback icon name for windows that has been set
4054 * with gtk_window_set_default_icon_name(). The returned
4055 * string is owned by GTK+ and should not be modified. It
4056 * is only valid until the next call to
4057 * gtk_window_set_default_icon_name().
4059 * Returns: the fallback icon name for windows
4064 gtk_window_get_default_icon_name (void)
4066 return default_icon_name;
4070 * gtk_window_set_default_icon_from_file:
4071 * @filename: (type filename): location of icon file
4072 * @err: (allow-none): location to store error, or %NULL.
4074 * Sets an icon to be used as fallback for windows that haven't
4075 * had gtk_window_set_icon_list() called on them from a file
4076 * on disk. Warns on failure if @err is %NULL.
4078 * Returns: %TRUE if setting the icon succeeded.
4083 gtk_window_set_default_icon_from_file (const gchar *filename,
4086 GdkPixbuf *pixbuf = load_pixbuf_verbosely (filename, err);
4090 gtk_window_set_default_icon (pixbuf);
4091 g_object_unref (pixbuf);
4100 * gtk_window_get_default_icon_list:
4102 * Gets the value set by gtk_window_set_default_icon_list().
4103 * The list is a copy and should be freed with g_list_free(),
4104 * but the pixbufs in the list have not had their reference count
4107 * Return value: (element-type GdkPixbuf) (transfer container): copy of default icon list
4110 gtk_window_get_default_icon_list (void)
4112 return g_list_copy (default_icon_list);
4116 gtk_window_set_default_size_internal (GtkWindow *window,
4117 gboolean change_width,
4119 gboolean change_height,
4121 gboolean is_geometry)
4123 GtkWindowGeometryInfo *info;
4125 g_return_if_fail (change_width == FALSE || width >= -1);
4126 g_return_if_fail (change_height == FALSE || height >= -1);
4128 info = gtk_window_get_geometry_info (window, TRUE);
4130 g_object_freeze_notify (G_OBJECT (window));
4132 info->default_is_geometry = is_geometry != FALSE;
4142 info->default_width = width;
4144 g_object_notify (G_OBJECT (window), "default-width");
4155 info->default_height = height;
4157 g_object_notify (G_OBJECT (window), "default-height");
4160 g_object_thaw_notify (G_OBJECT (window));
4162 gtk_widget_queue_resize_no_redraw (GTK_WIDGET (window));
4166 * gtk_window_set_default_size:
4167 * @window: a #GtkWindow
4168 * @width: width in pixels, or -1 to unset the default width
4169 * @height: height in pixels, or -1 to unset the default height
4171 * Sets the default size of a window. If the window's "natural" size
4172 * (its size request) is larger than the default, the default will be
4173 * ignored. More generally, if the default size does not obey the
4174 * geometry hints for the window (gtk_window_set_geometry_hints() can
4175 * be used to set these explicitly), the default size will be clamped
4176 * to the nearest permitted size.
4178 * Unlike gtk_widget_set_size_request(), which sets a size request for
4179 * a widget and thus would keep users from shrinking the window, this
4180 * function only sets the initial size, just as if the user had
4181 * resized the window themselves. Users can still shrink the window
4182 * again as they normally would. Setting a default size of -1 means to
4183 * use the "natural" default size (the size request of the window).
4185 * For more control over a window's initial size and how resizing works,
4186 * investigate gtk_window_set_geometry_hints().
4188 * For some uses, gtk_window_resize() is a more appropriate function.
4189 * gtk_window_resize() changes the current size of the window, rather
4190 * than the size to be used on initial display. gtk_window_resize() always
4191 * affects the window itself, not the geometry widget.
4193 * The default size of a window only affects the first time a window is
4194 * shown; if a window is hidden and re-shown, it will remember the size
4195 * it had prior to hiding, rather than using the default size.
4197 * Windows can't actually be 0x0 in size, they must be at least 1x1, but
4198 * passing 0 for @width and @height is OK, resulting in a 1x1 default size.
4201 gtk_window_set_default_size (GtkWindow *window,
4205 g_return_if_fail (GTK_IS_WINDOW (window));
4206 g_return_if_fail (width >= -1);
4207 g_return_if_fail (height >= -1);
4209 gtk_window_set_default_size_internal (window, TRUE, width, TRUE, height, FALSE);
4213 * gtk_window_set_default_geometry:
4214 * @window: a #GtkWindow
4215 * @width: width in resize increments, or -1 to unset the default width
4216 * @height: height in resize increments, or -1 to unset the default height
4218 * Like gtk_window_set_default_size(), but @width and @height are interpreted
4219 * in terms of the base size and increment set with
4220 * gtk_window_set_geometry_hints.
4225 gtk_window_set_default_geometry (GtkWindow *window,
4229 g_return_if_fail (GTK_IS_WINDOW (window));
4230 g_return_if_fail (width >= -1);
4231 g_return_if_fail (height >= -1);
4233 gtk_window_set_default_size_internal (window, TRUE, width, TRUE, height, TRUE);
4237 * gtk_window_get_default_size:
4238 * @window: a #GtkWindow
4239 * @width: (out) (allow-none): location to store the default width, or %NULL
4240 * @height: (out) (allow-none): location to store the default height, or %NULL
4242 * Gets the default size of the window. A value of -1 for the width or
4243 * height indicates that a default size has not been explicitly set
4244 * for that dimension, so the "natural" size of the window will be
4249 gtk_window_get_default_size (GtkWindow *window,
4253 GtkWindowGeometryInfo *info;
4255 g_return_if_fail (GTK_IS_WINDOW (window));
4257 info = gtk_window_get_geometry_info (window, FALSE);
4260 *width = info ? info->default_width : -1;
4263 *height = info ? info->default_height : -1;
4267 * gtk_window_resize:
4268 * @window: a #GtkWindow
4269 * @width: width in pixels to resize the window to
4270 * @height: height in pixels to resize the window to
4272 * Resizes the window as if the user had done so, obeying geometry
4273 * constraints. The default geometry constraint is that windows may
4274 * not be smaller than their size request; to override this
4275 * constraint, call gtk_widget_set_size_request() to set the window's
4276 * request to a smaller value.
4278 * If gtk_window_resize() is called before showing a window for the
4279 * first time, it overrides any default size set with
4280 * gtk_window_set_default_size().
4282 * Windows may not be resized smaller than 1 by 1 pixels.
4286 gtk_window_resize (GtkWindow *window,
4290 GtkWindowGeometryInfo *info;
4292 g_return_if_fail (GTK_IS_WINDOW (window));
4293 g_return_if_fail (width > 0);
4294 g_return_if_fail (height > 0);
4296 info = gtk_window_get_geometry_info (window, TRUE);
4298 info->resize_width = width;
4299 info->resize_height = height;
4300 info->resize_is_geometry = FALSE;
4302 gtk_widget_queue_resize_no_redraw (GTK_WIDGET (window));
4306 * gtk_window_resize_to_geometry:
4307 * @window: a #GtkWindow
4308 * @width: width in resize increments to resize the window to
4309 * @height: height in resize increments to resize the window to
4311 * Like gtk_window_resize(), but @width and @height are interpreted
4312 * in terms of the base size and increment set with
4313 * gtk_window_set_geometry_hints.
4318 gtk_window_resize_to_geometry (GtkWindow *window,
4322 GtkWindowGeometryInfo *info;
4324 g_return_if_fail (GTK_IS_WINDOW (window));
4325 g_return_if_fail (width > 0);
4326 g_return_if_fail (height > 0);
4328 info = gtk_window_get_geometry_info (window, TRUE);
4330 info->resize_width = width;
4331 info->resize_height = height;
4332 info->resize_is_geometry = TRUE;
4334 gtk_widget_queue_resize_no_redraw (GTK_WIDGET (window));
4338 * gtk_window_get_size:
4339 * @window: a #GtkWindow
4340 * @width: (out) (allow-none): return location for width, or %NULL
4341 * @height: (out) (allow-none): return location for height, or %NULL
4343 * Obtains the current size of @window. If @window is not onscreen,
4344 * it returns the size GTK+ will suggest to the <link
4345 * linkend="gtk-X11-arch">window manager</link> for the initial window
4346 * size (but this is not reliably the same as the size the window
4347 * manager will actually select). The size obtained by
4348 * gtk_window_get_size() is the last size received in a
4349 * #GdkEventConfigure, that is, GTK+ uses its locally-stored size,
4350 * rather than querying the X server for the size. As a result, if you
4351 * call gtk_window_resize() then immediately call
4352 * gtk_window_get_size(), the size won't have taken effect yet. After
4353 * the window manager processes the resize request, GTK+ receives
4354 * notification that the size has changed via a configure event, and
4355 * the size of the window gets updated.
4357 * Note 1: Nearly any use of this function creates a race condition,
4358 * because the size of the window may change between the time that you
4359 * get the size and the time that you perform some action assuming
4360 * that size is the current size. To avoid race conditions, connect to
4361 * "configure-event" on the window and adjust your size-dependent
4362 * state to match the size delivered in the #GdkEventConfigure.
4364 * Note 2: The returned size does <emphasis>not</emphasis> include the
4365 * size of the window manager decorations (aka the window frame or
4366 * border). Those are not drawn by GTK+ and GTK+ has no reliable
4367 * method of determining their size.
4369 * Note 3: If you are getting a window size in order to position
4370 * the window onscreen, there may be a better way. The preferred
4371 * way is to simply set the window's semantic type with
4372 * gtk_window_set_type_hint(), which allows the window manager to
4373 * e.g. center dialogs. Also, if you set the transient parent of
4374 * dialogs with gtk_window_set_transient_for() window managers
4375 * will often center the dialog over its parent window. It's
4376 * much preferred to let the window manager handle these
4377 * things rather than doing it yourself, because all apps will
4378 * behave consistently and according to user prefs if the window
4379 * manager handles it. Also, the window manager can take the size
4380 * of the window decorations/border into account, while your
4381 * application cannot.
4383 * In any case, if you insist on application-specified window
4384 * positioning, there's <emphasis>still</emphasis> a better way than
4385 * doing it yourself - gtk_window_set_position() will frequently
4386 * handle the details for you.
4390 gtk_window_get_size (GtkWindow *window,
4396 g_return_if_fail (GTK_IS_WINDOW (window));
4398 if (width == NULL && height == NULL)
4401 if (gtk_widget_get_mapped (GTK_WIDGET (window)))
4403 w = gdk_window_get_width (gtk_widget_get_window (GTK_WIDGET (window)));
4404 h = gdk_window_get_height (gtk_widget_get_window (GTK_WIDGET (window)));
4408 GdkRectangle configure_request;
4410 gtk_window_compute_configure_request (window,
4414 w = configure_request.width;
4415 h = configure_request.height;
4426 * @window: a #GtkWindow
4427 * @x: X coordinate to move window to
4428 * @y: Y coordinate to move window to
4430 * Asks the <link linkend="gtk-X11-arch">window manager</link> to move
4431 * @window to the given position. Window managers are free to ignore
4432 * this; most window managers ignore requests for initial window
4433 * positions (instead using a user-defined placement algorithm) and
4434 * honor requests after the window has already been shown.
4436 * Note: the position is the position of the gravity-determined
4437 * reference point for the window. The gravity determines two things:
4438 * first, the location of the reference point in root window
4439 * coordinates; and second, which point on the window is positioned at
4440 * the reference point.
4442 * By default the gravity is #GDK_GRAVITY_NORTH_WEST, so the reference
4443 * point is simply the @x, @y supplied to gtk_window_move(). The
4444 * top-left corner of the window decorations (aka window frame or
4445 * border) will be placed at @x, @y. Therefore, to position a window
4446 * at the top left of the screen, you want to use the default gravity
4447 * (which is #GDK_GRAVITY_NORTH_WEST) and move the window to 0,0.
4449 * To position a window at the bottom right corner of the screen, you
4450 * would set #GDK_GRAVITY_SOUTH_EAST, which means that the reference
4451 * point is at @x + the window width and @y + the window height, and
4452 * the bottom-right corner of the window border will be placed at that
4453 * reference point. So, to place a window in the bottom right corner
4454 * you would first set gravity to south east, then write:
4455 * <literal>gtk_window_move (window, gdk_screen_width () - window_width,
4456 * gdk_screen_height () - window_height)</literal> (note that this
4457 * example does not take multi-head scenarios into account).
4459 * The Extended Window Manager Hints specification at <ulink
4460 * url="http://www.freedesktop.org/Standards/wm-spec">
4461 * http://www.freedesktop.org/Standards/wm-spec</ulink> has a
4462 * nice table of gravities in the "implementation notes" section.
4464 * The gtk_window_get_position() documentation may also be relevant.
4467 gtk_window_move (GtkWindow *window,
4471 GtkWindowGeometryInfo *info;
4474 g_return_if_fail (GTK_IS_WINDOW (window));
4476 widget = GTK_WIDGET (window);
4478 info = gtk_window_get_geometry_info (window, TRUE);
4480 if (gtk_widget_get_mapped (widget))
4482 GtkAllocation allocation;
4484 gtk_widget_get_allocation (widget, &allocation);
4486 /* we have now sent a request with this position
4487 * with currently-active constraints, so toggle flag.
4489 info->position_constraints_changed = FALSE;
4491 /* we only constrain if mapped - if not mapped,
4492 * then gtk_window_compute_configure_request()
4493 * will apply the constraints later, and we
4494 * don't want to lose information about
4495 * what position the user set before then.
4496 * i.e. if you do a move() then turn off POS_CENTER
4497 * then show the window, your move() will work.
4499 gtk_window_constrain_position (window,
4500 allocation.width, allocation.height,
4503 /* Note that this request doesn't go through our standard request
4504 * framework, e.g. doesn't increment configure_request_count,
4505 * doesn't set info->last, etc.; that's because
4506 * we don't save the info needed to arrive at this same request
4509 * To gtk_window_move_resize(), this will end up looking exactly
4510 * the same as the position being changed by the window
4513 gdk_window_move (gtk_widget_get_window (GTK_WIDGET (window)), x, y);
4517 /* Save this position to apply on mapping */
4518 info->initial_x = x;
4519 info->initial_y = y;
4520 info->initial_pos_set = TRUE;
4525 * gtk_window_get_position:
4526 * @window: a #GtkWindow
4527 * @root_x: (out) (allow-none): return location for X coordinate of
4528 * gravity-determined reference point, or %NULL
4529 * @root_y: (out) (allow-none): return location for Y coordinate of
4530 * gravity-determined reference point, or %NULL
4532 * This function returns the position you need to pass to
4533 * gtk_window_move() to keep @window in its current position.
4534 * This means that the meaning of the returned value varies with
4535 * window gravity. See gtk_window_move() for more details.
4537 * If you haven't changed the window gravity, its gravity will be
4538 * #GDK_GRAVITY_NORTH_WEST. This means that gtk_window_get_position()
4539 * gets the position of the top-left corner of the window manager
4540 * frame for the window. gtk_window_move() sets the position of this
4541 * same top-left corner.
4543 * gtk_window_get_position() is not 100% reliable because the X Window System
4544 * does not specify a way to obtain the geometry of the
4545 * decorations placed on a window by the window manager.
4546 * Thus GTK+ is using a "best guess" that works with most
4549 * Moreover, nearly all window managers are historically broken with
4550 * respect to their handling of window gravity. So moving a window to
4551 * its current position as returned by gtk_window_get_position() tends
4552 * to result in moving the window slightly. Window managers are
4553 * slowly getting better over time.
4555 * If a window has gravity #GDK_GRAVITY_STATIC the window manager
4556 * frame is not relevant, and thus gtk_window_get_position() will
4557 * always produce accurate results. However you can't use static
4558 * gravity to do things like place a window in a corner of the screen,
4559 * because static gravity ignores the window manager decorations.
4561 * If you are saving and restoring your application's window
4562 * positions, you should know that it's impossible for applications to
4563 * do this without getting it somewhat wrong because applications do
4564 * not have sufficient knowledge of window manager state. The Correct
4565 * Mechanism is to support the session management protocol (see the
4566 * "GnomeClient" object in the GNOME libraries for example) and allow
4567 * the window manager to save your window sizes and positions.
4572 gtk_window_get_position (GtkWindow *window,
4576 GtkWindowPrivate *priv;
4578 GdkWindow *gdk_window;
4580 g_return_if_fail (GTK_IS_WINDOW (window));
4582 priv = window->priv;
4583 widget = GTK_WIDGET (window);
4584 gdk_window = gtk_widget_get_window (widget);
4586 if (priv->gravity == GDK_GRAVITY_STATIC)
4588 if (gtk_widget_get_mapped (widget))
4590 /* This does a server round-trip, which is sort of wrong;
4591 * but a server round-trip is inevitable for
4592 * gdk_window_get_frame_extents() in the usual
4593 * NorthWestGravity case below, so not sure what else to
4594 * do. We should likely be consistent about whether we get
4595 * the client-side info or the server-side info.
4597 gdk_window_get_origin (gdk_window, root_x, root_y);
4601 GdkRectangle configure_request;
4603 gtk_window_compute_configure_request (window,
4607 *root_x = configure_request.x;
4608 *root_y = configure_request.y;
4613 GdkRectangle frame_extents;
4618 if (gtk_widget_get_mapped (widget))
4620 gdk_window_get_frame_extents (gdk_window, &frame_extents);
4621 x = frame_extents.x;
4622 y = frame_extents.y;
4623 gtk_window_get_size (window, &w, &h);
4627 /* We just say the frame has 0 size on all sides.
4628 * Not sure what else to do.
4630 gtk_window_compute_configure_request (window,
4633 x = frame_extents.x;
4634 y = frame_extents.y;
4635 w = frame_extents.width;
4636 h = frame_extents.height;
4639 switch (priv->gravity)
4641 case GDK_GRAVITY_NORTH:
4642 case GDK_GRAVITY_CENTER:
4643 case GDK_GRAVITY_SOUTH:
4644 /* Find center of frame. */
4645 x += frame_extents.width / 2;
4646 /* Center client window on that point. */
4650 case GDK_GRAVITY_SOUTH_EAST:
4651 case GDK_GRAVITY_EAST:
4652 case GDK_GRAVITY_NORTH_EAST:
4653 /* Find right edge of frame */
4654 x += frame_extents.width;
4655 /* Align left edge of client at that point. */
4662 switch (priv->gravity)
4664 case GDK_GRAVITY_WEST:
4665 case GDK_GRAVITY_CENTER:
4666 case GDK_GRAVITY_EAST:
4667 /* Find center of frame. */
4668 y += frame_extents.height / 2;
4669 /* Center client window there. */
4672 case GDK_GRAVITY_SOUTH_WEST:
4673 case GDK_GRAVITY_SOUTH:
4674 case GDK_GRAVITY_SOUTH_EAST:
4675 /* Find south edge of frame */
4676 y += frame_extents.height;
4677 /* Place bottom edge of client there */
4692 * gtk_window_reshow_with_initial_size:
4693 * @window: a #GtkWindow
4695 * Hides @window, then reshows it, resetting the
4696 * default size and position of the window. Used
4697 * by GUI builders only.
4700 gtk_window_reshow_with_initial_size (GtkWindow *window)
4704 g_return_if_fail (GTK_IS_WINDOW (window));
4706 widget = GTK_WIDGET (window);
4708 gtk_widget_hide (widget);
4709 gtk_widget_unrealize (widget);
4710 gtk_widget_show (widget);
4714 gtk_window_destroy (GtkWidget *widget)
4716 GtkWindow *window = GTK_WINDOW (widget);
4717 GtkWindowPrivate *priv = window->priv;
4719 gtk_window_release_application (window);
4721 toplevel_list = g_slist_remove (toplevel_list, window);
4723 if (priv->transient_parent)
4724 gtk_window_set_transient_for (window, NULL);
4726 remove_attach_widget (GTK_WINDOW (widget));
4728 /* frees the icons */
4729 gtk_window_set_icon_list (window, NULL);
4731 if (priv->has_user_ref_count)
4733 priv->has_user_ref_count = FALSE;
4734 g_object_unref (window);
4738 gtk_window_group_remove_window (priv->group, window);
4740 gtk_window_free_key_hash (window);
4742 GTK_WIDGET_CLASS (gtk_window_parent_class)->destroy (widget);
4746 gtk_window_finalize (GObject *object)
4748 GtkWindow *window = GTK_WINDOW (object);
4749 GtkWindowPrivate *priv = window->priv;
4750 GtkMnemonicHash *mnemonic_hash;
4752 g_free (priv->title);
4753 g_free (priv->wmclass_name);
4754 g_free (priv->wmclass_class);
4755 g_free (priv->wm_role);
4756 gtk_window_release_application (window);
4758 mnemonic_hash = gtk_window_get_mnemonic_hash (window, FALSE);
4760 _gtk_mnemonic_hash_free (mnemonic_hash);
4762 if (priv->geometry_info)
4764 if (priv->geometry_info->widget)
4765 g_signal_handlers_disconnect_by_func (priv->geometry_info->widget,
4766 gtk_widget_destroyed,
4767 &priv->geometry_info->widget);
4768 g_free (priv->geometry_info);
4771 if (priv->keys_changed_handler)
4773 g_source_remove (priv->keys_changed_handler);
4774 priv->keys_changed_handler = 0;
4778 g_signal_handlers_disconnect_by_func (priv->screen,
4779 gtk_window_on_composited_changed, window);
4781 g_free (priv->startup_id);
4783 #ifdef GDK_WINDOWING_X11
4784 g_signal_handlers_disconnect_by_func (gtk_settings_get_default (),
4785 gtk_window_on_theme_variant_changed,
4789 G_OBJECT_CLASS (gtk_window_parent_class)->finalize (object);
4793 gtk_window_show (GtkWidget *widget)
4795 GtkWindow *window = GTK_WINDOW (widget);
4796 GtkWindowPrivate *priv = window->priv;
4797 GtkContainer *container = GTK_CONTAINER (window);
4798 gboolean need_resize;
4801 if (!gtk_widget_is_toplevel (GTK_WIDGET (widget)))
4803 GTK_WIDGET_CLASS (gtk_window_parent_class)->show (widget);
4807 _gtk_widget_set_visible_flag (widget, TRUE);
4809 need_resize = _gtk_widget_get_alloc_needed (widget) || !gtk_widget_get_realized (widget);
4811 _gtk_style_context_validate (gtk_widget_get_style_context (widget),
4812 g_get_monotonic_time (),
4817 GtkWindowGeometryInfo *info = gtk_window_get_geometry_info (window, TRUE);
4818 GtkAllocation allocation = { 0, 0 };
4819 GdkRectangle configure_request;
4820 GdkGeometry new_geometry;
4822 gboolean was_realized;
4824 /* We are going to go ahead and perform this configure request
4825 * and then emulate a configure notify by going ahead and
4826 * doing a size allocate. Sort of a synchronous
4827 * mini-copy of gtk_window_move_resize() here.
4829 gtk_window_compute_configure_request (window,
4834 /* We update this because we are going to go ahead
4835 * and gdk_window_resize() below, rather than
4838 info->last.configure_request.width = configure_request.width;
4839 info->last.configure_request.height = configure_request.height;
4841 /* and allocate the window - this is normally done
4842 * in move_resize in response to configure notify
4844 allocation.width = configure_request.width;
4845 allocation.height = configure_request.height;
4846 gtk_widget_size_allocate (widget, &allocation);
4848 /* Then we guarantee we have a realize */
4849 was_realized = FALSE;
4850 if (!gtk_widget_get_realized (widget))
4852 gtk_widget_realize (widget);
4853 was_realized = TRUE;
4856 /* We only send configure request if we didn't just finish
4857 * creating the window; if we just created the window
4858 * then we created it with widget->allocation anyhow.
4861 gdk_window_move_resize (gtk_widget_get_window (widget),
4862 configure_request.x,
4863 configure_request.y,
4864 configure_request.width,
4865 configure_request.height);
4868 gtk_container_check_resize (container);
4870 gtk_widget_map (widget);
4872 /* Try to make sure that we have some focused widget
4874 #ifdef GDK_WINDOWING_X11
4875 is_plug = GDK_IS_X11_WINDOW (gtk_widget_get_window (widget)) &&
4876 GTK_IS_PLUG (window);
4880 if (!priv->focus_widget && !is_plug)
4881 gtk_window_move_focus (widget, GTK_DIR_TAB_FORWARD);
4884 gtk_grab_add (widget);
4888 gtk_window_hide (GtkWidget *widget)
4890 GtkWindow *window = GTK_WINDOW (widget);
4891 GtkWindowPrivate *priv = window->priv;
4893 if (!gtk_widget_is_toplevel (GTK_WIDGET (widget)))
4895 GTK_WIDGET_CLASS (gtk_window_parent_class)->hide (widget);
4899 _gtk_widget_set_visible_flag (widget, FALSE);
4900 gtk_widget_unmap (widget);
4903 gtk_grab_remove (widget);
4907 gtk_window_map (GtkWidget *widget)
4910 GtkWindow *window = GTK_WINDOW (widget);
4911 GtkWindowPrivate *priv = window->priv;
4912 GdkWindow *gdk_window;
4913 gboolean auto_mnemonics;
4914 GtkPolicyType visible_focus;
4916 if (!gtk_widget_is_toplevel (widget))
4918 GTK_WIDGET_CLASS (gtk_window_parent_class)->map (widget);
4922 gtk_widget_set_mapped (widget, TRUE);
4924 child = gtk_bin_get_child (&(window->bin));
4926 gtk_widget_get_visible (child) &&
4927 !gtk_widget_get_mapped (child))
4928 gtk_widget_map (child);
4930 gdk_window = gtk_widget_get_window (widget);
4932 if (priv->maximize_initially)
4933 gdk_window_maximize (gdk_window);
4935 gdk_window_unmaximize (gdk_window);
4937 if (priv->stick_initially)
4938 gdk_window_stick (gdk_window);
4940 gdk_window_unstick (gdk_window);
4942 if (priv->iconify_initially)
4943 gdk_window_iconify (gdk_window);
4945 gdk_window_deiconify (gdk_window);
4947 if (priv->fullscreen_initially)
4948 gdk_window_fullscreen (gdk_window);
4950 gdk_window_unfullscreen (gdk_window);
4952 gdk_window_set_keep_above (gdk_window, priv->above_initially);
4954 gdk_window_set_keep_below (gdk_window, priv->below_initially);
4956 if (priv->type == GTK_WINDOW_TOPLEVEL)
4958 gtk_window_set_theme_variant (window);
4959 gtk_window_set_hide_titlebar_when_maximized (window,
4960 priv->hide_titlebar_when_maximized);
4963 /* No longer use the default settings */
4964 priv->need_default_size = FALSE;
4965 priv->need_default_position = FALSE;
4967 if (priv->reset_type_hint)
4969 /* We should only reset the type hint when the application
4970 * used gtk_window_set_type_hint() to change the hint.
4971 * Some applications use X directly to change the properties;
4972 * in that case, we shouldn't overwrite what they did.
4974 gdk_window_set_type_hint (gdk_window, priv->gdk_type_hint);
4975 priv->reset_type_hint = FALSE;
4978 gdk_window_show (gdk_window);
4980 if (priv->grip_window)
4981 gdk_window_show (priv->grip_window);
4983 if (!disable_startup_notification)
4985 /* Do we have a custom startup-notification id? */
4986 if (priv->startup_id != NULL)
4988 /* Make sure we have a "real" id */
4989 if (!startup_id_is_fake (priv->startup_id))
4990 gdk_notify_startup_complete_with_id (priv->startup_id);
4992 g_free (priv->startup_id);
4993 priv->startup_id = NULL;
4995 else if (!sent_startup_notification)
4997 sent_startup_notification = TRUE;
4998 gdk_notify_startup_complete ();
5002 /* if auto-mnemonics is enabled and mnemonics visible is not already set
5003 * (as in the case of popup menus), then hide mnemonics initially
5005 g_object_get (gtk_widget_get_settings (widget),
5006 "gtk-auto-mnemonics", &auto_mnemonics,
5007 "gtk-visible-focus", &visible_focus,
5010 if (auto_mnemonics && !priv->mnemonics_visible_set)
5011 gtk_window_set_mnemonics_visible (window, FALSE);
5013 /* inherit from transient parent, so that a dialog that is
5014 * opened via keynav shows focus initially
5016 if (priv->transient_parent)
5017 gtk_window_set_focus_visible (window, gtk_window_get_focus_visible (priv->transient_parent));
5019 gtk_window_set_focus_visible (window, visible_focus == GTK_POLICY_ALWAYS);
5021 ensure_state_flag_backdrop (widget);
5025 gtk_window_map_event (GtkWidget *widget,
5028 if (!gtk_widget_get_mapped (widget))
5030 /* we should be be unmapped, but are getting a MapEvent, this may happen
5031 * to toplevel XWindows if mapping was intercepted by a window manager
5032 * and an unmap request occoured while the MapRequestEvent was still
5033 * being handled. we work around this situaiton here by re-requesting
5034 * the window being unmapped. more details can be found in:
5035 * http://bugzilla.gnome.org/show_bug.cgi?id=316180
5037 gdk_window_hide (gtk_widget_get_window (widget));
5043 gtk_window_unmap (GtkWidget *widget)
5045 GtkWindow *window = GTK_WINDOW (widget);
5046 GtkWindowPrivate *priv = window->priv;
5048 GtkWindowGeometryInfo *info;
5049 GdkWindow *gdk_window;
5050 GdkWindowState state;
5052 if (!gtk_widget_is_toplevel (GTK_WIDGET (widget)))
5054 GTK_WIDGET_CLASS (gtk_window_parent_class)->unmap (widget);
5058 gdk_window = gtk_widget_get_window (widget);
5060 gtk_widget_set_mapped (widget, FALSE);
5061 gdk_window_withdraw (gdk_window);
5063 priv->configure_request_count = 0;
5064 priv->configure_notify_received = FALSE;
5066 /* on unmap, we reset the default positioning of the window,
5067 * so it's placed again, but we don't reset the default
5068 * size of the window, so it's remembered.
5070 priv->need_default_position = TRUE;
5072 info = gtk_window_get_geometry_info (window, FALSE);
5075 info->initial_pos_set = FALSE;
5076 info->position_constraints_changed = FALSE;
5079 state = gdk_window_get_state (gdk_window);
5080 priv->iconify_initially = (state & GDK_WINDOW_STATE_ICONIFIED) != 0;
5081 priv->maximize_initially = (state & GDK_WINDOW_STATE_MAXIMIZED) != 0;
5082 priv->stick_initially = (state & GDK_WINDOW_STATE_STICKY) != 0;
5083 priv->above_initially = (state & GDK_WINDOW_STATE_ABOVE) != 0;
5084 priv->below_initially = (state & GDK_WINDOW_STATE_BELOW) != 0;
5086 child = gtk_bin_get_child (&(window->bin));
5088 gtk_widget_unmap (child);
5091 /* (Note: Replace "size" with "width" or "height". Also, the request
5092 * mode is honoured.)
5093 * For selecting the default window size, the following conditions
5094 * should hold (in order of importance):
5095 * - the size is not below the minimum size
5096 * Windows cannot be resized below their minimum size, so we must
5097 * ensure we don't do that either.
5098 * - the size is not above the natural size
5099 * It seems weird to allocate more than this in an initial guess.
5100 * - the size does not exceed that of a maximized window
5101 * We want to see the whole window after all.
5102 * (Note that this may not be possible to achieve due to imperfect
5103 * information from the windowing system.)
5106 /* We use these for now to not make windows too big by accident. Note
5107 * that we still clamp these numbers by screen size. Also note that
5108 * minimum size still overrides this. So keep your windows small! :)
5110 #define MAX_DEFAULT_WINDOW_WIDTH 640
5111 #define MAX_DEFAULT_WINDOW_HEIGHT 480
5114 gtk_window_guess_default_size (GtkWindow *window,
5118 GtkWidget *widget = GTK_WIDGET (window);
5120 int minimum, natural;
5122 screen = gtk_widget_get_screen (widget);
5124 *width = gdk_screen_get_width (screen);
5125 *height = gdk_screen_get_height (screen);
5127 if (*width >= *height)
5130 *width = MIN (*width, MAX_DEFAULT_WINDOW_WIDTH);
5131 *height = MIN (*height, MAX_DEFAULT_WINDOW_HEIGHT);
5136 *width = MIN (*width, MAX_DEFAULT_WINDOW_HEIGHT);
5137 *height = MIN (*height, MAX_DEFAULT_WINDOW_WIDTH);
5140 if (gtk_widget_get_request_mode (widget) == GTK_SIZE_REQUEST_WIDTH_FOR_HEIGHT)
5142 gtk_widget_get_preferred_height (widget, &minimum, &natural);
5143 *height = MAX (minimum, MIN (*height, natural));
5145 gtk_widget_get_preferred_width_for_height (widget, *height, &minimum, &natural);
5146 *width = MAX (minimum, MIN (*width, natural));
5148 else /* GTK_SIZE_REQUEST_HEIGHT_FOR_WIDTH or CONSTANT_SIZE */
5150 gtk_widget_get_preferred_width (widget, &minimum, &natural);
5151 *width = MAX (minimum, MIN (*width, natural));
5153 gtk_widget_get_preferred_height_for_width (widget, *width, &minimum, &natural);
5154 *height = MAX (minimum, MIN (*height, natural));
5159 gtk_window_realize (GtkWidget *widget)
5161 GtkAllocation allocation;
5163 GdkWindow *parent_window;
5164 GdkWindow *gdk_window;
5165 GdkWindowAttr attributes;
5166 gint attributes_mask;
5167 GtkWindowPrivate *priv;
5168 GtkStyleContext *context;
5170 window = GTK_WINDOW (widget);
5171 priv = window->priv;
5173 gtk_widget_get_allocation (widget, &allocation);
5175 if (gtk_widget_get_parent_window (widget))
5177 gtk_container_set_resize_mode (GTK_CONTAINER (widget), GTK_RESIZE_PARENT);
5179 gtk_widget_set_realized (widget, TRUE);
5181 attributes.x = allocation.x;
5182 attributes.y = allocation.y;
5183 attributes.width = allocation.width;
5184 attributes.height = allocation.height;
5185 attributes.window_type = GDK_WINDOW_CHILD;
5187 attributes.event_mask = gtk_widget_get_events (widget) | GDK_EXPOSURE_MASK | GDK_STRUCTURE_MASK;
5189 attributes.visual = gtk_widget_get_visual (widget);
5190 attributes.wclass = GDK_INPUT_OUTPUT;
5192 attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL;
5194 gdk_window = gdk_window_new (gtk_widget_get_parent_window (widget),
5195 &attributes, attributes_mask);
5196 gtk_widget_set_window (widget, gdk_window);
5197 gdk_window_set_user_data (gdk_window, widget);
5199 gtk_style_context_set_background (gtk_widget_get_style_context (widget), gdk_window);
5201 gdk_window_enable_synchronized_configure (gdk_window);
5205 gtk_container_set_resize_mode (GTK_CONTAINER (window), GTK_RESIZE_QUEUE);
5207 /* ensure widget tree is properly size allocated */
5208 if (allocation.x == -1 &&
5209 allocation.y == -1 &&
5210 allocation.width == 1 &&
5211 allocation.height == 1)
5217 gtk_window_guess_default_size (window, &allocation.width, &allocation.height);
5218 if (allocation.width == 0 || allocation.height == 0)
5220 /* non-empty window */
5221 allocation.width = 200;
5222 allocation.height = 200;
5224 gtk_widget_size_allocate (widget, &allocation);
5226 _gtk_container_queue_resize (GTK_CONTAINER (widget));
5228 g_return_if_fail (!gtk_widget_get_realized (widget));
5231 gtk_widget_set_realized (widget, TRUE);
5235 case GTK_WINDOW_TOPLEVEL:
5236 attributes.window_type = GDK_WINDOW_TOPLEVEL;
5238 case GTK_WINDOW_POPUP:
5239 attributes.window_type = GDK_WINDOW_TEMP;
5242 g_warning (G_STRLOC": Unknown window type %d!", priv->type);
5246 attributes.title = priv->title;
5247 attributes.wmclass_name = priv->wmclass_name;
5248 attributes.wmclass_class = priv->wmclass_class;
5249 attributes.wclass = GDK_INPUT_OUTPUT;
5250 attributes.visual = gtk_widget_get_visual (widget);
5252 attributes_mask = 0;
5253 parent_window = gtk_widget_get_root_window (widget);
5255 gtk_widget_get_allocation (widget, &allocation);
5256 attributes.width = allocation.width;
5257 attributes.height = allocation.height;
5258 attributes.event_mask = gtk_widget_get_events (widget);
5259 attributes.event_mask |= (GDK_EXPOSURE_MASK |
5260 GDK_KEY_PRESS_MASK |
5261 GDK_KEY_RELEASE_MASK |
5262 GDK_ENTER_NOTIFY_MASK |
5263 GDK_LEAVE_NOTIFY_MASK |
5264 GDK_FOCUS_CHANGE_MASK |
5265 GDK_STRUCTURE_MASK);
5266 attributes.type_hint = priv->type_hint;
5268 attributes_mask |= GDK_WA_VISUAL | GDK_WA_TYPE_HINT;
5269 attributes_mask |= (priv->title ? GDK_WA_TITLE : 0);
5270 attributes_mask |= (priv->wmclass_name ? GDK_WA_WMCLASS : 0);
5272 gdk_window = gdk_window_new (parent_window, &attributes, attributes_mask);
5273 gtk_widget_set_window (widget, gdk_window);
5275 if (priv->opacity_set)
5276 gdk_window_set_opacity (gdk_window, priv->opacity);
5278 gdk_window_enable_synchronized_configure (gdk_window);
5280 gdk_window_set_user_data (gdk_window, window);
5282 context = gtk_widget_get_style_context (widget);
5283 gtk_style_context_set_background (context, gdk_window);
5286 if (priv->transient_parent &&
5287 gtk_widget_get_realized (GTK_WIDGET (priv->transient_parent)))
5288 gdk_window_set_transient_for (gdk_window,
5289 gtk_widget_get_window (GTK_WIDGET (priv->transient_parent)));
5292 gdk_window_set_role (gdk_window, priv->wm_role);
5294 if (!priv->decorated)
5295 gdk_window_set_decorations (gdk_window, 0);
5297 if (!priv->deletable)
5298 gdk_window_set_functions (gdk_window, GDK_FUNC_ALL | GDK_FUNC_CLOSE);
5300 if (gtk_window_get_skip_pager_hint (window))
5301 gdk_window_set_skip_pager_hint (gdk_window, TRUE);
5303 if (gtk_window_get_skip_taskbar_hint (window))
5304 gdk_window_set_skip_taskbar_hint (gdk_window, TRUE);
5306 if (gtk_window_get_accept_focus (window))
5307 gdk_window_set_accept_focus (gdk_window, TRUE);
5309 gdk_window_set_accept_focus (gdk_window, FALSE);
5311 if (gtk_window_get_focus_on_map (window))
5312 gdk_window_set_focus_on_map (gdk_window, TRUE);
5314 gdk_window_set_focus_on_map (gdk_window, FALSE);
5317 gdk_window_set_modal_hint (gdk_window, TRUE);
5319 gdk_window_set_modal_hint (gdk_window, FALSE);
5321 if (priv->startup_id)
5323 #ifdef GDK_WINDOWING_X11
5324 if (GDK_IS_X11_WINDOW (gdk_window))
5326 guint32 timestamp = extract_time_from_startup_id (priv->startup_id);
5327 if (timestamp != GDK_CURRENT_TIME)
5328 gdk_x11_window_set_user_time (gdk_window, timestamp);
5331 if (!startup_id_is_fake (priv->startup_id))
5332 gdk_window_set_startup_id (gdk_window, priv->startup_id);
5335 #ifdef GDK_WINDOWING_X11
5336 if (priv->initial_timestamp != GDK_CURRENT_TIME)
5338 if (GDK_IS_X11_WINDOW (gdk_window))
5339 gdk_x11_window_set_user_time (gdk_window, priv->initial_timestamp);
5344 gtk_window_realize_icon (window);
5346 if (priv->has_resize_grip)
5347 resize_grip_create_window (window);
5351 gtk_window_unrealize (GtkWidget *widget)
5353 GtkWindow *window = GTK_WINDOW (widget);
5354 GtkWindowPrivate *priv = window->priv;
5355 GtkWindowGeometryInfo *info;
5357 /* On unrealize, we reset the size of the window such
5358 * that we will re-apply the default sizing stuff
5359 * next time we show the window.
5361 * Default positioning is reset on unmap, instead of unrealize.
5363 priv->need_default_size = TRUE;
5364 info = gtk_window_get_geometry_info (window, FALSE);
5367 info->resize_width = -1;
5368 info->resize_height = -1;
5369 info->last.configure_request.x = 0;
5370 info->last.configure_request.y = 0;
5371 info->last.configure_request.width = -1;
5372 info->last.configure_request.height = -1;
5373 /* be sure we reset geom hints on re-realize */
5374 info->last.flags = 0;
5378 gtk_window_unrealize_icon (window);
5380 if (priv->grip_window != NULL)
5381 resize_grip_destroy_window (window);
5383 GTK_WIDGET_CLASS (gtk_window_parent_class)->unrealize (widget);
5386 static GtkJunctionSides
5387 get_grip_junction (GtkWidget *widget)
5389 if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_LTR)
5390 return GTK_JUNCTION_CORNER_BOTTOMRIGHT;
5392 return GTK_JUNCTION_CORNER_BOTTOMLEFT;
5396 get_drag_edge (GtkWidget *widget,
5397 GdkWindowEdge *edge)
5399 GtkWindowPrivate *priv = GTK_WINDOW (widget)->priv;
5400 gboolean hresizable;
5401 gboolean vresizable;
5402 GtkTextDirection dir;
5403 GtkWindowGeometryInfo *info;
5408 info = priv->geometry_info;
5411 GdkWindowHints flags = info->last.flags;
5412 GdkGeometry *geometry = &info->last.geometry;
5414 if ((flags & GDK_HINT_MIN_SIZE) && (flags & GDK_HINT_MAX_SIZE))
5416 hresizable = geometry->min_width < geometry->max_width;
5417 vresizable = geometry->min_height < geometry->max_height;
5421 dir = gtk_widget_get_direction (widget);
5423 if (hresizable && vresizable)
5424 *edge = dir == GTK_TEXT_DIR_LTR ? GDK_WINDOW_EDGE_SOUTH_EAST : GDK_WINDOW_EDGE_SOUTH_WEST;
5425 else if (hresizable)
5426 *edge = dir == GTK_TEXT_DIR_LTR ? GDK_WINDOW_EDGE_EAST : GDK_WINDOW_EDGE_WEST;
5427 else if (vresizable)
5428 *edge = GDK_WINDOW_EDGE_SOUTH;
5436 set_grip_cursor (GtkWindow *window)
5438 GtkWidget *widget = GTK_WIDGET (window);
5439 GtkWindowPrivate *priv = window->priv;
5441 if (priv->grip_window == NULL)
5444 if (gtk_widget_is_sensitive (widget))
5447 GdkDisplay *display;
5448 GdkCursorType cursor_type;
5451 cursor_type = GDK_LEFT_PTR;
5453 if (get_drag_edge (widget, &edge))
5457 case GDK_WINDOW_EDGE_EAST:
5458 cursor_type = GDK_RIGHT_SIDE;
5460 case GDK_WINDOW_EDGE_SOUTH_EAST:
5461 cursor_type = GDK_BOTTOM_RIGHT_CORNER;
5463 case GDK_WINDOW_EDGE_SOUTH:
5464 cursor_type = GDK_BOTTOM_SIDE;
5466 case GDK_WINDOW_EDGE_SOUTH_WEST:
5467 cursor_type = GDK_BOTTOM_LEFT_CORNER;
5469 case GDK_WINDOW_EDGE_WEST:
5470 cursor_type = GDK_LEFT_SIDE;
5476 display = gtk_widget_get_display (widget);
5477 cursor = gdk_cursor_new_for_display (display, cursor_type);
5478 gdk_window_set_cursor (priv->grip_window, cursor);
5479 g_object_unref (cursor);
5482 gdk_window_set_cursor (priv->grip_window, NULL);
5486 set_grip_shape (GtkWindow *window)
5488 GtkWindowPrivate *priv = window->priv;
5489 cairo_region_t *region;
5490 cairo_surface_t *surface;
5492 double width, height;
5494 if (priv->grip_window == NULL)
5497 width = gdk_window_get_width (priv->grip_window);
5498 height = gdk_window_get_height (priv->grip_window);
5499 surface = cairo_image_surface_create (CAIRO_FORMAT_A1, width, height);
5501 cr = cairo_create (surface);
5502 cairo_set_source_rgba (cr, 0.0, 0.0, 0.0, 0.0);
5504 cairo_set_source_rgba (cr, 0.0, 0.0, 0.0, 1.0);
5505 if (get_grip_junction (GTK_WIDGET (window)) & GTK_JUNCTION_CORNER_BOTTOMRIGHT)
5507 cairo_move_to (cr, width, 0.0);
5508 cairo_line_to (cr, width, height);
5509 cairo_line_to (cr, 0.0, height);
5513 cairo_move_to (cr, 0.0, 0.0);
5514 cairo_line_to (cr, width, height);
5515 cairo_line_to (cr, 0.0, height);
5517 cairo_close_path (cr);
5520 region = gdk_cairo_region_create_from_surface (surface);
5521 cairo_surface_destroy (surface);
5523 gdk_window_shape_combine_region (priv->grip_window, region, 0, 0);
5524 cairo_region_destroy (region);
5528 set_grip_position (GtkWindow *window)
5530 GtkWindowPrivate *priv = window->priv;
5533 if (priv->grip_window == NULL)
5536 gtk_window_get_resize_grip_area (window, &rect);
5537 gdk_window_raise (priv->grip_window);
5538 gdk_window_move_resize (priv->grip_window,
5540 rect.width, rect.height);
5543 /* _gtk_window_set_allocation:
5544 * @window: a #GtkWindow
5545 * @allocation: the new allocation
5547 * This function is like gtk_widget_set_allocation()
5548 * but does the necessary extra work to update
5549 * the resize grip positioning, etc.
5551 * Call this instead of gtk_widget_set_allocation()
5552 * when overriding ::size_allocate in a GtkWindow
5553 * subclass without chaining up.
5556 _gtk_window_set_allocation (GtkWindow *window,
5557 GtkAllocation *allocation)
5559 GtkWidget *widget = (GtkWidget *)window;
5561 gtk_widget_set_allocation (widget, allocation);
5563 if (gtk_widget_get_realized (widget))
5565 /* If it's not a toplevel we're embedded, we need to resize
5566 * the window's window and skip the grip.
5568 if (!gtk_widget_is_toplevel (widget))
5570 gdk_window_move_resize (gtk_widget_get_window (widget),
5571 allocation->x, allocation->y,
5572 allocation->width, allocation->height);
5576 update_grip_visibility (window);
5577 set_grip_position (window);
5583 gtk_window_size_allocate (GtkWidget *widget,
5584 GtkAllocation *allocation)
5586 GtkWindow *window = GTK_WINDOW (widget);
5587 GtkAllocation child_allocation;
5591 _gtk_window_set_allocation (window, allocation);
5593 child = gtk_bin_get_child (&(window->bin));
5594 if (child && gtk_widget_get_visible (child))
5596 border_width = gtk_container_get_border_width (GTK_CONTAINER (window));
5597 child_allocation.x = border_width;
5598 child_allocation.y = border_width;
5599 child_allocation.width = MAX (1, allocation->width - border_width * 2);
5600 child_allocation.height = MAX (1, allocation->height - border_width * 2);
5602 gtk_widget_size_allocate (child, &child_allocation);
5607 gtk_window_configure_event (GtkWidget *widget,
5608 GdkEventConfigure *event)
5610 GtkAllocation allocation;
5611 GtkWindow *window = GTK_WINDOW (widget);
5612 GtkWindowPrivate *priv = window->priv;
5613 gboolean expected_reply = priv->configure_request_count > 0;
5615 if (!gtk_widget_is_toplevel (GTK_WIDGET (widget)))
5617 if (GTK_WIDGET_CLASS (gtk_window_parent_class)->configure_event)
5618 return GTK_WIDGET_CLASS (gtk_window_parent_class)->configure_event (widget, event);
5620 gdk_window_configure_finished (gtk_widget_get_window (widget));
5624 /* priv->configure_request_count incremented for each
5625 * configure request, and decremented to a min of 0 for
5626 * each configure notify.
5628 * All it means is that we know we will get at least
5629 * priv->configure_request_count more configure notifies.
5630 * We could get more configure notifies than that; some
5631 * of the configure notifies we get may be unrelated to
5632 * the configure requests. But we will get at least
5633 * priv->configure_request_count notifies.
5636 if (priv->configure_request_count > 0)
5638 priv->configure_request_count -= 1;
5639 gdk_window_thaw_toplevel_updates_libgtk_only (gtk_widget_get_window (widget));
5642 /* As an optimization, we avoid a resize when possible.
5644 * The only times we can avoid a resize are:
5645 * - we know only the position changed, not the size
5646 * - we know we have made more requests and so will get more
5647 * notifies and can wait to resize when we get them
5649 gtk_widget_get_allocation (widget, &allocation);
5650 if (!expected_reply &&
5651 (allocation.width == event->width &&
5652 allocation.height == event->height))
5654 gdk_window_configure_finished (gtk_widget_get_window (widget));
5659 * If we do need to resize, we do that by:
5660 * - filling in widget->allocation with the new size
5661 * - setting configure_notify_received to TRUE
5662 * for use in gtk_window_move_resize()
5663 * - queueing a resize, leading to invocation of
5664 * gtk_window_move_resize() in an idle handler
5668 priv->configure_notify_received = TRUE;
5670 allocation.width = event->width;
5671 allocation.height = event->height;
5672 gtk_widget_set_allocation (widget, &allocation);
5674 gdk_window_invalidate_rect (gtk_widget_get_window (widget), NULL, FALSE); // XXX - What was this for again?
5676 _gtk_container_queue_resize (GTK_CONTAINER (widget));
5682 gtk_window_state_event (GtkWidget *widget,
5683 GdkEventWindowState *event)
5685 update_grip_visibility (GTK_WINDOW (widget));
5687 if (event->changed_mask & GDK_WINDOW_STATE_FOCUSED)
5688 ensure_state_flag_backdrop (widget);
5694 gtk_window_direction_changed (GtkWidget *widget,
5695 GtkTextDirection prev_dir)
5697 GtkWindow *window = GTK_WINDOW (widget);
5699 set_grip_cursor (window);
5700 set_grip_position (window);
5701 set_grip_shape (window);
5705 gtk_window_state_changed (GtkWidget *widget,
5706 GtkStateType previous_state)
5708 GtkWindow *window = GTK_WINDOW (widget);
5710 update_grip_visibility (window);
5714 gtk_window_style_updated (GtkWidget *widget)
5716 GtkWindow *window = GTK_WINDOW (widget);
5717 GtkWindowPrivate *priv = window->priv;
5720 GTK_WIDGET_CLASS (gtk_window_parent_class)->style_updated (widget);
5722 if (priv->grip_window != NULL && gtk_window_get_resize_grip_area (window, &rect))
5724 gdk_window_move_resize (priv->grip_window,
5726 rect.width, rect.height);
5728 set_grip_shape (window);
5729 gtk_widget_queue_resize (widget);
5734 resize_grip_create_window (GtkWindow *window)
5737 GtkWindowPrivate *priv;
5738 GdkWindowAttr attributes;
5739 gint attributes_mask;
5741 GdkRGBA transparent = {0, 0, 0, 0};
5743 priv = window->priv;
5744 widget = GTK_WIDGET (window);
5746 g_return_if_fail (gtk_widget_get_realized (widget));
5747 g_return_if_fail (priv->grip_window == NULL);
5749 gtk_window_get_resize_grip_area (window, &rect);
5751 attributes.x = rect.x;
5752 attributes.y = rect.y;
5753 attributes.width = rect.width;
5754 attributes.height = rect.height;
5755 attributes.window_type = GDK_WINDOW_CHILD;
5756 attributes.wclass = GDK_INPUT_OUTPUT;
5757 attributes.event_mask = gtk_widget_get_events (widget) |
5759 GDK_BUTTON_PRESS_MASK;
5761 attributes_mask = GDK_WA_X | GDK_WA_Y;
5763 priv->grip_window = gdk_window_new (gtk_widget_get_window (widget),
5766 gdk_window_set_background_rgba (priv->grip_window, &transparent);
5768 gdk_window_set_user_data (priv->grip_window, widget);
5770 gdk_window_raise (priv->grip_window);
5772 set_grip_shape (window);
5773 update_grip_visibility (window);
5777 resize_grip_destroy_window (GtkWindow *window)
5779 GtkWindowPrivate *priv = window->priv;
5781 gdk_window_set_user_data (priv->grip_window, NULL);
5782 gdk_window_destroy (priv->grip_window);
5783 priv->grip_window = NULL;
5784 update_grip_visibility (window);
5788 * gtk_window_set_has_resize_grip:
5789 * @window: a #GtkWindow
5790 * @value: %TRUE to allow a resize grip
5792 * Sets whether @window has a corner resize grip.
5794 * Note that the resize grip is only shown if the window
5795 * is actually resizable and not maximized. Use
5796 * gtk_window_resize_grip_is_visible() to find out if the
5797 * resize grip is currently shown.
5802 gtk_window_set_has_resize_grip (GtkWindow *window,
5805 GtkWidget *widget = GTK_WIDGET (window);
5806 GtkWindowPrivate *priv = window->priv;
5808 value = value != FALSE;
5810 if (value != priv->has_resize_grip)
5812 priv->has_resize_grip = value;
5813 gtk_widget_queue_draw (widget);
5815 if (gtk_widget_get_realized (widget) &&
5816 gtk_widget_is_toplevel (GTK_WIDGET (widget)))
5818 if (priv->has_resize_grip && priv->grip_window == NULL)
5819 resize_grip_create_window (window);
5820 else if (!priv->has_resize_grip && priv->grip_window != NULL)
5821 resize_grip_destroy_window (window);
5824 g_object_notify (G_OBJECT (window), "has-resize-grip");
5829 update_grip_visibility (GtkWindow *window)
5831 GtkWindowPrivate *priv = window->priv;
5834 val = gtk_window_resize_grip_is_visible (window);
5836 if (priv->grip_window != NULL)
5840 gdk_window_show (priv->grip_window);
5841 set_grip_cursor (window);
5845 gdk_window_hide (priv->grip_window);
5849 if (priv->resize_grip_visible != val)
5851 priv->resize_grip_visible = val;
5853 g_object_notify (G_OBJECT (window), "resize-grip-visible");
5858 * gtk_window_resize_grip_is_visible:
5859 * @window: a #GtkWindow
5861 * Determines whether a resize grip is visible for the specified window.
5863 * Returns: %TRUE if a resize grip exists and is visible
5868 gtk_window_resize_grip_is_visible (GtkWindow *window)
5871 GtkWindowPrivate *priv;
5874 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
5876 priv = window->priv;
5877 widget = GTK_WIDGET (window);
5879 if (priv->type == GTK_WINDOW_POPUP)
5882 if (!priv->resizable)
5885 if (!gtk_widget_is_toplevel (GTK_WIDGET (widget)))
5888 if (gtk_widget_get_realized (widget))
5890 GdkWindowState state;
5892 state = gdk_window_get_state (gtk_widget_get_window (widget));
5894 if (state & GDK_WINDOW_STATE_MAXIMIZED || state & GDK_WINDOW_STATE_FULLSCREEN)
5898 if (!get_drag_edge (widget, &edge))
5901 return window->priv->has_resize_grip;
5905 * gtk_window_get_has_resize_grip:
5906 * @window: a #GtkWindow
5908 * Determines whether the window may have a resize grip.
5910 * Returns: %TRUE if the window has a resize grip
5915 gtk_window_get_has_resize_grip (GtkWindow *window)
5917 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
5919 return window->priv->has_resize_grip;
5923 * gtk_window_get_resize_grip_area:
5924 * @window: a #GtkWindow
5925 * @rect: (out): a pointer to a #GdkRectangle which we should store
5926 * the resize grip area
5928 * If a window has a resize grip, this will retrieve the grip
5929 * position, width and height into the specified #GdkRectangle.
5931 * Returns: %TRUE if the resize grip's area was retrieved
5936 gtk_window_get_resize_grip_area (GtkWindow *window,
5939 GtkWidget *widget = GTK_WIDGET (window);
5940 GtkAllocation allocation;
5944 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
5946 if (!window->priv->has_resize_grip)
5949 gtk_widget_get_allocation (widget, &allocation);
5951 gtk_widget_style_get (widget,
5952 "resize-grip-width", &grip_width,
5953 "resize-grip-height", &grip_height,
5956 if (grip_width > allocation.width)
5957 grip_width = allocation.width;
5959 if (grip_height > allocation.height)
5960 grip_height = allocation.height;
5962 rect->width = grip_width;
5963 rect->height = grip_height;
5964 rect->y = allocation.y + allocation.height - grip_height;
5966 if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_LTR)
5967 rect->x = allocation.x + allocation.width - grip_width;
5969 rect->x = allocation.x;
5974 /* the accel_key and accel_mods fields of the key have to be setup
5975 * upon calling this function. it'll then return whether that key
5976 * is at all used as accelerator, and if so will OR in the
5977 * accel_flags member of the key.
5980 _gtk_window_query_nonaccels (GtkWindow *window,
5982 GdkModifierType accel_mods)
5984 GtkWindowPrivate *priv;
5986 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
5988 priv = window->priv;
5990 /* movement keys are considered locked accels */
5993 static const guint bindings[] = {
5994 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,
5995 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,
5999 for (i = 0; i < G_N_ELEMENTS (bindings); i++)
6000 if (bindings[i] == accel_key)
6004 /* mnemonics are considered locked accels */
6005 if (accel_mods == priv->mnemonic_modifier)
6007 GtkMnemonicHash *mnemonic_hash = gtk_window_get_mnemonic_hash (window, FALSE);
6008 if (mnemonic_hash && _gtk_mnemonic_hash_lookup (mnemonic_hash, accel_key))
6016 * gtk_window_propagate_key_event:
6017 * @window: a #GtkWindow
6018 * @event: a #GdkEventKey
6020 * Propagate a key press or release event to the focus widget and
6021 * up the focus container chain until a widget handles @event.
6022 * This is normally called by the default ::key_press_event and
6023 * ::key_release_event handlers for toplevel windows,
6024 * however in some cases it may be useful to call this directly when
6025 * overriding the standard key handling for a toplevel window.
6027 * Return value: %TRUE if a widget in the focus chain handled the event.
6032 gtk_window_propagate_key_event (GtkWindow *window,
6035 GtkWindowPrivate *priv;
6036 gboolean handled = FALSE;
6037 GtkWidget *widget, *focus;
6039 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
6041 priv = window->priv;
6042 widget = GTK_WIDGET (window);
6044 focus = priv->focus_widget;
6046 g_object_ref (focus);
6049 focus && focus != widget &&
6050 gtk_widget_get_toplevel (focus) == widget)
6054 if (gtk_widget_is_sensitive (focus))
6055 handled = gtk_widget_event (focus, (GdkEvent*) event);
6057 parent = gtk_widget_get_parent (focus);
6059 g_object_ref (parent);
6061 g_object_unref (focus);
6067 g_object_unref (focus);
6073 gtk_window_key_press_event (GtkWidget *widget,
6076 GtkWindow *window = GTK_WINDOW (widget);
6077 gboolean handled = FALSE;
6079 /* handle mnemonics and accelerators */
6081 handled = gtk_window_activate_key (window, event);
6083 /* handle focus widget key events */
6085 handled = gtk_window_propagate_key_event (window, event);
6087 /* Chain up, invokes binding set */
6089 handled = GTK_WIDGET_CLASS (gtk_window_parent_class)->key_press_event (widget, event);
6095 gtk_window_key_release_event (GtkWidget *widget,
6098 GtkWindow *window = GTK_WINDOW (widget);
6099 gboolean handled = FALSE;
6101 /* handle focus widget key events */
6103 handled = gtk_window_propagate_key_event (window, event);
6105 /* Chain up, invokes binding set */
6107 handled = GTK_WIDGET_CLASS (gtk_window_parent_class)->key_release_event (widget, event);
6113 gtk_window_button_press_event (GtkWidget *widget,
6114 GdkEventButton *event)
6116 GtkWindowPrivate *priv = GTK_WINDOW (widget)->priv;
6119 if (event->window == priv->grip_window)
6121 if (get_drag_edge (widget, &edge))
6122 gdk_window_begin_resize_drag_for_device (gtk_widget_get_window (widget),
6124 gdk_event_get_device ((GdkEvent *) event),
6137 gtk_window_real_activate_default (GtkWindow *window)
6139 gtk_window_activate_default (window);
6143 gtk_window_real_activate_focus (GtkWindow *window)
6145 gtk_window_activate_focus (window);
6149 gtk_window_enter_notify_event (GtkWidget *widget,
6150 GdkEventCrossing *event)
6156 gtk_window_leave_notify_event (GtkWidget *widget,
6157 GdkEventCrossing *event)
6163 do_focus_change (GtkWidget *widget,
6167 GdkDeviceManager *device_manager;
6170 g_object_ref (widget);
6172 device_manager = gdk_display_get_device_manager (gtk_widget_get_display (widget));
6173 devices = gdk_device_manager_list_devices (device_manager, GDK_DEVICE_TYPE_MASTER);
6174 devices = g_list_concat (devices, gdk_device_manager_list_devices (device_manager, GDK_DEVICE_TYPE_SLAVE));
6175 devices = g_list_concat (devices, gdk_device_manager_list_devices (device_manager, GDK_DEVICE_TYPE_FLOATING));
6177 for (d = devices; d; d = d->next)
6179 GdkDevice *dev = d->data;
6182 if (gdk_device_get_source (dev) != GDK_SOURCE_KEYBOARD)
6185 /* Skip non-master keyboards that haven't
6186 * selected for events from this window
6188 window = gtk_widget_get_window (widget);
6189 if (gdk_device_get_device_type (dev) != GDK_DEVICE_TYPE_MASTER &&
6190 window && !gdk_window_get_device_events (window, dev))
6193 fevent = gdk_event_new (GDK_FOCUS_CHANGE);
6195 fevent->focus_change.type = GDK_FOCUS_CHANGE;
6196 fevent->focus_change.window = window;
6198 g_object_ref (window);
6199 fevent->focus_change.in = in;
6200 gdk_event_set_device (fevent, dev);
6202 gtk_widget_send_focus_change (widget, fevent);
6204 gdk_event_free (fevent);
6207 g_list_free (devices);
6208 g_object_unref (widget);
6212 maybe_set_mnemonics_visible (GtkWindow *window)
6215 GdkDeviceManager *device_manager;
6217 device_manager = gdk_display_get_device_manager (gtk_widget_get_display (GTK_WIDGET (window)));
6218 devices = gdk_device_manager_list_devices (device_manager, GDK_DEVICE_TYPE_MASTER);
6220 for (d = devices; d; d = d->next)
6222 GdkDevice *dev = d->data;
6224 if (gdk_device_get_source (dev) == GDK_SOURCE_MOUSE)
6226 GdkModifierType mask;
6228 gdk_device_get_state (dev, gtk_widget_get_window (GTK_WIDGET (window)),
6230 if (window->priv->mnemonic_modifier == (mask & gtk_accelerator_get_default_mod_mask ()))
6232 gtk_window_set_mnemonics_visible (window, TRUE);
6238 g_list_free (devices);
6242 gtk_window_focus_in_event (GtkWidget *widget,
6243 GdkEventFocus *event)
6245 GtkWindow *window = GTK_WINDOW (widget);
6246 gboolean auto_mnemonics;
6248 /* It appears spurious focus in events can occur when
6249 * the window is hidden. So we'll just check to see if
6250 * the window is visible before actually handling the
6253 if (gtk_widget_get_visible (widget))
6255 _gtk_window_set_has_toplevel_focus (window, TRUE);
6256 _gtk_window_set_is_active (window, TRUE);
6258 g_object_get (gtk_widget_get_settings (widget),
6259 "gtk-auto-mnemonics", &auto_mnemonics, NULL);
6261 maybe_set_mnemonics_visible (window);
6268 gtk_window_focus_out_event (GtkWidget *widget,
6269 GdkEventFocus *event)
6271 GtkWindow *window = GTK_WINDOW (widget);
6272 gboolean auto_mnemonics;
6274 _gtk_window_set_has_toplevel_focus (window, FALSE);
6275 _gtk_window_set_is_active (window, FALSE);
6277 /* set the mnemonic-visible property to false */
6278 g_object_get (gtk_widget_get_settings (widget),
6279 "gtk-auto-mnemonics", &auto_mnemonics, NULL);
6281 gtk_window_set_mnemonics_visible (window, FALSE);
6287 gtk_window_check_resize (GtkContainer *container)
6289 /* If the window is not toplevel anymore than it's embedded somewhere,
6290 * so handle it like a normal window */
6291 if (!gtk_widget_is_toplevel (GTK_WIDGET (container)))
6292 GTK_CONTAINER_CLASS (gtk_window_parent_class)->check_resize (container);
6293 else if (gtk_widget_get_visible (GTK_WIDGET (container)))
6294 gtk_window_move_resize (GTK_WINDOW (container));
6298 gtk_window_focus (GtkWidget *widget,
6299 GtkDirectionType direction)
6301 GtkWindowPrivate *priv;
6304 GtkContainer *container;
6306 GtkWidget *old_focus_child;
6309 if (!gtk_widget_is_toplevel (GTK_WIDGET (widget)))
6310 return GTK_WIDGET_CLASS (gtk_window_parent_class)->focus (widget, direction);
6312 container = GTK_CONTAINER (widget);
6313 window = GTK_WINDOW (widget);
6314 priv = window->priv;
6315 bin = GTK_BIN (widget);
6317 old_focus_child = gtk_container_get_focus_child (container);
6319 /* We need a special implementation here to deal properly with wrapping
6320 * around in the tab chain without the danger of going into an
6323 if (old_focus_child)
6325 if (gtk_widget_child_focus (old_focus_child, direction))
6329 if (priv->focus_widget)
6331 if (direction == GTK_DIR_LEFT ||
6332 direction == GTK_DIR_RIGHT ||
6333 direction == GTK_DIR_UP ||
6334 direction == GTK_DIR_DOWN)
6339 /* Wrapped off the end, clear the focus setting for the toplpevel */
6340 parent = gtk_widget_get_parent (priv->focus_widget);
6343 gtk_container_set_focus_child (GTK_CONTAINER (parent), NULL);
6344 parent = gtk_widget_get_parent (parent);
6347 gtk_window_set_focus (GTK_WINDOW (container), NULL);
6350 /* Now try to focus the first widget in the window */
6351 child = gtk_bin_get_child (bin);
6354 if (gtk_widget_child_focus (child, direction))
6362 gtk_window_move_focus (GtkWidget *widget,
6363 GtkDirectionType dir)
6365 if (!gtk_widget_is_toplevel (GTK_WIDGET (widget)))
6367 GTK_WIDGET_CLASS (gtk_window_parent_class)->move_focus (widget, dir);
6371 gtk_widget_child_focus (widget, dir);
6373 if (! gtk_container_get_focus_child (GTK_CONTAINER (widget)))
6374 gtk_window_set_focus (GTK_WINDOW (widget), NULL);
6378 gtk_window_real_set_focus (GtkWindow *window,
6381 GtkWindowPrivate *priv = window->priv;
6382 GtkWidget *old_focus = priv->focus_widget;
6383 gboolean had_default = FALSE;
6384 gboolean focus_had_default = FALSE;
6385 gboolean old_focus_had_default = FALSE;
6389 g_object_ref (old_focus);
6390 g_object_freeze_notify (G_OBJECT (old_focus));
6391 old_focus_had_default = gtk_widget_has_default (old_focus);
6395 g_object_ref (focus);
6396 g_object_freeze_notify (G_OBJECT (focus));
6397 focus_had_default = gtk_widget_has_default (focus);
6400 if (priv->default_widget)
6401 had_default = gtk_widget_has_default (priv->default_widget);
6403 if (priv->focus_widget)
6405 if (gtk_widget_get_receives_default (priv->focus_widget) &&
6406 (priv->focus_widget != priv->default_widget))
6408 _gtk_widget_set_has_default (priv->focus_widget, FALSE);
6409 gtk_widget_queue_draw (priv->focus_widget);
6411 if (priv->default_widget)
6412 _gtk_widget_set_has_default (priv->default_widget, TRUE);
6415 priv->focus_widget = NULL;
6417 if (priv->has_focus)
6418 do_focus_change (old_focus, FALSE);
6420 g_object_notify (G_OBJECT (old_focus), "is-focus");
6423 /* The above notifications may have set a new focus widget,
6424 * if so, we don't want to override it.
6426 if (focus && !priv->focus_widget)
6428 priv->focus_widget = focus;
6430 if (gtk_widget_get_receives_default (priv->focus_widget) &&
6431 (priv->focus_widget != priv->default_widget))
6433 if (gtk_widget_get_can_default (priv->focus_widget))
6434 _gtk_widget_set_has_default (priv->focus_widget, TRUE);
6436 if (priv->default_widget)
6437 _gtk_widget_set_has_default (priv->default_widget, FALSE);
6440 if (priv->has_focus)
6441 do_focus_change (priv->focus_widget, TRUE);
6443 g_object_notify (G_OBJECT (priv->focus_widget), "is-focus");
6446 /* If the default widget changed, a redraw will have been queued
6447 * on the old and new default widgets by gtk_window_set_default(), so
6448 * we only have to worry about the case where it didn't change.
6449 * We'll sometimes queue a draw twice on the new widget but that
6452 if (priv->default_widget &&
6453 (had_default != gtk_widget_has_default (priv->default_widget)))
6454 gtk_widget_queue_draw (priv->default_widget);
6458 if (old_focus_had_default != gtk_widget_has_default (old_focus))
6459 gtk_widget_queue_draw (old_focus);
6461 g_object_thaw_notify (G_OBJECT (old_focus));
6462 g_object_unref (old_focus);
6466 if (focus_had_default != gtk_widget_has_default (focus))
6467 gtk_widget_queue_draw (focus);
6469 g_object_thaw_notify (G_OBJECT (focus));
6470 g_object_unref (focus);
6476 gtk_window_get_preferred_width (GtkWidget *widget,
6484 window = GTK_WINDOW (widget);
6485 child = gtk_bin_get_child (GTK_BIN (window));
6487 border_width = gtk_container_get_border_width (GTK_CONTAINER (window));
6488 *minimum_size = border_width * 2;
6489 *natural_size = border_width * 2;
6491 if (child && gtk_widget_get_visible (child))
6493 gint child_min, child_nat;
6494 gtk_widget_get_preferred_width (child, &child_min, &child_nat);
6496 *minimum_size += child_min;
6497 *natural_size += child_nat;
6502 gtk_window_get_preferred_height (GtkWidget *widget,
6510 window = GTK_WINDOW (widget);
6511 child = gtk_bin_get_child (GTK_BIN (window));
6513 border_width = gtk_container_get_border_width (GTK_CONTAINER (window));
6514 *minimum_size = border_width * 2;
6515 *natural_size = border_width * 2;
6517 if (child && gtk_widget_get_visible (child))
6519 gint child_min, child_nat;
6520 gtk_widget_get_preferred_height (child, &child_min, &child_nat);
6522 *minimum_size += child_min;
6523 *natural_size += child_nat;
6529 * _gtk_window_unset_focus_and_default:
6530 * @window: a #GtkWindow
6531 * @widget: a widget inside of @window
6533 * Checks whether the focus and default widgets of @window are
6534 * @widget or a descendent of @widget, and if so, unset them.
6537 _gtk_window_unset_focus_and_default (GtkWindow *window,
6541 GtkWindowPrivate *priv = window->priv;
6545 g_object_ref (window);
6546 g_object_ref (widget);
6548 parent = gtk_widget_get_parent (widget);
6549 if (gtk_container_get_focus_child (GTK_CONTAINER (parent)) == widget)
6551 child = priv->focus_widget;
6553 while (child && child != widget)
6554 child = gtk_widget_get_parent (child);
6556 if (child == widget)
6557 gtk_window_set_focus (GTK_WINDOW (window), NULL);
6560 child = priv->default_widget;
6562 while (child && child != widget)
6563 child = gtk_widget_get_parent (child);
6565 if (child == widget)
6566 gtk_window_set_default (window, NULL);
6568 g_object_unref (widget);
6569 g_object_unref (window);
6572 /*********************************
6573 * Functions related to resizing *
6574 *********************************/
6577 geometry_size_to_pixels (GdkGeometry *geometry,
6582 gint base_width = 0;
6583 gint base_height = 0;
6585 gint min_height = 0;
6587 gint height_inc = 1;
6589 if (flags & GDK_HINT_BASE_SIZE)
6591 base_width = geometry->base_width;
6592 base_height = geometry->base_height;
6594 if (flags & GDK_HINT_MIN_SIZE)
6596 min_width = geometry->min_width;
6597 min_height = geometry->min_height;
6599 if (flags & GDK_HINT_RESIZE_INC)
6601 width_inc = geometry->width_inc;
6602 height_inc = geometry->height_inc;
6606 *width = MAX (*width * width_inc + base_width, min_width);
6608 *height = MAX (*height * height_inc + base_height, min_height);
6611 /* This function doesn't constrain to geometry hints */
6613 gtk_window_compute_configure_request_size (GtkWindow *window,
6614 GdkGeometry *geometry,
6619 GtkWindowPrivate *priv = window->priv;
6620 GtkWindowGeometryInfo *info;
6623 * - we've done a size request
6626 info = gtk_window_get_geometry_info (window, FALSE);
6628 if (priv->need_default_size)
6630 gtk_window_guess_default_size (window, width, height);
6632 /* If window is empty so requests 0, default to random nonzero size */
6633 if (*width == 0 && *height == 0)
6639 /* Override with default size */
6643 if (info->default_width > 0)
6644 *width = info->default_width;
6645 if (info->default_height > 0)
6646 *height = info->default_height;
6648 if (info->default_is_geometry)
6649 geometry_size_to_pixels (geometry, flags,
6650 info->default_width > 0 ? width : NULL,
6651 info->default_height > 0 ? height : NULL);
6656 GtkAllocation allocation;
6658 gtk_widget_get_allocation (GTK_WIDGET (window), &allocation);
6660 /* Default to keeping current size */
6661 *width = allocation.width;
6662 *height = allocation.height;
6665 /* Override any size with gtk_window_resize() values */
6668 if (info->resize_width > 0)
6669 *width = info->resize_width;
6670 if (info->resize_height > 0)
6671 *height = info->resize_height;
6673 if (info->resize_is_geometry)
6674 geometry_size_to_pixels (geometry, flags,
6675 info->resize_width > 0 ? width : NULL,
6676 info->resize_height > 0 ? height : NULL);
6679 /* Don't ever request zero width or height, its not supported by
6680 gdk. The size allocation code will round it to 1 anyway but if
6681 we do it then the value returned from this function will is
6682 not comparable to the size allocation read from the GtkWindow. */
6683 *width = MAX (*width, 1);
6684 *height = MAX (*height, 1);
6687 static GtkWindowPosition
6688 get_effective_position (GtkWindow *window)
6690 GtkWindowPrivate *priv = window->priv;
6691 GtkWindowPosition pos = priv->position;
6693 if (pos == GTK_WIN_POS_CENTER_ON_PARENT &&
6694 (priv->transient_parent == NULL ||
6695 !gtk_widget_get_mapped (GTK_WIDGET (priv->transient_parent))))
6696 pos = GTK_WIN_POS_NONE;
6702 get_center_monitor_of_window (GtkWindow *window)
6704 /* We could try to sort out the relative positions of the monitors and
6705 * stuff, or we could just be losers and assume you have a row
6706 * or column of monitors.
6708 return gdk_screen_get_n_monitors (gtk_window_check_screen (window)) / 2;
6712 get_monitor_containing_pointer (GtkWindow *window)
6716 GdkScreen *window_screen;
6717 GdkScreen *pointer_screen;
6718 GdkDisplay *display;
6719 GdkDeviceManager *device_manager;
6722 window_screen = gtk_window_check_screen (window);
6723 display = gdk_screen_get_display (window_screen);
6724 device_manager = gdk_display_get_device_manager (display);
6725 pointer = gdk_device_manager_get_client_pointer (device_manager);
6727 gdk_device_get_position (pointer,
6731 if (pointer_screen == window_screen)
6732 monitor_num = gdk_screen_get_monitor_at_point (pointer_screen, px, py);
6740 center_window_on_monitor (GtkWindow *window,
6746 GdkRectangle monitor;
6749 monitor_num = get_monitor_containing_pointer (window);
6751 if (monitor_num == -1)
6752 monitor_num = get_center_monitor_of_window (window);
6754 gdk_screen_get_monitor_workarea (gtk_window_check_screen (window),
6755 monitor_num, &monitor);
6757 *x = (monitor.width - w) / 2 + monitor.x;
6758 *y = (monitor.height - h) / 2 + monitor.y;
6760 /* Be sure we aren't off the monitor, ignoring _NET_WM_STRUT
6761 * and WM decorations.
6775 if (extent > clamp_extent)
6777 *base = clamp_base + clamp_extent/2 - extent/2;
6778 else if (*base < clamp_base)
6780 else if (*base + extent > clamp_base + clamp_extent)
6781 *base = clamp_base + clamp_extent - extent;
6785 clamp_window_to_rectangle (gint *x,
6789 const GdkRectangle *rect)
6791 #ifdef DEBUGGING_OUTPUT
6792 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);
6795 /* If it is too large, center it. If it fits on the monitor but is
6796 * partially outside, move it to the closest edge. Do this
6797 * separately in x and y directions.
6799 clamp (x, w, rect->x, rect->width);
6800 clamp (y, h, rect->y, rect->height);
6801 #ifdef DEBUGGING_OUTPUT
6802 g_print (" ==> %+d%+d: %dx%d\n", *x, *y, w, h);
6808 gtk_window_compute_configure_request (GtkWindow *window,
6809 GdkRectangle *request,
6810 GdkGeometry *geometry,
6813 GtkWindowPrivate *priv = window->priv;
6814 GdkGeometry new_geometry;
6817 GtkWindowPosition pos;
6818 GtkWidget *parent_widget;
6819 GtkWindowGeometryInfo *info;
6823 screen = gtk_window_check_screen (window);
6825 gtk_window_compute_hints (window, &new_geometry, &new_flags);
6826 gtk_window_compute_configure_request_size (window,
6827 &new_geometry, new_flags,
6830 gtk_window_constrain_size (window,
6831 &new_geometry, new_flags,
6835 parent_widget = (GtkWidget*) priv->transient_parent;
6837 pos = get_effective_position (window);
6838 info = gtk_window_get_geometry_info (window, FALSE);
6840 /* by default, don't change position requested */
6843 x = info->last.configure_request.x;
6844 y = info->last.configure_request.y;
6853 if (priv->need_default_position)
6856 /* FIXME this all interrelates with window gravity.
6857 * For most of them I think we want to set GRAVITY_CENTER.
6859 * Not sure how to go about that.
6863 /* here we are only handling CENTER_ALWAYS
6864 * as it relates to default positioning,
6865 * where it's equivalent to simply CENTER
6867 case GTK_WIN_POS_CENTER_ALWAYS:
6868 case GTK_WIN_POS_CENTER:
6869 center_window_on_monitor (window, w, h, &x, &y);
6872 case GTK_WIN_POS_CENTER_ON_PARENT:
6874 GtkAllocation allocation;
6875 GdkWindow *gdk_window;
6877 GdkRectangle monitor;
6880 g_assert (gtk_widget_get_mapped (parent_widget)); /* established earlier */
6882 gdk_window = gtk_widget_get_window (parent_widget);
6884 if (gdk_window != NULL)
6885 monitor_num = gdk_screen_get_monitor_at_window (screen,
6890 gdk_window_get_origin (gdk_window,
6893 gtk_widget_get_allocation (parent_widget, &allocation);
6894 x = ox + (allocation.width - w) / 2;
6895 y = oy + (allocation.height - h) / 2;
6897 /* Clamp onto current monitor, ignoring _NET_WM_STRUT and
6898 * WM decorations. If parent wasn't on a monitor, just
6901 if (monitor_num >= 0)
6903 gdk_screen_get_monitor_geometry (screen, monitor_num, &monitor);
6904 clamp_window_to_rectangle (&x, &y, w, h, &monitor);
6909 case GTK_WIN_POS_MOUSE:
6911 gint screen_width = gdk_screen_get_width (screen);
6912 gint screen_height = gdk_screen_get_height (screen);
6914 GdkRectangle monitor;
6915 GdkDisplay *display;
6916 GdkDeviceManager *device_manager;
6918 GdkScreen *pointer_screen;
6921 display = gdk_screen_get_display (screen);
6922 device_manager = gdk_display_get_device_manager (display);
6923 pointer = gdk_device_manager_get_client_pointer (device_manager);
6925 gdk_device_get_position (pointer,
6929 if (pointer_screen == screen)
6930 monitor_num = gdk_screen_get_monitor_at_point (screen, px, py);
6936 x = CLAMP (x, 0, screen_width - w);
6937 y = CLAMP (y, 0, screen_height - h);
6939 /* Clamp onto current monitor, ignoring _NET_WM_STRUT and
6940 * WM decorations. Don't try to figure out what's going
6941 * on if the mouse wasn't inside a monitor.
6943 if (monitor_num >= 0)
6945 gdk_screen_get_monitor_geometry (screen, monitor_num, &monitor);
6946 clamp_window_to_rectangle (&x, &y, w, h, &monitor);
6954 } /* if (priv->need_default_position) */
6956 if (priv->need_default_position && info &&
6957 info->initial_pos_set)
6959 x = info->initial_x;
6960 y = info->initial_y;
6961 gtk_window_constrain_position (window, w, h, &x, &y);
6967 request->height = h;
6970 *geometry = new_geometry;
6976 gtk_window_constrain_position (GtkWindow *window,
6982 GtkWindowPrivate *priv = window->priv;
6984 /* See long comments in gtk_window_move_resize()
6985 * on when it's safe to call this function.
6987 if (priv->position == GTK_WIN_POS_CENTER_ALWAYS)
6989 gint center_x, center_y;
6991 center_window_on_monitor (window, new_width, new_height, ¢er_x, ¢er_y);
6999 gtk_window_move_resize (GtkWindow *window)
7003 * First we determine whether any information has changed that would
7004 * cause us to revise our last configure request. If we would send
7005 * a different configure request from last time, then
7006 * configure_request_size_changed = TRUE or
7007 * configure_request_pos_changed = TRUE. configure_request_size_changed
7008 * may be true due to new hints, a gtk_window_resize(), or whatever.
7009 * configure_request_pos_changed may be true due to gtk_window_set_position()
7010 * or gtk_window_move().
7012 * If the configure request has changed, we send off a new one. To
7013 * ensure GTK+ invariants are maintained (resize queue does what it
7014 * should), we go ahead and size_allocate the requested size in this
7017 * If the configure request has not changed, we don't ever resend
7018 * it, because it could mean fighting the user or window manager.
7021 * To prepare the configure request, we come up with a base size/pos:
7022 * - the one from gtk_window_move()/gtk_window_resize()
7023 * - else default_width, default_height if we haven't ever
7025 * - else the size request if we haven't ever been mapped,
7026 * as a substitute default size
7027 * - else the current size of the window, as received from
7028 * configure notifies (i.e. the current allocation)
7030 * If GTK_WIN_POS_CENTER_ALWAYS is active, we constrain
7031 * the position request to be centered.
7033 GtkWindowPrivate *priv = window->priv;
7034 GtkAllocation allocation;
7036 GtkContainer *container;
7037 GtkWindowGeometryInfo *info;
7038 GdkGeometry new_geometry;
7039 GdkWindow *gdk_window;
7041 GdkRectangle new_request;
7042 gboolean configure_request_size_changed;
7043 gboolean configure_request_pos_changed;
7044 gboolean hints_changed; /* do we need to send these again */
7045 GtkWindowLastGeometryInfo saved_last_info;
7047 widget = GTK_WIDGET (window);
7049 gdk_window = gtk_widget_get_window (widget);
7050 container = GTK_CONTAINER (widget);
7051 info = gtk_window_get_geometry_info (window, TRUE);
7053 configure_request_size_changed = FALSE;
7054 configure_request_pos_changed = FALSE;
7056 gtk_window_compute_configure_request (window, &new_request,
7057 &new_geometry, &new_flags);
7059 /* This check implies the invariant that we never set info->last
7060 * without setting the hints and sending off a configure request.
7062 * If we change info->last without sending the request, we may
7065 if (info->last.configure_request.x != new_request.x ||
7066 info->last.configure_request.y != new_request.y)
7067 configure_request_pos_changed = TRUE;
7069 if ((info->last.configure_request.width != new_request.width ||
7070 info->last.configure_request.height != new_request.height))
7071 configure_request_size_changed = TRUE;
7073 hints_changed = FALSE;
7075 if (!gtk_window_compare_hints (&info->last.geometry, info->last.flags,
7076 &new_geometry, new_flags))
7078 hints_changed = TRUE;
7081 /* Position Constraints
7082 * ====================
7084 * POS_CENTER_ALWAYS is conceptually a constraint rather than
7085 * a default. The other POS_ values are used only when the
7086 * window is shown, not after that.
7088 * However, we can't implement a position constraint as
7089 * "anytime the window size changes, center the window"
7090 * because this may well end up fighting the WM or user. In
7091 * fact it gets in an infinite loop with at least one WM.
7093 * Basically, applications are in no way in a position to
7094 * constrain the position of a window, with one exception:
7095 * override redirect windows. (Really the intended purpose
7096 * of CENTER_ALWAYS anyhow, I would think.)
7098 * So the way we implement this "constraint" is to say that when WE
7099 * cause a move or resize, i.e. we make a configure request changing
7100 * window size, we recompute the CENTER_ALWAYS position to reflect
7101 * the new window size, and include it in our request. Also, if we
7102 * just turned on CENTER_ALWAYS we snap to center with a new
7103 * request. Otherwise, if we are just NOTIFIED of a move or resize
7104 * done by someone else e.g. the window manager, we do NOT send a
7105 * new configure request.
7107 * For override redirect windows, this works fine; all window
7108 * sizes are from our configure requests. For managed windows,
7109 * it is at least semi-sane, though who knows what the
7110 * app author is thinking.
7113 /* This condition should be kept in sync with the condition later on
7114 * that determines whether we send a configure request. i.e. we
7115 * should do this position constraining anytime we were going to
7116 * send a configure request anyhow, plus when constraints have
7119 if (configure_request_pos_changed ||
7120 configure_request_size_changed ||
7122 info->position_constraints_changed)
7124 /* We request the constrained position if:
7125 * - we were changing position, and need to clamp
7126 * the change to the constraint
7127 * - we're changing the size anyway
7128 * - set_position() was called to toggle CENTER_ALWAYS on
7131 gtk_window_constrain_position (window,
7137 /* Update whether we need to request a move */
7138 if (info->last.configure_request.x != new_request.x ||
7139 info->last.configure_request.y != new_request.y)
7140 configure_request_pos_changed = TRUE;
7142 configure_request_pos_changed = FALSE;
7146 if (priv->type == GTK_WINDOW_TOPLEVEL)
7148 int notify_x, notify_y;
7150 /* this is the position from the last configure notify */
7151 gdk_window_get_position (widget->window, ¬ify_x, ¬ify_y);
7153 g_message ("--- %s ---\n"
7154 "last : %d,%d\t%d x %d\n"
7155 "this : %d,%d\t%d x %d\n"
7156 "alloc : %d,%d\t%d x %d\n"
7158 "resize: \t%d x %d\n"
7159 "size_changed: %d pos_changed: %d hints_changed: %d\n"
7160 "configure_notify_received: %d\n"
7161 "configure_request_count: %d\n"
7162 "position_constraints_changed: %d\n",
7163 priv->title ? priv->title : "(no title)",
7164 info->last.configure_request.x,
7165 info->last.configure_request.y,
7166 info->last.configure_request.width,
7167 info->last.configure_request.height,
7173 widget->allocation.width,
7174 widget->allocation.height,
7175 widget->requisition.width,
7176 widget->requisition.height,
7178 info->resize_height,
7179 configure_request_pos_changed,
7180 configure_request_size_changed,
7182 priv->configure_notify_received,
7183 priv->configure_request_count,
7184 info->position_constraints_changed);
7188 saved_last_info = info->last;
7189 info->last.geometry = new_geometry;
7190 info->last.flags = new_flags;
7191 info->last.configure_request = new_request;
7193 /* need to set PPosition so the WM will look at our position,
7194 * but we don't want to count PPosition coming and going as a hints
7195 * change for future iterations. So we saved info->last prior to
7199 /* Also, if the initial position was explicitly set, then we always
7200 * toggle on PPosition. This makes gtk_window_move(window, 0, 0)
7204 /* Also, we toggle on PPosition if GTK_WIN_POS_ is in use and
7205 * this is an initial map
7208 if ((configure_request_pos_changed ||
7209 info->initial_pos_set ||
7210 (priv->need_default_position &&
7211 get_effective_position (window) != GTK_WIN_POS_NONE)) &&
7212 (new_flags & GDK_HINT_POS) == 0)
7214 new_flags |= GDK_HINT_POS;
7215 hints_changed = TRUE;
7218 /* Set hints if necessary
7221 gdk_window_set_geometry_hints (gdk_window,
7225 gtk_widget_get_allocation (widget, &allocation);
7227 /* handle resizing/moving and widget tree allocation
7229 if (priv->configure_notify_received)
7231 /* If we have received a configure event since
7232 * the last time in this function, we need to
7233 * accept our new size and size_allocate child widgets.
7234 * (see gtk_window_configure_event() for more details).
7236 * 1 or more configure notifies may have been received.
7237 * Also, configure_notify_received will only be TRUE
7238 * if all expected configure notifies have been received
7239 * (one per configure request), as an optimization.
7242 priv->configure_notify_received = FALSE;
7244 /* gtk_window_configure_event() filled in widget->allocation */
7245 gtk_widget_size_allocate (widget, &allocation);
7247 set_grip_position (window);
7248 update_grip_visibility (window);
7250 gdk_window_process_updates (gdk_window, TRUE);
7252 gdk_window_configure_finished (gdk_window);
7254 /* If the configure request changed, it means that
7256 * 1) coincidentally changed hints or widget properties
7257 * impacting the configure request before getting
7258 * a configure notify, or
7259 * 2) some broken widget is changing its size request
7260 * during size allocation, resulting in
7261 * a false appearance of changed configure request.
7263 * For 1), we could just go ahead and ask for the
7264 * new size right now, but doing that for 2)
7265 * might well be fighting the user (and can even
7266 * trigger a loop). Since we really don't want to
7267 * do that, we requeue a resize in hopes that
7268 * by the time it gets handled, the child has seen
7269 * the light and is willing to go along with the
7270 * new size. (this happens for the zvt widget, since
7271 * the size_allocate() above will have stored the
7272 * requisition corresponding to the new size in the
7275 * This doesn't buy us anything for 1), but it shouldn't
7276 * hurt us too badly, since it is what would have
7277 * happened if we had gotten the configure event before
7278 * the new size had been set.
7281 if (configure_request_size_changed ||
7282 configure_request_pos_changed)
7284 /* Don't change the recorded last info after all, because we
7285 * haven't actually updated to the new info yet - we decided
7286 * to postpone our configure request until later.
7288 info->last = saved_last_info;
7290 gtk_widget_queue_resize_no_redraw (widget); /* migth recurse for GTK_RESIZE_IMMEDIATE */
7293 return; /* Bail out, we didn't really process the move/resize */
7295 else if ((configure_request_size_changed || hints_changed) &&
7296 (allocation.width != new_request.width || allocation.height != new_request.height))
7299 /* We are in one of the following situations:
7300 * A. configure_request_size_changed
7301 * our requisition has changed and we need a different window size,
7302 * so we request it from the window manager.
7303 * B. !configure_request_size_changed && hints_changed
7304 * the window manager rejects our size, but we have just changed the
7305 * window manager hints, so there's a chance our request will
7306 * be honoured this time, so we try again.
7308 * However, if the new requisition is the same as the current allocation,
7309 * we don't request it again, since we won't get a ConfigureNotify back from
7310 * the window manager unless it decides to change our requisition. If
7311 * we don't get the ConfigureNotify back, the resize queue will never be run.
7314 /* Now send the configure request */
7315 if (configure_request_pos_changed)
7317 gdk_window_move_resize (gdk_window,
7318 new_request.x, new_request.y,
7319 new_request.width, new_request.height);
7321 else /* only size changed */
7323 gdk_window_resize (gdk_window,
7324 new_request.width, new_request.height);
7327 if (priv->type == GTK_WINDOW_POPUP)
7329 GtkAllocation allocation;
7331 /* Directly size allocate for override redirect (popup) windows. */
7334 allocation.width = new_request.width;
7335 allocation.height = new_request.height;
7337 gtk_widget_size_allocate (widget, &allocation);
7339 gdk_window_process_updates (gdk_window, TRUE);
7341 if (gtk_container_get_resize_mode (container) == GTK_RESIZE_QUEUE)
7342 gtk_widget_queue_draw (widget);
7346 /* Increment the number of have-not-yet-received-notify requests */
7347 priv->configure_request_count += 1;
7348 gdk_window_freeze_toplevel_updates_libgtk_only (gdk_window);
7350 /* for GTK_RESIZE_QUEUE toplevels, we are now awaiting a new
7351 * configure event in response to our resizing request.
7352 * the configure event will cause a new resize with
7353 * ->configure_notify_received=TRUE.
7354 * until then, we want to
7355 * - discard expose events
7356 * - coalesce resizes for our children
7357 * - defer any window resizes until the configure event arrived
7358 * to achieve this, we queue a resize for the window, but remove its
7359 * resizing handler, so resizing will not be handled from the next
7360 * idle handler but when the configure event arrives.
7362 * FIXME: we should also dequeue the pending redraws here, since
7363 * we handle those ourselves upon ->configure_notify_received==TRUE.
7365 if (gtk_container_get_resize_mode (container) == GTK_RESIZE_QUEUE)
7367 gtk_widget_queue_resize_no_redraw (widget);
7368 _gtk_container_dequeue_resize_handler (container);
7374 /* Handle any position changes.
7376 if (configure_request_pos_changed)
7378 gdk_window_move (gdk_window,
7379 new_request.x, new_request.y);
7382 /* And run the resize queue.
7384 gtk_container_resize_children (container);
7387 /* We have now processed a move/resize since the last position
7388 * constraint change, setting of the initial position, or resize.
7389 * (Not resetting these flags here can lead to infinite loops for
7390 * GTK_RESIZE_IMMEDIATE containers)
7392 info->position_constraints_changed = FALSE;
7393 info->initial_pos_set = FALSE;
7394 info->resize_width = -1;
7395 info->resize_height = -1;
7398 /* Compare two sets of Geometry hints for equality.
7401 gtk_window_compare_hints (GdkGeometry *geometry_a,
7403 GdkGeometry *geometry_b,
7406 if (flags_a != flags_b)
7409 if ((flags_a & GDK_HINT_MIN_SIZE) &&
7410 (geometry_a->min_width != geometry_b->min_width ||
7411 geometry_a->min_height != geometry_b->min_height))
7414 if ((flags_a & GDK_HINT_MAX_SIZE) &&
7415 (geometry_a->max_width != geometry_b->max_width ||
7416 geometry_a->max_height != geometry_b->max_height))
7419 if ((flags_a & GDK_HINT_BASE_SIZE) &&
7420 (geometry_a->base_width != geometry_b->base_width ||
7421 geometry_a->base_height != geometry_b->base_height))
7424 if ((flags_a & GDK_HINT_ASPECT) &&
7425 (geometry_a->min_aspect != geometry_b->min_aspect ||
7426 geometry_a->max_aspect != geometry_b->max_aspect))
7429 if ((flags_a & GDK_HINT_RESIZE_INC) &&
7430 (geometry_a->width_inc != geometry_b->width_inc ||
7431 geometry_a->height_inc != geometry_b->height_inc))
7434 if ((flags_a & GDK_HINT_WIN_GRAVITY) &&
7435 geometry_a->win_gravity != geometry_b->win_gravity)
7442 _gtk_window_constrain_size (GtkWindow *window,
7448 GtkWindowPrivate *priv;
7449 GtkWindowGeometryInfo *info;
7451 g_return_if_fail (GTK_IS_WINDOW (window));
7453 priv = window->priv;
7455 info = priv->geometry_info;
7458 GdkWindowHints flags = info->last.flags;
7459 GdkGeometry *geometry = &info->last.geometry;
7461 gtk_window_constrain_size (window,
7472 gtk_window_constrain_size (GtkWindow *window,
7473 GdkGeometry *geometry,
7480 gdk_window_constrain_size (geometry, flags, width, height,
7481 new_width, new_height);
7484 /* Compute the set of geometry hints and flags for a window
7485 * based on the application set geometry, and requisition
7486 * of the window. gtk_widget_get_preferred_size() must have been
7490 gtk_window_compute_hints (GtkWindow *window,
7491 GdkGeometry *new_geometry,
7494 GtkWindowPrivate *priv = window->priv;
7496 gint extra_width = 0;
7497 gint extra_height = 0;
7498 GtkWindowGeometryInfo *geometry_info;
7499 GtkRequisition requisition;
7501 widget = GTK_WIDGET (window);
7503 gtk_widget_get_preferred_size (widget, &requisition, NULL);
7504 geometry_info = gtk_window_get_geometry_info (GTK_WINDOW (widget), FALSE);
7508 *new_flags = geometry_info->mask;
7509 *new_geometry = geometry_info->geometry;
7516 if (geometry_info && geometry_info->widget)
7518 /* If the geometry widget is set, then the hints really apply to that
7519 * widget. This is pretty much meaningless unless the window layout
7520 * is such that the rest of the window adds fixed size borders to
7521 * the geometry widget. Our job is to figure the size of the borders;
7522 * We do that by asking how big the toplevel would be if the
7523 * geometry widget was *really big*.
7526 * |AAAAAAAAA | At small sizes, the minimum sizes of widgets
7527 * |GGGGG B| in the border can confuse things
7533 * |AAAAAAAAA | When the geometry widget is large, things are
7534 * |GGGGGGGGGGB| clearer.
7539 #define TEMPORARY_SIZE 10000 /* 10,000 pixels should be bigger than real widget sizes */
7540 GtkRequisition requisition;
7541 int current_width, current_height;
7543 _gtk_widget_override_size_request (geometry_info->widget,
7544 TEMPORARY_SIZE, TEMPORARY_SIZE,
7545 ¤t_width, ¤t_height);
7546 gtk_widget_get_preferred_size (widget,
7547 &requisition, NULL);
7548 _gtk_widget_restore_size_request (geometry_info->widget,
7549 current_width, current_height);
7551 extra_width = requisition.width - TEMPORARY_SIZE;
7552 extra_height = requisition.height - TEMPORARY_SIZE;
7554 if (extra_width < 0 || extra_height < 0)
7556 g_warning("Toplevel size doesn't seem to directly depend on the "
7557 "size of the geometry widget from gtk_window_set_geometry_hints(). "
7558 "The geometry widget might not be in the window, or it might not "
7559 "be packed into the window appropriately");
7560 extra_width = MAX(extra_width, 0);
7561 extra_height = MAX(extra_height, 0);
7563 #undef TEMPORARY_SIZE
7566 /* We don't want to set GDK_HINT_POS in here, we just set it
7567 * in gtk_window_move_resize() when we want the position
7571 if (*new_flags & GDK_HINT_BASE_SIZE)
7573 new_geometry->base_width += extra_width;
7574 new_geometry->base_height += extra_height;
7578 /* For simplicity, we always set the base hint, even when we
7579 * don't expect it to have any visible effect.
7580 * (Note: geometry_size_to_pixels() depends on this.)
7582 *new_flags |= GDK_HINT_BASE_SIZE;
7584 new_geometry->base_width = extra_width;
7585 new_geometry->base_height = extra_height;
7587 /* As for X, if BASE_SIZE is not set but MIN_SIZE is set, then the
7588 * base size is the minimum size */
7589 if (*new_flags & GDK_HINT_MIN_SIZE)
7591 if (new_geometry->min_width > 0)
7592 new_geometry->base_width += new_geometry->min_width;
7593 if (new_geometry->min_height > 0)
7594 new_geometry->base_height += new_geometry->min_height;
7598 /* Please use a good size for unresizable widgets, not the minimum one. */
7599 if (!priv->resizable)
7600 gtk_window_guess_default_size (window, &requisition.width, &requisition.height);
7602 if (*new_flags & GDK_HINT_MIN_SIZE)
7604 if (new_geometry->min_width < 0)
7605 new_geometry->min_width = requisition.width;
7607 new_geometry->min_width = MAX (requisition.width, new_geometry->min_width + extra_width);
7609 if (new_geometry->min_height < 0)
7610 new_geometry->min_height = requisition.height;
7612 new_geometry->min_height = MAX (requisition.height, new_geometry->min_height + extra_height);
7616 *new_flags |= GDK_HINT_MIN_SIZE;
7618 new_geometry->min_width = requisition.width;
7619 new_geometry->min_height = requisition.height;
7622 if (*new_flags & GDK_HINT_MAX_SIZE)
7624 if (new_geometry->max_width < 0)
7625 new_geometry->max_width = requisition.width;
7627 new_geometry->max_width += extra_width;
7629 if (new_geometry->max_height < 0)
7630 new_geometry->max_height = requisition.height;
7632 new_geometry->max_height += extra_height;
7634 else if (!priv->resizable)
7636 *new_flags |= GDK_HINT_MAX_SIZE;
7638 new_geometry->max_width = requisition.width;
7639 new_geometry->max_height = requisition.height;
7642 *new_flags |= GDK_HINT_WIN_GRAVITY;
7643 new_geometry->win_gravity = priv->gravity;
7646 /***********************
7647 * Redrawing functions *
7648 ***********************/
7651 gtk_window_draw (GtkWidget *widget,
7654 GtkWindowPrivate *priv = GTK_WINDOW (widget)->priv;
7655 GtkStyleContext *context;
7656 gboolean ret = FALSE;
7658 context = gtk_widget_get_style_context (widget);
7660 if (!gtk_widget_get_app_paintable (widget) &&
7661 gtk_cairo_should_draw_window (cr, gtk_widget_get_window (widget)))
7663 gtk_style_context_save (context);
7665 gtk_style_context_add_class (context, GTK_STYLE_CLASS_BACKGROUND);
7666 gtk_render_background (context, cr, 0, 0,
7667 gtk_widget_get_allocated_width (widget),
7668 gtk_widget_get_allocated_height (widget));
7670 gtk_style_context_restore (context);
7673 if (GTK_WIDGET_CLASS (gtk_window_parent_class)->draw)
7674 ret = GTK_WIDGET_CLASS (gtk_window_parent_class)->draw (widget, cr);
7676 if (priv->grip_window &&
7677 gtk_cairo_should_draw_window (cr, priv->grip_window))
7681 gtk_style_context_save (context);
7684 gtk_cairo_transform_to_window (cr, widget, priv->grip_window);
7685 gtk_window_get_resize_grip_area (GTK_WINDOW (widget), &rect);
7687 gtk_style_context_add_class (context, GTK_STYLE_CLASS_GRIP);
7688 gtk_style_context_set_junction_sides (context, get_grip_junction (widget));
7689 gtk_render_handle (context, cr, 0, 0, rect.width, rect.height);
7692 gtk_style_context_restore (context);
7699 * gtk_window_present:
7700 * @window: a #GtkWindow
7702 * Presents a window to the user. This may mean raising the window
7703 * in the stacking order, deiconifying it, moving it to the current
7704 * desktop, and/or giving it the keyboard focus, possibly dependent
7705 * on the user's platform, window manager, and preferences.
7707 * If @window is hidden, this function calls gtk_widget_show()
7710 * This function should be used when the user tries to open a window
7711 * that's already open. Say for example the preferences dialog is
7712 * currently open, and the user chooses Preferences from the menu
7713 * a second time; use gtk_window_present() to move the already-open dialog
7714 * where the user can see it.
7716 * If you are calling this function in response to a user interaction,
7717 * it is preferable to use gtk_window_present_with_time().
7721 gtk_window_present (GtkWindow *window)
7723 gtk_window_present_with_time (window, GDK_CURRENT_TIME);
7727 * gtk_window_present_with_time:
7728 * @window: a #GtkWindow
7729 * @timestamp: the timestamp of the user interaction (typically a
7730 * button or key press event) which triggered this call
7732 * Presents a window to the user in response to a user interaction.
7733 * If you need to present a window without a timestamp, use
7734 * gtk_window_present(). See gtk_window_present() for details.
7739 gtk_window_present_with_time (GtkWindow *window,
7742 GtkWindowPrivate *priv;
7744 GdkWindow *gdk_window;
7746 g_return_if_fail (GTK_IS_WINDOW (window));
7748 priv = window->priv;
7749 widget = GTK_WIDGET (window);
7751 if (gtk_widget_get_visible (widget))
7753 gdk_window = gtk_widget_get_window (widget);
7755 g_assert (gdk_window != NULL);
7757 gdk_window_show (gdk_window);
7759 /* Translate a timestamp of GDK_CURRENT_TIME appropriately */
7760 if (timestamp == GDK_CURRENT_TIME)
7762 #ifdef GDK_WINDOWING_X11
7763 if (GDK_IS_X11_WINDOW(gdk_window))
7765 GdkDisplay *display;
7767 display = gtk_widget_get_display (GTK_WIDGET (window));
7768 timestamp = gdk_x11_display_get_user_time (display);
7772 timestamp = gtk_get_current_event_time ();
7775 gdk_window_focus (gdk_window, timestamp);
7779 priv->initial_timestamp = timestamp;
7780 gtk_widget_show (widget);
7785 * gtk_window_iconify:
7786 * @window: a #GtkWindow
7788 * Asks to iconify (i.e. minimize) the specified @window. Note that
7789 * you shouldn't assume the window is definitely iconified afterward,
7790 * because other entities (e.g. the user or <link
7791 * linkend="gtk-X11-arch">window manager</link>) could deiconify it
7792 * again, or there may not be a window manager in which case
7793 * iconification isn't possible, etc. But normally the window will end
7794 * up iconified. Just don't write code that crashes if not.
7796 * It's permitted to call this function before showing a window,
7797 * in which case the window will be iconified before it ever appears
7800 * You can track iconification via the "window-state-event" signal
7805 gtk_window_iconify (GtkWindow *window)
7807 GtkWindowPrivate *priv;
7809 GdkWindow *toplevel;
7811 g_return_if_fail (GTK_IS_WINDOW (window));
7813 priv = window->priv;
7814 widget = GTK_WIDGET (window);
7816 priv->iconify_initially = TRUE;
7818 toplevel = gtk_widget_get_window (widget);
7820 if (toplevel != NULL)
7821 gdk_window_iconify (toplevel);
7825 * gtk_window_deiconify:
7826 * @window: a #GtkWindow
7828 * Asks to deiconify (i.e. unminimize) the specified @window. Note
7829 * that you shouldn't assume the window is definitely deiconified
7830 * afterward, because other entities (e.g. the user or <link
7831 * linkend="gtk-X11-arch">window manager</link>) could iconify it
7832 * again before your code which assumes deiconification gets to run.
7834 * You can track iconification via the "window-state-event" signal
7838 gtk_window_deiconify (GtkWindow *window)
7840 GtkWindowPrivate *priv;
7842 GdkWindow *toplevel;
7844 g_return_if_fail (GTK_IS_WINDOW (window));
7846 priv = window->priv;
7847 widget = GTK_WIDGET (window);
7849 priv->iconify_initially = FALSE;
7851 toplevel = gtk_widget_get_window (widget);
7853 if (toplevel != NULL)
7854 gdk_window_deiconify (toplevel);
7859 * @window: a #GtkWindow
7861 * Asks to stick @window, which means that it will appear on all user
7862 * desktops. Note that you shouldn't assume the window is definitely
7863 * stuck afterward, because other entities (e.g. the user or <link
7864 * linkend="gtk-X11-arch">window manager</link>) could unstick it
7865 * again, and some window managers do not support sticking
7866 * windows. But normally the window will end up stuck. Just don't
7867 * write code that crashes if not.
7869 * It's permitted to call this function before showing a window.
7871 * You can track stickiness via the "window-state-event" signal
7876 gtk_window_stick (GtkWindow *window)
7878 GtkWindowPrivate *priv;
7880 GdkWindow *toplevel;
7882 g_return_if_fail (GTK_IS_WINDOW (window));
7884 priv = window->priv;
7885 widget = GTK_WIDGET (window);
7887 priv->stick_initially = TRUE;
7889 toplevel = gtk_widget_get_window (widget);
7891 if (toplevel != NULL)
7892 gdk_window_stick (toplevel);
7896 * gtk_window_unstick:
7897 * @window: a #GtkWindow
7899 * Asks to unstick @window, which means that it will appear on only
7900 * one of the user's desktops. Note that you shouldn't assume the
7901 * window is definitely unstuck afterward, because other entities
7902 * (e.g. the user or <link linkend="gtk-X11-arch">window
7903 * manager</link>) could stick it again. But normally the window will
7904 * end up stuck. Just don't write code that crashes if not.
7906 * You can track stickiness via the "window-state-event" signal
7911 gtk_window_unstick (GtkWindow *window)
7913 GtkWindowPrivate *priv;
7915 GdkWindow *toplevel;
7917 g_return_if_fail (GTK_IS_WINDOW (window));
7919 priv = window->priv;
7920 widget = GTK_WIDGET (window);
7922 priv->stick_initially = FALSE;
7924 toplevel = gtk_widget_get_window (widget);
7926 if (toplevel != NULL)
7927 gdk_window_unstick (toplevel);
7931 * gtk_window_maximize:
7932 * @window: a #GtkWindow
7934 * Asks to maximize @window, so that it becomes full-screen. Note that
7935 * you shouldn't assume the window is definitely maximized afterward,
7936 * because other entities (e.g. the user or <link
7937 * linkend="gtk-X11-arch">window manager</link>) could unmaximize it
7938 * again, and not all window managers support maximization. But
7939 * normally the window will end up maximized. Just don't write code
7940 * that crashes if not.
7942 * It's permitted to call this function before showing a window,
7943 * in which case the window will be maximized when it appears onscreen
7946 * You can track maximization via the "window-state-event" signal
7951 gtk_window_maximize (GtkWindow *window)
7953 GtkWindowPrivate *priv;
7955 GdkWindow *toplevel;
7957 g_return_if_fail (GTK_IS_WINDOW (window));
7959 priv = window->priv;
7960 widget = GTK_WIDGET (window);
7962 priv->maximize_initially = TRUE;
7964 toplevel = gtk_widget_get_window (widget);
7966 if (toplevel != NULL)
7967 gdk_window_maximize (toplevel);
7971 * gtk_window_unmaximize:
7972 * @window: a #GtkWindow
7974 * Asks to unmaximize @window. Note that you shouldn't assume the
7975 * window is definitely unmaximized afterward, because other entities
7976 * (e.g. the user or <link linkend="gtk-X11-arch">window
7977 * manager</link>) could maximize it again, and not all window
7978 * managers honor requests to unmaximize. But normally the window will
7979 * end up unmaximized. Just don't write code that crashes if not.
7981 * You can track maximization via the "window-state-event" signal
7986 gtk_window_unmaximize (GtkWindow *window)
7988 GtkWindowPrivate *priv;
7990 GdkWindow *toplevel;
7992 g_return_if_fail (GTK_IS_WINDOW (window));
7994 priv = window->priv;
7995 widget = GTK_WIDGET (window);
7997 priv->maximize_initially = FALSE;
7999 toplevel = gtk_widget_get_window (widget);
8001 if (toplevel != NULL)
8002 gdk_window_unmaximize (toplevel);
8006 * gtk_window_fullscreen:
8007 * @window: a #GtkWindow
8009 * Asks to place @window in the fullscreen state. Note that you
8010 * shouldn't assume the window is definitely full screen afterward,
8011 * because other entities (e.g. the user or <link
8012 * linkend="gtk-X11-arch">window manager</link>) could unfullscreen it
8013 * again, and not all window managers honor requests to fullscreen
8014 * windows. But normally the window will end up fullscreen. Just
8015 * don't write code that crashes if not.
8017 * You can track the fullscreen state via the "window-state-event" signal
8023 gtk_window_fullscreen (GtkWindow *window)
8025 GtkWindowPrivate *priv;
8027 GdkWindow *toplevel;
8029 g_return_if_fail (GTK_IS_WINDOW (window));
8031 priv = window->priv;
8032 widget = GTK_WIDGET (window);
8034 priv->fullscreen_initially = TRUE;
8036 toplevel = gtk_widget_get_window (widget);
8038 if (toplevel != NULL)
8039 gdk_window_fullscreen (toplevel);
8043 * gtk_window_unfullscreen:
8044 * @window: a #GtkWindow
8046 * Asks to toggle off the fullscreen state for @window. Note that you
8047 * shouldn't assume the window is definitely not full screen
8048 * afterward, because other entities (e.g. the user or <link
8049 * linkend="gtk-X11-arch">window manager</link>) could fullscreen it
8050 * again, and not all window managers honor requests to unfullscreen
8051 * windows. But normally the window will end up restored to its normal
8052 * state. Just don't write code that crashes if not.
8054 * You can track the fullscreen state via the "window-state-event" signal
8060 gtk_window_unfullscreen (GtkWindow *window)
8063 GdkWindow *toplevel;
8064 GtkWindowPrivate *priv;
8066 g_return_if_fail (GTK_IS_WINDOW (window));
8068 priv = window->priv;
8069 widget = GTK_WIDGET (window);
8071 priv->fullscreen_initially = FALSE;
8073 toplevel = gtk_widget_get_window (widget);
8075 if (toplevel != NULL)
8076 gdk_window_unfullscreen (toplevel);
8080 * gtk_window_set_keep_above:
8081 * @window: a #GtkWindow
8082 * @setting: whether to keep @window above other windows
8084 * Asks to keep @window above, so that it stays on top. Note that
8085 * you shouldn't assume the window is definitely above afterward,
8086 * because other entities (e.g. the user or <link
8087 * linkend="gtk-X11-arch">window manager</link>) could not keep it above,
8088 * and not all window managers support keeping windows above. But
8089 * normally the window will end kept above. Just don't write code
8090 * that crashes if not.
8092 * It's permitted to call this function before showing a window,
8093 * in which case the window will be kept above when it appears onscreen
8096 * You can track the above state via the "window-state-event" signal
8099 * Note that, according to the <ulink
8100 * url="http://www.freedesktop.org/Standards/wm-spec">Extended Window
8101 * Manager Hints</ulink> specification, the above state is mainly meant
8102 * for user preferences and should not be used by applications e.g. for
8103 * drawing attention to their dialogs.
8108 gtk_window_set_keep_above (GtkWindow *window,
8112 GtkWindowPrivate *priv;
8113 GdkWindow *toplevel;
8115 g_return_if_fail (GTK_IS_WINDOW (window));
8117 priv = window->priv;
8118 widget = GTK_WIDGET (window);
8120 priv->above_initially = setting != FALSE;
8122 priv->below_initially = FALSE;
8124 toplevel = gtk_widget_get_window (widget);
8126 if (toplevel != NULL)
8127 gdk_window_set_keep_above (toplevel, setting);
8131 * gtk_window_set_keep_below:
8132 * @window: a #GtkWindow
8133 * @setting: whether to keep @window below other windows
8135 * Asks to keep @window below, so that it stays in bottom. Note that
8136 * you shouldn't assume the window is definitely below afterward,
8137 * because other entities (e.g. the user or <link
8138 * linkend="gtk-X11-arch">window manager</link>) could not keep it below,
8139 * and not all window managers support putting windows below. But
8140 * normally the window will be kept below. Just don't write code
8141 * that crashes if not.
8143 * It's permitted to call this function before showing a window,
8144 * in which case the window will be kept below when it appears onscreen
8147 * You can track the below state via the "window-state-event" signal
8150 * Note that, according to the <ulink
8151 * url="http://www.freedesktop.org/Standards/wm-spec">Extended Window
8152 * Manager Hints</ulink> specification, the above state is mainly meant
8153 * for user preferences and should not be used by applications e.g. for
8154 * drawing attention to their dialogs.
8159 gtk_window_set_keep_below (GtkWindow *window,
8163 GtkWindowPrivate *priv;
8164 GdkWindow *toplevel;
8166 g_return_if_fail (GTK_IS_WINDOW (window));
8168 priv = window->priv;
8169 widget = GTK_WIDGET (window);
8171 priv->below_initially = setting != FALSE;
8173 priv->above_initially = FALSE;
8175 toplevel = gtk_widget_get_window (widget);
8177 if (toplevel != NULL)
8178 gdk_window_set_keep_below (toplevel, setting);
8182 * gtk_window_set_resizable:
8183 * @window: a #GtkWindow
8184 * @resizable: %TRUE if the user can resize this window
8186 * Sets whether the user can resize a window. Windows are user resizable
8190 gtk_window_set_resizable (GtkWindow *window,
8193 GtkWindowPrivate *priv;
8195 g_return_if_fail (GTK_IS_WINDOW (window));
8197 priv = window->priv;
8199 resizable = (resizable != FALSE);
8201 if (priv->resizable != resizable)
8203 priv->resizable = (resizable != FALSE);
8205 update_grip_visibility (window);
8207 gtk_widget_queue_resize_no_redraw (GTK_WIDGET (window));
8209 g_object_notify (G_OBJECT (window), "resizable");
8214 * gtk_window_get_resizable:
8215 * @window: a #GtkWindow
8217 * Gets the value set by gtk_window_set_resizable().
8219 * Return value: %TRUE if the user can resize the window
8222 gtk_window_get_resizable (GtkWindow *window)
8224 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
8226 return window->priv->resizable;
8230 * gtk_window_set_gravity:
8231 * @window: a #GtkWindow
8232 * @gravity: window gravity
8234 * Window gravity defines the meaning of coordinates passed to
8235 * gtk_window_move(). See gtk_window_move() and #GdkGravity for
8238 * The default window gravity is #GDK_GRAVITY_NORTH_WEST which will
8239 * typically "do what you mean."
8243 gtk_window_set_gravity (GtkWindow *window,
8246 GtkWindowPrivate *priv;
8248 g_return_if_fail (GTK_IS_WINDOW (window));
8250 priv = window->priv;
8252 if (gravity != priv->gravity)
8254 priv->gravity = gravity;
8256 /* gtk_window_move_resize() will adapt gravity
8258 gtk_widget_queue_resize_no_redraw (GTK_WIDGET (window));
8260 g_object_notify (G_OBJECT (window), "gravity");
8265 * gtk_window_get_gravity:
8266 * @window: a #GtkWindow
8268 * Gets the value set by gtk_window_set_gravity().
8270 * Return value: (transfer none): window gravity
8273 gtk_window_get_gravity (GtkWindow *window)
8275 g_return_val_if_fail (GTK_IS_WINDOW (window), 0);
8277 return window->priv->gravity;
8281 * gtk_window_begin_resize_drag:
8282 * @window: a #GtkWindow
8283 * @button: mouse button that initiated the drag
8284 * @edge: position of the resize control
8285 * @root_x: X position where the user clicked to initiate the drag, in root window coordinates
8286 * @root_y: Y position where the user clicked to initiate the drag
8287 * @timestamp: timestamp from the click event that initiated the drag
8289 * Starts resizing a window. This function is used if an application
8290 * has window resizing controls. When GDK can support it, the resize
8291 * will be done using the standard mechanism for the <link
8292 * linkend="gtk-X11-arch">window manager</link> or windowing
8293 * system. Otherwise, GDK will try to emulate window resizing,
8294 * potentially not all that well, depending on the windowing system.
8298 gtk_window_begin_resize_drag (GtkWindow *window,
8306 GdkWindow *toplevel;
8308 g_return_if_fail (GTK_IS_WINDOW (window));
8309 widget = GTK_WIDGET (window);
8310 g_return_if_fail (gtk_widget_get_visible (widget));
8312 toplevel = gtk_widget_get_window (widget);
8314 gdk_window_begin_resize_drag (toplevel,
8321 * gtk_window_begin_move_drag:
8322 * @window: a #GtkWindow
8323 * @button: mouse button that initiated the drag
8324 * @root_x: X position where the user clicked to initiate the drag, in root window coordinates
8325 * @root_y: Y position where the user clicked to initiate the drag
8326 * @timestamp: timestamp from the click event that initiated the drag
8328 * Starts moving a window. This function is used if an application has
8329 * window movement grips. When GDK can support it, the window movement
8330 * will be done using the standard mechanism for the <link
8331 * linkend="gtk-X11-arch">window manager</link> or windowing
8332 * system. Otherwise, GDK will try to emulate window movement,
8333 * potentially not all that well, depending on the windowing system.
8337 gtk_window_begin_move_drag (GtkWindow *window,
8344 GdkWindow *toplevel;
8346 g_return_if_fail (GTK_IS_WINDOW (window));
8347 widget = GTK_WIDGET (window);
8348 g_return_if_fail (gtk_widget_get_visible (widget));
8350 toplevel = gtk_widget_get_window (widget);
8352 gdk_window_begin_move_drag (toplevel,
8359 * gtk_window_set_screen:
8360 * @window: a #GtkWindow.
8361 * @screen: a #GdkScreen.
8363 * Sets the #GdkScreen where the @window is displayed; if
8364 * the window is already mapped, it will be unmapped, and
8365 * then remapped on the new screen.
8370 gtk_window_set_screen (GtkWindow *window,
8373 GtkWindowPrivate *priv;
8375 GdkScreen *previous_screen;
8376 gboolean was_mapped;
8378 g_return_if_fail (GTK_IS_WINDOW (window));
8379 g_return_if_fail (GDK_IS_SCREEN (screen));
8381 priv = window->priv;
8383 if (screen == priv->screen)
8386 widget = GTK_WIDGET (window);
8388 previous_screen = priv->screen;
8389 was_mapped = gtk_widget_get_mapped (widget);
8392 gtk_widget_unmap (widget);
8393 if (gtk_widget_get_realized (widget))
8394 gtk_widget_unrealize (widget);
8396 gtk_window_free_key_hash (window);
8397 priv->screen = screen;
8398 gtk_widget_reset_rc_styles (widget);
8399 if (screen != previous_screen)
8401 if (previous_screen)
8403 g_signal_handlers_disconnect_by_func (previous_screen,
8404 gtk_window_on_composited_changed, window);
8405 #ifdef GDK_WINDOWING_X11
8406 g_signal_handlers_disconnect_by_func (gtk_settings_get_for_screen (previous_screen),
8407 gtk_window_on_theme_variant_changed, window);
8410 g_signal_connect (screen, "composited-changed",
8411 G_CALLBACK (gtk_window_on_composited_changed), window);
8412 #ifdef GDK_WINDOWING_X11
8413 g_signal_connect (gtk_settings_get_for_screen (screen),
8414 "notify::gtk-application-prefer-dark-theme",
8415 G_CALLBACK (gtk_window_on_theme_variant_changed), window);
8418 _gtk_widget_propagate_screen_changed (widget, previous_screen);
8419 _gtk_widget_propagate_composited_changed (widget);
8421 g_object_notify (G_OBJECT (window), "screen");
8424 gtk_widget_map (widget);
8428 gtk_window_set_theme_variant (GtkWindow *window)
8430 #ifdef GDK_WINDOWING_X11
8431 GdkWindow *gdk_window;
8432 gboolean dark_theme_requested;
8434 g_object_get (gtk_settings_get_for_screen (window->priv->screen),
8435 "gtk-application-prefer-dark-theme", &dark_theme_requested,
8438 gdk_window = gtk_widget_get_window (GTK_WIDGET (window));
8440 if (GDK_IS_X11_WINDOW (gdk_window))
8441 gdk_x11_window_set_theme_variant (gdk_window,
8442 dark_theme_requested ? "dark" : NULL);
8447 gtk_window_on_theme_variant_changed (GtkSettings *settings,
8451 if (window->priv->type == GTK_WINDOW_TOPLEVEL)
8452 gtk_window_set_theme_variant (window);
8456 gtk_window_on_composited_changed (GdkScreen *screen,
8459 gtk_widget_queue_draw (GTK_WIDGET (window));
8461 _gtk_widget_propagate_composited_changed (GTK_WIDGET (window));
8465 gtk_window_check_screen (GtkWindow *window)
8467 GtkWindowPrivate *priv = window->priv;
8470 return priv->screen;
8473 g_warning ("Screen for GtkWindow not set; you must always set\n"
8474 "a screen for a GtkWindow before using the window");
8480 * gtk_window_get_screen:
8481 * @window: a #GtkWindow.
8483 * Returns the #GdkScreen associated with @window.
8485 * Return value: (transfer none): a #GdkScreen.
8490 gtk_window_get_screen (GtkWindow *window)
8492 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
8494 return window->priv->screen;
8498 * gtk_window_is_active:
8499 * @window: a #GtkWindow
8501 * Returns whether the window is part of the current active toplevel.
8502 * (That is, the toplevel window receiving keystrokes.)
8503 * The return value is %TRUE if the window is active toplevel
8504 * itself, but also if it is, say, a #GtkPlug embedded in the active toplevel.
8505 * You might use this function if you wanted to draw a widget
8506 * differently in an active window from a widget in an inactive window.
8507 * See gtk_window_has_toplevel_focus()
8509 * Return value: %TRUE if the window part of the current active window.
8514 gtk_window_is_active (GtkWindow *window)
8516 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
8518 return window->priv->is_active;
8522 * gtk_window_has_toplevel_focus:
8523 * @window: a #GtkWindow
8525 * Returns whether the input focus is within this GtkWindow.
8526 * For real toplevel windows, this is identical to gtk_window_is_active(),
8527 * but for embedded windows, like #GtkPlug, the results will differ.
8529 * Return value: %TRUE if the input focus is within this GtkWindow
8534 gtk_window_has_toplevel_focus (GtkWindow *window)
8536 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
8538 return window->priv->has_toplevel_focus;
8543 * SECTION:gtkwindowgroup
8544 * @Short_description: Limit the effect of grabs
8545 * @Title: GtkWindowGroup
8547 * #GtkWindowGroup objects are referenced by each window in the group,
8548 * so once you have added all windows to a #GtkWindowGroup, you can drop
8549 * the initial reference to the window group with g_object_unref(). If the
8550 * windows in the window group are subsequently destroyed, then they will
8551 * be removed from the window group and drop their references on the window
8552 * group; when all window have been removed, the window group will be
8556 G_DEFINE_TYPE (GtkWindowGroup, gtk_window_group, G_TYPE_OBJECT)
8559 gtk_window_group_init (GtkWindowGroup *group)
8561 group->priv = G_TYPE_INSTANCE_GET_PRIVATE (group,
8562 GTK_TYPE_WINDOW_GROUP,
8563 GtkWindowGroupPrivate);
8567 gtk_window_group_class_init (GtkWindowGroupClass *klass)
8569 g_type_class_add_private (klass, sizeof (GtkWindowGroupPrivate));
8573 * gtk_window_group_new:
8575 * Creates a new #GtkWindowGroup object. Grabs added with
8576 * gtk_grab_add() only affect windows within the same #GtkWindowGroup.
8578 * Return value: a new #GtkWindowGroup.
8581 gtk_window_group_new (void)
8583 return g_object_new (GTK_TYPE_WINDOW_GROUP, NULL);
8587 window_group_cleanup_grabs (GtkWindowGroup *group,
8590 GtkWindowGroupPrivate *priv;
8591 GtkDeviceGrabInfo *info;
8593 GSList *to_remove = NULL;
8597 tmp_list = priv->grabs;
8600 if (gtk_widget_get_toplevel (tmp_list->data) == (GtkWidget*) window)
8601 to_remove = g_slist_prepend (to_remove, g_object_ref (tmp_list->data));
8602 tmp_list = tmp_list->next;
8607 gtk_grab_remove (to_remove->data);
8608 g_object_unref (to_remove->data);
8609 to_remove = g_slist_delete_link (to_remove, to_remove);
8612 tmp_list = priv->device_grabs;
8616 info = tmp_list->data;
8618 if (gtk_widget_get_toplevel (info->widget) == (GtkWidget *) window)
8619 to_remove = g_slist_prepend (to_remove, info);
8621 tmp_list = tmp_list->next;
8626 info = to_remove->data;
8628 gtk_device_grab_remove (info->widget, info->device);
8629 to_remove = g_slist_delete_link (to_remove, to_remove);
8634 * gtk_window_group_add_window:
8635 * @window_group: a #GtkWindowGroup
8636 * @window: the #GtkWindow to add
8638 * Adds a window to a #GtkWindowGroup.
8641 gtk_window_group_add_window (GtkWindowGroup *window_group,
8644 GtkWindowPrivate *priv;
8646 g_return_if_fail (GTK_IS_WINDOW_GROUP (window_group));
8647 g_return_if_fail (GTK_IS_WINDOW (window));
8649 priv = window->priv;
8651 if (priv->group != window_group)
8653 g_object_ref (window);
8654 g_object_ref (window_group);
8657 gtk_window_group_remove_window (priv->group, window);
8659 window_group_cleanup_grabs (gtk_window_get_group (NULL), window);
8661 priv->group = window_group;
8663 g_object_unref (window);
8668 * gtk_window_group_remove_window:
8669 * @window_group: a #GtkWindowGroup
8670 * @window: the #GtkWindow to remove
8672 * Removes a window from a #GtkWindowGroup.
8675 gtk_window_group_remove_window (GtkWindowGroup *window_group,
8678 GtkWindowPrivate *priv;
8680 g_return_if_fail (GTK_IS_WINDOW_GROUP (window_group));
8681 g_return_if_fail (GTK_IS_WINDOW (window));
8682 priv = window->priv;
8683 g_return_if_fail (priv->group == window_group);
8685 g_object_ref (window);
8687 window_group_cleanup_grabs (window_group, window);
8690 g_object_unref (window_group);
8691 g_object_unref (window);
8695 * gtk_window_group_list_windows:
8696 * @window_group: a #GtkWindowGroup
8698 * Returns a list of the #GtkWindows that belong to @window_group.
8700 * Returns: (element-type GtkWindow) (transfer container): A
8701 * newly-allocated list of windows inside the group.
8706 gtk_window_group_list_windows (GtkWindowGroup *window_group)
8708 GList *toplevels, *toplevel, *group_windows;
8710 g_return_val_if_fail (GTK_IS_WINDOW_GROUP (window_group), NULL);
8712 group_windows = NULL;
8713 toplevels = gtk_window_list_toplevels ();
8715 for (toplevel = toplevels; toplevel; toplevel = toplevel->next)
8717 GtkWindow *window = toplevel->data;
8719 if (window_group == window->priv->group)
8720 group_windows = g_list_prepend (group_windows, window);
8723 g_list_free (toplevels);
8725 return g_list_reverse (group_windows);
8729 * gtk_window_get_group:
8730 * @window: (allow-none): a #GtkWindow, or %NULL
8732 * Returns the group for @window or the default group, if
8733 * @window is %NULL or if @window does not have an explicit
8736 * Returns: (transfer none): the #GtkWindowGroup for a window or the default group
8741 gtk_window_get_group (GtkWindow *window)
8743 if (window && window->priv->group)
8744 return window->priv->group;
8747 static GtkWindowGroup *default_group = NULL;
8750 default_group = gtk_window_group_new ();
8752 return default_group;
8757 * gtk_window_has_group:
8758 * @window: a #GtkWindow
8760 * Returns whether @window has an explicit window group.
8762 * Return value: %TRUE if @window has an explicit window group.
8767 gtk_window_has_group (GtkWindow *window)
8769 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
8771 return window->priv->group != NULL;
8775 * gtk_window_group_get_current_grab:
8776 * @window_group: a #GtkWindowGroup
8778 * Gets the current grab widget of the given group,
8779 * see gtk_grab_add().
8781 * Returns: (transfer none): the current grab widget of the group
8786 gtk_window_group_get_current_grab (GtkWindowGroup *window_group)
8788 g_return_val_if_fail (GTK_IS_WINDOW_GROUP (window_group), NULL);
8790 if (window_group->priv->grabs)
8791 return GTK_WIDGET (window_group->priv->grabs->data);
8796 _gtk_window_group_add_grab (GtkWindowGroup *window_group,
8799 GtkWindowGroupPrivate *priv;
8801 priv = window_group->priv;
8802 priv->grabs = g_slist_prepend (priv->grabs, widget);
8806 _gtk_window_group_remove_grab (GtkWindowGroup *window_group,
8809 GtkWindowGroupPrivate *priv;
8811 priv = window_group->priv;
8812 priv->grabs = g_slist_remove (priv->grabs, widget);
8817 _gtk_window_group_add_device_grab (GtkWindowGroup *window_group,
8820 gboolean block_others)
8822 GtkWindowGroupPrivate *priv;
8823 GtkDeviceGrabInfo *info;
8825 priv = window_group->priv;
8827 info = g_slice_new0 (GtkDeviceGrabInfo);
8828 info->widget = widget;
8829 info->device = device;
8830 info->block_others = block_others;
8832 priv->device_grabs = g_slist_prepend (priv->device_grabs, info);
8836 _gtk_window_group_remove_device_grab (GtkWindowGroup *window_group,
8840 GtkWindowGroupPrivate *priv;
8841 GtkDeviceGrabInfo *info;
8842 GSList *list, *node = NULL;
8843 GdkDevice *other_device;
8845 priv = window_group->priv;
8846 other_device = gdk_device_get_associated_device (device);
8847 list = priv->device_grabs;
8853 if (info->widget == widget &&
8854 (info->device == device ||
8855 info->device == other_device))
8868 priv->device_grabs = g_slist_delete_link (priv->device_grabs, node);
8869 g_slice_free (GtkDeviceGrabInfo, info);
8874 * gtk_window_group_get_current_device_grab:
8875 * @window_group: a #GtkWindowGroup
8876 * @device: a #GdkDevice
8878 * Returns the current grab widget for @device, or %NULL if none.
8880 * Returns: (transfer none): The grab widget, or %NULL
8885 gtk_window_group_get_current_device_grab (GtkWindowGroup *window_group,
8888 GtkWindowGroupPrivate *priv;
8889 GtkDeviceGrabInfo *info;
8890 GdkDevice *other_device;
8893 g_return_val_if_fail (GTK_IS_WINDOW_GROUP (window_group), NULL);
8894 g_return_val_if_fail (GDK_IS_DEVICE (device), NULL);
8896 priv = window_group->priv;
8897 list = priv->device_grabs;
8898 other_device = gdk_device_get_associated_device (device);
8905 if (info->device == device ||
8906 info->device == other_device)
8907 return info->widget;
8914 _gtk_window_group_widget_is_blocked_for_device (GtkWindowGroup *window_group,
8918 GtkWindowGroupPrivate *priv;
8919 GtkDeviceGrabInfo *info;
8920 GdkDevice *other_device;
8923 priv = window_group->priv;
8924 other_device = gdk_device_get_associated_device (device);
8925 list = priv->device_grabs;
8932 /* Look for blocking grabs on other device pairs
8933 * that have the passed widget within the GTK+ grab.
8935 if (info->block_others &&
8936 info->device != device &&
8937 info->device != other_device &&
8938 (info->widget == widget ||
8939 gtk_widget_is_ancestor (widget, info->widget)))
8947 Derived from XParseGeometry() in XFree86
8949 Copyright 1985, 1986, 1987,1998 The Open Group
8951 All Rights Reserved.
8953 The above copyright notice and this permission notice shall be included
8954 in all copies or substantial portions of the Software.
8956 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
8957 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
8958 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
8959 IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
8960 OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
8961 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
8962 OTHER DEALINGS IN THE SOFTWARE.
8964 Except as contained in this notice, the name of The Open Group shall
8965 not be used in advertising or otherwise to promote the sale, use or
8966 other dealings in this Software without prior written authorization
8967 from The Open Group.
8972 * XParseGeometry parses strings of the form
8973 * "=<width>x<height>{+-}<xoffset>{+-}<yoffset>", where
8974 * width, height, xoffset, and yoffset are unsigned integers.
8975 * Example: "=80x24+300-49"
8976 * The equal sign is optional.
8977 * It returns a bitmask that indicates which of the four values
8978 * were actually found in the string. For each value found,
8979 * the corresponding argument is updated; for each value
8980 * not found, the corresponding argument is left unchanged.
8983 /* The following code is from Xlib, and is minimally modified, so we
8984 * can track any upstream changes if required. Don't change this
8985 * code. Or if you do, put in a huge comment marking which thing
8990 read_int (gchar *string,
8998 else if (*string == '-')
9004 for (; (*string >= '0') && (*string <= '9'); string++)
9006 result = (result * 10) + (*string - '0');
9018 * Bitmask returned by XParseGeometry(). Each bit tells if the corresponding
9019 * value (x, y, width, height) was found in the parsed string.
9021 #define NoValue 0x0000
9022 #define XValue 0x0001
9023 #define YValue 0x0002
9024 #define WidthValue 0x0004
9025 #define HeightValue 0x0008
9026 #define AllValues 0x000F
9027 #define XNegative 0x0010
9028 #define YNegative 0x0020
9030 /* Try not to reformat/modify, so we can compare/sync with X sources */
9032 gtk_XParseGeometry (const char *string,
9035 unsigned int *width,
9036 unsigned int *height)
9040 unsigned int tempWidth, tempHeight;
9042 char *nextCharacter;
9044 /* These initializations are just to silence gcc */
9050 if ( (string == NULL) || (*string == '\0')) return(mask);
9052 string++; /* ignore possible '=' at beg of geometry spec */
9054 strind = (char *)string;
9055 if (*strind != '+' && *strind != '-' && *strind != 'x') {
9056 tempWidth = read_int(strind, &nextCharacter);
9057 if (strind == nextCharacter)
9059 strind = nextCharacter;
9063 if (*strind == 'x' || *strind == 'X') {
9065 tempHeight = read_int(strind, &nextCharacter);
9066 if (strind == nextCharacter)
9068 strind = nextCharacter;
9069 mask |= HeightValue;
9072 if ((*strind == '+') || (*strind == '-')) {
9073 if (*strind == '-') {
9075 tempX = -read_int(strind, &nextCharacter);
9076 if (strind == nextCharacter)
9078 strind = nextCharacter;
9084 tempX = read_int(strind, &nextCharacter);
9085 if (strind == nextCharacter)
9087 strind = nextCharacter;
9090 if ((*strind == '+') || (*strind == '-')) {
9091 if (*strind == '-') {
9093 tempY = -read_int(strind, &nextCharacter);
9094 if (strind == nextCharacter)
9096 strind = nextCharacter;
9103 tempY = read_int(strind, &nextCharacter);
9104 if (strind == nextCharacter)
9106 strind = nextCharacter;
9112 /* If strind isn't at the end of the string the it's an invalid
9113 geometry specification. */
9115 if (*strind != '\0') return (0);
9121 if (mask & WidthValue)
9123 if (mask & HeightValue)
9124 *height = tempHeight;
9129 * gtk_window_parse_geometry:
9130 * @window: a #GtkWindow
9131 * @geometry: geometry string
9133 * Parses a standard X Window System geometry string - see the
9134 * manual page for X (type 'man X') for details on this.
9135 * gtk_window_parse_geometry() does work on all GTK+ ports
9136 * including Win32 but is primarily intended for an X environment.
9138 * If either a size or a position can be extracted from the
9139 * geometry string, gtk_window_parse_geometry() returns %TRUE
9140 * and calls gtk_window_set_default_size() and/or gtk_window_move()
9141 * to resize/move the window.
9143 * If gtk_window_parse_geometry() returns %TRUE, it will also
9144 * set the #GDK_HINT_USER_POS and/or #GDK_HINT_USER_SIZE hints
9145 * indicating to the window manager that the size/position of
9146 * the window was user-specified. This causes most window
9147 * managers to honor the geometry.
9149 * Note that for gtk_window_parse_geometry() to work as expected, it has
9150 * to be called when the window has its "final" size, i.e. after calling
9151 * gtk_widget_show_all() on the contents and gtk_window_set_geometry_hints()
9154 * #include <gtk/gtk.h>
9157 * fill_with_content (GtkWidget *vbox)
9159 * /* fill with content... */
9163 * main (int argc, char *argv[])
9165 * GtkWidget *window, *vbox;
9166 * GdkGeometry size_hints = {
9167 * 100, 50, 0, 0, 100, 50, 10, 10, 0.0, 0.0, GDK_GRAVITY_NORTH_WEST
9170 * gtk_init (&argc, &argv);
9172 * window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
9173 * vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, FALSE, 0);
9175 * gtk_container_add (GTK_CONTAINER (window), vbox);
9176 * fill_with_content (vbox);
9177 * gtk_widget_show_all (vbox);
9179 * gtk_window_set_geometry_hints (GTK_WINDOW (window),
9182 * GDK_HINT_MIN_SIZE |
9183 * GDK_HINT_BASE_SIZE |
9184 * GDK_HINT_RESIZE_INC);
9188 * if (!gtk_window_parse_geometry (GTK_WINDOW (window), argv[1]))
9189 * fprintf (stderr, "Failed to parse '%s'\n", argv[1]);
9192 * gtk_widget_show_all (window);
9199 * Return value: %TRUE if string was parsed successfully
9202 gtk_window_parse_geometry (GtkWindow *window,
9203 const gchar *geometry)
9205 gint result, x = 0, y = 0;
9209 gboolean size_set, pos_set;
9212 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
9213 g_return_val_if_fail (geometry != NULL, FALSE);
9215 child = gtk_bin_get_child (GTK_BIN (window));
9216 if (!child || !gtk_widget_get_visible (child))
9217 g_warning ("gtk_window_parse_geometry() called on a window with no "
9218 "visible children; the window should be set up before "
9219 "gtk_window_parse_geometry() is called.");
9221 screen = gtk_window_check_screen (window);
9223 result = gtk_XParseGeometry (geometry, &x, &y, &w, &h);
9226 if ((result & WidthValue) || (result & HeightValue))
9228 gtk_window_set_default_size_internal (window,
9229 TRUE, result & WidthValue ? w : -1,
9230 TRUE, result & HeightValue ? h : -1,
9235 gtk_window_get_size (window, (gint *)&w, (gint *)&h);
9237 grav = GDK_GRAVITY_NORTH_WEST;
9239 if ((result & XNegative) && (result & YNegative))
9240 grav = GDK_GRAVITY_SOUTH_EAST;
9241 else if (result & XNegative)
9242 grav = GDK_GRAVITY_NORTH_EAST;
9243 else if (result & YNegative)
9244 grav = GDK_GRAVITY_SOUTH_WEST;
9246 if ((result & XValue) == 0)
9249 if ((result & YValue) == 0)
9252 if (grav == GDK_GRAVITY_SOUTH_WEST ||
9253 grav == GDK_GRAVITY_SOUTH_EAST)
9254 y = gdk_screen_get_height (screen) - h + y;
9256 if (grav == GDK_GRAVITY_SOUTH_EAST ||
9257 grav == GDK_GRAVITY_NORTH_EAST)
9258 x = gdk_screen_get_width (screen) - w + x;
9260 /* we don't let you put a window offscreen; maybe some people would
9261 * prefer to be able to, but it's kind of a bogus thing to do.
9270 if ((result & XValue) || (result & YValue))
9272 gtk_window_set_gravity (window, grav);
9273 gtk_window_move (window, x, y);
9277 if (size_set || pos_set)
9279 /* Set USSize, USPosition hints */
9280 GtkWindowGeometryInfo *info;
9282 info = gtk_window_get_geometry_info (window, TRUE);
9285 info->mask |= GDK_HINT_USER_POS;
9287 info->mask |= GDK_HINT_USER_SIZE;
9294 gtk_window_mnemonic_hash_foreach (guint keyval,
9300 GtkWindowKeysForeachFunc func;
9304 (*info->func) (info->window, keyval, info->window->priv->mnemonic_modifier, TRUE, info->func_data);
9308 _gtk_window_keys_foreach (GtkWindow *window,
9309 GtkWindowKeysForeachFunc func,
9313 GtkMnemonicHash *mnemonic_hash;
9317 GtkWindowKeysForeachFunc func;
9321 info.window = window;
9323 info.func_data = func_data;
9325 mnemonic_hash = gtk_window_get_mnemonic_hash (window, FALSE);
9327 _gtk_mnemonic_hash_foreach (mnemonic_hash,
9328 gtk_window_mnemonic_hash_foreach, &info);
9330 groups = gtk_accel_groups_from_object (G_OBJECT (window));
9333 GtkAccelGroup *group = groups->data;
9336 for (i = 0; i < group->priv->n_accels; i++)
9338 GtkAccelKey *key = &group->priv->priv_accels[i].key;
9341 (*func) (window, key->accel_key, key->accel_mods, FALSE, func_data);
9344 groups = groups->next;
9349 gtk_window_keys_changed (GtkWindow *window)
9351 gtk_window_free_key_hash (window);
9352 gtk_window_get_key_hash (window);
9355 typedef struct _GtkWindowKeyEntry GtkWindowKeyEntry;
9357 struct _GtkWindowKeyEntry
9361 guint is_mnemonic : 1;
9365 window_key_entry_destroy (gpointer data)
9367 g_slice_free (GtkWindowKeyEntry, data);
9371 add_to_key_hash (GtkWindow *window,
9373 GdkModifierType modifiers,
9374 gboolean is_mnemonic,
9377 GtkKeyHash *key_hash = data;
9379 GtkWindowKeyEntry *entry = g_slice_new (GtkWindowKeyEntry);
9381 entry->keyval = keyval;
9382 entry->modifiers = modifiers;
9383 entry->is_mnemonic = is_mnemonic;
9385 /* GtkAccelGroup stores lowercased accelerators. To deal
9386 * with this, if <Shift> was specified, uppercase.
9388 if (modifiers & GDK_SHIFT_MASK)
9390 if (keyval == GDK_KEY_Tab)
9391 keyval = GDK_KEY_ISO_Left_Tab;
9393 keyval = gdk_keyval_to_upper (keyval);
9396 _gtk_key_hash_add_entry (key_hash, keyval, entry->modifiers, entry);
9400 gtk_window_get_key_hash (GtkWindow *window)
9402 GdkScreen *screen = gtk_window_check_screen (window);
9403 GtkKeyHash *key_hash = g_object_get_qdata (G_OBJECT (window), quark_gtk_window_key_hash);
9408 key_hash = _gtk_key_hash_new (gdk_keymap_get_for_display (gdk_screen_get_display (screen)),
9409 (GDestroyNotify)window_key_entry_destroy);
9410 _gtk_window_keys_foreach (window, add_to_key_hash, key_hash);
9411 g_object_set_qdata (G_OBJECT (window), quark_gtk_window_key_hash, key_hash);
9417 gtk_window_free_key_hash (GtkWindow *window)
9419 GtkKeyHash *key_hash = g_object_get_qdata (G_OBJECT (window), quark_gtk_window_key_hash);
9422 _gtk_key_hash_free (key_hash);
9423 g_object_set_qdata (G_OBJECT (window), quark_gtk_window_key_hash, NULL);
9428 * gtk_window_activate_key:
9429 * @window: a #GtkWindow
9430 * @event: a #GdkEventKey
9432 * Activates mnemonics and accelerators for this #GtkWindow. This is normally
9433 * called by the default ::key_press_event handler for toplevel windows,
9434 * however in some cases it may be useful to call this directly when
9435 * overriding the standard key handling for a toplevel window.
9437 * Return value: %TRUE if a mnemonic or accelerator was found and activated.
9442 gtk_window_activate_key (GtkWindow *window,
9445 GtkKeyHash *key_hash;
9446 GtkWindowKeyEntry *found_entry = NULL;
9447 gboolean enable_mnemonics;
9448 gboolean enable_accels;
9450 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
9451 g_return_val_if_fail (event != NULL, FALSE);
9453 key_hash = gtk_window_get_key_hash (window);
9458 GSList *entries = _gtk_key_hash_lookup (key_hash,
9459 event->hardware_keycode,
9461 gtk_accelerator_get_default_mod_mask (),
9464 g_object_get (gtk_widget_get_settings (GTK_WIDGET (window)),
9465 "gtk-enable-mnemonics", &enable_mnemonics,
9466 "gtk-enable-accels", &enable_accels,
9469 for (tmp_list = entries; tmp_list; tmp_list = tmp_list->next)
9471 GtkWindowKeyEntry *entry = tmp_list->data;
9472 if (entry->is_mnemonic)
9474 if (enable_mnemonics)
9476 found_entry = entry;
9482 if (enable_accels && !found_entry)
9484 found_entry = entry;
9489 g_slist_free (entries);
9494 if (found_entry->is_mnemonic)
9496 if (enable_mnemonics)
9497 return gtk_window_mnemonic_activate (window, found_entry->keyval,
9498 found_entry->modifiers);
9503 return gtk_accel_groups_activate (G_OBJECT (window), found_entry->keyval,
9504 found_entry->modifiers);
9512 window_update_has_focus (GtkWindow *window)
9514 GtkWindowPrivate *priv = window->priv;
9515 GtkWidget *widget = GTK_WIDGET (window);
9516 gboolean has_focus = priv->has_toplevel_focus && priv->is_active;
9518 if (has_focus != priv->has_focus)
9520 priv->has_focus = has_focus;
9524 if (priv->focus_widget &&
9525 priv->focus_widget != widget &&
9526 !gtk_widget_has_focus (priv->focus_widget))
9527 do_focus_change (priv->focus_widget, TRUE);
9531 if (priv->focus_widget &&
9532 priv->focus_widget != widget &&
9533 gtk_widget_has_focus (priv->focus_widget))
9534 do_focus_change (priv->focus_widget, FALSE);
9540 * _gtk_window_set_is_active:
9541 * @window: a #GtkWindow
9542 * @is_active: %TRUE if the window is in the currently active toplevel
9544 * Internal function that sets whether the #GtkWindow is part
9545 * of the currently active toplevel window (taking into account inter-process
9549 _gtk_window_set_is_active (GtkWindow *window,
9552 GtkWindowPrivate *priv;
9554 g_return_if_fail (GTK_IS_WINDOW (window));
9556 priv = window->priv;
9558 is_active = is_active != FALSE;
9560 if (is_active != priv->is_active)
9562 priv->is_active = is_active;
9563 window_update_has_focus (window);
9565 g_object_notify (G_OBJECT (window), "is-active");
9570 * _gtk_window_set_is_toplevel:
9571 * @window: a #GtkWindow
9572 * @is_toplevel: %TRUE if the window is still a real toplevel (nominally a
9573 * child of the root window); %FALSE if it is not (for example, for an
9574 * in-process, parented GtkPlug)
9576 * Internal function used by #GtkPlug when it gets parented/unparented by a
9577 * #GtkSocket. This keeps the @window's #GTK_TOPLEVEL flag in sync with the
9578 * global list of toplevel windows.
9581 _gtk_window_set_is_toplevel (GtkWindow *window,
9582 gboolean is_toplevel)
9585 GtkWidget *toplevel;
9587 widget = GTK_WIDGET (window);
9589 if (gtk_widget_is_toplevel (widget))
9590 g_assert (g_slist_find (toplevel_list, window) != NULL);
9592 g_assert (g_slist_find (toplevel_list, window) == NULL);
9594 if (is_toplevel == gtk_widget_is_toplevel (widget))
9599 /* Pass through regular pathways of an embedded toplevel
9600 * to go through unmapping and hiding the widget before
9601 * becomming a toplevel again.
9603 * We remain hidden after becomming toplevel in order to
9604 * avoid problems during an embedded toplevel's dispose cycle
9605 * (When a toplevel window is shown it tries to grab focus again,
9606 * this causes problems while disposing).
9608 gtk_widget_hide (widget);
9610 /* Save the toplevel this widget was previously anchored into before
9611 * propagating a hierarchy-changed.
9613 * Usually this happens by way of gtk_widget_unparent() and we are
9614 * already unanchored at this point, just adding this clause incase
9615 * things happen differently.
9617 toplevel = gtk_widget_get_toplevel (widget);
9618 if (!gtk_widget_is_toplevel (toplevel))
9621 _gtk_widget_set_is_toplevel (widget, TRUE);
9623 /* When a window becomes toplevel after being embedded and anchored
9624 * into another window we need to unset its anchored flag so that
9625 * the hierarchy changed signal kicks in properly.
9627 _gtk_widget_set_anchored (widget, FALSE);
9628 _gtk_widget_propagate_hierarchy_changed (widget, toplevel);
9630 toplevel_list = g_slist_prepend (toplevel_list, window);
9634 _gtk_widget_set_is_toplevel (widget, FALSE);
9635 toplevel_list = g_slist_remove (toplevel_list, window);
9637 _gtk_widget_propagate_hierarchy_changed (widget, widget);
9642 * _gtk_window_set_has_toplevel_focus:
9643 * @window: a #GtkWindow
9644 * @has_toplevel_focus: %TRUE if the in
9646 * Internal function that sets whether the keyboard focus for the
9647 * toplevel window (taking into account inter-process embedding.)
9650 _gtk_window_set_has_toplevel_focus (GtkWindow *window,
9651 gboolean has_toplevel_focus)
9653 GtkWindowPrivate *priv;
9655 g_return_if_fail (GTK_IS_WINDOW (window));
9657 priv = window->priv;
9659 has_toplevel_focus = has_toplevel_focus != FALSE;
9661 if (has_toplevel_focus != priv->has_toplevel_focus)
9663 priv->has_toplevel_focus = has_toplevel_focus;
9664 window_update_has_focus (window);
9666 g_object_notify (G_OBJECT (window), "has-toplevel-focus");
9671 * gtk_window_set_auto_startup_notification:
9672 * @setting: %TRUE to automatically do startup notification
9674 * By default, after showing the first #GtkWindow, GTK+ calls
9675 * gdk_notify_startup_complete(). Call this function to disable
9676 * the automatic startup notification. You might do this if your
9677 * first window is a splash screen, and you want to delay notification
9678 * until after your real main window has been shown, for example.
9680 * In that example, you would disable startup notification
9681 * temporarily, show your splash screen, then re-enable it so that
9682 * showing the main window would automatically result in notification.
9687 gtk_window_set_auto_startup_notification (gboolean setting)
9689 disable_startup_notification = !setting;
9693 * gtk_window_get_window_type:
9694 * @window: a #GtkWindow
9696 * Gets the type of the window. See #GtkWindowType.
9698 * Return value: the type of the window
9703 gtk_window_get_window_type (GtkWindow *window)
9705 g_return_val_if_fail (GTK_IS_WINDOW (window), GTK_WINDOW_TOPLEVEL);
9707 return window->priv->type;
9711 * gtk_window_get_mnemonics_visible:
9712 * @window: a #GtkWindow
9714 * Gets the value of the #GtkWindow:mnemonics-visible property.
9716 * Returns: %TRUE if mnemonics are supposed to be visible
9722 gtk_window_get_mnemonics_visible (GtkWindow *window)
9724 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
9726 return window->priv->mnemonics_visible;
9730 * gtk_window_set_mnemonics_visible:
9731 * @window: a #GtkWindow
9732 * @setting: the new value
9734 * Sets the #GtkWindow:mnemonics-visible property.
9739 gtk_window_set_mnemonics_visible (GtkWindow *window,
9742 GtkWindowPrivate *priv;
9744 g_return_if_fail (GTK_IS_WINDOW (window));
9746 priv = window->priv;
9748 setting = setting != FALSE;
9750 if (priv->mnemonics_visible != setting)
9752 priv->mnemonics_visible = setting;
9753 g_object_notify (G_OBJECT (window), "mnemonics-visible");
9756 priv->mnemonics_visible_set = TRUE;
9760 * gtk_window_get_focus_visible:
9761 * @window: a #GtkWindow
9763 * Gets the value of the #GtkWindow:focus-visible property.
9765 * Returns: %TRUE if 'focus rectangles' are supposed to be visible
9771 gtk_window_get_focus_visible (GtkWindow *window)
9773 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
9775 return window->priv->focus_visible;
9779 * gtk_window_set_focus_visible:
9780 * @window: a #GtkWindow
9781 * @setting: the new value
9783 * Sets the #GtkWindow:focus-visible property.
9788 gtk_window_set_focus_visible (GtkWindow *window,
9791 GtkWindowPrivate *priv;
9793 g_return_if_fail (GTK_IS_WINDOW (window));
9795 priv = window->priv;
9797 setting = setting != FALSE;
9799 if (priv->focus_visible != setting)
9801 priv->focus_visible = setting;
9802 g_object_notify (G_OBJECT (window), "focus-visible");
9807 _gtk_window_get_wmclass (GtkWindow *window,
9808 gchar **wmclass_name,
9809 gchar **wmclass_class)
9811 GtkWindowPrivate *priv = window->priv;
9813 *wmclass_name = priv->wmclass_name;
9814 *wmclass_class = priv->wmclass_class;
9818 * gtk_window_set_has_user_ref_count:
9819 * @window: a #GtkWindow
9820 * @setting: the new value
9822 * Tells GTK+ whether to drop its extra reference to the window
9823 * when gtk_window_destroy() is called.
9825 * This function is only exported for the benefit of language
9826 * bindings which may need to keep the window alive until their
9827 * wrapper object is garbage collected. There is no justification
9828 * for ever calling this function in an application.
9833 gtk_window_set_has_user_ref_count (GtkWindow *window,
9836 g_return_if_fail (GTK_IS_WINDOW (window));
9838 window->priv->has_user_ref_count = setting;
9842 ensure_state_flag_backdrop (GtkWidget *widget)
9845 gboolean window_focused = TRUE;
9847 window = gtk_widget_get_window (widget);
9849 window_focused = gdk_window_get_state (window) & GDK_WINDOW_STATE_FOCUSED;
9851 if (!window_focused)
9852 gtk_widget_set_state_flags (widget, GTK_STATE_FLAG_BACKDROP, FALSE);
9854 gtk_widget_unset_state_flags (widget, GTK_STATE_FLAG_BACKDROP);
9856 gtk_widget_queue_draw (widget);