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"
51 #include "gtkextendedlayout.h"
54 #ifdef GDK_WINDOWING_X11
83 PROP_DESTROY_WITH_PARENT,
88 PROP_SKIP_TASKBAR_HINT,
99 /* Readonly properties */
101 PROP_HAS_TOPLEVEL_FOCUS,
103 /* Writeonly properties */
106 PROP_MNEMONICS_VISIBLE,
114 GdkPixmap *icon_pixmap;
115 GdkPixmap *icon_mask;
118 guint using_default_icon : 1;
119 guint using_parent_icon : 1;
120 guint using_themed_icon : 1;
124 GdkGeometry geometry; /* Last set of geometry hints we set */
125 GdkWindowHints flags;
126 GdkRectangle configure_request;
127 } GtkWindowLastGeometryInfo;
129 struct _GtkWindowGeometryInfo
131 /* Properties that the app has set on the window
133 GdkGeometry geometry; /* Geometry hints */
135 GtkWidget *widget; /* subwidget to which hints apply */
136 /* from last gtk_window_resize () - if > 0, indicates that
137 * we should resize to this size.
142 /* From last gtk_window_move () prior to mapping -
143 * only used if initial_pos_set
148 /* Default size - used only the FIRST time we map a window,
153 /* whether to use initial_x, initial_y */
154 guint initial_pos_set : 1;
155 /* CENTER_ALWAYS or other position constraint changed since
156 * we sent the last configure request.
158 guint position_constraints_changed : 1;
160 /* if true, default_width, height come from gtk_window_parse_geometry,
161 * and thus should be multiplied by the increments and affect the
162 * geometry widget only
164 guint default_is_geometry : 1;
166 GtkWindowLastGeometryInfo last;
169 #define GTK_WINDOW_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GTK_TYPE_WINDOW, GtkWindowPrivate))
170 #define GTK_WINDOW_GROUP_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GTK_TYPE_WINDOW_GROUP, GtkWindowGroupPrivate))
172 typedef struct _GtkWindowPrivate GtkWindowPrivate;
174 struct _GtkWindowPrivate
176 GtkMnemonicHash *mnemonic_hash;
178 guint above_initially : 1;
179 guint below_initially : 1;
180 guint fullscreen_initially : 1;
181 guint skips_taskbar : 1;
182 guint skips_pager : 1;
184 guint accept_focus : 1;
185 guint focus_on_map : 1;
187 guint transient_parent_group : 1;
189 guint reset_type_hint : 1;
190 guint opacity_set : 1;
191 guint builder_visible : 1;
193 guint mnemonics_visible : 1;
194 guint mnemonics_visible_set : 1;
196 GdkWindowTypeHint type_hint;
203 typedef struct _GtkDeviceGrabInfo GtkDeviceGrabInfo;
204 typedef struct _GtkWindowGroupPrivate GtkWindowGroupPrivate;
206 struct _GtkDeviceGrabInfo
210 guint block_others : 1;
213 struct _GtkWindowGroupPrivate
215 GSList *device_grabs;
218 static void gtk_window_dispose (GObject *object);
219 static void gtk_window_destroy (GtkObject *object);
220 static void gtk_window_finalize (GObject *object);
221 static void gtk_window_show (GtkWidget *widget);
222 static void gtk_window_hide (GtkWidget *widget);
223 static void gtk_window_map (GtkWidget *widget);
224 static void gtk_window_unmap (GtkWidget *widget);
225 static void gtk_window_realize (GtkWidget *widget);
226 static void gtk_window_unrealize (GtkWidget *widget);
227 static void gtk_window_size_allocate (GtkWidget *widget,
228 GtkAllocation *allocation);
229 static gint gtk_window_event (GtkWidget *widget,
231 static gboolean gtk_window_map_event (GtkWidget *widget,
233 static gboolean gtk_window_frame_event (GtkWindow *window,
235 static gint gtk_window_configure_event (GtkWidget *widget,
236 GdkEventConfigure *event);
237 static gint gtk_window_key_press_event (GtkWidget *widget,
239 static gint gtk_window_key_release_event (GtkWidget *widget,
241 static gint gtk_window_enter_notify_event (GtkWidget *widget,
242 GdkEventCrossing *event);
243 static gint gtk_window_leave_notify_event (GtkWidget *widget,
244 GdkEventCrossing *event);
245 static gint gtk_window_focus_in_event (GtkWidget *widget,
246 GdkEventFocus *event);
247 static gint gtk_window_focus_out_event (GtkWidget *widget,
248 GdkEventFocus *event);
249 static gint gtk_window_client_event (GtkWidget *widget,
250 GdkEventClient *event);
251 static void gtk_window_check_resize (GtkContainer *container);
252 static gint gtk_window_focus (GtkWidget *widget,
253 GtkDirectionType direction);
254 static void gtk_window_real_set_focus (GtkWindow *window,
257 static void gtk_window_real_activate_default (GtkWindow *window);
258 static void gtk_window_real_activate_focus (GtkWindow *window);
259 static void gtk_window_move_focus (GtkWindow *window,
260 GtkDirectionType dir);
261 static void gtk_window_keys_changed (GtkWindow *window);
262 static void gtk_window_paint (GtkWidget *widget,
264 static gint gtk_window_expose (GtkWidget *widget,
265 GdkEventExpose *event);
266 static void gtk_window_unset_transient_for (GtkWindow *window);
267 static void gtk_window_transient_parent_realized (GtkWidget *parent,
269 static void gtk_window_transient_parent_unrealized (GtkWidget *parent,
272 static GdkScreen *gtk_window_check_screen (GtkWindow *window);
274 static GtkWindowGeometryInfo* gtk_window_get_geometry_info (GtkWindow *window,
277 static void gtk_window_move_resize (GtkWindow *window);
278 static gboolean gtk_window_compare_hints (GdkGeometry *geometry_a,
280 GdkGeometry *geometry_b,
282 static void gtk_window_constrain_size (GtkWindow *window,
283 GdkGeometry *geometry,
289 static void gtk_window_constrain_position (GtkWindow *window,
294 static void gtk_window_compute_hints (GtkWindow *window,
295 GdkGeometry *new_geometry,
297 static void gtk_window_compute_configure_request (GtkWindow *window,
298 GdkRectangle *request,
299 GdkGeometry *geometry,
302 static void gtk_window_set_default_size_internal (GtkWindow *window,
303 gboolean change_width,
305 gboolean change_height,
307 gboolean is_geometry);
309 static void update_themed_icon (GtkIconTheme *theme,
311 static GList *icon_list_from_theme (GtkWidget *widget,
313 static void gtk_window_realize_icon (GtkWindow *window);
314 static void gtk_window_unrealize_icon (GtkWindow *window);
316 static void gtk_window_notify_keys_changed (GtkWindow *window);
317 static GtkKeyHash *gtk_window_get_key_hash (GtkWindow *window);
318 static void gtk_window_free_key_hash (GtkWindow *window);
319 static void gtk_window_on_composited_changed (GdkScreen *screen,
322 static GSList *toplevel_list = NULL;
323 static guint window_signals[LAST_SIGNAL] = { 0 };
324 static GList *default_icon_list = NULL;
325 static gchar *default_icon_name = NULL;
326 static guint default_icon_serial = 0;
327 static gboolean disable_startup_notification = FALSE;
328 static gboolean sent_startup_notification = FALSE;
330 static GQuark quark_gtk_embedded = 0;
331 static GQuark quark_gtk_window_key_hash = 0;
332 static GQuark quark_gtk_window_default_icon_pixmap = 0;
333 static GQuark quark_gtk_window_icon_info = 0;
334 static GQuark quark_gtk_buildable_accels = 0;
336 static GtkBuildableIface *parent_buildable_iface;
338 static void gtk_window_set_property (GObject *object,
342 static void gtk_window_get_property (GObject *object,
348 static void gtk_window_buildable_interface_init (GtkBuildableIface *iface);
349 static void gtk_window_buildable_set_buildable_property (GtkBuildable *buildable,
352 const GValue *value);
353 static void gtk_window_buildable_parser_finished (GtkBuildable *buildable,
354 GtkBuilder *builder);
355 static gboolean gtk_window_buildable_custom_tag_start (GtkBuildable *buildable,
358 const gchar *tagname,
359 GMarkupParser *parser,
361 static void gtk_window_buildable_custom_finished (GtkBuildable *buildable,
364 const gchar *tagname,
368 static void gtk_window_extended_layout_init (GtkExtendedLayoutIface *iface);
369 static void gtk_window_get_desired_width (GtkExtendedLayout *layout,
372 static void gtk_window_get_desired_height (GtkExtendedLayout *layout,
376 G_DEFINE_TYPE_WITH_CODE (GtkWindow, gtk_window, GTK_TYPE_BIN,
377 G_IMPLEMENT_INTERFACE (GTK_TYPE_BUILDABLE,
378 gtk_window_buildable_interface_init)
379 G_IMPLEMENT_INTERFACE (GTK_TYPE_EXTENDED_LAYOUT,
380 gtk_window_extended_layout_init))
383 add_tab_bindings (GtkBindingSet *binding_set,
384 GdkModifierType modifiers,
385 GtkDirectionType direction)
387 gtk_binding_entry_add_signal (binding_set, GDK_Tab, modifiers,
389 GTK_TYPE_DIRECTION_TYPE, direction);
390 gtk_binding_entry_add_signal (binding_set, GDK_KP_Tab, modifiers,
392 GTK_TYPE_DIRECTION_TYPE, direction);
396 add_arrow_bindings (GtkBindingSet *binding_set,
398 GtkDirectionType direction)
400 guint keypad_keysym = keysym - GDK_Left + GDK_KP_Left;
402 gtk_binding_entry_add_signal (binding_set, keysym, 0,
404 GTK_TYPE_DIRECTION_TYPE, direction);
405 gtk_binding_entry_add_signal (binding_set, keysym, GDK_CONTROL_MASK,
407 GTK_TYPE_DIRECTION_TYPE, direction);
408 gtk_binding_entry_add_signal (binding_set, keypad_keysym, 0,
410 GTK_TYPE_DIRECTION_TYPE, direction);
411 gtk_binding_entry_add_signal (binding_set, keypad_keysym, GDK_CONTROL_MASK,
413 GTK_TYPE_DIRECTION_TYPE, direction);
417 extract_time_from_startup_id (const gchar* startup_id)
419 gchar *timestr = g_strrstr (startup_id, "_TIME");
420 guint32 retval = GDK_CURRENT_TIME;
427 /* Skip past the "_TIME" part */
431 timestamp = strtoul (timestr, &end, 0);
432 if (end != timestr && errno == 0)
440 startup_id_is_fake (const gchar* startup_id)
442 return strncmp (startup_id, "_TIME", 5) == 0;
446 gtk_window_class_init (GtkWindowClass *klass)
448 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
449 GtkObjectClass *object_class;
450 GtkWidgetClass *widget_class;
451 GtkContainerClass *container_class;
452 GtkBindingSet *binding_set;
454 object_class = (GtkObjectClass*) klass;
455 widget_class = (GtkWidgetClass*) klass;
456 container_class = (GtkContainerClass*) klass;
458 quark_gtk_embedded = g_quark_from_static_string ("gtk-embedded");
459 quark_gtk_window_key_hash = g_quark_from_static_string ("gtk-window-key-hash");
460 quark_gtk_window_default_icon_pixmap = g_quark_from_static_string ("gtk-window-default-icon-pixmap");
461 quark_gtk_window_icon_info = g_quark_from_static_string ("gtk-window-icon-info");
462 quark_gtk_buildable_accels = g_quark_from_static_string ("gtk-window-buildable-accels");
464 gobject_class->dispose = gtk_window_dispose;
465 gobject_class->finalize = gtk_window_finalize;
467 gobject_class->set_property = gtk_window_set_property;
468 gobject_class->get_property = gtk_window_get_property;
470 object_class->destroy = gtk_window_destroy;
472 widget_class->show = gtk_window_show;
473 widget_class->hide = gtk_window_hide;
474 widget_class->map = gtk_window_map;
475 widget_class->map_event = gtk_window_map_event;
476 widget_class->unmap = gtk_window_unmap;
477 widget_class->realize = gtk_window_realize;
478 widget_class->unrealize = gtk_window_unrealize;
479 widget_class->size_allocate = gtk_window_size_allocate;
480 widget_class->configure_event = gtk_window_configure_event;
481 widget_class->key_press_event = gtk_window_key_press_event;
482 widget_class->key_release_event = gtk_window_key_release_event;
483 widget_class->enter_notify_event = gtk_window_enter_notify_event;
484 widget_class->leave_notify_event = gtk_window_leave_notify_event;
485 widget_class->focus_in_event = gtk_window_focus_in_event;
486 widget_class->focus_out_event = gtk_window_focus_out_event;
487 widget_class->client_event = gtk_window_client_event;
488 widget_class->focus = gtk_window_focus;
489 widget_class->expose_event = gtk_window_expose;
491 container_class->check_resize = gtk_window_check_resize;
493 klass->set_focus = gtk_window_real_set_focus;
494 klass->frame_event = gtk_window_frame_event;
496 klass->activate_default = gtk_window_real_activate_default;
497 klass->activate_focus = gtk_window_real_activate_focus;
498 klass->move_focus = gtk_window_move_focus;
499 klass->keys_changed = gtk_window_keys_changed;
501 g_type_class_add_private (gobject_class, sizeof (GtkWindowPrivate));
504 g_object_class_install_property (gobject_class,
506 g_param_spec_enum ("type",
508 P_("The type of the window"),
509 GTK_TYPE_WINDOW_TYPE,
511 GTK_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
513 g_object_class_install_property (gobject_class,
515 g_param_spec_string ("title",
517 P_("The title of the window"),
519 GTK_PARAM_READWRITE));
521 g_object_class_install_property (gobject_class,
523 g_param_spec_string ("role",
525 P_("Unique identifier for the window to be used when restoring a session"),
527 GTK_PARAM_READWRITE));
530 * GtkWindow:startup-id:
532 * The :startup-id is a write-only property for setting window's
533 * startup notification identifier. See gtk_window_set_startup_id()
538 g_object_class_install_property (gobject_class,
540 g_param_spec_string ("startup-id",
542 P_("Unique startup identifier for the window used by startup-notification"),
544 GTK_PARAM_WRITABLE));
546 g_object_class_install_property (gobject_class,
548 g_param_spec_boolean ("allow-shrink",
550 /* xgettext:no-c-format */
551 P_("If TRUE, the window has no mimimum size. Setting this to TRUE is 99% of the time a bad idea"),
553 GTK_PARAM_READWRITE));
555 g_object_class_install_property (gobject_class,
557 g_param_spec_boolean ("allow-grow",
559 P_("If TRUE, users can expand the window beyond its minimum size"),
561 GTK_PARAM_READWRITE));
563 g_object_class_install_property (gobject_class,
565 g_param_spec_boolean ("resizable",
567 P_("If TRUE, users can resize the window"),
569 GTK_PARAM_READWRITE));
571 g_object_class_install_property (gobject_class,
573 g_param_spec_boolean ("modal",
575 P_("If TRUE, the window is modal (other windows are not usable while this one is up)"),
577 GTK_PARAM_READWRITE));
579 g_object_class_install_property (gobject_class,
581 g_param_spec_enum ("window-position",
582 P_("Window Position"),
583 P_("The initial position of the window"),
584 GTK_TYPE_WINDOW_POSITION,
586 GTK_PARAM_READWRITE));
588 g_object_class_install_property (gobject_class,
590 g_param_spec_int ("default-width",
592 P_("The default width of the window, used when initially showing the window"),
596 GTK_PARAM_READWRITE));
598 g_object_class_install_property (gobject_class,
600 g_param_spec_int ("default-height",
601 P_("Default Height"),
602 P_("The default height of the window, used when initially showing the window"),
606 GTK_PARAM_READWRITE));
608 g_object_class_install_property (gobject_class,
609 PROP_DESTROY_WITH_PARENT,
610 g_param_spec_boolean ("destroy-with-parent",
611 P_("Destroy with Parent"),
612 P_("If this window should be destroyed when the parent is destroyed"),
614 GTK_PARAM_READWRITE));
616 g_object_class_install_property (gobject_class,
618 g_param_spec_object ("icon",
620 P_("Icon for this window"),
622 GTK_PARAM_READWRITE));
623 g_object_class_install_property (gobject_class,
624 PROP_MNEMONICS_VISIBLE,
625 g_param_spec_boolean ("mnemonics-visible",
626 P_("Mnemonics Visible"),
627 P_("Whether mnemonics are currently visible in this window"),
629 GTK_PARAM_READWRITE));
632 * GtkWindow:icon-name:
634 * The :icon-name property specifies the name of the themed icon to
635 * use as the window icon. See #GtkIconTheme for more details.
639 g_object_class_install_property (gobject_class,
641 g_param_spec_string ("icon-name",
643 P_("Name of the themed icon for this window"),
645 GTK_PARAM_READWRITE));
647 g_object_class_install_property (gobject_class,
649 g_param_spec_object ("screen",
651 P_("The screen where this window will be displayed"),
653 GTK_PARAM_READWRITE));
655 g_object_class_install_property (gobject_class,
657 g_param_spec_boolean ("is-active",
659 P_("Whether the toplevel is the current active window"),
661 GTK_PARAM_READABLE));
663 g_object_class_install_property (gobject_class,
664 PROP_HAS_TOPLEVEL_FOCUS,
665 g_param_spec_boolean ("has-toplevel-focus",
666 P_("Focus in Toplevel"),
667 P_("Whether the input focus is within this GtkWindow"),
669 GTK_PARAM_READABLE));
671 g_object_class_install_property (gobject_class,
673 g_param_spec_enum ("type-hint",
675 P_("Hint to help the desktop environment understand what kind of window this is and how to treat it."),
676 GDK_TYPE_WINDOW_TYPE_HINT,
677 GDK_WINDOW_TYPE_HINT_NORMAL,
678 GTK_PARAM_READWRITE));
680 g_object_class_install_property (gobject_class,
681 PROP_SKIP_TASKBAR_HINT,
682 g_param_spec_boolean ("skip-taskbar-hint",
684 P_("TRUE if the window should not be in the task bar."),
686 GTK_PARAM_READWRITE));
688 g_object_class_install_property (gobject_class,
689 PROP_SKIP_PAGER_HINT,
690 g_param_spec_boolean ("skip-pager-hint",
692 P_("TRUE if the window should not be in the pager."),
694 GTK_PARAM_READWRITE));
696 g_object_class_install_property (gobject_class,
698 g_param_spec_boolean ("urgency-hint",
700 P_("TRUE if the window should be brought to the user's attention."),
702 GTK_PARAM_READWRITE));
705 * GtkWindow:accept-focus:
707 * Whether the window should receive the input focus.
711 g_object_class_install_property (gobject_class,
713 g_param_spec_boolean ("accept-focus",
715 P_("TRUE if the window should receive the input focus."),
717 GTK_PARAM_READWRITE));
720 * GtkWindow:focus-on-map:
722 * Whether the window should receive the input focus when mapped.
726 g_object_class_install_property (gobject_class,
728 g_param_spec_boolean ("focus-on-map",
730 P_("TRUE if the window should receive the input focus when mapped."),
732 GTK_PARAM_READWRITE));
735 * GtkWindow:decorated:
737 * Whether the window should be decorated by the window manager.
741 g_object_class_install_property (gobject_class,
743 g_param_spec_boolean ("decorated",
745 P_("Whether the window should be decorated by the window manager"),
747 GTK_PARAM_READWRITE));
750 * GtkWindow:deletable:
752 * Whether the window frame should have a close button.
756 g_object_class_install_property (gobject_class,
758 g_param_spec_boolean ("deletable",
760 P_("Whether the window frame should have a close button"),
762 GTK_PARAM_READWRITE));
768 * The window gravity of the window. See gtk_window_move() and #GdkGravity for
769 * more details about window gravity.
773 g_object_class_install_property (gobject_class,
775 g_param_spec_enum ("gravity",
777 P_("The window gravity of the window"),
779 GDK_GRAVITY_NORTH_WEST,
780 GTK_PARAM_READWRITE));
784 * GtkWindow:transient-for:
786 * The transient parent of the window. See gtk_window_set_transient_for() for
787 * more details about transient windows.
791 g_object_class_install_property (gobject_class,
793 g_param_spec_object ("transient-for",
794 P_("Transient for Window"),
795 P_("The transient parent of the dialog"),
797 GTK_PARAM_READWRITE| G_PARAM_CONSTRUCT));
802 * The requested opacity of the window. See gtk_window_set_opacity() for
803 * more details about window opacity.
807 g_object_class_install_property (gobject_class,
809 g_param_spec_double ("opacity",
810 P_("Opacity for Window"),
811 P_("The opacity of the window, from 0 to 1"),
815 GTK_PARAM_READWRITE));
817 window_signals[SET_FOCUS] =
818 g_signal_new (I_("set-focus"),
819 G_TYPE_FROM_CLASS (gobject_class),
821 G_STRUCT_OFFSET (GtkWindowClass, set_focus),
823 _gtk_marshal_VOID__OBJECT,
827 window_signals[FRAME_EVENT] =
828 g_signal_new (I_("frame-event"),
829 G_TYPE_FROM_CLASS (gobject_class),
831 G_STRUCT_OFFSET(GtkWindowClass, frame_event),
832 _gtk_boolean_handled_accumulator, NULL,
833 _gtk_marshal_BOOLEAN__BOXED,
838 * GtkWindow::activate-focus:
839 * @window: the window which received the signal
841 * The ::activate-default signal is a
842 * <link linkend="keybinding-signals">keybinding signal</link>
843 * which gets emitted when the user activates the currently
844 * focused widget of @window.
846 window_signals[ACTIVATE_FOCUS] =
847 g_signal_new (I_("activate-focus"),
848 G_TYPE_FROM_CLASS (gobject_class),
849 G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
850 G_STRUCT_OFFSET (GtkWindowClass, activate_focus),
852 _gtk_marshal_VOID__VOID,
857 * GtkWindow::activate-default:
858 * @window: the window which received the signal
860 * The ::activate-default signal is a
861 * <link linkend="keybinding-signals">keybinding signal</link>
862 * which gets emitted when the user activates the default widget
865 window_signals[ACTIVATE_DEFAULT] =
866 g_signal_new (I_("activate-default"),
867 G_TYPE_FROM_CLASS (gobject_class),
868 G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
869 G_STRUCT_OFFSET (GtkWindowClass, activate_default),
871 _gtk_marshal_VOID__VOID,
876 * GtkWindow::keys-changed:
877 * @window: the window which received the signal
879 * The ::keys-changed signal gets emitted when the set of accelerators
880 * or mnemonics that are associated with @window changes.
882 window_signals[KEYS_CHANGED] =
883 g_signal_new (I_("keys-changed"),
884 G_TYPE_FROM_CLASS (gobject_class),
886 G_STRUCT_OFFSET (GtkWindowClass, keys_changed),
888 _gtk_marshal_VOID__VOID,
896 binding_set = gtk_binding_set_by_class (klass);
898 gtk_binding_entry_add_signal (binding_set, GDK_space, 0,
899 "activate-focus", 0);
900 gtk_binding_entry_add_signal (binding_set, GDK_KP_Space, 0,
901 "activate-focus", 0);
903 gtk_binding_entry_add_signal (binding_set, GDK_Return, 0,
904 "activate-default", 0);
905 gtk_binding_entry_add_signal (binding_set, GDK_ISO_Enter, 0,
906 "activate-default", 0);
907 gtk_binding_entry_add_signal (binding_set, GDK_KP_Enter, 0,
908 "activate-default", 0);
910 add_arrow_bindings (binding_set, GDK_Up, GTK_DIR_UP);
911 add_arrow_bindings (binding_set, GDK_Down, GTK_DIR_DOWN);
912 add_arrow_bindings (binding_set, GDK_Left, GTK_DIR_LEFT);
913 add_arrow_bindings (binding_set, GDK_Right, GTK_DIR_RIGHT);
915 add_tab_bindings (binding_set, 0, GTK_DIR_TAB_FORWARD);
916 add_tab_bindings (binding_set, GDK_CONTROL_MASK, GTK_DIR_TAB_FORWARD);
917 add_tab_bindings (binding_set, GDK_SHIFT_MASK, GTK_DIR_TAB_BACKWARD);
918 add_tab_bindings (binding_set, GDK_CONTROL_MASK | GDK_SHIFT_MASK, GTK_DIR_TAB_BACKWARD);
922 gtk_window_init (GtkWindow *window)
924 GdkColormap *colormap;
925 GtkWindowPrivate *priv = GTK_WINDOW_GET_PRIVATE (window);
927 gtk_widget_set_has_window (GTK_WIDGET (window), TRUE);
928 _gtk_widget_set_is_toplevel (GTK_WIDGET (window), TRUE);
930 GTK_PRIVATE_SET_FLAG (window, GTK_ANCHORED);
932 gtk_container_set_resize_mode (GTK_CONTAINER (window), GTK_RESIZE_QUEUE);
934 window->title = NULL;
935 window->wmclass_name = g_strdup (g_get_prgname ());
936 window->wmclass_class = g_strdup (gdk_get_program_class ());
937 window->wm_role = NULL;
938 window->geometry_info = NULL;
939 window->type = GTK_WINDOW_TOPLEVEL;
940 window->focus_widget = NULL;
941 window->default_widget = NULL;
942 window->configure_request_count = 0;
943 window->allow_shrink = FALSE;
944 window->allow_grow = TRUE;
945 window->configure_notify_received = FALSE;
946 window->position = GTK_WIN_POS_NONE;
947 window->need_default_size = TRUE;
948 window->need_default_position = TRUE;
949 window->modal = FALSE;
950 window->frame = NULL;
951 window->has_frame = FALSE;
952 window->frame_left = 0;
953 window->frame_right = 0;
954 window->frame_top = 0;
955 window->frame_bottom = 0;
956 window->type_hint = GDK_WINDOW_TYPE_HINT_NORMAL;
957 window->gravity = GDK_GRAVITY_NORTH_WEST;
958 window->decorated = TRUE;
959 window->mnemonic_modifier = GDK_MOD1_MASK;
960 window->screen = gdk_screen_get_default ();
962 priv->accept_focus = TRUE;
963 priv->focus_on_map = TRUE;
964 priv->deletable = TRUE;
965 priv->type_hint = GDK_WINDOW_TYPE_HINT_NORMAL;
967 priv->startup_id = NULL;
968 priv->mnemonics_visible = TRUE;
970 colormap = _gtk_widget_peek_colormap ();
972 gtk_widget_set_colormap (GTK_WIDGET (window), colormap);
974 g_object_ref_sink (window);
975 window->has_user_ref_count = TRUE;
976 toplevel_list = g_slist_prepend (toplevel_list, window);
978 gtk_decorated_window_init (window);
980 g_signal_connect (window->screen, "composited-changed",
981 G_CALLBACK (gtk_window_on_composited_changed), window);
985 gtk_window_set_property (GObject *object,
991 GtkWindowPrivate *priv;
993 window = GTK_WINDOW (object);
995 priv = GTK_WINDOW_GET_PRIVATE (window);
1000 window->type = g_value_get_enum (value);
1003 gtk_window_set_title (window, g_value_get_string (value));
1006 gtk_window_set_role (window, g_value_get_string (value));
1008 case PROP_STARTUP_ID:
1009 gtk_window_set_startup_id (window, g_value_get_string (value));
1011 case PROP_ALLOW_SHRINK:
1012 window->allow_shrink = g_value_get_boolean (value);
1013 gtk_widget_queue_resize (GTK_WIDGET (window));
1015 case PROP_ALLOW_GROW:
1016 window->allow_grow = g_value_get_boolean (value);
1017 gtk_widget_queue_resize (GTK_WIDGET (window));
1018 g_object_notify (G_OBJECT (window), "resizable");
1020 case PROP_RESIZABLE:
1021 window->allow_grow = g_value_get_boolean (value);
1022 gtk_widget_queue_resize (GTK_WIDGET (window));
1023 g_object_notify (G_OBJECT (window), "allow-grow");
1026 gtk_window_set_modal (window, g_value_get_boolean (value));
1029 gtk_window_set_position (window, g_value_get_enum (value));
1031 case PROP_DEFAULT_WIDTH:
1032 gtk_window_set_default_size_internal (window,
1033 TRUE, g_value_get_int (value),
1036 case PROP_DEFAULT_HEIGHT:
1037 gtk_window_set_default_size_internal (window,
1039 TRUE, g_value_get_int (value), FALSE);
1041 case PROP_DESTROY_WITH_PARENT:
1042 gtk_window_set_destroy_with_parent (window, g_value_get_boolean (value));
1045 gtk_window_set_icon (window,
1046 g_value_get_object (value));
1048 case PROP_ICON_NAME:
1049 gtk_window_set_icon_name (window, g_value_get_string (value));
1052 gtk_window_set_screen (window, g_value_get_object (value));
1054 case PROP_TYPE_HINT:
1055 gtk_window_set_type_hint (window,
1056 g_value_get_enum (value));
1058 case PROP_SKIP_TASKBAR_HINT:
1059 gtk_window_set_skip_taskbar_hint (window,
1060 g_value_get_boolean (value));
1062 case PROP_SKIP_PAGER_HINT:
1063 gtk_window_set_skip_pager_hint (window,
1064 g_value_get_boolean (value));
1066 case PROP_URGENCY_HINT:
1067 gtk_window_set_urgency_hint (window,
1068 g_value_get_boolean (value));
1070 case PROP_ACCEPT_FOCUS:
1071 gtk_window_set_accept_focus (window,
1072 g_value_get_boolean (value));
1074 case PROP_FOCUS_ON_MAP:
1075 gtk_window_set_focus_on_map (window,
1076 g_value_get_boolean (value));
1078 case PROP_DECORATED:
1079 gtk_window_set_decorated (window, g_value_get_boolean (value));
1081 case PROP_DELETABLE:
1082 gtk_window_set_deletable (window, g_value_get_boolean (value));
1085 gtk_window_set_gravity (window, g_value_get_enum (value));
1087 case PROP_TRANSIENT_FOR:
1088 gtk_window_set_transient_for (window, g_value_get_object (value));
1091 gtk_window_set_opacity (window, g_value_get_double (value));
1093 case PROP_MNEMONICS_VISIBLE:
1094 gtk_window_set_mnemonics_visible (window, g_value_get_boolean (value));
1097 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1103 gtk_window_get_property (GObject *object,
1109 GtkWindowPrivate *priv;
1111 window = GTK_WINDOW (object);
1112 priv = GTK_WINDOW_GET_PRIVATE (window);
1116 GtkWindowGeometryInfo *info;
1118 g_value_set_enum (value, window->type);
1121 g_value_set_string (value, window->wm_role);
1124 g_value_set_string (value, window->title);
1126 case PROP_ALLOW_SHRINK:
1127 g_value_set_boolean (value, window->allow_shrink);
1129 case PROP_ALLOW_GROW:
1130 g_value_set_boolean (value, window->allow_grow);
1132 case PROP_RESIZABLE:
1133 g_value_set_boolean (value, window->allow_grow);
1136 g_value_set_boolean (value, window->modal);
1139 g_value_set_enum (value, window->position);
1141 case PROP_DEFAULT_WIDTH:
1142 info = gtk_window_get_geometry_info (window, FALSE);
1144 g_value_set_int (value, -1);
1146 g_value_set_int (value, info->default_width);
1148 case PROP_DEFAULT_HEIGHT:
1149 info = gtk_window_get_geometry_info (window, FALSE);
1151 g_value_set_int (value, -1);
1153 g_value_set_int (value, info->default_height);
1155 case PROP_DESTROY_WITH_PARENT:
1156 g_value_set_boolean (value, window->destroy_with_parent);
1159 g_value_set_object (value, gtk_window_get_icon (window));
1161 case PROP_ICON_NAME:
1162 g_value_set_string (value, gtk_window_get_icon_name (window));
1165 g_value_set_object (value, window->screen);
1167 case PROP_IS_ACTIVE:
1168 g_value_set_boolean (value, window->is_active);
1170 case PROP_HAS_TOPLEVEL_FOCUS:
1171 g_value_set_boolean (value, window->has_toplevel_focus);
1173 case PROP_TYPE_HINT:
1174 g_value_set_enum (value, priv->type_hint);
1176 case PROP_SKIP_TASKBAR_HINT:
1177 g_value_set_boolean (value,
1178 gtk_window_get_skip_taskbar_hint (window));
1180 case PROP_SKIP_PAGER_HINT:
1181 g_value_set_boolean (value,
1182 gtk_window_get_skip_pager_hint (window));
1184 case PROP_URGENCY_HINT:
1185 g_value_set_boolean (value,
1186 gtk_window_get_urgency_hint (window));
1188 case PROP_ACCEPT_FOCUS:
1189 g_value_set_boolean (value,
1190 gtk_window_get_accept_focus (window));
1192 case PROP_FOCUS_ON_MAP:
1193 g_value_set_boolean (value,
1194 gtk_window_get_focus_on_map (window));
1196 case PROP_DECORATED:
1197 g_value_set_boolean (value, gtk_window_get_decorated (window));
1199 case PROP_DELETABLE:
1200 g_value_set_boolean (value, gtk_window_get_deletable (window));
1203 g_value_set_enum (value, gtk_window_get_gravity (window));
1205 case PROP_TRANSIENT_FOR:
1206 g_value_set_object (value, gtk_window_get_transient_for (window));
1209 g_value_set_double (value, gtk_window_get_opacity (window));
1211 case PROP_MNEMONICS_VISIBLE:
1212 g_value_set_boolean (value, priv->mnemonics_visible);
1215 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1221 gtk_window_buildable_interface_init (GtkBuildableIface *iface)
1223 parent_buildable_iface = g_type_interface_peek_parent (iface);
1224 iface->set_buildable_property = gtk_window_buildable_set_buildable_property;
1225 iface->parser_finished = gtk_window_buildable_parser_finished;
1226 iface->custom_tag_start = gtk_window_buildable_custom_tag_start;
1227 iface->custom_finished = gtk_window_buildable_custom_finished;
1231 gtk_window_buildable_set_buildable_property (GtkBuildable *buildable,
1232 GtkBuilder *builder,
1234 const GValue *value)
1236 GtkWindowPrivate *priv = GTK_WINDOW_GET_PRIVATE (buildable);
1238 if (strcmp (name, "visible") == 0 && g_value_get_boolean (value))
1239 priv->builder_visible = TRUE;
1241 parent_buildable_iface->set_buildable_property (buildable, builder, name, value);
1245 gtk_window_buildable_parser_finished (GtkBuildable *buildable,
1246 GtkBuilder *builder)
1248 GtkWindowPrivate *priv = GTK_WINDOW_GET_PRIVATE (buildable);
1252 if (priv->builder_visible)
1253 gtk_widget_show (GTK_WIDGET (buildable));
1255 accels = g_object_get_qdata (G_OBJECT (buildable), quark_gtk_buildable_accels);
1256 for (l = accels; l; l = l->next)
1258 object = gtk_builder_get_object (builder, l->data);
1261 g_warning ("Unknown accel group %s specified in window %s",
1262 (const gchar*)l->data, gtk_buildable_get_name (buildable));
1265 gtk_window_add_accel_group (GTK_WINDOW (buildable),
1266 GTK_ACCEL_GROUP (object));
1270 g_object_set_qdata (G_OBJECT (buildable), quark_gtk_buildable_accels, NULL);
1272 parent_buildable_iface->parser_finished (buildable, builder);
1278 } GSListSubParserData;
1281 window_start_element (GMarkupParseContext *context,
1282 const gchar *element_name,
1283 const gchar **names,
1284 const gchar **values,
1289 GSListSubParserData *data = (GSListSubParserData*)user_data;
1291 if (strcmp (element_name, "group") == 0)
1293 for (i = 0; names[i]; i++)
1295 if (strcmp (names[i], "name") == 0)
1296 data->items = g_slist_prepend (data->items, g_strdup (values[i]));
1299 else if (strcmp (element_name, "accel-groups") == 0)
1302 g_warning ("Unsupported tag type for GtkWindow: %s\n",
1307 static const GMarkupParser window_parser =
1309 window_start_element
1313 gtk_window_buildable_custom_tag_start (GtkBuildable *buildable,
1314 GtkBuilder *builder,
1316 const gchar *tagname,
1317 GMarkupParser *parser,
1320 GSListSubParserData *parser_data;
1322 if (parent_buildable_iface->custom_tag_start (buildable, builder, child,
1323 tagname, parser, data))
1326 if (strcmp (tagname, "accel-groups") == 0)
1328 parser_data = g_slice_new0 (GSListSubParserData);
1329 parser_data->items = NULL;
1330 parser_data->object = G_OBJECT (buildable);
1332 *parser = window_parser;
1333 *data = parser_data;
1341 gtk_window_buildable_custom_finished (GtkBuildable *buildable,
1342 GtkBuilder *builder,
1344 const gchar *tagname,
1347 GSListSubParserData *data;
1349 parent_buildable_iface->custom_finished (buildable, builder, child,
1350 tagname, user_data);
1352 if (strcmp (tagname, "accel-groups") != 0)
1355 data = (GSListSubParserData*)user_data;
1357 g_object_set_qdata_full (G_OBJECT (buildable), quark_gtk_buildable_accels,
1358 data->items, (GDestroyNotify) g_slist_free);
1360 g_slice_free (GSListSubParserData, data);
1365 * @type: type of window
1367 * Creates a new #GtkWindow, which is a toplevel window that can
1368 * contain other widgets. Nearly always, the type of the window should
1369 * be #GTK_WINDOW_TOPLEVEL. If you're implementing something like a
1370 * popup menu from scratch (which is a bad idea, just use #GtkMenu),
1371 * you might use #GTK_WINDOW_POPUP. #GTK_WINDOW_POPUP is not for
1372 * dialogs, though in some other toolkits dialogs are called "popups".
1373 * In GTK+, #GTK_WINDOW_POPUP means a pop-up menu or pop-up tooltip.
1374 * On X11, popup windows are not controlled by the <link
1375 * linkend="gtk-X11-arch">window manager</link>.
1377 * If you simply want an undecorated window (no window borders), use
1378 * gtk_window_set_decorated(), don't use #GTK_WINDOW_POPUP.
1380 * Return value: a new #GtkWindow.
1383 gtk_window_new (GtkWindowType type)
1387 g_return_val_if_fail (type >= GTK_WINDOW_TOPLEVEL && type <= GTK_WINDOW_POPUP, NULL);
1389 window = g_object_new (GTK_TYPE_WINDOW, NULL);
1391 window->type = type;
1393 return GTK_WIDGET (window);
1397 * gtk_window_set_title:
1398 * @window: a #GtkWindow
1399 * @title: title of the window
1401 * Sets the title of the #GtkWindow. The title of a window will be
1402 * displayed in its title bar; on the X Window System, the title bar
1403 * is rendered by the <link linkend="gtk-X11-arch">window
1404 * manager</link>, so exactly how the title appears to users may vary
1405 * according to a user's exact configuration. The title should help a
1406 * user distinguish this window from other windows they may have
1407 * open. A good title might include the application name and current
1408 * document filename, for example.
1412 gtk_window_set_title (GtkWindow *window,
1417 g_return_if_fail (GTK_IS_WINDOW (window));
1419 new_title = g_strdup (title);
1420 g_free (window->title);
1421 window->title = new_title;
1423 if (gtk_widget_get_realized (GTK_WIDGET (window)))
1425 gdk_window_set_title (GTK_WIDGET (window)->window, window->title);
1427 gtk_decorated_window_set_title (window, title);
1430 g_object_notify (G_OBJECT (window), "title");
1434 * gtk_window_get_title:
1435 * @window: a #GtkWindow
1437 * Retrieves the title of the window. See gtk_window_set_title().
1439 * Return value: the title of the window, or %NULL if none has
1440 * been set explicitely. The returned string is owned by the widget
1441 * and must not be modified or freed.
1443 G_CONST_RETURN gchar *
1444 gtk_window_get_title (GtkWindow *window)
1446 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
1448 return window->title;
1452 * gtk_window_set_wmclass:
1453 * @window: a #GtkWindow
1454 * @wmclass_name: window name hint
1455 * @wmclass_class: window class hint
1457 * Don't use this function. It sets the X Window System "class" and
1458 * "name" hints for a window. According to the ICCCM, you should
1459 * always set these to the same value for all windows in an
1460 * application, and GTK+ sets them to that value by default, so calling
1461 * this function is sort of pointless. However, you may want to call
1462 * gtk_window_set_role() on each window in your application, for the
1463 * benefit of the session manager. Setting the role allows the window
1464 * manager to restore window positions when loading a saved session.
1468 gtk_window_set_wmclass (GtkWindow *window,
1469 const gchar *wmclass_name,
1470 const gchar *wmclass_class)
1472 g_return_if_fail (GTK_IS_WINDOW (window));
1474 g_free (window->wmclass_name);
1475 window->wmclass_name = g_strdup (wmclass_name);
1477 g_free (window->wmclass_class);
1478 window->wmclass_class = g_strdup (wmclass_class);
1480 if (gtk_widget_get_realized (GTK_WIDGET (window)))
1481 g_warning ("gtk_window_set_wmclass: shouldn't set wmclass after window is realized!\n");
1485 * gtk_window_set_role:
1486 * @window: a #GtkWindow
1487 * @role: unique identifier for the window to be used when restoring a session
1489 * This function is only useful on X11, not with other GTK+ targets.
1491 * In combination with the window title, the window role allows a
1492 * <link linkend="gtk-X11-arch">window manager</link> to identify "the
1493 * same" window when an application is restarted. So for example you
1494 * might set the "toolbox" role on your app's toolbox window, so that
1495 * when the user restarts their session, the window manager can put
1496 * the toolbox back in the same place.
1498 * If a window already has a unique title, you don't need to set the
1499 * role, since the WM can use the title to identify the window when
1500 * restoring the session.
1504 gtk_window_set_role (GtkWindow *window,
1509 g_return_if_fail (GTK_IS_WINDOW (window));
1511 new_role = g_strdup (role);
1512 g_free (window->wm_role);
1513 window->wm_role = new_role;
1515 if (gtk_widget_get_realized (GTK_WIDGET (window)))
1516 gdk_window_set_role (GTK_WIDGET (window)->window, window->wm_role);
1518 g_object_notify (G_OBJECT (window), "role");
1522 * gtk_window_set_startup_id:
1523 * @window: a #GtkWindow
1524 * @startup_id: a string with startup-notification identifier
1526 * Startup notification identifiers are used by desktop environment to
1527 * track application startup, to provide user feedback and other
1528 * features. This function changes the corresponding property on the
1529 * underlying GdkWindow. Normally, startup identifier is managed
1530 * automatically and you should only use this function in special cases
1531 * like transferring focus from other processes. You should use this
1532 * function before calling gtk_window_present() or any equivalent
1533 * function generating a window map event.
1535 * This function is only useful on X11, not with other GTK+ targets.
1540 gtk_window_set_startup_id (GtkWindow *window,
1541 const gchar *startup_id)
1543 GtkWindowPrivate *priv;
1545 g_return_if_fail (GTK_IS_WINDOW (window));
1547 priv = GTK_WINDOW_GET_PRIVATE (window);
1549 g_free (priv->startup_id);
1550 priv->startup_id = g_strdup (startup_id);
1552 if (gtk_widget_get_realized (GTK_WIDGET (window)))
1554 guint32 timestamp = extract_time_from_startup_id (priv->startup_id);
1556 #ifdef GDK_WINDOWING_X11
1557 if (timestamp != GDK_CURRENT_TIME)
1558 gdk_x11_window_set_user_time (GTK_WIDGET (window)->window, timestamp);
1561 /* Here we differentiate real and "fake" startup notification IDs,
1562 * constructed on purpose just to pass interaction timestamp
1564 if (startup_id_is_fake (priv->startup_id))
1565 gtk_window_present_with_time (window, timestamp);
1568 gdk_window_set_startup_id (GTK_WIDGET (window)->window,
1571 /* If window is mapped, terminate the startup-notification too */
1572 if (gtk_widget_get_mapped (GTK_WIDGET (window)) &&
1573 !disable_startup_notification)
1574 gdk_notify_startup_complete_with_id (priv->startup_id);
1578 g_object_notify (G_OBJECT (window), "startup-id");
1582 * gtk_window_get_role:
1583 * @window: a #GtkWindow
1585 * Returns the role of the window. See gtk_window_set_role() for
1586 * further explanation.
1588 * Return value: the role of the window if set, or %NULL. The
1589 * returned is owned by the widget and must not be modified
1592 G_CONST_RETURN gchar *
1593 gtk_window_get_role (GtkWindow *window)
1595 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
1597 return window->wm_role;
1601 * gtk_window_set_focus:
1602 * @window: a #GtkWindow
1603 * @focus: (allow-none): widget to be the new focus widget, or %NULL to unset
1604 * any focus widget for the toplevel window.
1606 * If @focus is not the current focus widget, and is focusable, sets
1607 * it as the focus widget for the window. If @focus is %NULL, unsets
1608 * the focus widget for this window. To set the focus to a particular
1609 * widget in the toplevel, it is usually more convenient to use
1610 * gtk_widget_grab_focus() instead of this function.
1613 gtk_window_set_focus (GtkWindow *window,
1616 g_return_if_fail (GTK_IS_WINDOW (window));
1619 g_return_if_fail (GTK_IS_WIDGET (focus));
1620 g_return_if_fail (gtk_widget_get_can_focus (focus));
1624 gtk_widget_grab_focus (focus);
1627 /* Clear the existing focus chain, so that when we focus into
1628 * the window again, we start at the beginnning.
1630 GtkWidget *widget = window->focus_widget;
1633 while (widget->parent)
1635 widget = widget->parent;
1636 gtk_container_set_focus_child (GTK_CONTAINER (widget), NULL);
1640 _gtk_window_internal_set_focus (window, NULL);
1645 _gtk_window_internal_set_focus (GtkWindow *window,
1648 g_return_if_fail (GTK_IS_WINDOW (window));
1650 if ((window->focus_widget != focus) ||
1651 (focus && !gtk_widget_has_focus (focus)))
1652 g_signal_emit (window, window_signals[SET_FOCUS], 0, focus);
1656 * gtk_window_set_default:
1657 * @window: a #GtkWindow
1658 * @default_widget: (allow-none): widget to be the default, or %NULL to unset the
1659 * default widget for the toplevel.
1661 * The default widget is the widget that's activated when the user
1662 * presses Enter in a dialog (for example). This function sets or
1663 * unsets the default widget for a #GtkWindow about. When setting
1664 * (rather than unsetting) the default widget it's generally easier to
1665 * call gtk_widget_grab_focus() on the widget. Before making a widget
1666 * the default widget, you must set the #GTK_CAN_DEFAULT flag on the
1667 * widget you'd like to make the default using GTK_WIDGET_SET_FLAGS().
1670 gtk_window_set_default (GtkWindow *window,
1671 GtkWidget *default_widget)
1673 g_return_if_fail (GTK_IS_WINDOW (window));
1676 g_return_if_fail (gtk_widget_get_can_default (default_widget));
1678 if (window->default_widget != default_widget)
1680 GtkWidget *old_default_widget = NULL;
1683 g_object_ref (default_widget);
1685 if (window->default_widget)
1687 old_default_widget = window->default_widget;
1689 if (window->focus_widget != window->default_widget ||
1690 !gtk_widget_get_receives_default (window->default_widget))
1691 _gtk_widget_set_has_default (window->default_widget, FALSE);
1692 gtk_widget_queue_draw (window->default_widget);
1695 window->default_widget = default_widget;
1697 if (window->default_widget)
1699 if (window->focus_widget == NULL ||
1700 !gtk_widget_get_receives_default (window->focus_widget))
1701 _gtk_widget_set_has_default (window->default_widget, TRUE);
1702 gtk_widget_queue_draw (window->default_widget);
1705 if (old_default_widget)
1706 g_object_notify (G_OBJECT (old_default_widget), "has-default");
1710 g_object_notify (G_OBJECT (default_widget), "has-default");
1711 g_object_unref (default_widget);
1717 * gtk_window_get_default_widget:
1718 * @window: a #GtkWindow
1720 * Returns the default widget for @window. See gtk_window_set_default()
1723 * Returns: the default widget, or %NULL if there is none.
1728 gtk_window_get_default_widget (GtkWindow *window)
1730 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
1732 return window->default_widget;
1736 gtk_window_set_policy_internal (GtkWindow *window,
1737 gboolean allow_shrink,
1738 gboolean allow_grow,
1739 gboolean auto_shrink)
1741 window->allow_shrink = (allow_shrink != FALSE);
1742 window->allow_grow = (allow_grow != FALSE);
1744 g_object_freeze_notify (G_OBJECT (window));
1745 g_object_notify (G_OBJECT (window), "allow-shrink");
1746 g_object_notify (G_OBJECT (window), "allow-grow");
1747 g_object_notify (G_OBJECT (window), "resizable");
1748 g_object_thaw_notify (G_OBJECT (window));
1750 gtk_widget_queue_resize_no_redraw (GTK_WIDGET (window));
1754 handle_keys_changed (gpointer data)
1758 window = GTK_WINDOW (data);
1760 if (window->keys_changed_handler)
1762 g_source_remove (window->keys_changed_handler);
1763 window->keys_changed_handler = 0;
1766 g_signal_emit (window, window_signals[KEYS_CHANGED], 0);
1772 gtk_window_notify_keys_changed (GtkWindow *window)
1774 if (!window->keys_changed_handler)
1775 window->keys_changed_handler = gdk_threads_add_idle (handle_keys_changed, window);
1779 * gtk_window_add_accel_group:
1780 * @window: window to attach accelerator group to
1781 * @accel_group: a #GtkAccelGroup
1783 * Associate @accel_group with @window, such that calling
1784 * gtk_accel_groups_activate() on @window will activate accelerators
1788 gtk_window_add_accel_group (GtkWindow *window,
1789 GtkAccelGroup *accel_group)
1791 g_return_if_fail (GTK_IS_WINDOW (window));
1792 g_return_if_fail (GTK_IS_ACCEL_GROUP (accel_group));
1794 _gtk_accel_group_attach (accel_group, G_OBJECT (window));
1795 g_signal_connect_object (accel_group, "accel-changed",
1796 G_CALLBACK (gtk_window_notify_keys_changed),
1797 window, G_CONNECT_SWAPPED);
1798 gtk_window_notify_keys_changed (window);
1802 * gtk_window_remove_accel_group:
1803 * @window: a #GtkWindow
1804 * @accel_group: a #GtkAccelGroup
1806 * Reverses the effects of gtk_window_add_accel_group().
1809 gtk_window_remove_accel_group (GtkWindow *window,
1810 GtkAccelGroup *accel_group)
1812 g_return_if_fail (GTK_IS_WINDOW (window));
1813 g_return_if_fail (GTK_IS_ACCEL_GROUP (accel_group));
1815 g_signal_handlers_disconnect_by_func (accel_group,
1816 gtk_window_notify_keys_changed,
1818 _gtk_accel_group_detach (accel_group, G_OBJECT (window));
1819 gtk_window_notify_keys_changed (window);
1822 static GtkMnemonicHash *
1823 gtk_window_get_mnemonic_hash (GtkWindow *window,
1826 GtkWindowPrivate *private = GTK_WINDOW_GET_PRIVATE (window);
1827 if (!private->mnemonic_hash && create)
1828 private->mnemonic_hash = _gtk_mnemonic_hash_new ();
1830 return private->mnemonic_hash;
1834 * gtk_window_add_mnemonic:
1835 * @window: a #GtkWindow
1836 * @keyval: the mnemonic
1837 * @target: the widget that gets activated by the mnemonic
1839 * Adds a mnemonic to this window.
1842 gtk_window_add_mnemonic (GtkWindow *window,
1846 g_return_if_fail (GTK_IS_WINDOW (window));
1847 g_return_if_fail (GTK_IS_WIDGET (target));
1849 _gtk_mnemonic_hash_add (gtk_window_get_mnemonic_hash (window, TRUE),
1851 gtk_window_notify_keys_changed (window);
1855 * gtk_window_remove_mnemonic:
1856 * @window: a #GtkWindow
1857 * @keyval: the mnemonic
1858 * @target: the widget that gets activated by the mnemonic
1860 * Removes a mnemonic from this window.
1863 gtk_window_remove_mnemonic (GtkWindow *window,
1867 g_return_if_fail (GTK_IS_WINDOW (window));
1868 g_return_if_fail (GTK_IS_WIDGET (target));
1870 _gtk_mnemonic_hash_remove (gtk_window_get_mnemonic_hash (window, TRUE),
1872 gtk_window_notify_keys_changed (window);
1876 * gtk_window_mnemonic_activate:
1877 * @window: a #GtkWindow
1878 * @keyval: the mnemonic
1879 * @modifier: the modifiers
1880 * @returns: %TRUE if the activation is done.
1882 * Activates the targets associated with the mnemonic.
1885 gtk_window_mnemonic_activate (GtkWindow *window,
1887 GdkModifierType modifier)
1889 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
1891 if (window->mnemonic_modifier == (modifier & gtk_accelerator_get_default_mod_mask ()))
1893 GtkMnemonicHash *mnemonic_hash = gtk_window_get_mnemonic_hash (window, FALSE);
1895 return _gtk_mnemonic_hash_activate (mnemonic_hash, keyval);
1902 * gtk_window_set_mnemonic_modifier:
1903 * @window: a #GtkWindow
1904 * @modifier: the modifier mask used to activate
1905 * mnemonics on this window.
1907 * Sets the mnemonic modifier for this window.
1910 gtk_window_set_mnemonic_modifier (GtkWindow *window,
1911 GdkModifierType modifier)
1913 g_return_if_fail (GTK_IS_WINDOW (window));
1914 g_return_if_fail ((modifier & ~GDK_MODIFIER_MASK) == 0);
1916 window->mnemonic_modifier = modifier;
1917 gtk_window_notify_keys_changed (window);
1921 * gtk_window_get_mnemonic_modifier:
1922 * @window: a #GtkWindow
1924 * Returns the mnemonic modifier for this window. See
1925 * gtk_window_set_mnemonic_modifier().
1927 * Return value: the modifier mask used to activate
1928 * mnemonics on this window.
1931 gtk_window_get_mnemonic_modifier (GtkWindow *window)
1933 g_return_val_if_fail (GTK_IS_WINDOW (window), 0);
1935 return window->mnemonic_modifier;
1939 * gtk_window_set_position:
1940 * @window: a #GtkWindow.
1941 * @position: a position constraint.
1943 * Sets a position constraint for this window. If the old or new
1944 * constraint is %GTK_WIN_POS_CENTER_ALWAYS, this will also cause
1945 * the window to be repositioned to satisfy the new constraint.
1948 gtk_window_set_position (GtkWindow *window,
1949 GtkWindowPosition position)
1951 g_return_if_fail (GTK_IS_WINDOW (window));
1953 if (position == GTK_WIN_POS_CENTER_ALWAYS ||
1954 window->position == GTK_WIN_POS_CENTER_ALWAYS)
1956 GtkWindowGeometryInfo *info;
1958 info = gtk_window_get_geometry_info (window, TRUE);
1960 /* this flag causes us to re-request the CENTER_ALWAYS
1961 * constraint in gtk_window_move_resize(), see
1962 * comment in that function.
1964 info->position_constraints_changed = TRUE;
1966 gtk_widget_queue_resize_no_redraw (GTK_WIDGET (window));
1969 window->position = position;
1971 g_object_notify (G_OBJECT (window), "window-position");
1975 * gtk_window_activate_focus:
1976 * @window: a #GtkWindow
1978 * Activates the current focused widget within the window.
1980 * Return value: %TRUE if a widget got activated.
1983 gtk_window_activate_focus (GtkWindow *window)
1985 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
1987 if (window->focus_widget && gtk_widget_is_sensitive (window->focus_widget))
1988 return gtk_widget_activate (window->focus_widget);
1994 * gtk_window_get_focus:
1995 * @window: a #GtkWindow
1997 * Retrieves the current focused widget within the window.
1998 * Note that this is the widget that would have the focus
1999 * if the toplevel window focused; if the toplevel window
2000 * is not focused then <literal>gtk_widget_has_focus (widget)</literal> will
2001 * not be %TRUE for the widget.
2003 * Return value: (transfer none): the currently focused widget, or %NULL if there is none.
2006 gtk_window_get_focus (GtkWindow *window)
2008 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
2010 return window->focus_widget;
2014 * gtk_window_activate_default:
2015 * @window: a #GtkWindow
2017 * Activates the default widget for the window, unless the current
2018 * focused widget has been configured to receive the default action
2019 * (see gtk_widget_set_receives_default()), in which case the
2020 * focused widget is activated.
2022 * Return value: %TRUE if a widget got activated.
2025 gtk_window_activate_default (GtkWindow *window)
2027 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
2029 if (window->default_widget && gtk_widget_is_sensitive (window->default_widget) &&
2030 (!window->focus_widget || !gtk_widget_get_receives_default (window->focus_widget)))
2031 return gtk_widget_activate (window->default_widget);
2032 else if (window->focus_widget && gtk_widget_is_sensitive (window->focus_widget))
2033 return gtk_widget_activate (window->focus_widget);
2039 * gtk_window_set_modal:
2040 * @window: a #GtkWindow
2041 * @modal: whether the window is modal
2043 * Sets a window modal or non-modal. Modal windows prevent interaction
2044 * with other windows in the same application. To keep modal dialogs
2045 * on top of main application windows, use
2046 * gtk_window_set_transient_for() to make the dialog transient for the
2047 * parent; most <link linkend="gtk-X11-arch">window managers</link>
2048 * will then disallow lowering the dialog below the parent.
2053 gtk_window_set_modal (GtkWindow *window,
2058 g_return_if_fail (GTK_IS_WINDOW (window));
2060 modal = modal != FALSE;
2061 if (window->modal == modal)
2064 window->modal = modal;
2065 widget = GTK_WIDGET (window);
2067 /* adjust desired modality state */
2068 if (gtk_widget_get_realized (widget))
2071 gdk_window_set_modal_hint (widget->window, TRUE);
2073 gdk_window_set_modal_hint (widget->window, FALSE);
2076 if (gtk_widget_get_visible (widget))
2079 gtk_grab_add (widget);
2081 gtk_grab_remove (widget);
2084 g_object_notify (G_OBJECT (window), "modal");
2088 * gtk_window_get_modal:
2089 * @window: a #GtkWindow
2091 * Returns whether the window is modal. See gtk_window_set_modal().
2093 * Return value: %TRUE if the window is set to be modal and
2094 * establishes a grab when shown
2097 gtk_window_get_modal (GtkWindow *window)
2099 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
2101 return window->modal;
2105 * gtk_window_list_toplevels:
2107 * Returns a list of all existing toplevel windows. The widgets
2108 * in the list are not individually referenced. If you want
2109 * to iterate through the list and perform actions involving
2110 * callbacks that might destroy the widgets, you <emphasis>must</emphasis> call
2111 * <literal>g_list_foreach (result, (GFunc)g_object_ref, NULL)</literal> first, and
2112 * then unref all the widgets afterwards.
2114 * Return value: (element-type GtkWidget) (transfer container): list of toplevel widgets
2117 gtk_window_list_toplevels (void)
2122 for (slist = toplevel_list; slist; slist = slist->next)
2123 list = g_list_prepend (list, slist->data);
2129 gtk_window_add_embedded_xid (GtkWindow *window, GdkNativeWindow xid)
2131 GList *embedded_windows;
2133 g_return_if_fail (GTK_IS_WINDOW (window));
2135 embedded_windows = g_object_get_qdata (G_OBJECT (window), quark_gtk_embedded);
2136 if (embedded_windows)
2137 g_object_steal_qdata (G_OBJECT (window), quark_gtk_embedded);
2138 embedded_windows = g_list_prepend (embedded_windows,
2139 GUINT_TO_POINTER (xid));
2141 g_object_set_qdata_full (G_OBJECT (window), quark_gtk_embedded,
2144 (GDestroyNotify) g_list_free : NULL);
2148 gtk_window_remove_embedded_xid (GtkWindow *window, GdkNativeWindow xid)
2150 GList *embedded_windows;
2153 g_return_if_fail (GTK_IS_WINDOW (window));
2155 embedded_windows = g_object_get_qdata (G_OBJECT (window), quark_gtk_embedded);
2156 if (embedded_windows)
2157 g_object_steal_qdata (G_OBJECT (window), quark_gtk_embedded);
2159 node = g_list_find (embedded_windows, GUINT_TO_POINTER (xid));
2162 embedded_windows = g_list_remove_link (embedded_windows, node);
2163 g_list_free_1 (node);
2166 g_object_set_qdata_full (G_OBJECT (window), quark_gtk_embedded,
2169 (GDestroyNotify) g_list_free : NULL);
2173 _gtk_window_reposition (GtkWindow *window,
2177 g_return_if_fail (GTK_IS_WINDOW (window));
2179 gtk_window_move (window, x, y);
2183 gtk_window_dispose (GObject *object)
2185 GtkWindow *window = GTK_WINDOW (object);
2187 gtk_window_set_focus (window, NULL);
2188 gtk_window_set_default (window, NULL);
2190 G_OBJECT_CLASS (gtk_window_parent_class)->dispose (object);
2194 parent_destroyed_callback (GtkWindow *parent, GtkWindow *child)
2196 gtk_widget_destroy (GTK_WIDGET (child));
2200 connect_parent_destroyed (GtkWindow *window)
2202 if (window->transient_parent)
2204 g_signal_connect (window->transient_parent,
2206 G_CALLBACK (parent_destroyed_callback),
2212 disconnect_parent_destroyed (GtkWindow *window)
2214 if (window->transient_parent)
2216 g_signal_handlers_disconnect_by_func (window->transient_parent,
2217 parent_destroyed_callback,
2223 gtk_window_transient_parent_realized (GtkWidget *parent,
2226 if (gtk_widget_get_realized (GTK_WIDGET (window)))
2227 gdk_window_set_transient_for (window->window, parent->window);
2231 gtk_window_transient_parent_unrealized (GtkWidget *parent,
2234 if (gtk_widget_get_realized (GTK_WIDGET (window)))
2235 gdk_property_delete (window->window,
2236 gdk_atom_intern_static_string ("WM_TRANSIENT_FOR"));
2240 gtk_window_transient_parent_screen_changed (GtkWindow *parent,
2244 gtk_window_set_screen (window, parent->screen);
2248 gtk_window_unset_transient_for (GtkWindow *window)
2250 GtkWindowPrivate *priv = GTK_WINDOW_GET_PRIVATE (window);
2252 if (window->transient_parent)
2254 g_signal_handlers_disconnect_by_func (window->transient_parent,
2255 gtk_window_transient_parent_realized,
2257 g_signal_handlers_disconnect_by_func (window->transient_parent,
2258 gtk_window_transient_parent_unrealized,
2260 g_signal_handlers_disconnect_by_func (window->transient_parent,
2261 gtk_window_transient_parent_screen_changed,
2263 g_signal_handlers_disconnect_by_func (window->transient_parent,
2264 gtk_widget_destroyed,
2265 &window->transient_parent);
2267 if (window->destroy_with_parent)
2268 disconnect_parent_destroyed (window);
2270 window->transient_parent = NULL;
2272 if (priv->transient_parent_group)
2274 priv->transient_parent_group = FALSE;
2275 gtk_window_group_remove_window (window->group,
2282 * gtk_window_set_transient_for:
2283 * @window: a #GtkWindow
2284 * @parent: (allow-none): parent window, or %NULL
2286 * Dialog windows should be set transient for the main application
2287 * window they were spawned from. This allows <link
2288 * linkend="gtk-X11-arch">window managers</link> to e.g. keep the
2289 * dialog on top of the main window, or center the dialog over the
2290 * main window. gtk_dialog_new_with_buttons() and other convenience
2291 * functions in GTK+ will sometimes call
2292 * gtk_window_set_transient_for() on your behalf.
2294 * Passing %NULL for @parent unsets the current transient window.
2296 * On Windows, this function puts the child window on top of the parent,
2297 * much as the window manager would have done on X.
2300 gtk_window_set_transient_for (GtkWindow *window,
2303 GtkWindowPrivate *priv;
2305 g_return_if_fail (GTK_IS_WINDOW (window));
2306 g_return_if_fail (parent == NULL || GTK_IS_WINDOW (parent));
2307 g_return_if_fail (window != parent);
2309 priv = GTK_WINDOW_GET_PRIVATE (window);
2311 if (window->transient_parent)
2313 if (gtk_widget_get_realized (GTK_WIDGET (window)) &&
2314 gtk_widget_get_realized (GTK_WIDGET (window->transient_parent)) &&
2315 (!parent || !gtk_widget_get_realized (GTK_WIDGET (parent))))
2316 gtk_window_transient_parent_unrealized (GTK_WIDGET (window->transient_parent),
2317 GTK_WIDGET (window));
2319 gtk_window_unset_transient_for (window);
2322 window->transient_parent = parent;
2326 g_signal_connect (parent, "destroy",
2327 G_CALLBACK (gtk_widget_destroyed),
2328 &window->transient_parent);
2329 g_signal_connect (parent, "realize",
2330 G_CALLBACK (gtk_window_transient_parent_realized),
2332 g_signal_connect (parent, "unrealize",
2333 G_CALLBACK (gtk_window_transient_parent_unrealized),
2335 g_signal_connect (parent, "notify::screen",
2336 G_CALLBACK (gtk_window_transient_parent_screen_changed),
2339 gtk_window_set_screen (window, parent->screen);
2341 if (window->destroy_with_parent)
2342 connect_parent_destroyed (window);
2344 if (gtk_widget_get_realized (GTK_WIDGET (window)) &&
2345 gtk_widget_get_realized (GTK_WIDGET (parent)))
2346 gtk_window_transient_parent_realized (GTK_WIDGET (parent),
2347 GTK_WIDGET (window));
2351 gtk_window_group_add_window (parent->group, window);
2352 priv->transient_parent_group = TRUE;
2358 * gtk_window_get_transient_for:
2359 * @window: a #GtkWindow
2361 * Fetches the transient parent for this window. See
2362 * gtk_window_set_transient_for().
2364 * Return value: (transfer none): the transient parent for this window, or %NULL
2365 * if no transient parent has been set.
2368 gtk_window_get_transient_for (GtkWindow *window)
2370 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
2372 return window->transient_parent;
2376 * gtk_window_set_opacity:
2377 * @window: a #GtkWindow
2378 * @opacity: desired opacity, between 0 and 1
2380 * Request the windowing system to make @window partially transparent,
2381 * with opacity 0 being fully transparent and 1 fully opaque. (Values
2382 * of the opacity parameter are clamped to the [0,1] range.) On X11
2383 * this has any effect only on X screens with a compositing manager
2384 * running. See gtk_widget_is_composited(). On Windows it should work
2387 * Note that setting a window's opacity after the window has been
2388 * shown causes it to flicker once on Windows.
2393 gtk_window_set_opacity (GtkWindow *window,
2396 GtkWindowPrivate *priv;
2398 g_return_if_fail (GTK_IS_WINDOW (window));
2400 priv = GTK_WINDOW_GET_PRIVATE (window);
2404 else if (opacity > 1.0)
2407 priv->opacity_set = TRUE;
2408 priv->opacity = opacity;
2410 if (gtk_widget_get_realized (GTK_WIDGET (window)))
2411 gdk_window_set_opacity (GTK_WIDGET (window)->window, priv->opacity);
2415 * gtk_window_get_opacity:
2416 * @window: a #GtkWindow
2418 * Fetches the requested opacity for this window. See
2419 * gtk_window_set_opacity().
2421 * Return value: the requested opacity for this window.
2426 gtk_window_get_opacity (GtkWindow *window)
2428 GtkWindowPrivate *priv;
2430 g_return_val_if_fail (GTK_IS_WINDOW (window), 0.0);
2432 priv = GTK_WINDOW_GET_PRIVATE (window);
2434 return priv->opacity;
2438 * gtk_window_set_type_hint:
2439 * @window: a #GtkWindow
2440 * @hint: the window type
2442 * By setting the type hint for the window, you allow the window
2443 * manager to decorate and handle the window in a way which is
2444 * suitable to the function of the window in your application.
2446 * This function should be called before the window becomes visible.
2448 * gtk_dialog_new_with_buttons() and other convenience functions in GTK+
2449 * will sometimes call gtk_window_set_type_hint() on your behalf.
2453 gtk_window_set_type_hint (GtkWindow *window,
2454 GdkWindowTypeHint hint)
2456 GtkWindowPrivate *priv;
2458 g_return_if_fail (GTK_IS_WINDOW (window));
2459 g_return_if_fail (!gtk_widget_get_mapped (GTK_WIDGET (window)));
2461 priv = GTK_WINDOW_GET_PRIVATE (window);
2463 if (hint < GDK_WINDOW_TYPE_HINT_DROPDOWN_MENU)
2464 window->type_hint = hint;
2466 window->type_hint = GDK_WINDOW_TYPE_HINT_NORMAL;
2468 priv->reset_type_hint = TRUE;
2469 priv->type_hint = hint;
2473 * gtk_window_get_type_hint:
2474 * @window: a #GtkWindow
2476 * Gets the type hint for this window. See gtk_window_set_type_hint().
2478 * Return value: the type hint for @window.
2481 gtk_window_get_type_hint (GtkWindow *window)
2483 GtkWindowPrivate *priv;
2485 g_return_val_if_fail (GTK_IS_WINDOW (window), GDK_WINDOW_TYPE_HINT_NORMAL);
2487 priv = GTK_WINDOW_GET_PRIVATE (window);
2489 return priv->type_hint;
2493 * gtk_window_set_skip_taskbar_hint:
2494 * @window: a #GtkWindow
2495 * @setting: %TRUE to keep this window from appearing in the task bar
2497 * Windows may set a hint asking the desktop environment not to display
2498 * the window in the task bar. This function sets this hint.
2503 gtk_window_set_skip_taskbar_hint (GtkWindow *window,
2506 GtkWindowPrivate *priv;
2508 g_return_if_fail (GTK_IS_WINDOW (window));
2510 priv = GTK_WINDOW_GET_PRIVATE (window);
2512 setting = setting != FALSE;
2514 if (priv->skips_taskbar != setting)
2516 priv->skips_taskbar = setting;
2517 if (gtk_widget_get_realized (GTK_WIDGET (window)))
2518 gdk_window_set_skip_taskbar_hint (GTK_WIDGET (window)->window,
2519 priv->skips_taskbar);
2520 g_object_notify (G_OBJECT (window), "skip-taskbar-hint");
2525 * gtk_window_get_skip_taskbar_hint:
2526 * @window: a #GtkWindow
2528 * Gets the value set by gtk_window_set_skip_taskbar_hint()
2530 * Return value: %TRUE if window shouldn't be in taskbar
2535 gtk_window_get_skip_taskbar_hint (GtkWindow *window)
2537 GtkWindowPrivate *priv;
2539 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
2541 priv = GTK_WINDOW_GET_PRIVATE (window);
2543 return priv->skips_taskbar;
2547 * gtk_window_set_skip_pager_hint:
2548 * @window: a #GtkWindow
2549 * @setting: %TRUE to keep this window from appearing in the pager
2551 * Windows may set a hint asking the desktop environment not to display
2552 * the window in the pager. This function sets this hint.
2553 * (A "pager" is any desktop navigation tool such as a workspace
2554 * switcher that displays a thumbnail representation of the windows
2560 gtk_window_set_skip_pager_hint (GtkWindow *window,
2563 GtkWindowPrivate *priv;
2565 g_return_if_fail (GTK_IS_WINDOW (window));
2567 priv = GTK_WINDOW_GET_PRIVATE (window);
2569 setting = setting != FALSE;
2571 if (priv->skips_pager != setting)
2573 priv->skips_pager = setting;
2574 if (gtk_widget_get_realized (GTK_WIDGET (window)))
2575 gdk_window_set_skip_pager_hint (GTK_WIDGET (window)->window,
2577 g_object_notify (G_OBJECT (window), "skip-pager-hint");
2582 * gtk_window_get_skip_pager_hint:
2583 * @window: a #GtkWindow
2585 * Gets the value set by gtk_window_set_skip_pager_hint().
2587 * Return value: %TRUE if window shouldn't be in pager
2592 gtk_window_get_skip_pager_hint (GtkWindow *window)
2594 GtkWindowPrivate *priv;
2596 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
2598 priv = GTK_WINDOW_GET_PRIVATE (window);
2600 return priv->skips_pager;
2604 * gtk_window_set_urgency_hint:
2605 * @window: a #GtkWindow
2606 * @setting: %TRUE to mark this window as urgent
2608 * Windows may set a hint asking the desktop environment to draw
2609 * the users attention to the window. This function sets this hint.
2614 gtk_window_set_urgency_hint (GtkWindow *window,
2617 GtkWindowPrivate *priv;
2619 g_return_if_fail (GTK_IS_WINDOW (window));
2621 priv = GTK_WINDOW_GET_PRIVATE (window);
2623 setting = setting != FALSE;
2625 if (priv->urgent != setting)
2627 priv->urgent = setting;
2628 if (gtk_widget_get_realized (GTK_WIDGET (window)))
2629 gdk_window_set_urgency_hint (GTK_WIDGET (window)->window,
2631 g_object_notify (G_OBJECT (window), "urgency-hint");
2636 * gtk_window_get_urgency_hint:
2637 * @window: a #GtkWindow
2639 * Gets the value set by gtk_window_set_urgency_hint()
2641 * Return value: %TRUE if window is urgent
2646 gtk_window_get_urgency_hint (GtkWindow *window)
2648 GtkWindowPrivate *priv;
2650 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
2652 priv = GTK_WINDOW_GET_PRIVATE (window);
2654 return priv->urgent;
2658 * gtk_window_set_accept_focus:
2659 * @window: a #GtkWindow
2660 * @setting: %TRUE to let this window receive input focus
2662 * Windows may set a hint asking the desktop environment not to receive
2663 * the input focus. This function sets this hint.
2668 gtk_window_set_accept_focus (GtkWindow *window,
2671 GtkWindowPrivate *priv;
2673 g_return_if_fail (GTK_IS_WINDOW (window));
2675 priv = GTK_WINDOW_GET_PRIVATE (window);
2677 setting = setting != FALSE;
2679 if (priv->accept_focus != setting)
2681 priv->accept_focus = setting;
2682 if (gtk_widget_get_realized (GTK_WIDGET (window)))
2683 gdk_window_set_accept_focus (GTK_WIDGET (window)->window,
2684 priv->accept_focus);
2685 g_object_notify (G_OBJECT (window), "accept-focus");
2690 * gtk_window_get_accept_focus:
2691 * @window: a #GtkWindow
2693 * Gets the value set by gtk_window_set_accept_focus().
2695 * Return value: %TRUE if window should receive the input focus
2700 gtk_window_get_accept_focus (GtkWindow *window)
2702 GtkWindowPrivate *priv;
2704 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
2706 priv = GTK_WINDOW_GET_PRIVATE (window);
2708 return priv->accept_focus;
2712 * gtk_window_set_focus_on_map:
2713 * @window: a #GtkWindow
2714 * @setting: %TRUE to let this window receive input focus on map
2716 * Windows may set a hint asking the desktop environment not to receive
2717 * the input focus when the window is mapped. This function sets this
2723 gtk_window_set_focus_on_map (GtkWindow *window,
2726 GtkWindowPrivate *priv;
2728 g_return_if_fail (GTK_IS_WINDOW (window));
2730 priv = GTK_WINDOW_GET_PRIVATE (window);
2732 setting = setting != FALSE;
2734 if (priv->focus_on_map != setting)
2736 priv->focus_on_map = setting;
2737 if (gtk_widget_get_realized (GTK_WIDGET (window)))
2738 gdk_window_set_focus_on_map (GTK_WIDGET (window)->window,
2739 priv->focus_on_map);
2740 g_object_notify (G_OBJECT (window), "focus-on-map");
2745 * gtk_window_get_focus_on_map:
2746 * @window: a #GtkWindow
2748 * Gets the value set by gtk_window_set_focus_on_map().
2750 * Return value: %TRUE if window should receive the input focus when
2756 gtk_window_get_focus_on_map (GtkWindow *window)
2758 GtkWindowPrivate *priv;
2760 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
2762 priv = GTK_WINDOW_GET_PRIVATE (window);
2764 return priv->focus_on_map;
2768 * gtk_window_set_destroy_with_parent:
2769 * @window: a #GtkWindow
2770 * @setting: whether to destroy @window with its transient parent
2772 * If @setting is %TRUE, then destroying the transient parent of @window
2773 * will also destroy @window itself. This is useful for dialogs that
2774 * shouldn't persist beyond the lifetime of the main window they're
2775 * associated with, for example.
2778 gtk_window_set_destroy_with_parent (GtkWindow *window,
2781 g_return_if_fail (GTK_IS_WINDOW (window));
2783 if (window->destroy_with_parent == (setting != FALSE))
2786 if (window->destroy_with_parent)
2788 disconnect_parent_destroyed (window);
2792 connect_parent_destroyed (window);
2795 window->destroy_with_parent = setting;
2797 g_object_notify (G_OBJECT (window), "destroy-with-parent");
2801 * gtk_window_get_destroy_with_parent:
2802 * @window: a #GtkWindow
2804 * Returns whether the window will be destroyed with its transient parent. See
2805 * gtk_window_set_destroy_with_parent ().
2807 * Return value: %TRUE if the window will be destroyed with its transient parent.
2810 gtk_window_get_destroy_with_parent (GtkWindow *window)
2812 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
2814 return window->destroy_with_parent;
2817 static GtkWindowGeometryInfo*
2818 gtk_window_get_geometry_info (GtkWindow *window,
2821 GtkWindowGeometryInfo *info;
2823 info = window->geometry_info;
2824 if (!info && create)
2826 info = g_new0 (GtkWindowGeometryInfo, 1);
2828 info->default_width = -1;
2829 info->default_height = -1;
2830 info->resize_width = -1;
2831 info->resize_height = -1;
2832 info->initial_x = 0;
2833 info->initial_y = 0;
2834 info->initial_pos_set = FALSE;
2835 info->default_is_geometry = FALSE;
2836 info->position_constraints_changed = FALSE;
2837 info->last.configure_request.x = 0;
2838 info->last.configure_request.y = 0;
2839 info->last.configure_request.width = -1;
2840 info->last.configure_request.height = -1;
2841 info->widget = NULL;
2843 window->geometry_info = info;
2850 * gtk_window_set_geometry_hints:
2851 * @window: a #GtkWindow
2852 * @geometry_widget: (allow-none): widget the geometry hints will be applied to or %NULL
2853 * @geometry: (allow-none): struct containing geometry information or %NULL
2854 * @geom_mask: mask indicating which struct fields should be paid attention to
2856 * This function sets up hints about how a window can be resized by
2857 * the user. You can set a minimum and maximum size; allowed resize
2858 * increments (e.g. for xterm, you can only resize by the size of a
2859 * character); aspect ratios; and more. See the #GdkGeometry struct.
2863 gtk_window_set_geometry_hints (GtkWindow *window,
2864 GtkWidget *geometry_widget,
2865 GdkGeometry *geometry,
2866 GdkWindowHints geom_mask)
2868 GtkWindowGeometryInfo *info;
2870 g_return_if_fail (GTK_IS_WINDOW (window));
2871 g_return_if_fail (geometry_widget == NULL || GTK_IS_WIDGET (geometry_widget));
2873 info = gtk_window_get_geometry_info (window, TRUE);
2876 g_signal_handlers_disconnect_by_func (info->widget,
2877 gtk_widget_destroyed,
2880 info->widget = geometry_widget;
2882 g_signal_connect (geometry_widget, "destroy",
2883 G_CALLBACK (gtk_widget_destroyed),
2887 info->geometry = *geometry;
2889 /* We store gravity in window->gravity not in the hints. */
2890 info->mask = geom_mask & ~(GDK_HINT_WIN_GRAVITY);
2892 if (geom_mask & GDK_HINT_WIN_GRAVITY)
2894 gtk_window_set_gravity (window, geometry->win_gravity);
2897 gtk_widget_queue_resize_no_redraw (GTK_WIDGET (window));
2901 * gtk_window_set_decorated:
2902 * @window: a #GtkWindow
2903 * @setting: %TRUE to decorate the window
2905 * By default, windows are decorated with a title bar, resize
2906 * controls, etc. Some <link linkend="gtk-X11-arch">window
2907 * managers</link> allow GTK+ to disable these decorations, creating a
2908 * borderless window. If you set the decorated property to %FALSE
2909 * using this function, GTK+ will do its best to convince the window
2910 * manager not to decorate the window. Depending on the system, this
2911 * function may not have any effect when called on a window that is
2912 * already visible, so you should call it before calling gtk_window_show().
2914 * On Windows, this function always works, since there's no window manager
2919 gtk_window_set_decorated (GtkWindow *window,
2922 g_return_if_fail (GTK_IS_WINDOW (window));
2924 setting = setting != FALSE;
2926 if (setting == window->decorated)
2929 window->decorated = setting;
2931 if (GTK_WIDGET (window)->window)
2933 if (window->decorated)
2934 gdk_window_set_decorations (GTK_WIDGET (window)->window,
2937 gdk_window_set_decorations (GTK_WIDGET (window)->window,
2941 g_object_notify (G_OBJECT (window), "decorated");
2945 * gtk_window_get_decorated:
2946 * @window: a #GtkWindow
2948 * Returns whether the window has been set to have decorations
2949 * such as a title bar via gtk_window_set_decorated().
2951 * Return value: %TRUE if the window has been set to have decorations
2954 gtk_window_get_decorated (GtkWindow *window)
2956 g_return_val_if_fail (GTK_IS_WINDOW (window), TRUE);
2958 return window->decorated;
2962 * gtk_window_set_deletable:
2963 * @window: a #GtkWindow
2964 * @setting: %TRUE to decorate the window as deletable
2966 * By default, windows have a close button in the window frame. Some
2967 * <link linkend="gtk-X11-arch">window managers</link> allow GTK+ to
2968 * disable this button. If you set the deletable property to %FALSE
2969 * using this function, GTK+ will do its best to convince the window
2970 * manager not to show a close button. Depending on the system, this
2971 * function may not have any effect when called on a window that is
2972 * already visible, so you should call it before calling gtk_window_show().
2974 * On Windows, this function always works, since there's no window manager
2980 gtk_window_set_deletable (GtkWindow *window,
2983 GtkWindowPrivate *priv;
2985 g_return_if_fail (GTK_IS_WINDOW (window));
2987 priv = GTK_WINDOW_GET_PRIVATE (window);
2989 setting = setting != FALSE;
2991 if (setting == priv->deletable)
2994 priv->deletable = setting;
2996 if (GTK_WIDGET (window)->window)
2998 if (priv->deletable)
2999 gdk_window_set_functions (GTK_WIDGET (window)->window,
3002 gdk_window_set_functions (GTK_WIDGET (window)->window,
3003 GDK_FUNC_ALL | GDK_FUNC_CLOSE);
3006 g_object_notify (G_OBJECT (window), "deletable");
3010 * gtk_window_get_deletable:
3011 * @window: a #GtkWindow
3013 * Returns whether the window has been set to have a close button
3014 * via gtk_window_set_deletable().
3016 * Return value: %TRUE if the window has been set to have a close button
3021 gtk_window_get_deletable (GtkWindow *window)
3023 GtkWindowPrivate *priv;
3025 g_return_val_if_fail (GTK_IS_WINDOW (window), TRUE);
3027 priv = GTK_WINDOW_GET_PRIVATE (window);
3029 return priv->deletable;
3032 static GtkWindowIconInfo*
3033 get_icon_info (GtkWindow *window)
3035 return g_object_get_qdata (G_OBJECT (window), quark_gtk_window_icon_info);
3039 free_icon_info (GtkWindowIconInfo *info)
3041 g_free (info->icon_name);
3042 g_slice_free (GtkWindowIconInfo, info);
3046 static GtkWindowIconInfo*
3047 ensure_icon_info (GtkWindow *window)
3049 GtkWindowIconInfo *info;
3051 info = get_icon_info (window);
3055 info = g_slice_new0 (GtkWindowIconInfo);
3056 g_object_set_qdata_full (G_OBJECT (window),
3057 quark_gtk_window_icon_info,
3059 (GDestroyNotify)free_icon_info);
3071 static ScreenIconInfo *
3072 get_screen_icon_info (GdkScreen *screen)
3074 ScreenIconInfo *info = g_object_get_qdata (G_OBJECT (screen),
3075 quark_gtk_window_default_icon_pixmap);
3078 info = g_slice_new0 (ScreenIconInfo);
3079 g_object_set_qdata (G_OBJECT (screen),
3080 quark_gtk_window_default_icon_pixmap, info);
3083 if (info->serial != default_icon_serial)
3087 g_object_remove_weak_pointer (G_OBJECT (info->pixmap), (gpointer*)&info->pixmap);
3088 info->pixmap = NULL;
3093 g_object_remove_weak_pointer (G_OBJECT (info->mask), (gpointer*)&info->mask);
3097 info->serial = default_icon_serial;
3104 get_pixmap_and_mask (GdkWindow *window,
3105 GtkWindowIconInfo *parent_info,
3106 gboolean is_default_list,
3108 GdkPixmap **pmap_return,
3109 GdkBitmap **mask_return)
3111 GdkScreen *screen = gdk_drawable_get_screen (window);
3112 ScreenIconInfo *default_icon_info = get_screen_icon_info (screen);
3113 GdkPixbuf *best_icon;
3117 *pmap_return = NULL;
3118 *mask_return = NULL;
3120 if (is_default_list &&
3121 default_icon_info->pixmap != NULL)
3123 /* Use shared icon pixmap for all windows on this screen.
3125 if (default_icon_info->pixmap)
3126 g_object_ref (default_icon_info->pixmap);
3127 if (default_icon_info->mask)
3128 g_object_ref (default_icon_info->mask);
3130 *pmap_return = default_icon_info->pixmap;
3131 *mask_return = default_icon_info->mask;
3133 else if (parent_info && parent_info->icon_pixmap)
3135 if (parent_info->icon_pixmap)
3136 g_object_ref (parent_info->icon_pixmap);
3137 if (parent_info->icon_mask)
3138 g_object_ref (parent_info->icon_mask);
3140 *pmap_return = parent_info->icon_pixmap;
3141 *mask_return = parent_info->icon_mask;
3145 #define IDEAL_SIZE 48
3147 best_size = G_MAXINT;
3149 tmp_list = icon_list;
3150 while (tmp_list != NULL)
3152 GdkPixbuf *pixbuf = tmp_list->data;
3155 /* average width and height - if someone passes in a rectangular
3156 * icon they deserve what they get.
3158 this = gdk_pixbuf_get_width (pixbuf) + gdk_pixbuf_get_height (pixbuf);
3161 if (best_icon == NULL)
3168 /* icon is better if it's 32 pixels or larger, and closer to
3169 * the ideal size than the current best.
3172 (ABS (best_size - IDEAL_SIZE) <
3173 ABS (this - IDEAL_SIZE)))
3180 tmp_list = tmp_list->next;
3184 gdk_pixbuf_render_pixmap_and_mask_for_colormap (best_icon,
3185 gdk_screen_get_system_colormap (screen),
3190 /* Save pmap/mask for others to use if appropriate */
3193 parent_info->icon_pixmap = *pmap_return;
3194 parent_info->icon_mask = *mask_return;
3196 if (parent_info->icon_pixmap)
3197 g_object_ref (parent_info->icon_pixmap);
3198 if (parent_info->icon_mask)
3199 g_object_ref (parent_info->icon_mask);
3201 else if (is_default_list)
3203 default_icon_info->pixmap = *pmap_return;
3204 default_icon_info->mask = *mask_return;
3206 if (default_icon_info->pixmap)
3207 g_object_add_weak_pointer (G_OBJECT (default_icon_info->pixmap),
3208 (gpointer*)&default_icon_info->pixmap);
3209 if (default_icon_info->mask)
3210 g_object_add_weak_pointer (G_OBJECT (default_icon_info->mask),
3211 (gpointer*)&default_icon_info->mask);
3217 icon_list_from_theme (GtkWidget *widget,
3222 GtkIconTheme *icon_theme;
3227 icon_theme = gtk_icon_theme_get_for_screen (gtk_widget_get_screen (widget));
3229 sizes = gtk_icon_theme_get_icon_sizes (icon_theme, name);
3232 for (i = 0; sizes[i]; i++)
3235 * We need an EWMH extension to handle scalable icons
3236 * by passing their name to the WM. For now just use a
3240 icon = gtk_icon_theme_load_icon (icon_theme, name,
3243 icon = gtk_icon_theme_load_icon (icon_theme, name,
3246 list = g_list_append (list, icon);
3256 gtk_window_realize_icon (GtkWindow *window)
3259 GtkWindowIconInfo *info;
3262 widget = GTK_WIDGET (window);
3264 g_return_if_fail (widget->window != NULL);
3266 /* no point setting an icon on override-redirect */
3267 if (window->type == GTK_WINDOW_POPUP)
3272 info = ensure_icon_info (window);
3277 g_return_if_fail (info->icon_pixmap == NULL);
3278 g_return_if_fail (info->icon_mask == NULL);
3280 info->using_default_icon = FALSE;
3281 info->using_parent_icon = FALSE;
3282 info->using_themed_icon = FALSE;
3284 icon_list = info->icon_list;
3286 /* Look up themed icon */
3287 if (icon_list == NULL && info->icon_name)
3289 icon_list = icon_list_from_theme (widget, info->icon_name);
3291 info->using_themed_icon = TRUE;
3294 /* Inherit from transient parent */
3295 if (icon_list == NULL && window->transient_parent)
3297 icon_list = ensure_icon_info (window->transient_parent)->icon_list;
3299 info->using_parent_icon = TRUE;
3302 /* Inherit from default */
3303 if (icon_list == NULL)
3305 icon_list = default_icon_list;
3307 info->using_default_icon = TRUE;
3310 /* Look up themed icon */
3311 if (icon_list == NULL && default_icon_name)
3313 icon_list = icon_list_from_theme (widget, default_icon_name);
3314 info->using_default_icon = TRUE;
3315 info->using_themed_icon = TRUE;
3318 gdk_window_set_icon_list (widget->window, icon_list);
3320 get_pixmap_and_mask (widget->window,
3321 info->using_parent_icon ? ensure_icon_info (window->transient_parent) : NULL,
3322 info->using_default_icon,
3327 /* This is a slight ICCCM violation since it's a color pixmap not
3328 * a bitmap, but everyone does it.
3330 gdk_window_set_icon (widget->window,
3335 info->realized = TRUE;
3337 if (info->using_themed_icon)
3339 GtkIconTheme *icon_theme;
3341 g_list_foreach (icon_list, (GFunc) g_object_unref, NULL);
3342 g_list_free (icon_list);
3344 icon_theme = gtk_icon_theme_get_for_screen (gtk_widget_get_screen (GTK_WIDGET (window)));
3345 g_signal_connect (icon_theme, "changed",
3346 G_CALLBACK (update_themed_icon), window);
3351 gtk_window_unrealize_icon (GtkWindow *window)
3353 GtkWindowIconInfo *info;
3355 info = get_icon_info (window);
3360 if (info->icon_pixmap)
3361 g_object_unref (info->icon_pixmap);
3363 if (info->icon_mask)
3364 g_object_unref (info->icon_mask);
3366 info->icon_pixmap = NULL;
3367 info->icon_mask = NULL;
3369 if (info->using_themed_icon)
3371 GtkIconTheme *icon_theme;
3373 icon_theme = gtk_icon_theme_get_for_screen (gtk_widget_get_screen (GTK_WIDGET (window)));
3375 g_signal_handlers_disconnect_by_func (icon_theme, update_themed_icon, window);
3378 /* We don't clear the properties on the window, just figure the
3379 * window is going away.
3382 info->realized = FALSE;
3387 * gtk_window_set_icon_list:
3388 * @window: a #GtkWindow
3389 * @list: (element-type GdkPixbuf) (transfer container): list of #GdkPixbuf
3391 * Sets up the icon representing a #GtkWindow. The icon is used when
3392 * the window is minimized (also known as iconified). Some window
3393 * managers or desktop environments may also place it in the window
3394 * frame, or display it in other contexts.
3396 * gtk_window_set_icon_list() allows you to pass in the same icon in
3397 * several hand-drawn sizes. The list should contain the natural sizes
3398 * your icon is available in; that is, don't scale the image before
3399 * passing it to GTK+. Scaling is postponed until the last minute,
3400 * when the desired final size is known, to allow best quality.
3402 * By passing several sizes, you may improve the final image quality
3403 * of the icon, by reducing or eliminating automatic image scaling.
3405 * Recommended sizes to provide: 16x16, 32x32, 48x48 at minimum, and
3406 * larger images (64x64, 128x128) if you have them.
3408 * See also gtk_window_set_default_icon_list() to set the icon
3409 * for all windows in your application in one go.
3411 * Note that transient windows (those who have been set transient for another
3412 * window using gtk_window_set_transient_for()) will inherit their
3413 * icon from their transient parent. So there's no need to explicitly
3414 * set the icon on transient windows.
3417 gtk_window_set_icon_list (GtkWindow *window,
3420 GtkWindowIconInfo *info;
3422 g_return_if_fail (GTK_IS_WINDOW (window));
3424 info = ensure_icon_info (window);
3426 if (info->icon_list == list) /* check for NULL mostly */
3429 g_list_foreach (list,
3430 (GFunc) g_object_ref, NULL);
3432 g_list_foreach (info->icon_list,
3433 (GFunc) g_object_unref, NULL);
3435 g_list_free (info->icon_list);
3437 info->icon_list = g_list_copy (list);
3439 g_object_notify (G_OBJECT (window), "icon");
3441 gtk_window_unrealize_icon (window);
3443 if (gtk_widget_get_realized (GTK_WIDGET (window)))
3444 gtk_window_realize_icon (window);
3446 /* We could try to update our transient children, but I don't think
3447 * it's really worth it. If we did it, the best way would probably
3448 * be to have children connect to notify::icon-list
3453 * gtk_window_get_icon_list:
3454 * @window: a #GtkWindow
3456 * Retrieves the list of icons set by gtk_window_set_icon_list().
3457 * The list is copied, but the reference count on each
3458 * member won't be incremented.
3460 * Return value: (element-type GdkPixbuf) (transfer container): copy of window's icon list
3463 gtk_window_get_icon_list (GtkWindow *window)
3465 GtkWindowIconInfo *info;
3467 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
3469 info = get_icon_info (window);
3472 return g_list_copy (info->icon_list);
3478 * gtk_window_set_icon:
3479 * @window: a #GtkWindow
3480 * @icon: (allow-none): icon image, or %NULL
3482 * Sets up the icon representing a #GtkWindow. This icon is used when
3483 * the window is minimized (also known as iconified). Some window
3484 * managers or desktop environments may also place it in the window
3485 * frame, or display it in other contexts.
3487 * The icon should be provided in whatever size it was naturally
3488 * drawn; that is, don't scale the image before passing it to
3489 * GTK+. Scaling is postponed until the last minute, when the desired
3490 * final size is known, to allow best quality.
3492 * If you have your icon hand-drawn in multiple sizes, use
3493 * gtk_window_set_icon_list(). Then the best size will be used.
3495 * This function is equivalent to calling gtk_window_set_icon_list()
3496 * with a 1-element list.
3498 * See also gtk_window_set_default_icon_list() to set the icon
3499 * for all windows in your application in one go.
3502 gtk_window_set_icon (GtkWindow *window,
3507 g_return_if_fail (GTK_IS_WINDOW (window));
3508 g_return_if_fail (icon == NULL || GDK_IS_PIXBUF (icon));
3513 list = g_list_append (list, icon);
3515 gtk_window_set_icon_list (window, list);
3521 update_themed_icon (GtkIconTheme *icon_theme,
3524 g_object_notify (G_OBJECT (window), "icon");
3526 gtk_window_unrealize_icon (window);
3528 if (gtk_widget_get_realized (GTK_WIDGET (window)))
3529 gtk_window_realize_icon (window);
3533 * gtk_window_set_icon_name:
3534 * @window: a #GtkWindow
3535 * @name: (allow-none): the name of the themed icon
3537 * Sets the icon for the window from a named themed icon. See
3538 * the docs for #GtkIconTheme for more details.
3540 * Note that this has nothing to do with the WM_ICON_NAME
3541 * property which is mentioned in the ICCCM.
3546 gtk_window_set_icon_name (GtkWindow *window,
3549 GtkWindowIconInfo *info;
3552 g_return_if_fail (GTK_IS_WINDOW (window));
3554 info = ensure_icon_info (window);
3556 if (g_strcmp0 (info->icon_name, name) == 0)
3559 tmp = info->icon_name;
3560 info->icon_name = g_strdup (name);
3563 g_list_foreach (info->icon_list, (GFunc) g_object_unref, NULL);
3564 g_list_free (info->icon_list);
3565 info->icon_list = NULL;
3567 update_themed_icon (NULL, window);
3569 g_object_notify (G_OBJECT (window), "icon-name");
3573 * gtk_window_get_icon_name:
3574 * @window: a #GtkWindow
3576 * Returns the name of the themed icon for the window,
3577 * see gtk_window_set_icon_name().
3579 * Returns: the icon name or %NULL if the window has
3585 gtk_window_get_icon_name (GtkWindow *window)
3587 GtkWindowIconInfo *info;
3589 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
3591 info = ensure_icon_info (window);
3593 return info->icon_name;
3597 * gtk_window_get_icon:
3598 * @window: a #GtkWindow
3600 * Gets the value set by gtk_window_set_icon() (or if you've
3601 * called gtk_window_set_icon_list(), gets the first icon in
3604 * Return value: (transfer none): icon for window
3607 gtk_window_get_icon (GtkWindow *window)
3609 GtkWindowIconInfo *info;
3611 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
3613 info = get_icon_info (window);
3614 if (info && info->icon_list)
3615 return GDK_PIXBUF (info->icon_list->data);
3620 /* Load pixbuf, printing warning on failure if error == NULL
3623 load_pixbuf_verbosely (const char *filename,
3626 GError *local_err = NULL;
3629 pixbuf = gdk_pixbuf_new_from_file (filename, &local_err);
3637 g_warning ("Error loading icon from file '%s':\n\t%s",
3638 filename, local_err->message);
3639 g_error_free (local_err);
3647 * gtk_window_set_icon_from_file:
3648 * @window: a #GtkWindow
3649 * @filename: location of icon file
3650 * @err: (allow-none): location to store error, or %NULL.
3652 * Sets the icon for @window.
3653 * Warns on failure if @err is %NULL.
3655 * This function is equivalent to calling gtk_window_set_icon()
3656 * with a pixbuf created by loading the image from @filename.
3658 * Returns: %TRUE if setting the icon succeeded.
3663 gtk_window_set_icon_from_file (GtkWindow *window,
3664 const gchar *filename,
3667 GdkPixbuf *pixbuf = load_pixbuf_verbosely (filename, err);
3671 gtk_window_set_icon (window, pixbuf);
3672 g_object_unref (pixbuf);
3681 * gtk_window_set_default_icon_list:
3682 * @list: (element-type GdkPixbuf) (transfer container) a list of #GdkPixbuf
3684 * Sets an icon list to be used as fallback for windows that haven't
3685 * had gtk_window_set_icon_list() called on them to set up a
3686 * window-specific icon list. This function allows you to set up the
3687 * icon for all windows in your app at once.
3689 * See gtk_window_set_icon_list() for more details.
3693 gtk_window_set_default_icon_list (GList *list)
3697 if (list == default_icon_list)
3700 /* Update serial so we don't used cached pixmaps/masks
3702 default_icon_serial++;
3704 g_list_foreach (list,
3705 (GFunc) g_object_ref, NULL);
3707 g_list_foreach (default_icon_list,
3708 (GFunc) g_object_unref, NULL);
3710 g_list_free (default_icon_list);
3712 default_icon_list = g_list_copy (list);
3714 /* Update all toplevels */
3715 toplevels = gtk_window_list_toplevels ();
3716 tmp_list = toplevels;
3717 while (tmp_list != NULL)
3719 GtkWindowIconInfo *info;
3720 GtkWindow *w = tmp_list->data;
3722 info = get_icon_info (w);
3723 if (info && info->using_default_icon)
3725 gtk_window_unrealize_icon (w);
3726 if (gtk_widget_get_realized (GTK_WIDGET (w)))
3727 gtk_window_realize_icon (w);
3730 tmp_list = tmp_list->next;
3732 g_list_free (toplevels);
3736 * gtk_window_set_default_icon:
3739 * Sets an icon to be used as fallback for windows that haven't
3740 * had gtk_window_set_icon() called on them from a pixbuf.
3745 gtk_window_set_default_icon (GdkPixbuf *icon)
3749 g_return_if_fail (GDK_IS_PIXBUF (icon));
3751 list = g_list_prepend (NULL, icon);
3752 gtk_window_set_default_icon_list (list);
3757 * gtk_window_set_default_icon_name:
3758 * @name: the name of the themed icon
3760 * Sets an icon to be used as fallback for windows that haven't
3761 * had gtk_window_set_icon_list() called on them from a named
3762 * themed icon, see gtk_window_set_icon_name().
3767 gtk_window_set_default_icon_name (const gchar *name)
3772 /* Update serial so we don't used cached pixmaps/masks
3774 default_icon_serial++;
3776 g_free (default_icon_name);
3777 default_icon_name = g_strdup (name);
3779 g_list_foreach (default_icon_list,
3780 (GFunc) g_object_unref, NULL);
3782 g_list_free (default_icon_list);
3783 default_icon_list = NULL;
3785 /* Update all toplevels */
3786 toplevels = gtk_window_list_toplevels ();
3787 tmp_list = toplevels;
3788 while (tmp_list != NULL)
3790 GtkWindowIconInfo *info;
3791 GtkWindow *w = tmp_list->data;
3793 info = get_icon_info (w);
3794 if (info && info->using_default_icon && info->using_themed_icon)
3796 gtk_window_unrealize_icon (w);
3797 if (gtk_widget_get_realized (GTK_WIDGET (w)))
3798 gtk_window_realize_icon (w);
3801 tmp_list = tmp_list->next;
3803 g_list_free (toplevels);
3807 * gtk_window_get_default_icon_name:
3809 * Returns the fallback icon name for windows that has been set
3810 * with gtk_window_set_default_icon_name(). The returned
3811 * string is owned by GTK+ and should not be modified. It
3812 * is only valid until the next call to
3813 * gtk_window_set_default_icon_name().
3815 * Returns: the fallback icon name for windows
3820 gtk_window_get_default_icon_name (void)
3822 return default_icon_name;
3826 * gtk_window_set_default_icon_from_file:
3827 * @filename: location of icon file
3828 * @err: (allow-none): location to store error, or %NULL.
3830 * Sets an icon to be used as fallback for windows that haven't
3831 * had gtk_window_set_icon_list() called on them from a file
3832 * on disk. Warns on failure if @err is %NULL.
3834 * Returns: %TRUE if setting the icon succeeded.
3839 gtk_window_set_default_icon_from_file (const gchar *filename,
3842 GdkPixbuf *pixbuf = load_pixbuf_verbosely (filename, err);
3846 gtk_window_set_default_icon (pixbuf);
3847 g_object_unref (pixbuf);
3856 * gtk_window_get_default_icon_list:
3858 * Gets the value set by gtk_window_set_default_icon_list().
3859 * The list is a copy and should be freed with g_list_free(),
3860 * but the pixbufs in the list have not had their reference count
3863 * Return value: (element-type GdkPixbuf) (transfer container): copy of default icon list
3866 gtk_window_get_default_icon_list (void)
3868 return g_list_copy (default_icon_list);
3872 gtk_window_set_default_size_internal (GtkWindow *window,
3873 gboolean change_width,
3875 gboolean change_height,
3877 gboolean is_geometry)
3879 GtkWindowGeometryInfo *info;
3881 g_return_if_fail (change_width == FALSE || width >= -1);
3882 g_return_if_fail (change_height == FALSE || height >= -1);
3884 info = gtk_window_get_geometry_info (window, TRUE);
3886 g_object_freeze_notify (G_OBJECT (window));
3888 info->default_is_geometry = is_geometry != FALSE;
3898 info->default_width = width;
3900 g_object_notify (G_OBJECT (window), "default-width");
3911 info->default_height = height;
3913 g_object_notify (G_OBJECT (window), "default-height");
3916 g_object_thaw_notify (G_OBJECT (window));
3918 gtk_widget_queue_resize_no_redraw (GTK_WIDGET (window));
3922 * gtk_window_set_default_size:
3923 * @window: a #GtkWindow
3924 * @width: width in pixels, or -1 to unset the default width
3925 * @height: height in pixels, or -1 to unset the default height
3927 * Sets the default size of a window. If the window's "natural" size
3928 * (its size request) is larger than the default, the default will be
3929 * ignored. More generally, if the default size does not obey the
3930 * geometry hints for the window (gtk_window_set_geometry_hints() can
3931 * be used to set these explicitly), the default size will be clamped
3932 * to the nearest permitted size.
3934 * Unlike gtk_widget_set_size_request(), which sets a size request for
3935 * a widget and thus would keep users from shrinking the window, this
3936 * function only sets the initial size, just as if the user had
3937 * resized the window themselves. Users can still shrink the window
3938 * again as they normally would. Setting a default size of -1 means to
3939 * use the "natural" default size (the size request of the window).
3941 * For more control over a window's initial size and how resizing works,
3942 * investigate gtk_window_set_geometry_hints().
3944 * For some uses, gtk_window_resize() is a more appropriate function.
3945 * gtk_window_resize() changes the current size of the window, rather
3946 * than the size to be used on initial display. gtk_window_resize() always
3947 * affects the window itself, not the geometry widget.
3949 * The default size of a window only affects the first time a window is
3950 * shown; if a window is hidden and re-shown, it will remember the size
3951 * it had prior to hiding, rather than using the default size.
3953 * Windows can't actually be 0x0 in size, they must be at least 1x1, but
3954 * passing 0 for @width and @height is OK, resulting in a 1x1 default size.
3957 gtk_window_set_default_size (GtkWindow *window,
3961 g_return_if_fail (GTK_IS_WINDOW (window));
3962 g_return_if_fail (width >= -1);
3963 g_return_if_fail (height >= -1);
3965 gtk_window_set_default_size_internal (window, TRUE, width, TRUE, height, FALSE);
3969 * gtk_window_get_default_size:
3970 * @window: a #GtkWindow
3971 * @width: (out) (allow-none): location to store the default width, or %NULL
3972 * @height: (out) (allow-none): location to store the default height, or %NULL
3974 * Gets the default size of the window. A value of -1 for the width or
3975 * height indicates that a default size has not been explicitly set
3976 * for that dimension, so the "natural" size of the window will be
3981 gtk_window_get_default_size (GtkWindow *window,
3985 GtkWindowGeometryInfo *info;
3987 g_return_if_fail (GTK_IS_WINDOW (window));
3989 info = gtk_window_get_geometry_info (window, FALSE);
3992 *width = info ? info->default_width : -1;
3995 *height = info ? info->default_height : -1;
3999 * gtk_window_resize:
4000 * @window: a #GtkWindow
4001 * @width: width in pixels to resize the window to
4002 * @height: height in pixels to resize the window to
4004 * Resizes the window as if the user had done so, obeying geometry
4005 * constraints. The default geometry constraint is that windows may
4006 * not be smaller than their size request; to override this
4007 * constraint, call gtk_widget_set_size_request() to set the window's
4008 * request to a smaller value.
4010 * If gtk_window_resize() is called before showing a window for the
4011 * first time, it overrides any default size set with
4012 * gtk_window_set_default_size().
4014 * Windows may not be resized smaller than 1 by 1 pixels.
4018 gtk_window_resize (GtkWindow *window,
4022 GtkWindowGeometryInfo *info;
4024 g_return_if_fail (GTK_IS_WINDOW (window));
4025 g_return_if_fail (width > 0);
4026 g_return_if_fail (height > 0);
4028 info = gtk_window_get_geometry_info (window, TRUE);
4030 info->resize_width = width;
4031 info->resize_height = height;
4033 gtk_widget_queue_resize_no_redraw (GTK_WIDGET (window));
4037 * gtk_window_get_size:
4038 * @window: a #GtkWindow
4039 * @width: (allow-none): (out): return location for width, or %NULL
4040 * @height: (allow-none): (out): return location for height, or %NULL
4042 * Obtains the current size of @window. If @window is not onscreen,
4043 * it returns the size GTK+ will suggest to the <link
4044 * linkend="gtk-X11-arch">window manager</link> for the initial window
4045 * size (but this is not reliably the same as the size the window
4046 * manager will actually select). The size obtained by
4047 * gtk_window_get_size() is the last size received in a
4048 * #GdkEventConfigure, that is, GTK+ uses its locally-stored size,
4049 * rather than querying the X server for the size. As a result, if you
4050 * call gtk_window_resize() then immediately call
4051 * gtk_window_get_size(), the size won't have taken effect yet. After
4052 * the window manager processes the resize request, GTK+ receives
4053 * notification that the size has changed via a configure event, and
4054 * the size of the window gets updated.
4056 * Note 1: Nearly any use of this function creates a race condition,
4057 * because the size of the window may change between the time that you
4058 * get the size and the time that you perform some action assuming
4059 * that size is the current size. To avoid race conditions, connect to
4060 * "configure-event" on the window and adjust your size-dependent
4061 * state to match the size delivered in the #GdkEventConfigure.
4063 * Note 2: The returned size does <emphasis>not</emphasis> include the
4064 * size of the window manager decorations (aka the window frame or
4065 * border). Those are not drawn by GTK+ and GTK+ has no reliable
4066 * method of determining their size.
4068 * Note 3: If you are getting a window size in order to position
4069 * the window onscreen, there may be a better way. The preferred
4070 * way is to simply set the window's semantic type with
4071 * gtk_window_set_type_hint(), which allows the window manager to
4072 * e.g. center dialogs. Also, if you set the transient parent of
4073 * dialogs with gtk_window_set_transient_for() window managers
4074 * will often center the dialog over its parent window. It's
4075 * much preferred to let the window manager handle these
4076 * things rather than doing it yourself, because all apps will
4077 * behave consistently and according to user prefs if the window
4078 * manager handles it. Also, the window manager can take the size
4079 * of the window decorations/border into account, while your
4080 * application cannot.
4082 * In any case, if you insist on application-specified window
4083 * positioning, there's <emphasis>still</emphasis> a better way than
4084 * doing it yourself - gtk_window_set_position() will frequently
4085 * handle the details for you.
4089 gtk_window_get_size (GtkWindow *window,
4095 g_return_if_fail (GTK_IS_WINDOW (window));
4097 if (width == NULL && height == NULL)
4100 if (gtk_widget_get_mapped (GTK_WIDGET (window)))
4102 gdk_drawable_get_size (GTK_WIDGET (window)->window,
4107 GdkRectangle configure_request;
4109 gtk_window_compute_configure_request (window,
4113 w = configure_request.width;
4114 h = configure_request.height;
4125 * @window: a #GtkWindow
4126 * @x: X coordinate to move window to
4127 * @y: Y coordinate to move window to
4129 * Asks the <link linkend="gtk-X11-arch">window manager</link> to move
4130 * @window to the given position. Window managers are free to ignore
4131 * this; most window managers ignore requests for initial window
4132 * positions (instead using a user-defined placement algorithm) and
4133 * honor requests after the window has already been shown.
4135 * Note: the position is the position of the gravity-determined
4136 * reference point for the window. The gravity determines two things:
4137 * first, the location of the reference point in root window
4138 * coordinates; and second, which point on the window is positioned at
4139 * the reference point.
4141 * By default the gravity is #GDK_GRAVITY_NORTH_WEST, so the reference
4142 * point is simply the @x, @y supplied to gtk_window_move(). The
4143 * top-left corner of the window decorations (aka window frame or
4144 * border) will be placed at @x, @y. Therefore, to position a window
4145 * at the top left of the screen, you want to use the default gravity
4146 * (which is #GDK_GRAVITY_NORTH_WEST) and move the window to 0,0.
4148 * To position a window at the bottom right corner of the screen, you
4149 * would set #GDK_GRAVITY_SOUTH_EAST, which means that the reference
4150 * point is at @x + the window width and @y + the window height, and
4151 * the bottom-right corner of the window border will be placed at that
4152 * reference point. So, to place a window in the bottom right corner
4153 * you would first set gravity to south east, then write:
4154 * <literal>gtk_window_move (window, gdk_screen_width () - window_width,
4155 * gdk_screen_height () - window_height)</literal> (note that this
4156 * example does not take multi-head scenarios into account).
4158 * The Extended Window Manager Hints specification at <ulink
4159 * url="http://www.freedesktop.org/Standards/wm-spec">
4160 * http://www.freedesktop.org/Standards/wm-spec</ulink> has a
4161 * nice table of gravities in the "implementation notes" section.
4163 * The gtk_window_get_position() documentation may also be relevant.
4166 gtk_window_move (GtkWindow *window,
4170 GtkWindowGeometryInfo *info;
4173 g_return_if_fail (GTK_IS_WINDOW (window));
4175 widget = GTK_WIDGET (window);
4177 info = gtk_window_get_geometry_info (window, TRUE);
4179 if (gtk_widget_get_mapped (widget))
4181 /* we have now sent a request with this position
4182 * with currently-active constraints, so toggle flag.
4184 info->position_constraints_changed = FALSE;
4186 /* we only constrain if mapped - if not mapped,
4187 * then gtk_window_compute_configure_request()
4188 * will apply the constraints later, and we
4189 * don't want to lose information about
4190 * what position the user set before then.
4191 * i.e. if you do a move() then turn off POS_CENTER
4192 * then show the window, your move() will work.
4194 gtk_window_constrain_position (window,
4195 widget->allocation.width,
4196 widget->allocation.height,
4199 /* Note that this request doesn't go through our standard request
4200 * framework, e.g. doesn't increment configure_request_count,
4201 * doesn't set info->last, etc.; that's because
4202 * we don't save the info needed to arrive at this same request
4205 * To gtk_window_move_resize(), this will end up looking exactly
4206 * the same as the position being changed by the window
4210 /* FIXME are we handling gravity properly for framed windows? */
4212 gdk_window_move (window->frame,
4213 x - window->frame_left,
4214 y - window->frame_top);
4216 gdk_window_move (GTK_WIDGET (window)->window,
4221 /* Save this position to apply on mapping */
4222 info->initial_x = x;
4223 info->initial_y = y;
4224 info->initial_pos_set = TRUE;
4229 * gtk_window_get_position:
4230 * @window: a #GtkWindow
4231 * @root_x: (out): return location for X coordinate of gravity-determined reference point
4232 * @root_y: (out): return location for Y coordinate of gravity-determined reference point
4234 * This function returns the position you need to pass to
4235 * gtk_window_move() to keep @window in its current position. This
4236 * means that the meaning of the returned value varies with window
4237 * gravity. See gtk_window_move() for more details.
4239 * If you haven't changed the window gravity, its gravity will be
4240 * #GDK_GRAVITY_NORTH_WEST. This means that gtk_window_get_position()
4241 * gets the position of the top-left corner of the window manager
4242 * frame for the window. gtk_window_move() sets the position of this
4243 * same top-left corner.
4245 * gtk_window_get_position() is not 100% reliable because the X Window System
4246 * does not specify a way to obtain the geometry of the
4247 * decorations placed on a window by the window manager.
4248 * Thus GTK+ is using a "best guess" that works with most
4251 * Moreover, nearly all window managers are historically broken with
4252 * respect to their handling of window gravity. So moving a window to
4253 * its current position as returned by gtk_window_get_position() tends
4254 * to result in moving the window slightly. Window managers are
4255 * slowly getting better over time.
4257 * If a window has gravity #GDK_GRAVITY_STATIC the window manager
4258 * frame is not relevant, and thus gtk_window_get_position() will
4259 * always produce accurate results. However you can't use static
4260 * gravity to do things like place a window in a corner of the screen,
4261 * because static gravity ignores the window manager decorations.
4263 * If you are saving and restoring your application's window
4264 * positions, you should know that it's impossible for applications to
4265 * do this without getting it somewhat wrong because applications do
4266 * not have sufficient knowledge of window manager state. The Correct
4267 * Mechanism is to support the session management protocol (see the
4268 * "GnomeClient" object in the GNOME libraries for example) and allow
4269 * the window manager to save your window sizes and positions.
4274 gtk_window_get_position (GtkWindow *window,
4280 g_return_if_fail (GTK_IS_WINDOW (window));
4282 widget = GTK_WIDGET (window);
4284 if (window->gravity == GDK_GRAVITY_STATIC)
4286 if (gtk_widget_get_mapped (widget))
4288 /* This does a server round-trip, which is sort of wrong;
4289 * but a server round-trip is inevitable for
4290 * gdk_window_get_frame_extents() in the usual
4291 * NorthWestGravity case below, so not sure what else to
4292 * do. We should likely be consistent about whether we get
4293 * the client-side info or the server-side info.
4295 gdk_window_get_origin (widget->window, root_x, root_y);
4299 GdkRectangle configure_request;
4301 gtk_window_compute_configure_request (window,
4305 *root_x = configure_request.x;
4306 *root_y = configure_request.y;
4311 GdkRectangle frame_extents;
4316 if (gtk_widget_get_mapped (widget))
4319 gdk_window_get_frame_extents (window->frame, &frame_extents);
4321 gdk_window_get_frame_extents (widget->window, &frame_extents);
4322 x = frame_extents.x;
4323 y = frame_extents.y;
4324 gtk_window_get_size (window, &w, &h);
4328 /* We just say the frame has 0 size on all sides.
4329 * Not sure what else to do.
4331 gtk_window_compute_configure_request (window,
4334 x = frame_extents.x;
4335 y = frame_extents.y;
4336 w = frame_extents.width;
4337 h = frame_extents.height;
4340 switch (window->gravity)
4342 case GDK_GRAVITY_NORTH:
4343 case GDK_GRAVITY_CENTER:
4344 case GDK_GRAVITY_SOUTH:
4345 /* Find center of frame. */
4346 x += frame_extents.width / 2;
4347 /* Center client window on that point. */
4351 case GDK_GRAVITY_SOUTH_EAST:
4352 case GDK_GRAVITY_EAST:
4353 case GDK_GRAVITY_NORTH_EAST:
4354 /* Find right edge of frame */
4355 x += frame_extents.width;
4356 /* Align left edge of client at that point. */
4363 switch (window->gravity)
4365 case GDK_GRAVITY_WEST:
4366 case GDK_GRAVITY_CENTER:
4367 case GDK_GRAVITY_EAST:
4368 /* Find center of frame. */
4369 y += frame_extents.height / 2;
4370 /* Center client window there. */
4373 case GDK_GRAVITY_SOUTH_WEST:
4374 case GDK_GRAVITY_SOUTH:
4375 case GDK_GRAVITY_SOUTH_EAST:
4376 /* Find south edge of frame */
4377 y += frame_extents.height;
4378 /* Place bottom edge of client there */
4393 * gtk_window_reshow_with_initial_size:
4394 * @window: a #GtkWindow
4396 * Hides @window, then reshows it, resetting the
4397 * default size and position of the window. Used
4398 * by GUI builders only.
4401 gtk_window_reshow_with_initial_size (GtkWindow *window)
4405 g_return_if_fail (GTK_IS_WINDOW (window));
4407 widget = GTK_WIDGET (window);
4409 gtk_widget_hide (widget);
4410 gtk_widget_unrealize (widget);
4411 gtk_widget_show (widget);
4415 gtk_window_destroy (GtkObject *object)
4417 GtkWindow *window = GTK_WINDOW (object);
4419 toplevel_list = g_slist_remove (toplevel_list, window);
4421 if (window->transient_parent)
4422 gtk_window_set_transient_for (window, NULL);
4424 /* frees the icons */
4425 gtk_window_set_icon_list (window, NULL);
4427 if (window->has_user_ref_count)
4429 window->has_user_ref_count = FALSE;
4430 g_object_unref (window);
4434 gtk_window_group_remove_window (window->group, window);
4436 gtk_window_free_key_hash (window);
4438 GTK_OBJECT_CLASS (gtk_window_parent_class)->destroy (object);
4442 gtk_window_finalize (GObject *object)
4444 GtkWindow *window = GTK_WINDOW (object);
4445 GtkWindowPrivate *priv = GTK_WINDOW_GET_PRIVATE (window);
4446 GtkMnemonicHash *mnemonic_hash;
4448 g_free (window->title);
4449 g_free (window->wmclass_name);
4450 g_free (window->wmclass_class);
4451 g_free (window->wm_role);
4453 mnemonic_hash = gtk_window_get_mnemonic_hash (window, FALSE);
4455 _gtk_mnemonic_hash_free (mnemonic_hash);
4457 if (window->geometry_info)
4459 if (window->geometry_info->widget)
4460 g_signal_handlers_disconnect_by_func (window->geometry_info->widget,
4461 gtk_widget_destroyed,
4462 &window->geometry_info->widget);
4463 g_free (window->geometry_info);
4466 if (window->keys_changed_handler)
4468 g_source_remove (window->keys_changed_handler);
4469 window->keys_changed_handler = 0;
4473 g_signal_handlers_disconnect_by_func (window->screen,
4474 gtk_window_on_composited_changed, window);
4476 g_free (priv->startup_id);
4478 G_OBJECT_CLASS (gtk_window_parent_class)->finalize (object);
4482 gtk_window_show (GtkWidget *widget)
4484 GtkWindow *window = GTK_WINDOW (widget);
4485 GtkContainer *container = GTK_CONTAINER (window);
4486 gboolean need_resize;
4488 GTK_WIDGET_SET_FLAGS (widget, GTK_VISIBLE);
4490 need_resize = container->need_resize || !gtk_widget_get_realized (widget);
4491 container->need_resize = FALSE;
4495 GtkWindowGeometryInfo *info = gtk_window_get_geometry_info (window, TRUE);
4496 GtkAllocation allocation = { 0, 0 };
4497 GdkRectangle configure_request;
4498 GdkGeometry new_geometry;
4500 gboolean was_realized;
4502 /* We are going to go ahead and perform this configure request
4503 * and then emulate a configure notify by going ahead and
4504 * doing a size allocate. Sort of a synchronous
4505 * mini-copy of gtk_window_move_resize() here.
4507 gtk_window_compute_configure_request (window,
4512 /* We update this because we are going to go ahead
4513 * and gdk_window_resize() below, rather than
4516 info->last.configure_request.width = configure_request.width;
4517 info->last.configure_request.height = configure_request.height;
4519 /* and allocate the window - this is normally done
4520 * in move_resize in response to configure notify
4522 allocation.width = configure_request.width;
4523 allocation.height = configure_request.height;
4524 gtk_widget_size_allocate (widget, &allocation);
4526 /* Then we guarantee we have a realize */
4527 was_realized = FALSE;
4528 if (!gtk_widget_get_realized (widget))
4530 gtk_widget_realize (widget);
4531 was_realized = TRUE;
4534 /* Must be done after the windows are realized,
4535 * so that the decorations can be read
4537 gtk_decorated_window_calculate_frame_size (window);
4539 /* We only send configure request if we didn't just finish
4540 * creating the window; if we just created the window
4541 * then we created it with widget->allocation anyhow.
4544 gdk_window_move_resize (widget->window,
4545 configure_request.x,
4546 configure_request.y,
4547 configure_request.width,
4548 configure_request.height);
4551 gtk_container_check_resize (container);
4553 gtk_widget_map (widget);
4555 /* Try to make sure that we have some focused widget
4557 if (!window->focus_widget && !GTK_IS_PLUG (window))
4558 gtk_window_move_focus (window, GTK_DIR_TAB_FORWARD);
4561 gtk_grab_add (widget);
4565 gtk_window_hide (GtkWidget *widget)
4567 GtkWindow *window = GTK_WINDOW (widget);
4569 GTK_WIDGET_UNSET_FLAGS (widget, GTK_VISIBLE);
4570 gtk_widget_unmap (widget);
4573 gtk_grab_remove (widget);
4577 gtk_window_map (GtkWidget *widget)
4579 GtkWindow *window = GTK_WINDOW (widget);
4580 GtkWindowPrivate *priv = GTK_WINDOW_GET_PRIVATE (window);
4581 GdkWindow *toplevel;
4582 gboolean auto_mnemonics;
4584 gtk_widget_set_mapped (widget, TRUE);
4586 if (window->bin.child &&
4587 gtk_widget_get_visible (window->bin.child) &&
4588 !gtk_widget_get_mapped (window->bin.child))
4589 gtk_widget_map (window->bin.child);
4592 toplevel = window->frame;
4594 toplevel = widget->window;
4596 if (window->maximize_initially)
4597 gdk_window_maximize (toplevel);
4599 gdk_window_unmaximize (toplevel);
4601 if (window->stick_initially)
4602 gdk_window_stick (toplevel);
4604 gdk_window_unstick (toplevel);
4606 if (window->iconify_initially)
4607 gdk_window_iconify (toplevel);
4609 gdk_window_deiconify (toplevel);
4611 if (priv->fullscreen_initially)
4612 gdk_window_fullscreen (toplevel);
4614 gdk_window_unfullscreen (toplevel);
4616 gdk_window_set_keep_above (toplevel, priv->above_initially);
4618 gdk_window_set_keep_below (toplevel, priv->below_initially);
4620 /* No longer use the default settings */
4621 window->need_default_size = FALSE;
4622 window->need_default_position = FALSE;
4624 if (priv->reset_type_hint)
4626 /* We should only reset the type hint when the application
4627 * used gtk_window_set_type_hint() to change the hint.
4628 * Some applications use X directly to change the properties;
4629 * in that case, we shouldn't overwrite what they did.
4631 gdk_window_set_type_hint (widget->window, priv->type_hint);
4632 priv->reset_type_hint = FALSE;
4635 gdk_window_show (widget->window);
4638 gdk_window_show (window->frame);
4640 if (!disable_startup_notification)
4642 /* Do we have a custom startup-notification id? */
4643 if (priv->startup_id != NULL)
4645 /* Make sure we have a "real" id */
4646 if (!startup_id_is_fake (priv->startup_id))
4647 gdk_notify_startup_complete_with_id (priv->startup_id);
4649 g_free (priv->startup_id);
4650 priv->startup_id = NULL;
4652 else if (!sent_startup_notification)
4654 sent_startup_notification = TRUE;
4655 gdk_notify_startup_complete ();
4659 /* if auto-mnemonics is enabled and mnemonics visible is not already set
4660 * (as in the case of popup menus), then hide mnemonics initially
4662 g_object_get (gtk_widget_get_settings (widget), "gtk-auto-mnemonics",
4663 &auto_mnemonics, NULL);
4664 if (auto_mnemonics && !priv->mnemonics_visible_set)
4665 gtk_window_set_mnemonics_visible (window, FALSE);
4669 gtk_window_map_event (GtkWidget *widget,
4672 if (!gtk_widget_get_mapped (widget))
4674 /* we should be be unmapped, but are getting a MapEvent, this may happen
4675 * to toplevel XWindows if mapping was intercepted by a window manager
4676 * and an unmap request occoured while the MapRequestEvent was still
4677 * being handled. we work around this situaiton here by re-requesting
4678 * the window being unmapped. more details can be found in:
4679 * http://bugzilla.gnome.org/show_bug.cgi?id=316180
4681 gdk_window_hide (widget->window);
4687 gtk_window_unmap (GtkWidget *widget)
4689 GtkWindow *window = GTK_WINDOW (widget);
4690 GtkWindowPrivate *priv = GTK_WINDOW_GET_PRIVATE (widget);
4691 GtkWindowGeometryInfo *info;
4692 GdkWindowState state;
4694 gtk_widget_set_mapped (widget, FALSE);
4696 gdk_window_withdraw (window->frame);
4698 gdk_window_withdraw (widget->window);
4700 window->configure_request_count = 0;
4701 window->configure_notify_received = FALSE;
4703 /* on unmap, we reset the default positioning of the window,
4704 * so it's placed again, but we don't reset the default
4705 * size of the window, so it's remembered.
4707 window->need_default_position = TRUE;
4709 info = gtk_window_get_geometry_info (window, FALSE);
4712 info->initial_pos_set = FALSE;
4713 info->position_constraints_changed = FALSE;
4716 state = gdk_window_get_state (widget->window);
4717 window->iconify_initially = (state & GDK_WINDOW_STATE_ICONIFIED) != 0;
4718 window->maximize_initially = (state & GDK_WINDOW_STATE_MAXIMIZED) != 0;
4719 window->stick_initially = (state & GDK_WINDOW_STATE_STICKY) != 0;
4720 priv->above_initially = (state & GDK_WINDOW_STATE_ABOVE) != 0;
4721 priv->below_initially = (state & GDK_WINDOW_STATE_BELOW) != 0;
4725 gtk_window_realize (GtkWidget *widget)
4728 GdkWindow *parent_window;
4729 GdkWindowAttr attributes;
4730 gint attributes_mask;
4731 GtkWindowPrivate *priv;
4733 window = GTK_WINDOW (widget);
4734 priv = GTK_WINDOW_GET_PRIVATE (window);
4736 /* ensure widget tree is properly size allocated */
4737 if (widget->allocation.x == -1 &&
4738 widget->allocation.y == -1 &&
4739 widget->allocation.width == 1 &&
4740 widget->allocation.height == 1)
4742 GtkRequisition requisition;
4743 GtkAllocation allocation = { 0, 0, 200, 200 };
4745 gtk_widget_size_request (widget, &requisition);
4746 if (requisition.width || requisition.height)
4748 /* non-empty window */
4749 allocation.width = requisition.width;
4750 allocation.height = requisition.height;
4752 gtk_widget_size_allocate (widget, &allocation);
4754 _gtk_container_queue_resize (GTK_CONTAINER (widget));
4756 g_return_if_fail (!gtk_widget_get_realized (widget));
4759 gtk_widget_set_realized (widget, TRUE);
4761 switch (window->type)
4763 case GTK_WINDOW_TOPLEVEL:
4764 attributes.window_type = GDK_WINDOW_TOPLEVEL;
4766 case GTK_WINDOW_POPUP:
4767 attributes.window_type = GDK_WINDOW_TEMP;
4770 g_warning (G_STRLOC": Unknown window type %d!", window->type);
4774 attributes.title = window->title;
4775 attributes.wmclass_name = window->wmclass_name;
4776 attributes.wmclass_class = window->wmclass_class;
4777 attributes.wclass = GDK_INPUT_OUTPUT;
4778 attributes.visual = gtk_widget_get_visual (widget);
4779 attributes.colormap = gtk_widget_get_colormap (widget);
4781 if (window->has_frame)
4783 attributes.width = widget->allocation.width + window->frame_left + window->frame_right;
4784 attributes.height = widget->allocation.height + window->frame_top + window->frame_bottom;
4785 attributes.event_mask = (GDK_EXPOSURE_MASK |
4786 GDK_KEY_PRESS_MASK |
4787 GDK_ENTER_NOTIFY_MASK |
4788 GDK_LEAVE_NOTIFY_MASK |
4789 GDK_FOCUS_CHANGE_MASK |
4790 GDK_STRUCTURE_MASK |
4791 GDK_BUTTON_MOTION_MASK |
4792 GDK_POINTER_MOTION_HINT_MASK |
4793 GDK_BUTTON_PRESS_MASK |
4794 GDK_BUTTON_RELEASE_MASK);
4796 attributes_mask = GDK_WA_VISUAL | GDK_WA_COLORMAP;
4798 window->frame = gdk_window_new (gtk_widget_get_root_window (widget),
4799 &attributes, attributes_mask);
4801 if (priv->opacity_set)
4802 gdk_window_set_opacity (window->frame, priv->opacity);
4804 gdk_window_set_user_data (window->frame, widget);
4806 attributes.window_type = GDK_WINDOW_CHILD;
4807 attributes.x = window->frame_left;
4808 attributes.y = window->frame_top;
4810 attributes_mask = GDK_WA_X | GDK_WA_Y;
4812 parent_window = window->frame;
4814 g_signal_connect (window,
4816 G_CALLBACK (gtk_window_event),
4821 attributes_mask = 0;
4822 parent_window = gtk_widget_get_root_window (widget);
4825 attributes.width = widget->allocation.width;
4826 attributes.height = widget->allocation.height;
4827 attributes.event_mask = gtk_widget_get_events (widget);
4828 attributes.event_mask |= (GDK_EXPOSURE_MASK |
4829 GDK_KEY_PRESS_MASK |
4830 GDK_KEY_RELEASE_MASK |
4831 GDK_ENTER_NOTIFY_MASK |
4832 GDK_LEAVE_NOTIFY_MASK |
4833 GDK_FOCUS_CHANGE_MASK |
4834 GDK_STRUCTURE_MASK);
4835 attributes.type_hint = priv->type_hint;
4837 attributes_mask |= GDK_WA_VISUAL | GDK_WA_COLORMAP | GDK_WA_TYPE_HINT;
4838 attributes_mask |= (window->title ? GDK_WA_TITLE : 0);
4839 attributes_mask |= (window->wmclass_name ? GDK_WA_WMCLASS : 0);
4841 widget->window = gdk_window_new (parent_window, &attributes, attributes_mask);
4843 if (!window->has_frame && priv->opacity_set)
4844 gdk_window_set_opacity (widget->window, priv->opacity);
4846 gdk_window_enable_synchronized_configure (widget->window);
4848 gdk_window_set_user_data (widget->window, window);
4850 widget->style = gtk_style_attach (widget->style, widget->window);
4851 gtk_style_set_background (widget->style, widget->window, GTK_STATE_NORMAL);
4853 gtk_style_set_background (widget->style, window->frame, GTK_STATE_NORMAL);
4855 /* This is a bad hack to set the window background. */
4856 gtk_window_paint (widget, NULL);
4858 if (window->transient_parent &&
4859 gtk_widget_get_realized (GTK_WIDGET (window->transient_parent)))
4860 gdk_window_set_transient_for (widget->window,
4861 GTK_WIDGET (window->transient_parent)->window);
4863 if (window->wm_role)
4864 gdk_window_set_role (widget->window, window->wm_role);
4866 if (!window->decorated)
4867 gdk_window_set_decorations (widget->window, 0);
4869 if (!priv->deletable)
4870 gdk_window_set_functions (widget->window, GDK_FUNC_ALL | GDK_FUNC_CLOSE);
4872 if (gtk_window_get_skip_pager_hint (window))
4873 gdk_window_set_skip_pager_hint (widget->window, TRUE);
4875 if (gtk_window_get_skip_taskbar_hint (window))
4876 gdk_window_set_skip_taskbar_hint (widget->window, TRUE);
4878 if (gtk_window_get_accept_focus (window))
4879 gdk_window_set_accept_focus (widget->window, TRUE);
4881 gdk_window_set_accept_focus (widget->window, FALSE);
4883 if (gtk_window_get_focus_on_map (window))
4884 gdk_window_set_focus_on_map (widget->window, TRUE);
4886 gdk_window_set_focus_on_map (widget->window, FALSE);
4889 gdk_window_set_modal_hint (widget->window, TRUE);
4891 gdk_window_set_modal_hint (widget->window, FALSE);
4893 if (priv->startup_id)
4895 #ifdef GDK_WINDOWING_X11
4896 guint32 timestamp = extract_time_from_startup_id (priv->startup_id);
4897 if (timestamp != GDK_CURRENT_TIME)
4898 gdk_x11_window_set_user_time (widget->window, timestamp);
4900 if (!startup_id_is_fake (priv->startup_id))
4901 gdk_window_set_startup_id (widget->window, priv->startup_id);
4905 gtk_window_realize_icon (window);
4909 gtk_window_unrealize (GtkWidget *widget)
4912 GtkWindowGeometryInfo *info;
4914 window = GTK_WINDOW (widget);
4916 /* On unrealize, we reset the size of the window such
4917 * that we will re-apply the default sizing stuff
4918 * next time we show the window.
4920 * Default positioning is reset on unmap, instead of unrealize.
4922 window->need_default_size = TRUE;
4923 info = gtk_window_get_geometry_info (window, FALSE);
4926 info->resize_width = -1;
4927 info->resize_height = -1;
4928 info->last.configure_request.x = 0;
4929 info->last.configure_request.y = 0;
4930 info->last.configure_request.width = -1;
4931 info->last.configure_request.height = -1;
4932 /* be sure we reset geom hints on re-realize */
4933 info->last.flags = 0;
4938 gdk_window_set_user_data (window->frame, NULL);
4939 gdk_window_destroy (window->frame);
4940 window->frame = NULL;
4944 gtk_window_unrealize_icon (window);
4946 GTK_WIDGET_CLASS (gtk_window_parent_class)->unrealize (widget);
4950 gtk_window_size_allocate (GtkWidget *widget,
4951 GtkAllocation *allocation)
4954 GtkAllocation child_allocation;
4956 window = GTK_WINDOW (widget);
4957 widget->allocation = *allocation;
4959 if (window->bin.child && gtk_widget_get_visible (window->bin.child))
4961 child_allocation.x = GTK_CONTAINER (window)->border_width;
4962 child_allocation.y = GTK_CONTAINER (window)->border_width;
4963 child_allocation.width =
4964 MAX (1, (gint)allocation->width - child_allocation.x * 2);
4965 child_allocation.height =
4966 MAX (1, (gint)allocation->height - child_allocation.y * 2);
4968 gtk_widget_size_allocate (window->bin.child, &child_allocation);
4971 if (gtk_widget_get_realized (widget) && window->frame)
4973 gdk_window_resize (window->frame,
4974 allocation->width + window->frame_left + window->frame_right,
4975 allocation->height + window->frame_top + window->frame_bottom);
4980 gtk_window_event (GtkWidget *widget, GdkEvent *event)
4983 gboolean return_val;
4985 window = GTK_WINDOW (widget);
4987 if (window->frame && (event->any.window == window->frame))
4989 if ((event->type != GDK_KEY_PRESS) &&
4990 (event->type != GDK_KEY_RELEASE) &&
4991 (event->type != GDK_FOCUS_CHANGE))
4993 g_signal_stop_emission_by_name (widget, "event");
4995 g_signal_emit (widget, window_signals[FRAME_EVENT], 0, event, &return_val);
5000 g_object_unref (event->any.window);
5001 event->any.window = g_object_ref (widget->window);
5009 gtk_window_frame_event (GtkWindow *window, GdkEvent *event)
5011 GdkEventConfigure *configure_event;
5014 switch (event->type)
5017 configure_event = (GdkEventConfigure *)event;
5019 /* Invalidate the decorations */
5022 rect.width = configure_event->width;
5023 rect.height = configure_event->height;
5025 gdk_window_invalidate_rect (window->frame, &rect, FALSE);
5027 /* Pass on the (modified) configure event */
5028 configure_event->width -= window->frame_left + window->frame_right;
5029 configure_event->height -= window->frame_top + window->frame_bottom;
5030 return gtk_window_configure_event (GTK_WIDGET (window), configure_event);
5039 gtk_window_configure_event (GtkWidget *widget,
5040 GdkEventConfigure *event)
5042 GtkWindow *window = GTK_WINDOW (widget);
5043 gboolean expected_reply = window->configure_request_count > 0;
5045 /* window->configure_request_count incremented for each
5046 * configure request, and decremented to a min of 0 for
5047 * each configure notify.
5049 * All it means is that we know we will get at least
5050 * window->configure_request_count more configure notifies.
5051 * We could get more configure notifies than that; some
5052 * of the configure notifies we get may be unrelated to
5053 * the configure requests. But we will get at least
5054 * window->configure_request_count notifies.
5057 if (window->configure_request_count > 0)
5059 window->configure_request_count -= 1;
5060 gdk_window_thaw_toplevel_updates_libgtk_only (widget->window);
5063 /* As an optimization, we avoid a resize when possible.
5065 * The only times we can avoid a resize are:
5066 * - we know only the position changed, not the size
5067 * - we know we have made more requests and so will get more
5068 * notifies and can wait to resize when we get them
5071 if (!expected_reply &&
5072 (widget->allocation.width == event->width &&
5073 widget->allocation.height == event->height))
5075 gdk_window_configure_finished (widget->window);
5080 * If we do need to resize, we do that by:
5081 * - filling in widget->allocation with the new size
5082 * - setting configure_notify_received to TRUE
5083 * for use in gtk_window_move_resize()
5084 * - queueing a resize, leading to invocation of
5085 * gtk_window_move_resize() in an idle handler
5089 window->configure_notify_received = TRUE;
5091 widget->allocation.width = event->width;
5092 widget->allocation.height = event->height;
5094 _gtk_container_queue_resize (GTK_CONTAINER (widget));
5099 /* the accel_key and accel_mods fields of the key have to be setup
5100 * upon calling this function. it'll then return whether that key
5101 * is at all used as accelerator, and if so will OR in the
5102 * accel_flags member of the key.
5105 _gtk_window_query_nonaccels (GtkWindow *window,
5107 GdkModifierType accel_mods)
5109 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
5111 /* movement keys are considered locked accels */
5114 static const guint bindings[] = {
5115 GDK_space, GDK_KP_Space, GDK_Return, GDK_ISO_Enter, GDK_KP_Enter, GDK_Up, GDK_KP_Up, GDK_Down, GDK_KP_Down,
5116 GDK_Left, GDK_KP_Left, GDK_Right, GDK_KP_Right, GDK_Tab, GDK_KP_Tab, GDK_ISO_Left_Tab,
5120 for (i = 0; i < G_N_ELEMENTS (bindings); i++)
5121 if (bindings[i] == accel_key)
5125 /* mnemonics are considered locked accels */
5126 if (accel_mods == window->mnemonic_modifier)
5128 GtkMnemonicHash *mnemonic_hash = gtk_window_get_mnemonic_hash (window, FALSE);
5129 if (mnemonic_hash && _gtk_mnemonic_hash_lookup (mnemonic_hash, accel_key))
5137 * gtk_window_propagate_key_event:
5138 * @window: a #GtkWindow
5139 * @event: a #GdkEventKey
5141 * Propagate a key press or release event to the focus widget and
5142 * up the focus container chain until a widget handles @event.
5143 * This is normally called by the default ::key_press_event and
5144 * ::key_release_event handlers for toplevel windows,
5145 * however in some cases it may be useful to call this directly when
5146 * overriding the standard key handling for a toplevel window.
5148 * Return value: %TRUE if a widget in the focus chain handled the event.
5153 gtk_window_propagate_key_event (GtkWindow *window,
5156 gboolean handled = FALSE;
5157 GtkWidget *widget, *focus;
5159 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
5161 widget = GTK_WIDGET (window);
5162 focus = window->focus_widget;
5164 g_object_ref (focus);
5167 focus && focus != widget &&
5168 gtk_widget_get_toplevel (focus) == widget)
5172 if (gtk_widget_is_sensitive (focus))
5173 handled = gtk_widget_event (focus, (GdkEvent*) event);
5175 parent = focus->parent;
5177 g_object_ref (parent);
5179 g_object_unref (focus);
5185 g_object_unref (focus);
5191 gtk_window_key_press_event (GtkWidget *widget,
5194 GtkWindow *window = GTK_WINDOW (widget);
5195 gboolean handled = FALSE;
5197 /* handle mnemonics and accelerators */
5199 handled = gtk_window_activate_key (window, event);
5201 /* handle focus widget key events */
5203 handled = gtk_window_propagate_key_event (window, event);
5205 /* Chain up, invokes binding set */
5207 handled = GTK_WIDGET_CLASS (gtk_window_parent_class)->key_press_event (widget, event);
5213 gtk_window_key_release_event (GtkWidget *widget,
5216 GtkWindow *window = GTK_WINDOW (widget);
5217 gboolean handled = FALSE;
5219 /* handle focus widget key events */
5221 handled = gtk_window_propagate_key_event (window, event);
5223 /* Chain up, invokes binding set */
5225 handled = GTK_WIDGET_CLASS (gtk_window_parent_class)->key_release_event (widget, event);
5231 gtk_window_real_activate_default (GtkWindow *window)
5233 gtk_window_activate_default (window);
5237 gtk_window_real_activate_focus (GtkWindow *window)
5239 gtk_window_activate_focus (window);
5243 gtk_window_move_focus (GtkWindow *window,
5244 GtkDirectionType dir)
5246 gtk_widget_child_focus (GTK_WIDGET (window), dir);
5248 if (!GTK_CONTAINER (window)->focus_child)
5249 gtk_window_set_focus (window, NULL);
5253 gtk_window_enter_notify_event (GtkWidget *widget,
5254 GdkEventCrossing *event)
5260 gtk_window_leave_notify_event (GtkWidget *widget,
5261 GdkEventCrossing *event)
5267 do_focus_change (GtkWidget *widget,
5270 GdkDeviceManager *device_manager;
5273 device_manager = gdk_display_get_device_manager (gtk_widget_get_display (widget));
5274 devices = gdk_device_manager_list_devices (device_manager, GDK_DEVICE_TYPE_MASTER);
5275 devices = g_list_concat (devices, gdk_device_manager_list_devices (device_manager, GDK_DEVICE_TYPE_SLAVE));
5276 devices = g_list_concat (devices, gdk_device_manager_list_devices (device_manager, GDK_DEVICE_TYPE_FLOATING));
5278 for (d = devices; d; d = d->next)
5280 GdkDevice *dev = d->data;
5283 if (dev->source != GDK_SOURCE_KEYBOARD)
5286 /* Skip non-master keyboards that haven't
5287 * selected for events from this window
5289 if (gdk_device_get_device_type (dev) != GDK_DEVICE_TYPE_MASTER &&
5291 !gdk_window_get_device_events (widget->window, dev))
5294 fevent = gdk_event_new (GDK_FOCUS_CHANGE);
5296 fevent->focus_change.type = GDK_FOCUS_CHANGE;
5297 fevent->focus_change.window = widget->window;
5299 g_object_ref (widget->window);
5300 fevent->focus_change.in = in;
5301 gdk_event_set_device (fevent, dev);
5303 gtk_widget_send_focus_change (widget, fevent);
5305 gdk_event_free (fevent);
5310 gtk_window_focus_in_event (GtkWidget *widget,
5311 GdkEventFocus *event)
5313 GtkWindow *window = GTK_WINDOW (widget);
5315 /* It appears spurious focus in events can occur when
5316 * the window is hidden. So we'll just check to see if
5317 * the window is visible before actually handling the
5320 if (gtk_widget_get_visible (widget))
5322 _gtk_window_set_has_toplevel_focus (window, TRUE);
5323 _gtk_window_set_is_active (window, TRUE);
5330 gtk_window_focus_out_event (GtkWidget *widget,
5331 GdkEventFocus *event)
5333 GtkWindow *window = GTK_WINDOW (widget);
5334 gboolean auto_mnemonics;
5336 _gtk_window_set_has_toplevel_focus (window, FALSE);
5337 _gtk_window_set_is_active (window, FALSE);
5339 /* set the mnemonic-visible property to false */
5340 g_object_get (gtk_widget_get_settings (widget),
5341 "gtk-auto-mnemonics", &auto_mnemonics, NULL);
5343 gtk_window_set_mnemonics_visible (window, FALSE);
5348 static GdkAtom atom_rcfiles = GDK_NONE;
5349 static GdkAtom atom_iconthemes = GDK_NONE;
5352 send_client_message_to_embedded_windows (GtkWidget *widget,
5353 GdkAtom message_type)
5355 GList *embedded_windows;
5357 embedded_windows = g_object_get_qdata (G_OBJECT (widget), quark_gtk_embedded);
5358 if (embedded_windows)
5360 GdkEvent *send_event = gdk_event_new (GDK_CLIENT_EVENT);
5363 for (i = 0; i < 5; i++)
5364 send_event->client.data.l[i] = 0;
5365 send_event->client.data_format = 32;
5366 send_event->client.message_type = message_type;
5368 while (embedded_windows)
5370 GdkNativeWindow xid = GDK_GPOINTER_TO_NATIVE_WINDOW(embedded_windows->data);
5371 gdk_event_send_client_message_for_display (gtk_widget_get_display (widget), send_event, xid);
5372 embedded_windows = embedded_windows->next;
5375 gdk_event_free (send_event);
5380 gtk_window_client_event (GtkWidget *widget,
5381 GdkEventClient *event)
5385 atom_rcfiles = gdk_atom_intern_static_string ("_GTK_READ_RCFILES");
5386 atom_iconthemes = gdk_atom_intern_static_string ("_GTK_LOAD_ICONTHEMES");
5389 if (event->message_type == atom_rcfiles)
5391 send_client_message_to_embedded_windows (widget, atom_rcfiles);
5392 gtk_rc_reparse_all_for_settings (gtk_widget_get_settings (widget), FALSE);
5395 if (event->message_type == atom_iconthemes)
5397 send_client_message_to_embedded_windows (widget, atom_iconthemes);
5398 _gtk_icon_theme_check_reload (gtk_widget_get_display (widget));
5405 gtk_window_check_resize (GtkContainer *container)
5407 if (gtk_widget_get_visible (GTK_WIDGET (container)))
5408 gtk_window_move_resize (GTK_WINDOW (container));
5412 gtk_window_focus (GtkWidget *widget,
5413 GtkDirectionType direction)
5417 GtkContainer *container;
5418 GtkWidget *old_focus_child;
5421 container = GTK_CONTAINER (widget);
5422 window = GTK_WINDOW (widget);
5423 bin = GTK_BIN (widget);
5425 old_focus_child = container->focus_child;
5427 /* We need a special implementation here to deal properly with wrapping
5428 * around in the tab chain without the danger of going into an
5431 if (old_focus_child)
5433 if (gtk_widget_child_focus (old_focus_child, direction))
5437 if (window->focus_widget)
5439 if (direction == GTK_DIR_LEFT ||
5440 direction == GTK_DIR_RIGHT ||
5441 direction == GTK_DIR_UP ||
5442 direction == GTK_DIR_DOWN)
5447 /* Wrapped off the end, clear the focus setting for the toplpevel */
5448 parent = window->focus_widget->parent;
5451 gtk_container_set_focus_child (GTK_CONTAINER (parent), NULL);
5452 parent = GTK_WIDGET (parent)->parent;
5455 gtk_window_set_focus (GTK_WINDOW (container), NULL);
5458 /* Now try to focus the first widget in the window */
5461 if (gtk_widget_child_focus (bin->child, direction))
5469 gtk_window_real_set_focus (GtkWindow *window,
5472 GtkWidget *old_focus = window->focus_widget;
5473 gboolean had_default = FALSE;
5474 gboolean focus_had_default = FALSE;
5475 gboolean old_focus_had_default = FALSE;
5479 g_object_ref (old_focus);
5480 g_object_freeze_notify (G_OBJECT (old_focus));
5481 old_focus_had_default = gtk_widget_has_default (old_focus);
5485 g_object_ref (focus);
5486 g_object_freeze_notify (G_OBJECT (focus));
5487 focus_had_default = gtk_widget_has_default (focus);
5490 if (window->default_widget)
5491 had_default = gtk_widget_has_default (window->default_widget);
5493 if (window->focus_widget)
5495 if (gtk_widget_get_receives_default (window->focus_widget) &&
5496 (window->focus_widget != window->default_widget))
5498 _gtk_widget_set_has_default (window->focus_widget, FALSE);
5499 gtk_widget_queue_draw (window->focus_widget);
5501 if (window->default_widget)
5502 _gtk_widget_set_has_default (window->default_widget, TRUE);
5505 window->focus_widget = NULL;
5507 if (window->has_focus)
5508 do_focus_change (old_focus, FALSE);
5510 g_object_notify (G_OBJECT (old_focus), "is-focus");
5513 /* The above notifications may have set a new focus widget,
5514 * if so, we don't want to override it.
5516 if (focus && !window->focus_widget)
5518 window->focus_widget = focus;
5520 if (gtk_widget_get_receives_default (window->focus_widget) &&
5521 (window->focus_widget != window->default_widget))
5523 if (gtk_widget_get_can_default (window->focus_widget))
5524 _gtk_widget_set_has_default (window->focus_widget, TRUE);
5526 if (window->default_widget)
5527 _gtk_widget_set_has_default (window->default_widget, FALSE);
5530 if (window->has_focus)
5531 do_focus_change (window->focus_widget, TRUE);
5533 g_object_notify (G_OBJECT (window->focus_widget), "is-focus");
5536 /* If the default widget changed, a redraw will have been queued
5537 * on the old and new default widgets by gtk_window_set_default(), so
5538 * we only have to worry about the case where it didn't change.
5539 * We'll sometimes queue a draw twice on the new widget but that
5542 if (window->default_widget &&
5543 (had_default != gtk_widget_has_default (window->default_widget)))
5544 gtk_widget_queue_draw (window->default_widget);
5548 if (old_focus_had_default != gtk_widget_has_default (old_focus))
5549 gtk_widget_queue_draw (old_focus);
5551 g_object_thaw_notify (G_OBJECT (old_focus));
5552 g_object_unref (old_focus);
5556 if (focus_had_default != gtk_widget_has_default (focus))
5557 gtk_widget_queue_draw (focus);
5559 g_object_thaw_notify (G_OBJECT (focus));
5560 g_object_unref (focus);
5566 gtk_window_extended_layout_init (GtkExtendedLayoutIface *iface)
5568 iface->get_desired_width = gtk_window_get_desired_width;
5569 iface->get_desired_height = gtk_window_get_desired_height;
5574 gtk_window_get_desired_width (GtkExtendedLayout *layout,
5581 window = GTK_WINDOW (layout);
5582 child = gtk_bin_get_child (GTK_BIN (window));
5584 *minimum_size = GTK_CONTAINER (window)->border_width * 2;
5585 *natural_size = GTK_CONTAINER (window)->border_width * 2;
5587 if (child && gtk_widget_get_visible (child))
5589 gint child_min, child_nat;
5590 gtk_extended_layout_get_desired_width (GTK_EXTENDED_LAYOUT (child), &child_min, &child_nat);
5592 *minimum_size += child_min;
5593 *natural_size += child_nat;
5598 gtk_window_get_desired_height (GtkExtendedLayout *layout,
5605 window = GTK_WINDOW (layout);
5606 child = gtk_bin_get_child (GTK_BIN (window));
5608 *minimum_size = GTK_CONTAINER (window)->border_width * 2;
5609 *natural_size = GTK_CONTAINER (window)->border_width * 2;
5611 if (child && gtk_widget_get_visible (child))
5613 gint child_min, child_nat;
5614 gtk_extended_layout_get_desired_height (GTK_EXTENDED_LAYOUT (child), &child_min, &child_nat);
5616 *minimum_size += child_min;
5617 *natural_size += child_nat;
5623 * _gtk_window_unset_focus_and_default:
5624 * @window: a #GtkWindow
5625 * @widget: a widget inside of @window
5627 * Checks whether the focus and default widgets of @window are
5628 * @widget or a descendent of @widget, and if so, unset them.
5631 _gtk_window_unset_focus_and_default (GtkWindow *window,
5637 g_object_ref (window);
5638 g_object_ref (widget);
5640 if (GTK_CONTAINER (widget->parent)->focus_child == widget)
5642 child = window->focus_widget;
5644 while (child && child != widget)
5645 child = child->parent;
5647 if (child == widget)
5648 gtk_window_set_focus (GTK_WINDOW (window), NULL);
5651 child = window->default_widget;
5653 while (child && child != widget)
5654 child = child->parent;
5656 if (child == widget)
5657 gtk_window_set_default (window, NULL);
5659 g_object_unref (widget);
5660 g_object_unref (window);
5663 /*********************************
5664 * Functions related to resizing *
5665 *********************************/
5667 /* This function doesn't constrain to geometry hints */
5669 gtk_window_compute_configure_request_size (GtkWindow *window,
5673 GtkRequisition requisition;
5674 GtkWindowGeometryInfo *info;
5678 * - we've done a size request
5681 widget = GTK_WIDGET (window);
5683 info = gtk_window_get_geometry_info (window, FALSE);
5685 if (window->need_default_size)
5687 gtk_widget_get_child_requisition (widget, &requisition);
5689 /* Default to requisition */
5690 *width = requisition.width;
5691 *height = requisition.height;
5693 /* If window is empty so requests 0, default to random nonzero size */
5694 if (*width == 0 && *height == 0)
5700 /* Override requisition with default size */
5704 gint base_width = 0;
5705 gint base_height = 0;
5707 gint min_height = 0;
5709 gint height_inc = 1;
5711 if (info->default_is_geometry &&
5712 (info->default_width > 0 || info->default_height > 0))
5714 GdkGeometry geometry;
5717 gtk_window_compute_hints (window, &geometry, &flags);
5719 if (flags & GDK_HINT_BASE_SIZE)
5721 base_width = geometry.base_width;
5722 base_height = geometry.base_height;
5724 if (flags & GDK_HINT_MIN_SIZE)
5726 min_width = geometry.min_width;
5727 min_height = geometry.min_height;
5729 if (flags & GDK_HINT_RESIZE_INC)
5731 width_inc = geometry.width_inc;
5732 height_inc = geometry.height_inc;
5736 if (info->default_width > 0)
5737 *width = MAX (info->default_width * width_inc + base_width, min_width);
5739 if (info->default_height > 0)
5740 *height = MAX (info->default_height * height_inc + base_height, min_height);
5745 /* Default to keeping current size */
5746 *width = widget->allocation.width;
5747 *height = widget->allocation.height;
5750 /* Override any size with gtk_window_resize() values */
5753 if (info->resize_width > 0)
5754 *width = info->resize_width;
5756 if (info->resize_height > 0)
5757 *height = info->resize_height;
5760 /* Don't ever request zero width or height, its not supported by
5761 gdk. The size allocation code will round it to 1 anyway but if
5762 we do it then the value returned from this function will is
5763 not comparable to the size allocation read from the GtkWindow. */
5764 *width = MAX (*width, 1);
5765 *height = MAX (*height, 1);
5768 static GtkWindowPosition
5769 get_effective_position (GtkWindow *window)
5771 GtkWindowPosition pos = window->position;
5773 if (pos == GTK_WIN_POS_CENTER_ON_PARENT &&
5774 (window->transient_parent == NULL ||
5775 !gtk_widget_get_mapped (GTK_WIDGET (window->transient_parent))))
5776 pos = GTK_WIN_POS_NONE;
5782 get_center_monitor_of_window (GtkWindow *window)
5784 /* We could try to sort out the relative positions of the monitors and
5785 * stuff, or we could just be losers and assume you have a row
5786 * or column of monitors.
5788 return gdk_screen_get_n_monitors (gtk_window_check_screen (window)) / 2;
5792 get_monitor_containing_pointer (GtkWindow *window)
5796 GdkScreen *window_screen;
5797 GdkScreen *pointer_screen;
5798 GdkDisplay *display;
5801 window_screen = gtk_window_check_screen (window);
5802 display = gdk_screen_get_display (window_screen);
5803 pointer = gdk_display_get_core_pointer (display);
5805 gdk_display_get_device_state (display, pointer,
5809 if (pointer_screen == window_screen)
5810 monitor_num = gdk_screen_get_monitor_at_point (pointer_screen, px, py);
5818 center_window_on_monitor (GtkWindow *window,
5824 GdkRectangle monitor;
5827 monitor_num = get_monitor_containing_pointer (window);
5829 if (monitor_num == -1)
5830 monitor_num = get_center_monitor_of_window (window);
5832 gdk_screen_get_monitor_geometry (gtk_window_check_screen (window),
5833 monitor_num, &monitor);
5835 *x = (monitor.width - w) / 2 + monitor.x;
5836 *y = (monitor.height - h) / 2 + monitor.y;
5838 /* Be sure we aren't off the monitor, ignoring _NET_WM_STRUT
5839 * and WM decorations.
5853 if (extent > clamp_extent)
5855 *base = clamp_base + clamp_extent/2 - extent/2;
5856 else if (*base < clamp_base)
5858 else if (*base + extent > clamp_base + clamp_extent)
5859 *base = clamp_base + clamp_extent - extent;
5863 clamp_window_to_rectangle (gint *x,
5867 const GdkRectangle *rect)
5869 #ifdef DEBUGGING_OUTPUT
5870 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);
5873 /* If it is too large, center it. If it fits on the monitor but is
5874 * partially outside, move it to the closest edge. Do this
5875 * separately in x and y directions.
5877 clamp (x, w, rect->x, rect->width);
5878 clamp (y, h, rect->y, rect->height);
5879 #ifdef DEBUGGING_OUTPUT
5880 g_print (" ==> %+d%+d: %dx%d\n", *x, *y, w, h);
5886 gtk_window_compute_configure_request (GtkWindow *window,
5887 GdkRectangle *request,
5888 GdkGeometry *geometry,
5891 GdkGeometry new_geometry;
5895 GtkWindowPosition pos;
5896 GtkWidget *parent_widget;
5897 GtkWindowGeometryInfo *info;
5901 widget = GTK_WIDGET (window);
5903 screen = gtk_window_check_screen (window);
5905 gtk_widget_size_request (widget, NULL);
5906 gtk_window_compute_configure_request_size (window, (guint *)&w, (guint *)&h);
5908 gtk_window_compute_hints (window, &new_geometry, &new_flags);
5909 gtk_window_constrain_size (window,
5910 &new_geometry, new_flags,
5914 parent_widget = (GtkWidget*) window->transient_parent;
5916 pos = get_effective_position (window);
5917 info = gtk_window_get_geometry_info (window, FALSE);
5919 /* by default, don't change position requested */
5922 x = info->last.configure_request.x;
5923 y = info->last.configure_request.y;
5932 if (window->need_default_position)
5935 /* FIXME this all interrelates with window gravity.
5936 * For most of them I think we want to set GRAVITY_CENTER.
5938 * Not sure how to go about that.
5943 /* here we are only handling CENTER_ALWAYS
5944 * as it relates to default positioning,
5945 * where it's equivalent to simply CENTER
5947 case GTK_WIN_POS_CENTER_ALWAYS:
5948 case GTK_WIN_POS_CENTER:
5949 center_window_on_monitor (window, w, h, &x, &y);
5952 case GTK_WIN_POS_CENTER_ON_PARENT:
5955 GdkRectangle monitor;
5958 g_assert (gtk_widget_get_mapped (parent_widget)); /* established earlier */
5960 if (parent_widget->window != NULL)
5961 monitor_num = gdk_screen_get_monitor_at_window (screen,
5962 parent_widget->window);
5966 gdk_window_get_origin (parent_widget->window,
5969 x = ox + (parent_widget->allocation.width - w) / 2;
5970 y = oy + (parent_widget->allocation.height - h) / 2;
5972 /* Clamp onto current monitor, ignoring _NET_WM_STRUT and
5973 * WM decorations. If parent wasn't on a monitor, just
5976 if (monitor_num >= 0)
5978 gdk_screen_get_monitor_geometry (screen, monitor_num, &monitor);
5979 clamp_window_to_rectangle (&x, &y, w, h, &monitor);
5984 case GTK_WIN_POS_MOUSE:
5986 gint screen_width = gdk_screen_get_width (screen);
5987 gint screen_height = gdk_screen_get_height (screen);
5989 GdkRectangle monitor;
5990 GdkDisplay *display;
5992 GdkScreen *pointer_screen;
5995 display = gdk_screen_get_display (screen);
5996 pointer = gdk_display_get_core_pointer (display);
5997 gdk_display_get_device_state (display, pointer,
6001 if (pointer_screen == screen)
6002 monitor_num = gdk_screen_get_monitor_at_point (screen, px, py);
6008 x = CLAMP (x, 0, screen_width - w);
6009 y = CLAMP (y, 0, screen_height - h);
6011 /* Clamp onto current monitor, ignoring _NET_WM_STRUT and
6012 * WM decorations. Don't try to figure out what's going
6013 * on if the mouse wasn't inside a monitor.
6015 if (monitor_num >= 0)
6017 gdk_screen_get_monitor_geometry (screen, monitor_num, &monitor);
6018 clamp_window_to_rectangle (&x, &y, w, h, &monitor);
6026 } /* if (window->need_default_position) */
6028 if (window->need_default_position && info &&
6029 info->initial_pos_set)
6031 x = info->initial_x;
6032 y = info->initial_y;
6033 gtk_window_constrain_position (window, w, h, &x, &y);
6039 request->height = h;
6042 *geometry = new_geometry;
6048 gtk_window_constrain_position (GtkWindow *window,
6054 /* See long comments in gtk_window_move_resize()
6055 * on when it's safe to call this function.
6057 if (window->position == GTK_WIN_POS_CENTER_ALWAYS)
6059 gint center_x, center_y;
6061 center_window_on_monitor (window, new_width, new_height, ¢er_x, ¢er_y);
6069 gtk_window_move_resize (GtkWindow *window)
6073 * First we determine whether any information has changed that would
6074 * cause us to revise our last configure request. If we would send
6075 * a different configure request from last time, then
6076 * configure_request_size_changed = TRUE or
6077 * configure_request_pos_changed = TRUE. configure_request_size_changed
6078 * may be true due to new hints, a gtk_window_resize(), or whatever.
6079 * configure_request_pos_changed may be true due to gtk_window_set_position()
6080 * or gtk_window_move().
6082 * If the configure request has changed, we send off a new one. To
6083 * ensure GTK+ invariants are maintained (resize queue does what it
6084 * should), we go ahead and size_allocate the requested size in this
6087 * If the configure request has not changed, we don't ever resend
6088 * it, because it could mean fighting the user or window manager.
6091 * To prepare the configure request, we come up with a base size/pos:
6092 * - the one from gtk_window_move()/gtk_window_resize()
6093 * - else default_width, default_height if we haven't ever
6095 * - else the size request if we haven't ever been mapped,
6096 * as a substitute default size
6097 * - else the current size of the window, as received from
6098 * configure notifies (i.e. the current allocation)
6100 * If GTK_WIN_POS_CENTER_ALWAYS is active, we constrain
6101 * the position request to be centered.
6104 GtkContainer *container;
6105 GtkWindowGeometryInfo *info;
6106 GdkGeometry new_geometry;
6108 GdkRectangle new_request;
6109 gboolean configure_request_size_changed;
6110 gboolean configure_request_pos_changed;
6111 gboolean hints_changed; /* do we need to send these again */
6112 GtkWindowLastGeometryInfo saved_last_info;
6114 widget = GTK_WIDGET (window);
6115 container = GTK_CONTAINER (widget);
6116 info = gtk_window_get_geometry_info (window, TRUE);
6118 configure_request_size_changed = FALSE;
6119 configure_request_pos_changed = FALSE;
6121 gtk_window_compute_configure_request (window, &new_request,
6122 &new_geometry, &new_flags);
6124 /* This check implies the invariant that we never set info->last
6125 * without setting the hints and sending off a configure request.
6127 * If we change info->last without sending the request, we may
6130 if (info->last.configure_request.x != new_request.x ||
6131 info->last.configure_request.y != new_request.y)
6132 configure_request_pos_changed = TRUE;
6134 if ((info->last.configure_request.width != new_request.width ||
6135 info->last.configure_request.height != new_request.height))
6136 configure_request_size_changed = TRUE;
6138 hints_changed = FALSE;
6140 if (!gtk_window_compare_hints (&info->last.geometry, info->last.flags,
6141 &new_geometry, new_flags))
6143 hints_changed = TRUE;
6146 /* Position Constraints
6147 * ====================
6149 * POS_CENTER_ALWAYS is conceptually a constraint rather than
6150 * a default. The other POS_ values are used only when the
6151 * window is shown, not after that.
6153 * However, we can't implement a position constraint as
6154 * "anytime the window size changes, center the window"
6155 * because this may well end up fighting the WM or user. In
6156 * fact it gets in an infinite loop with at least one WM.
6158 * Basically, applications are in no way in a position to
6159 * constrain the position of a window, with one exception:
6160 * override redirect windows. (Really the intended purpose
6161 * of CENTER_ALWAYS anyhow, I would think.)
6163 * So the way we implement this "constraint" is to say that when WE
6164 * cause a move or resize, i.e. we make a configure request changing
6165 * window size, we recompute the CENTER_ALWAYS position to reflect
6166 * the new window size, and include it in our request. Also, if we
6167 * just turned on CENTER_ALWAYS we snap to center with a new
6168 * request. Otherwise, if we are just NOTIFIED of a move or resize
6169 * done by someone else e.g. the window manager, we do NOT send a
6170 * new configure request.
6172 * For override redirect windows, this works fine; all window
6173 * sizes are from our configure requests. For managed windows,
6174 * it is at least semi-sane, though who knows what the
6175 * app author is thinking.
6178 /* This condition should be kept in sync with the condition later on
6179 * that determines whether we send a configure request. i.e. we
6180 * should do this position constraining anytime we were going to
6181 * send a configure request anyhow, plus when constraints have
6184 if (configure_request_pos_changed ||
6185 configure_request_size_changed ||
6187 info->position_constraints_changed)
6189 /* We request the constrained position if:
6190 * - we were changing position, and need to clamp
6191 * the change to the constraint
6192 * - we're changing the size anyway
6193 * - set_position() was called to toggle CENTER_ALWAYS on
6196 gtk_window_constrain_position (window,
6202 /* Update whether we need to request a move */
6203 if (info->last.configure_request.x != new_request.x ||
6204 info->last.configure_request.y != new_request.y)
6205 configure_request_pos_changed = TRUE;
6207 configure_request_pos_changed = FALSE;
6211 if (window->type == GTK_WINDOW_TOPLEVEL)
6213 int notify_x, notify_y;
6215 /* this is the position from the last configure notify */
6216 gdk_window_get_position (widget->window, ¬ify_x, ¬ify_y);
6218 g_message ("--- %s ---\n"
6219 "last : %d,%d\t%d x %d\n"
6220 "this : %d,%d\t%d x %d\n"
6221 "alloc : %d,%d\t%d x %d\n"
6223 "resize: \t%d x %d\n"
6224 "size_changed: %d pos_changed: %d hints_changed: %d\n"
6225 "configure_notify_received: %d\n"
6226 "configure_request_count: %d\n"
6227 "position_constraints_changed: %d\n",
6228 window->title ? window->title : "(no title)",
6229 info->last.configure_request.x,
6230 info->last.configure_request.y,
6231 info->last.configure_request.width,
6232 info->last.configure_request.height,
6238 widget->allocation.width,
6239 widget->allocation.height,
6240 widget->requisition.width,
6241 widget->requisition.height,
6243 info->resize_height,
6244 configure_request_pos_changed,
6245 configure_request_size_changed,
6247 window->configure_notify_received,
6248 window->configure_request_count,
6249 info->position_constraints_changed);
6253 saved_last_info = info->last;
6254 info->last.geometry = new_geometry;
6255 info->last.flags = new_flags;
6256 info->last.configure_request = new_request;
6258 /* need to set PPosition so the WM will look at our position,
6259 * but we don't want to count PPosition coming and going as a hints
6260 * change for future iterations. So we saved info->last prior to
6264 /* Also, if the initial position was explicitly set, then we always
6265 * toggle on PPosition. This makes gtk_window_move(window, 0, 0)
6269 /* Also, we toggle on PPosition if GTK_WIN_POS_ is in use and
6270 * this is an initial map
6273 if ((configure_request_pos_changed ||
6274 info->initial_pos_set ||
6275 (window->need_default_position &&
6276 get_effective_position (window) != GTK_WIN_POS_NONE)) &&
6277 (new_flags & GDK_HINT_POS) == 0)
6279 new_flags |= GDK_HINT_POS;
6280 hints_changed = TRUE;
6283 /* Set hints if necessary
6286 gdk_window_set_geometry_hints (widget->window,
6290 /* handle resizing/moving and widget tree allocation
6292 if (window->configure_notify_received)
6294 GtkAllocation allocation;
6296 /* If we have received a configure event since
6297 * the last time in this function, we need to
6298 * accept our new size and size_allocate child widgets.
6299 * (see gtk_window_configure_event() for more details).
6301 * 1 or more configure notifies may have been received.
6302 * Also, configure_notify_received will only be TRUE
6303 * if all expected configure notifies have been received
6304 * (one per configure request), as an optimization.
6307 window->configure_notify_received = FALSE;
6309 /* gtk_window_configure_event() filled in widget->allocation */
6310 allocation = widget->allocation;
6311 gtk_widget_size_allocate (widget, &allocation);
6313 gdk_window_process_updates (widget->window, TRUE);
6315 gdk_window_configure_finished (widget->window);
6317 /* If the configure request changed, it means that
6319 * 1) coincidentally changed hints or widget properties
6320 * impacting the configure request before getting
6321 * a configure notify, or
6322 * 2) some broken widget is changing its size request
6323 * during size allocation, resulting in
6324 * a false appearance of changed configure request.
6326 * For 1), we could just go ahead and ask for the
6327 * new size right now, but doing that for 2)
6328 * might well be fighting the user (and can even
6329 * trigger a loop). Since we really don't want to
6330 * do that, we requeue a resize in hopes that
6331 * by the time it gets handled, the child has seen
6332 * the light and is willing to go along with the
6333 * new size. (this happens for the zvt widget, since
6334 * the size_allocate() above will have stored the
6335 * requisition corresponding to the new size in the
6338 * This doesn't buy us anything for 1), but it shouldn't
6339 * hurt us too badly, since it is what would have
6340 * happened if we had gotten the configure event before
6341 * the new size had been set.
6344 if (configure_request_size_changed ||
6345 configure_request_pos_changed)
6347 /* Don't change the recorded last info after all, because we
6348 * haven't actually updated to the new info yet - we decided
6349 * to postpone our configure request until later.
6351 info->last = saved_last_info;
6353 gtk_widget_queue_resize_no_redraw (widget); /* migth recurse for GTK_RESIZE_IMMEDIATE */
6356 return; /* Bail out, we didn't really process the move/resize */
6358 else if ((configure_request_size_changed || hints_changed) &&
6359 (widget->allocation.width != new_request.width ||
6360 widget->allocation.height != new_request.height))
6363 /* We are in one of the following situations:
6364 * A. configure_request_size_changed
6365 * our requisition has changed and we need a different window size,
6366 * so we request it from the window manager.
6367 * B. !configure_request_size_changed && hints_changed
6368 * the window manager rejects our size, but we have just changed the
6369 * window manager hints, so there's a chance our request will
6370 * be honoured this time, so we try again.
6372 * However, if the new requisition is the same as the current allocation,
6373 * we don't request it again, since we won't get a ConfigureNotify back from
6374 * the window manager unless it decides to change our requisition. If
6375 * we don't get the ConfigureNotify back, the resize queue will never be run.
6378 /* Now send the configure request */
6379 if (configure_request_pos_changed)
6383 gdk_window_move_resize (window->frame,
6384 new_request.x - window->frame_left,
6385 new_request.y - window->frame_top,
6386 new_request.width + window->frame_left + window->frame_right,
6387 new_request.height + window->frame_top + window->frame_bottom);
6388 gdk_window_resize (widget->window,
6389 new_request.width, new_request.height);
6392 gdk_window_move_resize (widget->window,
6393 new_request.x, new_request.y,
6394 new_request.width, new_request.height);
6396 else /* only size changed */
6399 gdk_window_resize (window->frame,
6400 new_request.width + window->frame_left + window->frame_right,
6401 new_request.height + window->frame_top + window->frame_bottom);
6402 gdk_window_resize (widget->window,
6403 new_request.width, new_request.height);
6406 if (window->type == GTK_WINDOW_POPUP)
6408 GtkAllocation allocation;
6410 /* Directly size allocate for override redirect (popup) windows. */
6413 allocation.width = new_request.width;
6414 allocation.height = new_request.height;
6416 gtk_widget_size_allocate (widget, &allocation);
6418 gdk_window_process_updates (widget->window, TRUE);
6420 if (container->resize_mode == GTK_RESIZE_QUEUE)
6421 gtk_widget_queue_draw (widget);
6425 /* Increment the number of have-not-yet-received-notify requests */
6426 window->configure_request_count += 1;
6427 gdk_window_freeze_toplevel_updates_libgtk_only (widget->window);
6429 /* for GTK_RESIZE_QUEUE toplevels, we are now awaiting a new
6430 * configure event in response to our resizing request.
6431 * the configure event will cause a new resize with
6432 * ->configure_notify_received=TRUE.
6433 * until then, we want to
6434 * - discard expose events
6435 * - coalesce resizes for our children
6436 * - defer any window resizes until the configure event arrived
6437 * to achieve this, we queue a resize for the window, but remove its
6438 * resizing handler, so resizing will not be handled from the next
6439 * idle handler but when the configure event arrives.
6441 * FIXME: we should also dequeue the pending redraws here, since
6442 * we handle those ourselves upon ->configure_notify_received==TRUE.
6444 if (container->resize_mode == GTK_RESIZE_QUEUE)
6446 gtk_widget_queue_resize_no_redraw (widget);
6447 _gtk_container_dequeue_resize_handler (container);
6453 /* Handle any position changes.
6455 if (configure_request_pos_changed)
6459 gdk_window_move (window->frame,
6460 new_request.x - window->frame_left,
6461 new_request.y - window->frame_top);
6464 gdk_window_move (widget->window,
6465 new_request.x, new_request.y);
6468 /* And run the resize queue.
6470 gtk_container_resize_children (container);
6473 /* We have now processed a move/resize since the last position
6474 * constraint change, setting of the initial position, or resize.
6475 * (Not resetting these flags here can lead to infinite loops for
6476 * GTK_RESIZE_IMMEDIATE containers)
6478 info->position_constraints_changed = FALSE;
6479 info->initial_pos_set = FALSE;
6480 info->resize_width = -1;
6481 info->resize_height = -1;
6484 /* Compare two sets of Geometry hints for equality.
6487 gtk_window_compare_hints (GdkGeometry *geometry_a,
6489 GdkGeometry *geometry_b,
6492 if (flags_a != flags_b)
6495 if ((flags_a & GDK_HINT_MIN_SIZE) &&
6496 (geometry_a->min_width != geometry_b->min_width ||
6497 geometry_a->min_height != geometry_b->min_height))
6500 if ((flags_a & GDK_HINT_MAX_SIZE) &&
6501 (geometry_a->max_width != geometry_b->max_width ||
6502 geometry_a->max_height != geometry_b->max_height))
6505 if ((flags_a & GDK_HINT_BASE_SIZE) &&
6506 (geometry_a->base_width != geometry_b->base_width ||
6507 geometry_a->base_height != geometry_b->base_height))
6510 if ((flags_a & GDK_HINT_ASPECT) &&
6511 (geometry_a->min_aspect != geometry_b->min_aspect ||
6512 geometry_a->max_aspect != geometry_b->max_aspect))
6515 if ((flags_a & GDK_HINT_RESIZE_INC) &&
6516 (geometry_a->width_inc != geometry_b->width_inc ||
6517 geometry_a->height_inc != geometry_b->height_inc))
6520 if ((flags_a & GDK_HINT_WIN_GRAVITY) &&
6521 geometry_a->win_gravity != geometry_b->win_gravity)
6528 _gtk_window_constrain_size (GtkWindow *window,
6534 GtkWindowGeometryInfo *info;
6536 g_return_if_fail (GTK_IS_WINDOW (window));
6538 info = window->geometry_info;
6541 GdkWindowHints flags = info->last.flags;
6542 GdkGeometry *geometry = &info->last.geometry;
6544 gtk_window_constrain_size (window,
6555 gtk_window_constrain_size (GtkWindow *window,
6556 GdkGeometry *geometry,
6563 gdk_window_constrain_size (geometry, flags, width, height,
6564 new_width, new_height);
6567 /* Compute the set of geometry hints and flags for a window
6568 * based on the application set geometry, and requisiition
6569 * of the window. gtk_widget_size_request() must have been
6573 gtk_window_compute_hints (GtkWindow *window,
6574 GdkGeometry *new_geometry,
6578 gint extra_width = 0;
6579 gint extra_height = 0;
6580 GtkWindowGeometryInfo *geometry_info;
6581 GtkRequisition requisition;
6583 widget = GTK_WIDGET (window);
6585 gtk_widget_get_child_requisition (widget, &requisition);
6586 geometry_info = gtk_window_get_geometry_info (GTK_WINDOW (widget), FALSE);
6590 *new_flags = geometry_info->mask;
6591 *new_geometry = geometry_info->geometry;
6598 if (geometry_info && geometry_info->widget)
6600 GtkRequisition child_requisition;
6602 /* FIXME: This really isn't right. It gets the min size wrong and forces
6603 * callers to do horrible hacks like set a huge usize on the child requisition
6604 * to get the base size right. We really want to find the answers to:
6606 * - If the geometry widget was infinitely big, how much extra space
6607 * would be needed for the stuff around it.
6609 * - If the geometry widget was infinitely small, how big would the
6610 * window still have to be.
6612 * Finding these answers would be a bit of a mess here. (Bug #68668)
6614 gtk_widget_get_child_requisition (geometry_info->widget, &child_requisition);
6616 extra_width = widget->requisition.width - child_requisition.width;
6617 extra_height = widget->requisition.height - child_requisition.height;
6620 /* We don't want to set GDK_HINT_POS in here, we just set it
6621 * in gtk_window_move_resize() when we want the position
6625 if (*new_flags & GDK_HINT_BASE_SIZE)
6627 new_geometry->base_width += extra_width;
6628 new_geometry->base_height += extra_height;
6630 else if (!(*new_flags & GDK_HINT_MIN_SIZE) &&
6631 (*new_flags & GDK_HINT_RESIZE_INC) &&
6632 ((extra_width != 0) || (extra_height != 0)))
6634 *new_flags |= GDK_HINT_BASE_SIZE;
6636 new_geometry->base_width = extra_width;
6637 new_geometry->base_height = extra_height;
6640 if (*new_flags & GDK_HINT_MIN_SIZE)
6642 if (new_geometry->min_width < 0)
6643 new_geometry->min_width = requisition.width;
6645 new_geometry->min_width += extra_width;
6647 if (new_geometry->min_height < 0)
6648 new_geometry->min_height = requisition.height;
6650 new_geometry->min_height += extra_height;
6652 else if (!window->allow_shrink)
6654 *new_flags |= GDK_HINT_MIN_SIZE;
6656 new_geometry->min_width = requisition.width;
6657 new_geometry->min_height = requisition.height;
6660 if (*new_flags & GDK_HINT_MAX_SIZE)
6662 if (new_geometry->max_width < 0)
6663 new_geometry->max_width = requisition.width;
6665 new_geometry->max_width += extra_width;
6667 if (new_geometry->max_height < 0)
6668 new_geometry->max_height = requisition.height;
6670 new_geometry->max_height += extra_height;
6672 else if (!window->allow_grow)
6674 *new_flags |= GDK_HINT_MAX_SIZE;
6676 new_geometry->max_width = requisition.width;
6677 new_geometry->max_height = requisition.height;
6680 *new_flags |= GDK_HINT_WIN_GRAVITY;
6681 new_geometry->win_gravity = window->gravity;
6684 /***********************
6685 * Redrawing functions *
6686 ***********************/
6689 gtk_window_paint (GtkWidget *widget,
6692 gtk_paint_flat_box (widget->style, widget->window, GTK_STATE_NORMAL,
6693 GTK_SHADOW_NONE, area, widget, "base", 0, 0, -1, -1);
6697 gtk_window_expose (GtkWidget *widget,
6698 GdkEventExpose *event)
6700 if (!gtk_widget_get_app_paintable (widget))
6701 gtk_window_paint (widget, &event->area);
6703 if (GTK_WIDGET_CLASS (gtk_window_parent_class)->expose_event)
6704 return GTK_WIDGET_CLASS (gtk_window_parent_class)->expose_event (widget, event);
6710 * gtk_window_set_has_frame:
6711 * @window: a #GtkWindow
6712 * @setting: a boolean
6714 * (Note: this is a special-purpose function for the framebuffer port,
6715 * that causes GTK+ to draw its own window border. For most applications,
6716 * you want gtk_window_set_decorated() instead, which tells the window
6717 * manager whether to draw the window border.)
6719 * If this function is called on a window with setting of %TRUE, before
6720 * it is realized or showed, it will have a "frame" window around
6721 * @window->window, accessible in @window->frame. Using the signal
6722 * frame_event you can receive all events targeted at the frame.
6724 * This function is used by the linux-fb port to implement managed
6725 * windows, but it could conceivably be used by X-programs that
6726 * want to do their own window decorations.
6730 gtk_window_set_has_frame (GtkWindow *window,
6733 g_return_if_fail (GTK_IS_WINDOW (window));
6734 g_return_if_fail (!gtk_widget_get_realized (GTK_WIDGET (window)));
6736 window->has_frame = setting != FALSE;
6740 * gtk_window_get_has_frame:
6741 * @window: a #GtkWindow
6743 * Accessor for whether the window has a frame window exterior to
6744 * @window->window. Gets the value set by gtk_window_set_has_frame ().
6746 * Return value: %TRUE if a frame has been added to the window
6747 * via gtk_window_set_has_frame().
6750 gtk_window_get_has_frame (GtkWindow *window)
6752 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
6754 return window->has_frame;
6758 * gtk_window_set_frame_dimensions:
6759 * @window: a #GtkWindow that has a frame
6760 * @left: The width of the left border
6761 * @top: The height of the top border
6762 * @right: The width of the right border
6763 * @bottom: The height of the bottom border
6765 * (Note: this is a special-purpose function intended for the framebuffer
6766 * port; see gtk_window_set_has_frame(). It will have no effect on the
6767 * window border drawn by the window manager, which is the normal
6768 * case when using the X Window system.)
6770 * For windows with frames (see gtk_window_set_has_frame()) this function
6771 * can be used to change the size of the frame border.
6774 gtk_window_set_frame_dimensions (GtkWindow *window,
6782 g_return_if_fail (GTK_IS_WINDOW (window));
6784 widget = GTK_WIDGET (window);
6786 if (window->frame_left == left &&
6787 window->frame_top == top &&
6788 window->frame_right == right &&
6789 window->frame_bottom == bottom)
6792 window->frame_left = left;
6793 window->frame_top = top;
6794 window->frame_right = right;
6795 window->frame_bottom = bottom;
6797 if (gtk_widget_get_realized (widget) && window->frame)
6799 gint width = widget->allocation.width + left + right;
6800 gint height = widget->allocation.height + top + bottom;
6801 gdk_window_resize (window->frame, width, height);
6802 gtk_decorated_window_move_resize_window (window,
6804 widget->allocation.width,
6805 widget->allocation.height);
6810 * gtk_window_present:
6811 * @window: a #GtkWindow
6813 * Presents a window to the user. This may mean raising the window
6814 * in the stacking order, deiconifying it, moving it to the current
6815 * desktop, and/or giving it the keyboard focus, possibly dependent
6816 * on the user's platform, window manager, and preferences.
6818 * If @window is hidden, this function calls gtk_widget_show()
6821 * This function should be used when the user tries to open a window
6822 * that's already open. Say for example the preferences dialog is
6823 * currently open, and the user chooses Preferences from the menu
6824 * a second time; use gtk_window_present() to move the already-open dialog
6825 * where the user can see it.
6827 * If you are calling this function in response to a user interaction,
6828 * it is preferable to use gtk_window_present_with_time().
6832 gtk_window_present (GtkWindow *window)
6834 gtk_window_present_with_time (window, GDK_CURRENT_TIME);
6838 * gtk_window_present_with_time:
6839 * @window: a #GtkWindow
6840 * @timestamp: the timestamp of the user interaction (typically a
6841 * button or key press event) which triggered this call
6843 * Presents a window to the user in response to a user interaction.
6844 * If you need to present a window without a timestamp, use
6845 * gtk_window_present(). See gtk_window_present() for details.
6850 gtk_window_present_with_time (GtkWindow *window,
6855 g_return_if_fail (GTK_IS_WINDOW (window));
6857 widget = GTK_WIDGET (window);
6859 if (gtk_widget_get_visible (widget))
6861 g_assert (widget->window != NULL);
6863 gdk_window_show (widget->window);
6865 /* Translate a timestamp of GDK_CURRENT_TIME appropriately */
6866 if (timestamp == GDK_CURRENT_TIME)
6868 #ifdef GDK_WINDOWING_X11
6869 GdkDisplay *display;
6871 display = gtk_widget_get_display (GTK_WIDGET (window));
6872 timestamp = gdk_x11_display_get_user_time (display);
6874 timestamp = gtk_get_current_event_time ();
6878 gdk_window_focus (widget->window, timestamp);
6882 gtk_widget_show (widget);
6887 * gtk_window_iconify:
6888 * @window: a #GtkWindow
6890 * Asks to iconify (i.e. minimize) the specified @window. Note that
6891 * you shouldn't assume the window is definitely iconified afterward,
6892 * because other entities (e.g. the user or <link
6893 * linkend="gtk-X11-arch">window manager</link>) could deiconify it
6894 * again, or there may not be a window manager in which case
6895 * iconification isn't possible, etc. But normally the window will end
6896 * up iconified. Just don't write code that crashes if not.
6898 * It's permitted to call this function before showing a window,
6899 * in which case the window will be iconified before it ever appears
6902 * You can track iconification via the "window-state-event" signal
6907 gtk_window_iconify (GtkWindow *window)
6910 GdkWindow *toplevel;
6912 g_return_if_fail (GTK_IS_WINDOW (window));
6914 widget = GTK_WIDGET (window);
6916 window->iconify_initially = TRUE;
6919 toplevel = window->frame;
6921 toplevel = widget->window;
6923 if (toplevel != NULL)
6924 gdk_window_iconify (toplevel);
6928 * gtk_window_deiconify:
6929 * @window: a #GtkWindow
6931 * Asks to deiconify (i.e. unminimize) the specified @window. Note
6932 * that you shouldn't assume the window is definitely deiconified
6933 * afterward, because other entities (e.g. the user or <link
6934 * linkend="gtk-X11-arch">window manager</link>) could iconify it
6935 * again before your code which assumes deiconification gets to run.
6937 * You can track iconification via the "window-state-event" signal
6941 gtk_window_deiconify (GtkWindow *window)
6944 GdkWindow *toplevel;
6946 g_return_if_fail (GTK_IS_WINDOW (window));
6948 widget = GTK_WIDGET (window);
6950 window->iconify_initially = FALSE;
6953 toplevel = window->frame;
6955 toplevel = widget->window;
6957 if (toplevel != NULL)
6958 gdk_window_deiconify (toplevel);
6963 * @window: a #GtkWindow
6965 * Asks to stick @window, which means that it will appear on all user
6966 * desktops. Note that you shouldn't assume the window is definitely
6967 * stuck afterward, because other entities (e.g. the user or <link
6968 * linkend="gtk-X11-arch">window manager</link>) could unstick it
6969 * again, and some window managers do not support sticking
6970 * windows. But normally the window will end up stuck. Just don't
6971 * write code that crashes if not.
6973 * It's permitted to call this function before showing a window.
6975 * You can track stickiness via the "window-state-event" signal
6980 gtk_window_stick (GtkWindow *window)
6983 GdkWindow *toplevel;
6985 g_return_if_fail (GTK_IS_WINDOW (window));
6987 widget = GTK_WIDGET (window);
6989 window->stick_initially = TRUE;
6992 toplevel = window->frame;
6994 toplevel = widget->window;
6996 if (toplevel != NULL)
6997 gdk_window_stick (toplevel);
7001 * gtk_window_unstick:
7002 * @window: a #GtkWindow
7004 * Asks to unstick @window, which means that it will appear on only
7005 * one of the user's desktops. Note that you shouldn't assume the
7006 * window is definitely unstuck afterward, because other entities
7007 * (e.g. the user or <link linkend="gtk-X11-arch">window
7008 * manager</link>) could stick it again. But normally the window will
7009 * end up stuck. Just don't write code that crashes if not.
7011 * You can track stickiness via the "window-state-event" signal
7016 gtk_window_unstick (GtkWindow *window)
7019 GdkWindow *toplevel;
7021 g_return_if_fail (GTK_IS_WINDOW (window));
7023 widget = GTK_WIDGET (window);
7025 window->stick_initially = FALSE;
7028 toplevel = window->frame;
7030 toplevel = widget->window;
7032 if (toplevel != NULL)
7033 gdk_window_unstick (toplevel);
7037 * gtk_window_maximize:
7038 * @window: a #GtkWindow
7040 * Asks to maximize @window, so that it becomes full-screen. Note that
7041 * you shouldn't assume the window is definitely maximized afterward,
7042 * because other entities (e.g. the user or <link
7043 * linkend="gtk-X11-arch">window manager</link>) could unmaximize it
7044 * again, and not all window managers support maximization. But
7045 * normally the window will end up maximized. Just don't write code
7046 * that crashes if not.
7048 * It's permitted to call this function before showing a window,
7049 * in which case the window will be maximized when it appears onscreen
7052 * You can track maximization via the "window-state-event" signal
7057 gtk_window_maximize (GtkWindow *window)
7060 GdkWindow *toplevel;
7062 g_return_if_fail (GTK_IS_WINDOW (window));
7064 widget = GTK_WIDGET (window);
7066 window->maximize_initially = TRUE;
7069 toplevel = window->frame;
7071 toplevel = widget->window;
7073 if (toplevel != NULL)
7074 gdk_window_maximize (toplevel);
7078 * gtk_window_unmaximize:
7079 * @window: a #GtkWindow
7081 * Asks to unmaximize @window. Note that you shouldn't assume the
7082 * window is definitely unmaximized afterward, because other entities
7083 * (e.g. the user or <link linkend="gtk-X11-arch">window
7084 * manager</link>) could maximize it again, and not all window
7085 * managers honor requests to unmaximize. But normally the window will
7086 * end up unmaximized. Just don't write code that crashes if not.
7088 * You can track maximization via the "window-state-event" signal
7093 gtk_window_unmaximize (GtkWindow *window)
7096 GdkWindow *toplevel;
7098 g_return_if_fail (GTK_IS_WINDOW (window));
7100 widget = GTK_WIDGET (window);
7102 window->maximize_initially = FALSE;
7105 toplevel = window->frame;
7107 toplevel = widget->window;
7109 if (toplevel != NULL)
7110 gdk_window_unmaximize (toplevel);
7114 * gtk_window_fullscreen:
7115 * @window: a #GtkWindow
7117 * Asks to place @window in the fullscreen state. Note that you
7118 * shouldn't assume the window is definitely full screen afterward,
7119 * because other entities (e.g. the user or <link
7120 * linkend="gtk-X11-arch">window manager</link>) could unfullscreen it
7121 * again, and not all window managers honor requests to fullscreen
7122 * windows. But normally the window will end up fullscreen. Just
7123 * don't write code that crashes if not.
7125 * You can track the fullscreen state via the "window-state-event" signal
7131 gtk_window_fullscreen (GtkWindow *window)
7134 GdkWindow *toplevel;
7135 GtkWindowPrivate *priv;
7137 g_return_if_fail (GTK_IS_WINDOW (window));
7139 widget = GTK_WIDGET (window);
7140 priv = GTK_WINDOW_GET_PRIVATE (window);
7142 priv->fullscreen_initially = TRUE;
7145 toplevel = window->frame;
7147 toplevel = widget->window;
7149 if (toplevel != NULL)
7150 gdk_window_fullscreen (toplevel);
7154 * gtk_window_unfullscreen:
7155 * @window: a #GtkWindow
7157 * Asks to toggle off the fullscreen state for @window. Note that you
7158 * shouldn't assume the window is definitely not full screen
7159 * afterward, because other entities (e.g. the user or <link
7160 * linkend="gtk-X11-arch">window manager</link>) could fullscreen it
7161 * again, and not all window managers honor requests to unfullscreen
7162 * windows. But normally the window will end up restored to its normal
7163 * state. Just don't write code that crashes if not.
7165 * You can track the fullscreen state via the "window-state-event" signal
7171 gtk_window_unfullscreen (GtkWindow *window)
7174 GdkWindow *toplevel;
7175 GtkWindowPrivate *priv;
7177 g_return_if_fail (GTK_IS_WINDOW (window));
7179 widget = GTK_WIDGET (window);
7180 priv = GTK_WINDOW_GET_PRIVATE (window);
7182 priv->fullscreen_initially = FALSE;
7185 toplevel = window->frame;
7187 toplevel = widget->window;
7189 if (toplevel != NULL)
7190 gdk_window_unfullscreen (toplevel);
7194 * gtk_window_set_keep_above:
7195 * @window: a #GtkWindow
7196 * @setting: whether to keep @window above other windows
7198 * Asks to keep @window above, so that it stays on top. Note that
7199 * you shouldn't assume the window is definitely above afterward,
7200 * because other entities (e.g. the user or <link
7201 * linkend="gtk-X11-arch">window manager</link>) could not keep it above,
7202 * and not all window managers support keeping windows above. But
7203 * normally the window will end kept above. Just don't write code
7204 * that crashes if not.
7206 * It's permitted to call this function before showing a window,
7207 * in which case the window will be kept above when it appears onscreen
7210 * You can track the above state via the "window-state-event" signal
7213 * Note that, according to the <ulink
7214 * url="http://www.freedesktop.org/Standards/wm-spec">Extended Window
7215 * Manager Hints</ulink> specification, the above state is mainly meant
7216 * for user preferences and should not be used by applications e.g. for
7217 * drawing attention to their dialogs.
7222 gtk_window_set_keep_above (GtkWindow *window,
7226 GtkWindowPrivate *priv;
7227 GdkWindow *toplevel;
7229 g_return_if_fail (GTK_IS_WINDOW (window));
7231 widget = GTK_WIDGET (window);
7232 priv = GTK_WINDOW_GET_PRIVATE (window);
7234 priv->above_initially = setting != FALSE;
7236 priv->below_initially = FALSE;
7239 toplevel = window->frame;
7241 toplevel = widget->window;
7243 if (toplevel != NULL)
7244 gdk_window_set_keep_above (toplevel, setting);
7248 * gtk_window_set_keep_below:
7249 * @window: a #GtkWindow
7250 * @setting: whether to keep @window below other windows
7252 * Asks to keep @window below, so that it stays in bottom. Note that
7253 * you shouldn't assume the window is definitely below afterward,
7254 * because other entities (e.g. the user or <link
7255 * linkend="gtk-X11-arch">window manager</link>) could not keep it below,
7256 * and not all window managers support putting windows below. But
7257 * normally the window will be kept below. Just don't write code
7258 * that crashes if not.
7260 * It's permitted to call this function before showing a window,
7261 * in which case the window will be kept below when it appears onscreen
7264 * You can track the below state via the "window-state-event" signal
7267 * Note that, according to the <ulink
7268 * url="http://www.freedesktop.org/Standards/wm-spec">Extended Window
7269 * Manager Hints</ulink> specification, the above state is mainly meant
7270 * for user preferences and should not be used by applications e.g. for
7271 * drawing attention to their dialogs.
7276 gtk_window_set_keep_below (GtkWindow *window,
7280 GtkWindowPrivate *priv;
7281 GdkWindow *toplevel;
7283 g_return_if_fail (GTK_IS_WINDOW (window));
7285 widget = GTK_WIDGET (window);
7286 priv = GTK_WINDOW_GET_PRIVATE (window);
7288 priv->below_initially = setting != FALSE;
7290 priv->above_initially = FALSE;
7293 toplevel = window->frame;
7295 toplevel = widget->window;
7297 if (toplevel != NULL)
7298 gdk_window_set_keep_below (toplevel, setting);
7302 * gtk_window_set_resizable:
7303 * @window: a #GtkWindow
7304 * @resizable: %TRUE if the user can resize this window
7306 * Sets whether the user can resize a window. Windows are user resizable
7310 gtk_window_set_resizable (GtkWindow *window,
7313 g_return_if_fail (GTK_IS_WINDOW (window));
7315 gtk_window_set_policy_internal (window, FALSE, resizable, FALSE);
7319 * gtk_window_get_resizable:
7320 * @window: a #GtkWindow
7322 * Gets the value set by gtk_window_set_resizable().
7324 * Return value: %TRUE if the user can resize the window
7327 gtk_window_get_resizable (GtkWindow *window)
7329 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
7331 /* allow_grow is most likely to indicate the semantic concept we
7332 * mean by "resizable" (and will be a reliable indicator if
7333 * set_policy() hasn't been called)
7335 return window->allow_grow;
7339 * gtk_window_set_gravity:
7340 * @window: a #GtkWindow
7341 * @gravity: window gravity
7343 * Window gravity defines the meaning of coordinates passed to
7344 * gtk_window_move(). See gtk_window_move() and #GdkGravity for
7347 * The default window gravity is #GDK_GRAVITY_NORTH_WEST which will
7348 * typically "do what you mean."
7352 gtk_window_set_gravity (GtkWindow *window,
7355 g_return_if_fail (GTK_IS_WINDOW (window));
7357 if (gravity != window->gravity)
7359 window->gravity = gravity;
7361 /* gtk_window_move_resize() will adapt gravity
7363 gtk_widget_queue_resize_no_redraw (GTK_WIDGET (window));
7365 g_object_notify (G_OBJECT (window), "gravity");
7370 * gtk_window_get_gravity:
7371 * @window: a #GtkWindow
7373 * Gets the value set by gtk_window_set_gravity().
7375 * Return value: (transfer none): window gravity
7378 gtk_window_get_gravity (GtkWindow *window)
7380 g_return_val_if_fail (GTK_IS_WINDOW (window), 0);
7382 return window->gravity;
7386 * gtk_window_begin_resize_drag:
7387 * @window: a #GtkWindow
7388 * @button: mouse button that initiated the drag
7389 * @edge: position of the resize control
7390 * @root_x: X position where the user clicked to initiate the drag, in root window coordinates
7391 * @root_y: Y position where the user clicked to initiate the drag
7392 * @timestamp: timestamp from the click event that initiated the drag
7394 * Starts resizing a window. This function is used if an application
7395 * has window resizing controls. When GDK can support it, the resize
7396 * will be done using the standard mechanism for the <link
7397 * linkend="gtk-X11-arch">window manager</link> or windowing
7398 * system. Otherwise, GDK will try to emulate window resizing,
7399 * potentially not all that well, depending on the windowing system.
7403 gtk_window_begin_resize_drag (GtkWindow *window,
7411 GdkWindow *toplevel;
7413 g_return_if_fail (GTK_IS_WINDOW (window));
7414 widget = GTK_WIDGET (window);
7415 g_return_if_fail (gtk_widget_get_visible (widget));
7418 toplevel = window->frame;
7420 toplevel = widget->window;
7422 gdk_window_begin_resize_drag (toplevel,
7429 * gtk_window_get_frame_dimensions:
7430 * @window: a #GtkWindow
7431 * @left: (allow-none) (out): location to store the width of the frame at the left, or %NULL
7432 * @top: (allow-none) (out): location to store the height of the frame at the top, or %NULL
7433 * @right: (allow-none) (out): location to store the width of the frame at the returns, or %NULL
7434 * @bottom: (allow-none) (out): location to store the height of the frame at the bottom, or %NULL
7436 * (Note: this is a special-purpose function intended for the
7437 * framebuffer port; see gtk_window_set_has_frame(). It will not
7438 * return the size of the window border drawn by the <link
7439 * linkend="gtk-X11-arch">window manager</link>, which is the normal
7440 * case when using a windowing system. See
7441 * gdk_window_get_frame_extents() to get the standard window border
7444 * Retrieves the dimensions of the frame window for this toplevel.
7445 * See gtk_window_set_has_frame(), gtk_window_set_frame_dimensions().
7448 gtk_window_get_frame_dimensions (GtkWindow *window,
7454 g_return_if_fail (GTK_IS_WINDOW (window));
7457 *left = window->frame_left;
7459 *top = window->frame_top;
7461 *right = window->frame_right;
7463 *bottom = window->frame_bottom;
7467 * gtk_window_begin_move_drag:
7468 * @window: a #GtkWindow
7469 * @button: mouse button that initiated the drag
7470 * @root_x: X position where the user clicked to initiate the drag, in root window coordinates
7471 * @root_y: Y position where the user clicked to initiate the drag
7472 * @timestamp: timestamp from the click event that initiated the drag
7474 * Starts moving a window. This function is used if an application has
7475 * window movement grips. When GDK can support it, the window movement
7476 * will be done using the standard mechanism for the <link
7477 * linkend="gtk-X11-arch">window manager</link> or windowing
7478 * system. Otherwise, GDK will try to emulate window movement,
7479 * potentially not all that well, depending on the windowing system.
7483 gtk_window_begin_move_drag (GtkWindow *window,
7490 GdkWindow *toplevel;
7492 g_return_if_fail (GTK_IS_WINDOW (window));
7493 widget = GTK_WIDGET (window);
7494 g_return_if_fail (gtk_widget_get_visible (widget));
7497 toplevel = window->frame;
7499 toplevel = widget->window;
7501 gdk_window_begin_move_drag (toplevel,
7508 * gtk_window_set_screen:
7509 * @window: a #GtkWindow.
7510 * @screen: a #GdkScreen.
7512 * Sets the #GdkScreen where the @window is displayed; if
7513 * the window is already mapped, it will be unmapped, and
7514 * then remapped on the new screen.
7519 gtk_window_set_screen (GtkWindow *window,
7523 GdkScreen *previous_screen;
7524 gboolean was_mapped;
7526 g_return_if_fail (GTK_IS_WINDOW (window));
7527 g_return_if_fail (GDK_IS_SCREEN (screen));
7529 if (screen == window->screen)
7532 widget = GTK_WIDGET (window);
7534 previous_screen = window->screen;
7535 was_mapped = gtk_widget_get_mapped (widget);
7538 gtk_widget_unmap (widget);
7539 if (gtk_widget_get_realized (widget))
7540 gtk_widget_unrealize (widget);
7542 gtk_window_free_key_hash (window);
7543 window->screen = screen;
7544 gtk_widget_reset_rc_styles (widget);
7545 if (screen != previous_screen)
7547 g_signal_handlers_disconnect_by_func (previous_screen,
7548 gtk_window_on_composited_changed, window);
7549 g_signal_connect (screen, "composited-changed",
7550 G_CALLBACK (gtk_window_on_composited_changed), window);
7552 _gtk_widget_propagate_screen_changed (widget, previous_screen);
7553 _gtk_widget_propagate_composited_changed (widget);
7555 g_object_notify (G_OBJECT (window), "screen");
7558 gtk_widget_map (widget);
7562 gtk_window_on_composited_changed (GdkScreen *screen,
7565 gtk_widget_queue_draw (GTK_WIDGET (window));
7567 _gtk_widget_propagate_composited_changed (GTK_WIDGET (window));
7571 gtk_window_check_screen (GtkWindow *window)
7574 return window->screen;
7577 g_warning ("Screen for GtkWindow not set; you must always set\n"
7578 "a screen for a GtkWindow before using the window");
7584 * gtk_window_get_screen:
7585 * @window: a #GtkWindow.
7587 * Returns the #GdkScreen associated with @window.
7589 * Return value: (transfer none): a #GdkScreen.
7594 gtk_window_get_screen (GtkWindow *window)
7596 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
7598 return window->screen;
7602 * gtk_window_is_active:
7603 * @window: a #GtkWindow
7605 * Returns whether the window is part of the current active toplevel.
7606 * (That is, the toplevel window receiving keystrokes.)
7607 * The return value is %TRUE if the window is active toplevel
7608 * itself, but also if it is, say, a #GtkPlug embedded in the active toplevel.
7609 * You might use this function if you wanted to draw a widget
7610 * differently in an active window from a widget in an inactive window.
7611 * See gtk_window_has_toplevel_focus()
7613 * Return value: %TRUE if the window part of the current active window.
7618 gtk_window_is_active (GtkWindow *window)
7620 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
7622 return window->is_active;
7626 * gtk_window_has_toplevel_focus:
7627 * @window: a #GtkWindow
7629 * Returns whether the input focus is within this GtkWindow.
7630 * For real toplevel windows, this is identical to gtk_window_is_active(),
7631 * but for embedded windows, like #GtkPlug, the results will differ.
7633 * Return value: %TRUE if the input focus is within this GtkWindow
7638 gtk_window_has_toplevel_focus (GtkWindow *window)
7640 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
7642 return window->has_toplevel_focus;
7646 gtk_window_group_class_init (GtkWindowGroupClass *klass)
7648 g_type_class_add_private (klass, sizeof (GtkWindowGroupPrivate));
7652 gtk_window_group_get_type (void)
7654 static GType window_group_type = 0;
7656 if (!window_group_type)
7658 const GTypeInfo window_group_info =
7660 sizeof (GtkWindowGroupClass),
7661 NULL, /* base_init */
7662 NULL, /* base_finalize */
7663 (GClassInitFunc) gtk_window_group_class_init,
7664 NULL, /* class_finalize */
7665 NULL, /* class_data */
7666 sizeof (GtkWindowGroup),
7667 0, /* n_preallocs */
7668 (GInstanceInitFunc) NULL,
7671 window_group_type = g_type_register_static (G_TYPE_OBJECT, I_("GtkWindowGroup"),
7672 &window_group_info, 0);
7675 return window_group_type;
7679 * gtk_window_group_new:
7681 * Creates a new #GtkWindowGroup object. Grabs added with
7682 * gtk_grab_add() only affect windows within the same #GtkWindowGroup.
7684 * Return value: a new #GtkWindowGroup.
7687 gtk_window_group_new (void)
7689 return g_object_new (GTK_TYPE_WINDOW_GROUP, NULL);
7693 window_group_cleanup_grabs (GtkWindowGroup *group,
7696 GtkWindowGroupPrivate *priv;
7697 GtkDeviceGrabInfo *info;
7699 GSList *to_remove = NULL;
7701 tmp_list = group->grabs;
7704 if (gtk_widget_get_toplevel (tmp_list->data) == (GtkWidget*) window)
7705 to_remove = g_slist_prepend (to_remove, g_object_ref (tmp_list->data));
7706 tmp_list = tmp_list->next;
7711 gtk_grab_remove (to_remove->data);
7712 g_object_unref (to_remove->data);
7713 to_remove = g_slist_delete_link (to_remove, to_remove);
7716 priv = GTK_WINDOW_GROUP_GET_PRIVATE (group);
7717 tmp_list = priv->device_grabs;
7721 info = tmp_list->data;
7723 if (gtk_widget_get_toplevel (info->widget) == (GtkWidget *) window)
7724 to_remove = g_slist_prepend (to_remove, info);
7726 tmp_list = tmp_list->next;
7731 info = to_remove->data;
7733 gtk_device_grab_remove (info->widget, info->device);
7734 to_remove = g_slist_delete_link (to_remove, to_remove);
7739 * gtk_window_group_add_window:
7740 * @window_group: a #GtkWindowGroup
7741 * @window: the #GtkWindow to add
7743 * Adds a window to a #GtkWindowGroup.
7746 gtk_window_group_add_window (GtkWindowGroup *window_group,
7749 g_return_if_fail (GTK_IS_WINDOW_GROUP (window_group));
7750 g_return_if_fail (GTK_IS_WINDOW (window));
7752 if (window->group != window_group)
7754 g_object_ref (window);
7755 g_object_ref (window_group);
7758 gtk_window_group_remove_window (window->group, window);
7760 window_group_cleanup_grabs (gtk_window_get_group (NULL), window);
7762 window->group = window_group;
7764 g_object_unref (window);
7769 * gtk_window_group_remove_window:
7770 * @window_group: a #GtkWindowGroup
7771 * @window: the #GtkWindow to remove
7773 * Removes a window from a #GtkWindowGroup.
7776 gtk_window_group_remove_window (GtkWindowGroup *window_group,
7779 g_return_if_fail (GTK_IS_WINDOW_GROUP (window_group));
7780 g_return_if_fail (GTK_IS_WINDOW (window));
7781 g_return_if_fail (window->group == window_group);
7783 g_object_ref (window);
7785 window_group_cleanup_grabs (window_group, window);
7786 window->group = NULL;
7788 g_object_unref (window_group);
7789 g_object_unref (window);
7793 * gtk_window_group_list_windows:
7794 * @window_group: a #GtkWindowGroup
7796 * Returns a list of the #GtkWindows that belong to @window_group.
7798 * Returns: (element-type GtkWidget) (transfer container): A newly-allocated list of
7799 * windows inside the group.
7804 gtk_window_group_list_windows (GtkWindowGroup *window_group)
7806 GList *toplevels, *toplevel, *group_windows;
7808 g_return_val_if_fail (GTK_IS_WINDOW_GROUP (window_group), NULL);
7810 group_windows = NULL;
7811 toplevels = gtk_window_list_toplevels ();
7813 for (toplevel = toplevels; toplevel; toplevel = toplevel->next)
7815 GtkWindow *window = toplevel->data;
7817 if (window_group == window->group)
7818 group_windows = g_list_prepend (group_windows, window);
7821 return g_list_reverse (group_windows);
7825 * gtk_window_get_group:
7826 * @window: (allow-none): a #GtkWindow, or %NULL
7828 * Returns the group for @window or the default group, if
7829 * @window is %NULL or if @window does not have an explicit
7832 * Returns: (transfer none): the #GtkWindowGroup for a window or the default group
7837 gtk_window_get_group (GtkWindow *window)
7839 if (window && window->group)
7840 return window->group;
7843 static GtkWindowGroup *default_group = NULL;
7846 default_group = gtk_window_group_new ();
7848 return default_group;
7852 /* Return the current grab widget of the given group
7855 _gtk_window_group_get_current_grab (GtkWindowGroup *window_group)
7857 if (window_group->grabs)
7858 return GTK_WIDGET (window_group->grabs->data);
7863 _gtk_window_group_add_device_grab (GtkWindowGroup *window_group,
7866 gboolean block_others)
7868 GtkWindowGroupPrivate *priv;
7869 GtkDeviceGrabInfo *info;
7871 priv = GTK_WINDOW_GROUP_GET_PRIVATE (window_group);
7873 info = g_slice_new0 (GtkDeviceGrabInfo);
7874 info->widget = widget;
7875 info->device = device;
7876 info->block_others = block_others;
7878 priv->device_grabs = g_slist_prepend (priv->device_grabs, info);
7882 _gtk_window_group_remove_device_grab (GtkWindowGroup *window_group,
7886 GtkWindowGroupPrivate *priv;
7887 GtkDeviceGrabInfo *info;
7888 GSList *list, *node = NULL;
7889 GdkDevice *other_device;
7891 priv = GTK_WINDOW_GROUP_GET_PRIVATE (window_group);
7892 other_device = gdk_device_get_associated_device (device);
7893 list = priv->device_grabs;
7899 if (info->widget == widget &&
7900 (info->device == device ||
7901 info->device == other_device))
7914 priv->device_grabs = g_slist_delete_link (priv->device_grabs, node);
7915 g_slice_free (GtkDeviceGrabInfo, info);
7920 * gtk_window_group_get_current_device_grab:
7921 * @window_group: a #GtkWindowGroup
7922 * @device: a #GdkDevice
7924 * Returns the current grab widget for @device, or %NULL if none.
7926 * Returns: The grab widget, or %NULL
7929 gtk_window_group_get_current_device_grab (GtkWindowGroup *window_group,
7932 GtkWindowGroupPrivate *priv;
7933 GtkDeviceGrabInfo *info;
7934 GdkDevice *other_device;
7937 priv = GTK_WINDOW_GROUP_GET_PRIVATE (window_group);
7938 list = priv->device_grabs;
7939 other_device = gdk_device_get_associated_device (device);
7946 if (info->device == device ||
7947 info->device == other_device)
7948 return info->widget;
7955 _gtk_window_group_widget_is_blocked_for_device (GtkWindowGroup *window_group,
7959 GtkWindowGroupPrivate *priv;
7960 GtkDeviceGrabInfo *info;
7961 GdkDevice *other_device;
7964 priv = GTK_WINDOW_GROUP_GET_PRIVATE (window_group);
7965 other_device = gdk_device_get_associated_device (device);
7966 list = priv->device_grabs;
7973 /* Look for blocking grabs on other device pairs
7974 * that have the passed widget within the GTK+ grab.
7976 if (info->block_others &&
7977 info->device != device &&
7978 info->device != other_device &&
7979 (info->widget == widget ||
7980 gtk_widget_is_ancestor (widget, info->widget)))
7988 Derived from XParseGeometry() in XFree86
7990 Copyright 1985, 1986, 1987,1998 The Open Group
7992 All Rights Reserved.
7994 The above copyright notice and this permission notice shall be included
7995 in all copies or substantial portions of the Software.
7997 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
7998 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
7999 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
8000 IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
8001 OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
8002 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
8003 OTHER DEALINGS IN THE SOFTWARE.
8005 Except as contained in this notice, the name of The Open Group shall
8006 not be used in advertising or otherwise to promote the sale, use or
8007 other dealings in this Software without prior written authorization
8008 from The Open Group.
8013 * XParseGeometry parses strings of the form
8014 * "=<width>x<height>{+-}<xoffset>{+-}<yoffset>", where
8015 * width, height, xoffset, and yoffset are unsigned integers.
8016 * Example: "=80x24+300-49"
8017 * The equal sign is optional.
8018 * It returns a bitmask that indicates which of the four values
8019 * were actually found in the string. For each value found,
8020 * the corresponding argument is updated; for each value
8021 * not found, the corresponding argument is left unchanged.
8024 /* The following code is from Xlib, and is minimally modified, so we
8025 * can track any upstream changes if required. Don't change this
8026 * code. Or if you do, put in a huge comment marking which thing
8031 read_int (gchar *string,
8039 else if (*string == '-')
8045 for (; (*string >= '0') && (*string <= '9'); string++)
8047 result = (result * 10) + (*string - '0');
8059 * Bitmask returned by XParseGeometry(). Each bit tells if the corresponding
8060 * value (x, y, width, height) was found in the parsed string.
8062 #define NoValue 0x0000
8063 #define XValue 0x0001
8064 #define YValue 0x0002
8065 #define WidthValue 0x0004
8066 #define HeightValue 0x0008
8067 #define AllValues 0x000F
8068 #define XNegative 0x0010
8069 #define YNegative 0x0020
8071 /* Try not to reformat/modify, so we can compare/sync with X sources */
8073 gtk_XParseGeometry (const char *string,
8076 unsigned int *width,
8077 unsigned int *height)
8081 unsigned int tempWidth, tempHeight;
8083 char *nextCharacter;
8085 /* These initializations are just to silence gcc */
8091 if ( (string == NULL) || (*string == '\0')) return(mask);
8093 string++; /* ignore possible '=' at beg of geometry spec */
8095 strind = (char *)string;
8096 if (*strind != '+' && *strind != '-' && *strind != 'x') {
8097 tempWidth = read_int(strind, &nextCharacter);
8098 if (strind == nextCharacter)
8100 strind = nextCharacter;
8104 if (*strind == 'x' || *strind == 'X') {
8106 tempHeight = read_int(strind, &nextCharacter);
8107 if (strind == nextCharacter)
8109 strind = nextCharacter;
8110 mask |= HeightValue;
8113 if ((*strind == '+') || (*strind == '-')) {
8114 if (*strind == '-') {
8116 tempX = -read_int(strind, &nextCharacter);
8117 if (strind == nextCharacter)
8119 strind = nextCharacter;
8125 tempX = read_int(strind, &nextCharacter);
8126 if (strind == nextCharacter)
8128 strind = nextCharacter;
8131 if ((*strind == '+') || (*strind == '-')) {
8132 if (*strind == '-') {
8134 tempY = -read_int(strind, &nextCharacter);
8135 if (strind == nextCharacter)
8137 strind = nextCharacter;
8144 tempY = read_int(strind, &nextCharacter);
8145 if (strind == nextCharacter)
8147 strind = nextCharacter;
8153 /* If strind isn't at the end of the string the it's an invalid
8154 geometry specification. */
8156 if (*strind != '\0') return (0);
8162 if (mask & WidthValue)
8164 if (mask & HeightValue)
8165 *height = tempHeight;
8170 * gtk_window_parse_geometry:
8171 * @window: a #GtkWindow
8172 * @geometry: geometry string
8174 * Parses a standard X Window System geometry string - see the
8175 * manual page for X (type 'man X') for details on this.
8176 * gtk_window_parse_geometry() does work on all GTK+ ports
8177 * including Win32 but is primarily intended for an X environment.
8179 * If either a size or a position can be extracted from the
8180 * geometry string, gtk_window_parse_geometry() returns %TRUE
8181 * and calls gtk_window_set_default_size() and/or gtk_window_move()
8182 * to resize/move the window.
8184 * If gtk_window_parse_geometry() returns %TRUE, it will also
8185 * set the #GDK_HINT_USER_POS and/or #GDK_HINT_USER_SIZE hints
8186 * indicating to the window manager that the size/position of
8187 * the window was user-specified. This causes most window
8188 * managers to honor the geometry.
8190 * Note that for gtk_window_parse_geometry() to work as expected, it has
8191 * to be called when the window has its "final" size, i.e. after calling
8192 * gtk_widget_show_all() on the contents and gtk_window_set_geometry_hints()
8195 * #include <gtk/gtk.h>
8198 * fill_with_content (GtkWidget *vbox)
8200 * /* fill with content... */
8204 * main (int argc, char *argv[])
8206 * GtkWidget *window, *vbox;
8207 * GdkGeometry size_hints = {
8208 * 100, 50, 0, 0, 100, 50, 10, 10, 0.0, 0.0, GDK_GRAVITY_NORTH_WEST
8211 * gtk_init (&argc, &argv);
8213 * window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
8214 * vbox = gtk_vbox_new (FALSE, 0);
8216 * gtk_container_add (GTK_CONTAINER (window), vbox);
8217 * fill_with_content (vbox);
8218 * gtk_widget_show_all (vbox);
8220 * gtk_window_set_geometry_hints (GTK_WINDOW (window),
8223 * GDK_HINT_MIN_SIZE |
8224 * GDK_HINT_BASE_SIZE |
8225 * GDK_HINT_RESIZE_INC);
8229 * if (!gtk_window_parse_geometry (GTK_WINDOW (window), argv[1]))
8230 * fprintf (stderr, "Failed to parse '%s'\n", argv[1]);
8233 * gtk_widget_show_all (window);
8240 * Return value: %TRUE if string was parsed successfully
8243 gtk_window_parse_geometry (GtkWindow *window,
8244 const gchar *geometry)
8246 gint result, x = 0, y = 0;
8249 gboolean size_set, pos_set;
8252 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
8253 g_return_val_if_fail (geometry != NULL, FALSE);
8255 screen = gtk_window_check_screen (window);
8257 result = gtk_XParseGeometry (geometry, &x, &y, &w, &h);
8260 if ((result & WidthValue) || (result & HeightValue))
8262 gtk_window_set_default_size_internal (window,
8263 TRUE, result & WidthValue ? w : -1,
8264 TRUE, result & HeightValue ? h : -1,
8269 gtk_window_get_size (window, (gint *)&w, (gint *)&h);
8271 grav = GDK_GRAVITY_NORTH_WEST;
8273 if ((result & XNegative) && (result & YNegative))
8274 grav = GDK_GRAVITY_SOUTH_EAST;
8275 else if (result & XNegative)
8276 grav = GDK_GRAVITY_NORTH_EAST;
8277 else if (result & YNegative)
8278 grav = GDK_GRAVITY_SOUTH_WEST;
8280 if ((result & XValue) == 0)
8283 if ((result & YValue) == 0)
8286 if (grav == GDK_GRAVITY_SOUTH_WEST ||
8287 grav == GDK_GRAVITY_SOUTH_EAST)
8288 y = gdk_screen_get_height (screen) - h + y;
8290 if (grav == GDK_GRAVITY_SOUTH_EAST ||
8291 grav == GDK_GRAVITY_NORTH_EAST)
8292 x = gdk_screen_get_width (screen) - w + x;
8294 /* we don't let you put a window offscreen; maybe some people would
8295 * prefer to be able to, but it's kind of a bogus thing to do.
8304 if ((result & XValue) || (result & YValue))
8306 gtk_window_set_gravity (window, grav);
8307 gtk_window_move (window, x, y);
8311 if (size_set || pos_set)
8313 /* Set USSize, USPosition hints */
8314 GtkWindowGeometryInfo *info;
8316 info = gtk_window_get_geometry_info (window, TRUE);
8319 info->mask |= GDK_HINT_USER_POS;
8321 info->mask |= GDK_HINT_USER_SIZE;
8328 gtk_window_mnemonic_hash_foreach (guint keyval,
8334 GtkWindowKeysForeachFunc func;
8338 (*info->func) (info->window, keyval, info->window->mnemonic_modifier, TRUE, info->func_data);
8342 _gtk_window_keys_foreach (GtkWindow *window,
8343 GtkWindowKeysForeachFunc func,
8347 GtkMnemonicHash *mnemonic_hash;
8351 GtkWindowKeysForeachFunc func;
8355 info.window = window;
8357 info.func_data = func_data;
8359 mnemonic_hash = gtk_window_get_mnemonic_hash (window, FALSE);
8361 _gtk_mnemonic_hash_foreach (mnemonic_hash,
8362 gtk_window_mnemonic_hash_foreach, &info);
8364 groups = gtk_accel_groups_from_object (G_OBJECT (window));
8367 GtkAccelGroup *group = groups->data;
8370 for (i = 0; i < group->priv->n_accels; i++)
8372 GtkAccelKey *key = &group->priv->priv_accels[i].key;
8375 (*func) (window, key->accel_key, key->accel_mods, FALSE, func_data);
8378 groups = groups->next;
8383 gtk_window_keys_changed (GtkWindow *window)
8385 gtk_window_free_key_hash (window);
8386 gtk_window_get_key_hash (window);
8389 typedef struct _GtkWindowKeyEntry GtkWindowKeyEntry;
8391 struct _GtkWindowKeyEntry
8395 guint is_mnemonic : 1;
8399 window_key_entry_destroy (gpointer data)
8401 g_slice_free (GtkWindowKeyEntry, data);
8405 add_to_key_hash (GtkWindow *window,
8407 GdkModifierType modifiers,
8408 gboolean is_mnemonic,
8411 GtkKeyHash *key_hash = data;
8413 GtkWindowKeyEntry *entry = g_slice_new (GtkWindowKeyEntry);
8415 entry->keyval = keyval;
8416 entry->modifiers = modifiers;
8417 entry->is_mnemonic = is_mnemonic;
8419 /* GtkAccelGroup stores lowercased accelerators. To deal
8420 * with this, if <Shift> was specified, uppercase.
8422 if (modifiers & GDK_SHIFT_MASK)
8424 if (keyval == GDK_Tab)
8425 keyval = GDK_ISO_Left_Tab;
8427 keyval = gdk_keyval_to_upper (keyval);
8430 _gtk_key_hash_add_entry (key_hash, keyval, entry->modifiers, entry);
8434 gtk_window_get_key_hash (GtkWindow *window)
8436 GdkScreen *screen = gtk_window_check_screen (window);
8437 GtkKeyHash *key_hash = g_object_get_qdata (G_OBJECT (window), quark_gtk_window_key_hash);
8442 key_hash = _gtk_key_hash_new (gdk_keymap_get_for_display (gdk_screen_get_display (screen)),
8443 (GDestroyNotify)window_key_entry_destroy);
8444 _gtk_window_keys_foreach (window, add_to_key_hash, key_hash);
8445 g_object_set_qdata (G_OBJECT (window), quark_gtk_window_key_hash, key_hash);
8451 gtk_window_free_key_hash (GtkWindow *window)
8453 GtkKeyHash *key_hash = g_object_get_qdata (G_OBJECT (window), quark_gtk_window_key_hash);
8456 _gtk_key_hash_free (key_hash);
8457 g_object_set_qdata (G_OBJECT (window), quark_gtk_window_key_hash, NULL);
8462 * gtk_window_activate_key:
8463 * @window: a #GtkWindow
8464 * @event: a #GdkEventKey
8466 * Activates mnemonics and accelerators for this #GtkWindow. This is normally
8467 * called by the default ::key_press_event handler for toplevel windows,
8468 * however in some cases it may be useful to call this directly when
8469 * overriding the standard key handling for a toplevel window.
8471 * Return value: %TRUE if a mnemonic or accelerator was found and activated.
8476 gtk_window_activate_key (GtkWindow *window,
8479 GtkKeyHash *key_hash;
8480 GtkWindowKeyEntry *found_entry = NULL;
8481 gboolean enable_mnemonics;
8482 gboolean enable_accels;
8484 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
8485 g_return_val_if_fail (event != NULL, FALSE);
8487 key_hash = gtk_window_get_key_hash (window);
8492 GSList *entries = _gtk_key_hash_lookup (key_hash,
8493 event->hardware_keycode,
8495 gtk_accelerator_get_default_mod_mask (),
8498 g_object_get (gtk_widget_get_settings (GTK_WIDGET (window)),
8499 "gtk-enable-mnemonics", &enable_mnemonics,
8500 "gtk-enable-accels", &enable_accels,
8503 for (tmp_list = entries; tmp_list; tmp_list = tmp_list->next)
8505 GtkWindowKeyEntry *entry = tmp_list->data;
8506 if (entry->is_mnemonic)
8508 if (enable_mnemonics)
8510 found_entry = entry;
8516 if (enable_accels && !found_entry)
8518 found_entry = entry;
8523 g_slist_free (entries);
8528 if (found_entry->is_mnemonic)
8530 if (enable_mnemonics)
8531 return gtk_window_mnemonic_activate (window, found_entry->keyval,
8532 found_entry->modifiers);
8537 return gtk_accel_groups_activate (G_OBJECT (window), found_entry->keyval,
8538 found_entry->modifiers);
8546 window_update_has_focus (GtkWindow *window)
8548 GtkWidget *widget = GTK_WIDGET (window);
8549 gboolean has_focus = window->has_toplevel_focus && window->is_active;
8551 if (has_focus != window->has_focus)
8553 window->has_focus = has_focus;
8557 if (window->focus_widget &&
8558 window->focus_widget != widget &&
8559 !gtk_widget_has_focus (window->focus_widget))
8560 do_focus_change (window->focus_widget, TRUE);
8564 if (window->focus_widget &&
8565 window->focus_widget != widget &&
8566 gtk_widget_has_focus (window->focus_widget))
8567 do_focus_change (window->focus_widget, FALSE);
8573 * _gtk_window_set_is_active:
8574 * @window: a #GtkWindow
8575 * @is_active: %TRUE if the window is in the currently active toplevel
8577 * Internal function that sets whether the #GtkWindow is part
8578 * of the currently active toplevel window (taking into account inter-process
8582 _gtk_window_set_is_active (GtkWindow *window,
8585 g_return_if_fail (GTK_IS_WINDOW (window));
8587 is_active = is_active != FALSE;
8589 if (is_active != window->is_active)
8591 window->is_active = is_active;
8592 window_update_has_focus (window);
8594 g_object_notify (G_OBJECT (window), "is-active");
8599 * _gtk_window_set_is_toplevel:
8600 * @window: a #GtkWindow
8601 * @is_toplevel: %TRUE if the window is still a real toplevel (nominally a
8602 * parent of the root window); %FALSE if it is not (for example, for an
8603 * in-process, parented GtkPlug)
8605 * Internal function used by #GtkPlug when it gets parented/unparented by a
8606 * #GtkSocket. This keeps the @window's #GTK_TOPLEVEL flag in sync with the
8607 * global list of toplevel windows.
8610 _gtk_window_set_is_toplevel (GtkWindow *window,
8611 gboolean is_toplevel)
8615 widget = GTK_WIDGET (window);
8617 if (gtk_widget_is_toplevel (widget))
8618 g_assert (g_slist_find (toplevel_list, window) != NULL);
8620 g_assert (g_slist_find (toplevel_list, window) == NULL);
8622 if (is_toplevel == gtk_widget_is_toplevel (widget))
8627 _gtk_widget_set_is_toplevel (widget, TRUE);
8628 toplevel_list = g_slist_prepend (toplevel_list, window);
8632 _gtk_widget_set_is_toplevel (widget, FALSE);
8633 toplevel_list = g_slist_remove (toplevel_list, window);
8638 * _gtk_window_set_has_toplevel_focus:
8639 * @window: a #GtkWindow
8640 * @has_toplevel_focus: %TRUE if the in
8642 * Internal function that sets whether the keyboard focus for the
8643 * toplevel window (taking into account inter-process embedding.)
8646 _gtk_window_set_has_toplevel_focus (GtkWindow *window,
8647 gboolean has_toplevel_focus)
8649 g_return_if_fail (GTK_IS_WINDOW (window));
8651 has_toplevel_focus = has_toplevel_focus != FALSE;
8653 if (has_toplevel_focus != window->has_toplevel_focus)
8655 window->has_toplevel_focus = has_toplevel_focus;
8656 window_update_has_focus (window);
8658 g_object_notify (G_OBJECT (window), "has-toplevel-focus");
8663 * gtk_window_set_auto_startup_notification:
8664 * @setting: %TRUE to automatically do startup notification
8666 * By default, after showing the first #GtkWindow, GTK+ calls
8667 * gdk_notify_startup_complete(). Call this function to disable
8668 * the automatic startup notification. You might do this if your
8669 * first window is a splash screen, and you want to delay notification
8670 * until after your real main window has been shown, for example.
8672 * In that example, you would disable startup notification
8673 * temporarily, show your splash screen, then re-enable it so that
8674 * showing the main window would automatically result in notification.
8679 gtk_window_set_auto_startup_notification (gboolean setting)
8681 disable_startup_notification = !setting;
8685 * gtk_window_get_window_type:
8686 * @window: a #GtkWindow
8688 * Gets the type of the window. See #GtkWindowType.
8690 * Return value: the type of the window
8695 gtk_window_get_window_type (GtkWindow *window)
8697 g_return_val_if_fail (GTK_IS_WINDOW (window), GTK_WINDOW_TOPLEVEL);
8699 return window->type;
8703 * gtk_window_get_mnemonics_visible:
8704 * @window: a #GtkWindow
8706 * Gets the value of the #GtkWindow:mnemonics-visible property.
8708 * Returns: %TRUE if mnemonics are supposed to be visible
8714 gtk_window_get_mnemonics_visible (GtkWindow *window)
8716 GtkWindowPrivate *priv;
8718 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
8720 priv = GTK_WINDOW_GET_PRIVATE (window);
8722 return priv->mnemonics_visible;
8726 * gtk_window_set_mnemonics_visible:
8727 * @window: a #GtkWindow
8728 * @setting: the new value
8730 * Sets the #GtkWindow:mnemonics-visible property.
8735 gtk_window_set_mnemonics_visible (GtkWindow *window,
8738 GtkWindowPrivate *priv;
8740 g_return_if_fail (GTK_IS_WINDOW (window));
8742 priv = GTK_WINDOW_GET_PRIVATE (window);
8744 setting = setting != FALSE;
8746 if (priv->mnemonics_visible != setting)
8748 priv->mnemonics_visible = setting;
8749 g_object_notify (G_OBJECT (window), "mnemonics-visible");
8752 priv->mnemonics_visible_set = TRUE;
8755 #if defined (G_OS_WIN32) && !defined (_WIN64)
8757 #undef gtk_window_set_icon_from_file
8760 gtk_window_set_icon_from_file (GtkWindow *window,
8761 const gchar *filename,
8764 gchar *utf8_filename = g_locale_to_utf8 (filename, -1, NULL, NULL, err);
8767 if (utf8_filename == NULL)
8770 retval = gtk_window_set_icon_from_file_utf8 (window, utf8_filename, err);
8772 g_free (utf8_filename);
8777 #undef gtk_window_set_default_icon_from_file
8780 gtk_window_set_default_icon_from_file (const gchar *filename,
8783 gchar *utf8_filename = g_locale_to_utf8 (filename, -1, NULL, NULL, err);
8786 if (utf8_filename == NULL)
8789 retval = gtk_window_set_default_icon_from_file_utf8 (utf8_filename, err);
8791 g_free (utf8_filename);
8798 #define __GTK_WINDOW_C__
8799 #include "gtkaliasdef.c"