1 /* GTK - The GIMP Toolkit
2 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
21 * Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
22 * file for a list of people on the GTK+ Team. See the ChangeLog
23 * files for a list of changes. These files are distributed with
24 * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
29 #include "gtkwindow.h"
36 #include "gtkprivate.h"
37 #include "gtkwindowprivate.h"
38 #include "gtkaccelgroupprivate.h"
39 #include "gtkbindings.h"
40 #include "gtkkeyhash.h"
42 #include "gtkmnemonichash.h"
43 #include "gtkmenubar.h"
44 #include "gtkiconfactory.h"
45 #include "gtkicontheme.h"
46 #include "gtkmarshalers.h"
48 #include "gtkbuildable.h"
49 #include "gtkwidgetprivate.h"
50 #include "gtkcontainerprivate.h"
52 #include "gtktypebuiltins.h"
53 #include "a11y/gtkwindowaccessible.h"
55 #include "deprecated/gtkstyle.h"
57 #ifdef GDK_WINDOWING_X11
64 * @short_description: Toplevel which can contain other widgets
66 * A GtkWindow is a toplevel window which can contain other widgets.
67 * Windows normally have decorations that are under the control
68 * of the windowing system and allow the user to manipulate the window
69 * (resize it, move it, close it,...).
71 * GTK+ also allows windows to have a resize grip (a small area in the lower
72 * right or left corner) which can be clicked to reszie the window. To
73 * control whether a window has a resize grip, use
74 * gtk_window_set_has_resize_grip().
76 * <refsect2 id="GtkWindow-BUILDER-UI">
77 * <title>GtkWindow as GtkBuildable</title>
79 * The GtkWindow implementation of the GtkBuildable interface supports a
80 * custom <tag class="starttag">accel-groups</tag> element, which supports
81 * any number of <tag class="starttag">group</tag> elements representing the
82 * #GtkAccelGroup objects you want to add to your window (synonymous with
83 * gtk_window_add_accel_group().
86 * <title>A UI definition fragment with accel groups</title>
87 * <programlisting><![CDATA[
88 * <object class="GtkWindow">
90 * <group name="accelgroup1"/>
96 * <object class="GtkAccelGroup" id="accelgroup1"/>
97 * ]]></programlisting>
102 typedef struct _GtkDeviceGrabInfo GtkDeviceGrabInfo;
104 struct _GtkWindowPrivate
106 GtkMnemonicHash *mnemonic_hash;
108 GtkWidget *attach_widget;
109 GtkWidget *default_widget;
110 GtkWidget *focus_widget;
111 GtkWindow *transient_parent;
112 GtkWindowGeometryInfo *geometry_info;
113 GtkWindowGroup *group;
115 GtkApplication *application;
117 GdkModifierType mnemonic_modifier;
118 GdkWindowTypeHint gdk_type_hint;
122 GdkWindow *grip_window;
126 gchar *wmclass_class;
130 guint keys_changed_handler;
132 guint32 initial_timestamp;
134 guint16 configure_request_count;
136 /* The following flags are initially TRUE (before a window is mapped).
137 * They cause us to compute a configure request that involves
138 * default-only parameters. Once mapped, we set them to FALSE.
139 * Then we set them to TRUE again on unmap (for position)
140 * and on unrealize (for size).
142 guint need_default_position : 1;
143 guint need_default_size : 1;
145 guint above_initially : 1;
146 guint accept_focus : 1;
147 guint below_initially : 1;
148 guint builder_visible : 1;
149 guint configure_notify_received : 1;
152 guint destroy_with_parent : 1;
153 guint focus_on_map : 1;
154 guint fullscreen_initially : 1;
156 guint has_user_ref_count : 1;
157 guint has_toplevel_focus : 1;
158 guint hide_titlebar_when_maximized : 1;
159 guint iconify_initially : 1; /* gtk_window_iconify() called before realization */
161 guint maximize_initially : 1;
162 guint mnemonics_visible : 1;
163 guint mnemonics_visible_set : 1;
164 guint focus_visible : 1;
166 guint opacity_set : 1;
168 guint reset_type_hint : 1;
170 guint skips_pager : 1;
171 guint skips_taskbar : 1;
172 guint stick_initially : 1;
173 guint transient_parent_group : 1;
174 guint type : 4; /* GtkWindowType */
175 guint type_hint : 3; /* GdkWindowTypeHint if the hint is
176 * one of the original eight. If not,
178 * GDK_WINDOW_TYPE_HINT_NORMAL
181 guint has_resize_grip : 1;
182 guint resize_grip_visible : 1; /* don't use, just for "resize-
183 * grip-visible" notification
185 guint gravity : 5; /* GdkGravity */
212 PROP_DESTROY_WITH_PARENT,
213 PROP_HIDE_TITLEBAR_WHEN_MAXIMIZED,
218 PROP_SKIP_TASKBAR_HINT,
219 PROP_SKIP_PAGER_HINT,
229 PROP_HAS_RESIZE_GRIP,
230 PROP_RESIZE_GRIP_VISIBLE,
232 /* Readonly properties */
234 PROP_HAS_TOPLEVEL_FOCUS,
236 /* Writeonly properties */
239 PROP_MNEMONICS_VISIBLE,
250 guint using_default_icon : 1;
251 guint using_parent_icon : 1;
252 guint using_themed_icon : 1;
256 GdkGeometry geometry; /* Last set of geometry hints we set */
257 GdkWindowHints flags;
258 GdkRectangle configure_request;
259 } GtkWindowLastGeometryInfo;
261 struct _GtkWindowGeometryInfo
263 /* Properties that the app has set on the window
265 GdkGeometry geometry; /* Geometry hints */
267 GtkWidget *widget; /* subwidget to which hints apply */
268 /* from last gtk_window_resize () - if > 0, indicates that
269 * we should resize to this size.
274 /* From last gtk_window_move () prior to mapping -
275 * only used if initial_pos_set
280 /* Default size - used only the FIRST time we map a window,
285 /* whether to use initial_x, initial_y */
286 guint initial_pos_set : 1;
287 /* CENTER_ALWAYS or other position constraint changed since
288 * we sent the last configure request.
290 guint position_constraints_changed : 1;
292 /* if true, default_width, height should be multiplied by the
293 * increments and affect the geometry widget only
295 guint default_is_geometry : 1;
297 /* if true, resize_width, height should be multiplied by the
298 * increments and affect the geometry widget only
300 guint resize_is_geometry : 1;
302 GtkWindowLastGeometryInfo last;
306 struct _GtkDeviceGrabInfo
310 guint block_others : 1;
313 struct _GtkWindowGroupPrivate
316 GSList *device_grabs;
319 static void gtk_window_dispose (GObject *object);
320 static void gtk_window_finalize (GObject *object);
321 static void gtk_window_destroy (GtkWidget *widget);
322 static void gtk_window_show (GtkWidget *widget);
323 static void gtk_window_hide (GtkWidget *widget);
324 static void gtk_window_map (GtkWidget *widget);
325 static void gtk_window_unmap (GtkWidget *widget);
326 static void gtk_window_realize (GtkWidget *widget);
327 static void gtk_window_unrealize (GtkWidget *widget);
328 static void gtk_window_size_allocate (GtkWidget *widget,
329 GtkAllocation *allocation);
330 static gboolean gtk_window_map_event (GtkWidget *widget,
332 static gint gtk_window_configure_event (GtkWidget *widget,
333 GdkEventConfigure *event);
334 static gint gtk_window_key_press_event (GtkWidget *widget,
336 static gint gtk_window_key_release_event (GtkWidget *widget,
338 static gint gtk_window_button_press_event (GtkWidget *widget,
339 GdkEventButton *event);
340 static gint gtk_window_enter_notify_event (GtkWidget *widget,
341 GdkEventCrossing *event);
342 static gint gtk_window_leave_notify_event (GtkWidget *widget,
343 GdkEventCrossing *event);
344 static gint gtk_window_focus_in_event (GtkWidget *widget,
345 GdkEventFocus *event);
346 static gint gtk_window_focus_out_event (GtkWidget *widget,
347 GdkEventFocus *event);
348 static void gtk_window_style_updated (GtkWidget *widget);
349 static gboolean gtk_window_state_event (GtkWidget *widget,
350 GdkEventWindowState *event);
351 static void gtk_window_check_resize (GtkContainer *container);
352 static gint gtk_window_focus (GtkWidget *widget,
353 GtkDirectionType direction);
354 static void gtk_window_move_focus (GtkWidget *widget,
355 GtkDirectionType dir);
356 static void gtk_window_real_set_focus (GtkWindow *window,
358 static void gtk_window_direction_changed (GtkWidget *widget,
359 GtkTextDirection prev_dir);
360 static void gtk_window_state_changed (GtkWidget *widget,
361 GtkStateType previous_state);
363 static void gtk_window_real_activate_default (GtkWindow *window);
364 static void gtk_window_real_activate_focus (GtkWindow *window);
365 static void gtk_window_keys_changed (GtkWindow *window);
366 static gint gtk_window_draw (GtkWidget *widget,
368 static void gtk_window_unset_transient_for (GtkWindow *window);
369 static void gtk_window_transient_parent_realized (GtkWidget *parent,
371 static void gtk_window_transient_parent_unrealized (GtkWidget *parent,
374 static GdkScreen *gtk_window_check_screen (GtkWindow *window);
376 static GtkWindowGeometryInfo* gtk_window_get_geometry_info (GtkWindow *window,
379 static void gtk_window_move_resize (GtkWindow *window);
380 static gboolean gtk_window_compare_hints (GdkGeometry *geometry_a,
382 GdkGeometry *geometry_b,
384 static void gtk_window_constrain_size (GtkWindow *window,
385 GdkGeometry *geometry,
391 static void gtk_window_constrain_position (GtkWindow *window,
396 static void gtk_window_compute_hints (GtkWindow *window,
397 GdkGeometry *new_geometry,
399 static void gtk_window_compute_configure_request (GtkWindow *window,
400 GdkRectangle *request,
401 GdkGeometry *geometry,
404 static void gtk_window_set_default_size_internal (GtkWindow *window,
405 gboolean change_width,
407 gboolean change_height,
409 gboolean is_geometry);
411 static void update_themed_icon (GtkIconTheme *theme,
413 static GList *icon_list_from_theme (GtkWidget *widget,
415 static void gtk_window_realize_icon (GtkWindow *window);
416 static void gtk_window_unrealize_icon (GtkWindow *window);
417 static void resize_grip_create_window (GtkWindow *window);
418 static void resize_grip_destroy_window (GtkWindow *window);
419 static void update_grip_visibility (GtkWindow *window);
421 static void gtk_window_notify_keys_changed (GtkWindow *window);
422 static GtkKeyHash *gtk_window_get_key_hash (GtkWindow *window);
423 static void gtk_window_free_key_hash (GtkWindow *window);
424 static void gtk_window_on_composited_changed (GdkScreen *screen,
426 static void gtk_window_on_theme_variant_changed (GtkSettings *settings,
429 static void gtk_window_set_theme_variant (GtkWindow *window);
431 static GSList *toplevel_list = NULL;
432 static guint window_signals[LAST_SIGNAL] = { 0 };
433 static GList *default_icon_list = NULL;
434 static gchar *default_icon_name = NULL;
435 static guint default_icon_serial = 0;
436 static gboolean disable_startup_notification = FALSE;
437 static gboolean sent_startup_notification = FALSE;
439 static GQuark quark_gtk_embedded = 0;
440 static GQuark quark_gtk_window_key_hash = 0;
441 static GQuark quark_gtk_window_icon_info = 0;
442 static GQuark quark_gtk_buildable_accels = 0;
444 static GtkBuildableIface *parent_buildable_iface;
446 static void gtk_window_set_property (GObject *object,
450 static void gtk_window_get_property (GObject *object,
456 static void gtk_window_buildable_interface_init (GtkBuildableIface *iface);
457 static void gtk_window_buildable_set_buildable_property (GtkBuildable *buildable,
460 const GValue *value);
461 static void gtk_window_buildable_parser_finished (GtkBuildable *buildable,
462 GtkBuilder *builder);
463 static gboolean gtk_window_buildable_custom_tag_start (GtkBuildable *buildable,
466 const gchar *tagname,
467 GMarkupParser *parser,
469 static void gtk_window_buildable_custom_finished (GtkBuildable *buildable,
472 const gchar *tagname,
476 static void gtk_window_get_preferred_width (GtkWidget *widget,
479 static void gtk_window_get_preferred_height (GtkWidget *widget,
483 static void ensure_state_flag_backdrop (GtkWidget *widget);
485 G_DEFINE_TYPE_WITH_CODE (GtkWindow, gtk_window, GTK_TYPE_BIN,
486 G_IMPLEMENT_INTERFACE (GTK_TYPE_BUILDABLE,
487 gtk_window_buildable_interface_init))
490 add_tab_bindings (GtkBindingSet *binding_set,
491 GdkModifierType modifiers,
492 GtkDirectionType direction)
494 gtk_binding_entry_add_signal (binding_set, GDK_KEY_Tab, modifiers,
496 GTK_TYPE_DIRECTION_TYPE, direction);
497 gtk_binding_entry_add_signal (binding_set, GDK_KEY_KP_Tab, modifiers,
499 GTK_TYPE_DIRECTION_TYPE, direction);
503 add_arrow_bindings (GtkBindingSet *binding_set,
505 GtkDirectionType direction)
507 guint keypad_keysym = keysym - GDK_KEY_Left + GDK_KEY_KP_Left;
509 gtk_binding_entry_add_signal (binding_set, keysym, 0,
511 GTK_TYPE_DIRECTION_TYPE, direction);
512 gtk_binding_entry_add_signal (binding_set, keysym, GDK_CONTROL_MASK,
514 GTK_TYPE_DIRECTION_TYPE, direction);
515 gtk_binding_entry_add_signal (binding_set, keypad_keysym, 0,
517 GTK_TYPE_DIRECTION_TYPE, direction);
518 gtk_binding_entry_add_signal (binding_set, keypad_keysym, GDK_CONTROL_MASK,
520 GTK_TYPE_DIRECTION_TYPE, direction);
524 extract_time_from_startup_id (const gchar* startup_id)
526 gchar *timestr = g_strrstr (startup_id, "_TIME");
527 guint32 retval = GDK_CURRENT_TIME;
534 /* Skip past the "_TIME" part */
539 timestamp = g_ascii_strtoull (timestr, &end, 0);
540 if (errno == 0 && end != timestr)
548 startup_id_is_fake (const gchar* startup_id)
550 return strncmp (startup_id, "_TIME", 5) == 0;
554 gtk_window_class_init (GtkWindowClass *klass)
556 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
557 GtkWidgetClass *widget_class;
558 GtkContainerClass *container_class;
559 GtkBindingSet *binding_set;
561 widget_class = (GtkWidgetClass*) klass;
562 container_class = (GtkContainerClass*) klass;
564 quark_gtk_embedded = g_quark_from_static_string ("gtk-embedded");
565 quark_gtk_window_key_hash = g_quark_from_static_string ("gtk-window-key-hash");
566 quark_gtk_window_icon_info = g_quark_from_static_string ("gtk-window-icon-info");
567 quark_gtk_buildable_accels = g_quark_from_static_string ("gtk-window-buildable-accels");
569 gobject_class->dispose = gtk_window_dispose;
570 gobject_class->finalize = gtk_window_finalize;
572 gobject_class->set_property = gtk_window_set_property;
573 gobject_class->get_property = gtk_window_get_property;
575 widget_class->destroy = gtk_window_destroy;
576 widget_class->show = gtk_window_show;
577 widget_class->hide = gtk_window_hide;
578 widget_class->map = gtk_window_map;
579 widget_class->map_event = gtk_window_map_event;
580 widget_class->unmap = gtk_window_unmap;
581 widget_class->realize = gtk_window_realize;
582 widget_class->unrealize = gtk_window_unrealize;
583 widget_class->size_allocate = gtk_window_size_allocate;
584 widget_class->configure_event = gtk_window_configure_event;
585 widget_class->key_press_event = gtk_window_key_press_event;
586 widget_class->key_release_event = gtk_window_key_release_event;
587 widget_class->enter_notify_event = gtk_window_enter_notify_event;
588 widget_class->leave_notify_event = gtk_window_leave_notify_event;
589 widget_class->focus_in_event = gtk_window_focus_in_event;
590 widget_class->button_press_event = gtk_window_button_press_event;
591 widget_class->focus_out_event = gtk_window_focus_out_event;
592 widget_class->focus = gtk_window_focus;
593 widget_class->move_focus = gtk_window_move_focus;
594 widget_class->draw = gtk_window_draw;
595 widget_class->get_preferred_width = gtk_window_get_preferred_width;
596 widget_class->get_preferred_height = gtk_window_get_preferred_height;
597 widget_class->window_state_event = gtk_window_state_event;
598 widget_class->direction_changed = gtk_window_direction_changed;
599 widget_class->state_changed = gtk_window_state_changed;
600 widget_class->style_updated = gtk_window_style_updated;
602 container_class->check_resize = gtk_window_check_resize;
604 klass->set_focus = gtk_window_real_set_focus;
606 klass->activate_default = gtk_window_real_activate_default;
607 klass->activate_focus = gtk_window_real_activate_focus;
608 klass->keys_changed = gtk_window_keys_changed;
610 g_type_class_add_private (gobject_class, sizeof (GtkWindowPrivate));
613 g_object_class_install_property (gobject_class,
615 g_param_spec_enum ("type",
617 P_("The type of the window"),
618 GTK_TYPE_WINDOW_TYPE,
620 GTK_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
622 g_object_class_install_property (gobject_class,
624 g_param_spec_string ("title",
626 P_("The title of the window"),
628 GTK_PARAM_READWRITE));
630 g_object_class_install_property (gobject_class,
632 g_param_spec_string ("role",
634 P_("Unique identifier for the window to be used when restoring a session"),
636 GTK_PARAM_READWRITE));
639 * GtkWindow:startup-id:
641 * The :startup-id is a write-only property for setting window's
642 * startup notification identifier. See gtk_window_set_startup_id()
647 g_object_class_install_property (gobject_class,
649 g_param_spec_string ("startup-id",
651 P_("Unique startup identifier for the window used by startup-notification"),
653 GTK_PARAM_WRITABLE));
655 g_object_class_install_property (gobject_class,
657 g_param_spec_boolean ("resizable",
659 P_("If TRUE, users can resize the window"),
661 GTK_PARAM_READWRITE));
663 g_object_class_install_property (gobject_class,
665 g_param_spec_boolean ("modal",
667 P_("If TRUE, the window is modal (other windows are not usable while this one is up)"),
669 GTK_PARAM_READWRITE));
671 g_object_class_install_property (gobject_class,
673 g_param_spec_enum ("window-position",
674 P_("Window Position"),
675 P_("The initial position of the window"),
676 GTK_TYPE_WINDOW_POSITION,
678 GTK_PARAM_READWRITE));
680 g_object_class_install_property (gobject_class,
682 g_param_spec_int ("default-width",
684 P_("The default width of the window, used when initially showing the window"),
688 GTK_PARAM_READWRITE));
690 g_object_class_install_property (gobject_class,
692 g_param_spec_int ("default-height",
693 P_("Default Height"),
694 P_("The default height of the window, used when initially showing the window"),
698 GTK_PARAM_READWRITE));
700 g_object_class_install_property (gobject_class,
701 PROP_DESTROY_WITH_PARENT,
702 g_param_spec_boolean ("destroy-with-parent",
703 P_("Destroy with Parent"),
704 P_("If this window should be destroyed when the parent is destroyed"),
706 GTK_PARAM_READWRITE));
709 * GtkWindow:hide-titlebar-when-maximized:
711 * Whether the titlebar should be hidden during maximization.
715 g_object_class_install_property (gobject_class,
716 PROP_HIDE_TITLEBAR_WHEN_MAXIMIZED,
717 g_param_spec_boolean ("hide-titlebar-when-maximized",
718 P_("Hide the titlebar during maximization"),
719 P_("If this window's titlebar should be hidden when the window is maximized"),
721 GTK_PARAM_READWRITE));
723 g_object_class_install_property (gobject_class,
725 g_param_spec_object ("icon",
727 P_("Icon for this window"),
729 GTK_PARAM_READWRITE));
732 * GtkWindow:mnemonics-visible:
734 * Whether mnemonics are currently visible in this window.
736 * This property is maintained by GTK+ based on the
737 * #GtkSettings:gtk-auto-mnemonics setting and user input,
738 * and should not be set by applications.
742 g_object_class_install_property (gobject_class,
743 PROP_MNEMONICS_VISIBLE,
744 g_param_spec_boolean ("mnemonics-visible",
745 P_("Mnemonics Visible"),
746 P_("Whether mnemonics are currently visible in this window"),
748 GTK_PARAM_READWRITE));
751 * GtkWindow:focus-visible:
753 * Whether 'focus rectangles' are currently visible in this window.
755 * This property is maintained by GTK+ based on the
756 * #GtkSettings:gtk-visible-focus setting and user input
757 * and should not be set by applications.
761 g_object_class_install_property (gobject_class,
763 g_param_spec_boolean ("focus-visible",
765 P_("Whether focus rectangles are currently visible in this window"),
767 GTK_PARAM_READWRITE));
770 * GtkWindow:icon-name:
772 * The :icon-name property specifies the name of the themed icon to
773 * use as the window icon. See #GtkIconTheme for more details.
777 g_object_class_install_property (gobject_class,
779 g_param_spec_string ("icon-name",
781 P_("Name of the themed icon for this window"),
783 GTK_PARAM_READWRITE));
785 g_object_class_install_property (gobject_class,
787 g_param_spec_object ("screen",
789 P_("The screen where this window will be displayed"),
791 GTK_PARAM_READWRITE));
793 g_object_class_install_property (gobject_class,
795 g_param_spec_boolean ("is-active",
797 P_("Whether the toplevel is the current active window"),
799 GTK_PARAM_READABLE));
801 g_object_class_install_property (gobject_class,
802 PROP_HAS_TOPLEVEL_FOCUS,
803 g_param_spec_boolean ("has-toplevel-focus",
804 P_("Focus in Toplevel"),
805 P_("Whether the input focus is within this GtkWindow"),
807 GTK_PARAM_READABLE));
809 g_object_class_install_property (gobject_class,
811 g_param_spec_enum ("type-hint",
813 P_("Hint to help the desktop environment understand what kind of window this is and how to treat it."),
814 GDK_TYPE_WINDOW_TYPE_HINT,
815 GDK_WINDOW_TYPE_HINT_NORMAL,
816 GTK_PARAM_READWRITE));
818 g_object_class_install_property (gobject_class,
819 PROP_SKIP_TASKBAR_HINT,
820 g_param_spec_boolean ("skip-taskbar-hint",
822 P_("TRUE if the window should not be in the task bar."),
824 GTK_PARAM_READWRITE));
826 g_object_class_install_property (gobject_class,
827 PROP_SKIP_PAGER_HINT,
828 g_param_spec_boolean ("skip-pager-hint",
830 P_("TRUE if the window should not be in the pager."),
832 GTK_PARAM_READWRITE));
834 g_object_class_install_property (gobject_class,
836 g_param_spec_boolean ("urgency-hint",
838 P_("TRUE if the window should be brought to the user's attention."),
840 GTK_PARAM_READWRITE));
843 * GtkWindow:accept-focus:
845 * Whether the window should receive the input focus.
849 g_object_class_install_property (gobject_class,
851 g_param_spec_boolean ("accept-focus",
853 P_("TRUE if the window should receive the input focus."),
855 GTK_PARAM_READWRITE));
858 * GtkWindow:focus-on-map:
860 * Whether the window should receive the input focus when mapped.
864 g_object_class_install_property (gobject_class,
866 g_param_spec_boolean ("focus-on-map",
868 P_("TRUE if the window should receive the input focus when mapped."),
870 GTK_PARAM_READWRITE));
873 * GtkWindow:decorated:
875 * Whether the window should be decorated by the window manager.
879 g_object_class_install_property (gobject_class,
881 g_param_spec_boolean ("decorated",
883 P_("Whether the window should be decorated by the window manager"),
885 GTK_PARAM_READWRITE));
888 * GtkWindow:deletable:
890 * Whether the window frame should have a close button.
894 g_object_class_install_property (gobject_class,
896 g_param_spec_boolean ("deletable",
898 P_("Whether the window frame should have a close button"),
900 GTK_PARAM_READWRITE));
903 * GtkWindow:has-resize-grip
905 * Whether the window has a corner resize grip.
907 * Note that the resize grip is only shown if the window is
908 * actually resizable and not maximized. Use
909 * #GtkWindow:resize-grip-visible to find out if the resize
910 * grip is currently shown.
914 g_object_class_install_property (gobject_class,
915 PROP_HAS_RESIZE_GRIP,
916 g_param_spec_boolean ("has-resize-grip",
918 P_("Specifies whether the window should have a resize grip"),
920 GTK_PARAM_READWRITE));
923 * GtkWindow:resize-grip-visible:
925 * Whether a corner resize grip is currently shown.
929 g_object_class_install_property (gobject_class,
930 PROP_RESIZE_GRIP_VISIBLE,
931 g_param_spec_boolean ("resize-grip-visible",
932 P_("Resize grip is visible"),
933 P_("Specifies whether the window's resize grip is visible."),
935 GTK_PARAM_READABLE));
941 * The window gravity of the window. See gtk_window_move() and #GdkGravity for
942 * more details about window gravity.
946 g_object_class_install_property (gobject_class,
948 g_param_spec_enum ("gravity",
950 P_("The window gravity of the window"),
952 GDK_GRAVITY_NORTH_WEST,
953 GTK_PARAM_READWRITE));
957 * GtkWindow:transient-for:
959 * The transient parent of the window. See gtk_window_set_transient_for() for
960 * more details about transient windows.
964 g_object_class_install_property (gobject_class,
966 g_param_spec_object ("transient-for",
967 P_("Transient for Window"),
968 P_("The transient parent of the dialog"),
970 GTK_PARAM_READWRITE| G_PARAM_CONSTRUCT));
973 * GtkWindow:attached-to:
975 * The widget to which this window is attached.
976 * See gtk_window_set_attached_to().
978 * Examples of places where specifying this relation is useful are
979 * for instance a #GtkMenu created by a #GtkComboBox, a completion
980 * popup window created by #GtkEntry or a typeahead search entry
981 * created by #GtkTreeView.
985 g_object_class_install_property (gobject_class,
987 g_param_spec_object ("attached-to",
988 P_("Attached to Widget"),
989 P_("The widget where the window is attached"),
991 GTK_PARAM_READWRITE | G_PARAM_CONSTRUCT));
996 * The requested opacity of the window. See gtk_window_set_opacity() for
997 * more details about window opacity.
1001 g_object_class_install_property (gobject_class,
1003 g_param_spec_double ("opacity",
1004 P_("Opacity for Window"),
1005 P_("The opacity of the window, from 0 to 1"),
1009 GTK_PARAM_READWRITE));
1011 /* Style properties.
1013 gtk_widget_class_install_style_property (widget_class,
1014 g_param_spec_int ("resize-grip-width",
1015 P_("Width of resize grip"),
1016 P_("Width of resize grip"),
1017 0, G_MAXINT, 16, GTK_PARAM_READWRITE));
1019 gtk_widget_class_install_style_property (widget_class,
1020 g_param_spec_int ("resize-grip-height",
1021 P_("Height of resize grip"),
1022 P_("Height of resize grip"),
1023 0, G_MAXINT, 16, GTK_PARAM_READWRITE));
1027 * GtkWindow:application:
1029 * The #GtkApplication associated with the window.
1031 * The application will be kept alive for at least as long as it
1032 * has any windows associated with it (see g_application_hold()
1033 * for a way to keep it alive without windows).
1035 * Normally, the connection between the application and the window
1036 * will remain until the window is destroyed, but you can explicitly
1037 * remove it by setting the ::application property to %NULL.
1041 g_object_class_install_property (gobject_class,
1043 g_param_spec_object ("application",
1044 P_("GtkApplication"),
1045 P_("The GtkApplication for the window"),
1046 GTK_TYPE_APPLICATION,
1047 GTK_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
1049 window_signals[SET_FOCUS] =
1050 g_signal_new (I_("set-focus"),
1051 G_TYPE_FROM_CLASS (gobject_class),
1053 G_STRUCT_OFFSET (GtkWindowClass, set_focus),
1055 _gtk_marshal_VOID__OBJECT,
1060 * GtkWindow::activate-focus:
1061 * @window: the window which received the signal
1063 * The ::activate-focus signal is a
1064 * <link linkend="keybinding-signals">keybinding signal</link>
1065 * which gets emitted when the user activates the currently
1066 * focused widget of @window.
1068 window_signals[ACTIVATE_FOCUS] =
1069 g_signal_new (I_("activate-focus"),
1070 G_TYPE_FROM_CLASS (gobject_class),
1071 G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
1072 G_STRUCT_OFFSET (GtkWindowClass, activate_focus),
1074 _gtk_marshal_VOID__VOID,
1079 * GtkWindow::activate-default:
1080 * @window: the window which received the signal
1082 * The ::activate-default signal is a
1083 * <link linkend="keybinding-signals">keybinding signal</link>
1084 * which gets emitted when the user activates the default widget
1087 window_signals[ACTIVATE_DEFAULT] =
1088 g_signal_new (I_("activate-default"),
1089 G_TYPE_FROM_CLASS (gobject_class),
1090 G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
1091 G_STRUCT_OFFSET (GtkWindowClass, activate_default),
1093 _gtk_marshal_VOID__VOID,
1098 * GtkWindow::keys-changed:
1099 * @window: the window which received the signal
1101 * The ::keys-changed signal gets emitted when the set of accelerators
1102 * or mnemonics that are associated with @window changes.
1104 window_signals[KEYS_CHANGED] =
1105 g_signal_new (I_("keys-changed"),
1106 G_TYPE_FROM_CLASS (gobject_class),
1108 G_STRUCT_OFFSET (GtkWindowClass, keys_changed),
1110 _gtk_marshal_VOID__VOID,
1118 binding_set = gtk_binding_set_by_class (klass);
1120 gtk_binding_entry_add_signal (binding_set, GDK_KEY_space, 0,
1121 "activate-focus", 0);
1122 gtk_binding_entry_add_signal (binding_set, GDK_KEY_KP_Space, 0,
1123 "activate-focus", 0);
1125 gtk_binding_entry_add_signal (binding_set, GDK_KEY_Return, 0,
1126 "activate-default", 0);
1127 gtk_binding_entry_add_signal (binding_set, GDK_KEY_ISO_Enter, 0,
1128 "activate-default", 0);
1129 gtk_binding_entry_add_signal (binding_set, GDK_KEY_KP_Enter, 0,
1130 "activate-default", 0);
1132 add_arrow_bindings (binding_set, GDK_KEY_Up, GTK_DIR_UP);
1133 add_arrow_bindings (binding_set, GDK_KEY_Down, GTK_DIR_DOWN);
1134 add_arrow_bindings (binding_set, GDK_KEY_Left, GTK_DIR_LEFT);
1135 add_arrow_bindings (binding_set, GDK_KEY_Right, GTK_DIR_RIGHT);
1137 add_tab_bindings (binding_set, 0, GTK_DIR_TAB_FORWARD);
1138 add_tab_bindings (binding_set, GDK_CONTROL_MASK, GTK_DIR_TAB_FORWARD);
1139 add_tab_bindings (binding_set, GDK_SHIFT_MASK, GTK_DIR_TAB_BACKWARD);
1140 add_tab_bindings (binding_set, GDK_CONTROL_MASK | GDK_SHIFT_MASK, GTK_DIR_TAB_BACKWARD);
1142 gtk_widget_class_set_accessible_type (widget_class, GTK_TYPE_WINDOW_ACCESSIBLE);
1146 gtk_window_init (GtkWindow *window)
1148 GtkWindowPrivate *priv;
1150 window->priv = G_TYPE_INSTANCE_GET_PRIVATE (window,
1153 priv = window->priv;
1155 gtk_widget_set_has_window (GTK_WIDGET (window), TRUE);
1156 _gtk_widget_set_is_toplevel (GTK_WIDGET (window), TRUE);
1158 _gtk_widget_set_anchored (GTK_WIDGET (window), TRUE);
1160 gtk_container_set_resize_mode (GTK_CONTAINER (window), GTK_RESIZE_QUEUE);
1163 priv->wmclass_name = g_strdup (g_get_prgname ());
1164 priv->wmclass_class = g_strdup (gdk_get_program_class ());
1165 priv->wm_role = NULL;
1166 priv->geometry_info = NULL;
1167 priv->type = GTK_WINDOW_TOPLEVEL;
1168 priv->focus_widget = NULL;
1169 priv->default_widget = NULL;
1170 priv->configure_request_count = 0;
1171 priv->resizable = TRUE;
1172 priv->configure_notify_received = FALSE;
1173 priv->position = GTK_WIN_POS_NONE;
1174 priv->need_default_size = TRUE;
1175 priv->need_default_position = TRUE;
1176 priv->modal = FALSE;
1177 priv->gdk_type_hint = GDK_WINDOW_TYPE_HINT_NORMAL;
1178 priv->gravity = GDK_GRAVITY_NORTH_WEST;
1179 priv->decorated = TRUE;
1180 priv->mnemonic_modifier = GDK_MOD1_MASK;
1181 priv->screen = gdk_screen_get_default ();
1183 priv->accept_focus = TRUE;
1184 priv->focus_on_map = TRUE;
1185 priv->deletable = TRUE;
1186 priv->type_hint = GDK_WINDOW_TYPE_HINT_NORMAL;
1187 priv->opacity = 1.0;
1188 priv->startup_id = NULL;
1189 priv->initial_timestamp = GDK_CURRENT_TIME;
1190 priv->has_resize_grip = TRUE;
1191 priv->mnemonics_visible = TRUE;
1192 priv->focus_visible = TRUE;
1194 g_object_ref_sink (window);
1195 priv->has_user_ref_count = TRUE;
1196 toplevel_list = g_slist_prepend (toplevel_list, window);
1199 g_signal_connect (priv->screen, "composited-changed",
1200 G_CALLBACK (gtk_window_on_composited_changed), window);
1202 #ifdef GDK_WINDOWING_X11
1203 g_signal_connect (gtk_settings_get_for_screen (priv->screen),
1204 "notify::gtk-application-prefer-dark-theme",
1205 G_CALLBACK (gtk_window_on_theme_variant_changed), window);
1210 gtk_window_set_property (GObject *object,
1212 const GValue *value,
1215 GtkWindow *window = GTK_WINDOW (object);
1216 GtkWindowPrivate *priv = window->priv;
1221 priv->type = g_value_get_enum (value);
1224 gtk_window_set_title (window, g_value_get_string (value));
1227 gtk_window_set_role (window, g_value_get_string (value));
1229 case PROP_STARTUP_ID:
1230 gtk_window_set_startup_id (window, g_value_get_string (value));
1232 case PROP_RESIZABLE:
1233 gtk_window_set_resizable (window, g_value_get_boolean (value));
1236 gtk_window_set_modal (window, g_value_get_boolean (value));
1239 gtk_window_set_position (window, g_value_get_enum (value));
1241 case PROP_DEFAULT_WIDTH:
1242 gtk_window_set_default_size_internal (window,
1243 TRUE, g_value_get_int (value),
1246 case PROP_DEFAULT_HEIGHT:
1247 gtk_window_set_default_size_internal (window,
1249 TRUE, g_value_get_int (value), FALSE);
1251 case PROP_DESTROY_WITH_PARENT:
1252 gtk_window_set_destroy_with_parent (window, g_value_get_boolean (value));
1254 case PROP_HIDE_TITLEBAR_WHEN_MAXIMIZED:
1255 gtk_window_set_hide_titlebar_when_maximized (window, g_value_get_boolean (value));
1258 gtk_window_set_icon (window,
1259 g_value_get_object (value));
1261 case PROP_ICON_NAME:
1262 gtk_window_set_icon_name (window, g_value_get_string (value));
1265 gtk_window_set_screen (window, g_value_get_object (value));
1267 case PROP_TYPE_HINT:
1268 gtk_window_set_type_hint (window,
1269 g_value_get_enum (value));
1271 case PROP_SKIP_TASKBAR_HINT:
1272 gtk_window_set_skip_taskbar_hint (window,
1273 g_value_get_boolean (value));
1275 case PROP_SKIP_PAGER_HINT:
1276 gtk_window_set_skip_pager_hint (window,
1277 g_value_get_boolean (value));
1279 case PROP_URGENCY_HINT:
1280 gtk_window_set_urgency_hint (window,
1281 g_value_get_boolean (value));
1283 case PROP_ACCEPT_FOCUS:
1284 gtk_window_set_accept_focus (window,
1285 g_value_get_boolean (value));
1287 case PROP_FOCUS_ON_MAP:
1288 gtk_window_set_focus_on_map (window,
1289 g_value_get_boolean (value));
1291 case PROP_DECORATED:
1292 gtk_window_set_decorated (window, g_value_get_boolean (value));
1294 case PROP_DELETABLE:
1295 gtk_window_set_deletable (window, g_value_get_boolean (value));
1298 gtk_window_set_gravity (window, g_value_get_enum (value));
1300 case PROP_TRANSIENT_FOR:
1301 gtk_window_set_transient_for (window, g_value_get_object (value));
1303 case PROP_ATTACHED_TO:
1304 gtk_window_set_attached_to (window, g_value_get_object (value));
1307 gtk_window_set_opacity (window, g_value_get_double (value));
1309 case PROP_HAS_RESIZE_GRIP:
1310 gtk_window_set_has_resize_grip (window, g_value_get_boolean (value));
1312 case PROP_APPLICATION:
1313 gtk_window_set_application (window, g_value_get_object (value));
1315 case PROP_MNEMONICS_VISIBLE:
1316 gtk_window_set_mnemonics_visible (window, g_value_get_boolean (value));
1318 case PROP_FOCUS_VISIBLE:
1319 gtk_window_set_focus_visible (window, g_value_get_boolean (value));
1322 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1328 gtk_window_get_property (GObject *object,
1333 GtkWindow *window = GTK_WINDOW (object);
1334 GtkWindowPrivate *priv = window->priv;
1338 GtkWindowGeometryInfo *info;
1340 g_value_set_enum (value, priv->type);
1343 g_value_set_string (value, priv->wm_role);
1346 g_value_set_string (value, priv->title);
1348 case PROP_RESIZABLE:
1349 g_value_set_boolean (value, priv->resizable);
1352 g_value_set_boolean (value, priv->modal);
1355 g_value_set_enum (value, priv->position);
1357 case PROP_DEFAULT_WIDTH:
1358 info = gtk_window_get_geometry_info (window, FALSE);
1360 g_value_set_int (value, -1);
1362 g_value_set_int (value, info->default_width);
1364 case PROP_DEFAULT_HEIGHT:
1365 info = gtk_window_get_geometry_info (window, FALSE);
1367 g_value_set_int (value, -1);
1369 g_value_set_int (value, info->default_height);
1371 case PROP_DESTROY_WITH_PARENT:
1372 g_value_set_boolean (value, priv->destroy_with_parent);
1374 case PROP_HIDE_TITLEBAR_WHEN_MAXIMIZED:
1375 g_value_set_boolean (value, priv->hide_titlebar_when_maximized);
1378 g_value_set_object (value, gtk_window_get_icon (window));
1380 case PROP_ICON_NAME:
1381 g_value_set_string (value, gtk_window_get_icon_name (window));
1384 g_value_set_object (value, priv->screen);
1386 case PROP_IS_ACTIVE:
1387 g_value_set_boolean (value, priv->is_active);
1389 case PROP_HAS_TOPLEVEL_FOCUS:
1390 g_value_set_boolean (value, priv->has_toplevel_focus);
1392 case PROP_TYPE_HINT:
1393 g_value_set_enum (value, priv->type_hint);
1395 case PROP_SKIP_TASKBAR_HINT:
1396 g_value_set_boolean (value,
1397 gtk_window_get_skip_taskbar_hint (window));
1399 case PROP_SKIP_PAGER_HINT:
1400 g_value_set_boolean (value,
1401 gtk_window_get_skip_pager_hint (window));
1403 case PROP_URGENCY_HINT:
1404 g_value_set_boolean (value,
1405 gtk_window_get_urgency_hint (window));
1407 case PROP_ACCEPT_FOCUS:
1408 g_value_set_boolean (value,
1409 gtk_window_get_accept_focus (window));
1411 case PROP_FOCUS_ON_MAP:
1412 g_value_set_boolean (value,
1413 gtk_window_get_focus_on_map (window));
1415 case PROP_DECORATED:
1416 g_value_set_boolean (value, gtk_window_get_decorated (window));
1418 case PROP_DELETABLE:
1419 g_value_set_boolean (value, gtk_window_get_deletable (window));
1422 g_value_set_enum (value, gtk_window_get_gravity (window));
1424 case PROP_TRANSIENT_FOR:
1425 g_value_set_object (value, gtk_window_get_transient_for (window));
1427 case PROP_ATTACHED_TO:
1428 g_value_set_object (value, gtk_window_get_attached_to (window));
1431 g_value_set_double (value, gtk_window_get_opacity (window));
1433 case PROP_HAS_RESIZE_GRIP:
1434 g_value_set_boolean (value, priv->has_resize_grip);
1436 case PROP_RESIZE_GRIP_VISIBLE:
1437 g_value_set_boolean (value, gtk_window_resize_grip_is_visible (window));
1439 case PROP_APPLICATION:
1440 g_value_set_object (value, gtk_window_get_application (window));
1442 case PROP_MNEMONICS_VISIBLE:
1443 g_value_set_boolean (value, priv->mnemonics_visible);
1445 case PROP_FOCUS_VISIBLE:
1446 g_value_set_boolean (value, priv->focus_visible);
1449 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1455 gtk_window_buildable_interface_init (GtkBuildableIface *iface)
1457 parent_buildable_iface = g_type_interface_peek_parent (iface);
1458 iface->set_buildable_property = gtk_window_buildable_set_buildable_property;
1459 iface->parser_finished = gtk_window_buildable_parser_finished;
1460 iface->custom_tag_start = gtk_window_buildable_custom_tag_start;
1461 iface->custom_finished = gtk_window_buildable_custom_finished;
1465 gtk_window_buildable_set_buildable_property (GtkBuildable *buildable,
1466 GtkBuilder *builder,
1468 const GValue *value)
1470 GtkWindow *window = GTK_WINDOW (buildable);
1471 GtkWindowPrivate *priv = window->priv;
1473 if (strcmp (name, "visible") == 0 && g_value_get_boolean (value))
1474 priv->builder_visible = TRUE;
1476 parent_buildable_iface->set_buildable_property (buildable, builder, name, value);
1480 gtk_window_buildable_parser_finished (GtkBuildable *buildable,
1481 GtkBuilder *builder)
1483 GtkWindow *window = GTK_WINDOW (buildable);
1484 GtkWindowPrivate *priv = window->priv;
1488 if (priv->builder_visible)
1489 gtk_widget_show (GTK_WIDGET (buildable));
1491 accels = g_object_get_qdata (G_OBJECT (buildable), quark_gtk_buildable_accels);
1492 for (l = accels; l; l = l->next)
1494 object = gtk_builder_get_object (builder, l->data);
1497 g_warning ("Unknown accel group %s specified in window %s",
1498 (const gchar*)l->data, gtk_buildable_get_name (buildable));
1501 gtk_window_add_accel_group (GTK_WINDOW (buildable),
1502 GTK_ACCEL_GROUP (object));
1506 g_object_set_qdata (G_OBJECT (buildable), quark_gtk_buildable_accels, NULL);
1508 parent_buildable_iface->parser_finished (buildable, builder);
1514 } GSListSubParserData;
1517 window_start_element (GMarkupParseContext *context,
1518 const gchar *element_name,
1519 const gchar **names,
1520 const gchar **values,
1525 GSListSubParserData *data = (GSListSubParserData*)user_data;
1527 if (strcmp (element_name, "group") == 0)
1529 for (i = 0; names[i]; i++)
1531 if (strcmp (names[i], "name") == 0)
1532 data->items = g_slist_prepend (data->items, g_strdup (values[i]));
1535 else if (strcmp (element_name, "accel-groups") == 0)
1538 g_warning ("Unsupported tag type for GtkWindow: %s\n",
1543 static const GMarkupParser window_parser =
1545 window_start_element
1549 gtk_window_buildable_custom_tag_start (GtkBuildable *buildable,
1550 GtkBuilder *builder,
1552 const gchar *tagname,
1553 GMarkupParser *parser,
1556 GSListSubParserData *parser_data;
1558 if (parent_buildable_iface->custom_tag_start (buildable, builder, child,
1559 tagname, parser, data))
1562 if (strcmp (tagname, "accel-groups") == 0)
1564 parser_data = g_slice_new0 (GSListSubParserData);
1565 parser_data->items = NULL;
1566 parser_data->object = G_OBJECT (buildable);
1568 *parser = window_parser;
1569 *data = parser_data;
1577 gtk_window_buildable_custom_finished (GtkBuildable *buildable,
1578 GtkBuilder *builder,
1580 const gchar *tagname,
1583 GSListSubParserData *data;
1585 parent_buildable_iface->custom_finished (buildable, builder, child,
1586 tagname, user_data);
1588 if (strcmp (tagname, "accel-groups") != 0)
1591 data = (GSListSubParserData*)user_data;
1593 g_object_set_qdata_full (G_OBJECT (buildable), quark_gtk_buildable_accels,
1594 data->items, (GDestroyNotify) g_slist_free);
1596 g_slice_free (GSListSubParserData, data);
1601 * @type: type of window
1603 * Creates a new #GtkWindow, which is a toplevel window that can
1604 * contain other widgets. Nearly always, the type of the window should
1605 * be #GTK_WINDOW_TOPLEVEL. If you're implementing something like a
1606 * popup menu from scratch (which is a bad idea, just use #GtkMenu),
1607 * you might use #GTK_WINDOW_POPUP. #GTK_WINDOW_POPUP is not for
1608 * dialogs, though in some other toolkits dialogs are called "popups".
1609 * In GTK+, #GTK_WINDOW_POPUP means a pop-up menu or pop-up tooltip.
1610 * On X11, popup windows are not controlled by the <link
1611 * linkend="gtk-X11-arch">window manager</link>.
1613 * If you simply want an undecorated window (no window borders), use
1614 * gtk_window_set_decorated(), don't use #GTK_WINDOW_POPUP.
1616 * Return value: a new #GtkWindow.
1619 gtk_window_new (GtkWindowType type)
1621 GtkWindowPrivate *priv;
1624 g_return_val_if_fail (type >= GTK_WINDOW_TOPLEVEL && type <= GTK_WINDOW_POPUP, NULL);
1626 window = g_object_new (GTK_TYPE_WINDOW, NULL);
1627 priv = window->priv;
1631 return GTK_WIDGET (window);
1635 * gtk_window_set_title:
1636 * @window: a #GtkWindow
1637 * @title: title of the window
1639 * Sets the title of the #GtkWindow. The title of a window will be
1640 * displayed in its title bar; on the X Window System, the title bar
1641 * is rendered by the <link linkend="gtk-X11-arch">window
1642 * manager</link>, so exactly how the title appears to users may vary
1643 * according to a user's exact configuration. The title should help a
1644 * user distinguish this window from other windows they may have
1645 * open. A good title might include the application name and current
1646 * document filename, for example.
1650 gtk_window_set_title (GtkWindow *window,
1653 GtkWindowPrivate *priv;
1657 g_return_if_fail (GTK_IS_WINDOW (window));
1659 priv = window->priv;
1660 widget = GTK_WIDGET (window);
1662 new_title = g_strdup (title);
1663 g_free (priv->title);
1664 priv->title = new_title;
1666 if (gtk_widget_get_realized (widget))
1668 gdk_window_set_title (gtk_widget_get_window (widget),
1672 g_object_notify (G_OBJECT (window), "title");
1676 * gtk_window_get_title:
1677 * @window: a #GtkWindow
1679 * Retrieves the title of the window. See gtk_window_set_title().
1681 * Return value: the title of the window, or %NULL if none has
1682 * been set explicitely. The returned string is owned by the widget
1683 * and must not be modified or freed.
1686 gtk_window_get_title (GtkWindow *window)
1688 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
1690 return window->priv->title;
1694 * gtk_window_set_wmclass:
1695 * @window: a #GtkWindow
1696 * @wmclass_name: window name hint
1697 * @wmclass_class: window class hint
1699 * Don't use this function. It sets the X Window System "class" and
1700 * "name" hints for a window. According to the ICCCM, you should
1701 * always set these to the same value for all windows in an
1702 * application, and GTK+ sets them to that value by default, so calling
1703 * this function is sort of pointless. However, you may want to call
1704 * gtk_window_set_role() on each window in your application, for the
1705 * benefit of the session manager. Setting the role allows the window
1706 * manager to restore window positions when loading a saved session.
1710 gtk_window_set_wmclass (GtkWindow *window,
1711 const gchar *wmclass_name,
1712 const gchar *wmclass_class)
1714 GtkWindowPrivate *priv;
1716 g_return_if_fail (GTK_IS_WINDOW (window));
1718 priv = window->priv;
1720 g_free (priv->wmclass_name);
1721 priv->wmclass_name = g_strdup (wmclass_name);
1723 g_free (priv->wmclass_class);
1724 priv->wmclass_class = g_strdup (wmclass_class);
1726 if (gtk_widget_get_realized (GTK_WIDGET (window)))
1727 g_warning ("gtk_window_set_wmclass: shouldn't set wmclass after window is realized!\n");
1731 * gtk_window_set_role:
1732 * @window: a #GtkWindow
1733 * @role: unique identifier for the window to be used when restoring a session
1735 * This function is only useful on X11, not with other GTK+ targets.
1737 * In combination with the window title, the window role allows a
1738 * <link linkend="gtk-X11-arch">window manager</link> to identify "the
1739 * same" window when an application is restarted. So for example you
1740 * might set the "toolbox" role on your app's toolbox window, so that
1741 * when the user restarts their session, the window manager can put
1742 * the toolbox back in the same place.
1744 * If a window already has a unique title, you don't need to set the
1745 * role, since the WM can use the title to identify the window when
1746 * restoring the session.
1750 gtk_window_set_role (GtkWindow *window,
1753 GtkWindowPrivate *priv;
1756 g_return_if_fail (GTK_IS_WINDOW (window));
1758 priv = window->priv;
1760 new_role = g_strdup (role);
1761 g_free (priv->wm_role);
1762 priv->wm_role = new_role;
1764 if (gtk_widget_get_realized (GTK_WIDGET (window)))
1765 gdk_window_set_role (gtk_widget_get_window (GTK_WIDGET (window)),
1768 g_object_notify (G_OBJECT (window), "role");
1772 * gtk_window_set_startup_id:
1773 * @window: a #GtkWindow
1774 * @startup_id: a string with startup-notification identifier
1776 * Startup notification identifiers are used by desktop environment to
1777 * track application startup, to provide user feedback and other
1778 * features. This function changes the corresponding property on the
1779 * underlying GdkWindow. Normally, startup identifier is managed
1780 * automatically and you should only use this function in special cases
1781 * like transferring focus from other processes. You should use this
1782 * function before calling gtk_window_present() or any equivalent
1783 * function generating a window map event.
1785 * This function is only useful on X11, not with other GTK+ targets.
1790 gtk_window_set_startup_id (GtkWindow *window,
1791 const gchar *startup_id)
1793 GtkWindowPrivate *priv;
1796 g_return_if_fail (GTK_IS_WINDOW (window));
1798 priv = window->priv;
1799 widget = GTK_WIDGET (window);
1801 g_free (priv->startup_id);
1802 priv->startup_id = g_strdup (startup_id);
1804 if (gtk_widget_get_realized (widget))
1806 GdkWindow *gdk_window;
1807 guint32 timestamp = extract_time_from_startup_id (priv->startup_id);
1809 gdk_window = gtk_widget_get_window (widget);
1811 #ifdef GDK_WINDOWING_X11
1812 if (timestamp != GDK_CURRENT_TIME && GDK_IS_X11_WINDOW(gdk_window))
1813 gdk_x11_window_set_user_time (gdk_window, timestamp);
1816 /* Here we differentiate real and "fake" startup notification IDs,
1817 * constructed on purpose just to pass interaction timestamp
1819 if (startup_id_is_fake (priv->startup_id))
1820 gtk_window_present_with_time (window, timestamp);
1823 gdk_window_set_startup_id (gdk_window,
1826 /* If window is mapped, terminate the startup-notification too */
1827 if (gtk_widget_get_mapped (widget) &&
1828 !disable_startup_notification)
1829 gdk_notify_startup_complete_with_id (priv->startup_id);
1833 g_object_notify (G_OBJECT (window), "startup-id");
1837 * gtk_window_get_role:
1838 * @window: a #GtkWindow
1840 * Returns the role of the window. See gtk_window_set_role() for
1841 * further explanation.
1843 * Return value: the role of the window if set, or %NULL. The
1844 * returned is owned by the widget and must not be modified
1848 gtk_window_get_role (GtkWindow *window)
1850 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
1852 return window->priv->wm_role;
1856 * gtk_window_set_focus:
1857 * @window: a #GtkWindow
1858 * @focus: (allow-none): widget to be the new focus widget, or %NULL to unset
1859 * any focus widget for the toplevel window.
1861 * If @focus is not the current focus widget, and is focusable, sets
1862 * it as the focus widget for the window. If @focus is %NULL, unsets
1863 * the focus widget for this window. To set the focus to a particular
1864 * widget in the toplevel, it is usually more convenient to use
1865 * gtk_widget_grab_focus() instead of this function.
1868 gtk_window_set_focus (GtkWindow *window,
1871 GtkWindowPrivate *priv;
1874 g_return_if_fail (GTK_IS_WINDOW (window));
1876 priv = window->priv;
1880 g_return_if_fail (GTK_IS_WIDGET (focus));
1881 g_return_if_fail (gtk_widget_get_can_focus (focus));
1885 gtk_widget_grab_focus (focus);
1888 /* Clear the existing focus chain, so that when we focus into
1889 * the window again, we start at the beginnning.
1891 GtkWidget *widget = priv->focus_widget;
1894 while ((parent = gtk_widget_get_parent (widget)))
1897 gtk_container_set_focus_child (GTK_CONTAINER (widget), NULL);
1901 _gtk_window_internal_set_focus (window, NULL);
1906 _gtk_window_internal_set_focus (GtkWindow *window,
1909 GtkWindowPrivate *priv;
1911 g_return_if_fail (GTK_IS_WINDOW (window));
1913 priv = window->priv;
1915 if ((priv->focus_widget != focus) ||
1916 (focus && !gtk_widget_has_focus (focus)))
1917 g_signal_emit (window, window_signals[SET_FOCUS], 0, focus);
1921 * gtk_window_set_default:
1922 * @window: a #GtkWindow
1923 * @default_widget: (allow-none): widget to be the default, or %NULL to unset the
1924 * default widget for the toplevel.
1926 * The default widget is the widget that's activated when the user
1927 * presses Enter in a dialog (for example). This function sets or
1928 * unsets the default widget for a #GtkWindow about. When setting
1929 * (rather than unsetting) the default widget it's generally easier to
1930 * call gtk_widget_grab_focus() on the widget. Before making a widget
1931 * the default widget, you must set the #GTK_CAN_DEFAULT flag on the
1932 * widget you'd like to make the default using GTK_WIDGET_SET_FLAGS().
1935 gtk_window_set_default (GtkWindow *window,
1936 GtkWidget *default_widget)
1938 GtkWindowPrivate *priv;
1940 g_return_if_fail (GTK_IS_WINDOW (window));
1942 priv = window->priv;
1945 g_return_if_fail (gtk_widget_get_can_default (default_widget));
1947 if (priv->default_widget != default_widget)
1949 GtkWidget *old_default_widget = NULL;
1952 g_object_ref (default_widget);
1954 if (priv->default_widget)
1956 old_default_widget = priv->default_widget;
1958 if (priv->focus_widget != priv->default_widget ||
1959 !gtk_widget_get_receives_default (priv->default_widget))
1960 _gtk_widget_set_has_default (priv->default_widget, FALSE);
1962 gtk_widget_queue_draw (priv->default_widget);
1965 priv->default_widget = default_widget;
1967 if (priv->default_widget)
1969 if (priv->focus_widget == NULL ||
1970 !gtk_widget_get_receives_default (priv->focus_widget))
1971 _gtk_widget_set_has_default (priv->default_widget, TRUE);
1973 gtk_widget_queue_draw (priv->default_widget);
1976 if (old_default_widget)
1977 g_object_notify (G_OBJECT (old_default_widget), "has-default");
1981 g_object_notify (G_OBJECT (default_widget), "has-default");
1982 g_object_unref (default_widget);
1988 * gtk_window_get_default_widget:
1989 * @window: a #GtkWindow
1991 * Returns the default widget for @window. See gtk_window_set_default()
1994 * Returns: (transfer none): the default widget, or %NULL if there is none.
1999 gtk_window_get_default_widget (GtkWindow *window)
2001 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
2003 return window->priv->default_widget;
2007 handle_keys_changed (gpointer data)
2009 GtkWindow *window = GTK_WINDOW (data);
2010 GtkWindowPrivate *priv = window->priv;
2012 if (priv->keys_changed_handler)
2014 g_source_remove (priv->keys_changed_handler);
2015 priv->keys_changed_handler = 0;
2018 g_signal_emit (window, window_signals[KEYS_CHANGED], 0);
2024 gtk_window_notify_keys_changed (GtkWindow *window)
2026 GtkWindowPrivate *priv = window->priv;
2028 if (!priv->keys_changed_handler)
2029 priv->keys_changed_handler = gdk_threads_add_idle (handle_keys_changed, window);
2033 * gtk_window_add_accel_group:
2034 * @window: window to attach accelerator group to
2035 * @accel_group: a #GtkAccelGroup
2037 * Associate @accel_group with @window, such that calling
2038 * gtk_accel_groups_activate() on @window will activate accelerators
2042 gtk_window_add_accel_group (GtkWindow *window,
2043 GtkAccelGroup *accel_group)
2045 g_return_if_fail (GTK_IS_WINDOW (window));
2046 g_return_if_fail (GTK_IS_ACCEL_GROUP (accel_group));
2048 _gtk_accel_group_attach (accel_group, G_OBJECT (window));
2049 g_signal_connect_object (accel_group, "accel-changed",
2050 G_CALLBACK (gtk_window_notify_keys_changed),
2051 window, G_CONNECT_SWAPPED);
2052 gtk_window_notify_keys_changed (window);
2056 * gtk_window_remove_accel_group:
2057 * @window: a #GtkWindow
2058 * @accel_group: a #GtkAccelGroup
2060 * Reverses the effects of gtk_window_add_accel_group().
2063 gtk_window_remove_accel_group (GtkWindow *window,
2064 GtkAccelGroup *accel_group)
2066 g_return_if_fail (GTK_IS_WINDOW (window));
2067 g_return_if_fail (GTK_IS_ACCEL_GROUP (accel_group));
2069 g_signal_handlers_disconnect_by_func (accel_group,
2070 gtk_window_notify_keys_changed,
2072 _gtk_accel_group_detach (accel_group, G_OBJECT (window));
2073 gtk_window_notify_keys_changed (window);
2076 static GtkMnemonicHash *
2077 gtk_window_get_mnemonic_hash (GtkWindow *window,
2080 GtkWindowPrivate *private = window->priv;
2082 if (!private->mnemonic_hash && create)
2083 private->mnemonic_hash = _gtk_mnemonic_hash_new ();
2085 return private->mnemonic_hash;
2089 * gtk_window_add_mnemonic:
2090 * @window: a #GtkWindow
2091 * @keyval: the mnemonic
2092 * @target: the widget that gets activated by the mnemonic
2094 * Adds a mnemonic to this window.
2097 gtk_window_add_mnemonic (GtkWindow *window,
2101 g_return_if_fail (GTK_IS_WINDOW (window));
2102 g_return_if_fail (GTK_IS_WIDGET (target));
2104 _gtk_mnemonic_hash_add (gtk_window_get_mnemonic_hash (window, TRUE),
2106 gtk_window_notify_keys_changed (window);
2110 * gtk_window_remove_mnemonic:
2111 * @window: a #GtkWindow
2112 * @keyval: the mnemonic
2113 * @target: the widget that gets activated by the mnemonic
2115 * Removes a mnemonic from this window.
2118 gtk_window_remove_mnemonic (GtkWindow *window,
2122 g_return_if_fail (GTK_IS_WINDOW (window));
2123 g_return_if_fail (GTK_IS_WIDGET (target));
2125 _gtk_mnemonic_hash_remove (gtk_window_get_mnemonic_hash (window, TRUE),
2127 gtk_window_notify_keys_changed (window);
2131 * gtk_window_mnemonic_activate:
2132 * @window: a #GtkWindow
2133 * @keyval: the mnemonic
2134 * @modifier: the modifiers
2136 * Activates the targets associated with the mnemonic.
2138 * Returns: %TRUE if the activation is done.
2141 gtk_window_mnemonic_activate (GtkWindow *window,
2143 GdkModifierType modifier)
2145 GtkWindowPrivate *priv;
2147 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
2149 priv = window->priv;
2151 if (priv->mnemonic_modifier == (modifier & gtk_accelerator_get_default_mod_mask ()))
2153 GtkMnemonicHash *mnemonic_hash = gtk_window_get_mnemonic_hash (window, FALSE);
2155 return _gtk_mnemonic_hash_activate (mnemonic_hash, keyval);
2162 * gtk_window_set_mnemonic_modifier:
2163 * @window: a #GtkWindow
2164 * @modifier: the modifier mask used to activate
2165 * mnemonics on this window.
2167 * Sets the mnemonic modifier for this window.
2170 gtk_window_set_mnemonic_modifier (GtkWindow *window,
2171 GdkModifierType modifier)
2173 GtkWindowPrivate *priv;
2175 g_return_if_fail (GTK_IS_WINDOW (window));
2176 g_return_if_fail ((modifier & ~GDK_MODIFIER_MASK) == 0);
2178 priv = window->priv;
2180 priv->mnemonic_modifier = modifier;
2181 gtk_window_notify_keys_changed (window);
2185 * gtk_window_get_mnemonic_modifier:
2186 * @window: a #GtkWindow
2188 * Returns the mnemonic modifier for this window. See
2189 * gtk_window_set_mnemonic_modifier().
2191 * Return value: the modifier mask used to activate
2192 * mnemonics on this window.
2195 gtk_window_get_mnemonic_modifier (GtkWindow *window)
2197 g_return_val_if_fail (GTK_IS_WINDOW (window), 0);
2199 return window->priv->mnemonic_modifier;
2203 * gtk_window_set_position:
2204 * @window: a #GtkWindow.
2205 * @position: a position constraint.
2207 * Sets a position constraint for this window. If the old or new
2208 * constraint is %GTK_WIN_POS_CENTER_ALWAYS, this will also cause
2209 * the window to be repositioned to satisfy the new constraint.
2212 gtk_window_set_position (GtkWindow *window,
2213 GtkWindowPosition position)
2215 GtkWindowPrivate *priv;
2217 g_return_if_fail (GTK_IS_WINDOW (window));
2219 priv = window->priv;
2221 if (position == GTK_WIN_POS_CENTER_ALWAYS ||
2222 priv->position == GTK_WIN_POS_CENTER_ALWAYS)
2224 GtkWindowGeometryInfo *info;
2226 info = gtk_window_get_geometry_info (window, TRUE);
2228 /* this flag causes us to re-request the CENTER_ALWAYS
2229 * constraint in gtk_window_move_resize(), see
2230 * comment in that function.
2232 info->position_constraints_changed = TRUE;
2234 gtk_widget_queue_resize_no_redraw (GTK_WIDGET (window));
2237 priv->position = position;
2239 g_object_notify (G_OBJECT (window), "window-position");
2243 * gtk_window_activate_focus:
2244 * @window: a #GtkWindow
2246 * Activates the current focused widget within the window.
2248 * Return value: %TRUE if a widget got activated.
2251 gtk_window_activate_focus (GtkWindow *window)
2253 GtkWindowPrivate *priv;
2255 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
2257 priv = window->priv;
2259 if (priv->focus_widget && gtk_widget_is_sensitive (priv->focus_widget))
2260 return gtk_widget_activate (priv->focus_widget);
2266 * gtk_window_get_focus:
2267 * @window: a #GtkWindow
2269 * Retrieves the current focused widget within the window.
2270 * Note that this is the widget that would have the focus
2271 * if the toplevel window focused; if the toplevel window
2272 * is not focused then <literal>gtk_widget_has_focus (widget)</literal> will
2273 * not be %TRUE for the widget.
2275 * Return value: (transfer none): the currently focused widget, or %NULL if there is none.
2278 gtk_window_get_focus (GtkWindow *window)
2280 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
2282 return window->priv->focus_widget;
2286 * gtk_window_activate_default:
2287 * @window: a #GtkWindow
2289 * Activates the default widget for the window, unless the current
2290 * focused widget has been configured to receive the default action
2291 * (see gtk_widget_set_receives_default()), in which case the
2292 * focused widget is activated.
2294 * Return value: %TRUE if a widget got activated.
2297 gtk_window_activate_default (GtkWindow *window)
2299 GtkWindowPrivate *priv;
2301 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
2303 priv = window->priv;
2305 if (priv->default_widget && gtk_widget_is_sensitive (priv->default_widget) &&
2306 (!priv->focus_widget || !gtk_widget_get_receives_default (priv->focus_widget)))
2307 return gtk_widget_activate (priv->default_widget);
2308 else if (priv->focus_widget && gtk_widget_is_sensitive (priv->focus_widget))
2309 return gtk_widget_activate (priv->focus_widget);
2315 * gtk_window_set_modal:
2316 * @window: a #GtkWindow
2317 * @modal: whether the window is modal
2319 * Sets a window modal or non-modal. Modal windows prevent interaction
2320 * with other windows in the same application. To keep modal dialogs
2321 * on top of main application windows, use
2322 * gtk_window_set_transient_for() to make the dialog transient for the
2323 * parent; most <link linkend="gtk-X11-arch">window managers</link>
2324 * will then disallow lowering the dialog below the parent.
2329 gtk_window_set_modal (GtkWindow *window,
2332 GtkWindowPrivate *priv;
2335 g_return_if_fail (GTK_IS_WINDOW (window));
2337 priv = window->priv;
2339 modal = modal != FALSE;
2340 if (priv->modal == modal)
2343 priv->modal = modal;
2344 widget = GTK_WIDGET (window);
2346 /* adjust desired modality state */
2347 if (gtk_widget_get_realized (widget))
2350 gdk_window_set_modal_hint (gtk_widget_get_window (widget), TRUE);
2352 gdk_window_set_modal_hint (gtk_widget_get_window (widget), FALSE);
2355 if (gtk_widget_get_visible (widget))
2358 gtk_grab_add (widget);
2360 gtk_grab_remove (widget);
2363 g_object_notify (G_OBJECT (window), "modal");
2367 * gtk_window_get_modal:
2368 * @window: a #GtkWindow
2370 * Returns whether the window is modal. See gtk_window_set_modal().
2372 * Return value: %TRUE if the window is set to be modal and
2373 * establishes a grab when shown
2376 gtk_window_get_modal (GtkWindow *window)
2378 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
2380 return window->priv->modal;
2384 * gtk_window_list_toplevels:
2386 * Returns a list of all existing toplevel windows. The widgets
2387 * in the list are not individually referenced. If you want
2388 * to iterate through the list and perform actions involving
2389 * callbacks that might destroy the widgets, you <emphasis>must</emphasis> call
2390 * <literal>g_list_foreach (result, (GFunc)g_object_ref, NULL)</literal> first, and
2391 * then unref all the widgets afterwards.
2393 * Return value: (element-type GtkWidget) (transfer container): list of toplevel widgets
2396 gtk_window_list_toplevels (void)
2401 for (slist = toplevel_list; slist; slist = slist->next)
2402 list = g_list_prepend (list, slist->data);
2408 remove_attach_widget (GtkWindow *window)
2410 GtkWindowPrivate *priv = window->priv;
2412 if (priv->attach_widget)
2414 _gtk_widget_remove_attached_window (priv->attach_widget, window);
2416 g_object_unref (priv->attach_widget);
2417 priv->attach_widget = NULL;
2422 gtk_window_dispose (GObject *object)
2424 GtkWindow *window = GTK_WINDOW (object);
2426 gtk_window_set_focus (window, NULL);
2427 gtk_window_set_default (window, NULL);
2429 remove_attach_widget (GTK_WINDOW (object));
2431 G_OBJECT_CLASS (gtk_window_parent_class)->dispose (object);
2435 parent_destroyed_callback (GtkWindow *parent, GtkWindow *child)
2437 gtk_widget_destroy (GTK_WIDGET (child));
2441 connect_parent_destroyed (GtkWindow *window)
2443 GtkWindowPrivate *priv = window->priv;
2445 if (priv->transient_parent)
2447 g_signal_connect (priv->transient_parent,
2449 G_CALLBACK (parent_destroyed_callback),
2455 disconnect_parent_destroyed (GtkWindow *window)
2457 GtkWindowPrivate *priv = window->priv;
2459 if (priv->transient_parent)
2461 g_signal_handlers_disconnect_by_func (priv->transient_parent,
2462 parent_destroyed_callback,
2468 gtk_window_transient_parent_realized (GtkWidget *parent,
2471 if (gtk_widget_get_realized (window))
2472 gdk_window_set_transient_for (gtk_widget_get_window (window),
2473 gtk_widget_get_window (parent));
2477 gtk_window_transient_parent_unrealized (GtkWidget *parent,
2480 if (gtk_widget_get_realized (window))
2481 gdk_property_delete (gtk_widget_get_window (window),
2482 gdk_atom_intern_static_string ("WM_TRANSIENT_FOR"));
2486 gtk_window_transient_parent_screen_changed (GtkWindow *parent,
2490 gtk_window_set_screen (window, parent->priv->screen);
2494 gtk_window_unset_transient_for (GtkWindow *window)
2496 GtkWindowPrivate *priv = window->priv;
2498 if (priv->transient_parent)
2500 g_signal_handlers_disconnect_by_func (priv->transient_parent,
2501 gtk_window_transient_parent_realized,
2503 g_signal_handlers_disconnect_by_func (priv->transient_parent,
2504 gtk_window_transient_parent_unrealized,
2506 g_signal_handlers_disconnect_by_func (priv->transient_parent,
2507 gtk_window_transient_parent_screen_changed,
2509 g_signal_handlers_disconnect_by_func (priv->transient_parent,
2510 gtk_widget_destroyed,
2511 &priv->transient_parent);
2513 if (priv->destroy_with_parent)
2514 disconnect_parent_destroyed (window);
2516 priv->transient_parent = NULL;
2518 if (priv->transient_parent_group)
2520 priv->transient_parent_group = FALSE;
2521 gtk_window_group_remove_window (priv->group,
2528 * gtk_window_set_transient_for:
2529 * @window: a #GtkWindow
2530 * @parent: (allow-none): parent window, or %NULL
2532 * Dialog windows should be set transient for the main application
2533 * window they were spawned from. This allows <link
2534 * linkend="gtk-X11-arch">window managers</link> to e.g. keep the
2535 * dialog on top of the main window, or center the dialog over the
2536 * main window. gtk_dialog_new_with_buttons() and other convenience
2537 * functions in GTK+ will sometimes call
2538 * gtk_window_set_transient_for() on your behalf.
2540 * Passing %NULL for @parent unsets the current transient window.
2542 * On Windows, this function puts the child window on top of the parent,
2543 * much as the window manager would have done on X.
2546 gtk_window_set_transient_for (GtkWindow *window,
2549 GtkWindowPrivate *priv;
2551 g_return_if_fail (GTK_IS_WINDOW (window));
2552 g_return_if_fail (parent == NULL || GTK_IS_WINDOW (parent));
2553 g_return_if_fail (window != parent);
2555 priv = window->priv;
2557 if (priv->transient_parent)
2559 if (gtk_widget_get_realized (GTK_WIDGET (window)) &&
2560 gtk_widget_get_realized (GTK_WIDGET (priv->transient_parent)) &&
2561 (!parent || !gtk_widget_get_realized (GTK_WIDGET (parent))))
2562 gtk_window_transient_parent_unrealized (GTK_WIDGET (priv->transient_parent),
2563 GTK_WIDGET (window));
2565 gtk_window_unset_transient_for (window);
2568 priv->transient_parent = parent;
2572 g_signal_connect (parent, "destroy",
2573 G_CALLBACK (gtk_widget_destroyed),
2574 &priv->transient_parent);
2575 g_signal_connect (parent, "realize",
2576 G_CALLBACK (gtk_window_transient_parent_realized),
2578 g_signal_connect (parent, "unrealize",
2579 G_CALLBACK (gtk_window_transient_parent_unrealized),
2581 g_signal_connect (parent, "notify::screen",
2582 G_CALLBACK (gtk_window_transient_parent_screen_changed),
2585 gtk_window_set_screen (window, parent->priv->screen);
2587 if (priv->destroy_with_parent)
2588 connect_parent_destroyed (window);
2590 if (gtk_widget_get_realized (GTK_WIDGET (window)) &&
2591 gtk_widget_get_realized (GTK_WIDGET (parent)))
2592 gtk_window_transient_parent_realized (GTK_WIDGET (parent),
2593 GTK_WIDGET (window));
2595 if (parent->priv->group)
2597 gtk_window_group_add_window (parent->priv->group, window);
2598 priv->transient_parent_group = TRUE;
2604 * gtk_window_get_transient_for:
2605 * @window: a #GtkWindow
2607 * Fetches the transient parent for this window. See
2608 * gtk_window_set_transient_for().
2610 * Return value: (transfer none): the transient parent for this window, or %NULL
2611 * if no transient parent has been set.
2614 gtk_window_get_transient_for (GtkWindow *window)
2616 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
2618 return window->priv->transient_parent;
2622 * gtk_window_set_attached_to:
2623 * @window: a #GtkWindow
2624 * @attach_widget (allow-none): a #GtkWidget, or %NULL
2626 * Marks @window as attached to @attach_widget. This creates a logical binding
2627 * between the window and the widget it belongs to, which is used by GTK+ to
2628 * propagate information such as styling or accessibility to @window as if it
2629 * was a children of @attach_widget.
2631 * Examples of places where specifying this relation is useful are for instance
2632 * a #GtkMenu created by a #GtkComboBox, a completion popup window
2633 * created by #GtkEntry or a typeahead search entry created by #GtkTreeView.
2635 * Note that this function should not be confused with
2636 * gtk_window_set_transient_for(), which specifies a window manager relation
2637 * between two toplevels instead.
2639 * Passing %NULL for @attach_widget detaches the window.
2644 gtk_window_set_attached_to (GtkWindow *window,
2645 GtkWidget *attach_widget)
2647 GtkWindowPrivate *priv;
2649 g_return_if_fail (GTK_IS_WINDOW (window));
2650 g_return_if_fail (GTK_WIDGET (window) != attach_widget);
2652 priv = window->priv;
2654 remove_attach_widget (window);
2656 priv->attach_widget = attach_widget;
2658 if (priv->attach_widget)
2660 _gtk_widget_add_attached_window (priv->attach_widget, window);
2662 g_object_ref_sink (priv->attach_widget);
2665 /* Update the style, as the widget path might change. */
2666 gtk_widget_reset_style (GTK_WIDGET (window));
2670 * gtk_window_get_attached_to:
2671 * @window: a #GtkWindow
2673 * Fetches the attach widget for this window. See
2674 * gtk_window_set_attached_to().
2676 * Return value: (transfer none): the widget where the window is attached,
2677 * or %NULL if the window is not attached to any widget.
2682 gtk_window_get_attached_to (GtkWindow *window)
2684 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
2686 return window->priv->attach_widget;
2690 * gtk_window_set_opacity:
2691 * @window: a #GtkWindow
2692 * @opacity: desired opacity, between 0 and 1
2694 * Request the windowing system to make @window partially transparent,
2695 * with opacity 0 being fully transparent and 1 fully opaque. (Values
2696 * of the opacity parameter are clamped to the [0,1] range.) On X11
2697 * this has any effect only on X screens with a compositing manager
2698 * running. See gtk_widget_is_composited(). On Windows it should work
2701 * Note that setting a window's opacity after the window has been
2702 * shown causes it to flicker once on Windows.
2707 gtk_window_set_opacity (GtkWindow *window,
2710 GtkWindowPrivate *priv;
2712 g_return_if_fail (GTK_IS_WINDOW (window));
2714 priv = window->priv;
2718 else if (opacity > 1.0)
2721 priv->opacity_set = TRUE;
2722 priv->opacity = opacity;
2724 if (gtk_widget_get_realized (GTK_WIDGET (window)))
2725 gdk_window_set_opacity (gtk_widget_get_window (GTK_WIDGET (window)),
2730 * gtk_window_get_opacity:
2731 * @window: a #GtkWindow
2733 * Fetches the requested opacity for this window. See
2734 * gtk_window_set_opacity().
2736 * Return value: the requested opacity for this window.
2741 gtk_window_get_opacity (GtkWindow *window)
2743 g_return_val_if_fail (GTK_IS_WINDOW (window), 0.0);
2745 return window->priv->opacity;
2749 * gtk_window_get_application:
2750 * @window: a #GtkWindow
2752 * Gets the #GtkApplication associated with the window (if any).
2754 * Return value: (transfer none): a #GtkApplication, or %NULL
2759 gtk_window_get_application (GtkWindow *window)
2761 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
2763 return window->priv->application;
2767 gtk_window_release_application (GtkWindow *window)
2769 if (window->priv->application)
2771 GtkApplication *application;
2773 /* steal reference into temp variable */
2774 application = window->priv->application;
2775 window->priv->application = NULL;
2777 gtk_application_remove_window (application, window);
2778 g_object_unref (application);
2783 * gtk_window_set_application:
2784 * @window: a #GtkWindow
2785 * @application: (allow-none): a #GtkApplication, or %NULL
2787 * Sets or unsets the #GtkApplication associated with the window.
2789 * The application will be kept alive for at least as long as the window
2795 gtk_window_set_application (GtkWindow *window,
2796 GtkApplication *application)
2798 GtkWindowPrivate *priv;
2800 g_return_if_fail (GTK_IS_WINDOW (window));
2802 priv = window->priv;
2803 if (priv->application != application)
2805 gtk_window_release_application (window);
2807 priv->application = application;
2809 if (priv->application != NULL)
2811 g_object_ref (priv->application);
2813 gtk_application_add_window (priv->application, window);
2816 g_object_notify (G_OBJECT (window), "application");
2821 * gtk_window_set_type_hint:
2822 * @window: a #GtkWindow
2823 * @hint: the window type
2825 * By setting the type hint for the window, you allow the window
2826 * manager to decorate and handle the window in a way which is
2827 * suitable to the function of the window in your application.
2829 * This function should be called before the window becomes visible.
2831 * gtk_dialog_new_with_buttons() and other convenience functions in GTK+
2832 * will sometimes call gtk_window_set_type_hint() on your behalf.
2836 gtk_window_set_type_hint (GtkWindow *window,
2837 GdkWindowTypeHint hint)
2839 GtkWindowPrivate *priv;
2841 g_return_if_fail (GTK_IS_WINDOW (window));
2842 g_return_if_fail (!gtk_widget_get_mapped (GTK_WIDGET (window)));
2844 priv = window->priv;
2846 if (hint < GDK_WINDOW_TYPE_HINT_DROPDOWN_MENU)
2847 priv->type_hint = hint;
2849 priv->type_hint = GDK_WINDOW_TYPE_HINT_NORMAL;
2851 priv->reset_type_hint = TRUE;
2852 priv->gdk_type_hint = hint;
2856 * gtk_window_get_type_hint:
2857 * @window: a #GtkWindow
2859 * Gets the type hint for this window. See gtk_window_set_type_hint().
2861 * Return value: the type hint for @window.
2864 gtk_window_get_type_hint (GtkWindow *window)
2866 g_return_val_if_fail (GTK_IS_WINDOW (window), GDK_WINDOW_TYPE_HINT_NORMAL);
2868 return window->priv->gdk_type_hint;
2872 * gtk_window_set_skip_taskbar_hint:
2873 * @window: a #GtkWindow
2874 * @setting: %TRUE to keep this window from appearing in the task bar
2876 * Windows may set a hint asking the desktop environment not to display
2877 * the window in the task bar. This function sets this hint.
2882 gtk_window_set_skip_taskbar_hint (GtkWindow *window,
2885 GtkWindowPrivate *priv;
2887 g_return_if_fail (GTK_IS_WINDOW (window));
2889 priv = window->priv;
2891 setting = setting != FALSE;
2893 if (priv->skips_taskbar != setting)
2895 priv->skips_taskbar = setting;
2896 if (gtk_widget_get_realized (GTK_WIDGET (window)))
2897 gdk_window_set_skip_taskbar_hint (gtk_widget_get_window (GTK_WIDGET (window)),
2898 priv->skips_taskbar);
2899 g_object_notify (G_OBJECT (window), "skip-taskbar-hint");
2904 * gtk_window_get_skip_taskbar_hint:
2905 * @window: a #GtkWindow
2907 * Gets the value set by gtk_window_set_skip_taskbar_hint()
2909 * Return value: %TRUE if window shouldn't be in taskbar
2914 gtk_window_get_skip_taskbar_hint (GtkWindow *window)
2916 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
2918 return window->priv->skips_taskbar;
2922 * gtk_window_set_skip_pager_hint:
2923 * @window: a #GtkWindow
2924 * @setting: %TRUE to keep this window from appearing in the pager
2926 * Windows may set a hint asking the desktop environment not to display
2927 * the window in the pager. This function sets this hint.
2928 * (A "pager" is any desktop navigation tool such as a workspace
2929 * switcher that displays a thumbnail representation of the windows
2935 gtk_window_set_skip_pager_hint (GtkWindow *window,
2938 GtkWindowPrivate *priv;
2940 g_return_if_fail (GTK_IS_WINDOW (window));
2942 priv = window->priv;
2944 setting = setting != FALSE;
2946 if (priv->skips_pager != setting)
2948 priv->skips_pager = setting;
2949 if (gtk_widget_get_realized (GTK_WIDGET (window)))
2950 gdk_window_set_skip_pager_hint (gtk_widget_get_window (GTK_WIDGET (window)),
2952 g_object_notify (G_OBJECT (window), "skip-pager-hint");
2957 * gtk_window_get_skip_pager_hint:
2958 * @window: a #GtkWindow
2960 * Gets the value set by gtk_window_set_skip_pager_hint().
2962 * Return value: %TRUE if window shouldn't be in pager
2967 gtk_window_get_skip_pager_hint (GtkWindow *window)
2969 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
2971 return window->priv->skips_pager;
2975 * gtk_window_set_urgency_hint:
2976 * @window: a #GtkWindow
2977 * @setting: %TRUE to mark this window as urgent
2979 * Windows may set a hint asking the desktop environment to draw
2980 * the users attention to the window. This function sets this hint.
2985 gtk_window_set_urgency_hint (GtkWindow *window,
2988 GtkWindowPrivate *priv;
2990 g_return_if_fail (GTK_IS_WINDOW (window));
2992 priv = window->priv;
2994 setting = setting != FALSE;
2996 if (priv->urgent != setting)
2998 priv->urgent = setting;
2999 if (gtk_widget_get_realized (GTK_WIDGET (window)))
3000 gdk_window_set_urgency_hint (gtk_widget_get_window (GTK_WIDGET (window)),
3002 g_object_notify (G_OBJECT (window), "urgency-hint");
3007 * gtk_window_get_urgency_hint:
3008 * @window: a #GtkWindow
3010 * Gets the value set by gtk_window_set_urgency_hint()
3012 * Return value: %TRUE if window is urgent
3017 gtk_window_get_urgency_hint (GtkWindow *window)
3019 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
3021 return window->priv->urgent;
3025 * gtk_window_set_accept_focus:
3026 * @window: a #GtkWindow
3027 * @setting: %TRUE to let this window receive input focus
3029 * Windows may set a hint asking the desktop environment not to receive
3030 * the input focus. This function sets this hint.
3035 gtk_window_set_accept_focus (GtkWindow *window,
3038 GtkWindowPrivate *priv;
3040 g_return_if_fail (GTK_IS_WINDOW (window));
3042 priv = window->priv;
3044 setting = setting != FALSE;
3046 if (priv->accept_focus != setting)
3048 priv->accept_focus = setting;
3049 if (gtk_widget_get_realized (GTK_WIDGET (window)))
3050 gdk_window_set_accept_focus (gtk_widget_get_window (GTK_WIDGET (window)),
3051 priv->accept_focus);
3052 g_object_notify (G_OBJECT (window), "accept-focus");
3057 * gtk_window_get_accept_focus:
3058 * @window: a #GtkWindow
3060 * Gets the value set by gtk_window_set_accept_focus().
3062 * Return value: %TRUE if window should receive the input focus
3067 gtk_window_get_accept_focus (GtkWindow *window)
3069 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
3071 return window->priv->accept_focus;
3075 * gtk_window_set_focus_on_map:
3076 * @window: a #GtkWindow
3077 * @setting: %TRUE to let this window receive input focus on map
3079 * Windows may set a hint asking the desktop environment not to receive
3080 * the input focus when the window is mapped. This function sets this
3086 gtk_window_set_focus_on_map (GtkWindow *window,
3089 GtkWindowPrivate *priv;
3091 g_return_if_fail (GTK_IS_WINDOW (window));
3093 priv = window->priv;
3095 setting = setting != FALSE;
3097 if (priv->focus_on_map != setting)
3099 priv->focus_on_map = setting;
3100 if (gtk_widget_get_realized (GTK_WIDGET (window)))
3101 gdk_window_set_focus_on_map (gtk_widget_get_window (GTK_WIDGET (window)),
3102 priv->focus_on_map);
3103 g_object_notify (G_OBJECT (window), "focus-on-map");
3108 * gtk_window_get_focus_on_map:
3109 * @window: a #GtkWindow
3111 * Gets the value set by gtk_window_set_focus_on_map().
3113 * Return value: %TRUE if window should receive the input focus when
3119 gtk_window_get_focus_on_map (GtkWindow *window)
3121 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
3123 return window->priv->focus_on_map;
3127 * gtk_window_set_destroy_with_parent:
3128 * @window: a #GtkWindow
3129 * @setting: whether to destroy @window with its transient parent
3131 * If @setting is %TRUE, then destroying the transient parent of @window
3132 * will also destroy @window itself. This is useful for dialogs that
3133 * shouldn't persist beyond the lifetime of the main window they're
3134 * associated with, for example.
3137 gtk_window_set_destroy_with_parent (GtkWindow *window,
3140 GtkWindowPrivate *priv;
3142 g_return_if_fail (GTK_IS_WINDOW (window));
3144 priv = window->priv;
3146 if (priv->destroy_with_parent == (setting != FALSE))
3149 if (priv->destroy_with_parent)
3151 disconnect_parent_destroyed (window);
3155 connect_parent_destroyed (window);
3158 priv->destroy_with_parent = setting;
3160 g_object_notify (G_OBJECT (window), "destroy-with-parent");
3164 * gtk_window_get_destroy_with_parent:
3165 * @window: a #GtkWindow
3167 * Returns whether the window will be destroyed with its transient parent. See
3168 * gtk_window_set_destroy_with_parent ().
3170 * Return value: %TRUE if the window will be destroyed with its transient parent.
3173 gtk_window_get_destroy_with_parent (GtkWindow *window)
3175 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
3177 return window->priv->destroy_with_parent;
3181 * gtk_window_set_hide_titlebar_when_maximized:
3182 * @window: a #GtkWindow
3183 * @setting: whether to hide the titlebar when @window is maximized
3185 * If @setting is %TRUE, then @window will request that it's titlebar
3186 * should be hidden when maximized.
3187 * This is useful for windows that don't convey any information other
3188 * than the application name in the titlebar, to put the available
3189 * screen space to better use. If the underlying window system does not
3190 * support the request, the setting will not have any effect.
3195 gtk_window_set_hide_titlebar_when_maximized (GtkWindow *window,
3198 g_return_if_fail (GTK_IS_WINDOW (window));
3200 #ifdef GDK_WINDOWING_X11
3202 GdkWindow *gdk_window;
3204 gdk_window = gtk_widget_get_window (GTK_WIDGET (window));
3206 if (GDK_IS_X11_WINDOW (gdk_window))
3207 gdk_x11_window_set_hide_titlebar_when_maximized (gdk_window, setting);
3211 window->priv->hide_titlebar_when_maximized = setting;
3212 g_object_notify (G_OBJECT (window), "hide-titlebar-when-maximized");
3216 * gtk_window_get_hide_titlebar_when_maximized:
3217 * @window: a #GtkWindow
3219 * Returns whether the window has requested to have its titlebar hidden
3220 * when maximized. See gtk_window_set_hide_titlebar_when_maximized ().
3222 * Return value: %TRUE if the window has requested to have its titlebar
3223 * hidden when maximized
3228 gtk_window_get_hide_titlebar_when_maximized (GtkWindow *window)
3230 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
3232 return window->priv->hide_titlebar_when_maximized;
3235 static GtkWindowGeometryInfo*
3236 gtk_window_get_geometry_info (GtkWindow *window,
3239 GtkWindowPrivate *priv = window->priv;
3240 GtkWindowGeometryInfo *info;
3242 info = priv->geometry_info;
3243 if (!info && create)
3245 info = g_new0 (GtkWindowGeometryInfo, 1);
3247 info->default_width = -1;
3248 info->default_height = -1;
3249 info->resize_width = -1;
3250 info->resize_height = -1;
3251 info->initial_x = 0;
3252 info->initial_y = 0;
3253 info->initial_pos_set = FALSE;
3254 info->default_is_geometry = FALSE;
3255 info->position_constraints_changed = FALSE;
3256 info->last.configure_request.x = 0;
3257 info->last.configure_request.y = 0;
3258 info->last.configure_request.width = -1;
3259 info->last.configure_request.height = -1;
3260 info->widget = NULL;
3262 priv->geometry_info = info;
3269 * gtk_window_set_geometry_hints:
3270 * @window: a #GtkWindow
3271 * @geometry_widget: (allow-none): widget the geometry hints will be applied to or %NULL
3272 * @geometry: (allow-none): struct containing geometry information or %NULL
3273 * @geom_mask: mask indicating which struct fields should be paid attention to
3275 * This function sets up hints about how a window can be resized by
3276 * the user. You can set a minimum and maximum size; allowed resize
3277 * increments (e.g. for xterm, you can only resize by the size of a
3278 * character); aspect ratios; and more. See the #GdkGeometry struct.
3282 gtk_window_set_geometry_hints (GtkWindow *window,
3283 GtkWidget *geometry_widget,
3284 GdkGeometry *geometry,
3285 GdkWindowHints geom_mask)
3287 GtkWindowGeometryInfo *info;
3289 g_return_if_fail (GTK_IS_WINDOW (window));
3290 g_return_if_fail (geometry_widget == NULL || GTK_IS_WIDGET (geometry_widget));
3292 info = gtk_window_get_geometry_info (window, TRUE);
3295 g_signal_handlers_disconnect_by_func (info->widget,
3296 gtk_widget_destroyed,
3299 info->widget = geometry_widget;
3301 g_signal_connect (geometry_widget, "destroy",
3302 G_CALLBACK (gtk_widget_destroyed),
3306 info->geometry = *geometry;
3308 /* We store gravity in priv->gravity not in the hints. */
3309 info->mask = geom_mask & ~(GDK_HINT_WIN_GRAVITY);
3311 if (geom_mask & GDK_HINT_WIN_GRAVITY)
3313 gtk_window_set_gravity (window, geometry->win_gravity);
3316 gtk_widget_queue_resize_no_redraw (GTK_WIDGET (window));
3320 * gtk_window_set_decorated:
3321 * @window: a #GtkWindow
3322 * @setting: %TRUE to decorate the window
3324 * By default, windows are decorated with a title bar, resize
3325 * controls, etc. Some <link linkend="gtk-X11-arch">window
3326 * managers</link> allow GTK+ to disable these decorations, creating a
3327 * borderless window. If you set the decorated property to %FALSE
3328 * using this function, GTK+ will do its best to convince the window
3329 * manager not to decorate the window. Depending on the system, this
3330 * function may not have any effect when called on a window that is
3331 * already visible, so you should call it before calling gtk_widget_show().
3333 * On Windows, this function always works, since there's no window manager
3338 gtk_window_set_decorated (GtkWindow *window,
3341 GtkWindowPrivate *priv;
3342 GdkWindow *gdk_window;
3344 g_return_if_fail (GTK_IS_WINDOW (window));
3346 priv = window->priv;
3348 setting = setting != FALSE;
3350 if (setting == priv->decorated)
3353 priv->decorated = setting;
3355 gdk_window = gtk_widget_get_window (GTK_WIDGET (window));
3358 if (priv->decorated)
3359 gdk_window_set_decorations (gdk_window,
3362 gdk_window_set_decorations (gdk_window,
3366 g_object_notify (G_OBJECT (window), "decorated");
3370 * gtk_window_get_decorated:
3371 * @window: a #GtkWindow
3373 * Returns whether the window has been set to have decorations
3374 * such as a title bar via gtk_window_set_decorated().
3376 * Return value: %TRUE if the window has been set to have decorations
3379 gtk_window_get_decorated (GtkWindow *window)
3381 g_return_val_if_fail (GTK_IS_WINDOW (window), TRUE);
3383 return window->priv->decorated;
3387 * gtk_window_set_deletable:
3388 * @window: a #GtkWindow
3389 * @setting: %TRUE to decorate the window as deletable
3391 * By default, windows have a close button in the window frame. Some
3392 * <link linkend="gtk-X11-arch">window managers</link> allow GTK+ to
3393 * disable this button. If you set the deletable property to %FALSE
3394 * using this function, GTK+ will do its best to convince the window
3395 * manager not to show a close button. Depending on the system, this
3396 * function may not have any effect when called on a window that is
3397 * already visible, so you should call it before calling gtk_window_show().
3399 * On Windows, this function always works, since there's no window manager
3405 gtk_window_set_deletable (GtkWindow *window,
3408 GtkWindowPrivate *priv;
3409 GdkWindow *gdk_window;
3411 g_return_if_fail (GTK_IS_WINDOW (window));
3413 priv = window->priv;
3415 setting = setting != FALSE;
3417 if (setting == priv->deletable)
3420 priv->deletable = setting;
3422 gdk_window = gtk_widget_get_window (GTK_WIDGET (window));
3425 if (priv->deletable)
3426 gdk_window_set_functions (gdk_window,
3429 gdk_window_set_functions (gdk_window,
3430 GDK_FUNC_ALL | GDK_FUNC_CLOSE);
3433 g_object_notify (G_OBJECT (window), "deletable");
3437 * gtk_window_get_deletable:
3438 * @window: a #GtkWindow
3440 * Returns whether the window has been set to have a close button
3441 * via gtk_window_set_deletable().
3443 * Return value: %TRUE if the window has been set to have a close button
3448 gtk_window_get_deletable (GtkWindow *window)
3450 g_return_val_if_fail (GTK_IS_WINDOW (window), TRUE);
3452 return window->priv->deletable;
3455 static GtkWindowIconInfo*
3456 get_icon_info (GtkWindow *window)
3458 return g_object_get_qdata (G_OBJECT (window), quark_gtk_window_icon_info);
3462 free_icon_info (GtkWindowIconInfo *info)
3464 g_free (info->icon_name);
3465 g_slice_free (GtkWindowIconInfo, info);
3469 static GtkWindowIconInfo*
3470 ensure_icon_info (GtkWindow *window)
3472 GtkWindowIconInfo *info;
3474 info = get_icon_info (window);
3478 info = g_slice_new0 (GtkWindowIconInfo);
3479 g_object_set_qdata_full (G_OBJECT (window),
3480 quark_gtk_window_icon_info,
3482 (GDestroyNotify)free_icon_info);
3489 icon_list_from_theme (GtkWidget *widget,
3494 GtkIconTheme *icon_theme;
3499 icon_theme = gtk_icon_theme_get_for_screen (gtk_widget_get_screen (widget));
3501 sizes = gtk_icon_theme_get_icon_sizes (icon_theme, name);
3504 for (i = 0; sizes[i]; i++)
3507 * We need an EWMH extension to handle scalable icons
3508 * by passing their name to the WM. For now just use a
3512 icon = gtk_icon_theme_load_icon (icon_theme, name,
3515 icon = gtk_icon_theme_load_icon (icon_theme, name,
3518 list = g_list_append (list, icon);
3528 gtk_window_realize_icon (GtkWindow *window)
3530 GtkWindowPrivate *priv = window->priv;
3532 GtkWindowIconInfo *info;
3533 GdkWindow *gdk_window;
3536 widget = GTK_WIDGET (window);
3537 gdk_window = gtk_widget_get_window (widget);
3539 g_return_if_fail (gdk_window != NULL);
3541 /* no point setting an icon on override-redirect */
3542 if (priv->type == GTK_WINDOW_POPUP)
3547 info = ensure_icon_info (window);
3552 info->using_default_icon = FALSE;
3553 info->using_parent_icon = FALSE;
3554 info->using_themed_icon = FALSE;
3556 icon_list = info->icon_list;
3558 /* Look up themed icon */
3559 if (icon_list == NULL && info->icon_name)
3561 icon_list = icon_list_from_theme (widget, info->icon_name);
3563 info->using_themed_icon = TRUE;
3566 /* Inherit from transient parent */
3567 if (icon_list == NULL && priv->transient_parent)
3569 icon_list = ensure_icon_info (priv->transient_parent)->icon_list;
3571 info->using_parent_icon = TRUE;
3574 /* Inherit from default */
3575 if (icon_list == NULL)
3577 icon_list = default_icon_list;
3579 info->using_default_icon = TRUE;
3582 /* Look up themed icon */
3583 if (icon_list == NULL && default_icon_name)
3585 icon_list = icon_list_from_theme (widget, default_icon_name);
3586 info->using_default_icon = TRUE;
3587 info->using_themed_icon = TRUE;
3590 info->realized = TRUE;
3592 gdk_window_set_icon_list (gtk_widget_get_window (widget), icon_list);
3594 if (info->using_themed_icon)
3596 GtkIconTheme *icon_theme;
3598 g_list_free_full (icon_list, g_object_unref);
3600 icon_theme = gtk_icon_theme_get_for_screen (gtk_widget_get_screen (GTK_WIDGET (window)));
3601 g_signal_connect (icon_theme, "changed",
3602 G_CALLBACK (update_themed_icon), window);
3607 gtk_window_unrealize_icon (GtkWindow *window)
3609 GtkWindowIconInfo *info;
3611 info = get_icon_info (window);
3616 if (info->using_themed_icon)
3618 GtkIconTheme *icon_theme;
3620 icon_theme = gtk_icon_theme_get_for_screen (gtk_widget_get_screen (GTK_WIDGET (window)));
3622 g_signal_handlers_disconnect_by_func (icon_theme, update_themed_icon, window);
3625 /* We don't clear the properties on the window, just figure the
3626 * window is going away.
3629 info->realized = FALSE;
3634 * gtk_window_set_icon_list:
3635 * @window: a #GtkWindow
3636 * @list: (element-type GdkPixbuf): list of #GdkPixbuf
3638 * Sets up the icon representing a #GtkWindow. The icon is used when
3639 * the window is minimized (also known as iconified). Some window
3640 * managers or desktop environments may also place it in the window
3641 * frame, or display it in other contexts.
3643 * gtk_window_set_icon_list() allows you to pass in the same icon in
3644 * several hand-drawn sizes. The list should contain the natural sizes
3645 * your icon is available in; that is, don't scale the image before
3646 * passing it to GTK+. Scaling is postponed until the last minute,
3647 * when the desired final size is known, to allow best quality.
3649 * By passing several sizes, you may improve the final image quality
3650 * of the icon, by reducing or eliminating automatic image scaling.
3652 * Recommended sizes to provide: 16x16, 32x32, 48x48 at minimum, and
3653 * larger images (64x64, 128x128) if you have them.
3655 * See also gtk_window_set_default_icon_list() to set the icon
3656 * for all windows in your application in one go.
3658 * Note that transient windows (those who have been set transient for another
3659 * window using gtk_window_set_transient_for()) will inherit their
3660 * icon from their transient parent. So there's no need to explicitly
3661 * set the icon on transient windows.
3664 gtk_window_set_icon_list (GtkWindow *window,
3667 GtkWindowIconInfo *info;
3669 g_return_if_fail (GTK_IS_WINDOW (window));
3671 info = ensure_icon_info (window);
3673 if (info->icon_list == list) /* check for NULL mostly */
3676 g_list_foreach (list,
3677 (GFunc) g_object_ref, NULL);
3679 g_list_free_full (info->icon_list, g_object_unref);
3681 info->icon_list = g_list_copy (list);
3683 g_object_notify (G_OBJECT (window), "icon");
3685 gtk_window_unrealize_icon (window);
3687 if (gtk_widget_get_realized (GTK_WIDGET (window)))
3688 gtk_window_realize_icon (window);
3690 /* We could try to update our transient children, but I don't think
3691 * it's really worth it. If we did it, the best way would probably
3692 * be to have children connect to notify::icon-list
3697 * gtk_window_get_icon_list:
3698 * @window: a #GtkWindow
3700 * Retrieves the list of icons set by gtk_window_set_icon_list().
3701 * The list is copied, but the reference count on each
3702 * member won't be incremented.
3704 * Return value: (element-type GdkPixbuf) (transfer container): copy of window's icon list
3707 gtk_window_get_icon_list (GtkWindow *window)
3709 GtkWindowIconInfo *info;
3711 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
3713 info = get_icon_info (window);
3716 return g_list_copy (info->icon_list);
3722 * gtk_window_set_icon:
3723 * @window: a #GtkWindow
3724 * @icon: (allow-none): icon image, or %NULL
3726 * Sets up the icon representing a #GtkWindow. This icon is used when
3727 * the window is minimized (also known as iconified). Some window
3728 * managers or desktop environments may also place it in the window
3729 * frame, or display it in other contexts.
3731 * The icon should be provided in whatever size it was naturally
3732 * drawn; that is, don't scale the image before passing it to
3733 * GTK+. Scaling is postponed until the last minute, when the desired
3734 * final size is known, to allow best quality.
3736 * If you have your icon hand-drawn in multiple sizes, use
3737 * gtk_window_set_icon_list(). Then the best size will be used.
3739 * This function is equivalent to calling gtk_window_set_icon_list()
3740 * with a 1-element list.
3742 * See also gtk_window_set_default_icon_list() to set the icon
3743 * for all windows in your application in one go.
3746 gtk_window_set_icon (GtkWindow *window,
3751 g_return_if_fail (GTK_IS_WINDOW (window));
3752 g_return_if_fail (icon == NULL || GDK_IS_PIXBUF (icon));
3757 list = g_list_append (list, icon);
3759 gtk_window_set_icon_list (window, list);
3765 update_themed_icon (GtkIconTheme *icon_theme,
3768 g_object_notify (G_OBJECT (window), "icon");
3770 gtk_window_unrealize_icon (window);
3772 if (gtk_widget_get_realized (GTK_WIDGET (window)))
3773 gtk_window_realize_icon (window);
3777 * gtk_window_set_icon_name:
3778 * @window: a #GtkWindow
3779 * @name: (allow-none): the name of the themed icon
3781 * Sets the icon for the window from a named themed icon. See
3782 * the docs for #GtkIconTheme for more details.
3784 * Note that this has nothing to do with the WM_ICON_NAME
3785 * property which is mentioned in the ICCCM.
3790 gtk_window_set_icon_name (GtkWindow *window,
3793 GtkWindowIconInfo *info;
3796 g_return_if_fail (GTK_IS_WINDOW (window));
3798 info = ensure_icon_info (window);
3800 if (g_strcmp0 (info->icon_name, name) == 0)
3803 tmp = info->icon_name;
3804 info->icon_name = g_strdup (name);
3807 g_list_free_full (info->icon_list, g_object_unref);
3808 info->icon_list = NULL;
3810 update_themed_icon (NULL, window);
3812 g_object_notify (G_OBJECT (window), "icon-name");
3816 * gtk_window_get_icon_name:
3817 * @window: a #GtkWindow
3819 * Returns the name of the themed icon for the window,
3820 * see gtk_window_set_icon_name().
3822 * Returns: the icon name or %NULL if the window has
3828 gtk_window_get_icon_name (GtkWindow *window)
3830 GtkWindowIconInfo *info;
3832 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
3834 info = ensure_icon_info (window);
3836 return info->icon_name;
3840 * gtk_window_get_icon:
3841 * @window: a #GtkWindow
3843 * Gets the value set by gtk_window_set_icon() (or if you've
3844 * called gtk_window_set_icon_list(), gets the first icon in
3847 * Return value: (transfer none): icon for window
3850 gtk_window_get_icon (GtkWindow *window)
3852 GtkWindowIconInfo *info;
3854 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
3856 info = get_icon_info (window);
3857 if (info && info->icon_list)
3858 return GDK_PIXBUF (info->icon_list->data);
3863 /* Load pixbuf, printing warning on failure if error == NULL
3866 load_pixbuf_verbosely (const char *filename,
3869 GError *local_err = NULL;
3872 pixbuf = gdk_pixbuf_new_from_file (filename, &local_err);
3880 g_warning ("Error loading icon from file '%s':\n\t%s",
3881 filename, local_err->message);
3882 g_error_free (local_err);
3890 * gtk_window_set_icon_from_file:
3891 * @window: a #GtkWindow
3892 * @filename: (type filename): location of icon file
3893 * @err: (allow-none): location to store error, or %NULL.
3895 * Sets the icon for @window.
3896 * Warns on failure if @err is %NULL.
3898 * This function is equivalent to calling gtk_window_set_icon()
3899 * with a pixbuf created by loading the image from @filename.
3901 * Returns: %TRUE if setting the icon succeeded.
3906 gtk_window_set_icon_from_file (GtkWindow *window,
3907 const gchar *filename,
3910 GdkPixbuf *pixbuf = load_pixbuf_verbosely (filename, err);
3914 gtk_window_set_icon (window, pixbuf);
3915 g_object_unref (pixbuf);
3924 * gtk_window_set_default_icon_list:
3925 * @list: (element-type GdkPixbuf) (transfer container): a list of #GdkPixbuf
3927 * Sets an icon list to be used as fallback for windows that haven't
3928 * had gtk_window_set_icon_list() called on them to set up a
3929 * window-specific icon list. This function allows you to set up the
3930 * icon for all windows in your app at once.
3932 * See gtk_window_set_icon_list() for more details.
3936 gtk_window_set_default_icon_list (GList *list)
3940 if (list == default_icon_list)
3943 /* Update serial so we don't used cached pixmaps/masks
3945 default_icon_serial++;
3947 g_list_foreach (list,
3948 (GFunc) g_object_ref, NULL);
3950 g_list_free_full (default_icon_list, g_object_unref);
3952 default_icon_list = g_list_copy (list);
3954 /* Update all toplevels */
3955 toplevels = gtk_window_list_toplevels ();
3956 tmp_list = toplevels;
3957 while (tmp_list != NULL)
3959 GtkWindowIconInfo *info;
3960 GtkWindow *w = tmp_list->data;
3962 info = get_icon_info (w);
3963 if (info && info->using_default_icon)
3965 gtk_window_unrealize_icon (w);
3966 if (gtk_widget_get_realized (GTK_WIDGET (w)))
3967 gtk_window_realize_icon (w);
3970 tmp_list = tmp_list->next;
3972 g_list_free (toplevels);
3976 * gtk_window_set_default_icon:
3979 * Sets an icon to be used as fallback for windows that haven't
3980 * had gtk_window_set_icon() called on them from a pixbuf.
3985 gtk_window_set_default_icon (GdkPixbuf *icon)
3989 g_return_if_fail (GDK_IS_PIXBUF (icon));
3991 list = g_list_prepend (NULL, icon);
3992 gtk_window_set_default_icon_list (list);
3997 * gtk_window_set_default_icon_name:
3998 * @name: the name of the themed icon
4000 * Sets an icon to be used as fallback for windows that haven't
4001 * had gtk_window_set_icon_list() called on them from a named
4002 * themed icon, see gtk_window_set_icon_name().
4007 gtk_window_set_default_icon_name (const gchar *name)
4012 /* Update serial so we don't used cached pixmaps/masks
4014 default_icon_serial++;
4016 g_free (default_icon_name);
4017 default_icon_name = g_strdup (name);
4019 g_list_free_full (default_icon_list, g_object_unref);
4020 default_icon_list = NULL;
4022 /* Update all toplevels */
4023 toplevels = gtk_window_list_toplevels ();
4024 tmp_list = toplevels;
4025 while (tmp_list != NULL)
4027 GtkWindowIconInfo *info;
4028 GtkWindow *w = tmp_list->data;
4030 info = get_icon_info (w);
4031 if (info && info->using_default_icon && info->using_themed_icon)
4033 gtk_window_unrealize_icon (w);
4034 if (gtk_widget_get_realized (GTK_WIDGET (w)))
4035 gtk_window_realize_icon (w);
4038 tmp_list = tmp_list->next;
4040 g_list_free (toplevels);
4044 * gtk_window_get_default_icon_name:
4046 * Returns the fallback icon name for windows that has been set
4047 * with gtk_window_set_default_icon_name(). The returned
4048 * string is owned by GTK+ and should not be modified. It
4049 * is only valid until the next call to
4050 * gtk_window_set_default_icon_name().
4052 * Returns: the fallback icon name for windows
4057 gtk_window_get_default_icon_name (void)
4059 return default_icon_name;
4063 * gtk_window_set_default_icon_from_file:
4064 * @filename: (type filename): location of icon file
4065 * @err: (allow-none): location to store error, or %NULL.
4067 * Sets an icon to be used as fallback for windows that haven't
4068 * had gtk_window_set_icon_list() called on them from a file
4069 * on disk. Warns on failure if @err is %NULL.
4071 * Returns: %TRUE if setting the icon succeeded.
4076 gtk_window_set_default_icon_from_file (const gchar *filename,
4079 GdkPixbuf *pixbuf = load_pixbuf_verbosely (filename, err);
4083 gtk_window_set_default_icon (pixbuf);
4084 g_object_unref (pixbuf);
4093 * gtk_window_get_default_icon_list:
4095 * Gets the value set by gtk_window_set_default_icon_list().
4096 * The list is a copy and should be freed with g_list_free(),
4097 * but the pixbufs in the list have not had their reference count
4100 * Return value: (element-type GdkPixbuf) (transfer container): copy of default icon list
4103 gtk_window_get_default_icon_list (void)
4105 return g_list_copy (default_icon_list);
4109 gtk_window_set_default_size_internal (GtkWindow *window,
4110 gboolean change_width,
4112 gboolean change_height,
4114 gboolean is_geometry)
4116 GtkWindowGeometryInfo *info;
4118 g_return_if_fail (change_width == FALSE || width >= -1);
4119 g_return_if_fail (change_height == FALSE || height >= -1);
4121 info = gtk_window_get_geometry_info (window, TRUE);
4123 g_object_freeze_notify (G_OBJECT (window));
4125 info->default_is_geometry = is_geometry != FALSE;
4135 info->default_width = width;
4137 g_object_notify (G_OBJECT (window), "default-width");
4148 info->default_height = height;
4150 g_object_notify (G_OBJECT (window), "default-height");
4153 g_object_thaw_notify (G_OBJECT (window));
4155 gtk_widget_queue_resize_no_redraw (GTK_WIDGET (window));
4159 * gtk_window_set_default_size:
4160 * @window: a #GtkWindow
4161 * @width: width in pixels, or -1 to unset the default width
4162 * @height: height in pixels, or -1 to unset the default height
4164 * Sets the default size of a window. If the window's "natural" size
4165 * (its size request) is larger than the default, the default will be
4166 * ignored. More generally, if the default size does not obey the
4167 * geometry hints for the window (gtk_window_set_geometry_hints() can
4168 * be used to set these explicitly), the default size will be clamped
4169 * to the nearest permitted size.
4171 * Unlike gtk_widget_set_size_request(), which sets a size request for
4172 * a widget and thus would keep users from shrinking the window, this
4173 * function only sets the initial size, just as if the user had
4174 * resized the window themselves. Users can still shrink the window
4175 * again as they normally would. Setting a default size of -1 means to
4176 * use the "natural" default size (the size request of the window).
4178 * For more control over a window's initial size and how resizing works,
4179 * investigate gtk_window_set_geometry_hints().
4181 * For some uses, gtk_window_resize() is a more appropriate function.
4182 * gtk_window_resize() changes the current size of the window, rather
4183 * than the size to be used on initial display. gtk_window_resize() always
4184 * affects the window itself, not the geometry widget.
4186 * The default size of a window only affects the first time a window is
4187 * shown; if a window is hidden and re-shown, it will remember the size
4188 * it had prior to hiding, rather than using the default size.
4190 * Windows can't actually be 0x0 in size, they must be at least 1x1, but
4191 * passing 0 for @width and @height is OK, resulting in a 1x1 default size.
4194 gtk_window_set_default_size (GtkWindow *window,
4198 g_return_if_fail (GTK_IS_WINDOW (window));
4199 g_return_if_fail (width >= -1);
4200 g_return_if_fail (height >= -1);
4202 gtk_window_set_default_size_internal (window, TRUE, width, TRUE, height, FALSE);
4206 * gtk_window_set_default_geometry:
4207 * @window: a #GtkWindow
4208 * @width: width in resize increments, or -1 to unset the default width
4209 * @height: height in resize increments, or -1 to unset the default height
4211 * Like gtk_window_set_default_size(), but @width and @height are interpreted
4212 * in terms of the base size and increment set with
4213 * gtk_window_set_geometry_hints.
4218 gtk_window_set_default_geometry (GtkWindow *window,
4222 g_return_if_fail (GTK_IS_WINDOW (window));
4223 g_return_if_fail (width >= -1);
4224 g_return_if_fail (height >= -1);
4226 gtk_window_set_default_size_internal (window, TRUE, width, TRUE, height, TRUE);
4230 * gtk_window_get_default_size:
4231 * @window: a #GtkWindow
4232 * @width: (out) (allow-none): location to store the default width, or %NULL
4233 * @height: (out) (allow-none): location to store the default height, or %NULL
4235 * Gets the default size of the window. A value of -1 for the width or
4236 * height indicates that a default size has not been explicitly set
4237 * for that dimension, so the "natural" size of the window will be
4242 gtk_window_get_default_size (GtkWindow *window,
4246 GtkWindowGeometryInfo *info;
4248 g_return_if_fail (GTK_IS_WINDOW (window));
4250 info = gtk_window_get_geometry_info (window, FALSE);
4253 *width = info ? info->default_width : -1;
4256 *height = info ? info->default_height : -1;
4260 * gtk_window_resize:
4261 * @window: a #GtkWindow
4262 * @width: width in pixels to resize the window to
4263 * @height: height in pixels to resize the window to
4265 * Resizes the window as if the user had done so, obeying geometry
4266 * constraints. The default geometry constraint is that windows may
4267 * not be smaller than their size request; to override this
4268 * constraint, call gtk_widget_set_size_request() to set the window's
4269 * request to a smaller value.
4271 * If gtk_window_resize() is called before showing a window for the
4272 * first time, it overrides any default size set with
4273 * gtk_window_set_default_size().
4275 * Windows may not be resized smaller than 1 by 1 pixels.
4279 gtk_window_resize (GtkWindow *window,
4283 GtkWindowGeometryInfo *info;
4285 g_return_if_fail (GTK_IS_WINDOW (window));
4286 g_return_if_fail (width > 0);
4287 g_return_if_fail (height > 0);
4289 info = gtk_window_get_geometry_info (window, TRUE);
4291 info->resize_width = width;
4292 info->resize_height = height;
4293 info->resize_is_geometry = FALSE;
4295 gtk_widget_queue_resize_no_redraw (GTK_WIDGET (window));
4299 * gtk_window_resize_to_geometry:
4300 * @window: a #GtkWindow
4301 * @width: width in resize increments to resize the window to
4302 * @height: height in resize increments to resize the window to
4304 * Like gtk_window_resize(), but @width and @height are interpreted
4305 * in terms of the base size and increment set with
4306 * gtk_window_set_geometry_hints.
4311 gtk_window_resize_to_geometry (GtkWindow *window,
4315 GtkWindowGeometryInfo *info;
4317 g_return_if_fail (GTK_IS_WINDOW (window));
4318 g_return_if_fail (width > 0);
4319 g_return_if_fail (height > 0);
4321 info = gtk_window_get_geometry_info (window, TRUE);
4323 info->resize_width = width;
4324 info->resize_height = height;
4325 info->resize_is_geometry = TRUE;
4327 gtk_widget_queue_resize_no_redraw (GTK_WIDGET (window));
4331 * gtk_window_get_size:
4332 * @window: a #GtkWindow
4333 * @width: (out) (allow-none): return location for width, or %NULL
4334 * @height: (out) (allow-none): return location for height, or %NULL
4336 * Obtains the current size of @window. If @window is not onscreen,
4337 * it returns the size GTK+ will suggest to the <link
4338 * linkend="gtk-X11-arch">window manager</link> for the initial window
4339 * size (but this is not reliably the same as the size the window
4340 * manager will actually select). The size obtained by
4341 * gtk_window_get_size() is the last size received in a
4342 * #GdkEventConfigure, that is, GTK+ uses its locally-stored size,
4343 * rather than querying the X server for the size. As a result, if you
4344 * call gtk_window_resize() then immediately call
4345 * gtk_window_get_size(), the size won't have taken effect yet. After
4346 * the window manager processes the resize request, GTK+ receives
4347 * notification that the size has changed via a configure event, and
4348 * the size of the window gets updated.
4350 * Note 1: Nearly any use of this function creates a race condition,
4351 * because the size of the window may change between the time that you
4352 * get the size and the time that you perform some action assuming
4353 * that size is the current size. To avoid race conditions, connect to
4354 * "configure-event" on the window and adjust your size-dependent
4355 * state to match the size delivered in the #GdkEventConfigure.
4357 * Note 2: The returned size does <emphasis>not</emphasis> include the
4358 * size of the window manager decorations (aka the window frame or
4359 * border). Those are not drawn by GTK+ and GTK+ has no reliable
4360 * method of determining their size.
4362 * Note 3: If you are getting a window size in order to position
4363 * the window onscreen, there may be a better way. The preferred
4364 * way is to simply set the window's semantic type with
4365 * gtk_window_set_type_hint(), which allows the window manager to
4366 * e.g. center dialogs. Also, if you set the transient parent of
4367 * dialogs with gtk_window_set_transient_for() window managers
4368 * will often center the dialog over its parent window. It's
4369 * much preferred to let the window manager handle these
4370 * things rather than doing it yourself, because all apps will
4371 * behave consistently and according to user prefs if the window
4372 * manager handles it. Also, the window manager can take the size
4373 * of the window decorations/border into account, while your
4374 * application cannot.
4376 * In any case, if you insist on application-specified window
4377 * positioning, there's <emphasis>still</emphasis> a better way than
4378 * doing it yourself - gtk_window_set_position() will frequently
4379 * handle the details for you.
4383 gtk_window_get_size (GtkWindow *window,
4389 g_return_if_fail (GTK_IS_WINDOW (window));
4391 if (width == NULL && height == NULL)
4394 if (gtk_widget_get_mapped (GTK_WIDGET (window)))
4396 w = gdk_window_get_width (gtk_widget_get_window (GTK_WIDGET (window)));
4397 h = gdk_window_get_height (gtk_widget_get_window (GTK_WIDGET (window)));
4401 GdkRectangle configure_request;
4403 gtk_window_compute_configure_request (window,
4407 w = configure_request.width;
4408 h = configure_request.height;
4419 * @window: a #GtkWindow
4420 * @x: X coordinate to move window to
4421 * @y: Y coordinate to move window to
4423 * Asks the <link linkend="gtk-X11-arch">window manager</link> to move
4424 * @window to the given position. Window managers are free to ignore
4425 * this; most window managers ignore requests for initial window
4426 * positions (instead using a user-defined placement algorithm) and
4427 * honor requests after the window has already been shown.
4429 * Note: the position is the position of the gravity-determined
4430 * reference point for the window. The gravity determines two things:
4431 * first, the location of the reference point in root window
4432 * coordinates; and second, which point on the window is positioned at
4433 * the reference point.
4435 * By default the gravity is #GDK_GRAVITY_NORTH_WEST, so the reference
4436 * point is simply the @x, @y supplied to gtk_window_move(). The
4437 * top-left corner of the window decorations (aka window frame or
4438 * border) will be placed at @x, @y. Therefore, to position a window
4439 * at the top left of the screen, you want to use the default gravity
4440 * (which is #GDK_GRAVITY_NORTH_WEST) and move the window to 0,0.
4442 * To position a window at the bottom right corner of the screen, you
4443 * would set #GDK_GRAVITY_SOUTH_EAST, which means that the reference
4444 * point is at @x + the window width and @y + the window height, and
4445 * the bottom-right corner of the window border will be placed at that
4446 * reference point. So, to place a window in the bottom right corner
4447 * you would first set gravity to south east, then write:
4448 * <literal>gtk_window_move (window, gdk_screen_width () - window_width,
4449 * gdk_screen_height () - window_height)</literal> (note that this
4450 * example does not take multi-head scenarios into account).
4452 * The Extended Window Manager Hints specification at <ulink
4453 * url="http://www.freedesktop.org/Standards/wm-spec">
4454 * http://www.freedesktop.org/Standards/wm-spec</ulink> has a
4455 * nice table of gravities in the "implementation notes" section.
4457 * The gtk_window_get_position() documentation may also be relevant.
4460 gtk_window_move (GtkWindow *window,
4464 GtkWindowGeometryInfo *info;
4467 g_return_if_fail (GTK_IS_WINDOW (window));
4469 widget = GTK_WIDGET (window);
4471 info = gtk_window_get_geometry_info (window, TRUE);
4473 if (gtk_widget_get_mapped (widget))
4475 GtkAllocation allocation;
4477 gtk_widget_get_allocation (widget, &allocation);
4479 /* we have now sent a request with this position
4480 * with currently-active constraints, so toggle flag.
4482 info->position_constraints_changed = FALSE;
4484 /* we only constrain if mapped - if not mapped,
4485 * then gtk_window_compute_configure_request()
4486 * will apply the constraints later, and we
4487 * don't want to lose information about
4488 * what position the user set before then.
4489 * i.e. if you do a move() then turn off POS_CENTER
4490 * then show the window, your move() will work.
4492 gtk_window_constrain_position (window,
4493 allocation.width, allocation.height,
4496 /* Note that this request doesn't go through our standard request
4497 * framework, e.g. doesn't increment configure_request_count,
4498 * doesn't set info->last, etc.; that's because
4499 * we don't save the info needed to arrive at this same request
4502 * To gtk_window_move_resize(), this will end up looking exactly
4503 * the same as the position being changed by the window
4506 gdk_window_move (gtk_widget_get_window (GTK_WIDGET (window)), x, y);
4510 /* Save this position to apply on mapping */
4511 info->initial_x = x;
4512 info->initial_y = y;
4513 info->initial_pos_set = TRUE;
4518 * gtk_window_get_position:
4519 * @window: a #GtkWindow
4520 * @root_x: (out) (allow-none): eturn location for X coordinate of
4521 * gravity-determined reference point, or %NULL
4522 * @root_y: (out) (allow-none): return location for Y coordinate of
4523 * gravity-determined reference point, or %NULL
4525 * This function returns the position you need to pass to
4526 * gtk_window_move() to keep @window in its current position.
4527 * This means that the meaning of the returned value varies with
4528 * window gravity. See gtk_window_move() for more details.
4530 * If you haven't changed the window gravity, its gravity will be
4531 * #GDK_GRAVITY_NORTH_WEST. This means that gtk_window_get_position()
4532 * gets the position of the top-left corner of the window manager
4533 * frame for the window. gtk_window_move() sets the position of this
4534 * same top-left corner.
4536 * gtk_window_get_position() is not 100% reliable because the X Window System
4537 * does not specify a way to obtain the geometry of the
4538 * decorations placed on a window by the window manager.
4539 * Thus GTK+ is using a "best guess" that works with most
4542 * Moreover, nearly all window managers are historically broken with
4543 * respect to their handling of window gravity. So moving a window to
4544 * its current position as returned by gtk_window_get_position() tends
4545 * to result in moving the window slightly. Window managers are
4546 * slowly getting better over time.
4548 * If a window has gravity #GDK_GRAVITY_STATIC the window manager
4549 * frame is not relevant, and thus gtk_window_get_position() will
4550 * always produce accurate results. However you can't use static
4551 * gravity to do things like place a window in a corner of the screen,
4552 * because static gravity ignores the window manager decorations.
4554 * If you are saving and restoring your application's window
4555 * positions, you should know that it's impossible for applications to
4556 * do this without getting it somewhat wrong because applications do
4557 * not have sufficient knowledge of window manager state. The Correct
4558 * Mechanism is to support the session management protocol (see the
4559 * "GnomeClient" object in the GNOME libraries for example) and allow
4560 * the window manager to save your window sizes and positions.
4565 gtk_window_get_position (GtkWindow *window,
4569 GtkWindowPrivate *priv;
4571 GdkWindow *gdk_window;
4573 g_return_if_fail (GTK_IS_WINDOW (window));
4575 priv = window->priv;
4576 widget = GTK_WIDGET (window);
4577 gdk_window = gtk_widget_get_window (widget);
4579 if (priv->gravity == GDK_GRAVITY_STATIC)
4581 if (gtk_widget_get_mapped (widget))
4583 /* This does a server round-trip, which is sort of wrong;
4584 * but a server round-trip is inevitable for
4585 * gdk_window_get_frame_extents() in the usual
4586 * NorthWestGravity case below, so not sure what else to
4587 * do. We should likely be consistent about whether we get
4588 * the client-side info or the server-side info.
4590 gdk_window_get_origin (gdk_window, root_x, root_y);
4594 GdkRectangle configure_request;
4596 gtk_window_compute_configure_request (window,
4600 *root_x = configure_request.x;
4601 *root_y = configure_request.y;
4606 GdkRectangle frame_extents;
4611 if (gtk_widget_get_mapped (widget))
4613 gdk_window_get_frame_extents (gdk_window, &frame_extents);
4614 x = frame_extents.x;
4615 y = frame_extents.y;
4616 gtk_window_get_size (window, &w, &h);
4620 /* We just say the frame has 0 size on all sides.
4621 * Not sure what else to do.
4623 gtk_window_compute_configure_request (window,
4626 x = frame_extents.x;
4627 y = frame_extents.y;
4628 w = frame_extents.width;
4629 h = frame_extents.height;
4632 switch (priv->gravity)
4634 case GDK_GRAVITY_NORTH:
4635 case GDK_GRAVITY_CENTER:
4636 case GDK_GRAVITY_SOUTH:
4637 /* Find center of frame. */
4638 x += frame_extents.width / 2;
4639 /* Center client window on that point. */
4643 case GDK_GRAVITY_SOUTH_EAST:
4644 case GDK_GRAVITY_EAST:
4645 case GDK_GRAVITY_NORTH_EAST:
4646 /* Find right edge of frame */
4647 x += frame_extents.width;
4648 /* Align left edge of client at that point. */
4655 switch (priv->gravity)
4657 case GDK_GRAVITY_WEST:
4658 case GDK_GRAVITY_CENTER:
4659 case GDK_GRAVITY_EAST:
4660 /* Find center of frame. */
4661 y += frame_extents.height / 2;
4662 /* Center client window there. */
4665 case GDK_GRAVITY_SOUTH_WEST:
4666 case GDK_GRAVITY_SOUTH:
4667 case GDK_GRAVITY_SOUTH_EAST:
4668 /* Find south edge of frame */
4669 y += frame_extents.height;
4670 /* Place bottom edge of client there */
4685 * gtk_window_reshow_with_initial_size:
4686 * @window: a #GtkWindow
4688 * Hides @window, then reshows it, resetting the
4689 * default size and position of the window. Used
4690 * by GUI builders only.
4693 gtk_window_reshow_with_initial_size (GtkWindow *window)
4697 g_return_if_fail (GTK_IS_WINDOW (window));
4699 widget = GTK_WIDGET (window);
4701 gtk_widget_hide (widget);
4702 gtk_widget_unrealize (widget);
4703 gtk_widget_show (widget);
4707 gtk_window_destroy (GtkWidget *widget)
4709 GtkWindow *window = GTK_WINDOW (widget);
4710 GtkWindowPrivate *priv = window->priv;
4712 gtk_window_release_application (window);
4714 toplevel_list = g_slist_remove (toplevel_list, window);
4716 if (priv->transient_parent)
4717 gtk_window_set_transient_for (window, NULL);
4719 remove_attach_widget (GTK_WINDOW (widget));
4721 /* frees the icons */
4722 gtk_window_set_icon_list (window, NULL);
4724 if (priv->has_user_ref_count)
4726 priv->has_user_ref_count = FALSE;
4727 g_object_unref (window);
4731 gtk_window_group_remove_window (priv->group, window);
4733 gtk_window_free_key_hash (window);
4735 GTK_WIDGET_CLASS (gtk_window_parent_class)->destroy (widget);
4739 gtk_window_finalize (GObject *object)
4741 GtkWindow *window = GTK_WINDOW (object);
4742 GtkWindowPrivate *priv = window->priv;
4743 GtkMnemonicHash *mnemonic_hash;
4745 g_free (priv->title);
4746 g_free (priv->wmclass_name);
4747 g_free (priv->wmclass_class);
4748 g_free (priv->wm_role);
4749 gtk_window_release_application (window);
4751 mnemonic_hash = gtk_window_get_mnemonic_hash (window, FALSE);
4753 _gtk_mnemonic_hash_free (mnemonic_hash);
4755 if (priv->geometry_info)
4757 if (priv->geometry_info->widget)
4758 g_signal_handlers_disconnect_by_func (priv->geometry_info->widget,
4759 gtk_widget_destroyed,
4760 &priv->geometry_info->widget);
4761 g_free (priv->geometry_info);
4764 if (priv->keys_changed_handler)
4766 g_source_remove (priv->keys_changed_handler);
4767 priv->keys_changed_handler = 0;
4771 g_signal_handlers_disconnect_by_func (priv->screen,
4772 gtk_window_on_composited_changed, window);
4774 g_free (priv->startup_id);
4776 #ifdef GDK_WINDOWING_X11
4777 g_signal_handlers_disconnect_by_func (gtk_settings_get_default (),
4778 gtk_window_on_theme_variant_changed,
4782 G_OBJECT_CLASS (gtk_window_parent_class)->finalize (object);
4786 gtk_window_show (GtkWidget *widget)
4788 GtkWindow *window = GTK_WINDOW (widget);
4789 GtkWindowPrivate *priv = window->priv;
4790 GtkContainer *container = GTK_CONTAINER (window);
4791 gboolean need_resize;
4794 if (!gtk_widget_is_toplevel (GTK_WIDGET (widget)))
4796 GTK_WIDGET_CLASS (gtk_window_parent_class)->show (widget);
4800 _gtk_widget_set_visible_flag (widget, TRUE);
4802 need_resize = _gtk_container_get_need_resize (container) || !gtk_widget_get_realized (widget);
4803 _gtk_container_set_need_resize (container, FALSE);
4807 GtkWindowGeometryInfo *info = gtk_window_get_geometry_info (window, TRUE);
4808 GtkAllocation allocation = { 0, 0 };
4809 GdkRectangle configure_request;
4810 GdkGeometry new_geometry;
4812 gboolean was_realized;
4814 /* We are going to go ahead and perform this configure request
4815 * and then emulate a configure notify by going ahead and
4816 * doing a size allocate. Sort of a synchronous
4817 * mini-copy of gtk_window_move_resize() here.
4819 gtk_window_compute_configure_request (window,
4824 /* We update this because we are going to go ahead
4825 * and gdk_window_resize() below, rather than
4828 info->last.configure_request.width = configure_request.width;
4829 info->last.configure_request.height = configure_request.height;
4831 /* and allocate the window - this is normally done
4832 * in move_resize in response to configure notify
4834 allocation.width = configure_request.width;
4835 allocation.height = configure_request.height;
4836 gtk_widget_size_allocate (widget, &allocation);
4838 /* Then we guarantee we have a realize */
4839 was_realized = FALSE;
4840 if (!gtk_widget_get_realized (widget))
4842 gtk_widget_realize (widget);
4843 was_realized = TRUE;
4846 /* We only send configure request if we didn't just finish
4847 * creating the window; if we just created the window
4848 * then we created it with widget->allocation anyhow.
4851 gdk_window_move_resize (gtk_widget_get_window (widget),
4852 configure_request.x,
4853 configure_request.y,
4854 configure_request.width,
4855 configure_request.height);
4858 gtk_container_check_resize (container);
4860 gtk_widget_map (widget);
4862 /* Try to make sure that we have some focused widget
4864 #ifdef GDK_WINDOWING_X11
4865 is_plug = GDK_IS_X11_WINDOW (gtk_widget_get_window (widget)) &&
4866 GTK_IS_PLUG (window);
4870 if (!priv->focus_widget && !is_plug)
4871 gtk_window_move_focus (widget, GTK_DIR_TAB_FORWARD);
4874 gtk_grab_add (widget);
4878 gtk_window_hide (GtkWidget *widget)
4880 GtkWindow *window = GTK_WINDOW (widget);
4881 GtkWindowPrivate *priv = window->priv;
4883 if (!gtk_widget_is_toplevel (GTK_WIDGET (widget)))
4885 GTK_WIDGET_CLASS (gtk_window_parent_class)->hide (widget);
4889 _gtk_widget_set_visible_flag (widget, FALSE);
4890 gtk_widget_unmap (widget);
4893 gtk_grab_remove (widget);
4897 gtk_window_map (GtkWidget *widget)
4900 GtkWindow *window = GTK_WINDOW (widget);
4901 GtkWindowPrivate *priv = window->priv;
4902 GdkWindow *gdk_window;
4903 gboolean auto_mnemonics;
4904 GtkPolicyType visible_focus;
4906 if (!gtk_widget_is_toplevel (widget))
4908 GTK_WIDGET_CLASS (gtk_window_parent_class)->map (widget);
4912 gtk_widget_set_mapped (widget, TRUE);
4914 child = gtk_bin_get_child (&(window->bin));
4916 gtk_widget_get_visible (child) &&
4917 !gtk_widget_get_mapped (child))
4918 gtk_widget_map (child);
4920 gdk_window = gtk_widget_get_window (widget);
4922 if (priv->maximize_initially)
4923 gdk_window_maximize (gdk_window);
4925 gdk_window_unmaximize (gdk_window);
4927 if (priv->stick_initially)
4928 gdk_window_stick (gdk_window);
4930 gdk_window_unstick (gdk_window);
4932 if (priv->iconify_initially)
4933 gdk_window_iconify (gdk_window);
4935 gdk_window_deiconify (gdk_window);
4937 if (priv->fullscreen_initially)
4938 gdk_window_fullscreen (gdk_window);
4940 gdk_window_unfullscreen (gdk_window);
4942 gdk_window_set_keep_above (gdk_window, priv->above_initially);
4944 gdk_window_set_keep_below (gdk_window, priv->below_initially);
4946 if (priv->type == GTK_WINDOW_TOPLEVEL)
4948 gtk_window_set_theme_variant (window);
4949 gtk_window_set_hide_titlebar_when_maximized (window,
4950 priv->hide_titlebar_when_maximized);
4953 /* No longer use the default settings */
4954 priv->need_default_size = FALSE;
4955 priv->need_default_position = FALSE;
4957 if (priv->reset_type_hint)
4959 /* We should only reset the type hint when the application
4960 * used gtk_window_set_type_hint() to change the hint.
4961 * Some applications use X directly to change the properties;
4962 * in that case, we shouldn't overwrite what they did.
4964 gdk_window_set_type_hint (gdk_window, priv->gdk_type_hint);
4965 priv->reset_type_hint = FALSE;
4968 gdk_window_show (gdk_window);
4970 if (priv->grip_window)
4971 gdk_window_show (priv->grip_window);
4973 if (!disable_startup_notification)
4975 /* Do we have a custom startup-notification id? */
4976 if (priv->startup_id != NULL)
4978 /* Make sure we have a "real" id */
4979 if (!startup_id_is_fake (priv->startup_id))
4980 gdk_notify_startup_complete_with_id (priv->startup_id);
4982 g_free (priv->startup_id);
4983 priv->startup_id = NULL;
4985 else if (!sent_startup_notification)
4987 sent_startup_notification = TRUE;
4988 gdk_notify_startup_complete ();
4992 /* if auto-mnemonics is enabled and mnemonics visible is not already set
4993 * (as in the case of popup menus), then hide mnemonics initially
4995 g_object_get (gtk_widget_get_settings (widget),
4996 "gtk-auto-mnemonics", &auto_mnemonics,
4997 "gtk-visible-focus", &visible_focus,
5000 if (auto_mnemonics && !priv->mnemonics_visible_set)
5001 gtk_window_set_mnemonics_visible (window, FALSE);
5003 /* inherit from transient parent, so that a dialog that is
5004 * opened via keynav shows focus initially
5006 if (priv->transient_parent)
5007 gtk_window_set_focus_visible (window, gtk_window_get_focus_visible (priv->transient_parent));
5009 gtk_window_set_focus_visible (window, visible_focus == GTK_POLICY_ALWAYS);
5011 ensure_state_flag_backdrop (widget);
5015 gtk_window_map_event (GtkWidget *widget,
5018 if (!gtk_widget_get_mapped (widget))
5020 /* we should be be unmapped, but are getting a MapEvent, this may happen
5021 * to toplevel XWindows if mapping was intercepted by a window manager
5022 * and an unmap request occoured while the MapRequestEvent was still
5023 * being handled. we work around this situaiton here by re-requesting
5024 * the window being unmapped. more details can be found in:
5025 * http://bugzilla.gnome.org/show_bug.cgi?id=316180
5027 gdk_window_hide (gtk_widget_get_window (widget));
5033 gtk_window_unmap (GtkWidget *widget)
5035 GtkWindow *window = GTK_WINDOW (widget);
5036 GtkWindowPrivate *priv = window->priv;
5038 GtkWindowGeometryInfo *info;
5039 GdkWindow *gdk_window;
5040 GdkWindowState state;
5042 if (!gtk_widget_is_toplevel (GTK_WIDGET (widget)))
5044 GTK_WIDGET_CLASS (gtk_window_parent_class)->unmap (widget);
5048 gdk_window = gtk_widget_get_window (widget);
5050 gtk_widget_set_mapped (widget, FALSE);
5051 gdk_window_withdraw (gdk_window);
5053 priv->configure_request_count = 0;
5054 priv->configure_notify_received = FALSE;
5056 /* on unmap, we reset the default positioning of the window,
5057 * so it's placed again, but we don't reset the default
5058 * size of the window, so it's remembered.
5060 priv->need_default_position = TRUE;
5062 info = gtk_window_get_geometry_info (window, FALSE);
5065 info->initial_pos_set = FALSE;
5066 info->position_constraints_changed = FALSE;
5069 state = gdk_window_get_state (gdk_window);
5070 priv->iconify_initially = (state & GDK_WINDOW_STATE_ICONIFIED) != 0;
5071 priv->maximize_initially = (state & GDK_WINDOW_STATE_MAXIMIZED) != 0;
5072 priv->stick_initially = (state & GDK_WINDOW_STATE_STICKY) != 0;
5073 priv->above_initially = (state & GDK_WINDOW_STATE_ABOVE) != 0;
5074 priv->below_initially = (state & GDK_WINDOW_STATE_BELOW) != 0;
5076 child = gtk_bin_get_child (&(window->bin));
5078 gtk_widget_unmap (child);
5081 /* (Note: Replace "size" with "width" or "height". Also, the request
5082 * mode is honoured.)
5083 * For selecting the default window size, the following conditions
5084 * should hold (in order of importance):
5085 * - the size is not below the minimum size
5086 * Windows cannot be resized below their minimum size, so we must
5087 * ensure we don't do that either.
5088 * - the size is not above the natural size
5089 * It seems weird to allocate more than this in an initial guess.
5090 * - the size does not exceed that of a maximized window
5091 * We want to see the whole window after all.
5092 * (Note that this may not be possible to achieve due to imperfect
5093 * information from the windowing system.)
5096 /* We use these for now to not make windows too big by accident. Note
5097 * that we still clamp these numbers by screen size. Also note that
5098 * minimum size still overrides this. So keep your windows small! :)
5100 #define MAX_DEFAULT_WINDOW_WIDTH 640
5101 #define MAX_DEFAULT_WINDOW_HEIGHT 480
5104 gtk_window_guess_default_size (GtkWindow *window,
5108 GtkWidget *widget = GTK_WIDGET (window);
5110 int minimum, natural;
5112 screen = gtk_widget_get_screen (widget);
5114 *width = gdk_screen_get_width (screen);
5115 *height = gdk_screen_get_height (screen);
5117 if (*width >= *height)
5120 *width = MIN (*width, MAX_DEFAULT_WINDOW_WIDTH);
5121 *height = MIN (*height, MAX_DEFAULT_WINDOW_HEIGHT);
5126 *width = MIN (*width, MAX_DEFAULT_WINDOW_HEIGHT);
5127 *height = MIN (*height, MAX_DEFAULT_WINDOW_WIDTH);
5130 if (gtk_widget_get_request_mode (widget) == GTK_SIZE_REQUEST_WIDTH_FOR_HEIGHT)
5132 gtk_widget_get_preferred_height (widget, &minimum, &natural);
5133 *height = MAX (minimum, MIN (*height, natural));
5135 gtk_widget_get_preferred_width_for_height (widget, *height, &minimum, &natural);
5136 *width = MAX (minimum, MIN (*width, natural));
5138 else /* GTK_SIZE_REQUEST_HEIGHT_FOR_WIDTH or CONSTANT_SIZE */
5140 gtk_widget_get_preferred_width (widget, &minimum, &natural);
5141 *width = MAX (minimum, MIN (*width, natural));
5143 gtk_widget_get_preferred_height_for_width (widget, *width, &minimum, &natural);
5144 *height = MAX (minimum, MIN (*height, natural));
5149 gtk_window_realize (GtkWidget *widget)
5151 GtkAllocation allocation;
5153 GdkWindow *parent_window;
5154 GdkWindow *gdk_window;
5155 GdkWindowAttr attributes;
5156 gint attributes_mask;
5157 GtkWindowPrivate *priv;
5158 GtkStyleContext *context;
5160 window = GTK_WINDOW (widget);
5161 priv = window->priv;
5163 gtk_widget_get_allocation (widget, &allocation);
5165 if (gtk_widget_get_parent_window (widget))
5167 gtk_container_set_resize_mode (GTK_CONTAINER (widget), GTK_RESIZE_PARENT);
5169 gtk_widget_set_realized (widget, TRUE);
5171 attributes.x = allocation.x;
5172 attributes.y = allocation.y;
5173 attributes.width = allocation.width;
5174 attributes.height = allocation.height;
5175 attributes.window_type = GDK_WINDOW_CHILD;
5177 attributes.event_mask = gtk_widget_get_events (widget) | GDK_EXPOSURE_MASK | GDK_STRUCTURE_MASK;
5179 attributes.visual = gtk_widget_get_visual (widget);
5180 attributes.wclass = GDK_INPUT_OUTPUT;
5182 attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL;
5184 gdk_window = gdk_window_new (gtk_widget_get_parent_window (widget),
5185 &attributes, attributes_mask);
5186 gtk_widget_set_window (widget, gdk_window);
5187 gdk_window_set_user_data (gdk_window, widget);
5189 gtk_style_context_set_background (gtk_widget_get_style_context (widget), gdk_window);
5191 gdk_window_enable_synchronized_configure (gdk_window);
5195 gtk_container_set_resize_mode (GTK_CONTAINER (window), GTK_RESIZE_QUEUE);
5197 /* ensure widget tree is properly size allocated */
5198 if (allocation.x == -1 &&
5199 allocation.y == -1 &&
5200 allocation.width == 1 &&
5201 allocation.height == 1)
5207 gtk_window_guess_default_size (window, &allocation.width, &allocation.height);
5208 if (allocation.width == 0 || allocation.height == 0)
5210 /* non-empty window */
5211 allocation.width = 200;
5212 allocation.height = 200;
5214 gtk_widget_size_allocate (widget, &allocation);
5216 _gtk_container_queue_resize (GTK_CONTAINER (widget));
5218 g_return_if_fail (!gtk_widget_get_realized (widget));
5221 gtk_widget_set_realized (widget, TRUE);
5225 case GTK_WINDOW_TOPLEVEL:
5226 attributes.window_type = GDK_WINDOW_TOPLEVEL;
5228 case GTK_WINDOW_POPUP:
5229 attributes.window_type = GDK_WINDOW_TEMP;
5232 g_warning (G_STRLOC": Unknown window type %d!", priv->type);
5236 attributes.title = priv->title;
5237 attributes.wmclass_name = priv->wmclass_name;
5238 attributes.wmclass_class = priv->wmclass_class;
5239 attributes.wclass = GDK_INPUT_OUTPUT;
5240 attributes.visual = gtk_widget_get_visual (widget);
5242 attributes_mask = 0;
5243 parent_window = gtk_widget_get_root_window (widget);
5245 gtk_widget_get_allocation (widget, &allocation);
5246 attributes.width = allocation.width;
5247 attributes.height = allocation.height;
5248 attributes.event_mask = gtk_widget_get_events (widget);
5249 attributes.event_mask |= (GDK_EXPOSURE_MASK |
5250 GDK_KEY_PRESS_MASK |
5251 GDK_KEY_RELEASE_MASK |
5252 GDK_ENTER_NOTIFY_MASK |
5253 GDK_LEAVE_NOTIFY_MASK |
5254 GDK_FOCUS_CHANGE_MASK |
5255 GDK_STRUCTURE_MASK);
5256 attributes.type_hint = priv->type_hint;
5258 attributes_mask |= GDK_WA_VISUAL | GDK_WA_TYPE_HINT;
5259 attributes_mask |= (priv->title ? GDK_WA_TITLE : 0);
5260 attributes_mask |= (priv->wmclass_name ? GDK_WA_WMCLASS : 0);
5262 gdk_window = gdk_window_new (parent_window, &attributes, attributes_mask);
5263 gtk_widget_set_window (widget, gdk_window);
5265 if (priv->opacity_set)
5266 gdk_window_set_opacity (gdk_window, priv->opacity);
5268 gdk_window_enable_synchronized_configure (gdk_window);
5270 gdk_window_set_user_data (gdk_window, window);
5272 context = gtk_widget_get_style_context (widget);
5273 gtk_style_context_set_background (context, gdk_window);
5276 if (priv->transient_parent &&
5277 gtk_widget_get_realized (GTK_WIDGET (priv->transient_parent)))
5278 gdk_window_set_transient_for (gdk_window,
5279 gtk_widget_get_window (GTK_WIDGET (priv->transient_parent)));
5282 gdk_window_set_role (gdk_window, priv->wm_role);
5284 if (!priv->decorated)
5285 gdk_window_set_decorations (gdk_window, 0);
5287 if (!priv->deletable)
5288 gdk_window_set_functions (gdk_window, GDK_FUNC_ALL | GDK_FUNC_CLOSE);
5290 if (gtk_window_get_skip_pager_hint (window))
5291 gdk_window_set_skip_pager_hint (gdk_window, TRUE);
5293 if (gtk_window_get_skip_taskbar_hint (window))
5294 gdk_window_set_skip_taskbar_hint (gdk_window, TRUE);
5296 if (gtk_window_get_accept_focus (window))
5297 gdk_window_set_accept_focus (gdk_window, TRUE);
5299 gdk_window_set_accept_focus (gdk_window, FALSE);
5301 if (gtk_window_get_focus_on_map (window))
5302 gdk_window_set_focus_on_map (gdk_window, TRUE);
5304 gdk_window_set_focus_on_map (gdk_window, FALSE);
5307 gdk_window_set_modal_hint (gdk_window, TRUE);
5309 gdk_window_set_modal_hint (gdk_window, FALSE);
5311 if (priv->startup_id)
5313 #ifdef GDK_WINDOWING_X11
5314 if (GDK_IS_X11_WINDOW (gdk_window))
5316 guint32 timestamp = extract_time_from_startup_id (priv->startup_id);
5317 if (timestamp != GDK_CURRENT_TIME)
5318 gdk_x11_window_set_user_time (gdk_window, timestamp);
5321 if (!startup_id_is_fake (priv->startup_id))
5322 gdk_window_set_startup_id (gdk_window, priv->startup_id);
5325 #ifdef GDK_WINDOWING_X11
5326 if (priv->initial_timestamp != GDK_CURRENT_TIME)
5328 if (GDK_IS_X11_WINDOW (gdk_window))
5329 gdk_x11_window_set_user_time (gdk_window, priv->initial_timestamp);
5334 gtk_window_realize_icon (window);
5336 if (priv->has_resize_grip)
5337 resize_grip_create_window (window);
5341 gtk_window_unrealize (GtkWidget *widget)
5343 GtkWindow *window = GTK_WINDOW (widget);
5344 GtkWindowPrivate *priv = window->priv;
5345 GtkWindowGeometryInfo *info;
5347 /* On unrealize, we reset the size of the window such
5348 * that we will re-apply the default sizing stuff
5349 * next time we show the window.
5351 * Default positioning is reset on unmap, instead of unrealize.
5353 priv->need_default_size = TRUE;
5354 info = gtk_window_get_geometry_info (window, FALSE);
5357 info->resize_width = -1;
5358 info->resize_height = -1;
5359 info->last.configure_request.x = 0;
5360 info->last.configure_request.y = 0;
5361 info->last.configure_request.width = -1;
5362 info->last.configure_request.height = -1;
5363 /* be sure we reset geom hints on re-realize */
5364 info->last.flags = 0;
5368 gtk_window_unrealize_icon (window);
5370 if (priv->grip_window != NULL)
5371 resize_grip_destroy_window (window);
5373 GTK_WIDGET_CLASS (gtk_window_parent_class)->unrealize (widget);
5376 static GtkJunctionSides
5377 get_grip_junction (GtkWidget *widget)
5379 if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_LTR)
5380 return GTK_JUNCTION_CORNER_BOTTOMRIGHT;
5382 return GTK_JUNCTION_CORNER_BOTTOMLEFT;
5386 get_drag_edge (GtkWidget *widget,
5387 GdkWindowEdge *edge)
5389 GtkWindowPrivate *priv = GTK_WINDOW (widget)->priv;
5390 gboolean hresizable;
5391 gboolean vresizable;
5392 GtkTextDirection dir;
5393 GtkWindowGeometryInfo *info;
5398 info = priv->geometry_info;
5401 GdkWindowHints flags = info->last.flags;
5402 GdkGeometry *geometry = &info->last.geometry;
5404 if ((flags & GDK_HINT_MIN_SIZE) && (flags & GDK_HINT_MAX_SIZE))
5406 hresizable = geometry->min_width < geometry->max_width;
5407 vresizable = geometry->min_height < geometry->max_height;
5411 dir = gtk_widget_get_direction (widget);
5413 if (hresizable && vresizable)
5414 *edge = dir == GTK_TEXT_DIR_LTR ? GDK_WINDOW_EDGE_SOUTH_EAST : GDK_WINDOW_EDGE_SOUTH_WEST;
5415 else if (hresizable)
5416 *edge = dir == GTK_TEXT_DIR_LTR ? GDK_WINDOW_EDGE_EAST : GDK_WINDOW_EDGE_WEST;
5417 else if (vresizable)
5418 *edge = GDK_WINDOW_EDGE_SOUTH;
5426 set_grip_cursor (GtkWindow *window)
5428 GtkWidget *widget = GTK_WIDGET (window);
5429 GtkWindowPrivate *priv = window->priv;
5431 if (priv->grip_window == NULL)
5434 if (gtk_widget_is_sensitive (widget))
5437 GdkDisplay *display;
5438 GdkCursorType cursor_type;
5441 cursor_type = GDK_LEFT_PTR;
5443 if (get_drag_edge (widget, &edge))
5447 case GDK_WINDOW_EDGE_EAST:
5448 cursor_type = GDK_RIGHT_SIDE;
5450 case GDK_WINDOW_EDGE_SOUTH_EAST:
5451 cursor_type = GDK_BOTTOM_RIGHT_CORNER;
5453 case GDK_WINDOW_EDGE_SOUTH:
5454 cursor_type = GDK_BOTTOM_SIDE;
5456 case GDK_WINDOW_EDGE_SOUTH_WEST:
5457 cursor_type = GDK_BOTTOM_LEFT_CORNER;
5459 case GDK_WINDOW_EDGE_WEST:
5460 cursor_type = GDK_LEFT_SIDE;
5466 display = gtk_widget_get_display (widget);
5467 cursor = gdk_cursor_new_for_display (display, cursor_type);
5468 gdk_window_set_cursor (priv->grip_window, cursor);
5469 g_object_unref (cursor);
5472 gdk_window_set_cursor (priv->grip_window, NULL);
5476 set_grip_shape (GtkWindow *window)
5478 GtkWindowPrivate *priv = window->priv;
5479 cairo_region_t *region;
5480 cairo_surface_t *surface;
5482 double width, height;
5484 if (priv->grip_window == NULL)
5487 width = gdk_window_get_width (priv->grip_window);
5488 height = gdk_window_get_height (priv->grip_window);
5489 surface = cairo_image_surface_create (CAIRO_FORMAT_A1, width, height);
5491 cr = cairo_create (surface);
5492 cairo_set_source_rgba (cr, 0.0, 0.0, 0.0, 0.0);
5494 cairo_set_source_rgba (cr, 0.0, 0.0, 0.0, 1.0);
5495 if (get_grip_junction (GTK_WIDGET (window)) & GTK_JUNCTION_CORNER_BOTTOMRIGHT)
5497 cairo_move_to (cr, width, 0.0);
5498 cairo_line_to (cr, width, height);
5499 cairo_line_to (cr, 0.0, height);
5503 cairo_move_to (cr, 0.0, 0.0);
5504 cairo_line_to (cr, width, height);
5505 cairo_line_to (cr, 0.0, height);
5507 cairo_close_path (cr);
5510 region = gdk_cairo_region_create_from_surface (surface);
5511 cairo_surface_destroy (surface);
5513 gdk_window_shape_combine_region (priv->grip_window, region, 0, 0);
5514 cairo_region_destroy (region);
5518 set_grip_position (GtkWindow *window)
5520 GtkWindowPrivate *priv = window->priv;
5523 if (priv->grip_window == NULL)
5526 gtk_window_get_resize_grip_area (window, &rect);
5527 gdk_window_raise (priv->grip_window);
5528 gdk_window_move_resize (priv->grip_window,
5530 rect.width, rect.height);
5533 /* _gtk_window_set_allocation:
5534 * @window: a #GtkWindow
5535 * @allocation: the new allocation
5537 * This function is like gtk_widget_set_allocation()
5538 * but does the necessary extra work to update
5539 * the resize grip positioning, etc.
5541 * Call this instead of gtk_widget_set_allocation()
5542 * when overriding ::size_allocate in a GtkWindow
5543 * subclass without chaining up.
5546 _gtk_window_set_allocation (GtkWindow *window,
5547 GtkAllocation *allocation)
5549 GtkWidget *widget = (GtkWidget *)window;
5551 gtk_widget_set_allocation (widget, allocation);
5553 if (gtk_widget_get_realized (widget))
5555 /* If it's not a toplevel we're embedded, we need to resize
5556 * the window's window and skip the grip.
5558 if (!gtk_widget_is_toplevel (widget))
5560 gdk_window_move_resize (gtk_widget_get_window (widget),
5561 allocation->x, allocation->y,
5562 allocation->width, allocation->height);
5566 update_grip_visibility (window);
5567 set_grip_position (window);
5573 gtk_window_size_allocate (GtkWidget *widget,
5574 GtkAllocation *allocation)
5576 GtkWindow *window = GTK_WINDOW (widget);
5577 GtkAllocation child_allocation;
5581 _gtk_window_set_allocation (window, allocation);
5583 child = gtk_bin_get_child (&(window->bin));
5584 if (child && gtk_widget_get_visible (child))
5586 border_width = gtk_container_get_border_width (GTK_CONTAINER (window));
5587 child_allocation.x = border_width;
5588 child_allocation.y = border_width;
5589 child_allocation.width = MAX (1, allocation->width - border_width * 2);
5590 child_allocation.height = MAX (1, allocation->height - border_width * 2);
5592 gtk_widget_size_allocate (child, &child_allocation);
5597 gtk_window_configure_event (GtkWidget *widget,
5598 GdkEventConfigure *event)
5600 GtkAllocation allocation;
5601 GtkWindow *window = GTK_WINDOW (widget);
5602 GtkWindowPrivate *priv = window->priv;
5603 gboolean expected_reply = priv->configure_request_count > 0;
5605 if (!gtk_widget_is_toplevel (GTK_WIDGET (widget)))
5607 if (GTK_WIDGET_CLASS (gtk_window_parent_class)->configure_event)
5608 return GTK_WIDGET_CLASS (gtk_window_parent_class)->configure_event (widget, event);
5610 gdk_window_configure_finished (gtk_widget_get_window (widget));
5614 /* priv->configure_request_count incremented for each
5615 * configure request, and decremented to a min of 0 for
5616 * each configure notify.
5618 * All it means is that we know we will get at least
5619 * priv->configure_request_count more configure notifies.
5620 * We could get more configure notifies than that; some
5621 * of the configure notifies we get may be unrelated to
5622 * the configure requests. But we will get at least
5623 * priv->configure_request_count notifies.
5626 if (priv->configure_request_count > 0)
5628 priv->configure_request_count -= 1;
5629 gdk_window_thaw_toplevel_updates_libgtk_only (gtk_widget_get_window (widget));
5632 /* As an optimization, we avoid a resize when possible.
5634 * The only times we can avoid a resize are:
5635 * - we know only the position changed, not the size
5636 * - we know we have made more requests and so will get more
5637 * notifies and can wait to resize when we get them
5639 gtk_widget_get_allocation (widget, &allocation);
5640 if (!expected_reply &&
5641 (allocation.width == event->width &&
5642 allocation.height == event->height))
5644 gdk_window_configure_finished (gtk_widget_get_window (widget));
5649 * If we do need to resize, we do that by:
5650 * - filling in widget->allocation with the new size
5651 * - setting configure_notify_received to TRUE
5652 * for use in gtk_window_move_resize()
5653 * - queueing a resize, leading to invocation of
5654 * gtk_window_move_resize() in an idle handler
5658 priv->configure_notify_received = TRUE;
5660 allocation.width = event->width;
5661 allocation.height = event->height;
5662 gtk_widget_set_allocation (widget, &allocation);
5664 gdk_window_invalidate_rect (gtk_widget_get_window (widget), NULL, FALSE); // XXX - What was this for again?
5666 _gtk_container_queue_resize (GTK_CONTAINER (widget));
5672 gtk_window_state_event (GtkWidget *widget,
5673 GdkEventWindowState *event)
5675 update_grip_visibility (GTK_WINDOW (widget));
5677 if (event->changed_mask & GDK_WINDOW_STATE_FOCUSED)
5678 ensure_state_flag_backdrop (widget);
5684 gtk_window_direction_changed (GtkWidget *widget,
5685 GtkTextDirection prev_dir)
5687 GtkWindow *window = GTK_WINDOW (widget);
5689 set_grip_cursor (window);
5690 set_grip_position (window);
5691 set_grip_shape (window);
5695 gtk_window_state_changed (GtkWidget *widget,
5696 GtkStateType previous_state)
5698 GtkWindow *window = GTK_WINDOW (widget);
5700 update_grip_visibility (window);
5704 gtk_window_style_updated (GtkWidget *widget)
5706 GtkWindow *window = GTK_WINDOW (widget);
5707 GtkWindowPrivate *priv = window->priv;
5710 GTK_WIDGET_CLASS (gtk_window_parent_class)->style_updated (widget);
5712 if (priv->grip_window != NULL && gtk_window_get_resize_grip_area (window, &rect))
5714 gdk_window_move_resize (priv->grip_window,
5716 rect.width, rect.height);
5718 set_grip_shape (window);
5719 gtk_widget_queue_resize (widget);
5724 resize_grip_create_window (GtkWindow *window)
5727 GtkWindowPrivate *priv;
5728 GdkWindowAttr attributes;
5729 gint attributes_mask;
5731 GdkRGBA transparent = {0, 0, 0, 0};
5733 priv = window->priv;
5734 widget = GTK_WIDGET (window);
5736 g_return_if_fail (gtk_widget_get_realized (widget));
5737 g_return_if_fail (priv->grip_window == NULL);
5739 gtk_window_get_resize_grip_area (window, &rect);
5741 attributes.x = rect.x;
5742 attributes.y = rect.y;
5743 attributes.width = rect.width;
5744 attributes.height = rect.height;
5745 attributes.window_type = GDK_WINDOW_CHILD;
5746 attributes.wclass = GDK_INPUT_OUTPUT;
5747 attributes.event_mask = gtk_widget_get_events (widget) |
5749 GDK_BUTTON_PRESS_MASK;
5751 attributes_mask = GDK_WA_X | GDK_WA_Y;
5753 priv->grip_window = gdk_window_new (gtk_widget_get_window (widget),
5756 gdk_window_set_background_rgba (priv->grip_window, &transparent);
5758 gdk_window_set_user_data (priv->grip_window, widget);
5760 gdk_window_raise (priv->grip_window);
5762 set_grip_shape (window);
5763 update_grip_visibility (window);
5767 resize_grip_destroy_window (GtkWindow *window)
5769 GtkWindowPrivate *priv = window->priv;
5771 gdk_window_set_user_data (priv->grip_window, NULL);
5772 gdk_window_destroy (priv->grip_window);
5773 priv->grip_window = NULL;
5774 update_grip_visibility (window);
5778 * gtk_window_set_has_resize_grip:
5779 * @window: a #GtkWindow
5780 * @value: %TRUE to allow a resize grip
5782 * Sets whether @window has a corner resize grip.
5784 * Note that the resize grip is only shown if the window
5785 * is actually resizable and not maximized. Use
5786 * gtk_window_resize_grip_is_visible() to find out if the
5787 * resize grip is currently shown.
5792 gtk_window_set_has_resize_grip (GtkWindow *window,
5795 GtkWidget *widget = GTK_WIDGET (window);
5796 GtkWindowPrivate *priv = window->priv;
5798 value = value != FALSE;
5800 if (value != priv->has_resize_grip)
5802 priv->has_resize_grip = value;
5803 gtk_widget_queue_draw (widget);
5805 if (gtk_widget_get_realized (widget) &&
5806 gtk_widget_is_toplevel (GTK_WIDGET (widget)))
5808 if (priv->has_resize_grip && priv->grip_window == NULL)
5809 resize_grip_create_window (window);
5810 else if (!priv->has_resize_grip && priv->grip_window != NULL)
5811 resize_grip_destroy_window (window);
5814 g_object_notify (G_OBJECT (window), "has-resize-grip");
5819 update_grip_visibility (GtkWindow *window)
5821 GtkWindowPrivate *priv = window->priv;
5824 val = gtk_window_resize_grip_is_visible (window);
5826 if (priv->grip_window != NULL)
5830 gdk_window_show (priv->grip_window);
5831 set_grip_cursor (window);
5835 gdk_window_hide (priv->grip_window);
5839 if (priv->resize_grip_visible != val)
5841 priv->resize_grip_visible = val;
5843 g_object_notify (G_OBJECT (window), "resize-grip-visible");
5848 * gtk_window_resize_grip_is_visible:
5849 * @window: a #GtkWindow
5851 * Determines whether a resize grip is visible for the specified window.
5853 * Returns: %TRUE if a resize grip exists and is visible
5858 gtk_window_resize_grip_is_visible (GtkWindow *window)
5861 GtkWindowPrivate *priv;
5864 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
5866 priv = window->priv;
5867 widget = GTK_WIDGET (window);
5869 if (priv->type == GTK_WINDOW_POPUP)
5872 if (!priv->resizable)
5875 if (!gtk_widget_is_toplevel (GTK_WIDGET (widget)))
5878 if (gtk_widget_get_realized (widget))
5880 GdkWindowState state;
5882 state = gdk_window_get_state (gtk_widget_get_window (widget));
5884 if (state & GDK_WINDOW_STATE_MAXIMIZED || state & GDK_WINDOW_STATE_FULLSCREEN)
5888 if (!get_drag_edge (widget, &edge))
5891 return window->priv->has_resize_grip;
5895 * gtk_window_get_has_resize_grip:
5896 * @window: a #GtkWindow
5898 * Determines whether the window may have a resize grip.
5900 * Returns: %TRUE if the window has a resize grip
5905 gtk_window_get_has_resize_grip (GtkWindow *window)
5907 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
5909 return window->priv->has_resize_grip;
5913 * gtk_window_get_resize_grip_area:
5914 * @window: a #GtkWindow
5915 * @rect: (out): a pointer to a #GdkRectangle which we should store
5916 * the resize grip area
5918 * If a window has a resize grip, this will retrieve the grip
5919 * position, width and height into the specified #GdkRectangle.
5921 * Returns: %TRUE if the resize grip's area was retrieved
5926 gtk_window_get_resize_grip_area (GtkWindow *window,
5929 GtkWidget *widget = GTK_WIDGET (window);
5930 GtkAllocation allocation;
5934 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
5936 if (!window->priv->has_resize_grip)
5939 gtk_widget_get_allocation (widget, &allocation);
5941 gtk_widget_style_get (widget,
5942 "resize-grip-width", &grip_width,
5943 "resize-grip-height", &grip_height,
5946 if (grip_width > allocation.width)
5947 grip_width = allocation.width;
5949 if (grip_height > allocation.height)
5950 grip_height = allocation.height;
5952 rect->width = grip_width;
5953 rect->height = grip_height;
5954 rect->y = allocation.y + allocation.height - grip_height;
5956 if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_LTR)
5957 rect->x = allocation.x + allocation.width - grip_width;
5959 rect->x = allocation.x;
5964 /* the accel_key and accel_mods fields of the key have to be setup
5965 * upon calling this function. it'll then return whether that key
5966 * is at all used as accelerator, and if so will OR in the
5967 * accel_flags member of the key.
5970 _gtk_window_query_nonaccels (GtkWindow *window,
5972 GdkModifierType accel_mods)
5974 GtkWindowPrivate *priv;
5976 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
5978 priv = window->priv;
5980 /* movement keys are considered locked accels */
5983 static const guint bindings[] = {
5984 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,
5985 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,
5989 for (i = 0; i < G_N_ELEMENTS (bindings); i++)
5990 if (bindings[i] == accel_key)
5994 /* mnemonics are considered locked accels */
5995 if (accel_mods == priv->mnemonic_modifier)
5997 GtkMnemonicHash *mnemonic_hash = gtk_window_get_mnemonic_hash (window, FALSE);
5998 if (mnemonic_hash && _gtk_mnemonic_hash_lookup (mnemonic_hash, accel_key))
6006 * gtk_window_propagate_key_event:
6007 * @window: a #GtkWindow
6008 * @event: a #GdkEventKey
6010 * Propagate a key press or release event to the focus widget and
6011 * up the focus container chain until a widget handles @event.
6012 * This is normally called by the default ::key_press_event and
6013 * ::key_release_event handlers for toplevel windows,
6014 * however in some cases it may be useful to call this directly when
6015 * overriding the standard key handling for a toplevel window.
6017 * Return value: %TRUE if a widget in the focus chain handled the event.
6022 gtk_window_propagate_key_event (GtkWindow *window,
6025 GtkWindowPrivate *priv;
6026 gboolean handled = FALSE;
6027 GtkWidget *widget, *focus;
6029 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
6031 priv = window->priv;
6032 widget = GTK_WIDGET (window);
6034 focus = priv->focus_widget;
6036 g_object_ref (focus);
6039 focus && focus != widget &&
6040 gtk_widget_get_toplevel (focus) == widget)
6044 if (gtk_widget_is_sensitive (focus))
6045 handled = gtk_widget_event (focus, (GdkEvent*) event);
6047 parent = gtk_widget_get_parent (focus);
6049 g_object_ref (parent);
6051 g_object_unref (focus);
6057 g_object_unref (focus);
6063 gtk_window_key_press_event (GtkWidget *widget,
6066 GtkWindow *window = GTK_WINDOW (widget);
6067 gboolean handled = FALSE;
6069 /* handle mnemonics and accelerators */
6071 handled = gtk_window_activate_key (window, event);
6073 /* handle focus widget key events */
6075 handled = gtk_window_propagate_key_event (window, event);
6077 /* Chain up, invokes binding set */
6079 handled = GTK_WIDGET_CLASS (gtk_window_parent_class)->key_press_event (widget, event);
6085 gtk_window_key_release_event (GtkWidget *widget,
6088 GtkWindow *window = GTK_WINDOW (widget);
6089 gboolean handled = FALSE;
6091 /* handle focus widget key events */
6093 handled = gtk_window_propagate_key_event (window, event);
6095 /* Chain up, invokes binding set */
6097 handled = GTK_WIDGET_CLASS (gtk_window_parent_class)->key_release_event (widget, event);
6103 gtk_window_button_press_event (GtkWidget *widget,
6104 GdkEventButton *event)
6106 GtkWindowPrivate *priv = GTK_WINDOW (widget)->priv;
6109 if (event->window == priv->grip_window)
6111 if (get_drag_edge (widget, &edge))
6112 gdk_window_begin_resize_drag_for_device (gtk_widget_get_window (widget),
6114 gdk_event_get_device ((GdkEvent *) event),
6127 gtk_window_real_activate_default (GtkWindow *window)
6129 gtk_window_activate_default (window);
6133 gtk_window_real_activate_focus (GtkWindow *window)
6135 gtk_window_activate_focus (window);
6139 gtk_window_enter_notify_event (GtkWidget *widget,
6140 GdkEventCrossing *event)
6146 gtk_window_leave_notify_event (GtkWidget *widget,
6147 GdkEventCrossing *event)
6153 do_focus_change (GtkWidget *widget,
6157 GdkDeviceManager *device_manager;
6160 g_object_ref (widget);
6162 device_manager = gdk_display_get_device_manager (gtk_widget_get_display (widget));
6163 devices = gdk_device_manager_list_devices (device_manager, GDK_DEVICE_TYPE_MASTER);
6164 devices = g_list_concat (devices, gdk_device_manager_list_devices (device_manager, GDK_DEVICE_TYPE_SLAVE));
6165 devices = g_list_concat (devices, gdk_device_manager_list_devices (device_manager, GDK_DEVICE_TYPE_FLOATING));
6167 for (d = devices; d; d = d->next)
6169 GdkDevice *dev = d->data;
6172 if (gdk_device_get_source (dev) != GDK_SOURCE_KEYBOARD)
6175 /* Skip non-master keyboards that haven't
6176 * selected for events from this window
6178 window = gtk_widget_get_window (widget);
6179 if (gdk_device_get_device_type (dev) != GDK_DEVICE_TYPE_MASTER &&
6180 window && !gdk_window_get_device_events (window, dev))
6183 fevent = gdk_event_new (GDK_FOCUS_CHANGE);
6185 fevent->focus_change.type = GDK_FOCUS_CHANGE;
6186 fevent->focus_change.window = window;
6188 g_object_ref (window);
6189 fevent->focus_change.in = in;
6190 gdk_event_set_device (fevent, dev);
6192 gtk_widget_send_focus_change (widget, fevent);
6194 gdk_event_free (fevent);
6197 g_list_free (devices);
6198 g_object_unref (widget);
6202 maybe_set_mnemonics_visible (GtkWindow *window)
6205 GdkDeviceManager *device_manager;
6207 device_manager = gdk_display_get_device_manager (gtk_widget_get_display (GTK_WIDGET (window)));
6208 devices = gdk_device_manager_list_devices (device_manager, GDK_DEVICE_TYPE_MASTER);
6210 for (d = devices; d; d = d->next)
6212 GdkDevice *dev = d->data;
6214 if (gdk_device_get_source (dev) == GDK_SOURCE_MOUSE)
6216 GdkModifierType mask;
6218 gdk_device_get_state (dev, gtk_widget_get_window (GTK_WIDGET (window)),
6220 if (window->priv->mnemonic_modifier == (mask & gtk_accelerator_get_default_mod_mask ()))
6222 gtk_window_set_mnemonics_visible (window, TRUE);
6228 g_list_free (devices);
6232 gtk_window_focus_in_event (GtkWidget *widget,
6233 GdkEventFocus *event)
6235 GtkWindow *window = GTK_WINDOW (widget);
6236 gboolean auto_mnemonics;
6238 /* It appears spurious focus in events can occur when
6239 * the window is hidden. So we'll just check to see if
6240 * the window is visible before actually handling the
6243 if (gtk_widget_get_visible (widget))
6245 _gtk_window_set_has_toplevel_focus (window, TRUE);
6246 _gtk_window_set_is_active (window, TRUE);
6248 g_object_get (gtk_widget_get_settings (widget),
6249 "gtk-auto-mnemonics", &auto_mnemonics, NULL);
6251 maybe_set_mnemonics_visible (window);
6258 gtk_window_focus_out_event (GtkWidget *widget,
6259 GdkEventFocus *event)
6261 GtkWindow *window = GTK_WINDOW (widget);
6262 gboolean auto_mnemonics;
6264 _gtk_window_set_has_toplevel_focus (window, FALSE);
6265 _gtk_window_set_is_active (window, FALSE);
6267 /* set the mnemonic-visible property to false */
6268 g_object_get (gtk_widget_get_settings (widget),
6269 "gtk-auto-mnemonics", &auto_mnemonics, NULL);
6271 gtk_window_set_mnemonics_visible (window, FALSE);
6277 gtk_window_check_resize (GtkContainer *container)
6279 /* If the window is not toplevel anymore than it's embedded somewhere,
6280 * so handle it like a normal window */
6281 if (!gtk_widget_is_toplevel (GTK_WIDGET (container)))
6282 GTK_CONTAINER_CLASS (gtk_window_parent_class)->check_resize (container);
6283 else if (gtk_widget_get_visible (GTK_WIDGET (container)))
6284 gtk_window_move_resize (GTK_WINDOW (container));
6288 gtk_window_focus (GtkWidget *widget,
6289 GtkDirectionType direction)
6291 GtkWindowPrivate *priv;
6294 GtkContainer *container;
6296 GtkWidget *old_focus_child;
6299 if (!gtk_widget_is_toplevel (GTK_WIDGET (widget)))
6300 return GTK_WIDGET_CLASS (gtk_window_parent_class)->focus (widget, direction);
6302 container = GTK_CONTAINER (widget);
6303 window = GTK_WINDOW (widget);
6304 priv = window->priv;
6305 bin = GTK_BIN (widget);
6307 old_focus_child = gtk_container_get_focus_child (container);
6309 /* We need a special implementation here to deal properly with wrapping
6310 * around in the tab chain without the danger of going into an
6313 if (old_focus_child)
6315 if (gtk_widget_child_focus (old_focus_child, direction))
6319 if (priv->focus_widget)
6321 if (direction == GTK_DIR_LEFT ||
6322 direction == GTK_DIR_RIGHT ||
6323 direction == GTK_DIR_UP ||
6324 direction == GTK_DIR_DOWN)
6329 /* Wrapped off the end, clear the focus setting for the toplpevel */
6330 parent = gtk_widget_get_parent (priv->focus_widget);
6333 gtk_container_set_focus_child (GTK_CONTAINER (parent), NULL);
6334 parent = gtk_widget_get_parent (parent);
6337 gtk_window_set_focus (GTK_WINDOW (container), NULL);
6340 /* Now try to focus the first widget in the window */
6341 child = gtk_bin_get_child (bin);
6344 if (gtk_widget_child_focus (child, direction))
6352 gtk_window_move_focus (GtkWidget *widget,
6353 GtkDirectionType dir)
6355 if (!gtk_widget_is_toplevel (GTK_WIDGET (widget)))
6357 GTK_WIDGET_CLASS (gtk_window_parent_class)->move_focus (widget, dir);
6361 gtk_widget_child_focus (widget, dir);
6363 if (! gtk_container_get_focus_child (GTK_CONTAINER (widget)))
6364 gtk_window_set_focus (GTK_WINDOW (widget), NULL);
6368 gtk_window_real_set_focus (GtkWindow *window,
6371 GtkWindowPrivate *priv = window->priv;
6372 GtkWidget *old_focus = priv->focus_widget;
6373 gboolean had_default = FALSE;
6374 gboolean focus_had_default = FALSE;
6375 gboolean old_focus_had_default = FALSE;
6379 g_object_ref (old_focus);
6380 g_object_freeze_notify (G_OBJECT (old_focus));
6381 old_focus_had_default = gtk_widget_has_default (old_focus);
6385 g_object_ref (focus);
6386 g_object_freeze_notify (G_OBJECT (focus));
6387 focus_had_default = gtk_widget_has_default (focus);
6390 if (priv->default_widget)
6391 had_default = gtk_widget_has_default (priv->default_widget);
6393 if (priv->focus_widget)
6395 if (gtk_widget_get_receives_default (priv->focus_widget) &&
6396 (priv->focus_widget != priv->default_widget))
6398 _gtk_widget_set_has_default (priv->focus_widget, FALSE);
6399 gtk_widget_queue_draw (priv->focus_widget);
6401 if (priv->default_widget)
6402 _gtk_widget_set_has_default (priv->default_widget, TRUE);
6405 priv->focus_widget = NULL;
6407 if (priv->has_focus)
6408 do_focus_change (old_focus, FALSE);
6410 g_object_notify (G_OBJECT (old_focus), "is-focus");
6413 /* The above notifications may have set a new focus widget,
6414 * if so, we don't want to override it.
6416 if (focus && !priv->focus_widget)
6418 priv->focus_widget = focus;
6420 if (gtk_widget_get_receives_default (priv->focus_widget) &&
6421 (priv->focus_widget != priv->default_widget))
6423 if (gtk_widget_get_can_default (priv->focus_widget))
6424 _gtk_widget_set_has_default (priv->focus_widget, TRUE);
6426 if (priv->default_widget)
6427 _gtk_widget_set_has_default (priv->default_widget, FALSE);
6430 if (priv->has_focus)
6431 do_focus_change (priv->focus_widget, TRUE);
6433 g_object_notify (G_OBJECT (priv->focus_widget), "is-focus");
6436 /* If the default widget changed, a redraw will have been queued
6437 * on the old and new default widgets by gtk_window_set_default(), so
6438 * we only have to worry about the case where it didn't change.
6439 * We'll sometimes queue a draw twice on the new widget but that
6442 if (priv->default_widget &&
6443 (had_default != gtk_widget_has_default (priv->default_widget)))
6444 gtk_widget_queue_draw (priv->default_widget);
6448 if (old_focus_had_default != gtk_widget_has_default (old_focus))
6449 gtk_widget_queue_draw (old_focus);
6451 g_object_thaw_notify (G_OBJECT (old_focus));
6452 g_object_unref (old_focus);
6456 if (focus_had_default != gtk_widget_has_default (focus))
6457 gtk_widget_queue_draw (focus);
6459 g_object_thaw_notify (G_OBJECT (focus));
6460 g_object_unref (focus);
6466 gtk_window_get_preferred_width (GtkWidget *widget,
6474 window = GTK_WINDOW (widget);
6475 child = gtk_bin_get_child (GTK_BIN (window));
6477 border_width = gtk_container_get_border_width (GTK_CONTAINER (window));
6478 *minimum_size = border_width * 2;
6479 *natural_size = border_width * 2;
6481 if (child && gtk_widget_get_visible (child))
6483 gint child_min, child_nat;
6484 gtk_widget_get_preferred_width (child, &child_min, &child_nat);
6486 *minimum_size += child_min;
6487 *natural_size += child_nat;
6492 gtk_window_get_preferred_height (GtkWidget *widget,
6500 window = GTK_WINDOW (widget);
6501 child = gtk_bin_get_child (GTK_BIN (window));
6503 border_width = gtk_container_get_border_width (GTK_CONTAINER (window));
6504 *minimum_size = border_width * 2;
6505 *natural_size = border_width * 2;
6507 if (child && gtk_widget_get_visible (child))
6509 gint child_min, child_nat;
6510 gtk_widget_get_preferred_height (child, &child_min, &child_nat);
6512 *minimum_size += child_min;
6513 *natural_size += child_nat;
6519 * _gtk_window_unset_focus_and_default:
6520 * @window: a #GtkWindow
6521 * @widget: a widget inside of @window
6523 * Checks whether the focus and default widgets of @window are
6524 * @widget or a descendent of @widget, and if so, unset them.
6527 _gtk_window_unset_focus_and_default (GtkWindow *window,
6531 GtkWindowPrivate *priv = window->priv;
6535 g_object_ref (window);
6536 g_object_ref (widget);
6538 parent = gtk_widget_get_parent (widget);
6539 if (gtk_container_get_focus_child (GTK_CONTAINER (parent)) == widget)
6541 child = priv->focus_widget;
6543 while (child && child != widget)
6544 child = gtk_widget_get_parent (child);
6546 if (child == widget)
6547 gtk_window_set_focus (GTK_WINDOW (window), NULL);
6550 child = priv->default_widget;
6552 while (child && child != widget)
6553 child = gtk_widget_get_parent (child);
6555 if (child == widget)
6556 gtk_window_set_default (window, NULL);
6558 g_object_unref (widget);
6559 g_object_unref (window);
6562 /*********************************
6563 * Functions related to resizing *
6564 *********************************/
6567 geometry_size_to_pixels (GdkGeometry *geometry,
6572 gint base_width = 0;
6573 gint base_height = 0;
6575 gint min_height = 0;
6577 gint height_inc = 1;
6579 if (flags & GDK_HINT_BASE_SIZE)
6581 base_width = geometry->base_width;
6582 base_height = geometry->base_height;
6584 if (flags & GDK_HINT_MIN_SIZE)
6586 min_width = geometry->min_width;
6587 min_height = geometry->min_height;
6589 if (flags & GDK_HINT_RESIZE_INC)
6591 width_inc = geometry->width_inc;
6592 height_inc = geometry->height_inc;
6596 *width = MAX (*width * width_inc + base_width, min_width);
6598 *height = MAX (*height * height_inc + base_height, min_height);
6601 /* This function doesn't constrain to geometry hints */
6603 gtk_window_compute_configure_request_size (GtkWindow *window,
6604 GdkGeometry *geometry,
6609 GtkWindowPrivate *priv = window->priv;
6610 GtkWindowGeometryInfo *info;
6613 * - we've done a size request
6616 info = gtk_window_get_geometry_info (window, FALSE);
6618 if (priv->need_default_size)
6620 gtk_window_guess_default_size (window, width, height);
6622 /* If window is empty so requests 0, default to random nonzero size */
6623 if (*width == 0 && *height == 0)
6629 /* Override with default size */
6633 if (info->default_width > 0)
6634 *width = info->default_width;
6635 if (info->default_height > 0)
6636 *height = info->default_height;
6638 if (info->default_is_geometry)
6639 geometry_size_to_pixels (geometry, flags,
6640 info->default_width > 0 ? width : NULL,
6641 info->default_height > 0 ? height : NULL);
6646 GtkAllocation allocation;
6648 gtk_widget_get_allocation (GTK_WIDGET (window), &allocation);
6650 /* Default to keeping current size */
6651 *width = allocation.width;
6652 *height = allocation.height;
6655 /* Override any size with gtk_window_resize() values */
6658 if (info->resize_width > 0)
6659 *width = info->resize_width;
6660 if (info->resize_height > 0)
6661 *height = info->resize_height;
6663 if (info->resize_is_geometry)
6664 geometry_size_to_pixels (geometry, flags,
6665 info->resize_width > 0 ? width : NULL,
6666 info->resize_height > 0 ? height : NULL);
6669 /* Don't ever request zero width or height, its not supported by
6670 gdk. The size allocation code will round it to 1 anyway but if
6671 we do it then the value returned from this function will is
6672 not comparable to the size allocation read from the GtkWindow. */
6673 *width = MAX (*width, 1);
6674 *height = MAX (*height, 1);
6677 static GtkWindowPosition
6678 get_effective_position (GtkWindow *window)
6680 GtkWindowPrivate *priv = window->priv;
6681 GtkWindowPosition pos = priv->position;
6683 if (pos == GTK_WIN_POS_CENTER_ON_PARENT &&
6684 (priv->transient_parent == NULL ||
6685 !gtk_widget_get_mapped (GTK_WIDGET (priv->transient_parent))))
6686 pos = GTK_WIN_POS_NONE;
6692 get_center_monitor_of_window (GtkWindow *window)
6694 /* We could try to sort out the relative positions of the monitors and
6695 * stuff, or we could just be losers and assume you have a row
6696 * or column of monitors.
6698 return gdk_screen_get_n_monitors (gtk_window_check_screen (window)) / 2;
6702 get_monitor_containing_pointer (GtkWindow *window)
6706 GdkScreen *window_screen;
6707 GdkScreen *pointer_screen;
6708 GdkDisplay *display;
6709 GdkDeviceManager *device_manager;
6712 window_screen = gtk_window_check_screen (window);
6713 display = gdk_screen_get_display (window_screen);
6714 device_manager = gdk_display_get_device_manager (display);
6715 pointer = gdk_device_manager_get_client_pointer (device_manager);
6717 gdk_device_get_position (pointer,
6721 if (pointer_screen == window_screen)
6722 monitor_num = gdk_screen_get_monitor_at_point (pointer_screen, px, py);
6730 center_window_on_monitor (GtkWindow *window,
6736 GdkRectangle monitor;
6739 monitor_num = get_monitor_containing_pointer (window);
6741 if (monitor_num == -1)
6742 monitor_num = get_center_monitor_of_window (window);
6744 gdk_screen_get_monitor_workarea (gtk_window_check_screen (window),
6745 monitor_num, &monitor);
6747 *x = (monitor.width - w) / 2 + monitor.x;
6748 *y = (monitor.height - h) / 2 + monitor.y;
6750 /* Be sure we aren't off the monitor, ignoring _NET_WM_STRUT
6751 * and WM decorations.
6765 if (extent > clamp_extent)
6767 *base = clamp_base + clamp_extent/2 - extent/2;
6768 else if (*base < clamp_base)
6770 else if (*base + extent > clamp_base + clamp_extent)
6771 *base = clamp_base + clamp_extent - extent;
6775 clamp_window_to_rectangle (gint *x,
6779 const GdkRectangle *rect)
6781 #ifdef DEBUGGING_OUTPUT
6782 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);
6785 /* If it is too large, center it. If it fits on the monitor but is
6786 * partially outside, move it to the closest edge. Do this
6787 * separately in x and y directions.
6789 clamp (x, w, rect->x, rect->width);
6790 clamp (y, h, rect->y, rect->height);
6791 #ifdef DEBUGGING_OUTPUT
6792 g_print (" ==> %+d%+d: %dx%d\n", *x, *y, w, h);
6798 gtk_window_compute_configure_request (GtkWindow *window,
6799 GdkRectangle *request,
6800 GdkGeometry *geometry,
6803 GtkWindowPrivate *priv = window->priv;
6804 GdkGeometry new_geometry;
6807 GtkWindowPosition pos;
6808 GtkWidget *parent_widget;
6809 GtkWindowGeometryInfo *info;
6813 screen = gtk_window_check_screen (window);
6815 gtk_window_compute_hints (window, &new_geometry, &new_flags);
6816 gtk_window_compute_configure_request_size (window,
6817 &new_geometry, new_flags,
6820 gtk_window_constrain_size (window,
6821 &new_geometry, new_flags,
6825 parent_widget = (GtkWidget*) priv->transient_parent;
6827 pos = get_effective_position (window);
6828 info = gtk_window_get_geometry_info (window, FALSE);
6830 /* by default, don't change position requested */
6833 x = info->last.configure_request.x;
6834 y = info->last.configure_request.y;
6843 if (priv->need_default_position)
6846 /* FIXME this all interrelates with window gravity.
6847 * For most of them I think we want to set GRAVITY_CENTER.
6849 * Not sure how to go about that.
6853 /* here we are only handling CENTER_ALWAYS
6854 * as it relates to default positioning,
6855 * where it's equivalent to simply CENTER
6857 case GTK_WIN_POS_CENTER_ALWAYS:
6858 case GTK_WIN_POS_CENTER:
6859 center_window_on_monitor (window, w, h, &x, &y);
6862 case GTK_WIN_POS_CENTER_ON_PARENT:
6864 GtkAllocation allocation;
6865 GdkWindow *gdk_window;
6867 GdkRectangle monitor;
6870 g_assert (gtk_widget_get_mapped (parent_widget)); /* established earlier */
6872 gdk_window = gtk_widget_get_window (parent_widget);
6874 if (gdk_window != NULL)
6875 monitor_num = gdk_screen_get_monitor_at_window (screen,
6880 gdk_window_get_origin (gdk_window,
6883 gtk_widget_get_allocation (parent_widget, &allocation);
6884 x = ox + (allocation.width - w) / 2;
6885 y = oy + (allocation.height - h) / 2;
6887 /* Clamp onto current monitor, ignoring _NET_WM_STRUT and
6888 * WM decorations. If parent wasn't on a monitor, just
6891 if (monitor_num >= 0)
6893 gdk_screen_get_monitor_geometry (screen, monitor_num, &monitor);
6894 clamp_window_to_rectangle (&x, &y, w, h, &monitor);
6899 case GTK_WIN_POS_MOUSE:
6901 gint screen_width = gdk_screen_get_width (screen);
6902 gint screen_height = gdk_screen_get_height (screen);
6904 GdkRectangle monitor;
6905 GdkDisplay *display;
6906 GdkDeviceManager *device_manager;
6908 GdkScreen *pointer_screen;
6911 display = gdk_screen_get_display (screen);
6912 device_manager = gdk_display_get_device_manager (display);
6913 pointer = gdk_device_manager_get_client_pointer (device_manager);
6915 gdk_device_get_position (pointer,
6919 if (pointer_screen == screen)
6920 monitor_num = gdk_screen_get_monitor_at_point (screen, px, py);
6926 x = CLAMP (x, 0, screen_width - w);
6927 y = CLAMP (y, 0, screen_height - h);
6929 /* Clamp onto current monitor, ignoring _NET_WM_STRUT and
6930 * WM decorations. Don't try to figure out what's going
6931 * on if the mouse wasn't inside a monitor.
6933 if (monitor_num >= 0)
6935 gdk_screen_get_monitor_geometry (screen, monitor_num, &monitor);
6936 clamp_window_to_rectangle (&x, &y, w, h, &monitor);
6944 } /* if (priv->need_default_position) */
6946 if (priv->need_default_position && info &&
6947 info->initial_pos_set)
6949 x = info->initial_x;
6950 y = info->initial_y;
6951 gtk_window_constrain_position (window, w, h, &x, &y);
6957 request->height = h;
6960 *geometry = new_geometry;
6966 gtk_window_constrain_position (GtkWindow *window,
6972 GtkWindowPrivate *priv = window->priv;
6974 /* See long comments in gtk_window_move_resize()
6975 * on when it's safe to call this function.
6977 if (priv->position == GTK_WIN_POS_CENTER_ALWAYS)
6979 gint center_x, center_y;
6981 center_window_on_monitor (window, new_width, new_height, ¢er_x, ¢er_y);
6989 gtk_window_move_resize (GtkWindow *window)
6993 * First we determine whether any information has changed that would
6994 * cause us to revise our last configure request. If we would send
6995 * a different configure request from last time, then
6996 * configure_request_size_changed = TRUE or
6997 * configure_request_pos_changed = TRUE. configure_request_size_changed
6998 * may be true due to new hints, a gtk_window_resize(), or whatever.
6999 * configure_request_pos_changed may be true due to gtk_window_set_position()
7000 * or gtk_window_move().
7002 * If the configure request has changed, we send off a new one. To
7003 * ensure GTK+ invariants are maintained (resize queue does what it
7004 * should), we go ahead and size_allocate the requested size in this
7007 * If the configure request has not changed, we don't ever resend
7008 * it, because it could mean fighting the user or window manager.
7011 * To prepare the configure request, we come up with a base size/pos:
7012 * - the one from gtk_window_move()/gtk_window_resize()
7013 * - else default_width, default_height if we haven't ever
7015 * - else the size request if we haven't ever been mapped,
7016 * as a substitute default size
7017 * - else the current size of the window, as received from
7018 * configure notifies (i.e. the current allocation)
7020 * If GTK_WIN_POS_CENTER_ALWAYS is active, we constrain
7021 * the position request to be centered.
7023 GtkWindowPrivate *priv = window->priv;
7024 GtkAllocation allocation;
7026 GtkContainer *container;
7027 GtkWindowGeometryInfo *info;
7028 GdkGeometry new_geometry;
7029 GdkWindow *gdk_window;
7031 GdkRectangle new_request;
7032 gboolean configure_request_size_changed;
7033 gboolean configure_request_pos_changed;
7034 gboolean hints_changed; /* do we need to send these again */
7035 GtkWindowLastGeometryInfo saved_last_info;
7037 widget = GTK_WIDGET (window);
7039 gdk_window = gtk_widget_get_window (widget);
7040 container = GTK_CONTAINER (widget);
7041 info = gtk_window_get_geometry_info (window, TRUE);
7043 configure_request_size_changed = FALSE;
7044 configure_request_pos_changed = FALSE;
7046 gtk_window_compute_configure_request (window, &new_request,
7047 &new_geometry, &new_flags);
7049 /* This check implies the invariant that we never set info->last
7050 * without setting the hints and sending off a configure request.
7052 * If we change info->last without sending the request, we may
7055 if (info->last.configure_request.x != new_request.x ||
7056 info->last.configure_request.y != new_request.y)
7057 configure_request_pos_changed = TRUE;
7059 if ((info->last.configure_request.width != new_request.width ||
7060 info->last.configure_request.height != new_request.height))
7061 configure_request_size_changed = TRUE;
7063 hints_changed = FALSE;
7065 if (!gtk_window_compare_hints (&info->last.geometry, info->last.flags,
7066 &new_geometry, new_flags))
7068 hints_changed = TRUE;
7071 /* Position Constraints
7072 * ====================
7074 * POS_CENTER_ALWAYS is conceptually a constraint rather than
7075 * a default. The other POS_ values are used only when the
7076 * window is shown, not after that.
7078 * However, we can't implement a position constraint as
7079 * "anytime the window size changes, center the window"
7080 * because this may well end up fighting the WM or user. In
7081 * fact it gets in an infinite loop with at least one WM.
7083 * Basically, applications are in no way in a position to
7084 * constrain the position of a window, with one exception:
7085 * override redirect windows. (Really the intended purpose
7086 * of CENTER_ALWAYS anyhow, I would think.)
7088 * So the way we implement this "constraint" is to say that when WE
7089 * cause a move or resize, i.e. we make a configure request changing
7090 * window size, we recompute the CENTER_ALWAYS position to reflect
7091 * the new window size, and include it in our request. Also, if we
7092 * just turned on CENTER_ALWAYS we snap to center with a new
7093 * request. Otherwise, if we are just NOTIFIED of a move or resize
7094 * done by someone else e.g. the window manager, we do NOT send a
7095 * new configure request.
7097 * For override redirect windows, this works fine; all window
7098 * sizes are from our configure requests. For managed windows,
7099 * it is at least semi-sane, though who knows what the
7100 * app author is thinking.
7103 /* This condition should be kept in sync with the condition later on
7104 * that determines whether we send a configure request. i.e. we
7105 * should do this position constraining anytime we were going to
7106 * send a configure request anyhow, plus when constraints have
7109 if (configure_request_pos_changed ||
7110 configure_request_size_changed ||
7112 info->position_constraints_changed)
7114 /* We request the constrained position if:
7115 * - we were changing position, and need to clamp
7116 * the change to the constraint
7117 * - we're changing the size anyway
7118 * - set_position() was called to toggle CENTER_ALWAYS on
7121 gtk_window_constrain_position (window,
7127 /* Update whether we need to request a move */
7128 if (info->last.configure_request.x != new_request.x ||
7129 info->last.configure_request.y != new_request.y)
7130 configure_request_pos_changed = TRUE;
7132 configure_request_pos_changed = FALSE;
7136 if (priv->type == GTK_WINDOW_TOPLEVEL)
7138 int notify_x, notify_y;
7140 /* this is the position from the last configure notify */
7141 gdk_window_get_position (widget->window, ¬ify_x, ¬ify_y);
7143 g_message ("--- %s ---\n"
7144 "last : %d,%d\t%d x %d\n"
7145 "this : %d,%d\t%d x %d\n"
7146 "alloc : %d,%d\t%d x %d\n"
7148 "resize: \t%d x %d\n"
7149 "size_changed: %d pos_changed: %d hints_changed: %d\n"
7150 "configure_notify_received: %d\n"
7151 "configure_request_count: %d\n"
7152 "position_constraints_changed: %d\n",
7153 priv->title ? priv->title : "(no title)",
7154 info->last.configure_request.x,
7155 info->last.configure_request.y,
7156 info->last.configure_request.width,
7157 info->last.configure_request.height,
7163 widget->allocation.width,
7164 widget->allocation.height,
7165 widget->requisition.width,
7166 widget->requisition.height,
7168 info->resize_height,
7169 configure_request_pos_changed,
7170 configure_request_size_changed,
7172 priv->configure_notify_received,
7173 priv->configure_request_count,
7174 info->position_constraints_changed);
7178 saved_last_info = info->last;
7179 info->last.geometry = new_geometry;
7180 info->last.flags = new_flags;
7181 info->last.configure_request = new_request;
7183 /* need to set PPosition so the WM will look at our position,
7184 * but we don't want to count PPosition coming and going as a hints
7185 * change for future iterations. So we saved info->last prior to
7189 /* Also, if the initial position was explicitly set, then we always
7190 * toggle on PPosition. This makes gtk_window_move(window, 0, 0)
7194 /* Also, we toggle on PPosition if GTK_WIN_POS_ is in use and
7195 * this is an initial map
7198 if ((configure_request_pos_changed ||
7199 info->initial_pos_set ||
7200 (priv->need_default_position &&
7201 get_effective_position (window) != GTK_WIN_POS_NONE)) &&
7202 (new_flags & GDK_HINT_POS) == 0)
7204 new_flags |= GDK_HINT_POS;
7205 hints_changed = TRUE;
7208 /* Set hints if necessary
7211 gdk_window_set_geometry_hints (gdk_window,
7215 gtk_widget_get_allocation (widget, &allocation);
7217 /* handle resizing/moving and widget tree allocation
7219 if (priv->configure_notify_received)
7221 /* If we have received a configure event since
7222 * the last time in this function, we need to
7223 * accept our new size and size_allocate child widgets.
7224 * (see gtk_window_configure_event() for more details).
7226 * 1 or more configure notifies may have been received.
7227 * Also, configure_notify_received will only be TRUE
7228 * if all expected configure notifies have been received
7229 * (one per configure request), as an optimization.
7232 priv->configure_notify_received = FALSE;
7234 /* gtk_window_configure_event() filled in widget->allocation */
7235 gtk_widget_size_allocate (widget, &allocation);
7237 set_grip_position (window);
7238 update_grip_visibility (window);
7240 gdk_window_process_updates (gdk_window, TRUE);
7242 gdk_window_configure_finished (gdk_window);
7244 /* If the configure request changed, it means that
7246 * 1) coincidentally changed hints or widget properties
7247 * impacting the configure request before getting
7248 * a configure notify, or
7249 * 2) some broken widget is changing its size request
7250 * during size allocation, resulting in
7251 * a false appearance of changed configure request.
7253 * For 1), we could just go ahead and ask for the
7254 * new size right now, but doing that for 2)
7255 * might well be fighting the user (and can even
7256 * trigger a loop). Since we really don't want to
7257 * do that, we requeue a resize in hopes that
7258 * by the time it gets handled, the child has seen
7259 * the light and is willing to go along with the
7260 * new size. (this happens for the zvt widget, since
7261 * the size_allocate() above will have stored the
7262 * requisition corresponding to the new size in the
7265 * This doesn't buy us anything for 1), but it shouldn't
7266 * hurt us too badly, since it is what would have
7267 * happened if we had gotten the configure event before
7268 * the new size had been set.
7271 if (configure_request_size_changed ||
7272 configure_request_pos_changed)
7274 /* Don't change the recorded last info after all, because we
7275 * haven't actually updated to the new info yet - we decided
7276 * to postpone our configure request until later.
7278 info->last = saved_last_info;
7280 gtk_widget_queue_resize_no_redraw (widget); /* migth recurse for GTK_RESIZE_IMMEDIATE */
7283 return; /* Bail out, we didn't really process the move/resize */
7285 else if ((configure_request_size_changed || hints_changed) &&
7286 (allocation.width != new_request.width || allocation.height != new_request.height))
7289 /* We are in one of the following situations:
7290 * A. configure_request_size_changed
7291 * our requisition has changed and we need a different window size,
7292 * so we request it from the window manager.
7293 * B. !configure_request_size_changed && hints_changed
7294 * the window manager rejects our size, but we have just changed the
7295 * window manager hints, so there's a chance our request will
7296 * be honoured this time, so we try again.
7298 * However, if the new requisition is the same as the current allocation,
7299 * we don't request it again, since we won't get a ConfigureNotify back from
7300 * the window manager unless it decides to change our requisition. If
7301 * we don't get the ConfigureNotify back, the resize queue will never be run.
7304 /* Now send the configure request */
7305 if (configure_request_pos_changed)
7307 gdk_window_move_resize (gdk_window,
7308 new_request.x, new_request.y,
7309 new_request.width, new_request.height);
7311 else /* only size changed */
7313 gdk_window_resize (gdk_window,
7314 new_request.width, new_request.height);
7317 if (priv->type == GTK_WINDOW_POPUP)
7319 GtkAllocation allocation;
7321 /* Directly size allocate for override redirect (popup) windows. */
7324 allocation.width = new_request.width;
7325 allocation.height = new_request.height;
7327 gtk_widget_size_allocate (widget, &allocation);
7329 gdk_window_process_updates (gdk_window, TRUE);
7331 if (gtk_container_get_resize_mode (container) == GTK_RESIZE_QUEUE)
7332 gtk_widget_queue_draw (widget);
7336 /* Increment the number of have-not-yet-received-notify requests */
7337 priv->configure_request_count += 1;
7338 gdk_window_freeze_toplevel_updates_libgtk_only (gdk_window);
7340 /* for GTK_RESIZE_QUEUE toplevels, we are now awaiting a new
7341 * configure event in response to our resizing request.
7342 * the configure event will cause a new resize with
7343 * ->configure_notify_received=TRUE.
7344 * until then, we want to
7345 * - discard expose events
7346 * - coalesce resizes for our children
7347 * - defer any window resizes until the configure event arrived
7348 * to achieve this, we queue a resize for the window, but remove its
7349 * resizing handler, so resizing will not be handled from the next
7350 * idle handler but when the configure event arrives.
7352 * FIXME: we should also dequeue the pending redraws here, since
7353 * we handle those ourselves upon ->configure_notify_received==TRUE.
7355 if (gtk_container_get_resize_mode (container) == GTK_RESIZE_QUEUE)
7357 gtk_widget_queue_resize_no_redraw (widget);
7358 _gtk_container_dequeue_resize_handler (container);
7364 /* Handle any position changes.
7366 if (configure_request_pos_changed)
7368 gdk_window_move (gdk_window,
7369 new_request.x, new_request.y);
7372 /* And run the resize queue.
7374 gtk_container_resize_children (container);
7377 /* We have now processed a move/resize since the last position
7378 * constraint change, setting of the initial position, or resize.
7379 * (Not resetting these flags here can lead to infinite loops for
7380 * GTK_RESIZE_IMMEDIATE containers)
7382 info->position_constraints_changed = FALSE;
7383 info->initial_pos_set = FALSE;
7384 info->resize_width = -1;
7385 info->resize_height = -1;
7388 /* Compare two sets of Geometry hints for equality.
7391 gtk_window_compare_hints (GdkGeometry *geometry_a,
7393 GdkGeometry *geometry_b,
7396 if (flags_a != flags_b)
7399 if ((flags_a & GDK_HINT_MIN_SIZE) &&
7400 (geometry_a->min_width != geometry_b->min_width ||
7401 geometry_a->min_height != geometry_b->min_height))
7404 if ((flags_a & GDK_HINT_MAX_SIZE) &&
7405 (geometry_a->max_width != geometry_b->max_width ||
7406 geometry_a->max_height != geometry_b->max_height))
7409 if ((flags_a & GDK_HINT_BASE_SIZE) &&
7410 (geometry_a->base_width != geometry_b->base_width ||
7411 geometry_a->base_height != geometry_b->base_height))
7414 if ((flags_a & GDK_HINT_ASPECT) &&
7415 (geometry_a->min_aspect != geometry_b->min_aspect ||
7416 geometry_a->max_aspect != geometry_b->max_aspect))
7419 if ((flags_a & GDK_HINT_RESIZE_INC) &&
7420 (geometry_a->width_inc != geometry_b->width_inc ||
7421 geometry_a->height_inc != geometry_b->height_inc))
7424 if ((flags_a & GDK_HINT_WIN_GRAVITY) &&
7425 geometry_a->win_gravity != geometry_b->win_gravity)
7432 _gtk_window_constrain_size (GtkWindow *window,
7438 GtkWindowPrivate *priv;
7439 GtkWindowGeometryInfo *info;
7441 g_return_if_fail (GTK_IS_WINDOW (window));
7443 priv = window->priv;
7445 info = priv->geometry_info;
7448 GdkWindowHints flags = info->last.flags;
7449 GdkGeometry *geometry = &info->last.geometry;
7451 gtk_window_constrain_size (window,
7462 gtk_window_constrain_size (GtkWindow *window,
7463 GdkGeometry *geometry,
7470 gdk_window_constrain_size (geometry, flags, width, height,
7471 new_width, new_height);
7474 /* Compute the set of geometry hints and flags for a window
7475 * based on the application set geometry, and requisition
7476 * of the window. gtk_widget_get_preferred_size() must have been
7480 gtk_window_compute_hints (GtkWindow *window,
7481 GdkGeometry *new_geometry,
7484 GtkWindowPrivate *priv = window->priv;
7486 gint extra_width = 0;
7487 gint extra_height = 0;
7488 GtkWindowGeometryInfo *geometry_info;
7489 GtkRequisition requisition;
7491 widget = GTK_WIDGET (window);
7493 gtk_widget_get_preferred_size (widget, &requisition, NULL);
7494 geometry_info = gtk_window_get_geometry_info (GTK_WINDOW (widget), FALSE);
7498 *new_flags = geometry_info->mask;
7499 *new_geometry = geometry_info->geometry;
7506 if (geometry_info && geometry_info->widget)
7508 /* If the geometry widget is set, then the hints really apply to that
7509 * widget. This is pretty much meaningless unless the window layout
7510 * is such that the rest of the window adds fixed size borders to
7511 * the geometry widget. Our job is to figure the size of the borders;
7512 * We do that by asking how big the toplevel would be if the
7513 * geometry widget was *really big*.
7516 * |AAAAAAAAA | At small sizes, the minimum sizes of widgets
7517 * |GGGGG B| in the border can confuse things
7523 * |AAAAAAAAA | When the geometry widget is large, things are
7524 * |GGGGGGGGGGB| clearer.
7529 #define TEMPORARY_SIZE 10000 /* 10,000 pixels should be bigger than real widget sizes */
7530 GtkRequisition requisition;
7531 int current_width, current_height;
7533 _gtk_widget_override_size_request (geometry_info->widget,
7534 TEMPORARY_SIZE, TEMPORARY_SIZE,
7535 ¤t_width, ¤t_height);
7536 gtk_widget_get_preferred_size (widget,
7537 &requisition, NULL);
7538 _gtk_widget_restore_size_request (geometry_info->widget,
7539 current_width, current_height);
7541 extra_width = requisition.width - TEMPORARY_SIZE;
7542 extra_height = requisition.height - TEMPORARY_SIZE;
7544 if (extra_width < 0 || extra_height < 0)
7546 g_warning("Toplevel size doesn't seem to directly depend on the "
7547 "size of the geometry widget from gtk_window_set_geometry_hints(). "
7548 "The geometry widget might not be in the window, or it might not "
7549 "be packed into the window appropriately");
7550 extra_width = MAX(extra_width, 0);
7551 extra_height = MAX(extra_height, 0);
7553 #undef TEMPORARY_SIZE
7556 /* We don't want to set GDK_HINT_POS in here, we just set it
7557 * in gtk_window_move_resize() when we want the position
7561 if (*new_flags & GDK_HINT_BASE_SIZE)
7563 new_geometry->base_width += extra_width;
7564 new_geometry->base_height += extra_height;
7568 /* For simplicity, we always set the base hint, even when we
7569 * don't expect it to have any visible effect.
7570 * (Note: geometry_size_to_pixels() depends on this.)
7572 *new_flags |= GDK_HINT_BASE_SIZE;
7574 new_geometry->base_width = extra_width;
7575 new_geometry->base_height = extra_height;
7577 /* As for X, if BASE_SIZE is not set but MIN_SIZE is set, then the
7578 * base size is the minimum size */
7579 if (*new_flags & GDK_HINT_MIN_SIZE)
7581 if (new_geometry->min_width > 0)
7582 new_geometry->base_width += new_geometry->min_width;
7583 if (new_geometry->min_height > 0)
7584 new_geometry->base_height += new_geometry->min_height;
7588 /* Please use a good size for unresizable widgets, not the minimum one. */
7589 if (!priv->resizable)
7590 gtk_window_guess_default_size (window, &requisition.width, &requisition.height);
7592 if (*new_flags & GDK_HINT_MIN_SIZE)
7594 if (new_geometry->min_width < 0)
7595 new_geometry->min_width = requisition.width;
7597 new_geometry->min_width = MAX (requisition.width, new_geometry->min_width + extra_width);
7599 if (new_geometry->min_height < 0)
7600 new_geometry->min_height = requisition.height;
7602 new_geometry->min_height = MAX (requisition.height, new_geometry->min_height + extra_height);
7606 *new_flags |= GDK_HINT_MIN_SIZE;
7608 new_geometry->min_width = requisition.width;
7609 new_geometry->min_height = requisition.height;
7612 if (*new_flags & GDK_HINT_MAX_SIZE)
7614 if (new_geometry->max_width < 0)
7615 new_geometry->max_width = requisition.width;
7617 new_geometry->max_width += extra_width;
7619 if (new_geometry->max_height < 0)
7620 new_geometry->max_height = requisition.height;
7622 new_geometry->max_height += extra_height;
7624 else if (!priv->resizable)
7626 *new_flags |= GDK_HINT_MAX_SIZE;
7628 new_geometry->max_width = requisition.width;
7629 new_geometry->max_height = requisition.height;
7632 *new_flags |= GDK_HINT_WIN_GRAVITY;
7633 new_geometry->win_gravity = priv->gravity;
7636 /***********************
7637 * Redrawing functions *
7638 ***********************/
7641 gtk_window_draw (GtkWidget *widget,
7644 GtkWindowPrivate *priv = GTK_WINDOW (widget)->priv;
7645 GtkStyleContext *context;
7646 gboolean ret = FALSE;
7648 context = gtk_widget_get_style_context (widget);
7650 if (!gtk_widget_get_app_paintable (widget) &&
7651 gtk_cairo_should_draw_window (cr, gtk_widget_get_window (widget)))
7653 gtk_style_context_save (context);
7655 gtk_style_context_add_class (context, GTK_STYLE_CLASS_BACKGROUND);
7656 gtk_render_background (context, cr, 0, 0,
7657 gtk_widget_get_allocated_width (widget),
7658 gtk_widget_get_allocated_height (widget));
7660 gtk_style_context_restore (context);
7663 if (GTK_WIDGET_CLASS (gtk_window_parent_class)->draw)
7664 ret = GTK_WIDGET_CLASS (gtk_window_parent_class)->draw (widget, cr);
7666 if (priv->grip_window &&
7667 gtk_cairo_should_draw_window (cr, priv->grip_window))
7671 gtk_style_context_save (context);
7674 gtk_cairo_transform_to_window (cr, widget, priv->grip_window);
7675 gtk_window_get_resize_grip_area (GTK_WINDOW (widget), &rect);
7677 gtk_style_context_add_class (context, GTK_STYLE_CLASS_GRIP);
7678 gtk_style_context_set_junction_sides (context, get_grip_junction (widget));
7679 gtk_render_handle (context, cr, 0, 0, rect.width, rect.height);
7682 gtk_style_context_restore (context);
7689 * gtk_window_present:
7690 * @window: a #GtkWindow
7692 * Presents a window to the user. This may mean raising the window
7693 * in the stacking order, deiconifying it, moving it to the current
7694 * desktop, and/or giving it the keyboard focus, possibly dependent
7695 * on the user's platform, window manager, and preferences.
7697 * If @window is hidden, this function calls gtk_widget_show()
7700 * This function should be used when the user tries to open a window
7701 * that's already open. Say for example the preferences dialog is
7702 * currently open, and the user chooses Preferences from the menu
7703 * a second time; use gtk_window_present() to move the already-open dialog
7704 * where the user can see it.
7706 * If you are calling this function in response to a user interaction,
7707 * it is preferable to use gtk_window_present_with_time().
7711 gtk_window_present (GtkWindow *window)
7713 gtk_window_present_with_time (window, GDK_CURRENT_TIME);
7717 * gtk_window_present_with_time:
7718 * @window: a #GtkWindow
7719 * @timestamp: the timestamp of the user interaction (typically a
7720 * button or key press event) which triggered this call
7722 * Presents a window to the user in response to a user interaction.
7723 * If you need to present a window without a timestamp, use
7724 * gtk_window_present(). See gtk_window_present() for details.
7729 gtk_window_present_with_time (GtkWindow *window,
7732 GtkWindowPrivate *priv;
7734 GdkWindow *gdk_window;
7736 g_return_if_fail (GTK_IS_WINDOW (window));
7738 priv = window->priv;
7739 widget = GTK_WIDGET (window);
7741 if (gtk_widget_get_visible (widget))
7743 gdk_window = gtk_widget_get_window (widget);
7745 g_assert (gdk_window != NULL);
7747 gdk_window_show (gdk_window);
7749 /* Translate a timestamp of GDK_CURRENT_TIME appropriately */
7750 if (timestamp == GDK_CURRENT_TIME)
7752 #ifdef GDK_WINDOWING_X11
7753 if (GDK_IS_X11_WINDOW(gdk_window))
7755 GdkDisplay *display;
7757 display = gtk_widget_get_display (GTK_WIDGET (window));
7758 timestamp = gdk_x11_display_get_user_time (display);
7762 timestamp = gtk_get_current_event_time ();
7765 gdk_window_focus (gdk_window, timestamp);
7769 priv->initial_timestamp = timestamp;
7770 gtk_widget_show (widget);
7775 * gtk_window_iconify:
7776 * @window: a #GtkWindow
7778 * Asks to iconify (i.e. minimize) the specified @window. Note that
7779 * you shouldn't assume the window is definitely iconified afterward,
7780 * because other entities (e.g. the user or <link
7781 * linkend="gtk-X11-arch">window manager</link>) could deiconify it
7782 * again, or there may not be a window manager in which case
7783 * iconification isn't possible, etc. But normally the window will end
7784 * up iconified. Just don't write code that crashes if not.
7786 * It's permitted to call this function before showing a window,
7787 * in which case the window will be iconified before it ever appears
7790 * You can track iconification via the "window-state-event" signal
7795 gtk_window_iconify (GtkWindow *window)
7797 GtkWindowPrivate *priv;
7799 GdkWindow *toplevel;
7801 g_return_if_fail (GTK_IS_WINDOW (window));
7803 priv = window->priv;
7804 widget = GTK_WIDGET (window);
7806 priv->iconify_initially = TRUE;
7808 toplevel = gtk_widget_get_window (widget);
7810 if (toplevel != NULL)
7811 gdk_window_iconify (toplevel);
7815 * gtk_window_deiconify:
7816 * @window: a #GtkWindow
7818 * Asks to deiconify (i.e. unminimize) the specified @window. Note
7819 * that you shouldn't assume the window is definitely deiconified
7820 * afterward, because other entities (e.g. the user or <link
7821 * linkend="gtk-X11-arch">window manager</link>) could iconify it
7822 * again before your code which assumes deiconification gets to run.
7824 * You can track iconification via the "window-state-event" signal
7828 gtk_window_deiconify (GtkWindow *window)
7830 GtkWindowPrivate *priv;
7832 GdkWindow *toplevel;
7834 g_return_if_fail (GTK_IS_WINDOW (window));
7836 priv = window->priv;
7837 widget = GTK_WIDGET (window);
7839 priv->iconify_initially = FALSE;
7841 toplevel = gtk_widget_get_window (widget);
7843 if (toplevel != NULL)
7844 gdk_window_deiconify (toplevel);
7849 * @window: a #GtkWindow
7851 * Asks to stick @window, which means that it will appear on all user
7852 * desktops. Note that you shouldn't assume the window is definitely
7853 * stuck afterward, because other entities (e.g. the user or <link
7854 * linkend="gtk-X11-arch">window manager</link>) could unstick it
7855 * again, and some window managers do not support sticking
7856 * windows. But normally the window will end up stuck. Just don't
7857 * write code that crashes if not.
7859 * It's permitted to call this function before showing a window.
7861 * You can track stickiness via the "window-state-event" signal
7866 gtk_window_stick (GtkWindow *window)
7868 GtkWindowPrivate *priv;
7870 GdkWindow *toplevel;
7872 g_return_if_fail (GTK_IS_WINDOW (window));
7874 priv = window->priv;
7875 widget = GTK_WIDGET (window);
7877 priv->stick_initially = TRUE;
7879 toplevel = gtk_widget_get_window (widget);
7881 if (toplevel != NULL)
7882 gdk_window_stick (toplevel);
7886 * gtk_window_unstick:
7887 * @window: a #GtkWindow
7889 * Asks to unstick @window, which means that it will appear on only
7890 * one of the user's desktops. Note that you shouldn't assume the
7891 * window is definitely unstuck afterward, because other entities
7892 * (e.g. the user or <link linkend="gtk-X11-arch">window
7893 * manager</link>) could stick it again. But normally the window will
7894 * end up stuck. Just don't write code that crashes if not.
7896 * You can track stickiness via the "window-state-event" signal
7901 gtk_window_unstick (GtkWindow *window)
7903 GtkWindowPrivate *priv;
7905 GdkWindow *toplevel;
7907 g_return_if_fail (GTK_IS_WINDOW (window));
7909 priv = window->priv;
7910 widget = GTK_WIDGET (window);
7912 priv->stick_initially = FALSE;
7914 toplevel = gtk_widget_get_window (widget);
7916 if (toplevel != NULL)
7917 gdk_window_unstick (toplevel);
7921 * gtk_window_maximize:
7922 * @window: a #GtkWindow
7924 * Asks to maximize @window, so that it becomes full-screen. Note that
7925 * you shouldn't assume the window is definitely maximized afterward,
7926 * because other entities (e.g. the user or <link
7927 * linkend="gtk-X11-arch">window manager</link>) could unmaximize it
7928 * again, and not all window managers support maximization. But
7929 * normally the window will end up maximized. Just don't write code
7930 * that crashes if not.
7932 * It's permitted to call this function before showing a window,
7933 * in which case the window will be maximized when it appears onscreen
7936 * You can track maximization via the "window-state-event" signal
7941 gtk_window_maximize (GtkWindow *window)
7943 GtkWindowPrivate *priv;
7945 GdkWindow *toplevel;
7947 g_return_if_fail (GTK_IS_WINDOW (window));
7949 priv = window->priv;
7950 widget = GTK_WIDGET (window);
7952 priv->maximize_initially = TRUE;
7954 toplevel = gtk_widget_get_window (widget);
7956 if (toplevel != NULL)
7957 gdk_window_maximize (toplevel);
7961 * gtk_window_unmaximize:
7962 * @window: a #GtkWindow
7964 * Asks to unmaximize @window. Note that you shouldn't assume the
7965 * window is definitely unmaximized afterward, because other entities
7966 * (e.g. the user or <link linkend="gtk-X11-arch">window
7967 * manager</link>) could maximize it again, and not all window
7968 * managers honor requests to unmaximize. But normally the window will
7969 * end up unmaximized. Just don't write code that crashes if not.
7971 * You can track maximization via the "window-state-event" signal
7976 gtk_window_unmaximize (GtkWindow *window)
7978 GtkWindowPrivate *priv;
7980 GdkWindow *toplevel;
7982 g_return_if_fail (GTK_IS_WINDOW (window));
7984 priv = window->priv;
7985 widget = GTK_WIDGET (window);
7987 priv->maximize_initially = FALSE;
7989 toplevel = gtk_widget_get_window (widget);
7991 if (toplevel != NULL)
7992 gdk_window_unmaximize (toplevel);
7996 * gtk_window_fullscreen:
7997 * @window: a #GtkWindow
7999 * Asks to place @window in the fullscreen state. Note that you
8000 * shouldn't assume the window is definitely full screen afterward,
8001 * because other entities (e.g. the user or <link
8002 * linkend="gtk-X11-arch">window manager</link>) could unfullscreen it
8003 * again, and not all window managers honor requests to fullscreen
8004 * windows. But normally the window will end up fullscreen. Just
8005 * don't write code that crashes if not.
8007 * You can track the fullscreen state via the "window-state-event" signal
8013 gtk_window_fullscreen (GtkWindow *window)
8015 GtkWindowPrivate *priv;
8017 GdkWindow *toplevel;
8019 g_return_if_fail (GTK_IS_WINDOW (window));
8021 priv = window->priv;
8022 widget = GTK_WIDGET (window);
8024 priv->fullscreen_initially = TRUE;
8026 toplevel = gtk_widget_get_window (widget);
8028 if (toplevel != NULL)
8029 gdk_window_fullscreen (toplevel);
8033 * gtk_window_unfullscreen:
8034 * @window: a #GtkWindow
8036 * Asks to toggle off the fullscreen state for @window. Note that you
8037 * shouldn't assume the window is definitely not full screen
8038 * afterward, because other entities (e.g. the user or <link
8039 * linkend="gtk-X11-arch">window manager</link>) could fullscreen it
8040 * again, and not all window managers honor requests to unfullscreen
8041 * windows. But normally the window will end up restored to its normal
8042 * state. Just don't write code that crashes if not.
8044 * You can track the fullscreen state via the "window-state-event" signal
8050 gtk_window_unfullscreen (GtkWindow *window)
8053 GdkWindow *toplevel;
8054 GtkWindowPrivate *priv;
8056 g_return_if_fail (GTK_IS_WINDOW (window));
8058 priv = window->priv;
8059 widget = GTK_WIDGET (window);
8061 priv->fullscreen_initially = FALSE;
8063 toplevel = gtk_widget_get_window (widget);
8065 if (toplevel != NULL)
8066 gdk_window_unfullscreen (toplevel);
8070 * gtk_window_set_keep_above:
8071 * @window: a #GtkWindow
8072 * @setting: whether to keep @window above other windows
8074 * Asks to keep @window above, so that it stays on top. Note that
8075 * you shouldn't assume the window is definitely above afterward,
8076 * because other entities (e.g. the user or <link
8077 * linkend="gtk-X11-arch">window manager</link>) could not keep it above,
8078 * and not all window managers support keeping windows above. But
8079 * normally the window will end kept above. Just don't write code
8080 * that crashes if not.
8082 * It's permitted to call this function before showing a window,
8083 * in which case the window will be kept above when it appears onscreen
8086 * You can track the above state via the "window-state-event" signal
8089 * Note that, according to the <ulink
8090 * url="http://www.freedesktop.org/Standards/wm-spec">Extended Window
8091 * Manager Hints</ulink> specification, the above state is mainly meant
8092 * for user preferences and should not be used by applications e.g. for
8093 * drawing attention to their dialogs.
8098 gtk_window_set_keep_above (GtkWindow *window,
8102 GtkWindowPrivate *priv;
8103 GdkWindow *toplevel;
8105 g_return_if_fail (GTK_IS_WINDOW (window));
8107 priv = window->priv;
8108 widget = GTK_WIDGET (window);
8110 priv->above_initially = setting != FALSE;
8112 priv->below_initially = FALSE;
8114 toplevel = gtk_widget_get_window (widget);
8116 if (toplevel != NULL)
8117 gdk_window_set_keep_above (toplevel, setting);
8121 * gtk_window_set_keep_below:
8122 * @window: a #GtkWindow
8123 * @setting: whether to keep @window below other windows
8125 * Asks to keep @window below, so that it stays in bottom. Note that
8126 * you shouldn't assume the window is definitely below afterward,
8127 * because other entities (e.g. the user or <link
8128 * linkend="gtk-X11-arch">window manager</link>) could not keep it below,
8129 * and not all window managers support putting windows below. But
8130 * normally the window will be kept below. Just don't write code
8131 * that crashes if not.
8133 * It's permitted to call this function before showing a window,
8134 * in which case the window will be kept below when it appears onscreen
8137 * You can track the below state via the "window-state-event" signal
8140 * Note that, according to the <ulink
8141 * url="http://www.freedesktop.org/Standards/wm-spec">Extended Window
8142 * Manager Hints</ulink> specification, the above state is mainly meant
8143 * for user preferences and should not be used by applications e.g. for
8144 * drawing attention to their dialogs.
8149 gtk_window_set_keep_below (GtkWindow *window,
8153 GtkWindowPrivate *priv;
8154 GdkWindow *toplevel;
8156 g_return_if_fail (GTK_IS_WINDOW (window));
8158 priv = window->priv;
8159 widget = GTK_WIDGET (window);
8161 priv->below_initially = setting != FALSE;
8163 priv->above_initially = FALSE;
8165 toplevel = gtk_widget_get_window (widget);
8167 if (toplevel != NULL)
8168 gdk_window_set_keep_below (toplevel, setting);
8172 * gtk_window_set_resizable:
8173 * @window: a #GtkWindow
8174 * @resizable: %TRUE if the user can resize this window
8176 * Sets whether the user can resize a window. Windows are user resizable
8180 gtk_window_set_resizable (GtkWindow *window,
8183 GtkWindowPrivate *priv;
8185 g_return_if_fail (GTK_IS_WINDOW (window));
8187 priv = window->priv;
8189 resizable = (resizable != FALSE);
8191 if (priv->resizable != resizable)
8193 priv->resizable = (resizable != FALSE);
8195 update_grip_visibility (window);
8197 gtk_widget_queue_resize_no_redraw (GTK_WIDGET (window));
8199 g_object_notify (G_OBJECT (window), "resizable");
8204 * gtk_window_get_resizable:
8205 * @window: a #GtkWindow
8207 * Gets the value set by gtk_window_set_resizable().
8209 * Return value: %TRUE if the user can resize the window
8212 gtk_window_get_resizable (GtkWindow *window)
8214 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
8216 return window->priv->resizable;
8220 * gtk_window_set_gravity:
8221 * @window: a #GtkWindow
8222 * @gravity: window gravity
8224 * Window gravity defines the meaning of coordinates passed to
8225 * gtk_window_move(). See gtk_window_move() and #GdkGravity for
8228 * The default window gravity is #GDK_GRAVITY_NORTH_WEST which will
8229 * typically "do what you mean."
8233 gtk_window_set_gravity (GtkWindow *window,
8236 GtkWindowPrivate *priv;
8238 g_return_if_fail (GTK_IS_WINDOW (window));
8240 priv = window->priv;
8242 if (gravity != priv->gravity)
8244 priv->gravity = gravity;
8246 /* gtk_window_move_resize() will adapt gravity
8248 gtk_widget_queue_resize_no_redraw (GTK_WIDGET (window));
8250 g_object_notify (G_OBJECT (window), "gravity");
8255 * gtk_window_get_gravity:
8256 * @window: a #GtkWindow
8258 * Gets the value set by gtk_window_set_gravity().
8260 * Return value: (transfer none): window gravity
8263 gtk_window_get_gravity (GtkWindow *window)
8265 g_return_val_if_fail (GTK_IS_WINDOW (window), 0);
8267 return window->priv->gravity;
8271 * gtk_window_begin_resize_drag:
8272 * @window: a #GtkWindow
8273 * @button: mouse button that initiated the drag
8274 * @edge: position of the resize control
8275 * @root_x: X position where the user clicked to initiate the drag, in root window coordinates
8276 * @root_y: Y position where the user clicked to initiate the drag
8277 * @timestamp: timestamp from the click event that initiated the drag
8279 * Starts resizing a window. This function is used if an application
8280 * has window resizing controls. When GDK can support it, the resize
8281 * will be done using the standard mechanism for the <link
8282 * linkend="gtk-X11-arch">window manager</link> or windowing
8283 * system. Otherwise, GDK will try to emulate window resizing,
8284 * potentially not all that well, depending on the windowing system.
8288 gtk_window_begin_resize_drag (GtkWindow *window,
8296 GdkWindow *toplevel;
8298 g_return_if_fail (GTK_IS_WINDOW (window));
8299 widget = GTK_WIDGET (window);
8300 g_return_if_fail (gtk_widget_get_visible (widget));
8302 toplevel = gtk_widget_get_window (widget);
8304 gdk_window_begin_resize_drag (toplevel,
8311 * gtk_window_begin_move_drag:
8312 * @window: a #GtkWindow
8313 * @button: mouse button that initiated the drag
8314 * @root_x: X position where the user clicked to initiate the drag, in root window coordinates
8315 * @root_y: Y position where the user clicked to initiate the drag
8316 * @timestamp: timestamp from the click event that initiated the drag
8318 * Starts moving a window. This function is used if an application has
8319 * window movement grips. When GDK can support it, the window movement
8320 * will be done using the standard mechanism for the <link
8321 * linkend="gtk-X11-arch">window manager</link> or windowing
8322 * system. Otherwise, GDK will try to emulate window movement,
8323 * potentially not all that well, depending on the windowing system.
8327 gtk_window_begin_move_drag (GtkWindow *window,
8334 GdkWindow *toplevel;
8336 g_return_if_fail (GTK_IS_WINDOW (window));
8337 widget = GTK_WIDGET (window);
8338 g_return_if_fail (gtk_widget_get_visible (widget));
8340 toplevel = gtk_widget_get_window (widget);
8342 gdk_window_begin_move_drag (toplevel,
8349 * gtk_window_set_screen:
8350 * @window: a #GtkWindow.
8351 * @screen: a #GdkScreen.
8353 * Sets the #GdkScreen where the @window is displayed; if
8354 * the window is already mapped, it will be unmapped, and
8355 * then remapped on the new screen.
8360 gtk_window_set_screen (GtkWindow *window,
8363 GtkWindowPrivate *priv;
8365 GdkScreen *previous_screen;
8366 gboolean was_mapped;
8368 g_return_if_fail (GTK_IS_WINDOW (window));
8369 g_return_if_fail (GDK_IS_SCREEN (screen));
8371 priv = window->priv;
8373 if (screen == priv->screen)
8376 widget = GTK_WIDGET (window);
8378 previous_screen = priv->screen;
8379 was_mapped = gtk_widget_get_mapped (widget);
8382 gtk_widget_unmap (widget);
8383 if (gtk_widget_get_realized (widget))
8384 gtk_widget_unrealize (widget);
8386 gtk_window_free_key_hash (window);
8387 priv->screen = screen;
8388 gtk_widget_reset_rc_styles (widget);
8389 if (screen != previous_screen)
8391 if (previous_screen)
8393 g_signal_handlers_disconnect_by_func (previous_screen,
8394 gtk_window_on_composited_changed, window);
8395 #ifdef GDK_WINDOWING_X11
8396 g_signal_handlers_disconnect_by_func (gtk_settings_get_for_screen (previous_screen),
8397 gtk_window_on_theme_variant_changed, window);
8400 g_signal_connect (screen, "composited-changed",
8401 G_CALLBACK (gtk_window_on_composited_changed), window);
8402 #ifdef GDK_WINDOWING_X11
8403 g_signal_connect (gtk_settings_get_for_screen (screen),
8404 "notify::gtk-application-prefer-dark-theme",
8405 G_CALLBACK (gtk_window_on_theme_variant_changed), window);
8408 _gtk_widget_propagate_screen_changed (widget, previous_screen);
8409 _gtk_widget_propagate_composited_changed (widget);
8411 g_object_notify (G_OBJECT (window), "screen");
8414 gtk_widget_map (widget);
8418 gtk_window_set_theme_variant (GtkWindow *window)
8420 #ifdef GDK_WINDOWING_X11
8421 GdkWindow *gdk_window;
8422 gboolean dark_theme_requested;
8424 g_object_get (gtk_settings_get_for_screen (window->priv->screen),
8425 "gtk-application-prefer-dark-theme", &dark_theme_requested,
8428 gdk_window = gtk_widget_get_window (GTK_WIDGET (window));
8430 if (GDK_IS_X11_WINDOW (gdk_window))
8431 gdk_x11_window_set_theme_variant (gdk_window,
8432 dark_theme_requested ? "dark" : NULL);
8437 gtk_window_on_theme_variant_changed (GtkSettings *settings,
8441 if (window->priv->type == GTK_WINDOW_TOPLEVEL)
8442 gtk_window_set_theme_variant (window);
8446 gtk_window_on_composited_changed (GdkScreen *screen,
8449 gtk_widget_queue_draw (GTK_WIDGET (window));
8451 _gtk_widget_propagate_composited_changed (GTK_WIDGET (window));
8455 gtk_window_check_screen (GtkWindow *window)
8457 GtkWindowPrivate *priv = window->priv;
8460 return priv->screen;
8463 g_warning ("Screen for GtkWindow not set; you must always set\n"
8464 "a screen for a GtkWindow before using the window");
8470 * gtk_window_get_screen:
8471 * @window: a #GtkWindow.
8473 * Returns the #GdkScreen associated with @window.
8475 * Return value: (transfer none): a #GdkScreen.
8480 gtk_window_get_screen (GtkWindow *window)
8482 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
8484 return window->priv->screen;
8488 * gtk_window_is_active:
8489 * @window: a #GtkWindow
8491 * Returns whether the window is part of the current active toplevel.
8492 * (That is, the toplevel window receiving keystrokes.)
8493 * The return value is %TRUE if the window is active toplevel
8494 * itself, but also if it is, say, a #GtkPlug embedded in the active toplevel.
8495 * You might use this function if you wanted to draw a widget
8496 * differently in an active window from a widget in an inactive window.
8497 * See gtk_window_has_toplevel_focus()
8499 * Return value: %TRUE if the window part of the current active window.
8504 gtk_window_is_active (GtkWindow *window)
8506 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
8508 return window->priv->is_active;
8512 * gtk_window_has_toplevel_focus:
8513 * @window: a #GtkWindow
8515 * Returns whether the input focus is within this GtkWindow.
8516 * For real toplevel windows, this is identical to gtk_window_is_active(),
8517 * but for embedded windows, like #GtkPlug, the results will differ.
8519 * Return value: %TRUE if the input focus is within this GtkWindow
8524 gtk_window_has_toplevel_focus (GtkWindow *window)
8526 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
8528 return window->priv->has_toplevel_focus;
8533 * SECTION:gtkwindowgroup
8534 * @Short_description: Limit the effect of grabs
8535 * @Title: GtkWindowGroup
8537 * #GtkWindowGroup objects are referenced by each window in the group,
8538 * so once you have added all windows to a #GtkWindowGroup, you can drop
8539 * the initial reference to the window group with g_object_unref(). If the
8540 * windows in the window group are subsequently destroyed, then they will
8541 * be removed from the window group and drop their references on the window
8542 * group; when all window have been removed, the window group will be
8546 G_DEFINE_TYPE (GtkWindowGroup, gtk_window_group, G_TYPE_OBJECT)
8549 gtk_window_group_init (GtkWindowGroup *group)
8551 group->priv = G_TYPE_INSTANCE_GET_PRIVATE (group,
8552 GTK_TYPE_WINDOW_GROUP,
8553 GtkWindowGroupPrivate);
8557 gtk_window_group_class_init (GtkWindowGroupClass *klass)
8559 g_type_class_add_private (klass, sizeof (GtkWindowGroupPrivate));
8563 * gtk_window_group_new:
8565 * Creates a new #GtkWindowGroup object. Grabs added with
8566 * gtk_grab_add() only affect windows within the same #GtkWindowGroup.
8568 * Return value: a new #GtkWindowGroup.
8571 gtk_window_group_new (void)
8573 return g_object_new (GTK_TYPE_WINDOW_GROUP, NULL);
8577 window_group_cleanup_grabs (GtkWindowGroup *group,
8580 GtkWindowGroupPrivate *priv;
8581 GtkDeviceGrabInfo *info;
8583 GSList *to_remove = NULL;
8587 tmp_list = priv->grabs;
8590 if (gtk_widget_get_toplevel (tmp_list->data) == (GtkWidget*) window)
8591 to_remove = g_slist_prepend (to_remove, g_object_ref (tmp_list->data));
8592 tmp_list = tmp_list->next;
8597 gtk_grab_remove (to_remove->data);
8598 g_object_unref (to_remove->data);
8599 to_remove = g_slist_delete_link (to_remove, to_remove);
8602 tmp_list = priv->device_grabs;
8606 info = tmp_list->data;
8608 if (gtk_widget_get_toplevel (info->widget) == (GtkWidget *) window)
8609 to_remove = g_slist_prepend (to_remove, info);
8611 tmp_list = tmp_list->next;
8616 info = to_remove->data;
8618 gtk_device_grab_remove (info->widget, info->device);
8619 to_remove = g_slist_delete_link (to_remove, to_remove);
8624 * gtk_window_group_add_window:
8625 * @window_group: a #GtkWindowGroup
8626 * @window: the #GtkWindow to add
8628 * Adds a window to a #GtkWindowGroup.
8631 gtk_window_group_add_window (GtkWindowGroup *window_group,
8634 GtkWindowPrivate *priv;
8636 g_return_if_fail (GTK_IS_WINDOW_GROUP (window_group));
8637 g_return_if_fail (GTK_IS_WINDOW (window));
8639 priv = window->priv;
8641 if (priv->group != window_group)
8643 g_object_ref (window);
8644 g_object_ref (window_group);
8647 gtk_window_group_remove_window (priv->group, window);
8649 window_group_cleanup_grabs (gtk_window_get_group (NULL), window);
8651 priv->group = window_group;
8653 g_object_unref (window);
8658 * gtk_window_group_remove_window:
8659 * @window_group: a #GtkWindowGroup
8660 * @window: the #GtkWindow to remove
8662 * Removes a window from a #GtkWindowGroup.
8665 gtk_window_group_remove_window (GtkWindowGroup *window_group,
8668 GtkWindowPrivate *priv;
8670 g_return_if_fail (GTK_IS_WINDOW_GROUP (window_group));
8671 g_return_if_fail (GTK_IS_WINDOW (window));
8672 priv = window->priv;
8673 g_return_if_fail (priv->group == window_group);
8675 g_object_ref (window);
8677 window_group_cleanup_grabs (window_group, window);
8680 g_object_unref (window_group);
8681 g_object_unref (window);
8685 * gtk_window_group_list_windows:
8686 * @window_group: a #GtkWindowGroup
8688 * Returns a list of the #GtkWindows that belong to @window_group.
8690 * Returns: (element-type GtkWindow) (transfer container): A
8691 * newly-allocated list of windows inside the group.
8696 gtk_window_group_list_windows (GtkWindowGroup *window_group)
8698 GList *toplevels, *toplevel, *group_windows;
8700 g_return_val_if_fail (GTK_IS_WINDOW_GROUP (window_group), NULL);
8702 group_windows = NULL;
8703 toplevels = gtk_window_list_toplevels ();
8705 for (toplevel = toplevels; toplevel; toplevel = toplevel->next)
8707 GtkWindow *window = toplevel->data;
8709 if (window_group == window->priv->group)
8710 group_windows = g_list_prepend (group_windows, window);
8713 g_list_free (toplevels);
8715 return g_list_reverse (group_windows);
8719 * gtk_window_get_group:
8720 * @window: (allow-none): a #GtkWindow, or %NULL
8722 * Returns the group for @window or the default group, if
8723 * @window is %NULL or if @window does not have an explicit
8726 * Returns: (transfer none): the #GtkWindowGroup for a window or the default group
8731 gtk_window_get_group (GtkWindow *window)
8733 if (window && window->priv->group)
8734 return window->priv->group;
8737 static GtkWindowGroup *default_group = NULL;
8740 default_group = gtk_window_group_new ();
8742 return default_group;
8747 * gtk_window_has_group:
8748 * @window: a #GtkWindow
8750 * Returns whether @window has an explicit window group.
8752 * Return value: %TRUE if @window has an explicit window group.
8757 gtk_window_has_group (GtkWindow *window)
8759 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
8761 return window->priv->group != NULL;
8765 * gtk_window_group_get_current_grab:
8766 * @window_group: a #GtkWindowGroup
8768 * Gets the current grab widget of the given group,
8769 * see gtk_grab_add().
8771 * Returns: (transfer none): the current grab widget of the group
8776 gtk_window_group_get_current_grab (GtkWindowGroup *window_group)
8778 g_return_val_if_fail (GTK_IS_WINDOW_GROUP (window_group), NULL);
8780 if (window_group->priv->grabs)
8781 return GTK_WIDGET (window_group->priv->grabs->data);
8786 _gtk_window_group_add_grab (GtkWindowGroup *window_group,
8789 GtkWindowGroupPrivate *priv;
8791 priv = window_group->priv;
8792 priv->grabs = g_slist_prepend (priv->grabs, widget);
8796 _gtk_window_group_remove_grab (GtkWindowGroup *window_group,
8799 GtkWindowGroupPrivate *priv;
8801 priv = window_group->priv;
8802 priv->grabs = g_slist_remove (priv->grabs, widget);
8807 _gtk_window_group_add_device_grab (GtkWindowGroup *window_group,
8810 gboolean block_others)
8812 GtkWindowGroupPrivate *priv;
8813 GtkDeviceGrabInfo *info;
8815 priv = window_group->priv;
8817 info = g_slice_new0 (GtkDeviceGrabInfo);
8818 info->widget = widget;
8819 info->device = device;
8820 info->block_others = block_others;
8822 priv->device_grabs = g_slist_prepend (priv->device_grabs, info);
8826 _gtk_window_group_remove_device_grab (GtkWindowGroup *window_group,
8830 GtkWindowGroupPrivate *priv;
8831 GtkDeviceGrabInfo *info;
8832 GSList *list, *node = NULL;
8833 GdkDevice *other_device;
8835 priv = window_group->priv;
8836 other_device = gdk_device_get_associated_device (device);
8837 list = priv->device_grabs;
8843 if (info->widget == widget &&
8844 (info->device == device ||
8845 info->device == other_device))
8858 priv->device_grabs = g_slist_delete_link (priv->device_grabs, node);
8859 g_slice_free (GtkDeviceGrabInfo, info);
8864 * gtk_window_group_get_current_device_grab:
8865 * @window_group: a #GtkWindowGroup
8866 * @device: a #GdkDevice
8868 * Returns the current grab widget for @device, or %NULL if none.
8870 * Returns: (transfer none): The grab widget, or %NULL
8875 gtk_window_group_get_current_device_grab (GtkWindowGroup *window_group,
8878 GtkWindowGroupPrivate *priv;
8879 GtkDeviceGrabInfo *info;
8880 GdkDevice *other_device;
8883 g_return_val_if_fail (GTK_IS_WINDOW_GROUP (window_group), NULL);
8884 g_return_val_if_fail (GDK_IS_DEVICE (device), NULL);
8886 priv = window_group->priv;
8887 list = priv->device_grabs;
8888 other_device = gdk_device_get_associated_device (device);
8895 if (info->device == device ||
8896 info->device == other_device)
8897 return info->widget;
8904 _gtk_window_group_widget_is_blocked_for_device (GtkWindowGroup *window_group,
8908 GtkWindowGroupPrivate *priv;
8909 GtkDeviceGrabInfo *info;
8910 GdkDevice *other_device;
8913 priv = window_group->priv;
8914 other_device = gdk_device_get_associated_device (device);
8915 list = priv->device_grabs;
8922 /* Look for blocking grabs on other device pairs
8923 * that have the passed widget within the GTK+ grab.
8925 if (info->block_others &&
8926 info->device != device &&
8927 info->device != other_device &&
8928 (info->widget == widget ||
8929 gtk_widget_is_ancestor (widget, info->widget)))
8937 Derived from XParseGeometry() in XFree86
8939 Copyright 1985, 1986, 1987,1998 The Open Group
8941 All Rights Reserved.
8943 The above copyright notice and this permission notice shall be included
8944 in all copies or substantial portions of the Software.
8946 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
8947 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
8948 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
8949 IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
8950 OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
8951 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
8952 OTHER DEALINGS IN THE SOFTWARE.
8954 Except as contained in this notice, the name of The Open Group shall
8955 not be used in advertising or otherwise to promote the sale, use or
8956 other dealings in this Software without prior written authorization
8957 from The Open Group.
8962 * XParseGeometry parses strings of the form
8963 * "=<width>x<height>{+-}<xoffset>{+-}<yoffset>", where
8964 * width, height, xoffset, and yoffset are unsigned integers.
8965 * Example: "=80x24+300-49"
8966 * The equal sign is optional.
8967 * It returns a bitmask that indicates which of the four values
8968 * were actually found in the string. For each value found,
8969 * the corresponding argument is updated; for each value
8970 * not found, the corresponding argument is left unchanged.
8973 /* The following code is from Xlib, and is minimally modified, so we
8974 * can track any upstream changes if required. Don't change this
8975 * code. Or if you do, put in a huge comment marking which thing
8980 read_int (gchar *string,
8988 else if (*string == '-')
8994 for (; (*string >= '0') && (*string <= '9'); string++)
8996 result = (result * 10) + (*string - '0');
9008 * Bitmask returned by XParseGeometry(). Each bit tells if the corresponding
9009 * value (x, y, width, height) was found in the parsed string.
9011 #define NoValue 0x0000
9012 #define XValue 0x0001
9013 #define YValue 0x0002
9014 #define WidthValue 0x0004
9015 #define HeightValue 0x0008
9016 #define AllValues 0x000F
9017 #define XNegative 0x0010
9018 #define YNegative 0x0020
9020 /* Try not to reformat/modify, so we can compare/sync with X sources */
9022 gtk_XParseGeometry (const char *string,
9025 unsigned int *width,
9026 unsigned int *height)
9030 unsigned int tempWidth, tempHeight;
9032 char *nextCharacter;
9034 /* These initializations are just to silence gcc */
9040 if ( (string == NULL) || (*string == '\0')) return(mask);
9042 string++; /* ignore possible '=' at beg of geometry spec */
9044 strind = (char *)string;
9045 if (*strind != '+' && *strind != '-' && *strind != 'x') {
9046 tempWidth = read_int(strind, &nextCharacter);
9047 if (strind == nextCharacter)
9049 strind = nextCharacter;
9053 if (*strind == 'x' || *strind == 'X') {
9055 tempHeight = read_int(strind, &nextCharacter);
9056 if (strind == nextCharacter)
9058 strind = nextCharacter;
9059 mask |= HeightValue;
9062 if ((*strind == '+') || (*strind == '-')) {
9063 if (*strind == '-') {
9065 tempX = -read_int(strind, &nextCharacter);
9066 if (strind == nextCharacter)
9068 strind = nextCharacter;
9074 tempX = read_int(strind, &nextCharacter);
9075 if (strind == nextCharacter)
9077 strind = nextCharacter;
9080 if ((*strind == '+') || (*strind == '-')) {
9081 if (*strind == '-') {
9083 tempY = -read_int(strind, &nextCharacter);
9084 if (strind == nextCharacter)
9086 strind = nextCharacter;
9093 tempY = read_int(strind, &nextCharacter);
9094 if (strind == nextCharacter)
9096 strind = nextCharacter;
9102 /* If strind isn't at the end of the string the it's an invalid
9103 geometry specification. */
9105 if (*strind != '\0') return (0);
9111 if (mask & WidthValue)
9113 if (mask & HeightValue)
9114 *height = tempHeight;
9119 * gtk_window_parse_geometry:
9120 * @window: a #GtkWindow
9121 * @geometry: geometry string
9123 * Parses a standard X Window System geometry string - see the
9124 * manual page for X (type 'man X') for details on this.
9125 * gtk_window_parse_geometry() does work on all GTK+ ports
9126 * including Win32 but is primarily intended for an X environment.
9128 * If either a size or a position can be extracted from the
9129 * geometry string, gtk_window_parse_geometry() returns %TRUE
9130 * and calls gtk_window_set_default_size() and/or gtk_window_move()
9131 * to resize/move the window.
9133 * If gtk_window_parse_geometry() returns %TRUE, it will also
9134 * set the #GDK_HINT_USER_POS and/or #GDK_HINT_USER_SIZE hints
9135 * indicating to the window manager that the size/position of
9136 * the window was user-specified. This causes most window
9137 * managers to honor the geometry.
9139 * Note that for gtk_window_parse_geometry() to work as expected, it has
9140 * to be called when the window has its "final" size, i.e. after calling
9141 * gtk_widget_show_all() on the contents and gtk_window_set_geometry_hints()
9144 * #include <gtk/gtk.h>
9147 * fill_with_content (GtkWidget *vbox)
9149 * /* fill with content... */
9153 * main (int argc, char *argv[])
9155 * GtkWidget *window, *vbox;
9156 * GdkGeometry size_hints = {
9157 * 100, 50, 0, 0, 100, 50, 10, 10, 0.0, 0.0, GDK_GRAVITY_NORTH_WEST
9160 * gtk_init (&argc, &argv);
9162 * window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
9163 * vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, FALSE, 0);
9165 * gtk_container_add (GTK_CONTAINER (window), vbox);
9166 * fill_with_content (vbox);
9167 * gtk_widget_show_all (vbox);
9169 * gtk_window_set_geometry_hints (GTK_WINDOW (window),
9172 * GDK_HINT_MIN_SIZE |
9173 * GDK_HINT_BASE_SIZE |
9174 * GDK_HINT_RESIZE_INC);
9178 * if (!gtk_window_parse_geometry (GTK_WINDOW (window), argv[1]))
9179 * fprintf (stderr, "Failed to parse '%s'\n", argv[1]);
9182 * gtk_widget_show_all (window);
9189 * Return value: %TRUE if string was parsed successfully
9192 gtk_window_parse_geometry (GtkWindow *window,
9193 const gchar *geometry)
9195 gint result, x = 0, y = 0;
9199 gboolean size_set, pos_set;
9202 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
9203 g_return_val_if_fail (geometry != NULL, FALSE);
9205 child = gtk_bin_get_child (GTK_BIN (window));
9206 if (!child || !gtk_widget_get_visible (child))
9207 g_warning ("gtk_window_parse_geometry() called on a window with no "
9208 "visible children; the window should be set up before "
9209 "gtk_window_parse_geometry() is called.");
9211 screen = gtk_window_check_screen (window);
9213 result = gtk_XParseGeometry (geometry, &x, &y, &w, &h);
9216 if ((result & WidthValue) || (result & HeightValue))
9218 gtk_window_set_default_size_internal (window,
9219 TRUE, result & WidthValue ? w : -1,
9220 TRUE, result & HeightValue ? h : -1,
9225 gtk_window_get_size (window, (gint *)&w, (gint *)&h);
9227 grav = GDK_GRAVITY_NORTH_WEST;
9229 if ((result & XNegative) && (result & YNegative))
9230 grav = GDK_GRAVITY_SOUTH_EAST;
9231 else if (result & XNegative)
9232 grav = GDK_GRAVITY_NORTH_EAST;
9233 else if (result & YNegative)
9234 grav = GDK_GRAVITY_SOUTH_WEST;
9236 if ((result & XValue) == 0)
9239 if ((result & YValue) == 0)
9242 if (grav == GDK_GRAVITY_SOUTH_WEST ||
9243 grav == GDK_GRAVITY_SOUTH_EAST)
9244 y = gdk_screen_get_height (screen) - h + y;
9246 if (grav == GDK_GRAVITY_SOUTH_EAST ||
9247 grav == GDK_GRAVITY_NORTH_EAST)
9248 x = gdk_screen_get_width (screen) - w + x;
9250 /* we don't let you put a window offscreen; maybe some people would
9251 * prefer to be able to, but it's kind of a bogus thing to do.
9260 if ((result & XValue) || (result & YValue))
9262 gtk_window_set_gravity (window, grav);
9263 gtk_window_move (window, x, y);
9267 if (size_set || pos_set)
9269 /* Set USSize, USPosition hints */
9270 GtkWindowGeometryInfo *info;
9272 info = gtk_window_get_geometry_info (window, TRUE);
9275 info->mask |= GDK_HINT_USER_POS;
9277 info->mask |= GDK_HINT_USER_SIZE;
9284 gtk_window_mnemonic_hash_foreach (guint keyval,
9290 GtkWindowKeysForeachFunc func;
9294 (*info->func) (info->window, keyval, info->window->priv->mnemonic_modifier, TRUE, info->func_data);
9298 _gtk_window_keys_foreach (GtkWindow *window,
9299 GtkWindowKeysForeachFunc func,
9303 GtkMnemonicHash *mnemonic_hash;
9307 GtkWindowKeysForeachFunc func;
9311 info.window = window;
9313 info.func_data = func_data;
9315 mnemonic_hash = gtk_window_get_mnemonic_hash (window, FALSE);
9317 _gtk_mnemonic_hash_foreach (mnemonic_hash,
9318 gtk_window_mnemonic_hash_foreach, &info);
9320 groups = gtk_accel_groups_from_object (G_OBJECT (window));
9323 GtkAccelGroup *group = groups->data;
9326 for (i = 0; i < group->priv->n_accels; i++)
9328 GtkAccelKey *key = &group->priv->priv_accels[i].key;
9331 (*func) (window, key->accel_key, key->accel_mods, FALSE, func_data);
9334 groups = groups->next;
9339 gtk_window_keys_changed (GtkWindow *window)
9341 gtk_window_free_key_hash (window);
9342 gtk_window_get_key_hash (window);
9345 typedef struct _GtkWindowKeyEntry GtkWindowKeyEntry;
9347 struct _GtkWindowKeyEntry
9351 guint is_mnemonic : 1;
9355 window_key_entry_destroy (gpointer data)
9357 g_slice_free (GtkWindowKeyEntry, data);
9361 add_to_key_hash (GtkWindow *window,
9363 GdkModifierType modifiers,
9364 gboolean is_mnemonic,
9367 GtkKeyHash *key_hash = data;
9369 GtkWindowKeyEntry *entry = g_slice_new (GtkWindowKeyEntry);
9371 entry->keyval = keyval;
9372 entry->modifiers = modifiers;
9373 entry->is_mnemonic = is_mnemonic;
9375 /* GtkAccelGroup stores lowercased accelerators. To deal
9376 * with this, if <Shift> was specified, uppercase.
9378 if (modifiers & GDK_SHIFT_MASK)
9380 if (keyval == GDK_KEY_Tab)
9381 keyval = GDK_KEY_ISO_Left_Tab;
9383 keyval = gdk_keyval_to_upper (keyval);
9386 _gtk_key_hash_add_entry (key_hash, keyval, entry->modifiers, entry);
9390 gtk_window_get_key_hash (GtkWindow *window)
9392 GdkScreen *screen = gtk_window_check_screen (window);
9393 GtkKeyHash *key_hash = g_object_get_qdata (G_OBJECT (window), quark_gtk_window_key_hash);
9398 key_hash = _gtk_key_hash_new (gdk_keymap_get_for_display (gdk_screen_get_display (screen)),
9399 (GDestroyNotify)window_key_entry_destroy);
9400 _gtk_window_keys_foreach (window, add_to_key_hash, key_hash);
9401 g_object_set_qdata (G_OBJECT (window), quark_gtk_window_key_hash, key_hash);
9407 gtk_window_free_key_hash (GtkWindow *window)
9409 GtkKeyHash *key_hash = g_object_get_qdata (G_OBJECT (window), quark_gtk_window_key_hash);
9412 _gtk_key_hash_free (key_hash);
9413 g_object_set_qdata (G_OBJECT (window), quark_gtk_window_key_hash, NULL);
9418 * gtk_window_activate_key:
9419 * @window: a #GtkWindow
9420 * @event: a #GdkEventKey
9422 * Activates mnemonics and accelerators for this #GtkWindow. This is normally
9423 * called by the default ::key_press_event handler for toplevel windows,
9424 * however in some cases it may be useful to call this directly when
9425 * overriding the standard key handling for a toplevel window.
9427 * Return value: %TRUE if a mnemonic or accelerator was found and activated.
9432 gtk_window_activate_key (GtkWindow *window,
9435 GtkKeyHash *key_hash;
9436 GtkWindowKeyEntry *found_entry = NULL;
9437 gboolean enable_mnemonics;
9438 gboolean enable_accels;
9440 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
9441 g_return_val_if_fail (event != NULL, FALSE);
9443 key_hash = gtk_window_get_key_hash (window);
9448 GSList *entries = _gtk_key_hash_lookup (key_hash,
9449 event->hardware_keycode,
9451 gtk_accelerator_get_default_mod_mask (),
9454 g_object_get (gtk_widget_get_settings (GTK_WIDGET (window)),
9455 "gtk-enable-mnemonics", &enable_mnemonics,
9456 "gtk-enable-accels", &enable_accels,
9459 for (tmp_list = entries; tmp_list; tmp_list = tmp_list->next)
9461 GtkWindowKeyEntry *entry = tmp_list->data;
9462 if (entry->is_mnemonic)
9464 if (enable_mnemonics)
9466 found_entry = entry;
9472 if (enable_accels && !found_entry)
9474 found_entry = entry;
9479 g_slist_free (entries);
9484 if (found_entry->is_mnemonic)
9486 if (enable_mnemonics)
9487 return gtk_window_mnemonic_activate (window, found_entry->keyval,
9488 found_entry->modifiers);
9493 return gtk_accel_groups_activate (G_OBJECT (window), found_entry->keyval,
9494 found_entry->modifiers);
9502 window_update_has_focus (GtkWindow *window)
9504 GtkWindowPrivate *priv = window->priv;
9505 GtkWidget *widget = GTK_WIDGET (window);
9506 gboolean has_focus = priv->has_toplevel_focus && priv->is_active;
9508 if (has_focus != priv->has_focus)
9510 priv->has_focus = has_focus;
9514 if (priv->focus_widget &&
9515 priv->focus_widget != widget &&
9516 !gtk_widget_has_focus (priv->focus_widget))
9517 do_focus_change (priv->focus_widget, TRUE);
9521 if (priv->focus_widget &&
9522 priv->focus_widget != widget &&
9523 gtk_widget_has_focus (priv->focus_widget))
9524 do_focus_change (priv->focus_widget, FALSE);
9530 * _gtk_window_set_is_active:
9531 * @window: a #GtkWindow
9532 * @is_active: %TRUE if the window is in the currently active toplevel
9534 * Internal function that sets whether the #GtkWindow is part
9535 * of the currently active toplevel window (taking into account inter-process
9539 _gtk_window_set_is_active (GtkWindow *window,
9542 GtkWindowPrivate *priv;
9544 g_return_if_fail (GTK_IS_WINDOW (window));
9546 priv = window->priv;
9548 is_active = is_active != FALSE;
9550 if (is_active != priv->is_active)
9552 priv->is_active = is_active;
9553 window_update_has_focus (window);
9555 g_object_notify (G_OBJECT (window), "is-active");
9560 * _gtk_window_set_is_toplevel:
9561 * @window: a #GtkWindow
9562 * @is_toplevel: %TRUE if the window is still a real toplevel (nominally a
9563 * child of the root window); %FALSE if it is not (for example, for an
9564 * in-process, parented GtkPlug)
9566 * Internal function used by #GtkPlug when it gets parented/unparented by a
9567 * #GtkSocket. This keeps the @window's #GTK_TOPLEVEL flag in sync with the
9568 * global list of toplevel windows.
9571 _gtk_window_set_is_toplevel (GtkWindow *window,
9572 gboolean is_toplevel)
9575 GtkWidget *toplevel;
9577 widget = GTK_WIDGET (window);
9579 if (gtk_widget_is_toplevel (widget))
9580 g_assert (g_slist_find (toplevel_list, window) != NULL);
9582 g_assert (g_slist_find (toplevel_list, window) == NULL);
9584 if (is_toplevel == gtk_widget_is_toplevel (widget))
9589 /* Pass through regular pathways of an embedded toplevel
9590 * to go through unmapping and hiding the widget before
9591 * becomming a toplevel again.
9593 * We remain hidden after becomming toplevel in order to
9594 * avoid problems during an embedded toplevel's dispose cycle
9595 * (When a toplevel window is shown it tries to grab focus again,
9596 * this causes problems while disposing).
9598 gtk_widget_hide (widget);
9600 /* Save the toplevel this widget was previously anchored into before
9601 * propagating a hierarchy-changed.
9603 * Usually this happens by way of gtk_widget_unparent() and we are
9604 * already unanchored at this point, just adding this clause incase
9605 * things happen differently.
9607 toplevel = gtk_widget_get_toplevel (widget);
9608 if (!gtk_widget_is_toplevel (toplevel))
9611 _gtk_widget_set_is_toplevel (widget, TRUE);
9613 /* When a window becomes toplevel after being embedded and anchored
9614 * into another window we need to unset its anchored flag so that
9615 * the hierarchy changed signal kicks in properly.
9617 _gtk_widget_set_anchored (widget, FALSE);
9618 _gtk_widget_propagate_hierarchy_changed (widget, toplevel);
9620 toplevel_list = g_slist_prepend (toplevel_list, window);
9624 _gtk_widget_set_is_toplevel (widget, FALSE);
9625 toplevel_list = g_slist_remove (toplevel_list, window);
9627 _gtk_widget_propagate_hierarchy_changed (widget, widget);
9632 * _gtk_window_set_has_toplevel_focus:
9633 * @window: a #GtkWindow
9634 * @has_toplevel_focus: %TRUE if the in
9636 * Internal function that sets whether the keyboard focus for the
9637 * toplevel window (taking into account inter-process embedding.)
9640 _gtk_window_set_has_toplevel_focus (GtkWindow *window,
9641 gboolean has_toplevel_focus)
9643 GtkWindowPrivate *priv;
9645 g_return_if_fail (GTK_IS_WINDOW (window));
9647 priv = window->priv;
9649 has_toplevel_focus = has_toplevel_focus != FALSE;
9651 if (has_toplevel_focus != priv->has_toplevel_focus)
9653 priv->has_toplevel_focus = has_toplevel_focus;
9654 window_update_has_focus (window);
9656 g_object_notify (G_OBJECT (window), "has-toplevel-focus");
9661 * gtk_window_set_auto_startup_notification:
9662 * @setting: %TRUE to automatically do startup notification
9664 * By default, after showing the first #GtkWindow, GTK+ calls
9665 * gdk_notify_startup_complete(). Call this function to disable
9666 * the automatic startup notification. You might do this if your
9667 * first window is a splash screen, and you want to delay notification
9668 * until after your real main window has been shown, for example.
9670 * In that example, you would disable startup notification
9671 * temporarily, show your splash screen, then re-enable it so that
9672 * showing the main window would automatically result in notification.
9677 gtk_window_set_auto_startup_notification (gboolean setting)
9679 disable_startup_notification = !setting;
9683 * gtk_window_get_window_type:
9684 * @window: a #GtkWindow
9686 * Gets the type of the window. See #GtkWindowType.
9688 * Return value: the type of the window
9693 gtk_window_get_window_type (GtkWindow *window)
9695 g_return_val_if_fail (GTK_IS_WINDOW (window), GTK_WINDOW_TOPLEVEL);
9697 return window->priv->type;
9701 * gtk_window_get_mnemonics_visible:
9702 * @window: a #GtkWindow
9704 * Gets the value of the #GtkWindow:mnemonics-visible property.
9706 * Returns: %TRUE if mnemonics are supposed to be visible
9712 gtk_window_get_mnemonics_visible (GtkWindow *window)
9714 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
9716 return window->priv->mnemonics_visible;
9720 * gtk_window_set_mnemonics_visible:
9721 * @window: a #GtkWindow
9722 * @setting: the new value
9724 * Sets the #GtkWindow:mnemonics-visible property.
9729 gtk_window_set_mnemonics_visible (GtkWindow *window,
9732 GtkWindowPrivate *priv;
9734 g_return_if_fail (GTK_IS_WINDOW (window));
9736 priv = window->priv;
9738 setting = setting != FALSE;
9740 if (priv->mnemonics_visible != setting)
9742 priv->mnemonics_visible = setting;
9743 g_object_notify (G_OBJECT (window), "mnemonics-visible");
9746 priv->mnemonics_visible_set = TRUE;
9750 * gtk_window_get_focus_visible:
9751 * @window: a #GtkWindow
9753 * Gets the value of the #GtkWindow:focus-visible property.
9755 * Returns: %TRUE if 'focus rectangles' are supposed to be visible
9761 gtk_window_get_focus_visible (GtkWindow *window)
9763 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
9765 return window->priv->focus_visible;
9769 * gtk_window_set_focus_visible:
9770 * @window: a #GtkWindow
9771 * @setting: the new value
9773 * Sets the #GtkWindow:focus-visible property.
9778 gtk_window_set_focus_visible (GtkWindow *window,
9781 GtkWindowPrivate *priv;
9783 g_return_if_fail (GTK_IS_WINDOW (window));
9785 priv = window->priv;
9787 setting = setting != FALSE;
9789 if (priv->focus_visible != setting)
9791 priv->focus_visible = setting;
9792 g_object_notify (G_OBJECT (window), "focus-visible");
9797 _gtk_window_get_wmclass (GtkWindow *window,
9798 gchar **wmclass_name,
9799 gchar **wmclass_class)
9801 GtkWindowPrivate *priv = window->priv;
9803 *wmclass_name = priv->wmclass_name;
9804 *wmclass_class = priv->wmclass_class;
9808 * gtk_window_set_has_user_ref_count:
9809 * @window: a #GtkWindow
9810 * @setting: the new value
9812 * Tells GTK+ whether to drop its extra reference to the window
9813 * when gtk_window_destroy() is called.
9815 * This function is only exported for the benefit of language
9816 * bindings which may need to keep the window alive until their
9817 * wrapper object is garbage collected. There is no justification
9818 * for ever calling this function in an application.
9823 gtk_window_set_has_user_ref_count (GtkWindow *window,
9826 g_return_if_fail (GTK_IS_WINDOW (window));
9828 window->priv->has_user_ref_count = setting;
9832 ensure_state_flag_backdrop (GtkWidget *widget)
9835 gboolean window_focused = TRUE;
9837 window = gtk_widget_get_window (widget);
9839 window_focused = gdk_window_get_state (window) & GDK_WINDOW_STATE_FOCUSED;
9841 if (!window_focused)
9842 gtk_widget_set_state_flags (widget, GTK_STATE_FLAG_BACKDROP, FALSE);
9844 gtk_widget_unset_state_flags (widget, GTK_STATE_FLAG_BACKDROP);
9846 gtk_widget_queue_draw (widget);