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 "gtkiconfactory.h"
46 #include "gtkicontheme.h"
47 #include "gtkmarshalers.h"
49 #include "gtkbuildable.h"
52 #ifdef GDK_WINDOWING_X11
81 PROP_DESTROY_WITH_PARENT,
86 PROP_SKIP_TASKBAR_HINT,
97 /* Readonly properties */
99 PROP_HAS_TOPLEVEL_FOCUS,
101 /* Writeonly properties */
104 PROP_MNEMONICS_VISIBLE,
112 GdkPixmap *icon_pixmap;
113 GdkPixmap *icon_mask;
116 guint using_default_icon : 1;
117 guint using_parent_icon : 1;
118 guint using_themed_icon : 1;
122 GdkGeometry geometry; /* Last set of geometry hints we set */
123 GdkWindowHints flags;
124 GdkRectangle configure_request;
125 } GtkWindowLastGeometryInfo;
127 struct _GtkWindowGeometryInfo
129 /* Properties that the app has set on the window
131 GdkGeometry geometry; /* Geometry hints */
133 GtkWidget *widget; /* subwidget to which hints apply */
134 /* from last gtk_window_resize () - if > 0, indicates that
135 * we should resize to this size.
140 /* From last gtk_window_move () prior to mapping -
141 * only used if initial_pos_set
146 /* Default size - used only the FIRST time we map a window,
151 /* whether to use initial_x, initial_y */
152 guint initial_pos_set : 1;
153 /* CENTER_ALWAYS or other position constraint changed since
154 * we sent the last configure request.
156 guint position_constraints_changed : 1;
158 /* if true, default_width, height come from gtk_window_parse_geometry,
159 * and thus should be multiplied by the increments and affect the
160 * geometry widget only
162 guint default_is_geometry : 1;
164 GtkWindowLastGeometryInfo last;
167 #define GTK_WINDOW_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GTK_TYPE_WINDOW, GtkWindowPrivate))
169 typedef struct _GtkWindowPrivate GtkWindowPrivate;
171 struct _GtkWindowPrivate
173 GtkMnemonicHash *mnemonic_hash;
175 guint above_initially : 1;
176 guint below_initially : 1;
177 guint fullscreen_initially : 1;
178 guint skips_taskbar : 1;
179 guint skips_pager : 1;
181 guint accept_focus : 1;
182 guint focus_on_map : 1;
184 guint transient_parent_group : 1;
186 guint reset_type_hint : 1;
187 guint opacity_set : 1;
188 guint builder_visible : 1;
190 guint mnemonics_visible : 1;
191 guint mnemonics_visible_set : 1;
193 GdkWindowTypeHint type_hint;
200 static void gtk_window_dispose (GObject *object);
201 static void gtk_window_destroy (GtkObject *object);
202 static void gtk_window_finalize (GObject *object);
203 static void gtk_window_show (GtkWidget *widget);
204 static void gtk_window_hide (GtkWidget *widget);
205 static void gtk_window_map (GtkWidget *widget);
206 static void gtk_window_unmap (GtkWidget *widget);
207 static void gtk_window_realize (GtkWidget *widget);
208 static void gtk_window_unrealize (GtkWidget *widget);
209 static void gtk_window_size_request (GtkWidget *widget,
210 GtkRequisition *requisition);
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_grab_notify (GtkWidget *widget,
239 gboolean was_grabbed);
240 static void gtk_window_real_set_focus (GtkWindow *window,
243 static void gtk_window_real_activate_default (GtkWindow *window);
244 static void gtk_window_real_activate_focus (GtkWindow *window);
245 static void gtk_window_move_focus (GtkWindow *window,
246 GtkDirectionType dir);
247 static void gtk_window_keys_changed (GtkWindow *window);
248 static void gtk_window_paint (GtkWidget *widget,
250 static gint gtk_window_expose (GtkWidget *widget,
251 GdkEventExpose *event);
252 static void gtk_window_unset_transient_for (GtkWindow *window);
253 static void gtk_window_transient_parent_realized (GtkWidget *parent,
255 static void gtk_window_transient_parent_unrealized (GtkWidget *parent,
258 static GdkScreen *gtk_window_check_screen (GtkWindow *window);
260 static GtkWindowGeometryInfo* gtk_window_get_geometry_info (GtkWindow *window,
263 static void gtk_window_move_resize (GtkWindow *window);
264 static gboolean gtk_window_compare_hints (GdkGeometry *geometry_a,
266 GdkGeometry *geometry_b,
268 static void gtk_window_constrain_size (GtkWindow *window,
269 GdkGeometry *geometry,
275 static void gtk_window_constrain_position (GtkWindow *window,
280 static void gtk_window_compute_hints (GtkWindow *window,
281 GdkGeometry *new_geometry,
283 static void gtk_window_compute_configure_request (GtkWindow *window,
284 GdkRectangle *request,
285 GdkGeometry *geometry,
288 static void gtk_window_set_default_size_internal (GtkWindow *window,
289 gboolean change_width,
291 gboolean change_height,
293 gboolean is_geometry);
295 static void update_themed_icon (GtkIconTheme *theme,
297 static GList *icon_list_from_theme (GtkWidget *widget,
299 static void gtk_window_realize_icon (GtkWindow *window);
300 static void gtk_window_unrealize_icon (GtkWindow *window);
302 static void gtk_window_notify_keys_changed (GtkWindow *window);
303 static GtkKeyHash *gtk_window_get_key_hash (GtkWindow *window);
304 static void gtk_window_free_key_hash (GtkWindow *window);
305 static void gtk_window_on_composited_changed (GdkScreen *screen,
308 static GSList *toplevel_list = NULL;
309 static guint window_signals[LAST_SIGNAL] = { 0 };
310 static GList *default_icon_list = NULL;
311 static gchar *default_icon_name = NULL;
312 static guint default_icon_serial = 0;
313 static gboolean disable_startup_notification = FALSE;
314 static gboolean sent_startup_notification = FALSE;
316 static GQuark quark_gtk_embedded = 0;
317 static GQuark quark_gtk_window_key_hash = 0;
318 static GQuark quark_gtk_window_default_icon_pixmap = 0;
319 static GQuark quark_gtk_window_icon_info = 0;
320 static GQuark quark_gtk_buildable_accels = 0;
322 static GtkBuildableIface *parent_buildable_iface;
324 static void gtk_window_set_property (GObject *object,
328 static void gtk_window_get_property (GObject *object,
334 static void gtk_window_buildable_interface_init (GtkBuildableIface *iface);
335 static void gtk_window_buildable_set_buildable_property (GtkBuildable *buildable,
338 const GValue *value);
339 static void gtk_window_buildable_parser_finished (GtkBuildable *buildable,
340 GtkBuilder *builder);
341 static gboolean gtk_window_buildable_custom_tag_start (GtkBuildable *buildable,
344 const gchar *tagname,
345 GMarkupParser *parser,
347 static void gtk_window_buildable_custom_finished (GtkBuildable *buildable,
350 const gchar *tagname,
354 G_DEFINE_TYPE_WITH_CODE (GtkWindow, gtk_window, GTK_TYPE_BIN,
355 G_IMPLEMENT_INTERFACE (GTK_TYPE_BUILDABLE,
356 gtk_window_buildable_interface_init))
359 add_tab_bindings (GtkBindingSet *binding_set,
360 GdkModifierType modifiers,
361 GtkDirectionType direction)
363 gtk_binding_entry_add_signal (binding_set, GDK_Tab, modifiers,
365 GTK_TYPE_DIRECTION_TYPE, direction);
366 gtk_binding_entry_add_signal (binding_set, GDK_KP_Tab, modifiers,
368 GTK_TYPE_DIRECTION_TYPE, direction);
372 add_arrow_bindings (GtkBindingSet *binding_set,
374 GtkDirectionType direction)
376 guint keypad_keysym = keysym - GDK_Left + GDK_KP_Left;
378 gtk_binding_entry_add_signal (binding_set, keysym, 0,
380 GTK_TYPE_DIRECTION_TYPE, direction);
381 gtk_binding_entry_add_signal (binding_set, keysym, GDK_CONTROL_MASK,
383 GTK_TYPE_DIRECTION_TYPE, direction);
384 gtk_binding_entry_add_signal (binding_set, keypad_keysym, 0,
386 GTK_TYPE_DIRECTION_TYPE, direction);
387 gtk_binding_entry_add_signal (binding_set, keypad_keysym, GDK_CONTROL_MASK,
389 GTK_TYPE_DIRECTION_TYPE, direction);
393 extract_time_from_startup_id (const gchar* startup_id)
395 gchar *timestr = g_strrstr (startup_id, "_TIME");
396 guint32 retval = GDK_CURRENT_TIME;
403 /* Skip past the "_TIME" part */
407 timestamp = strtoul (timestr, &end, 0);
408 if (end != timestr && errno == 0)
416 startup_id_is_fake (const gchar* startup_id)
418 return strncmp (startup_id, "_TIME", 5) == 0;
422 gtk_window_class_init (GtkWindowClass *klass)
424 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
425 GtkObjectClass *object_class;
426 GtkWidgetClass *widget_class;
427 GtkContainerClass *container_class;
428 GtkBindingSet *binding_set;
430 object_class = (GtkObjectClass*) klass;
431 widget_class = (GtkWidgetClass*) klass;
432 container_class = (GtkContainerClass*) klass;
434 quark_gtk_embedded = g_quark_from_static_string ("gtk-embedded");
435 quark_gtk_window_key_hash = g_quark_from_static_string ("gtk-window-key-hash");
436 quark_gtk_window_default_icon_pixmap = g_quark_from_static_string ("gtk-window-default-icon-pixmap");
437 quark_gtk_window_icon_info = g_quark_from_static_string ("gtk-window-icon-info");
438 quark_gtk_buildable_accels = g_quark_from_static_string ("gtk-window-buildable-accels");
440 gobject_class->dispose = gtk_window_dispose;
441 gobject_class->finalize = gtk_window_finalize;
443 gobject_class->set_property = gtk_window_set_property;
444 gobject_class->get_property = gtk_window_get_property;
446 object_class->destroy = gtk_window_destroy;
448 widget_class->show = gtk_window_show;
449 widget_class->hide = gtk_window_hide;
450 widget_class->map = gtk_window_map;
451 widget_class->map_event = gtk_window_map_event;
452 widget_class->unmap = gtk_window_unmap;
453 widget_class->realize = gtk_window_realize;
454 widget_class->unrealize = gtk_window_unrealize;
455 widget_class->size_request = gtk_window_size_request;
456 widget_class->size_allocate = gtk_window_size_allocate;
457 widget_class->configure_event = gtk_window_configure_event;
458 widget_class->key_press_event = gtk_window_key_press_event;
459 widget_class->key_release_event = gtk_window_key_release_event;
460 widget_class->enter_notify_event = gtk_window_enter_notify_event;
461 widget_class->leave_notify_event = gtk_window_leave_notify_event;
462 widget_class->focus_in_event = gtk_window_focus_in_event;
463 widget_class->focus_out_event = gtk_window_focus_out_event;
464 widget_class->client_event = gtk_window_client_event;
465 widget_class->focus = gtk_window_focus;
466 widget_class->expose_event = gtk_window_expose;
467 widget_class->grab_notify = gtk_window_grab_notify;
469 container_class->check_resize = gtk_window_check_resize;
471 klass->set_focus = gtk_window_real_set_focus;
472 klass->frame_event = gtk_window_frame_event;
474 klass->activate_default = gtk_window_real_activate_default;
475 klass->activate_focus = gtk_window_real_activate_focus;
476 klass->move_focus = gtk_window_move_focus;
477 klass->keys_changed = gtk_window_keys_changed;
479 g_type_class_add_private (gobject_class, sizeof (GtkWindowPrivate));
482 g_object_class_install_property (gobject_class,
484 g_param_spec_enum ("type",
486 P_("The type of the window"),
487 GTK_TYPE_WINDOW_TYPE,
489 GTK_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
491 g_object_class_install_property (gobject_class,
493 g_param_spec_string ("title",
495 P_("The title of the window"),
497 GTK_PARAM_READWRITE));
499 g_object_class_install_property (gobject_class,
501 g_param_spec_string ("role",
503 P_("Unique identifier for the window to be used when restoring a session"),
505 GTK_PARAM_READWRITE));
508 * GtkWindow:startup-id:
510 * The :startup-id is a write-only property for setting window's
511 * startup notification identifier. See gtk_window_set_startup_id()
516 g_object_class_install_property (gobject_class,
518 g_param_spec_string ("startup-id",
520 P_("Unique startup identifier for the window used by startup-notification"),
522 GTK_PARAM_WRITABLE));
524 g_object_class_install_property (gobject_class,
526 g_param_spec_boolean ("allow-shrink",
528 /* xgettext:no-c-format */
529 P_("If TRUE, the window has no mimimum size. Setting this to TRUE is 99% of the time a bad idea"),
531 GTK_PARAM_READWRITE));
533 g_object_class_install_property (gobject_class,
535 g_param_spec_boolean ("allow-grow",
537 P_("If TRUE, users can expand the window beyond its minimum size"),
539 GTK_PARAM_READWRITE));
541 g_object_class_install_property (gobject_class,
543 g_param_spec_boolean ("resizable",
545 P_("If TRUE, users can resize the window"),
547 GTK_PARAM_READWRITE));
549 g_object_class_install_property (gobject_class,
551 g_param_spec_boolean ("modal",
553 P_("If TRUE, the window is modal (other windows are not usable while this one is up)"),
555 GTK_PARAM_READWRITE));
557 g_object_class_install_property (gobject_class,
559 g_param_spec_enum ("window-position",
560 P_("Window Position"),
561 P_("The initial position of the window"),
562 GTK_TYPE_WINDOW_POSITION,
564 GTK_PARAM_READWRITE));
566 g_object_class_install_property (gobject_class,
568 g_param_spec_int ("default-width",
570 P_("The default width of the window, used when initially showing the window"),
574 GTK_PARAM_READWRITE));
576 g_object_class_install_property (gobject_class,
578 g_param_spec_int ("default-height",
579 P_("Default Height"),
580 P_("The default height of the window, used when initially showing the window"),
584 GTK_PARAM_READWRITE));
586 g_object_class_install_property (gobject_class,
587 PROP_DESTROY_WITH_PARENT,
588 g_param_spec_boolean ("destroy-with-parent",
589 P_("Destroy with Parent"),
590 P_("If this window should be destroyed when the parent is destroyed"),
592 GTK_PARAM_READWRITE));
594 g_object_class_install_property (gobject_class,
596 g_param_spec_object ("icon",
598 P_("Icon for this window"),
600 GTK_PARAM_READWRITE));
601 g_object_class_install_property (gobject_class,
602 PROP_MNEMONICS_VISIBLE,
603 g_param_spec_boolean ("mnemonics-visible",
604 P_("Mnemonics Visible"),
605 P_("Whether mnemonics are currently visible in this window"),
607 GTK_PARAM_READWRITE));
610 * GtkWindow:icon-name:
612 * The :icon-name property specifies the name of the themed icon to
613 * use as the window icon. See #GtkIconTheme for more details.
617 g_object_class_install_property (gobject_class,
619 g_param_spec_string ("icon-name",
621 P_("Name of the themed icon for this window"),
623 GTK_PARAM_READWRITE));
625 g_object_class_install_property (gobject_class,
627 g_param_spec_object ("screen",
629 P_("The screen where this window will be displayed"),
631 GTK_PARAM_READWRITE));
633 g_object_class_install_property (gobject_class,
635 g_param_spec_boolean ("is-active",
637 P_("Whether the toplevel is the current active window"),
639 GTK_PARAM_READABLE));
641 g_object_class_install_property (gobject_class,
642 PROP_HAS_TOPLEVEL_FOCUS,
643 g_param_spec_boolean ("has-toplevel-focus",
644 P_("Focus in Toplevel"),
645 P_("Whether the input focus is within this GtkWindow"),
647 GTK_PARAM_READABLE));
649 g_object_class_install_property (gobject_class,
651 g_param_spec_enum ("type-hint",
653 P_("Hint to help the desktop environment understand what kind of window this is and how to treat it."),
654 GDK_TYPE_WINDOW_TYPE_HINT,
655 GDK_WINDOW_TYPE_HINT_NORMAL,
656 GTK_PARAM_READWRITE));
658 g_object_class_install_property (gobject_class,
659 PROP_SKIP_TASKBAR_HINT,
660 g_param_spec_boolean ("skip-taskbar-hint",
662 P_("TRUE if the window should not be in the task bar."),
664 GTK_PARAM_READWRITE));
666 g_object_class_install_property (gobject_class,
667 PROP_SKIP_PAGER_HINT,
668 g_param_spec_boolean ("skip-pager-hint",
670 P_("TRUE if the window should not be in the pager."),
672 GTK_PARAM_READWRITE));
674 g_object_class_install_property (gobject_class,
676 g_param_spec_boolean ("urgency-hint",
678 P_("TRUE if the window should be brought to the user's attention."),
680 GTK_PARAM_READWRITE));
683 * GtkWindow:accept-focus:
685 * Whether the window should receive the input focus.
689 g_object_class_install_property (gobject_class,
691 g_param_spec_boolean ("accept-focus",
693 P_("TRUE if the window should receive the input focus."),
695 GTK_PARAM_READWRITE));
698 * GtkWindow:focus-on-map:
700 * Whether the window should receive the input focus when mapped.
704 g_object_class_install_property (gobject_class,
706 g_param_spec_boolean ("focus-on-map",
708 P_("TRUE if the window should receive the input focus when mapped."),
710 GTK_PARAM_READWRITE));
713 * GtkWindow:decorated:
715 * Whether the window should be decorated by the window manager.
719 g_object_class_install_property (gobject_class,
721 g_param_spec_boolean ("decorated",
723 P_("Whether the window should be decorated by the window manager"),
725 GTK_PARAM_READWRITE));
728 * GtkWindow:deletable:
730 * Whether the window frame should have a close button.
734 g_object_class_install_property (gobject_class,
736 g_param_spec_boolean ("deletable",
738 P_("Whether the window frame should have a close button"),
740 GTK_PARAM_READWRITE));
746 * The window gravity of the window. See gtk_window_move() and #GdkGravity for
747 * more details about window gravity.
751 g_object_class_install_property (gobject_class,
753 g_param_spec_enum ("gravity",
755 P_("The window gravity of the window"),
757 GDK_GRAVITY_NORTH_WEST,
758 GTK_PARAM_READWRITE));
762 * GtkWindow:transient-for:
764 * The transient parent of the window. See gtk_window_set_transient_for() for
765 * more details about transient windows.
769 g_object_class_install_property (gobject_class,
771 g_param_spec_object ("transient-for",
772 P_("Transient for Window"),
773 P_("The transient parent of the dialog"),
775 GTK_PARAM_READWRITE| G_PARAM_CONSTRUCT));
780 * The requested opacity of the window. See gtk_window_set_opacity() for
781 * more details about window opacity.
785 g_object_class_install_property (gobject_class,
787 g_param_spec_double ("opacity",
788 P_("Opacity for Window"),
789 P_("The opacity of the window, from 0 to 1"),
793 GTK_PARAM_READWRITE));
795 window_signals[SET_FOCUS] =
796 g_signal_new (I_("set-focus"),
797 G_TYPE_FROM_CLASS (gobject_class),
799 G_STRUCT_OFFSET (GtkWindowClass, set_focus),
801 _gtk_marshal_VOID__OBJECT,
805 window_signals[FRAME_EVENT] =
806 g_signal_new (I_("frame-event"),
807 G_TYPE_FROM_CLASS (gobject_class),
809 G_STRUCT_OFFSET(GtkWindowClass, frame_event),
810 _gtk_boolean_handled_accumulator, NULL,
811 _gtk_marshal_BOOLEAN__BOXED,
816 * GtkWindow::activate-focus:
817 * @window: the window which received the signal
819 * The ::activate-default signal is a
820 * <link linkend="keybinding-signals">keybinding signal</link>
821 * which gets emitted when the user activates the currently
822 * focused widget of @window.
824 window_signals[ACTIVATE_FOCUS] =
825 g_signal_new (I_("activate-focus"),
826 G_TYPE_FROM_CLASS (gobject_class),
827 G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
828 G_STRUCT_OFFSET (GtkWindowClass, activate_focus),
830 _gtk_marshal_VOID__VOID,
835 * GtkWindow::activate-default:
836 * @window: the window which received the signal
838 * The ::activate-default signal is a
839 * <link linkend="keybinding-signals">keybinding signal</link>
840 * which gets emitted when the user activates the default widget
843 window_signals[ACTIVATE_DEFAULT] =
844 g_signal_new (I_("activate-default"),
845 G_TYPE_FROM_CLASS (gobject_class),
846 G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
847 G_STRUCT_OFFSET (GtkWindowClass, activate_default),
849 _gtk_marshal_VOID__VOID,
854 * GtkWindow::keys-changed:
855 * @window: the window which received the signal
857 * The ::keys-changed signal gets emitted when the set of accelerators
858 * or mnemonics that are associated with @window changes.
860 window_signals[KEYS_CHANGED] =
861 g_signal_new (I_("keys-changed"),
862 G_TYPE_FROM_CLASS (gobject_class),
864 G_STRUCT_OFFSET (GtkWindowClass, keys_changed),
866 _gtk_marshal_VOID__VOID,
874 binding_set = gtk_binding_set_by_class (klass);
876 gtk_binding_entry_add_signal (binding_set, GDK_space, 0,
877 "activate-focus", 0);
878 gtk_binding_entry_add_signal (binding_set, GDK_KP_Space, 0,
879 "activate-focus", 0);
881 gtk_binding_entry_add_signal (binding_set, GDK_Return, 0,
882 "activate-default", 0);
883 gtk_binding_entry_add_signal (binding_set, GDK_ISO_Enter, 0,
884 "activate-default", 0);
885 gtk_binding_entry_add_signal (binding_set, GDK_KP_Enter, 0,
886 "activate-default", 0);
888 add_arrow_bindings (binding_set, GDK_Up, GTK_DIR_UP);
889 add_arrow_bindings (binding_set, GDK_Down, GTK_DIR_DOWN);
890 add_arrow_bindings (binding_set, GDK_Left, GTK_DIR_LEFT);
891 add_arrow_bindings (binding_set, GDK_Right, GTK_DIR_RIGHT);
893 add_tab_bindings (binding_set, 0, GTK_DIR_TAB_FORWARD);
894 add_tab_bindings (binding_set, GDK_CONTROL_MASK, GTK_DIR_TAB_FORWARD);
895 add_tab_bindings (binding_set, GDK_SHIFT_MASK, GTK_DIR_TAB_BACKWARD);
896 add_tab_bindings (binding_set, GDK_CONTROL_MASK | GDK_SHIFT_MASK, GTK_DIR_TAB_BACKWARD);
900 gtk_window_init (GtkWindow *window)
902 GdkColormap *colormap;
903 GtkWindowPrivate *priv = GTK_WINDOW_GET_PRIVATE (window);
905 GTK_WIDGET_UNSET_FLAGS (window, GTK_NO_WINDOW);
906 GTK_WIDGET_SET_FLAGS (window, GTK_TOPLEVEL);
908 GTK_PRIVATE_SET_FLAG (window, GTK_ANCHORED);
910 gtk_container_set_resize_mode (GTK_CONTAINER (window), GTK_RESIZE_QUEUE);
912 window->title = NULL;
913 window->wmclass_name = g_strdup (g_get_prgname ());
914 window->wmclass_class = g_strdup (gdk_get_program_class ());
915 window->wm_role = NULL;
916 window->geometry_info = NULL;
917 window->type = GTK_WINDOW_TOPLEVEL;
918 window->focus_widget = NULL;
919 window->default_widget = NULL;
920 window->configure_request_count = 0;
921 window->allow_shrink = FALSE;
922 window->allow_grow = TRUE;
923 window->configure_notify_received = FALSE;
924 window->position = GTK_WIN_POS_NONE;
925 window->need_default_size = TRUE;
926 window->need_default_position = TRUE;
927 window->modal = FALSE;
928 window->frame = NULL;
929 window->has_frame = FALSE;
930 window->frame_left = 0;
931 window->frame_right = 0;
932 window->frame_top = 0;
933 window->frame_bottom = 0;
934 window->type_hint = GDK_WINDOW_TYPE_HINT_NORMAL;
935 window->gravity = GDK_GRAVITY_NORTH_WEST;
936 window->decorated = TRUE;
937 window->mnemonic_modifier = GDK_MOD1_MASK;
938 window->screen = gdk_screen_get_default ();
940 priv->accept_focus = TRUE;
941 priv->focus_on_map = TRUE;
942 priv->deletable = TRUE;
943 priv->type_hint = GDK_WINDOW_TYPE_HINT_NORMAL;
945 priv->startup_id = NULL;
946 priv->mnemonics_visible = TRUE;
948 colormap = _gtk_widget_peek_colormap ();
950 gtk_widget_set_colormap (GTK_WIDGET (window), colormap);
952 g_object_ref_sink (window);
953 window->has_user_ref_count = TRUE;
954 toplevel_list = g_slist_prepend (toplevel_list, window);
956 gtk_decorated_window_init (window);
958 g_signal_connect (window->screen, "composited-changed",
959 G_CALLBACK (gtk_window_on_composited_changed), window);
963 gtk_window_set_property (GObject *object,
969 GtkWindowPrivate *priv;
971 window = GTK_WINDOW (object);
973 priv = GTK_WINDOW_GET_PRIVATE (window);
978 window->type = g_value_get_enum (value);
981 gtk_window_set_title (window, g_value_get_string (value));
984 gtk_window_set_role (window, g_value_get_string (value));
986 case PROP_STARTUP_ID:
987 gtk_window_set_startup_id (window, g_value_get_string (value));
989 case PROP_ALLOW_SHRINK:
990 window->allow_shrink = g_value_get_boolean (value);
991 gtk_widget_queue_resize (GTK_WIDGET (window));
993 case PROP_ALLOW_GROW:
994 window->allow_grow = g_value_get_boolean (value);
995 gtk_widget_queue_resize (GTK_WIDGET (window));
996 g_object_notify (G_OBJECT (window), "resizable");
999 window->allow_grow = g_value_get_boolean (value);
1000 gtk_widget_queue_resize (GTK_WIDGET (window));
1001 g_object_notify (G_OBJECT (window), "allow-grow");
1004 gtk_window_set_modal (window, g_value_get_boolean (value));
1007 gtk_window_set_position (window, g_value_get_enum (value));
1009 case PROP_DEFAULT_WIDTH:
1010 gtk_window_set_default_size_internal (window,
1011 TRUE, g_value_get_int (value),
1014 case PROP_DEFAULT_HEIGHT:
1015 gtk_window_set_default_size_internal (window,
1017 TRUE, g_value_get_int (value), FALSE);
1019 case PROP_DESTROY_WITH_PARENT:
1020 gtk_window_set_destroy_with_parent (window, g_value_get_boolean (value));
1023 gtk_window_set_icon (window,
1024 g_value_get_object (value));
1026 case PROP_ICON_NAME:
1027 gtk_window_set_icon_name (window, g_value_get_string (value));
1030 gtk_window_set_screen (window, g_value_get_object (value));
1032 case PROP_TYPE_HINT:
1033 gtk_window_set_type_hint (window,
1034 g_value_get_enum (value));
1036 case PROP_SKIP_TASKBAR_HINT:
1037 gtk_window_set_skip_taskbar_hint (window,
1038 g_value_get_boolean (value));
1040 case PROP_SKIP_PAGER_HINT:
1041 gtk_window_set_skip_pager_hint (window,
1042 g_value_get_boolean (value));
1044 case PROP_URGENCY_HINT:
1045 gtk_window_set_urgency_hint (window,
1046 g_value_get_boolean (value));
1048 case PROP_ACCEPT_FOCUS:
1049 gtk_window_set_accept_focus (window,
1050 g_value_get_boolean (value));
1052 case PROP_FOCUS_ON_MAP:
1053 gtk_window_set_focus_on_map (window,
1054 g_value_get_boolean (value));
1056 case PROP_DECORATED:
1057 gtk_window_set_decorated (window, g_value_get_boolean (value));
1059 case PROP_DELETABLE:
1060 gtk_window_set_deletable (window, g_value_get_boolean (value));
1063 gtk_window_set_gravity (window, g_value_get_enum (value));
1065 case PROP_TRANSIENT_FOR:
1066 gtk_window_set_transient_for (window, g_value_get_object (value));
1069 gtk_window_set_opacity (window, g_value_get_double (value));
1071 case PROP_MNEMONICS_VISIBLE:
1072 gtk_window_set_mnemonics_visible (window, g_value_get_boolean (value));
1075 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1081 gtk_window_get_property (GObject *object,
1087 GtkWindowPrivate *priv;
1089 window = GTK_WINDOW (object);
1090 priv = GTK_WINDOW_GET_PRIVATE (window);
1094 GtkWindowGeometryInfo *info;
1096 g_value_set_enum (value, window->type);
1099 g_value_set_string (value, window->wm_role);
1102 g_value_set_string (value, window->title);
1104 case PROP_ALLOW_SHRINK:
1105 g_value_set_boolean (value, window->allow_shrink);
1107 case PROP_ALLOW_GROW:
1108 g_value_set_boolean (value, window->allow_grow);
1110 case PROP_RESIZABLE:
1111 g_value_set_boolean (value, window->allow_grow);
1114 g_value_set_boolean (value, window->modal);
1117 g_value_set_enum (value, window->position);
1119 case PROP_DEFAULT_WIDTH:
1120 info = gtk_window_get_geometry_info (window, FALSE);
1122 g_value_set_int (value, -1);
1124 g_value_set_int (value, info->default_width);
1126 case PROP_DEFAULT_HEIGHT:
1127 info = gtk_window_get_geometry_info (window, FALSE);
1129 g_value_set_int (value, -1);
1131 g_value_set_int (value, info->default_height);
1133 case PROP_DESTROY_WITH_PARENT:
1134 g_value_set_boolean (value, window->destroy_with_parent);
1137 g_value_set_object (value, gtk_window_get_icon (window));
1139 case PROP_ICON_NAME:
1140 g_value_set_string (value, gtk_window_get_icon_name (window));
1143 g_value_set_object (value, window->screen);
1145 case PROP_IS_ACTIVE:
1146 g_value_set_boolean (value, window->is_active);
1148 case PROP_HAS_TOPLEVEL_FOCUS:
1149 g_value_set_boolean (value, window->has_toplevel_focus);
1151 case PROP_TYPE_HINT:
1152 g_value_set_enum (value, priv->type_hint);
1154 case PROP_SKIP_TASKBAR_HINT:
1155 g_value_set_boolean (value,
1156 gtk_window_get_skip_taskbar_hint (window));
1158 case PROP_SKIP_PAGER_HINT:
1159 g_value_set_boolean (value,
1160 gtk_window_get_skip_pager_hint (window));
1162 case PROP_URGENCY_HINT:
1163 g_value_set_boolean (value,
1164 gtk_window_get_urgency_hint (window));
1166 case PROP_ACCEPT_FOCUS:
1167 g_value_set_boolean (value,
1168 gtk_window_get_accept_focus (window));
1170 case PROP_FOCUS_ON_MAP:
1171 g_value_set_boolean (value,
1172 gtk_window_get_focus_on_map (window));
1174 case PROP_DECORATED:
1175 g_value_set_boolean (value, gtk_window_get_decorated (window));
1177 case PROP_DELETABLE:
1178 g_value_set_boolean (value, gtk_window_get_deletable (window));
1181 g_value_set_enum (value, gtk_window_get_gravity (window));
1183 case PROP_TRANSIENT_FOR:
1184 g_value_set_object (value, gtk_window_get_transient_for (window));
1187 g_value_set_double (value, gtk_window_get_opacity (window));
1189 case PROP_MNEMONICS_VISIBLE:
1190 g_value_set_boolean (value, priv->mnemonics_visible);
1193 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1199 gtk_window_buildable_interface_init (GtkBuildableIface *iface)
1201 parent_buildable_iface = g_type_interface_peek_parent (iface);
1202 iface->set_buildable_property = gtk_window_buildable_set_buildable_property;
1203 iface->parser_finished = gtk_window_buildable_parser_finished;
1204 iface->custom_tag_start = gtk_window_buildable_custom_tag_start;
1205 iface->custom_finished = gtk_window_buildable_custom_finished;
1209 gtk_window_buildable_set_buildable_property (GtkBuildable *buildable,
1210 GtkBuilder *builder,
1212 const GValue *value)
1214 GtkWindowPrivate *priv = GTK_WINDOW_GET_PRIVATE (buildable);
1216 if (strcmp (name, "visible") == 0 && g_value_get_boolean (value))
1217 priv->builder_visible = TRUE;
1219 parent_buildable_iface->set_buildable_property (buildable, builder, name, value);
1223 gtk_window_buildable_parser_finished (GtkBuildable *buildable,
1224 GtkBuilder *builder)
1226 GtkWindowPrivate *priv = GTK_WINDOW_GET_PRIVATE (buildable);
1230 if (priv->builder_visible)
1231 gtk_widget_show (GTK_WIDGET (buildable));
1233 accels = g_object_get_qdata (G_OBJECT (buildable), quark_gtk_buildable_accels);
1234 for (l = accels; l; l = l->next)
1236 object = gtk_builder_get_object (builder, l->data);
1239 g_warning ("Unknown accel group %s specified in window %s",
1240 (const gchar*)l->data, gtk_buildable_get_name (buildable));
1243 gtk_window_add_accel_group (GTK_WINDOW (buildable),
1244 GTK_ACCEL_GROUP (object));
1248 g_object_set_qdata (G_OBJECT (buildable), quark_gtk_buildable_accels, NULL);
1250 parent_buildable_iface->parser_finished (buildable, builder);
1256 } GSListSubParserData;
1259 window_start_element (GMarkupParseContext *context,
1260 const gchar *element_name,
1261 const gchar **names,
1262 const gchar **values,
1267 GSListSubParserData *data = (GSListSubParserData*)user_data;
1269 if (strcmp (element_name, "group") == 0)
1271 for (i = 0; names[i]; i++)
1273 if (strcmp (names[i], "name") == 0)
1274 data->items = g_slist_prepend (data->items, g_strdup (values[i]));
1277 else if (strcmp (element_name, "accel-groups") == 0)
1280 g_warning ("Unsupported tag type for GtkWindow: %s\n",
1285 static const GMarkupParser window_parser =
1287 window_start_element
1291 gtk_window_buildable_custom_tag_start (GtkBuildable *buildable,
1292 GtkBuilder *builder,
1294 const gchar *tagname,
1295 GMarkupParser *parser,
1298 GSListSubParserData *parser_data;
1300 if (parent_buildable_iface->custom_tag_start (buildable, builder, child,
1301 tagname, parser, data))
1304 if (strcmp (tagname, "accel-groups") == 0)
1306 parser_data = g_slice_new0 (GSListSubParserData);
1307 parser_data->items = NULL;
1308 parser_data->object = G_OBJECT (buildable);
1310 *parser = window_parser;
1311 *data = parser_data;
1319 gtk_window_buildable_custom_finished (GtkBuildable *buildable,
1320 GtkBuilder *builder,
1322 const gchar *tagname,
1325 GSListSubParserData *data;
1327 parent_buildable_iface->custom_finished (buildable, builder, child,
1328 tagname, user_data);
1330 if (strcmp (tagname, "accel-groups") != 0)
1333 data = (GSListSubParserData*)user_data;
1335 g_object_set_qdata_full (G_OBJECT (buildable), quark_gtk_buildable_accels,
1336 data->items, (GDestroyNotify) g_slist_free);
1338 g_slice_free (GSListSubParserData, data);
1343 * @type: type of window
1345 * Creates a new #GtkWindow, which is a toplevel window that can
1346 * contain other widgets. Nearly always, the type of the window should
1347 * be #GTK_WINDOW_TOPLEVEL. If you're implementing something like a
1348 * popup menu from scratch (which is a bad idea, just use #GtkMenu),
1349 * you might use #GTK_WINDOW_POPUP. #GTK_WINDOW_POPUP is not for
1350 * dialogs, though in some other toolkits dialogs are called "popups".
1351 * In GTK+, #GTK_WINDOW_POPUP means a pop-up menu or pop-up tooltip.
1352 * On X11, popup windows are not controlled by the <link
1353 * linkend="gtk-X11-arch">window manager</link>.
1355 * If you simply want an undecorated window (no window borders), use
1356 * gtk_window_set_decorated(), don't use #GTK_WINDOW_POPUP.
1358 * Return value: a new #GtkWindow.
1361 gtk_window_new (GtkWindowType type)
1365 g_return_val_if_fail (type >= GTK_WINDOW_TOPLEVEL && type <= GTK_WINDOW_POPUP, NULL);
1367 window = g_object_new (GTK_TYPE_WINDOW, NULL);
1369 window->type = type;
1371 return GTK_WIDGET (window);
1375 * gtk_window_set_title:
1376 * @window: a #GtkWindow
1377 * @title: title of the window
1379 * Sets the title of the #GtkWindow. The title of a window will be
1380 * displayed in its title bar; on the X Window System, the title bar
1381 * is rendered by the <link linkend="gtk-X11-arch">window
1382 * manager</link>, so exactly how the title appears to users may vary
1383 * according to a user's exact configuration. The title should help a
1384 * user distinguish this window from other windows they may have
1385 * open. A good title might include the application name and current
1386 * document filename, for example.
1390 gtk_window_set_title (GtkWindow *window,
1395 g_return_if_fail (GTK_IS_WINDOW (window));
1397 new_title = g_strdup (title);
1398 g_free (window->title);
1399 window->title = new_title;
1401 if (GTK_WIDGET_REALIZED (window))
1403 gdk_window_set_title (GTK_WIDGET (window)->window, window->title);
1405 gtk_decorated_window_set_title (window, title);
1408 g_object_notify (G_OBJECT (window), "title");
1412 * gtk_window_get_title:
1413 * @window: a #GtkWindow
1415 * Retrieves the title of the window. See gtk_window_set_title().
1417 * Return value: the title of the window, or %NULL if none has
1418 * been set explicitely. The returned string is owned by the widget
1419 * and must not be modified or freed.
1421 G_CONST_RETURN gchar *
1422 gtk_window_get_title (GtkWindow *window)
1424 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
1426 return window->title;
1430 * gtk_window_set_wmclass:
1431 * @window: a #GtkWindow
1432 * @wmclass_name: window name hint
1433 * @wmclass_class: window class hint
1435 * Don't use this function. It sets the X Window System "class" and
1436 * "name" hints for a window. According to the ICCCM, you should
1437 * always set these to the same value for all windows in an
1438 * application, and GTK+ sets them to that value by default, so calling
1439 * this function is sort of pointless. However, you may want to call
1440 * gtk_window_set_role() on each window in your application, for the
1441 * benefit of the session manager. Setting the role allows the window
1442 * manager to restore window positions when loading a saved session.
1446 gtk_window_set_wmclass (GtkWindow *window,
1447 const gchar *wmclass_name,
1448 const gchar *wmclass_class)
1450 g_return_if_fail (GTK_IS_WINDOW (window));
1452 g_free (window->wmclass_name);
1453 window->wmclass_name = g_strdup (wmclass_name);
1455 g_free (window->wmclass_class);
1456 window->wmclass_class = g_strdup (wmclass_class);
1458 if (GTK_WIDGET_REALIZED (window))
1459 g_warning ("gtk_window_set_wmclass: shouldn't set wmclass after window is realized!\n");
1463 * gtk_window_set_role:
1464 * @window: a #GtkWindow
1465 * @role: unique identifier for the window to be used when restoring a session
1467 * This function is only useful on X11, not with other GTK+ targets.
1469 * In combination with the window title, the window role allows a
1470 * <link linkend="gtk-X11-arch">window manager</link> to identify "the
1471 * same" window when an application is restarted. So for example you
1472 * might set the "toolbox" role on your app's toolbox window, so that
1473 * when the user restarts their session, the window manager can put
1474 * the toolbox back in the same place.
1476 * If a window already has a unique title, you don't need to set the
1477 * role, since the WM can use the title to identify the window when
1478 * restoring the session.
1482 gtk_window_set_role (GtkWindow *window,
1487 g_return_if_fail (GTK_IS_WINDOW (window));
1489 new_role = g_strdup (role);
1490 g_free (window->wm_role);
1491 window->wm_role = new_role;
1493 if (GTK_WIDGET_REALIZED (window))
1494 gdk_window_set_role (GTK_WIDGET (window)->window, window->wm_role);
1496 g_object_notify (G_OBJECT (window), "role");
1500 * gtk_window_set_startup_id:
1501 * @window: a #GtkWindow
1502 * @startup_id: a string with startup-notification identifier
1504 * Startup notification identifiers are used by desktop environment to
1505 * track application startup, to provide user feedback and other
1506 * features. This function changes the corresponding property on the
1507 * underlying GdkWindow. Normally, startup identifier is managed
1508 * automatically and you should only use this function in special cases
1509 * like transferring focus from other processes. You should use this
1510 * function before calling gtk_window_present() or any equivalent
1511 * function generating a window map event.
1513 * This function is only useful on X11, not with other GTK+ targets.
1518 gtk_window_set_startup_id (GtkWindow *window,
1519 const gchar *startup_id)
1521 GtkWindowPrivate *priv = GTK_WINDOW_GET_PRIVATE (window);
1523 g_return_if_fail (GTK_IS_WINDOW (window));
1525 g_free (priv->startup_id);
1526 priv->startup_id = g_strdup (startup_id);
1528 if (GTK_WIDGET_REALIZED (window))
1530 guint32 timestamp = extract_time_from_startup_id (priv->startup_id);
1532 #ifdef GDK_WINDOWING_X11
1533 if (timestamp != GDK_CURRENT_TIME)
1534 gdk_x11_window_set_user_time (GTK_WIDGET (window)->window, timestamp);
1537 /* Here we differentiate real and "fake" startup notification IDs,
1538 * constructed on purpose just to pass interaction timestamp
1540 if (startup_id_is_fake (priv->startup_id))
1541 gtk_window_present_with_time (window, timestamp);
1544 gdk_window_set_startup_id (GTK_WIDGET (window)->window,
1547 /* If window is mapped, terminate the startup-notification too */
1548 if (GTK_WIDGET_MAPPED (window) && !disable_startup_notification)
1549 gdk_notify_startup_complete_with_id (priv->startup_id);
1553 g_object_notify (G_OBJECT (window), "startup-id");
1557 * gtk_window_get_role:
1558 * @window: a #GtkWindow
1560 * Returns the role of the window. See gtk_window_set_role() for
1561 * further explanation.
1563 * Return value: the role of the window if set, or %NULL. The
1564 * returned is owned by the widget and must not be modified
1567 G_CONST_RETURN gchar *
1568 gtk_window_get_role (GtkWindow *window)
1570 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
1572 return window->wm_role;
1576 * gtk_window_set_focus:
1577 * @window: a #GtkWindow
1578 * @focus: (allow-none): widget to be the new focus widget, or %NULL to unset
1579 * any focus widget for the toplevel window.
1581 * If @focus is not the current focus widget, and is focusable, sets
1582 * it as the focus widget for the window. If @focus is %NULL, unsets
1583 * the focus widget for this window. To set the focus to a particular
1584 * widget in the toplevel, it is usually more convenient to use
1585 * gtk_widget_grab_focus() instead of this function.
1588 gtk_window_set_focus (GtkWindow *window,
1591 g_return_if_fail (GTK_IS_WINDOW (window));
1594 g_return_if_fail (GTK_IS_WIDGET (focus));
1595 g_return_if_fail (GTK_WIDGET_CAN_FOCUS (focus));
1599 gtk_widget_grab_focus (focus);
1602 /* Clear the existing focus chain, so that when we focus into
1603 * the window again, we start at the beginnning.
1605 GtkWidget *widget = window->focus_widget;
1608 while (widget->parent)
1610 widget = widget->parent;
1611 gtk_container_set_focus_child (GTK_CONTAINER (widget), NULL);
1615 _gtk_window_internal_set_focus (window, NULL);
1620 _gtk_window_internal_set_focus (GtkWindow *window,
1623 g_return_if_fail (GTK_IS_WINDOW (window));
1625 if ((window->focus_widget != focus) ||
1626 (focus && !GTK_WIDGET_HAS_FOCUS (focus)))
1627 g_signal_emit (window, window_signals[SET_FOCUS], 0, focus);
1631 * gtk_window_set_default:
1632 * @window: a #GtkWindow
1633 * @default_widget: (allow-none): widget to be the default, or %NULL to unset the
1634 * default widget for the toplevel.
1636 * The default widget is the widget that's activated when the user
1637 * presses Enter in a dialog (for example). This function sets or
1638 * unsets the default widget for a #GtkWindow about. When setting
1639 * (rather than unsetting) the default widget it's generally easier to
1640 * call gtk_widget_grab_focus() on the widget. Before making a widget
1641 * the default widget, you must set the #GTK_CAN_DEFAULT flag on the
1642 * widget you'd like to make the default using GTK_WIDGET_SET_FLAGS().
1645 gtk_window_set_default (GtkWindow *window,
1646 GtkWidget *default_widget)
1648 g_return_if_fail (GTK_IS_WINDOW (window));
1651 g_return_if_fail (GTK_WIDGET_CAN_DEFAULT (default_widget));
1653 if (window->default_widget != default_widget)
1655 GtkWidget *old_default_widget = NULL;
1658 g_object_ref (default_widget);
1660 if (window->default_widget)
1662 old_default_widget = window->default_widget;
1664 if (window->focus_widget != window->default_widget ||
1665 !GTK_WIDGET_RECEIVES_DEFAULT (window->default_widget))
1666 GTK_WIDGET_UNSET_FLAGS (window->default_widget, GTK_HAS_DEFAULT);
1667 gtk_widget_queue_draw (window->default_widget);
1670 window->default_widget = default_widget;
1672 if (window->default_widget)
1674 if (window->focus_widget == NULL ||
1675 !GTK_WIDGET_RECEIVES_DEFAULT (window->focus_widget))
1676 GTK_WIDGET_SET_FLAGS (window->default_widget, GTK_HAS_DEFAULT);
1677 gtk_widget_queue_draw (window->default_widget);
1680 if (old_default_widget)
1681 g_object_notify (G_OBJECT (old_default_widget), "has-default");
1685 g_object_notify (G_OBJECT (default_widget), "has-default");
1686 g_object_unref (default_widget);
1692 * gtk_window_get_default_widget:
1693 * @window: a #GtkWindow
1695 * Returns the default widget for @window. See gtk_window_set_default()
1698 * Returns: the default widget, or %NULL if there is none.
1703 gtk_window_get_default_widget (GtkWindow *window)
1705 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
1707 return window->default_widget;
1711 gtk_window_set_policy_internal (GtkWindow *window,
1712 gboolean allow_shrink,
1713 gboolean allow_grow,
1714 gboolean auto_shrink)
1716 window->allow_shrink = (allow_shrink != FALSE);
1717 window->allow_grow = (allow_grow != FALSE);
1719 g_object_freeze_notify (G_OBJECT (window));
1720 g_object_notify (G_OBJECT (window), "allow-shrink");
1721 g_object_notify (G_OBJECT (window), "allow-grow");
1722 g_object_notify (G_OBJECT (window), "resizable");
1723 g_object_thaw_notify (G_OBJECT (window));
1725 gtk_widget_queue_resize_no_redraw (GTK_WIDGET (window));
1729 gtk_window_set_policy (GtkWindow *window,
1730 gboolean allow_shrink,
1731 gboolean allow_grow,
1732 gboolean auto_shrink)
1734 g_return_if_fail (GTK_IS_WINDOW (window));
1736 gtk_window_set_policy_internal (window, allow_shrink, allow_grow, auto_shrink);
1740 handle_keys_changed (gpointer data)
1744 window = GTK_WINDOW (data);
1746 if (window->keys_changed_handler)
1748 g_source_remove (window->keys_changed_handler);
1749 window->keys_changed_handler = 0;
1752 g_signal_emit (window, window_signals[KEYS_CHANGED], 0);
1758 gtk_window_notify_keys_changed (GtkWindow *window)
1760 if (!window->keys_changed_handler)
1761 window->keys_changed_handler = gdk_threads_add_idle (handle_keys_changed, window);
1765 * gtk_window_add_accel_group:
1766 * @window: window to attach accelerator group to
1767 * @accel_group: a #GtkAccelGroup
1769 * Associate @accel_group with @window, such that calling
1770 * gtk_accel_groups_activate() on @window will activate accelerators
1774 gtk_window_add_accel_group (GtkWindow *window,
1775 GtkAccelGroup *accel_group)
1777 g_return_if_fail (GTK_IS_WINDOW (window));
1778 g_return_if_fail (GTK_IS_ACCEL_GROUP (accel_group));
1780 _gtk_accel_group_attach (accel_group, G_OBJECT (window));
1781 g_signal_connect_object (accel_group, "accel-changed",
1782 G_CALLBACK (gtk_window_notify_keys_changed),
1783 window, G_CONNECT_SWAPPED);
1784 gtk_window_notify_keys_changed (window);
1788 * gtk_window_remove_accel_group:
1789 * @window: a #GtkWindow
1790 * @accel_group: a #GtkAccelGroup
1792 * Reverses the effects of gtk_window_add_accel_group().
1795 gtk_window_remove_accel_group (GtkWindow *window,
1796 GtkAccelGroup *accel_group)
1798 g_return_if_fail (GTK_IS_WINDOW (window));
1799 g_return_if_fail (GTK_IS_ACCEL_GROUP (accel_group));
1801 g_signal_handlers_disconnect_by_func (accel_group,
1802 gtk_window_notify_keys_changed,
1804 _gtk_accel_group_detach (accel_group, G_OBJECT (window));
1805 gtk_window_notify_keys_changed (window);
1808 static GtkMnemonicHash *
1809 gtk_window_get_mnemonic_hash (GtkWindow *window,
1812 GtkWindowPrivate *private = GTK_WINDOW_GET_PRIVATE (window);
1813 if (!private->mnemonic_hash && create)
1814 private->mnemonic_hash = _gtk_mnemonic_hash_new ();
1816 return private->mnemonic_hash;
1820 * gtk_window_add_mnemonic:
1821 * @window: a #GtkWindow
1822 * @keyval: the mnemonic
1823 * @target: the widget that gets activated by the mnemonic
1825 * Adds a mnemonic to this window.
1828 gtk_window_add_mnemonic (GtkWindow *window,
1832 g_return_if_fail (GTK_IS_WINDOW (window));
1833 g_return_if_fail (GTK_IS_WIDGET (target));
1835 _gtk_mnemonic_hash_add (gtk_window_get_mnemonic_hash (window, TRUE),
1837 gtk_window_notify_keys_changed (window);
1841 * gtk_window_remove_mnemonic:
1842 * @window: a #GtkWindow
1843 * @keyval: the mnemonic
1844 * @target: the widget that gets activated by the mnemonic
1846 * Removes a mnemonic from this window.
1849 gtk_window_remove_mnemonic (GtkWindow *window,
1853 g_return_if_fail (GTK_IS_WINDOW (window));
1854 g_return_if_fail (GTK_IS_WIDGET (target));
1856 _gtk_mnemonic_hash_remove (gtk_window_get_mnemonic_hash (window, TRUE),
1858 gtk_window_notify_keys_changed (window);
1862 * gtk_window_mnemonic_activate:
1863 * @window: a #GtkWindow
1864 * @keyval: the mnemonic
1865 * @modifier: the modifiers
1866 * @returns: %TRUE if the activation is done.
1868 * Activates the targets associated with the mnemonic.
1871 gtk_window_mnemonic_activate (GtkWindow *window,
1873 GdkModifierType modifier)
1875 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
1877 if (window->mnemonic_modifier == (modifier & gtk_accelerator_get_default_mod_mask ()))
1879 GtkMnemonicHash *mnemonic_hash = gtk_window_get_mnemonic_hash (window, FALSE);
1881 return _gtk_mnemonic_hash_activate (mnemonic_hash, keyval);
1888 * gtk_window_set_mnemonic_modifier:
1889 * @window: a #GtkWindow
1890 * @modifier: the modifier mask used to activate
1891 * mnemonics on this window.
1893 * Sets the mnemonic modifier for this window.
1896 gtk_window_set_mnemonic_modifier (GtkWindow *window,
1897 GdkModifierType modifier)
1899 g_return_if_fail (GTK_IS_WINDOW (window));
1900 g_return_if_fail ((modifier & ~GDK_MODIFIER_MASK) == 0);
1902 window->mnemonic_modifier = modifier;
1903 gtk_window_notify_keys_changed (window);
1907 * gtk_window_get_mnemonic_modifier:
1908 * @window: a #GtkWindow
1910 * Returns the mnemonic modifier for this window. See
1911 * gtk_window_set_mnemonic_modifier().
1913 * Return value: the modifier mask used to activate
1914 * mnemonics on this window.
1917 gtk_window_get_mnemonic_modifier (GtkWindow *window)
1919 g_return_val_if_fail (GTK_IS_WINDOW (window), 0);
1921 return window->mnemonic_modifier;
1925 * gtk_window_set_position:
1926 * @window: a #GtkWindow.
1927 * @position: a position constraint.
1929 * Sets a position constraint for this window. If the old or new
1930 * constraint is %GTK_WIN_POS_CENTER_ALWAYS, this will also cause
1931 * the window to be repositioned to satisfy the new constraint.
1934 gtk_window_set_position (GtkWindow *window,
1935 GtkWindowPosition position)
1937 g_return_if_fail (GTK_IS_WINDOW (window));
1939 if (position == GTK_WIN_POS_CENTER_ALWAYS ||
1940 window->position == GTK_WIN_POS_CENTER_ALWAYS)
1942 GtkWindowGeometryInfo *info;
1944 info = gtk_window_get_geometry_info (window, TRUE);
1946 /* this flag causes us to re-request the CENTER_ALWAYS
1947 * constraint in gtk_window_move_resize(), see
1948 * comment in that function.
1950 info->position_constraints_changed = TRUE;
1952 gtk_widget_queue_resize_no_redraw (GTK_WIDGET (window));
1955 window->position = position;
1957 g_object_notify (G_OBJECT (window), "window-position");
1961 * gtk_window_activate_focus:
1962 * @window: a #GtkWindow
1964 * Activates the current focused widget within the window.
1966 * Return value: %TRUE if a widget got activated.
1969 gtk_window_activate_focus (GtkWindow *window)
1971 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
1973 if (window->focus_widget && GTK_WIDGET_IS_SENSITIVE (window->focus_widget))
1974 return gtk_widget_activate (window->focus_widget);
1980 * gtk_window_get_focus:
1981 * @window: a #GtkWindow
1983 * Retrieves the current focused widget within the window.
1984 * Note that this is the widget that would have the focus
1985 * if the toplevel window focused; if the toplevel window
1986 * is not focused then <literal>GTK_WIDGET_HAS_FOCUS (widget)</literal> will
1987 * not be %TRUE for the widget.
1989 * Return value: (transfer none): the currently focused widget, or %NULL if there is none.
1992 gtk_window_get_focus (GtkWindow *window)
1994 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
1996 return window->focus_widget;
2000 * gtk_window_activate_default:
2001 * @window: a #GtkWindow
2003 * Activates the default widget for the window, unless the current
2004 * focused widget has been configured to receive the default action
2005 * (see #GTK_RECEIVES_DEFAULT in #GtkWidgetFlags), in which case the
2006 * focused widget is activated.
2008 * Return value: %TRUE if a widget got activated.
2011 gtk_window_activate_default (GtkWindow *window)
2013 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
2015 if (window->default_widget && GTK_WIDGET_IS_SENSITIVE (window->default_widget) &&
2016 (!window->focus_widget || !GTK_WIDGET_RECEIVES_DEFAULT (window->focus_widget)))
2017 return gtk_widget_activate (window->default_widget);
2018 else if (window->focus_widget && GTK_WIDGET_IS_SENSITIVE (window->focus_widget))
2019 return gtk_widget_activate (window->focus_widget);
2025 * gtk_window_set_modal:
2026 * @window: a #GtkWindow
2027 * @modal: whether the window is modal
2029 * Sets a window modal or non-modal. Modal windows prevent interaction
2030 * with other windows in the same application. To keep modal dialogs
2031 * on top of main application windows, use
2032 * gtk_window_set_transient_for() to make the dialog transient for the
2033 * parent; most <link linkend="gtk-X11-arch">window managers</link>
2034 * will then disallow lowering the dialog below the parent.
2039 gtk_window_set_modal (GtkWindow *window,
2042 g_return_if_fail (GTK_IS_WINDOW (window));
2044 modal = modal != FALSE;
2045 if (window->modal == modal)
2048 window->modal = modal;
2050 /* adjust desired modality state */
2051 if (GTK_WIDGET_REALIZED (window))
2053 GtkWidget *widget = GTK_WIDGET (window);
2056 gdk_window_set_modal_hint (widget->window, TRUE);
2058 gdk_window_set_modal_hint (widget->window, FALSE);
2061 if (GTK_WIDGET_VISIBLE (window))
2064 gtk_grab_add (GTK_WIDGET (window));
2066 gtk_grab_remove (GTK_WIDGET (window));
2069 g_object_notify (G_OBJECT (window), "modal");
2073 * gtk_window_get_modal:
2074 * @window: a #GtkWindow
2076 * Returns whether the window is modal. See gtk_window_set_modal().
2078 * Return value: %TRUE if the window is set to be modal and
2079 * establishes a grab when shown
2082 gtk_window_get_modal (GtkWindow *window)
2084 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
2086 return window->modal;
2090 * gtk_window_list_toplevels:
2092 * Returns a list of all existing toplevel windows. The widgets
2093 * in the list are not individually referenced. If you want
2094 * to iterate through the list and perform actions involving
2095 * callbacks that might destroy the widgets, you <emphasis>must</emphasis> call
2096 * <literal>g_list_foreach (result, (GFunc)g_object_ref, NULL)</literal> first, and
2097 * then unref all the widgets afterwards.
2099 * Return value: (element-type GtkWidget) (transfer container): list of toplevel widgets
2102 gtk_window_list_toplevels (void)
2107 for (slist = toplevel_list; slist; slist = slist->next)
2108 list = g_list_prepend (list, slist->data);
2114 gtk_window_add_embedded_xid (GtkWindow *window, GdkNativeWindow xid)
2116 GList *embedded_windows;
2118 g_return_if_fail (GTK_IS_WINDOW (window));
2120 embedded_windows = g_object_get_qdata (G_OBJECT (window), quark_gtk_embedded);
2121 if (embedded_windows)
2122 g_object_steal_qdata (G_OBJECT (window), quark_gtk_embedded);
2123 embedded_windows = g_list_prepend (embedded_windows,
2124 GUINT_TO_POINTER (xid));
2126 g_object_set_qdata_full (G_OBJECT (window), quark_gtk_embedded,
2129 (GDestroyNotify) g_list_free : NULL);
2133 gtk_window_remove_embedded_xid (GtkWindow *window, GdkNativeWindow xid)
2135 GList *embedded_windows;
2138 g_return_if_fail (GTK_IS_WINDOW (window));
2140 embedded_windows = g_object_get_qdata (G_OBJECT (window), quark_gtk_embedded);
2141 if (embedded_windows)
2142 g_object_steal_qdata (G_OBJECT (window), quark_gtk_embedded);
2144 node = g_list_find (embedded_windows, GUINT_TO_POINTER (xid));
2147 embedded_windows = g_list_remove_link (embedded_windows, node);
2148 g_list_free_1 (node);
2151 g_object_set_qdata_full (G_OBJECT (window), quark_gtk_embedded,
2154 (GDestroyNotify) g_list_free : NULL);
2158 _gtk_window_reposition (GtkWindow *window,
2162 g_return_if_fail (GTK_IS_WINDOW (window));
2164 gtk_window_move (window, x, y);
2168 gtk_window_dispose (GObject *object)
2170 GtkWindow *window = GTK_WINDOW (object);
2172 gtk_window_set_focus (window, NULL);
2173 gtk_window_set_default (window, NULL);
2175 G_OBJECT_CLASS (gtk_window_parent_class)->dispose (object);
2179 parent_destroyed_callback (GtkWindow *parent, GtkWindow *child)
2181 gtk_widget_destroy (GTK_WIDGET (child));
2185 connect_parent_destroyed (GtkWindow *window)
2187 if (window->transient_parent)
2189 g_signal_connect (window->transient_parent,
2191 G_CALLBACK (parent_destroyed_callback),
2197 disconnect_parent_destroyed (GtkWindow *window)
2199 if (window->transient_parent)
2201 g_signal_handlers_disconnect_by_func (window->transient_parent,
2202 parent_destroyed_callback,
2208 gtk_window_transient_parent_realized (GtkWidget *parent,
2211 if (GTK_WIDGET_REALIZED (window))
2212 gdk_window_set_transient_for (window->window, parent->window);
2216 gtk_window_transient_parent_unrealized (GtkWidget *parent,
2219 if (GTK_WIDGET_REALIZED (window))
2220 gdk_property_delete (window->window,
2221 gdk_atom_intern_static_string ("WM_TRANSIENT_FOR"));
2225 gtk_window_transient_parent_screen_changed (GtkWindow *parent,
2229 gtk_window_set_screen (window, parent->screen);
2233 gtk_window_unset_transient_for (GtkWindow *window)
2235 GtkWindowPrivate *priv = GTK_WINDOW_GET_PRIVATE (window);
2237 if (window->transient_parent)
2239 g_signal_handlers_disconnect_by_func (window->transient_parent,
2240 gtk_window_transient_parent_realized,
2242 g_signal_handlers_disconnect_by_func (window->transient_parent,
2243 gtk_window_transient_parent_unrealized,
2245 g_signal_handlers_disconnect_by_func (window->transient_parent,
2246 gtk_window_transient_parent_screen_changed,
2248 g_signal_handlers_disconnect_by_func (window->transient_parent,
2249 gtk_widget_destroyed,
2250 &window->transient_parent);
2252 if (window->destroy_with_parent)
2253 disconnect_parent_destroyed (window);
2255 window->transient_parent = NULL;
2257 if (priv->transient_parent_group)
2259 priv->transient_parent_group = FALSE;
2260 gtk_window_group_remove_window (window->group,
2267 * gtk_window_set_transient_for:
2268 * @window: a #GtkWindow
2269 * @parent: (allow-none): parent window
2271 * Dialog windows should be set transient for the main application
2272 * window they were spawned from. This allows <link
2273 * linkend="gtk-X11-arch">window managers</link> to e.g. keep the
2274 * dialog on top of the main window, or center the dialog over the
2275 * main window. gtk_dialog_new_with_buttons() and other convenience
2276 * functions in GTK+ will sometimes call
2277 * gtk_window_set_transient_for() on your behalf.
2279 * On Windows, this function puts the child window on top of the parent,
2280 * much as the window manager would have done on X.
2284 gtk_window_set_transient_for (GtkWindow *window,
2287 GtkWindowPrivate *priv = GTK_WINDOW_GET_PRIVATE (window);
2289 g_return_if_fail (GTK_IS_WINDOW (window));
2290 g_return_if_fail (parent == NULL || GTK_IS_WINDOW (parent));
2291 g_return_if_fail (window != parent);
2293 if (window->transient_parent)
2295 if (GTK_WIDGET_REALIZED (window) &&
2296 GTK_WIDGET_REALIZED (window->transient_parent) &&
2297 (!parent || !GTK_WIDGET_REALIZED (parent)))
2298 gtk_window_transient_parent_unrealized (GTK_WIDGET (window->transient_parent),
2299 GTK_WIDGET (window));
2301 gtk_window_unset_transient_for (window);
2304 window->transient_parent = parent;
2308 g_signal_connect (parent, "destroy",
2309 G_CALLBACK (gtk_widget_destroyed),
2310 &window->transient_parent);
2311 g_signal_connect (parent, "realize",
2312 G_CALLBACK (gtk_window_transient_parent_realized),
2314 g_signal_connect (parent, "unrealize",
2315 G_CALLBACK (gtk_window_transient_parent_unrealized),
2317 g_signal_connect (parent, "notify::screen",
2318 G_CALLBACK (gtk_window_transient_parent_screen_changed),
2321 gtk_window_set_screen (window, parent->screen);
2323 if (window->destroy_with_parent)
2324 connect_parent_destroyed (window);
2326 if (GTK_WIDGET_REALIZED (window) &&
2327 GTK_WIDGET_REALIZED (parent))
2328 gtk_window_transient_parent_realized (GTK_WIDGET (parent),
2329 GTK_WIDGET (window));
2333 gtk_window_group_add_window (parent->group, window);
2334 priv->transient_parent_group = TRUE;
2340 * gtk_window_get_transient_for:
2341 * @window: a #GtkWindow
2343 * Fetches the transient parent for this window. See
2344 * gtk_window_set_transient_for().
2346 * Return value: (transfer none): the transient parent for this window, or %NULL
2347 * if no transient parent has been set.
2350 gtk_window_get_transient_for (GtkWindow *window)
2352 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
2354 return window->transient_parent;
2358 * gtk_window_set_opacity:
2359 * @window: a #GtkWindow
2360 * @opacity: desired opacity, between 0 and 1
2362 * Request the windowing system to make @window partially transparent,
2363 * with opacity 0 being fully transparent and 1 fully opaque. (Values
2364 * of the opacity parameter are clamped to the [0,1] range.) On X11
2365 * this has any effect only on X screens with a compositing manager
2366 * running. See gtk_widget_is_composited(). On Windows it should work
2369 * Note that setting a window's opacity after the window has been
2370 * shown causes it to flicker once on Windows.
2375 gtk_window_set_opacity (GtkWindow *window,
2378 GtkWindowPrivate *priv;
2380 g_return_if_fail (GTK_IS_WINDOW (window));
2382 priv = GTK_WINDOW_GET_PRIVATE (window);
2386 else if (opacity > 1.0)
2389 priv->opacity_set = TRUE;
2390 priv->opacity = opacity;
2392 if (GTK_WIDGET_REALIZED (window))
2393 gdk_window_set_opacity (GTK_WIDGET (window)->window, priv->opacity);
2397 * gtk_window_get_opacity:
2398 * @window: a #GtkWindow
2400 * Fetches the requested opacity for this window. See
2401 * gtk_window_set_opacity().
2403 * Return value: the requested opacity for this window.
2408 gtk_window_get_opacity (GtkWindow *window)
2410 GtkWindowPrivate *priv;
2412 g_return_val_if_fail (GTK_IS_WINDOW (window), 0.0);
2414 priv = GTK_WINDOW_GET_PRIVATE (window);
2416 return priv->opacity;
2420 * gtk_window_set_type_hint:
2421 * @window: a #GtkWindow
2422 * @hint: the window type
2424 * By setting the type hint for the window, you allow the window
2425 * manager to decorate and handle the window in a way which is
2426 * suitable to the function of the window in your application.
2428 * This function should be called before the window becomes visible.
2430 * gtk_dialog_new_with_buttons() and other convenience functions in GTK+
2431 * will sometimes call gtk_window_set_type_hint() on your behalf.
2435 gtk_window_set_type_hint (GtkWindow *window,
2436 GdkWindowTypeHint hint)
2438 GtkWindowPrivate *priv;
2440 g_return_if_fail (GTK_IS_WINDOW (window));
2441 g_return_if_fail (!GTK_WIDGET_MAPPED (window));
2443 priv = GTK_WINDOW_GET_PRIVATE (window);
2445 if (hint < GDK_WINDOW_TYPE_HINT_DROPDOWN_MENU)
2446 window->type_hint = hint;
2448 window->type_hint = GDK_WINDOW_TYPE_HINT_NORMAL;
2450 priv->reset_type_hint = TRUE;
2451 priv->type_hint = hint;
2455 * gtk_window_get_type_hint:
2456 * @window: a #GtkWindow
2458 * Gets the type hint for this window. See gtk_window_set_type_hint().
2460 * Return value: the type hint for @window.
2463 gtk_window_get_type_hint (GtkWindow *window)
2465 GtkWindowPrivate *priv;
2467 g_return_val_if_fail (GTK_IS_WINDOW (window), GDK_WINDOW_TYPE_HINT_NORMAL);
2469 priv = GTK_WINDOW_GET_PRIVATE (window);
2471 return priv->type_hint;
2475 * gtk_window_set_skip_taskbar_hint:
2476 * @window: a #GtkWindow
2477 * @setting: %TRUE to keep this window from appearing in the task bar
2479 * Windows may set a hint asking the desktop environment not to display
2480 * the window in the task bar. This function sets this hint.
2485 gtk_window_set_skip_taskbar_hint (GtkWindow *window,
2488 GtkWindowPrivate *priv;
2490 g_return_if_fail (GTK_IS_WINDOW (window));
2492 priv = GTK_WINDOW_GET_PRIVATE (window);
2494 setting = setting != FALSE;
2496 if (priv->skips_taskbar != setting)
2498 priv->skips_taskbar = setting;
2499 if (GTK_WIDGET_REALIZED (window))
2500 gdk_window_set_skip_taskbar_hint (GTK_WIDGET (window)->window,
2501 priv->skips_taskbar);
2502 g_object_notify (G_OBJECT (window), "skip-taskbar-hint");
2507 * gtk_window_get_skip_taskbar_hint:
2508 * @window: a #GtkWindow
2510 * Gets the value set by gtk_window_set_skip_taskbar_hint()
2512 * Return value: %TRUE if window shouldn't be in taskbar
2517 gtk_window_get_skip_taskbar_hint (GtkWindow *window)
2519 GtkWindowPrivate *priv;
2521 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
2523 priv = GTK_WINDOW_GET_PRIVATE (window);
2525 return priv->skips_taskbar;
2529 * gtk_window_set_skip_pager_hint:
2530 * @window: a #GtkWindow
2531 * @setting: %TRUE to keep this window from appearing in the pager
2533 * Windows may set a hint asking the desktop environment not to display
2534 * the window in the pager. This function sets this hint.
2535 * (A "pager" is any desktop navigation tool such as a workspace
2536 * switcher that displays a thumbnail representation of the windows
2542 gtk_window_set_skip_pager_hint (GtkWindow *window,
2545 GtkWindowPrivate *priv;
2547 g_return_if_fail (GTK_IS_WINDOW (window));
2549 priv = GTK_WINDOW_GET_PRIVATE (window);
2551 setting = setting != FALSE;
2553 if (priv->skips_pager != setting)
2555 priv->skips_pager = setting;
2556 if (GTK_WIDGET_REALIZED (window))
2557 gdk_window_set_skip_pager_hint (GTK_WIDGET (window)->window,
2559 g_object_notify (G_OBJECT (window), "skip-pager-hint");
2564 * gtk_window_get_skip_pager_hint:
2565 * @window: a #GtkWindow
2567 * Gets the value set by gtk_window_set_skip_pager_hint().
2569 * Return value: %TRUE if window shouldn't be in pager
2574 gtk_window_get_skip_pager_hint (GtkWindow *window)
2576 GtkWindowPrivate *priv;
2578 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
2580 priv = GTK_WINDOW_GET_PRIVATE (window);
2582 return priv->skips_pager;
2586 * gtk_window_set_urgency_hint:
2587 * @window: a #GtkWindow
2588 * @setting: %TRUE to mark this window as urgent
2590 * Windows may set a hint asking the desktop environment to draw
2591 * the users attention to the window. This function sets this hint.
2596 gtk_window_set_urgency_hint (GtkWindow *window,
2599 GtkWindowPrivate *priv;
2601 g_return_if_fail (GTK_IS_WINDOW (window));
2603 priv = GTK_WINDOW_GET_PRIVATE (window);
2605 setting = setting != FALSE;
2607 if (priv->urgent != setting)
2609 priv->urgent = setting;
2610 if (GTK_WIDGET_REALIZED (window))
2611 gdk_window_set_urgency_hint (GTK_WIDGET (window)->window,
2613 g_object_notify (G_OBJECT (window), "urgency-hint");
2618 * gtk_window_get_urgency_hint:
2619 * @window: a #GtkWindow
2621 * Gets the value set by gtk_window_set_urgency_hint()
2623 * Return value: %TRUE if window is urgent
2628 gtk_window_get_urgency_hint (GtkWindow *window)
2630 GtkWindowPrivate *priv;
2632 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
2634 priv = GTK_WINDOW_GET_PRIVATE (window);
2636 return priv->urgent;
2640 * gtk_window_set_accept_focus:
2641 * @window: a #GtkWindow
2642 * @setting: %TRUE to let this window receive input focus
2644 * Windows may set a hint asking the desktop environment not to receive
2645 * the input focus. This function sets this hint.
2650 gtk_window_set_accept_focus (GtkWindow *window,
2653 GtkWindowPrivate *priv;
2655 g_return_if_fail (GTK_IS_WINDOW (window));
2657 priv = GTK_WINDOW_GET_PRIVATE (window);
2659 setting = setting != FALSE;
2661 if (priv->accept_focus != setting)
2663 priv->accept_focus = setting;
2664 if (GTK_WIDGET_REALIZED (window))
2665 gdk_window_set_accept_focus (GTK_WIDGET (window)->window,
2666 priv->accept_focus);
2667 g_object_notify (G_OBJECT (window), "accept-focus");
2672 * gtk_window_get_accept_focus:
2673 * @window: a #GtkWindow
2675 * Gets the value set by gtk_window_set_accept_focus().
2677 * Return value: %TRUE if window should receive the input focus
2682 gtk_window_get_accept_focus (GtkWindow *window)
2684 GtkWindowPrivate *priv;
2686 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
2688 priv = GTK_WINDOW_GET_PRIVATE (window);
2690 return priv->accept_focus;
2694 * gtk_window_set_focus_on_map:
2695 * @window: a #GtkWindow
2696 * @setting: %TRUE to let this window receive input focus on map
2698 * Windows may set a hint asking the desktop environment not to receive
2699 * the input focus when the window is mapped. This function sets this
2705 gtk_window_set_focus_on_map (GtkWindow *window,
2708 GtkWindowPrivate *priv;
2710 g_return_if_fail (GTK_IS_WINDOW (window));
2712 priv = GTK_WINDOW_GET_PRIVATE (window);
2714 setting = setting != FALSE;
2716 if (priv->focus_on_map != setting)
2718 priv->focus_on_map = setting;
2719 if (GTK_WIDGET_REALIZED (window))
2720 gdk_window_set_focus_on_map (GTK_WIDGET (window)->window,
2721 priv->focus_on_map);
2722 g_object_notify (G_OBJECT (window), "focus-on-map");
2727 * gtk_window_get_focus_on_map:
2728 * @window: a #GtkWindow
2730 * Gets the value set by gtk_window_set_focus_on_map().
2732 * Return value: %TRUE if window should receive the input focus when
2738 gtk_window_get_focus_on_map (GtkWindow *window)
2740 GtkWindowPrivate *priv;
2742 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
2744 priv = GTK_WINDOW_GET_PRIVATE (window);
2746 return priv->focus_on_map;
2750 * gtk_window_set_destroy_with_parent:
2751 * @window: a #GtkWindow
2752 * @setting: whether to destroy @window with its transient parent
2754 * If @setting is %TRUE, then destroying the transient parent of @window
2755 * will also destroy @window itself. This is useful for dialogs that
2756 * shouldn't persist beyond the lifetime of the main window they're
2757 * associated with, for example.
2760 gtk_window_set_destroy_with_parent (GtkWindow *window,
2763 g_return_if_fail (GTK_IS_WINDOW (window));
2765 if (window->destroy_with_parent == (setting != FALSE))
2768 if (window->destroy_with_parent)
2770 disconnect_parent_destroyed (window);
2774 connect_parent_destroyed (window);
2777 window->destroy_with_parent = setting;
2779 g_object_notify (G_OBJECT (window), "destroy-with-parent");
2783 * gtk_window_get_destroy_with_parent:
2784 * @window: a #GtkWindow
2786 * Returns whether the window will be destroyed with its transient parent. See
2787 * gtk_window_set_destroy_with_parent ().
2789 * Return value: %TRUE if the window will be destroyed with its transient parent.
2792 gtk_window_get_destroy_with_parent (GtkWindow *window)
2794 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
2796 return window->destroy_with_parent;
2799 static GtkWindowGeometryInfo*
2800 gtk_window_get_geometry_info (GtkWindow *window,
2803 GtkWindowGeometryInfo *info;
2805 info = window->geometry_info;
2806 if (!info && create)
2808 info = g_new0 (GtkWindowGeometryInfo, 1);
2810 info->default_width = -1;
2811 info->default_height = -1;
2812 info->resize_width = -1;
2813 info->resize_height = -1;
2814 info->initial_x = 0;
2815 info->initial_y = 0;
2816 info->initial_pos_set = FALSE;
2817 info->default_is_geometry = FALSE;
2818 info->position_constraints_changed = FALSE;
2819 info->last.configure_request.x = 0;
2820 info->last.configure_request.y = 0;
2821 info->last.configure_request.width = -1;
2822 info->last.configure_request.height = -1;
2823 info->widget = NULL;
2825 window->geometry_info = info;
2832 * gtk_window_set_geometry_hints:
2833 * @window: a #GtkWindow
2834 * @geometry_widget: widget the geometry hints will be applied to
2835 * @geometry: struct containing geometry information
2836 * @geom_mask: mask indicating which struct fields should be paid attention to
2838 * This function sets up hints about how a window can be resized by
2839 * the user. You can set a minimum and maximum size; allowed resize
2840 * increments (e.g. for xterm, you can only resize by the size of a
2841 * character); aspect ratios; and more. See the #GdkGeometry struct.
2845 gtk_window_set_geometry_hints (GtkWindow *window,
2846 GtkWidget *geometry_widget,
2847 GdkGeometry *geometry,
2848 GdkWindowHints geom_mask)
2850 GtkWindowGeometryInfo *info;
2852 g_return_if_fail (GTK_IS_WINDOW (window));
2853 g_return_if_fail (geometry_widget == NULL || GTK_IS_WIDGET (geometry_widget));
2855 info = gtk_window_get_geometry_info (window, TRUE);
2858 g_signal_handlers_disconnect_by_func (info->widget,
2859 gtk_widget_destroyed,
2862 info->widget = geometry_widget;
2864 g_signal_connect (geometry_widget, "destroy",
2865 G_CALLBACK (gtk_widget_destroyed),
2869 info->geometry = *geometry;
2871 /* We store gravity in window->gravity not in the hints. */
2872 info->mask = geom_mask & ~(GDK_HINT_WIN_GRAVITY);
2874 if (geom_mask & GDK_HINT_WIN_GRAVITY)
2876 gtk_window_set_gravity (window, geometry->win_gravity);
2879 gtk_widget_queue_resize_no_redraw (GTK_WIDGET (window));
2883 * gtk_window_set_decorated:
2884 * @window: a #GtkWindow
2885 * @setting: %TRUE to decorate the window
2887 * By default, windows are decorated with a title bar, resize
2888 * controls, etc. Some <link linkend="gtk-X11-arch">window
2889 * managers</link> allow GTK+ to disable these decorations, creating a
2890 * borderless window. If you set the decorated property to %FALSE
2891 * using this function, GTK+ will do its best to convince the window
2892 * manager not to decorate the window. Depending on the system, this
2893 * function may not have any effect when called on a window that is
2894 * already visible, so you should call it before calling gtk_window_show().
2896 * On Windows, this function always works, since there's no window manager
2901 gtk_window_set_decorated (GtkWindow *window,
2904 g_return_if_fail (GTK_IS_WINDOW (window));
2906 setting = setting != FALSE;
2908 if (setting == window->decorated)
2911 window->decorated = setting;
2913 if (GTK_WIDGET (window)->window)
2915 if (window->decorated)
2916 gdk_window_set_decorations (GTK_WIDGET (window)->window,
2919 gdk_window_set_decorations (GTK_WIDGET (window)->window,
2923 g_object_notify (G_OBJECT (window), "decorated");
2927 * gtk_window_get_decorated:
2928 * @window: a #GtkWindow
2930 * Returns whether the window has been set to have decorations
2931 * such as a title bar via gtk_window_set_decorated().
2933 * Return value: %TRUE if the window has been set to have decorations
2936 gtk_window_get_decorated (GtkWindow *window)
2938 g_return_val_if_fail (GTK_IS_WINDOW (window), TRUE);
2940 return window->decorated;
2944 * gtk_window_set_deletable:
2945 * @window: a #GtkWindow
2946 * @setting: %TRUE to decorate the window as deletable
2948 * By default, windows have a close button in the window frame. Some
2949 * <link linkend="gtk-X11-arch">window managers</link> allow GTK+ to
2950 * disable this button. If you set the deletable property to %FALSE
2951 * using this function, GTK+ will do its best to convince the window
2952 * manager not to show a close button. Depending on the system, this
2953 * function may not have any effect when called on a window that is
2954 * already visible, so you should call it before calling gtk_window_show().
2956 * On Windows, this function always works, since there's no window manager
2962 gtk_window_set_deletable (GtkWindow *window,
2965 GtkWindowPrivate *priv;
2967 g_return_if_fail (GTK_IS_WINDOW (window));
2969 priv = GTK_WINDOW_GET_PRIVATE (window);
2971 setting = setting != FALSE;
2973 if (setting == priv->deletable)
2976 priv->deletable = setting;
2978 if (GTK_WIDGET (window)->window)
2980 if (priv->deletable)
2981 gdk_window_set_functions (GTK_WIDGET (window)->window,
2984 gdk_window_set_functions (GTK_WIDGET (window)->window,
2985 GDK_FUNC_ALL | GDK_FUNC_CLOSE);
2988 g_object_notify (G_OBJECT (window), "deletable");
2992 * gtk_window_get_deletable:
2993 * @window: a #GtkWindow
2995 * Returns whether the window has been set to have a close button
2996 * via gtk_window_set_deletable().
2998 * Return value: %TRUE if the window has been set to have a close button
3003 gtk_window_get_deletable (GtkWindow *window)
3005 GtkWindowPrivate *priv;
3007 g_return_val_if_fail (GTK_IS_WINDOW (window), TRUE);
3009 priv = GTK_WINDOW_GET_PRIVATE (window);
3011 return priv->deletable;
3014 static GtkWindowIconInfo*
3015 get_icon_info (GtkWindow *window)
3017 return g_object_get_qdata (G_OBJECT (window), quark_gtk_window_icon_info);
3021 free_icon_info (GtkWindowIconInfo *info)
3023 g_free (info->icon_name);
3024 g_slice_free (GtkWindowIconInfo, info);
3028 static GtkWindowIconInfo*
3029 ensure_icon_info (GtkWindow *window)
3031 GtkWindowIconInfo *info;
3033 info = get_icon_info (window);
3037 info = g_slice_new0 (GtkWindowIconInfo);
3038 g_object_set_qdata_full (G_OBJECT (window),
3039 quark_gtk_window_icon_info,
3041 (GDestroyNotify)free_icon_info);
3053 static ScreenIconInfo *
3054 get_screen_icon_info (GdkScreen *screen)
3056 ScreenIconInfo *info = g_object_get_qdata (G_OBJECT (screen),
3057 quark_gtk_window_default_icon_pixmap);
3060 info = g_slice_new0 (ScreenIconInfo);
3061 g_object_set_qdata (G_OBJECT (screen),
3062 quark_gtk_window_default_icon_pixmap, info);
3065 if (info->serial != default_icon_serial)
3069 g_object_remove_weak_pointer (G_OBJECT (info->pixmap), (gpointer*)&info->pixmap);
3070 info->pixmap = NULL;
3075 g_object_remove_weak_pointer (G_OBJECT (info->mask), (gpointer*)&info->mask);
3079 info->serial = default_icon_serial;
3086 get_pixmap_and_mask (GdkWindow *window,
3087 GtkWindowIconInfo *parent_info,
3088 gboolean is_default_list,
3090 GdkPixmap **pmap_return,
3091 GdkBitmap **mask_return)
3093 GdkScreen *screen = gdk_drawable_get_screen (window);
3094 ScreenIconInfo *default_icon_info = get_screen_icon_info (screen);
3095 GdkPixbuf *best_icon;
3099 *pmap_return = NULL;
3100 *mask_return = NULL;
3102 if (is_default_list &&
3103 default_icon_info->pixmap != NULL)
3105 /* Use shared icon pixmap for all windows on this screen.
3107 if (default_icon_info->pixmap)
3108 g_object_ref (default_icon_info->pixmap);
3109 if (default_icon_info->mask)
3110 g_object_ref (default_icon_info->mask);
3112 *pmap_return = default_icon_info->pixmap;
3113 *mask_return = default_icon_info->mask;
3115 else if (parent_info && parent_info->icon_pixmap)
3117 if (parent_info->icon_pixmap)
3118 g_object_ref (parent_info->icon_pixmap);
3119 if (parent_info->icon_mask)
3120 g_object_ref (parent_info->icon_mask);
3122 *pmap_return = parent_info->icon_pixmap;
3123 *mask_return = parent_info->icon_mask;
3127 #define IDEAL_SIZE 48
3129 best_size = G_MAXINT;
3131 tmp_list = icon_list;
3132 while (tmp_list != NULL)
3134 GdkPixbuf *pixbuf = tmp_list->data;
3137 /* average width and height - if someone passes in a rectangular
3138 * icon they deserve what they get.
3140 this = gdk_pixbuf_get_width (pixbuf) + gdk_pixbuf_get_height (pixbuf);
3143 if (best_icon == NULL)
3150 /* icon is better if it's 32 pixels or larger, and closer to
3151 * the ideal size than the current best.
3154 (ABS (best_size - IDEAL_SIZE) <
3155 ABS (this - IDEAL_SIZE)))
3162 tmp_list = tmp_list->next;
3166 gdk_pixbuf_render_pixmap_and_mask_for_colormap (best_icon,
3167 gdk_screen_get_system_colormap (screen),
3172 /* Save pmap/mask for others to use if appropriate */
3175 parent_info->icon_pixmap = *pmap_return;
3176 parent_info->icon_mask = *mask_return;
3178 if (parent_info->icon_pixmap)
3179 g_object_ref (parent_info->icon_pixmap);
3180 if (parent_info->icon_mask)
3181 g_object_ref (parent_info->icon_mask);
3183 else if (is_default_list)
3185 default_icon_info->pixmap = *pmap_return;
3186 default_icon_info->mask = *mask_return;
3188 if (default_icon_info->pixmap)
3189 g_object_add_weak_pointer (G_OBJECT (default_icon_info->pixmap),
3190 (gpointer*)&default_icon_info->pixmap);
3191 if (default_icon_info->mask)
3192 g_object_add_weak_pointer (G_OBJECT (default_icon_info->mask),
3193 (gpointer*)&default_icon_info->mask);
3199 icon_list_from_theme (GtkWidget *widget,
3204 GtkIconTheme *icon_theme;
3209 icon_theme = gtk_icon_theme_get_for_screen (gtk_widget_get_screen (widget));
3211 sizes = gtk_icon_theme_get_icon_sizes (icon_theme, name);
3214 for (i = 0; sizes[i]; i++)
3217 * We need an EWMH extension to handle scalable icons
3218 * by passing their name to the WM. For now just use a
3222 icon = gtk_icon_theme_load_icon (icon_theme, name,
3225 icon = gtk_icon_theme_load_icon (icon_theme, name,
3228 list = g_list_append (list, icon);
3238 gtk_window_realize_icon (GtkWindow *window)
3241 GtkWindowIconInfo *info;
3244 widget = GTK_WIDGET (window);
3246 g_return_if_fail (widget->window != NULL);
3248 /* no point setting an icon on override-redirect */
3249 if (window->type == GTK_WINDOW_POPUP)
3254 info = ensure_icon_info (window);
3259 g_return_if_fail (info->icon_pixmap == NULL);
3260 g_return_if_fail (info->icon_mask == NULL);
3262 info->using_default_icon = FALSE;
3263 info->using_parent_icon = FALSE;
3264 info->using_themed_icon = FALSE;
3266 icon_list = info->icon_list;
3268 /* Look up themed icon */
3269 if (icon_list == NULL && info->icon_name)
3271 icon_list = icon_list_from_theme (widget, info->icon_name);
3273 info->using_themed_icon = TRUE;
3276 /* Inherit from transient parent */
3277 if (icon_list == NULL && window->transient_parent)
3279 icon_list = ensure_icon_info (window->transient_parent)->icon_list;
3281 info->using_parent_icon = TRUE;
3284 /* Inherit from default */
3285 if (icon_list == NULL)
3287 icon_list = default_icon_list;
3289 info->using_default_icon = TRUE;
3292 /* Look up themed icon */
3293 if (icon_list == NULL && default_icon_name)
3295 icon_list = icon_list_from_theme (widget, default_icon_name);
3296 info->using_default_icon = TRUE;
3297 info->using_themed_icon = TRUE;
3300 gdk_window_set_icon_list (widget->window, icon_list);
3302 get_pixmap_and_mask (widget->window,
3303 info->using_parent_icon ? ensure_icon_info (window->transient_parent) : NULL,
3304 info->using_default_icon,
3309 /* This is a slight ICCCM violation since it's a color pixmap not
3310 * a bitmap, but everyone does it.
3312 gdk_window_set_icon (widget->window,
3317 info->realized = TRUE;
3319 if (info->using_themed_icon)
3321 GtkIconTheme *icon_theme;
3323 g_list_foreach (icon_list, (GFunc) g_object_unref, NULL);
3324 g_list_free (icon_list);
3326 icon_theme = gtk_icon_theme_get_for_screen (gtk_widget_get_screen (GTK_WIDGET (window)));
3327 g_signal_connect (icon_theme, "changed",
3328 G_CALLBACK (update_themed_icon), window);
3333 gtk_window_unrealize_icon (GtkWindow *window)
3335 GtkWindowIconInfo *info;
3337 info = get_icon_info (window);
3342 if (info->icon_pixmap)
3343 g_object_unref (info->icon_pixmap);
3345 if (info->icon_mask)
3346 g_object_unref (info->icon_mask);
3348 info->icon_pixmap = NULL;
3349 info->icon_mask = NULL;
3351 if (info->using_themed_icon)
3353 GtkIconTheme *icon_theme;
3355 icon_theme = gtk_icon_theme_get_for_screen (gtk_widget_get_screen (GTK_WIDGET (window)));
3357 g_signal_handlers_disconnect_by_func (icon_theme, update_themed_icon, window);
3360 /* We don't clear the properties on the window, just figure the
3361 * window is going away.
3364 info->realized = FALSE;
3369 * gtk_window_set_icon_list:
3370 * @window: a #GtkWindow
3371 * @list: list of #GdkPixbuf
3373 * Sets up the icon representing a #GtkWindow. The icon is used when
3374 * the window is minimized (also known as iconified). Some window
3375 * managers or desktop environments may also place it in the window
3376 * frame, or display it in other contexts.
3378 * gtk_window_set_icon_list() allows you to pass in the same icon in
3379 * several hand-drawn sizes. The list should contain the natural sizes
3380 * your icon is available in; that is, don't scale the image before
3381 * passing it to GTK+. Scaling is postponed until the last minute,
3382 * when the desired final size is known, to allow best quality.
3384 * By passing several sizes, you may improve the final image quality
3385 * of the icon, by reducing or eliminating automatic image scaling.
3387 * Recommended sizes to provide: 16x16, 32x32, 48x48 at minimum, and
3388 * larger images (64x64, 128x128) if you have them.
3390 * See also gtk_window_set_default_icon_list() to set the icon
3391 * for all windows in your application in one go.
3393 * Note that transient windows (those who have been set transient for another
3394 * window using gtk_window_set_transient_for()) will inherit their
3395 * icon from their transient parent. So there's no need to explicitly
3396 * set the icon on transient windows.
3399 gtk_window_set_icon_list (GtkWindow *window,
3402 GtkWindowIconInfo *info;
3404 g_return_if_fail (GTK_IS_WINDOW (window));
3406 info = ensure_icon_info (window);
3408 if (info->icon_list == list) /* check for NULL mostly */
3411 g_list_foreach (list,
3412 (GFunc) g_object_ref, NULL);
3414 g_list_foreach (info->icon_list,
3415 (GFunc) g_object_unref, NULL);
3417 g_list_free (info->icon_list);
3419 info->icon_list = g_list_copy (list);
3421 g_object_notify (G_OBJECT (window), "icon");
3423 gtk_window_unrealize_icon (window);
3425 if (GTK_WIDGET_REALIZED (window))
3426 gtk_window_realize_icon (window);
3428 /* We could try to update our transient children, but I don't think
3429 * it's really worth it. If we did it, the best way would probably
3430 * be to have children connect to notify::icon-list
3435 * gtk_window_get_icon_list:
3436 * @window: a #GtkWindow
3438 * Retrieves the list of icons set by gtk_window_set_icon_list().
3439 * The list is copied, but the reference count on each
3440 * member won't be incremented.
3442 * Return value: (element-type GdkPixbuf) (transfer container): copy of window's icon list
3445 gtk_window_get_icon_list (GtkWindow *window)
3447 GtkWindowIconInfo *info;
3449 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
3451 info = get_icon_info (window);
3454 return g_list_copy (info->icon_list);
3460 * gtk_window_set_icon:
3461 * @window: a #GtkWindow
3462 * @icon: (allow-none): icon image, or %NULL
3464 * Sets up the icon representing a #GtkWindow. This icon is used when
3465 * the window is minimized (also known as iconified). Some window
3466 * managers or desktop environments may also place it in the window
3467 * frame, or display it in other contexts.
3469 * The icon should be provided in whatever size it was naturally
3470 * drawn; that is, don't scale the image before passing it to
3471 * GTK+. Scaling is postponed until the last minute, when the desired
3472 * final size is known, to allow best quality.
3474 * If you have your icon hand-drawn in multiple sizes, use
3475 * gtk_window_set_icon_list(). Then the best size will be used.
3477 * This function is equivalent to calling gtk_window_set_icon_list()
3478 * with a 1-element list.
3480 * See also gtk_window_set_default_icon_list() to set the icon
3481 * for all windows in your application in one go.
3484 gtk_window_set_icon (GtkWindow *window,
3489 g_return_if_fail (GTK_IS_WINDOW (window));
3490 g_return_if_fail (icon == NULL || GDK_IS_PIXBUF (icon));
3495 list = g_list_append (list, icon);
3497 gtk_window_set_icon_list (window, list);
3503 update_themed_icon (GtkIconTheme *icon_theme,
3506 g_object_notify (G_OBJECT (window), "icon");
3508 gtk_window_unrealize_icon (window);
3510 if (GTK_WIDGET_REALIZED (window))
3511 gtk_window_realize_icon (window);
3515 * gtk_window_set_icon_name:
3516 * @window: a #GtkWindow
3517 * @name: (allow-none): the name of the themed icon
3519 * Sets the icon for the window from a named themed icon. See
3520 * the docs for #GtkIconTheme for more details.
3522 * Note that this has nothing to do with the WM_ICON_NAME
3523 * property which is mentioned in the ICCCM.
3528 gtk_window_set_icon_name (GtkWindow *window,
3531 GtkWindowIconInfo *info;
3534 g_return_if_fail (GTK_IS_WINDOW (window));
3536 info = ensure_icon_info (window);
3538 if (g_strcmp0 (info->icon_name, name) == 0)
3541 tmp = info->icon_name;
3542 info->icon_name = g_strdup (name);
3545 g_list_foreach (info->icon_list, (GFunc) g_object_unref, NULL);
3546 g_list_free (info->icon_list);
3547 info->icon_list = NULL;
3549 update_themed_icon (NULL, window);
3551 g_object_notify (G_OBJECT (window), "icon-name");
3555 * gtk_window_get_icon_name:
3556 * @window: a #GtkWindow
3558 * Returns the name of the themed icon for the window,
3559 * see gtk_window_set_icon_name().
3561 * Returns: the icon name or %NULL if the window has
3566 G_CONST_RETURN gchar *
3567 gtk_window_get_icon_name (GtkWindow *window)
3569 GtkWindowIconInfo *info;
3571 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
3573 info = ensure_icon_info (window);
3575 return info->icon_name;
3579 * gtk_window_get_icon:
3580 * @window: a #GtkWindow
3582 * Gets the value set by gtk_window_set_icon() (or if you've
3583 * called gtk_window_set_icon_list(), gets the first icon in
3586 * Return value: (transfer none): icon for window
3589 gtk_window_get_icon (GtkWindow *window)
3591 GtkWindowIconInfo *info;
3593 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
3595 info = get_icon_info (window);
3596 if (info && info->icon_list)
3597 return GDK_PIXBUF (info->icon_list->data);
3602 /* Load pixbuf, printing warning on failure if error == NULL
3605 load_pixbuf_verbosely (const char *filename,
3608 GError *local_err = NULL;
3611 pixbuf = gdk_pixbuf_new_from_file (filename, &local_err);
3619 g_warning ("Error loading icon from file '%s':\n\t%s",
3620 filename, local_err->message);
3621 g_error_free (local_err);
3629 * gtk_window_set_icon_from_file:
3630 * @window: a #GtkWindow
3631 * @filename: location of icon file
3632 * @err: location to store error, or %NULL.
3634 * Sets the icon for @window.
3635 * Warns on failure if @err is %NULL.
3637 * This function is equivalent to calling gtk_window_set_icon()
3638 * with a pixbuf created by loading the image from @filename.
3640 * Returns: %TRUE if setting the icon succeeded.
3645 gtk_window_set_icon_from_file (GtkWindow *window,
3646 const gchar *filename,
3649 GdkPixbuf *pixbuf = load_pixbuf_verbosely (filename, err);
3653 gtk_window_set_icon (window, pixbuf);
3654 g_object_unref (pixbuf);
3663 * gtk_window_set_default_icon_list:
3664 * @list: a list of #GdkPixbuf
3666 * Sets an icon list to be used as fallback for windows that haven't
3667 * had gtk_window_set_icon_list() called on them to set up a
3668 * window-specific icon list. This function allows you to set up the
3669 * icon for all windows in your app at once.
3671 * See gtk_window_set_icon_list() for more details.
3675 gtk_window_set_default_icon_list (GList *list)
3679 if (list == default_icon_list)
3682 /* Update serial so we don't used cached pixmaps/masks
3684 default_icon_serial++;
3686 g_list_foreach (list,
3687 (GFunc) g_object_ref, NULL);
3689 g_list_foreach (default_icon_list,
3690 (GFunc) g_object_unref, NULL);
3692 g_list_free (default_icon_list);
3694 default_icon_list = g_list_copy (list);
3696 /* Update all toplevels */
3697 toplevels = gtk_window_list_toplevels ();
3698 tmp_list = toplevels;
3699 while (tmp_list != NULL)
3701 GtkWindowIconInfo *info;
3702 GtkWindow *w = tmp_list->data;
3704 info = get_icon_info (w);
3705 if (info && info->using_default_icon)
3707 gtk_window_unrealize_icon (w);
3708 if (GTK_WIDGET_REALIZED (w))
3709 gtk_window_realize_icon (w);
3712 tmp_list = tmp_list->next;
3714 g_list_free (toplevels);
3718 * gtk_window_set_default_icon:
3721 * Sets an icon to be used as fallback for windows that haven't
3722 * had gtk_window_set_icon() called on them from a pixbuf.
3727 gtk_window_set_default_icon (GdkPixbuf *icon)
3731 g_return_if_fail (GDK_IS_PIXBUF (icon));
3733 list = g_list_prepend (NULL, icon);
3734 gtk_window_set_default_icon_list (list);
3739 * gtk_window_set_default_icon_name:
3740 * @name: the name of the themed icon
3742 * Sets an icon to be used as fallback for windows that haven't
3743 * had gtk_window_set_icon_list() called on them from a named
3744 * themed icon, see gtk_window_set_icon_name().
3749 gtk_window_set_default_icon_name (const gchar *name)
3754 /* Update serial so we don't used cached pixmaps/masks
3756 default_icon_serial++;
3758 g_free (default_icon_name);
3759 default_icon_name = g_strdup (name);
3761 g_list_foreach (default_icon_list,
3762 (GFunc) g_object_unref, NULL);
3764 g_list_free (default_icon_list);
3765 default_icon_list = NULL;
3767 /* Update all toplevels */
3768 toplevels = gtk_window_list_toplevels ();
3769 tmp_list = toplevels;
3770 while (tmp_list != NULL)
3772 GtkWindowIconInfo *info;
3773 GtkWindow *w = tmp_list->data;
3775 info = get_icon_info (w);
3776 if (info && info->using_default_icon && info->using_themed_icon)
3778 gtk_window_unrealize_icon (w);
3779 if (GTK_WIDGET_REALIZED (w))
3780 gtk_window_realize_icon (w);
3783 tmp_list = tmp_list->next;
3785 g_list_free (toplevels);
3789 * gtk_window_get_default_icon_name:
3791 * Returns the fallback icon name for windows that has been set
3792 * with gtk_window_set_default_icon_name(). The returned
3793 * string is owned by GTK+ and should not be modified. It
3794 * is only valid until the next call to
3795 * gtk_window_set_default_icon_name().
3797 * Returns: the fallback icon name for windows
3802 gtk_window_get_default_icon_name (void)
3804 return default_icon_name;
3808 * gtk_window_set_default_icon_from_file:
3809 * @filename: location of icon file
3810 * @err: location to store error, or %NULL.
3812 * Sets an icon to be used as fallback for windows that haven't
3813 * had gtk_window_set_icon_list() called on them from a file
3814 * on disk. Warns on failure if @err is %NULL.
3816 * Returns: %TRUE if setting the icon succeeded.
3821 gtk_window_set_default_icon_from_file (const gchar *filename,
3824 GdkPixbuf *pixbuf = load_pixbuf_verbosely (filename, err);
3828 gtk_window_set_default_icon (pixbuf);
3829 g_object_unref (pixbuf);
3838 * gtk_window_get_default_icon_list:
3840 * Gets the value set by gtk_window_set_default_icon_list().
3841 * The list is a copy and should be freed with g_list_free(),
3842 * but the pixbufs in the list have not had their reference count
3845 * Return value: copy of default icon list
3848 gtk_window_get_default_icon_list (void)
3850 return g_list_copy (default_icon_list);
3854 gtk_window_set_default_size_internal (GtkWindow *window,
3855 gboolean change_width,
3857 gboolean change_height,
3859 gboolean is_geometry)
3861 GtkWindowGeometryInfo *info;
3863 g_return_if_fail (change_width == FALSE || width >= -1);
3864 g_return_if_fail (change_height == FALSE || height >= -1);
3866 info = gtk_window_get_geometry_info (window, TRUE);
3868 g_object_freeze_notify (G_OBJECT (window));
3870 info->default_is_geometry = is_geometry != FALSE;
3880 info->default_width = width;
3882 g_object_notify (G_OBJECT (window), "default-width");
3893 info->default_height = height;
3895 g_object_notify (G_OBJECT (window), "default-height");
3898 g_object_thaw_notify (G_OBJECT (window));
3900 gtk_widget_queue_resize_no_redraw (GTK_WIDGET (window));
3904 * gtk_window_set_default_size:
3905 * @window: a #GtkWindow
3906 * @width: width in pixels, or -1 to unset the default width
3907 * @height: height in pixels, or -1 to unset the default height
3909 * Sets the default size of a window. If the window's "natural" size
3910 * (its size request) is larger than the default, the default will be
3911 * ignored. More generally, if the default size does not obey the
3912 * geometry hints for the window (gtk_window_set_geometry_hints() can
3913 * be used to set these explicitly), the default size will be clamped
3914 * to the nearest permitted size.
3916 * Unlike gtk_widget_set_size_request(), which sets a size request for
3917 * a widget and thus would keep users from shrinking the window, this
3918 * function only sets the initial size, just as if the user had
3919 * resized the window themselves. Users can still shrink the window
3920 * again as they normally would. Setting a default size of -1 means to
3921 * use the "natural" default size (the size request of the window).
3923 * For more control over a window's initial size and how resizing works,
3924 * investigate gtk_window_set_geometry_hints().
3926 * For some uses, gtk_window_resize() is a more appropriate function.
3927 * gtk_window_resize() changes the current size of the window, rather
3928 * than the size to be used on initial display. gtk_window_resize() always
3929 * affects the window itself, not the geometry widget.
3931 * The default size of a window only affects the first time a window is
3932 * shown; if a window is hidden and re-shown, it will remember the size
3933 * it had prior to hiding, rather than using the default size.
3935 * Windows can't actually be 0x0 in size, they must be at least 1x1, but
3936 * passing 0 for @width and @height is OK, resulting in a 1x1 default size.
3939 gtk_window_set_default_size (GtkWindow *window,
3943 g_return_if_fail (GTK_IS_WINDOW (window));
3944 g_return_if_fail (width >= -1);
3945 g_return_if_fail (height >= -1);
3947 gtk_window_set_default_size_internal (window, TRUE, width, TRUE, height, FALSE);
3951 * gtk_window_get_default_size:
3952 * @window: a #GtkWindow
3953 * @width: location to store the default width, or %NULL
3954 * @height: location to store the default height, or %NULL
3956 * Gets the default size of the window. A value of -1 for the width or
3957 * height indicates that a default size has not been explicitly set
3958 * for that dimension, so the "natural" size of the window will be
3963 gtk_window_get_default_size (GtkWindow *window,
3967 GtkWindowGeometryInfo *info;
3969 g_return_if_fail (GTK_IS_WINDOW (window));
3971 info = gtk_window_get_geometry_info (window, FALSE);
3974 *width = info ? info->default_width : -1;
3977 *height = info ? info->default_height : -1;
3981 * gtk_window_resize:
3982 * @window: a #GtkWindow
3983 * @width: width in pixels to resize the window to
3984 * @height: height in pixels to resize the window to
3986 * Resizes the window as if the user had done so, obeying geometry
3987 * constraints. The default geometry constraint is that windows may
3988 * not be smaller than their size request; to override this
3989 * constraint, call gtk_widget_set_size_request() to set the window's
3990 * request to a smaller value.
3992 * If gtk_window_resize() is called before showing a window for the
3993 * first time, it overrides any default size set with
3994 * gtk_window_set_default_size().
3996 * Windows may not be resized smaller than 1 by 1 pixels.
4000 gtk_window_resize (GtkWindow *window,
4004 GtkWindowGeometryInfo *info;
4006 g_return_if_fail (GTK_IS_WINDOW (window));
4007 g_return_if_fail (width > 0);
4008 g_return_if_fail (height > 0);
4010 info = gtk_window_get_geometry_info (window, TRUE);
4012 info->resize_width = width;
4013 info->resize_height = height;
4015 gtk_widget_queue_resize_no_redraw (GTK_WIDGET (window));
4019 * gtk_window_get_size:
4020 * @window: a #GtkWindow
4021 * @width: (out): return location for width, or %NULL
4022 * @height: (out): return location for height, or %NULL
4024 * Obtains the current size of @window. If @window is not onscreen,
4025 * it returns the size GTK+ will suggest to the <link
4026 * linkend="gtk-X11-arch">window manager</link> for the initial window
4027 * size (but this is not reliably the same as the size the window
4028 * manager will actually select). The size obtained by
4029 * gtk_window_get_size() is the last size received in a
4030 * #GdkEventConfigure, that is, GTK+ uses its locally-stored size,
4031 * rather than querying the X server for the size. As a result, if you
4032 * call gtk_window_resize() then immediately call
4033 * gtk_window_get_size(), the size won't have taken effect yet. After
4034 * the window manager processes the resize request, GTK+ receives
4035 * notification that the size has changed via a configure event, and
4036 * the size of the window gets updated.
4038 * Note 1: Nearly any use of this function creates a race condition,
4039 * because the size of the window may change between the time that you
4040 * get the size and the time that you perform some action assuming
4041 * that size is the current size. To avoid race conditions, connect to
4042 * "configure-event" on the window and adjust your size-dependent
4043 * state to match the size delivered in the #GdkEventConfigure.
4045 * Note 2: The returned size does <emphasis>not</emphasis> include the
4046 * size of the window manager decorations (aka the window frame or
4047 * border). Those are not drawn by GTK+ and GTK+ has no reliable
4048 * method of determining their size.
4050 * Note 3: If you are getting a window size in order to position
4051 * the window onscreen, there may be a better way. The preferred
4052 * way is to simply set the window's semantic type with
4053 * gtk_window_set_type_hint(), which allows the window manager to
4054 * e.g. center dialogs. Also, if you set the transient parent of
4055 * dialogs with gtk_window_set_transient_for() window managers
4056 * will often center the dialog over its parent window. It's
4057 * much preferred to let the window manager handle these
4058 * things rather than doing it yourself, because all apps will
4059 * behave consistently and according to user prefs if the window
4060 * manager handles it. Also, the window manager can take the size
4061 * of the window decorations/border into account, while your
4062 * application cannot.
4064 * In any case, if you insist on application-specified window
4065 * positioning, there's <emphasis>still</emphasis> a better way than
4066 * doing it yourself - gtk_window_set_position() will frequently
4067 * handle the details for you.
4071 gtk_window_get_size (GtkWindow *window,
4077 g_return_if_fail (GTK_IS_WINDOW (window));
4079 if (width == NULL && height == NULL)
4082 if (GTK_WIDGET_MAPPED (window))
4084 gdk_drawable_get_size (GTK_WIDGET (window)->window,
4089 GdkRectangle configure_request;
4091 gtk_window_compute_configure_request (window,
4095 w = configure_request.width;
4096 h = configure_request.height;
4107 * @window: a #GtkWindow
4108 * @x: X coordinate to move window to
4109 * @y: Y coordinate to move window to
4111 * Asks the <link linkend="gtk-X11-arch">window manager</link> to move
4112 * @window to the given position. Window managers are free to ignore
4113 * this; most window managers ignore requests for initial window
4114 * positions (instead using a user-defined placement algorithm) and
4115 * honor requests after the window has already been shown.
4117 * Note: the position is the position of the gravity-determined
4118 * reference point for the window. The gravity determines two things:
4119 * first, the location of the reference point in root window
4120 * coordinates; and second, which point on the window is positioned at
4121 * the reference point.
4123 * By default the gravity is #GDK_GRAVITY_NORTH_WEST, so the reference
4124 * point is simply the @x, @y supplied to gtk_window_move(). The
4125 * top-left corner of the window decorations (aka window frame or
4126 * border) will be placed at @x, @y. Therefore, to position a window
4127 * at the top left of the screen, you want to use the default gravity
4128 * (which is #GDK_GRAVITY_NORTH_WEST) and move the window to 0,0.
4130 * To position a window at the bottom right corner of the screen, you
4131 * would set #GDK_GRAVITY_SOUTH_EAST, which means that the reference
4132 * point is at @x + the window width and @y + the window height, and
4133 * the bottom-right corner of the window border will be placed at that
4134 * reference point. So, to place a window in the bottom right corner
4135 * you would first set gravity to south east, then write:
4136 * <literal>gtk_window_move (window, gdk_screen_width () - window_width,
4137 * gdk_screen_height () - window_height)</literal> (note that this
4138 * example does not take multi-head scenarios into account).
4140 * The Extended Window Manager Hints specification at <ulink
4141 * url="http://www.freedesktop.org/Standards/wm-spec">
4142 * http://www.freedesktop.org/Standards/wm-spec</ulink> has a
4143 * nice table of gravities in the "implementation notes" section.
4145 * The gtk_window_get_position() documentation may also be relevant.
4148 gtk_window_move (GtkWindow *window,
4152 GtkWindowGeometryInfo *info;
4155 g_return_if_fail (GTK_IS_WINDOW (window));
4157 widget = GTK_WIDGET (window);
4159 info = gtk_window_get_geometry_info (window, TRUE);
4161 if (GTK_WIDGET_MAPPED (window))
4163 /* we have now sent a request with this position
4164 * with currently-active constraints, so toggle flag.
4166 info->position_constraints_changed = FALSE;
4168 /* we only constrain if mapped - if not mapped,
4169 * then gtk_window_compute_configure_request()
4170 * will apply the constraints later, and we
4171 * don't want to lose information about
4172 * what position the user set before then.
4173 * i.e. if you do a move() then turn off POS_CENTER
4174 * then show the window, your move() will work.
4176 gtk_window_constrain_position (window,
4177 widget->allocation.width,
4178 widget->allocation.height,
4181 /* Note that this request doesn't go through our standard request
4182 * framework, e.g. doesn't increment configure_request_count,
4183 * doesn't set info->last, etc.; that's because
4184 * we don't save the info needed to arrive at this same request
4187 * To gtk_window_move_resize(), this will end up looking exactly
4188 * the same as the position being changed by the window
4192 /* FIXME are we handling gravity properly for framed windows? */
4194 gdk_window_move (window->frame,
4195 x - window->frame_left,
4196 y - window->frame_top);
4198 gdk_window_move (GTK_WIDGET (window)->window,
4203 /* Save this position to apply on mapping */
4204 info->initial_x = x;
4205 info->initial_y = y;
4206 info->initial_pos_set = TRUE;
4211 * gtk_window_get_position:
4212 * @window: a #GtkWindow
4213 * @root_x: return location for X coordinate of gravity-determined reference point
4214 * @root_y: return location for Y coordinate of gravity-determined reference point
4216 * This function returns the position you need to pass to
4217 * gtk_window_move() to keep @window in its current position. This
4218 * means that the meaning of the returned value varies with window
4219 * gravity. See gtk_window_move() for more details.
4221 * If you haven't changed the window gravity, its gravity will be
4222 * #GDK_GRAVITY_NORTH_WEST. This means that gtk_window_get_position()
4223 * gets the position of the top-left corner of the window manager
4224 * frame for the window. gtk_window_move() sets the position of this
4225 * same top-left corner.
4227 * gtk_window_get_position() is not 100% reliable because the X Window System
4228 * does not specify a way to obtain the geometry of the
4229 * decorations placed on a window by the window manager.
4230 * Thus GTK+ is using a "best guess" that works with most
4233 * Moreover, nearly all window managers are historically broken with
4234 * respect to their handling of window gravity. So moving a window to
4235 * its current position as returned by gtk_window_get_position() tends
4236 * to result in moving the window slightly. Window managers are
4237 * slowly getting better over time.
4239 * If a window has gravity #GDK_GRAVITY_STATIC the window manager
4240 * frame is not relevant, and thus gtk_window_get_position() will
4241 * always produce accurate results. However you can't use static
4242 * gravity to do things like place a window in a corner of the screen,
4243 * because static gravity ignores the window manager decorations.
4245 * If you are saving and restoring your application's window
4246 * positions, you should know that it's impossible for applications to
4247 * do this without getting it somewhat wrong because applications do
4248 * not have sufficient knowledge of window manager state. The Correct
4249 * Mechanism is to support the session management protocol (see the
4250 * "GnomeClient" object in the GNOME libraries for example) and allow
4251 * the window manager to save your window sizes and positions.
4256 gtk_window_get_position (GtkWindow *window,
4262 g_return_if_fail (GTK_IS_WINDOW (window));
4264 widget = GTK_WIDGET (window);
4266 if (window->gravity == GDK_GRAVITY_STATIC)
4268 if (GTK_WIDGET_MAPPED (widget))
4270 /* This does a server round-trip, which is sort of wrong;
4271 * but a server round-trip is inevitable for
4272 * gdk_window_get_frame_extents() in the usual
4273 * NorthWestGravity case below, so not sure what else to
4274 * do. We should likely be consistent about whether we get
4275 * the client-side info or the server-side info.
4277 gdk_window_get_origin (widget->window, root_x, root_y);
4281 GdkRectangle configure_request;
4283 gtk_window_compute_configure_request (window,
4287 *root_x = configure_request.x;
4288 *root_y = configure_request.y;
4293 GdkRectangle frame_extents;
4298 if (GTK_WIDGET_MAPPED (widget))
4301 gdk_window_get_frame_extents (window->frame, &frame_extents);
4303 gdk_window_get_frame_extents (widget->window, &frame_extents);
4304 x = frame_extents.x;
4305 y = frame_extents.y;
4306 gtk_window_get_size (window, &w, &h);
4310 /* We just say the frame has 0 size on all sides.
4311 * Not sure what else to do.
4313 gtk_window_compute_configure_request (window,
4316 x = frame_extents.x;
4317 y = frame_extents.y;
4318 w = frame_extents.width;
4319 h = frame_extents.height;
4322 switch (window->gravity)
4324 case GDK_GRAVITY_NORTH:
4325 case GDK_GRAVITY_CENTER:
4326 case GDK_GRAVITY_SOUTH:
4327 /* Find center of frame. */
4328 x += frame_extents.width / 2;
4329 /* Center client window on that point. */
4333 case GDK_GRAVITY_SOUTH_EAST:
4334 case GDK_GRAVITY_EAST:
4335 case GDK_GRAVITY_NORTH_EAST:
4336 /* Find right edge of frame */
4337 x += frame_extents.width;
4338 /* Align left edge of client at that point. */
4345 switch (window->gravity)
4347 case GDK_GRAVITY_WEST:
4348 case GDK_GRAVITY_CENTER:
4349 case GDK_GRAVITY_EAST:
4350 /* Find center of frame. */
4351 y += frame_extents.height / 2;
4352 /* Center client window there. */
4355 case GDK_GRAVITY_SOUTH_WEST:
4356 case GDK_GRAVITY_SOUTH:
4357 case GDK_GRAVITY_SOUTH_EAST:
4358 /* Find south edge of frame */
4359 y += frame_extents.height;
4360 /* Place bottom edge of client there */
4375 * gtk_window_reshow_with_initial_size:
4376 * @window: a #GtkWindow
4378 * Hides @window, then reshows it, resetting the
4379 * default size and position of the window. Used
4380 * by GUI builders only.
4383 gtk_window_reshow_with_initial_size (GtkWindow *window)
4387 g_return_if_fail (GTK_IS_WINDOW (window));
4389 widget = GTK_WIDGET (window);
4391 gtk_widget_hide (widget);
4392 gtk_widget_unrealize (widget);
4393 gtk_widget_show (widget);
4397 gtk_window_destroy (GtkObject *object)
4399 GtkWindow *window = GTK_WINDOW (object);
4401 toplevel_list = g_slist_remove (toplevel_list, window);
4403 if (window->transient_parent)
4404 gtk_window_set_transient_for (window, NULL);
4406 /* frees the icons */
4407 gtk_window_set_icon_list (window, NULL);
4409 if (window->has_user_ref_count)
4411 window->has_user_ref_count = FALSE;
4412 g_object_unref (window);
4416 gtk_window_group_remove_window (window->group, window);
4418 gtk_window_free_key_hash (window);
4420 GTK_OBJECT_CLASS (gtk_window_parent_class)->destroy (object);
4424 gtk_window_finalize (GObject *object)
4426 GtkWindow *window = GTK_WINDOW (object);
4427 GtkWindowPrivate *priv = GTK_WINDOW_GET_PRIVATE (window);
4428 GtkMnemonicHash *mnemonic_hash;
4430 g_free (window->title);
4431 g_free (window->wmclass_name);
4432 g_free (window->wmclass_class);
4433 g_free (window->wm_role);
4435 mnemonic_hash = gtk_window_get_mnemonic_hash (window, FALSE);
4437 _gtk_mnemonic_hash_free (mnemonic_hash);
4439 if (window->geometry_info)
4441 if (window->geometry_info->widget)
4442 g_signal_handlers_disconnect_by_func (window->geometry_info->widget,
4443 gtk_widget_destroyed,
4444 &window->geometry_info->widget);
4445 g_free (window->geometry_info);
4448 if (window->keys_changed_handler)
4450 g_source_remove (window->keys_changed_handler);
4451 window->keys_changed_handler = 0;
4455 g_signal_handlers_disconnect_by_func (window->screen,
4456 gtk_window_on_composited_changed, window);
4458 g_free (priv->startup_id);
4460 G_OBJECT_CLASS (gtk_window_parent_class)->finalize (object);
4464 gtk_window_show (GtkWidget *widget)
4466 GtkWindow *window = GTK_WINDOW (widget);
4467 GtkContainer *container = GTK_CONTAINER (window);
4468 gboolean need_resize;
4470 GTK_WIDGET_SET_FLAGS (widget, GTK_VISIBLE);
4472 need_resize = container->need_resize || !GTK_WIDGET_REALIZED (widget);
4473 container->need_resize = FALSE;
4477 GtkWindowGeometryInfo *info = gtk_window_get_geometry_info (window, TRUE);
4478 GtkAllocation allocation = { 0, 0 };
4479 GdkRectangle configure_request;
4480 GdkGeometry new_geometry;
4482 gboolean was_realized;
4484 /* We are going to go ahead and perform this configure request
4485 * and then emulate a configure notify by going ahead and
4486 * doing a size allocate. Sort of a synchronous
4487 * mini-copy of gtk_window_move_resize() here.
4489 gtk_window_compute_configure_request (window,
4494 /* We update this because we are going to go ahead
4495 * and gdk_window_resize() below, rather than
4498 info->last.configure_request.width = configure_request.width;
4499 info->last.configure_request.height = configure_request.height;
4501 /* and allocate the window - this is normally done
4502 * in move_resize in response to configure notify
4504 allocation.width = configure_request.width;
4505 allocation.height = configure_request.height;
4506 gtk_widget_size_allocate (widget, &allocation);
4508 /* Then we guarantee we have a realize */
4509 was_realized = FALSE;
4510 if (!GTK_WIDGET_REALIZED (widget))
4512 gtk_widget_realize (widget);
4513 was_realized = TRUE;
4516 /* Must be done after the windows are realized,
4517 * so that the decorations can be read
4519 gtk_decorated_window_calculate_frame_size (window);
4521 /* We only send configure request if we didn't just finish
4522 * creating the window; if we just created the window
4523 * then we created it with widget->allocation anyhow.
4526 gdk_window_move_resize (widget->window,
4527 configure_request.x,
4528 configure_request.y,
4529 configure_request.width,
4530 configure_request.height);
4533 gtk_container_check_resize (container);
4535 gtk_widget_map (widget);
4537 /* Try to make sure that we have some focused widget
4539 if (!window->focus_widget && !GTK_IS_PLUG (window))
4540 gtk_window_move_focus (window, GTK_DIR_TAB_FORWARD);
4543 gtk_grab_add (widget);
4547 gtk_window_hide (GtkWidget *widget)
4549 GtkWindow *window = GTK_WINDOW (widget);
4551 GTK_WIDGET_UNSET_FLAGS (widget, GTK_VISIBLE);
4552 gtk_widget_unmap (widget);
4555 gtk_grab_remove (widget);
4559 gtk_window_map (GtkWidget *widget)
4561 GtkWindow *window = GTK_WINDOW (widget);
4562 GtkWindowPrivate *priv = GTK_WINDOW_GET_PRIVATE (window);
4563 GdkWindow *toplevel;
4564 gboolean auto_mnemonics;
4566 GTK_WIDGET_SET_FLAGS (widget, GTK_MAPPED);
4568 if (window->bin.child &&
4569 GTK_WIDGET_VISIBLE (window->bin.child) &&
4570 !GTK_WIDGET_MAPPED (window->bin.child))
4571 gtk_widget_map (window->bin.child);
4574 toplevel = window->frame;
4576 toplevel = widget->window;
4578 if (window->maximize_initially)
4579 gdk_window_maximize (toplevel);
4581 gdk_window_unmaximize (toplevel);
4583 if (window->stick_initially)
4584 gdk_window_stick (toplevel);
4586 gdk_window_unstick (toplevel);
4588 if (window->iconify_initially)
4589 gdk_window_iconify (toplevel);
4591 gdk_window_deiconify (toplevel);
4593 if (priv->fullscreen_initially)
4594 gdk_window_fullscreen (toplevel);
4596 gdk_window_unfullscreen (toplevel);
4598 gdk_window_set_keep_above (toplevel, priv->above_initially);
4600 gdk_window_set_keep_below (toplevel, priv->below_initially);
4602 /* No longer use the default settings */
4603 window->need_default_size = FALSE;
4604 window->need_default_position = FALSE;
4606 if (priv->reset_type_hint)
4608 /* We should only reset the type hint when the application
4609 * used gtk_window_set_type_hint() to change the hint.
4610 * Some applications use X directly to change the properties;
4611 * in that case, we shouldn't overwrite what they did.
4613 gdk_window_set_type_hint (widget->window, priv->type_hint);
4614 priv->reset_type_hint = FALSE;
4617 gdk_window_show (widget->window);
4620 gdk_window_show (window->frame);
4622 if (!disable_startup_notification)
4624 /* Do we have a custom startup-notification id? */
4625 if (priv->startup_id != NULL)
4627 /* Make sure we have a "real" id */
4628 if (!startup_id_is_fake (priv->startup_id))
4629 gdk_notify_startup_complete_with_id (priv->startup_id);
4631 g_free (priv->startup_id);
4632 priv->startup_id = NULL;
4634 else if (!sent_startup_notification)
4636 sent_startup_notification = TRUE;
4637 gdk_notify_startup_complete ();
4641 /* if auto-mnemonics is enabled and mnemonics visible is not already set
4642 * (as in the case of popup menus), then hide mnemonics initially
4644 g_object_get (gtk_widget_get_settings (widget), "gtk-auto-mnemonics",
4645 &auto_mnemonics, NULL);
4646 if (auto_mnemonics && !priv->mnemonics_visible_set)
4647 gtk_window_set_mnemonics_visible (window, FALSE);
4651 gtk_window_map_event (GtkWidget *widget,
4654 if (!GTK_WIDGET_MAPPED (widget))
4656 /* we should be be unmapped, but are getting a MapEvent, this may happen
4657 * to toplevel XWindows if mapping was intercepted by a window manager
4658 * and an unmap request occoured while the MapRequestEvent was still
4659 * being handled. we work around this situaiton here by re-requesting
4660 * the window being unmapped. more details can be found in:
4661 * http://bugzilla.gnome.org/show_bug.cgi?id=316180
4663 gdk_window_hide (widget->window);
4669 gtk_window_unmap (GtkWidget *widget)
4671 GtkWindow *window = GTK_WINDOW (widget);
4672 GtkWindowPrivate *priv = GTK_WINDOW_GET_PRIVATE (widget);
4673 GtkWindowGeometryInfo *info;
4674 GdkWindowState state;
4676 GTK_WIDGET_UNSET_FLAGS (widget, GTK_MAPPED);
4678 gdk_window_withdraw (window->frame);
4680 gdk_window_withdraw (widget->window);
4682 window->configure_request_count = 0;
4683 window->configure_notify_received = FALSE;
4685 /* on unmap, we reset the default positioning of the window,
4686 * so it's placed again, but we don't reset the default
4687 * size of the window, so it's remembered.
4689 window->need_default_position = TRUE;
4691 info = gtk_window_get_geometry_info (window, FALSE);
4694 info->initial_pos_set = FALSE;
4695 info->position_constraints_changed = FALSE;
4698 state = gdk_window_get_state (widget->window);
4699 window->iconify_initially = (state & GDK_WINDOW_STATE_ICONIFIED) != 0;
4700 window->maximize_initially = (state & GDK_WINDOW_STATE_MAXIMIZED) != 0;
4701 window->stick_initially = (state & GDK_WINDOW_STATE_STICKY) != 0;
4702 priv->above_initially = (state & GDK_WINDOW_STATE_ABOVE) != 0;
4703 priv->below_initially = (state & GDK_WINDOW_STATE_BELOW) != 0;
4707 gtk_window_realize (GtkWidget *widget)
4710 GdkWindow *parent_window;
4711 GdkWindowAttr attributes;
4712 gint attributes_mask;
4713 GtkWindowPrivate *priv;
4715 window = GTK_WINDOW (widget);
4716 priv = GTK_WINDOW_GET_PRIVATE (window);
4718 /* ensure widget tree is properly size allocated */
4719 if (widget->allocation.x == -1 &&
4720 widget->allocation.y == -1 &&
4721 widget->allocation.width == 1 &&
4722 widget->allocation.height == 1)
4724 GtkRequisition requisition;
4725 GtkAllocation allocation = { 0, 0, 200, 200 };
4727 gtk_widget_size_request (widget, &requisition);
4728 if (requisition.width || requisition.height)
4730 /* non-empty window */
4731 allocation.width = requisition.width;
4732 allocation.height = requisition.height;
4734 gtk_widget_size_allocate (widget, &allocation);
4736 _gtk_container_queue_resize (GTK_CONTAINER (widget));
4738 g_return_if_fail (!GTK_WIDGET_REALIZED (widget));
4741 GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED);
4743 switch (window->type)
4745 case GTK_WINDOW_TOPLEVEL:
4746 attributes.window_type = GDK_WINDOW_TOPLEVEL;
4748 case GTK_WINDOW_POPUP:
4749 attributes.window_type = GDK_WINDOW_TEMP;
4752 g_warning (G_STRLOC": Unknown window type %d!", window->type);
4756 attributes.title = window->title;
4757 attributes.wmclass_name = window->wmclass_name;
4758 attributes.wmclass_class = window->wmclass_class;
4759 attributes.wclass = GDK_INPUT_OUTPUT;
4760 attributes.visual = gtk_widget_get_visual (widget);
4761 attributes.colormap = gtk_widget_get_colormap (widget);
4763 if (window->has_frame)
4765 attributes.width = widget->allocation.width + window->frame_left + window->frame_right;
4766 attributes.height = widget->allocation.height + window->frame_top + window->frame_bottom;
4767 attributes.event_mask = (GDK_EXPOSURE_MASK |
4768 GDK_KEY_PRESS_MASK |
4769 GDK_ENTER_NOTIFY_MASK |
4770 GDK_LEAVE_NOTIFY_MASK |
4771 GDK_FOCUS_CHANGE_MASK |
4772 GDK_STRUCTURE_MASK |
4773 GDK_BUTTON_MOTION_MASK |
4774 GDK_POINTER_MOTION_HINT_MASK |
4775 GDK_BUTTON_PRESS_MASK |
4776 GDK_BUTTON_RELEASE_MASK);
4778 attributes_mask = GDK_WA_VISUAL | GDK_WA_COLORMAP;
4780 window->frame = gdk_window_new (gtk_widget_get_root_window (widget),
4781 &attributes, attributes_mask);
4783 if (priv->opacity_set)
4784 gdk_window_set_opacity (window->frame, priv->opacity);
4786 gdk_window_set_user_data (window->frame, widget);
4788 attributes.window_type = GDK_WINDOW_CHILD;
4789 attributes.x = window->frame_left;
4790 attributes.y = window->frame_top;
4792 attributes_mask = GDK_WA_X | GDK_WA_Y;
4794 parent_window = window->frame;
4796 g_signal_connect (window,
4798 G_CALLBACK (gtk_window_event),
4803 attributes_mask = 0;
4804 parent_window = gtk_widget_get_root_window (widget);
4807 attributes.width = widget->allocation.width;
4808 attributes.height = widget->allocation.height;
4809 attributes.event_mask = gtk_widget_get_events (widget);
4810 attributes.event_mask |= (GDK_EXPOSURE_MASK |
4811 GDK_KEY_PRESS_MASK |
4812 GDK_KEY_RELEASE_MASK |
4813 GDK_ENTER_NOTIFY_MASK |
4814 GDK_LEAVE_NOTIFY_MASK |
4815 GDK_FOCUS_CHANGE_MASK |
4816 GDK_STRUCTURE_MASK);
4817 attributes.type_hint = priv->type_hint;
4819 attributes_mask |= GDK_WA_VISUAL | GDK_WA_COLORMAP | GDK_WA_TYPE_HINT;
4820 attributes_mask |= (window->title ? GDK_WA_TITLE : 0);
4821 attributes_mask |= (window->wmclass_name ? GDK_WA_WMCLASS : 0);
4823 widget->window = gdk_window_new (parent_window, &attributes, attributes_mask);
4825 if (!window->has_frame && priv->opacity_set)
4826 gdk_window_set_opacity (widget->window, priv->opacity);
4828 gdk_window_enable_synchronized_configure (widget->window);
4830 gdk_window_set_user_data (widget->window, window);
4832 widget->style = gtk_style_attach (widget->style, widget->window);
4833 gtk_style_set_background (widget->style, widget->window, GTK_STATE_NORMAL);
4835 gtk_style_set_background (widget->style, window->frame, GTK_STATE_NORMAL);
4837 /* This is a bad hack to set the window background. */
4838 gtk_window_paint (widget, NULL);
4840 if (window->transient_parent &&
4841 GTK_WIDGET_REALIZED (window->transient_parent))
4842 gdk_window_set_transient_for (widget->window,
4843 GTK_WIDGET (window->transient_parent)->window);
4845 if (window->wm_role)
4846 gdk_window_set_role (widget->window, window->wm_role);
4848 if (!window->decorated)
4849 gdk_window_set_decorations (widget->window, 0);
4851 if (!priv->deletable)
4852 gdk_window_set_functions (widget->window, GDK_FUNC_ALL | GDK_FUNC_CLOSE);
4854 if (gtk_window_get_skip_pager_hint (window))
4855 gdk_window_set_skip_pager_hint (widget->window, TRUE);
4857 if (gtk_window_get_skip_taskbar_hint (window))
4858 gdk_window_set_skip_taskbar_hint (widget->window, TRUE);
4860 if (gtk_window_get_accept_focus (window))
4861 gdk_window_set_accept_focus (widget->window, TRUE);
4863 gdk_window_set_accept_focus (widget->window, FALSE);
4865 if (gtk_window_get_focus_on_map (window))
4866 gdk_window_set_focus_on_map (widget->window, TRUE);
4868 gdk_window_set_focus_on_map (widget->window, FALSE);
4871 gdk_window_set_modal_hint (widget->window, TRUE);
4873 gdk_window_set_modal_hint (widget->window, FALSE);
4875 if (priv->startup_id)
4877 #ifdef GDK_WINDOWING_X11
4878 guint32 timestamp = extract_time_from_startup_id (priv->startup_id);
4879 if (timestamp != GDK_CURRENT_TIME)
4880 gdk_x11_window_set_user_time (widget->window, timestamp);
4882 if (!startup_id_is_fake (priv->startup_id))
4883 gdk_window_set_startup_id (widget->window, priv->startup_id);
4887 gtk_window_realize_icon (window);
4891 gtk_window_unrealize (GtkWidget *widget)
4894 GtkWindowGeometryInfo *info;
4896 window = GTK_WINDOW (widget);
4898 /* On unrealize, we reset the size of the window such
4899 * that we will re-apply the default sizing stuff
4900 * next time we show the window.
4902 * Default positioning is reset on unmap, instead of unrealize.
4904 window->need_default_size = TRUE;
4905 info = gtk_window_get_geometry_info (window, FALSE);
4908 info->resize_width = -1;
4909 info->resize_height = -1;
4910 info->last.configure_request.x = 0;
4911 info->last.configure_request.y = 0;
4912 info->last.configure_request.width = -1;
4913 info->last.configure_request.height = -1;
4914 /* be sure we reset geom hints on re-realize */
4915 info->last.flags = 0;
4920 gdk_window_set_user_data (window->frame, NULL);
4921 gdk_window_destroy (window->frame);
4922 window->frame = NULL;
4926 gtk_window_unrealize_icon (window);
4928 GTK_WIDGET_CLASS (gtk_window_parent_class)->unrealize (widget);
4932 gtk_window_size_request (GtkWidget *widget,
4933 GtkRequisition *requisition)
4938 window = GTK_WINDOW (widget);
4939 bin = GTK_BIN (window);
4941 requisition->width = GTK_CONTAINER (window)->border_width * 2;
4942 requisition->height = GTK_CONTAINER (window)->border_width * 2;
4944 if (bin->child && GTK_WIDGET_VISIBLE (bin->child))
4946 GtkRequisition child_requisition;
4948 gtk_widget_size_request (bin->child, &child_requisition);
4950 requisition->width += child_requisition.width;
4951 requisition->height += child_requisition.height;
4956 gtk_window_size_allocate (GtkWidget *widget,
4957 GtkAllocation *allocation)
4960 GtkAllocation child_allocation;
4962 window = GTK_WINDOW (widget);
4963 widget->allocation = *allocation;
4965 if (window->bin.child && GTK_WIDGET_VISIBLE (window->bin.child))
4967 child_allocation.x = GTK_CONTAINER (window)->border_width;
4968 child_allocation.y = GTK_CONTAINER (window)->border_width;
4969 child_allocation.width =
4970 MAX (1, (gint)allocation->width - child_allocation.x * 2);
4971 child_allocation.height =
4972 MAX (1, (gint)allocation->height - child_allocation.y * 2);
4974 gtk_widget_size_allocate (window->bin.child, &child_allocation);
4977 if (GTK_WIDGET_REALIZED (widget) && window->frame)
4979 gdk_window_resize (window->frame,
4980 allocation->width + window->frame_left + window->frame_right,
4981 allocation->height + window->frame_top + window->frame_bottom);
4986 gtk_window_event (GtkWidget *widget, GdkEvent *event)
4989 gboolean return_val;
4991 window = GTK_WINDOW (widget);
4993 if (window->frame && (event->any.window == window->frame))
4995 if ((event->type != GDK_KEY_PRESS) &&
4996 (event->type != GDK_KEY_RELEASE) &&
4997 (event->type != GDK_FOCUS_CHANGE))
4999 g_signal_stop_emission_by_name (widget, "event");
5001 g_signal_emit (widget, window_signals[FRAME_EVENT], 0, event, &return_val);
5006 g_object_unref (event->any.window);
5007 event->any.window = g_object_ref (widget->window);
5015 gtk_window_frame_event (GtkWindow *window, GdkEvent *event)
5017 GdkEventConfigure *configure_event;
5020 switch (event->type)
5023 configure_event = (GdkEventConfigure *)event;
5025 /* Invalidate the decorations */
5028 rect.width = configure_event->width;
5029 rect.height = configure_event->height;
5031 gdk_window_invalidate_rect (window->frame, &rect, FALSE);
5033 /* Pass on the (modified) configure event */
5034 configure_event->width -= window->frame_left + window->frame_right;
5035 configure_event->height -= window->frame_top + window->frame_bottom;
5036 return gtk_window_configure_event (GTK_WIDGET (window), configure_event);
5045 gtk_window_configure_event (GtkWidget *widget,
5046 GdkEventConfigure *event)
5048 GtkWindow *window = GTK_WINDOW (widget);
5049 gboolean expected_reply = window->configure_request_count > 0;
5051 /* window->configure_request_count incremented for each
5052 * configure request, and decremented to a min of 0 for
5053 * each configure notify.
5055 * All it means is that we know we will get at least
5056 * window->configure_request_count more configure notifies.
5057 * We could get more configure notifies than that; some
5058 * of the configure notifies we get may be unrelated to
5059 * the configure requests. But we will get at least
5060 * window->configure_request_count notifies.
5063 if (window->configure_request_count > 0)
5065 window->configure_request_count -= 1;
5066 gdk_window_thaw_toplevel_updates_libgtk_only (widget->window);
5069 /* As an optimization, we avoid a resize when possible.
5071 * The only times we can avoid a resize are:
5072 * - we know only the position changed, not the size
5073 * - we know we have made more requests and so will get more
5074 * notifies and can wait to resize when we get them
5077 if (!expected_reply &&
5078 (widget->allocation.width == event->width &&
5079 widget->allocation.height == event->height))
5081 gdk_window_configure_finished (widget->window);
5086 * If we do need to resize, we do that by:
5087 * - filling in widget->allocation with the new size
5088 * - setting configure_notify_received to TRUE
5089 * for use in gtk_window_move_resize()
5090 * - queueing a resize, leading to invocation of
5091 * gtk_window_move_resize() in an idle handler
5095 window->configure_notify_received = TRUE;
5097 widget->allocation.width = event->width;
5098 widget->allocation.height = event->height;
5100 _gtk_container_queue_resize (GTK_CONTAINER (widget));
5105 /* the accel_key and accel_mods fields of the key have to be setup
5106 * upon calling this function. it'll then return whether that key
5107 * is at all used as accelerator, and if so will OR in the
5108 * accel_flags member of the key.
5111 _gtk_window_query_nonaccels (GtkWindow *window,
5113 GdkModifierType accel_mods)
5115 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
5117 /* movement keys are considered locked accels */
5120 static const guint bindings[] = {
5121 GDK_space, GDK_KP_Space, GDK_Return, GDK_ISO_Enter, GDK_KP_Enter, GDK_Up, GDK_KP_Up, GDK_Down, GDK_KP_Down,
5122 GDK_Left, GDK_KP_Left, GDK_Right, GDK_KP_Right, GDK_Tab, GDK_KP_Tab, GDK_ISO_Left_Tab,
5126 for (i = 0; i < G_N_ELEMENTS (bindings); i++)
5127 if (bindings[i] == accel_key)
5131 /* mnemonics are considered locked accels */
5132 if (accel_mods == window->mnemonic_modifier)
5134 GtkMnemonicHash *mnemonic_hash = gtk_window_get_mnemonic_hash (window, FALSE);
5135 if (mnemonic_hash && _gtk_mnemonic_hash_lookup (mnemonic_hash, accel_key))
5143 * gtk_window_propagate_key_event:
5144 * @window: a #GtkWindow
5145 * @event: a #GdkEventKey
5147 * Propagate a key press or release event to the focus widget and
5148 * up the focus container chain until a widget handles @event.
5149 * This is normally called by the default ::key_press_event and
5150 * ::key_release_event handlers for toplevel windows,
5151 * however in some cases it may be useful to call this directly when
5152 * overriding the standard key handling for a toplevel window.
5154 * Return value: %TRUE if a widget in the focus chain handled the event.
5159 gtk_window_propagate_key_event (GtkWindow *window,
5162 gboolean handled = FALSE;
5163 GtkWidget *widget, *focus;
5165 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
5167 widget = GTK_WIDGET (window);
5168 focus = window->focus_widget;
5170 g_object_ref (focus);
5173 focus && focus != widget &&
5174 gtk_widget_get_toplevel (focus) == widget)
5178 if (GTK_WIDGET_IS_SENSITIVE (focus))
5179 handled = gtk_widget_event (focus, (GdkEvent*) event);
5181 parent = focus->parent;
5183 g_object_ref (parent);
5185 g_object_unref (focus);
5191 g_object_unref (focus);
5197 gtk_window_key_press_event (GtkWidget *widget,
5200 GtkWindow *window = GTK_WINDOW (widget);
5201 gboolean handled = FALSE;
5203 /* handle mnemonics and accelerators */
5205 handled = gtk_window_activate_key (window, event);
5207 /* handle focus widget key events */
5209 handled = gtk_window_propagate_key_event (window, event);
5211 /* Chain up, invokes binding set */
5213 handled = GTK_WIDGET_CLASS (gtk_window_parent_class)->key_press_event (widget, event);
5219 gtk_window_key_release_event (GtkWidget *widget,
5222 GtkWindow *window = GTK_WINDOW (widget);
5223 gboolean handled = FALSE;
5225 /* handle focus widget key events */
5227 handled = gtk_window_propagate_key_event (window, event);
5229 /* Chain up, invokes binding set */
5231 handled = GTK_WIDGET_CLASS (gtk_window_parent_class)->key_release_event (widget, event);
5237 gtk_window_real_activate_default (GtkWindow *window)
5239 gtk_window_activate_default (window);
5243 gtk_window_real_activate_focus (GtkWindow *window)
5245 gtk_window_activate_focus (window);
5249 gtk_window_move_focus (GtkWindow *window,
5250 GtkDirectionType dir)
5252 gtk_widget_child_focus (GTK_WIDGET (window), dir);
5254 if (!GTK_CONTAINER (window)->focus_child)
5255 gtk_window_set_focus (window, NULL);
5259 gtk_window_enter_notify_event (GtkWidget *widget,
5260 GdkEventCrossing *event)
5266 gtk_window_leave_notify_event (GtkWidget *widget,
5267 GdkEventCrossing *event)
5273 do_focus_change (GtkWidget *widget,
5276 GdkEvent *fevent = gdk_event_new (GDK_FOCUS_CHANGE);
5278 g_object_ref (widget);
5281 GTK_WIDGET_SET_FLAGS (widget, GTK_HAS_FOCUS);
5283 GTK_WIDGET_UNSET_FLAGS (widget, GTK_HAS_FOCUS);
5285 fevent->focus_change.type = GDK_FOCUS_CHANGE;
5286 fevent->focus_change.window = widget->window;
5288 g_object_ref (widget->window);
5289 fevent->focus_change.in = in;
5291 gtk_widget_event (widget, fevent);
5293 g_object_notify (G_OBJECT (widget), "has-focus");
5295 g_object_unref (widget);
5296 gdk_event_free (fevent);
5300 gtk_window_focus_in_event (GtkWidget *widget,
5301 GdkEventFocus *event)
5303 GtkWindow *window = GTK_WINDOW (widget);
5305 /* It appears spurious focus in events can occur when
5306 * the window is hidden. So we'll just check to see if
5307 * the window is visible before actually handling the
5310 if (GTK_WIDGET_VISIBLE (widget))
5312 _gtk_window_set_has_toplevel_focus (window, TRUE);
5313 _gtk_window_set_is_active (window, TRUE);
5320 gtk_window_focus_out_event (GtkWidget *widget,
5321 GdkEventFocus *event)
5323 GtkWindow *window = GTK_WINDOW (widget);
5324 gboolean auto_mnemonics;
5326 _gtk_window_set_has_toplevel_focus (window, FALSE);
5327 _gtk_window_set_is_active (window, FALSE);
5329 /* set the mnemonic-visible property to false */
5330 g_object_get (gtk_widget_get_settings (widget),
5331 "gtk-auto-mnemonics", &auto_mnemonics, NULL);
5333 gtk_window_set_mnemonics_visible (window, FALSE);
5339 static GdkAtom atom_rcfiles = GDK_NONE;
5340 static GdkAtom atom_iconthemes = GDK_NONE;
5343 send_client_message_to_embedded_windows (GtkWidget *widget,
5344 GdkAtom message_type)
5346 GList *embedded_windows;
5348 embedded_windows = g_object_get_qdata (G_OBJECT (widget), quark_gtk_embedded);
5349 if (embedded_windows)
5351 GdkEvent *send_event = gdk_event_new (GDK_CLIENT_EVENT);
5354 for (i = 0; i < 5; i++)
5355 send_event->client.data.l[i] = 0;
5356 send_event->client.data_format = 32;
5357 send_event->client.message_type = message_type;
5359 while (embedded_windows)
5361 GdkNativeWindow xid = GDK_GPOINTER_TO_NATIVE_WINDOW(embedded_windows->data);
5362 gdk_event_send_client_message_for_display (gtk_widget_get_display (widget), send_event, xid);
5363 embedded_windows = embedded_windows->next;
5366 gdk_event_free (send_event);
5371 gtk_window_client_event (GtkWidget *widget,
5372 GdkEventClient *event)
5376 atom_rcfiles = gdk_atom_intern_static_string ("_GTK_READ_RCFILES");
5377 atom_iconthemes = gdk_atom_intern_static_string ("_GTK_LOAD_ICONTHEMES");
5380 if (event->message_type == atom_rcfiles)
5382 send_client_message_to_embedded_windows (widget, atom_rcfiles);
5383 gtk_rc_reparse_all_for_settings (gtk_widget_get_settings (widget), FALSE);
5386 if (event->message_type == atom_iconthemes)
5388 send_client_message_to_embedded_windows (widget, atom_iconthemes);
5389 _gtk_icon_theme_check_reload (gtk_widget_get_display (widget));
5396 gtk_window_check_resize (GtkContainer *container)
5398 GtkWindow *window = GTK_WINDOW (container);
5400 if (GTK_WIDGET_VISIBLE (container))
5401 gtk_window_move_resize (window);
5405 gtk_window_focus (GtkWidget *widget,
5406 GtkDirectionType direction)
5410 GtkContainer *container;
5411 GtkWidget *old_focus_child;
5414 container = GTK_CONTAINER (widget);
5415 window = GTK_WINDOW (widget);
5416 bin = GTK_BIN (widget);
5418 old_focus_child = container->focus_child;
5420 /* We need a special implementation here to deal properly with wrapping
5421 * around in the tab chain without the danger of going into an
5424 if (old_focus_child)
5426 if (gtk_widget_child_focus (old_focus_child, direction))
5430 if (window->focus_widget)
5432 if (direction == GTK_DIR_LEFT ||
5433 direction == GTK_DIR_RIGHT ||
5434 direction == GTK_DIR_UP ||
5435 direction == GTK_DIR_DOWN)
5440 /* Wrapped off the end, clear the focus setting for the toplpevel */
5441 parent = window->focus_widget->parent;
5444 gtk_container_set_focus_child (GTK_CONTAINER (parent), NULL);
5445 parent = GTK_WIDGET (parent)->parent;
5448 gtk_window_set_focus (GTK_WINDOW (container), NULL);
5451 /* Now try to focus the first widget in the window */
5454 if (gtk_widget_child_focus (bin->child, direction))
5462 gtk_window_real_set_focus (GtkWindow *window,
5465 GtkWidget *old_focus = window->focus_widget;
5466 gboolean had_default = FALSE;
5467 gboolean focus_had_default = FALSE;
5468 gboolean old_focus_had_default = FALSE;
5472 g_object_ref (old_focus);
5473 g_object_freeze_notify (G_OBJECT (old_focus));
5474 old_focus_had_default = GTK_WIDGET_HAS_DEFAULT (old_focus);
5478 g_object_ref (focus);
5479 g_object_freeze_notify (G_OBJECT (focus));
5480 focus_had_default = GTK_WIDGET_HAS_DEFAULT (focus);
5483 if (window->default_widget)
5484 had_default = GTK_WIDGET_HAS_DEFAULT (window->default_widget);
5486 if (window->focus_widget)
5488 if (GTK_WIDGET_RECEIVES_DEFAULT (window->focus_widget) &&
5489 (window->focus_widget != window->default_widget))
5491 GTK_WIDGET_UNSET_FLAGS (window->focus_widget, GTK_HAS_DEFAULT);
5492 gtk_widget_queue_draw (window->focus_widget);
5494 if (window->default_widget)
5495 GTK_WIDGET_SET_FLAGS (window->default_widget, GTK_HAS_DEFAULT);
5498 window->focus_widget = NULL;
5500 if (window->has_focus)
5501 do_focus_change (old_focus, FALSE);
5503 g_object_notify (G_OBJECT (old_focus), "is-focus");
5506 /* The above notifications may have set a new focus widget,
5507 * if so, we don't want to override it.
5509 if (focus && !window->focus_widget)
5511 window->focus_widget = focus;
5513 if (GTK_WIDGET_RECEIVES_DEFAULT (window->focus_widget) &&
5514 (window->focus_widget != window->default_widget))
5516 if (GTK_WIDGET_CAN_DEFAULT (window->focus_widget))
5517 GTK_WIDGET_SET_FLAGS (window->focus_widget, GTK_HAS_DEFAULT);
5519 if (window->default_widget)
5520 GTK_WIDGET_UNSET_FLAGS (window->default_widget, GTK_HAS_DEFAULT);
5523 if (window->has_focus)
5524 do_focus_change (window->focus_widget, TRUE);
5526 g_object_notify (G_OBJECT (window->focus_widget), "is-focus");
5529 /* If the default widget changed, a redraw will have been queued
5530 * on the old and new default widgets by gtk_window_set_default(), so
5531 * we only have to worry about the case where it didn't change.
5532 * We'll sometimes queue a draw twice on the new widget but that
5535 if (window->default_widget &&
5536 (had_default != GTK_WIDGET_HAS_DEFAULT (window->default_widget)))
5537 gtk_widget_queue_draw (window->default_widget);
5541 if (old_focus_had_default != GTK_WIDGET_HAS_DEFAULT (old_focus))
5542 gtk_widget_queue_draw (old_focus);
5544 g_object_thaw_notify (G_OBJECT (old_focus));
5545 g_object_unref (old_focus);
5549 if (focus_had_default != GTK_WIDGET_HAS_DEFAULT (focus))
5550 gtk_widget_queue_draw (focus);
5552 g_object_thaw_notify (G_OBJECT (focus));
5553 g_object_unref (focus);
5558 * _gtk_window_unset_focus_and_default:
5559 * @window: a #GtkWindow
5560 * @widget: a widget inside of @window
5562 * Checks whether the focus and default widgets of @window are
5563 * @widget or a descendent of @widget, and if so, unset them.
5566 _gtk_window_unset_focus_and_default (GtkWindow *window,
5572 g_object_ref (window);
5573 g_object_ref (widget);
5575 if (GTK_CONTAINER (widget->parent)->focus_child == widget)
5577 child = window->focus_widget;
5579 while (child && child != widget)
5580 child = child->parent;
5582 if (child == widget)
5583 gtk_window_set_focus (GTK_WINDOW (window), NULL);
5586 child = window->default_widget;
5588 while (child && child != widget)
5589 child = child->parent;
5591 if (child == widget)
5592 gtk_window_set_default (window, NULL);
5594 g_object_unref (widget);
5595 g_object_unref (window);
5598 /*********************************
5599 * Functions related to resizing *
5600 *********************************/
5602 /* This function doesn't constrain to geometry hints */
5604 gtk_window_compute_configure_request_size (GtkWindow *window,
5608 GtkRequisition requisition;
5609 GtkWindowGeometryInfo *info;
5613 * - we've done a size request
5616 widget = GTK_WIDGET (window);
5618 info = gtk_window_get_geometry_info (window, FALSE);
5620 if (window->need_default_size)
5622 gtk_widget_get_child_requisition (widget, &requisition);
5624 /* Default to requisition */
5625 *width = requisition.width;
5626 *height = requisition.height;
5628 /* If window is empty so requests 0, default to random nonzero size */
5629 if (*width == 0 && *height == 0)
5635 /* Override requisition with default size */
5639 gint base_width = 0;
5640 gint base_height = 0;
5642 gint min_height = 0;
5644 gint height_inc = 1;
5646 if (info->default_is_geometry &&
5647 (info->default_width > 0 || info->default_height > 0))
5649 GdkGeometry geometry;
5652 gtk_window_compute_hints (window, &geometry, &flags);
5654 if (flags & GDK_HINT_BASE_SIZE)
5656 base_width = geometry.base_width;
5657 base_height = geometry.base_height;
5659 if (flags & GDK_HINT_MIN_SIZE)
5661 min_width = geometry.min_width;
5662 min_height = geometry.min_height;
5664 if (flags & GDK_HINT_RESIZE_INC)
5666 width_inc = geometry.width_inc;
5667 height_inc = geometry.height_inc;
5671 if (info->default_width > 0)
5672 *width = MAX (info->default_width * width_inc + base_width, min_width);
5674 if (info->default_height > 0)
5675 *height = MAX (info->default_height * height_inc + base_height, min_height);
5680 /* Default to keeping current size */
5681 *width = widget->allocation.width;
5682 *height = widget->allocation.height;
5685 /* Override any size with gtk_window_resize() values */
5688 if (info->resize_width > 0)
5689 *width = info->resize_width;
5691 if (info->resize_height > 0)
5692 *height = info->resize_height;
5695 /* Don't ever request zero width or height, its not supported by
5696 gdk. The size allocation code will round it to 1 anyway but if
5697 we do it then the value returned from this function will is
5698 not comparable to the size allocation read from the GtkWindow. */
5699 *width = MAX (*width, 1);
5700 *height = MAX (*height, 1);
5703 static GtkWindowPosition
5704 get_effective_position (GtkWindow *window)
5706 GtkWindowPosition pos = window->position;
5707 if (pos == GTK_WIN_POS_CENTER_ON_PARENT &&
5708 (window->transient_parent == NULL ||
5709 !GTK_WIDGET_MAPPED (window->transient_parent)))
5710 pos = GTK_WIN_POS_NONE;
5716 get_center_monitor_of_window (GtkWindow *window)
5718 /* We could try to sort out the relative positions of the monitors and
5719 * stuff, or we could just be losers and assume you have a row
5720 * or column of monitors.
5722 return gdk_screen_get_n_monitors (gtk_window_check_screen (window)) / 2;
5726 get_monitor_containing_pointer (GtkWindow *window)
5730 GdkScreen *window_screen;
5731 GdkScreen *pointer_screen;
5733 window_screen = gtk_window_check_screen (window);
5734 gdk_display_get_pointer (gdk_screen_get_display (window_screen),
5738 if (pointer_screen == window_screen)
5739 monitor_num = gdk_screen_get_monitor_at_point (pointer_screen, px, py);
5747 center_window_on_monitor (GtkWindow *window,
5753 GdkRectangle monitor;
5756 monitor_num = get_monitor_containing_pointer (window);
5758 if (monitor_num == -1)
5759 monitor_num = get_center_monitor_of_window (window);
5761 gdk_screen_get_monitor_geometry (gtk_window_check_screen (window),
5762 monitor_num, &monitor);
5764 *x = (monitor.width - w) / 2 + monitor.x;
5765 *y = (monitor.height - h) / 2 + monitor.y;
5767 /* Be sure we aren't off the monitor, ignoring _NET_WM_STRUT
5768 * and WM decorations.
5782 if (extent > clamp_extent)
5784 *base = clamp_base + clamp_extent/2 - extent/2;
5785 else if (*base < clamp_base)
5787 else if (*base + extent > clamp_base + clamp_extent)
5788 *base = clamp_base + clamp_extent - extent;
5792 clamp_window_to_rectangle (gint *x,
5796 const GdkRectangle *rect)
5798 #ifdef DEBUGGING_OUTPUT
5799 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);
5802 /* If it is too large, center it. If it fits on the monitor but is
5803 * partially outside, move it to the closest edge. Do this
5804 * separately in x and y directions.
5806 clamp (x, w, rect->x, rect->width);
5807 clamp (y, h, rect->y, rect->height);
5808 #ifdef DEBUGGING_OUTPUT
5809 g_print (" ==> %+d%+d: %dx%d\n", *x, *y, w, h);
5815 gtk_window_compute_configure_request (GtkWindow *window,
5816 GdkRectangle *request,
5817 GdkGeometry *geometry,
5820 GdkGeometry new_geometry;
5824 GtkWindowPosition pos;
5825 GtkWidget *parent_widget;
5826 GtkWindowGeometryInfo *info;
5830 widget = GTK_WIDGET (window);
5832 screen = gtk_window_check_screen (window);
5834 gtk_widget_size_request (widget, NULL);
5835 gtk_window_compute_configure_request_size (window, (guint *)&w, (guint *)&h);
5837 gtk_window_compute_hints (window, &new_geometry, &new_flags);
5838 gtk_window_constrain_size (window,
5839 &new_geometry, new_flags,
5843 parent_widget = (GtkWidget*) window->transient_parent;
5845 pos = get_effective_position (window);
5846 info = gtk_window_get_geometry_info (window, FALSE);
5848 /* by default, don't change position requested */
5851 x = info->last.configure_request.x;
5852 y = info->last.configure_request.y;
5861 if (window->need_default_position)
5864 /* FIXME this all interrelates with window gravity.
5865 * For most of them I think we want to set GRAVITY_CENTER.
5867 * Not sure how to go about that.
5872 /* here we are only handling CENTER_ALWAYS
5873 * as it relates to default positioning,
5874 * where it's equivalent to simply CENTER
5876 case GTK_WIN_POS_CENTER_ALWAYS:
5877 case GTK_WIN_POS_CENTER:
5878 center_window_on_monitor (window, w, h, &x, &y);
5881 case GTK_WIN_POS_CENTER_ON_PARENT:
5884 GdkRectangle monitor;
5887 g_assert (GTK_WIDGET_MAPPED (parent_widget)); /* established earlier */
5889 if (parent_widget->window != NULL)
5890 monitor_num = gdk_screen_get_monitor_at_window (screen,
5891 parent_widget->window);
5895 gdk_window_get_origin (parent_widget->window,
5898 x = ox + (parent_widget->allocation.width - w) / 2;
5899 y = oy + (parent_widget->allocation.height - h) / 2;
5901 /* Clamp onto current monitor, ignoring _NET_WM_STRUT and
5902 * WM decorations. If parent wasn't on a monitor, just
5905 if (monitor_num >= 0)
5907 gdk_screen_get_monitor_geometry (screen, monitor_num, &monitor);
5908 clamp_window_to_rectangle (&x, &y, w, h, &monitor);
5913 case GTK_WIN_POS_MOUSE:
5915 gint screen_width = gdk_screen_get_width (screen);
5916 gint screen_height = gdk_screen_get_height (screen);
5918 GdkRectangle monitor;
5919 GdkScreen *pointer_screen;
5922 gdk_display_get_pointer (gdk_screen_get_display (screen),
5926 if (pointer_screen == screen)
5927 monitor_num = gdk_screen_get_monitor_at_point (screen, px, py);
5933 x = CLAMP (x, 0, screen_width - w);
5934 y = CLAMP (y, 0, screen_height - h);
5936 /* Clamp onto current monitor, ignoring _NET_WM_STRUT and
5937 * WM decorations. Don't try to figure out what's going
5938 * on if the mouse wasn't inside a monitor.
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);
5951 } /* if (window->need_default_position) */
5953 if (window->need_default_position && info &&
5954 info->initial_pos_set)
5956 x = info->initial_x;
5957 y = info->initial_y;
5958 gtk_window_constrain_position (window, w, h, &x, &y);
5964 request->height = h;
5967 *geometry = new_geometry;
5973 gtk_window_constrain_position (GtkWindow *window,
5979 /* See long comments in gtk_window_move_resize()
5980 * on when it's safe to call this function.
5982 if (window->position == GTK_WIN_POS_CENTER_ALWAYS)
5984 gint center_x, center_y;
5986 center_window_on_monitor (window, new_width, new_height, ¢er_x, ¢er_y);
5994 gtk_window_move_resize (GtkWindow *window)
5998 * First we determine whether any information has changed that would
5999 * cause us to revise our last configure request. If we would send
6000 * a different configure request from last time, then
6001 * configure_request_size_changed = TRUE or
6002 * configure_request_pos_changed = TRUE. configure_request_size_changed
6003 * may be true due to new hints, a gtk_window_resize(), or whatever.
6004 * configure_request_pos_changed may be true due to gtk_window_set_position()
6005 * or gtk_window_move().
6007 * If the configure request has changed, we send off a new one. To
6008 * ensure GTK+ invariants are maintained (resize queue does what it
6009 * should), we go ahead and size_allocate the requested size in this
6012 * If the configure request has not changed, we don't ever resend
6013 * it, because it could mean fighting the user or window manager.
6016 * To prepare the configure request, we come up with a base size/pos:
6017 * - the one from gtk_window_move()/gtk_window_resize()
6018 * - else default_width, default_height if we haven't ever
6020 * - else the size request if we haven't ever been mapped,
6021 * as a substitute default size
6022 * - else the current size of the window, as received from
6023 * configure notifies (i.e. the current allocation)
6025 * If GTK_WIN_POS_CENTER_ALWAYS is active, we constrain
6026 * the position request to be centered.
6029 GtkContainer *container;
6030 GtkWindowGeometryInfo *info;
6031 GdkGeometry new_geometry;
6033 GdkRectangle new_request;
6034 gboolean configure_request_size_changed;
6035 gboolean configure_request_pos_changed;
6036 gboolean hints_changed; /* do we need to send these again */
6037 GtkWindowLastGeometryInfo saved_last_info;
6039 widget = GTK_WIDGET (window);
6040 container = GTK_CONTAINER (widget);
6041 info = gtk_window_get_geometry_info (window, TRUE);
6043 configure_request_size_changed = FALSE;
6044 configure_request_pos_changed = FALSE;
6046 gtk_window_compute_configure_request (window, &new_request,
6047 &new_geometry, &new_flags);
6049 /* This check implies the invariant that we never set info->last
6050 * without setting the hints and sending off a configure request.
6052 * If we change info->last without sending the request, we may
6055 if (info->last.configure_request.x != new_request.x ||
6056 info->last.configure_request.y != new_request.y)
6057 configure_request_pos_changed = TRUE;
6059 if ((info->last.configure_request.width != new_request.width ||
6060 info->last.configure_request.height != new_request.height))
6061 configure_request_size_changed = TRUE;
6063 hints_changed = FALSE;
6065 if (!gtk_window_compare_hints (&info->last.geometry, info->last.flags,
6066 &new_geometry, new_flags))
6068 hints_changed = TRUE;
6071 /* Position Constraints
6072 * ====================
6074 * POS_CENTER_ALWAYS is conceptually a constraint rather than
6075 * a default. The other POS_ values are used only when the
6076 * window is shown, not after that.
6078 * However, we can't implement a position constraint as
6079 * "anytime the window size changes, center the window"
6080 * because this may well end up fighting the WM or user. In
6081 * fact it gets in an infinite loop with at least one WM.
6083 * Basically, applications are in no way in a position to
6084 * constrain the position of a window, with one exception:
6085 * override redirect windows. (Really the intended purpose
6086 * of CENTER_ALWAYS anyhow, I would think.)
6088 * So the way we implement this "constraint" is to say that when WE
6089 * cause a move or resize, i.e. we make a configure request changing
6090 * window size, we recompute the CENTER_ALWAYS position to reflect
6091 * the new window size, and include it in our request. Also, if we
6092 * just turned on CENTER_ALWAYS we snap to center with a new
6093 * request. Otherwise, if we are just NOTIFIED of a move or resize
6094 * done by someone else e.g. the window manager, we do NOT send a
6095 * new configure request.
6097 * For override redirect windows, this works fine; all window
6098 * sizes are from our configure requests. For managed windows,
6099 * it is at least semi-sane, though who knows what the
6100 * app author is thinking.
6103 /* This condition should be kept in sync with the condition later on
6104 * that determines whether we send a configure request. i.e. we
6105 * should do this position constraining anytime we were going to
6106 * send a configure request anyhow, plus when constraints have
6109 if (configure_request_pos_changed ||
6110 configure_request_size_changed ||
6112 info->position_constraints_changed)
6114 /* We request the constrained position if:
6115 * - we were changing position, and need to clamp
6116 * the change to the constraint
6117 * - we're changing the size anyway
6118 * - set_position() was called to toggle CENTER_ALWAYS on
6121 gtk_window_constrain_position (window,
6127 /* Update whether we need to request a move */
6128 if (info->last.configure_request.x != new_request.x ||
6129 info->last.configure_request.y != new_request.y)
6130 configure_request_pos_changed = TRUE;
6132 configure_request_pos_changed = FALSE;
6136 if (window->type == GTK_WINDOW_TOPLEVEL)
6138 int notify_x, notify_y;
6140 /* this is the position from the last configure notify */
6141 gdk_window_get_position (widget->window, ¬ify_x, ¬ify_y);
6143 g_message ("--- %s ---\n"
6144 "last : %d,%d\t%d x %d\n"
6145 "this : %d,%d\t%d x %d\n"
6146 "alloc : %d,%d\t%d x %d\n"
6148 "resize: \t%d x %d\n"
6149 "size_changed: %d pos_changed: %d hints_changed: %d\n"
6150 "configure_notify_received: %d\n"
6151 "configure_request_count: %d\n"
6152 "position_constraints_changed: %d\n",
6153 window->title ? window->title : "(no title)",
6154 info->last.configure_request.x,
6155 info->last.configure_request.y,
6156 info->last.configure_request.width,
6157 info->last.configure_request.height,
6163 widget->allocation.width,
6164 widget->allocation.height,
6165 widget->requisition.width,
6166 widget->requisition.height,
6168 info->resize_height,
6169 configure_request_pos_changed,
6170 configure_request_size_changed,
6172 window->configure_notify_received,
6173 window->configure_request_count,
6174 info->position_constraints_changed);
6178 saved_last_info = info->last;
6179 info->last.geometry = new_geometry;
6180 info->last.flags = new_flags;
6181 info->last.configure_request = new_request;
6183 /* need to set PPosition so the WM will look at our position,
6184 * but we don't want to count PPosition coming and going as a hints
6185 * change for future iterations. So we saved info->last prior to
6189 /* Also, if the initial position was explicitly set, then we always
6190 * toggle on PPosition. This makes gtk_window_move(window, 0, 0)
6194 /* Also, we toggle on PPosition if GTK_WIN_POS_ is in use and
6195 * this is an initial map
6198 if ((configure_request_pos_changed ||
6199 info->initial_pos_set ||
6200 (window->need_default_position &&
6201 get_effective_position (window) != GTK_WIN_POS_NONE)) &&
6202 (new_flags & GDK_HINT_POS) == 0)
6204 new_flags |= GDK_HINT_POS;
6205 hints_changed = TRUE;
6208 /* Set hints if necessary
6211 gdk_window_set_geometry_hints (widget->window,
6215 /* handle resizing/moving and widget tree allocation
6217 if (window->configure_notify_received)
6219 GtkAllocation allocation;
6221 /* If we have received a configure event since
6222 * the last time in this function, we need to
6223 * accept our new size and size_allocate child widgets.
6224 * (see gtk_window_configure_event() for more details).
6226 * 1 or more configure notifies may have been received.
6227 * Also, configure_notify_received will only be TRUE
6228 * if all expected configure notifies have been received
6229 * (one per configure request), as an optimization.
6232 window->configure_notify_received = FALSE;
6234 /* gtk_window_configure_event() filled in widget->allocation */
6235 allocation = widget->allocation;
6236 gtk_widget_size_allocate (widget, &allocation);
6238 gdk_window_process_updates (widget->window, TRUE);
6240 gdk_window_configure_finished (widget->window);
6242 /* If the configure request changed, it means that
6244 * 1) coincidentally changed hints or widget properties
6245 * impacting the configure request before getting
6246 * a configure notify, or
6247 * 2) some broken widget is changing its size request
6248 * during size allocation, resulting in
6249 * a false appearance of changed configure request.
6251 * For 1), we could just go ahead and ask for the
6252 * new size right now, but doing that for 2)
6253 * might well be fighting the user (and can even
6254 * trigger a loop). Since we really don't want to
6255 * do that, we requeue a resize in hopes that
6256 * by the time it gets handled, the child has seen
6257 * the light and is willing to go along with the
6258 * new size. (this happens for the zvt widget, since
6259 * the size_allocate() above will have stored the
6260 * requisition corresponding to the new size in the
6263 * This doesn't buy us anything for 1), but it shouldn't
6264 * hurt us too badly, since it is what would have
6265 * happened if we had gotten the configure event before
6266 * the new size had been set.
6269 if (configure_request_size_changed ||
6270 configure_request_pos_changed)
6272 /* Don't change the recorded last info after all, because we
6273 * haven't actually updated to the new info yet - we decided
6274 * to postpone our configure request until later.
6276 info->last = saved_last_info;
6278 gtk_widget_queue_resize_no_redraw (widget); /* migth recurse for GTK_RESIZE_IMMEDIATE */
6281 return; /* Bail out, we didn't really process the move/resize */
6283 else if ((configure_request_size_changed || hints_changed) &&
6284 (widget->allocation.width != new_request.width ||
6285 widget->allocation.height != new_request.height))
6288 /* We are in one of the following situations:
6289 * A. configure_request_size_changed
6290 * our requisition has changed and we need a different window size,
6291 * so we request it from the window manager.
6292 * B. !configure_request_size_changed && hints_changed
6293 * the window manager rejects our size, but we have just changed the
6294 * window manager hints, so there's a chance our request will
6295 * be honoured this time, so we try again.
6297 * However, if the new requisition is the same as the current allocation,
6298 * we don't request it again, since we won't get a ConfigureNotify back from
6299 * the window manager unless it decides to change our requisition. If
6300 * we don't get the ConfigureNotify back, the resize queue will never be run.
6303 /* Now send the configure request */
6304 if (configure_request_pos_changed)
6308 gdk_window_move_resize (window->frame,
6309 new_request.x - window->frame_left,
6310 new_request.y - window->frame_top,
6311 new_request.width + window->frame_left + window->frame_right,
6312 new_request.height + window->frame_top + window->frame_bottom);
6313 gdk_window_resize (widget->window,
6314 new_request.width, new_request.height);
6317 gdk_window_move_resize (widget->window,
6318 new_request.x, new_request.y,
6319 new_request.width, new_request.height);
6321 else /* only size changed */
6324 gdk_window_resize (window->frame,
6325 new_request.width + window->frame_left + window->frame_right,
6326 new_request.height + window->frame_top + window->frame_bottom);
6327 gdk_window_resize (widget->window,
6328 new_request.width, new_request.height);
6331 if (window->type == GTK_WINDOW_POPUP)
6333 GtkAllocation allocation;
6335 /* Directly size allocate for override redirect (popup) windows. */
6338 allocation.width = new_request.width;
6339 allocation.height = new_request.height;
6341 gtk_widget_size_allocate (widget, &allocation);
6343 gdk_window_process_updates (widget->window, TRUE);
6345 if (container->resize_mode == GTK_RESIZE_QUEUE)
6346 gtk_widget_queue_draw (widget);
6350 /* Increment the number of have-not-yet-received-notify requests */
6351 window->configure_request_count += 1;
6352 gdk_window_freeze_toplevel_updates_libgtk_only (widget->window);
6354 /* for GTK_RESIZE_QUEUE toplevels, we are now awaiting a new
6355 * configure event in response to our resizing request.
6356 * the configure event will cause a new resize with
6357 * ->configure_notify_received=TRUE.
6358 * until then, we want to
6359 * - discard expose events
6360 * - coalesce resizes for our children
6361 * - defer any window resizes until the configure event arrived
6362 * to achieve this, we queue a resize for the window, but remove its
6363 * resizing handler, so resizing will not be handled from the next
6364 * idle handler but when the configure event arrives.
6366 * FIXME: we should also dequeue the pending redraws here, since
6367 * we handle those ourselves upon ->configure_notify_received==TRUE.
6369 if (container->resize_mode == GTK_RESIZE_QUEUE)
6371 gtk_widget_queue_resize_no_redraw (widget);
6372 _gtk_container_dequeue_resize_handler (container);
6378 /* Handle any position changes.
6380 if (configure_request_pos_changed)
6384 gdk_window_move (window->frame,
6385 new_request.x - window->frame_left,
6386 new_request.y - window->frame_top);
6389 gdk_window_move (widget->window,
6390 new_request.x, new_request.y);
6393 /* And run the resize queue.
6395 gtk_container_resize_children (container);
6398 /* We have now processed a move/resize since the last position
6399 * constraint change, setting of the initial position, or resize.
6400 * (Not resetting these flags here can lead to infinite loops for
6401 * GTK_RESIZE_IMMEDIATE containers)
6403 info->position_constraints_changed = FALSE;
6404 info->initial_pos_set = FALSE;
6405 info->resize_width = -1;
6406 info->resize_height = -1;
6409 /* Compare two sets of Geometry hints for equality.
6412 gtk_window_compare_hints (GdkGeometry *geometry_a,
6414 GdkGeometry *geometry_b,
6417 if (flags_a != flags_b)
6420 if ((flags_a & GDK_HINT_MIN_SIZE) &&
6421 (geometry_a->min_width != geometry_b->min_width ||
6422 geometry_a->min_height != geometry_b->min_height))
6425 if ((flags_a & GDK_HINT_MAX_SIZE) &&
6426 (geometry_a->max_width != geometry_b->max_width ||
6427 geometry_a->max_height != geometry_b->max_height))
6430 if ((flags_a & GDK_HINT_BASE_SIZE) &&
6431 (geometry_a->base_width != geometry_b->base_width ||
6432 geometry_a->base_height != geometry_b->base_height))
6435 if ((flags_a & GDK_HINT_ASPECT) &&
6436 (geometry_a->min_aspect != geometry_b->min_aspect ||
6437 geometry_a->max_aspect != geometry_b->max_aspect))
6440 if ((flags_a & GDK_HINT_RESIZE_INC) &&
6441 (geometry_a->width_inc != geometry_b->width_inc ||
6442 geometry_a->height_inc != geometry_b->height_inc))
6445 if ((flags_a & GDK_HINT_WIN_GRAVITY) &&
6446 geometry_a->win_gravity != geometry_b->win_gravity)
6453 _gtk_window_constrain_size (GtkWindow *window,
6459 GtkWindowGeometryInfo *info;
6461 g_return_if_fail (GTK_IS_WINDOW (window));
6463 info = window->geometry_info;
6466 GdkWindowHints flags = info->last.flags;
6467 GdkGeometry *geometry = &info->last.geometry;
6469 gtk_window_constrain_size (window,
6480 gtk_window_constrain_size (GtkWindow *window,
6481 GdkGeometry *geometry,
6488 gdk_window_constrain_size (geometry, flags, width, height,
6489 new_width, new_height);
6492 /* Compute the set of geometry hints and flags for a window
6493 * based on the application set geometry, and requisiition
6494 * of the window. gtk_widget_size_request() must have been
6498 gtk_window_compute_hints (GtkWindow *window,
6499 GdkGeometry *new_geometry,
6503 gint extra_width = 0;
6504 gint extra_height = 0;
6505 GtkWindowGeometryInfo *geometry_info;
6506 GtkRequisition requisition;
6508 widget = GTK_WIDGET (window);
6510 gtk_widget_get_child_requisition (widget, &requisition);
6511 geometry_info = gtk_window_get_geometry_info (GTK_WINDOW (widget), FALSE);
6515 *new_flags = geometry_info->mask;
6516 *new_geometry = geometry_info->geometry;
6523 if (geometry_info && geometry_info->widget)
6525 GtkRequisition child_requisition;
6527 /* FIXME: This really isn't right. It gets the min size wrong and forces
6528 * callers to do horrible hacks like set a huge usize on the child requisition
6529 * to get the base size right. We really want to find the answers to:
6531 * - If the geometry widget was infinitely big, how much extra space
6532 * would be needed for the stuff around it.
6534 * - If the geometry widget was infinitely small, how big would the
6535 * window still have to be.
6537 * Finding these answers would be a bit of a mess here. (Bug #68668)
6539 gtk_widget_get_child_requisition (geometry_info->widget, &child_requisition);
6541 extra_width = widget->requisition.width - child_requisition.width;
6542 extra_height = widget->requisition.height - child_requisition.height;
6545 /* We don't want to set GDK_HINT_POS in here, we just set it
6546 * in gtk_window_move_resize() when we want the position
6550 if (*new_flags & GDK_HINT_BASE_SIZE)
6552 new_geometry->base_width += extra_width;
6553 new_geometry->base_height += extra_height;
6555 else if (!(*new_flags & GDK_HINT_MIN_SIZE) &&
6556 (*new_flags & GDK_HINT_RESIZE_INC) &&
6557 ((extra_width != 0) || (extra_height != 0)))
6559 *new_flags |= GDK_HINT_BASE_SIZE;
6561 new_geometry->base_width = extra_width;
6562 new_geometry->base_height = extra_height;
6565 if (*new_flags & GDK_HINT_MIN_SIZE)
6567 if (new_geometry->min_width < 0)
6568 new_geometry->min_width = requisition.width;
6570 new_geometry->min_width += extra_width;
6572 if (new_geometry->min_height < 0)
6573 new_geometry->min_height = requisition.height;
6575 new_geometry->min_height += extra_height;
6577 else if (!window->allow_shrink)
6579 *new_flags |= GDK_HINT_MIN_SIZE;
6581 new_geometry->min_width = requisition.width;
6582 new_geometry->min_height = requisition.height;
6585 if (*new_flags & GDK_HINT_MAX_SIZE)
6587 if (new_geometry->max_width < 0)
6588 new_geometry->max_width = requisition.width;
6590 new_geometry->max_width += extra_width;
6592 if (new_geometry->max_height < 0)
6593 new_geometry->max_height = requisition.height;
6595 new_geometry->max_height += extra_height;
6597 else if (!window->allow_grow)
6599 *new_flags |= GDK_HINT_MAX_SIZE;
6601 new_geometry->max_width = requisition.width;
6602 new_geometry->max_height = requisition.height;
6605 *new_flags |= GDK_HINT_WIN_GRAVITY;
6606 new_geometry->win_gravity = window->gravity;
6609 /***********************
6610 * Redrawing functions *
6611 ***********************/
6614 gtk_window_paint (GtkWidget *widget,
6617 gtk_paint_flat_box (widget->style, widget->window, GTK_STATE_NORMAL,
6618 GTK_SHADOW_NONE, area, widget, "base", 0, 0, -1, -1);
6622 gtk_window_expose (GtkWidget *widget,
6623 GdkEventExpose *event)
6625 if (!GTK_WIDGET_APP_PAINTABLE (widget))
6626 gtk_window_paint (widget, &event->area);
6628 if (GTK_WIDGET_CLASS (gtk_window_parent_class)->expose_event)
6629 return GTK_WIDGET_CLASS (gtk_window_parent_class)->expose_event (widget, event);
6635 * gtk_window_set_has_frame:
6636 * @window: a #GtkWindow
6637 * @setting: a boolean
6639 * (Note: this is a special-purpose function for the framebuffer port,
6640 * that causes GTK+ to draw its own window border. For most applications,
6641 * you want gtk_window_set_decorated() instead, which tells the window
6642 * manager whether to draw the window border.)
6644 * If this function is called on a window with setting of %TRUE, before
6645 * it is realized or showed, it will have a "frame" window around
6646 * @window->window, accessible in @window->frame. Using the signal
6647 * frame_event you can receive all events targeted at the frame.
6649 * This function is used by the linux-fb port to implement managed
6650 * windows, but it could conceivably be used by X-programs that
6651 * want to do their own window decorations.
6655 gtk_window_set_has_frame (GtkWindow *window,
6658 g_return_if_fail (GTK_IS_WINDOW (window));
6659 g_return_if_fail (!GTK_WIDGET_REALIZED (window));
6661 window->has_frame = setting != FALSE;
6665 * gtk_window_get_has_frame:
6666 * @window: a #GtkWindow
6668 * Accessor for whether the window has a frame window exterior to
6669 * @window->window. Gets the value set by gtk_window_set_has_frame ().
6671 * Return value: %TRUE if a frame has been added to the window
6672 * via gtk_window_set_has_frame().
6675 gtk_window_get_has_frame (GtkWindow *window)
6677 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
6679 return window->has_frame;
6683 * gtk_window_set_frame_dimensions:
6684 * @window: a #GtkWindow that has a frame
6685 * @left: The width of the left border
6686 * @top: The height of the top border
6687 * @right: The width of the right border
6688 * @bottom: The height of the bottom border
6690 * (Note: this is a special-purpose function intended for the framebuffer
6691 * port; see gtk_window_set_has_frame(). It will have no effect on the
6692 * window border drawn by the window manager, which is the normal
6693 * case when using the X Window system.)
6695 * For windows with frames (see gtk_window_set_has_frame()) this function
6696 * can be used to change the size of the frame border.
6699 gtk_window_set_frame_dimensions (GtkWindow *window,
6707 g_return_if_fail (GTK_IS_WINDOW (window));
6709 widget = GTK_WIDGET (window);
6711 if (window->frame_left == left &&
6712 window->frame_top == top &&
6713 window->frame_right == right &&
6714 window->frame_bottom == bottom)
6717 window->frame_left = left;
6718 window->frame_top = top;
6719 window->frame_right = right;
6720 window->frame_bottom = bottom;
6722 if (GTK_WIDGET_REALIZED (widget) && window->frame)
6724 gint width = widget->allocation.width + left + right;
6725 gint height = widget->allocation.height + top + bottom;
6726 gdk_window_resize (window->frame, width, height);
6727 gtk_decorated_window_move_resize_window (window,
6729 widget->allocation.width,
6730 widget->allocation.height);
6735 * gtk_window_present:
6736 * @window: a #GtkWindow
6738 * Presents a window to the user. This may mean raising the window
6739 * in the stacking order, deiconifying it, moving it to the current
6740 * desktop, and/or giving it the keyboard focus, possibly dependent
6741 * on the user's platform, window manager, and preferences.
6743 * If @window is hidden, this function calls gtk_widget_show()
6746 * This function should be used when the user tries to open a window
6747 * that's already open. Say for example the preferences dialog is
6748 * currently open, and the user chooses Preferences from the menu
6749 * a second time; use gtk_window_present() to move the already-open dialog
6750 * where the user can see it.
6752 * If you are calling this function in response to a user interaction,
6753 * it is preferable to use gtk_window_present_with_time().
6757 gtk_window_present (GtkWindow *window)
6759 gtk_window_present_with_time (window, GDK_CURRENT_TIME);
6763 * gtk_window_present_with_time:
6764 * @window: a #GtkWindow
6765 * @timestamp: the timestamp of the user interaction (typically a
6766 * button or key press event) which triggered this call
6768 * Presents a window to the user in response to a user interaction.
6769 * If you need to present a window without a timestamp, use
6770 * gtk_window_present(). See gtk_window_present() for details.
6775 gtk_window_present_with_time (GtkWindow *window,
6780 g_return_if_fail (GTK_IS_WINDOW (window));
6782 widget = GTK_WIDGET (window);
6784 if (GTK_WIDGET_VISIBLE (window))
6786 g_assert (widget->window != NULL);
6788 gdk_window_show (widget->window);
6790 /* Translate a timestamp of GDK_CURRENT_TIME appropriately */
6791 if (timestamp == GDK_CURRENT_TIME)
6793 #ifdef GDK_WINDOWING_X11
6794 GdkDisplay *display;
6796 display = gtk_widget_get_display (GTK_WIDGET (window));
6797 timestamp = gdk_x11_display_get_user_time (display);
6799 timestamp = gtk_get_current_event_time ();
6803 gdk_window_focus (widget->window, timestamp);
6807 gtk_widget_show (widget);
6812 * gtk_window_iconify:
6813 * @window: a #GtkWindow
6815 * Asks to iconify (i.e. minimize) the specified @window. Note that
6816 * you shouldn't assume the window is definitely iconified afterward,
6817 * because other entities (e.g. the user or <link
6818 * linkend="gtk-X11-arch">window manager</link>) could deiconify it
6819 * again, or there may not be a window manager in which case
6820 * iconification isn't possible, etc. But normally the window will end
6821 * up iconified. Just don't write code that crashes if not.
6823 * It's permitted to call this function before showing a window,
6824 * in which case the window will be iconified before it ever appears
6827 * You can track iconification via the "window-state-event" signal
6832 gtk_window_iconify (GtkWindow *window)
6835 GdkWindow *toplevel;
6837 g_return_if_fail (GTK_IS_WINDOW (window));
6839 widget = GTK_WIDGET (window);
6841 window->iconify_initially = TRUE;
6844 toplevel = window->frame;
6846 toplevel = widget->window;
6848 if (toplevel != NULL)
6849 gdk_window_iconify (toplevel);
6853 * gtk_window_deiconify:
6854 * @window: a #GtkWindow
6856 * Asks to deiconify (i.e. unminimize) the specified @window. Note
6857 * that you shouldn't assume the window is definitely deiconified
6858 * afterward, because other entities (e.g. the user or <link
6859 * linkend="gtk-X11-arch">window manager</link>) could iconify it
6860 * again before your code which assumes deiconification gets to run.
6862 * You can track iconification via the "window-state-event" signal
6866 gtk_window_deiconify (GtkWindow *window)
6869 GdkWindow *toplevel;
6871 g_return_if_fail (GTK_IS_WINDOW (window));
6873 widget = GTK_WIDGET (window);
6875 window->iconify_initially = FALSE;
6878 toplevel = window->frame;
6880 toplevel = widget->window;
6882 if (toplevel != NULL)
6883 gdk_window_deiconify (toplevel);
6888 * @window: a #GtkWindow
6890 * Asks to stick @window, which means that it will appear on all user
6891 * desktops. Note that you shouldn't assume the window is definitely
6892 * stuck afterward, because other entities (e.g. the user or <link
6893 * linkend="gtk-X11-arch">window manager</link>) could unstick it
6894 * again, and some window managers do not support sticking
6895 * windows. But normally the window will end up stuck. Just don't
6896 * write code that crashes if not.
6898 * It's permitted to call this function before showing a window.
6900 * You can track stickiness via the "window-state-event" signal
6905 gtk_window_stick (GtkWindow *window)
6908 GdkWindow *toplevel;
6910 g_return_if_fail (GTK_IS_WINDOW (window));
6912 widget = GTK_WIDGET (window);
6914 window->stick_initially = TRUE;
6917 toplevel = window->frame;
6919 toplevel = widget->window;
6921 if (toplevel != NULL)
6922 gdk_window_stick (toplevel);
6926 * gtk_window_unstick:
6927 * @window: a #GtkWindow
6929 * Asks to unstick @window, which means that it will appear on only
6930 * one of the user's desktops. Note that you shouldn't assume the
6931 * window is definitely unstuck afterward, because other entities
6932 * (e.g. the user or <link linkend="gtk-X11-arch">window
6933 * manager</link>) could stick it again. But normally the window will
6934 * end up stuck. Just don't write code that crashes if not.
6936 * You can track stickiness via the "window-state-event" signal
6941 gtk_window_unstick (GtkWindow *window)
6944 GdkWindow *toplevel;
6946 g_return_if_fail (GTK_IS_WINDOW (window));
6948 widget = GTK_WIDGET (window);
6950 window->stick_initially = FALSE;
6953 toplevel = window->frame;
6955 toplevel = widget->window;
6957 if (toplevel != NULL)
6958 gdk_window_unstick (toplevel);
6962 * gtk_window_maximize:
6963 * @window: a #GtkWindow
6965 * Asks to maximize @window, so that it becomes full-screen. Note that
6966 * you shouldn't assume the window is definitely maximized afterward,
6967 * because other entities (e.g. the user or <link
6968 * linkend="gtk-X11-arch">window manager</link>) could unmaximize it
6969 * again, and not all window managers support maximization. But
6970 * normally the window will end up maximized. Just don't write code
6971 * that crashes if not.
6973 * It's permitted to call this function before showing a window,
6974 * in which case the window will be maximized when it appears onscreen
6977 * You can track maximization via the "window-state-event" signal
6982 gtk_window_maximize (GtkWindow *window)
6985 GdkWindow *toplevel;
6987 g_return_if_fail (GTK_IS_WINDOW (window));
6989 widget = GTK_WIDGET (window);
6991 window->maximize_initially = TRUE;
6994 toplevel = window->frame;
6996 toplevel = widget->window;
6998 if (toplevel != NULL)
6999 gdk_window_maximize (toplevel);
7003 * gtk_window_unmaximize:
7004 * @window: a #GtkWindow
7006 * Asks to unmaximize @window. Note that you shouldn't assume the
7007 * window is definitely unmaximized afterward, because other entities
7008 * (e.g. the user or <link linkend="gtk-X11-arch">window
7009 * manager</link>) could maximize it again, and not all window
7010 * managers honor requests to unmaximize. But normally the window will
7011 * end up unmaximized. Just don't write code that crashes if not.
7013 * You can track maximization via the "window-state-event" signal
7018 gtk_window_unmaximize (GtkWindow *window)
7021 GdkWindow *toplevel;
7023 g_return_if_fail (GTK_IS_WINDOW (window));
7025 widget = GTK_WIDGET (window);
7027 window->maximize_initially = FALSE;
7030 toplevel = window->frame;
7032 toplevel = widget->window;
7034 if (toplevel != NULL)
7035 gdk_window_unmaximize (toplevel);
7039 * gtk_window_fullscreen:
7040 * @window: a #GtkWindow
7042 * Asks to place @window in the fullscreen state. Note that you
7043 * shouldn't assume the window is definitely full screen afterward,
7044 * because other entities (e.g. the user or <link
7045 * linkend="gtk-X11-arch">window manager</link>) could unfullscreen it
7046 * again, and not all window managers honor requests to fullscreen
7047 * windows. But normally the window will end up fullscreen. Just
7048 * don't write code that crashes if not.
7050 * You can track the fullscreen state via the "window-state-event" signal
7056 gtk_window_fullscreen (GtkWindow *window)
7059 GdkWindow *toplevel;
7060 GtkWindowPrivate *priv;
7062 g_return_if_fail (GTK_IS_WINDOW (window));
7064 widget = GTK_WIDGET (window);
7065 priv = GTK_WINDOW_GET_PRIVATE (window);
7067 priv->fullscreen_initially = TRUE;
7070 toplevel = window->frame;
7072 toplevel = widget->window;
7074 if (toplevel != NULL)
7075 gdk_window_fullscreen (toplevel);
7079 * gtk_window_unfullscreen:
7080 * @window: a #GtkWindow
7082 * Asks to toggle off the fullscreen state for @window. Note that you
7083 * shouldn't assume the window is definitely not full screen
7084 * afterward, because other entities (e.g. the user or <link
7085 * linkend="gtk-X11-arch">window manager</link>) could fullscreen it
7086 * again, and not all window managers honor requests to unfullscreen
7087 * windows. But normally the window will end up restored to its normal
7088 * state. Just don't write code that crashes if not.
7090 * You can track the fullscreen state via the "window-state-event" signal
7096 gtk_window_unfullscreen (GtkWindow *window)
7099 GdkWindow *toplevel;
7100 GtkWindowPrivate *priv;
7102 g_return_if_fail (GTK_IS_WINDOW (window));
7104 widget = GTK_WIDGET (window);
7105 priv = GTK_WINDOW_GET_PRIVATE (window);
7107 priv->fullscreen_initially = FALSE;
7110 toplevel = window->frame;
7112 toplevel = widget->window;
7114 if (toplevel != NULL)
7115 gdk_window_unfullscreen (toplevel);
7119 * gtk_window_set_keep_above:
7120 * @window: a #GtkWindow
7121 * @setting: whether to keep @window above other windows
7123 * Asks to keep @window above, so that it stays on top. Note that
7124 * you shouldn't assume the window is definitely above afterward,
7125 * because other entities (e.g. the user or <link
7126 * linkend="gtk-X11-arch">window manager</link>) could not keep it above,
7127 * and not all window managers support keeping windows above. But
7128 * normally the window will end kept above. Just don't write code
7129 * that crashes if not.
7131 * It's permitted to call this function before showing a window,
7132 * in which case the window will be kept above when it appears onscreen
7135 * You can track the above state via the "window-state-event" signal
7138 * Note that, according to the <ulink
7139 * url="http://www.freedesktop.org/Standards/wm-spec">Extended Window
7140 * Manager Hints</ulink> specification, the above state is mainly meant
7141 * for user preferences and should not be used by applications e.g. for
7142 * drawing attention to their dialogs.
7147 gtk_window_set_keep_above (GtkWindow *window,
7151 GtkWindowPrivate *priv;
7152 GdkWindow *toplevel;
7154 g_return_if_fail (GTK_IS_WINDOW (window));
7156 widget = GTK_WIDGET (window);
7157 priv = GTK_WINDOW_GET_PRIVATE (window);
7159 priv->above_initially = setting != FALSE;
7161 priv->below_initially = FALSE;
7164 toplevel = window->frame;
7166 toplevel = widget->window;
7168 if (toplevel != NULL)
7169 gdk_window_set_keep_above (toplevel, setting);
7173 * gtk_window_set_keep_below:
7174 * @window: a #GtkWindow
7175 * @setting: whether to keep @window below other windows
7177 * Asks to keep @window below, so that it stays in bottom. Note that
7178 * you shouldn't assume the window is definitely below afterward,
7179 * because other entities (e.g. the user or <link
7180 * linkend="gtk-X11-arch">window manager</link>) could not keep it below,
7181 * and not all window managers support putting windows below. But
7182 * normally the window will be kept below. Just don't write code
7183 * that crashes if not.
7185 * It's permitted to call this function before showing a window,
7186 * in which case the window will be kept below when it appears onscreen
7189 * You can track the below state via the "window-state-event" signal
7192 * Note that, according to the <ulink
7193 * url="http://www.freedesktop.org/Standards/wm-spec">Extended Window
7194 * Manager Hints</ulink> specification, the above state is mainly meant
7195 * for user preferences and should not be used by applications e.g. for
7196 * drawing attention to their dialogs.
7201 gtk_window_set_keep_below (GtkWindow *window,
7205 GtkWindowPrivate *priv;
7206 GdkWindow *toplevel;
7208 g_return_if_fail (GTK_IS_WINDOW (window));
7210 widget = GTK_WIDGET (window);
7211 priv = GTK_WINDOW_GET_PRIVATE (window);
7213 priv->below_initially = setting != FALSE;
7215 priv->above_initially = FALSE;
7218 toplevel = window->frame;
7220 toplevel = widget->window;
7222 if (toplevel != NULL)
7223 gdk_window_set_keep_below (toplevel, setting);
7227 * gtk_window_set_resizable:
7228 * @window: a #GtkWindow
7229 * @resizable: %TRUE if the user can resize this window
7231 * Sets whether the user can resize a window. Windows are user resizable
7235 gtk_window_set_resizable (GtkWindow *window,
7238 g_return_if_fail (GTK_IS_WINDOW (window));
7240 gtk_window_set_policy_internal (window, FALSE, resizable, FALSE);
7244 * gtk_window_get_resizable:
7245 * @window: a #GtkWindow
7247 * Gets the value set by gtk_window_set_resizable().
7249 * Return value: %TRUE if the user can resize the window
7252 gtk_window_get_resizable (GtkWindow *window)
7254 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
7256 /* allow_grow is most likely to indicate the semantic concept we
7257 * mean by "resizable" (and will be a reliable indicator if
7258 * set_policy() hasn't been called)
7260 return window->allow_grow;
7264 * gtk_window_set_gravity:
7265 * @window: a #GtkWindow
7266 * @gravity: window gravity
7268 * Window gravity defines the meaning of coordinates passed to
7269 * gtk_window_move(). See gtk_window_move() and #GdkGravity for
7272 * The default window gravity is #GDK_GRAVITY_NORTH_WEST which will
7273 * typically "do what you mean."
7277 gtk_window_set_gravity (GtkWindow *window,
7280 g_return_if_fail (GTK_IS_WINDOW (window));
7282 if (gravity != window->gravity)
7284 window->gravity = gravity;
7286 /* gtk_window_move_resize() will adapt gravity
7288 gtk_widget_queue_resize_no_redraw (GTK_WIDGET (window));
7290 g_object_notify (G_OBJECT (window), "gravity");
7295 * gtk_window_get_gravity:
7296 * @window: a #GtkWindow
7298 * Gets the value set by gtk_window_set_gravity().
7300 * Return value: (transfer none): window gravity
7303 gtk_window_get_gravity (GtkWindow *window)
7305 g_return_val_if_fail (GTK_IS_WINDOW (window), 0);
7307 return window->gravity;
7311 * gtk_window_begin_resize_drag:
7312 * @window: a #GtkWindow
7313 * @button: mouse button that initiated the drag
7314 * @edge: position of the resize control
7315 * @root_x: X position where the user clicked to initiate the drag, in root window coordinates
7316 * @root_y: Y position where the user clicked to initiate the drag
7317 * @timestamp: timestamp from the click event that initiated the drag
7319 * Starts resizing a window. This function is used if an application
7320 * has window resizing controls. When GDK can support it, the resize
7321 * will be done using the standard mechanism for the <link
7322 * linkend="gtk-X11-arch">window manager</link> or windowing
7323 * system. Otherwise, GDK will try to emulate window resizing,
7324 * potentially not all that well, depending on the windowing system.
7328 gtk_window_begin_resize_drag (GtkWindow *window,
7336 GdkWindow *toplevel;
7338 g_return_if_fail (GTK_IS_WINDOW (window));
7339 g_return_if_fail (GTK_WIDGET_VISIBLE (window));
7341 widget = GTK_WIDGET (window);
7344 toplevel = window->frame;
7346 toplevel = widget->window;
7348 gdk_window_begin_resize_drag (toplevel,
7355 * gtk_window_get_frame_dimensions:
7356 * @window: a #GtkWindow
7357 * @left: location to store the width of the frame at the left, or %NULL
7358 * @top: location to store the height of the frame at the top, or %NULL
7359 * @right: location to store the width of the frame at the returns, or %NULL
7360 * @bottom: location to store the height of the frame at the bottom, or %NULL
7362 * (Note: this is a special-purpose function intended for the
7363 * framebuffer port; see gtk_window_set_has_frame(). It will not
7364 * return the size of the window border drawn by the <link
7365 * linkend="gtk-X11-arch">window manager</link>, which is the normal
7366 * case when using a windowing system. See
7367 * gdk_window_get_frame_extents() to get the standard window border
7370 * Retrieves the dimensions of the frame window for this toplevel.
7371 * See gtk_window_set_has_frame(), gtk_window_set_frame_dimensions().
7374 gtk_window_get_frame_dimensions (GtkWindow *window,
7380 g_return_if_fail (GTK_IS_WINDOW (window));
7383 *left = window->frame_left;
7385 *top = window->frame_top;
7387 *right = window->frame_right;
7389 *bottom = window->frame_bottom;
7393 * gtk_window_begin_move_drag:
7394 * @window: a #GtkWindow
7395 * @button: mouse button that initiated the drag
7396 * @root_x: X position where the user clicked to initiate the drag, in root window coordinates
7397 * @root_y: Y position where the user clicked to initiate the drag
7398 * @timestamp: timestamp from the click event that initiated the drag
7400 * Starts moving a window. This function is used if an application has
7401 * window movement grips. When GDK can support it, the window movement
7402 * will be done using the standard mechanism for the <link
7403 * linkend="gtk-X11-arch">window manager</link> or windowing
7404 * system. Otherwise, GDK will try to emulate window movement,
7405 * potentially not all that well, depending on the windowing system.
7409 gtk_window_begin_move_drag (GtkWindow *window,
7416 GdkWindow *toplevel;
7418 g_return_if_fail (GTK_IS_WINDOW (window));
7419 g_return_if_fail (GTK_WIDGET_VISIBLE (window));
7421 widget = GTK_WIDGET (window);
7424 toplevel = window->frame;
7426 toplevel = widget->window;
7428 gdk_window_begin_move_drag (toplevel,
7435 * gtk_window_set_screen:
7436 * @window: a #GtkWindow.
7437 * @screen: a #GdkScreen.
7439 * Sets the #GdkScreen where the @window is displayed; if
7440 * the window is already mapped, it will be unmapped, and
7441 * then remapped on the new screen.
7446 gtk_window_set_screen (GtkWindow *window,
7450 GdkScreen *previous_screen;
7451 gboolean was_mapped;
7453 g_return_if_fail (GTK_IS_WINDOW (window));
7454 g_return_if_fail (GDK_IS_SCREEN (screen));
7456 if (screen == window->screen)
7459 widget = GTK_WIDGET (window);
7461 previous_screen = window->screen;
7462 was_mapped = GTK_WIDGET_MAPPED (widget);
7465 gtk_widget_unmap (widget);
7466 if (GTK_WIDGET_REALIZED (widget))
7467 gtk_widget_unrealize (widget);
7469 gtk_window_free_key_hash (window);
7470 window->screen = screen;
7471 gtk_widget_reset_rc_styles (widget);
7472 if (screen != previous_screen)
7474 g_signal_handlers_disconnect_by_func (previous_screen,
7475 gtk_window_on_composited_changed, window);
7476 g_signal_connect (screen, "composited-changed",
7477 G_CALLBACK (gtk_window_on_composited_changed), window);
7479 _gtk_widget_propagate_screen_changed (widget, previous_screen);
7480 _gtk_widget_propagate_composited_changed (widget);
7482 g_object_notify (G_OBJECT (window), "screen");
7485 gtk_widget_map (widget);
7489 gtk_window_on_composited_changed (GdkScreen *screen,
7492 gtk_widget_queue_draw (GTK_WIDGET (window));
7494 _gtk_widget_propagate_composited_changed (GTK_WIDGET (window));
7498 gtk_window_check_screen (GtkWindow *window)
7501 return window->screen;
7504 g_warning ("Screen for GtkWindow not set; you must always set\n"
7505 "a screen for a GtkWindow before using the window");
7511 * gtk_window_get_screen:
7512 * @window: a #GtkWindow.
7514 * Returns the #GdkScreen associated with @window.
7516 * Return value: (transfer none): a #GdkScreen.
7521 gtk_window_get_screen (GtkWindow *window)
7523 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
7525 return window->screen;
7529 * gtk_window_is_active:
7530 * @window: a #GtkWindow
7532 * Returns whether the window is part of the current active toplevel.
7533 * (That is, the toplevel window receiving keystrokes.)
7534 * The return value is %TRUE if the window is active toplevel
7535 * itself, but also if it is, say, a #GtkPlug embedded in the active toplevel.
7536 * You might use this function if you wanted to draw a widget
7537 * differently in an active window from a widget in an inactive window.
7538 * See gtk_window_has_toplevel_focus()
7540 * Return value: %TRUE if the window part of the current active window.
7545 gtk_window_is_active (GtkWindow *window)
7547 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
7549 return window->is_active;
7553 * gtk_window_has_toplevel_focus:
7554 * @window: a #GtkWindow
7556 * Returns whether the input focus is within this GtkWindow.
7557 * For real toplevel windows, this is identical to gtk_window_is_active(),
7558 * but for embedded windows, like #GtkPlug, the results will differ.
7560 * Return value: %TRUE if the input focus is within this GtkWindow
7565 gtk_window_has_toplevel_focus (GtkWindow *window)
7567 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
7569 return window->has_toplevel_focus;
7573 gtk_window_group_class_init (GtkWindowGroupClass *klass)
7578 gtk_window_group_get_type (void)
7580 static GType window_group_type = 0;
7582 if (!window_group_type)
7584 const GTypeInfo window_group_info =
7586 sizeof (GtkWindowGroupClass),
7587 NULL, /* base_init */
7588 NULL, /* base_finalize */
7589 (GClassInitFunc) gtk_window_group_class_init,
7590 NULL, /* class_finalize */
7591 NULL, /* class_data */
7592 sizeof (GtkWindowGroup),
7593 0, /* n_preallocs */
7594 (GInstanceInitFunc) NULL,
7597 window_group_type = g_type_register_static (G_TYPE_OBJECT, I_("GtkWindowGroup"),
7598 &window_group_info, 0);
7601 return window_group_type;
7605 * gtk_window_group_new:
7607 * Creates a new #GtkWindowGroup object. Grabs added with
7608 * gtk_grab_add() only affect windows within the same #GtkWindowGroup.
7610 * Return value: a new #GtkWindowGroup.
7613 gtk_window_group_new (void)
7615 return g_object_new (GTK_TYPE_WINDOW_GROUP, NULL);
7619 window_group_cleanup_grabs (GtkWindowGroup *group,
7623 GSList *to_remove = NULL;
7625 tmp_list = group->grabs;
7628 if (gtk_widget_get_toplevel (tmp_list->data) == (GtkWidget*) window)
7629 to_remove = g_slist_prepend (to_remove, g_object_ref (tmp_list->data));
7630 tmp_list = tmp_list->next;
7635 gtk_grab_remove (to_remove->data);
7636 g_object_unref (to_remove->data);
7637 to_remove = g_slist_delete_link (to_remove, to_remove);
7642 * gtk_window_group_add_window:
7643 * @window_group: a #GtkWindowGroup
7644 * @window: the #GtkWindow to add
7646 * Adds a window to a #GtkWindowGroup.
7649 gtk_window_group_add_window (GtkWindowGroup *window_group,
7652 g_return_if_fail (GTK_IS_WINDOW_GROUP (window_group));
7653 g_return_if_fail (GTK_IS_WINDOW (window));
7655 if (window->group != window_group)
7657 g_object_ref (window);
7658 g_object_ref (window_group);
7661 gtk_window_group_remove_window (window->group, window);
7663 window_group_cleanup_grabs (gtk_window_get_group (NULL), window);
7665 window->group = window_group;
7667 g_object_unref (window);
7672 * gtk_window_group_remove_window:
7673 * @window_group: a #GtkWindowGroup
7674 * @window: the #GtkWindow to remove
7676 * Removes a window from a #GtkWindowGroup.
7679 gtk_window_group_remove_window (GtkWindowGroup *window_group,
7682 g_return_if_fail (GTK_IS_WINDOW_GROUP (window_group));
7683 g_return_if_fail (GTK_IS_WINDOW (window));
7684 g_return_if_fail (window->group == window_group);
7686 g_object_ref (window);
7688 window_group_cleanup_grabs (window_group, window);
7689 window->group = NULL;
7691 g_object_unref (window_group);
7692 g_object_unref (window);
7696 * gtk_window_group_list_windows:
7697 * @window_group: a #GtkWindowGroup
7699 * Returns a list of the #GtkWindows that belong to @window_group.
7701 * Returns: (element-type GtkWidget) (transfer container): A newly-allocated list of
7702 * windows inside the group.
7707 gtk_window_group_list_windows (GtkWindowGroup *window_group)
7709 GList *toplevels, *toplevel, *group_windows;
7711 g_return_val_if_fail (GTK_IS_WINDOW_GROUP (window_group), NULL);
7713 group_windows = NULL;
7714 toplevels = gtk_window_list_toplevels ();
7716 for (toplevel = toplevels; toplevel; toplevel = toplevel->next)
7718 GtkWindow *window = toplevel->data;
7720 if (window_group == window->group)
7721 group_windows = g_list_prepend (group_windows, window);
7724 return g_list_reverse (group_windows);
7728 * gtk_window_get_group:
7729 * @window: a #GtkWindow, or %NULL
7731 * Returns the group for @window or the default group, if
7732 * @window is %NULL or if @window does not have an explicit
7735 * Returns: (transfer none): the #GtkWindowGroup for a window or the default group
7740 gtk_window_get_group (GtkWindow *window)
7742 if (window && window->group)
7743 return window->group;
7746 static GtkWindowGroup *default_group = NULL;
7749 default_group = gtk_window_group_new ();
7751 return default_group;
7755 /* Return the current grab widget of the given group
7758 _gtk_window_group_get_current_grab (GtkWindowGroup *window_group)
7760 if (window_group->grabs)
7761 return GTK_WIDGET (window_group->grabs->data);
7766 Derived from XParseGeometry() in XFree86
7768 Copyright 1985, 1986, 1987,1998 The Open Group
7770 All Rights Reserved.
7772 The above copyright notice and this permission notice shall be included
7773 in all copies or substantial portions of the Software.
7775 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
7776 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
7777 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
7778 IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
7779 OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
7780 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
7781 OTHER DEALINGS IN THE SOFTWARE.
7783 Except as contained in this notice, the name of The Open Group shall
7784 not be used in advertising or otherwise to promote the sale, use or
7785 other dealings in this Software without prior written authorization
7786 from The Open Group.
7791 * XParseGeometry parses strings of the form
7792 * "=<width>x<height>{+-}<xoffset>{+-}<yoffset>", where
7793 * width, height, xoffset, and yoffset are unsigned integers.
7794 * Example: "=80x24+300-49"
7795 * The equal sign is optional.
7796 * It returns a bitmask that indicates which of the four values
7797 * were actually found in the string. For each value found,
7798 * the corresponding argument is updated; for each value
7799 * not found, the corresponding argument is left unchanged.
7802 /* The following code is from Xlib, and is minimally modified, so we
7803 * can track any upstream changes if required. Don't change this
7804 * code. Or if you do, put in a huge comment marking which thing
7809 read_int (gchar *string,
7817 else if (*string == '-')
7823 for (; (*string >= '0') && (*string <= '9'); string++)
7825 result = (result * 10) + (*string - '0');
7837 * Bitmask returned by XParseGeometry(). Each bit tells if the corresponding
7838 * value (x, y, width, height) was found in the parsed string.
7840 #define NoValue 0x0000
7841 #define XValue 0x0001
7842 #define YValue 0x0002
7843 #define WidthValue 0x0004
7844 #define HeightValue 0x0008
7845 #define AllValues 0x000F
7846 #define XNegative 0x0010
7847 #define YNegative 0x0020
7849 /* Try not to reformat/modify, so we can compare/sync with X sources */
7851 gtk_XParseGeometry (const char *string,
7854 unsigned int *width,
7855 unsigned int *height)
7859 unsigned int tempWidth, tempHeight;
7861 char *nextCharacter;
7863 /* These initializations are just to silence gcc */
7869 if ( (string == NULL) || (*string == '\0')) return(mask);
7871 string++; /* ignore possible '=' at beg of geometry spec */
7873 strind = (char *)string;
7874 if (*strind != '+' && *strind != '-' && *strind != 'x') {
7875 tempWidth = read_int(strind, &nextCharacter);
7876 if (strind == nextCharacter)
7878 strind = nextCharacter;
7882 if (*strind == 'x' || *strind == 'X') {
7884 tempHeight = read_int(strind, &nextCharacter);
7885 if (strind == nextCharacter)
7887 strind = nextCharacter;
7888 mask |= HeightValue;
7891 if ((*strind == '+') || (*strind == '-')) {
7892 if (*strind == '-') {
7894 tempX = -read_int(strind, &nextCharacter);
7895 if (strind == nextCharacter)
7897 strind = nextCharacter;
7903 tempX = read_int(strind, &nextCharacter);
7904 if (strind == nextCharacter)
7906 strind = nextCharacter;
7909 if ((*strind == '+') || (*strind == '-')) {
7910 if (*strind == '-') {
7912 tempY = -read_int(strind, &nextCharacter);
7913 if (strind == nextCharacter)
7915 strind = nextCharacter;
7922 tempY = read_int(strind, &nextCharacter);
7923 if (strind == nextCharacter)
7925 strind = nextCharacter;
7931 /* If strind isn't at the end of the string the it's an invalid
7932 geometry specification. */
7934 if (*strind != '\0') return (0);
7940 if (mask & WidthValue)
7942 if (mask & HeightValue)
7943 *height = tempHeight;
7948 * gtk_window_parse_geometry:
7949 * @window: a #GtkWindow
7950 * @geometry: geometry string
7952 * Parses a standard X Window System geometry string - see the
7953 * manual page for X (type 'man X') for details on this.
7954 * gtk_window_parse_geometry() does work on all GTK+ ports
7955 * including Win32 but is primarily intended for an X environment.
7957 * If either a size or a position can be extracted from the
7958 * geometry string, gtk_window_parse_geometry() returns %TRUE
7959 * and calls gtk_window_set_default_size() and/or gtk_window_move()
7960 * to resize/move the window.
7962 * If gtk_window_parse_geometry() returns %TRUE, it will also
7963 * set the #GDK_HINT_USER_POS and/or #GDK_HINT_USER_SIZE hints
7964 * indicating to the window manager that the size/position of
7965 * the window was user-specified. This causes most window
7966 * managers to honor the geometry.
7968 * Note that for gtk_window_parse_geometry() to work as expected, it has
7969 * to be called when the window has its "final" size, i.e. after calling
7970 * gtk_widget_show_all() on the contents and gtk_window_set_geometry_hints()
7973 * #include <gtk/gtk.h>
7976 * fill_with_content (GtkWidget *vbox)
7978 * /* fill with content... */
7982 * main (int argc, char *argv[])
7984 * GtkWidget *window, *vbox;
7985 * GdkGeometry size_hints = {
7986 * 100, 50, 0, 0, 100, 50, 10, 10, 0.0, 0.0, GDK_GRAVITY_NORTH_WEST
7989 * gtk_init (&argc, &argv);
7991 * window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
7992 * vbox = gtk_vbox_new (FALSE, 0);
7994 * gtk_container_add (GTK_CONTAINER (window), vbox);
7995 * fill_with_content (vbox);
7996 * gtk_widget_show_all (vbox);
7998 * gtk_window_set_geometry_hints (GTK_WINDOW (window),
8001 * GDK_HINT_MIN_SIZE |
8002 * GDK_HINT_BASE_SIZE |
8003 * GDK_HINT_RESIZE_INC);
8007 * if (!gtk_window_parse_geometry (GTK_WINDOW (window), argv[1]))
8008 * fprintf (stderr, "Failed to parse '%s'\n", argv[1]);
8011 * gtk_widget_show_all (window);
8018 * Return value: %TRUE if string was parsed successfully
8021 gtk_window_parse_geometry (GtkWindow *window,
8022 const gchar *geometry)
8024 gint result, x = 0, y = 0;
8027 gboolean size_set, pos_set;
8030 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
8031 g_return_val_if_fail (geometry != NULL, FALSE);
8033 screen = gtk_window_check_screen (window);
8035 result = gtk_XParseGeometry (geometry, &x, &y, &w, &h);
8038 if ((result & WidthValue) || (result & HeightValue))
8040 gtk_window_set_default_size_internal (window,
8041 TRUE, result & WidthValue ? w : -1,
8042 TRUE, result & HeightValue ? h : -1,
8047 gtk_window_get_size (window, (gint *)&w, (gint *)&h);
8049 grav = GDK_GRAVITY_NORTH_WEST;
8051 if ((result & XNegative) && (result & YNegative))
8052 grav = GDK_GRAVITY_SOUTH_EAST;
8053 else if (result & XNegative)
8054 grav = GDK_GRAVITY_NORTH_EAST;
8055 else if (result & YNegative)
8056 grav = GDK_GRAVITY_SOUTH_WEST;
8058 if ((result & XValue) == 0)
8061 if ((result & YValue) == 0)
8064 if (grav == GDK_GRAVITY_SOUTH_WEST ||
8065 grav == GDK_GRAVITY_SOUTH_EAST)
8066 y = gdk_screen_get_height (screen) - h + y;
8068 if (grav == GDK_GRAVITY_SOUTH_EAST ||
8069 grav == GDK_GRAVITY_NORTH_EAST)
8070 x = gdk_screen_get_width (screen) - w + x;
8072 /* we don't let you put a window offscreen; maybe some people would
8073 * prefer to be able to, but it's kind of a bogus thing to do.
8082 if ((result & XValue) || (result & YValue))
8084 gtk_window_set_gravity (window, grav);
8085 gtk_window_move (window, x, y);
8089 if (size_set || pos_set)
8091 /* Set USSize, USPosition hints */
8092 GtkWindowGeometryInfo *info;
8094 info = gtk_window_get_geometry_info (window, TRUE);
8097 info->mask |= GDK_HINT_USER_POS;
8099 info->mask |= GDK_HINT_USER_SIZE;
8106 gtk_window_mnemonic_hash_foreach (guint keyval,
8112 GtkWindowKeysForeachFunc func;
8116 (*info->func) (info->window, keyval, info->window->mnemonic_modifier, TRUE, info->func_data);
8120 _gtk_window_keys_foreach (GtkWindow *window,
8121 GtkWindowKeysForeachFunc func,
8125 GtkMnemonicHash *mnemonic_hash;
8129 GtkWindowKeysForeachFunc func;
8133 info.window = window;
8135 info.func_data = func_data;
8137 mnemonic_hash = gtk_window_get_mnemonic_hash (window, FALSE);
8139 _gtk_mnemonic_hash_foreach (mnemonic_hash,
8140 gtk_window_mnemonic_hash_foreach, &info);
8142 groups = gtk_accel_groups_from_object (G_OBJECT (window));
8145 GtkAccelGroup *group = groups->data;
8148 for (i = 0; i < group->n_accels; i++)
8150 GtkAccelKey *key = &group->priv_accels[i].key;
8153 (*func) (window, key->accel_key, key->accel_mods, FALSE, func_data);
8156 groups = groups->next;
8161 gtk_window_keys_changed (GtkWindow *window)
8163 gtk_window_free_key_hash (window);
8164 gtk_window_get_key_hash (window);
8167 typedef struct _GtkWindowKeyEntry GtkWindowKeyEntry;
8169 struct _GtkWindowKeyEntry
8173 guint is_mnemonic : 1;
8177 window_key_entry_destroy (gpointer data)
8179 g_slice_free (GtkWindowKeyEntry, data);
8183 add_to_key_hash (GtkWindow *window,
8185 GdkModifierType modifiers,
8186 gboolean is_mnemonic,
8189 GtkKeyHash *key_hash = data;
8191 GtkWindowKeyEntry *entry = g_slice_new (GtkWindowKeyEntry);
8193 entry->keyval = keyval;
8194 entry->modifiers = modifiers;
8195 entry->is_mnemonic = is_mnemonic;
8197 /* GtkAccelGroup stores lowercased accelerators. To deal
8198 * with this, if <Shift> was specified, uppercase.
8200 if (modifiers & GDK_SHIFT_MASK)
8202 if (keyval == GDK_Tab)
8203 keyval = GDK_ISO_Left_Tab;
8205 keyval = gdk_keyval_to_upper (keyval);
8208 _gtk_key_hash_add_entry (key_hash, keyval, entry->modifiers, entry);
8212 gtk_window_get_key_hash (GtkWindow *window)
8214 GdkScreen *screen = gtk_window_check_screen (window);
8215 GtkKeyHash *key_hash = g_object_get_qdata (G_OBJECT (window), quark_gtk_window_key_hash);
8220 key_hash = _gtk_key_hash_new (gdk_keymap_get_for_display (gdk_screen_get_display (screen)),
8221 (GDestroyNotify)window_key_entry_destroy);
8222 _gtk_window_keys_foreach (window, add_to_key_hash, key_hash);
8223 g_object_set_qdata (G_OBJECT (window), quark_gtk_window_key_hash, key_hash);
8229 gtk_window_free_key_hash (GtkWindow *window)
8231 GtkKeyHash *key_hash = g_object_get_qdata (G_OBJECT (window), quark_gtk_window_key_hash);
8234 _gtk_key_hash_free (key_hash);
8235 g_object_set_qdata (G_OBJECT (window), quark_gtk_window_key_hash, NULL);
8240 * gtk_window_activate_key:
8241 * @window: a #GtkWindow
8242 * @event: a #GdkEventKey
8244 * Activates mnemonics and accelerators for this #GtkWindow. This is normally
8245 * called by the default ::key_press_event handler for toplevel windows,
8246 * however in some cases it may be useful to call this directly when
8247 * overriding the standard key handling for a toplevel window.
8249 * Return value: %TRUE if a mnemonic or accelerator was found and activated.
8254 gtk_window_activate_key (GtkWindow *window,
8257 GtkKeyHash *key_hash;
8258 GtkWindowKeyEntry *found_entry = NULL;
8259 gboolean enable_mnemonics;
8260 gboolean enable_accels;
8262 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
8263 g_return_val_if_fail (event != NULL, FALSE);
8265 key_hash = gtk_window_get_key_hash (window);
8270 GSList *entries = _gtk_key_hash_lookup (key_hash,
8271 event->hardware_keycode,
8273 gtk_accelerator_get_default_mod_mask (),
8276 g_object_get (gtk_widget_get_settings (GTK_WIDGET (window)),
8277 "gtk-enable-mnemonics", &enable_mnemonics,
8278 "gtk-enable-accels", &enable_accels,
8281 for (tmp_list = entries; tmp_list; tmp_list = tmp_list->next)
8283 GtkWindowKeyEntry *entry = tmp_list->data;
8284 if (entry->is_mnemonic)
8286 if (enable_mnemonics)
8288 found_entry = entry;
8294 if (enable_accels && !found_entry)
8296 found_entry = entry;
8301 g_slist_free (entries);
8306 if (found_entry->is_mnemonic)
8308 if (enable_mnemonics)
8309 return gtk_window_mnemonic_activate (window, found_entry->keyval,
8310 found_entry->modifiers);
8315 return gtk_accel_groups_activate (G_OBJECT (window), found_entry->keyval,
8316 found_entry->modifiers);
8324 window_update_has_focus (GtkWindow *window)
8326 GtkWidget *widget = GTK_WIDGET (window);
8327 gboolean has_focus = window->has_toplevel_focus && window->is_active;
8329 if (has_focus != window->has_focus)
8331 window->has_focus = has_focus;
8335 if (window->focus_widget &&
8336 window->focus_widget != widget &&
8337 !GTK_WIDGET_HAS_FOCUS (window->focus_widget))
8338 do_focus_change (window->focus_widget, TRUE);
8342 if (window->focus_widget &&
8343 window->focus_widget != widget &&
8344 GTK_WIDGET_HAS_FOCUS (window->focus_widget))
8345 do_focus_change (window->focus_widget, FALSE);
8351 * _gtk_window_set_is_active:
8352 * @window: a #GtkWindow
8353 * @is_active: %TRUE if the window is in the currently active toplevel
8355 * Internal function that sets whether the #GtkWindow is part
8356 * of the currently active toplevel window (taking into account inter-process
8360 _gtk_window_set_is_active (GtkWindow *window,
8363 g_return_if_fail (GTK_IS_WINDOW (window));
8365 is_active = is_active != FALSE;
8367 if (is_active != window->is_active)
8369 window->is_active = is_active;
8370 window_update_has_focus (window);
8372 g_object_notify (G_OBJECT (window), "is-active");
8377 * _gtk_window_set_is_toplevel:
8378 * @window: a #GtkWindow
8379 * @is_toplevel: %TRUE if the window is still a real toplevel (nominally a
8380 * parent of the root window); %FALSE if it is not (for example, for an
8381 * in-process, parented GtkPlug)
8383 * Internal function used by #GtkPlug when it gets parented/unparented by a
8384 * #GtkSocket. This keeps the @window's #GTK_TOPLEVEL flag in sync with the
8385 * global list of toplevel windows.
8388 _gtk_window_set_is_toplevel (GtkWindow *window,
8389 gboolean is_toplevel)
8391 if (GTK_WIDGET_TOPLEVEL (window))
8392 g_assert (g_slist_find (toplevel_list, window) != NULL);
8394 g_assert (g_slist_find (toplevel_list, window) == NULL);
8396 if (is_toplevel == GTK_WIDGET_TOPLEVEL (window))
8401 GTK_WIDGET_SET_FLAGS (window, GTK_TOPLEVEL);
8402 toplevel_list = g_slist_prepend (toplevel_list, window);
8406 GTK_WIDGET_UNSET_FLAGS (window, GTK_TOPLEVEL);
8407 toplevel_list = g_slist_remove (toplevel_list, window);
8412 * _gtk_window_set_has_toplevel_focus:
8413 * @window: a #GtkWindow
8414 * @has_toplevel_focus: %TRUE if the in
8416 * Internal function that sets whether the keyboard focus for the
8417 * toplevel window (taking into account inter-process embedding.)
8420 _gtk_window_set_has_toplevel_focus (GtkWindow *window,
8421 gboolean has_toplevel_focus)
8423 g_return_if_fail (GTK_IS_WINDOW (window));
8425 has_toplevel_focus = has_toplevel_focus != FALSE;
8427 if (has_toplevel_focus != window->has_toplevel_focus)
8429 window->has_toplevel_focus = has_toplevel_focus;
8430 window_update_has_focus (window);
8432 g_object_notify (G_OBJECT (window), "has-toplevel-focus");
8437 * gtk_window_set_auto_startup_notification:
8438 * @setting: %TRUE to automatically do startup notification
8440 * By default, after showing the first #GtkWindow, GTK+ calls
8441 * gdk_notify_startup_complete(). Call this function to disable
8442 * the automatic startup notification. You might do this if your
8443 * first window is a splash screen, and you want to delay notification
8444 * until after your real main window has been shown, for example.
8446 * In that example, you would disable startup notification
8447 * temporarily, show your splash screen, then re-enable it so that
8448 * showing the main window would automatically result in notification.
8453 gtk_window_set_auto_startup_notification (gboolean setting)
8455 disable_startup_notification = !setting;
8459 * gtk_window_get_window_type:
8460 * @window: a #GtkWindow
8462 * Gets the type of the window. See #GtkWindowType.
8464 * Return value: the type of the window
8469 gtk_window_get_window_type (GtkWindow *window)
8471 g_return_val_if_fail (GTK_IS_WINDOW (window), GTK_WINDOW_TOPLEVEL);
8473 return window->type;
8477 gtk_window_get_mnemonics_visible (GtkWindow *window)
8479 GtkWindowPrivate *priv;
8481 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
8483 priv = GTK_WINDOW_GET_PRIVATE (window);
8485 return priv->mnemonics_visible;
8489 gtk_window_set_mnemonics_visible (GtkWindow *window,
8492 GtkWindowPrivate *priv;
8494 g_return_if_fail (GTK_IS_WINDOW (window));
8496 priv = GTK_WINDOW_GET_PRIVATE (window);
8498 setting = setting != FALSE;
8500 if (priv->mnemonics_visible != setting)
8502 priv->mnemonics_visible = setting;
8503 g_object_notify (G_OBJECT (window), "mnemonics-visible");
8506 priv->mnemonics_visible_set = TRUE;
8510 gtk_window_grab_notify (GtkWidget *widget,
8511 gboolean was_grabbed)
8513 gboolean auto_mnemonics;
8518 g_object_get (gtk_widget_get_settings (widget), "gtk-auto-mnemonics",
8519 &auto_mnemonics, NULL);
8522 gtk_window_set_mnemonics_visible (GTK_WINDOW (widget), FALSE);
8525 #if defined (G_OS_WIN32) && !defined (_WIN64)
8527 #undef gtk_window_set_icon_from_file
8530 gtk_window_set_icon_from_file (GtkWindow *window,
8531 const gchar *filename,
8534 gchar *utf8_filename = g_locale_to_utf8 (filename, -1, NULL, NULL, err);
8537 if (utf8_filename == NULL)
8540 retval = gtk_window_set_icon_from_file_utf8 (window, utf8_filename, err);
8542 g_free (utf8_filename);
8547 #undef gtk_window_set_default_icon_from_file
8550 gtk_window_set_default_icon_from_file (const gchar *filename,
8553 gchar *utf8_filename = g_locale_to_utf8 (filename, -1, NULL, NULL, err);
8556 if (utf8_filename == NULL)
8559 retval = gtk_window_set_default_icon_from_file_utf8 (utf8_filename, err);
8561 g_free (utf8_filename);
8568 #define __GTK_WINDOW_C__
8569 #include "gtkaliasdef.c"