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_destroy (GtkObject *object);
289 static void gtk_window_finalize (GObject *object);
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 GtkObjectClass *object_class;
513 GtkWidgetClass *widget_class;
514 GtkContainerClass *container_class;
515 GtkBindingSet *binding_set;
517 object_class = (GtkObjectClass*) klass;
518 widget_class = (GtkWidgetClass*) klass;
519 container_class = (GtkContainerClass*) klass;
521 quark_gtk_embedded = g_quark_from_static_string ("gtk-embedded");
522 quark_gtk_window_key_hash = g_quark_from_static_string ("gtk-window-key-hash");
523 quark_gtk_window_icon_info = g_quark_from_static_string ("gtk-window-icon-info");
524 quark_gtk_buildable_accels = g_quark_from_static_string ("gtk-window-buildable-accels");
526 gobject_class->dispose = gtk_window_dispose;
527 gobject_class->finalize = gtk_window_finalize;
529 gobject_class->set_property = gtk_window_set_property;
530 gobject_class->get_property = gtk_window_get_property;
532 object_class->destroy = gtk_window_destroy;
534 widget_class->show = gtk_window_show;
535 widget_class->hide = gtk_window_hide;
536 widget_class->map = gtk_window_map;
537 widget_class->map_event = gtk_window_map_event;
538 widget_class->unmap = gtk_window_unmap;
539 widget_class->realize = gtk_window_realize;
540 widget_class->unrealize = gtk_window_unrealize;
541 widget_class->size_allocate = gtk_window_size_allocate;
542 widget_class->configure_event = gtk_window_configure_event;
543 widget_class->key_press_event = gtk_window_key_press_event;
544 widget_class->key_release_event = gtk_window_key_release_event;
545 widget_class->enter_notify_event = gtk_window_enter_notify_event;
546 widget_class->leave_notify_event = gtk_window_leave_notify_event;
547 widget_class->focus_in_event = gtk_window_focus_in_event;
548 widget_class->focus_out_event = gtk_window_focus_out_event;
549 widget_class->client_event = gtk_window_client_event;
550 widget_class->focus = gtk_window_focus;
551 widget_class->draw = gtk_window_draw;
552 widget_class->get_preferred_width = gtk_window_get_preferred_width;
553 widget_class->get_preferred_height = gtk_window_get_preferred_height;
555 container_class->check_resize = gtk_window_check_resize;
557 klass->set_focus = gtk_window_real_set_focus;
558 klass->frame_event = gtk_window_frame_event;
560 klass->activate_default = gtk_window_real_activate_default;
561 klass->activate_focus = gtk_window_real_activate_focus;
562 klass->move_focus = gtk_window_move_focus;
563 klass->keys_changed = gtk_window_keys_changed;
565 g_type_class_add_private (gobject_class, sizeof (GtkWindowPrivate));
568 g_object_class_install_property (gobject_class,
570 g_param_spec_enum ("type",
572 P_("The type of the window"),
573 GTK_TYPE_WINDOW_TYPE,
575 GTK_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
577 g_object_class_install_property (gobject_class,
579 g_param_spec_string ("title",
581 P_("The title of the window"),
583 GTK_PARAM_READWRITE));
585 g_object_class_install_property (gobject_class,
587 g_param_spec_string ("role",
589 P_("Unique identifier for the window to be used when restoring a session"),
591 GTK_PARAM_READWRITE));
594 * GtkWindow:startup-id:
596 * The :startup-id is a write-only property for setting window's
597 * startup notification identifier. See gtk_window_set_startup_id()
602 g_object_class_install_property (gobject_class,
604 g_param_spec_string ("startup-id",
606 P_("Unique startup identifier for the window used by startup-notification"),
608 GTK_PARAM_WRITABLE));
610 g_object_class_install_property (gobject_class,
612 g_param_spec_boolean ("resizable",
614 P_("If TRUE, users can resize the window"),
616 GTK_PARAM_READWRITE));
618 g_object_class_install_property (gobject_class,
620 g_param_spec_boolean ("modal",
622 P_("If TRUE, the window is modal (other windows are not usable while this one is up)"),
624 GTK_PARAM_READWRITE));
626 g_object_class_install_property (gobject_class,
628 g_param_spec_enum ("window-position",
629 P_("Window Position"),
630 P_("The initial position of the window"),
631 GTK_TYPE_WINDOW_POSITION,
633 GTK_PARAM_READWRITE));
635 g_object_class_install_property (gobject_class,
637 g_param_spec_int ("default-width",
639 P_("The default width of the window, used when initially showing the window"),
643 GTK_PARAM_READWRITE));
645 g_object_class_install_property (gobject_class,
647 g_param_spec_int ("default-height",
648 P_("Default Height"),
649 P_("The default height of the window, used when initially showing the window"),
653 GTK_PARAM_READWRITE));
655 g_object_class_install_property (gobject_class,
656 PROP_DESTROY_WITH_PARENT,
657 g_param_spec_boolean ("destroy-with-parent",
658 P_("Destroy with Parent"),
659 P_("If this window should be destroyed when the parent is destroyed"),
661 GTK_PARAM_READWRITE));
663 g_object_class_install_property (gobject_class,
665 g_param_spec_object ("icon",
667 P_("Icon for this window"),
669 GTK_PARAM_READWRITE));
670 g_object_class_install_property (gobject_class,
671 PROP_MNEMONICS_VISIBLE,
672 g_param_spec_boolean ("mnemonics-visible",
673 P_("Mnemonics Visible"),
674 P_("Whether mnemonics are currently visible in this window"),
676 GTK_PARAM_READWRITE));
679 * GtkWindow:icon-name:
681 * The :icon-name property specifies the name of the themed icon to
682 * use as the window icon. See #GtkIconTheme for more details.
686 g_object_class_install_property (gobject_class,
688 g_param_spec_string ("icon-name",
690 P_("Name of the themed icon for this window"),
692 GTK_PARAM_READWRITE));
694 g_object_class_install_property (gobject_class,
696 g_param_spec_object ("screen",
698 P_("The screen where this window will be displayed"),
700 GTK_PARAM_READWRITE));
705 * Specifies the visual used to create the window with. See gtk_window_set_visual()
708 g_object_class_install_property (gobject_class,
710 g_param_spec_object ("visual",
712 P_("The visual this window is created from"),
714 GTK_PARAM_READWRITE));
716 g_object_class_install_property (gobject_class,
718 g_param_spec_boolean ("is-active",
720 P_("Whether the toplevel is the current active window"),
722 GTK_PARAM_READABLE));
724 g_object_class_install_property (gobject_class,
725 PROP_HAS_TOPLEVEL_FOCUS,
726 g_param_spec_boolean ("has-toplevel-focus",
727 P_("Focus in Toplevel"),
728 P_("Whether the input focus is within this GtkWindow"),
730 GTK_PARAM_READABLE));
732 g_object_class_install_property (gobject_class,
734 g_param_spec_enum ("type-hint",
736 P_("Hint to help the desktop environment understand what kind of window this is and how to treat it."),
737 GDK_TYPE_WINDOW_TYPE_HINT,
738 GDK_WINDOW_TYPE_HINT_NORMAL,
739 GTK_PARAM_READWRITE));
741 g_object_class_install_property (gobject_class,
742 PROP_SKIP_TASKBAR_HINT,
743 g_param_spec_boolean ("skip-taskbar-hint",
745 P_("TRUE if the window should not be in the task bar."),
747 GTK_PARAM_READWRITE));
749 g_object_class_install_property (gobject_class,
750 PROP_SKIP_PAGER_HINT,
751 g_param_spec_boolean ("skip-pager-hint",
753 P_("TRUE if the window should not be in the pager."),
755 GTK_PARAM_READWRITE));
757 g_object_class_install_property (gobject_class,
759 g_param_spec_boolean ("urgency-hint",
761 P_("TRUE if the window should be brought to the user's attention."),
763 GTK_PARAM_READWRITE));
766 * GtkWindow:accept-focus:
768 * Whether the window should receive the input focus.
772 g_object_class_install_property (gobject_class,
774 g_param_spec_boolean ("accept-focus",
776 P_("TRUE if the window should receive the input focus."),
778 GTK_PARAM_READWRITE));
781 * GtkWindow:focus-on-map:
783 * Whether the window should receive the input focus when mapped.
787 g_object_class_install_property (gobject_class,
789 g_param_spec_boolean ("focus-on-map",
791 P_("TRUE if the window should receive the input focus when mapped."),
793 GTK_PARAM_READWRITE));
796 * GtkWindow:decorated:
798 * Whether the window should be decorated by the window manager.
802 g_object_class_install_property (gobject_class,
804 g_param_spec_boolean ("decorated",
806 P_("Whether the window should be decorated by the window manager"),
808 GTK_PARAM_READWRITE));
811 * GtkWindow:deletable:
813 * Whether the window frame should have a close button.
817 g_object_class_install_property (gobject_class,
819 g_param_spec_boolean ("deletable",
821 P_("Whether the window frame should have a close button"),
823 GTK_PARAM_READWRITE));
829 * The window gravity of the window. See gtk_window_move() and #GdkGravity for
830 * more details about window gravity.
834 g_object_class_install_property (gobject_class,
836 g_param_spec_enum ("gravity",
838 P_("The window gravity of the window"),
840 GDK_GRAVITY_NORTH_WEST,
841 GTK_PARAM_READWRITE));
845 * GtkWindow:transient-for:
847 * The transient parent of the window. See gtk_window_set_transient_for() for
848 * more details about transient windows.
852 g_object_class_install_property (gobject_class,
854 g_param_spec_object ("transient-for",
855 P_("Transient for Window"),
856 P_("The transient parent of the dialog"),
858 GTK_PARAM_READWRITE| G_PARAM_CONSTRUCT));
863 * The requested opacity of the window. See gtk_window_set_opacity() for
864 * more details about window opacity.
868 g_object_class_install_property (gobject_class,
870 g_param_spec_double ("opacity",
871 P_("Opacity for Window"),
872 P_("The opacity of the window, from 0 to 1"),
876 GTK_PARAM_READWRITE));
878 window_signals[SET_FOCUS] =
879 g_signal_new (I_("set-focus"),
880 G_TYPE_FROM_CLASS (gobject_class),
882 G_STRUCT_OFFSET (GtkWindowClass, set_focus),
884 _gtk_marshal_VOID__OBJECT,
888 window_signals[FRAME_EVENT] =
889 g_signal_new (I_("frame-event"),
890 G_TYPE_FROM_CLASS (gobject_class),
892 G_STRUCT_OFFSET(GtkWindowClass, frame_event),
893 _gtk_boolean_handled_accumulator, NULL,
894 _gtk_marshal_BOOLEAN__BOXED,
899 * GtkWindow::activate-focus:
900 * @window: the window which received the signal
902 * The ::activate-focus signal is a
903 * <link linkend="keybinding-signals">keybinding signal</link>
904 * which gets emitted when the user activates the currently
905 * focused widget of @window.
907 window_signals[ACTIVATE_FOCUS] =
908 g_signal_new (I_("activate-focus"),
909 G_TYPE_FROM_CLASS (gobject_class),
910 G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
911 G_STRUCT_OFFSET (GtkWindowClass, activate_focus),
913 _gtk_marshal_VOID__VOID,
918 * GtkWindow::activate-default:
919 * @window: the window which received the signal
921 * The ::activate-default signal is a
922 * <link linkend="keybinding-signals">keybinding signal</link>
923 * which gets emitted when the user activates the default widget
926 window_signals[ACTIVATE_DEFAULT] =
927 g_signal_new (I_("activate-default"),
928 G_TYPE_FROM_CLASS (gobject_class),
929 G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
930 G_STRUCT_OFFSET (GtkWindowClass, activate_default),
932 _gtk_marshal_VOID__VOID,
937 * GtkWindow::keys-changed:
938 * @window: the window which received the signal
940 * The ::keys-changed signal gets emitted when the set of accelerators
941 * or mnemonics that are associated with @window changes.
943 window_signals[KEYS_CHANGED] =
944 g_signal_new (I_("keys-changed"),
945 G_TYPE_FROM_CLASS (gobject_class),
947 G_STRUCT_OFFSET (GtkWindowClass, keys_changed),
949 _gtk_marshal_VOID__VOID,
957 binding_set = gtk_binding_set_by_class (klass);
959 gtk_binding_entry_add_signal (binding_set, GDK_KEY_space, 0,
960 "activate-focus", 0);
961 gtk_binding_entry_add_signal (binding_set, GDK_KEY_KP_Space, 0,
962 "activate-focus", 0);
964 gtk_binding_entry_add_signal (binding_set, GDK_KEY_Return, 0,
965 "activate-default", 0);
966 gtk_binding_entry_add_signal (binding_set, GDK_KEY_ISO_Enter, 0,
967 "activate-default", 0);
968 gtk_binding_entry_add_signal (binding_set, GDK_KEY_KP_Enter, 0,
969 "activate-default", 0);
971 add_arrow_bindings (binding_set, GDK_KEY_Up, GTK_DIR_UP);
972 add_arrow_bindings (binding_set, GDK_KEY_Down, GTK_DIR_DOWN);
973 add_arrow_bindings (binding_set, GDK_KEY_Left, GTK_DIR_LEFT);
974 add_arrow_bindings (binding_set, GDK_KEY_Right, GTK_DIR_RIGHT);
976 add_tab_bindings (binding_set, 0, GTK_DIR_TAB_FORWARD);
977 add_tab_bindings (binding_set, GDK_CONTROL_MASK, GTK_DIR_TAB_FORWARD);
978 add_tab_bindings (binding_set, GDK_SHIFT_MASK, GTK_DIR_TAB_BACKWARD);
979 add_tab_bindings (binding_set, GDK_CONTROL_MASK | GDK_SHIFT_MASK, GTK_DIR_TAB_BACKWARD);
983 gtk_window_init (GtkWindow *window)
985 GtkWindowPrivate *priv;
987 window->priv = G_TYPE_INSTANCE_GET_PRIVATE (window,
992 gtk_widget_set_has_window (GTK_WIDGET (window), TRUE);
993 _gtk_widget_set_is_toplevel (GTK_WIDGET (window), TRUE);
995 GTK_PRIVATE_SET_FLAG (window, GTK_ANCHORED);
997 gtk_container_set_resize_mode (GTK_CONTAINER (window), GTK_RESIZE_QUEUE);
1000 priv->wmclass_name = g_strdup (g_get_prgname ());
1001 priv->wmclass_class = g_strdup (gdk_get_program_class ());
1002 priv->wm_role = NULL;
1003 priv->geometry_info = NULL;
1004 priv->type = GTK_WINDOW_TOPLEVEL;
1005 priv->focus_widget = NULL;
1006 priv->default_widget = NULL;
1007 priv->configure_request_count = 0;
1008 priv->resizable = TRUE;
1009 priv->configure_notify_received = FALSE;
1010 priv->position = GTK_WIN_POS_NONE;
1011 priv->need_default_size = TRUE;
1012 priv->need_default_position = TRUE;
1013 priv->modal = FALSE;
1015 priv->has_frame = FALSE;
1016 priv->frame_left = 0;
1017 priv->frame_right = 0;
1018 priv->frame_top = 0;
1019 priv->frame_bottom = 0;
1020 priv->gdk_type_hint = GDK_WINDOW_TYPE_HINT_NORMAL;
1021 priv->gravity = GDK_GRAVITY_NORTH_WEST;
1022 priv->decorated = TRUE;
1023 priv->mnemonic_modifier = GDK_MOD1_MASK;
1024 priv->visual = gdk_screen_get_system_visual (gdk_screen_get_default ());
1026 priv->accept_focus = TRUE;
1027 priv->focus_on_map = TRUE;
1028 priv->deletable = TRUE;
1029 priv->type_hint = GDK_WINDOW_TYPE_HINT_NORMAL;
1030 priv->opacity = 1.0;
1031 priv->startup_id = NULL;
1032 priv->mnemonics_visible = TRUE;
1034 g_object_ref_sink (window);
1035 priv->has_user_ref_count = TRUE;
1036 toplevel_list = g_slist_prepend (toplevel_list, window);
1038 gtk_decorated_window_init (window);
1040 g_signal_connect (gdk_screen_get_default (), "composited-changed",
1041 G_CALLBACK (gtk_window_on_composited_changed), window);
1045 gtk_window_set_property (GObject *object,
1047 const GValue *value,
1050 GtkWindow *window = GTK_WINDOW (object);
1051 GtkWindowPrivate *priv = window->priv;
1056 priv->type = g_value_get_enum (value);
1059 gtk_window_set_title (window, g_value_get_string (value));
1062 gtk_window_set_role (window, g_value_get_string (value));
1064 case PROP_STARTUP_ID:
1065 gtk_window_set_startup_id (window, g_value_get_string (value));
1067 case PROP_RESIZABLE:
1068 priv->resizable = g_value_get_boolean (value);
1069 gtk_widget_queue_resize (GTK_WIDGET (window));
1072 gtk_window_set_modal (window, g_value_get_boolean (value));
1075 gtk_window_set_position (window, g_value_get_enum (value));
1077 case PROP_DEFAULT_WIDTH:
1078 gtk_window_set_default_size_internal (window,
1079 TRUE, g_value_get_int (value),
1082 case PROP_DEFAULT_HEIGHT:
1083 gtk_window_set_default_size_internal (window,
1085 TRUE, g_value_get_int (value), FALSE);
1087 case PROP_DESTROY_WITH_PARENT:
1088 gtk_window_set_destroy_with_parent (window, g_value_get_boolean (value));
1091 gtk_window_set_icon (window,
1092 g_value_get_object (value));
1094 case PROP_ICON_NAME:
1095 gtk_window_set_icon_name (window, g_value_get_string (value));
1098 gtk_window_set_screen (window, g_value_get_object (value));
1101 gtk_window_set_visual (window, g_value_get_object (value));
1103 case PROP_TYPE_HINT:
1104 gtk_window_set_type_hint (window,
1105 g_value_get_enum (value));
1107 case PROP_SKIP_TASKBAR_HINT:
1108 gtk_window_set_skip_taskbar_hint (window,
1109 g_value_get_boolean (value));
1111 case PROP_SKIP_PAGER_HINT:
1112 gtk_window_set_skip_pager_hint (window,
1113 g_value_get_boolean (value));
1115 case PROP_URGENCY_HINT:
1116 gtk_window_set_urgency_hint (window,
1117 g_value_get_boolean (value));
1119 case PROP_ACCEPT_FOCUS:
1120 gtk_window_set_accept_focus (window,
1121 g_value_get_boolean (value));
1123 case PROP_FOCUS_ON_MAP:
1124 gtk_window_set_focus_on_map (window,
1125 g_value_get_boolean (value));
1127 case PROP_DECORATED:
1128 gtk_window_set_decorated (window, g_value_get_boolean (value));
1130 case PROP_DELETABLE:
1131 gtk_window_set_deletable (window, g_value_get_boolean (value));
1134 gtk_window_set_gravity (window, g_value_get_enum (value));
1136 case PROP_TRANSIENT_FOR:
1137 gtk_window_set_transient_for (window, g_value_get_object (value));
1140 gtk_window_set_opacity (window, g_value_get_double (value));
1142 case PROP_MNEMONICS_VISIBLE:
1143 gtk_window_set_mnemonics_visible (window, g_value_get_boolean (value));
1146 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1152 gtk_window_get_property (GObject *object,
1157 GtkWindow *window = GTK_WINDOW (object);
1158 GtkWindowPrivate *priv = window->priv;
1162 GtkWindowGeometryInfo *info;
1164 g_value_set_enum (value, priv->type);
1167 g_value_set_string (value, priv->wm_role);
1170 g_value_set_string (value, priv->title);
1172 case PROP_RESIZABLE:
1173 g_value_set_boolean (value, priv->resizable);
1176 g_value_set_boolean (value, priv->modal);
1179 g_value_set_enum (value, priv->position);
1181 case PROP_DEFAULT_WIDTH:
1182 info = gtk_window_get_geometry_info (window, FALSE);
1184 g_value_set_int (value, -1);
1186 g_value_set_int (value, info->default_width);
1188 case PROP_DEFAULT_HEIGHT:
1189 info = gtk_window_get_geometry_info (window, FALSE);
1191 g_value_set_int (value, -1);
1193 g_value_set_int (value, info->default_height);
1195 case PROP_DESTROY_WITH_PARENT:
1196 g_value_set_boolean (value, priv->destroy_with_parent);
1199 g_value_set_object (value, gtk_window_get_icon (window));
1201 case PROP_ICON_NAME:
1202 g_value_set_string (value, gtk_window_get_icon_name (window));
1205 g_value_set_object (value, gdk_visual_get_screen (priv->visual));
1208 g_value_set_object (value, priv->visual);
1210 case PROP_IS_ACTIVE:
1211 g_value_set_boolean (value, priv->is_active);
1213 case PROP_HAS_TOPLEVEL_FOCUS:
1214 g_value_set_boolean (value, priv->has_toplevel_focus);
1216 case PROP_TYPE_HINT:
1217 g_value_set_enum (value, priv->type_hint);
1219 case PROP_SKIP_TASKBAR_HINT:
1220 g_value_set_boolean (value,
1221 gtk_window_get_skip_taskbar_hint (window));
1223 case PROP_SKIP_PAGER_HINT:
1224 g_value_set_boolean (value,
1225 gtk_window_get_skip_pager_hint (window));
1227 case PROP_URGENCY_HINT:
1228 g_value_set_boolean (value,
1229 gtk_window_get_urgency_hint (window));
1231 case PROP_ACCEPT_FOCUS:
1232 g_value_set_boolean (value,
1233 gtk_window_get_accept_focus (window));
1235 case PROP_FOCUS_ON_MAP:
1236 g_value_set_boolean (value,
1237 gtk_window_get_focus_on_map (window));
1239 case PROP_DECORATED:
1240 g_value_set_boolean (value, gtk_window_get_decorated (window));
1242 case PROP_DELETABLE:
1243 g_value_set_boolean (value, gtk_window_get_deletable (window));
1246 g_value_set_enum (value, gtk_window_get_gravity (window));
1248 case PROP_TRANSIENT_FOR:
1249 g_value_set_object (value, gtk_window_get_transient_for (window));
1252 g_value_set_double (value, gtk_window_get_opacity (window));
1254 case PROP_MNEMONICS_VISIBLE:
1255 g_value_set_boolean (value, priv->mnemonics_visible);
1258 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1264 gtk_window_buildable_interface_init (GtkBuildableIface *iface)
1266 parent_buildable_iface = g_type_interface_peek_parent (iface);
1267 iface->set_buildable_property = gtk_window_buildable_set_buildable_property;
1268 iface->parser_finished = gtk_window_buildable_parser_finished;
1269 iface->custom_tag_start = gtk_window_buildable_custom_tag_start;
1270 iface->custom_finished = gtk_window_buildable_custom_finished;
1274 gtk_window_buildable_set_buildable_property (GtkBuildable *buildable,
1275 GtkBuilder *builder,
1277 const GValue *value)
1279 GtkWindow *window = GTK_WINDOW (buildable);
1280 GtkWindowPrivate *priv = window->priv;
1282 if (strcmp (name, "visible") == 0 && g_value_get_boolean (value))
1283 priv->builder_visible = TRUE;
1285 parent_buildable_iface->set_buildable_property (buildable, builder, name, value);
1289 gtk_window_buildable_parser_finished (GtkBuildable *buildable,
1290 GtkBuilder *builder)
1292 GtkWindow *window = GTK_WINDOW (buildable);
1293 GtkWindowPrivate *priv = window->priv;
1297 if (priv->builder_visible)
1298 gtk_widget_show (GTK_WIDGET (buildable));
1300 accels = g_object_get_qdata (G_OBJECT (buildable), quark_gtk_buildable_accels);
1301 for (l = accels; l; l = l->next)
1303 object = gtk_builder_get_object (builder, l->data);
1306 g_warning ("Unknown accel group %s specified in window %s",
1307 (const gchar*)l->data, gtk_buildable_get_name (buildable));
1310 gtk_window_add_accel_group (GTK_WINDOW (buildable),
1311 GTK_ACCEL_GROUP (object));
1315 g_object_set_qdata (G_OBJECT (buildable), quark_gtk_buildable_accels, NULL);
1317 parent_buildable_iface->parser_finished (buildable, builder);
1323 } GSListSubParserData;
1326 window_start_element (GMarkupParseContext *context,
1327 const gchar *element_name,
1328 const gchar **names,
1329 const gchar **values,
1334 GSListSubParserData *data = (GSListSubParserData*)user_data;
1336 if (strcmp (element_name, "group") == 0)
1338 for (i = 0; names[i]; i++)
1340 if (strcmp (names[i], "name") == 0)
1341 data->items = g_slist_prepend (data->items, g_strdup (values[i]));
1344 else if (strcmp (element_name, "accel-groups") == 0)
1347 g_warning ("Unsupported tag type for GtkWindow: %s\n",
1352 static const GMarkupParser window_parser =
1354 window_start_element
1358 gtk_window_buildable_custom_tag_start (GtkBuildable *buildable,
1359 GtkBuilder *builder,
1361 const gchar *tagname,
1362 GMarkupParser *parser,
1365 GSListSubParserData *parser_data;
1367 if (parent_buildable_iface->custom_tag_start (buildable, builder, child,
1368 tagname, parser, data))
1371 if (strcmp (tagname, "accel-groups") == 0)
1373 parser_data = g_slice_new0 (GSListSubParserData);
1374 parser_data->items = NULL;
1375 parser_data->object = G_OBJECT (buildable);
1377 *parser = window_parser;
1378 *data = parser_data;
1386 gtk_window_buildable_custom_finished (GtkBuildable *buildable,
1387 GtkBuilder *builder,
1389 const gchar *tagname,
1392 GSListSubParserData *data;
1394 parent_buildable_iface->custom_finished (buildable, builder, child,
1395 tagname, user_data);
1397 if (strcmp (tagname, "accel-groups") != 0)
1400 data = (GSListSubParserData*)user_data;
1402 g_object_set_qdata_full (G_OBJECT (buildable), quark_gtk_buildable_accels,
1403 data->items, (GDestroyNotify) g_slist_free);
1405 g_slice_free (GSListSubParserData, data);
1410 * @type: type of window
1412 * Creates a new #GtkWindow, which is a toplevel window that can
1413 * contain other widgets. Nearly always, the type of the window should
1414 * be #GTK_WINDOW_TOPLEVEL. If you're implementing something like a
1415 * popup menu from scratch (which is a bad idea, just use #GtkMenu),
1416 * you might use #GTK_WINDOW_POPUP. #GTK_WINDOW_POPUP is not for
1417 * dialogs, though in some other toolkits dialogs are called "popups".
1418 * In GTK+, #GTK_WINDOW_POPUP means a pop-up menu or pop-up tooltip.
1419 * On X11, popup windows are not controlled by the <link
1420 * linkend="gtk-X11-arch">window manager</link>.
1422 * If you simply want an undecorated window (no window borders), use
1423 * gtk_window_set_decorated(), don't use #GTK_WINDOW_POPUP.
1425 * Return value: a new #GtkWindow.
1428 gtk_window_new (GtkWindowType type)
1430 GtkWindowPrivate *priv;
1433 g_return_val_if_fail (type >= GTK_WINDOW_TOPLEVEL && type <= GTK_WINDOW_POPUP, NULL);
1435 window = g_object_new (GTK_TYPE_WINDOW, NULL);
1436 priv = window->priv;
1440 return GTK_WIDGET (window);
1444 * gtk_window_set_title:
1445 * @window: a #GtkWindow
1446 * @title: title of the window
1448 * Sets the title of the #GtkWindow. The title of a window will be
1449 * displayed in its title bar; on the X Window System, the title bar
1450 * is rendered by the <link linkend="gtk-X11-arch">window
1451 * manager</link>, so exactly how the title appears to users may vary
1452 * according to a user's exact configuration. The title should help a
1453 * user distinguish this window from other windows they may have
1454 * open. A good title might include the application name and current
1455 * document filename, for example.
1459 gtk_window_set_title (GtkWindow *window,
1462 GtkWindowPrivate *priv;
1466 g_return_if_fail (GTK_IS_WINDOW (window));
1468 priv = window->priv;
1469 widget = GTK_WIDGET (window);
1471 new_title = g_strdup (title);
1472 g_free (priv->title);
1473 priv->title = new_title;
1475 if (gtk_widget_get_realized (widget))
1477 gdk_window_set_title (gtk_widget_get_window (widget),
1480 gtk_decorated_window_set_title (window, title);
1483 g_object_notify (G_OBJECT (window), "title");
1487 * gtk_window_get_title:
1488 * @window: a #GtkWindow
1490 * Retrieves the title of the window. See gtk_window_set_title().
1492 * Return value: the title of the window, or %NULL if none has
1493 * been set explicitely. The returned string is owned by the widget
1494 * and must not be modified or freed.
1496 G_CONST_RETURN gchar *
1497 gtk_window_get_title (GtkWindow *window)
1499 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
1501 return window->priv->title;
1505 * gtk_window_set_wmclass:
1506 * @window: a #GtkWindow
1507 * @wmclass_name: window name hint
1508 * @wmclass_class: window class hint
1510 * Don't use this function. It sets the X Window System "class" and
1511 * "name" hints for a window. According to the ICCCM, you should
1512 * always set these to the same value for all windows in an
1513 * application, and GTK+ sets them to that value by default, so calling
1514 * this function is sort of pointless. However, you may want to call
1515 * gtk_window_set_role() on each window in your application, for the
1516 * benefit of the session manager. Setting the role allows the window
1517 * manager to restore window positions when loading a saved session.
1521 gtk_window_set_wmclass (GtkWindow *window,
1522 const gchar *wmclass_name,
1523 const gchar *wmclass_class)
1525 GtkWindowPrivate *priv;
1527 g_return_if_fail (GTK_IS_WINDOW (window));
1529 priv = window->priv;
1531 g_free (priv->wmclass_name);
1532 priv->wmclass_name = g_strdup (wmclass_name);
1534 g_free (priv->wmclass_class);
1535 priv->wmclass_class = g_strdup (wmclass_class);
1537 if (gtk_widget_get_realized (GTK_WIDGET (window)))
1538 g_warning ("gtk_window_set_wmclass: shouldn't set wmclass after window is realized!\n");
1542 * gtk_window_set_role:
1543 * @window: a #GtkWindow
1544 * @role: unique identifier for the window to be used when restoring a session
1546 * This function is only useful on X11, not with other GTK+ targets.
1548 * In combination with the window title, the window role allows a
1549 * <link linkend="gtk-X11-arch">window manager</link> to identify "the
1550 * same" window when an application is restarted. So for example you
1551 * might set the "toolbox" role on your app's toolbox window, so that
1552 * when the user restarts their session, the window manager can put
1553 * the toolbox back in the same place.
1555 * If a window already has a unique title, you don't need to set the
1556 * role, since the WM can use the title to identify the window when
1557 * restoring the session.
1561 gtk_window_set_role (GtkWindow *window,
1564 GtkWindowPrivate *priv;
1567 g_return_if_fail (GTK_IS_WINDOW (window));
1569 priv = window->priv;
1571 new_role = g_strdup (role);
1572 g_free (priv->wm_role);
1573 priv->wm_role = new_role;
1575 if (gtk_widget_get_realized (GTK_WIDGET (window)))
1576 gdk_window_set_role (gtk_widget_get_window (GTK_WIDGET (window)),
1579 g_object_notify (G_OBJECT (window), "role");
1583 * gtk_window_set_startup_id:
1584 * @window: a #GtkWindow
1585 * @startup_id: a string with startup-notification identifier
1587 * Startup notification identifiers are used by desktop environment to
1588 * track application startup, to provide user feedback and other
1589 * features. This function changes the corresponding property on the
1590 * underlying GdkWindow. Normally, startup identifier is managed
1591 * automatically and you should only use this function in special cases
1592 * like transferring focus from other processes. You should use this
1593 * function before calling gtk_window_present() or any equivalent
1594 * function generating a window map event.
1596 * This function is only useful on X11, not with other GTK+ targets.
1601 gtk_window_set_startup_id (GtkWindow *window,
1602 const gchar *startup_id)
1604 GtkWindowPrivate *priv;
1607 g_return_if_fail (GTK_IS_WINDOW (window));
1609 priv = window->priv;
1610 widget = GTK_WIDGET (window);
1612 g_free (priv->startup_id);
1613 priv->startup_id = g_strdup (startup_id);
1615 if (gtk_widget_get_realized (widget))
1617 GdkWindow *gdk_window;
1618 guint32 timestamp = extract_time_from_startup_id (priv->startup_id);
1620 gdk_window = gtk_widget_get_window (widget);
1622 #ifdef GDK_WINDOWING_X11
1623 if (timestamp != GDK_CURRENT_TIME)
1624 gdk_x11_window_set_user_time (gdk_window, timestamp);
1627 /* Here we differentiate real and "fake" startup notification IDs,
1628 * constructed on purpose just to pass interaction timestamp
1630 if (startup_id_is_fake (priv->startup_id))
1631 gtk_window_present_with_time (window, timestamp);
1634 gdk_window_set_startup_id (gdk_window,
1637 /* If window is mapped, terminate the startup-notification too */
1638 if (gtk_widget_get_mapped (widget) &&
1639 !disable_startup_notification)
1640 gdk_notify_startup_complete_with_id (priv->startup_id);
1644 g_object_notify (G_OBJECT (window), "startup-id");
1648 * gtk_window_get_role:
1649 * @window: a #GtkWindow
1651 * Returns the role of the window. See gtk_window_set_role() for
1652 * further explanation.
1654 * Return value: the role of the window if set, or %NULL. The
1655 * returned is owned by the widget and must not be modified
1658 G_CONST_RETURN gchar *
1659 gtk_window_get_role (GtkWindow *window)
1661 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
1663 return window->priv->wm_role;
1667 * gtk_window_set_focus:
1668 * @window: a #GtkWindow
1669 * @focus: (allow-none): widget to be the new focus widget, or %NULL to unset
1670 * any focus widget for the toplevel window.
1672 * If @focus is not the current focus widget, and is focusable, sets
1673 * it as the focus widget for the window. If @focus is %NULL, unsets
1674 * the focus widget for this window. To set the focus to a particular
1675 * widget in the toplevel, it is usually more convenient to use
1676 * gtk_widget_grab_focus() instead of this function.
1679 gtk_window_set_focus (GtkWindow *window,
1682 GtkWindowPrivate *priv;
1685 g_return_if_fail (GTK_IS_WINDOW (window));
1687 priv = window->priv;
1691 g_return_if_fail (GTK_IS_WIDGET (focus));
1692 g_return_if_fail (gtk_widget_get_can_focus (focus));
1696 gtk_widget_grab_focus (focus);
1699 /* Clear the existing focus chain, so that when we focus into
1700 * the window again, we start at the beginnning.
1702 GtkWidget *widget = priv->focus_widget;
1705 while ((parent = gtk_widget_get_parent (widget)))
1708 gtk_container_set_focus_child (GTK_CONTAINER (widget), NULL);
1712 _gtk_window_internal_set_focus (window, NULL);
1717 _gtk_window_internal_set_focus (GtkWindow *window,
1720 GtkWindowPrivate *priv;
1722 g_return_if_fail (GTK_IS_WINDOW (window));
1724 priv = window->priv;
1726 if ((priv->focus_widget != focus) ||
1727 (focus && !gtk_widget_has_focus (focus)))
1728 g_signal_emit (window, window_signals[SET_FOCUS], 0, focus);
1732 * gtk_window_set_default:
1733 * @window: a #GtkWindow
1734 * @default_widget: (allow-none): widget to be the default, or %NULL to unset the
1735 * default widget for the toplevel.
1737 * The default widget is the widget that's activated when the user
1738 * presses Enter in a dialog (for example). This function sets or
1739 * unsets the default widget for a #GtkWindow about. When setting
1740 * (rather than unsetting) the default widget it's generally easier to
1741 * call gtk_widget_grab_focus() on the widget. Before making a widget
1742 * the default widget, you must set the #GTK_CAN_DEFAULT flag on the
1743 * widget you'd like to make the default using GTK_WIDGET_SET_FLAGS().
1746 gtk_window_set_default (GtkWindow *window,
1747 GtkWidget *default_widget)
1749 GtkWindowPrivate *priv;
1751 g_return_if_fail (GTK_IS_WINDOW (window));
1753 priv = window->priv;
1756 g_return_if_fail (gtk_widget_get_can_default (default_widget));
1758 if (priv->default_widget != default_widget)
1760 GtkWidget *old_default_widget = NULL;
1763 g_object_ref (default_widget);
1765 if (priv->default_widget)
1767 old_default_widget = priv->default_widget;
1769 if (priv->focus_widget != priv->default_widget ||
1770 !gtk_widget_get_receives_default (priv->default_widget))
1771 _gtk_widget_set_has_default (priv->default_widget, FALSE);
1773 gtk_widget_queue_draw (priv->default_widget);
1776 priv->default_widget = default_widget;
1778 if (priv->default_widget)
1780 if (priv->focus_widget == NULL ||
1781 !gtk_widget_get_receives_default (priv->focus_widget))
1782 _gtk_widget_set_has_default (priv->default_widget, TRUE);
1784 gtk_widget_queue_draw (priv->default_widget);
1787 if (old_default_widget)
1788 g_object_notify (G_OBJECT (old_default_widget), "has-default");
1792 g_object_notify (G_OBJECT (default_widget), "has-default");
1793 g_object_unref (default_widget);
1799 * gtk_window_get_default_widget:
1800 * @window: a #GtkWindow
1802 * Returns the default widget for @window. See gtk_window_set_default()
1805 * Returns: (transfer none): the default widget, or %NULL if there is none.
1810 gtk_window_get_default_widget (GtkWindow *window)
1812 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
1814 return window->priv->default_widget;
1818 handle_keys_changed (gpointer data)
1820 GtkWindow *window = GTK_WINDOW (data);
1821 GtkWindowPrivate *priv = window->priv;
1823 if (priv->keys_changed_handler)
1825 g_source_remove (priv->keys_changed_handler);
1826 priv->keys_changed_handler = 0;
1829 g_signal_emit (window, window_signals[KEYS_CHANGED], 0);
1835 gtk_window_notify_keys_changed (GtkWindow *window)
1837 GtkWindowPrivate *priv = window->priv;
1839 if (!priv->keys_changed_handler)
1840 priv->keys_changed_handler = gdk_threads_add_idle (handle_keys_changed, window);
1844 * gtk_window_add_accel_group:
1845 * @window: window to attach accelerator group to
1846 * @accel_group: a #GtkAccelGroup
1848 * Associate @accel_group with @window, such that calling
1849 * gtk_accel_groups_activate() on @window will activate accelerators
1853 gtk_window_add_accel_group (GtkWindow *window,
1854 GtkAccelGroup *accel_group)
1856 g_return_if_fail (GTK_IS_WINDOW (window));
1857 g_return_if_fail (GTK_IS_ACCEL_GROUP (accel_group));
1859 _gtk_accel_group_attach (accel_group, G_OBJECT (window));
1860 g_signal_connect_object (accel_group, "accel-changed",
1861 G_CALLBACK (gtk_window_notify_keys_changed),
1862 window, G_CONNECT_SWAPPED);
1863 gtk_window_notify_keys_changed (window);
1867 * gtk_window_remove_accel_group:
1868 * @window: a #GtkWindow
1869 * @accel_group: a #GtkAccelGroup
1871 * Reverses the effects of gtk_window_add_accel_group().
1874 gtk_window_remove_accel_group (GtkWindow *window,
1875 GtkAccelGroup *accel_group)
1877 g_return_if_fail (GTK_IS_WINDOW (window));
1878 g_return_if_fail (GTK_IS_ACCEL_GROUP (accel_group));
1880 g_signal_handlers_disconnect_by_func (accel_group,
1881 gtk_window_notify_keys_changed,
1883 _gtk_accel_group_detach (accel_group, G_OBJECT (window));
1884 gtk_window_notify_keys_changed (window);
1887 static GtkMnemonicHash *
1888 gtk_window_get_mnemonic_hash (GtkWindow *window,
1891 GtkWindowPrivate *private = window->priv;
1893 if (!private->mnemonic_hash && create)
1894 private->mnemonic_hash = _gtk_mnemonic_hash_new ();
1896 return private->mnemonic_hash;
1900 * gtk_window_add_mnemonic:
1901 * @window: a #GtkWindow
1902 * @keyval: the mnemonic
1903 * @target: the widget that gets activated by the mnemonic
1905 * Adds a mnemonic to this window.
1908 gtk_window_add_mnemonic (GtkWindow *window,
1912 g_return_if_fail (GTK_IS_WINDOW (window));
1913 g_return_if_fail (GTK_IS_WIDGET (target));
1915 _gtk_mnemonic_hash_add (gtk_window_get_mnemonic_hash (window, TRUE),
1917 gtk_window_notify_keys_changed (window);
1921 * gtk_window_remove_mnemonic:
1922 * @window: a #GtkWindow
1923 * @keyval: the mnemonic
1924 * @target: the widget that gets activated by the mnemonic
1926 * Removes a mnemonic from this window.
1929 gtk_window_remove_mnemonic (GtkWindow *window,
1933 g_return_if_fail (GTK_IS_WINDOW (window));
1934 g_return_if_fail (GTK_IS_WIDGET (target));
1936 _gtk_mnemonic_hash_remove (gtk_window_get_mnemonic_hash (window, TRUE),
1938 gtk_window_notify_keys_changed (window);
1942 * gtk_window_mnemonic_activate:
1943 * @window: a #GtkWindow
1944 * @keyval: the mnemonic
1945 * @modifier: the modifiers
1946 * @returns: %TRUE if the activation is done.
1948 * Activates the targets associated with the mnemonic.
1951 gtk_window_mnemonic_activate (GtkWindow *window,
1953 GdkModifierType modifier)
1955 GtkWindowPrivate *priv;
1957 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
1959 priv = window->priv;
1961 if (priv->mnemonic_modifier == (modifier & gtk_accelerator_get_default_mod_mask ()))
1963 GtkMnemonicHash *mnemonic_hash = gtk_window_get_mnemonic_hash (window, FALSE);
1965 return _gtk_mnemonic_hash_activate (mnemonic_hash, keyval);
1972 * gtk_window_set_mnemonic_modifier:
1973 * @window: a #GtkWindow
1974 * @modifier: the modifier mask used to activate
1975 * mnemonics on this window.
1977 * Sets the mnemonic modifier for this window.
1980 gtk_window_set_mnemonic_modifier (GtkWindow *window,
1981 GdkModifierType modifier)
1983 GtkWindowPrivate *priv;
1985 g_return_if_fail (GTK_IS_WINDOW (window));
1986 g_return_if_fail ((modifier & ~GDK_MODIFIER_MASK) == 0);
1988 priv = window->priv;
1990 priv->mnemonic_modifier = modifier;
1991 gtk_window_notify_keys_changed (window);
1995 * gtk_window_get_mnemonic_modifier:
1996 * @window: a #GtkWindow
1998 * Returns the mnemonic modifier for this window. See
1999 * gtk_window_set_mnemonic_modifier().
2001 * Return value: the modifier mask used to activate
2002 * mnemonics on this window.
2005 gtk_window_get_mnemonic_modifier (GtkWindow *window)
2007 g_return_val_if_fail (GTK_IS_WINDOW (window), 0);
2009 return window->priv->mnemonic_modifier;
2013 * gtk_window_set_position:
2014 * @window: a #GtkWindow.
2015 * @position: a position constraint.
2017 * Sets a position constraint for this window. If the old or new
2018 * constraint is %GTK_WIN_POS_CENTER_ALWAYS, this will also cause
2019 * the window to be repositioned to satisfy the new constraint.
2022 gtk_window_set_position (GtkWindow *window,
2023 GtkWindowPosition position)
2025 GtkWindowPrivate *priv;
2027 g_return_if_fail (GTK_IS_WINDOW (window));
2029 priv = window->priv;
2031 if (position == GTK_WIN_POS_CENTER_ALWAYS ||
2032 priv->position == GTK_WIN_POS_CENTER_ALWAYS)
2034 GtkWindowGeometryInfo *info;
2036 info = gtk_window_get_geometry_info (window, TRUE);
2038 /* this flag causes us to re-request the CENTER_ALWAYS
2039 * constraint in gtk_window_move_resize(), see
2040 * comment in that function.
2042 info->position_constraints_changed = TRUE;
2044 gtk_widget_queue_resize_no_redraw (GTK_WIDGET (window));
2047 priv->position = position;
2049 g_object_notify (G_OBJECT (window), "window-position");
2053 * gtk_window_activate_focus:
2054 * @window: a #GtkWindow
2056 * Activates the current focused widget within the window.
2058 * Return value: %TRUE if a widget got activated.
2061 gtk_window_activate_focus (GtkWindow *window)
2063 GtkWindowPrivate *priv;
2065 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
2067 priv = window->priv;
2069 if (priv->focus_widget && gtk_widget_is_sensitive (priv->focus_widget))
2070 return gtk_widget_activate (priv->focus_widget);
2076 * gtk_window_get_focus:
2077 * @window: a #GtkWindow
2079 * Retrieves the current focused widget within the window.
2080 * Note that this is the widget that would have the focus
2081 * if the toplevel window focused; if the toplevel window
2082 * is not focused then <literal>gtk_widget_has_focus (widget)</literal> will
2083 * not be %TRUE for the widget.
2085 * Return value: (transfer none): the currently focused widget, or %NULL if there is none.
2088 gtk_window_get_focus (GtkWindow *window)
2090 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
2092 return window->priv->focus_widget;
2096 * gtk_window_activate_default:
2097 * @window: a #GtkWindow
2099 * Activates the default widget for the window, unless the current
2100 * focused widget has been configured to receive the default action
2101 * (see gtk_widget_set_receives_default()), in which case the
2102 * focused widget is activated.
2104 * Return value: %TRUE if a widget got activated.
2107 gtk_window_activate_default (GtkWindow *window)
2109 GtkWindowPrivate *priv;
2111 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
2113 priv = window->priv;
2115 if (priv->default_widget && gtk_widget_is_sensitive (priv->default_widget) &&
2116 (!priv->focus_widget || !gtk_widget_get_receives_default (priv->focus_widget)))
2117 return gtk_widget_activate (priv->default_widget);
2118 else if (priv->focus_widget && gtk_widget_is_sensitive (priv->focus_widget))
2119 return gtk_widget_activate (priv->focus_widget);
2125 * gtk_window_set_modal:
2126 * @window: a #GtkWindow
2127 * @modal: whether the window is modal
2129 * Sets a window modal or non-modal. Modal windows prevent interaction
2130 * with other windows in the same application. To keep modal dialogs
2131 * on top of main application windows, use
2132 * gtk_window_set_transient_for() to make the dialog transient for the
2133 * parent; most <link linkend="gtk-X11-arch">window managers</link>
2134 * will then disallow lowering the dialog below the parent.
2139 gtk_window_set_modal (GtkWindow *window,
2142 GtkWindowPrivate *priv;
2145 g_return_if_fail (GTK_IS_WINDOW (window));
2147 priv = window->priv;
2149 modal = modal != FALSE;
2150 if (priv->modal == modal)
2153 priv->modal = modal;
2154 widget = GTK_WIDGET (window);
2156 /* adjust desired modality state */
2157 if (gtk_widget_get_realized (widget))
2160 gdk_window_set_modal_hint (gtk_widget_get_window (widget), TRUE);
2162 gdk_window_set_modal_hint (gtk_widget_get_window (widget), FALSE);
2165 if (gtk_widget_get_visible (widget))
2168 gtk_grab_add (widget);
2170 gtk_grab_remove (widget);
2173 g_object_notify (G_OBJECT (window), "modal");
2177 * gtk_window_get_modal:
2178 * @window: a #GtkWindow
2180 * Returns whether the window is modal. See gtk_window_set_modal().
2182 * Return value: %TRUE if the window is set to be modal and
2183 * establishes a grab when shown
2186 gtk_window_get_modal (GtkWindow *window)
2188 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
2190 return window->priv->modal;
2194 * gtk_window_list_toplevels:
2196 * Returns a list of all existing toplevel windows. The widgets
2197 * in the list are not individually referenced. If you want
2198 * to iterate through the list and perform actions involving
2199 * callbacks that might destroy the widgets, you <emphasis>must</emphasis> call
2200 * <literal>g_list_foreach (result, (GFunc)g_object_ref, NULL)</literal> first, and
2201 * then unref all the widgets afterwards.
2203 * Return value: (element-type GtkWidget) (transfer container): list of toplevel widgets
2206 gtk_window_list_toplevels (void)
2211 for (slist = toplevel_list; slist; slist = slist->next)
2212 list = g_list_prepend (list, slist->data);
2218 gtk_window_add_embedded_xid (GtkWindow *window, GdkNativeWindow xid)
2220 GList *embedded_windows;
2222 g_return_if_fail (GTK_IS_WINDOW (window));
2224 embedded_windows = g_object_get_qdata (G_OBJECT (window), quark_gtk_embedded);
2225 if (embedded_windows)
2226 g_object_steal_qdata (G_OBJECT (window), quark_gtk_embedded);
2227 embedded_windows = g_list_prepend (embedded_windows,
2228 GUINT_TO_POINTER (xid));
2230 g_object_set_qdata_full (G_OBJECT (window), quark_gtk_embedded,
2233 (GDestroyNotify) g_list_free : NULL);
2237 gtk_window_remove_embedded_xid (GtkWindow *window, GdkNativeWindow xid)
2239 GList *embedded_windows;
2242 g_return_if_fail (GTK_IS_WINDOW (window));
2244 embedded_windows = g_object_get_qdata (G_OBJECT (window), quark_gtk_embedded);
2245 if (embedded_windows)
2246 g_object_steal_qdata (G_OBJECT (window), quark_gtk_embedded);
2248 node = g_list_find (embedded_windows, GUINT_TO_POINTER (xid));
2251 embedded_windows = g_list_remove_link (embedded_windows, node);
2252 g_list_free_1 (node);
2255 g_object_set_qdata_full (G_OBJECT (window), quark_gtk_embedded,
2258 (GDestroyNotify) g_list_free : NULL);
2262 gtk_window_dispose (GObject *object)
2264 GtkWindow *window = GTK_WINDOW (object);
2266 gtk_window_set_focus (window, NULL);
2267 gtk_window_set_default (window, NULL);
2269 G_OBJECT_CLASS (gtk_window_parent_class)->dispose (object);
2273 parent_destroyed_callback (GtkWindow *parent, GtkWindow *child)
2275 gtk_widget_destroy (GTK_WIDGET (child));
2279 connect_parent_destroyed (GtkWindow *window)
2281 GtkWindowPrivate *priv = window->priv;
2283 if (priv->transient_parent)
2285 g_signal_connect (priv->transient_parent,
2287 G_CALLBACK (parent_destroyed_callback),
2293 disconnect_parent_destroyed (GtkWindow *window)
2295 GtkWindowPrivate *priv = window->priv;
2297 if (priv->transient_parent)
2299 g_signal_handlers_disconnect_by_func (priv->transient_parent,
2300 parent_destroyed_callback,
2306 gtk_window_transient_parent_realized (GtkWidget *parent,
2309 if (gtk_widget_get_realized (window))
2310 gdk_window_set_transient_for (gtk_widget_get_window (window),
2311 gtk_widget_get_window (parent));
2315 gtk_window_transient_parent_unrealized (GtkWidget *parent,
2318 if (gtk_widget_get_realized (window))
2319 gdk_property_delete (gtk_widget_get_window (window),
2320 gdk_atom_intern_static_string ("WM_TRANSIENT_FOR"));
2324 gtk_window_transient_parent_screen_changed (GtkWindow *parent,
2328 gtk_window_set_screen (window, gtk_window_get_screen (parent));
2332 gtk_window_unset_transient_for (GtkWindow *window)
2334 GtkWindowPrivate *priv = window->priv;
2336 if (priv->transient_parent)
2338 g_signal_handlers_disconnect_by_func (priv->transient_parent,
2339 gtk_window_transient_parent_realized,
2341 g_signal_handlers_disconnect_by_func (priv->transient_parent,
2342 gtk_window_transient_parent_unrealized,
2344 g_signal_handlers_disconnect_by_func (priv->transient_parent,
2345 gtk_window_transient_parent_screen_changed,
2347 g_signal_handlers_disconnect_by_func (priv->transient_parent,
2348 gtk_widget_destroyed,
2349 &priv->transient_parent);
2351 if (priv->destroy_with_parent)
2352 disconnect_parent_destroyed (window);
2354 priv->transient_parent = NULL;
2356 if (priv->transient_parent_group)
2358 priv->transient_parent_group = FALSE;
2359 gtk_window_group_remove_window (priv->group,
2366 * gtk_window_set_transient_for:
2367 * @window: a #GtkWindow
2368 * @parent: (allow-none): parent window, or %NULL
2370 * Dialog windows should be set transient for the main application
2371 * window they were spawned from. This allows <link
2372 * linkend="gtk-X11-arch">window managers</link> to e.g. keep the
2373 * dialog on top of the main window, or center the dialog over the
2374 * main window. gtk_dialog_new_with_buttons() and other convenience
2375 * functions in GTK+ will sometimes call
2376 * gtk_window_set_transient_for() on your behalf.
2378 * Passing %NULL for @parent unsets the current transient window.
2380 * On Windows, this function puts the child window on top of the parent,
2381 * much as the window manager would have done on X.
2384 gtk_window_set_transient_for (GtkWindow *window,
2387 GtkWindowPrivate *priv;
2389 g_return_if_fail (GTK_IS_WINDOW (window));
2390 g_return_if_fail (parent == NULL || GTK_IS_WINDOW (parent));
2391 g_return_if_fail (window != parent);
2393 priv = window->priv;
2395 if (priv->transient_parent)
2397 if (gtk_widget_get_realized (GTK_WIDGET (window)) &&
2398 gtk_widget_get_realized (GTK_WIDGET (priv->transient_parent)) &&
2399 (!parent || !gtk_widget_get_realized (GTK_WIDGET (parent))))
2400 gtk_window_transient_parent_unrealized (GTK_WIDGET (priv->transient_parent),
2401 GTK_WIDGET (window));
2403 gtk_window_unset_transient_for (window);
2406 priv->transient_parent = parent;
2410 g_signal_connect (parent, "destroy",
2411 G_CALLBACK (gtk_widget_destroyed),
2412 &priv->transient_parent);
2413 g_signal_connect (parent, "realize",
2414 G_CALLBACK (gtk_window_transient_parent_realized),
2416 g_signal_connect (parent, "unrealize",
2417 G_CALLBACK (gtk_window_transient_parent_unrealized),
2419 g_signal_connect (parent, "notify::screen",
2420 G_CALLBACK (gtk_window_transient_parent_screen_changed),
2423 gtk_window_set_screen (window, gtk_window_get_screen (parent));
2425 if (priv->destroy_with_parent)
2426 connect_parent_destroyed (window);
2428 if (gtk_widget_get_realized (GTK_WIDGET (window)) &&
2429 gtk_widget_get_realized (GTK_WIDGET (parent)))
2430 gtk_window_transient_parent_realized (GTK_WIDGET (parent),
2431 GTK_WIDGET (window));
2433 if (parent->priv->group)
2435 gtk_window_group_add_window (parent->priv->group, window);
2436 priv->transient_parent_group = TRUE;
2442 * gtk_window_get_transient_for:
2443 * @window: a #GtkWindow
2445 * Fetches the transient parent for this window. See
2446 * gtk_window_set_transient_for().
2448 * Return value: (transfer none): the transient parent for this window, or %NULL
2449 * if no transient parent has been set.
2452 gtk_window_get_transient_for (GtkWindow *window)
2454 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
2456 return window->priv->transient_parent;
2460 * gtk_window_set_opacity:
2461 * @window: a #GtkWindow
2462 * @opacity: desired opacity, between 0 and 1
2464 * Request the windowing system to make @window partially transparent,
2465 * with opacity 0 being fully transparent and 1 fully opaque. (Values
2466 * of the opacity parameter are clamped to the [0,1] range.) On X11
2467 * this has any effect only on X screens with a compositing manager
2468 * running. See gtk_widget_is_composited(). On Windows it should work
2471 * Note that setting a window's opacity after the window has been
2472 * shown causes it to flicker once on Windows.
2477 gtk_window_set_opacity (GtkWindow *window,
2480 GtkWindowPrivate *priv;
2482 g_return_if_fail (GTK_IS_WINDOW (window));
2484 priv = window->priv;
2488 else if (opacity > 1.0)
2491 priv->opacity_set = TRUE;
2492 priv->opacity = opacity;
2494 if (gtk_widget_get_realized (GTK_WIDGET (window)))
2495 gdk_window_set_opacity (gtk_widget_get_window (GTK_WIDGET (window)),
2500 * gtk_window_get_opacity:
2501 * @window: a #GtkWindow
2503 * Fetches the requested opacity for this window. See
2504 * gtk_window_set_opacity().
2506 * Return value: the requested opacity for this window.
2511 gtk_window_get_opacity (GtkWindow *window)
2513 g_return_val_if_fail (GTK_IS_WINDOW (window), 0.0);
2515 return window->priv->opacity;
2519 * gtk_window_set_type_hint:
2520 * @window: a #GtkWindow
2521 * @hint: the window type
2523 * By setting the type hint for the window, you allow the window
2524 * manager to decorate and handle the window in a way which is
2525 * suitable to the function of the window in your application.
2527 * This function should be called before the window becomes visible.
2529 * gtk_dialog_new_with_buttons() and other convenience functions in GTK+
2530 * will sometimes call gtk_window_set_type_hint() on your behalf.
2534 gtk_window_set_type_hint (GtkWindow *window,
2535 GdkWindowTypeHint hint)
2537 GtkWindowPrivate *priv;
2539 g_return_if_fail (GTK_IS_WINDOW (window));
2540 g_return_if_fail (!gtk_widget_get_mapped (GTK_WIDGET (window)));
2542 priv = window->priv;
2544 if (hint < GDK_WINDOW_TYPE_HINT_DROPDOWN_MENU)
2545 priv->gdk_type_hint = hint;
2547 priv->gdk_type_hint = GDK_WINDOW_TYPE_HINT_NORMAL;
2549 priv->reset_type_hint = TRUE;
2550 priv->type_hint = hint;
2554 * gtk_window_get_type_hint:
2555 * @window: a #GtkWindow
2557 * Gets the type hint for this window. See gtk_window_set_type_hint().
2559 * Return value: the type hint for @window.
2562 gtk_window_get_type_hint (GtkWindow *window)
2564 g_return_val_if_fail (GTK_IS_WINDOW (window), GDK_WINDOW_TYPE_HINT_NORMAL);
2566 return window->priv->type_hint;
2570 * gtk_window_set_skip_taskbar_hint:
2571 * @window: a #GtkWindow
2572 * @setting: %TRUE to keep this window from appearing in the task bar
2574 * Windows may set a hint asking the desktop environment not to display
2575 * the window in the task bar. This function sets this hint.
2580 gtk_window_set_skip_taskbar_hint (GtkWindow *window,
2583 GtkWindowPrivate *priv;
2585 g_return_if_fail (GTK_IS_WINDOW (window));
2587 priv = window->priv;
2589 setting = setting != FALSE;
2591 if (priv->skips_taskbar != setting)
2593 priv->skips_taskbar = setting;
2594 if (gtk_widget_get_realized (GTK_WIDGET (window)))
2595 gdk_window_set_skip_taskbar_hint (gtk_widget_get_window (GTK_WIDGET (window)),
2596 priv->skips_taskbar);
2597 g_object_notify (G_OBJECT (window), "skip-taskbar-hint");
2602 * gtk_window_get_skip_taskbar_hint:
2603 * @window: a #GtkWindow
2605 * Gets the value set by gtk_window_set_skip_taskbar_hint()
2607 * Return value: %TRUE if window shouldn't be in taskbar
2612 gtk_window_get_skip_taskbar_hint (GtkWindow *window)
2614 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
2616 return window->priv->skips_taskbar;
2620 * gtk_window_set_skip_pager_hint:
2621 * @window: a #GtkWindow
2622 * @setting: %TRUE to keep this window from appearing in the pager
2624 * Windows may set a hint asking the desktop environment not to display
2625 * the window in the pager. This function sets this hint.
2626 * (A "pager" is any desktop navigation tool such as a workspace
2627 * switcher that displays a thumbnail representation of the windows
2633 gtk_window_set_skip_pager_hint (GtkWindow *window,
2636 GtkWindowPrivate *priv;
2638 g_return_if_fail (GTK_IS_WINDOW (window));
2640 priv = window->priv;
2642 setting = setting != FALSE;
2644 if (priv->skips_pager != setting)
2646 priv->skips_pager = setting;
2647 if (gtk_widget_get_realized (GTK_WIDGET (window)))
2648 gdk_window_set_skip_pager_hint (gtk_widget_get_window (GTK_WIDGET (window)),
2650 g_object_notify (G_OBJECT (window), "skip-pager-hint");
2655 * gtk_window_get_skip_pager_hint:
2656 * @window: a #GtkWindow
2658 * Gets the value set by gtk_window_set_skip_pager_hint().
2660 * Return value: %TRUE if window shouldn't be in pager
2665 gtk_window_get_skip_pager_hint (GtkWindow *window)
2667 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
2669 return window->priv->skips_pager;
2673 * gtk_window_set_urgency_hint:
2674 * @window: a #GtkWindow
2675 * @setting: %TRUE to mark this window as urgent
2677 * Windows may set a hint asking the desktop environment to draw
2678 * the users attention to the window. This function sets this hint.
2683 gtk_window_set_urgency_hint (GtkWindow *window,
2686 GtkWindowPrivate *priv;
2688 g_return_if_fail (GTK_IS_WINDOW (window));
2690 priv = window->priv;
2692 setting = setting != FALSE;
2694 if (priv->urgent != setting)
2696 priv->urgent = setting;
2697 if (gtk_widget_get_realized (GTK_WIDGET (window)))
2698 gdk_window_set_urgency_hint (gtk_widget_get_window (GTK_WIDGET (window)),
2700 g_object_notify (G_OBJECT (window), "urgency-hint");
2705 * gtk_window_get_urgency_hint:
2706 * @window: a #GtkWindow
2708 * Gets the value set by gtk_window_set_urgency_hint()
2710 * Return value: %TRUE if window is urgent
2715 gtk_window_get_urgency_hint (GtkWindow *window)
2717 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
2719 return window->priv->urgent;
2723 * gtk_window_set_accept_focus:
2724 * @window: a #GtkWindow
2725 * @setting: %TRUE to let this window receive input focus
2727 * Windows may set a hint asking the desktop environment not to receive
2728 * the input focus. This function sets this hint.
2733 gtk_window_set_accept_focus (GtkWindow *window,
2736 GtkWindowPrivate *priv;
2738 g_return_if_fail (GTK_IS_WINDOW (window));
2740 priv = window->priv;
2742 setting = setting != FALSE;
2744 if (priv->accept_focus != setting)
2746 priv->accept_focus = setting;
2747 if (gtk_widget_get_realized (GTK_WIDGET (window)))
2748 gdk_window_set_accept_focus (gtk_widget_get_window (GTK_WIDGET (window)),
2749 priv->accept_focus);
2750 g_object_notify (G_OBJECT (window), "accept-focus");
2755 * gtk_window_get_accept_focus:
2756 * @window: a #GtkWindow
2758 * Gets the value set by gtk_window_set_accept_focus().
2760 * Return value: %TRUE if window should receive the input focus
2765 gtk_window_get_accept_focus (GtkWindow *window)
2767 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
2769 return window->priv->accept_focus;
2773 * gtk_window_set_focus_on_map:
2774 * @window: a #GtkWindow
2775 * @setting: %TRUE to let this window receive input focus on map
2777 * Windows may set a hint asking the desktop environment not to receive
2778 * the input focus when the window is mapped. This function sets this
2784 gtk_window_set_focus_on_map (GtkWindow *window,
2787 GtkWindowPrivate *priv;
2789 g_return_if_fail (GTK_IS_WINDOW (window));
2791 priv = window->priv;
2793 setting = setting != FALSE;
2795 if (priv->focus_on_map != setting)
2797 priv->focus_on_map = setting;
2798 if (gtk_widget_get_realized (GTK_WIDGET (window)))
2799 gdk_window_set_focus_on_map (gtk_widget_get_window (GTK_WIDGET (window)),
2800 priv->focus_on_map);
2801 g_object_notify (G_OBJECT (window), "focus-on-map");
2806 * gtk_window_get_focus_on_map:
2807 * @window: a #GtkWindow
2809 * Gets the value set by gtk_window_set_focus_on_map().
2811 * Return value: %TRUE if window should receive the input focus when
2817 gtk_window_get_focus_on_map (GtkWindow *window)
2819 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
2821 return window->priv->focus_on_map;
2825 * gtk_window_set_destroy_with_parent:
2826 * @window: a #GtkWindow
2827 * @setting: whether to destroy @window with its transient parent
2829 * If @setting is %TRUE, then destroying the transient parent of @window
2830 * will also destroy @window itself. This is useful for dialogs that
2831 * shouldn't persist beyond the lifetime of the main window they're
2832 * associated with, for example.
2835 gtk_window_set_destroy_with_parent (GtkWindow *window,
2838 GtkWindowPrivate *priv;
2840 g_return_if_fail (GTK_IS_WINDOW (window));
2842 priv = window->priv;
2844 if (priv->destroy_with_parent == (setting != FALSE))
2847 if (priv->destroy_with_parent)
2849 disconnect_parent_destroyed (window);
2853 connect_parent_destroyed (window);
2856 priv->destroy_with_parent = setting;
2858 g_object_notify (G_OBJECT (window), "destroy-with-parent");
2862 * gtk_window_get_destroy_with_parent:
2863 * @window: a #GtkWindow
2865 * Returns whether the window will be destroyed with its transient parent. See
2866 * gtk_window_set_destroy_with_parent ().
2868 * Return value: %TRUE if the window will be destroyed with its transient parent.
2871 gtk_window_get_destroy_with_parent (GtkWindow *window)
2873 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
2875 return window->priv->destroy_with_parent;
2878 static GtkWindowGeometryInfo*
2879 gtk_window_get_geometry_info (GtkWindow *window,
2882 GtkWindowPrivate *priv = window->priv;
2883 GtkWindowGeometryInfo *info;
2885 info = priv->geometry_info;
2886 if (!info && create)
2888 info = g_new0 (GtkWindowGeometryInfo, 1);
2890 info->default_width = -1;
2891 info->default_height = -1;
2892 info->resize_width = -1;
2893 info->resize_height = -1;
2894 info->initial_x = 0;
2895 info->initial_y = 0;
2896 info->initial_pos_set = FALSE;
2897 info->default_is_geometry = FALSE;
2898 info->position_constraints_changed = FALSE;
2899 info->last.configure_request.x = 0;
2900 info->last.configure_request.y = 0;
2901 info->last.configure_request.width = -1;
2902 info->last.configure_request.height = -1;
2903 info->widget = NULL;
2905 priv->geometry_info = info;
2912 * gtk_window_set_geometry_hints:
2913 * @window: a #GtkWindow
2914 * @geometry_widget: (allow-none): widget the geometry hints will be applied to or %NULL
2915 * @geometry: (allow-none): struct containing geometry information or %NULL
2916 * @geom_mask: mask indicating which struct fields should be paid attention to
2918 * This function sets up hints about how a window can be resized by
2919 * the user. You can set a minimum and maximum size; allowed resize
2920 * increments (e.g. for xterm, you can only resize by the size of a
2921 * character); aspect ratios; and more. See the #GdkGeometry struct.
2925 gtk_window_set_geometry_hints (GtkWindow *window,
2926 GtkWidget *geometry_widget,
2927 GdkGeometry *geometry,
2928 GdkWindowHints geom_mask)
2930 GtkWindowGeometryInfo *info;
2932 g_return_if_fail (GTK_IS_WINDOW (window));
2933 g_return_if_fail (geometry_widget == NULL || GTK_IS_WIDGET (geometry_widget));
2935 info = gtk_window_get_geometry_info (window, TRUE);
2938 g_signal_handlers_disconnect_by_func (info->widget,
2939 gtk_widget_destroyed,
2942 info->widget = geometry_widget;
2944 g_signal_connect (geometry_widget, "destroy",
2945 G_CALLBACK (gtk_widget_destroyed),
2949 info->geometry = *geometry;
2951 /* We store gravity in priv->gravity not in the hints. */
2952 info->mask = geom_mask & ~(GDK_HINT_WIN_GRAVITY);
2954 if (geom_mask & GDK_HINT_WIN_GRAVITY)
2956 gtk_window_set_gravity (window, geometry->win_gravity);
2959 gtk_widget_queue_resize_no_redraw (GTK_WIDGET (window));
2963 * gtk_window_set_decorated:
2964 * @window: a #GtkWindow
2965 * @setting: %TRUE to decorate the window
2967 * By default, windows are decorated with a title bar, resize
2968 * controls, etc. Some <link linkend="gtk-X11-arch">window
2969 * managers</link> allow GTK+ to disable these decorations, creating a
2970 * borderless window. If you set the decorated property to %FALSE
2971 * using this function, GTK+ will do its best to convince the window
2972 * manager not to decorate the window. Depending on the system, this
2973 * function may not have any effect when called on a window that is
2974 * already visible, so you should call it before calling gtk_window_show().
2976 * On Windows, this function always works, since there's no window manager
2981 gtk_window_set_decorated (GtkWindow *window,
2984 GtkWindowPrivate *priv;
2985 GdkWindow *gdk_window;
2987 g_return_if_fail (GTK_IS_WINDOW (window));
2989 priv = window->priv;
2991 setting = setting != FALSE;
2993 if (setting == priv->decorated)
2996 priv->decorated = setting;
2998 gdk_window = gtk_widget_get_window (GTK_WIDGET (window));
3001 if (priv->decorated)
3002 gdk_window_set_decorations (gdk_window,
3005 gdk_window_set_decorations (gdk_window,
3009 g_object_notify (G_OBJECT (window), "decorated");
3013 * gtk_window_get_decorated:
3014 * @window: a #GtkWindow
3016 * Returns whether the window has been set to have decorations
3017 * such as a title bar via gtk_window_set_decorated().
3019 * Return value: %TRUE if the window has been set to have decorations
3022 gtk_window_get_decorated (GtkWindow *window)
3024 g_return_val_if_fail (GTK_IS_WINDOW (window), TRUE);
3026 return window->priv->decorated;
3030 * gtk_window_set_deletable:
3031 * @window: a #GtkWindow
3032 * @setting: %TRUE to decorate the window as deletable
3034 * By default, windows have a close button in the window frame. Some
3035 * <link linkend="gtk-X11-arch">window managers</link> allow GTK+ to
3036 * disable this button. If you set the deletable property to %FALSE
3037 * using this function, GTK+ will do its best to convince the window
3038 * manager not to show a close button. Depending on the system, this
3039 * function may not have any effect when called on a window that is
3040 * already visible, so you should call it before calling gtk_window_show().
3042 * On Windows, this function always works, since there's no window manager
3048 gtk_window_set_deletable (GtkWindow *window,
3051 GtkWindowPrivate *priv;
3052 GdkWindow *gdk_window;
3054 g_return_if_fail (GTK_IS_WINDOW (window));
3056 priv = window->priv;
3058 setting = setting != FALSE;
3060 if (setting == priv->deletable)
3063 priv->deletable = setting;
3065 gdk_window = gtk_widget_get_window (GTK_WIDGET (window));
3068 if (priv->deletable)
3069 gdk_window_set_functions (gdk_window,
3072 gdk_window_set_functions (gdk_window,
3073 GDK_FUNC_ALL | GDK_FUNC_CLOSE);
3076 g_object_notify (G_OBJECT (window), "deletable");
3080 * gtk_window_get_deletable:
3081 * @window: a #GtkWindow
3083 * Returns whether the window has been set to have a close button
3084 * via gtk_window_set_deletable().
3086 * Return value: %TRUE if the window has been set to have a close button
3091 gtk_window_get_deletable (GtkWindow *window)
3093 g_return_val_if_fail (GTK_IS_WINDOW (window), TRUE);
3095 return window->priv->deletable;
3098 static GtkWindowIconInfo*
3099 get_icon_info (GtkWindow *window)
3101 return g_object_get_qdata (G_OBJECT (window), quark_gtk_window_icon_info);
3105 free_icon_info (GtkWindowIconInfo *info)
3107 g_free (info->icon_name);
3108 g_slice_free (GtkWindowIconInfo, info);
3112 static GtkWindowIconInfo*
3113 ensure_icon_info (GtkWindow *window)
3115 GtkWindowIconInfo *info;
3117 info = get_icon_info (window);
3121 info = g_slice_new0 (GtkWindowIconInfo);
3122 g_object_set_qdata_full (G_OBJECT (window),
3123 quark_gtk_window_icon_info,
3125 (GDestroyNotify)free_icon_info);
3132 icon_list_from_theme (GtkWidget *widget,
3137 GtkIconTheme *icon_theme;
3142 icon_theme = gtk_icon_theme_get_for_screen (gtk_widget_get_screen (widget));
3144 sizes = gtk_icon_theme_get_icon_sizes (icon_theme, name);
3147 for (i = 0; sizes[i]; i++)
3150 * We need an EWMH extension to handle scalable icons
3151 * by passing their name to the WM. For now just use a
3155 icon = gtk_icon_theme_load_icon (icon_theme, name,
3158 icon = gtk_icon_theme_load_icon (icon_theme, name,
3161 list = g_list_append (list, icon);
3171 gtk_window_realize_icon (GtkWindow *window)
3173 GtkWindowPrivate *priv = window->priv;
3175 GtkWindowIconInfo *info;
3176 GdkWindow *gdk_window;
3179 widget = GTK_WIDGET (window);
3180 gdk_window = gtk_widget_get_window (widget);
3182 g_return_if_fail (gdk_window != NULL);
3184 /* no point setting an icon on override-redirect */
3185 if (priv->type == GTK_WINDOW_POPUP)
3190 info = ensure_icon_info (window);
3195 info->using_default_icon = FALSE;
3196 info->using_parent_icon = FALSE;
3197 info->using_themed_icon = FALSE;
3199 icon_list = info->icon_list;
3201 /* Look up themed icon */
3202 if (icon_list == NULL && info->icon_name)
3204 icon_list = icon_list_from_theme (widget, info->icon_name);
3206 info->using_themed_icon = TRUE;
3209 /* Inherit from transient parent */
3210 if (icon_list == NULL && priv->transient_parent)
3212 icon_list = ensure_icon_info (priv->transient_parent)->icon_list;
3214 info->using_parent_icon = TRUE;
3217 /* Inherit from default */
3218 if (icon_list == NULL)
3220 icon_list = default_icon_list;
3222 info->using_default_icon = TRUE;
3225 /* Look up themed icon */
3226 if (icon_list == NULL && default_icon_name)
3228 icon_list = icon_list_from_theme (widget, default_icon_name);
3229 info->using_default_icon = TRUE;
3230 info->using_themed_icon = TRUE;
3233 info->realized = TRUE;
3235 if (info->using_themed_icon)
3237 GtkIconTheme *icon_theme;
3239 g_list_foreach (icon_list, (GFunc) g_object_unref, NULL);
3240 g_list_free (icon_list);
3242 icon_theme = gtk_icon_theme_get_for_screen (gtk_widget_get_screen (GTK_WIDGET (window)));
3243 g_signal_connect (icon_theme, "changed",
3244 G_CALLBACK (update_themed_icon), window);
3249 gtk_window_unrealize_icon (GtkWindow *window)
3251 GtkWindowIconInfo *info;
3253 info = get_icon_info (window);
3258 if (info->using_themed_icon)
3260 GtkIconTheme *icon_theme;
3262 icon_theme = gtk_icon_theme_get_for_screen (gtk_widget_get_screen (GTK_WIDGET (window)));
3264 g_signal_handlers_disconnect_by_func (icon_theme, update_themed_icon, window);
3267 /* We don't clear the properties on the window, just figure the
3268 * window is going away.
3271 info->realized = FALSE;
3276 * gtk_window_set_icon_list:
3277 * @window: a #GtkWindow
3278 * @list: (element-type GdkPixbuf) (transfer container): list of #GdkPixbuf
3280 * Sets up the icon representing a #GtkWindow. The icon is used when
3281 * the window is minimized (also known as iconified). Some window
3282 * managers or desktop environments may also place it in the window
3283 * frame, or display it in other contexts.
3285 * gtk_window_set_icon_list() allows you to pass in the same icon in
3286 * several hand-drawn sizes. The list should contain the natural sizes
3287 * your icon is available in; that is, don't scale the image before
3288 * passing it to GTK+. Scaling is postponed until the last minute,
3289 * when the desired final size is known, to allow best quality.
3291 * By passing several sizes, you may improve the final image quality
3292 * of the icon, by reducing or eliminating automatic image scaling.
3294 * Recommended sizes to provide: 16x16, 32x32, 48x48 at minimum, and
3295 * larger images (64x64, 128x128) if you have them.
3297 * See also gtk_window_set_default_icon_list() to set the icon
3298 * for all windows in your application in one go.
3300 * Note that transient windows (those who have been set transient for another
3301 * window using gtk_window_set_transient_for()) will inherit their
3302 * icon from their transient parent. So there's no need to explicitly
3303 * set the icon on transient windows.
3306 gtk_window_set_icon_list (GtkWindow *window,
3309 GtkWindowIconInfo *info;
3311 g_return_if_fail (GTK_IS_WINDOW (window));
3313 info = ensure_icon_info (window);
3315 if (info->icon_list == list) /* check for NULL mostly */
3318 g_list_foreach (list,
3319 (GFunc) g_object_ref, NULL);
3321 g_list_foreach (info->icon_list,
3322 (GFunc) g_object_unref, NULL);
3324 g_list_free (info->icon_list);
3326 info->icon_list = g_list_copy (list);
3328 g_object_notify (G_OBJECT (window), "icon");
3330 gtk_window_unrealize_icon (window);
3332 if (gtk_widget_get_realized (GTK_WIDGET (window)))
3333 gtk_window_realize_icon (window);
3335 /* We could try to update our transient children, but I don't think
3336 * it's really worth it. If we did it, the best way would probably
3337 * be to have children connect to notify::icon-list
3342 * gtk_window_get_icon_list:
3343 * @window: a #GtkWindow
3345 * Retrieves the list of icons set by gtk_window_set_icon_list().
3346 * The list is copied, but the reference count on each
3347 * member won't be incremented.
3349 * Return value: (element-type GdkPixbuf) (transfer container): copy of window's icon list
3352 gtk_window_get_icon_list (GtkWindow *window)
3354 GtkWindowIconInfo *info;
3356 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
3358 info = get_icon_info (window);
3361 return g_list_copy (info->icon_list);
3367 * gtk_window_set_icon:
3368 * @window: a #GtkWindow
3369 * @icon: (allow-none): icon image, or %NULL
3371 * Sets up the icon representing a #GtkWindow. This icon is used when
3372 * the window is minimized (also known as iconified). Some window
3373 * managers or desktop environments may also place it in the window
3374 * frame, or display it in other contexts.
3376 * The icon should be provided in whatever size it was naturally
3377 * drawn; that is, don't scale the image before passing it to
3378 * GTK+. Scaling is postponed until the last minute, when the desired
3379 * final size is known, to allow best quality.
3381 * If you have your icon hand-drawn in multiple sizes, use
3382 * gtk_window_set_icon_list(). Then the best size will be used.
3384 * This function is equivalent to calling gtk_window_set_icon_list()
3385 * with a 1-element list.
3387 * See also gtk_window_set_default_icon_list() to set the icon
3388 * for all windows in your application in one go.
3391 gtk_window_set_icon (GtkWindow *window,
3396 g_return_if_fail (GTK_IS_WINDOW (window));
3397 g_return_if_fail (icon == NULL || GDK_IS_PIXBUF (icon));
3402 list = g_list_append (list, icon);
3404 gtk_window_set_icon_list (window, list);
3410 update_themed_icon (GtkIconTheme *icon_theme,
3413 g_object_notify (G_OBJECT (window), "icon");
3415 gtk_window_unrealize_icon (window);
3417 if (gtk_widget_get_realized (GTK_WIDGET (window)))
3418 gtk_window_realize_icon (window);
3422 * gtk_window_set_icon_name:
3423 * @window: a #GtkWindow
3424 * @name: (allow-none): the name of the themed icon
3426 * Sets the icon for the window from a named themed icon. See
3427 * the docs for #GtkIconTheme for more details.
3429 * Note that this has nothing to do with the WM_ICON_NAME
3430 * property which is mentioned in the ICCCM.
3435 gtk_window_set_icon_name (GtkWindow *window,
3438 GtkWindowIconInfo *info;
3441 g_return_if_fail (GTK_IS_WINDOW (window));
3443 info = ensure_icon_info (window);
3445 if (g_strcmp0 (info->icon_name, name) == 0)
3448 tmp = info->icon_name;
3449 info->icon_name = g_strdup (name);
3452 g_list_foreach (info->icon_list, (GFunc) g_object_unref, NULL);
3453 g_list_free (info->icon_list);
3454 info->icon_list = NULL;
3456 update_themed_icon (NULL, window);
3458 g_object_notify (G_OBJECT (window), "icon-name");
3462 * gtk_window_get_icon_name:
3463 * @window: a #GtkWindow
3465 * Returns the name of the themed icon for the window,
3466 * see gtk_window_set_icon_name().
3468 * Returns: the icon name or %NULL if the window has
3474 gtk_window_get_icon_name (GtkWindow *window)
3476 GtkWindowIconInfo *info;
3478 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
3480 info = ensure_icon_info (window);
3482 return info->icon_name;
3486 * gtk_window_get_icon:
3487 * @window: a #GtkWindow
3489 * Gets the value set by gtk_window_set_icon() (or if you've
3490 * called gtk_window_set_icon_list(), gets the first icon in
3493 * Return value: (transfer none): icon for window
3496 gtk_window_get_icon (GtkWindow *window)
3498 GtkWindowIconInfo *info;
3500 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
3502 info = get_icon_info (window);
3503 if (info && info->icon_list)
3504 return GDK_PIXBUF (info->icon_list->data);
3509 /* Load pixbuf, printing warning on failure if error == NULL
3512 load_pixbuf_verbosely (const char *filename,
3515 GError *local_err = NULL;
3518 pixbuf = gdk_pixbuf_new_from_file (filename, &local_err);
3526 g_warning ("Error loading icon from file '%s':\n\t%s",
3527 filename, local_err->message);
3528 g_error_free (local_err);
3536 * gtk_window_set_icon_from_file:
3537 * @window: a #GtkWindow
3538 * @filename: location of icon file
3539 * @err: (allow-none): location to store error, or %NULL.
3541 * Sets the icon for @window.
3542 * Warns on failure if @err is %NULL.
3544 * This function is equivalent to calling gtk_window_set_icon()
3545 * with a pixbuf created by loading the image from @filename.
3547 * Returns: %TRUE if setting the icon succeeded.
3552 gtk_window_set_icon_from_file (GtkWindow *window,
3553 const gchar *filename,
3556 GdkPixbuf *pixbuf = load_pixbuf_verbosely (filename, err);
3560 gtk_window_set_icon (window, pixbuf);
3561 g_object_unref (pixbuf);
3570 * gtk_window_set_default_icon_list:
3571 * @list: (element-type GdkPixbuf) (transfer container): a list of #GdkPixbuf
3573 * Sets an icon list to be used as fallback for windows that haven't
3574 * had gtk_window_set_icon_list() called on them to set up a
3575 * window-specific icon list. This function allows you to set up the
3576 * icon for all windows in your app at once.
3578 * See gtk_window_set_icon_list() for more details.
3582 gtk_window_set_default_icon_list (GList *list)
3586 if (list == default_icon_list)
3589 /* Update serial so we don't used cached pixmaps/masks
3591 default_icon_serial++;
3593 g_list_foreach (list,
3594 (GFunc) g_object_ref, NULL);
3596 g_list_foreach (default_icon_list,
3597 (GFunc) g_object_unref, NULL);
3599 g_list_free (default_icon_list);
3601 default_icon_list = g_list_copy (list);
3603 /* Update all toplevels */
3604 toplevels = gtk_window_list_toplevels ();
3605 tmp_list = toplevels;
3606 while (tmp_list != NULL)
3608 GtkWindowIconInfo *info;
3609 GtkWindow *w = tmp_list->data;
3611 info = get_icon_info (w);
3612 if (info && info->using_default_icon)
3614 gtk_window_unrealize_icon (w);
3615 if (gtk_widget_get_realized (GTK_WIDGET (w)))
3616 gtk_window_realize_icon (w);
3619 tmp_list = tmp_list->next;
3621 g_list_free (toplevels);
3625 * gtk_window_set_default_icon:
3628 * Sets an icon to be used as fallback for windows that haven't
3629 * had gtk_window_set_icon() called on them from a pixbuf.
3634 gtk_window_set_default_icon (GdkPixbuf *icon)
3638 g_return_if_fail (GDK_IS_PIXBUF (icon));
3640 list = g_list_prepend (NULL, icon);
3641 gtk_window_set_default_icon_list (list);
3646 * gtk_window_set_default_icon_name:
3647 * @name: the name of the themed icon
3649 * Sets an icon to be used as fallback for windows that haven't
3650 * had gtk_window_set_icon_list() called on them from a named
3651 * themed icon, see gtk_window_set_icon_name().
3656 gtk_window_set_default_icon_name (const gchar *name)
3661 /* Update serial so we don't used cached pixmaps/masks
3663 default_icon_serial++;
3665 g_free (default_icon_name);
3666 default_icon_name = g_strdup (name);
3668 g_list_foreach (default_icon_list,
3669 (GFunc) g_object_unref, NULL);
3671 g_list_free (default_icon_list);
3672 default_icon_list = NULL;
3674 /* Update all toplevels */
3675 toplevels = gtk_window_list_toplevels ();
3676 tmp_list = toplevels;
3677 while (tmp_list != NULL)
3679 GtkWindowIconInfo *info;
3680 GtkWindow *w = tmp_list->data;
3682 info = get_icon_info (w);
3683 if (info && info->using_default_icon && info->using_themed_icon)
3685 gtk_window_unrealize_icon (w);
3686 if (gtk_widget_get_realized (GTK_WIDGET (w)))
3687 gtk_window_realize_icon (w);
3690 tmp_list = tmp_list->next;
3692 g_list_free (toplevels);
3696 * gtk_window_get_default_icon_name:
3698 * Returns the fallback icon name for windows that has been set
3699 * with gtk_window_set_default_icon_name(). The returned
3700 * string is owned by GTK+ and should not be modified. It
3701 * is only valid until the next call to
3702 * gtk_window_set_default_icon_name().
3704 * Returns: the fallback icon name for windows
3709 gtk_window_get_default_icon_name (void)
3711 return default_icon_name;
3715 * gtk_window_set_default_icon_from_file:
3716 * @filename: location of icon file
3717 * @err: (allow-none): location to store error, or %NULL.
3719 * Sets an icon to be used as fallback for windows that haven't
3720 * had gtk_window_set_icon_list() called on them from a file
3721 * on disk. Warns on failure if @err is %NULL.
3723 * Returns: %TRUE if setting the icon succeeded.
3728 gtk_window_set_default_icon_from_file (const gchar *filename,
3731 GdkPixbuf *pixbuf = load_pixbuf_verbosely (filename, err);
3735 gtk_window_set_default_icon (pixbuf);
3736 g_object_unref (pixbuf);
3745 * gtk_window_get_default_icon_list:
3747 * Gets the value set by gtk_window_set_default_icon_list().
3748 * The list is a copy and should be freed with g_list_free(),
3749 * but the pixbufs in the list have not had their reference count
3752 * Return value: (element-type GdkPixbuf) (transfer container): copy of default icon list
3755 gtk_window_get_default_icon_list (void)
3757 return g_list_copy (default_icon_list);
3761 gtk_window_set_default_size_internal (GtkWindow *window,
3762 gboolean change_width,
3764 gboolean change_height,
3766 gboolean is_geometry)
3768 GtkWindowGeometryInfo *info;
3770 g_return_if_fail (change_width == FALSE || width >= -1);
3771 g_return_if_fail (change_height == FALSE || height >= -1);
3773 info = gtk_window_get_geometry_info (window, TRUE);
3775 g_object_freeze_notify (G_OBJECT (window));
3777 info->default_is_geometry = is_geometry != FALSE;
3787 info->default_width = width;
3789 g_object_notify (G_OBJECT (window), "default-width");
3800 info->default_height = height;
3802 g_object_notify (G_OBJECT (window), "default-height");
3805 g_object_thaw_notify (G_OBJECT (window));
3807 gtk_widget_queue_resize_no_redraw (GTK_WIDGET (window));
3811 * gtk_window_set_default_size:
3812 * @window: a #GtkWindow
3813 * @width: width in pixels, or -1 to unset the default width
3814 * @height: height in pixels, or -1 to unset the default height
3816 * Sets the default size of a window. If the window's "natural" size
3817 * (its size request) is larger than the default, the default will be
3818 * ignored. More generally, if the default size does not obey the
3819 * geometry hints for the window (gtk_window_set_geometry_hints() can
3820 * be used to set these explicitly), the default size will be clamped
3821 * to the nearest permitted size.
3823 * Unlike gtk_widget_set_size_request(), which sets a size request for
3824 * a widget and thus would keep users from shrinking the window, this
3825 * function only sets the initial size, just as if the user had
3826 * resized the window themselves. Users can still shrink the window
3827 * again as they normally would. Setting a default size of -1 means to
3828 * use the "natural" default size (the size request of the window).
3830 * For more control over a window's initial size and how resizing works,
3831 * investigate gtk_window_set_geometry_hints().
3833 * For some uses, gtk_window_resize() is a more appropriate function.
3834 * gtk_window_resize() changes the current size of the window, rather
3835 * than the size to be used on initial display. gtk_window_resize() always
3836 * affects the window itself, not the geometry widget.
3838 * The default size of a window only affects the first time a window is
3839 * shown; if a window is hidden and re-shown, it will remember the size
3840 * it had prior to hiding, rather than using the default size.
3842 * Windows can't actually be 0x0 in size, they must be at least 1x1, but
3843 * passing 0 for @width and @height is OK, resulting in a 1x1 default size.
3846 gtk_window_set_default_size (GtkWindow *window,
3850 g_return_if_fail (GTK_IS_WINDOW (window));
3851 g_return_if_fail (width >= -1);
3852 g_return_if_fail (height >= -1);
3854 gtk_window_set_default_size_internal (window, TRUE, width, TRUE, height, FALSE);
3858 * gtk_window_get_default_size:
3859 * @window: a #GtkWindow
3860 * @width: (out) (allow-none): location to store the default width, or %NULL
3861 * @height: (out) (allow-none): location to store the default height, or %NULL
3863 * Gets the default size of the window. A value of -1 for the width or
3864 * height indicates that a default size has not been explicitly set
3865 * for that dimension, so the "natural" size of the window will be
3870 gtk_window_get_default_size (GtkWindow *window,
3874 GtkWindowGeometryInfo *info;
3876 g_return_if_fail (GTK_IS_WINDOW (window));
3878 info = gtk_window_get_geometry_info (window, FALSE);
3881 *width = info ? info->default_width : -1;
3884 *height = info ? info->default_height : -1;
3888 * gtk_window_resize:
3889 * @window: a #GtkWindow
3890 * @width: width in pixels to resize the window to
3891 * @height: height in pixels to resize the window to
3893 * Resizes the window as if the user had done so, obeying geometry
3894 * constraints. The default geometry constraint is that windows may
3895 * not be smaller than their size request; to override this
3896 * constraint, call gtk_widget_set_size_request() to set the window's
3897 * request to a smaller value.
3899 * If gtk_window_resize() is called before showing a window for the
3900 * first time, it overrides any default size set with
3901 * gtk_window_set_default_size().
3903 * Windows may not be resized smaller than 1 by 1 pixels.
3907 gtk_window_resize (GtkWindow *window,
3911 GtkWindowGeometryInfo *info;
3913 g_return_if_fail (GTK_IS_WINDOW (window));
3914 g_return_if_fail (width > 0);
3915 g_return_if_fail (height > 0);
3917 info = gtk_window_get_geometry_info (window, TRUE);
3919 info->resize_width = width;
3920 info->resize_height = height;
3922 gtk_widget_queue_resize_no_redraw (GTK_WIDGET (window));
3926 * gtk_window_get_size:
3927 * @window: a #GtkWindow
3928 * @width: (out) (allow-none): return location for width, or %NULL
3929 * @height: (out) (allow-none): return location for height, or %NULL
3931 * Obtains the current size of @window. If @window is not onscreen,
3932 * it returns the size GTK+ will suggest to the <link
3933 * linkend="gtk-X11-arch">window manager</link> for the initial window
3934 * size (but this is not reliably the same as the size the window
3935 * manager will actually select). The size obtained by
3936 * gtk_window_get_size() is the last size received in a
3937 * #GdkEventConfigure, that is, GTK+ uses its locally-stored size,
3938 * rather than querying the X server for the size. As a result, if you
3939 * call gtk_window_resize() then immediately call
3940 * gtk_window_get_size(), the size won't have taken effect yet. After
3941 * the window manager processes the resize request, GTK+ receives
3942 * notification that the size has changed via a configure event, and
3943 * the size of the window gets updated.
3945 * Note 1: Nearly any use of this function creates a race condition,
3946 * because the size of the window may change between the time that you
3947 * get the size and the time that you perform some action assuming
3948 * that size is the current size. To avoid race conditions, connect to
3949 * "configure-event" on the window and adjust your size-dependent
3950 * state to match the size delivered in the #GdkEventConfigure.
3952 * Note 2: The returned size does <emphasis>not</emphasis> include the
3953 * size of the window manager decorations (aka the window frame or
3954 * border). Those are not drawn by GTK+ and GTK+ has no reliable
3955 * method of determining their size.
3957 * Note 3: If you are getting a window size in order to position
3958 * the window onscreen, there may be a better way. The preferred
3959 * way is to simply set the window's semantic type with
3960 * gtk_window_set_type_hint(), which allows the window manager to
3961 * e.g. center dialogs. Also, if you set the transient parent of
3962 * dialogs with gtk_window_set_transient_for() window managers
3963 * will often center the dialog over its parent window. It's
3964 * much preferred to let the window manager handle these
3965 * things rather than doing it yourself, because all apps will
3966 * behave consistently and according to user prefs if the window
3967 * manager handles it. Also, the window manager can take the size
3968 * of the window decorations/border into account, while your
3969 * application cannot.
3971 * In any case, if you insist on application-specified window
3972 * positioning, there's <emphasis>still</emphasis> a better way than
3973 * doing it yourself - gtk_window_set_position() will frequently
3974 * handle the details for you.
3978 gtk_window_get_size (GtkWindow *window,
3984 g_return_if_fail (GTK_IS_WINDOW (window));
3986 if (width == NULL && height == NULL)
3989 if (gtk_widget_get_mapped (GTK_WIDGET (window)))
3991 w = gdk_window_get_width (gtk_widget_get_window (GTK_WIDGET (window)));
3992 h = gdk_window_get_height (gtk_widget_get_window (GTK_WIDGET (window)));
3996 GdkRectangle configure_request;
3998 gtk_window_compute_configure_request (window,
4002 w = configure_request.width;
4003 h = configure_request.height;
4014 * @window: a #GtkWindow
4015 * @x: X coordinate to move window to
4016 * @y: Y coordinate to move window to
4018 * Asks the <link linkend="gtk-X11-arch">window manager</link> to move
4019 * @window to the given position. Window managers are free to ignore
4020 * this; most window managers ignore requests for initial window
4021 * positions (instead using a user-defined placement algorithm) and
4022 * honor requests after the window has already been shown.
4024 * Note: the position is the position of the gravity-determined
4025 * reference point for the window. The gravity determines two things:
4026 * first, the location of the reference point in root window
4027 * coordinates; and second, which point on the window is positioned at
4028 * the reference point.
4030 * By default the gravity is #GDK_GRAVITY_NORTH_WEST, so the reference
4031 * point is simply the @x, @y supplied to gtk_window_move(). The
4032 * top-left corner of the window decorations (aka window frame or
4033 * border) will be placed at @x, @y. Therefore, to position a window
4034 * at the top left of the screen, you want to use the default gravity
4035 * (which is #GDK_GRAVITY_NORTH_WEST) and move the window to 0,0.
4037 * To position a window at the bottom right corner of the screen, you
4038 * would set #GDK_GRAVITY_SOUTH_EAST, which means that the reference
4039 * point is at @x + the window width and @y + the window height, and
4040 * the bottom-right corner of the window border will be placed at that
4041 * reference point. So, to place a window in the bottom right corner
4042 * you would first set gravity to south east, then write:
4043 * <literal>gtk_window_move (window, gdk_screen_width () - window_width,
4044 * gdk_screen_height () - window_height)</literal> (note that this
4045 * example does not take multi-head scenarios into account).
4047 * The Extended Window Manager Hints specification at <ulink
4048 * url="http://www.freedesktop.org/Standards/wm-spec">
4049 * http://www.freedesktop.org/Standards/wm-spec</ulink> has a
4050 * nice table of gravities in the "implementation notes" section.
4052 * The gtk_window_get_position() documentation may also be relevant.
4055 gtk_window_move (GtkWindow *window,
4059 GtkWindowPrivate *priv;
4060 GtkWindowGeometryInfo *info;
4063 g_return_if_fail (GTK_IS_WINDOW (window));
4065 priv = window->priv;
4066 widget = GTK_WIDGET (window);
4068 info = gtk_window_get_geometry_info (window, TRUE);
4070 if (gtk_widget_get_mapped (widget))
4072 GtkAllocation allocation;
4074 gtk_widget_get_allocation (widget, &allocation);
4076 /* we have now sent a request with this position
4077 * with currently-active constraints, so toggle flag.
4079 info->position_constraints_changed = FALSE;
4081 /* we only constrain if mapped - if not mapped,
4082 * then gtk_window_compute_configure_request()
4083 * will apply the constraints later, and we
4084 * don't want to lose information about
4085 * what position the user set before then.
4086 * i.e. if you do a move() then turn off POS_CENTER
4087 * then show the window, your move() will work.
4089 gtk_window_constrain_position (window,
4090 allocation.width, allocation.height,
4093 /* Note that this request doesn't go through our standard request
4094 * framework, e.g. doesn't increment configure_request_count,
4095 * doesn't set info->last, etc.; that's because
4096 * we don't save the info needed to arrive at this same request
4099 * To gtk_window_move_resize(), this will end up looking exactly
4100 * the same as the position being changed by the window
4104 /* FIXME are we handling gravity properly for framed windows? */
4106 gdk_window_move (priv->frame,
4107 x - priv->frame_left,
4108 y - priv->frame_top);
4110 gdk_window_move (gtk_widget_get_window (GTK_WIDGET (window)),
4115 /* Save this position to apply on mapping */
4116 info->initial_x = x;
4117 info->initial_y = y;
4118 info->initial_pos_set = TRUE;
4123 * gtk_window_get_position:
4124 * @window: a #GtkWindow
4125 * @root_x: (out): return location for X coordinate of gravity-determined reference point
4126 * @root_y: (out): return location for Y coordinate of gravity-determined reference point
4128 * This function returns the position you need to pass to
4129 * gtk_window_move() to keep @window in its current position. This
4130 * means that the meaning of the returned value varies with window
4131 * gravity. See gtk_window_move() for more details.
4133 * If you haven't changed the window gravity, its gravity will be
4134 * #GDK_GRAVITY_NORTH_WEST. This means that gtk_window_get_position()
4135 * gets the position of the top-left corner of the window manager
4136 * frame for the window. gtk_window_move() sets the position of this
4137 * same top-left corner.
4139 * gtk_window_get_position() is not 100% reliable because the X Window System
4140 * does not specify a way to obtain the geometry of the
4141 * decorations placed on a window by the window manager.
4142 * Thus GTK+ is using a "best guess" that works with most
4145 * Moreover, nearly all window managers are historically broken with
4146 * respect to their handling of window gravity. So moving a window to
4147 * its current position as returned by gtk_window_get_position() tends
4148 * to result in moving the window slightly. Window managers are
4149 * slowly getting better over time.
4151 * If a window has gravity #GDK_GRAVITY_STATIC the window manager
4152 * frame is not relevant, and thus gtk_window_get_position() will
4153 * always produce accurate results. However you can't use static
4154 * gravity to do things like place a window in a corner of the screen,
4155 * because static gravity ignores the window manager decorations.
4157 * If you are saving and restoring your application's window
4158 * positions, you should know that it's impossible for applications to
4159 * do this without getting it somewhat wrong because applications do
4160 * not have sufficient knowledge of window manager state. The Correct
4161 * Mechanism is to support the session management protocol (see the
4162 * "GnomeClient" object in the GNOME libraries for example) and allow
4163 * the window manager to save your window sizes and positions.
4168 gtk_window_get_position (GtkWindow *window,
4172 GtkWindowPrivate *priv;
4174 GdkWindow *gdk_window;
4176 g_return_if_fail (GTK_IS_WINDOW (window));
4178 priv = window->priv;
4179 widget = GTK_WIDGET (window);
4180 gdk_window = gtk_widget_get_window (widget);
4182 if (priv->gravity == GDK_GRAVITY_STATIC)
4184 if (gtk_widget_get_mapped (widget))
4186 /* This does a server round-trip, which is sort of wrong;
4187 * but a server round-trip is inevitable for
4188 * gdk_window_get_frame_extents() in the usual
4189 * NorthWestGravity case below, so not sure what else to
4190 * do. We should likely be consistent about whether we get
4191 * the client-side info or the server-side info.
4193 gdk_window_get_origin (gdk_window, root_x, root_y);
4197 GdkRectangle configure_request;
4199 gtk_window_compute_configure_request (window,
4203 *root_x = configure_request.x;
4204 *root_y = configure_request.y;
4209 GdkRectangle frame_extents;
4214 if (gtk_widget_get_mapped (widget))
4217 gdk_window_get_frame_extents (priv->frame, &frame_extents);
4219 gdk_window_get_frame_extents (gdk_window, &frame_extents);
4220 x = frame_extents.x;
4221 y = frame_extents.y;
4222 gtk_window_get_size (window, &w, &h);
4226 /* We just say the frame has 0 size on all sides.
4227 * Not sure what else to do.
4229 gtk_window_compute_configure_request (window,
4232 x = frame_extents.x;
4233 y = frame_extents.y;
4234 w = frame_extents.width;
4235 h = frame_extents.height;
4238 switch (priv->gravity)
4240 case GDK_GRAVITY_NORTH:
4241 case GDK_GRAVITY_CENTER:
4242 case GDK_GRAVITY_SOUTH:
4243 /* Find center of frame. */
4244 x += frame_extents.width / 2;
4245 /* Center client window on that point. */
4249 case GDK_GRAVITY_SOUTH_EAST:
4250 case GDK_GRAVITY_EAST:
4251 case GDK_GRAVITY_NORTH_EAST:
4252 /* Find right edge of frame */
4253 x += frame_extents.width;
4254 /* Align left edge of client at that point. */
4261 switch (priv->gravity)
4263 case GDK_GRAVITY_WEST:
4264 case GDK_GRAVITY_CENTER:
4265 case GDK_GRAVITY_EAST:
4266 /* Find center of frame. */
4267 y += frame_extents.height / 2;
4268 /* Center client window there. */
4271 case GDK_GRAVITY_SOUTH_WEST:
4272 case GDK_GRAVITY_SOUTH:
4273 case GDK_GRAVITY_SOUTH_EAST:
4274 /* Find south edge of frame */
4275 y += frame_extents.height;
4276 /* Place bottom edge of client there */
4291 * gtk_window_reshow_with_initial_size:
4292 * @window: a #GtkWindow
4294 * Hides @window, then reshows it, resetting the
4295 * default size and position of the window. Used
4296 * by GUI builders only.
4299 gtk_window_reshow_with_initial_size (GtkWindow *window)
4303 g_return_if_fail (GTK_IS_WINDOW (window));
4305 widget = GTK_WIDGET (window);
4307 gtk_widget_hide (widget);
4308 gtk_widget_unrealize (widget);
4309 gtk_widget_show (widget);
4313 gtk_window_destroy (GtkObject *object)
4315 GtkWindow *window = GTK_WINDOW (object);
4316 GtkWindowPrivate *priv = window->priv;
4318 toplevel_list = g_slist_remove (toplevel_list, window);
4320 if (priv->transient_parent)
4321 gtk_window_set_transient_for (window, NULL);
4323 /* frees the icons */
4324 gtk_window_set_icon_list (window, NULL);
4326 if (priv->has_user_ref_count)
4328 priv->has_user_ref_count = FALSE;
4329 g_object_unref (window);
4333 gtk_window_group_remove_window (priv->group, window);
4335 gtk_window_free_key_hash (window);
4337 GTK_OBJECT_CLASS (gtk_window_parent_class)->destroy (object);
4341 gtk_window_finalize (GObject *object)
4343 GtkWindow *window = GTK_WINDOW (object);
4344 GtkWindowPrivate *priv = window->priv;
4345 GtkMnemonicHash *mnemonic_hash;
4347 g_free (priv->title);
4348 g_free (priv->wmclass_name);
4349 g_free (priv->wmclass_class);
4350 g_free (priv->wm_role);
4352 mnemonic_hash = gtk_window_get_mnemonic_hash (window, FALSE);
4354 _gtk_mnemonic_hash_free (mnemonic_hash);
4356 if (priv->geometry_info)
4358 if (priv->geometry_info->widget)
4359 g_signal_handlers_disconnect_by_func (priv->geometry_info->widget,
4360 gtk_widget_destroyed,
4361 &priv->geometry_info->widget);
4362 g_free (priv->geometry_info);
4365 if (priv->keys_changed_handler)
4367 g_source_remove (priv->keys_changed_handler);
4368 priv->keys_changed_handler = 0;
4372 g_signal_handlers_disconnect_by_func (gdk_visual_get_screen (priv->visual),
4373 gtk_window_on_composited_changed, window);
4375 g_free (priv->startup_id);
4377 G_OBJECT_CLASS (gtk_window_parent_class)->finalize (object);
4381 gtk_window_show (GtkWidget *widget)
4383 GtkWindow *window = GTK_WINDOW (widget);
4384 GtkWindowPrivate *priv = window->priv;
4385 GtkContainer *container = GTK_CONTAINER (window);
4386 gboolean need_resize;
4388 GTK_WIDGET_SET_FLAGS (widget, GTK_VISIBLE);
4390 need_resize = _gtk_container_get_need_resize (container) || !gtk_widget_get_realized (widget);
4391 _gtk_container_set_need_resize (container, FALSE);
4395 GtkWindowGeometryInfo *info = gtk_window_get_geometry_info (window, TRUE);
4396 GtkAllocation allocation = { 0, 0 };
4397 GdkRectangle configure_request;
4398 GdkGeometry new_geometry;
4400 gboolean was_realized;
4402 /* We are going to go ahead and perform this configure request
4403 * and then emulate a configure notify by going ahead and
4404 * doing a size allocate. Sort of a synchronous
4405 * mini-copy of gtk_window_move_resize() here.
4407 gtk_window_compute_configure_request (window,
4412 /* We update this because we are going to go ahead
4413 * and gdk_window_resize() below, rather than
4416 info->last.configure_request.width = configure_request.width;
4417 info->last.configure_request.height = configure_request.height;
4419 /* and allocate the window - this is normally done
4420 * in move_resize in response to configure notify
4422 allocation.width = configure_request.width;
4423 allocation.height = configure_request.height;
4424 gtk_widget_size_allocate (widget, &allocation);
4426 /* Then we guarantee we have a realize */
4427 was_realized = FALSE;
4428 if (!gtk_widget_get_realized (widget))
4430 gtk_widget_realize (widget);
4431 was_realized = TRUE;
4434 /* Must be done after the windows are realized,
4435 * so that the decorations can be read
4437 gtk_decorated_window_calculate_frame_size (window);
4439 /* We only send configure request if we didn't just finish
4440 * creating the window; if we just created the window
4441 * then we created it with widget->allocation anyhow.
4444 gdk_window_move_resize (gtk_widget_get_window (widget),
4445 configure_request.x,
4446 configure_request.y,
4447 configure_request.width,
4448 configure_request.height);
4451 gtk_container_check_resize (container);
4453 gtk_widget_map (widget);
4455 /* Try to make sure that we have some focused widget
4457 if (!priv->focus_widget && !GTK_IS_PLUG (window))
4458 gtk_window_move_focus (window, GTK_DIR_TAB_FORWARD);
4461 gtk_grab_add (widget);
4465 gtk_window_hide (GtkWidget *widget)
4467 GtkWindow *window = GTK_WINDOW (widget);
4468 GtkWindowPrivate *priv = window->priv;
4470 GTK_WIDGET_UNSET_FLAGS (widget, GTK_VISIBLE);
4471 gtk_widget_unmap (widget);
4474 gtk_grab_remove (widget);
4478 gtk_window_map (GtkWidget *widget)
4481 GtkWindow *window = GTK_WINDOW (widget);
4482 GtkWindowPrivate *priv = window->priv;
4483 GdkWindow *toplevel;
4484 GdkWindow *gdk_window;
4485 gboolean auto_mnemonics;
4487 gdk_window = gtk_widget_get_window (widget);
4489 gtk_widget_set_mapped (widget, TRUE);
4491 child = gtk_bin_get_child (&(window->bin));
4493 gtk_widget_get_visible (child) &&
4494 !gtk_widget_get_mapped (child))
4495 gtk_widget_map (child);
4498 toplevel = priv->frame;
4500 toplevel = gdk_window;
4502 if (priv->maximize_initially)
4503 gdk_window_maximize (toplevel);
4505 gdk_window_unmaximize (toplevel);
4507 if (priv->stick_initially)
4508 gdk_window_stick (toplevel);
4510 gdk_window_unstick (toplevel);
4512 if (priv->iconify_initially)
4513 gdk_window_iconify (toplevel);
4515 gdk_window_deiconify (toplevel);
4517 if (priv->fullscreen_initially)
4518 gdk_window_fullscreen (toplevel);
4520 gdk_window_unfullscreen (toplevel);
4522 gdk_window_set_keep_above (toplevel, priv->above_initially);
4524 gdk_window_set_keep_below (toplevel, priv->below_initially);
4526 /* No longer use the default settings */
4527 priv->need_default_size = FALSE;
4528 priv->need_default_position = FALSE;
4530 if (priv->reset_type_hint)
4532 /* We should only reset the type hint when the application
4533 * used gtk_window_set_type_hint() to change the hint.
4534 * Some applications use X directly to change the properties;
4535 * in that case, we shouldn't overwrite what they did.
4537 gdk_window_set_type_hint (gdk_window, priv->type_hint);
4538 priv->reset_type_hint = FALSE;
4541 gdk_window_show (gdk_window);
4544 gdk_window_show (priv->frame);
4546 if (!disable_startup_notification)
4548 /* Do we have a custom startup-notification id? */
4549 if (priv->startup_id != NULL)
4551 /* Make sure we have a "real" id */
4552 if (!startup_id_is_fake (priv->startup_id))
4553 gdk_notify_startup_complete_with_id (priv->startup_id);
4555 g_free (priv->startup_id);
4556 priv->startup_id = NULL;
4558 else if (!sent_startup_notification)
4560 sent_startup_notification = TRUE;
4561 gdk_notify_startup_complete ();
4565 /* if auto-mnemonics is enabled and mnemonics visible is not already set
4566 * (as in the case of popup menus), then hide mnemonics initially
4568 g_object_get (gtk_widget_get_settings (widget), "gtk-auto-mnemonics",
4569 &auto_mnemonics, NULL);
4570 if (auto_mnemonics && !priv->mnemonics_visible_set)
4571 gtk_window_set_mnemonics_visible (window, FALSE);
4575 gtk_window_map_event (GtkWidget *widget,
4578 if (!gtk_widget_get_mapped (widget))
4580 /* we should be be unmapped, but are getting a MapEvent, this may happen
4581 * to toplevel XWindows if mapping was intercepted by a window manager
4582 * and an unmap request occoured while the MapRequestEvent was still
4583 * being handled. we work around this situaiton here by re-requesting
4584 * the window being unmapped. more details can be found in:
4585 * http://bugzilla.gnome.org/show_bug.cgi?id=316180
4587 gdk_window_hide (gtk_widget_get_window (widget));
4593 gtk_window_unmap (GtkWidget *widget)
4595 GtkWindow *window = GTK_WINDOW (widget);
4596 GtkWindowPrivate *priv = window->priv;
4597 GtkWindowGeometryInfo *info;
4598 GdkWindow *gdk_window;
4599 GdkWindowState state;
4601 gdk_window = gtk_widget_get_window (widget);
4603 gtk_widget_set_mapped (widget, FALSE);
4605 gdk_window_withdraw (priv->frame);
4607 gdk_window_withdraw (gdk_window);
4609 priv->configure_request_count = 0;
4610 priv->configure_notify_received = FALSE;
4612 /* on unmap, we reset the default positioning of the window,
4613 * so it's placed again, but we don't reset the default
4614 * size of the window, so it's remembered.
4616 priv->need_default_position = TRUE;
4618 info = gtk_window_get_geometry_info (window, FALSE);
4621 info->initial_pos_set = FALSE;
4622 info->position_constraints_changed = FALSE;
4625 state = gdk_window_get_state (gdk_window);
4626 priv->iconify_initially = (state & GDK_WINDOW_STATE_ICONIFIED) != 0;
4627 priv->maximize_initially = (state & GDK_WINDOW_STATE_MAXIMIZED) != 0;
4628 priv->stick_initially = (state & GDK_WINDOW_STATE_STICKY) != 0;
4629 priv->above_initially = (state & GDK_WINDOW_STATE_ABOVE) != 0;
4630 priv->below_initially = (state & GDK_WINDOW_STATE_BELOW) != 0;
4634 gtk_window_realize (GtkWidget *widget)
4636 GtkAllocation allocation;
4639 GdkWindow *parent_window;
4640 GdkWindow *gdk_window;
4641 GdkWindowAttr attributes;
4642 gint attributes_mask;
4643 GtkWindowPrivate *priv;
4645 window = GTK_WINDOW (widget);
4646 priv = window->priv;
4648 gtk_widget_get_allocation (widget, &allocation);
4650 /* ensure widget tree is properly size allocated */
4651 if (allocation.x == -1 &&
4652 allocation.y == -1 &&
4653 allocation.width == 1 &&
4654 allocation.height == 1)
4656 GtkRequisition requisition;
4657 GtkAllocation allocation = { 0, 0, 200, 200 };
4659 gtk_widget_get_preferred_size (widget, &requisition, NULL);
4660 if (requisition.width || requisition.height)
4662 /* non-empty window */
4663 allocation.width = requisition.width;
4664 allocation.height = requisition.height;
4666 gtk_widget_size_allocate (widget, &allocation);
4668 _gtk_container_queue_resize (GTK_CONTAINER (widget));
4670 g_return_if_fail (!gtk_widget_get_realized (widget));
4673 gtk_widget_set_realized (widget, TRUE);
4677 case GTK_WINDOW_TOPLEVEL:
4678 attributes.window_type = GDK_WINDOW_TOPLEVEL;
4680 case GTK_WINDOW_POPUP:
4681 attributes.window_type = GDK_WINDOW_TEMP;
4684 g_warning (G_STRLOC": Unknown window type %d!", priv->type);
4688 attributes.title = priv->title;
4689 attributes.wmclass_name = priv->wmclass_name;
4690 attributes.wmclass_class = priv->wmclass_class;
4691 attributes.wclass = GDK_INPUT_OUTPUT;
4692 attributes.visual = gtk_widget_get_visual (widget);
4694 if (priv->has_frame)
4696 gtk_widget_get_allocation (widget, &allocation);
4697 attributes.width = allocation.width + priv->frame_left + priv->frame_right;
4698 attributes.height = allocation.height + priv->frame_top + priv->frame_bottom;
4699 attributes.event_mask = (GDK_EXPOSURE_MASK |
4700 GDK_KEY_PRESS_MASK |
4701 GDK_ENTER_NOTIFY_MASK |
4702 GDK_LEAVE_NOTIFY_MASK |
4703 GDK_FOCUS_CHANGE_MASK |
4704 GDK_STRUCTURE_MASK |
4705 GDK_BUTTON_MOTION_MASK |
4706 GDK_POINTER_MOTION_HINT_MASK |
4707 GDK_BUTTON_PRESS_MASK |
4708 GDK_BUTTON_RELEASE_MASK);
4710 attributes_mask = GDK_WA_VISUAL;
4712 priv->frame = gdk_window_new (gtk_widget_get_root_window (widget),
4713 &attributes, attributes_mask);
4715 if (priv->opacity_set)
4716 gdk_window_set_opacity (priv->frame, priv->opacity);
4718 gdk_window_set_user_data (priv->frame, widget);
4720 attributes.window_type = GDK_WINDOW_CHILD;
4721 attributes.x = priv->frame_left;
4722 attributes.y = priv->frame_top;
4724 attributes_mask = GDK_WA_X | GDK_WA_Y;
4726 parent_window = priv->frame;
4728 g_signal_connect (window,
4730 G_CALLBACK (gtk_window_event),
4735 attributes_mask = 0;
4736 parent_window = gtk_widget_get_root_window (widget);
4739 gtk_widget_get_allocation (widget, &allocation);
4740 attributes.width = allocation.width;
4741 attributes.height = allocation.height;
4742 attributes.event_mask = gtk_widget_get_events (widget);
4743 attributes.event_mask |= (GDK_EXPOSURE_MASK |
4744 GDK_KEY_PRESS_MASK |
4745 GDK_KEY_RELEASE_MASK |
4746 GDK_ENTER_NOTIFY_MASK |
4747 GDK_LEAVE_NOTIFY_MASK |
4748 GDK_FOCUS_CHANGE_MASK |
4749 GDK_STRUCTURE_MASK);
4750 attributes.type_hint = priv->type_hint;
4752 attributes_mask |= GDK_WA_VISUAL | GDK_WA_TYPE_HINT;
4753 attributes_mask |= (priv->title ? GDK_WA_TITLE : 0);
4754 attributes_mask |= (priv->wmclass_name ? GDK_WA_WMCLASS : 0);
4756 gdk_window = gdk_window_new (parent_window, &attributes, attributes_mask);
4757 gtk_widget_set_window (widget, gdk_window);
4759 if (!priv->has_frame && priv->opacity_set)
4760 gdk_window_set_opacity (gdk_window, priv->opacity);
4762 gdk_window_enable_synchronized_configure (gdk_window);
4764 gdk_window_set_user_data (gdk_window, window);
4766 gtk_widget_style_attach (widget);
4767 style = gtk_widget_get_style (widget);
4768 gtk_style_set_background (style, gdk_window, GTK_STATE_NORMAL);
4770 gtk_style_set_background (style, priv->frame, GTK_STATE_NORMAL);
4772 if (priv->transient_parent &&
4773 gtk_widget_get_realized (GTK_WIDGET (priv->transient_parent)))
4774 gdk_window_set_transient_for (gdk_window,
4775 gtk_widget_get_window (GTK_WIDGET (priv->transient_parent)));
4778 gdk_window_set_role (gdk_window, priv->wm_role);
4780 if (!priv->decorated)
4781 gdk_window_set_decorations (gdk_window, 0);
4783 if (!priv->deletable)
4784 gdk_window_set_functions (gdk_window, GDK_FUNC_ALL | GDK_FUNC_CLOSE);
4786 if (gtk_window_get_skip_pager_hint (window))
4787 gdk_window_set_skip_pager_hint (gdk_window, TRUE);
4789 if (gtk_window_get_skip_taskbar_hint (window))
4790 gdk_window_set_skip_taskbar_hint (gdk_window, TRUE);
4792 if (gtk_window_get_accept_focus (window))
4793 gdk_window_set_accept_focus (gdk_window, TRUE);
4795 gdk_window_set_accept_focus (gdk_window, FALSE);
4797 if (gtk_window_get_focus_on_map (window))
4798 gdk_window_set_focus_on_map (gdk_window, TRUE);
4800 gdk_window_set_focus_on_map (gdk_window, FALSE);
4803 gdk_window_set_modal_hint (gdk_window, TRUE);
4805 gdk_window_set_modal_hint (gdk_window, FALSE);
4807 if (priv->startup_id)
4809 #ifdef GDK_WINDOWING_X11
4810 guint32 timestamp = extract_time_from_startup_id (priv->startup_id);
4811 if (timestamp != GDK_CURRENT_TIME)
4812 gdk_x11_window_set_user_time (gdk_window, timestamp);
4814 if (!startup_id_is_fake (priv->startup_id))
4815 gdk_window_set_startup_id (gdk_window, priv->startup_id);
4819 gtk_window_realize_icon (window);
4823 gtk_window_unrealize (GtkWidget *widget)
4825 GtkWindow *window = GTK_WINDOW (widget);
4826 GtkWindowPrivate *priv = window->priv;
4827 GtkWindowGeometryInfo *info;
4829 /* On unrealize, we reset the size of the window such
4830 * that we will re-apply the default sizing stuff
4831 * next time we show the window.
4833 * Default positioning is reset on unmap, instead of unrealize.
4835 priv->need_default_size = TRUE;
4836 info = gtk_window_get_geometry_info (window, FALSE);
4839 info->resize_width = -1;
4840 info->resize_height = -1;
4841 info->last.configure_request.x = 0;
4842 info->last.configure_request.y = 0;
4843 info->last.configure_request.width = -1;
4844 info->last.configure_request.height = -1;
4845 /* be sure we reset geom hints on re-realize */
4846 info->last.flags = 0;
4851 gdk_window_set_user_data (priv->frame, NULL);
4852 gdk_window_destroy (priv->frame);
4857 gtk_window_unrealize_icon (window);
4859 GTK_WIDGET_CLASS (gtk_window_parent_class)->unrealize (widget);
4863 gtk_window_size_allocate (GtkWidget *widget,
4864 GtkAllocation *allocation)
4866 GtkWindow *window = GTK_WINDOW (widget);
4867 GtkWindowPrivate *priv = window->priv;
4868 GtkAllocation child_allocation;
4872 gtk_widget_set_allocation (widget, allocation);
4874 child = gtk_bin_get_child (&(window->bin));
4875 if (child && gtk_widget_get_visible (child))
4877 border_width = gtk_container_get_border_width (GTK_CONTAINER (window));
4878 child_allocation.x = border_width;
4879 child_allocation.y = border_width;
4880 child_allocation.width =
4881 MAX (1, (gint)allocation->width - child_allocation.x * 2);
4882 child_allocation.height =
4883 MAX (1, (gint)allocation->height - child_allocation.y * 2);
4885 gtk_widget_size_allocate (child, &child_allocation);
4888 if (gtk_widget_get_realized (widget) && priv->frame)
4890 gdk_window_resize (priv->frame,
4891 allocation->width + priv->frame_left + priv->frame_right,
4892 allocation->height + priv->frame_top + priv->frame_bottom);
4897 gtk_window_event (GtkWidget *widget, GdkEvent *event)
4899 GtkWindow *window = GTK_WINDOW (widget);
4900 GtkWindowPrivate *priv = window->priv;
4901 gboolean return_val;
4903 if (priv->frame && (event->any.window == priv->frame))
4905 if ((event->type != GDK_KEY_PRESS) &&
4906 (event->type != GDK_KEY_RELEASE) &&
4907 (event->type != GDK_FOCUS_CHANGE))
4909 g_signal_stop_emission_by_name (widget, "event");
4911 g_signal_emit (widget, window_signals[FRAME_EVENT], 0, event, &return_val);
4916 g_object_unref (event->any.window);
4917 event->any.window = g_object_ref (gtk_widget_get_window (widget));
4925 gtk_window_frame_event (GtkWindow *window, GdkEvent *event)
4927 GtkWindowPrivate *priv = window->priv;
4928 GdkEventConfigure *configure_event;
4931 switch (event->type)
4934 configure_event = (GdkEventConfigure *)event;
4936 /* Invalidate the decorations */
4939 rect.width = configure_event->width;
4940 rect.height = configure_event->height;
4942 gdk_window_invalidate_rect (priv->frame, &rect, FALSE);
4944 /* Pass on the (modified) configure event */
4945 configure_event->width -= priv->frame_left + priv->frame_right;
4946 configure_event->height -= priv->frame_top + priv->frame_bottom;
4947 return gtk_window_configure_event (GTK_WIDGET (window), configure_event);
4956 gtk_window_configure_event (GtkWidget *widget,
4957 GdkEventConfigure *event)
4959 GtkAllocation allocation;
4960 GtkWindow *window = GTK_WINDOW (widget);
4961 GtkWindowPrivate *priv = window->priv;
4962 gboolean expected_reply = priv->configure_request_count > 0;
4964 /* priv->configure_request_count incremented for each
4965 * configure request, and decremented to a min of 0 for
4966 * each configure notify.
4968 * All it means is that we know we will get at least
4969 * priv->configure_request_count more configure notifies.
4970 * We could get more configure notifies than that; some
4971 * of the configure notifies we get may be unrelated to
4972 * the configure requests. But we will get at least
4973 * priv->configure_request_count notifies.
4976 if (priv->configure_request_count > 0)
4978 priv->configure_request_count -= 1;
4979 gdk_window_thaw_toplevel_updates_libgtk_only (gtk_widget_get_window (widget));
4982 /* As an optimization, we avoid a resize when possible.
4984 * The only times we can avoid a resize are:
4985 * - we know only the position changed, not the size
4986 * - we know we have made more requests and so will get more
4987 * notifies and can wait to resize when we get them
4989 gtk_widget_get_allocation (widget, &allocation);
4990 if (!expected_reply &&
4991 (allocation.width == event->width &&
4992 allocation.height == event->height))
4994 gdk_window_configure_finished (gtk_widget_get_window (widget));
4999 * If we do need to resize, we do that by:
5000 * - filling in widget->allocation with the new size
5001 * - setting configure_notify_received to TRUE
5002 * for use in gtk_window_move_resize()
5003 * - queueing a resize, leading to invocation of
5004 * gtk_window_move_resize() in an idle handler
5008 priv->configure_notify_received = TRUE;
5010 allocation.width = event->width;
5011 allocation.height = event->height;
5012 gtk_widget_set_allocation (widget, &allocation);
5014 _gtk_container_queue_resize (GTK_CONTAINER (widget));
5019 /* the accel_key and accel_mods fields of the key have to be setup
5020 * upon calling this function. it'll then return whether that key
5021 * is at all used as accelerator, and if so will OR in the
5022 * accel_flags member of the key.
5025 _gtk_window_query_nonaccels (GtkWindow *window,
5027 GdkModifierType accel_mods)
5029 GtkWindowPrivate *priv;
5031 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
5033 priv = window->priv;
5035 /* movement keys are considered locked accels */
5038 static const guint bindings[] = {
5039 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,
5040 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,
5044 for (i = 0; i < G_N_ELEMENTS (bindings); i++)
5045 if (bindings[i] == accel_key)
5049 /* mnemonics are considered locked accels */
5050 if (accel_mods == priv->mnemonic_modifier)
5052 GtkMnemonicHash *mnemonic_hash = gtk_window_get_mnemonic_hash (window, FALSE);
5053 if (mnemonic_hash && _gtk_mnemonic_hash_lookup (mnemonic_hash, accel_key))
5061 * gtk_window_propagate_key_event:
5062 * @window: a #GtkWindow
5063 * @event: a #GdkEventKey
5065 * Propagate a key press or release event to the focus widget and
5066 * up the focus container chain until a widget handles @event.
5067 * This is normally called by the default ::key_press_event and
5068 * ::key_release_event handlers for toplevel windows,
5069 * however in some cases it may be useful to call this directly when
5070 * overriding the standard key handling for a toplevel window.
5072 * Return value: %TRUE if a widget in the focus chain handled the event.
5077 gtk_window_propagate_key_event (GtkWindow *window,
5080 GtkWindowPrivate *priv;
5081 gboolean handled = FALSE;
5082 GtkWidget *widget, *focus;
5084 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
5086 priv = window->priv;
5087 widget = GTK_WIDGET (window);
5089 focus = priv->focus_widget;
5091 g_object_ref (focus);
5094 focus && focus != widget &&
5095 gtk_widget_get_toplevel (focus) == widget)
5099 if (gtk_widget_is_sensitive (focus))
5100 handled = gtk_widget_event (focus, (GdkEvent*) event);
5102 parent = gtk_widget_get_parent (focus);
5104 g_object_ref (parent);
5106 g_object_unref (focus);
5112 g_object_unref (focus);
5118 gtk_window_key_press_event (GtkWidget *widget,
5121 GtkWindow *window = GTK_WINDOW (widget);
5122 gboolean handled = FALSE;
5124 /* handle mnemonics and accelerators */
5126 handled = gtk_window_activate_key (window, event);
5128 /* handle focus widget key events */
5130 handled = gtk_window_propagate_key_event (window, event);
5132 /* Chain up, invokes binding set */
5134 handled = GTK_WIDGET_CLASS (gtk_window_parent_class)->key_press_event (widget, event);
5140 gtk_window_key_release_event (GtkWidget *widget,
5143 GtkWindow *window = GTK_WINDOW (widget);
5144 gboolean handled = FALSE;
5146 /* handle focus widget key events */
5148 handled = gtk_window_propagate_key_event (window, event);
5150 /* Chain up, invokes binding set */
5152 handled = GTK_WIDGET_CLASS (gtk_window_parent_class)->key_release_event (widget, event);
5158 gtk_window_real_activate_default (GtkWindow *window)
5160 gtk_window_activate_default (window);
5164 gtk_window_real_activate_focus (GtkWindow *window)
5166 gtk_window_activate_focus (window);
5170 gtk_window_move_focus (GtkWindow *window,
5171 GtkDirectionType dir)
5173 gtk_widget_child_focus (GTK_WIDGET (window), dir);
5175 if (!gtk_container_get_focus_child (GTK_CONTAINER (window)))
5176 gtk_window_set_focus (window, NULL);
5180 gtk_window_enter_notify_event (GtkWidget *widget,
5181 GdkEventCrossing *event)
5187 gtk_window_leave_notify_event (GtkWidget *widget,
5188 GdkEventCrossing *event)
5194 do_focus_change (GtkWidget *widget,
5198 GdkDeviceManager *device_manager;
5201 g_object_ref (widget);
5203 device_manager = gdk_display_get_device_manager (gtk_widget_get_display (widget));
5204 devices = gdk_device_manager_list_devices (device_manager, GDK_DEVICE_TYPE_MASTER);
5205 devices = g_list_concat (devices, gdk_device_manager_list_devices (device_manager, GDK_DEVICE_TYPE_SLAVE));
5206 devices = g_list_concat (devices, gdk_device_manager_list_devices (device_manager, GDK_DEVICE_TYPE_FLOATING));
5208 for (d = devices; d; d = d->next)
5210 GdkDevice *dev = d->data;
5213 if (dev->source != GDK_SOURCE_KEYBOARD)
5216 /* Skip non-master keyboards that haven't
5217 * selected for events from this window
5219 window = gtk_widget_get_window (widget);
5220 if (gdk_device_get_device_type (dev) != GDK_DEVICE_TYPE_MASTER &&
5221 window && !gdk_window_get_device_events (window, dev))
5224 fevent = gdk_event_new (GDK_FOCUS_CHANGE);
5226 fevent->focus_change.type = GDK_FOCUS_CHANGE;
5227 fevent->focus_change.window = window;
5229 g_object_ref (window);
5230 fevent->focus_change.in = in;
5231 gdk_event_set_device (fevent, dev);
5233 gtk_widget_send_focus_change (widget, fevent);
5235 gdk_event_free (fevent);
5238 g_list_free (devices);
5239 g_object_unref (widget);
5243 gtk_window_focus_in_event (GtkWidget *widget,
5244 GdkEventFocus *event)
5246 GtkWindow *window = GTK_WINDOW (widget);
5248 /* It appears spurious focus in events can occur when
5249 * the window is hidden. So we'll just check to see if
5250 * the window is visible before actually handling the
5253 if (gtk_widget_get_visible (widget))
5255 _gtk_window_set_has_toplevel_focus (window, TRUE);
5256 _gtk_window_set_is_active (window, TRUE);
5263 gtk_window_focus_out_event (GtkWidget *widget,
5264 GdkEventFocus *event)
5266 GtkWindow *window = GTK_WINDOW (widget);
5267 gboolean auto_mnemonics;
5269 _gtk_window_set_has_toplevel_focus (window, FALSE);
5270 _gtk_window_set_is_active (window, FALSE);
5272 /* set the mnemonic-visible property to false */
5273 g_object_get (gtk_widget_get_settings (widget),
5274 "gtk-auto-mnemonics", &auto_mnemonics, NULL);
5276 gtk_window_set_mnemonics_visible (window, FALSE);
5281 static GdkAtom atom_rcfiles = GDK_NONE;
5282 static GdkAtom atom_iconthemes = GDK_NONE;
5285 send_client_message_to_embedded_windows (GtkWidget *widget,
5286 GdkAtom message_type)
5288 GList *embedded_windows;
5290 embedded_windows = g_object_get_qdata (G_OBJECT (widget), quark_gtk_embedded);
5291 if (embedded_windows)
5293 GdkEvent *send_event = gdk_event_new (GDK_CLIENT_EVENT);
5296 for (i = 0; i < 5; i++)
5297 send_event->client.data.l[i] = 0;
5298 send_event->client.data_format = 32;
5299 send_event->client.message_type = message_type;
5301 while (embedded_windows)
5303 GdkNativeWindow xid = GDK_GPOINTER_TO_NATIVE_WINDOW(embedded_windows->data);
5304 gdk_event_send_client_message_for_display (gtk_widget_get_display (widget), send_event, xid);
5305 embedded_windows = embedded_windows->next;
5308 gdk_event_free (send_event);
5313 gtk_window_client_event (GtkWidget *widget,
5314 GdkEventClient *event)
5318 atom_rcfiles = gdk_atom_intern_static_string ("_GTK_READ_RCFILES");
5319 atom_iconthemes = gdk_atom_intern_static_string ("_GTK_LOAD_ICONTHEMES");
5322 if (event->message_type == atom_rcfiles)
5324 send_client_message_to_embedded_windows (widget, atom_rcfiles);
5325 gtk_rc_reparse_all_for_settings (gtk_widget_get_settings (widget), FALSE);
5328 if (event->message_type == atom_iconthemes)
5330 send_client_message_to_embedded_windows (widget, atom_iconthemes);
5331 _gtk_icon_theme_check_reload (gtk_widget_get_display (widget));
5338 gtk_window_check_resize (GtkContainer *container)
5340 if (gtk_widget_get_visible (GTK_WIDGET (container)))
5341 gtk_window_move_resize (GTK_WINDOW (container));
5345 gtk_window_focus (GtkWidget *widget,
5346 GtkDirectionType direction)
5348 GtkWindowPrivate *priv;
5351 GtkContainer *container;
5353 GtkWidget *old_focus_child;
5356 container = GTK_CONTAINER (widget);
5357 window = GTK_WINDOW (widget);
5358 priv = window->priv;
5359 bin = GTK_BIN (widget);
5361 old_focus_child = gtk_container_get_focus_child (container);
5363 /* We need a special implementation here to deal properly with wrapping
5364 * around in the tab chain without the danger of going into an
5367 if (old_focus_child)
5369 if (gtk_widget_child_focus (old_focus_child, direction))
5373 if (priv->focus_widget)
5375 if (direction == GTK_DIR_LEFT ||
5376 direction == GTK_DIR_RIGHT ||
5377 direction == GTK_DIR_UP ||
5378 direction == GTK_DIR_DOWN)
5383 /* Wrapped off the end, clear the focus setting for the toplpevel */
5384 parent = gtk_widget_get_parent (priv->focus_widget);
5387 gtk_container_set_focus_child (GTK_CONTAINER (parent), NULL);
5388 parent = gtk_widget_get_parent (parent);
5391 gtk_window_set_focus (GTK_WINDOW (container), NULL);
5394 /* Now try to focus the first widget in the window */
5395 child = gtk_bin_get_child (bin);
5398 if (gtk_widget_child_focus (child, direction))
5406 gtk_window_real_set_focus (GtkWindow *window,
5409 GtkWindowPrivate *priv = window->priv;
5410 GtkWidget *old_focus = priv->focus_widget;
5411 gboolean had_default = FALSE;
5412 gboolean focus_had_default = FALSE;
5413 gboolean old_focus_had_default = FALSE;
5417 g_object_ref (old_focus);
5418 g_object_freeze_notify (G_OBJECT (old_focus));
5419 old_focus_had_default = gtk_widget_has_default (old_focus);
5423 g_object_ref (focus);
5424 g_object_freeze_notify (G_OBJECT (focus));
5425 focus_had_default = gtk_widget_has_default (focus);
5428 if (priv->default_widget)
5429 had_default = gtk_widget_has_default (priv->default_widget);
5431 if (priv->focus_widget)
5433 if (gtk_widget_get_receives_default (priv->focus_widget) &&
5434 (priv->focus_widget != priv->default_widget))
5436 _gtk_widget_set_has_default (priv->focus_widget, FALSE);
5437 gtk_widget_queue_draw (priv->focus_widget);
5439 if (priv->default_widget)
5440 _gtk_widget_set_has_default (priv->default_widget, TRUE);
5443 priv->focus_widget = NULL;
5445 if (priv->has_focus)
5446 do_focus_change (old_focus, FALSE);
5448 g_object_notify (G_OBJECT (old_focus), "is-focus");
5451 /* The above notifications may have set a new focus widget,
5452 * if so, we don't want to override it.
5454 if (focus && !priv->focus_widget)
5456 priv->focus_widget = focus;
5458 if (gtk_widget_get_receives_default (priv->focus_widget) &&
5459 (priv->focus_widget != priv->default_widget))
5461 if (gtk_widget_get_can_default (priv->focus_widget))
5462 _gtk_widget_set_has_default (priv->focus_widget, TRUE);
5464 if (priv->default_widget)
5465 _gtk_widget_set_has_default (priv->default_widget, FALSE);
5468 if (priv->has_focus)
5469 do_focus_change (priv->focus_widget, TRUE);
5471 g_object_notify (G_OBJECT (priv->focus_widget), "is-focus");
5474 /* If the default widget changed, a redraw will have been queued
5475 * on the old and new default widgets by gtk_window_set_default(), so
5476 * we only have to worry about the case where it didn't change.
5477 * We'll sometimes queue a draw twice on the new widget but that
5480 if (priv->default_widget &&
5481 (had_default != gtk_widget_has_default (priv->default_widget)))
5482 gtk_widget_queue_draw (priv->default_widget);
5486 if (old_focus_had_default != gtk_widget_has_default (old_focus))
5487 gtk_widget_queue_draw (old_focus);
5489 g_object_thaw_notify (G_OBJECT (old_focus));
5490 g_object_unref (old_focus);
5494 if (focus_had_default != gtk_widget_has_default (focus))
5495 gtk_widget_queue_draw (focus);
5497 g_object_thaw_notify (G_OBJECT (focus));
5498 g_object_unref (focus);
5504 gtk_window_get_preferred_width (GtkWidget *widget,
5512 window = GTK_WINDOW (widget);
5513 child = gtk_bin_get_child (GTK_BIN (window));
5515 border_width = gtk_container_get_border_width (GTK_CONTAINER (window));
5516 *minimum_size = border_width * 2;
5517 *natural_size = border_width * 2;
5519 if (child && gtk_widget_get_visible (child))
5521 gint child_min, child_nat;
5522 gtk_widget_get_preferred_width (child, &child_min, &child_nat);
5524 *minimum_size += child_min;
5525 *natural_size += child_nat;
5530 gtk_window_get_preferred_height (GtkWidget *widget,
5538 window = GTK_WINDOW (widget);
5539 child = gtk_bin_get_child (GTK_BIN (window));
5541 border_width = gtk_container_get_border_width (GTK_CONTAINER (window));
5542 *minimum_size = border_width * 2;
5543 *natural_size = border_width * 2;
5545 if (child && gtk_widget_get_visible (child))
5547 gint child_min, child_nat;
5548 gtk_widget_get_preferred_height (child, &child_min, &child_nat);
5550 *minimum_size += child_min;
5551 *natural_size += child_nat;
5557 * _gtk_window_unset_focus_and_default:
5558 * @window: a #GtkWindow
5559 * @widget: a widget inside of @window
5561 * Checks whether the focus and default widgets of @window are
5562 * @widget or a descendent of @widget, and if so, unset them.
5565 _gtk_window_unset_focus_and_default (GtkWindow *window,
5569 GtkWindowPrivate *priv = window->priv;
5573 g_object_ref (window);
5574 g_object_ref (widget);
5576 parent = gtk_widget_get_parent (widget);
5577 if (gtk_container_get_focus_child (GTK_CONTAINER (parent)) == widget)
5579 child = priv->focus_widget;
5581 while (child && child != widget)
5582 child = gtk_widget_get_parent (child);
5584 if (child == widget)
5585 gtk_window_set_focus (GTK_WINDOW (window), NULL);
5588 child = priv->default_widget;
5590 while (child && child != widget)
5591 child = gtk_widget_get_parent (child);
5593 if (child == widget)
5594 gtk_window_set_default (window, NULL);
5596 g_object_unref (widget);
5597 g_object_unref (window);
5600 /*********************************
5601 * Functions related to resizing *
5602 *********************************/
5604 /* This function doesn't constrain to geometry hints */
5606 gtk_window_compute_configure_request_size (GtkWindow *window,
5610 GtkWindowPrivate *priv = window->priv;
5611 GtkRequisition requisition;
5612 GtkWindowGeometryInfo *info;
5616 * - we've done a size request
5619 widget = GTK_WIDGET (window);
5621 info = gtk_window_get_geometry_info (window, FALSE);
5623 if (priv->need_default_size)
5625 gtk_widget_get_preferred_size (widget, &requisition, NULL);
5627 /* Default to requisition */
5628 *width = requisition.width;
5629 *height = requisition.height;
5631 /* If window is empty so requests 0, default to random nonzero size */
5632 if (*width == 0 && *height == 0)
5638 /* Override requisition with default size */
5642 gint base_width = 0;
5643 gint base_height = 0;
5645 gint min_height = 0;
5647 gint height_inc = 1;
5649 if (info->default_is_geometry &&
5650 (info->default_width > 0 || info->default_height > 0))
5652 GdkGeometry geometry;
5655 gtk_window_compute_hints (window, &geometry, &flags);
5657 if (flags & GDK_HINT_BASE_SIZE)
5659 base_width = geometry.base_width;
5660 base_height = geometry.base_height;
5662 if (flags & GDK_HINT_MIN_SIZE)
5664 min_width = geometry.min_width;
5665 min_height = geometry.min_height;
5667 if (flags & GDK_HINT_RESIZE_INC)
5669 width_inc = geometry.width_inc;
5670 height_inc = geometry.height_inc;
5674 if (info->default_width > 0)
5675 *width = MAX (info->default_width * width_inc + base_width, min_width);
5677 if (info->default_height > 0)
5678 *height = MAX (info->default_height * height_inc + base_height, min_height);
5683 GtkAllocation allocation;
5685 gtk_widget_get_allocation (widget, &allocation);
5687 /* Default to keeping current size */
5688 *width = allocation.width;
5689 *height = allocation.height;
5692 /* Override any size with gtk_window_resize() values */
5695 if (info->resize_width > 0)
5696 *width = info->resize_width;
5698 if (info->resize_height > 0)
5699 *height = info->resize_height;
5702 /* Don't ever request zero width or height, its not supported by
5703 gdk. The size allocation code will round it to 1 anyway but if
5704 we do it then the value returned from this function will is
5705 not comparable to the size allocation read from the GtkWindow. */
5706 *width = MAX (*width, 1);
5707 *height = MAX (*height, 1);
5710 static GtkWindowPosition
5711 get_effective_position (GtkWindow *window)
5713 GtkWindowPrivate *priv = window->priv;
5714 GtkWindowPosition pos = priv->position;
5716 if (pos == GTK_WIN_POS_CENTER_ON_PARENT &&
5717 (priv->transient_parent == NULL ||
5718 !gtk_widget_get_mapped (GTK_WIDGET (priv->transient_parent))))
5719 pos = GTK_WIN_POS_NONE;
5725 get_center_monitor_of_window (GtkWindow *window)
5727 /* We could try to sort out the relative positions of the monitors and
5728 * stuff, or we could just be losers and assume you have a row
5729 * or column of monitors.
5731 return gdk_screen_get_n_monitors (gtk_window_check_screen (window)) / 2;
5735 get_monitor_containing_pointer (GtkWindow *window)
5739 GdkScreen *window_screen;
5740 GdkScreen *pointer_screen;
5741 GdkDisplay *display;
5742 GdkDeviceManager *device_manager;
5745 window_screen = gtk_window_check_screen (window);
5746 display = gdk_screen_get_display (window_screen);
5747 device_manager = gdk_display_get_device_manager (display);
5748 pointer = gdk_device_manager_get_client_pointer (device_manager);
5750 gdk_display_get_device_state (display, pointer,
5754 if (pointer_screen == window_screen)
5755 monitor_num = gdk_screen_get_monitor_at_point (pointer_screen, px, py);
5763 center_window_on_monitor (GtkWindow *window,
5769 GdkRectangle monitor;
5772 monitor_num = get_monitor_containing_pointer (window);
5774 if (monitor_num == -1)
5775 monitor_num = get_center_monitor_of_window (window);
5777 gdk_screen_get_monitor_geometry (gtk_window_check_screen (window),
5778 monitor_num, &monitor);
5780 *x = (monitor.width - w) / 2 + monitor.x;
5781 *y = (monitor.height - h) / 2 + monitor.y;
5783 /* Be sure we aren't off the monitor, ignoring _NET_WM_STRUT
5784 * and WM decorations.
5798 if (extent > clamp_extent)
5800 *base = clamp_base + clamp_extent/2 - extent/2;
5801 else if (*base < clamp_base)
5803 else if (*base + extent > clamp_base + clamp_extent)
5804 *base = clamp_base + clamp_extent - extent;
5808 clamp_window_to_rectangle (gint *x,
5812 const GdkRectangle *rect)
5814 #ifdef DEBUGGING_OUTPUT
5815 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);
5818 /* If it is too large, center it. If it fits on the monitor but is
5819 * partially outside, move it to the closest edge. Do this
5820 * separately in x and y directions.
5822 clamp (x, w, rect->x, rect->width);
5823 clamp (y, h, rect->y, rect->height);
5824 #ifdef DEBUGGING_OUTPUT
5825 g_print (" ==> %+d%+d: %dx%d\n", *x, *y, w, h);
5831 gtk_window_compute_configure_request (GtkWindow *window,
5832 GdkRectangle *request,
5833 GdkGeometry *geometry,
5836 GtkWindowPrivate *priv = window->priv;
5837 GdkGeometry new_geometry;
5841 GtkWindowPosition pos;
5842 GtkWidget *parent_widget;
5843 GtkWindowGeometryInfo *info;
5847 widget = GTK_WIDGET (window);
5849 screen = gtk_window_check_screen (window);
5851 gtk_widget_get_preferred_size (widget, NULL, NULL);
5852 gtk_window_compute_configure_request_size (window, (guint *)&w, (guint *)&h);
5854 gtk_window_compute_hints (window, &new_geometry, &new_flags);
5855 gtk_window_constrain_size (window,
5856 &new_geometry, new_flags,
5860 parent_widget = (GtkWidget*) priv->transient_parent;
5862 pos = get_effective_position (window);
5863 info = gtk_window_get_geometry_info (window, FALSE);
5865 /* by default, don't change position requested */
5868 x = info->last.configure_request.x;
5869 y = info->last.configure_request.y;
5878 if (priv->need_default_position)
5881 /* FIXME this all interrelates with window gravity.
5882 * For most of them I think we want to set GRAVITY_CENTER.
5884 * Not sure how to go about that.
5889 /* here we are only handling CENTER_ALWAYS
5890 * as it relates to default positioning,
5891 * where it's equivalent to simply CENTER
5893 case GTK_WIN_POS_CENTER_ALWAYS:
5894 case GTK_WIN_POS_CENTER:
5895 center_window_on_monitor (window, w, h, &x, &y);
5898 case GTK_WIN_POS_CENTER_ON_PARENT:
5900 GtkAllocation allocation;
5901 GdkWindow *gdk_window;
5903 GdkRectangle monitor;
5906 g_assert (gtk_widget_get_mapped (parent_widget)); /* established earlier */
5908 gdk_window = gtk_widget_get_window (parent_widget);
5910 if (gdk_window != NULL)
5911 monitor_num = gdk_screen_get_monitor_at_window (screen,
5916 gdk_window_get_origin (gdk_window,
5919 gtk_widget_get_allocation (parent_widget, &allocation);
5920 x = ox + (allocation.width - w) / 2;
5921 y = oy + (allocation.height - h) / 2;
5923 /* Clamp onto current monitor, ignoring _NET_WM_STRUT and
5924 * WM decorations. If parent wasn't on a monitor, just
5927 if (monitor_num >= 0)
5929 gdk_screen_get_monitor_geometry (screen, monitor_num, &monitor);
5930 clamp_window_to_rectangle (&x, &y, w, h, &monitor);
5935 case GTK_WIN_POS_MOUSE:
5937 gint screen_width = gdk_screen_get_width (screen);
5938 gint screen_height = gdk_screen_get_height (screen);
5940 GdkRectangle monitor;
5941 GdkDisplay *display;
5942 GdkDeviceManager *device_manager;
5944 GdkScreen *pointer_screen;
5947 display = gdk_screen_get_display (screen);
5948 device_manager = gdk_display_get_device_manager (display);
5949 pointer = gdk_device_manager_get_client_pointer (device_manager);
5951 gdk_display_get_device_state (display, pointer,
5955 if (pointer_screen == screen)
5956 monitor_num = gdk_screen_get_monitor_at_point (screen, px, py);
5962 x = CLAMP (x, 0, screen_width - w);
5963 y = CLAMP (y, 0, screen_height - h);
5965 /* Clamp onto current monitor, ignoring _NET_WM_STRUT and
5966 * WM decorations. Don't try to figure out what's going
5967 * on if the mouse wasn't inside a monitor.
5969 if (monitor_num >= 0)
5971 gdk_screen_get_monitor_geometry (screen, monitor_num, &monitor);
5972 clamp_window_to_rectangle (&x, &y, w, h, &monitor);
5980 } /* if (priv->need_default_position) */
5982 if (priv->need_default_position && info &&
5983 info->initial_pos_set)
5985 x = info->initial_x;
5986 y = info->initial_y;
5987 gtk_window_constrain_position (window, w, h, &x, &y);
5993 request->height = h;
5996 *geometry = new_geometry;
6002 gtk_window_constrain_position (GtkWindow *window,
6008 GtkWindowPrivate *priv = window->priv;
6010 /* See long comments in gtk_window_move_resize()
6011 * on when it's safe to call this function.
6013 if (priv->position == GTK_WIN_POS_CENTER_ALWAYS)
6015 gint center_x, center_y;
6017 center_window_on_monitor (window, new_width, new_height, ¢er_x, ¢er_y);
6025 gtk_window_move_resize (GtkWindow *window)
6029 * First we determine whether any information has changed that would
6030 * cause us to revise our last configure request. If we would send
6031 * a different configure request from last time, then
6032 * configure_request_size_changed = TRUE or
6033 * configure_request_pos_changed = TRUE. configure_request_size_changed
6034 * may be true due to new hints, a gtk_window_resize(), or whatever.
6035 * configure_request_pos_changed may be true due to gtk_window_set_position()
6036 * or gtk_window_move().
6038 * If the configure request has changed, we send off a new one. To
6039 * ensure GTK+ invariants are maintained (resize queue does what it
6040 * should), we go ahead and size_allocate the requested size in this
6043 * If the configure request has not changed, we don't ever resend
6044 * it, because it could mean fighting the user or window manager.
6047 * To prepare the configure request, we come up with a base size/pos:
6048 * - the one from gtk_window_move()/gtk_window_resize()
6049 * - else default_width, default_height if we haven't ever
6051 * - else the size request if we haven't ever been mapped,
6052 * as a substitute default size
6053 * - else the current size of the window, as received from
6054 * configure notifies (i.e. the current allocation)
6056 * If GTK_WIN_POS_CENTER_ALWAYS is active, we constrain
6057 * the position request to be centered.
6059 GtkWindowPrivate *priv = window->priv;
6060 GtkAllocation allocation;
6062 GtkContainer *container;
6063 GtkWindowGeometryInfo *info;
6064 GdkGeometry new_geometry;
6065 GdkWindow *gdk_window;
6067 GdkRectangle new_request;
6068 gboolean configure_request_size_changed;
6069 gboolean configure_request_pos_changed;
6070 gboolean hints_changed; /* do we need to send these again */
6071 GtkWindowLastGeometryInfo saved_last_info;
6073 widget = GTK_WIDGET (window);
6074 gdk_window = gtk_widget_get_window (widget);
6075 container = GTK_CONTAINER (widget);
6076 info = gtk_window_get_geometry_info (window, TRUE);
6078 configure_request_size_changed = FALSE;
6079 configure_request_pos_changed = FALSE;
6081 gtk_window_compute_configure_request (window, &new_request,
6082 &new_geometry, &new_flags);
6084 /* This check implies the invariant that we never set info->last
6085 * without setting the hints and sending off a configure request.
6087 * If we change info->last without sending the request, we may
6090 if (info->last.configure_request.x != new_request.x ||
6091 info->last.configure_request.y != new_request.y)
6092 configure_request_pos_changed = TRUE;
6094 if ((info->last.configure_request.width != new_request.width ||
6095 info->last.configure_request.height != new_request.height))
6096 configure_request_size_changed = TRUE;
6098 hints_changed = FALSE;
6100 if (!gtk_window_compare_hints (&info->last.geometry, info->last.flags,
6101 &new_geometry, new_flags))
6103 hints_changed = TRUE;
6106 /* Position Constraints
6107 * ====================
6109 * POS_CENTER_ALWAYS is conceptually a constraint rather than
6110 * a default. The other POS_ values are used only when the
6111 * window is shown, not after that.
6113 * However, we can't implement a position constraint as
6114 * "anytime the window size changes, center the window"
6115 * because this may well end up fighting the WM or user. In
6116 * fact it gets in an infinite loop with at least one WM.
6118 * Basically, applications are in no way in a position to
6119 * constrain the position of a window, with one exception:
6120 * override redirect windows. (Really the intended purpose
6121 * of CENTER_ALWAYS anyhow, I would think.)
6123 * So the way we implement this "constraint" is to say that when WE
6124 * cause a move or resize, i.e. we make a configure request changing
6125 * window size, we recompute the CENTER_ALWAYS position to reflect
6126 * the new window size, and include it in our request. Also, if we
6127 * just turned on CENTER_ALWAYS we snap to center with a new
6128 * request. Otherwise, if we are just NOTIFIED of a move or resize
6129 * done by someone else e.g. the window manager, we do NOT send a
6130 * new configure request.
6132 * For override redirect windows, this works fine; all window
6133 * sizes are from our configure requests. For managed windows,
6134 * it is at least semi-sane, though who knows what the
6135 * app author is thinking.
6138 /* This condition should be kept in sync with the condition later on
6139 * that determines whether we send a configure request. i.e. we
6140 * should do this position constraining anytime we were going to
6141 * send a configure request anyhow, plus when constraints have
6144 if (configure_request_pos_changed ||
6145 configure_request_size_changed ||
6147 info->position_constraints_changed)
6149 /* We request the constrained position if:
6150 * - we were changing position, and need to clamp
6151 * the change to the constraint
6152 * - we're changing the size anyway
6153 * - set_position() was called to toggle CENTER_ALWAYS on
6156 gtk_window_constrain_position (window,
6162 /* Update whether we need to request a move */
6163 if (info->last.configure_request.x != new_request.x ||
6164 info->last.configure_request.y != new_request.y)
6165 configure_request_pos_changed = TRUE;
6167 configure_request_pos_changed = FALSE;
6171 if (priv->type == GTK_WINDOW_TOPLEVEL)
6173 int notify_x, notify_y;
6175 /* this is the position from the last configure notify */
6176 gdk_window_get_position (widget->window, ¬ify_x, ¬ify_y);
6178 g_message ("--- %s ---\n"
6179 "last : %d,%d\t%d x %d\n"
6180 "this : %d,%d\t%d x %d\n"
6181 "alloc : %d,%d\t%d x %d\n"
6183 "resize: \t%d x %d\n"
6184 "size_changed: %d pos_changed: %d hints_changed: %d\n"
6185 "configure_notify_received: %d\n"
6186 "configure_request_count: %d\n"
6187 "position_constraints_changed: %d\n",
6188 priv->title ? priv->title : "(no title)",
6189 info->last.configure_request.x,
6190 info->last.configure_request.y,
6191 info->last.configure_request.width,
6192 info->last.configure_request.height,
6198 widget->allocation.width,
6199 widget->allocation.height,
6200 widget->requisition.width,
6201 widget->requisition.height,
6203 info->resize_height,
6204 configure_request_pos_changed,
6205 configure_request_size_changed,
6207 priv->configure_notify_received,
6208 priv->configure_request_count,
6209 info->position_constraints_changed);
6213 saved_last_info = info->last;
6214 info->last.geometry = new_geometry;
6215 info->last.flags = new_flags;
6216 info->last.configure_request = new_request;
6218 /* need to set PPosition so the WM will look at our position,
6219 * but we don't want to count PPosition coming and going as a hints
6220 * change for future iterations. So we saved info->last prior to
6224 /* Also, if the initial position was explicitly set, then we always
6225 * toggle on PPosition. This makes gtk_window_move(window, 0, 0)
6229 /* Also, we toggle on PPosition if GTK_WIN_POS_ is in use and
6230 * this is an initial map
6233 if ((configure_request_pos_changed ||
6234 info->initial_pos_set ||
6235 (priv->need_default_position &&
6236 get_effective_position (window) != GTK_WIN_POS_NONE)) &&
6237 (new_flags & GDK_HINT_POS) == 0)
6239 new_flags |= GDK_HINT_POS;
6240 hints_changed = TRUE;
6243 /* Set hints if necessary
6246 gdk_window_set_geometry_hints (gdk_window,
6250 gtk_widget_get_allocation (widget, &allocation);
6252 /* handle resizing/moving and widget tree allocation
6254 if (priv->configure_notify_received)
6256 /* If we have received a configure event since
6257 * the last time in this function, we need to
6258 * accept our new size and size_allocate child widgets.
6259 * (see gtk_window_configure_event() for more details).
6261 * 1 or more configure notifies may have been received.
6262 * Also, configure_notify_received will only be TRUE
6263 * if all expected configure notifies have been received
6264 * (one per configure request), as an optimization.
6267 priv->configure_notify_received = FALSE;
6269 /* gtk_window_configure_event() filled in widget->allocation */
6270 gtk_widget_size_allocate (widget, &allocation);
6272 gdk_window_process_updates (gdk_window, TRUE);
6274 gdk_window_configure_finished (gdk_window);
6276 /* If the configure request changed, it means that
6278 * 1) coincidentally changed hints or widget properties
6279 * impacting the configure request before getting
6280 * a configure notify, or
6281 * 2) some broken widget is changing its size request
6282 * during size allocation, resulting in
6283 * a false appearance of changed configure request.
6285 * For 1), we could just go ahead and ask for the
6286 * new size right now, but doing that for 2)
6287 * might well be fighting the user (and can even
6288 * trigger a loop). Since we really don't want to
6289 * do that, we requeue a resize in hopes that
6290 * by the time it gets handled, the child has seen
6291 * the light and is willing to go along with the
6292 * new size. (this happens for the zvt widget, since
6293 * the size_allocate() above will have stored the
6294 * requisition corresponding to the new size in the
6297 * This doesn't buy us anything for 1), but it shouldn't
6298 * hurt us too badly, since it is what would have
6299 * happened if we had gotten the configure event before
6300 * the new size had been set.
6303 if (configure_request_size_changed ||
6304 configure_request_pos_changed)
6306 /* Don't change the recorded last info after all, because we
6307 * haven't actually updated to the new info yet - we decided
6308 * to postpone our configure request until later.
6310 info->last = saved_last_info;
6312 gtk_widget_queue_resize_no_redraw (widget); /* migth recurse for GTK_RESIZE_IMMEDIATE */
6315 return; /* Bail out, we didn't really process the move/resize */
6317 else if ((configure_request_size_changed || hints_changed) &&
6318 (allocation.width != new_request.width || allocation.height != new_request.height))
6321 /* We are in one of the following situations:
6322 * A. configure_request_size_changed
6323 * our requisition has changed and we need a different window size,
6324 * so we request it from the window manager.
6325 * B. !configure_request_size_changed && hints_changed
6326 * the window manager rejects our size, but we have just changed the
6327 * window manager hints, so there's a chance our request will
6328 * be honoured this time, so we try again.
6330 * However, if the new requisition is the same as the current allocation,
6331 * we don't request it again, since we won't get a ConfigureNotify back from
6332 * the window manager unless it decides to change our requisition. If
6333 * we don't get the ConfigureNotify back, the resize queue will never be run.
6336 /* Now send the configure request */
6337 if (configure_request_pos_changed)
6341 gdk_window_move_resize (priv->frame,
6342 new_request.x - priv->frame_left,
6343 new_request.y - priv->frame_top,
6344 new_request.width + priv->frame_left + priv->frame_right,
6345 new_request.height + priv->frame_top + priv->frame_bottom);
6346 gdk_window_resize (gdk_window,
6347 new_request.width, new_request.height);
6350 gdk_window_move_resize (gdk_window,
6351 new_request.x, new_request.y,
6352 new_request.width, new_request.height);
6354 else /* only size changed */
6357 gdk_window_resize (priv->frame,
6358 new_request.width + priv->frame_left + priv->frame_right,
6359 new_request.height + priv->frame_top + priv->frame_bottom);
6360 gdk_window_resize (gdk_window,
6361 new_request.width, new_request.height);
6364 if (priv->type == GTK_WINDOW_POPUP)
6366 GtkAllocation allocation;
6368 /* Directly size allocate for override redirect (popup) windows. */
6371 allocation.width = new_request.width;
6372 allocation.height = new_request.height;
6374 gtk_widget_size_allocate (widget, &allocation);
6376 gdk_window_process_updates (gdk_window, TRUE);
6378 if (gtk_container_get_resize_mode (container) == GTK_RESIZE_QUEUE)
6379 gtk_widget_queue_draw (widget);
6383 /* Increment the number of have-not-yet-received-notify requests */
6384 priv->configure_request_count += 1;
6385 gdk_window_freeze_toplevel_updates_libgtk_only (gdk_window);
6387 /* for GTK_RESIZE_QUEUE toplevels, we are now awaiting a new
6388 * configure event in response to our resizing request.
6389 * the configure event will cause a new resize with
6390 * ->configure_notify_received=TRUE.
6391 * until then, we want to
6392 * - discard expose events
6393 * - coalesce resizes for our children
6394 * - defer any window resizes until the configure event arrived
6395 * to achieve this, we queue a resize for the window, but remove its
6396 * resizing handler, so resizing will not be handled from the next
6397 * idle handler but when the configure event arrives.
6399 * FIXME: we should also dequeue the pending redraws here, since
6400 * we handle those ourselves upon ->configure_notify_received==TRUE.
6402 if (gtk_container_get_resize_mode (container) == GTK_RESIZE_QUEUE)
6404 gtk_widget_queue_resize_no_redraw (widget);
6405 _gtk_container_dequeue_resize_handler (container);
6411 /* Handle any position changes.
6413 if (configure_request_pos_changed)
6417 gdk_window_move (priv->frame,
6418 new_request.x - priv->frame_left,
6419 new_request.y - priv->frame_top);
6422 gdk_window_move (gdk_window,
6423 new_request.x, new_request.y);
6426 /* And run the resize queue.
6428 gtk_container_resize_children (container);
6431 /* We have now processed a move/resize since the last position
6432 * constraint change, setting of the initial position, or resize.
6433 * (Not resetting these flags here can lead to infinite loops for
6434 * GTK_RESIZE_IMMEDIATE containers)
6436 info->position_constraints_changed = FALSE;
6437 info->initial_pos_set = FALSE;
6438 info->resize_width = -1;
6439 info->resize_height = -1;
6442 /* Compare two sets of Geometry hints for equality.
6445 gtk_window_compare_hints (GdkGeometry *geometry_a,
6447 GdkGeometry *geometry_b,
6450 if (flags_a != flags_b)
6453 if ((flags_a & GDK_HINT_MIN_SIZE) &&
6454 (geometry_a->min_width != geometry_b->min_width ||
6455 geometry_a->min_height != geometry_b->min_height))
6458 if ((flags_a & GDK_HINT_MAX_SIZE) &&
6459 (geometry_a->max_width != geometry_b->max_width ||
6460 geometry_a->max_height != geometry_b->max_height))
6463 if ((flags_a & GDK_HINT_BASE_SIZE) &&
6464 (geometry_a->base_width != geometry_b->base_width ||
6465 geometry_a->base_height != geometry_b->base_height))
6468 if ((flags_a & GDK_HINT_ASPECT) &&
6469 (geometry_a->min_aspect != geometry_b->min_aspect ||
6470 geometry_a->max_aspect != geometry_b->max_aspect))
6473 if ((flags_a & GDK_HINT_RESIZE_INC) &&
6474 (geometry_a->width_inc != geometry_b->width_inc ||
6475 geometry_a->height_inc != geometry_b->height_inc))
6478 if ((flags_a & GDK_HINT_WIN_GRAVITY) &&
6479 geometry_a->win_gravity != geometry_b->win_gravity)
6486 _gtk_window_constrain_size (GtkWindow *window,
6492 GtkWindowPrivate *priv;
6493 GtkWindowGeometryInfo *info;
6495 g_return_if_fail (GTK_IS_WINDOW (window));
6497 priv = window->priv;
6499 info = priv->geometry_info;
6502 GdkWindowHints flags = info->last.flags;
6503 GdkGeometry *geometry = &info->last.geometry;
6505 gtk_window_constrain_size (window,
6516 gtk_window_constrain_size (GtkWindow *window,
6517 GdkGeometry *geometry,
6524 gdk_window_constrain_size (geometry, flags, width, height,
6525 new_width, new_height);
6528 /* Compute the set of geometry hints and flags for a window
6529 * based on the application set geometry, and requisition
6530 * of the window. gtk_size_request_get_preferred_size() must have been
6534 gtk_window_compute_hints (GtkWindow *window,
6535 GdkGeometry *new_geometry,
6538 GtkWindowPrivate *priv = window->priv;
6540 gint extra_width = 0;
6541 gint extra_height = 0;
6542 GtkWindowGeometryInfo *geometry_info;
6543 GtkRequisition requisition;
6545 widget = GTK_WIDGET (window);
6547 gtk_widget_get_preferred_size (widget, &requisition, NULL);
6548 geometry_info = gtk_window_get_geometry_info (GTK_WINDOW (widget), FALSE);
6552 *new_flags = geometry_info->mask;
6553 *new_geometry = geometry_info->geometry;
6560 if (geometry_info && geometry_info->widget)
6562 GtkRequisition requisition;
6563 GtkRequisition child_requisition;
6565 /* FIXME: This really isn't right. It gets the min size wrong and forces
6566 * callers to do horrible hacks like set a huge usize on the child requisition
6567 * to get the base size right. We really want to find the answers to:
6569 * - If the geometry widget was infinitely big, how much extra space
6570 * would be needed for the stuff around it.
6572 * - If the geometry widget was infinitely small, how big would the
6573 * window still have to be.
6575 * Finding these answers would be a bit of a mess here. (Bug #68668)
6577 gtk_widget_get_preferred_size (geometry_info->widget,
6578 &child_requisition, NULL);
6580 gtk_widget_get_preferred_size (widget,
6581 &requisition, NULL);
6582 extra_width = requisition.width - child_requisition.width;
6583 extra_height = requisition.height - child_requisition.height;
6586 /* We don't want to set GDK_HINT_POS in here, we just set it
6587 * in gtk_window_move_resize() when we want the position
6591 if (*new_flags & GDK_HINT_BASE_SIZE)
6593 new_geometry->base_width += extra_width;
6594 new_geometry->base_height += extra_height;
6596 else if (!(*new_flags & GDK_HINT_MIN_SIZE) &&
6597 (*new_flags & GDK_HINT_RESIZE_INC) &&
6598 ((extra_width != 0) || (extra_height != 0)))
6600 *new_flags |= GDK_HINT_BASE_SIZE;
6602 new_geometry->base_width = extra_width;
6603 new_geometry->base_height = extra_height;
6606 if (*new_flags & GDK_HINT_MIN_SIZE)
6608 if (new_geometry->min_width < 0)
6609 new_geometry->min_width = requisition.width;
6611 new_geometry->min_width += extra_width;
6613 if (new_geometry->min_height < 0)
6614 new_geometry->min_height = requisition.height;
6616 new_geometry->min_height += extra_height;
6620 *new_flags |= GDK_HINT_MIN_SIZE;
6622 new_geometry->min_width = requisition.width;
6623 new_geometry->min_height = requisition.height;
6626 if (*new_flags & GDK_HINT_MAX_SIZE)
6628 if (new_geometry->max_width < 0)
6629 new_geometry->max_width = requisition.width;
6631 new_geometry->max_width += extra_width;
6633 if (new_geometry->max_height < 0)
6634 new_geometry->max_height = requisition.height;
6636 new_geometry->max_height += extra_height;
6638 else if (!priv->resizable)
6640 *new_flags |= GDK_HINT_MAX_SIZE;
6642 new_geometry->max_width = requisition.width;
6643 new_geometry->max_height = requisition.height;
6646 *new_flags |= GDK_HINT_WIN_GRAVITY;
6647 new_geometry->win_gravity = priv->gravity;
6650 /***********************
6651 * Redrawing functions *
6652 ***********************/
6655 gtk_window_draw (GtkWidget *widget,
6658 if (!gtk_widget_get_app_paintable (widget))
6659 gtk_paint_flat_box (gtk_widget_get_style (widget),
6662 GTK_SHADOW_NONE, widget, "base",
6664 gtk_widget_get_allocated_width (widget),
6665 gtk_widget_get_allocated_height (widget));
6667 if (GTK_WIDGET_CLASS (gtk_window_parent_class)->draw)
6668 return GTK_WIDGET_CLASS (gtk_window_parent_class)->draw (widget, cr);
6674 * gtk_window_set_has_frame:
6675 * @window: a #GtkWindow
6676 * @setting: a boolean
6678 * (Note: this is a special-purpose function for the framebuffer port,
6679 * that causes GTK+ to draw its own window border. For most applications,
6680 * you want gtk_window_set_decorated() instead, which tells the window
6681 * manager whether to draw the window border.)
6683 * If this function is called on a window with setting of %TRUE, before
6684 * it is realized or showed, it will have a "frame" window around
6685 * @window->window, accessible in @window->frame. Using the signal
6686 * frame_event you can receive all events targeted at the frame.
6688 * This function is used by the linux-fb port to implement managed
6689 * windows, but it could conceivably be used by X-programs that
6690 * want to do their own window decorations.
6694 gtk_window_set_has_frame (GtkWindow *window,
6697 GtkWindowPrivate *priv;
6699 g_return_if_fail (GTK_IS_WINDOW (window));
6700 g_return_if_fail (!gtk_widget_get_realized (GTK_WIDGET (window)));
6702 priv = window->priv;
6704 priv->has_frame = setting != FALSE;
6708 * gtk_window_get_has_frame:
6709 * @window: a #GtkWindow
6711 * Accessor for whether the window has a frame window exterior to
6712 * @window->window. Gets the value set by gtk_window_set_has_frame ().
6714 * Return value: %TRUE if a frame has been added to the window
6715 * via gtk_window_set_has_frame().
6718 gtk_window_get_has_frame (GtkWindow *window)
6720 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
6722 return window->priv->has_frame;
6726 * gtk_window_set_frame_dimensions:
6727 * @window: a #GtkWindow that has a frame
6728 * @left: The width of the left border
6729 * @top: The height of the top border
6730 * @right: The width of the right border
6731 * @bottom: The height of the bottom border
6733 * (Note: this is a special-purpose function intended for the framebuffer
6734 * port; see gtk_window_set_has_frame(). It will have no effect on the
6735 * window border drawn by the window manager, which is the normal
6736 * case when using the X Window system.)
6738 * For windows with frames (see gtk_window_set_has_frame()) this function
6739 * can be used to change the size of the frame border.
6742 gtk_window_set_frame_dimensions (GtkWindow *window,
6748 GtkWindowPrivate *priv;
6749 GtkAllocation allocation;
6752 g_return_if_fail (GTK_IS_WINDOW (window));
6754 priv = window->priv;
6755 widget = GTK_WIDGET (window);
6757 if (priv->frame_left == left &&
6758 priv->frame_top == top &&
6759 priv->frame_right == right &&
6760 priv->frame_bottom == bottom)
6763 priv->frame_left = left;
6764 priv->frame_top = top;
6765 priv->frame_right = right;
6766 priv->frame_bottom = bottom;
6768 if (gtk_widget_get_realized (widget) && priv->frame)
6770 gtk_widget_get_allocation (widget, &allocation);
6772 gint width = allocation.width + left + right;
6773 gint height = allocation.height + top + bottom;
6774 gdk_window_resize (priv->frame, width, height);
6775 gtk_decorated_window_move_resize_window (window,
6783 * gtk_window_present:
6784 * @window: a #GtkWindow
6786 * Presents a window to the user. This may mean raising the window
6787 * in the stacking order, deiconifying it, moving it to the current
6788 * desktop, and/or giving it the keyboard focus, possibly dependent
6789 * on the user's platform, window manager, and preferences.
6791 * If @window is hidden, this function calls gtk_widget_show()
6794 * This function should be used when the user tries to open a window
6795 * that's already open. Say for example the preferences dialog is
6796 * currently open, and the user chooses Preferences from the menu
6797 * a second time; use gtk_window_present() to move the already-open dialog
6798 * where the user can see it.
6800 * If you are calling this function in response to a user interaction,
6801 * it is preferable to use gtk_window_present_with_time().
6805 gtk_window_present (GtkWindow *window)
6807 gtk_window_present_with_time (window, GDK_CURRENT_TIME);
6811 * gtk_window_present_with_time:
6812 * @window: a #GtkWindow
6813 * @timestamp: the timestamp of the user interaction (typically a
6814 * button or key press event) which triggered this call
6816 * Presents a window to the user in response to a user interaction.
6817 * If you need to present a window without a timestamp, use
6818 * gtk_window_present(). See gtk_window_present() for details.
6823 gtk_window_present_with_time (GtkWindow *window,
6827 GdkWindow *gdk_window;
6829 g_return_if_fail (GTK_IS_WINDOW (window));
6831 widget = GTK_WIDGET (window);
6833 if (gtk_widget_get_visible (widget))
6835 gdk_window = gtk_widget_get_window (widget);
6837 g_assert (gdk_window != NULL);
6839 gdk_window_show (gdk_window);
6841 /* Translate a timestamp of GDK_CURRENT_TIME appropriately */
6842 if (timestamp == GDK_CURRENT_TIME)
6844 #ifdef GDK_WINDOWING_X11
6845 GdkDisplay *display;
6847 display = gtk_widget_get_display (GTK_WIDGET (window));
6848 timestamp = gdk_x11_display_get_user_time (display);
6850 timestamp = gtk_get_current_event_time ();
6854 gdk_window_focus (gdk_window, timestamp);
6858 gtk_widget_show (widget);
6863 * gtk_window_iconify:
6864 * @window: a #GtkWindow
6866 * Asks to iconify (i.e. minimize) the specified @window. Note that
6867 * you shouldn't assume the window is definitely iconified afterward,
6868 * because other entities (e.g. the user or <link
6869 * linkend="gtk-X11-arch">window manager</link>) could deiconify it
6870 * again, or there may not be a window manager in which case
6871 * iconification isn't possible, etc. But normally the window will end
6872 * up iconified. Just don't write code that crashes if not.
6874 * It's permitted to call this function before showing a window,
6875 * in which case the window will be iconified before it ever appears
6878 * You can track iconification via the "window-state-event" signal
6883 gtk_window_iconify (GtkWindow *window)
6885 GtkWindowPrivate *priv;
6887 GdkWindow *toplevel;
6889 g_return_if_fail (GTK_IS_WINDOW (window));
6891 priv = window->priv;
6892 widget = GTK_WIDGET (window);
6894 priv->iconify_initially = TRUE;
6897 toplevel = priv->frame;
6899 toplevel = gtk_widget_get_window (widget);
6901 if (toplevel != NULL)
6902 gdk_window_iconify (toplevel);
6906 * gtk_window_deiconify:
6907 * @window: a #GtkWindow
6909 * Asks to deiconify (i.e. unminimize) the specified @window. Note
6910 * that you shouldn't assume the window is definitely deiconified
6911 * afterward, because other entities (e.g. the user or <link
6912 * linkend="gtk-X11-arch">window manager</link>) could iconify it
6913 * again before your code which assumes deiconification gets to run.
6915 * You can track iconification via the "window-state-event" signal
6919 gtk_window_deiconify (GtkWindow *window)
6921 GtkWindowPrivate *priv;
6923 GdkWindow *toplevel;
6925 g_return_if_fail (GTK_IS_WINDOW (window));
6927 priv = window->priv;
6928 widget = GTK_WIDGET (window);
6930 priv->iconify_initially = FALSE;
6933 toplevel = priv->frame;
6935 toplevel = gtk_widget_get_window (widget);
6937 if (toplevel != NULL)
6938 gdk_window_deiconify (toplevel);
6943 * @window: a #GtkWindow
6945 * Asks to stick @window, which means that it will appear on all user
6946 * desktops. Note that you shouldn't assume the window is definitely
6947 * stuck afterward, because other entities (e.g. the user or <link
6948 * linkend="gtk-X11-arch">window manager</link>) could unstick it
6949 * again, and some window managers do not support sticking
6950 * windows. But normally the window will end up stuck. Just don't
6951 * write code that crashes if not.
6953 * It's permitted to call this function before showing a window.
6955 * You can track stickiness via the "window-state-event" signal
6960 gtk_window_stick (GtkWindow *window)
6962 GtkWindowPrivate *priv;
6964 GdkWindow *toplevel;
6966 g_return_if_fail (GTK_IS_WINDOW (window));
6968 priv = window->priv;
6969 widget = GTK_WIDGET (window);
6971 priv->stick_initially = TRUE;
6974 toplevel = priv->frame;
6976 toplevel = gtk_widget_get_window (widget);
6978 if (toplevel != NULL)
6979 gdk_window_stick (toplevel);
6983 * gtk_window_unstick:
6984 * @window: a #GtkWindow
6986 * Asks to unstick @window, which means that it will appear on only
6987 * one of the user's desktops. Note that you shouldn't assume the
6988 * window is definitely unstuck afterward, because other entities
6989 * (e.g. the user or <link linkend="gtk-X11-arch">window
6990 * manager</link>) could stick it again. But normally the window will
6991 * end up stuck. Just don't write code that crashes if not.
6993 * You can track stickiness via the "window-state-event" signal
6998 gtk_window_unstick (GtkWindow *window)
7000 GtkWindowPrivate *priv;
7002 GdkWindow *toplevel;
7004 g_return_if_fail (GTK_IS_WINDOW (window));
7006 priv = window->priv;
7007 widget = GTK_WIDGET (window);
7009 priv->stick_initially = FALSE;
7012 toplevel = priv->frame;
7014 toplevel = gtk_widget_get_window (widget);
7016 if (toplevel != NULL)
7017 gdk_window_unstick (toplevel);
7021 * gtk_window_maximize:
7022 * @window: a #GtkWindow
7024 * Asks to maximize @window, so that it becomes full-screen. Note that
7025 * you shouldn't assume the window is definitely maximized afterward,
7026 * because other entities (e.g. the user or <link
7027 * linkend="gtk-X11-arch">window manager</link>) could unmaximize it
7028 * again, and not all window managers support maximization. But
7029 * normally the window will end up maximized. Just don't write code
7030 * that crashes if not.
7032 * It's permitted to call this function before showing a window,
7033 * in which case the window will be maximized when it appears onscreen
7036 * You can track maximization via the "window-state-event" signal
7041 gtk_window_maximize (GtkWindow *window)
7043 GtkWindowPrivate *priv;
7045 GdkWindow *toplevel;
7047 g_return_if_fail (GTK_IS_WINDOW (window));
7049 priv = window->priv;
7050 widget = GTK_WIDGET (window);
7052 priv->maximize_initially = TRUE;
7055 toplevel = priv->frame;
7057 toplevel = gtk_widget_get_window (widget);
7059 if (toplevel != NULL)
7060 gdk_window_maximize (toplevel);
7064 * gtk_window_unmaximize:
7065 * @window: a #GtkWindow
7067 * Asks to unmaximize @window. Note that you shouldn't assume the
7068 * window is definitely unmaximized afterward, because other entities
7069 * (e.g. the user or <link linkend="gtk-X11-arch">window
7070 * manager</link>) could maximize it again, and not all window
7071 * managers honor requests to unmaximize. But normally the window will
7072 * end up unmaximized. Just don't write code that crashes if not.
7074 * You can track maximization via the "window-state-event" signal
7079 gtk_window_unmaximize (GtkWindow *window)
7081 GtkWindowPrivate *priv;
7083 GdkWindow *toplevel;
7085 g_return_if_fail (GTK_IS_WINDOW (window));
7087 priv = window->priv;
7088 widget = GTK_WIDGET (window);
7090 priv->maximize_initially = FALSE;
7093 toplevel = priv->frame;
7095 toplevel = gtk_widget_get_window (widget);
7097 if (toplevel != NULL)
7098 gdk_window_unmaximize (toplevel);
7102 * gtk_window_fullscreen:
7103 * @window: a #GtkWindow
7105 * Asks to place @window in the fullscreen state. Note that you
7106 * shouldn't assume the window is definitely full screen afterward,
7107 * because other entities (e.g. the user or <link
7108 * linkend="gtk-X11-arch">window manager</link>) could unfullscreen it
7109 * again, and not all window managers honor requests to fullscreen
7110 * windows. But normally the window will end up fullscreen. Just
7111 * don't write code that crashes if not.
7113 * You can track the fullscreen state via the "window-state-event" signal
7119 gtk_window_fullscreen (GtkWindow *window)
7121 GtkWindowPrivate *priv;
7123 GdkWindow *toplevel;
7125 g_return_if_fail (GTK_IS_WINDOW (window));
7127 priv = window->priv;
7128 widget = GTK_WIDGET (window);
7130 priv->fullscreen_initially = TRUE;
7133 toplevel = priv->frame;
7135 toplevel = gtk_widget_get_window (widget);
7137 if (toplevel != NULL)
7138 gdk_window_fullscreen (toplevel);
7142 * gtk_window_unfullscreen:
7143 * @window: a #GtkWindow
7145 * Asks to toggle off the fullscreen state for @window. Note that you
7146 * shouldn't assume the window is definitely not full screen
7147 * afterward, because other entities (e.g. the user or <link
7148 * linkend="gtk-X11-arch">window manager</link>) could fullscreen it
7149 * again, and not all window managers honor requests to unfullscreen
7150 * windows. But normally the window will end up restored to its normal
7151 * state. Just don't write code that crashes if not.
7153 * You can track the fullscreen state via the "window-state-event" signal
7159 gtk_window_unfullscreen (GtkWindow *window)
7162 GdkWindow *toplevel;
7163 GtkWindowPrivate *priv;
7165 g_return_if_fail (GTK_IS_WINDOW (window));
7167 priv = window->priv;
7168 widget = GTK_WIDGET (window);
7170 priv->fullscreen_initially = FALSE;
7173 toplevel = priv->frame;
7175 toplevel = gtk_widget_get_window (widget);
7177 if (toplevel != NULL)
7178 gdk_window_unfullscreen (toplevel);
7182 * gtk_window_set_keep_above:
7183 * @window: a #GtkWindow
7184 * @setting: whether to keep @window above other windows
7186 * Asks to keep @window above, so that it stays on top. Note that
7187 * you shouldn't assume the window is definitely above afterward,
7188 * because other entities (e.g. the user or <link
7189 * linkend="gtk-X11-arch">window manager</link>) could not keep it above,
7190 * and not all window managers support keeping windows above. But
7191 * normally the window will end kept above. Just don't write code
7192 * that crashes if not.
7194 * It's permitted to call this function before showing a window,
7195 * in which case the window will be kept above when it appears onscreen
7198 * You can track the above state via the "window-state-event" signal
7201 * Note that, according to the <ulink
7202 * url="http://www.freedesktop.org/Standards/wm-spec">Extended Window
7203 * Manager Hints</ulink> specification, the above state is mainly meant
7204 * for user preferences and should not be used by applications e.g. for
7205 * drawing attention to their dialogs.
7210 gtk_window_set_keep_above (GtkWindow *window,
7214 GtkWindowPrivate *priv;
7215 GdkWindow *toplevel;
7217 g_return_if_fail (GTK_IS_WINDOW (window));
7219 priv = window->priv;
7220 widget = GTK_WIDGET (window);
7222 priv->above_initially = setting != FALSE;
7224 priv->below_initially = FALSE;
7227 toplevel = priv->frame;
7229 toplevel = gtk_widget_get_window (widget);
7231 if (toplevel != NULL)
7232 gdk_window_set_keep_above (toplevel, setting);
7236 * gtk_window_set_keep_below:
7237 * @window: a #GtkWindow
7238 * @setting: whether to keep @window below other windows
7240 * Asks to keep @window below, so that it stays in bottom. Note that
7241 * you shouldn't assume the window is definitely below afterward,
7242 * because other entities (e.g. the user or <link
7243 * linkend="gtk-X11-arch">window manager</link>) could not keep it below,
7244 * and not all window managers support putting windows below. But
7245 * normally the window will be kept below. Just don't write code
7246 * that crashes if not.
7248 * It's permitted to call this function before showing a window,
7249 * in which case the window will be kept below when it appears onscreen
7252 * You can track the below state via the "window-state-event" signal
7255 * Note that, according to the <ulink
7256 * url="http://www.freedesktop.org/Standards/wm-spec">Extended Window
7257 * Manager Hints</ulink> specification, the above state is mainly meant
7258 * for user preferences and should not be used by applications e.g. for
7259 * drawing attention to their dialogs.
7264 gtk_window_set_keep_below (GtkWindow *window,
7268 GtkWindowPrivate *priv;
7269 GdkWindow *toplevel;
7271 g_return_if_fail (GTK_IS_WINDOW (window));
7273 priv = window->priv;
7274 widget = GTK_WIDGET (window);
7276 priv->below_initially = setting != FALSE;
7278 priv->above_initially = FALSE;
7281 toplevel = priv->frame;
7283 toplevel = gtk_widget_get_window (widget);
7285 if (toplevel != NULL)
7286 gdk_window_set_keep_below (toplevel, setting);
7290 * gtk_window_set_resizable:
7291 * @window: a #GtkWindow
7292 * @resizable: %TRUE if the user can resize this window
7294 * Sets whether the user can resize a window. Windows are user resizable
7298 gtk_window_set_resizable (GtkWindow *window,
7301 GtkWindowPrivate *priv;
7303 g_return_if_fail (GTK_IS_WINDOW (window));
7305 priv = window->priv;
7307 priv->resizable = (resizable != FALSE);
7309 g_object_notify (G_OBJECT (window), "resizable");
7311 gtk_widget_queue_resize_no_redraw (GTK_WIDGET (window));
7315 * gtk_window_get_resizable:
7316 * @window: a #GtkWindow
7318 * Gets the value set by gtk_window_set_resizable().
7320 * Return value: %TRUE if the user can resize the window
7323 gtk_window_get_resizable (GtkWindow *window)
7325 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
7327 return window->priv->resizable;
7331 * gtk_window_set_gravity:
7332 * @window: a #GtkWindow
7333 * @gravity: window gravity
7335 * Window gravity defines the meaning of coordinates passed to
7336 * gtk_window_move(). See gtk_window_move() and #GdkGravity for
7339 * The default window gravity is #GDK_GRAVITY_NORTH_WEST which will
7340 * typically "do what you mean."
7344 gtk_window_set_gravity (GtkWindow *window,
7347 GtkWindowPrivate *priv;
7349 g_return_if_fail (GTK_IS_WINDOW (window));
7351 priv = window->priv;
7353 if (gravity != priv->gravity)
7355 priv->gravity = gravity;
7357 /* gtk_window_move_resize() will adapt gravity
7359 gtk_widget_queue_resize_no_redraw (GTK_WIDGET (window));
7361 g_object_notify (G_OBJECT (window), "gravity");
7366 * gtk_window_get_gravity:
7367 * @window: a #GtkWindow
7369 * Gets the value set by gtk_window_set_gravity().
7371 * Return value: (transfer none): window gravity
7374 gtk_window_get_gravity (GtkWindow *window)
7376 g_return_val_if_fail (GTK_IS_WINDOW (window), 0);
7378 return window->priv->gravity;
7382 * gtk_window_begin_resize_drag:
7383 * @window: a #GtkWindow
7384 * @button: mouse button that initiated the drag
7385 * @edge: position of the resize control
7386 * @root_x: X position where the user clicked to initiate the drag, in root window coordinates
7387 * @root_y: Y position where the user clicked to initiate the drag
7388 * @timestamp: timestamp from the click event that initiated the drag
7390 * Starts resizing a window. This function is used if an application
7391 * has window resizing controls. When GDK can support it, the resize
7392 * will be done using the standard mechanism for the <link
7393 * linkend="gtk-X11-arch">window manager</link> or windowing
7394 * system. Otherwise, GDK will try to emulate window resizing,
7395 * potentially not all that well, depending on the windowing system.
7399 gtk_window_begin_resize_drag (GtkWindow *window,
7406 GtkWindowPrivate *priv;
7408 GdkWindow *toplevel;
7410 g_return_if_fail (GTK_IS_WINDOW (window));
7411 widget = GTK_WIDGET (window);
7412 g_return_if_fail (gtk_widget_get_visible (widget));
7414 priv = window->priv;
7417 toplevel = priv->frame;
7419 toplevel = gtk_widget_get_window (widget);
7421 gdk_window_begin_resize_drag (toplevel,
7428 * gtk_window_get_frame_dimensions:
7429 * @window: a #GtkWindow
7430 * @left: (out) (allow-none): location to store the width of the frame at the left, or %NULL
7431 * @top: (out) (allow-none): location to store the height of the frame at the top, or %NULL
7432 * @right: (out) (allow-none): location to store the width of the frame at the returns, or %NULL
7433 * @bottom: (out) (allow-none): location to store the height of the frame at the bottom, or %NULL
7435 * (Note: this is a special-purpose function intended for the
7436 * framebuffer port; see gtk_window_set_has_frame(). It will not
7437 * return the size of the window border drawn by the <link
7438 * linkend="gtk-X11-arch">window manager</link>, which is the normal
7439 * case when using a windowing system. See
7440 * gdk_window_get_frame_extents() to get the standard window border
7443 * Retrieves the dimensions of the frame window for this toplevel.
7444 * See gtk_window_set_has_frame(), gtk_window_set_frame_dimensions().
7447 gtk_window_get_frame_dimensions (GtkWindow *window,
7453 GtkWindowPrivate *priv;
7455 g_return_if_fail (GTK_IS_WINDOW (window));
7457 priv = window->priv;
7460 *left = priv->frame_left;
7462 *top = priv->frame_top;
7464 *right = priv->frame_right;
7466 *bottom = priv->frame_bottom;
7470 * gtk_window_begin_move_drag:
7471 * @window: a #GtkWindow
7472 * @button: mouse button that initiated the drag
7473 * @root_x: X position where the user clicked to initiate the drag, in root window coordinates
7474 * @root_y: Y position where the user clicked to initiate the drag
7475 * @timestamp: timestamp from the click event that initiated the drag
7477 * Starts moving a window. This function is used if an application has
7478 * window movement grips. When GDK can support it, the window movement
7479 * will be done using the standard mechanism for the <link
7480 * linkend="gtk-X11-arch">window manager</link> or windowing
7481 * system. Otherwise, GDK will try to emulate window movement,
7482 * potentially not all that well, depending on the windowing system.
7486 gtk_window_begin_move_drag (GtkWindow *window,
7492 GtkWindowPrivate *priv;
7494 GdkWindow *toplevel;
7496 g_return_if_fail (GTK_IS_WINDOW (window));
7497 widget = GTK_WIDGET (window);
7498 g_return_if_fail (gtk_widget_get_visible (widget));
7500 priv = window->priv;
7503 toplevel = priv->frame;
7505 toplevel = gtk_widget_get_window (widget);
7507 gdk_window_begin_move_drag (toplevel,
7514 _gtk_window_get_visual (GtkWindow *window)
7516 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
7518 return window->priv->visual;
7522 * gtk_window_set_visual:
7523 * @window: window to set the visual from
7524 * @visual: the new visual to use
7526 * Sets the #GdkVisual used to display @window; if the window
7527 * is already mapped, it will be unmapped, and then remapped
7528 * with the new visual. It is fine if @visual is on a
7529 * different #GdkScreen.
7531 * By default, a window's visual is set to the system visual
7532 * of the default screen.
7535 gtk_window_set_visual (GtkWindow *window,
7538 GtkWindowPrivate *priv;
7540 GdkVisual *previous_visual;
7541 GdkScreen *previous_screen, *screen;
7542 gboolean was_mapped;
7544 g_return_if_fail (GTK_IS_WINDOW (window));
7545 g_return_if_fail (GDK_IS_VISUAL (visual));
7547 priv = window->priv;
7549 if (priv->visual == visual)
7552 widget = GTK_WIDGET (window);
7554 previous_visual = priv->visual;
7555 previous_screen = gdk_visual_get_screen (previous_visual);
7556 screen = gdk_visual_get_screen (visual);
7557 was_mapped = gtk_widget_get_mapped (widget);
7560 gtk_widget_unmap (widget);
7561 if (gtk_widget_get_realized (widget))
7562 gtk_widget_unrealize (widget);
7563 g_object_freeze_notify (G_OBJECT (window));
7565 gtk_window_free_key_hash (window);
7566 priv->visual = visual;
7567 gtk_widget_reset_rc_styles (widget);
7568 if (previous_screen != screen)
7570 g_signal_handlers_disconnect_by_func (previous_screen,
7571 gtk_window_on_composited_changed, window);
7572 g_signal_connect (screen, "composited-changed",
7573 G_CALLBACK (gtk_window_on_composited_changed), window);
7575 _gtk_widget_propagate_screen_changed (widget, previous_screen);
7576 _gtk_widget_propagate_composited_changed (widget);
7577 g_object_notify (G_OBJECT (window), "screen");
7579 g_object_notify (G_OBJECT (window), "visual");
7581 g_object_thaw_notify (G_OBJECT (window));
7583 gtk_widget_map (widget);
7587 * gtk_window_set_screen:
7588 * @window: a #GtkWindow.
7589 * @screen: a #GdkScreen.
7591 * Sets the #GdkScreen where the @window is displayed. If
7592 * the @screen is equal to @window's current screen, this
7593 * function does nothing. If it is not and the window is
7594 * already mapped, it will be unmapped, and then remapped
7595 * on the new screen.
7597 * This function resets @window's visual to the system
7598 * visual of the given @screen. If you want to use a
7599 * different visual, consider using gtk_window_set_visual()
7605 gtk_window_set_screen (GtkWindow *window,
7608 g_return_if_fail (GTK_IS_WINDOW (window));
7609 g_return_if_fail (GDK_IS_SCREEN (screen));
7611 if (screen == gdk_visual_get_screen (window->priv->visual))
7614 gtk_window_set_visual (window,
7615 gdk_screen_get_system_visual (screen));
7619 gtk_window_on_composited_changed (GdkScreen *screen,
7622 gtk_widget_queue_draw (GTK_WIDGET (window));
7624 _gtk_widget_propagate_composited_changed (GTK_WIDGET (window));
7628 gtk_window_check_screen (GtkWindow *window)
7630 GtkWindowPrivate *priv = window->priv;
7633 return gdk_visual_get_screen (priv->visual);
7636 g_warning ("Screen for GtkWindow not set; you must always set\n"
7637 "a screen for a GtkWindow before using the window");
7643 * gtk_window_get_screen:
7644 * @window: a #GtkWindow.
7646 * Returns the #GdkScreen associated with @window.
7648 * Return value: (transfer none): a #GdkScreen.
7653 gtk_window_get_screen (GtkWindow *window)
7655 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
7657 return gdk_visual_get_screen (window->priv->visual);
7661 * gtk_window_is_active:
7662 * @window: a #GtkWindow
7664 * Returns whether the window is part of the current active toplevel.
7665 * (That is, the toplevel window receiving keystrokes.)
7666 * The return value is %TRUE if the window is active toplevel
7667 * itself, but also if it is, say, a #GtkPlug embedded in the active toplevel.
7668 * You might use this function if you wanted to draw a widget
7669 * differently in an active window from a widget in an inactive window.
7670 * See gtk_window_has_toplevel_focus()
7672 * Return value: %TRUE if the window part of the current active window.
7677 gtk_window_is_active (GtkWindow *window)
7679 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
7681 return window->priv->is_active;
7685 * gtk_window_has_toplevel_focus:
7686 * @window: a #GtkWindow
7688 * Returns whether the input focus is within this GtkWindow.
7689 * For real toplevel windows, this is identical to gtk_window_is_active(),
7690 * but for embedded windows, like #GtkPlug, the results will differ.
7692 * Return value: %TRUE if the input focus is within this GtkWindow
7697 gtk_window_has_toplevel_focus (GtkWindow *window)
7699 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
7701 return window->priv->has_toplevel_focus;
7705 gtk_window_group_class_init (GtkWindowGroupClass *klass)
7707 g_type_class_add_private (klass, sizeof (GtkWindowGroupPrivate));
7711 gtk_window_group_get_type (void)
7713 static GType window_group_type = 0;
7715 if (!window_group_type)
7717 const GTypeInfo window_group_info =
7719 sizeof (GtkWindowGroupClass),
7720 NULL, /* base_init */
7721 NULL, /* base_finalize */
7722 (GClassInitFunc) gtk_window_group_class_init,
7723 NULL, /* class_finalize */
7724 NULL, /* class_data */
7725 sizeof (GtkWindowGroup),
7726 0, /* n_preallocs */
7727 (GInstanceInitFunc) NULL,
7730 window_group_type = g_type_register_static (G_TYPE_OBJECT, I_("GtkWindowGroup"),
7731 &window_group_info, 0);
7734 return window_group_type;
7738 * gtk_window_group_new:
7740 * Creates a new #GtkWindowGroup object. Grabs added with
7741 * gtk_grab_add() only affect windows within the same #GtkWindowGroup.
7743 * Return value: a new #GtkWindowGroup.
7746 gtk_window_group_new (void)
7748 return g_object_new (GTK_TYPE_WINDOW_GROUP, NULL);
7752 window_group_cleanup_grabs (GtkWindowGroup *group,
7755 GtkWindowGroupPrivate *priv;
7756 GtkDeviceGrabInfo *info;
7758 GSList *to_remove = NULL;
7760 tmp_list = group->grabs;
7763 if (gtk_widget_get_toplevel (tmp_list->data) == (GtkWidget*) window)
7764 to_remove = g_slist_prepend (to_remove, g_object_ref (tmp_list->data));
7765 tmp_list = tmp_list->next;
7770 gtk_grab_remove (to_remove->data);
7771 g_object_unref (to_remove->data);
7772 to_remove = g_slist_delete_link (to_remove, to_remove);
7775 priv = GTK_WINDOW_GROUP_GET_PRIVATE (group);
7776 tmp_list = priv->device_grabs;
7780 info = tmp_list->data;
7782 if (gtk_widget_get_toplevel (info->widget) == (GtkWidget *) window)
7783 to_remove = g_slist_prepend (to_remove, info);
7785 tmp_list = tmp_list->next;
7790 info = to_remove->data;
7792 gtk_device_grab_remove (info->widget, info->device);
7793 to_remove = g_slist_delete_link (to_remove, to_remove);
7798 * gtk_window_group_add_window:
7799 * @window_group: a #GtkWindowGroup
7800 * @window: the #GtkWindow to add
7802 * Adds a window to a #GtkWindowGroup.
7805 gtk_window_group_add_window (GtkWindowGroup *window_group,
7808 GtkWindowPrivate *priv;
7810 g_return_if_fail (GTK_IS_WINDOW_GROUP (window_group));
7811 g_return_if_fail (GTK_IS_WINDOW (window));
7813 priv = window->priv;
7815 if (priv->group != window_group)
7817 g_object_ref (window);
7818 g_object_ref (window_group);
7821 gtk_window_group_remove_window (priv->group, window);
7823 window_group_cleanup_grabs (gtk_window_get_group (NULL), window);
7825 priv->group = window_group;
7827 g_object_unref (window);
7832 * gtk_window_group_remove_window:
7833 * @window_group: a #GtkWindowGroup
7834 * @window: the #GtkWindow to remove
7836 * Removes a window from a #GtkWindowGroup.
7839 gtk_window_group_remove_window (GtkWindowGroup *window_group,
7842 GtkWindowPrivate *priv;
7844 g_return_if_fail (GTK_IS_WINDOW_GROUP (window_group));
7845 g_return_if_fail (GTK_IS_WINDOW (window));
7846 priv = window->priv;
7847 g_return_if_fail (priv->group == window_group);
7849 g_object_ref (window);
7851 window_group_cleanup_grabs (window_group, window);
7854 g_object_unref (window_group);
7855 g_object_unref (window);
7859 * gtk_window_group_list_windows:
7860 * @window_group: a #GtkWindowGroup
7862 * Returns a list of the #GtkWindows that belong to @window_group.
7864 * Returns: (element-type GtkWidget) (transfer container): A newly-allocated list of
7865 * windows inside the group.
7870 gtk_window_group_list_windows (GtkWindowGroup *window_group)
7872 GList *toplevels, *toplevel, *group_windows;
7874 g_return_val_if_fail (GTK_IS_WINDOW_GROUP (window_group), NULL);
7876 group_windows = NULL;
7877 toplevels = gtk_window_list_toplevels ();
7879 for (toplevel = toplevels; toplevel; toplevel = toplevel->next)
7881 GtkWindow *window = toplevel->data;
7883 if (window_group == window->priv->group)
7884 group_windows = g_list_prepend (group_windows, window);
7887 return g_list_reverse (group_windows);
7891 * gtk_window_get_group:
7892 * @window: (allow-none): a #GtkWindow, or %NULL
7894 * Returns the group for @window or the default group, if
7895 * @window is %NULL or if @window does not have an explicit
7898 * Returns: (transfer none): the #GtkWindowGroup for a window or the default group
7903 gtk_window_get_group (GtkWindow *window)
7905 if (window && window->priv->group)
7906 return window->priv->group;
7909 static GtkWindowGroup *default_group = NULL;
7912 default_group = gtk_window_group_new ();
7914 return default_group;
7919 * gtk_window_has_group:
7920 * @window: a #GtkWindow
7922 * Returns whether @window has an explicit window group.
7924 * Return value: %TRUE if @window has an explicit window group.
7929 gtk_window_has_group (GtkWindow *window)
7931 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
7933 return window->priv->group != NULL;
7937 * gtk_window_group_get_current_grab:
7938 * @window_group: a #GtkWindowGroup
7940 * Gets the current grab widget of the given group,
7941 * see gtk_grab_add().
7943 * Returns: the current grab widget of the group
7948 gtk_window_group_get_current_grab (GtkWindowGroup *window_group)
7950 g_return_val_if_fail (GTK_IS_WINDOW_GROUP (window_group), NULL);
7952 if (window_group->grabs)
7953 return GTK_WIDGET (window_group->grabs->data);
7958 _gtk_window_group_add_device_grab (GtkWindowGroup *window_group,
7961 gboolean block_others)
7963 GtkWindowGroupPrivate *priv;
7964 GtkDeviceGrabInfo *info;
7966 priv = GTK_WINDOW_GROUP_GET_PRIVATE (window_group);
7968 info = g_slice_new0 (GtkDeviceGrabInfo);
7969 info->widget = widget;
7970 info->device = device;
7971 info->block_others = block_others;
7973 priv->device_grabs = g_slist_prepend (priv->device_grabs, info);
7977 _gtk_window_group_remove_device_grab (GtkWindowGroup *window_group,
7981 GtkWindowGroupPrivate *priv;
7982 GtkDeviceGrabInfo *info;
7983 GSList *list, *node = NULL;
7984 GdkDevice *other_device;
7986 priv = GTK_WINDOW_GROUP_GET_PRIVATE (window_group);
7987 other_device = gdk_device_get_associated_device (device);
7988 list = priv->device_grabs;
7994 if (info->widget == widget &&
7995 (info->device == device ||
7996 info->device == other_device))
8009 priv->device_grabs = g_slist_delete_link (priv->device_grabs, node);
8010 g_slice_free (GtkDeviceGrabInfo, info);
8015 * gtk_window_group_get_current_device_grab:
8016 * @window_group: a #GtkWindowGroup
8017 * @device: a #GdkDevice
8019 * Returns the current grab widget for @device, or %NULL if none.
8021 * Returns: The grab widget, or %NULL
8026 gtk_window_group_get_current_device_grab (GtkWindowGroup *window_group,
8029 GtkWindowGroupPrivate *priv;
8030 GtkDeviceGrabInfo *info;
8031 GdkDevice *other_device;
8034 g_return_val_if_fail (GTK_IS_WINDOW_GROUP (window_group), NULL);
8035 g_return_val_if_fail (GDK_IS_DEVICE (device), NULL);
8037 priv = GTK_WINDOW_GROUP_GET_PRIVATE (window_group);
8038 list = priv->device_grabs;
8039 other_device = gdk_device_get_associated_device (device);
8046 if (info->device == device ||
8047 info->device == other_device)
8048 return info->widget;
8055 _gtk_window_group_widget_is_blocked_for_device (GtkWindowGroup *window_group,
8059 GtkWindowGroupPrivate *priv;
8060 GtkDeviceGrabInfo *info;
8061 GdkDevice *other_device;
8064 priv = GTK_WINDOW_GROUP_GET_PRIVATE (window_group);
8065 other_device = gdk_device_get_associated_device (device);
8066 list = priv->device_grabs;
8073 /* Look for blocking grabs on other device pairs
8074 * that have the passed widget within the GTK+ grab.
8076 if (info->block_others &&
8077 info->device != device &&
8078 info->device != other_device &&
8079 (info->widget == widget ||
8080 gtk_widget_is_ancestor (widget, info->widget)))
8088 Derived from XParseGeometry() in XFree86
8090 Copyright 1985, 1986, 1987,1998 The Open Group
8092 All Rights Reserved.
8094 The above copyright notice and this permission notice shall be included
8095 in all copies or substantial portions of the Software.
8097 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
8098 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
8099 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
8100 IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
8101 OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
8102 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
8103 OTHER DEALINGS IN THE SOFTWARE.
8105 Except as contained in this notice, the name of The Open Group shall
8106 not be used in advertising or otherwise to promote the sale, use or
8107 other dealings in this Software without prior written authorization
8108 from The Open Group.
8113 * XParseGeometry parses strings of the form
8114 * "=<width>x<height>{+-}<xoffset>{+-}<yoffset>", where
8115 * width, height, xoffset, and yoffset are unsigned integers.
8116 * Example: "=80x24+300-49"
8117 * The equal sign is optional.
8118 * It returns a bitmask that indicates which of the four values
8119 * were actually found in the string. For each value found,
8120 * the corresponding argument is updated; for each value
8121 * not found, the corresponding argument is left unchanged.
8124 /* The following code is from Xlib, and is minimally modified, so we
8125 * can track any upstream changes if required. Don't change this
8126 * code. Or if you do, put in a huge comment marking which thing
8131 read_int (gchar *string,
8139 else if (*string == '-')
8145 for (; (*string >= '0') && (*string <= '9'); string++)
8147 result = (result * 10) + (*string - '0');
8159 * Bitmask returned by XParseGeometry(). Each bit tells if the corresponding
8160 * value (x, y, width, height) was found in the parsed string.
8162 #define NoValue 0x0000
8163 #define XValue 0x0001
8164 #define YValue 0x0002
8165 #define WidthValue 0x0004
8166 #define HeightValue 0x0008
8167 #define AllValues 0x000F
8168 #define XNegative 0x0010
8169 #define YNegative 0x0020
8171 /* Try not to reformat/modify, so we can compare/sync with X sources */
8173 gtk_XParseGeometry (const char *string,
8176 unsigned int *width,
8177 unsigned int *height)
8181 unsigned int tempWidth, tempHeight;
8183 char *nextCharacter;
8185 /* These initializations are just to silence gcc */
8191 if ( (string == NULL) || (*string == '\0')) return(mask);
8193 string++; /* ignore possible '=' at beg of geometry spec */
8195 strind = (char *)string;
8196 if (*strind != '+' && *strind != '-' && *strind != 'x') {
8197 tempWidth = read_int(strind, &nextCharacter);
8198 if (strind == nextCharacter)
8200 strind = nextCharacter;
8204 if (*strind == 'x' || *strind == 'X') {
8206 tempHeight = read_int(strind, &nextCharacter);
8207 if (strind == nextCharacter)
8209 strind = nextCharacter;
8210 mask |= HeightValue;
8213 if ((*strind == '+') || (*strind == '-')) {
8214 if (*strind == '-') {
8216 tempX = -read_int(strind, &nextCharacter);
8217 if (strind == nextCharacter)
8219 strind = nextCharacter;
8225 tempX = read_int(strind, &nextCharacter);
8226 if (strind == nextCharacter)
8228 strind = nextCharacter;
8231 if ((*strind == '+') || (*strind == '-')) {
8232 if (*strind == '-') {
8234 tempY = -read_int(strind, &nextCharacter);
8235 if (strind == nextCharacter)
8237 strind = nextCharacter;
8244 tempY = read_int(strind, &nextCharacter);
8245 if (strind == nextCharacter)
8247 strind = nextCharacter;
8253 /* If strind isn't at the end of the string the it's an invalid
8254 geometry specification. */
8256 if (*strind != '\0') return (0);
8262 if (mask & WidthValue)
8264 if (mask & HeightValue)
8265 *height = tempHeight;
8270 * gtk_window_parse_geometry:
8271 * @window: a #GtkWindow
8272 * @geometry: geometry string
8274 * Parses a standard X Window System geometry string - see the
8275 * manual page for X (type 'man X') for details on this.
8276 * gtk_window_parse_geometry() does work on all GTK+ ports
8277 * including Win32 but is primarily intended for an X environment.
8279 * If either a size or a position can be extracted from the
8280 * geometry string, gtk_window_parse_geometry() returns %TRUE
8281 * and calls gtk_window_set_default_size() and/or gtk_window_move()
8282 * to resize/move the window.
8284 * If gtk_window_parse_geometry() returns %TRUE, it will also
8285 * set the #GDK_HINT_USER_POS and/or #GDK_HINT_USER_SIZE hints
8286 * indicating to the window manager that the size/position of
8287 * the window was user-specified. This causes most window
8288 * managers to honor the geometry.
8290 * Note that for gtk_window_parse_geometry() to work as expected, it has
8291 * to be called when the window has its "final" size, i.e. after calling
8292 * gtk_widget_show_all() on the contents and gtk_window_set_geometry_hints()
8295 * #include <gtk/gtk.h>
8298 * fill_with_content (GtkWidget *vbox)
8300 * /* fill with content... */
8304 * main (int argc, char *argv[])
8306 * GtkWidget *window, *vbox;
8307 * GdkGeometry size_hints = {
8308 * 100, 50, 0, 0, 100, 50, 10, 10, 0.0, 0.0, GDK_GRAVITY_NORTH_WEST
8311 * gtk_init (&argc, &argv);
8313 * window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
8314 * vbox = gtk_vbox_new (FALSE, 0);
8316 * gtk_container_add (GTK_CONTAINER (window), vbox);
8317 * fill_with_content (vbox);
8318 * gtk_widget_show_all (vbox);
8320 * gtk_window_set_geometry_hints (GTK_WINDOW (window),
8323 * GDK_HINT_MIN_SIZE |
8324 * GDK_HINT_BASE_SIZE |
8325 * GDK_HINT_RESIZE_INC);
8329 * if (!gtk_window_parse_geometry (GTK_WINDOW (window), argv[1]))
8330 * fprintf (stderr, "Failed to parse '%s'\n", argv[1]);
8333 * gtk_widget_show_all (window);
8340 * Return value: %TRUE if string was parsed successfully
8343 gtk_window_parse_geometry (GtkWindow *window,
8344 const gchar *geometry)
8346 gint result, x = 0, y = 0;
8349 gboolean size_set, pos_set;
8352 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
8353 g_return_val_if_fail (geometry != NULL, FALSE);
8355 screen = gtk_window_check_screen (window);
8357 result = gtk_XParseGeometry (geometry, &x, &y, &w, &h);
8360 if ((result & WidthValue) || (result & HeightValue))
8362 gtk_window_set_default_size_internal (window,
8363 TRUE, result & WidthValue ? w : -1,
8364 TRUE, result & HeightValue ? h : -1,
8369 gtk_window_get_size (window, (gint *)&w, (gint *)&h);
8371 grav = GDK_GRAVITY_NORTH_WEST;
8373 if ((result & XNegative) && (result & YNegative))
8374 grav = GDK_GRAVITY_SOUTH_EAST;
8375 else if (result & XNegative)
8376 grav = GDK_GRAVITY_NORTH_EAST;
8377 else if (result & YNegative)
8378 grav = GDK_GRAVITY_SOUTH_WEST;
8380 if ((result & XValue) == 0)
8383 if ((result & YValue) == 0)
8386 if (grav == GDK_GRAVITY_SOUTH_WEST ||
8387 grav == GDK_GRAVITY_SOUTH_EAST)
8388 y = gdk_screen_get_height (screen) - h + y;
8390 if (grav == GDK_GRAVITY_SOUTH_EAST ||
8391 grav == GDK_GRAVITY_NORTH_EAST)
8392 x = gdk_screen_get_width (screen) - w + x;
8394 /* we don't let you put a window offscreen; maybe some people would
8395 * prefer to be able to, but it's kind of a bogus thing to do.
8404 if ((result & XValue) || (result & YValue))
8406 gtk_window_set_gravity (window, grav);
8407 gtk_window_move (window, x, y);
8411 if (size_set || pos_set)
8413 /* Set USSize, USPosition hints */
8414 GtkWindowGeometryInfo *info;
8416 info = gtk_window_get_geometry_info (window, TRUE);
8419 info->mask |= GDK_HINT_USER_POS;
8421 info->mask |= GDK_HINT_USER_SIZE;
8428 gtk_window_mnemonic_hash_foreach (guint keyval,
8434 GtkWindowKeysForeachFunc func;
8438 (*info->func) (info->window, keyval, info->window->priv->mnemonic_modifier, TRUE, info->func_data);
8442 _gtk_window_keys_foreach (GtkWindow *window,
8443 GtkWindowKeysForeachFunc func,
8447 GtkMnemonicHash *mnemonic_hash;
8451 GtkWindowKeysForeachFunc func;
8455 info.window = window;
8457 info.func_data = func_data;
8459 mnemonic_hash = gtk_window_get_mnemonic_hash (window, FALSE);
8461 _gtk_mnemonic_hash_foreach (mnemonic_hash,
8462 gtk_window_mnemonic_hash_foreach, &info);
8464 groups = gtk_accel_groups_from_object (G_OBJECT (window));
8467 GtkAccelGroup *group = groups->data;
8470 for (i = 0; i < group->priv->n_accels; i++)
8472 GtkAccelKey *key = &group->priv->priv_accels[i].key;
8475 (*func) (window, key->accel_key, key->accel_mods, FALSE, func_data);
8478 groups = groups->next;
8483 gtk_window_keys_changed (GtkWindow *window)
8485 gtk_window_free_key_hash (window);
8486 gtk_window_get_key_hash (window);
8489 typedef struct _GtkWindowKeyEntry GtkWindowKeyEntry;
8491 struct _GtkWindowKeyEntry
8495 guint is_mnemonic : 1;
8499 window_key_entry_destroy (gpointer data)
8501 g_slice_free (GtkWindowKeyEntry, data);
8505 add_to_key_hash (GtkWindow *window,
8507 GdkModifierType modifiers,
8508 gboolean is_mnemonic,
8511 GtkKeyHash *key_hash = data;
8513 GtkWindowKeyEntry *entry = g_slice_new (GtkWindowKeyEntry);
8515 entry->keyval = keyval;
8516 entry->modifiers = modifiers;
8517 entry->is_mnemonic = is_mnemonic;
8519 /* GtkAccelGroup stores lowercased accelerators. To deal
8520 * with this, if <Shift> was specified, uppercase.
8522 if (modifiers & GDK_SHIFT_MASK)
8524 if (keyval == GDK_KEY_Tab)
8525 keyval = GDK_KEY_ISO_Left_Tab;
8527 keyval = gdk_keyval_to_upper (keyval);
8530 _gtk_key_hash_add_entry (key_hash, keyval, entry->modifiers, entry);
8534 gtk_window_get_key_hash (GtkWindow *window)
8536 GdkScreen *screen = gtk_window_check_screen (window);
8537 GtkKeyHash *key_hash = g_object_get_qdata (G_OBJECT (window), quark_gtk_window_key_hash);
8542 key_hash = _gtk_key_hash_new (gdk_keymap_get_for_display (gdk_screen_get_display (screen)),
8543 (GDestroyNotify)window_key_entry_destroy);
8544 _gtk_window_keys_foreach (window, add_to_key_hash, key_hash);
8545 g_object_set_qdata (G_OBJECT (window), quark_gtk_window_key_hash, key_hash);
8551 gtk_window_free_key_hash (GtkWindow *window)
8553 GtkKeyHash *key_hash = g_object_get_qdata (G_OBJECT (window), quark_gtk_window_key_hash);
8556 _gtk_key_hash_free (key_hash);
8557 g_object_set_qdata (G_OBJECT (window), quark_gtk_window_key_hash, NULL);
8562 * gtk_window_activate_key:
8563 * @window: a #GtkWindow
8564 * @event: a #GdkEventKey
8566 * Activates mnemonics and accelerators for this #GtkWindow. This is normally
8567 * called by the default ::key_press_event handler for toplevel windows,
8568 * however in some cases it may be useful to call this directly when
8569 * overriding the standard key handling for a toplevel window.
8571 * Return value: %TRUE if a mnemonic or accelerator was found and activated.
8576 gtk_window_activate_key (GtkWindow *window,
8579 GtkKeyHash *key_hash;
8580 GtkWindowKeyEntry *found_entry = NULL;
8581 gboolean enable_mnemonics;
8582 gboolean enable_accels;
8584 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
8585 g_return_val_if_fail (event != NULL, FALSE);
8587 key_hash = gtk_window_get_key_hash (window);
8592 GSList *entries = _gtk_key_hash_lookup (key_hash,
8593 event->hardware_keycode,
8595 gtk_accelerator_get_default_mod_mask (),
8598 g_object_get (gtk_widget_get_settings (GTK_WIDGET (window)),
8599 "gtk-enable-mnemonics", &enable_mnemonics,
8600 "gtk-enable-accels", &enable_accels,
8603 for (tmp_list = entries; tmp_list; tmp_list = tmp_list->next)
8605 GtkWindowKeyEntry *entry = tmp_list->data;
8606 if (entry->is_mnemonic)
8608 if (enable_mnemonics)
8610 found_entry = entry;
8616 if (enable_accels && !found_entry)
8618 found_entry = entry;
8623 g_slist_free (entries);
8628 if (found_entry->is_mnemonic)
8630 if (enable_mnemonics)
8631 return gtk_window_mnemonic_activate (window, found_entry->keyval,
8632 found_entry->modifiers);
8637 return gtk_accel_groups_activate (G_OBJECT (window), found_entry->keyval,
8638 found_entry->modifiers);
8646 window_update_has_focus (GtkWindow *window)
8648 GtkWindowPrivate *priv = window->priv;
8649 GtkWidget *widget = GTK_WIDGET (window);
8650 gboolean has_focus = priv->has_toplevel_focus && priv->is_active;
8652 if (has_focus != priv->has_focus)
8654 priv->has_focus = has_focus;
8658 if (priv->focus_widget &&
8659 priv->focus_widget != widget &&
8660 !gtk_widget_has_focus (priv->focus_widget))
8661 do_focus_change (priv->focus_widget, TRUE);
8665 if (priv->focus_widget &&
8666 priv->focus_widget != widget &&
8667 gtk_widget_has_focus (priv->focus_widget))
8668 do_focus_change (priv->focus_widget, FALSE);
8674 * _gtk_window_set_is_active:
8675 * @window: a #GtkWindow
8676 * @is_active: %TRUE if the window is in the currently active toplevel
8678 * Internal function that sets whether the #GtkWindow is part
8679 * of the currently active toplevel window (taking into account inter-process
8683 _gtk_window_set_is_active (GtkWindow *window,
8686 GtkWindowPrivate *priv;
8688 g_return_if_fail (GTK_IS_WINDOW (window));
8690 priv = window->priv;
8692 is_active = is_active != FALSE;
8694 if (is_active != priv->is_active)
8696 priv->is_active = is_active;
8697 window_update_has_focus (window);
8699 g_object_notify (G_OBJECT (window), "is-active");
8704 * _gtk_window_set_is_toplevel:
8705 * @window: a #GtkWindow
8706 * @is_toplevel: %TRUE if the window is still a real toplevel (nominally a
8707 * parent of the root window); %FALSE if it is not (for example, for an
8708 * in-process, parented GtkPlug)
8710 * Internal function used by #GtkPlug when it gets parented/unparented by a
8711 * #GtkSocket. This keeps the @window's #GTK_TOPLEVEL flag in sync with the
8712 * global list of toplevel windows.
8715 _gtk_window_set_is_toplevel (GtkWindow *window,
8716 gboolean is_toplevel)
8720 widget = GTK_WIDGET (window);
8722 if (gtk_widget_is_toplevel (widget))
8723 g_assert (g_slist_find (toplevel_list, window) != NULL);
8725 g_assert (g_slist_find (toplevel_list, window) == NULL);
8727 if (is_toplevel == gtk_widget_is_toplevel (widget))
8732 _gtk_widget_set_is_toplevel (widget, TRUE);
8733 toplevel_list = g_slist_prepend (toplevel_list, window);
8737 _gtk_widget_set_is_toplevel (widget, FALSE);
8738 toplevel_list = g_slist_remove (toplevel_list, window);
8743 * _gtk_window_set_has_toplevel_focus:
8744 * @window: a #GtkWindow
8745 * @has_toplevel_focus: %TRUE if the in
8747 * Internal function that sets whether the keyboard focus for the
8748 * toplevel window (taking into account inter-process embedding.)
8751 _gtk_window_set_has_toplevel_focus (GtkWindow *window,
8752 gboolean has_toplevel_focus)
8754 GtkWindowPrivate *priv;
8756 g_return_if_fail (GTK_IS_WINDOW (window));
8758 priv = window->priv;
8760 has_toplevel_focus = has_toplevel_focus != FALSE;
8762 if (has_toplevel_focus != priv->has_toplevel_focus)
8764 priv->has_toplevel_focus = has_toplevel_focus;
8765 window_update_has_focus (window);
8767 g_object_notify (G_OBJECT (window), "has-toplevel-focus");
8772 * gtk_window_set_auto_startup_notification:
8773 * @setting: %TRUE to automatically do startup notification
8775 * By default, after showing the first #GtkWindow, GTK+ calls
8776 * gdk_notify_startup_complete(). Call this function to disable
8777 * the automatic startup notification. You might do this if your
8778 * first window is a splash screen, and you want to delay notification
8779 * until after your real main window has been shown, for example.
8781 * In that example, you would disable startup notification
8782 * temporarily, show your splash screen, then re-enable it so that
8783 * showing the main window would automatically result in notification.
8788 gtk_window_set_auto_startup_notification (gboolean setting)
8790 disable_startup_notification = !setting;
8794 * gtk_window_get_window_type:
8795 * @window: a #GtkWindow
8797 * Gets the type of the window. See #GtkWindowType.
8799 * Return value: the type of the window
8804 gtk_window_get_window_type (GtkWindow *window)
8806 g_return_val_if_fail (GTK_IS_WINDOW (window), GTK_WINDOW_TOPLEVEL);
8808 return window->priv->type;
8812 * gtk_window_get_mnemonics_visible:
8813 * @window: a #GtkWindow
8815 * Gets the value of the #GtkWindow:mnemonics-visible property.
8817 * Returns: %TRUE if mnemonics are supposed to be visible
8823 gtk_window_get_mnemonics_visible (GtkWindow *window)
8825 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
8827 return window->priv->mnemonics_visible;
8831 * gtk_window_set_mnemonics_visible:
8832 * @window: a #GtkWindow
8833 * @setting: the new value
8835 * Sets the #GtkWindow:mnemonics-visible property.
8840 gtk_window_set_mnemonics_visible (GtkWindow *window,
8843 GtkWindowPrivate *priv;
8845 g_return_if_fail (GTK_IS_WINDOW (window));
8847 priv = window->priv;
8849 setting = setting != FALSE;
8851 if (priv->mnemonics_visible != setting)
8853 priv->mnemonics_visible = setting;
8854 g_object_notify (G_OBJECT (window), "mnemonics-visible");
8857 priv->mnemonics_visible_set = TRUE;
8861 _gtk_window_get_wmclass (GtkWindow *window,
8862 gchar **wmclass_name,
8863 gchar **wmclass_class)
8865 GtkWindowPrivate *priv = window->priv;
8867 *wmclass_name = priv->wmclass_name;
8868 *wmclass_class = priv->wmclass_class;