1 /* GTK - The GIMP Toolkit
2 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
21 * Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
22 * file for a list of people on the GTK+ Team. See the ChangeLog
23 * files for a list of changes. These files are distributed with
24 * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
33 #include "gdk/gdkkeysyms.h"
37 #include "gtkprivate.h"
39 #include "gtkwindow.h"
40 #include "gtkwindow-decorate.h"
41 #include "gtkbindings.h"
42 #include "gtkkeyhash.h"
44 #include "gtkmnemonichash.h"
45 #include "gtkmenubar.h"
46 #include "gtkiconfactory.h"
47 #include "gtkicontheme.h"
48 #include "gtkmarshalers.h"
50 #include "gtkbuildable.h"
52 #ifdef GDK_WINDOWING_X11
59 * @short_description: Toplevel which can contain other widgets
61 * <refsect2 id="GtkWindow-BUILDER-UI">
62 * <title>GtkWindow as GtkBuildable</title>
64 * The GtkWindow implementation of the GtkBuildable interface supports a
65 * custom <tag class="starttag">accel-groups</tag> element, which supports
66 * any number of <tag class="starttag">group</tag> elements representing the
67 * #GtkAccelGroup objects you want to add to your window (synonymous with
68 * gtk_window_add_accel_group().
71 * <title>A UI definition fragment with accel groups</title>
72 * <programlisting><![CDATA[
73 * <object class="GtkWindow">
75 * <group name="accelgroup1"/>
81 * <object class="GtkAccelGroup" id="accelgroup1"/>
82 * ]]></programlisting>
87 typedef struct _GtkDeviceGrabInfo GtkDeviceGrabInfo;
88 typedef struct _GtkWindowGroupPrivate GtkWindowGroupPrivate;
90 struct _GtkWindowPrivate
92 GtkMnemonicHash *mnemonic_hash;
94 GtkWidget *default_widget;
95 GtkWidget *focus_widget;
96 GtkWindow *transient_parent;
97 GtkWindowGeometryInfo *geometry_info;
98 GtkWindowGroup *group;
100 GdkModifierType mnemonic_modifier;
103 GdkWindowTypeHint gdk_type_hint;
109 gchar *wmclass_class;
117 guint keys_changed_handler;
119 guint16 configure_request_count;
121 /* The following flags are initially TRUE (before a window is mapped).
122 * They cause us to compute a configure request that involves
123 * default-only parameters. Once mapped, we set them to FALSE.
124 * Then we set them to TRUE again on unmap (for position)
125 * and on unrealize (for size).
127 guint need_default_position : 1;
128 guint need_default_size : 1;
130 guint above_initially : 1;
131 guint accept_focus : 1;
132 guint below_initially : 1;
133 guint builder_visible : 1;
134 guint configure_notify_received : 1;
137 guint destroy_with_parent : 1;
138 guint focus_on_map : 1;
139 guint fullscreen_initially : 1;
140 guint gravity : 5; /* GdkGravity */
142 guint has_user_ref_count : 1;
144 guint has_toplevel_focus : 1;
145 guint iconify_initially : 1; /* gtk_window_iconify() called before realization */
147 guint maximize_initially : 1;
148 guint mnemonics_visible : 1;
149 guint mnemonics_visible_set : 1;
151 guint opacity_set : 1;
153 guint reset_type_hint : 1;
155 guint skips_pager : 1;
156 guint skips_taskbar : 1;
157 guint stick_initially : 1;
158 guint transient_parent_group : 1;
159 guint type : 4; /* GtkWindowType */
160 guint type_hint : 3; /* GdkWindowTypeHint if the hint is one of the original eight. If not, then
161 * it contains GDK_WINDOW_TYPE_HINT_NORMAL */
188 PROP_DESTROY_WITH_PARENT,
194 PROP_SKIP_TASKBAR_HINT,
195 PROP_SKIP_PAGER_HINT,
205 /* Readonly properties */
207 PROP_HAS_TOPLEVEL_FOCUS,
209 /* Writeonly properties */
212 PROP_MNEMONICS_VISIBLE,
222 guint using_default_icon : 1;
223 guint using_parent_icon : 1;
224 guint using_themed_icon : 1;
228 GdkGeometry geometry; /* Last set of geometry hints we set */
229 GdkWindowHints flags;
230 GdkRectangle configure_request;
231 } GtkWindowLastGeometryInfo;
233 struct _GtkWindowGeometryInfo
235 /* Properties that the app has set on the window
237 GdkGeometry geometry; /* Geometry hints */
239 GtkWidget *widget; /* subwidget to which hints apply */
240 /* from last gtk_window_resize () - if > 0, indicates that
241 * we should resize to this size.
246 /* From last gtk_window_move () prior to mapping -
247 * only used if initial_pos_set
252 /* Default size - used only the FIRST time we map a window,
257 /* whether to use initial_x, initial_y */
258 guint initial_pos_set : 1;
259 /* CENTER_ALWAYS or other position constraint changed since
260 * we sent the last configure request.
262 guint position_constraints_changed : 1;
264 /* if true, default_width, height come from gtk_window_parse_geometry,
265 * and thus should be multiplied by the increments and affect the
266 * geometry widget only
268 guint default_is_geometry : 1;
270 GtkWindowLastGeometryInfo last;
273 #define GTK_WINDOW_GROUP_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GTK_TYPE_WINDOW_GROUP, GtkWindowGroupPrivate))
275 struct _GtkDeviceGrabInfo
279 guint block_others : 1;
282 struct _GtkWindowGroupPrivate
284 GSList *device_grabs;
287 static void gtk_window_dispose (GObject *object);
288 static void gtk_window_finalize (GObject *object);
289 static void gtk_window_destroy (GtkWidget *widget);
290 static void gtk_window_show (GtkWidget *widget);
291 static void gtk_window_hide (GtkWidget *widget);
292 static void gtk_window_map (GtkWidget *widget);
293 static void gtk_window_unmap (GtkWidget *widget);
294 static void gtk_window_realize (GtkWidget *widget);
295 static void gtk_window_unrealize (GtkWidget *widget);
296 static void gtk_window_size_allocate (GtkWidget *widget,
297 GtkAllocation *allocation);
298 static gint gtk_window_event (GtkWidget *widget,
300 static gboolean gtk_window_map_event (GtkWidget *widget,
302 static gboolean gtk_window_frame_event (GtkWindow *window,
304 static gint gtk_window_configure_event (GtkWidget *widget,
305 GdkEventConfigure *event);
306 static gint gtk_window_key_press_event (GtkWidget *widget,
308 static gint gtk_window_key_release_event (GtkWidget *widget,
310 static gint gtk_window_enter_notify_event (GtkWidget *widget,
311 GdkEventCrossing *event);
312 static gint gtk_window_leave_notify_event (GtkWidget *widget,
313 GdkEventCrossing *event);
314 static gint gtk_window_focus_in_event (GtkWidget *widget,
315 GdkEventFocus *event);
316 static gint gtk_window_focus_out_event (GtkWidget *widget,
317 GdkEventFocus *event);
318 static gint gtk_window_client_event (GtkWidget *widget,
319 GdkEventClient *event);
320 static void gtk_window_check_resize (GtkContainer *container);
321 static gint gtk_window_focus (GtkWidget *widget,
322 GtkDirectionType direction);
323 static void gtk_window_real_set_focus (GtkWindow *window,
326 static void gtk_window_real_activate_default (GtkWindow *window);
327 static void gtk_window_real_activate_focus (GtkWindow *window);
328 static void gtk_window_move_focus (GtkWindow *window,
329 GtkDirectionType dir);
330 static void gtk_window_keys_changed (GtkWindow *window);
331 static gint gtk_window_draw (GtkWidget *widget,
333 static void gtk_window_unset_transient_for (GtkWindow *window);
334 static void gtk_window_transient_parent_realized (GtkWidget *parent,
336 static void gtk_window_transient_parent_unrealized (GtkWidget *parent,
339 static GdkScreen *gtk_window_check_screen (GtkWindow *window);
341 static GtkWindowGeometryInfo* gtk_window_get_geometry_info (GtkWindow *window,
344 static void gtk_window_move_resize (GtkWindow *window);
345 static gboolean gtk_window_compare_hints (GdkGeometry *geometry_a,
347 GdkGeometry *geometry_b,
349 static void gtk_window_constrain_size (GtkWindow *window,
350 GdkGeometry *geometry,
356 static void gtk_window_constrain_position (GtkWindow *window,
361 static void gtk_window_compute_hints (GtkWindow *window,
362 GdkGeometry *new_geometry,
364 static void gtk_window_compute_configure_request (GtkWindow *window,
365 GdkRectangle *request,
366 GdkGeometry *geometry,
369 static void gtk_window_set_default_size_internal (GtkWindow *window,
370 gboolean change_width,
372 gboolean change_height,
374 gboolean is_geometry);
376 static void update_themed_icon (GtkIconTheme *theme,
378 static GList *icon_list_from_theme (GtkWidget *widget,
380 static void gtk_window_realize_icon (GtkWindow *window);
381 static void gtk_window_unrealize_icon (GtkWindow *window);
383 static void gtk_window_notify_keys_changed (GtkWindow *window);
384 static GtkKeyHash *gtk_window_get_key_hash (GtkWindow *window);
385 static void gtk_window_free_key_hash (GtkWindow *window);
386 static void gtk_window_on_composited_changed (GdkScreen *screen,
389 static GSList *toplevel_list = NULL;
390 static guint window_signals[LAST_SIGNAL] = { 0 };
391 static GList *default_icon_list = NULL;
392 static gchar *default_icon_name = NULL;
393 static guint default_icon_serial = 0;
394 static gboolean disable_startup_notification = FALSE;
395 static gboolean sent_startup_notification = FALSE;
397 static GQuark quark_gtk_embedded = 0;
398 static GQuark quark_gtk_window_key_hash = 0;
399 static GQuark quark_gtk_window_icon_info = 0;
400 static GQuark quark_gtk_buildable_accels = 0;
402 static GtkBuildableIface *parent_buildable_iface;
404 static void gtk_window_set_property (GObject *object,
408 static void gtk_window_get_property (GObject *object,
414 static void gtk_window_buildable_interface_init (GtkBuildableIface *iface);
415 static void gtk_window_buildable_set_buildable_property (GtkBuildable *buildable,
418 const GValue *value);
419 static void gtk_window_buildable_parser_finished (GtkBuildable *buildable,
420 GtkBuilder *builder);
421 static gboolean gtk_window_buildable_custom_tag_start (GtkBuildable *buildable,
424 const gchar *tagname,
425 GMarkupParser *parser,
427 static void gtk_window_buildable_custom_finished (GtkBuildable *buildable,
430 const gchar *tagname,
434 static void gtk_window_get_preferred_width (GtkWidget *widget,
437 static void gtk_window_get_preferred_height (GtkWidget *widget,
441 G_DEFINE_TYPE_WITH_CODE (GtkWindow, gtk_window, GTK_TYPE_BIN,
442 G_IMPLEMENT_INTERFACE (GTK_TYPE_BUILDABLE,
443 gtk_window_buildable_interface_init))
446 add_tab_bindings (GtkBindingSet *binding_set,
447 GdkModifierType modifiers,
448 GtkDirectionType direction)
450 gtk_binding_entry_add_signal (binding_set, GDK_KEY_Tab, modifiers,
452 GTK_TYPE_DIRECTION_TYPE, direction);
453 gtk_binding_entry_add_signal (binding_set, GDK_KEY_KP_Tab, modifiers,
455 GTK_TYPE_DIRECTION_TYPE, direction);
459 add_arrow_bindings (GtkBindingSet *binding_set,
461 GtkDirectionType direction)
463 guint keypad_keysym = keysym - GDK_KEY_Left + GDK_KEY_KP_Left;
465 gtk_binding_entry_add_signal (binding_set, keysym, 0,
467 GTK_TYPE_DIRECTION_TYPE, direction);
468 gtk_binding_entry_add_signal (binding_set, keysym, GDK_CONTROL_MASK,
470 GTK_TYPE_DIRECTION_TYPE, direction);
471 gtk_binding_entry_add_signal (binding_set, keypad_keysym, 0,
473 GTK_TYPE_DIRECTION_TYPE, direction);
474 gtk_binding_entry_add_signal (binding_set, keypad_keysym, GDK_CONTROL_MASK,
476 GTK_TYPE_DIRECTION_TYPE, direction);
480 extract_time_from_startup_id (const gchar* startup_id)
482 gchar *timestr = g_strrstr (startup_id, "_TIME");
483 guint32 retval = GDK_CURRENT_TIME;
490 /* Skip past the "_TIME" part */
494 timestamp = strtoul (timestr, &end, 0);
495 if (end != timestr && errno == 0)
503 startup_id_is_fake (const gchar* startup_id)
505 return strncmp (startup_id, "_TIME", 5) == 0;
509 gtk_window_class_init (GtkWindowClass *klass)
511 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
512 GtkWidgetClass *widget_class;
513 GtkContainerClass *container_class;
514 GtkBindingSet *binding_set;
516 widget_class = (GtkWidgetClass*) klass;
517 container_class = (GtkContainerClass*) klass;
519 quark_gtk_embedded = g_quark_from_static_string ("gtk-embedded");
520 quark_gtk_window_key_hash = g_quark_from_static_string ("gtk-window-key-hash");
521 quark_gtk_window_icon_info = g_quark_from_static_string ("gtk-window-icon-info");
522 quark_gtk_buildable_accels = g_quark_from_static_string ("gtk-window-buildable-accels");
524 gobject_class->dispose = gtk_window_dispose;
525 gobject_class->finalize = gtk_window_finalize;
527 gobject_class->set_property = gtk_window_set_property;
528 gobject_class->get_property = gtk_window_get_property;
530 widget_class->destroy = gtk_window_destroy;
531 widget_class->show = gtk_window_show;
532 widget_class->hide = gtk_window_hide;
533 widget_class->map = gtk_window_map;
534 widget_class->map_event = gtk_window_map_event;
535 widget_class->unmap = gtk_window_unmap;
536 widget_class->realize = gtk_window_realize;
537 widget_class->unrealize = gtk_window_unrealize;
538 widget_class->size_allocate = gtk_window_size_allocate;
539 widget_class->configure_event = gtk_window_configure_event;
540 widget_class->key_press_event = gtk_window_key_press_event;
541 widget_class->key_release_event = gtk_window_key_release_event;
542 widget_class->enter_notify_event = gtk_window_enter_notify_event;
543 widget_class->leave_notify_event = gtk_window_leave_notify_event;
544 widget_class->focus_in_event = gtk_window_focus_in_event;
545 widget_class->focus_out_event = gtk_window_focus_out_event;
546 widget_class->client_event = gtk_window_client_event;
547 widget_class->focus = gtk_window_focus;
548 widget_class->draw = gtk_window_draw;
549 widget_class->get_preferred_width = gtk_window_get_preferred_width;
550 widget_class->get_preferred_height = gtk_window_get_preferred_height;
552 container_class->check_resize = gtk_window_check_resize;
554 klass->set_focus = gtk_window_real_set_focus;
555 klass->frame_event = gtk_window_frame_event;
557 klass->activate_default = gtk_window_real_activate_default;
558 klass->activate_focus = gtk_window_real_activate_focus;
559 klass->move_focus = gtk_window_move_focus;
560 klass->keys_changed = gtk_window_keys_changed;
562 g_type_class_add_private (gobject_class, sizeof (GtkWindowPrivate));
565 g_object_class_install_property (gobject_class,
567 g_param_spec_enum ("type",
569 P_("The type of the window"),
570 GTK_TYPE_WINDOW_TYPE,
572 GTK_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
574 g_object_class_install_property (gobject_class,
576 g_param_spec_string ("title",
578 P_("The title of the window"),
580 GTK_PARAM_READWRITE));
582 g_object_class_install_property (gobject_class,
584 g_param_spec_string ("role",
586 P_("Unique identifier for the window to be used when restoring a session"),
588 GTK_PARAM_READWRITE));
591 * GtkWindow:startup-id:
593 * The :startup-id is a write-only property for setting window's
594 * startup notification identifier. See gtk_window_set_startup_id()
599 g_object_class_install_property (gobject_class,
601 g_param_spec_string ("startup-id",
603 P_("Unique startup identifier for the window used by startup-notification"),
605 GTK_PARAM_WRITABLE));
607 g_object_class_install_property (gobject_class,
609 g_param_spec_boolean ("resizable",
611 P_("If TRUE, users can resize the window"),
613 GTK_PARAM_READWRITE));
615 g_object_class_install_property (gobject_class,
617 g_param_spec_boolean ("modal",
619 P_("If TRUE, the window is modal (other windows are not usable while this one is up)"),
621 GTK_PARAM_READWRITE));
623 g_object_class_install_property (gobject_class,
625 g_param_spec_enum ("window-position",
626 P_("Window Position"),
627 P_("The initial position of the window"),
628 GTK_TYPE_WINDOW_POSITION,
630 GTK_PARAM_READWRITE));
632 g_object_class_install_property (gobject_class,
634 g_param_spec_int ("default-width",
636 P_("The default width of the window, used when initially showing the window"),
640 GTK_PARAM_READWRITE));
642 g_object_class_install_property (gobject_class,
644 g_param_spec_int ("default-height",
645 P_("Default Height"),
646 P_("The default height of the window, used when initially showing the window"),
650 GTK_PARAM_READWRITE));
652 g_object_class_install_property (gobject_class,
653 PROP_DESTROY_WITH_PARENT,
654 g_param_spec_boolean ("destroy-with-parent",
655 P_("Destroy with Parent"),
656 P_("If this window should be destroyed when the parent is destroyed"),
658 GTK_PARAM_READWRITE));
660 g_object_class_install_property (gobject_class,
662 g_param_spec_object ("icon",
664 P_("Icon for this window"),
666 GTK_PARAM_READWRITE));
667 g_object_class_install_property (gobject_class,
668 PROP_MNEMONICS_VISIBLE,
669 g_param_spec_boolean ("mnemonics-visible",
670 P_("Mnemonics Visible"),
671 P_("Whether mnemonics are currently visible in this window"),
673 GTK_PARAM_READWRITE));
676 * GtkWindow:icon-name:
678 * The :icon-name property specifies the name of the themed icon to
679 * use as the window icon. See #GtkIconTheme for more details.
683 g_object_class_install_property (gobject_class,
685 g_param_spec_string ("icon-name",
687 P_("Name of the themed icon for this window"),
689 GTK_PARAM_READWRITE));
691 g_object_class_install_property (gobject_class,
693 g_param_spec_object ("screen",
695 P_("The screen where this window will be displayed"),
697 GTK_PARAM_READWRITE));
702 * Specifies the visual used to create the window with. See gtk_window_set_visual()
705 g_object_class_install_property (gobject_class,
707 g_param_spec_object ("visual",
709 P_("The visual this window is created from"),
711 GTK_PARAM_READWRITE));
713 g_object_class_install_property (gobject_class,
715 g_param_spec_boolean ("is-active",
717 P_("Whether the toplevel is the current active window"),
719 GTK_PARAM_READABLE));
721 g_object_class_install_property (gobject_class,
722 PROP_HAS_TOPLEVEL_FOCUS,
723 g_param_spec_boolean ("has-toplevel-focus",
724 P_("Focus in Toplevel"),
725 P_("Whether the input focus is within this GtkWindow"),
727 GTK_PARAM_READABLE));
729 g_object_class_install_property (gobject_class,
731 g_param_spec_enum ("type-hint",
733 P_("Hint to help the desktop environment understand what kind of window this is and how to treat it."),
734 GDK_TYPE_WINDOW_TYPE_HINT,
735 GDK_WINDOW_TYPE_HINT_NORMAL,
736 GTK_PARAM_READWRITE));
738 g_object_class_install_property (gobject_class,
739 PROP_SKIP_TASKBAR_HINT,
740 g_param_spec_boolean ("skip-taskbar-hint",
742 P_("TRUE if the window should not be in the task bar."),
744 GTK_PARAM_READWRITE));
746 g_object_class_install_property (gobject_class,
747 PROP_SKIP_PAGER_HINT,
748 g_param_spec_boolean ("skip-pager-hint",
750 P_("TRUE if the window should not be in the pager."),
752 GTK_PARAM_READWRITE));
754 g_object_class_install_property (gobject_class,
756 g_param_spec_boolean ("urgency-hint",
758 P_("TRUE if the window should be brought to the user's attention."),
760 GTK_PARAM_READWRITE));
763 * GtkWindow:accept-focus:
765 * Whether the window should receive the input focus.
769 g_object_class_install_property (gobject_class,
771 g_param_spec_boolean ("accept-focus",
773 P_("TRUE if the window should receive the input focus."),
775 GTK_PARAM_READWRITE));
778 * GtkWindow:focus-on-map:
780 * Whether the window should receive the input focus when mapped.
784 g_object_class_install_property (gobject_class,
786 g_param_spec_boolean ("focus-on-map",
788 P_("TRUE if the window should receive the input focus when mapped."),
790 GTK_PARAM_READWRITE));
793 * GtkWindow:decorated:
795 * Whether the window should be decorated by the window manager.
799 g_object_class_install_property (gobject_class,
801 g_param_spec_boolean ("decorated",
803 P_("Whether the window should be decorated by the window manager"),
805 GTK_PARAM_READWRITE));
808 * GtkWindow:deletable:
810 * Whether the window frame should have a close button.
814 g_object_class_install_property (gobject_class,
816 g_param_spec_boolean ("deletable",
818 P_("Whether the window frame should have a close button"),
820 GTK_PARAM_READWRITE));
826 * The window gravity of the window. See gtk_window_move() and #GdkGravity for
827 * more details about window gravity.
831 g_object_class_install_property (gobject_class,
833 g_param_spec_enum ("gravity",
835 P_("The window gravity of the window"),
837 GDK_GRAVITY_NORTH_WEST,
838 GTK_PARAM_READWRITE));
842 * GtkWindow:transient-for:
844 * The transient parent of the window. See gtk_window_set_transient_for() for
845 * more details about transient windows.
849 g_object_class_install_property (gobject_class,
851 g_param_spec_object ("transient-for",
852 P_("Transient for Window"),
853 P_("The transient parent of the dialog"),
855 GTK_PARAM_READWRITE| G_PARAM_CONSTRUCT));
860 * The requested opacity of the window. See gtk_window_set_opacity() for
861 * more details about window opacity.
865 g_object_class_install_property (gobject_class,
867 g_param_spec_double ("opacity",
868 P_("Opacity for Window"),
869 P_("The opacity of the window, from 0 to 1"),
873 GTK_PARAM_READWRITE));
875 window_signals[SET_FOCUS] =
876 g_signal_new (I_("set-focus"),
877 G_TYPE_FROM_CLASS (gobject_class),
879 G_STRUCT_OFFSET (GtkWindowClass, set_focus),
881 _gtk_marshal_VOID__OBJECT,
885 window_signals[FRAME_EVENT] =
886 g_signal_new (I_("frame-event"),
887 G_TYPE_FROM_CLASS (gobject_class),
889 G_STRUCT_OFFSET(GtkWindowClass, frame_event),
890 _gtk_boolean_handled_accumulator, NULL,
891 _gtk_marshal_BOOLEAN__BOXED,
896 * GtkWindow::activate-focus:
897 * @window: the window which received the signal
899 * The ::activate-focus signal is a
900 * <link linkend="keybinding-signals">keybinding signal</link>
901 * which gets emitted when the user activates the currently
902 * focused widget of @window.
904 window_signals[ACTIVATE_FOCUS] =
905 g_signal_new (I_("activate-focus"),
906 G_TYPE_FROM_CLASS (gobject_class),
907 G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
908 G_STRUCT_OFFSET (GtkWindowClass, activate_focus),
910 _gtk_marshal_VOID__VOID,
915 * GtkWindow::activate-default:
916 * @window: the window which received the signal
918 * The ::activate-default signal is a
919 * <link linkend="keybinding-signals">keybinding signal</link>
920 * which gets emitted when the user activates the default widget
923 window_signals[ACTIVATE_DEFAULT] =
924 g_signal_new (I_("activate-default"),
925 G_TYPE_FROM_CLASS (gobject_class),
926 G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
927 G_STRUCT_OFFSET (GtkWindowClass, activate_default),
929 _gtk_marshal_VOID__VOID,
934 * GtkWindow::keys-changed:
935 * @window: the window which received the signal
937 * The ::keys-changed signal gets emitted when the set of accelerators
938 * or mnemonics that are associated with @window changes.
940 window_signals[KEYS_CHANGED] =
941 g_signal_new (I_("keys-changed"),
942 G_TYPE_FROM_CLASS (gobject_class),
944 G_STRUCT_OFFSET (GtkWindowClass, keys_changed),
946 _gtk_marshal_VOID__VOID,
954 binding_set = gtk_binding_set_by_class (klass);
956 gtk_binding_entry_add_signal (binding_set, GDK_KEY_space, 0,
957 "activate-focus", 0);
958 gtk_binding_entry_add_signal (binding_set, GDK_KEY_KP_Space, 0,
959 "activate-focus", 0);
961 gtk_binding_entry_add_signal (binding_set, GDK_KEY_Return, 0,
962 "activate-default", 0);
963 gtk_binding_entry_add_signal (binding_set, GDK_KEY_ISO_Enter, 0,
964 "activate-default", 0);
965 gtk_binding_entry_add_signal (binding_set, GDK_KEY_KP_Enter, 0,
966 "activate-default", 0);
968 add_arrow_bindings (binding_set, GDK_KEY_Up, GTK_DIR_UP);
969 add_arrow_bindings (binding_set, GDK_KEY_Down, GTK_DIR_DOWN);
970 add_arrow_bindings (binding_set, GDK_KEY_Left, GTK_DIR_LEFT);
971 add_arrow_bindings (binding_set, GDK_KEY_Right, GTK_DIR_RIGHT);
973 add_tab_bindings (binding_set, 0, GTK_DIR_TAB_FORWARD);
974 add_tab_bindings (binding_set, GDK_CONTROL_MASK, GTK_DIR_TAB_FORWARD);
975 add_tab_bindings (binding_set, GDK_SHIFT_MASK, GTK_DIR_TAB_BACKWARD);
976 add_tab_bindings (binding_set, GDK_CONTROL_MASK | GDK_SHIFT_MASK, GTK_DIR_TAB_BACKWARD);
980 gtk_window_init (GtkWindow *window)
982 GtkWindowPrivate *priv;
984 window->priv = G_TYPE_INSTANCE_GET_PRIVATE (window,
989 gtk_widget_set_has_window (GTK_WIDGET (window), TRUE);
990 _gtk_widget_set_is_toplevel (GTK_WIDGET (window), TRUE);
992 GTK_PRIVATE_SET_FLAG (window, GTK_ANCHORED);
994 gtk_container_set_resize_mode (GTK_CONTAINER (window), GTK_RESIZE_QUEUE);
997 priv->wmclass_name = g_strdup (g_get_prgname ());
998 priv->wmclass_class = g_strdup (gdk_get_program_class ());
999 priv->wm_role = NULL;
1000 priv->geometry_info = NULL;
1001 priv->type = GTK_WINDOW_TOPLEVEL;
1002 priv->focus_widget = NULL;
1003 priv->default_widget = NULL;
1004 priv->configure_request_count = 0;
1005 priv->resizable = TRUE;
1006 priv->configure_notify_received = FALSE;
1007 priv->position = GTK_WIN_POS_NONE;
1008 priv->need_default_size = TRUE;
1009 priv->need_default_position = TRUE;
1010 priv->modal = FALSE;
1012 priv->has_frame = FALSE;
1013 priv->frame_left = 0;
1014 priv->frame_right = 0;
1015 priv->frame_top = 0;
1016 priv->frame_bottom = 0;
1017 priv->gdk_type_hint = GDK_WINDOW_TYPE_HINT_NORMAL;
1018 priv->gravity = GDK_GRAVITY_NORTH_WEST;
1019 priv->decorated = TRUE;
1020 priv->mnemonic_modifier = GDK_MOD1_MASK;
1021 priv->visual = gdk_screen_get_system_visual (gdk_screen_get_default ());
1023 priv->accept_focus = TRUE;
1024 priv->focus_on_map = TRUE;
1025 priv->deletable = TRUE;
1026 priv->type_hint = GDK_WINDOW_TYPE_HINT_NORMAL;
1027 priv->opacity = 1.0;
1028 priv->startup_id = NULL;
1029 priv->mnemonics_visible = TRUE;
1031 g_object_ref_sink (window);
1032 priv->has_user_ref_count = TRUE;
1033 toplevel_list = g_slist_prepend (toplevel_list, window);
1035 gtk_decorated_window_init (window);
1037 g_signal_connect (gdk_screen_get_default (), "composited-changed",
1038 G_CALLBACK (gtk_window_on_composited_changed), window);
1042 gtk_window_set_property (GObject *object,
1044 const GValue *value,
1047 GtkWindow *window = GTK_WINDOW (object);
1048 GtkWindowPrivate *priv = window->priv;
1053 priv->type = g_value_get_enum (value);
1056 gtk_window_set_title (window, g_value_get_string (value));
1059 gtk_window_set_role (window, g_value_get_string (value));
1061 case PROP_STARTUP_ID:
1062 gtk_window_set_startup_id (window, g_value_get_string (value));
1064 case PROP_RESIZABLE:
1065 priv->resizable = g_value_get_boolean (value);
1066 gtk_widget_queue_resize (GTK_WIDGET (window));
1069 gtk_window_set_modal (window, g_value_get_boolean (value));
1072 gtk_window_set_position (window, g_value_get_enum (value));
1074 case PROP_DEFAULT_WIDTH:
1075 gtk_window_set_default_size_internal (window,
1076 TRUE, g_value_get_int (value),
1079 case PROP_DEFAULT_HEIGHT:
1080 gtk_window_set_default_size_internal (window,
1082 TRUE, g_value_get_int (value), FALSE);
1084 case PROP_DESTROY_WITH_PARENT:
1085 gtk_window_set_destroy_with_parent (window, g_value_get_boolean (value));
1088 gtk_window_set_icon (window,
1089 g_value_get_object (value));
1091 case PROP_ICON_NAME:
1092 gtk_window_set_icon_name (window, g_value_get_string (value));
1095 gtk_window_set_screen (window, g_value_get_object (value));
1098 gtk_window_set_visual (window, g_value_get_object (value));
1100 case PROP_TYPE_HINT:
1101 gtk_window_set_type_hint (window,
1102 g_value_get_enum (value));
1104 case PROP_SKIP_TASKBAR_HINT:
1105 gtk_window_set_skip_taskbar_hint (window,
1106 g_value_get_boolean (value));
1108 case PROP_SKIP_PAGER_HINT:
1109 gtk_window_set_skip_pager_hint (window,
1110 g_value_get_boolean (value));
1112 case PROP_URGENCY_HINT:
1113 gtk_window_set_urgency_hint (window,
1114 g_value_get_boolean (value));
1116 case PROP_ACCEPT_FOCUS:
1117 gtk_window_set_accept_focus (window,
1118 g_value_get_boolean (value));
1120 case PROP_FOCUS_ON_MAP:
1121 gtk_window_set_focus_on_map (window,
1122 g_value_get_boolean (value));
1124 case PROP_DECORATED:
1125 gtk_window_set_decorated (window, g_value_get_boolean (value));
1127 case PROP_DELETABLE:
1128 gtk_window_set_deletable (window, g_value_get_boolean (value));
1131 gtk_window_set_gravity (window, g_value_get_enum (value));
1133 case PROP_TRANSIENT_FOR:
1134 gtk_window_set_transient_for (window, g_value_get_object (value));
1137 gtk_window_set_opacity (window, g_value_get_double (value));
1139 case PROP_MNEMONICS_VISIBLE:
1140 gtk_window_set_mnemonics_visible (window, g_value_get_boolean (value));
1143 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1149 gtk_window_get_property (GObject *object,
1154 GtkWindow *window = GTK_WINDOW (object);
1155 GtkWindowPrivate *priv = window->priv;
1159 GtkWindowGeometryInfo *info;
1161 g_value_set_enum (value, priv->type);
1164 g_value_set_string (value, priv->wm_role);
1167 g_value_set_string (value, priv->title);
1169 case PROP_RESIZABLE:
1170 g_value_set_boolean (value, priv->resizable);
1173 g_value_set_boolean (value, priv->modal);
1176 g_value_set_enum (value, priv->position);
1178 case PROP_DEFAULT_WIDTH:
1179 info = gtk_window_get_geometry_info (window, FALSE);
1181 g_value_set_int (value, -1);
1183 g_value_set_int (value, info->default_width);
1185 case PROP_DEFAULT_HEIGHT:
1186 info = gtk_window_get_geometry_info (window, FALSE);
1188 g_value_set_int (value, -1);
1190 g_value_set_int (value, info->default_height);
1192 case PROP_DESTROY_WITH_PARENT:
1193 g_value_set_boolean (value, priv->destroy_with_parent);
1196 g_value_set_object (value, gtk_window_get_icon (window));
1198 case PROP_ICON_NAME:
1199 g_value_set_string (value, gtk_window_get_icon_name (window));
1202 g_value_set_object (value, gdk_visual_get_screen (priv->visual));
1205 g_value_set_object (value, priv->visual);
1207 case PROP_IS_ACTIVE:
1208 g_value_set_boolean (value, priv->is_active);
1210 case PROP_HAS_TOPLEVEL_FOCUS:
1211 g_value_set_boolean (value, priv->has_toplevel_focus);
1213 case PROP_TYPE_HINT:
1214 g_value_set_enum (value, priv->type_hint);
1216 case PROP_SKIP_TASKBAR_HINT:
1217 g_value_set_boolean (value,
1218 gtk_window_get_skip_taskbar_hint (window));
1220 case PROP_SKIP_PAGER_HINT:
1221 g_value_set_boolean (value,
1222 gtk_window_get_skip_pager_hint (window));
1224 case PROP_URGENCY_HINT:
1225 g_value_set_boolean (value,
1226 gtk_window_get_urgency_hint (window));
1228 case PROP_ACCEPT_FOCUS:
1229 g_value_set_boolean (value,
1230 gtk_window_get_accept_focus (window));
1232 case PROP_FOCUS_ON_MAP:
1233 g_value_set_boolean (value,
1234 gtk_window_get_focus_on_map (window));
1236 case PROP_DECORATED:
1237 g_value_set_boolean (value, gtk_window_get_decorated (window));
1239 case PROP_DELETABLE:
1240 g_value_set_boolean (value, gtk_window_get_deletable (window));
1243 g_value_set_enum (value, gtk_window_get_gravity (window));
1245 case PROP_TRANSIENT_FOR:
1246 g_value_set_object (value, gtk_window_get_transient_for (window));
1249 g_value_set_double (value, gtk_window_get_opacity (window));
1251 case PROP_MNEMONICS_VISIBLE:
1252 g_value_set_boolean (value, priv->mnemonics_visible);
1255 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1261 gtk_window_buildable_interface_init (GtkBuildableIface *iface)
1263 parent_buildable_iface = g_type_interface_peek_parent (iface);
1264 iface->set_buildable_property = gtk_window_buildable_set_buildable_property;
1265 iface->parser_finished = gtk_window_buildable_parser_finished;
1266 iface->custom_tag_start = gtk_window_buildable_custom_tag_start;
1267 iface->custom_finished = gtk_window_buildable_custom_finished;
1271 gtk_window_buildable_set_buildable_property (GtkBuildable *buildable,
1272 GtkBuilder *builder,
1274 const GValue *value)
1276 GtkWindow *window = GTK_WINDOW (buildable);
1277 GtkWindowPrivate *priv = window->priv;
1279 if (strcmp (name, "visible") == 0 && g_value_get_boolean (value))
1280 priv->builder_visible = TRUE;
1282 parent_buildable_iface->set_buildable_property (buildable, builder, name, value);
1286 gtk_window_buildable_parser_finished (GtkBuildable *buildable,
1287 GtkBuilder *builder)
1289 GtkWindow *window = GTK_WINDOW (buildable);
1290 GtkWindowPrivate *priv = window->priv;
1294 if (priv->builder_visible)
1295 gtk_widget_show (GTK_WIDGET (buildable));
1297 accels = g_object_get_qdata (G_OBJECT (buildable), quark_gtk_buildable_accels);
1298 for (l = accels; l; l = l->next)
1300 object = gtk_builder_get_object (builder, l->data);
1303 g_warning ("Unknown accel group %s specified in window %s",
1304 (const gchar*)l->data, gtk_buildable_get_name (buildable));
1307 gtk_window_add_accel_group (GTK_WINDOW (buildable),
1308 GTK_ACCEL_GROUP (object));
1312 g_object_set_qdata (G_OBJECT (buildable), quark_gtk_buildable_accels, NULL);
1314 parent_buildable_iface->parser_finished (buildable, builder);
1320 } GSListSubParserData;
1323 window_start_element (GMarkupParseContext *context,
1324 const gchar *element_name,
1325 const gchar **names,
1326 const gchar **values,
1331 GSListSubParserData *data = (GSListSubParserData*)user_data;
1333 if (strcmp (element_name, "group") == 0)
1335 for (i = 0; names[i]; i++)
1337 if (strcmp (names[i], "name") == 0)
1338 data->items = g_slist_prepend (data->items, g_strdup (values[i]));
1341 else if (strcmp (element_name, "accel-groups") == 0)
1344 g_warning ("Unsupported tag type for GtkWindow: %s\n",
1349 static const GMarkupParser window_parser =
1351 window_start_element
1355 gtk_window_buildable_custom_tag_start (GtkBuildable *buildable,
1356 GtkBuilder *builder,
1358 const gchar *tagname,
1359 GMarkupParser *parser,
1362 GSListSubParserData *parser_data;
1364 if (parent_buildable_iface->custom_tag_start (buildable, builder, child,
1365 tagname, parser, data))
1368 if (strcmp (tagname, "accel-groups") == 0)
1370 parser_data = g_slice_new0 (GSListSubParserData);
1371 parser_data->items = NULL;
1372 parser_data->object = G_OBJECT (buildable);
1374 *parser = window_parser;
1375 *data = parser_data;
1383 gtk_window_buildable_custom_finished (GtkBuildable *buildable,
1384 GtkBuilder *builder,
1386 const gchar *tagname,
1389 GSListSubParserData *data;
1391 parent_buildable_iface->custom_finished (buildable, builder, child,
1392 tagname, user_data);
1394 if (strcmp (tagname, "accel-groups") != 0)
1397 data = (GSListSubParserData*)user_data;
1399 g_object_set_qdata_full (G_OBJECT (buildable), quark_gtk_buildable_accels,
1400 data->items, (GDestroyNotify) g_slist_free);
1402 g_slice_free (GSListSubParserData, data);
1407 * @type: type of window
1409 * Creates a new #GtkWindow, which is a toplevel window that can
1410 * contain other widgets. Nearly always, the type of the window should
1411 * be #GTK_WINDOW_TOPLEVEL. If you're implementing something like a
1412 * popup menu from scratch (which is a bad idea, just use #GtkMenu),
1413 * you might use #GTK_WINDOW_POPUP. #GTK_WINDOW_POPUP is not for
1414 * dialogs, though in some other toolkits dialogs are called "popups".
1415 * In GTK+, #GTK_WINDOW_POPUP means a pop-up menu or pop-up tooltip.
1416 * On X11, popup windows are not controlled by the <link
1417 * linkend="gtk-X11-arch">window manager</link>.
1419 * If you simply want an undecorated window (no window borders), use
1420 * gtk_window_set_decorated(), don't use #GTK_WINDOW_POPUP.
1422 * Return value: a new #GtkWindow.
1425 gtk_window_new (GtkWindowType type)
1427 GtkWindowPrivate *priv;
1430 g_return_val_if_fail (type >= GTK_WINDOW_TOPLEVEL && type <= GTK_WINDOW_POPUP, NULL);
1432 window = g_object_new (GTK_TYPE_WINDOW, NULL);
1433 priv = window->priv;
1437 return GTK_WIDGET (window);
1441 * gtk_window_set_title:
1442 * @window: a #GtkWindow
1443 * @title: title of the window
1445 * Sets the title of the #GtkWindow. The title of a window will be
1446 * displayed in its title bar; on the X Window System, the title bar
1447 * is rendered by the <link linkend="gtk-X11-arch">window
1448 * manager</link>, so exactly how the title appears to users may vary
1449 * according to a user's exact configuration. The title should help a
1450 * user distinguish this window from other windows they may have
1451 * open. A good title might include the application name and current
1452 * document filename, for example.
1456 gtk_window_set_title (GtkWindow *window,
1459 GtkWindowPrivate *priv;
1463 g_return_if_fail (GTK_IS_WINDOW (window));
1465 priv = window->priv;
1466 widget = GTK_WIDGET (window);
1468 new_title = g_strdup (title);
1469 g_free (priv->title);
1470 priv->title = new_title;
1472 if (gtk_widget_get_realized (widget))
1474 gdk_window_set_title (gtk_widget_get_window (widget),
1477 gtk_decorated_window_set_title (window, title);
1480 g_object_notify (G_OBJECT (window), "title");
1484 * gtk_window_get_title:
1485 * @window: a #GtkWindow
1487 * Retrieves the title of the window. See gtk_window_set_title().
1489 * Return value: the title of the window, or %NULL if none has
1490 * been set explicitely. The returned string is owned by the widget
1491 * and must not be modified or freed.
1493 G_CONST_RETURN gchar *
1494 gtk_window_get_title (GtkWindow *window)
1496 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
1498 return window->priv->title;
1502 * gtk_window_set_wmclass:
1503 * @window: a #GtkWindow
1504 * @wmclass_name: window name hint
1505 * @wmclass_class: window class hint
1507 * Don't use this function. It sets the X Window System "class" and
1508 * "name" hints for a window. According to the ICCCM, you should
1509 * always set these to the same value for all windows in an
1510 * application, and GTK+ sets them to that value by default, so calling
1511 * this function is sort of pointless. However, you may want to call
1512 * gtk_window_set_role() on each window in your application, for the
1513 * benefit of the session manager. Setting the role allows the window
1514 * manager to restore window positions when loading a saved session.
1518 gtk_window_set_wmclass (GtkWindow *window,
1519 const gchar *wmclass_name,
1520 const gchar *wmclass_class)
1522 GtkWindowPrivate *priv;
1524 g_return_if_fail (GTK_IS_WINDOW (window));
1526 priv = window->priv;
1528 g_free (priv->wmclass_name);
1529 priv->wmclass_name = g_strdup (wmclass_name);
1531 g_free (priv->wmclass_class);
1532 priv->wmclass_class = g_strdup (wmclass_class);
1534 if (gtk_widget_get_realized (GTK_WIDGET (window)))
1535 g_warning ("gtk_window_set_wmclass: shouldn't set wmclass after window is realized!\n");
1539 * gtk_window_set_role:
1540 * @window: a #GtkWindow
1541 * @role: unique identifier for the window to be used when restoring a session
1543 * This function is only useful on X11, not with other GTK+ targets.
1545 * In combination with the window title, the window role allows a
1546 * <link linkend="gtk-X11-arch">window manager</link> to identify "the
1547 * same" window when an application is restarted. So for example you
1548 * might set the "toolbox" role on your app's toolbox window, so that
1549 * when the user restarts their session, the window manager can put
1550 * the toolbox back in the same place.
1552 * If a window already has a unique title, you don't need to set the
1553 * role, since the WM can use the title to identify the window when
1554 * restoring the session.
1558 gtk_window_set_role (GtkWindow *window,
1561 GtkWindowPrivate *priv;
1564 g_return_if_fail (GTK_IS_WINDOW (window));
1566 priv = window->priv;
1568 new_role = g_strdup (role);
1569 g_free (priv->wm_role);
1570 priv->wm_role = new_role;
1572 if (gtk_widget_get_realized (GTK_WIDGET (window)))
1573 gdk_window_set_role (gtk_widget_get_window (GTK_WIDGET (window)),
1576 g_object_notify (G_OBJECT (window), "role");
1580 * gtk_window_set_startup_id:
1581 * @window: a #GtkWindow
1582 * @startup_id: a string with startup-notification identifier
1584 * Startup notification identifiers are used by desktop environment to
1585 * track application startup, to provide user feedback and other
1586 * features. This function changes the corresponding property on the
1587 * underlying GdkWindow. Normally, startup identifier is managed
1588 * automatically and you should only use this function in special cases
1589 * like transferring focus from other processes. You should use this
1590 * function before calling gtk_window_present() or any equivalent
1591 * function generating a window map event.
1593 * This function is only useful on X11, not with other GTK+ targets.
1598 gtk_window_set_startup_id (GtkWindow *window,
1599 const gchar *startup_id)
1601 GtkWindowPrivate *priv;
1604 g_return_if_fail (GTK_IS_WINDOW (window));
1606 priv = window->priv;
1607 widget = GTK_WIDGET (window);
1609 g_free (priv->startup_id);
1610 priv->startup_id = g_strdup (startup_id);
1612 if (gtk_widget_get_realized (widget))
1614 GdkWindow *gdk_window;
1615 guint32 timestamp = extract_time_from_startup_id (priv->startup_id);
1617 gdk_window = gtk_widget_get_window (widget);
1619 #ifdef GDK_WINDOWING_X11
1620 if (timestamp != GDK_CURRENT_TIME)
1621 gdk_x11_window_set_user_time (gdk_window, timestamp);
1624 /* Here we differentiate real and "fake" startup notification IDs,
1625 * constructed on purpose just to pass interaction timestamp
1627 if (startup_id_is_fake (priv->startup_id))
1628 gtk_window_present_with_time (window, timestamp);
1631 gdk_window_set_startup_id (gdk_window,
1634 /* If window is mapped, terminate the startup-notification too */
1635 if (gtk_widget_get_mapped (widget) &&
1636 !disable_startup_notification)
1637 gdk_notify_startup_complete_with_id (priv->startup_id);
1641 g_object_notify (G_OBJECT (window), "startup-id");
1645 * gtk_window_get_role:
1646 * @window: a #GtkWindow
1648 * Returns the role of the window. See gtk_window_set_role() for
1649 * further explanation.
1651 * Return value: the role of the window if set, or %NULL. The
1652 * returned is owned by the widget and must not be modified
1655 G_CONST_RETURN gchar *
1656 gtk_window_get_role (GtkWindow *window)
1658 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
1660 return window->priv->wm_role;
1664 * gtk_window_set_focus:
1665 * @window: a #GtkWindow
1666 * @focus: (allow-none): widget to be the new focus widget, or %NULL to unset
1667 * any focus widget for the toplevel window.
1669 * If @focus is not the current focus widget, and is focusable, sets
1670 * it as the focus widget for the window. If @focus is %NULL, unsets
1671 * the focus widget for this window. To set the focus to a particular
1672 * widget in the toplevel, it is usually more convenient to use
1673 * gtk_widget_grab_focus() instead of this function.
1676 gtk_window_set_focus (GtkWindow *window,
1679 GtkWindowPrivate *priv;
1682 g_return_if_fail (GTK_IS_WINDOW (window));
1684 priv = window->priv;
1688 g_return_if_fail (GTK_IS_WIDGET (focus));
1689 g_return_if_fail (gtk_widget_get_can_focus (focus));
1693 gtk_widget_grab_focus (focus);
1696 /* Clear the existing focus chain, so that when we focus into
1697 * the window again, we start at the beginnning.
1699 GtkWidget *widget = priv->focus_widget;
1702 while ((parent = gtk_widget_get_parent (widget)))
1705 gtk_container_set_focus_child (GTK_CONTAINER (widget), NULL);
1709 _gtk_window_internal_set_focus (window, NULL);
1714 _gtk_window_internal_set_focus (GtkWindow *window,
1717 GtkWindowPrivate *priv;
1719 g_return_if_fail (GTK_IS_WINDOW (window));
1721 priv = window->priv;
1723 if ((priv->focus_widget != focus) ||
1724 (focus && !gtk_widget_has_focus (focus)))
1725 g_signal_emit (window, window_signals[SET_FOCUS], 0, focus);
1729 * gtk_window_set_default:
1730 * @window: a #GtkWindow
1731 * @default_widget: (allow-none): widget to be the default, or %NULL to unset the
1732 * default widget for the toplevel.
1734 * The default widget is the widget that's activated when the user
1735 * presses Enter in a dialog (for example). This function sets or
1736 * unsets the default widget for a #GtkWindow about. When setting
1737 * (rather than unsetting) the default widget it's generally easier to
1738 * call gtk_widget_grab_focus() on the widget. Before making a widget
1739 * the default widget, you must set the #GTK_CAN_DEFAULT flag on the
1740 * widget you'd like to make the default using GTK_WIDGET_SET_FLAGS().
1743 gtk_window_set_default (GtkWindow *window,
1744 GtkWidget *default_widget)
1746 GtkWindowPrivate *priv;
1748 g_return_if_fail (GTK_IS_WINDOW (window));
1750 priv = window->priv;
1753 g_return_if_fail (gtk_widget_get_can_default (default_widget));
1755 if (priv->default_widget != default_widget)
1757 GtkWidget *old_default_widget = NULL;
1760 g_object_ref (default_widget);
1762 if (priv->default_widget)
1764 old_default_widget = priv->default_widget;
1766 if (priv->focus_widget != priv->default_widget ||
1767 !gtk_widget_get_receives_default (priv->default_widget))
1768 _gtk_widget_set_has_default (priv->default_widget, FALSE);
1770 gtk_widget_queue_draw (priv->default_widget);
1773 priv->default_widget = default_widget;
1775 if (priv->default_widget)
1777 if (priv->focus_widget == NULL ||
1778 !gtk_widget_get_receives_default (priv->focus_widget))
1779 _gtk_widget_set_has_default (priv->default_widget, TRUE);
1781 gtk_widget_queue_draw (priv->default_widget);
1784 if (old_default_widget)
1785 g_object_notify (G_OBJECT (old_default_widget), "has-default");
1789 g_object_notify (G_OBJECT (default_widget), "has-default");
1790 g_object_unref (default_widget);
1796 * gtk_window_get_default_widget:
1797 * @window: a #GtkWindow
1799 * Returns the default widget for @window. See gtk_window_set_default()
1802 * Returns: (transfer none): the default widget, or %NULL if there is none.
1807 gtk_window_get_default_widget (GtkWindow *window)
1809 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
1811 return window->priv->default_widget;
1815 handle_keys_changed (gpointer data)
1817 GtkWindow *window = GTK_WINDOW (data);
1818 GtkWindowPrivate *priv = window->priv;
1820 if (priv->keys_changed_handler)
1822 g_source_remove (priv->keys_changed_handler);
1823 priv->keys_changed_handler = 0;
1826 g_signal_emit (window, window_signals[KEYS_CHANGED], 0);
1832 gtk_window_notify_keys_changed (GtkWindow *window)
1834 GtkWindowPrivate *priv = window->priv;
1836 if (!priv->keys_changed_handler)
1837 priv->keys_changed_handler = gdk_threads_add_idle (handle_keys_changed, window);
1841 * gtk_window_add_accel_group:
1842 * @window: window to attach accelerator group to
1843 * @accel_group: a #GtkAccelGroup
1845 * Associate @accel_group with @window, such that calling
1846 * gtk_accel_groups_activate() on @window will activate accelerators
1850 gtk_window_add_accel_group (GtkWindow *window,
1851 GtkAccelGroup *accel_group)
1853 g_return_if_fail (GTK_IS_WINDOW (window));
1854 g_return_if_fail (GTK_IS_ACCEL_GROUP (accel_group));
1856 _gtk_accel_group_attach (accel_group, G_OBJECT (window));
1857 g_signal_connect_object (accel_group, "accel-changed",
1858 G_CALLBACK (gtk_window_notify_keys_changed),
1859 window, G_CONNECT_SWAPPED);
1860 gtk_window_notify_keys_changed (window);
1864 * gtk_window_remove_accel_group:
1865 * @window: a #GtkWindow
1866 * @accel_group: a #GtkAccelGroup
1868 * Reverses the effects of gtk_window_add_accel_group().
1871 gtk_window_remove_accel_group (GtkWindow *window,
1872 GtkAccelGroup *accel_group)
1874 g_return_if_fail (GTK_IS_WINDOW (window));
1875 g_return_if_fail (GTK_IS_ACCEL_GROUP (accel_group));
1877 g_signal_handlers_disconnect_by_func (accel_group,
1878 gtk_window_notify_keys_changed,
1880 _gtk_accel_group_detach (accel_group, G_OBJECT (window));
1881 gtk_window_notify_keys_changed (window);
1884 static GtkMnemonicHash *
1885 gtk_window_get_mnemonic_hash (GtkWindow *window,
1888 GtkWindowPrivate *private = window->priv;
1890 if (!private->mnemonic_hash && create)
1891 private->mnemonic_hash = _gtk_mnemonic_hash_new ();
1893 return private->mnemonic_hash;
1897 * gtk_window_add_mnemonic:
1898 * @window: a #GtkWindow
1899 * @keyval: the mnemonic
1900 * @target: the widget that gets activated by the mnemonic
1902 * Adds a mnemonic to this window.
1905 gtk_window_add_mnemonic (GtkWindow *window,
1909 g_return_if_fail (GTK_IS_WINDOW (window));
1910 g_return_if_fail (GTK_IS_WIDGET (target));
1912 _gtk_mnemonic_hash_add (gtk_window_get_mnemonic_hash (window, TRUE),
1914 gtk_window_notify_keys_changed (window);
1918 * gtk_window_remove_mnemonic:
1919 * @window: a #GtkWindow
1920 * @keyval: the mnemonic
1921 * @target: the widget that gets activated by the mnemonic
1923 * Removes a mnemonic from this window.
1926 gtk_window_remove_mnemonic (GtkWindow *window,
1930 g_return_if_fail (GTK_IS_WINDOW (window));
1931 g_return_if_fail (GTK_IS_WIDGET (target));
1933 _gtk_mnemonic_hash_remove (gtk_window_get_mnemonic_hash (window, TRUE),
1935 gtk_window_notify_keys_changed (window);
1939 * gtk_window_mnemonic_activate:
1940 * @window: a #GtkWindow
1941 * @keyval: the mnemonic
1942 * @modifier: the modifiers
1943 * @returns: %TRUE if the activation is done.
1945 * Activates the targets associated with the mnemonic.
1948 gtk_window_mnemonic_activate (GtkWindow *window,
1950 GdkModifierType modifier)
1952 GtkWindowPrivate *priv;
1954 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
1956 priv = window->priv;
1958 if (priv->mnemonic_modifier == (modifier & gtk_accelerator_get_default_mod_mask ()))
1960 GtkMnemonicHash *mnemonic_hash = gtk_window_get_mnemonic_hash (window, FALSE);
1962 return _gtk_mnemonic_hash_activate (mnemonic_hash, keyval);
1969 * gtk_window_set_mnemonic_modifier:
1970 * @window: a #GtkWindow
1971 * @modifier: the modifier mask used to activate
1972 * mnemonics on this window.
1974 * Sets the mnemonic modifier for this window.
1977 gtk_window_set_mnemonic_modifier (GtkWindow *window,
1978 GdkModifierType modifier)
1980 GtkWindowPrivate *priv;
1982 g_return_if_fail (GTK_IS_WINDOW (window));
1983 g_return_if_fail ((modifier & ~GDK_MODIFIER_MASK) == 0);
1985 priv = window->priv;
1987 priv->mnemonic_modifier = modifier;
1988 gtk_window_notify_keys_changed (window);
1992 * gtk_window_get_mnemonic_modifier:
1993 * @window: a #GtkWindow
1995 * Returns the mnemonic modifier for this window. See
1996 * gtk_window_set_mnemonic_modifier().
1998 * Return value: the modifier mask used to activate
1999 * mnemonics on this window.
2002 gtk_window_get_mnemonic_modifier (GtkWindow *window)
2004 g_return_val_if_fail (GTK_IS_WINDOW (window), 0);
2006 return window->priv->mnemonic_modifier;
2010 * gtk_window_set_position:
2011 * @window: a #GtkWindow.
2012 * @position: a position constraint.
2014 * Sets a position constraint for this window. If the old or new
2015 * constraint is %GTK_WIN_POS_CENTER_ALWAYS, this will also cause
2016 * the window to be repositioned to satisfy the new constraint.
2019 gtk_window_set_position (GtkWindow *window,
2020 GtkWindowPosition position)
2022 GtkWindowPrivate *priv;
2024 g_return_if_fail (GTK_IS_WINDOW (window));
2026 priv = window->priv;
2028 if (position == GTK_WIN_POS_CENTER_ALWAYS ||
2029 priv->position == GTK_WIN_POS_CENTER_ALWAYS)
2031 GtkWindowGeometryInfo *info;
2033 info = gtk_window_get_geometry_info (window, TRUE);
2035 /* this flag causes us to re-request the CENTER_ALWAYS
2036 * constraint in gtk_window_move_resize(), see
2037 * comment in that function.
2039 info->position_constraints_changed = TRUE;
2041 gtk_widget_queue_resize_no_redraw (GTK_WIDGET (window));
2044 priv->position = position;
2046 g_object_notify (G_OBJECT (window), "window-position");
2050 * gtk_window_activate_focus:
2051 * @window: a #GtkWindow
2053 * Activates the current focused widget within the window.
2055 * Return value: %TRUE if a widget got activated.
2058 gtk_window_activate_focus (GtkWindow *window)
2060 GtkWindowPrivate *priv;
2062 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
2064 priv = window->priv;
2066 if (priv->focus_widget && gtk_widget_is_sensitive (priv->focus_widget))
2067 return gtk_widget_activate (priv->focus_widget);
2073 * gtk_window_get_focus:
2074 * @window: a #GtkWindow
2076 * Retrieves the current focused widget within the window.
2077 * Note that this is the widget that would have the focus
2078 * if the toplevel window focused; if the toplevel window
2079 * is not focused then <literal>gtk_widget_has_focus (widget)</literal> will
2080 * not be %TRUE for the widget.
2082 * Return value: (transfer none): the currently focused widget, or %NULL if there is none.
2085 gtk_window_get_focus (GtkWindow *window)
2087 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
2089 return window->priv->focus_widget;
2093 * gtk_window_activate_default:
2094 * @window: a #GtkWindow
2096 * Activates the default widget for the window, unless the current
2097 * focused widget has been configured to receive the default action
2098 * (see gtk_widget_set_receives_default()), in which case the
2099 * focused widget is activated.
2101 * Return value: %TRUE if a widget got activated.
2104 gtk_window_activate_default (GtkWindow *window)
2106 GtkWindowPrivate *priv;
2108 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
2110 priv = window->priv;
2112 if (priv->default_widget && gtk_widget_is_sensitive (priv->default_widget) &&
2113 (!priv->focus_widget || !gtk_widget_get_receives_default (priv->focus_widget)))
2114 return gtk_widget_activate (priv->default_widget);
2115 else if (priv->focus_widget && gtk_widget_is_sensitive (priv->focus_widget))
2116 return gtk_widget_activate (priv->focus_widget);
2122 * gtk_window_set_modal:
2123 * @window: a #GtkWindow
2124 * @modal: whether the window is modal
2126 * Sets a window modal or non-modal. Modal windows prevent interaction
2127 * with other windows in the same application. To keep modal dialogs
2128 * on top of main application windows, use
2129 * gtk_window_set_transient_for() to make the dialog transient for the
2130 * parent; most <link linkend="gtk-X11-arch">window managers</link>
2131 * will then disallow lowering the dialog below the parent.
2136 gtk_window_set_modal (GtkWindow *window,
2139 GtkWindowPrivate *priv;
2142 g_return_if_fail (GTK_IS_WINDOW (window));
2144 priv = window->priv;
2146 modal = modal != FALSE;
2147 if (priv->modal == modal)
2150 priv->modal = modal;
2151 widget = GTK_WIDGET (window);
2153 /* adjust desired modality state */
2154 if (gtk_widget_get_realized (widget))
2157 gdk_window_set_modal_hint (gtk_widget_get_window (widget), TRUE);
2159 gdk_window_set_modal_hint (gtk_widget_get_window (widget), FALSE);
2162 if (gtk_widget_get_visible (widget))
2165 gtk_grab_add (widget);
2167 gtk_grab_remove (widget);
2170 g_object_notify (G_OBJECT (window), "modal");
2174 * gtk_window_get_modal:
2175 * @window: a #GtkWindow
2177 * Returns whether the window is modal. See gtk_window_set_modal().
2179 * Return value: %TRUE if the window is set to be modal and
2180 * establishes a grab when shown
2183 gtk_window_get_modal (GtkWindow *window)
2185 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
2187 return window->priv->modal;
2191 * gtk_window_list_toplevels:
2193 * Returns a list of all existing toplevel windows. The widgets
2194 * in the list are not individually referenced. If you want
2195 * to iterate through the list and perform actions involving
2196 * callbacks that might destroy the widgets, you <emphasis>must</emphasis> call
2197 * <literal>g_list_foreach (result, (GFunc)g_object_ref, NULL)</literal> first, and
2198 * then unref all the widgets afterwards.
2200 * Return value: (element-type GtkWidget) (transfer container): list of toplevel widgets
2203 gtk_window_list_toplevels (void)
2208 for (slist = toplevel_list; slist; slist = slist->next)
2209 list = g_list_prepend (list, slist->data);
2215 gtk_window_add_embedded_xid (GtkWindow *window, GdkNativeWindow xid)
2217 GList *embedded_windows;
2219 g_return_if_fail (GTK_IS_WINDOW (window));
2221 embedded_windows = g_object_get_qdata (G_OBJECT (window), quark_gtk_embedded);
2222 if (embedded_windows)
2223 g_object_steal_qdata (G_OBJECT (window), quark_gtk_embedded);
2224 embedded_windows = g_list_prepend (embedded_windows,
2225 GUINT_TO_POINTER (xid));
2227 g_object_set_qdata_full (G_OBJECT (window), quark_gtk_embedded,
2230 (GDestroyNotify) g_list_free : NULL);
2234 gtk_window_remove_embedded_xid (GtkWindow *window, GdkNativeWindow xid)
2236 GList *embedded_windows;
2239 g_return_if_fail (GTK_IS_WINDOW (window));
2241 embedded_windows = g_object_get_qdata (G_OBJECT (window), quark_gtk_embedded);
2242 if (embedded_windows)
2243 g_object_steal_qdata (G_OBJECT (window), quark_gtk_embedded);
2245 node = g_list_find (embedded_windows, GUINT_TO_POINTER (xid));
2248 embedded_windows = g_list_remove_link (embedded_windows, node);
2249 g_list_free_1 (node);
2252 g_object_set_qdata_full (G_OBJECT (window), quark_gtk_embedded,
2255 (GDestroyNotify) g_list_free : NULL);
2259 gtk_window_dispose (GObject *object)
2261 GtkWindow *window = GTK_WINDOW (object);
2263 gtk_window_set_focus (window, NULL);
2264 gtk_window_set_default (window, NULL);
2266 G_OBJECT_CLASS (gtk_window_parent_class)->dispose (object);
2270 parent_destroyed_callback (GtkWindow *parent, GtkWindow *child)
2272 gtk_widget_destroy (GTK_WIDGET (child));
2276 connect_parent_destroyed (GtkWindow *window)
2278 GtkWindowPrivate *priv = window->priv;
2280 if (priv->transient_parent)
2282 g_signal_connect (priv->transient_parent,
2284 G_CALLBACK (parent_destroyed_callback),
2290 disconnect_parent_destroyed (GtkWindow *window)
2292 GtkWindowPrivate *priv = window->priv;
2294 if (priv->transient_parent)
2296 g_signal_handlers_disconnect_by_func (priv->transient_parent,
2297 parent_destroyed_callback,
2303 gtk_window_transient_parent_realized (GtkWidget *parent,
2306 if (gtk_widget_get_realized (window))
2307 gdk_window_set_transient_for (gtk_widget_get_window (window),
2308 gtk_widget_get_window (parent));
2312 gtk_window_transient_parent_unrealized (GtkWidget *parent,
2315 if (gtk_widget_get_realized (window))
2316 gdk_property_delete (gtk_widget_get_window (window),
2317 gdk_atom_intern_static_string ("WM_TRANSIENT_FOR"));
2321 gtk_window_transient_parent_screen_changed (GtkWindow *parent,
2325 gtk_window_set_screen (window, gtk_window_get_screen (parent));
2329 gtk_window_unset_transient_for (GtkWindow *window)
2331 GtkWindowPrivate *priv = window->priv;
2333 if (priv->transient_parent)
2335 g_signal_handlers_disconnect_by_func (priv->transient_parent,
2336 gtk_window_transient_parent_realized,
2338 g_signal_handlers_disconnect_by_func (priv->transient_parent,
2339 gtk_window_transient_parent_unrealized,
2341 g_signal_handlers_disconnect_by_func (priv->transient_parent,
2342 gtk_window_transient_parent_screen_changed,
2344 g_signal_handlers_disconnect_by_func (priv->transient_parent,
2345 gtk_widget_destroyed,
2346 &priv->transient_parent);
2348 if (priv->destroy_with_parent)
2349 disconnect_parent_destroyed (window);
2351 priv->transient_parent = NULL;
2353 if (priv->transient_parent_group)
2355 priv->transient_parent_group = FALSE;
2356 gtk_window_group_remove_window (priv->group,
2363 * gtk_window_set_transient_for:
2364 * @window: a #GtkWindow
2365 * @parent: (allow-none): parent window, or %NULL
2367 * Dialog windows should be set transient for the main application
2368 * window they were spawned from. This allows <link
2369 * linkend="gtk-X11-arch">window managers</link> to e.g. keep the
2370 * dialog on top of the main window, or center the dialog over the
2371 * main window. gtk_dialog_new_with_buttons() and other convenience
2372 * functions in GTK+ will sometimes call
2373 * gtk_window_set_transient_for() on your behalf.
2375 * Passing %NULL for @parent unsets the current transient window.
2377 * On Windows, this function puts the child window on top of the parent,
2378 * much as the window manager would have done on X.
2381 gtk_window_set_transient_for (GtkWindow *window,
2384 GtkWindowPrivate *priv;
2386 g_return_if_fail (GTK_IS_WINDOW (window));
2387 g_return_if_fail (parent == NULL || GTK_IS_WINDOW (parent));
2388 g_return_if_fail (window != parent);
2390 priv = window->priv;
2392 if (priv->transient_parent)
2394 if (gtk_widget_get_realized (GTK_WIDGET (window)) &&
2395 gtk_widget_get_realized (GTK_WIDGET (priv->transient_parent)) &&
2396 (!parent || !gtk_widget_get_realized (GTK_WIDGET (parent))))
2397 gtk_window_transient_parent_unrealized (GTK_WIDGET (priv->transient_parent),
2398 GTK_WIDGET (window));
2400 gtk_window_unset_transient_for (window);
2403 priv->transient_parent = parent;
2407 g_signal_connect (parent, "destroy",
2408 G_CALLBACK (gtk_widget_destroyed),
2409 &priv->transient_parent);
2410 g_signal_connect (parent, "realize",
2411 G_CALLBACK (gtk_window_transient_parent_realized),
2413 g_signal_connect (parent, "unrealize",
2414 G_CALLBACK (gtk_window_transient_parent_unrealized),
2416 g_signal_connect (parent, "notify::screen",
2417 G_CALLBACK (gtk_window_transient_parent_screen_changed),
2420 gtk_window_set_screen (window, gtk_window_get_screen (parent));
2422 if (priv->destroy_with_parent)
2423 connect_parent_destroyed (window);
2425 if (gtk_widget_get_realized (GTK_WIDGET (window)) &&
2426 gtk_widget_get_realized (GTK_WIDGET (parent)))
2427 gtk_window_transient_parent_realized (GTK_WIDGET (parent),
2428 GTK_WIDGET (window));
2430 if (parent->priv->group)
2432 gtk_window_group_add_window (parent->priv->group, window);
2433 priv->transient_parent_group = TRUE;
2439 * gtk_window_get_transient_for:
2440 * @window: a #GtkWindow
2442 * Fetches the transient parent for this window. See
2443 * gtk_window_set_transient_for().
2445 * Return value: (transfer none): the transient parent for this window, or %NULL
2446 * if no transient parent has been set.
2449 gtk_window_get_transient_for (GtkWindow *window)
2451 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
2453 return window->priv->transient_parent;
2457 * gtk_window_set_opacity:
2458 * @window: a #GtkWindow
2459 * @opacity: desired opacity, between 0 and 1
2461 * Request the windowing system to make @window partially transparent,
2462 * with opacity 0 being fully transparent and 1 fully opaque. (Values
2463 * of the opacity parameter are clamped to the [0,1] range.) On X11
2464 * this has any effect only on X screens with a compositing manager
2465 * running. See gtk_widget_is_composited(). On Windows it should work
2468 * Note that setting a window's opacity after the window has been
2469 * shown causes it to flicker once on Windows.
2474 gtk_window_set_opacity (GtkWindow *window,
2477 GtkWindowPrivate *priv;
2479 g_return_if_fail (GTK_IS_WINDOW (window));
2481 priv = window->priv;
2485 else if (opacity > 1.0)
2488 priv->opacity_set = TRUE;
2489 priv->opacity = opacity;
2491 if (gtk_widget_get_realized (GTK_WIDGET (window)))
2492 gdk_window_set_opacity (gtk_widget_get_window (GTK_WIDGET (window)),
2497 * gtk_window_get_opacity:
2498 * @window: a #GtkWindow
2500 * Fetches the requested opacity for this window. See
2501 * gtk_window_set_opacity().
2503 * Return value: the requested opacity for this window.
2508 gtk_window_get_opacity (GtkWindow *window)
2510 g_return_val_if_fail (GTK_IS_WINDOW (window), 0.0);
2512 return window->priv->opacity;
2516 * gtk_window_set_type_hint:
2517 * @window: a #GtkWindow
2518 * @hint: the window type
2520 * By setting the type hint for the window, you allow the window
2521 * manager to decorate and handle the window in a way which is
2522 * suitable to the function of the window in your application.
2524 * This function should be called before the window becomes visible.
2526 * gtk_dialog_new_with_buttons() and other convenience functions in GTK+
2527 * will sometimes call gtk_window_set_type_hint() on your behalf.
2531 gtk_window_set_type_hint (GtkWindow *window,
2532 GdkWindowTypeHint hint)
2534 GtkWindowPrivate *priv;
2536 g_return_if_fail (GTK_IS_WINDOW (window));
2537 g_return_if_fail (!gtk_widget_get_mapped (GTK_WIDGET (window)));
2539 priv = window->priv;
2541 if (hint < GDK_WINDOW_TYPE_HINT_DROPDOWN_MENU)
2542 priv->gdk_type_hint = hint;
2544 priv->gdk_type_hint = GDK_WINDOW_TYPE_HINT_NORMAL;
2546 priv->reset_type_hint = TRUE;
2547 priv->type_hint = hint;
2551 * gtk_window_get_type_hint:
2552 * @window: a #GtkWindow
2554 * Gets the type hint for this window. See gtk_window_set_type_hint().
2556 * Return value: the type hint for @window.
2559 gtk_window_get_type_hint (GtkWindow *window)
2561 g_return_val_if_fail (GTK_IS_WINDOW (window), GDK_WINDOW_TYPE_HINT_NORMAL);
2563 return window->priv->type_hint;
2567 * gtk_window_set_skip_taskbar_hint:
2568 * @window: a #GtkWindow
2569 * @setting: %TRUE to keep this window from appearing in the task bar
2571 * Windows may set a hint asking the desktop environment not to display
2572 * the window in the task bar. This function sets this hint.
2577 gtk_window_set_skip_taskbar_hint (GtkWindow *window,
2580 GtkWindowPrivate *priv;
2582 g_return_if_fail (GTK_IS_WINDOW (window));
2584 priv = window->priv;
2586 setting = setting != FALSE;
2588 if (priv->skips_taskbar != setting)
2590 priv->skips_taskbar = setting;
2591 if (gtk_widget_get_realized (GTK_WIDGET (window)))
2592 gdk_window_set_skip_taskbar_hint (gtk_widget_get_window (GTK_WIDGET (window)),
2593 priv->skips_taskbar);
2594 g_object_notify (G_OBJECT (window), "skip-taskbar-hint");
2599 * gtk_window_get_skip_taskbar_hint:
2600 * @window: a #GtkWindow
2602 * Gets the value set by gtk_window_set_skip_taskbar_hint()
2604 * Return value: %TRUE if window shouldn't be in taskbar
2609 gtk_window_get_skip_taskbar_hint (GtkWindow *window)
2611 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
2613 return window->priv->skips_taskbar;
2617 * gtk_window_set_skip_pager_hint:
2618 * @window: a #GtkWindow
2619 * @setting: %TRUE to keep this window from appearing in the pager
2621 * Windows may set a hint asking the desktop environment not to display
2622 * the window in the pager. This function sets this hint.
2623 * (A "pager" is any desktop navigation tool such as a workspace
2624 * switcher that displays a thumbnail representation of the windows
2630 gtk_window_set_skip_pager_hint (GtkWindow *window,
2633 GtkWindowPrivate *priv;
2635 g_return_if_fail (GTK_IS_WINDOW (window));
2637 priv = window->priv;
2639 setting = setting != FALSE;
2641 if (priv->skips_pager != setting)
2643 priv->skips_pager = setting;
2644 if (gtk_widget_get_realized (GTK_WIDGET (window)))
2645 gdk_window_set_skip_pager_hint (gtk_widget_get_window (GTK_WIDGET (window)),
2647 g_object_notify (G_OBJECT (window), "skip-pager-hint");
2652 * gtk_window_get_skip_pager_hint:
2653 * @window: a #GtkWindow
2655 * Gets the value set by gtk_window_set_skip_pager_hint().
2657 * Return value: %TRUE if window shouldn't be in pager
2662 gtk_window_get_skip_pager_hint (GtkWindow *window)
2664 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
2666 return window->priv->skips_pager;
2670 * gtk_window_set_urgency_hint:
2671 * @window: a #GtkWindow
2672 * @setting: %TRUE to mark this window as urgent
2674 * Windows may set a hint asking the desktop environment to draw
2675 * the users attention to the window. This function sets this hint.
2680 gtk_window_set_urgency_hint (GtkWindow *window,
2683 GtkWindowPrivate *priv;
2685 g_return_if_fail (GTK_IS_WINDOW (window));
2687 priv = window->priv;
2689 setting = setting != FALSE;
2691 if (priv->urgent != setting)
2693 priv->urgent = setting;
2694 if (gtk_widget_get_realized (GTK_WIDGET (window)))
2695 gdk_window_set_urgency_hint (gtk_widget_get_window (GTK_WIDGET (window)),
2697 g_object_notify (G_OBJECT (window), "urgency-hint");
2702 * gtk_window_get_urgency_hint:
2703 * @window: a #GtkWindow
2705 * Gets the value set by gtk_window_set_urgency_hint()
2707 * Return value: %TRUE if window is urgent
2712 gtk_window_get_urgency_hint (GtkWindow *window)
2714 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
2716 return window->priv->urgent;
2720 * gtk_window_set_accept_focus:
2721 * @window: a #GtkWindow
2722 * @setting: %TRUE to let this window receive input focus
2724 * Windows may set a hint asking the desktop environment not to receive
2725 * the input focus. This function sets this hint.
2730 gtk_window_set_accept_focus (GtkWindow *window,
2733 GtkWindowPrivate *priv;
2735 g_return_if_fail (GTK_IS_WINDOW (window));
2737 priv = window->priv;
2739 setting = setting != FALSE;
2741 if (priv->accept_focus != setting)
2743 priv->accept_focus = setting;
2744 if (gtk_widget_get_realized (GTK_WIDGET (window)))
2745 gdk_window_set_accept_focus (gtk_widget_get_window (GTK_WIDGET (window)),
2746 priv->accept_focus);
2747 g_object_notify (G_OBJECT (window), "accept-focus");
2752 * gtk_window_get_accept_focus:
2753 * @window: a #GtkWindow
2755 * Gets the value set by gtk_window_set_accept_focus().
2757 * Return value: %TRUE if window should receive the input focus
2762 gtk_window_get_accept_focus (GtkWindow *window)
2764 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
2766 return window->priv->accept_focus;
2770 * gtk_window_set_focus_on_map:
2771 * @window: a #GtkWindow
2772 * @setting: %TRUE to let this window receive input focus on map
2774 * Windows may set a hint asking the desktop environment not to receive
2775 * the input focus when the window is mapped. This function sets this
2781 gtk_window_set_focus_on_map (GtkWindow *window,
2784 GtkWindowPrivate *priv;
2786 g_return_if_fail (GTK_IS_WINDOW (window));
2788 priv = window->priv;
2790 setting = setting != FALSE;
2792 if (priv->focus_on_map != setting)
2794 priv->focus_on_map = setting;
2795 if (gtk_widget_get_realized (GTK_WIDGET (window)))
2796 gdk_window_set_focus_on_map (gtk_widget_get_window (GTK_WIDGET (window)),
2797 priv->focus_on_map);
2798 g_object_notify (G_OBJECT (window), "focus-on-map");
2803 * gtk_window_get_focus_on_map:
2804 * @window: a #GtkWindow
2806 * Gets the value set by gtk_window_set_focus_on_map().
2808 * Return value: %TRUE if window should receive the input focus when
2814 gtk_window_get_focus_on_map (GtkWindow *window)
2816 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
2818 return window->priv->focus_on_map;
2822 * gtk_window_set_destroy_with_parent:
2823 * @window: a #GtkWindow
2824 * @setting: whether to destroy @window with its transient parent
2826 * If @setting is %TRUE, then destroying the transient parent of @window
2827 * will also destroy @window itself. This is useful for dialogs that
2828 * shouldn't persist beyond the lifetime of the main window they're
2829 * associated with, for example.
2832 gtk_window_set_destroy_with_parent (GtkWindow *window,
2835 GtkWindowPrivate *priv;
2837 g_return_if_fail (GTK_IS_WINDOW (window));
2839 priv = window->priv;
2841 if (priv->destroy_with_parent == (setting != FALSE))
2844 if (priv->destroy_with_parent)
2846 disconnect_parent_destroyed (window);
2850 connect_parent_destroyed (window);
2853 priv->destroy_with_parent = setting;
2855 g_object_notify (G_OBJECT (window), "destroy-with-parent");
2859 * gtk_window_get_destroy_with_parent:
2860 * @window: a #GtkWindow
2862 * Returns whether the window will be destroyed with its transient parent. See
2863 * gtk_window_set_destroy_with_parent ().
2865 * Return value: %TRUE if the window will be destroyed with its transient parent.
2868 gtk_window_get_destroy_with_parent (GtkWindow *window)
2870 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
2872 return window->priv->destroy_with_parent;
2875 static GtkWindowGeometryInfo*
2876 gtk_window_get_geometry_info (GtkWindow *window,
2879 GtkWindowPrivate *priv = window->priv;
2880 GtkWindowGeometryInfo *info;
2882 info = priv->geometry_info;
2883 if (!info && create)
2885 info = g_new0 (GtkWindowGeometryInfo, 1);
2887 info->default_width = -1;
2888 info->default_height = -1;
2889 info->resize_width = -1;
2890 info->resize_height = -1;
2891 info->initial_x = 0;
2892 info->initial_y = 0;
2893 info->initial_pos_set = FALSE;
2894 info->default_is_geometry = FALSE;
2895 info->position_constraints_changed = FALSE;
2896 info->last.configure_request.x = 0;
2897 info->last.configure_request.y = 0;
2898 info->last.configure_request.width = -1;
2899 info->last.configure_request.height = -1;
2900 info->widget = NULL;
2902 priv->geometry_info = info;
2909 * gtk_window_set_geometry_hints:
2910 * @window: a #GtkWindow
2911 * @geometry_widget: (allow-none): widget the geometry hints will be applied to or %NULL
2912 * @geometry: (allow-none): struct containing geometry information or %NULL
2913 * @geom_mask: mask indicating which struct fields should be paid attention to
2915 * This function sets up hints about how a window can be resized by
2916 * the user. You can set a minimum and maximum size; allowed resize
2917 * increments (e.g. for xterm, you can only resize by the size of a
2918 * character); aspect ratios; and more. See the #GdkGeometry struct.
2922 gtk_window_set_geometry_hints (GtkWindow *window,
2923 GtkWidget *geometry_widget,
2924 GdkGeometry *geometry,
2925 GdkWindowHints geom_mask)
2927 GtkWindowGeometryInfo *info;
2929 g_return_if_fail (GTK_IS_WINDOW (window));
2930 g_return_if_fail (geometry_widget == NULL || GTK_IS_WIDGET (geometry_widget));
2932 info = gtk_window_get_geometry_info (window, TRUE);
2935 g_signal_handlers_disconnect_by_func (info->widget,
2936 gtk_widget_destroyed,
2939 info->widget = geometry_widget;
2941 g_signal_connect (geometry_widget, "destroy",
2942 G_CALLBACK (gtk_widget_destroyed),
2946 info->geometry = *geometry;
2948 /* We store gravity in priv->gravity not in the hints. */
2949 info->mask = geom_mask & ~(GDK_HINT_WIN_GRAVITY);
2951 if (geom_mask & GDK_HINT_WIN_GRAVITY)
2953 gtk_window_set_gravity (window, geometry->win_gravity);
2956 gtk_widget_queue_resize_no_redraw (GTK_WIDGET (window));
2960 * gtk_window_set_decorated:
2961 * @window: a #GtkWindow
2962 * @setting: %TRUE to decorate the window
2964 * By default, windows are decorated with a title bar, resize
2965 * controls, etc. Some <link linkend="gtk-X11-arch">window
2966 * managers</link> allow GTK+ to disable these decorations, creating a
2967 * borderless window. If you set the decorated property to %FALSE
2968 * using this function, GTK+ will do its best to convince the window
2969 * manager not to decorate the window. Depending on the system, this
2970 * function may not have any effect when called on a window that is
2971 * already visible, so you should call it before calling gtk_window_show().
2973 * On Windows, this function always works, since there's no window manager
2978 gtk_window_set_decorated (GtkWindow *window,
2981 GtkWindowPrivate *priv;
2982 GdkWindow *gdk_window;
2984 g_return_if_fail (GTK_IS_WINDOW (window));
2986 priv = window->priv;
2988 setting = setting != FALSE;
2990 if (setting == priv->decorated)
2993 priv->decorated = setting;
2995 gdk_window = gtk_widget_get_window (GTK_WIDGET (window));
2998 if (priv->decorated)
2999 gdk_window_set_decorations (gdk_window,
3002 gdk_window_set_decorations (gdk_window,
3006 g_object_notify (G_OBJECT (window), "decorated");
3010 * gtk_window_get_decorated:
3011 * @window: a #GtkWindow
3013 * Returns whether the window has been set to have decorations
3014 * such as a title bar via gtk_window_set_decorated().
3016 * Return value: %TRUE if the window has been set to have decorations
3019 gtk_window_get_decorated (GtkWindow *window)
3021 g_return_val_if_fail (GTK_IS_WINDOW (window), TRUE);
3023 return window->priv->decorated;
3027 * gtk_window_set_deletable:
3028 * @window: a #GtkWindow
3029 * @setting: %TRUE to decorate the window as deletable
3031 * By default, windows have a close button in the window frame. Some
3032 * <link linkend="gtk-X11-arch">window managers</link> allow GTK+ to
3033 * disable this button. If you set the deletable property to %FALSE
3034 * using this function, GTK+ will do its best to convince the window
3035 * manager not to show a close button. Depending on the system, this
3036 * function may not have any effect when called on a window that is
3037 * already visible, so you should call it before calling gtk_window_show().
3039 * On Windows, this function always works, since there's no window manager
3045 gtk_window_set_deletable (GtkWindow *window,
3048 GtkWindowPrivate *priv;
3049 GdkWindow *gdk_window;
3051 g_return_if_fail (GTK_IS_WINDOW (window));
3053 priv = window->priv;
3055 setting = setting != FALSE;
3057 if (setting == priv->deletable)
3060 priv->deletable = setting;
3062 gdk_window = gtk_widget_get_window (GTK_WIDGET (window));
3065 if (priv->deletable)
3066 gdk_window_set_functions (gdk_window,
3069 gdk_window_set_functions (gdk_window,
3070 GDK_FUNC_ALL | GDK_FUNC_CLOSE);
3073 g_object_notify (G_OBJECT (window), "deletable");
3077 * gtk_window_get_deletable:
3078 * @window: a #GtkWindow
3080 * Returns whether the window has been set to have a close button
3081 * via gtk_window_set_deletable().
3083 * Return value: %TRUE if the window has been set to have a close button
3088 gtk_window_get_deletable (GtkWindow *window)
3090 g_return_val_if_fail (GTK_IS_WINDOW (window), TRUE);
3092 return window->priv->deletable;
3095 static GtkWindowIconInfo*
3096 get_icon_info (GtkWindow *window)
3098 return g_object_get_qdata (G_OBJECT (window), quark_gtk_window_icon_info);
3102 free_icon_info (GtkWindowIconInfo *info)
3104 g_free (info->icon_name);
3105 g_slice_free (GtkWindowIconInfo, info);
3109 static GtkWindowIconInfo*
3110 ensure_icon_info (GtkWindow *window)
3112 GtkWindowIconInfo *info;
3114 info = get_icon_info (window);
3118 info = g_slice_new0 (GtkWindowIconInfo);
3119 g_object_set_qdata_full (G_OBJECT (window),
3120 quark_gtk_window_icon_info,
3122 (GDestroyNotify)free_icon_info);
3129 icon_list_from_theme (GtkWidget *widget,
3134 GtkIconTheme *icon_theme;
3139 icon_theme = gtk_icon_theme_get_for_screen (gtk_widget_get_screen (widget));
3141 sizes = gtk_icon_theme_get_icon_sizes (icon_theme, name);
3144 for (i = 0; sizes[i]; i++)
3147 * We need an EWMH extension to handle scalable icons
3148 * by passing their name to the WM. For now just use a
3152 icon = gtk_icon_theme_load_icon (icon_theme, name,
3155 icon = gtk_icon_theme_load_icon (icon_theme, name,
3158 list = g_list_append (list, icon);
3168 gtk_window_realize_icon (GtkWindow *window)
3170 GtkWindowPrivate *priv = window->priv;
3172 GtkWindowIconInfo *info;
3173 GdkWindow *gdk_window;
3176 widget = GTK_WIDGET (window);
3177 gdk_window = gtk_widget_get_window (widget);
3179 g_return_if_fail (gdk_window != NULL);
3181 /* no point setting an icon on override-redirect */
3182 if (priv->type == GTK_WINDOW_POPUP)
3187 info = ensure_icon_info (window);
3192 info->using_default_icon = FALSE;
3193 info->using_parent_icon = FALSE;
3194 info->using_themed_icon = FALSE;
3196 icon_list = info->icon_list;
3198 /* Look up themed icon */
3199 if (icon_list == NULL && info->icon_name)
3201 icon_list = icon_list_from_theme (widget, info->icon_name);
3203 info->using_themed_icon = TRUE;
3206 /* Inherit from transient parent */
3207 if (icon_list == NULL && priv->transient_parent)
3209 icon_list = ensure_icon_info (priv->transient_parent)->icon_list;
3211 info->using_parent_icon = TRUE;
3214 /* Inherit from default */
3215 if (icon_list == NULL)
3217 icon_list = default_icon_list;
3219 info->using_default_icon = TRUE;
3222 /* Look up themed icon */
3223 if (icon_list == NULL && default_icon_name)
3225 icon_list = icon_list_from_theme (widget, default_icon_name);
3226 info->using_default_icon = TRUE;
3227 info->using_themed_icon = TRUE;
3230 info->realized = TRUE;
3232 if (info->using_themed_icon)
3234 GtkIconTheme *icon_theme;
3236 g_list_foreach (icon_list, (GFunc) g_object_unref, NULL);
3237 g_list_free (icon_list);
3239 icon_theme = gtk_icon_theme_get_for_screen (gtk_widget_get_screen (GTK_WIDGET (window)));
3240 g_signal_connect (icon_theme, "changed",
3241 G_CALLBACK (update_themed_icon), window);
3246 gtk_window_unrealize_icon (GtkWindow *window)
3248 GtkWindowIconInfo *info;
3250 info = get_icon_info (window);
3255 if (info->using_themed_icon)
3257 GtkIconTheme *icon_theme;
3259 icon_theme = gtk_icon_theme_get_for_screen (gtk_widget_get_screen (GTK_WIDGET (window)));
3261 g_signal_handlers_disconnect_by_func (icon_theme, update_themed_icon, window);
3264 /* We don't clear the properties on the window, just figure the
3265 * window is going away.
3268 info->realized = FALSE;
3273 * gtk_window_set_icon_list:
3274 * @window: a #GtkWindow
3275 * @list: (element-type GdkPixbuf) (transfer container): list of #GdkPixbuf
3277 * Sets up the icon representing a #GtkWindow. The icon is used when
3278 * the window is minimized (also known as iconified). Some window
3279 * managers or desktop environments may also place it in the window
3280 * frame, or display it in other contexts.
3282 * gtk_window_set_icon_list() allows you to pass in the same icon in
3283 * several hand-drawn sizes. The list should contain the natural sizes
3284 * your icon is available in; that is, don't scale the image before
3285 * passing it to GTK+. Scaling is postponed until the last minute,
3286 * when the desired final size is known, to allow best quality.
3288 * By passing several sizes, you may improve the final image quality
3289 * of the icon, by reducing or eliminating automatic image scaling.
3291 * Recommended sizes to provide: 16x16, 32x32, 48x48 at minimum, and
3292 * larger images (64x64, 128x128) if you have them.
3294 * See also gtk_window_set_default_icon_list() to set the icon
3295 * for all windows in your application in one go.
3297 * Note that transient windows (those who have been set transient for another
3298 * window using gtk_window_set_transient_for()) will inherit their
3299 * icon from their transient parent. So there's no need to explicitly
3300 * set the icon on transient windows.
3303 gtk_window_set_icon_list (GtkWindow *window,
3306 GtkWindowIconInfo *info;
3308 g_return_if_fail (GTK_IS_WINDOW (window));
3310 info = ensure_icon_info (window);
3312 if (info->icon_list == list) /* check for NULL mostly */
3315 g_list_foreach (list,
3316 (GFunc) g_object_ref, NULL);
3318 g_list_foreach (info->icon_list,
3319 (GFunc) g_object_unref, NULL);
3321 g_list_free (info->icon_list);
3323 info->icon_list = g_list_copy (list);
3325 g_object_notify (G_OBJECT (window), "icon");
3327 gtk_window_unrealize_icon (window);
3329 if (gtk_widget_get_realized (GTK_WIDGET (window)))
3330 gtk_window_realize_icon (window);
3332 /* We could try to update our transient children, but I don't think
3333 * it's really worth it. If we did it, the best way would probably
3334 * be to have children connect to notify::icon-list
3339 * gtk_window_get_icon_list:
3340 * @window: a #GtkWindow
3342 * Retrieves the list of icons set by gtk_window_set_icon_list().
3343 * The list is copied, but the reference count on each
3344 * member won't be incremented.
3346 * Return value: (element-type GdkPixbuf) (transfer container): copy of window's icon list
3349 gtk_window_get_icon_list (GtkWindow *window)
3351 GtkWindowIconInfo *info;
3353 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
3355 info = get_icon_info (window);
3358 return g_list_copy (info->icon_list);
3364 * gtk_window_set_icon:
3365 * @window: a #GtkWindow
3366 * @icon: (allow-none): icon image, or %NULL
3368 * Sets up the icon representing a #GtkWindow. This icon is used when
3369 * the window is minimized (also known as iconified). Some window
3370 * managers or desktop environments may also place it in the window
3371 * frame, or display it in other contexts.
3373 * The icon should be provided in whatever size it was naturally
3374 * drawn; that is, don't scale the image before passing it to
3375 * GTK+. Scaling is postponed until the last minute, when the desired
3376 * final size is known, to allow best quality.
3378 * If you have your icon hand-drawn in multiple sizes, use
3379 * gtk_window_set_icon_list(). Then the best size will be used.
3381 * This function is equivalent to calling gtk_window_set_icon_list()
3382 * with a 1-element list.
3384 * See also gtk_window_set_default_icon_list() to set the icon
3385 * for all windows in your application in one go.
3388 gtk_window_set_icon (GtkWindow *window,
3393 g_return_if_fail (GTK_IS_WINDOW (window));
3394 g_return_if_fail (icon == NULL || GDK_IS_PIXBUF (icon));
3399 list = g_list_append (list, icon);
3401 gtk_window_set_icon_list (window, list);
3407 update_themed_icon (GtkIconTheme *icon_theme,
3410 g_object_notify (G_OBJECT (window), "icon");
3412 gtk_window_unrealize_icon (window);
3414 if (gtk_widget_get_realized (GTK_WIDGET (window)))
3415 gtk_window_realize_icon (window);
3419 * gtk_window_set_icon_name:
3420 * @window: a #GtkWindow
3421 * @name: (allow-none): the name of the themed icon
3423 * Sets the icon for the window from a named themed icon. See
3424 * the docs for #GtkIconTheme for more details.
3426 * Note that this has nothing to do with the WM_ICON_NAME
3427 * property which is mentioned in the ICCCM.
3432 gtk_window_set_icon_name (GtkWindow *window,
3435 GtkWindowIconInfo *info;
3438 g_return_if_fail (GTK_IS_WINDOW (window));
3440 info = ensure_icon_info (window);
3442 if (g_strcmp0 (info->icon_name, name) == 0)
3445 tmp = info->icon_name;
3446 info->icon_name = g_strdup (name);
3449 g_list_foreach (info->icon_list, (GFunc) g_object_unref, NULL);
3450 g_list_free (info->icon_list);
3451 info->icon_list = NULL;
3453 update_themed_icon (NULL, window);
3455 g_object_notify (G_OBJECT (window), "icon-name");
3459 * gtk_window_get_icon_name:
3460 * @window: a #GtkWindow
3462 * Returns the name of the themed icon for the window,
3463 * see gtk_window_set_icon_name().
3465 * Returns: the icon name or %NULL if the window has
3471 gtk_window_get_icon_name (GtkWindow *window)
3473 GtkWindowIconInfo *info;
3475 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
3477 info = ensure_icon_info (window);
3479 return info->icon_name;
3483 * gtk_window_get_icon:
3484 * @window: a #GtkWindow
3486 * Gets the value set by gtk_window_set_icon() (or if you've
3487 * called gtk_window_set_icon_list(), gets the first icon in
3490 * Return value: (transfer none): icon for window
3493 gtk_window_get_icon (GtkWindow *window)
3495 GtkWindowIconInfo *info;
3497 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
3499 info = get_icon_info (window);
3500 if (info && info->icon_list)
3501 return GDK_PIXBUF (info->icon_list->data);
3506 /* Load pixbuf, printing warning on failure if error == NULL
3509 load_pixbuf_verbosely (const char *filename,
3512 GError *local_err = NULL;
3515 pixbuf = gdk_pixbuf_new_from_file (filename, &local_err);
3523 g_warning ("Error loading icon from file '%s':\n\t%s",
3524 filename, local_err->message);
3525 g_error_free (local_err);
3533 * gtk_window_set_icon_from_file:
3534 * @window: a #GtkWindow
3535 * @filename: location of icon file
3536 * @err: (allow-none): location to store error, or %NULL.
3538 * Sets the icon for @window.
3539 * Warns on failure if @err is %NULL.
3541 * This function is equivalent to calling gtk_window_set_icon()
3542 * with a pixbuf created by loading the image from @filename.
3544 * Returns: %TRUE if setting the icon succeeded.
3549 gtk_window_set_icon_from_file (GtkWindow *window,
3550 const gchar *filename,
3553 GdkPixbuf *pixbuf = load_pixbuf_verbosely (filename, err);
3557 gtk_window_set_icon (window, pixbuf);
3558 g_object_unref (pixbuf);
3567 * gtk_window_set_default_icon_list:
3568 * @list: (element-type GdkPixbuf) (transfer container): a list of #GdkPixbuf
3570 * Sets an icon list to be used as fallback for windows that haven't
3571 * had gtk_window_set_icon_list() called on them to set up a
3572 * window-specific icon list. This function allows you to set up the
3573 * icon for all windows in your app at once.
3575 * See gtk_window_set_icon_list() for more details.
3579 gtk_window_set_default_icon_list (GList *list)
3583 if (list == default_icon_list)
3586 /* Update serial so we don't used cached pixmaps/masks
3588 default_icon_serial++;
3590 g_list_foreach (list,
3591 (GFunc) g_object_ref, NULL);
3593 g_list_foreach (default_icon_list,
3594 (GFunc) g_object_unref, NULL);
3596 g_list_free (default_icon_list);
3598 default_icon_list = g_list_copy (list);
3600 /* Update all toplevels */
3601 toplevels = gtk_window_list_toplevels ();
3602 tmp_list = toplevels;
3603 while (tmp_list != NULL)
3605 GtkWindowIconInfo *info;
3606 GtkWindow *w = tmp_list->data;
3608 info = get_icon_info (w);
3609 if (info && info->using_default_icon)
3611 gtk_window_unrealize_icon (w);
3612 if (gtk_widget_get_realized (GTK_WIDGET (w)))
3613 gtk_window_realize_icon (w);
3616 tmp_list = tmp_list->next;
3618 g_list_free (toplevels);
3622 * gtk_window_set_default_icon:
3625 * Sets an icon to be used as fallback for windows that haven't
3626 * had gtk_window_set_icon() called on them from a pixbuf.
3631 gtk_window_set_default_icon (GdkPixbuf *icon)
3635 g_return_if_fail (GDK_IS_PIXBUF (icon));
3637 list = g_list_prepend (NULL, icon);
3638 gtk_window_set_default_icon_list (list);
3643 * gtk_window_set_default_icon_name:
3644 * @name: the name of the themed icon
3646 * Sets an icon to be used as fallback for windows that haven't
3647 * had gtk_window_set_icon_list() called on them from a named
3648 * themed icon, see gtk_window_set_icon_name().
3653 gtk_window_set_default_icon_name (const gchar *name)
3658 /* Update serial so we don't used cached pixmaps/masks
3660 default_icon_serial++;
3662 g_free (default_icon_name);
3663 default_icon_name = g_strdup (name);
3665 g_list_foreach (default_icon_list,
3666 (GFunc) g_object_unref, NULL);
3668 g_list_free (default_icon_list);
3669 default_icon_list = NULL;
3671 /* Update all toplevels */
3672 toplevels = gtk_window_list_toplevels ();
3673 tmp_list = toplevels;
3674 while (tmp_list != NULL)
3676 GtkWindowIconInfo *info;
3677 GtkWindow *w = tmp_list->data;
3679 info = get_icon_info (w);
3680 if (info && info->using_default_icon && info->using_themed_icon)
3682 gtk_window_unrealize_icon (w);
3683 if (gtk_widget_get_realized (GTK_WIDGET (w)))
3684 gtk_window_realize_icon (w);
3687 tmp_list = tmp_list->next;
3689 g_list_free (toplevels);
3693 * gtk_window_get_default_icon_name:
3695 * Returns the fallback icon name for windows that has been set
3696 * with gtk_window_set_default_icon_name(). The returned
3697 * string is owned by GTK+ and should not be modified. It
3698 * is only valid until the next call to
3699 * gtk_window_set_default_icon_name().
3701 * Returns: the fallback icon name for windows
3706 gtk_window_get_default_icon_name (void)
3708 return default_icon_name;
3712 * gtk_window_set_default_icon_from_file:
3713 * @filename: location of icon file
3714 * @err: (allow-none): location to store error, or %NULL.
3716 * Sets an icon to be used as fallback for windows that haven't
3717 * had gtk_window_set_icon_list() called on them from a file
3718 * on disk. Warns on failure if @err is %NULL.
3720 * Returns: %TRUE if setting the icon succeeded.
3725 gtk_window_set_default_icon_from_file (const gchar *filename,
3728 GdkPixbuf *pixbuf = load_pixbuf_verbosely (filename, err);
3732 gtk_window_set_default_icon (pixbuf);
3733 g_object_unref (pixbuf);
3742 * gtk_window_get_default_icon_list:
3744 * Gets the value set by gtk_window_set_default_icon_list().
3745 * The list is a copy and should be freed with g_list_free(),
3746 * but the pixbufs in the list have not had their reference count
3749 * Return value: (element-type GdkPixbuf) (transfer container): copy of default icon list
3752 gtk_window_get_default_icon_list (void)
3754 return g_list_copy (default_icon_list);
3758 gtk_window_set_default_size_internal (GtkWindow *window,
3759 gboolean change_width,
3761 gboolean change_height,
3763 gboolean is_geometry)
3765 GtkWindowGeometryInfo *info;
3767 g_return_if_fail (change_width == FALSE || width >= -1);
3768 g_return_if_fail (change_height == FALSE || height >= -1);
3770 info = gtk_window_get_geometry_info (window, TRUE);
3772 g_object_freeze_notify (G_OBJECT (window));
3774 info->default_is_geometry = is_geometry != FALSE;
3784 info->default_width = width;
3786 g_object_notify (G_OBJECT (window), "default-width");
3797 info->default_height = height;
3799 g_object_notify (G_OBJECT (window), "default-height");
3802 g_object_thaw_notify (G_OBJECT (window));
3804 gtk_widget_queue_resize_no_redraw (GTK_WIDGET (window));
3808 * gtk_window_set_default_size:
3809 * @window: a #GtkWindow
3810 * @width: width in pixels, or -1 to unset the default width
3811 * @height: height in pixels, or -1 to unset the default height
3813 * Sets the default size of a window. If the window's "natural" size
3814 * (its size request) is larger than the default, the default will be
3815 * ignored. More generally, if the default size does not obey the
3816 * geometry hints for the window (gtk_window_set_geometry_hints() can
3817 * be used to set these explicitly), the default size will be clamped
3818 * to the nearest permitted size.
3820 * Unlike gtk_widget_set_size_request(), which sets a size request for
3821 * a widget and thus would keep users from shrinking the window, this
3822 * function only sets the initial size, just as if the user had
3823 * resized the window themselves. Users can still shrink the window
3824 * again as they normally would. Setting a default size of -1 means to
3825 * use the "natural" default size (the size request of the window).
3827 * For more control over a window's initial size and how resizing works,
3828 * investigate gtk_window_set_geometry_hints().
3830 * For some uses, gtk_window_resize() is a more appropriate function.
3831 * gtk_window_resize() changes the current size of the window, rather
3832 * than the size to be used on initial display. gtk_window_resize() always
3833 * affects the window itself, not the geometry widget.
3835 * The default size of a window only affects the first time a window is
3836 * shown; if a window is hidden and re-shown, it will remember the size
3837 * it had prior to hiding, rather than using the default size.
3839 * Windows can't actually be 0x0 in size, they must be at least 1x1, but
3840 * passing 0 for @width and @height is OK, resulting in a 1x1 default size.
3843 gtk_window_set_default_size (GtkWindow *window,
3847 g_return_if_fail (GTK_IS_WINDOW (window));
3848 g_return_if_fail (width >= -1);
3849 g_return_if_fail (height >= -1);
3851 gtk_window_set_default_size_internal (window, TRUE, width, TRUE, height, FALSE);
3855 * gtk_window_get_default_size:
3856 * @window: a #GtkWindow
3857 * @width: (out) (allow-none): location to store the default width, or %NULL
3858 * @height: (out) (allow-none): location to store the default height, or %NULL
3860 * Gets the default size of the window. A value of -1 for the width or
3861 * height indicates that a default size has not been explicitly set
3862 * for that dimension, so the "natural" size of the window will be
3867 gtk_window_get_default_size (GtkWindow *window,
3871 GtkWindowGeometryInfo *info;
3873 g_return_if_fail (GTK_IS_WINDOW (window));
3875 info = gtk_window_get_geometry_info (window, FALSE);
3878 *width = info ? info->default_width : -1;
3881 *height = info ? info->default_height : -1;
3885 * gtk_window_resize:
3886 * @window: a #GtkWindow
3887 * @width: width in pixels to resize the window to
3888 * @height: height in pixels to resize the window to
3890 * Resizes the window as if the user had done so, obeying geometry
3891 * constraints. The default geometry constraint is that windows may
3892 * not be smaller than their size request; to override this
3893 * constraint, call gtk_widget_set_size_request() to set the window's
3894 * request to a smaller value.
3896 * If gtk_window_resize() is called before showing a window for the
3897 * first time, it overrides any default size set with
3898 * gtk_window_set_default_size().
3900 * Windows may not be resized smaller than 1 by 1 pixels.
3904 gtk_window_resize (GtkWindow *window,
3908 GtkWindowGeometryInfo *info;
3910 g_return_if_fail (GTK_IS_WINDOW (window));
3911 g_return_if_fail (width > 0);
3912 g_return_if_fail (height > 0);
3914 info = gtk_window_get_geometry_info (window, TRUE);
3916 info->resize_width = width;
3917 info->resize_height = height;
3919 gtk_widget_queue_resize_no_redraw (GTK_WIDGET (window));
3923 * gtk_window_get_size:
3924 * @window: a #GtkWindow
3925 * @width: (out) (allow-none): return location for width, or %NULL
3926 * @height: (out) (allow-none): return location for height, or %NULL
3928 * Obtains the current size of @window. If @window is not onscreen,
3929 * it returns the size GTK+ will suggest to the <link
3930 * linkend="gtk-X11-arch">window manager</link> for the initial window
3931 * size (but this is not reliably the same as the size the window
3932 * manager will actually select). The size obtained by
3933 * gtk_window_get_size() is the last size received in a
3934 * #GdkEventConfigure, that is, GTK+ uses its locally-stored size,
3935 * rather than querying the X server for the size. As a result, if you
3936 * call gtk_window_resize() then immediately call
3937 * gtk_window_get_size(), the size won't have taken effect yet. After
3938 * the window manager processes the resize request, GTK+ receives
3939 * notification that the size has changed via a configure event, and
3940 * the size of the window gets updated.
3942 * Note 1: Nearly any use of this function creates a race condition,
3943 * because the size of the window may change between the time that you
3944 * get the size and the time that you perform some action assuming
3945 * that size is the current size. To avoid race conditions, connect to
3946 * "configure-event" on the window and adjust your size-dependent
3947 * state to match the size delivered in the #GdkEventConfigure.
3949 * Note 2: The returned size does <emphasis>not</emphasis> include the
3950 * size of the window manager decorations (aka the window frame or
3951 * border). Those are not drawn by GTK+ and GTK+ has no reliable
3952 * method of determining their size.
3954 * Note 3: If you are getting a window size in order to position
3955 * the window onscreen, there may be a better way. The preferred
3956 * way is to simply set the window's semantic type with
3957 * gtk_window_set_type_hint(), which allows the window manager to
3958 * e.g. center dialogs. Also, if you set the transient parent of
3959 * dialogs with gtk_window_set_transient_for() window managers
3960 * will often center the dialog over its parent window. It's
3961 * much preferred to let the window manager handle these
3962 * things rather than doing it yourself, because all apps will
3963 * behave consistently and according to user prefs if the window
3964 * manager handles it. Also, the window manager can take the size
3965 * of the window decorations/border into account, while your
3966 * application cannot.
3968 * In any case, if you insist on application-specified window
3969 * positioning, there's <emphasis>still</emphasis> a better way than
3970 * doing it yourself - gtk_window_set_position() will frequently
3971 * handle the details for you.
3975 gtk_window_get_size (GtkWindow *window,
3981 g_return_if_fail (GTK_IS_WINDOW (window));
3983 if (width == NULL && height == NULL)
3986 if (gtk_widget_get_mapped (GTK_WIDGET (window)))
3988 w = gdk_window_get_width (gtk_widget_get_window (GTK_WIDGET (window)));
3989 h = gdk_window_get_height (gtk_widget_get_window (GTK_WIDGET (window)));
3993 GdkRectangle configure_request;
3995 gtk_window_compute_configure_request (window,
3999 w = configure_request.width;
4000 h = configure_request.height;
4011 * @window: a #GtkWindow
4012 * @x: X coordinate to move window to
4013 * @y: Y coordinate to move window to
4015 * Asks the <link linkend="gtk-X11-arch">window manager</link> to move
4016 * @window to the given position. Window managers are free to ignore
4017 * this; most window managers ignore requests for initial window
4018 * positions (instead using a user-defined placement algorithm) and
4019 * honor requests after the window has already been shown.
4021 * Note: the position is the position of the gravity-determined
4022 * reference point for the window. The gravity determines two things:
4023 * first, the location of the reference point in root window
4024 * coordinates; and second, which point on the window is positioned at
4025 * the reference point.
4027 * By default the gravity is #GDK_GRAVITY_NORTH_WEST, so the reference
4028 * point is simply the @x, @y supplied to gtk_window_move(). The
4029 * top-left corner of the window decorations (aka window frame or
4030 * border) will be placed at @x, @y. Therefore, to position a window
4031 * at the top left of the screen, you want to use the default gravity
4032 * (which is #GDK_GRAVITY_NORTH_WEST) and move the window to 0,0.
4034 * To position a window at the bottom right corner of the screen, you
4035 * would set #GDK_GRAVITY_SOUTH_EAST, which means that the reference
4036 * point is at @x + the window width and @y + the window height, and
4037 * the bottom-right corner of the window border will be placed at that
4038 * reference point. So, to place a window in the bottom right corner
4039 * you would first set gravity to south east, then write:
4040 * <literal>gtk_window_move (window, gdk_screen_width () - window_width,
4041 * gdk_screen_height () - window_height)</literal> (note that this
4042 * example does not take multi-head scenarios into account).
4044 * The Extended Window Manager Hints specification at <ulink
4045 * url="http://www.freedesktop.org/Standards/wm-spec">
4046 * http://www.freedesktop.org/Standards/wm-spec</ulink> has a
4047 * nice table of gravities in the "implementation notes" section.
4049 * The gtk_window_get_position() documentation may also be relevant.
4052 gtk_window_move (GtkWindow *window,
4056 GtkWindowPrivate *priv;
4057 GtkWindowGeometryInfo *info;
4060 g_return_if_fail (GTK_IS_WINDOW (window));
4062 priv = window->priv;
4063 widget = GTK_WIDGET (window);
4065 info = gtk_window_get_geometry_info (window, TRUE);
4067 if (gtk_widget_get_mapped (widget))
4069 GtkAllocation allocation;
4071 gtk_widget_get_allocation (widget, &allocation);
4073 /* we have now sent a request with this position
4074 * with currently-active constraints, so toggle flag.
4076 info->position_constraints_changed = FALSE;
4078 /* we only constrain if mapped - if not mapped,
4079 * then gtk_window_compute_configure_request()
4080 * will apply the constraints later, and we
4081 * don't want to lose information about
4082 * what position the user set before then.
4083 * i.e. if you do a move() then turn off POS_CENTER
4084 * then show the window, your move() will work.
4086 gtk_window_constrain_position (window,
4087 allocation.width, allocation.height,
4090 /* Note that this request doesn't go through our standard request
4091 * framework, e.g. doesn't increment configure_request_count,
4092 * doesn't set info->last, etc.; that's because
4093 * we don't save the info needed to arrive at this same request
4096 * To gtk_window_move_resize(), this will end up looking exactly
4097 * the same as the position being changed by the window
4101 /* FIXME are we handling gravity properly for framed windows? */
4103 gdk_window_move (priv->frame,
4104 x - priv->frame_left,
4105 y - priv->frame_top);
4107 gdk_window_move (gtk_widget_get_window (GTK_WIDGET (window)),
4112 /* Save this position to apply on mapping */
4113 info->initial_x = x;
4114 info->initial_y = y;
4115 info->initial_pos_set = TRUE;
4120 * gtk_window_get_position:
4121 * @window: a #GtkWindow
4122 * @root_x: (out): return location for X coordinate of gravity-determined reference point
4123 * @root_y: (out): return location for Y coordinate of gravity-determined reference point
4125 * This function returns the position you need to pass to
4126 * gtk_window_move() to keep @window in its current position. This
4127 * means that the meaning of the returned value varies with window
4128 * gravity. See gtk_window_move() for more details.
4130 * If you haven't changed the window gravity, its gravity will be
4131 * #GDK_GRAVITY_NORTH_WEST. This means that gtk_window_get_position()
4132 * gets the position of the top-left corner of the window manager
4133 * frame for the window. gtk_window_move() sets the position of this
4134 * same top-left corner.
4136 * gtk_window_get_position() is not 100% reliable because the X Window System
4137 * does not specify a way to obtain the geometry of the
4138 * decorations placed on a window by the window manager.
4139 * Thus GTK+ is using a "best guess" that works with most
4142 * Moreover, nearly all window managers are historically broken with
4143 * respect to their handling of window gravity. So moving a window to
4144 * its current position as returned by gtk_window_get_position() tends
4145 * to result in moving the window slightly. Window managers are
4146 * slowly getting better over time.
4148 * If a window has gravity #GDK_GRAVITY_STATIC the window manager
4149 * frame is not relevant, and thus gtk_window_get_position() will
4150 * always produce accurate results. However you can't use static
4151 * gravity to do things like place a window in a corner of the screen,
4152 * because static gravity ignores the window manager decorations.
4154 * If you are saving and restoring your application's window
4155 * positions, you should know that it's impossible for applications to
4156 * do this without getting it somewhat wrong because applications do
4157 * not have sufficient knowledge of window manager state. The Correct
4158 * Mechanism is to support the session management protocol (see the
4159 * "GnomeClient" object in the GNOME libraries for example) and allow
4160 * the window manager to save your window sizes and positions.
4165 gtk_window_get_position (GtkWindow *window,
4169 GtkWindowPrivate *priv;
4171 GdkWindow *gdk_window;
4173 g_return_if_fail (GTK_IS_WINDOW (window));
4175 priv = window->priv;
4176 widget = GTK_WIDGET (window);
4177 gdk_window = gtk_widget_get_window (widget);
4179 if (priv->gravity == GDK_GRAVITY_STATIC)
4181 if (gtk_widget_get_mapped (widget))
4183 /* This does a server round-trip, which is sort of wrong;
4184 * but a server round-trip is inevitable for
4185 * gdk_window_get_frame_extents() in the usual
4186 * NorthWestGravity case below, so not sure what else to
4187 * do. We should likely be consistent about whether we get
4188 * the client-side info or the server-side info.
4190 gdk_window_get_origin (gdk_window, root_x, root_y);
4194 GdkRectangle configure_request;
4196 gtk_window_compute_configure_request (window,
4200 *root_x = configure_request.x;
4201 *root_y = configure_request.y;
4206 GdkRectangle frame_extents;
4211 if (gtk_widget_get_mapped (widget))
4214 gdk_window_get_frame_extents (priv->frame, &frame_extents);
4216 gdk_window_get_frame_extents (gdk_window, &frame_extents);
4217 x = frame_extents.x;
4218 y = frame_extents.y;
4219 gtk_window_get_size (window, &w, &h);
4223 /* We just say the frame has 0 size on all sides.
4224 * Not sure what else to do.
4226 gtk_window_compute_configure_request (window,
4229 x = frame_extents.x;
4230 y = frame_extents.y;
4231 w = frame_extents.width;
4232 h = frame_extents.height;
4235 switch (priv->gravity)
4237 case GDK_GRAVITY_NORTH:
4238 case GDK_GRAVITY_CENTER:
4239 case GDK_GRAVITY_SOUTH:
4240 /* Find center of frame. */
4241 x += frame_extents.width / 2;
4242 /* Center client window on that point. */
4246 case GDK_GRAVITY_SOUTH_EAST:
4247 case GDK_GRAVITY_EAST:
4248 case GDK_GRAVITY_NORTH_EAST:
4249 /* Find right edge of frame */
4250 x += frame_extents.width;
4251 /* Align left edge of client at that point. */
4258 switch (priv->gravity)
4260 case GDK_GRAVITY_WEST:
4261 case GDK_GRAVITY_CENTER:
4262 case GDK_GRAVITY_EAST:
4263 /* Find center of frame. */
4264 y += frame_extents.height / 2;
4265 /* Center client window there. */
4268 case GDK_GRAVITY_SOUTH_WEST:
4269 case GDK_GRAVITY_SOUTH:
4270 case GDK_GRAVITY_SOUTH_EAST:
4271 /* Find south edge of frame */
4272 y += frame_extents.height;
4273 /* Place bottom edge of client there */
4288 * gtk_window_reshow_with_initial_size:
4289 * @window: a #GtkWindow
4291 * Hides @window, then reshows it, resetting the
4292 * default size and position of the window. Used
4293 * by GUI builders only.
4296 gtk_window_reshow_with_initial_size (GtkWindow *window)
4300 g_return_if_fail (GTK_IS_WINDOW (window));
4302 widget = GTK_WIDGET (window);
4304 gtk_widget_hide (widget);
4305 gtk_widget_unrealize (widget);
4306 gtk_widget_show (widget);
4310 gtk_window_destroy (GtkWidget *widget)
4312 GtkWindow *window = GTK_WINDOW (widget);
4313 GtkWindowPrivate *priv = window->priv;
4315 toplevel_list = g_slist_remove (toplevel_list, window);
4317 if (priv->transient_parent)
4318 gtk_window_set_transient_for (window, NULL);
4320 /* frees the icons */
4321 gtk_window_set_icon_list (window, NULL);
4323 if (priv->has_user_ref_count)
4325 priv->has_user_ref_count = FALSE;
4326 g_object_unref (window);
4330 gtk_window_group_remove_window (priv->group, window);
4332 gtk_window_free_key_hash (window);
4334 GTK_WIDGET_CLASS (gtk_window_parent_class)->destroy (widget);
4338 gtk_window_finalize (GObject *object)
4340 GtkWindow *window = GTK_WINDOW (object);
4341 GtkWindowPrivate *priv = window->priv;
4342 GtkMnemonicHash *mnemonic_hash;
4344 g_free (priv->title);
4345 g_free (priv->wmclass_name);
4346 g_free (priv->wmclass_class);
4347 g_free (priv->wm_role);
4349 mnemonic_hash = gtk_window_get_mnemonic_hash (window, FALSE);
4351 _gtk_mnemonic_hash_free (mnemonic_hash);
4353 if (priv->geometry_info)
4355 if (priv->geometry_info->widget)
4356 g_signal_handlers_disconnect_by_func (priv->geometry_info->widget,
4357 gtk_widget_destroyed,
4358 &priv->geometry_info->widget);
4359 g_free (priv->geometry_info);
4362 if (priv->keys_changed_handler)
4364 g_source_remove (priv->keys_changed_handler);
4365 priv->keys_changed_handler = 0;
4369 g_signal_handlers_disconnect_by_func (gdk_visual_get_screen (priv->visual),
4370 gtk_window_on_composited_changed, window);
4372 g_free (priv->startup_id);
4374 G_OBJECT_CLASS (gtk_window_parent_class)->finalize (object);
4378 gtk_window_show (GtkWidget *widget)
4380 GtkWindow *window = GTK_WINDOW (widget);
4381 GtkWindowPrivate *priv = window->priv;
4382 GtkContainer *container = GTK_CONTAINER (window);
4383 gboolean need_resize;
4385 GTK_WIDGET_SET_FLAGS (widget, GTK_VISIBLE);
4387 need_resize = _gtk_container_get_need_resize (container) || !gtk_widget_get_realized (widget);
4388 _gtk_container_set_need_resize (container, FALSE);
4392 GtkWindowGeometryInfo *info = gtk_window_get_geometry_info (window, TRUE);
4393 GtkAllocation allocation = { 0, 0 };
4394 GdkRectangle configure_request;
4395 GdkGeometry new_geometry;
4397 gboolean was_realized;
4399 /* We are going to go ahead and perform this configure request
4400 * and then emulate a configure notify by going ahead and
4401 * doing a size allocate. Sort of a synchronous
4402 * mini-copy of gtk_window_move_resize() here.
4404 gtk_window_compute_configure_request (window,
4409 /* We update this because we are going to go ahead
4410 * and gdk_window_resize() below, rather than
4413 info->last.configure_request.width = configure_request.width;
4414 info->last.configure_request.height = configure_request.height;
4416 /* and allocate the window - this is normally done
4417 * in move_resize in response to configure notify
4419 allocation.width = configure_request.width;
4420 allocation.height = configure_request.height;
4421 gtk_widget_size_allocate (widget, &allocation);
4423 /* Then we guarantee we have a realize */
4424 was_realized = FALSE;
4425 if (!gtk_widget_get_realized (widget))
4427 gtk_widget_realize (widget);
4428 was_realized = TRUE;
4431 /* Must be done after the windows are realized,
4432 * so that the decorations can be read
4434 gtk_decorated_window_calculate_frame_size (window);
4436 /* We only send configure request if we didn't just finish
4437 * creating the window; if we just created the window
4438 * then we created it with widget->allocation anyhow.
4441 gdk_window_move_resize (gtk_widget_get_window (widget),
4442 configure_request.x,
4443 configure_request.y,
4444 configure_request.width,
4445 configure_request.height);
4448 gtk_container_check_resize (container);
4450 gtk_widget_map (widget);
4452 /* Try to make sure that we have some focused widget
4454 if (!priv->focus_widget && !GTK_IS_PLUG (window))
4455 gtk_window_move_focus (window, GTK_DIR_TAB_FORWARD);
4458 gtk_grab_add (widget);
4462 gtk_window_hide (GtkWidget *widget)
4464 GtkWindow *window = GTK_WINDOW (widget);
4465 GtkWindowPrivate *priv = window->priv;
4467 GTK_WIDGET_UNSET_FLAGS (widget, GTK_VISIBLE);
4468 gtk_widget_unmap (widget);
4471 gtk_grab_remove (widget);
4475 gtk_window_map (GtkWidget *widget)
4478 GtkWindow *window = GTK_WINDOW (widget);
4479 GtkWindowPrivate *priv = window->priv;
4480 GdkWindow *toplevel;
4481 GdkWindow *gdk_window;
4482 gboolean auto_mnemonics;
4484 gdk_window = gtk_widget_get_window (widget);
4486 gtk_widget_set_mapped (widget, TRUE);
4488 child = gtk_bin_get_child (&(window->bin));
4490 gtk_widget_get_visible (child) &&
4491 !gtk_widget_get_mapped (child))
4492 gtk_widget_map (child);
4495 toplevel = priv->frame;
4497 toplevel = gdk_window;
4499 if (priv->maximize_initially)
4500 gdk_window_maximize (toplevel);
4502 gdk_window_unmaximize (toplevel);
4504 if (priv->stick_initially)
4505 gdk_window_stick (toplevel);
4507 gdk_window_unstick (toplevel);
4509 if (priv->iconify_initially)
4510 gdk_window_iconify (toplevel);
4512 gdk_window_deiconify (toplevel);
4514 if (priv->fullscreen_initially)
4515 gdk_window_fullscreen (toplevel);
4517 gdk_window_unfullscreen (toplevel);
4519 gdk_window_set_keep_above (toplevel, priv->above_initially);
4521 gdk_window_set_keep_below (toplevel, priv->below_initially);
4523 /* No longer use the default settings */
4524 priv->need_default_size = FALSE;
4525 priv->need_default_position = FALSE;
4527 if (priv->reset_type_hint)
4529 /* We should only reset the type hint when the application
4530 * used gtk_window_set_type_hint() to change the hint.
4531 * Some applications use X directly to change the properties;
4532 * in that case, we shouldn't overwrite what they did.
4534 gdk_window_set_type_hint (gdk_window, priv->type_hint);
4535 priv->reset_type_hint = FALSE;
4538 gdk_window_show (gdk_window);
4541 gdk_window_show (priv->frame);
4543 if (!disable_startup_notification)
4545 /* Do we have a custom startup-notification id? */
4546 if (priv->startup_id != NULL)
4548 /* Make sure we have a "real" id */
4549 if (!startup_id_is_fake (priv->startup_id))
4550 gdk_notify_startup_complete_with_id (priv->startup_id);
4552 g_free (priv->startup_id);
4553 priv->startup_id = NULL;
4555 else if (!sent_startup_notification)
4557 sent_startup_notification = TRUE;
4558 gdk_notify_startup_complete ();
4562 /* if auto-mnemonics is enabled and mnemonics visible is not already set
4563 * (as in the case of popup menus), then hide mnemonics initially
4565 g_object_get (gtk_widget_get_settings (widget), "gtk-auto-mnemonics",
4566 &auto_mnemonics, NULL);
4567 if (auto_mnemonics && !priv->mnemonics_visible_set)
4568 gtk_window_set_mnemonics_visible (window, FALSE);
4572 gtk_window_map_event (GtkWidget *widget,
4575 if (!gtk_widget_get_mapped (widget))
4577 /* we should be be unmapped, but are getting a MapEvent, this may happen
4578 * to toplevel XWindows if mapping was intercepted by a window manager
4579 * and an unmap request occoured while the MapRequestEvent was still
4580 * being handled. we work around this situaiton here by re-requesting
4581 * the window being unmapped. more details can be found in:
4582 * http://bugzilla.gnome.org/show_bug.cgi?id=316180
4584 gdk_window_hide (gtk_widget_get_window (widget));
4590 gtk_window_unmap (GtkWidget *widget)
4592 GtkWindow *window = GTK_WINDOW (widget);
4593 GtkWindowPrivate *priv = window->priv;
4594 GtkWindowGeometryInfo *info;
4595 GdkWindow *gdk_window;
4596 GdkWindowState state;
4598 gdk_window = gtk_widget_get_window (widget);
4600 gtk_widget_set_mapped (widget, FALSE);
4602 gdk_window_withdraw (priv->frame);
4604 gdk_window_withdraw (gdk_window);
4606 priv->configure_request_count = 0;
4607 priv->configure_notify_received = FALSE;
4609 /* on unmap, we reset the default positioning of the window,
4610 * so it's placed again, but we don't reset the default
4611 * size of the window, so it's remembered.
4613 priv->need_default_position = TRUE;
4615 info = gtk_window_get_geometry_info (window, FALSE);
4618 info->initial_pos_set = FALSE;
4619 info->position_constraints_changed = FALSE;
4622 state = gdk_window_get_state (gdk_window);
4623 priv->iconify_initially = (state & GDK_WINDOW_STATE_ICONIFIED) != 0;
4624 priv->maximize_initially = (state & GDK_WINDOW_STATE_MAXIMIZED) != 0;
4625 priv->stick_initially = (state & GDK_WINDOW_STATE_STICKY) != 0;
4626 priv->above_initially = (state & GDK_WINDOW_STATE_ABOVE) != 0;
4627 priv->below_initially = (state & GDK_WINDOW_STATE_BELOW) != 0;
4631 gtk_window_realize (GtkWidget *widget)
4633 GtkAllocation allocation;
4636 GdkWindow *parent_window;
4637 GdkWindow *gdk_window;
4638 GdkWindowAttr attributes;
4639 gint attributes_mask;
4640 GtkWindowPrivate *priv;
4642 window = GTK_WINDOW (widget);
4643 priv = window->priv;
4645 gtk_widget_get_allocation (widget, &allocation);
4647 /* ensure widget tree is properly size allocated */
4648 if (allocation.x == -1 &&
4649 allocation.y == -1 &&
4650 allocation.width == 1 &&
4651 allocation.height == 1)
4653 GtkRequisition requisition;
4654 GtkAllocation allocation = { 0, 0, 200, 200 };
4656 gtk_widget_get_preferred_size (widget, &requisition, NULL);
4657 if (requisition.width || requisition.height)
4659 /* non-empty window */
4660 allocation.width = requisition.width;
4661 allocation.height = requisition.height;
4663 gtk_widget_size_allocate (widget, &allocation);
4665 _gtk_container_queue_resize (GTK_CONTAINER (widget));
4667 g_return_if_fail (!gtk_widget_get_realized (widget));
4670 gtk_widget_set_realized (widget, TRUE);
4674 case GTK_WINDOW_TOPLEVEL:
4675 attributes.window_type = GDK_WINDOW_TOPLEVEL;
4677 case GTK_WINDOW_POPUP:
4678 attributes.window_type = GDK_WINDOW_TEMP;
4681 g_warning (G_STRLOC": Unknown window type %d!", priv->type);
4685 attributes.title = priv->title;
4686 attributes.wmclass_name = priv->wmclass_name;
4687 attributes.wmclass_class = priv->wmclass_class;
4688 attributes.wclass = GDK_INPUT_OUTPUT;
4689 attributes.visual = gtk_widget_get_visual (widget);
4691 if (priv->has_frame)
4693 gtk_widget_get_allocation (widget, &allocation);
4694 attributes.width = allocation.width + priv->frame_left + priv->frame_right;
4695 attributes.height = allocation.height + priv->frame_top + priv->frame_bottom;
4696 attributes.event_mask = (GDK_EXPOSURE_MASK |
4697 GDK_KEY_PRESS_MASK |
4698 GDK_ENTER_NOTIFY_MASK |
4699 GDK_LEAVE_NOTIFY_MASK |
4700 GDK_FOCUS_CHANGE_MASK |
4701 GDK_STRUCTURE_MASK |
4702 GDK_BUTTON_MOTION_MASK |
4703 GDK_POINTER_MOTION_HINT_MASK |
4704 GDK_BUTTON_PRESS_MASK |
4705 GDK_BUTTON_RELEASE_MASK);
4707 attributes_mask = GDK_WA_VISUAL;
4709 priv->frame = gdk_window_new (gtk_widget_get_root_window (widget),
4710 &attributes, attributes_mask);
4712 if (priv->opacity_set)
4713 gdk_window_set_opacity (priv->frame, priv->opacity);
4715 gdk_window_set_user_data (priv->frame, widget);
4717 attributes.window_type = GDK_WINDOW_CHILD;
4718 attributes.x = priv->frame_left;
4719 attributes.y = priv->frame_top;
4721 attributes_mask = GDK_WA_X | GDK_WA_Y;
4723 parent_window = priv->frame;
4725 g_signal_connect (window,
4727 G_CALLBACK (gtk_window_event),
4732 attributes_mask = 0;
4733 parent_window = gtk_widget_get_root_window (widget);
4736 gtk_widget_get_allocation (widget, &allocation);
4737 attributes.width = allocation.width;
4738 attributes.height = allocation.height;
4739 attributes.event_mask = gtk_widget_get_events (widget);
4740 attributes.event_mask |= (GDK_EXPOSURE_MASK |
4741 GDK_KEY_PRESS_MASK |
4742 GDK_KEY_RELEASE_MASK |
4743 GDK_ENTER_NOTIFY_MASK |
4744 GDK_LEAVE_NOTIFY_MASK |
4745 GDK_FOCUS_CHANGE_MASK |
4746 GDK_STRUCTURE_MASK);
4747 attributes.type_hint = priv->type_hint;
4749 attributes_mask |= GDK_WA_VISUAL | GDK_WA_TYPE_HINT;
4750 attributes_mask |= (priv->title ? GDK_WA_TITLE : 0);
4751 attributes_mask |= (priv->wmclass_name ? GDK_WA_WMCLASS : 0);
4753 gdk_window = gdk_window_new (parent_window, &attributes, attributes_mask);
4754 gtk_widget_set_window (widget, gdk_window);
4756 if (!priv->has_frame && priv->opacity_set)
4757 gdk_window_set_opacity (gdk_window, priv->opacity);
4759 gdk_window_enable_synchronized_configure (gdk_window);
4761 gdk_window_set_user_data (gdk_window, window);
4763 gtk_widget_style_attach (widget);
4764 style = gtk_widget_get_style (widget);
4765 gtk_style_set_background (style, gdk_window, GTK_STATE_NORMAL);
4767 gtk_style_set_background (style, priv->frame, GTK_STATE_NORMAL);
4769 if (priv->transient_parent &&
4770 gtk_widget_get_realized (GTK_WIDGET (priv->transient_parent)))
4771 gdk_window_set_transient_for (gdk_window,
4772 gtk_widget_get_window (GTK_WIDGET (priv->transient_parent)));
4775 gdk_window_set_role (gdk_window, priv->wm_role);
4777 if (!priv->decorated)
4778 gdk_window_set_decorations (gdk_window, 0);
4780 if (!priv->deletable)
4781 gdk_window_set_functions (gdk_window, GDK_FUNC_ALL | GDK_FUNC_CLOSE);
4783 if (gtk_window_get_skip_pager_hint (window))
4784 gdk_window_set_skip_pager_hint (gdk_window, TRUE);
4786 if (gtk_window_get_skip_taskbar_hint (window))
4787 gdk_window_set_skip_taskbar_hint (gdk_window, TRUE);
4789 if (gtk_window_get_accept_focus (window))
4790 gdk_window_set_accept_focus (gdk_window, TRUE);
4792 gdk_window_set_accept_focus (gdk_window, FALSE);
4794 if (gtk_window_get_focus_on_map (window))
4795 gdk_window_set_focus_on_map (gdk_window, TRUE);
4797 gdk_window_set_focus_on_map (gdk_window, FALSE);
4800 gdk_window_set_modal_hint (gdk_window, TRUE);
4802 gdk_window_set_modal_hint (gdk_window, FALSE);
4804 if (priv->startup_id)
4806 #ifdef GDK_WINDOWING_X11
4807 guint32 timestamp = extract_time_from_startup_id (priv->startup_id);
4808 if (timestamp != GDK_CURRENT_TIME)
4809 gdk_x11_window_set_user_time (gdk_window, timestamp);
4811 if (!startup_id_is_fake (priv->startup_id))
4812 gdk_window_set_startup_id (gdk_window, priv->startup_id);
4816 gtk_window_realize_icon (window);
4820 gtk_window_unrealize (GtkWidget *widget)
4822 GtkWindow *window = GTK_WINDOW (widget);
4823 GtkWindowPrivate *priv = window->priv;
4824 GtkWindowGeometryInfo *info;
4826 /* On unrealize, we reset the size of the window such
4827 * that we will re-apply the default sizing stuff
4828 * next time we show the window.
4830 * Default positioning is reset on unmap, instead of unrealize.
4832 priv->need_default_size = TRUE;
4833 info = gtk_window_get_geometry_info (window, FALSE);
4836 info->resize_width = -1;
4837 info->resize_height = -1;
4838 info->last.configure_request.x = 0;
4839 info->last.configure_request.y = 0;
4840 info->last.configure_request.width = -1;
4841 info->last.configure_request.height = -1;
4842 /* be sure we reset geom hints on re-realize */
4843 info->last.flags = 0;
4848 gdk_window_set_user_data (priv->frame, NULL);
4849 gdk_window_destroy (priv->frame);
4854 gtk_window_unrealize_icon (window);
4856 GTK_WIDGET_CLASS (gtk_window_parent_class)->unrealize (widget);
4860 gtk_window_size_allocate (GtkWidget *widget,
4861 GtkAllocation *allocation)
4863 GtkWindow *window = GTK_WINDOW (widget);
4864 GtkWindowPrivate *priv = window->priv;
4865 GtkAllocation child_allocation;
4869 gtk_widget_set_allocation (widget, allocation);
4871 child = gtk_bin_get_child (&(window->bin));
4872 if (child && gtk_widget_get_visible (child))
4874 border_width = gtk_container_get_border_width (GTK_CONTAINER (window));
4875 child_allocation.x = border_width;
4876 child_allocation.y = border_width;
4877 child_allocation.width =
4878 MAX (1, (gint)allocation->width - child_allocation.x * 2);
4879 child_allocation.height =
4880 MAX (1, (gint)allocation->height - child_allocation.y * 2);
4882 gtk_widget_size_allocate (child, &child_allocation);
4885 if (gtk_widget_get_realized (widget) && priv->frame)
4887 gdk_window_resize (priv->frame,
4888 allocation->width + priv->frame_left + priv->frame_right,
4889 allocation->height + priv->frame_top + priv->frame_bottom);
4894 gtk_window_event (GtkWidget *widget, GdkEvent *event)
4896 GtkWindow *window = GTK_WINDOW (widget);
4897 GtkWindowPrivate *priv = window->priv;
4898 gboolean return_val;
4900 if (priv->frame && (event->any.window == priv->frame))
4902 if ((event->type != GDK_KEY_PRESS) &&
4903 (event->type != GDK_KEY_RELEASE) &&
4904 (event->type != GDK_FOCUS_CHANGE))
4906 g_signal_stop_emission_by_name (widget, "event");
4908 g_signal_emit (widget, window_signals[FRAME_EVENT], 0, event, &return_val);
4913 g_object_unref (event->any.window);
4914 event->any.window = g_object_ref (gtk_widget_get_window (widget));
4922 gtk_window_frame_event (GtkWindow *window, GdkEvent *event)
4924 GtkWindowPrivate *priv = window->priv;
4925 GdkEventConfigure *configure_event;
4928 switch (event->type)
4931 configure_event = (GdkEventConfigure *)event;
4933 /* Invalidate the decorations */
4936 rect.width = configure_event->width;
4937 rect.height = configure_event->height;
4939 gdk_window_invalidate_rect (priv->frame, &rect, FALSE);
4941 /* Pass on the (modified) configure event */
4942 configure_event->width -= priv->frame_left + priv->frame_right;
4943 configure_event->height -= priv->frame_top + priv->frame_bottom;
4944 return gtk_window_configure_event (GTK_WIDGET (window), configure_event);
4953 gtk_window_configure_event (GtkWidget *widget,
4954 GdkEventConfigure *event)
4956 GtkAllocation allocation;
4957 GtkWindow *window = GTK_WINDOW (widget);
4958 GtkWindowPrivate *priv = window->priv;
4959 gboolean expected_reply = priv->configure_request_count > 0;
4961 /* priv->configure_request_count incremented for each
4962 * configure request, and decremented to a min of 0 for
4963 * each configure notify.
4965 * All it means is that we know we will get at least
4966 * priv->configure_request_count more configure notifies.
4967 * We could get more configure notifies than that; some
4968 * of the configure notifies we get may be unrelated to
4969 * the configure requests. But we will get at least
4970 * priv->configure_request_count notifies.
4973 if (priv->configure_request_count > 0)
4975 priv->configure_request_count -= 1;
4976 gdk_window_thaw_toplevel_updates_libgtk_only (gtk_widget_get_window (widget));
4979 /* As an optimization, we avoid a resize when possible.
4981 * The only times we can avoid a resize are:
4982 * - we know only the position changed, not the size
4983 * - we know we have made more requests and so will get more
4984 * notifies and can wait to resize when we get them
4986 gtk_widget_get_allocation (widget, &allocation);
4987 if (!expected_reply &&
4988 (allocation.width == event->width &&
4989 allocation.height == event->height))
4991 gdk_window_configure_finished (gtk_widget_get_window (widget));
4996 * If we do need to resize, we do that by:
4997 * - filling in widget->allocation with the new size
4998 * - setting configure_notify_received to TRUE
4999 * for use in gtk_window_move_resize()
5000 * - queueing a resize, leading to invocation of
5001 * gtk_window_move_resize() in an idle handler
5005 priv->configure_notify_received = TRUE;
5007 allocation.width = event->width;
5008 allocation.height = event->height;
5009 gtk_widget_set_allocation (widget, &allocation);
5011 _gtk_container_queue_resize (GTK_CONTAINER (widget));
5016 /* the accel_key and accel_mods fields of the key have to be setup
5017 * upon calling this function. it'll then return whether that key
5018 * is at all used as accelerator, and if so will OR in the
5019 * accel_flags member of the key.
5022 _gtk_window_query_nonaccels (GtkWindow *window,
5024 GdkModifierType accel_mods)
5026 GtkWindowPrivate *priv;
5028 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
5030 priv = window->priv;
5032 /* movement keys are considered locked accels */
5035 static const guint bindings[] = {
5036 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,
5037 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,
5041 for (i = 0; i < G_N_ELEMENTS (bindings); i++)
5042 if (bindings[i] == accel_key)
5046 /* mnemonics are considered locked accels */
5047 if (accel_mods == priv->mnemonic_modifier)
5049 GtkMnemonicHash *mnemonic_hash = gtk_window_get_mnemonic_hash (window, FALSE);
5050 if (mnemonic_hash && _gtk_mnemonic_hash_lookup (mnemonic_hash, accel_key))
5058 * gtk_window_propagate_key_event:
5059 * @window: a #GtkWindow
5060 * @event: a #GdkEventKey
5062 * Propagate a key press or release event to the focus widget and
5063 * up the focus container chain until a widget handles @event.
5064 * This is normally called by the default ::key_press_event and
5065 * ::key_release_event handlers for toplevel windows,
5066 * however in some cases it may be useful to call this directly when
5067 * overriding the standard key handling for a toplevel window.
5069 * Return value: %TRUE if a widget in the focus chain handled the event.
5074 gtk_window_propagate_key_event (GtkWindow *window,
5077 GtkWindowPrivate *priv;
5078 gboolean handled = FALSE;
5079 GtkWidget *widget, *focus;
5081 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
5083 priv = window->priv;
5084 widget = GTK_WIDGET (window);
5086 focus = priv->focus_widget;
5088 g_object_ref (focus);
5091 focus && focus != widget &&
5092 gtk_widget_get_toplevel (focus) == widget)
5096 if (gtk_widget_is_sensitive (focus))
5097 handled = gtk_widget_event (focus, (GdkEvent*) event);
5099 parent = gtk_widget_get_parent (focus);
5101 g_object_ref (parent);
5103 g_object_unref (focus);
5109 g_object_unref (focus);
5115 gtk_window_key_press_event (GtkWidget *widget,
5118 GtkWindow *window = GTK_WINDOW (widget);
5119 gboolean handled = FALSE;
5121 /* handle mnemonics and accelerators */
5123 handled = gtk_window_activate_key (window, event);
5125 /* handle focus widget key events */
5127 handled = gtk_window_propagate_key_event (window, event);
5129 /* Chain up, invokes binding set */
5131 handled = GTK_WIDGET_CLASS (gtk_window_parent_class)->key_press_event (widget, event);
5137 gtk_window_key_release_event (GtkWidget *widget,
5140 GtkWindow *window = GTK_WINDOW (widget);
5141 gboolean handled = FALSE;
5143 /* handle focus widget key events */
5145 handled = gtk_window_propagate_key_event (window, event);
5147 /* Chain up, invokes binding set */
5149 handled = GTK_WIDGET_CLASS (gtk_window_parent_class)->key_release_event (widget, event);
5155 gtk_window_real_activate_default (GtkWindow *window)
5157 gtk_window_activate_default (window);
5161 gtk_window_real_activate_focus (GtkWindow *window)
5163 gtk_window_activate_focus (window);
5167 gtk_window_move_focus (GtkWindow *window,
5168 GtkDirectionType dir)
5170 gtk_widget_child_focus (GTK_WIDGET (window), dir);
5172 if (!gtk_container_get_focus_child (GTK_CONTAINER (window)))
5173 gtk_window_set_focus (window, NULL);
5177 gtk_window_enter_notify_event (GtkWidget *widget,
5178 GdkEventCrossing *event)
5184 gtk_window_leave_notify_event (GtkWidget *widget,
5185 GdkEventCrossing *event)
5191 do_focus_change (GtkWidget *widget,
5195 GdkDeviceManager *device_manager;
5198 g_object_ref (widget);
5200 device_manager = gdk_display_get_device_manager (gtk_widget_get_display (widget));
5201 devices = gdk_device_manager_list_devices (device_manager, GDK_DEVICE_TYPE_MASTER);
5202 devices = g_list_concat (devices, gdk_device_manager_list_devices (device_manager, GDK_DEVICE_TYPE_SLAVE));
5203 devices = g_list_concat (devices, gdk_device_manager_list_devices (device_manager, GDK_DEVICE_TYPE_FLOATING));
5205 for (d = devices; d; d = d->next)
5207 GdkDevice *dev = d->data;
5210 if (dev->source != GDK_SOURCE_KEYBOARD)
5213 /* Skip non-master keyboards that haven't
5214 * selected for events from this window
5216 window = gtk_widget_get_window (widget);
5217 if (gdk_device_get_device_type (dev) != GDK_DEVICE_TYPE_MASTER &&
5218 window && !gdk_window_get_device_events (window, dev))
5221 fevent = gdk_event_new (GDK_FOCUS_CHANGE);
5223 fevent->focus_change.type = GDK_FOCUS_CHANGE;
5224 fevent->focus_change.window = window;
5226 g_object_ref (window);
5227 fevent->focus_change.in = in;
5228 gdk_event_set_device (fevent, dev);
5230 gtk_widget_send_focus_change (widget, fevent);
5232 gdk_event_free (fevent);
5235 g_list_free (devices);
5236 g_object_unref (widget);
5240 gtk_window_focus_in_event (GtkWidget *widget,
5241 GdkEventFocus *event)
5243 GtkWindow *window = GTK_WINDOW (widget);
5245 /* It appears spurious focus in events can occur when
5246 * the window is hidden. So we'll just check to see if
5247 * the window is visible before actually handling the
5250 if (gtk_widget_get_visible (widget))
5252 _gtk_window_set_has_toplevel_focus (window, TRUE);
5253 _gtk_window_set_is_active (window, TRUE);
5260 gtk_window_focus_out_event (GtkWidget *widget,
5261 GdkEventFocus *event)
5263 GtkWindow *window = GTK_WINDOW (widget);
5264 gboolean auto_mnemonics;
5266 _gtk_window_set_has_toplevel_focus (window, FALSE);
5267 _gtk_window_set_is_active (window, FALSE);
5269 /* set the mnemonic-visible property to false */
5270 g_object_get (gtk_widget_get_settings (widget),
5271 "gtk-auto-mnemonics", &auto_mnemonics, NULL);
5273 gtk_window_set_mnemonics_visible (window, FALSE);
5278 static GdkAtom atom_rcfiles = GDK_NONE;
5279 static GdkAtom atom_iconthemes = GDK_NONE;
5282 send_client_message_to_embedded_windows (GtkWidget *widget,
5283 GdkAtom message_type)
5285 GList *embedded_windows;
5287 embedded_windows = g_object_get_qdata (G_OBJECT (widget), quark_gtk_embedded);
5288 if (embedded_windows)
5290 GdkEvent *send_event = gdk_event_new (GDK_CLIENT_EVENT);
5293 for (i = 0; i < 5; i++)
5294 send_event->client.data.l[i] = 0;
5295 send_event->client.data_format = 32;
5296 send_event->client.message_type = message_type;
5298 while (embedded_windows)
5300 GdkNativeWindow xid = GDK_GPOINTER_TO_NATIVE_WINDOW(embedded_windows->data);
5301 gdk_event_send_client_message_for_display (gtk_widget_get_display (widget), send_event, xid);
5302 embedded_windows = embedded_windows->next;
5305 gdk_event_free (send_event);
5310 gtk_window_client_event (GtkWidget *widget,
5311 GdkEventClient *event)
5315 atom_rcfiles = gdk_atom_intern_static_string ("_GTK_READ_RCFILES");
5316 atom_iconthemes = gdk_atom_intern_static_string ("_GTK_LOAD_ICONTHEMES");
5319 if (event->message_type == atom_rcfiles)
5321 send_client_message_to_embedded_windows (widget, atom_rcfiles);
5322 gtk_rc_reparse_all_for_settings (gtk_widget_get_settings (widget), FALSE);
5325 if (event->message_type == atom_iconthemes)
5327 send_client_message_to_embedded_windows (widget, atom_iconthemes);
5328 _gtk_icon_theme_check_reload (gtk_widget_get_display (widget));
5335 gtk_window_check_resize (GtkContainer *container)
5337 if (gtk_widget_get_visible (GTK_WIDGET (container)))
5338 gtk_window_move_resize (GTK_WINDOW (container));
5342 gtk_window_focus (GtkWidget *widget,
5343 GtkDirectionType direction)
5345 GtkWindowPrivate *priv;
5348 GtkContainer *container;
5350 GtkWidget *old_focus_child;
5353 container = GTK_CONTAINER (widget);
5354 window = GTK_WINDOW (widget);
5355 priv = window->priv;
5356 bin = GTK_BIN (widget);
5358 old_focus_child = gtk_container_get_focus_child (container);
5360 /* We need a special implementation here to deal properly with wrapping
5361 * around in the tab chain without the danger of going into an
5364 if (old_focus_child)
5366 if (gtk_widget_child_focus (old_focus_child, direction))
5370 if (priv->focus_widget)
5372 if (direction == GTK_DIR_LEFT ||
5373 direction == GTK_DIR_RIGHT ||
5374 direction == GTK_DIR_UP ||
5375 direction == GTK_DIR_DOWN)
5380 /* Wrapped off the end, clear the focus setting for the toplpevel */
5381 parent = gtk_widget_get_parent (priv->focus_widget);
5384 gtk_container_set_focus_child (GTK_CONTAINER (parent), NULL);
5385 parent = gtk_widget_get_parent (parent);
5388 gtk_window_set_focus (GTK_WINDOW (container), NULL);
5391 /* Now try to focus the first widget in the window */
5392 child = gtk_bin_get_child (bin);
5395 if (gtk_widget_child_focus (child, direction))
5403 gtk_window_real_set_focus (GtkWindow *window,
5406 GtkWindowPrivate *priv = window->priv;
5407 GtkWidget *old_focus = priv->focus_widget;
5408 gboolean had_default = FALSE;
5409 gboolean focus_had_default = FALSE;
5410 gboolean old_focus_had_default = FALSE;
5414 g_object_ref (old_focus);
5415 g_object_freeze_notify (G_OBJECT (old_focus));
5416 old_focus_had_default = gtk_widget_has_default (old_focus);
5420 g_object_ref (focus);
5421 g_object_freeze_notify (G_OBJECT (focus));
5422 focus_had_default = gtk_widget_has_default (focus);
5425 if (priv->default_widget)
5426 had_default = gtk_widget_has_default (priv->default_widget);
5428 if (priv->focus_widget)
5430 if (gtk_widget_get_receives_default (priv->focus_widget) &&
5431 (priv->focus_widget != priv->default_widget))
5433 _gtk_widget_set_has_default (priv->focus_widget, FALSE);
5434 gtk_widget_queue_draw (priv->focus_widget);
5436 if (priv->default_widget)
5437 _gtk_widget_set_has_default (priv->default_widget, TRUE);
5440 priv->focus_widget = NULL;
5442 if (priv->has_focus)
5443 do_focus_change (old_focus, FALSE);
5445 g_object_notify (G_OBJECT (old_focus), "is-focus");
5448 /* The above notifications may have set a new focus widget,
5449 * if so, we don't want to override it.
5451 if (focus && !priv->focus_widget)
5453 priv->focus_widget = focus;
5455 if (gtk_widget_get_receives_default (priv->focus_widget) &&
5456 (priv->focus_widget != priv->default_widget))
5458 if (gtk_widget_get_can_default (priv->focus_widget))
5459 _gtk_widget_set_has_default (priv->focus_widget, TRUE);
5461 if (priv->default_widget)
5462 _gtk_widget_set_has_default (priv->default_widget, FALSE);
5465 if (priv->has_focus)
5466 do_focus_change (priv->focus_widget, TRUE);
5468 g_object_notify (G_OBJECT (priv->focus_widget), "is-focus");
5471 /* If the default widget changed, a redraw will have been queued
5472 * on the old and new default widgets by gtk_window_set_default(), so
5473 * we only have to worry about the case where it didn't change.
5474 * We'll sometimes queue a draw twice on the new widget but that
5477 if (priv->default_widget &&
5478 (had_default != gtk_widget_has_default (priv->default_widget)))
5479 gtk_widget_queue_draw (priv->default_widget);
5483 if (old_focus_had_default != gtk_widget_has_default (old_focus))
5484 gtk_widget_queue_draw (old_focus);
5486 g_object_thaw_notify (G_OBJECT (old_focus));
5487 g_object_unref (old_focus);
5491 if (focus_had_default != gtk_widget_has_default (focus))
5492 gtk_widget_queue_draw (focus);
5494 g_object_thaw_notify (G_OBJECT (focus));
5495 g_object_unref (focus);
5501 gtk_window_get_preferred_width (GtkWidget *widget,
5509 window = GTK_WINDOW (widget);
5510 child = gtk_bin_get_child (GTK_BIN (window));
5512 border_width = gtk_container_get_border_width (GTK_CONTAINER (window));
5513 *minimum_size = border_width * 2;
5514 *natural_size = border_width * 2;
5516 if (child && gtk_widget_get_visible (child))
5518 gint child_min, child_nat;
5519 gtk_widget_get_preferred_width (child, &child_min, &child_nat);
5521 *minimum_size += child_min;
5522 *natural_size += child_nat;
5527 gtk_window_get_preferred_height (GtkWidget *widget,
5535 window = GTK_WINDOW (widget);
5536 child = gtk_bin_get_child (GTK_BIN (window));
5538 border_width = gtk_container_get_border_width (GTK_CONTAINER (window));
5539 *minimum_size = border_width * 2;
5540 *natural_size = border_width * 2;
5542 if (child && gtk_widget_get_visible (child))
5544 gint child_min, child_nat;
5545 gtk_widget_get_preferred_height (child, &child_min, &child_nat);
5547 *minimum_size += child_min;
5548 *natural_size += child_nat;
5554 * _gtk_window_unset_focus_and_default:
5555 * @window: a #GtkWindow
5556 * @widget: a widget inside of @window
5558 * Checks whether the focus and default widgets of @window are
5559 * @widget or a descendent of @widget, and if so, unset them.
5562 _gtk_window_unset_focus_and_default (GtkWindow *window,
5566 GtkWindowPrivate *priv = window->priv;
5570 g_object_ref (window);
5571 g_object_ref (widget);
5573 parent = gtk_widget_get_parent (widget);
5574 if (gtk_container_get_focus_child (GTK_CONTAINER (parent)) == widget)
5576 child = priv->focus_widget;
5578 while (child && child != widget)
5579 child = gtk_widget_get_parent (child);
5581 if (child == widget)
5582 gtk_window_set_focus (GTK_WINDOW (window), NULL);
5585 child = priv->default_widget;
5587 while (child && child != widget)
5588 child = gtk_widget_get_parent (child);
5590 if (child == widget)
5591 gtk_window_set_default (window, NULL);
5593 g_object_unref (widget);
5594 g_object_unref (window);
5597 /*********************************
5598 * Functions related to resizing *
5599 *********************************/
5601 /* This function doesn't constrain to geometry hints */
5603 gtk_window_compute_configure_request_size (GtkWindow *window,
5607 GtkWindowPrivate *priv = window->priv;
5608 GtkRequisition requisition;
5609 GtkWindowGeometryInfo *info;
5613 * - we've done a size request
5616 widget = GTK_WIDGET (window);
5618 info = gtk_window_get_geometry_info (window, FALSE);
5620 if (priv->need_default_size)
5622 gtk_widget_get_preferred_size (widget, &requisition, NULL);
5624 /* Default to requisition */
5625 *width = requisition.width;
5626 *height = requisition.height;
5628 /* If window is empty so requests 0, default to random nonzero size */
5629 if (*width == 0 && *height == 0)
5635 /* Override requisition with default size */
5639 gint base_width = 0;
5640 gint base_height = 0;
5642 gint min_height = 0;
5644 gint height_inc = 1;
5646 if (info->default_is_geometry &&
5647 (info->default_width > 0 || info->default_height > 0))
5649 GdkGeometry geometry;
5652 gtk_window_compute_hints (window, &geometry, &flags);
5654 if (flags & GDK_HINT_BASE_SIZE)
5656 base_width = geometry.base_width;
5657 base_height = geometry.base_height;
5659 if (flags & GDK_HINT_MIN_SIZE)
5661 min_width = geometry.min_width;
5662 min_height = geometry.min_height;
5664 if (flags & GDK_HINT_RESIZE_INC)
5666 width_inc = geometry.width_inc;
5667 height_inc = geometry.height_inc;
5671 if (info->default_width > 0)
5672 *width = MAX (info->default_width * width_inc + base_width, min_width);
5674 if (info->default_height > 0)
5675 *height = MAX (info->default_height * height_inc + base_height, min_height);
5680 GtkAllocation allocation;
5682 gtk_widget_get_allocation (widget, &allocation);
5684 /* Default to keeping current size */
5685 *width = allocation.width;
5686 *height = allocation.height;
5689 /* Override any size with gtk_window_resize() values */
5692 if (info->resize_width > 0)
5693 *width = info->resize_width;
5695 if (info->resize_height > 0)
5696 *height = info->resize_height;
5699 /* Don't ever request zero width or height, its not supported by
5700 gdk. The size allocation code will round it to 1 anyway but if
5701 we do it then the value returned from this function will is
5702 not comparable to the size allocation read from the GtkWindow. */
5703 *width = MAX (*width, 1);
5704 *height = MAX (*height, 1);
5707 static GtkWindowPosition
5708 get_effective_position (GtkWindow *window)
5710 GtkWindowPrivate *priv = window->priv;
5711 GtkWindowPosition pos = priv->position;
5713 if (pos == GTK_WIN_POS_CENTER_ON_PARENT &&
5714 (priv->transient_parent == NULL ||
5715 !gtk_widget_get_mapped (GTK_WIDGET (priv->transient_parent))))
5716 pos = GTK_WIN_POS_NONE;
5722 get_center_monitor_of_window (GtkWindow *window)
5724 /* We could try to sort out the relative positions of the monitors and
5725 * stuff, or we could just be losers and assume you have a row
5726 * or column of monitors.
5728 return gdk_screen_get_n_monitors (gtk_window_check_screen (window)) / 2;
5732 get_monitor_containing_pointer (GtkWindow *window)
5736 GdkScreen *window_screen;
5737 GdkScreen *pointer_screen;
5738 GdkDisplay *display;
5739 GdkDeviceManager *device_manager;
5742 window_screen = gtk_window_check_screen (window);
5743 display = gdk_screen_get_display (window_screen);
5744 device_manager = gdk_display_get_device_manager (display);
5745 pointer = gdk_device_manager_get_client_pointer (device_manager);
5747 gdk_display_get_device_state (display, pointer,
5751 if (pointer_screen == window_screen)
5752 monitor_num = gdk_screen_get_monitor_at_point (pointer_screen, px, py);
5760 center_window_on_monitor (GtkWindow *window,
5766 GdkRectangle monitor;
5769 monitor_num = get_monitor_containing_pointer (window);
5771 if (monitor_num == -1)
5772 monitor_num = get_center_monitor_of_window (window);
5774 gdk_screen_get_monitor_geometry (gtk_window_check_screen (window),
5775 monitor_num, &monitor);
5777 *x = (monitor.width - w) / 2 + monitor.x;
5778 *y = (monitor.height - h) / 2 + monitor.y;
5780 /* Be sure we aren't off the monitor, ignoring _NET_WM_STRUT
5781 * and WM decorations.
5795 if (extent > clamp_extent)
5797 *base = clamp_base + clamp_extent/2 - extent/2;
5798 else if (*base < clamp_base)
5800 else if (*base + extent > clamp_base + clamp_extent)
5801 *base = clamp_base + clamp_extent - extent;
5805 clamp_window_to_rectangle (gint *x,
5809 const GdkRectangle *rect)
5811 #ifdef DEBUGGING_OUTPUT
5812 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);
5815 /* If it is too large, center it. If it fits on the monitor but is
5816 * partially outside, move it to the closest edge. Do this
5817 * separately in x and y directions.
5819 clamp (x, w, rect->x, rect->width);
5820 clamp (y, h, rect->y, rect->height);
5821 #ifdef DEBUGGING_OUTPUT
5822 g_print (" ==> %+d%+d: %dx%d\n", *x, *y, w, h);
5828 gtk_window_compute_configure_request (GtkWindow *window,
5829 GdkRectangle *request,
5830 GdkGeometry *geometry,
5833 GtkWindowPrivate *priv = window->priv;
5834 GdkGeometry new_geometry;
5838 GtkWindowPosition pos;
5839 GtkWidget *parent_widget;
5840 GtkWindowGeometryInfo *info;
5844 widget = GTK_WIDGET (window);
5846 screen = gtk_window_check_screen (window);
5848 gtk_widget_get_preferred_size (widget, NULL, NULL);
5849 gtk_window_compute_configure_request_size (window, (guint *)&w, (guint *)&h);
5851 gtk_window_compute_hints (window, &new_geometry, &new_flags);
5852 gtk_window_constrain_size (window,
5853 &new_geometry, new_flags,
5857 parent_widget = (GtkWidget*) priv->transient_parent;
5859 pos = get_effective_position (window);
5860 info = gtk_window_get_geometry_info (window, FALSE);
5862 /* by default, don't change position requested */
5865 x = info->last.configure_request.x;
5866 y = info->last.configure_request.y;
5875 if (priv->need_default_position)
5878 /* FIXME this all interrelates with window gravity.
5879 * For most of them I think we want to set GRAVITY_CENTER.
5881 * Not sure how to go about that.
5886 /* here we are only handling CENTER_ALWAYS
5887 * as it relates to default positioning,
5888 * where it's equivalent to simply CENTER
5890 case GTK_WIN_POS_CENTER_ALWAYS:
5891 case GTK_WIN_POS_CENTER:
5892 center_window_on_monitor (window, w, h, &x, &y);
5895 case GTK_WIN_POS_CENTER_ON_PARENT:
5897 GtkAllocation allocation;
5898 GdkWindow *gdk_window;
5900 GdkRectangle monitor;
5903 g_assert (gtk_widget_get_mapped (parent_widget)); /* established earlier */
5905 gdk_window = gtk_widget_get_window (parent_widget);
5907 if (gdk_window != NULL)
5908 monitor_num = gdk_screen_get_monitor_at_window (screen,
5913 gdk_window_get_origin (gdk_window,
5916 gtk_widget_get_allocation (parent_widget, &allocation);
5917 x = ox + (allocation.width - w) / 2;
5918 y = oy + (allocation.height - h) / 2;
5920 /* Clamp onto current monitor, ignoring _NET_WM_STRUT and
5921 * WM decorations. If parent wasn't on a monitor, just
5924 if (monitor_num >= 0)
5926 gdk_screen_get_monitor_geometry (screen, monitor_num, &monitor);
5927 clamp_window_to_rectangle (&x, &y, w, h, &monitor);
5932 case GTK_WIN_POS_MOUSE:
5934 gint screen_width = gdk_screen_get_width (screen);
5935 gint screen_height = gdk_screen_get_height (screen);
5937 GdkRectangle monitor;
5938 GdkDisplay *display;
5939 GdkDeviceManager *device_manager;
5941 GdkScreen *pointer_screen;
5944 display = gdk_screen_get_display (screen);
5945 device_manager = gdk_display_get_device_manager (display);
5946 pointer = gdk_device_manager_get_client_pointer (device_manager);
5948 gdk_display_get_device_state (display, pointer,
5952 if (pointer_screen == screen)
5953 monitor_num = gdk_screen_get_monitor_at_point (screen, px, py);
5959 x = CLAMP (x, 0, screen_width - w);
5960 y = CLAMP (y, 0, screen_height - h);
5962 /* Clamp onto current monitor, ignoring _NET_WM_STRUT and
5963 * WM decorations. Don't try to figure out what's going
5964 * on if the mouse wasn't inside a monitor.
5966 if (monitor_num >= 0)
5968 gdk_screen_get_monitor_geometry (screen, monitor_num, &monitor);
5969 clamp_window_to_rectangle (&x, &y, w, h, &monitor);
5977 } /* if (priv->need_default_position) */
5979 if (priv->need_default_position && info &&
5980 info->initial_pos_set)
5982 x = info->initial_x;
5983 y = info->initial_y;
5984 gtk_window_constrain_position (window, w, h, &x, &y);
5990 request->height = h;
5993 *geometry = new_geometry;
5999 gtk_window_constrain_position (GtkWindow *window,
6005 GtkWindowPrivate *priv = window->priv;
6007 /* See long comments in gtk_window_move_resize()
6008 * on when it's safe to call this function.
6010 if (priv->position == GTK_WIN_POS_CENTER_ALWAYS)
6012 gint center_x, center_y;
6014 center_window_on_monitor (window, new_width, new_height, ¢er_x, ¢er_y);
6022 gtk_window_move_resize (GtkWindow *window)
6026 * First we determine whether any information has changed that would
6027 * cause us to revise our last configure request. If we would send
6028 * a different configure request from last time, then
6029 * configure_request_size_changed = TRUE or
6030 * configure_request_pos_changed = TRUE. configure_request_size_changed
6031 * may be true due to new hints, a gtk_window_resize(), or whatever.
6032 * configure_request_pos_changed may be true due to gtk_window_set_position()
6033 * or gtk_window_move().
6035 * If the configure request has changed, we send off a new one. To
6036 * ensure GTK+ invariants are maintained (resize queue does what it
6037 * should), we go ahead and size_allocate the requested size in this
6040 * If the configure request has not changed, we don't ever resend
6041 * it, because it could mean fighting the user or window manager.
6044 * To prepare the configure request, we come up with a base size/pos:
6045 * - the one from gtk_window_move()/gtk_window_resize()
6046 * - else default_width, default_height if we haven't ever
6048 * - else the size request if we haven't ever been mapped,
6049 * as a substitute default size
6050 * - else the current size of the window, as received from
6051 * configure notifies (i.e. the current allocation)
6053 * If GTK_WIN_POS_CENTER_ALWAYS is active, we constrain
6054 * the position request to be centered.
6056 GtkWindowPrivate *priv = window->priv;
6057 GtkAllocation allocation;
6059 GtkContainer *container;
6060 GtkWindowGeometryInfo *info;
6061 GdkGeometry new_geometry;
6062 GdkWindow *gdk_window;
6064 GdkRectangle new_request;
6065 gboolean configure_request_size_changed;
6066 gboolean configure_request_pos_changed;
6067 gboolean hints_changed; /* do we need to send these again */
6068 GtkWindowLastGeometryInfo saved_last_info;
6070 widget = GTK_WIDGET (window);
6071 gdk_window = gtk_widget_get_window (widget);
6072 container = GTK_CONTAINER (widget);
6073 info = gtk_window_get_geometry_info (window, TRUE);
6075 configure_request_size_changed = FALSE;
6076 configure_request_pos_changed = FALSE;
6078 gtk_window_compute_configure_request (window, &new_request,
6079 &new_geometry, &new_flags);
6081 /* This check implies the invariant that we never set info->last
6082 * without setting the hints and sending off a configure request.
6084 * If we change info->last without sending the request, we may
6087 if (info->last.configure_request.x != new_request.x ||
6088 info->last.configure_request.y != new_request.y)
6089 configure_request_pos_changed = TRUE;
6091 if ((info->last.configure_request.width != new_request.width ||
6092 info->last.configure_request.height != new_request.height))
6093 configure_request_size_changed = TRUE;
6095 hints_changed = FALSE;
6097 if (!gtk_window_compare_hints (&info->last.geometry, info->last.flags,
6098 &new_geometry, new_flags))
6100 hints_changed = TRUE;
6103 /* Position Constraints
6104 * ====================
6106 * POS_CENTER_ALWAYS is conceptually a constraint rather than
6107 * a default. The other POS_ values are used only when the
6108 * window is shown, not after that.
6110 * However, we can't implement a position constraint as
6111 * "anytime the window size changes, center the window"
6112 * because this may well end up fighting the WM or user. In
6113 * fact it gets in an infinite loop with at least one WM.
6115 * Basically, applications are in no way in a position to
6116 * constrain the position of a window, with one exception:
6117 * override redirect windows. (Really the intended purpose
6118 * of CENTER_ALWAYS anyhow, I would think.)
6120 * So the way we implement this "constraint" is to say that when WE
6121 * cause a move or resize, i.e. we make a configure request changing
6122 * window size, we recompute the CENTER_ALWAYS position to reflect
6123 * the new window size, and include it in our request. Also, if we
6124 * just turned on CENTER_ALWAYS we snap to center with a new
6125 * request. Otherwise, if we are just NOTIFIED of a move or resize
6126 * done by someone else e.g. the window manager, we do NOT send a
6127 * new configure request.
6129 * For override redirect windows, this works fine; all window
6130 * sizes are from our configure requests. For managed windows,
6131 * it is at least semi-sane, though who knows what the
6132 * app author is thinking.
6135 /* This condition should be kept in sync with the condition later on
6136 * that determines whether we send a configure request. i.e. we
6137 * should do this position constraining anytime we were going to
6138 * send a configure request anyhow, plus when constraints have
6141 if (configure_request_pos_changed ||
6142 configure_request_size_changed ||
6144 info->position_constraints_changed)
6146 /* We request the constrained position if:
6147 * - we were changing position, and need to clamp
6148 * the change to the constraint
6149 * - we're changing the size anyway
6150 * - set_position() was called to toggle CENTER_ALWAYS on
6153 gtk_window_constrain_position (window,
6159 /* Update whether we need to request a move */
6160 if (info->last.configure_request.x != new_request.x ||
6161 info->last.configure_request.y != new_request.y)
6162 configure_request_pos_changed = TRUE;
6164 configure_request_pos_changed = FALSE;
6168 if (priv->type == GTK_WINDOW_TOPLEVEL)
6170 int notify_x, notify_y;
6172 /* this is the position from the last configure notify */
6173 gdk_window_get_position (widget->window, ¬ify_x, ¬ify_y);
6175 g_message ("--- %s ---\n"
6176 "last : %d,%d\t%d x %d\n"
6177 "this : %d,%d\t%d x %d\n"
6178 "alloc : %d,%d\t%d x %d\n"
6180 "resize: \t%d x %d\n"
6181 "size_changed: %d pos_changed: %d hints_changed: %d\n"
6182 "configure_notify_received: %d\n"
6183 "configure_request_count: %d\n"
6184 "position_constraints_changed: %d\n",
6185 priv->title ? priv->title : "(no title)",
6186 info->last.configure_request.x,
6187 info->last.configure_request.y,
6188 info->last.configure_request.width,
6189 info->last.configure_request.height,
6195 widget->allocation.width,
6196 widget->allocation.height,
6197 widget->requisition.width,
6198 widget->requisition.height,
6200 info->resize_height,
6201 configure_request_pos_changed,
6202 configure_request_size_changed,
6204 priv->configure_notify_received,
6205 priv->configure_request_count,
6206 info->position_constraints_changed);
6210 saved_last_info = info->last;
6211 info->last.geometry = new_geometry;
6212 info->last.flags = new_flags;
6213 info->last.configure_request = new_request;
6215 /* need to set PPosition so the WM will look at our position,
6216 * but we don't want to count PPosition coming and going as a hints
6217 * change for future iterations. So we saved info->last prior to
6221 /* Also, if the initial position was explicitly set, then we always
6222 * toggle on PPosition. This makes gtk_window_move(window, 0, 0)
6226 /* Also, we toggle on PPosition if GTK_WIN_POS_ is in use and
6227 * this is an initial map
6230 if ((configure_request_pos_changed ||
6231 info->initial_pos_set ||
6232 (priv->need_default_position &&
6233 get_effective_position (window) != GTK_WIN_POS_NONE)) &&
6234 (new_flags & GDK_HINT_POS) == 0)
6236 new_flags |= GDK_HINT_POS;
6237 hints_changed = TRUE;
6240 /* Set hints if necessary
6243 gdk_window_set_geometry_hints (gdk_window,
6247 gtk_widget_get_allocation (widget, &allocation);
6249 /* handle resizing/moving and widget tree allocation
6251 if (priv->configure_notify_received)
6253 /* If we have received a configure event since
6254 * the last time in this function, we need to
6255 * accept our new size and size_allocate child widgets.
6256 * (see gtk_window_configure_event() for more details).
6258 * 1 or more configure notifies may have been received.
6259 * Also, configure_notify_received will only be TRUE
6260 * if all expected configure notifies have been received
6261 * (one per configure request), as an optimization.
6264 priv->configure_notify_received = FALSE;
6266 /* gtk_window_configure_event() filled in widget->allocation */
6267 gtk_widget_size_allocate (widget, &allocation);
6269 gdk_window_process_updates (gdk_window, TRUE);
6271 gdk_window_configure_finished (gdk_window);
6273 /* If the configure request changed, it means that
6275 * 1) coincidentally changed hints or widget properties
6276 * impacting the configure request before getting
6277 * a configure notify, or
6278 * 2) some broken widget is changing its size request
6279 * during size allocation, resulting in
6280 * a false appearance of changed configure request.
6282 * For 1), we could just go ahead and ask for the
6283 * new size right now, but doing that for 2)
6284 * might well be fighting the user (and can even
6285 * trigger a loop). Since we really don't want to
6286 * do that, we requeue a resize in hopes that
6287 * by the time it gets handled, the child has seen
6288 * the light and is willing to go along with the
6289 * new size. (this happens for the zvt widget, since
6290 * the size_allocate() above will have stored the
6291 * requisition corresponding to the new size in the
6294 * This doesn't buy us anything for 1), but it shouldn't
6295 * hurt us too badly, since it is what would have
6296 * happened if we had gotten the configure event before
6297 * the new size had been set.
6300 if (configure_request_size_changed ||
6301 configure_request_pos_changed)
6303 /* Don't change the recorded last info after all, because we
6304 * haven't actually updated to the new info yet - we decided
6305 * to postpone our configure request until later.
6307 info->last = saved_last_info;
6309 gtk_widget_queue_resize_no_redraw (widget); /* migth recurse for GTK_RESIZE_IMMEDIATE */
6312 return; /* Bail out, we didn't really process the move/resize */
6314 else if ((configure_request_size_changed || hints_changed) &&
6315 (allocation.width != new_request.width || allocation.height != new_request.height))
6318 /* We are in one of the following situations:
6319 * A. configure_request_size_changed
6320 * our requisition has changed and we need a different window size,
6321 * so we request it from the window manager.
6322 * B. !configure_request_size_changed && hints_changed
6323 * the window manager rejects our size, but we have just changed the
6324 * window manager hints, so there's a chance our request will
6325 * be honoured this time, so we try again.
6327 * However, if the new requisition is the same as the current allocation,
6328 * we don't request it again, since we won't get a ConfigureNotify back from
6329 * the window manager unless it decides to change our requisition. If
6330 * we don't get the ConfigureNotify back, the resize queue will never be run.
6333 /* Now send the configure request */
6334 if (configure_request_pos_changed)
6338 gdk_window_move_resize (priv->frame,
6339 new_request.x - priv->frame_left,
6340 new_request.y - priv->frame_top,
6341 new_request.width + priv->frame_left + priv->frame_right,
6342 new_request.height + priv->frame_top + priv->frame_bottom);
6343 gdk_window_resize (gdk_window,
6344 new_request.width, new_request.height);
6347 gdk_window_move_resize (gdk_window,
6348 new_request.x, new_request.y,
6349 new_request.width, new_request.height);
6351 else /* only size changed */
6354 gdk_window_resize (priv->frame,
6355 new_request.width + priv->frame_left + priv->frame_right,
6356 new_request.height + priv->frame_top + priv->frame_bottom);
6357 gdk_window_resize (gdk_window,
6358 new_request.width, new_request.height);
6361 if (priv->type == GTK_WINDOW_POPUP)
6363 GtkAllocation allocation;
6365 /* Directly size allocate for override redirect (popup) windows. */
6368 allocation.width = new_request.width;
6369 allocation.height = new_request.height;
6371 gtk_widget_size_allocate (widget, &allocation);
6373 gdk_window_process_updates (gdk_window, TRUE);
6375 if (gtk_container_get_resize_mode (container) == GTK_RESIZE_QUEUE)
6376 gtk_widget_queue_draw (widget);
6380 /* Increment the number of have-not-yet-received-notify requests */
6381 priv->configure_request_count += 1;
6382 gdk_window_freeze_toplevel_updates_libgtk_only (gdk_window);
6384 /* for GTK_RESIZE_QUEUE toplevels, we are now awaiting a new
6385 * configure event in response to our resizing request.
6386 * the configure event will cause a new resize with
6387 * ->configure_notify_received=TRUE.
6388 * until then, we want to
6389 * - discard expose events
6390 * - coalesce resizes for our children
6391 * - defer any window resizes until the configure event arrived
6392 * to achieve this, we queue a resize for the window, but remove its
6393 * resizing handler, so resizing will not be handled from the next
6394 * idle handler but when the configure event arrives.
6396 * FIXME: we should also dequeue the pending redraws here, since
6397 * we handle those ourselves upon ->configure_notify_received==TRUE.
6399 if (gtk_container_get_resize_mode (container) == GTK_RESIZE_QUEUE)
6401 gtk_widget_queue_resize_no_redraw (widget);
6402 _gtk_container_dequeue_resize_handler (container);
6408 /* Handle any position changes.
6410 if (configure_request_pos_changed)
6414 gdk_window_move (priv->frame,
6415 new_request.x - priv->frame_left,
6416 new_request.y - priv->frame_top);
6419 gdk_window_move (gdk_window,
6420 new_request.x, new_request.y);
6423 /* And run the resize queue.
6425 gtk_container_resize_children (container);
6428 /* We have now processed a move/resize since the last position
6429 * constraint change, setting of the initial position, or resize.
6430 * (Not resetting these flags here can lead to infinite loops for
6431 * GTK_RESIZE_IMMEDIATE containers)
6433 info->position_constraints_changed = FALSE;
6434 info->initial_pos_set = FALSE;
6435 info->resize_width = -1;
6436 info->resize_height = -1;
6439 /* Compare two sets of Geometry hints for equality.
6442 gtk_window_compare_hints (GdkGeometry *geometry_a,
6444 GdkGeometry *geometry_b,
6447 if (flags_a != flags_b)
6450 if ((flags_a & GDK_HINT_MIN_SIZE) &&
6451 (geometry_a->min_width != geometry_b->min_width ||
6452 geometry_a->min_height != geometry_b->min_height))
6455 if ((flags_a & GDK_HINT_MAX_SIZE) &&
6456 (geometry_a->max_width != geometry_b->max_width ||
6457 geometry_a->max_height != geometry_b->max_height))
6460 if ((flags_a & GDK_HINT_BASE_SIZE) &&
6461 (geometry_a->base_width != geometry_b->base_width ||
6462 geometry_a->base_height != geometry_b->base_height))
6465 if ((flags_a & GDK_HINT_ASPECT) &&
6466 (geometry_a->min_aspect != geometry_b->min_aspect ||
6467 geometry_a->max_aspect != geometry_b->max_aspect))
6470 if ((flags_a & GDK_HINT_RESIZE_INC) &&
6471 (geometry_a->width_inc != geometry_b->width_inc ||
6472 geometry_a->height_inc != geometry_b->height_inc))
6475 if ((flags_a & GDK_HINT_WIN_GRAVITY) &&
6476 geometry_a->win_gravity != geometry_b->win_gravity)
6483 _gtk_window_constrain_size (GtkWindow *window,
6489 GtkWindowPrivate *priv;
6490 GtkWindowGeometryInfo *info;
6492 g_return_if_fail (GTK_IS_WINDOW (window));
6494 priv = window->priv;
6496 info = priv->geometry_info;
6499 GdkWindowHints flags = info->last.flags;
6500 GdkGeometry *geometry = &info->last.geometry;
6502 gtk_window_constrain_size (window,
6513 gtk_window_constrain_size (GtkWindow *window,
6514 GdkGeometry *geometry,
6521 gdk_window_constrain_size (geometry, flags, width, height,
6522 new_width, new_height);
6525 /* Compute the set of geometry hints and flags for a window
6526 * based on the application set geometry, and requisition
6527 * of the window. gtk_size_request_get_preferred_size() must have been
6531 gtk_window_compute_hints (GtkWindow *window,
6532 GdkGeometry *new_geometry,
6535 GtkWindowPrivate *priv = window->priv;
6537 gint extra_width = 0;
6538 gint extra_height = 0;
6539 GtkWindowGeometryInfo *geometry_info;
6540 GtkRequisition requisition;
6542 widget = GTK_WIDGET (window);
6544 gtk_widget_get_preferred_size (widget, &requisition, NULL);
6545 geometry_info = gtk_window_get_geometry_info (GTK_WINDOW (widget), FALSE);
6549 *new_flags = geometry_info->mask;
6550 *new_geometry = geometry_info->geometry;
6557 if (geometry_info && geometry_info->widget)
6559 GtkRequisition requisition;
6560 GtkRequisition child_requisition;
6562 /* FIXME: This really isn't right. It gets the min size wrong and forces
6563 * callers to do horrible hacks like set a huge usize on the child requisition
6564 * to get the base size right. We really want to find the answers to:
6566 * - If the geometry widget was infinitely big, how much extra space
6567 * would be needed for the stuff around it.
6569 * - If the geometry widget was infinitely small, how big would the
6570 * window still have to be.
6572 * Finding these answers would be a bit of a mess here. (Bug #68668)
6574 gtk_widget_get_preferred_size (geometry_info->widget,
6575 &child_requisition, NULL);
6577 gtk_widget_get_preferred_size (widget,
6578 &requisition, NULL);
6579 extra_width = requisition.width - child_requisition.width;
6580 extra_height = requisition.height - child_requisition.height;
6583 /* We don't want to set GDK_HINT_POS in here, we just set it
6584 * in gtk_window_move_resize() when we want the position
6588 if (*new_flags & GDK_HINT_BASE_SIZE)
6590 new_geometry->base_width += extra_width;
6591 new_geometry->base_height += extra_height;
6593 else if (!(*new_flags & GDK_HINT_MIN_SIZE) &&
6594 (*new_flags & GDK_HINT_RESIZE_INC) &&
6595 ((extra_width != 0) || (extra_height != 0)))
6597 *new_flags |= GDK_HINT_BASE_SIZE;
6599 new_geometry->base_width = extra_width;
6600 new_geometry->base_height = extra_height;
6603 if (*new_flags & GDK_HINT_MIN_SIZE)
6605 if (new_geometry->min_width < 0)
6606 new_geometry->min_width = requisition.width;
6608 new_geometry->min_width += extra_width;
6610 if (new_geometry->min_height < 0)
6611 new_geometry->min_height = requisition.height;
6613 new_geometry->min_height += extra_height;
6617 *new_flags |= GDK_HINT_MIN_SIZE;
6619 new_geometry->min_width = requisition.width;
6620 new_geometry->min_height = requisition.height;
6623 if (*new_flags & GDK_HINT_MAX_SIZE)
6625 if (new_geometry->max_width < 0)
6626 new_geometry->max_width = requisition.width;
6628 new_geometry->max_width += extra_width;
6630 if (new_geometry->max_height < 0)
6631 new_geometry->max_height = requisition.height;
6633 new_geometry->max_height += extra_height;
6635 else if (!priv->resizable)
6637 *new_flags |= GDK_HINT_MAX_SIZE;
6639 new_geometry->max_width = requisition.width;
6640 new_geometry->max_height = requisition.height;
6643 *new_flags |= GDK_HINT_WIN_GRAVITY;
6644 new_geometry->win_gravity = priv->gravity;
6647 /***********************
6648 * Redrawing functions *
6649 ***********************/
6652 gtk_window_draw (GtkWidget *widget,
6655 if (!gtk_widget_get_app_paintable (widget))
6656 gtk_paint_flat_box (gtk_widget_get_style (widget),
6659 GTK_SHADOW_NONE, widget, "base",
6661 gtk_widget_get_allocated_width (widget),
6662 gtk_widget_get_allocated_height (widget));
6664 if (GTK_WIDGET_CLASS (gtk_window_parent_class)->draw)
6665 return GTK_WIDGET_CLASS (gtk_window_parent_class)->draw (widget, cr);
6671 * gtk_window_set_has_frame:
6672 * @window: a #GtkWindow
6673 * @setting: a boolean
6675 * (Note: this is a special-purpose function for the framebuffer port,
6676 * that causes GTK+ to draw its own window border. For most applications,
6677 * you want gtk_window_set_decorated() instead, which tells the window
6678 * manager whether to draw the window border.)
6680 * If this function is called on a window with setting of %TRUE, before
6681 * it is realized or showed, it will have a "frame" window around
6682 * @window->window, accessible in @window->frame. Using the signal
6683 * frame_event you can receive all events targeted at the frame.
6685 * This function is used by the linux-fb port to implement managed
6686 * windows, but it could conceivably be used by X-programs that
6687 * want to do their own window decorations.
6691 gtk_window_set_has_frame (GtkWindow *window,
6694 GtkWindowPrivate *priv;
6696 g_return_if_fail (GTK_IS_WINDOW (window));
6697 g_return_if_fail (!gtk_widget_get_realized (GTK_WIDGET (window)));
6699 priv = window->priv;
6701 priv->has_frame = setting != FALSE;
6705 * gtk_window_get_has_frame:
6706 * @window: a #GtkWindow
6708 * Accessor for whether the window has a frame window exterior to
6709 * @window->window. Gets the value set by gtk_window_set_has_frame ().
6711 * Return value: %TRUE if a frame has been added to the window
6712 * via gtk_window_set_has_frame().
6715 gtk_window_get_has_frame (GtkWindow *window)
6717 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
6719 return window->priv->has_frame;
6723 * gtk_window_set_frame_dimensions:
6724 * @window: a #GtkWindow that has a frame
6725 * @left: The width of the left border
6726 * @top: The height of the top border
6727 * @right: The width of the right border
6728 * @bottom: The height of the bottom border
6730 * (Note: this is a special-purpose function intended for the framebuffer
6731 * port; see gtk_window_set_has_frame(). It will have no effect on the
6732 * window border drawn by the window manager, which is the normal
6733 * case when using the X Window system.)
6735 * For windows with frames (see gtk_window_set_has_frame()) this function
6736 * can be used to change the size of the frame border.
6739 gtk_window_set_frame_dimensions (GtkWindow *window,
6745 GtkWindowPrivate *priv;
6746 GtkAllocation allocation;
6749 g_return_if_fail (GTK_IS_WINDOW (window));
6751 priv = window->priv;
6752 widget = GTK_WIDGET (window);
6754 if (priv->frame_left == left &&
6755 priv->frame_top == top &&
6756 priv->frame_right == right &&
6757 priv->frame_bottom == bottom)
6760 priv->frame_left = left;
6761 priv->frame_top = top;
6762 priv->frame_right = right;
6763 priv->frame_bottom = bottom;
6765 if (gtk_widget_get_realized (widget) && priv->frame)
6767 gtk_widget_get_allocation (widget, &allocation);
6769 gint width = allocation.width + left + right;
6770 gint height = allocation.height + top + bottom;
6771 gdk_window_resize (priv->frame, width, height);
6772 gtk_decorated_window_move_resize_window (window,
6780 * gtk_window_present:
6781 * @window: a #GtkWindow
6783 * Presents a window to the user. This may mean raising the window
6784 * in the stacking order, deiconifying it, moving it to the current
6785 * desktop, and/or giving it the keyboard focus, possibly dependent
6786 * on the user's platform, window manager, and preferences.
6788 * If @window is hidden, this function calls gtk_widget_show()
6791 * This function should be used when the user tries to open a window
6792 * that's already open. Say for example the preferences dialog is
6793 * currently open, and the user chooses Preferences from the menu
6794 * a second time; use gtk_window_present() to move the already-open dialog
6795 * where the user can see it.
6797 * If you are calling this function in response to a user interaction,
6798 * it is preferable to use gtk_window_present_with_time().
6802 gtk_window_present (GtkWindow *window)
6804 gtk_window_present_with_time (window, GDK_CURRENT_TIME);
6808 * gtk_window_present_with_time:
6809 * @window: a #GtkWindow
6810 * @timestamp: the timestamp of the user interaction (typically a
6811 * button or key press event) which triggered this call
6813 * Presents a window to the user in response to a user interaction.
6814 * If you need to present a window without a timestamp, use
6815 * gtk_window_present(). See gtk_window_present() for details.
6820 gtk_window_present_with_time (GtkWindow *window,
6824 GdkWindow *gdk_window;
6826 g_return_if_fail (GTK_IS_WINDOW (window));
6828 widget = GTK_WIDGET (window);
6830 if (gtk_widget_get_visible (widget))
6832 gdk_window = gtk_widget_get_window (widget);
6834 g_assert (gdk_window != NULL);
6836 gdk_window_show (gdk_window);
6838 /* Translate a timestamp of GDK_CURRENT_TIME appropriately */
6839 if (timestamp == GDK_CURRENT_TIME)
6841 #ifdef GDK_WINDOWING_X11
6842 GdkDisplay *display;
6844 display = gtk_widget_get_display (GTK_WIDGET (window));
6845 timestamp = gdk_x11_display_get_user_time (display);
6847 timestamp = gtk_get_current_event_time ();
6851 gdk_window_focus (gdk_window, timestamp);
6855 gtk_widget_show (widget);
6860 * gtk_window_iconify:
6861 * @window: a #GtkWindow
6863 * Asks to iconify (i.e. minimize) the specified @window. Note that
6864 * you shouldn't assume the window is definitely iconified afterward,
6865 * because other entities (e.g. the user or <link
6866 * linkend="gtk-X11-arch">window manager</link>) could deiconify it
6867 * again, or there may not be a window manager in which case
6868 * iconification isn't possible, etc. But normally the window will end
6869 * up iconified. Just don't write code that crashes if not.
6871 * It's permitted to call this function before showing a window,
6872 * in which case the window will be iconified before it ever appears
6875 * You can track iconification via the "window-state-event" signal
6880 gtk_window_iconify (GtkWindow *window)
6882 GtkWindowPrivate *priv;
6884 GdkWindow *toplevel;
6886 g_return_if_fail (GTK_IS_WINDOW (window));
6888 priv = window->priv;
6889 widget = GTK_WIDGET (window);
6891 priv->iconify_initially = TRUE;
6894 toplevel = priv->frame;
6896 toplevel = gtk_widget_get_window (widget);
6898 if (toplevel != NULL)
6899 gdk_window_iconify (toplevel);
6903 * gtk_window_deiconify:
6904 * @window: a #GtkWindow
6906 * Asks to deiconify (i.e. unminimize) the specified @window. Note
6907 * that you shouldn't assume the window is definitely deiconified
6908 * afterward, because other entities (e.g. the user or <link
6909 * linkend="gtk-X11-arch">window manager</link>) could iconify it
6910 * again before your code which assumes deiconification gets to run.
6912 * You can track iconification via the "window-state-event" signal
6916 gtk_window_deiconify (GtkWindow *window)
6918 GtkWindowPrivate *priv;
6920 GdkWindow *toplevel;
6922 g_return_if_fail (GTK_IS_WINDOW (window));
6924 priv = window->priv;
6925 widget = GTK_WIDGET (window);
6927 priv->iconify_initially = FALSE;
6930 toplevel = priv->frame;
6932 toplevel = gtk_widget_get_window (widget);
6934 if (toplevel != NULL)
6935 gdk_window_deiconify (toplevel);
6940 * @window: a #GtkWindow
6942 * Asks to stick @window, which means that it will appear on all user
6943 * desktops. Note that you shouldn't assume the window is definitely
6944 * stuck afterward, because other entities (e.g. the user or <link
6945 * linkend="gtk-X11-arch">window manager</link>) could unstick it
6946 * again, and some window managers do not support sticking
6947 * windows. But normally the window will end up stuck. Just don't
6948 * write code that crashes if not.
6950 * It's permitted to call this function before showing a window.
6952 * You can track stickiness via the "window-state-event" signal
6957 gtk_window_stick (GtkWindow *window)
6959 GtkWindowPrivate *priv;
6961 GdkWindow *toplevel;
6963 g_return_if_fail (GTK_IS_WINDOW (window));
6965 priv = window->priv;
6966 widget = GTK_WIDGET (window);
6968 priv->stick_initially = TRUE;
6971 toplevel = priv->frame;
6973 toplevel = gtk_widget_get_window (widget);
6975 if (toplevel != NULL)
6976 gdk_window_stick (toplevel);
6980 * gtk_window_unstick:
6981 * @window: a #GtkWindow
6983 * Asks to unstick @window, which means that it will appear on only
6984 * one of the user's desktops. Note that you shouldn't assume the
6985 * window is definitely unstuck afterward, because other entities
6986 * (e.g. the user or <link linkend="gtk-X11-arch">window
6987 * manager</link>) could stick it again. But normally the window will
6988 * end up stuck. Just don't write code that crashes if not.
6990 * You can track stickiness via the "window-state-event" signal
6995 gtk_window_unstick (GtkWindow *window)
6997 GtkWindowPrivate *priv;
6999 GdkWindow *toplevel;
7001 g_return_if_fail (GTK_IS_WINDOW (window));
7003 priv = window->priv;
7004 widget = GTK_WIDGET (window);
7006 priv->stick_initially = FALSE;
7009 toplevel = priv->frame;
7011 toplevel = gtk_widget_get_window (widget);
7013 if (toplevel != NULL)
7014 gdk_window_unstick (toplevel);
7018 * gtk_window_maximize:
7019 * @window: a #GtkWindow
7021 * Asks to maximize @window, so that it becomes full-screen. Note that
7022 * you shouldn't assume the window is definitely maximized afterward,
7023 * because other entities (e.g. the user or <link
7024 * linkend="gtk-X11-arch">window manager</link>) could unmaximize it
7025 * again, and not all window managers support maximization. But
7026 * normally the window will end up maximized. Just don't write code
7027 * that crashes if not.
7029 * It's permitted to call this function before showing a window,
7030 * in which case the window will be maximized when it appears onscreen
7033 * You can track maximization via the "window-state-event" signal
7038 gtk_window_maximize (GtkWindow *window)
7040 GtkWindowPrivate *priv;
7042 GdkWindow *toplevel;
7044 g_return_if_fail (GTK_IS_WINDOW (window));
7046 priv = window->priv;
7047 widget = GTK_WIDGET (window);
7049 priv->maximize_initially = TRUE;
7052 toplevel = priv->frame;
7054 toplevel = gtk_widget_get_window (widget);
7056 if (toplevel != NULL)
7057 gdk_window_maximize (toplevel);
7061 * gtk_window_unmaximize:
7062 * @window: a #GtkWindow
7064 * Asks to unmaximize @window. Note that you shouldn't assume the
7065 * window is definitely unmaximized afterward, because other entities
7066 * (e.g. the user or <link linkend="gtk-X11-arch">window
7067 * manager</link>) could maximize it again, and not all window
7068 * managers honor requests to unmaximize. But normally the window will
7069 * end up unmaximized. Just don't write code that crashes if not.
7071 * You can track maximization via the "window-state-event" signal
7076 gtk_window_unmaximize (GtkWindow *window)
7078 GtkWindowPrivate *priv;
7080 GdkWindow *toplevel;
7082 g_return_if_fail (GTK_IS_WINDOW (window));
7084 priv = window->priv;
7085 widget = GTK_WIDGET (window);
7087 priv->maximize_initially = FALSE;
7090 toplevel = priv->frame;
7092 toplevel = gtk_widget_get_window (widget);
7094 if (toplevel != NULL)
7095 gdk_window_unmaximize (toplevel);
7099 * gtk_window_fullscreen:
7100 * @window: a #GtkWindow
7102 * Asks to place @window in the fullscreen state. Note that you
7103 * shouldn't assume the window is definitely full screen afterward,
7104 * because other entities (e.g. the user or <link
7105 * linkend="gtk-X11-arch">window manager</link>) could unfullscreen it
7106 * again, and not all window managers honor requests to fullscreen
7107 * windows. But normally the window will end up fullscreen. Just
7108 * don't write code that crashes if not.
7110 * You can track the fullscreen state via the "window-state-event" signal
7116 gtk_window_fullscreen (GtkWindow *window)
7118 GtkWindowPrivate *priv;
7120 GdkWindow *toplevel;
7122 g_return_if_fail (GTK_IS_WINDOW (window));
7124 priv = window->priv;
7125 widget = GTK_WIDGET (window);
7127 priv->fullscreen_initially = TRUE;
7130 toplevel = priv->frame;
7132 toplevel = gtk_widget_get_window (widget);
7134 if (toplevel != NULL)
7135 gdk_window_fullscreen (toplevel);
7139 * gtk_window_unfullscreen:
7140 * @window: a #GtkWindow
7142 * Asks to toggle off the fullscreen state for @window. Note that you
7143 * shouldn't assume the window is definitely not full screen
7144 * afterward, because other entities (e.g. the user or <link
7145 * linkend="gtk-X11-arch">window manager</link>) could fullscreen it
7146 * again, and not all window managers honor requests to unfullscreen
7147 * windows. But normally the window will end up restored to its normal
7148 * state. Just don't write code that crashes if not.
7150 * You can track the fullscreen state via the "window-state-event" signal
7156 gtk_window_unfullscreen (GtkWindow *window)
7159 GdkWindow *toplevel;
7160 GtkWindowPrivate *priv;
7162 g_return_if_fail (GTK_IS_WINDOW (window));
7164 priv = window->priv;
7165 widget = GTK_WIDGET (window);
7167 priv->fullscreen_initially = FALSE;
7170 toplevel = priv->frame;
7172 toplevel = gtk_widget_get_window (widget);
7174 if (toplevel != NULL)
7175 gdk_window_unfullscreen (toplevel);
7179 * gtk_window_set_keep_above:
7180 * @window: a #GtkWindow
7181 * @setting: whether to keep @window above other windows
7183 * Asks to keep @window above, so that it stays on top. Note that
7184 * you shouldn't assume the window is definitely above afterward,
7185 * because other entities (e.g. the user or <link
7186 * linkend="gtk-X11-arch">window manager</link>) could not keep it above,
7187 * and not all window managers support keeping windows above. But
7188 * normally the window will end kept above. Just don't write code
7189 * that crashes if not.
7191 * It's permitted to call this function before showing a window,
7192 * in which case the window will be kept above when it appears onscreen
7195 * You can track the above state via the "window-state-event" signal
7198 * Note that, according to the <ulink
7199 * url="http://www.freedesktop.org/Standards/wm-spec">Extended Window
7200 * Manager Hints</ulink> specification, the above state is mainly meant
7201 * for user preferences and should not be used by applications e.g. for
7202 * drawing attention to their dialogs.
7207 gtk_window_set_keep_above (GtkWindow *window,
7211 GtkWindowPrivate *priv;
7212 GdkWindow *toplevel;
7214 g_return_if_fail (GTK_IS_WINDOW (window));
7216 priv = window->priv;
7217 widget = GTK_WIDGET (window);
7219 priv->above_initially = setting != FALSE;
7221 priv->below_initially = FALSE;
7224 toplevel = priv->frame;
7226 toplevel = gtk_widget_get_window (widget);
7228 if (toplevel != NULL)
7229 gdk_window_set_keep_above (toplevel, setting);
7233 * gtk_window_set_keep_below:
7234 * @window: a #GtkWindow
7235 * @setting: whether to keep @window below other windows
7237 * Asks to keep @window below, so that it stays in bottom. Note that
7238 * you shouldn't assume the window is definitely below afterward,
7239 * because other entities (e.g. the user or <link
7240 * linkend="gtk-X11-arch">window manager</link>) could not keep it below,
7241 * and not all window managers support putting windows below. But
7242 * normally the window will be kept below. Just don't write code
7243 * that crashes if not.
7245 * It's permitted to call this function before showing a window,
7246 * in which case the window will be kept below when it appears onscreen
7249 * You can track the below state via the "window-state-event" signal
7252 * Note that, according to the <ulink
7253 * url="http://www.freedesktop.org/Standards/wm-spec">Extended Window
7254 * Manager Hints</ulink> specification, the above state is mainly meant
7255 * for user preferences and should not be used by applications e.g. for
7256 * drawing attention to their dialogs.
7261 gtk_window_set_keep_below (GtkWindow *window,
7265 GtkWindowPrivate *priv;
7266 GdkWindow *toplevel;
7268 g_return_if_fail (GTK_IS_WINDOW (window));
7270 priv = window->priv;
7271 widget = GTK_WIDGET (window);
7273 priv->below_initially = setting != FALSE;
7275 priv->above_initially = FALSE;
7278 toplevel = priv->frame;
7280 toplevel = gtk_widget_get_window (widget);
7282 if (toplevel != NULL)
7283 gdk_window_set_keep_below (toplevel, setting);
7287 * gtk_window_set_resizable:
7288 * @window: a #GtkWindow
7289 * @resizable: %TRUE if the user can resize this window
7291 * Sets whether the user can resize a window. Windows are user resizable
7295 gtk_window_set_resizable (GtkWindow *window,
7298 GtkWindowPrivate *priv;
7300 g_return_if_fail (GTK_IS_WINDOW (window));
7302 priv = window->priv;
7304 priv->resizable = (resizable != FALSE);
7306 g_object_notify (G_OBJECT (window), "resizable");
7308 gtk_widget_queue_resize_no_redraw (GTK_WIDGET (window));
7312 * gtk_window_get_resizable:
7313 * @window: a #GtkWindow
7315 * Gets the value set by gtk_window_set_resizable().
7317 * Return value: %TRUE if the user can resize the window
7320 gtk_window_get_resizable (GtkWindow *window)
7322 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
7324 return window->priv->resizable;
7328 * gtk_window_set_gravity:
7329 * @window: a #GtkWindow
7330 * @gravity: window gravity
7332 * Window gravity defines the meaning of coordinates passed to
7333 * gtk_window_move(). See gtk_window_move() and #GdkGravity for
7336 * The default window gravity is #GDK_GRAVITY_NORTH_WEST which will
7337 * typically "do what you mean."
7341 gtk_window_set_gravity (GtkWindow *window,
7344 GtkWindowPrivate *priv;
7346 g_return_if_fail (GTK_IS_WINDOW (window));
7348 priv = window->priv;
7350 if (gravity != priv->gravity)
7352 priv->gravity = gravity;
7354 /* gtk_window_move_resize() will adapt gravity
7356 gtk_widget_queue_resize_no_redraw (GTK_WIDGET (window));
7358 g_object_notify (G_OBJECT (window), "gravity");
7363 * gtk_window_get_gravity:
7364 * @window: a #GtkWindow
7366 * Gets the value set by gtk_window_set_gravity().
7368 * Return value: (transfer none): window gravity
7371 gtk_window_get_gravity (GtkWindow *window)
7373 g_return_val_if_fail (GTK_IS_WINDOW (window), 0);
7375 return window->priv->gravity;
7379 * gtk_window_begin_resize_drag:
7380 * @window: a #GtkWindow
7381 * @button: mouse button that initiated the drag
7382 * @edge: position of the resize control
7383 * @root_x: X position where the user clicked to initiate the drag, in root window coordinates
7384 * @root_y: Y position where the user clicked to initiate the drag
7385 * @timestamp: timestamp from the click event that initiated the drag
7387 * Starts resizing a window. This function is used if an application
7388 * has window resizing controls. When GDK can support it, the resize
7389 * will be done using the standard mechanism for the <link
7390 * linkend="gtk-X11-arch">window manager</link> or windowing
7391 * system. Otherwise, GDK will try to emulate window resizing,
7392 * potentially not all that well, depending on the windowing system.
7396 gtk_window_begin_resize_drag (GtkWindow *window,
7403 GtkWindowPrivate *priv;
7405 GdkWindow *toplevel;
7407 g_return_if_fail (GTK_IS_WINDOW (window));
7408 widget = GTK_WIDGET (window);
7409 g_return_if_fail (gtk_widget_get_visible (widget));
7411 priv = window->priv;
7414 toplevel = priv->frame;
7416 toplevel = gtk_widget_get_window (widget);
7418 gdk_window_begin_resize_drag (toplevel,
7425 * gtk_window_get_frame_dimensions:
7426 * @window: a #GtkWindow
7427 * @left: (out) (allow-none): location to store the width of the frame at the left, or %NULL
7428 * @top: (out) (allow-none): location to store the height of the frame at the top, or %NULL
7429 * @right: (out) (allow-none): location to store the width of the frame at the returns, or %NULL
7430 * @bottom: (out) (allow-none): location to store the height of the frame at the bottom, or %NULL
7432 * (Note: this is a special-purpose function intended for the
7433 * framebuffer port; see gtk_window_set_has_frame(). It will not
7434 * return the size of the window border drawn by the <link
7435 * linkend="gtk-X11-arch">window manager</link>, which is the normal
7436 * case when using a windowing system. See
7437 * gdk_window_get_frame_extents() to get the standard window border
7440 * Retrieves the dimensions of the frame window for this toplevel.
7441 * See gtk_window_set_has_frame(), gtk_window_set_frame_dimensions().
7444 gtk_window_get_frame_dimensions (GtkWindow *window,
7450 GtkWindowPrivate *priv;
7452 g_return_if_fail (GTK_IS_WINDOW (window));
7454 priv = window->priv;
7457 *left = priv->frame_left;
7459 *top = priv->frame_top;
7461 *right = priv->frame_right;
7463 *bottom = priv->frame_bottom;
7467 * gtk_window_begin_move_drag:
7468 * @window: a #GtkWindow
7469 * @button: mouse button that initiated the drag
7470 * @root_x: X position where the user clicked to initiate the drag, in root window coordinates
7471 * @root_y: Y position where the user clicked to initiate the drag
7472 * @timestamp: timestamp from the click event that initiated the drag
7474 * Starts moving a window. This function is used if an application has
7475 * window movement grips. When GDK can support it, the window movement
7476 * will be done using the standard mechanism for the <link
7477 * linkend="gtk-X11-arch">window manager</link> or windowing
7478 * system. Otherwise, GDK will try to emulate window movement,
7479 * potentially not all that well, depending on the windowing system.
7483 gtk_window_begin_move_drag (GtkWindow *window,
7489 GtkWindowPrivate *priv;
7491 GdkWindow *toplevel;
7493 g_return_if_fail (GTK_IS_WINDOW (window));
7494 widget = GTK_WIDGET (window);
7495 g_return_if_fail (gtk_widget_get_visible (widget));
7497 priv = window->priv;
7500 toplevel = priv->frame;
7502 toplevel = gtk_widget_get_window (widget);
7504 gdk_window_begin_move_drag (toplevel,
7511 _gtk_window_get_visual (GtkWindow *window)
7513 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
7515 return window->priv->visual;
7519 * gtk_window_set_visual:
7520 * @window: window to set the visual from
7521 * @visual: the new visual to use
7523 * Sets the #GdkVisual used to display @window; if the window
7524 * is already mapped, it will be unmapped, and then remapped
7525 * with the new visual. It is fine if @visual is on a
7526 * different #GdkScreen.
7528 * By default, a window's visual is set to the system visual
7529 * of the default screen.
7532 gtk_window_set_visual (GtkWindow *window,
7535 GtkWindowPrivate *priv;
7537 GdkVisual *previous_visual;
7538 GdkScreen *previous_screen, *screen;
7539 gboolean was_mapped;
7541 g_return_if_fail (GTK_IS_WINDOW (window));
7542 g_return_if_fail (GDK_IS_VISUAL (visual));
7544 priv = window->priv;
7546 if (priv->visual == visual)
7549 widget = GTK_WIDGET (window);
7551 previous_visual = priv->visual;
7552 previous_screen = gdk_visual_get_screen (previous_visual);
7553 screen = gdk_visual_get_screen (visual);
7554 was_mapped = gtk_widget_get_mapped (widget);
7557 gtk_widget_unmap (widget);
7558 if (gtk_widget_get_realized (widget))
7559 gtk_widget_unrealize (widget);
7560 g_object_freeze_notify (G_OBJECT (window));
7562 gtk_window_free_key_hash (window);
7563 priv->visual = visual;
7564 gtk_widget_reset_rc_styles (widget);
7565 if (previous_screen != screen)
7567 g_signal_handlers_disconnect_by_func (previous_screen,
7568 gtk_window_on_composited_changed, window);
7569 g_signal_connect (screen, "composited-changed",
7570 G_CALLBACK (gtk_window_on_composited_changed), window);
7572 _gtk_widget_propagate_screen_changed (widget, previous_screen);
7573 _gtk_widget_propagate_composited_changed (widget);
7574 g_object_notify (G_OBJECT (window), "screen");
7576 g_object_notify (G_OBJECT (window), "visual");
7578 g_object_thaw_notify (G_OBJECT (window));
7580 gtk_widget_map (widget);
7584 * gtk_window_set_screen:
7585 * @window: a #GtkWindow.
7586 * @screen: a #GdkScreen.
7588 * Sets the #GdkScreen where the @window is displayed. If
7589 * the @screen is equal to @window's current screen, this
7590 * function does nothing. If it is not and the window is
7591 * already mapped, it will be unmapped, and then remapped
7592 * on the new screen.
7594 * This function resets @window's visual to the system
7595 * visual of the given @screen. If you want to use a
7596 * different visual, consider using gtk_window_set_visual()
7602 gtk_window_set_screen (GtkWindow *window,
7605 g_return_if_fail (GTK_IS_WINDOW (window));
7606 g_return_if_fail (GDK_IS_SCREEN (screen));
7608 if (screen == gdk_visual_get_screen (window->priv->visual))
7611 gtk_window_set_visual (window,
7612 gdk_screen_get_system_visual (screen));
7616 gtk_window_on_composited_changed (GdkScreen *screen,
7619 gtk_widget_queue_draw (GTK_WIDGET (window));
7621 _gtk_widget_propagate_composited_changed (GTK_WIDGET (window));
7625 gtk_window_check_screen (GtkWindow *window)
7627 GtkWindowPrivate *priv = window->priv;
7630 return gdk_visual_get_screen (priv->visual);
7633 g_warning ("Screen for GtkWindow not set; you must always set\n"
7634 "a screen for a GtkWindow before using the window");
7640 * gtk_window_get_screen:
7641 * @window: a #GtkWindow.
7643 * Returns the #GdkScreen associated with @window.
7645 * Return value: (transfer none): a #GdkScreen.
7650 gtk_window_get_screen (GtkWindow *window)
7652 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
7654 return gdk_visual_get_screen (window->priv->visual);
7658 * gtk_window_is_active:
7659 * @window: a #GtkWindow
7661 * Returns whether the window is part of the current active toplevel.
7662 * (That is, the toplevel window receiving keystrokes.)
7663 * The return value is %TRUE if the window is active toplevel
7664 * itself, but also if it is, say, a #GtkPlug embedded in the active toplevel.
7665 * You might use this function if you wanted to draw a widget
7666 * differently in an active window from a widget in an inactive window.
7667 * See gtk_window_has_toplevel_focus()
7669 * Return value: %TRUE if the window part of the current active window.
7674 gtk_window_is_active (GtkWindow *window)
7676 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
7678 return window->priv->is_active;
7682 * gtk_window_has_toplevel_focus:
7683 * @window: a #GtkWindow
7685 * Returns whether the input focus is within this GtkWindow.
7686 * For real toplevel windows, this is identical to gtk_window_is_active(),
7687 * but for embedded windows, like #GtkPlug, the results will differ.
7689 * Return value: %TRUE if the input focus is within this GtkWindow
7694 gtk_window_has_toplevel_focus (GtkWindow *window)
7696 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
7698 return window->priv->has_toplevel_focus;
7702 gtk_window_group_class_init (GtkWindowGroupClass *klass)
7704 g_type_class_add_private (klass, sizeof (GtkWindowGroupPrivate));
7708 gtk_window_group_get_type (void)
7710 static GType window_group_type = 0;
7712 if (!window_group_type)
7714 const GTypeInfo window_group_info =
7716 sizeof (GtkWindowGroupClass),
7717 NULL, /* base_init */
7718 NULL, /* base_finalize */
7719 (GClassInitFunc) gtk_window_group_class_init,
7720 NULL, /* class_finalize */
7721 NULL, /* class_data */
7722 sizeof (GtkWindowGroup),
7723 0, /* n_preallocs */
7724 (GInstanceInitFunc) NULL,
7727 window_group_type = g_type_register_static (G_TYPE_OBJECT, I_("GtkWindowGroup"),
7728 &window_group_info, 0);
7731 return window_group_type;
7735 * gtk_window_group_new:
7737 * Creates a new #GtkWindowGroup object. Grabs added with
7738 * gtk_grab_add() only affect windows within the same #GtkWindowGroup.
7740 * Return value: a new #GtkWindowGroup.
7743 gtk_window_group_new (void)
7745 return g_object_new (GTK_TYPE_WINDOW_GROUP, NULL);
7749 window_group_cleanup_grabs (GtkWindowGroup *group,
7752 GtkWindowGroupPrivate *priv;
7753 GtkDeviceGrabInfo *info;
7755 GSList *to_remove = NULL;
7757 tmp_list = group->grabs;
7760 if (gtk_widget_get_toplevel (tmp_list->data) == (GtkWidget*) window)
7761 to_remove = g_slist_prepend (to_remove, g_object_ref (tmp_list->data));
7762 tmp_list = tmp_list->next;
7767 gtk_grab_remove (to_remove->data);
7768 g_object_unref (to_remove->data);
7769 to_remove = g_slist_delete_link (to_remove, to_remove);
7772 priv = GTK_WINDOW_GROUP_GET_PRIVATE (group);
7773 tmp_list = priv->device_grabs;
7777 info = tmp_list->data;
7779 if (gtk_widget_get_toplevel (info->widget) == (GtkWidget *) window)
7780 to_remove = g_slist_prepend (to_remove, info);
7782 tmp_list = tmp_list->next;
7787 info = to_remove->data;
7789 gtk_device_grab_remove (info->widget, info->device);
7790 to_remove = g_slist_delete_link (to_remove, to_remove);
7795 * gtk_window_group_add_window:
7796 * @window_group: a #GtkWindowGroup
7797 * @window: the #GtkWindow to add
7799 * Adds a window to a #GtkWindowGroup.
7802 gtk_window_group_add_window (GtkWindowGroup *window_group,
7805 GtkWindowPrivate *priv;
7807 g_return_if_fail (GTK_IS_WINDOW_GROUP (window_group));
7808 g_return_if_fail (GTK_IS_WINDOW (window));
7810 priv = window->priv;
7812 if (priv->group != window_group)
7814 g_object_ref (window);
7815 g_object_ref (window_group);
7818 gtk_window_group_remove_window (priv->group, window);
7820 window_group_cleanup_grabs (gtk_window_get_group (NULL), window);
7822 priv->group = window_group;
7824 g_object_unref (window);
7829 * gtk_window_group_remove_window:
7830 * @window_group: a #GtkWindowGroup
7831 * @window: the #GtkWindow to remove
7833 * Removes a window from a #GtkWindowGroup.
7836 gtk_window_group_remove_window (GtkWindowGroup *window_group,
7839 GtkWindowPrivate *priv;
7841 g_return_if_fail (GTK_IS_WINDOW_GROUP (window_group));
7842 g_return_if_fail (GTK_IS_WINDOW (window));
7843 priv = window->priv;
7844 g_return_if_fail (priv->group == window_group);
7846 g_object_ref (window);
7848 window_group_cleanup_grabs (window_group, window);
7851 g_object_unref (window_group);
7852 g_object_unref (window);
7856 * gtk_window_group_list_windows:
7857 * @window_group: a #GtkWindowGroup
7859 * Returns a list of the #GtkWindows that belong to @window_group.
7861 * Returns: (element-type GtkWidget) (transfer container): A newly-allocated list of
7862 * windows inside the group.
7867 gtk_window_group_list_windows (GtkWindowGroup *window_group)
7869 GList *toplevels, *toplevel, *group_windows;
7871 g_return_val_if_fail (GTK_IS_WINDOW_GROUP (window_group), NULL);
7873 group_windows = NULL;
7874 toplevels = gtk_window_list_toplevels ();
7876 for (toplevel = toplevels; toplevel; toplevel = toplevel->next)
7878 GtkWindow *window = toplevel->data;
7880 if (window_group == window->priv->group)
7881 group_windows = g_list_prepend (group_windows, window);
7884 return g_list_reverse (group_windows);
7888 * gtk_window_get_group:
7889 * @window: (allow-none): a #GtkWindow, or %NULL
7891 * Returns the group for @window or the default group, if
7892 * @window is %NULL or if @window does not have an explicit
7895 * Returns: (transfer none): the #GtkWindowGroup for a window or the default group
7900 gtk_window_get_group (GtkWindow *window)
7902 if (window && window->priv->group)
7903 return window->priv->group;
7906 static GtkWindowGroup *default_group = NULL;
7909 default_group = gtk_window_group_new ();
7911 return default_group;
7916 * gtk_window_has_group:
7917 * @window: a #GtkWindow
7919 * Returns whether @window has an explicit window group.
7921 * Return value: %TRUE if @window has an explicit window group.
7926 gtk_window_has_group (GtkWindow *window)
7928 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
7930 return window->priv->group != NULL;
7934 * gtk_window_group_get_current_grab:
7935 * @window_group: a #GtkWindowGroup
7937 * Gets the current grab widget of the given group,
7938 * see gtk_grab_add().
7940 * Returns: the current grab widget of the group
7945 gtk_window_group_get_current_grab (GtkWindowGroup *window_group)
7947 g_return_val_if_fail (GTK_IS_WINDOW_GROUP (window_group), NULL);
7949 if (window_group->grabs)
7950 return GTK_WIDGET (window_group->grabs->data);
7955 _gtk_window_group_add_device_grab (GtkWindowGroup *window_group,
7958 gboolean block_others)
7960 GtkWindowGroupPrivate *priv;
7961 GtkDeviceGrabInfo *info;
7963 priv = GTK_WINDOW_GROUP_GET_PRIVATE (window_group);
7965 info = g_slice_new0 (GtkDeviceGrabInfo);
7966 info->widget = widget;
7967 info->device = device;
7968 info->block_others = block_others;
7970 priv->device_grabs = g_slist_prepend (priv->device_grabs, info);
7974 _gtk_window_group_remove_device_grab (GtkWindowGroup *window_group,
7978 GtkWindowGroupPrivate *priv;
7979 GtkDeviceGrabInfo *info;
7980 GSList *list, *node = NULL;
7981 GdkDevice *other_device;
7983 priv = GTK_WINDOW_GROUP_GET_PRIVATE (window_group);
7984 other_device = gdk_device_get_associated_device (device);
7985 list = priv->device_grabs;
7991 if (info->widget == widget &&
7992 (info->device == device ||
7993 info->device == other_device))
8006 priv->device_grabs = g_slist_delete_link (priv->device_grabs, node);
8007 g_slice_free (GtkDeviceGrabInfo, info);
8012 * gtk_window_group_get_current_device_grab:
8013 * @window_group: a #GtkWindowGroup
8014 * @device: a #GdkDevice
8016 * Returns the current grab widget for @device, or %NULL if none.
8018 * Returns: The grab widget, or %NULL
8023 gtk_window_group_get_current_device_grab (GtkWindowGroup *window_group,
8026 GtkWindowGroupPrivate *priv;
8027 GtkDeviceGrabInfo *info;
8028 GdkDevice *other_device;
8031 g_return_val_if_fail (GTK_IS_WINDOW_GROUP (window_group), NULL);
8032 g_return_val_if_fail (GDK_IS_DEVICE (device), NULL);
8034 priv = GTK_WINDOW_GROUP_GET_PRIVATE (window_group);
8035 list = priv->device_grabs;
8036 other_device = gdk_device_get_associated_device (device);
8043 if (info->device == device ||
8044 info->device == other_device)
8045 return info->widget;
8052 _gtk_window_group_widget_is_blocked_for_device (GtkWindowGroup *window_group,
8056 GtkWindowGroupPrivate *priv;
8057 GtkDeviceGrabInfo *info;
8058 GdkDevice *other_device;
8061 priv = GTK_WINDOW_GROUP_GET_PRIVATE (window_group);
8062 other_device = gdk_device_get_associated_device (device);
8063 list = priv->device_grabs;
8070 /* Look for blocking grabs on other device pairs
8071 * that have the passed widget within the GTK+ grab.
8073 if (info->block_others &&
8074 info->device != device &&
8075 info->device != other_device &&
8076 (info->widget == widget ||
8077 gtk_widget_is_ancestor (widget, info->widget)))
8085 Derived from XParseGeometry() in XFree86
8087 Copyright 1985, 1986, 1987,1998 The Open Group
8089 All Rights Reserved.
8091 The above copyright notice and this permission notice shall be included
8092 in all copies or substantial portions of the Software.
8094 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
8095 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
8096 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
8097 IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
8098 OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
8099 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
8100 OTHER DEALINGS IN THE SOFTWARE.
8102 Except as contained in this notice, the name of The Open Group shall
8103 not be used in advertising or otherwise to promote the sale, use or
8104 other dealings in this Software without prior written authorization
8105 from The Open Group.
8110 * XParseGeometry parses strings of the form
8111 * "=<width>x<height>{+-}<xoffset>{+-}<yoffset>", where
8112 * width, height, xoffset, and yoffset are unsigned integers.
8113 * Example: "=80x24+300-49"
8114 * The equal sign is optional.
8115 * It returns a bitmask that indicates which of the four values
8116 * were actually found in the string. For each value found,
8117 * the corresponding argument is updated; for each value
8118 * not found, the corresponding argument is left unchanged.
8121 /* The following code is from Xlib, and is minimally modified, so we
8122 * can track any upstream changes if required. Don't change this
8123 * code. Or if you do, put in a huge comment marking which thing
8128 read_int (gchar *string,
8136 else if (*string == '-')
8142 for (; (*string >= '0') && (*string <= '9'); string++)
8144 result = (result * 10) + (*string - '0');
8156 * Bitmask returned by XParseGeometry(). Each bit tells if the corresponding
8157 * value (x, y, width, height) was found in the parsed string.
8159 #define NoValue 0x0000
8160 #define XValue 0x0001
8161 #define YValue 0x0002
8162 #define WidthValue 0x0004
8163 #define HeightValue 0x0008
8164 #define AllValues 0x000F
8165 #define XNegative 0x0010
8166 #define YNegative 0x0020
8168 /* Try not to reformat/modify, so we can compare/sync with X sources */
8170 gtk_XParseGeometry (const char *string,
8173 unsigned int *width,
8174 unsigned int *height)
8178 unsigned int tempWidth, tempHeight;
8180 char *nextCharacter;
8182 /* These initializations are just to silence gcc */
8188 if ( (string == NULL) || (*string == '\0')) return(mask);
8190 string++; /* ignore possible '=' at beg of geometry spec */
8192 strind = (char *)string;
8193 if (*strind != '+' && *strind != '-' && *strind != 'x') {
8194 tempWidth = read_int(strind, &nextCharacter);
8195 if (strind == nextCharacter)
8197 strind = nextCharacter;
8201 if (*strind == 'x' || *strind == 'X') {
8203 tempHeight = read_int(strind, &nextCharacter);
8204 if (strind == nextCharacter)
8206 strind = nextCharacter;
8207 mask |= HeightValue;
8210 if ((*strind == '+') || (*strind == '-')) {
8211 if (*strind == '-') {
8213 tempX = -read_int(strind, &nextCharacter);
8214 if (strind == nextCharacter)
8216 strind = nextCharacter;
8222 tempX = read_int(strind, &nextCharacter);
8223 if (strind == nextCharacter)
8225 strind = nextCharacter;
8228 if ((*strind == '+') || (*strind == '-')) {
8229 if (*strind == '-') {
8231 tempY = -read_int(strind, &nextCharacter);
8232 if (strind == nextCharacter)
8234 strind = nextCharacter;
8241 tempY = read_int(strind, &nextCharacter);
8242 if (strind == nextCharacter)
8244 strind = nextCharacter;
8250 /* If strind isn't at the end of the string the it's an invalid
8251 geometry specification. */
8253 if (*strind != '\0') return (0);
8259 if (mask & WidthValue)
8261 if (mask & HeightValue)
8262 *height = tempHeight;
8267 * gtk_window_parse_geometry:
8268 * @window: a #GtkWindow
8269 * @geometry: geometry string
8271 * Parses a standard X Window System geometry string - see the
8272 * manual page for X (type 'man X') for details on this.
8273 * gtk_window_parse_geometry() does work on all GTK+ ports
8274 * including Win32 but is primarily intended for an X environment.
8276 * If either a size or a position can be extracted from the
8277 * geometry string, gtk_window_parse_geometry() returns %TRUE
8278 * and calls gtk_window_set_default_size() and/or gtk_window_move()
8279 * to resize/move the window.
8281 * If gtk_window_parse_geometry() returns %TRUE, it will also
8282 * set the #GDK_HINT_USER_POS and/or #GDK_HINT_USER_SIZE hints
8283 * indicating to the window manager that the size/position of
8284 * the window was user-specified. This causes most window
8285 * managers to honor the geometry.
8287 * Note that for gtk_window_parse_geometry() to work as expected, it has
8288 * to be called when the window has its "final" size, i.e. after calling
8289 * gtk_widget_show_all() on the contents and gtk_window_set_geometry_hints()
8292 * #include <gtk/gtk.h>
8295 * fill_with_content (GtkWidget *vbox)
8297 * /* fill with content... */
8301 * main (int argc, char *argv[])
8303 * GtkWidget *window, *vbox;
8304 * GdkGeometry size_hints = {
8305 * 100, 50, 0, 0, 100, 50, 10, 10, 0.0, 0.0, GDK_GRAVITY_NORTH_WEST
8308 * gtk_init (&argc, &argv);
8310 * window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
8311 * vbox = gtk_vbox_new (FALSE, 0);
8313 * gtk_container_add (GTK_CONTAINER (window), vbox);
8314 * fill_with_content (vbox);
8315 * gtk_widget_show_all (vbox);
8317 * gtk_window_set_geometry_hints (GTK_WINDOW (window),
8320 * GDK_HINT_MIN_SIZE |
8321 * GDK_HINT_BASE_SIZE |
8322 * GDK_HINT_RESIZE_INC);
8326 * if (!gtk_window_parse_geometry (GTK_WINDOW (window), argv[1]))
8327 * fprintf (stderr, "Failed to parse '%s'\n", argv[1]);
8330 * gtk_widget_show_all (window);
8337 * Return value: %TRUE if string was parsed successfully
8340 gtk_window_parse_geometry (GtkWindow *window,
8341 const gchar *geometry)
8343 gint result, x = 0, y = 0;
8346 gboolean size_set, pos_set;
8349 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
8350 g_return_val_if_fail (geometry != NULL, FALSE);
8352 screen = gtk_window_check_screen (window);
8354 result = gtk_XParseGeometry (geometry, &x, &y, &w, &h);
8357 if ((result & WidthValue) || (result & HeightValue))
8359 gtk_window_set_default_size_internal (window,
8360 TRUE, result & WidthValue ? w : -1,
8361 TRUE, result & HeightValue ? h : -1,
8366 gtk_window_get_size (window, (gint *)&w, (gint *)&h);
8368 grav = GDK_GRAVITY_NORTH_WEST;
8370 if ((result & XNegative) && (result & YNegative))
8371 grav = GDK_GRAVITY_SOUTH_EAST;
8372 else if (result & XNegative)
8373 grav = GDK_GRAVITY_NORTH_EAST;
8374 else if (result & YNegative)
8375 grav = GDK_GRAVITY_SOUTH_WEST;
8377 if ((result & XValue) == 0)
8380 if ((result & YValue) == 0)
8383 if (grav == GDK_GRAVITY_SOUTH_WEST ||
8384 grav == GDK_GRAVITY_SOUTH_EAST)
8385 y = gdk_screen_get_height (screen) - h + y;
8387 if (grav == GDK_GRAVITY_SOUTH_EAST ||
8388 grav == GDK_GRAVITY_NORTH_EAST)
8389 x = gdk_screen_get_width (screen) - w + x;
8391 /* we don't let you put a window offscreen; maybe some people would
8392 * prefer to be able to, but it's kind of a bogus thing to do.
8401 if ((result & XValue) || (result & YValue))
8403 gtk_window_set_gravity (window, grav);
8404 gtk_window_move (window, x, y);
8408 if (size_set || pos_set)
8410 /* Set USSize, USPosition hints */
8411 GtkWindowGeometryInfo *info;
8413 info = gtk_window_get_geometry_info (window, TRUE);
8416 info->mask |= GDK_HINT_USER_POS;
8418 info->mask |= GDK_HINT_USER_SIZE;
8425 gtk_window_mnemonic_hash_foreach (guint keyval,
8431 GtkWindowKeysForeachFunc func;
8435 (*info->func) (info->window, keyval, info->window->priv->mnemonic_modifier, TRUE, info->func_data);
8439 _gtk_window_keys_foreach (GtkWindow *window,
8440 GtkWindowKeysForeachFunc func,
8444 GtkMnemonicHash *mnemonic_hash;
8448 GtkWindowKeysForeachFunc func;
8452 info.window = window;
8454 info.func_data = func_data;
8456 mnemonic_hash = gtk_window_get_mnemonic_hash (window, FALSE);
8458 _gtk_mnemonic_hash_foreach (mnemonic_hash,
8459 gtk_window_mnemonic_hash_foreach, &info);
8461 groups = gtk_accel_groups_from_object (G_OBJECT (window));
8464 GtkAccelGroup *group = groups->data;
8467 for (i = 0; i < group->priv->n_accels; i++)
8469 GtkAccelKey *key = &group->priv->priv_accels[i].key;
8472 (*func) (window, key->accel_key, key->accel_mods, FALSE, func_data);
8475 groups = groups->next;
8480 gtk_window_keys_changed (GtkWindow *window)
8482 gtk_window_free_key_hash (window);
8483 gtk_window_get_key_hash (window);
8486 typedef struct _GtkWindowKeyEntry GtkWindowKeyEntry;
8488 struct _GtkWindowKeyEntry
8492 guint is_mnemonic : 1;
8496 window_key_entry_destroy (gpointer data)
8498 g_slice_free (GtkWindowKeyEntry, data);
8502 add_to_key_hash (GtkWindow *window,
8504 GdkModifierType modifiers,
8505 gboolean is_mnemonic,
8508 GtkKeyHash *key_hash = data;
8510 GtkWindowKeyEntry *entry = g_slice_new (GtkWindowKeyEntry);
8512 entry->keyval = keyval;
8513 entry->modifiers = modifiers;
8514 entry->is_mnemonic = is_mnemonic;
8516 /* GtkAccelGroup stores lowercased accelerators. To deal
8517 * with this, if <Shift> was specified, uppercase.
8519 if (modifiers & GDK_SHIFT_MASK)
8521 if (keyval == GDK_KEY_Tab)
8522 keyval = GDK_KEY_ISO_Left_Tab;
8524 keyval = gdk_keyval_to_upper (keyval);
8527 _gtk_key_hash_add_entry (key_hash, keyval, entry->modifiers, entry);
8531 gtk_window_get_key_hash (GtkWindow *window)
8533 GdkScreen *screen = gtk_window_check_screen (window);
8534 GtkKeyHash *key_hash = g_object_get_qdata (G_OBJECT (window), quark_gtk_window_key_hash);
8539 key_hash = _gtk_key_hash_new (gdk_keymap_get_for_display (gdk_screen_get_display (screen)),
8540 (GDestroyNotify)window_key_entry_destroy);
8541 _gtk_window_keys_foreach (window, add_to_key_hash, key_hash);
8542 g_object_set_qdata (G_OBJECT (window), quark_gtk_window_key_hash, key_hash);
8548 gtk_window_free_key_hash (GtkWindow *window)
8550 GtkKeyHash *key_hash = g_object_get_qdata (G_OBJECT (window), quark_gtk_window_key_hash);
8553 _gtk_key_hash_free (key_hash);
8554 g_object_set_qdata (G_OBJECT (window), quark_gtk_window_key_hash, NULL);
8559 * gtk_window_activate_key:
8560 * @window: a #GtkWindow
8561 * @event: a #GdkEventKey
8563 * Activates mnemonics and accelerators for this #GtkWindow. This is normally
8564 * called by the default ::key_press_event handler for toplevel windows,
8565 * however in some cases it may be useful to call this directly when
8566 * overriding the standard key handling for a toplevel window.
8568 * Return value: %TRUE if a mnemonic or accelerator was found and activated.
8573 gtk_window_activate_key (GtkWindow *window,
8576 GtkKeyHash *key_hash;
8577 GtkWindowKeyEntry *found_entry = NULL;
8578 gboolean enable_mnemonics;
8579 gboolean enable_accels;
8581 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
8582 g_return_val_if_fail (event != NULL, FALSE);
8584 key_hash = gtk_window_get_key_hash (window);
8589 GSList *entries = _gtk_key_hash_lookup (key_hash,
8590 event->hardware_keycode,
8592 gtk_accelerator_get_default_mod_mask (),
8595 g_object_get (gtk_widget_get_settings (GTK_WIDGET (window)),
8596 "gtk-enable-mnemonics", &enable_mnemonics,
8597 "gtk-enable-accels", &enable_accels,
8600 for (tmp_list = entries; tmp_list; tmp_list = tmp_list->next)
8602 GtkWindowKeyEntry *entry = tmp_list->data;
8603 if (entry->is_mnemonic)
8605 if (enable_mnemonics)
8607 found_entry = entry;
8613 if (enable_accels && !found_entry)
8615 found_entry = entry;
8620 g_slist_free (entries);
8625 if (found_entry->is_mnemonic)
8627 if (enable_mnemonics)
8628 return gtk_window_mnemonic_activate (window, found_entry->keyval,
8629 found_entry->modifiers);
8634 return gtk_accel_groups_activate (G_OBJECT (window), found_entry->keyval,
8635 found_entry->modifiers);
8643 window_update_has_focus (GtkWindow *window)
8645 GtkWindowPrivate *priv = window->priv;
8646 GtkWidget *widget = GTK_WIDGET (window);
8647 gboolean has_focus = priv->has_toplevel_focus && priv->is_active;
8649 if (has_focus != priv->has_focus)
8651 priv->has_focus = has_focus;
8655 if (priv->focus_widget &&
8656 priv->focus_widget != widget &&
8657 !gtk_widget_has_focus (priv->focus_widget))
8658 do_focus_change (priv->focus_widget, TRUE);
8662 if (priv->focus_widget &&
8663 priv->focus_widget != widget &&
8664 gtk_widget_has_focus (priv->focus_widget))
8665 do_focus_change (priv->focus_widget, FALSE);
8671 * _gtk_window_set_is_active:
8672 * @window: a #GtkWindow
8673 * @is_active: %TRUE if the window is in the currently active toplevel
8675 * Internal function that sets whether the #GtkWindow is part
8676 * of the currently active toplevel window (taking into account inter-process
8680 _gtk_window_set_is_active (GtkWindow *window,
8683 GtkWindowPrivate *priv;
8685 g_return_if_fail (GTK_IS_WINDOW (window));
8687 priv = window->priv;
8689 is_active = is_active != FALSE;
8691 if (is_active != priv->is_active)
8693 priv->is_active = is_active;
8694 window_update_has_focus (window);
8696 g_object_notify (G_OBJECT (window), "is-active");
8701 * _gtk_window_set_is_toplevel:
8702 * @window: a #GtkWindow
8703 * @is_toplevel: %TRUE if the window is still a real toplevel (nominally a
8704 * parent of the root window); %FALSE if it is not (for example, for an
8705 * in-process, parented GtkPlug)
8707 * Internal function used by #GtkPlug when it gets parented/unparented by a
8708 * #GtkSocket. This keeps the @window's #GTK_TOPLEVEL flag in sync with the
8709 * global list of toplevel windows.
8712 _gtk_window_set_is_toplevel (GtkWindow *window,
8713 gboolean is_toplevel)
8717 widget = GTK_WIDGET (window);
8719 if (gtk_widget_is_toplevel (widget))
8720 g_assert (g_slist_find (toplevel_list, window) != NULL);
8722 g_assert (g_slist_find (toplevel_list, window) == NULL);
8724 if (is_toplevel == gtk_widget_is_toplevel (widget))
8729 _gtk_widget_set_is_toplevel (widget, TRUE);
8730 toplevel_list = g_slist_prepend (toplevel_list, window);
8734 _gtk_widget_set_is_toplevel (widget, FALSE);
8735 toplevel_list = g_slist_remove (toplevel_list, window);
8740 * _gtk_window_set_has_toplevel_focus:
8741 * @window: a #GtkWindow
8742 * @has_toplevel_focus: %TRUE if the in
8744 * Internal function that sets whether the keyboard focus for the
8745 * toplevel window (taking into account inter-process embedding.)
8748 _gtk_window_set_has_toplevel_focus (GtkWindow *window,
8749 gboolean has_toplevel_focus)
8751 GtkWindowPrivate *priv;
8753 g_return_if_fail (GTK_IS_WINDOW (window));
8755 priv = window->priv;
8757 has_toplevel_focus = has_toplevel_focus != FALSE;
8759 if (has_toplevel_focus != priv->has_toplevel_focus)
8761 priv->has_toplevel_focus = has_toplevel_focus;
8762 window_update_has_focus (window);
8764 g_object_notify (G_OBJECT (window), "has-toplevel-focus");
8769 * gtk_window_set_auto_startup_notification:
8770 * @setting: %TRUE to automatically do startup notification
8772 * By default, after showing the first #GtkWindow, GTK+ calls
8773 * gdk_notify_startup_complete(). Call this function to disable
8774 * the automatic startup notification. You might do this if your
8775 * first window is a splash screen, and you want to delay notification
8776 * until after your real main window has been shown, for example.
8778 * In that example, you would disable startup notification
8779 * temporarily, show your splash screen, then re-enable it so that
8780 * showing the main window would automatically result in notification.
8785 gtk_window_set_auto_startup_notification (gboolean setting)
8787 disable_startup_notification = !setting;
8791 * gtk_window_get_window_type:
8792 * @window: a #GtkWindow
8794 * Gets the type of the window. See #GtkWindowType.
8796 * Return value: the type of the window
8801 gtk_window_get_window_type (GtkWindow *window)
8803 g_return_val_if_fail (GTK_IS_WINDOW (window), GTK_WINDOW_TOPLEVEL);
8805 return window->priv->type;
8809 * gtk_window_get_mnemonics_visible:
8810 * @window: a #GtkWindow
8812 * Gets the value of the #GtkWindow:mnemonics-visible property.
8814 * Returns: %TRUE if mnemonics are supposed to be visible
8820 gtk_window_get_mnemonics_visible (GtkWindow *window)
8822 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
8824 return window->priv->mnemonics_visible;
8828 * gtk_window_set_mnemonics_visible:
8829 * @window: a #GtkWindow
8830 * @setting: the new value
8832 * Sets the #GtkWindow:mnemonics-visible property.
8837 gtk_window_set_mnemonics_visible (GtkWindow *window,
8840 GtkWindowPrivate *priv;
8842 g_return_if_fail (GTK_IS_WINDOW (window));
8844 priv = window->priv;
8846 setting = setting != FALSE;
8848 if (priv->mnemonics_visible != setting)
8850 priv->mnemonics_visible = setting;
8851 g_object_notify (G_OBJECT (window), "mnemonics-visible");
8854 priv->mnemonics_visible_set = TRUE;
8858 _gtk_window_get_wmclass (GtkWindow *window,
8859 gchar **wmclass_name,
8860 gchar **wmclass_class)
8862 GtkWindowPrivate *priv = window->priv;
8864 *wmclass_name = priv->wmclass_name;
8865 *wmclass_class = priv->wmclass_class;