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))
171 typedef struct _GtkWindowPrivate GtkWindowPrivate;
173 struct _GtkWindowPrivate
175 GtkMnemonicHash *mnemonic_hash;
177 guint above_initially : 1;
178 guint below_initially : 1;
179 guint fullscreen_initially : 1;
180 guint skips_taskbar : 1;
181 guint skips_pager : 1;
183 guint accept_focus : 1;
184 guint focus_on_map : 1;
186 guint transient_parent_group : 1;
188 guint reset_type_hint : 1;
189 guint opacity_set : 1;
190 guint builder_visible : 1;
192 guint mnemonics_visible : 1;
193 guint mnemonics_visible_set : 1;
195 GdkWindowTypeHint type_hint;
202 static void gtk_window_dispose (GObject *object);
203 static void gtk_window_destroy (GtkObject *object);
204 static void gtk_window_finalize (GObject *object);
205 static void gtk_window_show (GtkWidget *widget);
206 static void gtk_window_hide (GtkWidget *widget);
207 static void gtk_window_map (GtkWidget *widget);
208 static void gtk_window_unmap (GtkWidget *widget);
209 static void gtk_window_realize (GtkWidget *widget);
210 static void gtk_window_unrealize (GtkWidget *widget);
211 static void gtk_window_size_allocate (GtkWidget *widget,
212 GtkAllocation *allocation);
213 static gint gtk_window_event (GtkWidget *widget,
215 static gboolean gtk_window_map_event (GtkWidget *widget,
217 static gboolean gtk_window_frame_event (GtkWindow *window,
219 static gint gtk_window_configure_event (GtkWidget *widget,
220 GdkEventConfigure *event);
221 static gint gtk_window_key_press_event (GtkWidget *widget,
223 static gint gtk_window_key_release_event (GtkWidget *widget,
225 static gint gtk_window_enter_notify_event (GtkWidget *widget,
226 GdkEventCrossing *event);
227 static gint gtk_window_leave_notify_event (GtkWidget *widget,
228 GdkEventCrossing *event);
229 static gint gtk_window_focus_in_event (GtkWidget *widget,
230 GdkEventFocus *event);
231 static gint gtk_window_focus_out_event (GtkWidget *widget,
232 GdkEventFocus *event);
233 static gint gtk_window_client_event (GtkWidget *widget,
234 GdkEventClient *event);
235 static void gtk_window_check_resize (GtkContainer *container);
236 static gint gtk_window_focus (GtkWidget *widget,
237 GtkDirectionType direction);
238 static void gtk_window_real_set_focus (GtkWindow *window,
241 static void gtk_window_real_activate_default (GtkWindow *window);
242 static void gtk_window_real_activate_focus (GtkWindow *window);
243 static void gtk_window_move_focus (GtkWindow *window,
244 GtkDirectionType dir);
245 static void gtk_window_keys_changed (GtkWindow *window);
246 static void gtk_window_paint (GtkWidget *widget,
248 static gint gtk_window_expose (GtkWidget *widget,
249 GdkEventExpose *event);
250 static void gtk_window_unset_transient_for (GtkWindow *window);
251 static void gtk_window_transient_parent_realized (GtkWidget *parent,
253 static void gtk_window_transient_parent_unrealized (GtkWidget *parent,
256 static GdkScreen *gtk_window_check_screen (GtkWindow *window);
258 static GtkWindowGeometryInfo* gtk_window_get_geometry_info (GtkWindow *window,
261 static void gtk_window_move_resize (GtkWindow *window);
262 static gboolean gtk_window_compare_hints (GdkGeometry *geometry_a,
264 GdkGeometry *geometry_b,
266 static void gtk_window_constrain_size (GtkWindow *window,
267 GdkGeometry *geometry,
273 static void gtk_window_constrain_position (GtkWindow *window,
278 static void gtk_window_compute_hints (GtkWindow *window,
279 GdkGeometry *new_geometry,
281 static void gtk_window_compute_configure_request (GtkWindow *window,
282 GdkRectangle *request,
283 GdkGeometry *geometry,
286 static void gtk_window_set_default_size_internal (GtkWindow *window,
287 gboolean change_width,
289 gboolean change_height,
291 gboolean is_geometry);
293 static void update_themed_icon (GtkIconTheme *theme,
295 static GList *icon_list_from_theme (GtkWidget *widget,
297 static void gtk_window_realize_icon (GtkWindow *window);
298 static void gtk_window_unrealize_icon (GtkWindow *window);
300 static void gtk_window_notify_keys_changed (GtkWindow *window);
301 static GtkKeyHash *gtk_window_get_key_hash (GtkWindow *window);
302 static void gtk_window_free_key_hash (GtkWindow *window);
303 static void gtk_window_on_composited_changed (GdkScreen *screen,
306 static GSList *toplevel_list = NULL;
307 static guint window_signals[LAST_SIGNAL] = { 0 };
308 static GList *default_icon_list = NULL;
309 static gchar *default_icon_name = NULL;
310 static guint default_icon_serial = 0;
311 static gboolean disable_startup_notification = FALSE;
312 static gboolean sent_startup_notification = FALSE;
314 static GQuark quark_gtk_embedded = 0;
315 static GQuark quark_gtk_window_key_hash = 0;
316 static GQuark quark_gtk_window_default_icon_pixmap = 0;
317 static GQuark quark_gtk_window_icon_info = 0;
318 static GQuark quark_gtk_buildable_accels = 0;
320 static GtkBuildableIface *parent_buildable_iface;
322 static void gtk_window_set_property (GObject *object,
326 static void gtk_window_get_property (GObject *object,
332 static void gtk_window_buildable_interface_init (GtkBuildableIface *iface);
333 static void gtk_window_buildable_set_buildable_property (GtkBuildable *buildable,
336 const GValue *value);
337 static void gtk_window_buildable_parser_finished (GtkBuildable *buildable,
338 GtkBuilder *builder);
339 static gboolean gtk_window_buildable_custom_tag_start (GtkBuildable *buildable,
342 const gchar *tagname,
343 GMarkupParser *parser,
345 static void gtk_window_buildable_custom_finished (GtkBuildable *buildable,
348 const gchar *tagname,
352 static void gtk_window_extended_layout_init (GtkExtendedLayoutIface *iface);
353 static void gtk_window_get_desired_width (GtkExtendedLayout *layout,
356 static void gtk_window_get_desired_height (GtkExtendedLayout *layout,
360 G_DEFINE_TYPE_WITH_CODE (GtkWindow, gtk_window, GTK_TYPE_BIN,
361 G_IMPLEMENT_INTERFACE (GTK_TYPE_BUILDABLE,
362 gtk_window_buildable_interface_init)
363 G_IMPLEMENT_INTERFACE (GTK_TYPE_EXTENDED_LAYOUT,
364 gtk_window_extended_layout_init))
367 add_tab_bindings (GtkBindingSet *binding_set,
368 GdkModifierType modifiers,
369 GtkDirectionType direction)
371 gtk_binding_entry_add_signal (binding_set, GDK_Tab, modifiers,
373 GTK_TYPE_DIRECTION_TYPE, direction);
374 gtk_binding_entry_add_signal (binding_set, GDK_KP_Tab, modifiers,
376 GTK_TYPE_DIRECTION_TYPE, direction);
380 add_arrow_bindings (GtkBindingSet *binding_set,
382 GtkDirectionType direction)
384 guint keypad_keysym = keysym - GDK_Left + GDK_KP_Left;
386 gtk_binding_entry_add_signal (binding_set, keysym, 0,
388 GTK_TYPE_DIRECTION_TYPE, direction);
389 gtk_binding_entry_add_signal (binding_set, keysym, GDK_CONTROL_MASK,
391 GTK_TYPE_DIRECTION_TYPE, direction);
392 gtk_binding_entry_add_signal (binding_set, keypad_keysym, 0,
394 GTK_TYPE_DIRECTION_TYPE, direction);
395 gtk_binding_entry_add_signal (binding_set, keypad_keysym, GDK_CONTROL_MASK,
397 GTK_TYPE_DIRECTION_TYPE, direction);
401 extract_time_from_startup_id (const gchar* startup_id)
403 gchar *timestr = g_strrstr (startup_id, "_TIME");
404 guint32 retval = GDK_CURRENT_TIME;
411 /* Skip past the "_TIME" part */
415 timestamp = strtoul (timestr, &end, 0);
416 if (end != timestr && errno == 0)
424 startup_id_is_fake (const gchar* startup_id)
426 return strncmp (startup_id, "_TIME", 5) == 0;
430 gtk_window_class_init (GtkWindowClass *klass)
432 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
433 GtkObjectClass *object_class;
434 GtkWidgetClass *widget_class;
435 GtkContainerClass *container_class;
436 GtkBindingSet *binding_set;
438 object_class = (GtkObjectClass*) klass;
439 widget_class = (GtkWidgetClass*) klass;
440 container_class = (GtkContainerClass*) klass;
442 quark_gtk_embedded = g_quark_from_static_string ("gtk-embedded");
443 quark_gtk_window_key_hash = g_quark_from_static_string ("gtk-window-key-hash");
444 quark_gtk_window_default_icon_pixmap = g_quark_from_static_string ("gtk-window-default-icon-pixmap");
445 quark_gtk_window_icon_info = g_quark_from_static_string ("gtk-window-icon-info");
446 quark_gtk_buildable_accels = g_quark_from_static_string ("gtk-window-buildable-accels");
448 gobject_class->dispose = gtk_window_dispose;
449 gobject_class->finalize = gtk_window_finalize;
451 gobject_class->set_property = gtk_window_set_property;
452 gobject_class->get_property = gtk_window_get_property;
454 object_class->destroy = gtk_window_destroy;
456 widget_class->show = gtk_window_show;
457 widget_class->hide = gtk_window_hide;
458 widget_class->map = gtk_window_map;
459 widget_class->map_event = gtk_window_map_event;
460 widget_class->unmap = gtk_window_unmap;
461 widget_class->realize = gtk_window_realize;
462 widget_class->unrealize = gtk_window_unrealize;
463 widget_class->size_allocate = gtk_window_size_allocate;
464 widget_class->configure_event = gtk_window_configure_event;
465 widget_class->key_press_event = gtk_window_key_press_event;
466 widget_class->key_release_event = gtk_window_key_release_event;
467 widget_class->enter_notify_event = gtk_window_enter_notify_event;
468 widget_class->leave_notify_event = gtk_window_leave_notify_event;
469 widget_class->focus_in_event = gtk_window_focus_in_event;
470 widget_class->focus_out_event = gtk_window_focus_out_event;
471 widget_class->client_event = gtk_window_client_event;
472 widget_class->focus = gtk_window_focus;
473 widget_class->expose_event = gtk_window_expose;
475 container_class->check_resize = gtk_window_check_resize;
477 klass->set_focus = gtk_window_real_set_focus;
478 klass->frame_event = gtk_window_frame_event;
480 klass->activate_default = gtk_window_real_activate_default;
481 klass->activate_focus = gtk_window_real_activate_focus;
482 klass->move_focus = gtk_window_move_focus;
483 klass->keys_changed = gtk_window_keys_changed;
485 g_type_class_add_private (gobject_class, sizeof (GtkWindowPrivate));
488 g_object_class_install_property (gobject_class,
490 g_param_spec_enum ("type",
492 P_("The type of the window"),
493 GTK_TYPE_WINDOW_TYPE,
495 GTK_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
497 g_object_class_install_property (gobject_class,
499 g_param_spec_string ("title",
501 P_("The title of the window"),
503 GTK_PARAM_READWRITE));
505 g_object_class_install_property (gobject_class,
507 g_param_spec_string ("role",
509 P_("Unique identifier for the window to be used when restoring a session"),
511 GTK_PARAM_READWRITE));
514 * GtkWindow:startup-id:
516 * The :startup-id is a write-only property for setting window's
517 * startup notification identifier. See gtk_window_set_startup_id()
522 g_object_class_install_property (gobject_class,
524 g_param_spec_string ("startup-id",
526 P_("Unique startup identifier for the window used by startup-notification"),
528 GTK_PARAM_WRITABLE));
530 g_object_class_install_property (gobject_class,
532 g_param_spec_boolean ("allow-shrink",
534 /* xgettext:no-c-format */
535 P_("If TRUE, the window has no mimimum size. Setting this to TRUE is 99% of the time a bad idea"),
537 GTK_PARAM_READWRITE));
539 g_object_class_install_property (gobject_class,
541 g_param_spec_boolean ("allow-grow",
543 P_("If TRUE, users can expand the window beyond its minimum size"),
545 GTK_PARAM_READWRITE));
547 g_object_class_install_property (gobject_class,
549 g_param_spec_boolean ("resizable",
551 P_("If TRUE, users can resize the window"),
553 GTK_PARAM_READWRITE));
555 g_object_class_install_property (gobject_class,
557 g_param_spec_boolean ("modal",
559 P_("If TRUE, the window is modal (other windows are not usable while this one is up)"),
561 GTK_PARAM_READWRITE));
563 g_object_class_install_property (gobject_class,
565 g_param_spec_enum ("window-position",
566 P_("Window Position"),
567 P_("The initial position of the window"),
568 GTK_TYPE_WINDOW_POSITION,
570 GTK_PARAM_READWRITE));
572 g_object_class_install_property (gobject_class,
574 g_param_spec_int ("default-width",
576 P_("The default width of the window, used when initially showing the window"),
580 GTK_PARAM_READWRITE));
582 g_object_class_install_property (gobject_class,
584 g_param_spec_int ("default-height",
585 P_("Default Height"),
586 P_("The default height of the window, used when initially showing the window"),
590 GTK_PARAM_READWRITE));
592 g_object_class_install_property (gobject_class,
593 PROP_DESTROY_WITH_PARENT,
594 g_param_spec_boolean ("destroy-with-parent",
595 P_("Destroy with Parent"),
596 P_("If this window should be destroyed when the parent is destroyed"),
598 GTK_PARAM_READWRITE));
600 g_object_class_install_property (gobject_class,
602 g_param_spec_object ("icon",
604 P_("Icon for this window"),
606 GTK_PARAM_READWRITE));
607 g_object_class_install_property (gobject_class,
608 PROP_MNEMONICS_VISIBLE,
609 g_param_spec_boolean ("mnemonics-visible",
610 P_("Mnemonics Visible"),
611 P_("Whether mnemonics are currently visible in this window"),
613 GTK_PARAM_READWRITE));
616 * GtkWindow:icon-name:
618 * The :icon-name property specifies the name of the themed icon to
619 * use as the window icon. See #GtkIconTheme for more details.
623 g_object_class_install_property (gobject_class,
625 g_param_spec_string ("icon-name",
627 P_("Name of the themed icon for this window"),
629 GTK_PARAM_READWRITE));
631 g_object_class_install_property (gobject_class,
633 g_param_spec_object ("screen",
635 P_("The screen where this window will be displayed"),
637 GTK_PARAM_READWRITE));
639 g_object_class_install_property (gobject_class,
641 g_param_spec_boolean ("is-active",
643 P_("Whether the toplevel is the current active window"),
645 GTK_PARAM_READABLE));
647 g_object_class_install_property (gobject_class,
648 PROP_HAS_TOPLEVEL_FOCUS,
649 g_param_spec_boolean ("has-toplevel-focus",
650 P_("Focus in Toplevel"),
651 P_("Whether the input focus is within this GtkWindow"),
653 GTK_PARAM_READABLE));
655 g_object_class_install_property (gobject_class,
657 g_param_spec_enum ("type-hint",
659 P_("Hint to help the desktop environment understand what kind of window this is and how to treat it."),
660 GDK_TYPE_WINDOW_TYPE_HINT,
661 GDK_WINDOW_TYPE_HINT_NORMAL,
662 GTK_PARAM_READWRITE));
664 g_object_class_install_property (gobject_class,
665 PROP_SKIP_TASKBAR_HINT,
666 g_param_spec_boolean ("skip-taskbar-hint",
668 P_("TRUE if the window should not be in the task bar."),
670 GTK_PARAM_READWRITE));
672 g_object_class_install_property (gobject_class,
673 PROP_SKIP_PAGER_HINT,
674 g_param_spec_boolean ("skip-pager-hint",
676 P_("TRUE if the window should not be in the pager."),
678 GTK_PARAM_READWRITE));
680 g_object_class_install_property (gobject_class,
682 g_param_spec_boolean ("urgency-hint",
684 P_("TRUE if the window should be brought to the user's attention."),
686 GTK_PARAM_READWRITE));
689 * GtkWindow:accept-focus:
691 * Whether the window should receive the input focus.
695 g_object_class_install_property (gobject_class,
697 g_param_spec_boolean ("accept-focus",
699 P_("TRUE if the window should receive the input focus."),
701 GTK_PARAM_READWRITE));
704 * GtkWindow:focus-on-map:
706 * Whether the window should receive the input focus when mapped.
710 g_object_class_install_property (gobject_class,
712 g_param_spec_boolean ("focus-on-map",
714 P_("TRUE if the window should receive the input focus when mapped."),
716 GTK_PARAM_READWRITE));
719 * GtkWindow:decorated:
721 * Whether the window should be decorated by the window manager.
725 g_object_class_install_property (gobject_class,
727 g_param_spec_boolean ("decorated",
729 P_("Whether the window should be decorated by the window manager"),
731 GTK_PARAM_READWRITE));
734 * GtkWindow:deletable:
736 * Whether the window frame should have a close button.
740 g_object_class_install_property (gobject_class,
742 g_param_spec_boolean ("deletable",
744 P_("Whether the window frame should have a close button"),
746 GTK_PARAM_READWRITE));
752 * The window gravity of the window. See gtk_window_move() and #GdkGravity for
753 * more details about window gravity.
757 g_object_class_install_property (gobject_class,
759 g_param_spec_enum ("gravity",
761 P_("The window gravity of the window"),
763 GDK_GRAVITY_NORTH_WEST,
764 GTK_PARAM_READWRITE));
768 * GtkWindow:transient-for:
770 * The transient parent of the window. See gtk_window_set_transient_for() for
771 * more details about transient windows.
775 g_object_class_install_property (gobject_class,
777 g_param_spec_object ("transient-for",
778 P_("Transient for Window"),
779 P_("The transient parent of the dialog"),
781 GTK_PARAM_READWRITE| G_PARAM_CONSTRUCT));
786 * The requested opacity of the window. See gtk_window_set_opacity() for
787 * more details about window opacity.
791 g_object_class_install_property (gobject_class,
793 g_param_spec_double ("opacity",
794 P_("Opacity for Window"),
795 P_("The opacity of the window, from 0 to 1"),
799 GTK_PARAM_READWRITE));
801 window_signals[SET_FOCUS] =
802 g_signal_new (I_("set-focus"),
803 G_TYPE_FROM_CLASS (gobject_class),
805 G_STRUCT_OFFSET (GtkWindowClass, set_focus),
807 _gtk_marshal_VOID__OBJECT,
811 window_signals[FRAME_EVENT] =
812 g_signal_new (I_("frame-event"),
813 G_TYPE_FROM_CLASS (gobject_class),
815 G_STRUCT_OFFSET(GtkWindowClass, frame_event),
816 _gtk_boolean_handled_accumulator, NULL,
817 _gtk_marshal_BOOLEAN__BOXED,
822 * GtkWindow::activate-focus:
823 * @window: the window which received the signal
825 * The ::activate-default signal is a
826 * <link linkend="keybinding-signals">keybinding signal</link>
827 * which gets emitted when the user activates the currently
828 * focused widget of @window.
830 window_signals[ACTIVATE_FOCUS] =
831 g_signal_new (I_("activate-focus"),
832 G_TYPE_FROM_CLASS (gobject_class),
833 G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
834 G_STRUCT_OFFSET (GtkWindowClass, activate_focus),
836 _gtk_marshal_VOID__VOID,
841 * GtkWindow::activate-default:
842 * @window: the window which received the signal
844 * The ::activate-default signal is a
845 * <link linkend="keybinding-signals">keybinding signal</link>
846 * which gets emitted when the user activates the default widget
849 window_signals[ACTIVATE_DEFAULT] =
850 g_signal_new (I_("activate-default"),
851 G_TYPE_FROM_CLASS (gobject_class),
852 G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
853 G_STRUCT_OFFSET (GtkWindowClass, activate_default),
855 _gtk_marshal_VOID__VOID,
860 * GtkWindow::keys-changed:
861 * @window: the window which received the signal
863 * The ::keys-changed signal gets emitted when the set of accelerators
864 * or mnemonics that are associated with @window changes.
866 window_signals[KEYS_CHANGED] =
867 g_signal_new (I_("keys-changed"),
868 G_TYPE_FROM_CLASS (gobject_class),
870 G_STRUCT_OFFSET (GtkWindowClass, keys_changed),
872 _gtk_marshal_VOID__VOID,
880 binding_set = gtk_binding_set_by_class (klass);
882 gtk_binding_entry_add_signal (binding_set, GDK_space, 0,
883 "activate-focus", 0);
884 gtk_binding_entry_add_signal (binding_set, GDK_KP_Space, 0,
885 "activate-focus", 0);
887 gtk_binding_entry_add_signal (binding_set, GDK_Return, 0,
888 "activate-default", 0);
889 gtk_binding_entry_add_signal (binding_set, GDK_ISO_Enter, 0,
890 "activate-default", 0);
891 gtk_binding_entry_add_signal (binding_set, GDK_KP_Enter, 0,
892 "activate-default", 0);
894 add_arrow_bindings (binding_set, GDK_Up, GTK_DIR_UP);
895 add_arrow_bindings (binding_set, GDK_Down, GTK_DIR_DOWN);
896 add_arrow_bindings (binding_set, GDK_Left, GTK_DIR_LEFT);
897 add_arrow_bindings (binding_set, GDK_Right, GTK_DIR_RIGHT);
899 add_tab_bindings (binding_set, 0, GTK_DIR_TAB_FORWARD);
900 add_tab_bindings (binding_set, GDK_CONTROL_MASK, GTK_DIR_TAB_FORWARD);
901 add_tab_bindings (binding_set, GDK_SHIFT_MASK, GTK_DIR_TAB_BACKWARD);
902 add_tab_bindings (binding_set, GDK_CONTROL_MASK | GDK_SHIFT_MASK, GTK_DIR_TAB_BACKWARD);
906 gtk_window_init (GtkWindow *window)
908 GdkColormap *colormap;
909 GtkWindowPrivate *priv = GTK_WINDOW_GET_PRIVATE (window);
911 gtk_widget_set_has_window (GTK_WIDGET (window), TRUE);
912 _gtk_widget_set_is_toplevel (GTK_WIDGET (window), TRUE);
914 GTK_PRIVATE_SET_FLAG (window, GTK_ANCHORED);
916 gtk_container_set_resize_mode (GTK_CONTAINER (window), GTK_RESIZE_QUEUE);
918 window->title = NULL;
919 window->wmclass_name = g_strdup (g_get_prgname ());
920 window->wmclass_class = g_strdup (gdk_get_program_class ());
921 window->wm_role = NULL;
922 window->geometry_info = NULL;
923 window->type = GTK_WINDOW_TOPLEVEL;
924 window->focus_widget = NULL;
925 window->default_widget = NULL;
926 window->configure_request_count = 0;
927 window->allow_shrink = FALSE;
928 window->allow_grow = TRUE;
929 window->configure_notify_received = FALSE;
930 window->position = GTK_WIN_POS_NONE;
931 window->need_default_size = TRUE;
932 window->need_default_position = TRUE;
933 window->modal = FALSE;
934 window->frame = NULL;
935 window->has_frame = FALSE;
936 window->frame_left = 0;
937 window->frame_right = 0;
938 window->frame_top = 0;
939 window->frame_bottom = 0;
940 window->type_hint = GDK_WINDOW_TYPE_HINT_NORMAL;
941 window->gravity = GDK_GRAVITY_NORTH_WEST;
942 window->decorated = TRUE;
943 window->mnemonic_modifier = GDK_MOD1_MASK;
944 window->screen = gdk_screen_get_default ();
946 priv->accept_focus = TRUE;
947 priv->focus_on_map = TRUE;
948 priv->deletable = TRUE;
949 priv->type_hint = GDK_WINDOW_TYPE_HINT_NORMAL;
951 priv->startup_id = NULL;
952 priv->mnemonics_visible = TRUE;
954 colormap = _gtk_widget_peek_colormap ();
956 gtk_widget_set_colormap (GTK_WIDGET (window), colormap);
958 g_object_ref_sink (window);
959 window->has_user_ref_count = TRUE;
960 toplevel_list = g_slist_prepend (toplevel_list, window);
962 gtk_decorated_window_init (window);
964 g_signal_connect (window->screen, "composited-changed",
965 G_CALLBACK (gtk_window_on_composited_changed), window);
969 gtk_window_set_property (GObject *object,
975 GtkWindowPrivate *priv;
977 window = GTK_WINDOW (object);
979 priv = GTK_WINDOW_GET_PRIVATE (window);
984 window->type = g_value_get_enum (value);
987 gtk_window_set_title (window, g_value_get_string (value));
990 gtk_window_set_role (window, g_value_get_string (value));
992 case PROP_STARTUP_ID:
993 gtk_window_set_startup_id (window, g_value_get_string (value));
995 case PROP_ALLOW_SHRINK:
996 window->allow_shrink = g_value_get_boolean (value);
997 gtk_widget_queue_resize (GTK_WIDGET (window));
999 case PROP_ALLOW_GROW:
1000 window->allow_grow = g_value_get_boolean (value);
1001 gtk_widget_queue_resize (GTK_WIDGET (window));
1002 g_object_notify (G_OBJECT (window), "resizable");
1004 case PROP_RESIZABLE:
1005 window->allow_grow = g_value_get_boolean (value);
1006 gtk_widget_queue_resize (GTK_WIDGET (window));
1007 g_object_notify (G_OBJECT (window), "allow-grow");
1010 gtk_window_set_modal (window, g_value_get_boolean (value));
1013 gtk_window_set_position (window, g_value_get_enum (value));
1015 case PROP_DEFAULT_WIDTH:
1016 gtk_window_set_default_size_internal (window,
1017 TRUE, g_value_get_int (value),
1020 case PROP_DEFAULT_HEIGHT:
1021 gtk_window_set_default_size_internal (window,
1023 TRUE, g_value_get_int (value), FALSE);
1025 case PROP_DESTROY_WITH_PARENT:
1026 gtk_window_set_destroy_with_parent (window, g_value_get_boolean (value));
1029 gtk_window_set_icon (window,
1030 g_value_get_object (value));
1032 case PROP_ICON_NAME:
1033 gtk_window_set_icon_name (window, g_value_get_string (value));
1036 gtk_window_set_screen (window, g_value_get_object (value));
1038 case PROP_TYPE_HINT:
1039 gtk_window_set_type_hint (window,
1040 g_value_get_enum (value));
1042 case PROP_SKIP_TASKBAR_HINT:
1043 gtk_window_set_skip_taskbar_hint (window,
1044 g_value_get_boolean (value));
1046 case PROP_SKIP_PAGER_HINT:
1047 gtk_window_set_skip_pager_hint (window,
1048 g_value_get_boolean (value));
1050 case PROP_URGENCY_HINT:
1051 gtk_window_set_urgency_hint (window,
1052 g_value_get_boolean (value));
1054 case PROP_ACCEPT_FOCUS:
1055 gtk_window_set_accept_focus (window,
1056 g_value_get_boolean (value));
1058 case PROP_FOCUS_ON_MAP:
1059 gtk_window_set_focus_on_map (window,
1060 g_value_get_boolean (value));
1062 case PROP_DECORATED:
1063 gtk_window_set_decorated (window, g_value_get_boolean (value));
1065 case PROP_DELETABLE:
1066 gtk_window_set_deletable (window, g_value_get_boolean (value));
1069 gtk_window_set_gravity (window, g_value_get_enum (value));
1071 case PROP_TRANSIENT_FOR:
1072 gtk_window_set_transient_for (window, g_value_get_object (value));
1075 gtk_window_set_opacity (window, g_value_get_double (value));
1077 case PROP_MNEMONICS_VISIBLE:
1078 gtk_window_set_mnemonics_visible (window, g_value_get_boolean (value));
1081 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1087 gtk_window_get_property (GObject *object,
1093 GtkWindowPrivate *priv;
1095 window = GTK_WINDOW (object);
1096 priv = GTK_WINDOW_GET_PRIVATE (window);
1100 GtkWindowGeometryInfo *info;
1102 g_value_set_enum (value, window->type);
1105 g_value_set_string (value, window->wm_role);
1108 g_value_set_string (value, window->title);
1110 case PROP_ALLOW_SHRINK:
1111 g_value_set_boolean (value, window->allow_shrink);
1113 case PROP_ALLOW_GROW:
1114 g_value_set_boolean (value, window->allow_grow);
1116 case PROP_RESIZABLE:
1117 g_value_set_boolean (value, window->allow_grow);
1120 g_value_set_boolean (value, window->modal);
1123 g_value_set_enum (value, window->position);
1125 case PROP_DEFAULT_WIDTH:
1126 info = gtk_window_get_geometry_info (window, FALSE);
1128 g_value_set_int (value, -1);
1130 g_value_set_int (value, info->default_width);
1132 case PROP_DEFAULT_HEIGHT:
1133 info = gtk_window_get_geometry_info (window, FALSE);
1135 g_value_set_int (value, -1);
1137 g_value_set_int (value, info->default_height);
1139 case PROP_DESTROY_WITH_PARENT:
1140 g_value_set_boolean (value, window->destroy_with_parent);
1143 g_value_set_object (value, gtk_window_get_icon (window));
1145 case PROP_ICON_NAME:
1146 g_value_set_string (value, gtk_window_get_icon_name (window));
1149 g_value_set_object (value, window->screen);
1151 case PROP_IS_ACTIVE:
1152 g_value_set_boolean (value, window->is_active);
1154 case PROP_HAS_TOPLEVEL_FOCUS:
1155 g_value_set_boolean (value, window->has_toplevel_focus);
1157 case PROP_TYPE_HINT:
1158 g_value_set_enum (value, priv->type_hint);
1160 case PROP_SKIP_TASKBAR_HINT:
1161 g_value_set_boolean (value,
1162 gtk_window_get_skip_taskbar_hint (window));
1164 case PROP_SKIP_PAGER_HINT:
1165 g_value_set_boolean (value,
1166 gtk_window_get_skip_pager_hint (window));
1168 case PROP_URGENCY_HINT:
1169 g_value_set_boolean (value,
1170 gtk_window_get_urgency_hint (window));
1172 case PROP_ACCEPT_FOCUS:
1173 g_value_set_boolean (value,
1174 gtk_window_get_accept_focus (window));
1176 case PROP_FOCUS_ON_MAP:
1177 g_value_set_boolean (value,
1178 gtk_window_get_focus_on_map (window));
1180 case PROP_DECORATED:
1181 g_value_set_boolean (value, gtk_window_get_decorated (window));
1183 case PROP_DELETABLE:
1184 g_value_set_boolean (value, gtk_window_get_deletable (window));
1187 g_value_set_enum (value, gtk_window_get_gravity (window));
1189 case PROP_TRANSIENT_FOR:
1190 g_value_set_object (value, gtk_window_get_transient_for (window));
1193 g_value_set_double (value, gtk_window_get_opacity (window));
1195 case PROP_MNEMONICS_VISIBLE:
1196 g_value_set_boolean (value, priv->mnemonics_visible);
1199 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1205 gtk_window_buildable_interface_init (GtkBuildableIface *iface)
1207 parent_buildable_iface = g_type_interface_peek_parent (iface);
1208 iface->set_buildable_property = gtk_window_buildable_set_buildable_property;
1209 iface->parser_finished = gtk_window_buildable_parser_finished;
1210 iface->custom_tag_start = gtk_window_buildable_custom_tag_start;
1211 iface->custom_finished = gtk_window_buildable_custom_finished;
1215 gtk_window_buildable_set_buildable_property (GtkBuildable *buildable,
1216 GtkBuilder *builder,
1218 const GValue *value)
1220 GtkWindowPrivate *priv = GTK_WINDOW_GET_PRIVATE (buildable);
1222 if (strcmp (name, "visible") == 0 && g_value_get_boolean (value))
1223 priv->builder_visible = TRUE;
1225 parent_buildable_iface->set_buildable_property (buildable, builder, name, value);
1229 gtk_window_buildable_parser_finished (GtkBuildable *buildable,
1230 GtkBuilder *builder)
1232 GtkWindowPrivate *priv = GTK_WINDOW_GET_PRIVATE (buildable);
1236 if (priv->builder_visible)
1237 gtk_widget_show (GTK_WIDGET (buildable));
1239 accels = g_object_get_qdata (G_OBJECT (buildable), quark_gtk_buildable_accels);
1240 for (l = accels; l; l = l->next)
1242 object = gtk_builder_get_object (builder, l->data);
1245 g_warning ("Unknown accel group %s specified in window %s",
1246 (const gchar*)l->data, gtk_buildable_get_name (buildable));
1249 gtk_window_add_accel_group (GTK_WINDOW (buildable),
1250 GTK_ACCEL_GROUP (object));
1254 g_object_set_qdata (G_OBJECT (buildable), quark_gtk_buildable_accels, NULL);
1256 parent_buildable_iface->parser_finished (buildable, builder);
1262 } GSListSubParserData;
1265 window_start_element (GMarkupParseContext *context,
1266 const gchar *element_name,
1267 const gchar **names,
1268 const gchar **values,
1273 GSListSubParserData *data = (GSListSubParserData*)user_data;
1275 if (strcmp (element_name, "group") == 0)
1277 for (i = 0; names[i]; i++)
1279 if (strcmp (names[i], "name") == 0)
1280 data->items = g_slist_prepend (data->items, g_strdup (values[i]));
1283 else if (strcmp (element_name, "accel-groups") == 0)
1286 g_warning ("Unsupported tag type for GtkWindow: %s\n",
1291 static const GMarkupParser window_parser =
1293 window_start_element
1297 gtk_window_buildable_custom_tag_start (GtkBuildable *buildable,
1298 GtkBuilder *builder,
1300 const gchar *tagname,
1301 GMarkupParser *parser,
1304 GSListSubParserData *parser_data;
1306 if (parent_buildable_iface->custom_tag_start (buildable, builder, child,
1307 tagname, parser, data))
1310 if (strcmp (tagname, "accel-groups") == 0)
1312 parser_data = g_slice_new0 (GSListSubParserData);
1313 parser_data->items = NULL;
1314 parser_data->object = G_OBJECT (buildable);
1316 *parser = window_parser;
1317 *data = parser_data;
1325 gtk_window_buildable_custom_finished (GtkBuildable *buildable,
1326 GtkBuilder *builder,
1328 const gchar *tagname,
1331 GSListSubParserData *data;
1333 parent_buildable_iface->custom_finished (buildable, builder, child,
1334 tagname, user_data);
1336 if (strcmp (tagname, "accel-groups") != 0)
1339 data = (GSListSubParserData*)user_data;
1341 g_object_set_qdata_full (G_OBJECT (buildable), quark_gtk_buildable_accels,
1342 data->items, (GDestroyNotify) g_slist_free);
1344 g_slice_free (GSListSubParserData, data);
1349 * @type: type of window
1351 * Creates a new #GtkWindow, which is a toplevel window that can
1352 * contain other widgets. Nearly always, the type of the window should
1353 * be #GTK_WINDOW_TOPLEVEL. If you're implementing something like a
1354 * popup menu from scratch (which is a bad idea, just use #GtkMenu),
1355 * you might use #GTK_WINDOW_POPUP. #GTK_WINDOW_POPUP is not for
1356 * dialogs, though in some other toolkits dialogs are called "popups".
1357 * In GTK+, #GTK_WINDOW_POPUP means a pop-up menu or pop-up tooltip.
1358 * On X11, popup windows are not controlled by the <link
1359 * linkend="gtk-X11-arch">window manager</link>.
1361 * If you simply want an undecorated window (no window borders), use
1362 * gtk_window_set_decorated(), don't use #GTK_WINDOW_POPUP.
1364 * Return value: a new #GtkWindow.
1367 gtk_window_new (GtkWindowType type)
1371 g_return_val_if_fail (type >= GTK_WINDOW_TOPLEVEL && type <= GTK_WINDOW_POPUP, NULL);
1373 window = g_object_new (GTK_TYPE_WINDOW, NULL);
1375 window->type = type;
1377 return GTK_WIDGET (window);
1381 * gtk_window_set_title:
1382 * @window: a #GtkWindow
1383 * @title: title of the window
1385 * Sets the title of the #GtkWindow. The title of a window will be
1386 * displayed in its title bar; on the X Window System, the title bar
1387 * is rendered by the <link linkend="gtk-X11-arch">window
1388 * manager</link>, so exactly how the title appears to users may vary
1389 * according to a user's exact configuration. The title should help a
1390 * user distinguish this window from other windows they may have
1391 * open. A good title might include the application name and current
1392 * document filename, for example.
1396 gtk_window_set_title (GtkWindow *window,
1401 g_return_if_fail (GTK_IS_WINDOW (window));
1403 new_title = g_strdup (title);
1404 g_free (window->title);
1405 window->title = new_title;
1407 if (gtk_widget_get_realized (GTK_WIDGET (window)))
1409 gdk_window_set_title (GTK_WIDGET (window)->window, window->title);
1411 gtk_decorated_window_set_title (window, title);
1414 g_object_notify (G_OBJECT (window), "title");
1418 * gtk_window_get_title:
1419 * @window: a #GtkWindow
1421 * Retrieves the title of the window. See gtk_window_set_title().
1423 * Return value: the title of the window, or %NULL if none has
1424 * been set explicitely. The returned string is owned by the widget
1425 * and must not be modified or freed.
1427 G_CONST_RETURN gchar *
1428 gtk_window_get_title (GtkWindow *window)
1430 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
1432 return window->title;
1436 * gtk_window_set_wmclass:
1437 * @window: a #GtkWindow
1438 * @wmclass_name: window name hint
1439 * @wmclass_class: window class hint
1441 * Don't use this function. It sets the X Window System "class" and
1442 * "name" hints for a window. According to the ICCCM, you should
1443 * always set these to the same value for all windows in an
1444 * application, and GTK+ sets them to that value by default, so calling
1445 * this function is sort of pointless. However, you may want to call
1446 * gtk_window_set_role() on each window in your application, for the
1447 * benefit of the session manager. Setting the role allows the window
1448 * manager to restore window positions when loading a saved session.
1452 gtk_window_set_wmclass (GtkWindow *window,
1453 const gchar *wmclass_name,
1454 const gchar *wmclass_class)
1456 g_return_if_fail (GTK_IS_WINDOW (window));
1458 g_free (window->wmclass_name);
1459 window->wmclass_name = g_strdup (wmclass_name);
1461 g_free (window->wmclass_class);
1462 window->wmclass_class = g_strdup (wmclass_class);
1464 if (gtk_widget_get_realized (GTK_WIDGET (window)))
1465 g_warning ("gtk_window_set_wmclass: shouldn't set wmclass after window is realized!\n");
1469 * gtk_window_set_role:
1470 * @window: a #GtkWindow
1471 * @role: unique identifier for the window to be used when restoring a session
1473 * This function is only useful on X11, not with other GTK+ targets.
1475 * In combination with the window title, the window role allows a
1476 * <link linkend="gtk-X11-arch">window manager</link> to identify "the
1477 * same" window when an application is restarted. So for example you
1478 * might set the "toolbox" role on your app's toolbox window, so that
1479 * when the user restarts their session, the window manager can put
1480 * the toolbox back in the same place.
1482 * If a window already has a unique title, you don't need to set the
1483 * role, since the WM can use the title to identify the window when
1484 * restoring the session.
1488 gtk_window_set_role (GtkWindow *window,
1493 g_return_if_fail (GTK_IS_WINDOW (window));
1495 new_role = g_strdup (role);
1496 g_free (window->wm_role);
1497 window->wm_role = new_role;
1499 if (gtk_widget_get_realized (GTK_WIDGET (window)))
1500 gdk_window_set_role (GTK_WIDGET (window)->window, window->wm_role);
1502 g_object_notify (G_OBJECT (window), "role");
1506 * gtk_window_set_startup_id:
1507 * @window: a #GtkWindow
1508 * @startup_id: a string with startup-notification identifier
1510 * Startup notification identifiers are used by desktop environment to
1511 * track application startup, to provide user feedback and other
1512 * features. This function changes the corresponding property on the
1513 * underlying GdkWindow. Normally, startup identifier is managed
1514 * automatically and you should only use this function in special cases
1515 * like transferring focus from other processes. You should use this
1516 * function before calling gtk_window_present() or any equivalent
1517 * function generating a window map event.
1519 * This function is only useful on X11, not with other GTK+ targets.
1524 gtk_window_set_startup_id (GtkWindow *window,
1525 const gchar *startup_id)
1527 GtkWindowPrivate *priv;
1529 g_return_if_fail (GTK_IS_WINDOW (window));
1531 priv = GTK_WINDOW_GET_PRIVATE (window);
1533 g_free (priv->startup_id);
1534 priv->startup_id = g_strdup (startup_id);
1536 if (gtk_widget_get_realized (GTK_WIDGET (window)))
1538 guint32 timestamp = extract_time_from_startup_id (priv->startup_id);
1540 #ifdef GDK_WINDOWING_X11
1541 if (timestamp != GDK_CURRENT_TIME)
1542 gdk_x11_window_set_user_time (GTK_WIDGET (window)->window, timestamp);
1545 /* Here we differentiate real and "fake" startup notification IDs,
1546 * constructed on purpose just to pass interaction timestamp
1548 if (startup_id_is_fake (priv->startup_id))
1549 gtk_window_present_with_time (window, timestamp);
1552 gdk_window_set_startup_id (GTK_WIDGET (window)->window,
1555 /* If window is mapped, terminate the startup-notification too */
1556 if (gtk_widget_get_mapped (GTK_WIDGET (window)) &&
1557 !disable_startup_notification)
1558 gdk_notify_startup_complete_with_id (priv->startup_id);
1562 g_object_notify (G_OBJECT (window), "startup-id");
1566 * gtk_window_get_role:
1567 * @window: a #GtkWindow
1569 * Returns the role of the window. See gtk_window_set_role() for
1570 * further explanation.
1572 * Return value: the role of the window if set, or %NULL. The
1573 * returned is owned by the widget and must not be modified
1576 G_CONST_RETURN gchar *
1577 gtk_window_get_role (GtkWindow *window)
1579 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
1581 return window->wm_role;
1585 * gtk_window_set_focus:
1586 * @window: a #GtkWindow
1587 * @focus: (allow-none): widget to be the new focus widget, or %NULL to unset
1588 * any focus widget for the toplevel window.
1590 * If @focus is not the current focus widget, and is focusable, sets
1591 * it as the focus widget for the window. If @focus is %NULL, unsets
1592 * the focus widget for this window. To set the focus to a particular
1593 * widget in the toplevel, it is usually more convenient to use
1594 * gtk_widget_grab_focus() instead of this function.
1597 gtk_window_set_focus (GtkWindow *window,
1600 g_return_if_fail (GTK_IS_WINDOW (window));
1603 g_return_if_fail (GTK_IS_WIDGET (focus));
1604 g_return_if_fail (gtk_widget_get_can_focus (focus));
1608 gtk_widget_grab_focus (focus);
1611 /* Clear the existing focus chain, so that when we focus into
1612 * the window again, we start at the beginnning.
1614 GtkWidget *widget = window->focus_widget;
1617 while (widget->parent)
1619 widget = widget->parent;
1620 gtk_container_set_focus_child (GTK_CONTAINER (widget), NULL);
1624 _gtk_window_internal_set_focus (window, NULL);
1629 _gtk_window_internal_set_focus (GtkWindow *window,
1632 g_return_if_fail (GTK_IS_WINDOW (window));
1634 if ((window->focus_widget != focus) ||
1635 (focus && !gtk_widget_has_focus (focus)))
1636 g_signal_emit (window, window_signals[SET_FOCUS], 0, focus);
1640 * gtk_window_set_default:
1641 * @window: a #GtkWindow
1642 * @default_widget: (allow-none): widget to be the default, or %NULL to unset the
1643 * default widget for the toplevel.
1645 * The default widget is the widget that's activated when the user
1646 * presses Enter in a dialog (for example). This function sets or
1647 * unsets the default widget for a #GtkWindow about. When setting
1648 * (rather than unsetting) the default widget it's generally easier to
1649 * call gtk_widget_grab_focus() on the widget. Before making a widget
1650 * the default widget, you must set the #GTK_CAN_DEFAULT flag on the
1651 * widget you'd like to make the default using GTK_WIDGET_SET_FLAGS().
1654 gtk_window_set_default (GtkWindow *window,
1655 GtkWidget *default_widget)
1657 g_return_if_fail (GTK_IS_WINDOW (window));
1660 g_return_if_fail (gtk_widget_get_can_default (default_widget));
1662 if (window->default_widget != default_widget)
1664 GtkWidget *old_default_widget = NULL;
1667 g_object_ref (default_widget);
1669 if (window->default_widget)
1671 old_default_widget = window->default_widget;
1673 if (window->focus_widget != window->default_widget ||
1674 !gtk_widget_get_receives_default (window->default_widget))
1675 _gtk_widget_set_has_default (window->default_widget, FALSE);
1676 gtk_widget_queue_draw (window->default_widget);
1679 window->default_widget = default_widget;
1681 if (window->default_widget)
1683 if (window->focus_widget == NULL ||
1684 !gtk_widget_get_receives_default (window->focus_widget))
1685 _gtk_widget_set_has_default (window->default_widget, TRUE);
1686 gtk_widget_queue_draw (window->default_widget);
1689 if (old_default_widget)
1690 g_object_notify (G_OBJECT (old_default_widget), "has-default");
1694 g_object_notify (G_OBJECT (default_widget), "has-default");
1695 g_object_unref (default_widget);
1701 * gtk_window_get_default_widget:
1702 * @window: a #GtkWindow
1704 * Returns the default widget for @window. See gtk_window_set_default()
1707 * Returns: the default widget, or %NULL if there is none.
1712 gtk_window_get_default_widget (GtkWindow *window)
1714 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
1716 return window->default_widget;
1720 gtk_window_set_policy_internal (GtkWindow *window,
1721 gboolean allow_shrink,
1722 gboolean allow_grow,
1723 gboolean auto_shrink)
1725 window->allow_shrink = (allow_shrink != FALSE);
1726 window->allow_grow = (allow_grow != FALSE);
1728 g_object_freeze_notify (G_OBJECT (window));
1729 g_object_notify (G_OBJECT (window), "allow-shrink");
1730 g_object_notify (G_OBJECT (window), "allow-grow");
1731 g_object_notify (G_OBJECT (window), "resizable");
1732 g_object_thaw_notify (G_OBJECT (window));
1734 gtk_widget_queue_resize_no_redraw (GTK_WIDGET (window));
1738 gtk_window_set_policy (GtkWindow *window,
1739 gboolean allow_shrink,
1740 gboolean allow_grow,
1741 gboolean auto_shrink)
1743 g_return_if_fail (GTK_IS_WINDOW (window));
1745 gtk_window_set_policy_internal (window, allow_shrink, allow_grow, auto_shrink);
1749 handle_keys_changed (gpointer data)
1753 window = GTK_WINDOW (data);
1755 if (window->keys_changed_handler)
1757 g_source_remove (window->keys_changed_handler);
1758 window->keys_changed_handler = 0;
1761 g_signal_emit (window, window_signals[KEYS_CHANGED], 0);
1767 gtk_window_notify_keys_changed (GtkWindow *window)
1769 if (!window->keys_changed_handler)
1770 window->keys_changed_handler = gdk_threads_add_idle (handle_keys_changed, window);
1774 * gtk_window_add_accel_group:
1775 * @window: window to attach accelerator group to
1776 * @accel_group: a #GtkAccelGroup
1778 * Associate @accel_group with @window, such that calling
1779 * gtk_accel_groups_activate() on @window will activate accelerators
1783 gtk_window_add_accel_group (GtkWindow *window,
1784 GtkAccelGroup *accel_group)
1786 g_return_if_fail (GTK_IS_WINDOW (window));
1787 g_return_if_fail (GTK_IS_ACCEL_GROUP (accel_group));
1789 _gtk_accel_group_attach (accel_group, G_OBJECT (window));
1790 g_signal_connect_object (accel_group, "accel-changed",
1791 G_CALLBACK (gtk_window_notify_keys_changed),
1792 window, G_CONNECT_SWAPPED);
1793 gtk_window_notify_keys_changed (window);
1797 * gtk_window_remove_accel_group:
1798 * @window: a #GtkWindow
1799 * @accel_group: a #GtkAccelGroup
1801 * Reverses the effects of gtk_window_add_accel_group().
1804 gtk_window_remove_accel_group (GtkWindow *window,
1805 GtkAccelGroup *accel_group)
1807 g_return_if_fail (GTK_IS_WINDOW (window));
1808 g_return_if_fail (GTK_IS_ACCEL_GROUP (accel_group));
1810 g_signal_handlers_disconnect_by_func (accel_group,
1811 gtk_window_notify_keys_changed,
1813 _gtk_accel_group_detach (accel_group, G_OBJECT (window));
1814 gtk_window_notify_keys_changed (window);
1817 static GtkMnemonicHash *
1818 gtk_window_get_mnemonic_hash (GtkWindow *window,
1821 GtkWindowPrivate *private = GTK_WINDOW_GET_PRIVATE (window);
1822 if (!private->mnemonic_hash && create)
1823 private->mnemonic_hash = _gtk_mnemonic_hash_new ();
1825 return private->mnemonic_hash;
1829 * gtk_window_add_mnemonic:
1830 * @window: a #GtkWindow
1831 * @keyval: the mnemonic
1832 * @target: the widget that gets activated by the mnemonic
1834 * Adds a mnemonic to this window.
1837 gtk_window_add_mnemonic (GtkWindow *window,
1841 g_return_if_fail (GTK_IS_WINDOW (window));
1842 g_return_if_fail (GTK_IS_WIDGET (target));
1844 _gtk_mnemonic_hash_add (gtk_window_get_mnemonic_hash (window, TRUE),
1846 gtk_window_notify_keys_changed (window);
1850 * gtk_window_remove_mnemonic:
1851 * @window: a #GtkWindow
1852 * @keyval: the mnemonic
1853 * @target: the widget that gets activated by the mnemonic
1855 * Removes a mnemonic from this window.
1858 gtk_window_remove_mnemonic (GtkWindow *window,
1862 g_return_if_fail (GTK_IS_WINDOW (window));
1863 g_return_if_fail (GTK_IS_WIDGET (target));
1865 _gtk_mnemonic_hash_remove (gtk_window_get_mnemonic_hash (window, TRUE),
1867 gtk_window_notify_keys_changed (window);
1871 * gtk_window_mnemonic_activate:
1872 * @window: a #GtkWindow
1873 * @keyval: the mnemonic
1874 * @modifier: the modifiers
1875 * @returns: %TRUE if the activation is done.
1877 * Activates the targets associated with the mnemonic.
1880 gtk_window_mnemonic_activate (GtkWindow *window,
1882 GdkModifierType modifier)
1884 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
1886 if (window->mnemonic_modifier == (modifier & gtk_accelerator_get_default_mod_mask ()))
1888 GtkMnemonicHash *mnemonic_hash = gtk_window_get_mnemonic_hash (window, FALSE);
1890 return _gtk_mnemonic_hash_activate (mnemonic_hash, keyval);
1897 * gtk_window_set_mnemonic_modifier:
1898 * @window: a #GtkWindow
1899 * @modifier: the modifier mask used to activate
1900 * mnemonics on this window.
1902 * Sets the mnemonic modifier for this window.
1905 gtk_window_set_mnemonic_modifier (GtkWindow *window,
1906 GdkModifierType modifier)
1908 g_return_if_fail (GTK_IS_WINDOW (window));
1909 g_return_if_fail ((modifier & ~GDK_MODIFIER_MASK) == 0);
1911 window->mnemonic_modifier = modifier;
1912 gtk_window_notify_keys_changed (window);
1916 * gtk_window_get_mnemonic_modifier:
1917 * @window: a #GtkWindow
1919 * Returns the mnemonic modifier for this window. See
1920 * gtk_window_set_mnemonic_modifier().
1922 * Return value: the modifier mask used to activate
1923 * mnemonics on this window.
1926 gtk_window_get_mnemonic_modifier (GtkWindow *window)
1928 g_return_val_if_fail (GTK_IS_WINDOW (window), 0);
1930 return window->mnemonic_modifier;
1934 * gtk_window_set_position:
1935 * @window: a #GtkWindow.
1936 * @position: a position constraint.
1938 * Sets a position constraint for this window. If the old or new
1939 * constraint is %GTK_WIN_POS_CENTER_ALWAYS, this will also cause
1940 * the window to be repositioned to satisfy the new constraint.
1943 gtk_window_set_position (GtkWindow *window,
1944 GtkWindowPosition position)
1946 g_return_if_fail (GTK_IS_WINDOW (window));
1948 if (position == GTK_WIN_POS_CENTER_ALWAYS ||
1949 window->position == GTK_WIN_POS_CENTER_ALWAYS)
1951 GtkWindowGeometryInfo *info;
1953 info = gtk_window_get_geometry_info (window, TRUE);
1955 /* this flag causes us to re-request the CENTER_ALWAYS
1956 * constraint in gtk_window_move_resize(), see
1957 * comment in that function.
1959 info->position_constraints_changed = TRUE;
1961 gtk_widget_queue_resize_no_redraw (GTK_WIDGET (window));
1964 window->position = position;
1966 g_object_notify (G_OBJECT (window), "window-position");
1970 * gtk_window_activate_focus:
1971 * @window: a #GtkWindow
1973 * Activates the current focused widget within the window.
1975 * Return value: %TRUE if a widget got activated.
1978 gtk_window_activate_focus (GtkWindow *window)
1980 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
1982 if (window->focus_widget && gtk_widget_is_sensitive (window->focus_widget))
1983 return gtk_widget_activate (window->focus_widget);
1989 * gtk_window_get_focus:
1990 * @window: a #GtkWindow
1992 * Retrieves the current focused widget within the window.
1993 * Note that this is the widget that would have the focus
1994 * if the toplevel window focused; if the toplevel window
1995 * is not focused then <literal>gtk_widget_has_focus (widget)</literal> will
1996 * not be %TRUE for the widget.
1998 * Return value: (transfer none): the currently focused widget, or %NULL if there is none.
2001 gtk_window_get_focus (GtkWindow *window)
2003 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
2005 return window->focus_widget;
2009 * gtk_window_activate_default:
2010 * @window: a #GtkWindow
2012 * Activates the default widget for the window, unless the current
2013 * focused widget has been configured to receive the default action
2014 * (see gtk_widget_set_receives_default()), in which case the
2015 * focused widget is activated.
2017 * Return value: %TRUE if a widget got activated.
2020 gtk_window_activate_default (GtkWindow *window)
2022 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
2024 if (window->default_widget && gtk_widget_is_sensitive (window->default_widget) &&
2025 (!window->focus_widget || !gtk_widget_get_receives_default (window->focus_widget)))
2026 return gtk_widget_activate (window->default_widget);
2027 else if (window->focus_widget && gtk_widget_is_sensitive (window->focus_widget))
2028 return gtk_widget_activate (window->focus_widget);
2034 * gtk_window_set_modal:
2035 * @window: a #GtkWindow
2036 * @modal: whether the window is modal
2038 * Sets a window modal or non-modal. Modal windows prevent interaction
2039 * with other windows in the same application. To keep modal dialogs
2040 * on top of main application windows, use
2041 * gtk_window_set_transient_for() to make the dialog transient for the
2042 * parent; most <link linkend="gtk-X11-arch">window managers</link>
2043 * will then disallow lowering the dialog below the parent.
2048 gtk_window_set_modal (GtkWindow *window,
2053 g_return_if_fail (GTK_IS_WINDOW (window));
2055 modal = modal != FALSE;
2056 if (window->modal == modal)
2059 window->modal = modal;
2060 widget = GTK_WIDGET (window);
2062 /* adjust desired modality state */
2063 if (gtk_widget_get_realized (widget))
2066 gdk_window_set_modal_hint (widget->window, TRUE);
2068 gdk_window_set_modal_hint (widget->window, FALSE);
2071 if (gtk_widget_get_visible (widget))
2074 gtk_grab_add (widget);
2076 gtk_grab_remove (widget);
2079 g_object_notify (G_OBJECT (window), "modal");
2083 * gtk_window_get_modal:
2084 * @window: a #GtkWindow
2086 * Returns whether the window is modal. See gtk_window_set_modal().
2088 * Return value: %TRUE if the window is set to be modal and
2089 * establishes a grab when shown
2092 gtk_window_get_modal (GtkWindow *window)
2094 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
2096 return window->modal;
2100 * gtk_window_list_toplevels:
2102 * Returns a list of all existing toplevel windows. The widgets
2103 * in the list are not individually referenced. If you want
2104 * to iterate through the list and perform actions involving
2105 * callbacks that might destroy the widgets, you <emphasis>must</emphasis> call
2106 * <literal>g_list_foreach (result, (GFunc)g_object_ref, NULL)</literal> first, and
2107 * then unref all the widgets afterwards.
2109 * Return value: (element-type GtkWidget) (transfer container): list of toplevel widgets
2112 gtk_window_list_toplevels (void)
2117 for (slist = toplevel_list; slist; slist = slist->next)
2118 list = g_list_prepend (list, slist->data);
2124 gtk_window_add_embedded_xid (GtkWindow *window, GdkNativeWindow xid)
2126 GList *embedded_windows;
2128 g_return_if_fail (GTK_IS_WINDOW (window));
2130 embedded_windows = g_object_get_qdata (G_OBJECT (window), quark_gtk_embedded);
2131 if (embedded_windows)
2132 g_object_steal_qdata (G_OBJECT (window), quark_gtk_embedded);
2133 embedded_windows = g_list_prepend (embedded_windows,
2134 GUINT_TO_POINTER (xid));
2136 g_object_set_qdata_full (G_OBJECT (window), quark_gtk_embedded,
2139 (GDestroyNotify) g_list_free : NULL);
2143 gtk_window_remove_embedded_xid (GtkWindow *window, GdkNativeWindow xid)
2145 GList *embedded_windows;
2148 g_return_if_fail (GTK_IS_WINDOW (window));
2150 embedded_windows = g_object_get_qdata (G_OBJECT (window), quark_gtk_embedded);
2151 if (embedded_windows)
2152 g_object_steal_qdata (G_OBJECT (window), quark_gtk_embedded);
2154 node = g_list_find (embedded_windows, GUINT_TO_POINTER (xid));
2157 embedded_windows = g_list_remove_link (embedded_windows, node);
2158 g_list_free_1 (node);
2161 g_object_set_qdata_full (G_OBJECT (window), quark_gtk_embedded,
2164 (GDestroyNotify) g_list_free : NULL);
2168 _gtk_window_reposition (GtkWindow *window,
2172 g_return_if_fail (GTK_IS_WINDOW (window));
2174 gtk_window_move (window, x, y);
2178 gtk_window_dispose (GObject *object)
2180 GtkWindow *window = GTK_WINDOW (object);
2182 gtk_window_set_focus (window, NULL);
2183 gtk_window_set_default (window, NULL);
2185 G_OBJECT_CLASS (gtk_window_parent_class)->dispose (object);
2189 parent_destroyed_callback (GtkWindow *parent, GtkWindow *child)
2191 gtk_widget_destroy (GTK_WIDGET (child));
2195 connect_parent_destroyed (GtkWindow *window)
2197 if (window->transient_parent)
2199 g_signal_connect (window->transient_parent,
2201 G_CALLBACK (parent_destroyed_callback),
2207 disconnect_parent_destroyed (GtkWindow *window)
2209 if (window->transient_parent)
2211 g_signal_handlers_disconnect_by_func (window->transient_parent,
2212 parent_destroyed_callback,
2218 gtk_window_transient_parent_realized (GtkWidget *parent,
2221 if (gtk_widget_get_realized (GTK_WIDGET (window)))
2222 gdk_window_set_transient_for (window->window, parent->window);
2226 gtk_window_transient_parent_unrealized (GtkWidget *parent,
2229 if (gtk_widget_get_realized (GTK_WIDGET (window)))
2230 gdk_property_delete (window->window,
2231 gdk_atom_intern_static_string ("WM_TRANSIENT_FOR"));
2235 gtk_window_transient_parent_screen_changed (GtkWindow *parent,
2239 gtk_window_set_screen (window, parent->screen);
2243 gtk_window_unset_transient_for (GtkWindow *window)
2245 GtkWindowPrivate *priv = GTK_WINDOW_GET_PRIVATE (window);
2247 if (window->transient_parent)
2249 g_signal_handlers_disconnect_by_func (window->transient_parent,
2250 gtk_window_transient_parent_realized,
2252 g_signal_handlers_disconnect_by_func (window->transient_parent,
2253 gtk_window_transient_parent_unrealized,
2255 g_signal_handlers_disconnect_by_func (window->transient_parent,
2256 gtk_window_transient_parent_screen_changed,
2258 g_signal_handlers_disconnect_by_func (window->transient_parent,
2259 gtk_widget_destroyed,
2260 &window->transient_parent);
2262 if (window->destroy_with_parent)
2263 disconnect_parent_destroyed (window);
2265 window->transient_parent = NULL;
2267 if (priv->transient_parent_group)
2269 priv->transient_parent_group = FALSE;
2270 gtk_window_group_remove_window (window->group,
2277 * gtk_window_set_transient_for:
2278 * @window: a #GtkWindow
2279 * @parent: (allow-none): parent window, or %NULL
2281 * Dialog windows should be set transient for the main application
2282 * window they were spawned from. This allows <link
2283 * linkend="gtk-X11-arch">window managers</link> to e.g. keep the
2284 * dialog on top of the main window, or center the dialog over the
2285 * main window. gtk_dialog_new_with_buttons() and other convenience
2286 * functions in GTK+ will sometimes call
2287 * gtk_window_set_transient_for() on your behalf.
2289 * Passing %NULL for @parent unsets the current transient window.
2291 * On Windows, this function puts the child window on top of the parent,
2292 * much as the window manager would have done on X.
2295 gtk_window_set_transient_for (GtkWindow *window,
2298 GtkWindowPrivate *priv;
2300 g_return_if_fail (GTK_IS_WINDOW (window));
2301 g_return_if_fail (parent == NULL || GTK_IS_WINDOW (parent));
2302 g_return_if_fail (window != parent);
2304 priv = GTK_WINDOW_GET_PRIVATE (window);
2306 if (window->transient_parent)
2308 if (gtk_widget_get_realized (GTK_WIDGET (window)) &&
2309 gtk_widget_get_realized (GTK_WIDGET (window->transient_parent)) &&
2310 (!parent || !gtk_widget_get_realized (GTK_WIDGET (parent))))
2311 gtk_window_transient_parent_unrealized (GTK_WIDGET (window->transient_parent),
2312 GTK_WIDGET (window));
2314 gtk_window_unset_transient_for (window);
2317 window->transient_parent = parent;
2321 g_signal_connect (parent, "destroy",
2322 G_CALLBACK (gtk_widget_destroyed),
2323 &window->transient_parent);
2324 g_signal_connect (parent, "realize",
2325 G_CALLBACK (gtk_window_transient_parent_realized),
2327 g_signal_connect (parent, "unrealize",
2328 G_CALLBACK (gtk_window_transient_parent_unrealized),
2330 g_signal_connect (parent, "notify::screen",
2331 G_CALLBACK (gtk_window_transient_parent_screen_changed),
2334 gtk_window_set_screen (window, parent->screen);
2336 if (window->destroy_with_parent)
2337 connect_parent_destroyed (window);
2339 if (gtk_widget_get_realized (GTK_WIDGET (window)) &&
2340 gtk_widget_get_realized (GTK_WIDGET (parent)))
2341 gtk_window_transient_parent_realized (GTK_WIDGET (parent),
2342 GTK_WIDGET (window));
2346 gtk_window_group_add_window (parent->group, window);
2347 priv->transient_parent_group = TRUE;
2353 * gtk_window_get_transient_for:
2354 * @window: a #GtkWindow
2356 * Fetches the transient parent for this window. See
2357 * gtk_window_set_transient_for().
2359 * Return value: (transfer none): the transient parent for this window, or %NULL
2360 * if no transient parent has been set.
2363 gtk_window_get_transient_for (GtkWindow *window)
2365 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
2367 return window->transient_parent;
2371 * gtk_window_set_opacity:
2372 * @window: a #GtkWindow
2373 * @opacity: desired opacity, between 0 and 1
2375 * Request the windowing system to make @window partially transparent,
2376 * with opacity 0 being fully transparent and 1 fully opaque. (Values
2377 * of the opacity parameter are clamped to the [0,1] range.) On X11
2378 * this has any effect only on X screens with a compositing manager
2379 * running. See gtk_widget_is_composited(). On Windows it should work
2382 * Note that setting a window's opacity after the window has been
2383 * shown causes it to flicker once on Windows.
2388 gtk_window_set_opacity (GtkWindow *window,
2391 GtkWindowPrivate *priv;
2393 g_return_if_fail (GTK_IS_WINDOW (window));
2395 priv = GTK_WINDOW_GET_PRIVATE (window);
2399 else if (opacity > 1.0)
2402 priv->opacity_set = TRUE;
2403 priv->opacity = opacity;
2405 if (gtk_widget_get_realized (GTK_WIDGET (window)))
2406 gdk_window_set_opacity (GTK_WIDGET (window)->window, priv->opacity);
2410 * gtk_window_get_opacity:
2411 * @window: a #GtkWindow
2413 * Fetches the requested opacity for this window. See
2414 * gtk_window_set_opacity().
2416 * Return value: the requested opacity for this window.
2421 gtk_window_get_opacity (GtkWindow *window)
2423 GtkWindowPrivate *priv;
2425 g_return_val_if_fail (GTK_IS_WINDOW (window), 0.0);
2427 priv = GTK_WINDOW_GET_PRIVATE (window);
2429 return priv->opacity;
2433 * gtk_window_set_type_hint:
2434 * @window: a #GtkWindow
2435 * @hint: the window type
2437 * By setting the type hint for the window, you allow the window
2438 * manager to decorate and handle the window in a way which is
2439 * suitable to the function of the window in your application.
2441 * This function should be called before the window becomes visible.
2443 * gtk_dialog_new_with_buttons() and other convenience functions in GTK+
2444 * will sometimes call gtk_window_set_type_hint() on your behalf.
2448 gtk_window_set_type_hint (GtkWindow *window,
2449 GdkWindowTypeHint hint)
2451 GtkWindowPrivate *priv;
2453 g_return_if_fail (GTK_IS_WINDOW (window));
2454 g_return_if_fail (!gtk_widget_get_mapped (GTK_WIDGET (window)));
2456 priv = GTK_WINDOW_GET_PRIVATE (window);
2458 if (hint < GDK_WINDOW_TYPE_HINT_DROPDOWN_MENU)
2459 window->type_hint = hint;
2461 window->type_hint = GDK_WINDOW_TYPE_HINT_NORMAL;
2463 priv->reset_type_hint = TRUE;
2464 priv->type_hint = hint;
2468 * gtk_window_get_type_hint:
2469 * @window: a #GtkWindow
2471 * Gets the type hint for this window. See gtk_window_set_type_hint().
2473 * Return value: the type hint for @window.
2476 gtk_window_get_type_hint (GtkWindow *window)
2478 GtkWindowPrivate *priv;
2480 g_return_val_if_fail (GTK_IS_WINDOW (window), GDK_WINDOW_TYPE_HINT_NORMAL);
2482 priv = GTK_WINDOW_GET_PRIVATE (window);
2484 return priv->type_hint;
2488 * gtk_window_set_skip_taskbar_hint:
2489 * @window: a #GtkWindow
2490 * @setting: %TRUE to keep this window from appearing in the task bar
2492 * Windows may set a hint asking the desktop environment not to display
2493 * the window in the task bar. This function sets this hint.
2498 gtk_window_set_skip_taskbar_hint (GtkWindow *window,
2501 GtkWindowPrivate *priv;
2503 g_return_if_fail (GTK_IS_WINDOW (window));
2505 priv = GTK_WINDOW_GET_PRIVATE (window);
2507 setting = setting != FALSE;
2509 if (priv->skips_taskbar != setting)
2511 priv->skips_taskbar = setting;
2512 if (gtk_widget_get_realized (GTK_WIDGET (window)))
2513 gdk_window_set_skip_taskbar_hint (GTK_WIDGET (window)->window,
2514 priv->skips_taskbar);
2515 g_object_notify (G_OBJECT (window), "skip-taskbar-hint");
2520 * gtk_window_get_skip_taskbar_hint:
2521 * @window: a #GtkWindow
2523 * Gets the value set by gtk_window_set_skip_taskbar_hint()
2525 * Return value: %TRUE if window shouldn't be in taskbar
2530 gtk_window_get_skip_taskbar_hint (GtkWindow *window)
2532 GtkWindowPrivate *priv;
2534 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
2536 priv = GTK_WINDOW_GET_PRIVATE (window);
2538 return priv->skips_taskbar;
2542 * gtk_window_set_skip_pager_hint:
2543 * @window: a #GtkWindow
2544 * @setting: %TRUE to keep this window from appearing in the pager
2546 * Windows may set a hint asking the desktop environment not to display
2547 * the window in the pager. This function sets this hint.
2548 * (A "pager" is any desktop navigation tool such as a workspace
2549 * switcher that displays a thumbnail representation of the windows
2555 gtk_window_set_skip_pager_hint (GtkWindow *window,
2558 GtkWindowPrivate *priv;
2560 g_return_if_fail (GTK_IS_WINDOW (window));
2562 priv = GTK_WINDOW_GET_PRIVATE (window);
2564 setting = setting != FALSE;
2566 if (priv->skips_pager != setting)
2568 priv->skips_pager = setting;
2569 if (gtk_widget_get_realized (GTK_WIDGET (window)))
2570 gdk_window_set_skip_pager_hint (GTK_WIDGET (window)->window,
2572 g_object_notify (G_OBJECT (window), "skip-pager-hint");
2577 * gtk_window_get_skip_pager_hint:
2578 * @window: a #GtkWindow
2580 * Gets the value set by gtk_window_set_skip_pager_hint().
2582 * Return value: %TRUE if window shouldn't be in pager
2587 gtk_window_get_skip_pager_hint (GtkWindow *window)
2589 GtkWindowPrivate *priv;
2591 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
2593 priv = GTK_WINDOW_GET_PRIVATE (window);
2595 return priv->skips_pager;
2599 * gtk_window_set_urgency_hint:
2600 * @window: a #GtkWindow
2601 * @setting: %TRUE to mark this window as urgent
2603 * Windows may set a hint asking the desktop environment to draw
2604 * the users attention to the window. This function sets this hint.
2609 gtk_window_set_urgency_hint (GtkWindow *window,
2612 GtkWindowPrivate *priv;
2614 g_return_if_fail (GTK_IS_WINDOW (window));
2616 priv = GTK_WINDOW_GET_PRIVATE (window);
2618 setting = setting != FALSE;
2620 if (priv->urgent != setting)
2622 priv->urgent = setting;
2623 if (gtk_widget_get_realized (GTK_WIDGET (window)))
2624 gdk_window_set_urgency_hint (GTK_WIDGET (window)->window,
2626 g_object_notify (G_OBJECT (window), "urgency-hint");
2631 * gtk_window_get_urgency_hint:
2632 * @window: a #GtkWindow
2634 * Gets the value set by gtk_window_set_urgency_hint()
2636 * Return value: %TRUE if window is urgent
2641 gtk_window_get_urgency_hint (GtkWindow *window)
2643 GtkWindowPrivate *priv;
2645 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
2647 priv = GTK_WINDOW_GET_PRIVATE (window);
2649 return priv->urgent;
2653 * gtk_window_set_accept_focus:
2654 * @window: a #GtkWindow
2655 * @setting: %TRUE to let this window receive input focus
2657 * Windows may set a hint asking the desktop environment not to receive
2658 * the input focus. This function sets this hint.
2663 gtk_window_set_accept_focus (GtkWindow *window,
2666 GtkWindowPrivate *priv;
2668 g_return_if_fail (GTK_IS_WINDOW (window));
2670 priv = GTK_WINDOW_GET_PRIVATE (window);
2672 setting = setting != FALSE;
2674 if (priv->accept_focus != setting)
2676 priv->accept_focus = setting;
2677 if (gtk_widget_get_realized (GTK_WIDGET (window)))
2678 gdk_window_set_accept_focus (GTK_WIDGET (window)->window,
2679 priv->accept_focus);
2680 g_object_notify (G_OBJECT (window), "accept-focus");
2685 * gtk_window_get_accept_focus:
2686 * @window: a #GtkWindow
2688 * Gets the value set by gtk_window_set_accept_focus().
2690 * Return value: %TRUE if window should receive the input focus
2695 gtk_window_get_accept_focus (GtkWindow *window)
2697 GtkWindowPrivate *priv;
2699 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
2701 priv = GTK_WINDOW_GET_PRIVATE (window);
2703 return priv->accept_focus;
2707 * gtk_window_set_focus_on_map:
2708 * @window: a #GtkWindow
2709 * @setting: %TRUE to let this window receive input focus on map
2711 * Windows may set a hint asking the desktop environment not to receive
2712 * the input focus when the window is mapped. This function sets this
2718 gtk_window_set_focus_on_map (GtkWindow *window,
2721 GtkWindowPrivate *priv;
2723 g_return_if_fail (GTK_IS_WINDOW (window));
2725 priv = GTK_WINDOW_GET_PRIVATE (window);
2727 setting = setting != FALSE;
2729 if (priv->focus_on_map != setting)
2731 priv->focus_on_map = setting;
2732 if (gtk_widget_get_realized (GTK_WIDGET (window)))
2733 gdk_window_set_focus_on_map (GTK_WIDGET (window)->window,
2734 priv->focus_on_map);
2735 g_object_notify (G_OBJECT (window), "focus-on-map");
2740 * gtk_window_get_focus_on_map:
2741 * @window: a #GtkWindow
2743 * Gets the value set by gtk_window_set_focus_on_map().
2745 * Return value: %TRUE if window should receive the input focus when
2751 gtk_window_get_focus_on_map (GtkWindow *window)
2753 GtkWindowPrivate *priv;
2755 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
2757 priv = GTK_WINDOW_GET_PRIVATE (window);
2759 return priv->focus_on_map;
2763 * gtk_window_set_destroy_with_parent:
2764 * @window: a #GtkWindow
2765 * @setting: whether to destroy @window with its transient parent
2767 * If @setting is %TRUE, then destroying the transient parent of @window
2768 * will also destroy @window itself. This is useful for dialogs that
2769 * shouldn't persist beyond the lifetime of the main window they're
2770 * associated with, for example.
2773 gtk_window_set_destroy_with_parent (GtkWindow *window,
2776 g_return_if_fail (GTK_IS_WINDOW (window));
2778 if (window->destroy_with_parent == (setting != FALSE))
2781 if (window->destroy_with_parent)
2783 disconnect_parent_destroyed (window);
2787 connect_parent_destroyed (window);
2790 window->destroy_with_parent = setting;
2792 g_object_notify (G_OBJECT (window), "destroy-with-parent");
2796 * gtk_window_get_destroy_with_parent:
2797 * @window: a #GtkWindow
2799 * Returns whether the window will be destroyed with its transient parent. See
2800 * gtk_window_set_destroy_with_parent ().
2802 * Return value: %TRUE if the window will be destroyed with its transient parent.
2805 gtk_window_get_destroy_with_parent (GtkWindow *window)
2807 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
2809 return window->destroy_with_parent;
2812 static GtkWindowGeometryInfo*
2813 gtk_window_get_geometry_info (GtkWindow *window,
2816 GtkWindowGeometryInfo *info;
2818 info = window->geometry_info;
2819 if (!info && create)
2821 info = g_new0 (GtkWindowGeometryInfo, 1);
2823 info->default_width = -1;
2824 info->default_height = -1;
2825 info->resize_width = -1;
2826 info->resize_height = -1;
2827 info->initial_x = 0;
2828 info->initial_y = 0;
2829 info->initial_pos_set = FALSE;
2830 info->default_is_geometry = FALSE;
2831 info->position_constraints_changed = FALSE;
2832 info->last.configure_request.x = 0;
2833 info->last.configure_request.y = 0;
2834 info->last.configure_request.width = -1;
2835 info->last.configure_request.height = -1;
2836 info->widget = NULL;
2838 window->geometry_info = info;
2845 * gtk_window_set_geometry_hints:
2846 * @window: a #GtkWindow
2847 * @geometry_widget: widget the geometry hints will be applied to
2848 * @geometry: struct containing geometry information
2849 * @geom_mask: mask indicating which struct fields should be paid attention to
2851 * This function sets up hints about how a window can be resized by
2852 * the user. You can set a minimum and maximum size; allowed resize
2853 * increments (e.g. for xterm, you can only resize by the size of a
2854 * character); aspect ratios; and more. See the #GdkGeometry struct.
2858 gtk_window_set_geometry_hints (GtkWindow *window,
2859 GtkWidget *geometry_widget,
2860 GdkGeometry *geometry,
2861 GdkWindowHints geom_mask)
2863 GtkWindowGeometryInfo *info;
2865 g_return_if_fail (GTK_IS_WINDOW (window));
2866 g_return_if_fail (geometry_widget == NULL || GTK_IS_WIDGET (geometry_widget));
2868 info = gtk_window_get_geometry_info (window, TRUE);
2871 g_signal_handlers_disconnect_by_func (info->widget,
2872 gtk_widget_destroyed,
2875 info->widget = geometry_widget;
2877 g_signal_connect (geometry_widget, "destroy",
2878 G_CALLBACK (gtk_widget_destroyed),
2882 info->geometry = *geometry;
2884 /* We store gravity in window->gravity not in the hints. */
2885 info->mask = geom_mask & ~(GDK_HINT_WIN_GRAVITY);
2887 if (geom_mask & GDK_HINT_WIN_GRAVITY)
2889 gtk_window_set_gravity (window, geometry->win_gravity);
2892 gtk_widget_queue_resize_no_redraw (GTK_WIDGET (window));
2896 * gtk_window_set_decorated:
2897 * @window: a #GtkWindow
2898 * @setting: %TRUE to decorate the window
2900 * By default, windows are decorated with a title bar, resize
2901 * controls, etc. Some <link linkend="gtk-X11-arch">window
2902 * managers</link> allow GTK+ to disable these decorations, creating a
2903 * borderless window. If you set the decorated property to %FALSE
2904 * using this function, GTK+ will do its best to convince the window
2905 * manager not to decorate the window. Depending on the system, this
2906 * function may not have any effect when called on a window that is
2907 * already visible, so you should call it before calling gtk_window_show().
2909 * On Windows, this function always works, since there's no window manager
2914 gtk_window_set_decorated (GtkWindow *window,
2917 g_return_if_fail (GTK_IS_WINDOW (window));
2919 setting = setting != FALSE;
2921 if (setting == window->decorated)
2924 window->decorated = setting;
2926 if (GTK_WIDGET (window)->window)
2928 if (window->decorated)
2929 gdk_window_set_decorations (GTK_WIDGET (window)->window,
2932 gdk_window_set_decorations (GTK_WIDGET (window)->window,
2936 g_object_notify (G_OBJECT (window), "decorated");
2940 * gtk_window_get_decorated:
2941 * @window: a #GtkWindow
2943 * Returns whether the window has been set to have decorations
2944 * such as a title bar via gtk_window_set_decorated().
2946 * Return value: %TRUE if the window has been set to have decorations
2949 gtk_window_get_decorated (GtkWindow *window)
2951 g_return_val_if_fail (GTK_IS_WINDOW (window), TRUE);
2953 return window->decorated;
2957 * gtk_window_set_deletable:
2958 * @window: a #GtkWindow
2959 * @setting: %TRUE to decorate the window as deletable
2961 * By default, windows have a close button in the window frame. Some
2962 * <link linkend="gtk-X11-arch">window managers</link> allow GTK+ to
2963 * disable this button. If you set the deletable property to %FALSE
2964 * using this function, GTK+ will do its best to convince the window
2965 * manager not to show a close button. Depending on the system, this
2966 * function may not have any effect when called on a window that is
2967 * already visible, so you should call it before calling gtk_window_show().
2969 * On Windows, this function always works, since there's no window manager
2975 gtk_window_set_deletable (GtkWindow *window,
2978 GtkWindowPrivate *priv;
2980 g_return_if_fail (GTK_IS_WINDOW (window));
2982 priv = GTK_WINDOW_GET_PRIVATE (window);
2984 setting = setting != FALSE;
2986 if (setting == priv->deletable)
2989 priv->deletable = setting;
2991 if (GTK_WIDGET (window)->window)
2993 if (priv->deletable)
2994 gdk_window_set_functions (GTK_WIDGET (window)->window,
2997 gdk_window_set_functions (GTK_WIDGET (window)->window,
2998 GDK_FUNC_ALL | GDK_FUNC_CLOSE);
3001 g_object_notify (G_OBJECT (window), "deletable");
3005 * gtk_window_get_deletable:
3006 * @window: a #GtkWindow
3008 * Returns whether the window has been set to have a close button
3009 * via gtk_window_set_deletable().
3011 * Return value: %TRUE if the window has been set to have a close button
3016 gtk_window_get_deletable (GtkWindow *window)
3018 GtkWindowPrivate *priv;
3020 g_return_val_if_fail (GTK_IS_WINDOW (window), TRUE);
3022 priv = GTK_WINDOW_GET_PRIVATE (window);
3024 return priv->deletable;
3027 static GtkWindowIconInfo*
3028 get_icon_info (GtkWindow *window)
3030 return g_object_get_qdata (G_OBJECT (window), quark_gtk_window_icon_info);
3034 free_icon_info (GtkWindowIconInfo *info)
3036 g_free (info->icon_name);
3037 g_slice_free (GtkWindowIconInfo, info);
3041 static GtkWindowIconInfo*
3042 ensure_icon_info (GtkWindow *window)
3044 GtkWindowIconInfo *info;
3046 info = get_icon_info (window);
3050 info = g_slice_new0 (GtkWindowIconInfo);
3051 g_object_set_qdata_full (G_OBJECT (window),
3052 quark_gtk_window_icon_info,
3054 (GDestroyNotify)free_icon_info);
3066 static ScreenIconInfo *
3067 get_screen_icon_info (GdkScreen *screen)
3069 ScreenIconInfo *info = g_object_get_qdata (G_OBJECT (screen),
3070 quark_gtk_window_default_icon_pixmap);
3073 info = g_slice_new0 (ScreenIconInfo);
3074 g_object_set_qdata (G_OBJECT (screen),
3075 quark_gtk_window_default_icon_pixmap, info);
3078 if (info->serial != default_icon_serial)
3082 g_object_remove_weak_pointer (G_OBJECT (info->pixmap), (gpointer*)&info->pixmap);
3083 info->pixmap = NULL;
3088 g_object_remove_weak_pointer (G_OBJECT (info->mask), (gpointer*)&info->mask);
3092 info->serial = default_icon_serial;
3099 get_pixmap_and_mask (GdkWindow *window,
3100 GtkWindowIconInfo *parent_info,
3101 gboolean is_default_list,
3103 GdkPixmap **pmap_return,
3104 GdkBitmap **mask_return)
3106 GdkScreen *screen = gdk_drawable_get_screen (window);
3107 ScreenIconInfo *default_icon_info = get_screen_icon_info (screen);
3108 GdkPixbuf *best_icon;
3112 *pmap_return = NULL;
3113 *mask_return = NULL;
3115 if (is_default_list &&
3116 default_icon_info->pixmap != NULL)
3118 /* Use shared icon pixmap for all windows on this screen.
3120 if (default_icon_info->pixmap)
3121 g_object_ref (default_icon_info->pixmap);
3122 if (default_icon_info->mask)
3123 g_object_ref (default_icon_info->mask);
3125 *pmap_return = default_icon_info->pixmap;
3126 *mask_return = default_icon_info->mask;
3128 else if (parent_info && parent_info->icon_pixmap)
3130 if (parent_info->icon_pixmap)
3131 g_object_ref (parent_info->icon_pixmap);
3132 if (parent_info->icon_mask)
3133 g_object_ref (parent_info->icon_mask);
3135 *pmap_return = parent_info->icon_pixmap;
3136 *mask_return = parent_info->icon_mask;
3140 #define IDEAL_SIZE 48
3142 best_size = G_MAXINT;
3144 tmp_list = icon_list;
3145 while (tmp_list != NULL)
3147 GdkPixbuf *pixbuf = tmp_list->data;
3150 /* average width and height - if someone passes in a rectangular
3151 * icon they deserve what they get.
3153 this = gdk_pixbuf_get_width (pixbuf) + gdk_pixbuf_get_height (pixbuf);
3156 if (best_icon == NULL)
3163 /* icon is better if it's 32 pixels or larger, and closer to
3164 * the ideal size than the current best.
3167 (ABS (best_size - IDEAL_SIZE) <
3168 ABS (this - IDEAL_SIZE)))
3175 tmp_list = tmp_list->next;
3179 gdk_pixbuf_render_pixmap_and_mask_for_colormap (best_icon,
3180 gdk_screen_get_system_colormap (screen),
3185 /* Save pmap/mask for others to use if appropriate */
3188 parent_info->icon_pixmap = *pmap_return;
3189 parent_info->icon_mask = *mask_return;
3191 if (parent_info->icon_pixmap)
3192 g_object_ref (parent_info->icon_pixmap);
3193 if (parent_info->icon_mask)
3194 g_object_ref (parent_info->icon_mask);
3196 else if (is_default_list)
3198 default_icon_info->pixmap = *pmap_return;
3199 default_icon_info->mask = *mask_return;
3201 if (default_icon_info->pixmap)
3202 g_object_add_weak_pointer (G_OBJECT (default_icon_info->pixmap),
3203 (gpointer*)&default_icon_info->pixmap);
3204 if (default_icon_info->mask)
3205 g_object_add_weak_pointer (G_OBJECT (default_icon_info->mask),
3206 (gpointer*)&default_icon_info->mask);
3212 icon_list_from_theme (GtkWidget *widget,
3217 GtkIconTheme *icon_theme;
3222 icon_theme = gtk_icon_theme_get_for_screen (gtk_widget_get_screen (widget));
3224 sizes = gtk_icon_theme_get_icon_sizes (icon_theme, name);
3227 for (i = 0; sizes[i]; i++)
3230 * We need an EWMH extension to handle scalable icons
3231 * by passing their name to the WM. For now just use a
3235 icon = gtk_icon_theme_load_icon (icon_theme, name,
3238 icon = gtk_icon_theme_load_icon (icon_theme, name,
3241 list = g_list_append (list, icon);
3251 gtk_window_realize_icon (GtkWindow *window)
3254 GtkWindowIconInfo *info;
3257 widget = GTK_WIDGET (window);
3259 g_return_if_fail (widget->window != NULL);
3261 /* no point setting an icon on override-redirect */
3262 if (window->type == GTK_WINDOW_POPUP)
3267 info = ensure_icon_info (window);
3272 g_return_if_fail (info->icon_pixmap == NULL);
3273 g_return_if_fail (info->icon_mask == NULL);
3275 info->using_default_icon = FALSE;
3276 info->using_parent_icon = FALSE;
3277 info->using_themed_icon = FALSE;
3279 icon_list = info->icon_list;
3281 /* Look up themed icon */
3282 if (icon_list == NULL && info->icon_name)
3284 icon_list = icon_list_from_theme (widget, info->icon_name);
3286 info->using_themed_icon = TRUE;
3289 /* Inherit from transient parent */
3290 if (icon_list == NULL && window->transient_parent)
3292 icon_list = ensure_icon_info (window->transient_parent)->icon_list;
3294 info->using_parent_icon = TRUE;
3297 /* Inherit from default */
3298 if (icon_list == NULL)
3300 icon_list = default_icon_list;
3302 info->using_default_icon = TRUE;
3305 /* Look up themed icon */
3306 if (icon_list == NULL && default_icon_name)
3308 icon_list = icon_list_from_theme (widget, default_icon_name);
3309 info->using_default_icon = TRUE;
3310 info->using_themed_icon = TRUE;
3313 gdk_window_set_icon_list (widget->window, icon_list);
3315 get_pixmap_and_mask (widget->window,
3316 info->using_parent_icon ? ensure_icon_info (window->transient_parent) : NULL,
3317 info->using_default_icon,
3322 /* This is a slight ICCCM violation since it's a color pixmap not
3323 * a bitmap, but everyone does it.
3325 gdk_window_set_icon (widget->window,
3330 info->realized = TRUE;
3332 if (info->using_themed_icon)
3334 GtkIconTheme *icon_theme;
3336 g_list_foreach (icon_list, (GFunc) g_object_unref, NULL);
3337 g_list_free (icon_list);
3339 icon_theme = gtk_icon_theme_get_for_screen (gtk_widget_get_screen (GTK_WIDGET (window)));
3340 g_signal_connect (icon_theme, "changed",
3341 G_CALLBACK (update_themed_icon), window);
3346 gtk_window_unrealize_icon (GtkWindow *window)
3348 GtkWindowIconInfo *info;
3350 info = get_icon_info (window);
3355 if (info->icon_pixmap)
3356 g_object_unref (info->icon_pixmap);
3358 if (info->icon_mask)
3359 g_object_unref (info->icon_mask);
3361 info->icon_pixmap = NULL;
3362 info->icon_mask = NULL;
3364 if (info->using_themed_icon)
3366 GtkIconTheme *icon_theme;
3368 icon_theme = gtk_icon_theme_get_for_screen (gtk_widget_get_screen (GTK_WIDGET (window)));
3370 g_signal_handlers_disconnect_by_func (icon_theme, update_themed_icon, window);
3373 /* We don't clear the properties on the window, just figure the
3374 * window is going away.
3377 info->realized = FALSE;
3382 * gtk_window_set_icon_list:
3383 * @window: a #GtkWindow
3384 * @list: list of #GdkPixbuf
3386 * Sets up the icon representing a #GtkWindow. The icon is used when
3387 * the window is minimized (also known as iconified). Some window
3388 * managers or desktop environments may also place it in the window
3389 * frame, or display it in other contexts.
3391 * gtk_window_set_icon_list() allows you to pass in the same icon in
3392 * several hand-drawn sizes. The list should contain the natural sizes
3393 * your icon is available in; that is, don't scale the image before
3394 * passing it to GTK+. Scaling is postponed until the last minute,
3395 * when the desired final size is known, to allow best quality.
3397 * By passing several sizes, you may improve the final image quality
3398 * of the icon, by reducing or eliminating automatic image scaling.
3400 * Recommended sizes to provide: 16x16, 32x32, 48x48 at minimum, and
3401 * larger images (64x64, 128x128) if you have them.
3403 * See also gtk_window_set_default_icon_list() to set the icon
3404 * for all windows in your application in one go.
3406 * Note that transient windows (those who have been set transient for another
3407 * window using gtk_window_set_transient_for()) will inherit their
3408 * icon from their transient parent. So there's no need to explicitly
3409 * set the icon on transient windows.
3412 gtk_window_set_icon_list (GtkWindow *window,
3415 GtkWindowIconInfo *info;
3417 g_return_if_fail (GTK_IS_WINDOW (window));
3419 info = ensure_icon_info (window);
3421 if (info->icon_list == list) /* check for NULL mostly */
3424 g_list_foreach (list,
3425 (GFunc) g_object_ref, NULL);
3427 g_list_foreach (info->icon_list,
3428 (GFunc) g_object_unref, NULL);
3430 g_list_free (info->icon_list);
3432 info->icon_list = g_list_copy (list);
3434 g_object_notify (G_OBJECT (window), "icon");
3436 gtk_window_unrealize_icon (window);
3438 if (gtk_widget_get_realized (GTK_WIDGET (window)))
3439 gtk_window_realize_icon (window);
3441 /* We could try to update our transient children, but I don't think
3442 * it's really worth it. If we did it, the best way would probably
3443 * be to have children connect to notify::icon-list
3448 * gtk_window_get_icon_list:
3449 * @window: a #GtkWindow
3451 * Retrieves the list of icons set by gtk_window_set_icon_list().
3452 * The list is copied, but the reference count on each
3453 * member won't be incremented.
3455 * Return value: (element-type GdkPixbuf) (transfer container): copy of window's icon list
3458 gtk_window_get_icon_list (GtkWindow *window)
3460 GtkWindowIconInfo *info;
3462 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
3464 info = get_icon_info (window);
3467 return g_list_copy (info->icon_list);
3473 * gtk_window_set_icon:
3474 * @window: a #GtkWindow
3475 * @icon: (allow-none): icon image, or %NULL
3477 * Sets up the icon representing a #GtkWindow. This icon is used when
3478 * the window is minimized (also known as iconified). Some window
3479 * managers or desktop environments may also place it in the window
3480 * frame, or display it in other contexts.
3482 * The icon should be provided in whatever size it was naturally
3483 * drawn; that is, don't scale the image before passing it to
3484 * GTK+. Scaling is postponed until the last minute, when the desired
3485 * final size is known, to allow best quality.
3487 * If you have your icon hand-drawn in multiple sizes, use
3488 * gtk_window_set_icon_list(). Then the best size will be used.
3490 * This function is equivalent to calling gtk_window_set_icon_list()
3491 * with a 1-element list.
3493 * See also gtk_window_set_default_icon_list() to set the icon
3494 * for all windows in your application in one go.
3497 gtk_window_set_icon (GtkWindow *window,
3502 g_return_if_fail (GTK_IS_WINDOW (window));
3503 g_return_if_fail (icon == NULL || GDK_IS_PIXBUF (icon));
3508 list = g_list_append (list, icon);
3510 gtk_window_set_icon_list (window, list);
3516 update_themed_icon (GtkIconTheme *icon_theme,
3519 g_object_notify (G_OBJECT (window), "icon");
3521 gtk_window_unrealize_icon (window);
3523 if (gtk_widget_get_realized (GTK_WIDGET (window)))
3524 gtk_window_realize_icon (window);
3528 * gtk_window_set_icon_name:
3529 * @window: a #GtkWindow
3530 * @name: (allow-none): the name of the themed icon
3532 * Sets the icon for the window from a named themed icon. See
3533 * the docs for #GtkIconTheme for more details.
3535 * Note that this has nothing to do with the WM_ICON_NAME
3536 * property which is mentioned in the ICCCM.
3541 gtk_window_set_icon_name (GtkWindow *window,
3544 GtkWindowIconInfo *info;
3547 g_return_if_fail (GTK_IS_WINDOW (window));
3549 info = ensure_icon_info (window);
3551 if (g_strcmp0 (info->icon_name, name) == 0)
3554 tmp = info->icon_name;
3555 info->icon_name = g_strdup (name);
3558 g_list_foreach (info->icon_list, (GFunc) g_object_unref, NULL);
3559 g_list_free (info->icon_list);
3560 info->icon_list = NULL;
3562 update_themed_icon (NULL, window);
3564 g_object_notify (G_OBJECT (window), "icon-name");
3568 * gtk_window_get_icon_name:
3569 * @window: a #GtkWindow
3571 * Returns the name of the themed icon for the window,
3572 * see gtk_window_set_icon_name().
3574 * Returns: the icon name or %NULL if the window has
3580 gtk_window_get_icon_name (GtkWindow *window)
3582 GtkWindowIconInfo *info;
3584 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
3586 info = ensure_icon_info (window);
3588 return info->icon_name;
3592 * gtk_window_get_icon:
3593 * @window: a #GtkWindow
3595 * Gets the value set by gtk_window_set_icon() (or if you've
3596 * called gtk_window_set_icon_list(), gets the first icon in
3599 * Return value: (transfer none): icon for window
3602 gtk_window_get_icon (GtkWindow *window)
3604 GtkWindowIconInfo *info;
3606 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
3608 info = get_icon_info (window);
3609 if (info && info->icon_list)
3610 return GDK_PIXBUF (info->icon_list->data);
3615 /* Load pixbuf, printing warning on failure if error == NULL
3618 load_pixbuf_verbosely (const char *filename,
3621 GError *local_err = NULL;
3624 pixbuf = gdk_pixbuf_new_from_file (filename, &local_err);
3632 g_warning ("Error loading icon from file '%s':\n\t%s",
3633 filename, local_err->message);
3634 g_error_free (local_err);
3642 * gtk_window_set_icon_from_file:
3643 * @window: a #GtkWindow
3644 * @filename: location of icon file
3645 * @err: (allow-none): location to store error, or %NULL.
3647 * Sets the icon for @window.
3648 * Warns on failure if @err is %NULL.
3650 * This function is equivalent to calling gtk_window_set_icon()
3651 * with a pixbuf created by loading the image from @filename.
3653 * Returns: %TRUE if setting the icon succeeded.
3658 gtk_window_set_icon_from_file (GtkWindow *window,
3659 const gchar *filename,
3662 GdkPixbuf *pixbuf = load_pixbuf_verbosely (filename, err);
3666 gtk_window_set_icon (window, pixbuf);
3667 g_object_unref (pixbuf);
3676 * gtk_window_set_default_icon_list:
3677 * @list: a list of #GdkPixbuf
3679 * Sets an icon list to be used as fallback for windows that haven't
3680 * had gtk_window_set_icon_list() called on them to set up a
3681 * window-specific icon list. This function allows you to set up the
3682 * icon for all windows in your app at once.
3684 * See gtk_window_set_icon_list() for more details.
3688 gtk_window_set_default_icon_list (GList *list)
3692 if (list == default_icon_list)
3695 /* Update serial so we don't used cached pixmaps/masks
3697 default_icon_serial++;
3699 g_list_foreach (list,
3700 (GFunc) g_object_ref, NULL);
3702 g_list_foreach (default_icon_list,
3703 (GFunc) g_object_unref, NULL);
3705 g_list_free (default_icon_list);
3707 default_icon_list = g_list_copy (list);
3709 /* Update all toplevels */
3710 toplevels = gtk_window_list_toplevels ();
3711 tmp_list = toplevels;
3712 while (tmp_list != NULL)
3714 GtkWindowIconInfo *info;
3715 GtkWindow *w = tmp_list->data;
3717 info = get_icon_info (w);
3718 if (info && info->using_default_icon)
3720 gtk_window_unrealize_icon (w);
3721 if (gtk_widget_get_realized (GTK_WIDGET (w)))
3722 gtk_window_realize_icon (w);
3725 tmp_list = tmp_list->next;
3727 g_list_free (toplevels);
3731 * gtk_window_set_default_icon:
3734 * Sets an icon to be used as fallback for windows that haven't
3735 * had gtk_window_set_icon() called on them from a pixbuf.
3740 gtk_window_set_default_icon (GdkPixbuf *icon)
3744 g_return_if_fail (GDK_IS_PIXBUF (icon));
3746 list = g_list_prepend (NULL, icon);
3747 gtk_window_set_default_icon_list (list);
3752 * gtk_window_set_default_icon_name:
3753 * @name: the name of the themed icon
3755 * Sets an icon to be used as fallback for windows that haven't
3756 * had gtk_window_set_icon_list() called on them from a named
3757 * themed icon, see gtk_window_set_icon_name().
3762 gtk_window_set_default_icon_name (const gchar *name)
3767 /* Update serial so we don't used cached pixmaps/masks
3769 default_icon_serial++;
3771 g_free (default_icon_name);
3772 default_icon_name = g_strdup (name);
3774 g_list_foreach (default_icon_list,
3775 (GFunc) g_object_unref, NULL);
3777 g_list_free (default_icon_list);
3778 default_icon_list = NULL;
3780 /* Update all toplevels */
3781 toplevels = gtk_window_list_toplevels ();
3782 tmp_list = toplevels;
3783 while (tmp_list != NULL)
3785 GtkWindowIconInfo *info;
3786 GtkWindow *w = tmp_list->data;
3788 info = get_icon_info (w);
3789 if (info && info->using_default_icon && info->using_themed_icon)
3791 gtk_window_unrealize_icon (w);
3792 if (gtk_widget_get_realized (GTK_WIDGET (w)))
3793 gtk_window_realize_icon (w);
3796 tmp_list = tmp_list->next;
3798 g_list_free (toplevels);
3802 * gtk_window_get_default_icon_name:
3804 * Returns the fallback icon name for windows that has been set
3805 * with gtk_window_set_default_icon_name(). The returned
3806 * string is owned by GTK+ and should not be modified. It
3807 * is only valid until the next call to
3808 * gtk_window_set_default_icon_name().
3810 * Returns: the fallback icon name for windows
3815 gtk_window_get_default_icon_name (void)
3817 return default_icon_name;
3821 * gtk_window_set_default_icon_from_file:
3822 * @filename: location of icon file
3823 * @err: (allow-none): location to store error, or %NULL.
3825 * Sets an icon to be used as fallback for windows that haven't
3826 * had gtk_window_set_icon_list() called on them from a file
3827 * on disk. Warns on failure if @err is %NULL.
3829 * Returns: %TRUE if setting the icon succeeded.
3834 gtk_window_set_default_icon_from_file (const gchar *filename,
3837 GdkPixbuf *pixbuf = load_pixbuf_verbosely (filename, err);
3841 gtk_window_set_default_icon (pixbuf);
3842 g_object_unref (pixbuf);
3851 * gtk_window_get_default_icon_list:
3853 * Gets the value set by gtk_window_set_default_icon_list().
3854 * The list is a copy and should be freed with g_list_free(),
3855 * but the pixbufs in the list have not had their reference count
3858 * Return value: copy of default icon list
3861 gtk_window_get_default_icon_list (void)
3863 return g_list_copy (default_icon_list);
3867 gtk_window_set_default_size_internal (GtkWindow *window,
3868 gboolean change_width,
3870 gboolean change_height,
3872 gboolean is_geometry)
3874 GtkWindowGeometryInfo *info;
3876 g_return_if_fail (change_width == FALSE || width >= -1);
3877 g_return_if_fail (change_height == FALSE || height >= -1);
3879 info = gtk_window_get_geometry_info (window, TRUE);
3881 g_object_freeze_notify (G_OBJECT (window));
3883 info->default_is_geometry = is_geometry != FALSE;
3893 info->default_width = width;
3895 g_object_notify (G_OBJECT (window), "default-width");
3906 info->default_height = height;
3908 g_object_notify (G_OBJECT (window), "default-height");
3911 g_object_thaw_notify (G_OBJECT (window));
3913 gtk_widget_queue_resize_no_redraw (GTK_WIDGET (window));
3917 * gtk_window_set_default_size:
3918 * @window: a #GtkWindow
3919 * @width: width in pixels, or -1 to unset the default width
3920 * @height: height in pixels, or -1 to unset the default height
3922 * Sets the default size of a window. If the window's "natural" size
3923 * (its size request) is larger than the default, the default will be
3924 * ignored. More generally, if the default size does not obey the
3925 * geometry hints for the window (gtk_window_set_geometry_hints() can
3926 * be used to set these explicitly), the default size will be clamped
3927 * to the nearest permitted size.
3929 * Unlike gtk_widget_set_size_request(), which sets a size request for
3930 * a widget and thus would keep users from shrinking the window, this
3931 * function only sets the initial size, just as if the user had
3932 * resized the window themselves. Users can still shrink the window
3933 * again as they normally would. Setting a default size of -1 means to
3934 * use the "natural" default size (the size request of the window).
3936 * For more control over a window's initial size and how resizing works,
3937 * investigate gtk_window_set_geometry_hints().
3939 * For some uses, gtk_window_resize() is a more appropriate function.
3940 * gtk_window_resize() changes the current size of the window, rather
3941 * than the size to be used on initial display. gtk_window_resize() always
3942 * affects the window itself, not the geometry widget.
3944 * The default size of a window only affects the first time a window is
3945 * shown; if a window is hidden and re-shown, it will remember the size
3946 * it had prior to hiding, rather than using the default size.
3948 * Windows can't actually be 0x0 in size, they must be at least 1x1, but
3949 * passing 0 for @width and @height is OK, resulting in a 1x1 default size.
3952 gtk_window_set_default_size (GtkWindow *window,
3956 g_return_if_fail (GTK_IS_WINDOW (window));
3957 g_return_if_fail (width >= -1);
3958 g_return_if_fail (height >= -1);
3960 gtk_window_set_default_size_internal (window, TRUE, width, TRUE, height, FALSE);
3964 * gtk_window_get_default_size:
3965 * @window: a #GtkWindow
3966 * @width: (allow-none): location to store the default width, or %NULL
3967 * @height: (allow-none): location to store the default height, or %NULL
3969 * Gets the default size of the window. A value of -1 for the width or
3970 * height indicates that a default size has not been explicitly set
3971 * for that dimension, so the "natural" size of the window will be
3976 gtk_window_get_default_size (GtkWindow *window,
3980 GtkWindowGeometryInfo *info;
3982 g_return_if_fail (GTK_IS_WINDOW (window));
3984 info = gtk_window_get_geometry_info (window, FALSE);
3987 *width = info ? info->default_width : -1;
3990 *height = info ? info->default_height : -1;
3994 * gtk_window_resize:
3995 * @window: a #GtkWindow
3996 * @width: width in pixels to resize the window to
3997 * @height: height in pixels to resize the window to
3999 * Resizes the window as if the user had done so, obeying geometry
4000 * constraints. The default geometry constraint is that windows may
4001 * not be smaller than their size request; to override this
4002 * constraint, call gtk_widget_set_size_request() to set the window's
4003 * request to a smaller value.
4005 * If gtk_window_resize() is called before showing a window for the
4006 * first time, it overrides any default size set with
4007 * gtk_window_set_default_size().
4009 * Windows may not be resized smaller than 1 by 1 pixels.
4013 gtk_window_resize (GtkWindow *window,
4017 GtkWindowGeometryInfo *info;
4019 g_return_if_fail (GTK_IS_WINDOW (window));
4020 g_return_if_fail (width > 0);
4021 g_return_if_fail (height > 0);
4023 info = gtk_window_get_geometry_info (window, TRUE);
4025 info->resize_width = width;
4026 info->resize_height = height;
4028 gtk_widget_queue_resize_no_redraw (GTK_WIDGET (window));
4032 * gtk_window_get_size:
4033 * @window: a #GtkWindow
4034 * @width: (allow-none): (out): return location for width, or %NULL
4035 * @height: (allow-none): (out): return location for height, or %NULL
4037 * Obtains the current size of @window. If @window is not onscreen,
4038 * it returns the size GTK+ will suggest to the <link
4039 * linkend="gtk-X11-arch">window manager</link> for the initial window
4040 * size (but this is not reliably the same as the size the window
4041 * manager will actually select). The size obtained by
4042 * gtk_window_get_size() is the last size received in a
4043 * #GdkEventConfigure, that is, GTK+ uses its locally-stored size,
4044 * rather than querying the X server for the size. As a result, if you
4045 * call gtk_window_resize() then immediately call
4046 * gtk_window_get_size(), the size won't have taken effect yet. After
4047 * the window manager processes the resize request, GTK+ receives
4048 * notification that the size has changed via a configure event, and
4049 * the size of the window gets updated.
4051 * Note 1: Nearly any use of this function creates a race condition,
4052 * because the size of the window may change between the time that you
4053 * get the size and the time that you perform some action assuming
4054 * that size is the current size. To avoid race conditions, connect to
4055 * "configure-event" on the window and adjust your size-dependent
4056 * state to match the size delivered in the #GdkEventConfigure.
4058 * Note 2: The returned size does <emphasis>not</emphasis> include the
4059 * size of the window manager decorations (aka the window frame or
4060 * border). Those are not drawn by GTK+ and GTK+ has no reliable
4061 * method of determining their size.
4063 * Note 3: If you are getting a window size in order to position
4064 * the window onscreen, there may be a better way. The preferred
4065 * way is to simply set the window's semantic type with
4066 * gtk_window_set_type_hint(), which allows the window manager to
4067 * e.g. center dialogs. Also, if you set the transient parent of
4068 * dialogs with gtk_window_set_transient_for() window managers
4069 * will often center the dialog over its parent window. It's
4070 * much preferred to let the window manager handle these
4071 * things rather than doing it yourself, because all apps will
4072 * behave consistently and according to user prefs if the window
4073 * manager handles it. Also, the window manager can take the size
4074 * of the window decorations/border into account, while your
4075 * application cannot.
4077 * In any case, if you insist on application-specified window
4078 * positioning, there's <emphasis>still</emphasis> a better way than
4079 * doing it yourself - gtk_window_set_position() will frequently
4080 * handle the details for you.
4084 gtk_window_get_size (GtkWindow *window,
4090 g_return_if_fail (GTK_IS_WINDOW (window));
4092 if (width == NULL && height == NULL)
4095 if (gtk_widget_get_mapped (GTK_WIDGET (window)))
4097 gdk_drawable_get_size (GTK_WIDGET (window)->window,
4102 GdkRectangle configure_request;
4104 gtk_window_compute_configure_request (window,
4108 w = configure_request.width;
4109 h = configure_request.height;
4120 * @window: a #GtkWindow
4121 * @x: X coordinate to move window to
4122 * @y: Y coordinate to move window to
4124 * Asks the <link linkend="gtk-X11-arch">window manager</link> to move
4125 * @window to the given position. Window managers are free to ignore
4126 * this; most window managers ignore requests for initial window
4127 * positions (instead using a user-defined placement algorithm) and
4128 * honor requests after the window has already been shown.
4130 * Note: the position is the position of the gravity-determined
4131 * reference point for the window. The gravity determines two things:
4132 * first, the location of the reference point in root window
4133 * coordinates; and second, which point on the window is positioned at
4134 * the reference point.
4136 * By default the gravity is #GDK_GRAVITY_NORTH_WEST, so the reference
4137 * point is simply the @x, @y supplied to gtk_window_move(). The
4138 * top-left corner of the window decorations (aka window frame or
4139 * border) will be placed at @x, @y. Therefore, to position a window
4140 * at the top left of the screen, you want to use the default gravity
4141 * (which is #GDK_GRAVITY_NORTH_WEST) and move the window to 0,0.
4143 * To position a window at the bottom right corner of the screen, you
4144 * would set #GDK_GRAVITY_SOUTH_EAST, which means that the reference
4145 * point is at @x + the window width and @y + the window height, and
4146 * the bottom-right corner of the window border will be placed at that
4147 * reference point. So, to place a window in the bottom right corner
4148 * you would first set gravity to south east, then write:
4149 * <literal>gtk_window_move (window, gdk_screen_width () - window_width,
4150 * gdk_screen_height () - window_height)</literal> (note that this
4151 * example does not take multi-head scenarios into account).
4153 * The Extended Window Manager Hints specification at <ulink
4154 * url="http://www.freedesktop.org/Standards/wm-spec">
4155 * http://www.freedesktop.org/Standards/wm-spec</ulink> has a
4156 * nice table of gravities in the "implementation notes" section.
4158 * The gtk_window_get_position() documentation may also be relevant.
4161 gtk_window_move (GtkWindow *window,
4165 GtkWindowGeometryInfo *info;
4168 g_return_if_fail (GTK_IS_WINDOW (window));
4170 widget = GTK_WIDGET (window);
4172 info = gtk_window_get_geometry_info (window, TRUE);
4174 if (gtk_widget_get_mapped (widget))
4176 /* we have now sent a request with this position
4177 * with currently-active constraints, so toggle flag.
4179 info->position_constraints_changed = FALSE;
4181 /* we only constrain if mapped - if not mapped,
4182 * then gtk_window_compute_configure_request()
4183 * will apply the constraints later, and we
4184 * don't want to lose information about
4185 * what position the user set before then.
4186 * i.e. if you do a move() then turn off POS_CENTER
4187 * then show the window, your move() will work.
4189 gtk_window_constrain_position (window,
4190 widget->allocation.width,
4191 widget->allocation.height,
4194 /* Note that this request doesn't go through our standard request
4195 * framework, e.g. doesn't increment configure_request_count,
4196 * doesn't set info->last, etc.; that's because
4197 * we don't save the info needed to arrive at this same request
4200 * To gtk_window_move_resize(), this will end up looking exactly
4201 * the same as the position being changed by the window
4205 /* FIXME are we handling gravity properly for framed windows? */
4207 gdk_window_move (window->frame,
4208 x - window->frame_left,
4209 y - window->frame_top);
4211 gdk_window_move (GTK_WIDGET (window)->window,
4216 /* Save this position to apply on mapping */
4217 info->initial_x = x;
4218 info->initial_y = y;
4219 info->initial_pos_set = TRUE;
4224 * gtk_window_get_position:
4225 * @window: a #GtkWindow
4226 * @root_x: return location for X coordinate of gravity-determined reference point
4227 * @root_y: return location for Y coordinate of gravity-determined reference point
4229 * This function returns the position you need to pass to
4230 * gtk_window_move() to keep @window in its current position. This
4231 * means that the meaning of the returned value varies with window
4232 * gravity. See gtk_window_move() for more details.
4234 * If you haven't changed the window gravity, its gravity will be
4235 * #GDK_GRAVITY_NORTH_WEST. This means that gtk_window_get_position()
4236 * gets the position of the top-left corner of the window manager
4237 * frame for the window. gtk_window_move() sets the position of this
4238 * same top-left corner.
4240 * gtk_window_get_position() is not 100% reliable because the X Window System
4241 * does not specify a way to obtain the geometry of the
4242 * decorations placed on a window by the window manager.
4243 * Thus GTK+ is using a "best guess" that works with most
4246 * Moreover, nearly all window managers are historically broken with
4247 * respect to their handling of window gravity. So moving a window to
4248 * its current position as returned by gtk_window_get_position() tends
4249 * to result in moving the window slightly. Window managers are
4250 * slowly getting better over time.
4252 * If a window has gravity #GDK_GRAVITY_STATIC the window manager
4253 * frame is not relevant, and thus gtk_window_get_position() will
4254 * always produce accurate results. However you can't use static
4255 * gravity to do things like place a window in a corner of the screen,
4256 * because static gravity ignores the window manager decorations.
4258 * If you are saving and restoring your application's window
4259 * positions, you should know that it's impossible for applications to
4260 * do this without getting it somewhat wrong because applications do
4261 * not have sufficient knowledge of window manager state. The Correct
4262 * Mechanism is to support the session management protocol (see the
4263 * "GnomeClient" object in the GNOME libraries for example) and allow
4264 * the window manager to save your window sizes and positions.
4269 gtk_window_get_position (GtkWindow *window,
4275 g_return_if_fail (GTK_IS_WINDOW (window));
4277 widget = GTK_WIDGET (window);
4279 if (window->gravity == GDK_GRAVITY_STATIC)
4281 if (gtk_widget_get_mapped (widget))
4283 /* This does a server round-trip, which is sort of wrong;
4284 * but a server round-trip is inevitable for
4285 * gdk_window_get_frame_extents() in the usual
4286 * NorthWestGravity case below, so not sure what else to
4287 * do. We should likely be consistent about whether we get
4288 * the client-side info or the server-side info.
4290 gdk_window_get_origin (widget->window, root_x, root_y);
4294 GdkRectangle configure_request;
4296 gtk_window_compute_configure_request (window,
4300 *root_x = configure_request.x;
4301 *root_y = configure_request.y;
4306 GdkRectangle frame_extents;
4311 if (gtk_widget_get_mapped (widget))
4314 gdk_window_get_frame_extents (window->frame, &frame_extents);
4316 gdk_window_get_frame_extents (widget->window, &frame_extents);
4317 x = frame_extents.x;
4318 y = frame_extents.y;
4319 gtk_window_get_size (window, &w, &h);
4323 /* We just say the frame has 0 size on all sides.
4324 * Not sure what else to do.
4326 gtk_window_compute_configure_request (window,
4329 x = frame_extents.x;
4330 y = frame_extents.y;
4331 w = frame_extents.width;
4332 h = frame_extents.height;
4335 switch (window->gravity)
4337 case GDK_GRAVITY_NORTH:
4338 case GDK_GRAVITY_CENTER:
4339 case GDK_GRAVITY_SOUTH:
4340 /* Find center of frame. */
4341 x += frame_extents.width / 2;
4342 /* Center client window on that point. */
4346 case GDK_GRAVITY_SOUTH_EAST:
4347 case GDK_GRAVITY_EAST:
4348 case GDK_GRAVITY_NORTH_EAST:
4349 /* Find right edge of frame */
4350 x += frame_extents.width;
4351 /* Align left edge of client at that point. */
4358 switch (window->gravity)
4360 case GDK_GRAVITY_WEST:
4361 case GDK_GRAVITY_CENTER:
4362 case GDK_GRAVITY_EAST:
4363 /* Find center of frame. */
4364 y += frame_extents.height / 2;
4365 /* Center client window there. */
4368 case GDK_GRAVITY_SOUTH_WEST:
4369 case GDK_GRAVITY_SOUTH:
4370 case GDK_GRAVITY_SOUTH_EAST:
4371 /* Find south edge of frame */
4372 y += frame_extents.height;
4373 /* Place bottom edge of client there */
4388 * gtk_window_reshow_with_initial_size:
4389 * @window: a #GtkWindow
4391 * Hides @window, then reshows it, resetting the
4392 * default size and position of the window. Used
4393 * by GUI builders only.
4396 gtk_window_reshow_with_initial_size (GtkWindow *window)
4400 g_return_if_fail (GTK_IS_WINDOW (window));
4402 widget = GTK_WIDGET (window);
4404 gtk_widget_hide (widget);
4405 gtk_widget_unrealize (widget);
4406 gtk_widget_show (widget);
4410 gtk_window_destroy (GtkObject *object)
4412 GtkWindow *window = GTK_WINDOW (object);
4414 toplevel_list = g_slist_remove (toplevel_list, window);
4416 if (window->transient_parent)
4417 gtk_window_set_transient_for (window, NULL);
4419 /* frees the icons */
4420 gtk_window_set_icon_list (window, NULL);
4422 if (window->has_user_ref_count)
4424 window->has_user_ref_count = FALSE;
4425 g_object_unref (window);
4429 gtk_window_group_remove_window (window->group, window);
4431 gtk_window_free_key_hash (window);
4433 GTK_OBJECT_CLASS (gtk_window_parent_class)->destroy (object);
4437 gtk_window_finalize (GObject *object)
4439 GtkWindow *window = GTK_WINDOW (object);
4440 GtkWindowPrivate *priv = GTK_WINDOW_GET_PRIVATE (window);
4441 GtkMnemonicHash *mnemonic_hash;
4443 g_free (window->title);
4444 g_free (window->wmclass_name);
4445 g_free (window->wmclass_class);
4446 g_free (window->wm_role);
4448 mnemonic_hash = gtk_window_get_mnemonic_hash (window, FALSE);
4450 _gtk_mnemonic_hash_free (mnemonic_hash);
4452 if (window->geometry_info)
4454 if (window->geometry_info->widget)
4455 g_signal_handlers_disconnect_by_func (window->geometry_info->widget,
4456 gtk_widget_destroyed,
4457 &window->geometry_info->widget);
4458 g_free (window->geometry_info);
4461 if (window->keys_changed_handler)
4463 g_source_remove (window->keys_changed_handler);
4464 window->keys_changed_handler = 0;
4468 g_signal_handlers_disconnect_by_func (window->screen,
4469 gtk_window_on_composited_changed, window);
4471 g_free (priv->startup_id);
4473 G_OBJECT_CLASS (gtk_window_parent_class)->finalize (object);
4477 gtk_window_show (GtkWidget *widget)
4479 GtkWindow *window = GTK_WINDOW (widget);
4480 GtkContainer *container = GTK_CONTAINER (window);
4481 gboolean need_resize;
4483 GTK_WIDGET_SET_FLAGS (widget, GTK_VISIBLE);
4485 need_resize = container->need_resize || !gtk_widget_get_realized (widget);
4486 container->need_resize = FALSE;
4490 GtkWindowGeometryInfo *info = gtk_window_get_geometry_info (window, TRUE);
4491 GtkAllocation allocation = { 0, 0 };
4492 GdkRectangle configure_request;
4493 GdkGeometry new_geometry;
4495 gboolean was_realized;
4497 /* We are going to go ahead and perform this configure request
4498 * and then emulate a configure notify by going ahead and
4499 * doing a size allocate. Sort of a synchronous
4500 * mini-copy of gtk_window_move_resize() here.
4502 gtk_window_compute_configure_request (window,
4507 /* We update this because we are going to go ahead
4508 * and gdk_window_resize() below, rather than
4511 info->last.configure_request.width = configure_request.width;
4512 info->last.configure_request.height = configure_request.height;
4514 /* and allocate the window - this is normally done
4515 * in move_resize in response to configure notify
4517 allocation.width = configure_request.width;
4518 allocation.height = configure_request.height;
4519 gtk_widget_size_allocate (widget, &allocation);
4521 /* Then we guarantee we have a realize */
4522 was_realized = FALSE;
4523 if (!gtk_widget_get_realized (widget))
4525 gtk_widget_realize (widget);
4526 was_realized = TRUE;
4529 /* Must be done after the windows are realized,
4530 * so that the decorations can be read
4532 gtk_decorated_window_calculate_frame_size (window);
4534 /* We only send configure request if we didn't just finish
4535 * creating the window; if we just created the window
4536 * then we created it with widget->allocation anyhow.
4539 gdk_window_move_resize (widget->window,
4540 configure_request.x,
4541 configure_request.y,
4542 configure_request.width,
4543 configure_request.height);
4546 gtk_container_check_resize (container);
4548 gtk_widget_map (widget);
4550 /* Try to make sure that we have some focused widget
4552 if (!window->focus_widget && !GTK_IS_PLUG (window))
4553 gtk_window_move_focus (window, GTK_DIR_TAB_FORWARD);
4556 gtk_grab_add (widget);
4560 gtk_window_hide (GtkWidget *widget)
4562 GtkWindow *window = GTK_WINDOW (widget);
4564 GTK_WIDGET_UNSET_FLAGS (widget, GTK_VISIBLE);
4565 gtk_widget_unmap (widget);
4568 gtk_grab_remove (widget);
4572 gtk_window_map (GtkWidget *widget)
4574 GtkWindow *window = GTK_WINDOW (widget);
4575 GtkWindowPrivate *priv = GTK_WINDOW_GET_PRIVATE (window);
4576 GdkWindow *toplevel;
4577 gboolean auto_mnemonics;
4579 gtk_widget_set_mapped (widget, TRUE);
4581 if (window->bin.child &&
4582 gtk_widget_get_visible (window->bin.child) &&
4583 !gtk_widget_get_mapped (window->bin.child))
4584 gtk_widget_map (window->bin.child);
4587 toplevel = window->frame;
4589 toplevel = widget->window;
4591 if (window->maximize_initially)
4592 gdk_window_maximize (toplevel);
4594 gdk_window_unmaximize (toplevel);
4596 if (window->stick_initially)
4597 gdk_window_stick (toplevel);
4599 gdk_window_unstick (toplevel);
4601 if (window->iconify_initially)
4602 gdk_window_iconify (toplevel);
4604 gdk_window_deiconify (toplevel);
4606 if (priv->fullscreen_initially)
4607 gdk_window_fullscreen (toplevel);
4609 gdk_window_unfullscreen (toplevel);
4611 gdk_window_set_keep_above (toplevel, priv->above_initially);
4613 gdk_window_set_keep_below (toplevel, priv->below_initially);
4615 /* No longer use the default settings */
4616 window->need_default_size = FALSE;
4617 window->need_default_position = FALSE;
4619 if (priv->reset_type_hint)
4621 /* We should only reset the type hint when the application
4622 * used gtk_window_set_type_hint() to change the hint.
4623 * Some applications use X directly to change the properties;
4624 * in that case, we shouldn't overwrite what they did.
4626 gdk_window_set_type_hint (widget->window, priv->type_hint);
4627 priv->reset_type_hint = FALSE;
4630 gdk_window_show (widget->window);
4633 gdk_window_show (window->frame);
4635 if (!disable_startup_notification)
4637 /* Do we have a custom startup-notification id? */
4638 if (priv->startup_id != NULL)
4640 /* Make sure we have a "real" id */
4641 if (!startup_id_is_fake (priv->startup_id))
4642 gdk_notify_startup_complete_with_id (priv->startup_id);
4644 g_free (priv->startup_id);
4645 priv->startup_id = NULL;
4647 else if (!sent_startup_notification)
4649 sent_startup_notification = TRUE;
4650 gdk_notify_startup_complete ();
4654 /* if auto-mnemonics is enabled and mnemonics visible is not already set
4655 * (as in the case of popup menus), then hide mnemonics initially
4657 g_object_get (gtk_widget_get_settings (widget), "gtk-auto-mnemonics",
4658 &auto_mnemonics, NULL);
4659 if (auto_mnemonics && !priv->mnemonics_visible_set)
4660 gtk_window_set_mnemonics_visible (window, FALSE);
4664 gtk_window_map_event (GtkWidget *widget,
4667 if (!gtk_widget_get_mapped (widget))
4669 /* we should be be unmapped, but are getting a MapEvent, this may happen
4670 * to toplevel XWindows if mapping was intercepted by a window manager
4671 * and an unmap request occoured while the MapRequestEvent was still
4672 * being handled. we work around this situaiton here by re-requesting
4673 * the window being unmapped. more details can be found in:
4674 * http://bugzilla.gnome.org/show_bug.cgi?id=316180
4676 gdk_window_hide (widget->window);
4682 gtk_window_unmap (GtkWidget *widget)
4684 GtkWindow *window = GTK_WINDOW (widget);
4685 GtkWindowPrivate *priv = GTK_WINDOW_GET_PRIVATE (widget);
4686 GtkWindowGeometryInfo *info;
4687 GdkWindowState state;
4689 gtk_widget_set_mapped (widget, FALSE);
4691 gdk_window_withdraw (window->frame);
4693 gdk_window_withdraw (widget->window);
4695 window->configure_request_count = 0;
4696 window->configure_notify_received = FALSE;
4698 /* on unmap, we reset the default positioning of the window,
4699 * so it's placed again, but we don't reset the default
4700 * size of the window, so it's remembered.
4702 window->need_default_position = TRUE;
4704 info = gtk_window_get_geometry_info (window, FALSE);
4707 info->initial_pos_set = FALSE;
4708 info->position_constraints_changed = FALSE;
4711 state = gdk_window_get_state (widget->window);
4712 window->iconify_initially = (state & GDK_WINDOW_STATE_ICONIFIED) != 0;
4713 window->maximize_initially = (state & GDK_WINDOW_STATE_MAXIMIZED) != 0;
4714 window->stick_initially = (state & GDK_WINDOW_STATE_STICKY) != 0;
4715 priv->above_initially = (state & GDK_WINDOW_STATE_ABOVE) != 0;
4716 priv->below_initially = (state & GDK_WINDOW_STATE_BELOW) != 0;
4720 gtk_window_realize (GtkWidget *widget)
4723 GdkWindow *parent_window;
4724 GdkWindowAttr attributes;
4725 gint attributes_mask;
4726 GtkWindowPrivate *priv;
4728 window = GTK_WINDOW (widget);
4729 priv = GTK_WINDOW_GET_PRIVATE (window);
4731 /* ensure widget tree is properly size allocated */
4732 if (widget->allocation.x == -1 &&
4733 widget->allocation.y == -1 &&
4734 widget->allocation.width == 1 &&
4735 widget->allocation.height == 1)
4737 GtkRequisition requisition;
4738 GtkAllocation allocation = { 0, 0, 200, 200 };
4740 gtk_widget_size_request (widget, &requisition);
4741 if (requisition.width || requisition.height)
4743 /* non-empty window */
4744 allocation.width = requisition.width;
4745 allocation.height = requisition.height;
4747 gtk_widget_size_allocate (widget, &allocation);
4749 _gtk_container_queue_resize (GTK_CONTAINER (widget));
4751 g_return_if_fail (!gtk_widget_get_realized (widget));
4754 gtk_widget_set_realized (widget, TRUE);
4756 switch (window->type)
4758 case GTK_WINDOW_TOPLEVEL:
4759 attributes.window_type = GDK_WINDOW_TOPLEVEL;
4761 case GTK_WINDOW_POPUP:
4762 attributes.window_type = GDK_WINDOW_TEMP;
4765 g_warning (G_STRLOC": Unknown window type %d!", window->type);
4769 attributes.title = window->title;
4770 attributes.wmclass_name = window->wmclass_name;
4771 attributes.wmclass_class = window->wmclass_class;
4772 attributes.wclass = GDK_INPUT_OUTPUT;
4773 attributes.visual = gtk_widget_get_visual (widget);
4774 attributes.colormap = gtk_widget_get_colormap (widget);
4776 if (window->has_frame)
4778 attributes.width = widget->allocation.width + window->frame_left + window->frame_right;
4779 attributes.height = widget->allocation.height + window->frame_top + window->frame_bottom;
4780 attributes.event_mask = (GDK_EXPOSURE_MASK |
4781 GDK_KEY_PRESS_MASK |
4782 GDK_ENTER_NOTIFY_MASK |
4783 GDK_LEAVE_NOTIFY_MASK |
4784 GDK_FOCUS_CHANGE_MASK |
4785 GDK_STRUCTURE_MASK |
4786 GDK_BUTTON_MOTION_MASK |
4787 GDK_POINTER_MOTION_HINT_MASK |
4788 GDK_BUTTON_PRESS_MASK |
4789 GDK_BUTTON_RELEASE_MASK);
4791 attributes_mask = GDK_WA_VISUAL | GDK_WA_COLORMAP;
4793 window->frame = gdk_window_new (gtk_widget_get_root_window (widget),
4794 &attributes, attributes_mask);
4796 if (priv->opacity_set)
4797 gdk_window_set_opacity (window->frame, priv->opacity);
4799 gdk_window_set_user_data (window->frame, widget);
4801 attributes.window_type = GDK_WINDOW_CHILD;
4802 attributes.x = window->frame_left;
4803 attributes.y = window->frame_top;
4805 attributes_mask = GDK_WA_X | GDK_WA_Y;
4807 parent_window = window->frame;
4809 g_signal_connect (window,
4811 G_CALLBACK (gtk_window_event),
4816 attributes_mask = 0;
4817 parent_window = gtk_widget_get_root_window (widget);
4820 attributes.width = widget->allocation.width;
4821 attributes.height = widget->allocation.height;
4822 attributes.event_mask = gtk_widget_get_events (widget);
4823 attributes.event_mask |= (GDK_EXPOSURE_MASK |
4824 GDK_KEY_PRESS_MASK |
4825 GDK_KEY_RELEASE_MASK |
4826 GDK_ENTER_NOTIFY_MASK |
4827 GDK_LEAVE_NOTIFY_MASK |
4828 GDK_FOCUS_CHANGE_MASK |
4829 GDK_STRUCTURE_MASK);
4830 attributes.type_hint = priv->type_hint;
4832 attributes_mask |= GDK_WA_VISUAL | GDK_WA_COLORMAP | GDK_WA_TYPE_HINT;
4833 attributes_mask |= (window->title ? GDK_WA_TITLE : 0);
4834 attributes_mask |= (window->wmclass_name ? GDK_WA_WMCLASS : 0);
4836 widget->window = gdk_window_new (parent_window, &attributes, attributes_mask);
4838 if (!window->has_frame && priv->opacity_set)
4839 gdk_window_set_opacity (widget->window, priv->opacity);
4841 gdk_window_enable_synchronized_configure (widget->window);
4843 gdk_window_set_user_data (widget->window, window);
4845 widget->style = gtk_style_attach (widget->style, widget->window);
4846 gtk_style_set_background (widget->style, widget->window, GTK_STATE_NORMAL);
4848 gtk_style_set_background (widget->style, window->frame, GTK_STATE_NORMAL);
4850 /* This is a bad hack to set the window background. */
4851 gtk_window_paint (widget, NULL);
4853 if (window->transient_parent &&
4854 gtk_widget_get_realized (GTK_WIDGET (window->transient_parent)))
4855 gdk_window_set_transient_for (widget->window,
4856 GTK_WIDGET (window->transient_parent)->window);
4858 if (window->wm_role)
4859 gdk_window_set_role (widget->window, window->wm_role);
4861 if (!window->decorated)
4862 gdk_window_set_decorations (widget->window, 0);
4864 if (!priv->deletable)
4865 gdk_window_set_functions (widget->window, GDK_FUNC_ALL | GDK_FUNC_CLOSE);
4867 if (gtk_window_get_skip_pager_hint (window))
4868 gdk_window_set_skip_pager_hint (widget->window, TRUE);
4870 if (gtk_window_get_skip_taskbar_hint (window))
4871 gdk_window_set_skip_taskbar_hint (widget->window, TRUE);
4873 if (gtk_window_get_accept_focus (window))
4874 gdk_window_set_accept_focus (widget->window, TRUE);
4876 gdk_window_set_accept_focus (widget->window, FALSE);
4878 if (gtk_window_get_focus_on_map (window))
4879 gdk_window_set_focus_on_map (widget->window, TRUE);
4881 gdk_window_set_focus_on_map (widget->window, FALSE);
4884 gdk_window_set_modal_hint (widget->window, TRUE);
4886 gdk_window_set_modal_hint (widget->window, FALSE);
4888 if (priv->startup_id)
4890 #ifdef GDK_WINDOWING_X11
4891 guint32 timestamp = extract_time_from_startup_id (priv->startup_id);
4892 if (timestamp != GDK_CURRENT_TIME)
4893 gdk_x11_window_set_user_time (widget->window, timestamp);
4895 if (!startup_id_is_fake (priv->startup_id))
4896 gdk_window_set_startup_id (widget->window, priv->startup_id);
4900 gtk_window_realize_icon (window);
4904 gtk_window_unrealize (GtkWidget *widget)
4907 GtkWindowGeometryInfo *info;
4909 window = GTK_WINDOW (widget);
4911 /* On unrealize, we reset the size of the window such
4912 * that we will re-apply the default sizing stuff
4913 * next time we show the window.
4915 * Default positioning is reset on unmap, instead of unrealize.
4917 window->need_default_size = TRUE;
4918 info = gtk_window_get_geometry_info (window, FALSE);
4921 info->resize_width = -1;
4922 info->resize_height = -1;
4923 info->last.configure_request.x = 0;
4924 info->last.configure_request.y = 0;
4925 info->last.configure_request.width = -1;
4926 info->last.configure_request.height = -1;
4927 /* be sure we reset geom hints on re-realize */
4928 info->last.flags = 0;
4933 gdk_window_set_user_data (window->frame, NULL);
4934 gdk_window_destroy (window->frame);
4935 window->frame = NULL;
4939 gtk_window_unrealize_icon (window);
4941 GTK_WIDGET_CLASS (gtk_window_parent_class)->unrealize (widget);
4945 gtk_window_size_allocate (GtkWidget *widget,
4946 GtkAllocation *allocation)
4949 GtkAllocation child_allocation;
4951 window = GTK_WINDOW (widget);
4952 widget->allocation = *allocation;
4954 if (window->bin.child && gtk_widget_get_visible (window->bin.child))
4956 child_allocation.x = GTK_CONTAINER (window)->border_width;
4957 child_allocation.y = GTK_CONTAINER (window)->border_width;
4958 child_allocation.width =
4959 MAX (1, (gint)allocation->width - child_allocation.x * 2);
4960 child_allocation.height =
4961 MAX (1, (gint)allocation->height - child_allocation.y * 2);
4963 gtk_widget_size_allocate (window->bin.child, &child_allocation);
4966 if (gtk_widget_get_realized (widget) && window->frame)
4968 gdk_window_resize (window->frame,
4969 allocation->width + window->frame_left + window->frame_right,
4970 allocation->height + window->frame_top + window->frame_bottom);
4975 gtk_window_event (GtkWidget *widget, GdkEvent *event)
4978 gboolean return_val;
4980 window = GTK_WINDOW (widget);
4982 if (window->frame && (event->any.window == window->frame))
4984 if ((event->type != GDK_KEY_PRESS) &&
4985 (event->type != GDK_KEY_RELEASE) &&
4986 (event->type != GDK_FOCUS_CHANGE))
4988 g_signal_stop_emission_by_name (widget, "event");
4990 g_signal_emit (widget, window_signals[FRAME_EVENT], 0, event, &return_val);
4995 g_object_unref (event->any.window);
4996 event->any.window = g_object_ref (widget->window);
5004 gtk_window_frame_event (GtkWindow *window, GdkEvent *event)
5006 GdkEventConfigure *configure_event;
5009 switch (event->type)
5012 configure_event = (GdkEventConfigure *)event;
5014 /* Invalidate the decorations */
5017 rect.width = configure_event->width;
5018 rect.height = configure_event->height;
5020 gdk_window_invalidate_rect (window->frame, &rect, FALSE);
5022 /* Pass on the (modified) configure event */
5023 configure_event->width -= window->frame_left + window->frame_right;
5024 configure_event->height -= window->frame_top + window->frame_bottom;
5025 return gtk_window_configure_event (GTK_WIDGET (window), configure_event);
5034 gtk_window_configure_event (GtkWidget *widget,
5035 GdkEventConfigure *event)
5037 GtkWindow *window = GTK_WINDOW (widget);
5038 gboolean expected_reply = window->configure_request_count > 0;
5040 /* window->configure_request_count incremented for each
5041 * configure request, and decremented to a min of 0 for
5042 * each configure notify.
5044 * All it means is that we know we will get at least
5045 * window->configure_request_count more configure notifies.
5046 * We could get more configure notifies than that; some
5047 * of the configure notifies we get may be unrelated to
5048 * the configure requests. But we will get at least
5049 * window->configure_request_count notifies.
5052 if (window->configure_request_count > 0)
5054 window->configure_request_count -= 1;
5055 gdk_window_thaw_toplevel_updates_libgtk_only (widget->window);
5058 /* As an optimization, we avoid a resize when possible.
5060 * The only times we can avoid a resize are:
5061 * - we know only the position changed, not the size
5062 * - we know we have made more requests and so will get more
5063 * notifies and can wait to resize when we get them
5066 if (!expected_reply &&
5067 (widget->allocation.width == event->width &&
5068 widget->allocation.height == event->height))
5070 gdk_window_configure_finished (widget->window);
5075 * If we do need to resize, we do that by:
5076 * - filling in widget->allocation with the new size
5077 * - setting configure_notify_received to TRUE
5078 * for use in gtk_window_move_resize()
5079 * - queueing a resize, leading to invocation of
5080 * gtk_window_move_resize() in an idle handler
5084 window->configure_notify_received = TRUE;
5086 widget->allocation.width = event->width;
5087 widget->allocation.height = event->height;
5089 _gtk_container_queue_resize (GTK_CONTAINER (widget));
5094 /* the accel_key and accel_mods fields of the key have to be setup
5095 * upon calling this function. it'll then return whether that key
5096 * is at all used as accelerator, and if so will OR in the
5097 * accel_flags member of the key.
5100 _gtk_window_query_nonaccels (GtkWindow *window,
5102 GdkModifierType accel_mods)
5104 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
5106 /* movement keys are considered locked accels */
5109 static const guint bindings[] = {
5110 GDK_space, GDK_KP_Space, GDK_Return, GDK_ISO_Enter, GDK_KP_Enter, GDK_Up, GDK_KP_Up, GDK_Down, GDK_KP_Down,
5111 GDK_Left, GDK_KP_Left, GDK_Right, GDK_KP_Right, GDK_Tab, GDK_KP_Tab, GDK_ISO_Left_Tab,
5115 for (i = 0; i < G_N_ELEMENTS (bindings); i++)
5116 if (bindings[i] == accel_key)
5120 /* mnemonics are considered locked accels */
5121 if (accel_mods == window->mnemonic_modifier)
5123 GtkMnemonicHash *mnemonic_hash = gtk_window_get_mnemonic_hash (window, FALSE);
5124 if (mnemonic_hash && _gtk_mnemonic_hash_lookup (mnemonic_hash, accel_key))
5132 * gtk_window_propagate_key_event:
5133 * @window: a #GtkWindow
5134 * @event: a #GdkEventKey
5136 * Propagate a key press or release event to the focus widget and
5137 * up the focus container chain until a widget handles @event.
5138 * This is normally called by the default ::key_press_event and
5139 * ::key_release_event handlers for toplevel windows,
5140 * however in some cases it may be useful to call this directly when
5141 * overriding the standard key handling for a toplevel window.
5143 * Return value: %TRUE if a widget in the focus chain handled the event.
5148 gtk_window_propagate_key_event (GtkWindow *window,
5151 gboolean handled = FALSE;
5152 GtkWidget *widget, *focus;
5154 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
5156 widget = GTK_WIDGET (window);
5157 focus = window->focus_widget;
5159 g_object_ref (focus);
5162 focus && focus != widget &&
5163 gtk_widget_get_toplevel (focus) == widget)
5167 if (gtk_widget_is_sensitive (focus))
5168 handled = gtk_widget_event (focus, (GdkEvent*) event);
5170 parent = focus->parent;
5172 g_object_ref (parent);
5174 g_object_unref (focus);
5180 g_object_unref (focus);
5186 gtk_window_key_press_event (GtkWidget *widget,
5189 GtkWindow *window = GTK_WINDOW (widget);
5190 gboolean handled = FALSE;
5192 /* handle mnemonics and accelerators */
5194 handled = gtk_window_activate_key (window, event);
5196 /* handle focus widget key events */
5198 handled = gtk_window_propagate_key_event (window, event);
5200 /* Chain up, invokes binding set */
5202 handled = GTK_WIDGET_CLASS (gtk_window_parent_class)->key_press_event (widget, event);
5208 gtk_window_key_release_event (GtkWidget *widget,
5211 GtkWindow *window = GTK_WINDOW (widget);
5212 gboolean handled = FALSE;
5214 /* handle focus widget key events */
5216 handled = gtk_window_propagate_key_event (window, event);
5218 /* Chain up, invokes binding set */
5220 handled = GTK_WIDGET_CLASS (gtk_window_parent_class)->key_release_event (widget, event);
5226 gtk_window_real_activate_default (GtkWindow *window)
5228 gtk_window_activate_default (window);
5232 gtk_window_real_activate_focus (GtkWindow *window)
5234 gtk_window_activate_focus (window);
5238 gtk_window_move_focus (GtkWindow *window,
5239 GtkDirectionType dir)
5241 gtk_widget_child_focus (GTK_WIDGET (window), dir);
5243 if (!GTK_CONTAINER (window)->focus_child)
5244 gtk_window_set_focus (window, NULL);
5248 gtk_window_enter_notify_event (GtkWidget *widget,
5249 GdkEventCrossing *event)
5255 gtk_window_leave_notify_event (GtkWidget *widget,
5256 GdkEventCrossing *event)
5262 do_focus_change (GtkWidget *widget,
5265 GdkEvent *fevent = gdk_event_new (GDK_FOCUS_CHANGE);
5267 fevent->focus_change.type = GDK_FOCUS_CHANGE;
5268 fevent->focus_change.window = widget->window;
5269 fevent->focus_change.in = in;
5271 g_object_ref (widget->window);
5273 gtk_widget_send_focus_change (widget, fevent);
5275 gdk_event_free (fevent);
5279 gtk_window_focus_in_event (GtkWidget *widget,
5280 GdkEventFocus *event)
5282 GtkWindow *window = GTK_WINDOW (widget);
5284 /* It appears spurious focus in events can occur when
5285 * the window is hidden. So we'll just check to see if
5286 * the window is visible before actually handling the
5289 if (gtk_widget_get_visible (widget))
5291 _gtk_window_set_has_toplevel_focus (window, TRUE);
5292 _gtk_window_set_is_active (window, TRUE);
5299 gtk_window_focus_out_event (GtkWidget *widget,
5300 GdkEventFocus *event)
5302 GtkWindow *window = GTK_WINDOW (widget);
5303 gboolean auto_mnemonics;
5305 _gtk_window_set_has_toplevel_focus (window, FALSE);
5306 _gtk_window_set_is_active (window, FALSE);
5308 /* set the mnemonic-visible property to false */
5309 g_object_get (gtk_widget_get_settings (widget),
5310 "gtk-auto-mnemonics", &auto_mnemonics, NULL);
5312 gtk_window_set_mnemonics_visible (window, FALSE);
5317 static GdkAtom atom_rcfiles = GDK_NONE;
5318 static GdkAtom atom_iconthemes = GDK_NONE;
5321 send_client_message_to_embedded_windows (GtkWidget *widget,
5322 GdkAtom message_type)
5324 GList *embedded_windows;
5326 embedded_windows = g_object_get_qdata (G_OBJECT (widget), quark_gtk_embedded);
5327 if (embedded_windows)
5329 GdkEvent *send_event = gdk_event_new (GDK_CLIENT_EVENT);
5332 for (i = 0; i < 5; i++)
5333 send_event->client.data.l[i] = 0;
5334 send_event->client.data_format = 32;
5335 send_event->client.message_type = message_type;
5337 while (embedded_windows)
5339 GdkNativeWindow xid = GDK_GPOINTER_TO_NATIVE_WINDOW(embedded_windows->data);
5340 gdk_event_send_client_message_for_display (gtk_widget_get_display (widget), send_event, xid);
5341 embedded_windows = embedded_windows->next;
5344 gdk_event_free (send_event);
5349 gtk_window_client_event (GtkWidget *widget,
5350 GdkEventClient *event)
5354 atom_rcfiles = gdk_atom_intern_static_string ("_GTK_READ_RCFILES");
5355 atom_iconthemes = gdk_atom_intern_static_string ("_GTK_LOAD_ICONTHEMES");
5358 if (event->message_type == atom_rcfiles)
5360 send_client_message_to_embedded_windows (widget, atom_rcfiles);
5361 gtk_rc_reparse_all_for_settings (gtk_widget_get_settings (widget), FALSE);
5364 if (event->message_type == atom_iconthemes)
5366 send_client_message_to_embedded_windows (widget, atom_iconthemes);
5367 _gtk_icon_theme_check_reload (gtk_widget_get_display (widget));
5374 gtk_window_check_resize (GtkContainer *container)
5376 if (gtk_widget_get_visible (GTK_WIDGET (container)))
5377 gtk_window_move_resize (GTK_WINDOW (container));
5381 gtk_window_focus (GtkWidget *widget,
5382 GtkDirectionType direction)
5386 GtkContainer *container;
5387 GtkWidget *old_focus_child;
5390 container = GTK_CONTAINER (widget);
5391 window = GTK_WINDOW (widget);
5392 bin = GTK_BIN (widget);
5394 old_focus_child = container->focus_child;
5396 /* We need a special implementation here to deal properly with wrapping
5397 * around in the tab chain without the danger of going into an
5400 if (old_focus_child)
5402 if (gtk_widget_child_focus (old_focus_child, direction))
5406 if (window->focus_widget)
5408 if (direction == GTK_DIR_LEFT ||
5409 direction == GTK_DIR_RIGHT ||
5410 direction == GTK_DIR_UP ||
5411 direction == GTK_DIR_DOWN)
5416 /* Wrapped off the end, clear the focus setting for the toplpevel */
5417 parent = window->focus_widget->parent;
5420 gtk_container_set_focus_child (GTK_CONTAINER (parent), NULL);
5421 parent = GTK_WIDGET (parent)->parent;
5424 gtk_window_set_focus (GTK_WINDOW (container), NULL);
5427 /* Now try to focus the first widget in the window */
5430 if (gtk_widget_child_focus (bin->child, direction))
5438 gtk_window_real_set_focus (GtkWindow *window,
5441 GtkWidget *old_focus = window->focus_widget;
5442 gboolean had_default = FALSE;
5443 gboolean focus_had_default = FALSE;
5444 gboolean old_focus_had_default = FALSE;
5448 g_object_ref (old_focus);
5449 g_object_freeze_notify (G_OBJECT (old_focus));
5450 old_focus_had_default = gtk_widget_has_default (old_focus);
5454 g_object_ref (focus);
5455 g_object_freeze_notify (G_OBJECT (focus));
5456 focus_had_default = gtk_widget_has_default (focus);
5459 if (window->default_widget)
5460 had_default = gtk_widget_has_default (window->default_widget);
5462 if (window->focus_widget)
5464 if (gtk_widget_get_receives_default (window->focus_widget) &&
5465 (window->focus_widget != window->default_widget))
5467 _gtk_widget_set_has_default (window->focus_widget, FALSE);
5468 gtk_widget_queue_draw (window->focus_widget);
5470 if (window->default_widget)
5471 _gtk_widget_set_has_default (window->default_widget, TRUE);
5474 window->focus_widget = NULL;
5476 if (window->has_focus)
5477 do_focus_change (old_focus, FALSE);
5479 g_object_notify (G_OBJECT (old_focus), "is-focus");
5482 /* The above notifications may have set a new focus widget,
5483 * if so, we don't want to override it.
5485 if (focus && !window->focus_widget)
5487 window->focus_widget = focus;
5489 if (gtk_widget_get_receives_default (window->focus_widget) &&
5490 (window->focus_widget != window->default_widget))
5492 if (gtk_widget_get_can_default (window->focus_widget))
5493 _gtk_widget_set_has_default (window->focus_widget, TRUE);
5495 if (window->default_widget)
5496 _gtk_widget_set_has_default (window->default_widget, FALSE);
5499 if (window->has_focus)
5500 do_focus_change (window->focus_widget, TRUE);
5502 g_object_notify (G_OBJECT (window->focus_widget), "is-focus");
5505 /* If the default widget changed, a redraw will have been queued
5506 * on the old and new default widgets by gtk_window_set_default(), so
5507 * we only have to worry about the case where it didn't change.
5508 * We'll sometimes queue a draw twice on the new widget but that
5511 if (window->default_widget &&
5512 (had_default != gtk_widget_has_default (window->default_widget)))
5513 gtk_widget_queue_draw (window->default_widget);
5517 if (old_focus_had_default != gtk_widget_has_default (old_focus))
5518 gtk_widget_queue_draw (old_focus);
5520 g_object_thaw_notify (G_OBJECT (old_focus));
5521 g_object_unref (old_focus);
5525 if (focus_had_default != gtk_widget_has_default (focus))
5526 gtk_widget_queue_draw (focus);
5528 g_object_thaw_notify (G_OBJECT (focus));
5529 g_object_unref (focus);
5535 gtk_window_extended_layout_init (GtkExtendedLayoutIface *iface)
5537 iface->get_desired_width = gtk_window_get_desired_width;
5538 iface->get_desired_height = gtk_window_get_desired_height;
5543 gtk_window_get_desired_width (GtkExtendedLayout *layout,
5550 window = GTK_WINDOW (layout);
5551 child = gtk_bin_get_child (GTK_BIN (window));
5553 *minimum_size = GTK_CONTAINER (window)->border_width * 2;
5554 *natural_size = GTK_CONTAINER (window)->border_width * 2;
5556 if (child && gtk_widget_get_visible (child))
5558 gint child_min, child_nat;
5559 gtk_extended_layout_get_desired_width (GTK_EXTENDED_LAYOUT (child), &child_min, &child_nat);
5561 *minimum_size += child_min;
5562 *natural_size += child_nat;
5567 gtk_window_get_desired_height (GtkExtendedLayout *layout,
5574 window = GTK_WINDOW (layout);
5575 child = gtk_bin_get_child (GTK_BIN (window));
5577 *minimum_size = GTK_CONTAINER (window)->border_width * 2;
5578 *natural_size = GTK_CONTAINER (window)->border_width * 2;
5580 if (child && gtk_widget_get_visible (child))
5582 gint child_min, child_nat;
5583 gtk_extended_layout_get_desired_height (GTK_EXTENDED_LAYOUT (child), &child_min, &child_nat);
5585 *minimum_size += child_min;
5586 *natural_size += child_nat;
5592 * _gtk_window_unset_focus_and_default:
5593 * @window: a #GtkWindow
5594 * @widget: a widget inside of @window
5596 * Checks whether the focus and default widgets of @window are
5597 * @widget or a descendent of @widget, and if so, unset them.
5600 _gtk_window_unset_focus_and_default (GtkWindow *window,
5606 g_object_ref (window);
5607 g_object_ref (widget);
5609 if (GTK_CONTAINER (widget->parent)->focus_child == widget)
5611 child = window->focus_widget;
5613 while (child && child != widget)
5614 child = child->parent;
5616 if (child == widget)
5617 gtk_window_set_focus (GTK_WINDOW (window), NULL);
5620 child = window->default_widget;
5622 while (child && child != widget)
5623 child = child->parent;
5625 if (child == widget)
5626 gtk_window_set_default (window, NULL);
5628 g_object_unref (widget);
5629 g_object_unref (window);
5632 /*********************************
5633 * Functions related to resizing *
5634 *********************************/
5636 /* This function doesn't constrain to geometry hints */
5638 gtk_window_compute_configure_request_size (GtkWindow *window,
5642 GtkRequisition requisition;
5643 GtkWindowGeometryInfo *info;
5647 * - we've done a size request
5650 widget = GTK_WIDGET (window);
5652 info = gtk_window_get_geometry_info (window, FALSE);
5654 if (window->need_default_size)
5656 gtk_widget_get_child_requisition (widget, &requisition);
5658 /* Default to requisition */
5659 *width = requisition.width;
5660 *height = requisition.height;
5662 /* If window is empty so requests 0, default to random nonzero size */
5663 if (*width == 0 && *height == 0)
5669 /* Override requisition with default size */
5673 gint base_width = 0;
5674 gint base_height = 0;
5676 gint min_height = 0;
5678 gint height_inc = 1;
5680 if (info->default_is_geometry &&
5681 (info->default_width > 0 || info->default_height > 0))
5683 GdkGeometry geometry;
5686 gtk_window_compute_hints (window, &geometry, &flags);
5688 if (flags & GDK_HINT_BASE_SIZE)
5690 base_width = geometry.base_width;
5691 base_height = geometry.base_height;
5693 if (flags & GDK_HINT_MIN_SIZE)
5695 min_width = geometry.min_width;
5696 min_height = geometry.min_height;
5698 if (flags & GDK_HINT_RESIZE_INC)
5700 width_inc = geometry.width_inc;
5701 height_inc = geometry.height_inc;
5705 if (info->default_width > 0)
5706 *width = MAX (info->default_width * width_inc + base_width, min_width);
5708 if (info->default_height > 0)
5709 *height = MAX (info->default_height * height_inc + base_height, min_height);
5714 /* Default to keeping current size */
5715 *width = widget->allocation.width;
5716 *height = widget->allocation.height;
5719 /* Override any size with gtk_window_resize() values */
5722 if (info->resize_width > 0)
5723 *width = info->resize_width;
5725 if (info->resize_height > 0)
5726 *height = info->resize_height;
5729 /* Don't ever request zero width or height, its not supported by
5730 gdk. The size allocation code will round it to 1 anyway but if
5731 we do it then the value returned from this function will is
5732 not comparable to the size allocation read from the GtkWindow. */
5733 *width = MAX (*width, 1);
5734 *height = MAX (*height, 1);
5737 static GtkWindowPosition
5738 get_effective_position (GtkWindow *window)
5740 GtkWindowPosition pos = window->position;
5742 if (pos == GTK_WIN_POS_CENTER_ON_PARENT &&
5743 (window->transient_parent == NULL ||
5744 !gtk_widget_get_mapped (GTK_WIDGET (window->transient_parent))))
5745 pos = GTK_WIN_POS_NONE;
5751 get_center_monitor_of_window (GtkWindow *window)
5753 /* We could try to sort out the relative positions of the monitors and
5754 * stuff, or we could just be losers and assume you have a row
5755 * or column of monitors.
5757 return gdk_screen_get_n_monitors (gtk_window_check_screen (window)) / 2;
5761 get_monitor_containing_pointer (GtkWindow *window)
5765 GdkScreen *window_screen;
5766 GdkScreen *pointer_screen;
5768 window_screen = gtk_window_check_screen (window);
5769 gdk_display_get_pointer (gdk_screen_get_display (window_screen),
5773 if (pointer_screen == window_screen)
5774 monitor_num = gdk_screen_get_monitor_at_point (pointer_screen, px, py);
5782 center_window_on_monitor (GtkWindow *window,
5788 GdkRectangle monitor;
5791 monitor_num = get_monitor_containing_pointer (window);
5793 if (monitor_num == -1)
5794 monitor_num = get_center_monitor_of_window (window);
5796 gdk_screen_get_monitor_geometry (gtk_window_check_screen (window),
5797 monitor_num, &monitor);
5799 *x = (monitor.width - w) / 2 + monitor.x;
5800 *y = (monitor.height - h) / 2 + monitor.y;
5802 /* Be sure we aren't off the monitor, ignoring _NET_WM_STRUT
5803 * and WM decorations.
5817 if (extent > clamp_extent)
5819 *base = clamp_base + clamp_extent/2 - extent/2;
5820 else if (*base < clamp_base)
5822 else if (*base + extent > clamp_base + clamp_extent)
5823 *base = clamp_base + clamp_extent - extent;
5827 clamp_window_to_rectangle (gint *x,
5831 const GdkRectangle *rect)
5833 #ifdef DEBUGGING_OUTPUT
5834 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);
5837 /* If it is too large, center it. If it fits on the monitor but is
5838 * partially outside, move it to the closest edge. Do this
5839 * separately in x and y directions.
5841 clamp (x, w, rect->x, rect->width);
5842 clamp (y, h, rect->y, rect->height);
5843 #ifdef DEBUGGING_OUTPUT
5844 g_print (" ==> %+d%+d: %dx%d\n", *x, *y, w, h);
5850 gtk_window_compute_configure_request (GtkWindow *window,
5851 GdkRectangle *request,
5852 GdkGeometry *geometry,
5855 GdkGeometry new_geometry;
5859 GtkWindowPosition pos;
5860 GtkWidget *parent_widget;
5861 GtkWindowGeometryInfo *info;
5865 widget = GTK_WIDGET (window);
5867 screen = gtk_window_check_screen (window);
5869 gtk_widget_size_request (widget, NULL);
5870 gtk_window_compute_configure_request_size (window, (guint *)&w, (guint *)&h);
5872 gtk_window_compute_hints (window, &new_geometry, &new_flags);
5873 gtk_window_constrain_size (window,
5874 &new_geometry, new_flags,
5878 parent_widget = (GtkWidget*) window->transient_parent;
5880 pos = get_effective_position (window);
5881 info = gtk_window_get_geometry_info (window, FALSE);
5883 /* by default, don't change position requested */
5886 x = info->last.configure_request.x;
5887 y = info->last.configure_request.y;
5896 if (window->need_default_position)
5899 /* FIXME this all interrelates with window gravity.
5900 * For most of them I think we want to set GRAVITY_CENTER.
5902 * Not sure how to go about that.
5907 /* here we are only handling CENTER_ALWAYS
5908 * as it relates to default positioning,
5909 * where it's equivalent to simply CENTER
5911 case GTK_WIN_POS_CENTER_ALWAYS:
5912 case GTK_WIN_POS_CENTER:
5913 center_window_on_monitor (window, w, h, &x, &y);
5916 case GTK_WIN_POS_CENTER_ON_PARENT:
5919 GdkRectangle monitor;
5922 g_assert (gtk_widget_get_mapped (parent_widget)); /* established earlier */
5924 if (parent_widget->window != NULL)
5925 monitor_num = gdk_screen_get_monitor_at_window (screen,
5926 parent_widget->window);
5930 gdk_window_get_origin (parent_widget->window,
5933 x = ox + (parent_widget->allocation.width - w) / 2;
5934 y = oy + (parent_widget->allocation.height - h) / 2;
5936 /* Clamp onto current monitor, ignoring _NET_WM_STRUT and
5937 * WM decorations. If parent wasn't on a monitor, just
5940 if (monitor_num >= 0)
5942 gdk_screen_get_monitor_geometry (screen, monitor_num, &monitor);
5943 clamp_window_to_rectangle (&x, &y, w, h, &monitor);
5948 case GTK_WIN_POS_MOUSE:
5950 gint screen_width = gdk_screen_get_width (screen);
5951 gint screen_height = gdk_screen_get_height (screen);
5953 GdkRectangle monitor;
5954 GdkScreen *pointer_screen;
5957 gdk_display_get_pointer (gdk_screen_get_display (screen),
5961 if (pointer_screen == screen)
5962 monitor_num = gdk_screen_get_monitor_at_point (screen, px, py);
5968 x = CLAMP (x, 0, screen_width - w);
5969 y = CLAMP (y, 0, screen_height - h);
5971 /* Clamp onto current monitor, ignoring _NET_WM_STRUT and
5972 * WM decorations. Don't try to figure out what's going
5973 * on if the mouse wasn't inside a monitor.
5975 if (monitor_num >= 0)
5977 gdk_screen_get_monitor_geometry (screen, monitor_num, &monitor);
5978 clamp_window_to_rectangle (&x, &y, w, h, &monitor);
5986 } /* if (window->need_default_position) */
5988 if (window->need_default_position && info &&
5989 info->initial_pos_set)
5991 x = info->initial_x;
5992 y = info->initial_y;
5993 gtk_window_constrain_position (window, w, h, &x, &y);
5999 request->height = h;
6002 *geometry = new_geometry;
6008 gtk_window_constrain_position (GtkWindow *window,
6014 /* See long comments in gtk_window_move_resize()
6015 * on when it's safe to call this function.
6017 if (window->position == GTK_WIN_POS_CENTER_ALWAYS)
6019 gint center_x, center_y;
6021 center_window_on_monitor (window, new_width, new_height, ¢er_x, ¢er_y);
6029 gtk_window_move_resize (GtkWindow *window)
6033 * First we determine whether any information has changed that would
6034 * cause us to revise our last configure request. If we would send
6035 * a different configure request from last time, then
6036 * configure_request_size_changed = TRUE or
6037 * configure_request_pos_changed = TRUE. configure_request_size_changed
6038 * may be true due to new hints, a gtk_window_resize(), or whatever.
6039 * configure_request_pos_changed may be true due to gtk_window_set_position()
6040 * or gtk_window_move().
6042 * If the configure request has changed, we send off a new one. To
6043 * ensure GTK+ invariants are maintained (resize queue does what it
6044 * should), we go ahead and size_allocate the requested size in this
6047 * If the configure request has not changed, we don't ever resend
6048 * it, because it could mean fighting the user or window manager.
6051 * To prepare the configure request, we come up with a base size/pos:
6052 * - the one from gtk_window_move()/gtk_window_resize()
6053 * - else default_width, default_height if we haven't ever
6055 * - else the size request if we haven't ever been mapped,
6056 * as a substitute default size
6057 * - else the current size of the window, as received from
6058 * configure notifies (i.e. the current allocation)
6060 * If GTK_WIN_POS_CENTER_ALWAYS is active, we constrain
6061 * the position request to be centered.
6064 GtkContainer *container;
6065 GtkWindowGeometryInfo *info;
6066 GdkGeometry new_geometry;
6068 GdkRectangle new_request;
6069 gboolean configure_request_size_changed;
6070 gboolean configure_request_pos_changed;
6071 gboolean hints_changed; /* do we need to send these again */
6072 GtkWindowLastGeometryInfo saved_last_info;
6074 widget = GTK_WIDGET (window);
6075 container = GTK_CONTAINER (widget);
6076 info = gtk_window_get_geometry_info (window, TRUE);
6078 configure_request_size_changed = FALSE;
6079 configure_request_pos_changed = FALSE;
6081 gtk_window_compute_configure_request (window, &new_request,
6082 &new_geometry, &new_flags);
6084 /* This check implies the invariant that we never set info->last
6085 * without setting the hints and sending off a configure request.
6087 * If we change info->last without sending the request, we may
6090 if (info->last.configure_request.x != new_request.x ||
6091 info->last.configure_request.y != new_request.y)
6092 configure_request_pos_changed = TRUE;
6094 if ((info->last.configure_request.width != new_request.width ||
6095 info->last.configure_request.height != new_request.height))
6096 configure_request_size_changed = TRUE;
6098 hints_changed = FALSE;
6100 if (!gtk_window_compare_hints (&info->last.geometry, info->last.flags,
6101 &new_geometry, new_flags))
6103 hints_changed = TRUE;
6106 /* Position Constraints
6107 * ====================
6109 * POS_CENTER_ALWAYS is conceptually a constraint rather than
6110 * a default. The other POS_ values are used only when the
6111 * window is shown, not after that.
6113 * However, we can't implement a position constraint as
6114 * "anytime the window size changes, center the window"
6115 * because this may well end up fighting the WM or user. In
6116 * fact it gets in an infinite loop with at least one WM.
6118 * Basically, applications are in no way in a position to
6119 * constrain the position of a window, with one exception:
6120 * override redirect windows. (Really the intended purpose
6121 * of CENTER_ALWAYS anyhow, I would think.)
6123 * So the way we implement this "constraint" is to say that when WE
6124 * cause a move or resize, i.e. we make a configure request changing
6125 * window size, we recompute the CENTER_ALWAYS position to reflect
6126 * the new window size, and include it in our request. Also, if we
6127 * just turned on CENTER_ALWAYS we snap to center with a new
6128 * request. Otherwise, if we are just NOTIFIED of a move or resize
6129 * done by someone else e.g. the window manager, we do NOT send a
6130 * new configure request.
6132 * For override redirect windows, this works fine; all window
6133 * sizes are from our configure requests. For managed windows,
6134 * it is at least semi-sane, though who knows what the
6135 * app author is thinking.
6138 /* This condition should be kept in sync with the condition later on
6139 * that determines whether we send a configure request. i.e. we
6140 * should do this position constraining anytime we were going to
6141 * send a configure request anyhow, plus when constraints have
6144 if (configure_request_pos_changed ||
6145 configure_request_size_changed ||
6147 info->position_constraints_changed)
6149 /* We request the constrained position if:
6150 * - we were changing position, and need to clamp
6151 * the change to the constraint
6152 * - we're changing the size anyway
6153 * - set_position() was called to toggle CENTER_ALWAYS on
6156 gtk_window_constrain_position (window,
6162 /* Update whether we need to request a move */
6163 if (info->last.configure_request.x != new_request.x ||
6164 info->last.configure_request.y != new_request.y)
6165 configure_request_pos_changed = TRUE;
6167 configure_request_pos_changed = FALSE;
6171 if (window->type == GTK_WINDOW_TOPLEVEL)
6173 int notify_x, notify_y;
6175 /* this is the position from the last configure notify */
6176 gdk_window_get_position (widget->window, ¬ify_x, ¬ify_y);
6178 g_message ("--- %s ---\n"
6179 "last : %d,%d\t%d x %d\n"
6180 "this : %d,%d\t%d x %d\n"
6181 "alloc : %d,%d\t%d x %d\n"
6183 "resize: \t%d x %d\n"
6184 "size_changed: %d pos_changed: %d hints_changed: %d\n"
6185 "configure_notify_received: %d\n"
6186 "configure_request_count: %d\n"
6187 "position_constraints_changed: %d\n",
6188 window->title ? window->title : "(no title)",
6189 info->last.configure_request.x,
6190 info->last.configure_request.y,
6191 info->last.configure_request.width,
6192 info->last.configure_request.height,
6198 widget->allocation.width,
6199 widget->allocation.height,
6200 widget->requisition.width,
6201 widget->requisition.height,
6203 info->resize_height,
6204 configure_request_pos_changed,
6205 configure_request_size_changed,
6207 window->configure_notify_received,
6208 window->configure_request_count,
6209 info->position_constraints_changed);
6213 saved_last_info = info->last;
6214 info->last.geometry = new_geometry;
6215 info->last.flags = new_flags;
6216 info->last.configure_request = new_request;
6218 /* need to set PPosition so the WM will look at our position,
6219 * but we don't want to count PPosition coming and going as a hints
6220 * change for future iterations. So we saved info->last prior to
6224 /* Also, if the initial position was explicitly set, then we always
6225 * toggle on PPosition. This makes gtk_window_move(window, 0, 0)
6229 /* Also, we toggle on PPosition if GTK_WIN_POS_ is in use and
6230 * this is an initial map
6233 if ((configure_request_pos_changed ||
6234 info->initial_pos_set ||
6235 (window->need_default_position &&
6236 get_effective_position (window) != GTK_WIN_POS_NONE)) &&
6237 (new_flags & GDK_HINT_POS) == 0)
6239 new_flags |= GDK_HINT_POS;
6240 hints_changed = TRUE;
6243 /* Set hints if necessary
6246 gdk_window_set_geometry_hints (widget->window,
6250 /* handle resizing/moving and widget tree allocation
6252 if (window->configure_notify_received)
6254 GtkAllocation allocation;
6256 /* If we have received a configure event since
6257 * the last time in this function, we need to
6258 * accept our new size and size_allocate child widgets.
6259 * (see gtk_window_configure_event() for more details).
6261 * 1 or more configure notifies may have been received.
6262 * Also, configure_notify_received will only be TRUE
6263 * if all expected configure notifies have been received
6264 * (one per configure request), as an optimization.
6267 window->configure_notify_received = FALSE;
6269 /* gtk_window_configure_event() filled in widget->allocation */
6270 allocation = widget->allocation;
6271 gtk_widget_size_allocate (widget, &allocation);
6273 gdk_window_process_updates (widget->window, TRUE);
6275 gdk_window_configure_finished (widget->window);
6277 /* If the configure request changed, it means that
6279 * 1) coincidentally changed hints or widget properties
6280 * impacting the configure request before getting
6281 * a configure notify, or
6282 * 2) some broken widget is changing its size request
6283 * during size allocation, resulting in
6284 * a false appearance of changed configure request.
6286 * For 1), we could just go ahead and ask for the
6287 * new size right now, but doing that for 2)
6288 * might well be fighting the user (and can even
6289 * trigger a loop). Since we really don't want to
6290 * do that, we requeue a resize in hopes that
6291 * by the time it gets handled, the child has seen
6292 * the light and is willing to go along with the
6293 * new size. (this happens for the zvt widget, since
6294 * the size_allocate() above will have stored the
6295 * requisition corresponding to the new size in the
6298 * This doesn't buy us anything for 1), but it shouldn't
6299 * hurt us too badly, since it is what would have
6300 * happened if we had gotten the configure event before
6301 * the new size had been set.
6304 if (configure_request_size_changed ||
6305 configure_request_pos_changed)
6307 /* Don't change the recorded last info after all, because we
6308 * haven't actually updated to the new info yet - we decided
6309 * to postpone our configure request until later.
6311 info->last = saved_last_info;
6313 gtk_widget_queue_resize_no_redraw (widget); /* migth recurse for GTK_RESIZE_IMMEDIATE */
6316 return; /* Bail out, we didn't really process the move/resize */
6318 else if ((configure_request_size_changed || hints_changed) &&
6319 (widget->allocation.width != new_request.width ||
6320 widget->allocation.height != new_request.height))
6323 /* We are in one of the following situations:
6324 * A. configure_request_size_changed
6325 * our requisition has changed and we need a different window size,
6326 * so we request it from the window manager.
6327 * B. !configure_request_size_changed && hints_changed
6328 * the window manager rejects our size, but we have just changed the
6329 * window manager hints, so there's a chance our request will
6330 * be honoured this time, so we try again.
6332 * However, if the new requisition is the same as the current allocation,
6333 * we don't request it again, since we won't get a ConfigureNotify back from
6334 * the window manager unless it decides to change our requisition. If
6335 * we don't get the ConfigureNotify back, the resize queue will never be run.
6338 /* Now send the configure request */
6339 if (configure_request_pos_changed)
6343 gdk_window_move_resize (window->frame,
6344 new_request.x - window->frame_left,
6345 new_request.y - window->frame_top,
6346 new_request.width + window->frame_left + window->frame_right,
6347 new_request.height + window->frame_top + window->frame_bottom);
6348 gdk_window_resize (widget->window,
6349 new_request.width, new_request.height);
6352 gdk_window_move_resize (widget->window,
6353 new_request.x, new_request.y,
6354 new_request.width, new_request.height);
6356 else /* only size changed */
6359 gdk_window_resize (window->frame,
6360 new_request.width + window->frame_left + window->frame_right,
6361 new_request.height + window->frame_top + window->frame_bottom);
6362 gdk_window_resize (widget->window,
6363 new_request.width, new_request.height);
6366 if (window->type == GTK_WINDOW_POPUP)
6368 GtkAllocation allocation;
6370 /* Directly size allocate for override redirect (popup) windows. */
6373 allocation.width = new_request.width;
6374 allocation.height = new_request.height;
6376 gtk_widget_size_allocate (widget, &allocation);
6378 gdk_window_process_updates (widget->window, TRUE);
6380 if (container->resize_mode == GTK_RESIZE_QUEUE)
6381 gtk_widget_queue_draw (widget);
6385 /* Increment the number of have-not-yet-received-notify requests */
6386 window->configure_request_count += 1;
6387 gdk_window_freeze_toplevel_updates_libgtk_only (widget->window);
6389 /* for GTK_RESIZE_QUEUE toplevels, we are now awaiting a new
6390 * configure event in response to our resizing request.
6391 * the configure event will cause a new resize with
6392 * ->configure_notify_received=TRUE.
6393 * until then, we want to
6394 * - discard expose events
6395 * - coalesce resizes for our children
6396 * - defer any window resizes until the configure event arrived
6397 * to achieve this, we queue a resize for the window, but remove its
6398 * resizing handler, so resizing will not be handled from the next
6399 * idle handler but when the configure event arrives.
6401 * FIXME: we should also dequeue the pending redraws here, since
6402 * we handle those ourselves upon ->configure_notify_received==TRUE.
6404 if (container->resize_mode == GTK_RESIZE_QUEUE)
6406 gtk_widget_queue_resize_no_redraw (widget);
6407 _gtk_container_dequeue_resize_handler (container);
6413 /* Handle any position changes.
6415 if (configure_request_pos_changed)
6419 gdk_window_move (window->frame,
6420 new_request.x - window->frame_left,
6421 new_request.y - window->frame_top);
6424 gdk_window_move (widget->window,
6425 new_request.x, new_request.y);
6428 /* And run the resize queue.
6430 gtk_container_resize_children (container);
6433 /* We have now processed a move/resize since the last position
6434 * constraint change, setting of the initial position, or resize.
6435 * (Not resetting these flags here can lead to infinite loops for
6436 * GTK_RESIZE_IMMEDIATE containers)
6438 info->position_constraints_changed = FALSE;
6439 info->initial_pos_set = FALSE;
6440 info->resize_width = -1;
6441 info->resize_height = -1;
6444 /* Compare two sets of Geometry hints for equality.
6447 gtk_window_compare_hints (GdkGeometry *geometry_a,
6449 GdkGeometry *geometry_b,
6452 if (flags_a != flags_b)
6455 if ((flags_a & GDK_HINT_MIN_SIZE) &&
6456 (geometry_a->min_width != geometry_b->min_width ||
6457 geometry_a->min_height != geometry_b->min_height))
6460 if ((flags_a & GDK_HINT_MAX_SIZE) &&
6461 (geometry_a->max_width != geometry_b->max_width ||
6462 geometry_a->max_height != geometry_b->max_height))
6465 if ((flags_a & GDK_HINT_BASE_SIZE) &&
6466 (geometry_a->base_width != geometry_b->base_width ||
6467 geometry_a->base_height != geometry_b->base_height))
6470 if ((flags_a & GDK_HINT_ASPECT) &&
6471 (geometry_a->min_aspect != geometry_b->min_aspect ||
6472 geometry_a->max_aspect != geometry_b->max_aspect))
6475 if ((flags_a & GDK_HINT_RESIZE_INC) &&
6476 (geometry_a->width_inc != geometry_b->width_inc ||
6477 geometry_a->height_inc != geometry_b->height_inc))
6480 if ((flags_a & GDK_HINT_WIN_GRAVITY) &&
6481 geometry_a->win_gravity != geometry_b->win_gravity)
6488 _gtk_window_constrain_size (GtkWindow *window,
6494 GtkWindowGeometryInfo *info;
6496 g_return_if_fail (GTK_IS_WINDOW (window));
6498 info = window->geometry_info;
6501 GdkWindowHints flags = info->last.flags;
6502 GdkGeometry *geometry = &info->last.geometry;
6504 gtk_window_constrain_size (window,
6515 gtk_window_constrain_size (GtkWindow *window,
6516 GdkGeometry *geometry,
6523 gdk_window_constrain_size (geometry, flags, width, height,
6524 new_width, new_height);
6527 /* Compute the set of geometry hints and flags for a window
6528 * based on the application set geometry, and requisiition
6529 * of the window. gtk_widget_size_request() must have been
6533 gtk_window_compute_hints (GtkWindow *window,
6534 GdkGeometry *new_geometry,
6538 gint extra_width = 0;
6539 gint extra_height = 0;
6540 GtkWindowGeometryInfo *geometry_info;
6541 GtkRequisition requisition;
6543 widget = GTK_WIDGET (window);
6545 gtk_widget_get_child_requisition (widget, &requisition);
6546 geometry_info = gtk_window_get_geometry_info (GTK_WINDOW (widget), FALSE);
6550 *new_flags = geometry_info->mask;
6551 *new_geometry = geometry_info->geometry;
6558 if (geometry_info && geometry_info->widget)
6560 GtkRequisition child_requisition;
6562 /* FIXME: This really isn't right. It gets the min size wrong and forces
6563 * callers to do horrible hacks like set a huge usize on the child requisition
6564 * to get the base size right. We really want to find the answers to:
6566 * - If the geometry widget was infinitely big, how much extra space
6567 * would be needed for the stuff around it.
6569 * - If the geometry widget was infinitely small, how big would the
6570 * window still have to be.
6572 * Finding these answers would be a bit of a mess here. (Bug #68668)
6574 gtk_widget_get_child_requisition (geometry_info->widget, &child_requisition);
6576 extra_width = widget->requisition.width - child_requisition.width;
6577 extra_height = widget->requisition.height - child_requisition.height;
6580 /* We don't want to set GDK_HINT_POS in here, we just set it
6581 * in gtk_window_move_resize() when we want the position
6585 if (*new_flags & GDK_HINT_BASE_SIZE)
6587 new_geometry->base_width += extra_width;
6588 new_geometry->base_height += extra_height;
6590 else if (!(*new_flags & GDK_HINT_MIN_SIZE) &&
6591 (*new_flags & GDK_HINT_RESIZE_INC) &&
6592 ((extra_width != 0) || (extra_height != 0)))
6594 *new_flags |= GDK_HINT_BASE_SIZE;
6596 new_geometry->base_width = extra_width;
6597 new_geometry->base_height = extra_height;
6600 if (*new_flags & GDK_HINT_MIN_SIZE)
6602 if (new_geometry->min_width < 0)
6603 new_geometry->min_width = requisition.width;
6605 new_geometry->min_width += extra_width;
6607 if (new_geometry->min_height < 0)
6608 new_geometry->min_height = requisition.height;
6610 new_geometry->min_height += extra_height;
6612 else if (!window->allow_shrink)
6614 *new_flags |= GDK_HINT_MIN_SIZE;
6616 new_geometry->min_width = requisition.width;
6617 new_geometry->min_height = requisition.height;
6620 if (*new_flags & GDK_HINT_MAX_SIZE)
6622 if (new_geometry->max_width < 0)
6623 new_geometry->max_width = requisition.width;
6625 new_geometry->max_width += extra_width;
6627 if (new_geometry->max_height < 0)
6628 new_geometry->max_height = requisition.height;
6630 new_geometry->max_height += extra_height;
6632 else if (!window->allow_grow)
6634 *new_flags |= GDK_HINT_MAX_SIZE;
6636 new_geometry->max_width = requisition.width;
6637 new_geometry->max_height = requisition.height;
6640 *new_flags |= GDK_HINT_WIN_GRAVITY;
6641 new_geometry->win_gravity = window->gravity;
6644 /***********************
6645 * Redrawing functions *
6646 ***********************/
6649 gtk_window_paint (GtkWidget *widget,
6652 gtk_paint_flat_box (widget->style, widget->window, GTK_STATE_NORMAL,
6653 GTK_SHADOW_NONE, area, widget, "base", 0, 0, -1, -1);
6657 gtk_window_expose (GtkWidget *widget,
6658 GdkEventExpose *event)
6660 if (!gtk_widget_get_app_paintable (widget))
6661 gtk_window_paint (widget, &event->area);
6663 if (GTK_WIDGET_CLASS (gtk_window_parent_class)->expose_event)
6664 return GTK_WIDGET_CLASS (gtk_window_parent_class)->expose_event (widget, event);
6670 * gtk_window_set_has_frame:
6671 * @window: a #GtkWindow
6672 * @setting: a boolean
6674 * (Note: this is a special-purpose function for the framebuffer port,
6675 * that causes GTK+ to draw its own window border. For most applications,
6676 * you want gtk_window_set_decorated() instead, which tells the window
6677 * manager whether to draw the window border.)
6679 * If this function is called on a window with setting of %TRUE, before
6680 * it is realized or showed, it will have a "frame" window around
6681 * @window->window, accessible in @window->frame. Using the signal
6682 * frame_event you can receive all events targeted at the frame.
6684 * This function is used by the linux-fb port to implement managed
6685 * windows, but it could conceivably be used by X-programs that
6686 * want to do their own window decorations.
6690 gtk_window_set_has_frame (GtkWindow *window,
6693 g_return_if_fail (GTK_IS_WINDOW (window));
6694 g_return_if_fail (!gtk_widget_get_realized (GTK_WIDGET (window)));
6696 window->has_frame = setting != FALSE;
6700 * gtk_window_get_has_frame:
6701 * @window: a #GtkWindow
6703 * Accessor for whether the window has a frame window exterior to
6704 * @window->window. Gets the value set by gtk_window_set_has_frame ().
6706 * Return value: %TRUE if a frame has been added to the window
6707 * via gtk_window_set_has_frame().
6710 gtk_window_get_has_frame (GtkWindow *window)
6712 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
6714 return window->has_frame;
6718 * gtk_window_set_frame_dimensions:
6719 * @window: a #GtkWindow that has a frame
6720 * @left: The width of the left border
6721 * @top: The height of the top border
6722 * @right: The width of the right border
6723 * @bottom: The height of the bottom border
6725 * (Note: this is a special-purpose function intended for the framebuffer
6726 * port; see gtk_window_set_has_frame(). It will have no effect on the
6727 * window border drawn by the window manager, which is the normal
6728 * case when using the X Window system.)
6730 * For windows with frames (see gtk_window_set_has_frame()) this function
6731 * can be used to change the size of the frame border.
6734 gtk_window_set_frame_dimensions (GtkWindow *window,
6742 g_return_if_fail (GTK_IS_WINDOW (window));
6744 widget = GTK_WIDGET (window);
6746 if (window->frame_left == left &&
6747 window->frame_top == top &&
6748 window->frame_right == right &&
6749 window->frame_bottom == bottom)
6752 window->frame_left = left;
6753 window->frame_top = top;
6754 window->frame_right = right;
6755 window->frame_bottom = bottom;
6757 if (gtk_widget_get_realized (widget) && window->frame)
6759 gint width = widget->allocation.width + left + right;
6760 gint height = widget->allocation.height + top + bottom;
6761 gdk_window_resize (window->frame, width, height);
6762 gtk_decorated_window_move_resize_window (window,
6764 widget->allocation.width,
6765 widget->allocation.height);
6770 * gtk_window_present:
6771 * @window: a #GtkWindow
6773 * Presents a window to the user. This may mean raising the window
6774 * in the stacking order, deiconifying it, moving it to the current
6775 * desktop, and/or giving it the keyboard focus, possibly dependent
6776 * on the user's platform, window manager, and preferences.
6778 * If @window is hidden, this function calls gtk_widget_show()
6781 * This function should be used when the user tries to open a window
6782 * that's already open. Say for example the preferences dialog is
6783 * currently open, and the user chooses Preferences from the menu
6784 * a second time; use gtk_window_present() to move the already-open dialog
6785 * where the user can see it.
6787 * If you are calling this function in response to a user interaction,
6788 * it is preferable to use gtk_window_present_with_time().
6792 gtk_window_present (GtkWindow *window)
6794 gtk_window_present_with_time (window, GDK_CURRENT_TIME);
6798 * gtk_window_present_with_time:
6799 * @window: a #GtkWindow
6800 * @timestamp: the timestamp of the user interaction (typically a
6801 * button or key press event) which triggered this call
6803 * Presents a window to the user in response to a user interaction.
6804 * If you need to present a window without a timestamp, use
6805 * gtk_window_present(). See gtk_window_present() for details.
6810 gtk_window_present_with_time (GtkWindow *window,
6815 g_return_if_fail (GTK_IS_WINDOW (window));
6817 widget = GTK_WIDGET (window);
6819 if (gtk_widget_get_visible (widget))
6821 g_assert (widget->window != NULL);
6823 gdk_window_show (widget->window);
6825 /* Translate a timestamp of GDK_CURRENT_TIME appropriately */
6826 if (timestamp == GDK_CURRENT_TIME)
6828 #ifdef GDK_WINDOWING_X11
6829 GdkDisplay *display;
6831 display = gtk_widget_get_display (GTK_WIDGET (window));
6832 timestamp = gdk_x11_display_get_user_time (display);
6834 timestamp = gtk_get_current_event_time ();
6838 gdk_window_focus (widget->window, timestamp);
6842 gtk_widget_show (widget);
6847 * gtk_window_iconify:
6848 * @window: a #GtkWindow
6850 * Asks to iconify (i.e. minimize) the specified @window. Note that
6851 * you shouldn't assume the window is definitely iconified afterward,
6852 * because other entities (e.g. the user or <link
6853 * linkend="gtk-X11-arch">window manager</link>) could deiconify it
6854 * again, or there may not be a window manager in which case
6855 * iconification isn't possible, etc. But normally the window will end
6856 * up iconified. Just don't write code that crashes if not.
6858 * It's permitted to call this function before showing a window,
6859 * in which case the window will be iconified before it ever appears
6862 * You can track iconification via the "window-state-event" signal
6867 gtk_window_iconify (GtkWindow *window)
6870 GdkWindow *toplevel;
6872 g_return_if_fail (GTK_IS_WINDOW (window));
6874 widget = GTK_WIDGET (window);
6876 window->iconify_initially = TRUE;
6879 toplevel = window->frame;
6881 toplevel = widget->window;
6883 if (toplevel != NULL)
6884 gdk_window_iconify (toplevel);
6888 * gtk_window_deiconify:
6889 * @window: a #GtkWindow
6891 * Asks to deiconify (i.e. unminimize) the specified @window. Note
6892 * that you shouldn't assume the window is definitely deiconified
6893 * afterward, because other entities (e.g. the user or <link
6894 * linkend="gtk-X11-arch">window manager</link>) could iconify it
6895 * again before your code which assumes deiconification gets to run.
6897 * You can track iconification via the "window-state-event" signal
6901 gtk_window_deiconify (GtkWindow *window)
6904 GdkWindow *toplevel;
6906 g_return_if_fail (GTK_IS_WINDOW (window));
6908 widget = GTK_WIDGET (window);
6910 window->iconify_initially = FALSE;
6913 toplevel = window->frame;
6915 toplevel = widget->window;
6917 if (toplevel != NULL)
6918 gdk_window_deiconify (toplevel);
6923 * @window: a #GtkWindow
6925 * Asks to stick @window, which means that it will appear on all user
6926 * desktops. Note that you shouldn't assume the window is definitely
6927 * stuck afterward, because other entities (e.g. the user or <link
6928 * linkend="gtk-X11-arch">window manager</link>) could unstick it
6929 * again, and some window managers do not support sticking
6930 * windows. But normally the window will end up stuck. Just don't
6931 * write code that crashes if not.
6933 * It's permitted to call this function before showing a window.
6935 * You can track stickiness via the "window-state-event" signal
6940 gtk_window_stick (GtkWindow *window)
6943 GdkWindow *toplevel;
6945 g_return_if_fail (GTK_IS_WINDOW (window));
6947 widget = GTK_WIDGET (window);
6949 window->stick_initially = TRUE;
6952 toplevel = window->frame;
6954 toplevel = widget->window;
6956 if (toplevel != NULL)
6957 gdk_window_stick (toplevel);
6961 * gtk_window_unstick:
6962 * @window: a #GtkWindow
6964 * Asks to unstick @window, which means that it will appear on only
6965 * one of the user's desktops. Note that you shouldn't assume the
6966 * window is definitely unstuck afterward, because other entities
6967 * (e.g. the user or <link linkend="gtk-X11-arch">window
6968 * manager</link>) could stick it again. But normally the window will
6969 * end up stuck. Just don't write code that crashes if not.
6971 * You can track stickiness via the "window-state-event" signal
6976 gtk_window_unstick (GtkWindow *window)
6979 GdkWindow *toplevel;
6981 g_return_if_fail (GTK_IS_WINDOW (window));
6983 widget = GTK_WIDGET (window);
6985 window->stick_initially = FALSE;
6988 toplevel = window->frame;
6990 toplevel = widget->window;
6992 if (toplevel != NULL)
6993 gdk_window_unstick (toplevel);
6997 * gtk_window_maximize:
6998 * @window: a #GtkWindow
7000 * Asks to maximize @window, so that it becomes full-screen. Note that
7001 * you shouldn't assume the window is definitely maximized afterward,
7002 * because other entities (e.g. the user or <link
7003 * linkend="gtk-X11-arch">window manager</link>) could unmaximize it
7004 * again, and not all window managers support maximization. But
7005 * normally the window will end up maximized. Just don't write code
7006 * that crashes if not.
7008 * It's permitted to call this function before showing a window,
7009 * in which case the window will be maximized when it appears onscreen
7012 * You can track maximization via the "window-state-event" signal
7017 gtk_window_maximize (GtkWindow *window)
7020 GdkWindow *toplevel;
7022 g_return_if_fail (GTK_IS_WINDOW (window));
7024 widget = GTK_WIDGET (window);
7026 window->maximize_initially = TRUE;
7029 toplevel = window->frame;
7031 toplevel = widget->window;
7033 if (toplevel != NULL)
7034 gdk_window_maximize (toplevel);
7038 * gtk_window_unmaximize:
7039 * @window: a #GtkWindow
7041 * Asks to unmaximize @window. Note that you shouldn't assume the
7042 * window is definitely unmaximized afterward, because other entities
7043 * (e.g. the user or <link linkend="gtk-X11-arch">window
7044 * manager</link>) could maximize it again, and not all window
7045 * managers honor requests to unmaximize. But normally the window will
7046 * end up unmaximized. Just don't write code that crashes if not.
7048 * You can track maximization via the "window-state-event" signal
7053 gtk_window_unmaximize (GtkWindow *window)
7056 GdkWindow *toplevel;
7058 g_return_if_fail (GTK_IS_WINDOW (window));
7060 widget = GTK_WIDGET (window);
7062 window->maximize_initially = FALSE;
7065 toplevel = window->frame;
7067 toplevel = widget->window;
7069 if (toplevel != NULL)
7070 gdk_window_unmaximize (toplevel);
7074 * gtk_window_fullscreen:
7075 * @window: a #GtkWindow
7077 * Asks to place @window in the fullscreen state. Note that you
7078 * shouldn't assume the window is definitely full screen afterward,
7079 * because other entities (e.g. the user or <link
7080 * linkend="gtk-X11-arch">window manager</link>) could unfullscreen it
7081 * again, and not all window managers honor requests to fullscreen
7082 * windows. But normally the window will end up fullscreen. Just
7083 * don't write code that crashes if not.
7085 * You can track the fullscreen state via the "window-state-event" signal
7091 gtk_window_fullscreen (GtkWindow *window)
7094 GdkWindow *toplevel;
7095 GtkWindowPrivate *priv;
7097 g_return_if_fail (GTK_IS_WINDOW (window));
7099 widget = GTK_WIDGET (window);
7100 priv = GTK_WINDOW_GET_PRIVATE (window);
7102 priv->fullscreen_initially = TRUE;
7105 toplevel = window->frame;
7107 toplevel = widget->window;
7109 if (toplevel != NULL)
7110 gdk_window_fullscreen (toplevel);
7114 * gtk_window_unfullscreen:
7115 * @window: a #GtkWindow
7117 * Asks to toggle off the fullscreen state for @window. Note that you
7118 * shouldn't assume the window is definitely not full screen
7119 * afterward, because other entities (e.g. the user or <link
7120 * linkend="gtk-X11-arch">window manager</link>) could fullscreen it
7121 * again, and not all window managers honor requests to unfullscreen
7122 * windows. But normally the window will end up restored to its normal
7123 * state. Just don't write code that crashes if not.
7125 * You can track the fullscreen state via the "window-state-event" signal
7131 gtk_window_unfullscreen (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 = FALSE;
7145 toplevel = window->frame;
7147 toplevel = widget->window;
7149 if (toplevel != NULL)
7150 gdk_window_unfullscreen (toplevel);
7154 * gtk_window_set_keep_above:
7155 * @window: a #GtkWindow
7156 * @setting: whether to keep @window above other windows
7158 * Asks to keep @window above, so that it stays on top. Note that
7159 * you shouldn't assume the window is definitely above afterward,
7160 * because other entities (e.g. the user or <link
7161 * linkend="gtk-X11-arch">window manager</link>) could not keep it above,
7162 * and not all window managers support keeping windows above. But
7163 * normally the window will end kept above. Just don't write code
7164 * that crashes if not.
7166 * It's permitted to call this function before showing a window,
7167 * in which case the window will be kept above when it appears onscreen
7170 * You can track the above state via the "window-state-event" signal
7173 * Note that, according to the <ulink
7174 * url="http://www.freedesktop.org/Standards/wm-spec">Extended Window
7175 * Manager Hints</ulink> specification, the above state is mainly meant
7176 * for user preferences and should not be used by applications e.g. for
7177 * drawing attention to their dialogs.
7182 gtk_window_set_keep_above (GtkWindow *window,
7186 GtkWindowPrivate *priv;
7187 GdkWindow *toplevel;
7189 g_return_if_fail (GTK_IS_WINDOW (window));
7191 widget = GTK_WIDGET (window);
7192 priv = GTK_WINDOW_GET_PRIVATE (window);
7194 priv->above_initially = setting != FALSE;
7196 priv->below_initially = FALSE;
7199 toplevel = window->frame;
7201 toplevel = widget->window;
7203 if (toplevel != NULL)
7204 gdk_window_set_keep_above (toplevel, setting);
7208 * gtk_window_set_keep_below:
7209 * @window: a #GtkWindow
7210 * @setting: whether to keep @window below other windows
7212 * Asks to keep @window below, so that it stays in bottom. Note that
7213 * you shouldn't assume the window is definitely below afterward,
7214 * because other entities (e.g. the user or <link
7215 * linkend="gtk-X11-arch">window manager</link>) could not keep it below,
7216 * and not all window managers support putting windows below. But
7217 * normally the window will be kept below. Just don't write code
7218 * that crashes if not.
7220 * It's permitted to call this function before showing a window,
7221 * in which case the window will be kept below when it appears onscreen
7224 * You can track the below state via the "window-state-event" signal
7227 * Note that, according to the <ulink
7228 * url="http://www.freedesktop.org/Standards/wm-spec">Extended Window
7229 * Manager Hints</ulink> specification, the above state is mainly meant
7230 * for user preferences and should not be used by applications e.g. for
7231 * drawing attention to their dialogs.
7236 gtk_window_set_keep_below (GtkWindow *window,
7240 GtkWindowPrivate *priv;
7241 GdkWindow *toplevel;
7243 g_return_if_fail (GTK_IS_WINDOW (window));
7245 widget = GTK_WIDGET (window);
7246 priv = GTK_WINDOW_GET_PRIVATE (window);
7248 priv->below_initially = setting != FALSE;
7250 priv->above_initially = FALSE;
7253 toplevel = window->frame;
7255 toplevel = widget->window;
7257 if (toplevel != NULL)
7258 gdk_window_set_keep_below (toplevel, setting);
7262 * gtk_window_set_resizable:
7263 * @window: a #GtkWindow
7264 * @resizable: %TRUE if the user can resize this window
7266 * Sets whether the user can resize a window. Windows are user resizable
7270 gtk_window_set_resizable (GtkWindow *window,
7273 g_return_if_fail (GTK_IS_WINDOW (window));
7275 gtk_window_set_policy_internal (window, FALSE, resizable, FALSE);
7279 * gtk_window_get_resizable:
7280 * @window: a #GtkWindow
7282 * Gets the value set by gtk_window_set_resizable().
7284 * Return value: %TRUE if the user can resize the window
7287 gtk_window_get_resizable (GtkWindow *window)
7289 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
7291 /* allow_grow is most likely to indicate the semantic concept we
7292 * mean by "resizable" (and will be a reliable indicator if
7293 * set_policy() hasn't been called)
7295 return window->allow_grow;
7299 * gtk_window_set_gravity:
7300 * @window: a #GtkWindow
7301 * @gravity: window gravity
7303 * Window gravity defines the meaning of coordinates passed to
7304 * gtk_window_move(). See gtk_window_move() and #GdkGravity for
7307 * The default window gravity is #GDK_GRAVITY_NORTH_WEST which will
7308 * typically "do what you mean."
7312 gtk_window_set_gravity (GtkWindow *window,
7315 g_return_if_fail (GTK_IS_WINDOW (window));
7317 if (gravity != window->gravity)
7319 window->gravity = gravity;
7321 /* gtk_window_move_resize() will adapt gravity
7323 gtk_widget_queue_resize_no_redraw (GTK_WIDGET (window));
7325 g_object_notify (G_OBJECT (window), "gravity");
7330 * gtk_window_get_gravity:
7331 * @window: a #GtkWindow
7333 * Gets the value set by gtk_window_set_gravity().
7335 * Return value: (transfer none): window gravity
7338 gtk_window_get_gravity (GtkWindow *window)
7340 g_return_val_if_fail (GTK_IS_WINDOW (window), 0);
7342 return window->gravity;
7346 * gtk_window_begin_resize_drag:
7347 * @window: a #GtkWindow
7348 * @button: mouse button that initiated the drag
7349 * @edge: position of the resize control
7350 * @root_x: X position where the user clicked to initiate the drag, in root window coordinates
7351 * @root_y: Y position where the user clicked to initiate the drag
7352 * @timestamp: timestamp from the click event that initiated the drag
7354 * Starts resizing a window. This function is used if an application
7355 * has window resizing controls. When GDK can support it, the resize
7356 * will be done using the standard mechanism for the <link
7357 * linkend="gtk-X11-arch">window manager</link> or windowing
7358 * system. Otherwise, GDK will try to emulate window resizing,
7359 * potentially not all that well, depending on the windowing system.
7363 gtk_window_begin_resize_drag (GtkWindow *window,
7371 GdkWindow *toplevel;
7373 g_return_if_fail (GTK_IS_WINDOW (window));
7374 widget = GTK_WIDGET (window);
7375 g_return_if_fail (gtk_widget_get_visible (widget));
7378 toplevel = window->frame;
7380 toplevel = widget->window;
7382 gdk_window_begin_resize_drag (toplevel,
7389 * gtk_window_get_frame_dimensions:
7390 * @window: a #GtkWindow
7391 * @left: (allow-none): location to store the width of the frame at the left, or %NULL
7392 * @top: (allow-none): location to store the height of the frame at the top, or %NULL
7393 * @right: (allow-none): location to store the width of the frame at the returns, or %NULL
7394 * @bottom: (allow-none): location to store the height of the frame at the bottom, or %NULL
7396 * (Note: this is a special-purpose function intended for the
7397 * framebuffer port; see gtk_window_set_has_frame(). It will not
7398 * return the size of the window border drawn by the <link
7399 * linkend="gtk-X11-arch">window manager</link>, which is the normal
7400 * case when using a windowing system. See
7401 * gdk_window_get_frame_extents() to get the standard window border
7404 * Retrieves the dimensions of the frame window for this toplevel.
7405 * See gtk_window_set_has_frame(), gtk_window_set_frame_dimensions().
7408 gtk_window_get_frame_dimensions (GtkWindow *window,
7414 g_return_if_fail (GTK_IS_WINDOW (window));
7417 *left = window->frame_left;
7419 *top = window->frame_top;
7421 *right = window->frame_right;
7423 *bottom = window->frame_bottom;
7427 * gtk_window_begin_move_drag:
7428 * @window: a #GtkWindow
7429 * @button: mouse button that initiated the drag
7430 * @root_x: X position where the user clicked to initiate the drag, in root window coordinates
7431 * @root_y: Y position where the user clicked to initiate the drag
7432 * @timestamp: timestamp from the click event that initiated the drag
7434 * Starts moving a window. This function is used if an application has
7435 * window movement grips. When GDK can support it, the window movement
7436 * will be done using the standard mechanism for the <link
7437 * linkend="gtk-X11-arch">window manager</link> or windowing
7438 * system. Otherwise, GDK will try to emulate window movement,
7439 * potentially not all that well, depending on the windowing system.
7443 gtk_window_begin_move_drag (GtkWindow *window,
7450 GdkWindow *toplevel;
7452 g_return_if_fail (GTK_IS_WINDOW (window));
7453 widget = GTK_WIDGET (window);
7454 g_return_if_fail (gtk_widget_get_visible (widget));
7457 toplevel = window->frame;
7459 toplevel = widget->window;
7461 gdk_window_begin_move_drag (toplevel,
7468 * gtk_window_set_screen:
7469 * @window: a #GtkWindow.
7470 * @screen: a #GdkScreen.
7472 * Sets the #GdkScreen where the @window is displayed; if
7473 * the window is already mapped, it will be unmapped, and
7474 * then remapped on the new screen.
7479 gtk_window_set_screen (GtkWindow *window,
7483 GdkScreen *previous_screen;
7484 gboolean was_mapped;
7486 g_return_if_fail (GTK_IS_WINDOW (window));
7487 g_return_if_fail (GDK_IS_SCREEN (screen));
7489 if (screen == window->screen)
7492 widget = GTK_WIDGET (window);
7494 previous_screen = window->screen;
7495 was_mapped = gtk_widget_get_mapped (widget);
7498 gtk_widget_unmap (widget);
7499 if (gtk_widget_get_realized (widget))
7500 gtk_widget_unrealize (widget);
7502 gtk_window_free_key_hash (window);
7503 window->screen = screen;
7504 gtk_widget_reset_rc_styles (widget);
7505 if (screen != previous_screen)
7507 g_signal_handlers_disconnect_by_func (previous_screen,
7508 gtk_window_on_composited_changed, window);
7509 g_signal_connect (screen, "composited-changed",
7510 G_CALLBACK (gtk_window_on_composited_changed), window);
7512 _gtk_widget_propagate_screen_changed (widget, previous_screen);
7513 _gtk_widget_propagate_composited_changed (widget);
7515 g_object_notify (G_OBJECT (window), "screen");
7518 gtk_widget_map (widget);
7522 gtk_window_on_composited_changed (GdkScreen *screen,
7525 gtk_widget_queue_draw (GTK_WIDGET (window));
7527 _gtk_widget_propagate_composited_changed (GTK_WIDGET (window));
7531 gtk_window_check_screen (GtkWindow *window)
7534 return window->screen;
7537 g_warning ("Screen for GtkWindow not set; you must always set\n"
7538 "a screen for a GtkWindow before using the window");
7544 * gtk_window_get_screen:
7545 * @window: a #GtkWindow.
7547 * Returns the #GdkScreen associated with @window.
7549 * Return value: (transfer none): a #GdkScreen.
7554 gtk_window_get_screen (GtkWindow *window)
7556 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
7558 return window->screen;
7562 * gtk_window_is_active:
7563 * @window: a #GtkWindow
7565 * Returns whether the window is part of the current active toplevel.
7566 * (That is, the toplevel window receiving keystrokes.)
7567 * The return value is %TRUE if the window is active toplevel
7568 * itself, but also if it is, say, a #GtkPlug embedded in the active toplevel.
7569 * You might use this function if you wanted to draw a widget
7570 * differently in an active window from a widget in an inactive window.
7571 * See gtk_window_has_toplevel_focus()
7573 * Return value: %TRUE if the window part of the current active window.
7578 gtk_window_is_active (GtkWindow *window)
7580 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
7582 return window->is_active;
7586 * gtk_window_has_toplevel_focus:
7587 * @window: a #GtkWindow
7589 * Returns whether the input focus is within this GtkWindow.
7590 * For real toplevel windows, this is identical to gtk_window_is_active(),
7591 * but for embedded windows, like #GtkPlug, the results will differ.
7593 * Return value: %TRUE if the input focus is within this GtkWindow
7598 gtk_window_has_toplevel_focus (GtkWindow *window)
7600 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
7602 return window->has_toplevel_focus;
7606 gtk_window_group_class_init (GtkWindowGroupClass *klass)
7611 gtk_window_group_get_type (void)
7613 static GType window_group_type = 0;
7615 if (!window_group_type)
7617 const GTypeInfo window_group_info =
7619 sizeof (GtkWindowGroupClass),
7620 NULL, /* base_init */
7621 NULL, /* base_finalize */
7622 (GClassInitFunc) gtk_window_group_class_init,
7623 NULL, /* class_finalize */
7624 NULL, /* class_data */
7625 sizeof (GtkWindowGroup),
7626 0, /* n_preallocs */
7627 (GInstanceInitFunc) NULL,
7630 window_group_type = g_type_register_static (G_TYPE_OBJECT, I_("GtkWindowGroup"),
7631 &window_group_info, 0);
7634 return window_group_type;
7638 * gtk_window_group_new:
7640 * Creates a new #GtkWindowGroup object. Grabs added with
7641 * gtk_grab_add() only affect windows within the same #GtkWindowGroup.
7643 * Return value: a new #GtkWindowGroup.
7646 gtk_window_group_new (void)
7648 return g_object_new (GTK_TYPE_WINDOW_GROUP, NULL);
7652 window_group_cleanup_grabs (GtkWindowGroup *group,
7656 GSList *to_remove = NULL;
7658 tmp_list = group->grabs;
7661 if (gtk_widget_get_toplevel (tmp_list->data) == (GtkWidget*) window)
7662 to_remove = g_slist_prepend (to_remove, g_object_ref (tmp_list->data));
7663 tmp_list = tmp_list->next;
7668 gtk_grab_remove (to_remove->data);
7669 g_object_unref (to_remove->data);
7670 to_remove = g_slist_delete_link (to_remove, to_remove);
7675 * gtk_window_group_add_window:
7676 * @window_group: a #GtkWindowGroup
7677 * @window: the #GtkWindow to add
7679 * Adds a window to a #GtkWindowGroup.
7682 gtk_window_group_add_window (GtkWindowGroup *window_group,
7685 g_return_if_fail (GTK_IS_WINDOW_GROUP (window_group));
7686 g_return_if_fail (GTK_IS_WINDOW (window));
7688 if (window->group != window_group)
7690 g_object_ref (window);
7691 g_object_ref (window_group);
7694 gtk_window_group_remove_window (window->group, window);
7696 window_group_cleanup_grabs (gtk_window_get_group (NULL), window);
7698 window->group = window_group;
7700 g_object_unref (window);
7705 * gtk_window_group_remove_window:
7706 * @window_group: a #GtkWindowGroup
7707 * @window: the #GtkWindow to remove
7709 * Removes a window from a #GtkWindowGroup.
7712 gtk_window_group_remove_window (GtkWindowGroup *window_group,
7715 g_return_if_fail (GTK_IS_WINDOW_GROUP (window_group));
7716 g_return_if_fail (GTK_IS_WINDOW (window));
7717 g_return_if_fail (window->group == window_group);
7719 g_object_ref (window);
7721 window_group_cleanup_grabs (window_group, window);
7722 window->group = NULL;
7724 g_object_unref (window_group);
7725 g_object_unref (window);
7729 * gtk_window_group_list_windows:
7730 * @window_group: a #GtkWindowGroup
7732 * Returns a list of the #GtkWindows that belong to @window_group.
7734 * Returns: (element-type GtkWidget) (transfer container): A newly-allocated list of
7735 * windows inside the group.
7740 gtk_window_group_list_windows (GtkWindowGroup *window_group)
7742 GList *toplevels, *toplevel, *group_windows;
7744 g_return_val_if_fail (GTK_IS_WINDOW_GROUP (window_group), NULL);
7746 group_windows = NULL;
7747 toplevels = gtk_window_list_toplevels ();
7749 for (toplevel = toplevels; toplevel; toplevel = toplevel->next)
7751 GtkWindow *window = toplevel->data;
7753 if (window_group == window->group)
7754 group_windows = g_list_prepend (group_windows, window);
7757 return g_list_reverse (group_windows);
7761 * gtk_window_get_group:
7762 * @window: (allow-none): a #GtkWindow, or %NULL
7764 * Returns the group for @window or the default group, if
7765 * @window is %NULL or if @window does not have an explicit
7768 * Returns: (transfer none): the #GtkWindowGroup for a window or the default group
7773 gtk_window_get_group (GtkWindow *window)
7775 if (window && window->group)
7776 return window->group;
7779 static GtkWindowGroup *default_group = NULL;
7782 default_group = gtk_window_group_new ();
7784 return default_group;
7788 /* Return the current grab widget of the given group
7791 _gtk_window_group_get_current_grab (GtkWindowGroup *window_group)
7793 if (window_group->grabs)
7794 return GTK_WIDGET (window_group->grabs->data);
7799 Derived from XParseGeometry() in XFree86
7801 Copyright 1985, 1986, 1987,1998 The Open Group
7803 All Rights Reserved.
7805 The above copyright notice and this permission notice shall be included
7806 in all copies or substantial portions of the Software.
7808 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
7809 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
7810 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
7811 IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
7812 OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
7813 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
7814 OTHER DEALINGS IN THE SOFTWARE.
7816 Except as contained in this notice, the name of The Open Group shall
7817 not be used in advertising or otherwise to promote the sale, use or
7818 other dealings in this Software without prior written authorization
7819 from The Open Group.
7824 * XParseGeometry parses strings of the form
7825 * "=<width>x<height>{+-}<xoffset>{+-}<yoffset>", where
7826 * width, height, xoffset, and yoffset are unsigned integers.
7827 * Example: "=80x24+300-49"
7828 * The equal sign is optional.
7829 * It returns a bitmask that indicates which of the four values
7830 * were actually found in the string. For each value found,
7831 * the corresponding argument is updated; for each value
7832 * not found, the corresponding argument is left unchanged.
7835 /* The following code is from Xlib, and is minimally modified, so we
7836 * can track any upstream changes if required. Don't change this
7837 * code. Or if you do, put in a huge comment marking which thing
7842 read_int (gchar *string,
7850 else if (*string == '-')
7856 for (; (*string >= '0') && (*string <= '9'); string++)
7858 result = (result * 10) + (*string - '0');
7870 * Bitmask returned by XParseGeometry(). Each bit tells if the corresponding
7871 * value (x, y, width, height) was found in the parsed string.
7873 #define NoValue 0x0000
7874 #define XValue 0x0001
7875 #define YValue 0x0002
7876 #define WidthValue 0x0004
7877 #define HeightValue 0x0008
7878 #define AllValues 0x000F
7879 #define XNegative 0x0010
7880 #define YNegative 0x0020
7882 /* Try not to reformat/modify, so we can compare/sync with X sources */
7884 gtk_XParseGeometry (const char *string,
7887 unsigned int *width,
7888 unsigned int *height)
7892 unsigned int tempWidth, tempHeight;
7894 char *nextCharacter;
7896 /* These initializations are just to silence gcc */
7902 if ( (string == NULL) || (*string == '\0')) return(mask);
7904 string++; /* ignore possible '=' at beg of geometry spec */
7906 strind = (char *)string;
7907 if (*strind != '+' && *strind != '-' && *strind != 'x') {
7908 tempWidth = read_int(strind, &nextCharacter);
7909 if (strind == nextCharacter)
7911 strind = nextCharacter;
7915 if (*strind == 'x' || *strind == 'X') {
7917 tempHeight = read_int(strind, &nextCharacter);
7918 if (strind == nextCharacter)
7920 strind = nextCharacter;
7921 mask |= HeightValue;
7924 if ((*strind == '+') || (*strind == '-')) {
7925 if (*strind == '-') {
7927 tempX = -read_int(strind, &nextCharacter);
7928 if (strind == nextCharacter)
7930 strind = nextCharacter;
7936 tempX = read_int(strind, &nextCharacter);
7937 if (strind == nextCharacter)
7939 strind = nextCharacter;
7942 if ((*strind == '+') || (*strind == '-')) {
7943 if (*strind == '-') {
7945 tempY = -read_int(strind, &nextCharacter);
7946 if (strind == nextCharacter)
7948 strind = nextCharacter;
7955 tempY = read_int(strind, &nextCharacter);
7956 if (strind == nextCharacter)
7958 strind = nextCharacter;
7964 /* If strind isn't at the end of the string the it's an invalid
7965 geometry specification. */
7967 if (*strind != '\0') return (0);
7973 if (mask & WidthValue)
7975 if (mask & HeightValue)
7976 *height = tempHeight;
7981 * gtk_window_parse_geometry:
7982 * @window: a #GtkWindow
7983 * @geometry: geometry string
7985 * Parses a standard X Window System geometry string - see the
7986 * manual page for X (type 'man X') for details on this.
7987 * gtk_window_parse_geometry() does work on all GTK+ ports
7988 * including Win32 but is primarily intended for an X environment.
7990 * If either a size or a position can be extracted from the
7991 * geometry string, gtk_window_parse_geometry() returns %TRUE
7992 * and calls gtk_window_set_default_size() and/or gtk_window_move()
7993 * to resize/move the window.
7995 * If gtk_window_parse_geometry() returns %TRUE, it will also
7996 * set the #GDK_HINT_USER_POS and/or #GDK_HINT_USER_SIZE hints
7997 * indicating to the window manager that the size/position of
7998 * the window was user-specified. This causes most window
7999 * managers to honor the geometry.
8001 * Note that for gtk_window_parse_geometry() to work as expected, it has
8002 * to be called when the window has its "final" size, i.e. after calling
8003 * gtk_widget_show_all() on the contents and gtk_window_set_geometry_hints()
8006 * #include <gtk/gtk.h>
8009 * fill_with_content (GtkWidget *vbox)
8011 * /* fill with content... */
8015 * main (int argc, char *argv[])
8017 * GtkWidget *window, *vbox;
8018 * GdkGeometry size_hints = {
8019 * 100, 50, 0, 0, 100, 50, 10, 10, 0.0, 0.0, GDK_GRAVITY_NORTH_WEST
8022 * gtk_init (&argc, &argv);
8024 * window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
8025 * vbox = gtk_vbox_new (FALSE, 0);
8027 * gtk_container_add (GTK_CONTAINER (window), vbox);
8028 * fill_with_content (vbox);
8029 * gtk_widget_show_all (vbox);
8031 * gtk_window_set_geometry_hints (GTK_WINDOW (window),
8034 * GDK_HINT_MIN_SIZE |
8035 * GDK_HINT_BASE_SIZE |
8036 * GDK_HINT_RESIZE_INC);
8040 * if (!gtk_window_parse_geometry (GTK_WINDOW (window), argv[1]))
8041 * fprintf (stderr, "Failed to parse '%s'\n", argv[1]);
8044 * gtk_widget_show_all (window);
8051 * Return value: %TRUE if string was parsed successfully
8054 gtk_window_parse_geometry (GtkWindow *window,
8055 const gchar *geometry)
8057 gint result, x = 0, y = 0;
8060 gboolean size_set, pos_set;
8063 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
8064 g_return_val_if_fail (geometry != NULL, FALSE);
8066 screen = gtk_window_check_screen (window);
8068 result = gtk_XParseGeometry (geometry, &x, &y, &w, &h);
8071 if ((result & WidthValue) || (result & HeightValue))
8073 gtk_window_set_default_size_internal (window,
8074 TRUE, result & WidthValue ? w : -1,
8075 TRUE, result & HeightValue ? h : -1,
8080 gtk_window_get_size (window, (gint *)&w, (gint *)&h);
8082 grav = GDK_GRAVITY_NORTH_WEST;
8084 if ((result & XNegative) && (result & YNegative))
8085 grav = GDK_GRAVITY_SOUTH_EAST;
8086 else if (result & XNegative)
8087 grav = GDK_GRAVITY_NORTH_EAST;
8088 else if (result & YNegative)
8089 grav = GDK_GRAVITY_SOUTH_WEST;
8091 if ((result & XValue) == 0)
8094 if ((result & YValue) == 0)
8097 if (grav == GDK_GRAVITY_SOUTH_WEST ||
8098 grav == GDK_GRAVITY_SOUTH_EAST)
8099 y = gdk_screen_get_height (screen) - h + y;
8101 if (grav == GDK_GRAVITY_SOUTH_EAST ||
8102 grav == GDK_GRAVITY_NORTH_EAST)
8103 x = gdk_screen_get_width (screen) - w + x;
8105 /* we don't let you put a window offscreen; maybe some people would
8106 * prefer to be able to, but it's kind of a bogus thing to do.
8115 if ((result & XValue) || (result & YValue))
8117 gtk_window_set_gravity (window, grav);
8118 gtk_window_move (window, x, y);
8122 if (size_set || pos_set)
8124 /* Set USSize, USPosition hints */
8125 GtkWindowGeometryInfo *info;
8127 info = gtk_window_get_geometry_info (window, TRUE);
8130 info->mask |= GDK_HINT_USER_POS;
8132 info->mask |= GDK_HINT_USER_SIZE;
8139 gtk_window_mnemonic_hash_foreach (guint keyval,
8145 GtkWindowKeysForeachFunc func;
8149 (*info->func) (info->window, keyval, info->window->mnemonic_modifier, TRUE, info->func_data);
8153 _gtk_window_keys_foreach (GtkWindow *window,
8154 GtkWindowKeysForeachFunc func,
8158 GtkMnemonicHash *mnemonic_hash;
8162 GtkWindowKeysForeachFunc func;
8166 info.window = window;
8168 info.func_data = func_data;
8170 mnemonic_hash = gtk_window_get_mnemonic_hash (window, FALSE);
8172 _gtk_mnemonic_hash_foreach (mnemonic_hash,
8173 gtk_window_mnemonic_hash_foreach, &info);
8175 groups = gtk_accel_groups_from_object (G_OBJECT (window));
8178 GtkAccelGroup *group = groups->data;
8181 for (i = 0; i < group->n_accels; i++)
8183 GtkAccelKey *key = &group->priv_accels[i].key;
8186 (*func) (window, key->accel_key, key->accel_mods, FALSE, func_data);
8189 groups = groups->next;
8194 gtk_window_keys_changed (GtkWindow *window)
8196 gtk_window_free_key_hash (window);
8197 gtk_window_get_key_hash (window);
8200 typedef struct _GtkWindowKeyEntry GtkWindowKeyEntry;
8202 struct _GtkWindowKeyEntry
8206 guint is_mnemonic : 1;
8210 window_key_entry_destroy (gpointer data)
8212 g_slice_free (GtkWindowKeyEntry, data);
8216 add_to_key_hash (GtkWindow *window,
8218 GdkModifierType modifiers,
8219 gboolean is_mnemonic,
8222 GtkKeyHash *key_hash = data;
8224 GtkWindowKeyEntry *entry = g_slice_new (GtkWindowKeyEntry);
8226 entry->keyval = keyval;
8227 entry->modifiers = modifiers;
8228 entry->is_mnemonic = is_mnemonic;
8230 /* GtkAccelGroup stores lowercased accelerators. To deal
8231 * with this, if <Shift> was specified, uppercase.
8233 if (modifiers & GDK_SHIFT_MASK)
8235 if (keyval == GDK_Tab)
8236 keyval = GDK_ISO_Left_Tab;
8238 keyval = gdk_keyval_to_upper (keyval);
8241 _gtk_key_hash_add_entry (key_hash, keyval, entry->modifiers, entry);
8245 gtk_window_get_key_hash (GtkWindow *window)
8247 GdkScreen *screen = gtk_window_check_screen (window);
8248 GtkKeyHash *key_hash = g_object_get_qdata (G_OBJECT (window), quark_gtk_window_key_hash);
8253 key_hash = _gtk_key_hash_new (gdk_keymap_get_for_display (gdk_screen_get_display (screen)),
8254 (GDestroyNotify)window_key_entry_destroy);
8255 _gtk_window_keys_foreach (window, add_to_key_hash, key_hash);
8256 g_object_set_qdata (G_OBJECT (window), quark_gtk_window_key_hash, key_hash);
8262 gtk_window_free_key_hash (GtkWindow *window)
8264 GtkKeyHash *key_hash = g_object_get_qdata (G_OBJECT (window), quark_gtk_window_key_hash);
8267 _gtk_key_hash_free (key_hash);
8268 g_object_set_qdata (G_OBJECT (window), quark_gtk_window_key_hash, NULL);
8273 * gtk_window_activate_key:
8274 * @window: a #GtkWindow
8275 * @event: a #GdkEventKey
8277 * Activates mnemonics and accelerators for this #GtkWindow. This is normally
8278 * called by the default ::key_press_event handler for toplevel windows,
8279 * however in some cases it may be useful to call this directly when
8280 * overriding the standard key handling for a toplevel window.
8282 * Return value: %TRUE if a mnemonic or accelerator was found and activated.
8287 gtk_window_activate_key (GtkWindow *window,
8290 GtkKeyHash *key_hash;
8291 GtkWindowKeyEntry *found_entry = NULL;
8292 gboolean enable_mnemonics;
8293 gboolean enable_accels;
8295 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
8296 g_return_val_if_fail (event != NULL, FALSE);
8298 key_hash = gtk_window_get_key_hash (window);
8303 GSList *entries = _gtk_key_hash_lookup (key_hash,
8304 event->hardware_keycode,
8306 gtk_accelerator_get_default_mod_mask (),
8309 g_object_get (gtk_widget_get_settings (GTK_WIDGET (window)),
8310 "gtk-enable-mnemonics", &enable_mnemonics,
8311 "gtk-enable-accels", &enable_accels,
8314 for (tmp_list = entries; tmp_list; tmp_list = tmp_list->next)
8316 GtkWindowKeyEntry *entry = tmp_list->data;
8317 if (entry->is_mnemonic)
8319 if (enable_mnemonics)
8321 found_entry = entry;
8327 if (enable_accels && !found_entry)
8329 found_entry = entry;
8334 g_slist_free (entries);
8339 if (found_entry->is_mnemonic)
8341 if (enable_mnemonics)
8342 return gtk_window_mnemonic_activate (window, found_entry->keyval,
8343 found_entry->modifiers);
8348 return gtk_accel_groups_activate (G_OBJECT (window), found_entry->keyval,
8349 found_entry->modifiers);
8357 window_update_has_focus (GtkWindow *window)
8359 GtkWidget *widget = GTK_WIDGET (window);
8360 gboolean has_focus = window->has_toplevel_focus && window->is_active;
8362 if (has_focus != window->has_focus)
8364 window->has_focus = has_focus;
8368 if (window->focus_widget &&
8369 window->focus_widget != widget &&
8370 !gtk_widget_has_focus (window->focus_widget))
8371 do_focus_change (window->focus_widget, TRUE);
8375 if (window->focus_widget &&
8376 window->focus_widget != widget &&
8377 gtk_widget_has_focus (window->focus_widget))
8378 do_focus_change (window->focus_widget, FALSE);
8384 * _gtk_window_set_is_active:
8385 * @window: a #GtkWindow
8386 * @is_active: %TRUE if the window is in the currently active toplevel
8388 * Internal function that sets whether the #GtkWindow is part
8389 * of the currently active toplevel window (taking into account inter-process
8393 _gtk_window_set_is_active (GtkWindow *window,
8396 g_return_if_fail (GTK_IS_WINDOW (window));
8398 is_active = is_active != FALSE;
8400 if (is_active != window->is_active)
8402 window->is_active = is_active;
8403 window_update_has_focus (window);
8405 g_object_notify (G_OBJECT (window), "is-active");
8410 * _gtk_window_set_is_toplevel:
8411 * @window: a #GtkWindow
8412 * @is_toplevel: %TRUE if the window is still a real toplevel (nominally a
8413 * parent of the root window); %FALSE if it is not (for example, for an
8414 * in-process, parented GtkPlug)
8416 * Internal function used by #GtkPlug when it gets parented/unparented by a
8417 * #GtkSocket. This keeps the @window's #GTK_TOPLEVEL flag in sync with the
8418 * global list of toplevel windows.
8421 _gtk_window_set_is_toplevel (GtkWindow *window,
8422 gboolean is_toplevel)
8426 widget = GTK_WIDGET (window);
8428 if (gtk_widget_is_toplevel (widget))
8429 g_assert (g_slist_find (toplevel_list, window) != NULL);
8431 g_assert (g_slist_find (toplevel_list, window) == NULL);
8433 if (is_toplevel == gtk_widget_is_toplevel (widget))
8438 _gtk_widget_set_is_toplevel (widget, TRUE);
8439 toplevel_list = g_slist_prepend (toplevel_list, window);
8443 _gtk_widget_set_is_toplevel (widget, FALSE);
8444 toplevel_list = g_slist_remove (toplevel_list, window);
8449 * _gtk_window_set_has_toplevel_focus:
8450 * @window: a #GtkWindow
8451 * @has_toplevel_focus: %TRUE if the in
8453 * Internal function that sets whether the keyboard focus for the
8454 * toplevel window (taking into account inter-process embedding.)
8457 _gtk_window_set_has_toplevel_focus (GtkWindow *window,
8458 gboolean has_toplevel_focus)
8460 g_return_if_fail (GTK_IS_WINDOW (window));
8462 has_toplevel_focus = has_toplevel_focus != FALSE;
8464 if (has_toplevel_focus != window->has_toplevel_focus)
8466 window->has_toplevel_focus = has_toplevel_focus;
8467 window_update_has_focus (window);
8469 g_object_notify (G_OBJECT (window), "has-toplevel-focus");
8474 * gtk_window_set_auto_startup_notification:
8475 * @setting: %TRUE to automatically do startup notification
8477 * By default, after showing the first #GtkWindow, GTK+ calls
8478 * gdk_notify_startup_complete(). Call this function to disable
8479 * the automatic startup notification. You might do this if your
8480 * first window is a splash screen, and you want to delay notification
8481 * until after your real main window has been shown, for example.
8483 * In that example, you would disable startup notification
8484 * temporarily, show your splash screen, then re-enable it so that
8485 * showing the main window would automatically result in notification.
8490 gtk_window_set_auto_startup_notification (gboolean setting)
8492 disable_startup_notification = !setting;
8496 * gtk_window_get_window_type:
8497 * @window: a #GtkWindow
8499 * Gets the type of the window. See #GtkWindowType.
8501 * Return value: the type of the window
8506 gtk_window_get_window_type (GtkWindow *window)
8508 g_return_val_if_fail (GTK_IS_WINDOW (window), GTK_WINDOW_TOPLEVEL);
8510 return window->type;
8513 /* gtk_window_get_mnemonics_visible:
8514 * @window: a #GtkWindow
8516 * Gets the value of the #GtkWindow:mnemonics-visible property.
8518 * Returns: %TRUE if mnemonics are supposed to be visible
8524 gtk_window_get_mnemonics_visible (GtkWindow *window)
8526 GtkWindowPrivate *priv;
8528 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
8530 priv = GTK_WINDOW_GET_PRIVATE (window);
8532 return priv->mnemonics_visible;
8536 * gtk_window_set_mnemonics_visible:
8537 * @window: a #GtkWindow
8538 * @setting: the new value
8540 * Sets the #GtkWindow:mnemonics-visible property.
8545 gtk_window_set_mnemonics_visible (GtkWindow *window,
8548 GtkWindowPrivate *priv;
8550 g_return_if_fail (GTK_IS_WINDOW (window));
8552 priv = GTK_WINDOW_GET_PRIVATE (window);
8554 setting = setting != FALSE;
8556 if (priv->mnemonics_visible != setting)
8558 priv->mnemonics_visible = setting;
8559 g_object_notify (G_OBJECT (window), "mnemonics-visible");
8562 priv->mnemonics_visible_set = TRUE;
8565 #if defined (G_OS_WIN32) && !defined (_WIN64)
8567 #undef gtk_window_set_icon_from_file
8570 gtk_window_set_icon_from_file (GtkWindow *window,
8571 const gchar *filename,
8574 gchar *utf8_filename = g_locale_to_utf8 (filename, -1, NULL, NULL, err);
8577 if (utf8_filename == NULL)
8580 retval = gtk_window_set_icon_from_file_utf8 (window, utf8_filename, err);
8582 g_free (utf8_filename);
8587 #undef gtk_window_set_default_icon_from_file
8590 gtk_window_set_default_icon_from_file (const gchar *filename,
8593 gchar *utf8_filename = g_locale_to_utf8 (filename, -1, NULL, NULL, err);
8596 if (utf8_filename == NULL)
8599 retval = gtk_window_set_default_icon_from_file_utf8 (utf8_filename, err);
8601 g_free (utf8_filename);
8608 #define __GTK_WINDOW_C__
8609 #include "gtkaliasdef.c"