1 /* GTK - The GIMP Toolkit
2 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
21 * Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
22 * file for a list of people on the GTK+ Team. See the ChangeLog
23 * files for a list of changes. These files are distributed with
24 * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
33 #include "gdk/gdkkeysyms.h"
37 #include "gtkprivate.h"
39 #include "gtkwindow.h"
40 #include "gtkwindow-decorate.h"
41 #include "gtkbindings.h"
42 #include "gtkkeyhash.h"
44 #include "gtkmnemonichash.h"
45 #include "gtkmenubar.h"
46 #include "gtkiconfactory.h"
47 #include "gtkicontheme.h"
48 #include "gtkmarshalers.h"
50 #include "gtkbuildable.h"
53 #ifdef GDK_WINDOWING_X11
82 PROP_DESTROY_WITH_PARENT,
87 PROP_SKIP_TASKBAR_HINT,
98 /* Readonly properties */
100 PROP_HAS_TOPLEVEL_FOCUS,
102 /* Writeonly properties */
105 PROP_MNEMONICS_VISIBLE,
113 GdkPixmap *icon_pixmap;
114 GdkPixmap *icon_mask;
117 guint using_default_icon : 1;
118 guint using_parent_icon : 1;
119 guint using_themed_icon : 1;
123 GdkGeometry geometry; /* Last set of geometry hints we set */
124 GdkWindowHints flags;
125 GdkRectangle configure_request;
126 } GtkWindowLastGeometryInfo;
128 struct _GtkWindowGeometryInfo
130 /* Properties that the app has set on the window
132 GdkGeometry geometry; /* Geometry hints */
134 GtkWidget *widget; /* subwidget to which hints apply */
135 /* from last gtk_window_resize () - if > 0, indicates that
136 * we should resize to this size.
141 /* From last gtk_window_move () prior to mapping -
142 * only used if initial_pos_set
147 /* Default size - used only the FIRST time we map a window,
152 /* whether to use initial_x, initial_y */
153 guint initial_pos_set : 1;
154 /* CENTER_ALWAYS or other position constraint changed since
155 * we sent the last configure request.
157 guint position_constraints_changed : 1;
159 /* if true, default_width, height come from gtk_window_parse_geometry,
160 * and thus should be multiplied by the increments and affect the
161 * geometry widget only
163 guint default_is_geometry : 1;
165 GtkWindowLastGeometryInfo last;
168 #define GTK_WINDOW_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GTK_TYPE_WINDOW, GtkWindowPrivate))
170 typedef struct _GtkWindowPrivate GtkWindowPrivate;
172 struct _GtkWindowPrivate
174 GtkMnemonicHash *mnemonic_hash;
176 guint above_initially : 1;
177 guint below_initially : 1;
178 guint fullscreen_initially : 1;
179 guint skips_taskbar : 1;
180 guint skips_pager : 1;
182 guint accept_focus : 1;
183 guint focus_on_map : 1;
185 guint transient_parent_group : 1;
187 guint reset_type_hint : 1;
188 guint opacity_set : 1;
189 guint builder_visible : 1;
191 guint mnemonics_visible : 1;
192 guint mnemonics_visible_set : 1;
194 GdkWindowTypeHint type_hint;
201 static void gtk_window_dispose (GObject *object);
202 static void gtk_window_destroy (GtkObject *object);
203 static void gtk_window_finalize (GObject *object);
204 static void gtk_window_show (GtkWidget *widget);
205 static void gtk_window_hide (GtkWidget *widget);
206 static void gtk_window_map (GtkWidget *widget);
207 static void gtk_window_unmap (GtkWidget *widget);
208 static void gtk_window_realize (GtkWidget *widget);
209 static void gtk_window_unrealize (GtkWidget *widget);
210 static void gtk_window_size_request (GtkWidget *widget,
211 GtkRequisition *requisition);
212 static void gtk_window_size_allocate (GtkWidget *widget,
213 GtkAllocation *allocation);
214 static gint gtk_window_event (GtkWidget *widget,
216 static gboolean gtk_window_map_event (GtkWidget *widget,
218 static gboolean gtk_window_frame_event (GtkWindow *window,
220 static gint gtk_window_configure_event (GtkWidget *widget,
221 GdkEventConfigure *event);
222 static gint gtk_window_key_press_event (GtkWidget *widget,
224 static gint gtk_window_key_release_event (GtkWidget *widget,
226 static gint gtk_window_enter_notify_event (GtkWidget *widget,
227 GdkEventCrossing *event);
228 static gint gtk_window_leave_notify_event (GtkWidget *widget,
229 GdkEventCrossing *event);
230 static gint gtk_window_focus_in_event (GtkWidget *widget,
231 GdkEventFocus *event);
232 static gint gtk_window_focus_out_event (GtkWidget *widget,
233 GdkEventFocus *event);
234 static gint gtk_window_client_event (GtkWidget *widget,
235 GdkEventClient *event);
236 static void gtk_window_check_resize (GtkContainer *container);
237 static gint gtk_window_focus (GtkWidget *widget,
238 GtkDirectionType direction);
239 static void gtk_window_real_set_focus (GtkWindow *window,
242 static void gtk_window_real_activate_default (GtkWindow *window);
243 static void gtk_window_real_activate_focus (GtkWindow *window);
244 static void gtk_window_move_focus (GtkWindow *window,
245 GtkDirectionType dir);
246 static void gtk_window_keys_changed (GtkWindow *window);
247 static void gtk_window_paint (GtkWidget *widget,
249 static gint gtk_window_expose (GtkWidget *widget,
250 GdkEventExpose *event);
251 static void gtk_window_unset_transient_for (GtkWindow *window);
252 static void gtk_window_transient_parent_realized (GtkWidget *parent,
254 static void gtk_window_transient_parent_unrealized (GtkWidget *parent,
257 static GdkScreen *gtk_window_check_screen (GtkWindow *window);
259 static GtkWindowGeometryInfo* gtk_window_get_geometry_info (GtkWindow *window,
262 static void gtk_window_move_resize (GtkWindow *window);
263 static gboolean gtk_window_compare_hints (GdkGeometry *geometry_a,
265 GdkGeometry *geometry_b,
267 static void gtk_window_constrain_size (GtkWindow *window,
268 GdkGeometry *geometry,
274 static void gtk_window_constrain_position (GtkWindow *window,
279 static void gtk_window_compute_hints (GtkWindow *window,
280 GdkGeometry *new_geometry,
282 static void gtk_window_compute_configure_request (GtkWindow *window,
283 GdkRectangle *request,
284 GdkGeometry *geometry,
287 static void gtk_window_set_default_size_internal (GtkWindow *window,
288 gboolean change_width,
290 gboolean change_height,
292 gboolean is_geometry);
294 static void update_themed_icon (GtkIconTheme *theme,
296 static GList *icon_list_from_theme (GtkWidget *widget,
298 static void gtk_window_realize_icon (GtkWindow *window);
299 static void gtk_window_unrealize_icon (GtkWindow *window);
301 static void gtk_window_notify_keys_changed (GtkWindow *window);
302 static GtkKeyHash *gtk_window_get_key_hash (GtkWindow *window);
303 static void gtk_window_free_key_hash (GtkWindow *window);
304 static void gtk_window_on_composited_changed (GdkScreen *screen,
307 static GSList *toplevel_list = NULL;
308 static guint window_signals[LAST_SIGNAL] = { 0 };
309 static GList *default_icon_list = NULL;
310 static gchar *default_icon_name = NULL;
311 static guint default_icon_serial = 0;
312 static gboolean disable_startup_notification = FALSE;
313 static gboolean sent_startup_notification = FALSE;
315 static GQuark quark_gtk_embedded = 0;
316 static GQuark quark_gtk_window_key_hash = 0;
317 static GQuark quark_gtk_window_default_icon_pixmap = 0;
318 static GQuark quark_gtk_window_icon_info = 0;
319 static GQuark quark_gtk_buildable_accels = 0;
321 static GtkBuildableIface *parent_buildable_iface;
323 static void gtk_window_set_property (GObject *object,
327 static void gtk_window_get_property (GObject *object,
333 static void gtk_window_buildable_interface_init (GtkBuildableIface *iface);
334 static void gtk_window_buildable_set_buildable_property (GtkBuildable *buildable,
337 const GValue *value);
338 static void gtk_window_buildable_parser_finished (GtkBuildable *buildable,
339 GtkBuilder *builder);
340 static gboolean gtk_window_buildable_custom_tag_start (GtkBuildable *buildable,
343 const gchar *tagname,
344 GMarkupParser *parser,
346 static void gtk_window_buildable_custom_finished (GtkBuildable *buildable,
349 const gchar *tagname,
353 G_DEFINE_TYPE_WITH_CODE (GtkWindow, gtk_window, GTK_TYPE_BIN,
354 G_IMPLEMENT_INTERFACE (GTK_TYPE_BUILDABLE,
355 gtk_window_buildable_interface_init))
358 add_tab_bindings (GtkBindingSet *binding_set,
359 GdkModifierType modifiers,
360 GtkDirectionType direction)
362 gtk_binding_entry_add_signal (binding_set, GDK_Tab, modifiers,
364 GTK_TYPE_DIRECTION_TYPE, direction);
365 gtk_binding_entry_add_signal (binding_set, GDK_KP_Tab, modifiers,
367 GTK_TYPE_DIRECTION_TYPE, direction);
371 add_arrow_bindings (GtkBindingSet *binding_set,
373 GtkDirectionType direction)
375 guint keypad_keysym = keysym - GDK_Left + GDK_KP_Left;
377 gtk_binding_entry_add_signal (binding_set, keysym, 0,
379 GTK_TYPE_DIRECTION_TYPE, direction);
380 gtk_binding_entry_add_signal (binding_set, keysym, GDK_CONTROL_MASK,
382 GTK_TYPE_DIRECTION_TYPE, direction);
383 gtk_binding_entry_add_signal (binding_set, keypad_keysym, 0,
385 GTK_TYPE_DIRECTION_TYPE, direction);
386 gtk_binding_entry_add_signal (binding_set, keypad_keysym, GDK_CONTROL_MASK,
388 GTK_TYPE_DIRECTION_TYPE, direction);
392 extract_time_from_startup_id (const gchar* startup_id)
394 gchar *timestr = g_strrstr (startup_id, "_TIME");
395 guint32 retval = GDK_CURRENT_TIME;
402 /* Skip past the "_TIME" part */
406 timestamp = strtoul (timestr, &end, 0);
407 if (end != timestr && errno == 0)
415 startup_id_is_fake (const gchar* startup_id)
417 return strncmp (startup_id, "_TIME", 5) == 0;
421 gtk_window_class_init (GtkWindowClass *klass)
423 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
424 GtkObjectClass *object_class;
425 GtkWidgetClass *widget_class;
426 GtkContainerClass *container_class;
427 GtkBindingSet *binding_set;
429 object_class = (GtkObjectClass*) klass;
430 widget_class = (GtkWidgetClass*) klass;
431 container_class = (GtkContainerClass*) klass;
433 quark_gtk_embedded = g_quark_from_static_string ("gtk-embedded");
434 quark_gtk_window_key_hash = g_quark_from_static_string ("gtk-window-key-hash");
435 quark_gtk_window_default_icon_pixmap = g_quark_from_static_string ("gtk-window-default-icon-pixmap");
436 quark_gtk_window_icon_info = g_quark_from_static_string ("gtk-window-icon-info");
437 quark_gtk_buildable_accels = g_quark_from_static_string ("gtk-window-buildable-accels");
439 gobject_class->dispose = gtk_window_dispose;
440 gobject_class->finalize = gtk_window_finalize;
442 gobject_class->set_property = gtk_window_set_property;
443 gobject_class->get_property = gtk_window_get_property;
445 object_class->destroy = gtk_window_destroy;
447 widget_class->show = gtk_window_show;
448 widget_class->hide = gtk_window_hide;
449 widget_class->map = gtk_window_map;
450 widget_class->map_event = gtk_window_map_event;
451 widget_class->unmap = gtk_window_unmap;
452 widget_class->realize = gtk_window_realize;
453 widget_class->unrealize = gtk_window_unrealize;
454 widget_class->size_request = gtk_window_size_request;
455 widget_class->size_allocate = gtk_window_size_allocate;
456 widget_class->configure_event = gtk_window_configure_event;
457 widget_class->key_press_event = gtk_window_key_press_event;
458 widget_class->key_release_event = gtk_window_key_release_event;
459 widget_class->enter_notify_event = gtk_window_enter_notify_event;
460 widget_class->leave_notify_event = gtk_window_leave_notify_event;
461 widget_class->focus_in_event = gtk_window_focus_in_event;
462 widget_class->focus_out_event = gtk_window_focus_out_event;
463 widget_class->client_event = gtk_window_client_event;
464 widget_class->focus = gtk_window_focus;
465 widget_class->expose_event = gtk_window_expose;
467 container_class->check_resize = gtk_window_check_resize;
469 klass->set_focus = gtk_window_real_set_focus;
470 klass->frame_event = gtk_window_frame_event;
472 klass->activate_default = gtk_window_real_activate_default;
473 klass->activate_focus = gtk_window_real_activate_focus;
474 klass->move_focus = gtk_window_move_focus;
475 klass->keys_changed = gtk_window_keys_changed;
477 g_type_class_add_private (gobject_class, sizeof (GtkWindowPrivate));
480 g_object_class_install_property (gobject_class,
482 g_param_spec_enum ("type",
484 P_("The type of the window"),
485 GTK_TYPE_WINDOW_TYPE,
487 GTK_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
489 g_object_class_install_property (gobject_class,
491 g_param_spec_string ("title",
493 P_("The title of the window"),
495 GTK_PARAM_READWRITE));
497 g_object_class_install_property (gobject_class,
499 g_param_spec_string ("role",
501 P_("Unique identifier for the window to be used when restoring a session"),
503 GTK_PARAM_READWRITE));
506 * GtkWindow:startup-id:
508 * The :startup-id is a write-only property for setting window's
509 * startup notification identifier. See gtk_window_set_startup_id()
514 g_object_class_install_property (gobject_class,
516 g_param_spec_string ("startup-id",
518 P_("Unique startup identifier for the window used by startup-notification"),
520 GTK_PARAM_WRITABLE));
522 g_object_class_install_property (gobject_class,
524 g_param_spec_boolean ("allow-shrink",
526 /* xgettext:no-c-format */
527 P_("If TRUE, the window has no mimimum size. Setting this to TRUE is 99% of the time a bad idea"),
529 GTK_PARAM_READWRITE));
531 g_object_class_install_property (gobject_class,
533 g_param_spec_boolean ("allow-grow",
535 P_("If TRUE, users can expand the window beyond its minimum size"),
537 GTK_PARAM_READWRITE));
539 g_object_class_install_property (gobject_class,
541 g_param_spec_boolean ("resizable",
543 P_("If TRUE, users can resize the window"),
545 GTK_PARAM_READWRITE));
547 g_object_class_install_property (gobject_class,
549 g_param_spec_boolean ("modal",
551 P_("If TRUE, the window is modal (other windows are not usable while this one is up)"),
553 GTK_PARAM_READWRITE));
555 g_object_class_install_property (gobject_class,
557 g_param_spec_enum ("window-position",
558 P_("Window Position"),
559 P_("The initial position of the window"),
560 GTK_TYPE_WINDOW_POSITION,
562 GTK_PARAM_READWRITE));
564 g_object_class_install_property (gobject_class,
566 g_param_spec_int ("default-width",
568 P_("The default width of the window, used when initially showing the window"),
572 GTK_PARAM_READWRITE));
574 g_object_class_install_property (gobject_class,
576 g_param_spec_int ("default-height",
577 P_("Default Height"),
578 P_("The default height of the window, used when initially showing the window"),
582 GTK_PARAM_READWRITE));
584 g_object_class_install_property (gobject_class,
585 PROP_DESTROY_WITH_PARENT,
586 g_param_spec_boolean ("destroy-with-parent",
587 P_("Destroy with Parent"),
588 P_("If this window should be destroyed when the parent is destroyed"),
590 GTK_PARAM_READWRITE));
592 g_object_class_install_property (gobject_class,
594 g_param_spec_object ("icon",
596 P_("Icon for this window"),
598 GTK_PARAM_READWRITE));
599 g_object_class_install_property (gobject_class,
600 PROP_MNEMONICS_VISIBLE,
601 g_param_spec_boolean ("mnemonics-visible",
602 P_("Mnemonics Visible"),
603 P_("Whether mnemonics are currently visible in this window"),
605 GTK_PARAM_READWRITE));
608 * GtkWindow:icon-name:
610 * The :icon-name property specifies the name of the themed icon to
611 * use as the window icon. See #GtkIconTheme for more details.
615 g_object_class_install_property (gobject_class,
617 g_param_spec_string ("icon-name",
619 P_("Name of the themed icon for this window"),
621 GTK_PARAM_READWRITE));
623 g_object_class_install_property (gobject_class,
625 g_param_spec_object ("screen",
627 P_("The screen where this window will be displayed"),
629 GTK_PARAM_READWRITE));
631 g_object_class_install_property (gobject_class,
633 g_param_spec_boolean ("is-active",
635 P_("Whether the toplevel is the current active window"),
637 GTK_PARAM_READABLE));
639 g_object_class_install_property (gobject_class,
640 PROP_HAS_TOPLEVEL_FOCUS,
641 g_param_spec_boolean ("has-toplevel-focus",
642 P_("Focus in Toplevel"),
643 P_("Whether the input focus is within this GtkWindow"),
645 GTK_PARAM_READABLE));
647 g_object_class_install_property (gobject_class,
649 g_param_spec_enum ("type-hint",
651 P_("Hint to help the desktop environment understand what kind of window this is and how to treat it."),
652 GDK_TYPE_WINDOW_TYPE_HINT,
653 GDK_WINDOW_TYPE_HINT_NORMAL,
654 GTK_PARAM_READWRITE));
656 g_object_class_install_property (gobject_class,
657 PROP_SKIP_TASKBAR_HINT,
658 g_param_spec_boolean ("skip-taskbar-hint",
660 P_("TRUE if the window should not be in the task bar."),
662 GTK_PARAM_READWRITE));
664 g_object_class_install_property (gobject_class,
665 PROP_SKIP_PAGER_HINT,
666 g_param_spec_boolean ("skip-pager-hint",
668 P_("TRUE if the window should not be in the pager."),
670 GTK_PARAM_READWRITE));
672 g_object_class_install_property (gobject_class,
674 g_param_spec_boolean ("urgency-hint",
676 P_("TRUE if the window should be brought to the user's attention."),
678 GTK_PARAM_READWRITE));
681 * GtkWindow:accept-focus:
683 * Whether the window should receive the input focus.
687 g_object_class_install_property (gobject_class,
689 g_param_spec_boolean ("accept-focus",
691 P_("TRUE if the window should receive the input focus."),
693 GTK_PARAM_READWRITE));
696 * GtkWindow:focus-on-map:
698 * Whether the window should receive the input focus when mapped.
702 g_object_class_install_property (gobject_class,
704 g_param_spec_boolean ("focus-on-map",
706 P_("TRUE if the window should receive the input focus when mapped."),
708 GTK_PARAM_READWRITE));
711 * GtkWindow:decorated:
713 * Whether the window should be decorated by the window manager.
717 g_object_class_install_property (gobject_class,
719 g_param_spec_boolean ("decorated",
721 P_("Whether the window should be decorated by the window manager"),
723 GTK_PARAM_READWRITE));
726 * GtkWindow:deletable:
728 * Whether the window frame should have a close button.
732 g_object_class_install_property (gobject_class,
734 g_param_spec_boolean ("deletable",
736 P_("Whether the window frame should have a close button"),
738 GTK_PARAM_READWRITE));
744 * The window gravity of the window. See gtk_window_move() and #GdkGravity for
745 * more details about window gravity.
749 g_object_class_install_property (gobject_class,
751 g_param_spec_enum ("gravity",
753 P_("The window gravity of the window"),
755 GDK_GRAVITY_NORTH_WEST,
756 GTK_PARAM_READWRITE));
760 * GtkWindow:transient-for:
762 * The transient parent of the window. See gtk_window_set_transient_for() for
763 * more details about transient windows.
767 g_object_class_install_property (gobject_class,
769 g_param_spec_object ("transient-for",
770 P_("Transient for Window"),
771 P_("The transient parent of the dialog"),
773 GTK_PARAM_READWRITE| G_PARAM_CONSTRUCT));
778 * The requested opacity of the window. See gtk_window_set_opacity() for
779 * more details about window opacity.
783 g_object_class_install_property (gobject_class,
785 g_param_spec_double ("opacity",
786 P_("Opacity for Window"),
787 P_("The opacity of the window, from 0 to 1"),
791 GTK_PARAM_READWRITE));
793 window_signals[SET_FOCUS] =
794 g_signal_new (I_("set-focus"),
795 G_TYPE_FROM_CLASS (gobject_class),
797 G_STRUCT_OFFSET (GtkWindowClass, set_focus),
799 _gtk_marshal_VOID__OBJECT,
803 window_signals[FRAME_EVENT] =
804 g_signal_new (I_("frame-event"),
805 G_TYPE_FROM_CLASS (gobject_class),
807 G_STRUCT_OFFSET(GtkWindowClass, frame_event),
808 _gtk_boolean_handled_accumulator, NULL,
809 _gtk_marshal_BOOLEAN__BOXED,
814 * GtkWindow::activate-focus:
815 * @window: the window which received the signal
817 * The ::activate-default signal is a
818 * <link linkend="keybinding-signals">keybinding signal</link>
819 * which gets emitted when the user activates the currently
820 * focused widget of @window.
822 window_signals[ACTIVATE_FOCUS] =
823 g_signal_new (I_("activate-focus"),
824 G_TYPE_FROM_CLASS (gobject_class),
825 G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
826 G_STRUCT_OFFSET (GtkWindowClass, activate_focus),
828 _gtk_marshal_VOID__VOID,
833 * GtkWindow::activate-default:
834 * @window: the window which received the signal
836 * The ::activate-default signal is a
837 * <link linkend="keybinding-signals">keybinding signal</link>
838 * which gets emitted when the user activates the default widget
841 window_signals[ACTIVATE_DEFAULT] =
842 g_signal_new (I_("activate-default"),
843 G_TYPE_FROM_CLASS (gobject_class),
844 G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
845 G_STRUCT_OFFSET (GtkWindowClass, activate_default),
847 _gtk_marshal_VOID__VOID,
852 * GtkWindow::keys-changed:
853 * @window: the window which received the signal
855 * The ::keys-changed signal gets emitted when the set of accelerators
856 * or mnemonics that are associated with @window changes.
858 window_signals[KEYS_CHANGED] =
859 g_signal_new (I_("keys-changed"),
860 G_TYPE_FROM_CLASS (gobject_class),
862 G_STRUCT_OFFSET (GtkWindowClass, keys_changed),
864 _gtk_marshal_VOID__VOID,
872 binding_set = gtk_binding_set_by_class (klass);
874 gtk_binding_entry_add_signal (binding_set, GDK_space, 0,
875 "activate-focus", 0);
876 gtk_binding_entry_add_signal (binding_set, GDK_KP_Space, 0,
877 "activate-focus", 0);
879 gtk_binding_entry_add_signal (binding_set, GDK_Return, 0,
880 "activate-default", 0);
881 gtk_binding_entry_add_signal (binding_set, GDK_ISO_Enter, 0,
882 "activate-default", 0);
883 gtk_binding_entry_add_signal (binding_set, GDK_KP_Enter, 0,
884 "activate-default", 0);
886 add_arrow_bindings (binding_set, GDK_Up, GTK_DIR_UP);
887 add_arrow_bindings (binding_set, GDK_Down, GTK_DIR_DOWN);
888 add_arrow_bindings (binding_set, GDK_Left, GTK_DIR_LEFT);
889 add_arrow_bindings (binding_set, GDK_Right, GTK_DIR_RIGHT);
891 add_tab_bindings (binding_set, 0, GTK_DIR_TAB_FORWARD);
892 add_tab_bindings (binding_set, GDK_CONTROL_MASK, GTK_DIR_TAB_FORWARD);
893 add_tab_bindings (binding_set, GDK_SHIFT_MASK, GTK_DIR_TAB_BACKWARD);
894 add_tab_bindings (binding_set, GDK_CONTROL_MASK | GDK_SHIFT_MASK, GTK_DIR_TAB_BACKWARD);
898 gtk_window_init (GtkWindow *window)
900 GdkColormap *colormap;
901 GtkWindowPrivate *priv = GTK_WINDOW_GET_PRIVATE (window);
903 GTK_WIDGET_UNSET_FLAGS (window, GTK_NO_WINDOW);
904 GTK_WIDGET_SET_FLAGS (window, GTK_TOPLEVEL);
906 GTK_PRIVATE_SET_FLAG (window, GTK_ANCHORED);
908 gtk_container_set_resize_mode (GTK_CONTAINER (window), GTK_RESIZE_QUEUE);
910 window->title = NULL;
911 window->wmclass_name = g_strdup (g_get_prgname ());
912 window->wmclass_class = g_strdup (gdk_get_program_class ());
913 window->wm_role = NULL;
914 window->geometry_info = NULL;
915 window->type = GTK_WINDOW_TOPLEVEL;
916 window->focus_widget = NULL;
917 window->default_widget = NULL;
918 window->configure_request_count = 0;
919 window->allow_shrink = FALSE;
920 window->allow_grow = TRUE;
921 window->configure_notify_received = FALSE;
922 window->position = GTK_WIN_POS_NONE;
923 window->need_default_size = TRUE;
924 window->need_default_position = TRUE;
925 window->modal = FALSE;
926 window->frame = NULL;
927 window->has_frame = FALSE;
928 window->frame_left = 0;
929 window->frame_right = 0;
930 window->frame_top = 0;
931 window->frame_bottom = 0;
932 window->type_hint = GDK_WINDOW_TYPE_HINT_NORMAL;
933 window->gravity = GDK_GRAVITY_NORTH_WEST;
934 window->decorated = TRUE;
935 window->mnemonic_modifier = GDK_MOD1_MASK;
936 window->screen = gdk_screen_get_default ();
938 priv->accept_focus = TRUE;
939 priv->focus_on_map = TRUE;
940 priv->deletable = TRUE;
941 priv->type_hint = GDK_WINDOW_TYPE_HINT_NORMAL;
943 priv->startup_id = NULL;
944 priv->mnemonics_visible = TRUE;
946 colormap = _gtk_widget_peek_colormap ();
948 gtk_widget_set_colormap (GTK_WIDGET (window), colormap);
950 g_object_ref_sink (window);
951 window->has_user_ref_count = TRUE;
952 toplevel_list = g_slist_prepend (toplevel_list, window);
954 gtk_decorated_window_init (window);
956 g_signal_connect (window->screen, "composited-changed",
957 G_CALLBACK (gtk_window_on_composited_changed), window);
961 gtk_window_set_property (GObject *object,
967 GtkWindowPrivate *priv;
969 window = GTK_WINDOW (object);
971 priv = GTK_WINDOW_GET_PRIVATE (window);
976 window->type = g_value_get_enum (value);
979 gtk_window_set_title (window, g_value_get_string (value));
982 gtk_window_set_role (window, g_value_get_string (value));
984 case PROP_STARTUP_ID:
985 gtk_window_set_startup_id (window, g_value_get_string (value));
987 case PROP_ALLOW_SHRINK:
988 window->allow_shrink = g_value_get_boolean (value);
989 gtk_widget_queue_resize (GTK_WIDGET (window));
991 case PROP_ALLOW_GROW:
992 window->allow_grow = g_value_get_boolean (value);
993 gtk_widget_queue_resize (GTK_WIDGET (window));
994 g_object_notify (G_OBJECT (window), "resizable");
997 window->allow_grow = g_value_get_boolean (value);
998 gtk_widget_queue_resize (GTK_WIDGET (window));
999 g_object_notify (G_OBJECT (window), "allow-grow");
1002 gtk_window_set_modal (window, g_value_get_boolean (value));
1005 gtk_window_set_position (window, g_value_get_enum (value));
1007 case PROP_DEFAULT_WIDTH:
1008 gtk_window_set_default_size_internal (window,
1009 TRUE, g_value_get_int (value),
1012 case PROP_DEFAULT_HEIGHT:
1013 gtk_window_set_default_size_internal (window,
1015 TRUE, g_value_get_int (value), FALSE);
1017 case PROP_DESTROY_WITH_PARENT:
1018 gtk_window_set_destroy_with_parent (window, g_value_get_boolean (value));
1021 gtk_window_set_icon (window,
1022 g_value_get_object (value));
1024 case PROP_ICON_NAME:
1025 gtk_window_set_icon_name (window, g_value_get_string (value));
1028 gtk_window_set_screen (window, g_value_get_object (value));
1030 case PROP_TYPE_HINT:
1031 gtk_window_set_type_hint (window,
1032 g_value_get_enum (value));
1034 case PROP_SKIP_TASKBAR_HINT:
1035 gtk_window_set_skip_taskbar_hint (window,
1036 g_value_get_boolean (value));
1038 case PROP_SKIP_PAGER_HINT:
1039 gtk_window_set_skip_pager_hint (window,
1040 g_value_get_boolean (value));
1042 case PROP_URGENCY_HINT:
1043 gtk_window_set_urgency_hint (window,
1044 g_value_get_boolean (value));
1046 case PROP_ACCEPT_FOCUS:
1047 gtk_window_set_accept_focus (window,
1048 g_value_get_boolean (value));
1050 case PROP_FOCUS_ON_MAP:
1051 gtk_window_set_focus_on_map (window,
1052 g_value_get_boolean (value));
1054 case PROP_DECORATED:
1055 gtk_window_set_decorated (window, g_value_get_boolean (value));
1057 case PROP_DELETABLE:
1058 gtk_window_set_deletable (window, g_value_get_boolean (value));
1061 gtk_window_set_gravity (window, g_value_get_enum (value));
1063 case PROP_TRANSIENT_FOR:
1064 gtk_window_set_transient_for (window, g_value_get_object (value));
1067 gtk_window_set_opacity (window, g_value_get_double (value));
1069 case PROP_MNEMONICS_VISIBLE:
1070 gtk_window_set_mnemonics_visible (window, g_value_get_boolean (value));
1073 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1079 gtk_window_get_property (GObject *object,
1085 GtkWindowPrivate *priv;
1087 window = GTK_WINDOW (object);
1088 priv = GTK_WINDOW_GET_PRIVATE (window);
1092 GtkWindowGeometryInfo *info;
1094 g_value_set_enum (value, window->type);
1097 g_value_set_string (value, window->wm_role);
1100 g_value_set_string (value, window->title);
1102 case PROP_ALLOW_SHRINK:
1103 g_value_set_boolean (value, window->allow_shrink);
1105 case PROP_ALLOW_GROW:
1106 g_value_set_boolean (value, window->allow_grow);
1108 case PROP_RESIZABLE:
1109 g_value_set_boolean (value, window->allow_grow);
1112 g_value_set_boolean (value, window->modal);
1115 g_value_set_enum (value, window->position);
1117 case PROP_DEFAULT_WIDTH:
1118 info = gtk_window_get_geometry_info (window, FALSE);
1120 g_value_set_int (value, -1);
1122 g_value_set_int (value, info->default_width);
1124 case PROP_DEFAULT_HEIGHT:
1125 info = gtk_window_get_geometry_info (window, FALSE);
1127 g_value_set_int (value, -1);
1129 g_value_set_int (value, info->default_height);
1131 case PROP_DESTROY_WITH_PARENT:
1132 g_value_set_boolean (value, window->destroy_with_parent);
1135 g_value_set_object (value, gtk_window_get_icon (window));
1137 case PROP_ICON_NAME:
1138 g_value_set_string (value, gtk_window_get_icon_name (window));
1141 g_value_set_object (value, window->screen);
1143 case PROP_IS_ACTIVE:
1144 g_value_set_boolean (value, window->is_active);
1146 case PROP_HAS_TOPLEVEL_FOCUS:
1147 g_value_set_boolean (value, window->has_toplevel_focus);
1149 case PROP_TYPE_HINT:
1150 g_value_set_enum (value, priv->type_hint);
1152 case PROP_SKIP_TASKBAR_HINT:
1153 g_value_set_boolean (value,
1154 gtk_window_get_skip_taskbar_hint (window));
1156 case PROP_SKIP_PAGER_HINT:
1157 g_value_set_boolean (value,
1158 gtk_window_get_skip_pager_hint (window));
1160 case PROP_URGENCY_HINT:
1161 g_value_set_boolean (value,
1162 gtk_window_get_urgency_hint (window));
1164 case PROP_ACCEPT_FOCUS:
1165 g_value_set_boolean (value,
1166 gtk_window_get_accept_focus (window));
1168 case PROP_FOCUS_ON_MAP:
1169 g_value_set_boolean (value,
1170 gtk_window_get_focus_on_map (window));
1172 case PROP_DECORATED:
1173 g_value_set_boolean (value, gtk_window_get_decorated (window));
1175 case PROP_DELETABLE:
1176 g_value_set_boolean (value, gtk_window_get_deletable (window));
1179 g_value_set_enum (value, gtk_window_get_gravity (window));
1181 case PROP_TRANSIENT_FOR:
1182 g_value_set_object (value, gtk_window_get_transient_for (window));
1185 g_value_set_double (value, gtk_window_get_opacity (window));
1187 case PROP_MNEMONICS_VISIBLE:
1188 g_value_set_boolean (value, priv->mnemonics_visible);
1191 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1197 gtk_window_buildable_interface_init (GtkBuildableIface *iface)
1199 parent_buildable_iface = g_type_interface_peek_parent (iface);
1200 iface->set_buildable_property = gtk_window_buildable_set_buildable_property;
1201 iface->parser_finished = gtk_window_buildable_parser_finished;
1202 iface->custom_tag_start = gtk_window_buildable_custom_tag_start;
1203 iface->custom_finished = gtk_window_buildable_custom_finished;
1207 gtk_window_buildable_set_buildable_property (GtkBuildable *buildable,
1208 GtkBuilder *builder,
1210 const GValue *value)
1212 GtkWindowPrivate *priv = GTK_WINDOW_GET_PRIVATE (buildable);
1214 if (strcmp (name, "visible") == 0 && g_value_get_boolean (value))
1215 priv->builder_visible = TRUE;
1217 parent_buildable_iface->set_buildable_property (buildable, builder, name, value);
1221 gtk_window_buildable_parser_finished (GtkBuildable *buildable,
1222 GtkBuilder *builder)
1224 GtkWindowPrivate *priv = GTK_WINDOW_GET_PRIVATE (buildable);
1228 if (priv->builder_visible)
1229 gtk_widget_show (GTK_WIDGET (buildable));
1231 accels = g_object_get_qdata (G_OBJECT (buildable), quark_gtk_buildable_accels);
1232 for (l = accels; l; l = l->next)
1234 object = gtk_builder_get_object (builder, l->data);
1237 g_warning ("Unknown accel group %s specified in window %s",
1238 (const gchar*)l->data, gtk_buildable_get_name (buildable));
1241 gtk_window_add_accel_group (GTK_WINDOW (buildable),
1242 GTK_ACCEL_GROUP (object));
1246 g_object_set_qdata (G_OBJECT (buildable), quark_gtk_buildable_accels, NULL);
1248 parent_buildable_iface->parser_finished (buildable, builder);
1254 } GSListSubParserData;
1257 window_start_element (GMarkupParseContext *context,
1258 const gchar *element_name,
1259 const gchar **names,
1260 const gchar **values,
1265 GSListSubParserData *data = (GSListSubParserData*)user_data;
1267 if (strcmp (element_name, "group") == 0)
1269 for (i = 0; names[i]; i++)
1271 if (strcmp (names[i], "name") == 0)
1272 data->items = g_slist_prepend (data->items, g_strdup (values[i]));
1275 else if (strcmp (element_name, "accel-groups") == 0)
1278 g_warning ("Unsupported tag type for GtkWindow: %s\n",
1283 static const GMarkupParser window_parser =
1285 window_start_element
1289 gtk_window_buildable_custom_tag_start (GtkBuildable *buildable,
1290 GtkBuilder *builder,
1292 const gchar *tagname,
1293 GMarkupParser *parser,
1296 GSListSubParserData *parser_data;
1298 if (parent_buildable_iface->custom_tag_start (buildable, builder, child,
1299 tagname, parser, data))
1302 if (strcmp (tagname, "accel-groups") == 0)
1304 parser_data = g_slice_new0 (GSListSubParserData);
1305 parser_data->items = NULL;
1306 parser_data->object = G_OBJECT (buildable);
1308 *parser = window_parser;
1309 *data = parser_data;
1317 gtk_window_buildable_custom_finished (GtkBuildable *buildable,
1318 GtkBuilder *builder,
1320 const gchar *tagname,
1323 GSListSubParserData *data;
1325 parent_buildable_iface->custom_finished (buildable, builder, child,
1326 tagname, user_data);
1328 if (strcmp (tagname, "accel-groups") != 0)
1331 data = (GSListSubParserData*)user_data;
1333 g_object_set_qdata_full (G_OBJECT (buildable), quark_gtk_buildable_accels,
1334 data->items, (GDestroyNotify) g_slist_free);
1336 g_slice_free (GSListSubParserData, data);
1341 * @type: type of window
1343 * Creates a new #GtkWindow, which is a toplevel window that can
1344 * contain other widgets. Nearly always, the type of the window should
1345 * be #GTK_WINDOW_TOPLEVEL. If you're implementing something like a
1346 * popup menu from scratch (which is a bad idea, just use #GtkMenu),
1347 * you might use #GTK_WINDOW_POPUP. #GTK_WINDOW_POPUP is not for
1348 * dialogs, though in some other toolkits dialogs are called "popups".
1349 * In GTK+, #GTK_WINDOW_POPUP means a pop-up menu or pop-up tooltip.
1350 * On X11, popup windows are not controlled by the <link
1351 * linkend="gtk-X11-arch">window manager</link>.
1353 * If you simply want an undecorated window (no window borders), use
1354 * gtk_window_set_decorated(), don't use #GTK_WINDOW_POPUP.
1356 * Return value: a new #GtkWindow.
1359 gtk_window_new (GtkWindowType type)
1363 g_return_val_if_fail (type >= GTK_WINDOW_TOPLEVEL && type <= GTK_WINDOW_POPUP, NULL);
1365 window = g_object_new (GTK_TYPE_WINDOW, NULL);
1367 window->type = type;
1369 return GTK_WIDGET (window);
1373 * gtk_window_set_title:
1374 * @window: a #GtkWindow
1375 * @title: title of the window
1377 * Sets the title of the #GtkWindow. The title of a window will be
1378 * displayed in its title bar; on the X Window System, the title bar
1379 * is rendered by the <link linkend="gtk-X11-arch">window
1380 * manager</link>, so exactly how the title appears to users may vary
1381 * according to a user's exact configuration. The title should help a
1382 * user distinguish this window from other windows they may have
1383 * open. A good title might include the application name and current
1384 * document filename, for example.
1388 gtk_window_set_title (GtkWindow *window,
1393 g_return_if_fail (GTK_IS_WINDOW (window));
1395 new_title = g_strdup (title);
1396 g_free (window->title);
1397 window->title = new_title;
1399 if (gtk_widget_get_realized (GTK_WIDGET (window)))
1401 gdk_window_set_title (GTK_WIDGET (window)->window, window->title);
1403 gtk_decorated_window_set_title (window, title);
1406 g_object_notify (G_OBJECT (window), "title");
1410 * gtk_window_get_title:
1411 * @window: a #GtkWindow
1413 * Retrieves the title of the window. See gtk_window_set_title().
1415 * Return value: the title of the window, or %NULL if none has
1416 * been set explicitely. The returned string is owned by the widget
1417 * and must not be modified or freed.
1419 G_CONST_RETURN gchar *
1420 gtk_window_get_title (GtkWindow *window)
1422 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
1424 return window->title;
1428 * gtk_window_set_wmclass:
1429 * @window: a #GtkWindow
1430 * @wmclass_name: window name hint
1431 * @wmclass_class: window class hint
1433 * Don't use this function. It sets the X Window System "class" and
1434 * "name" hints for a window. According to the ICCCM, you should
1435 * always set these to the same value for all windows in an
1436 * application, and GTK+ sets them to that value by default, so calling
1437 * this function is sort of pointless. However, you may want to call
1438 * gtk_window_set_role() on each window in your application, for the
1439 * benefit of the session manager. Setting the role allows the window
1440 * manager to restore window positions when loading a saved session.
1444 gtk_window_set_wmclass (GtkWindow *window,
1445 const gchar *wmclass_name,
1446 const gchar *wmclass_class)
1448 g_return_if_fail (GTK_IS_WINDOW (window));
1450 g_free (window->wmclass_name);
1451 window->wmclass_name = g_strdup (wmclass_name);
1453 g_free (window->wmclass_class);
1454 window->wmclass_class = g_strdup (wmclass_class);
1456 if (gtk_widget_get_realized (GTK_WIDGET (window)))
1457 g_warning ("gtk_window_set_wmclass: shouldn't set wmclass after window is realized!\n");
1461 * gtk_window_set_role:
1462 * @window: a #GtkWindow
1463 * @role: unique identifier for the window to be used when restoring a session
1465 * This function is only useful on X11, not with other GTK+ targets.
1467 * In combination with the window title, the window role allows a
1468 * <link linkend="gtk-X11-arch">window manager</link> to identify "the
1469 * same" window when an application is restarted. So for example you
1470 * might set the "toolbox" role on your app's toolbox window, so that
1471 * when the user restarts their session, the window manager can put
1472 * the toolbox back in the same place.
1474 * If a window already has a unique title, you don't need to set the
1475 * role, since the WM can use the title to identify the window when
1476 * restoring the session.
1480 gtk_window_set_role (GtkWindow *window,
1485 g_return_if_fail (GTK_IS_WINDOW (window));
1487 new_role = g_strdup (role);
1488 g_free (window->wm_role);
1489 window->wm_role = new_role;
1491 if (gtk_widget_get_realized (GTK_WIDGET (window)))
1492 gdk_window_set_role (GTK_WIDGET (window)->window, window->wm_role);
1494 g_object_notify (G_OBJECT (window), "role");
1498 * gtk_window_set_startup_id:
1499 * @window: a #GtkWindow
1500 * @startup_id: a string with startup-notification identifier
1502 * Startup notification identifiers are used by desktop environment to
1503 * track application startup, to provide user feedback and other
1504 * features. This function changes the corresponding property on the
1505 * underlying GdkWindow. Normally, startup identifier is managed
1506 * automatically and you should only use this function in special cases
1507 * like transferring focus from other processes. You should use this
1508 * function before calling gtk_window_present() or any equivalent
1509 * function generating a window map event.
1511 * This function is only useful on X11, not with other GTK+ targets.
1516 gtk_window_set_startup_id (GtkWindow *window,
1517 const gchar *startup_id)
1519 GtkWindowPrivate *priv;
1521 g_return_if_fail (GTK_IS_WINDOW (window));
1523 priv = GTK_WINDOW_GET_PRIVATE (window);
1525 g_free (priv->startup_id);
1526 priv->startup_id = g_strdup (startup_id);
1528 if (gtk_widget_get_realized (GTK_WIDGET (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_get_mapped (GTK_WIDGET (window)) &&
1549 !disable_startup_notification)
1550 gdk_notify_startup_complete_with_id (priv->startup_id);
1554 g_object_notify (G_OBJECT (window), "startup-id");
1558 * gtk_window_get_role:
1559 * @window: a #GtkWindow
1561 * Returns the role of the window. See gtk_window_set_role() for
1562 * further explanation.
1564 * Return value: the role of the window if set, or %NULL. The
1565 * returned is owned by the widget and must not be modified
1568 G_CONST_RETURN gchar *
1569 gtk_window_get_role (GtkWindow *window)
1571 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
1573 return window->wm_role;
1577 * gtk_window_set_focus:
1578 * @window: a #GtkWindow
1579 * @focus: (allow-none): widget to be the new focus widget, or %NULL to unset
1580 * any focus widget for the toplevel window.
1582 * If @focus is not the current focus widget, and is focusable, sets
1583 * it as the focus widget for the window. If @focus is %NULL, unsets
1584 * the focus widget for this window. To set the focus to a particular
1585 * widget in the toplevel, it is usually more convenient to use
1586 * gtk_widget_grab_focus() instead of this function.
1589 gtk_window_set_focus (GtkWindow *window,
1592 g_return_if_fail (GTK_IS_WINDOW (window));
1595 g_return_if_fail (GTK_IS_WIDGET (focus));
1596 g_return_if_fail (gtk_widget_get_can_focus (focus));
1600 gtk_widget_grab_focus (focus);
1603 /* Clear the existing focus chain, so that when we focus into
1604 * the window again, we start at the beginnning.
1606 GtkWidget *widget = window->focus_widget;
1609 while (widget->parent)
1611 widget = widget->parent;
1612 gtk_container_set_focus_child (GTK_CONTAINER (widget), NULL);
1616 _gtk_window_internal_set_focus (window, NULL);
1621 _gtk_window_internal_set_focus (GtkWindow *window,
1624 g_return_if_fail (GTK_IS_WINDOW (window));
1626 if ((window->focus_widget != focus) ||
1627 (focus && !gtk_widget_has_focus (focus)))
1628 g_signal_emit (window, window_signals[SET_FOCUS], 0, focus);
1632 * gtk_window_set_default:
1633 * @window: a #GtkWindow
1634 * @default_widget: (allow-none): widget to be the default, or %NULL to unset the
1635 * default widget for the toplevel.
1637 * The default widget is the widget that's activated when the user
1638 * presses Enter in a dialog (for example). This function sets or
1639 * unsets the default widget for a #GtkWindow about. When setting
1640 * (rather than unsetting) the default widget it's generally easier to
1641 * call gtk_widget_grab_focus() on the widget. Before making a widget
1642 * the default widget, you must set the #GTK_CAN_DEFAULT flag on the
1643 * widget you'd like to make the default using GTK_WIDGET_SET_FLAGS().
1646 gtk_window_set_default (GtkWindow *window,
1647 GtkWidget *default_widget)
1649 g_return_if_fail (GTK_IS_WINDOW (window));
1652 g_return_if_fail (gtk_widget_get_can_default (default_widget));
1654 if (window->default_widget != default_widget)
1656 GtkWidget *old_default_widget = NULL;
1659 g_object_ref (default_widget);
1661 if (window->default_widget)
1663 old_default_widget = window->default_widget;
1665 if (window->focus_widget != window->default_widget ||
1666 !gtk_widget_get_receives_default (window->default_widget))
1667 GTK_WIDGET_UNSET_FLAGS (window->default_widget, GTK_HAS_DEFAULT);
1668 gtk_widget_queue_draw (window->default_widget);
1671 window->default_widget = default_widget;
1673 if (window->default_widget)
1675 if (window->focus_widget == NULL ||
1676 !gtk_widget_get_receives_default (window->focus_widget))
1677 GTK_WIDGET_SET_FLAGS (window->default_widget, GTK_HAS_DEFAULT);
1678 gtk_widget_queue_draw (window->default_widget);
1681 if (old_default_widget)
1682 g_object_notify (G_OBJECT (old_default_widget), "has-default");
1686 g_object_notify (G_OBJECT (default_widget), "has-default");
1687 g_object_unref (default_widget);
1693 * gtk_window_get_default_widget:
1694 * @window: a #GtkWindow
1696 * Returns the default widget for @window. See gtk_window_set_default()
1699 * Returns: the default widget, or %NULL if there is none.
1704 gtk_window_get_default_widget (GtkWindow *window)
1706 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
1708 return window->default_widget;
1712 gtk_window_set_policy_internal (GtkWindow *window,
1713 gboolean allow_shrink,
1714 gboolean allow_grow,
1715 gboolean auto_shrink)
1717 window->allow_shrink = (allow_shrink != FALSE);
1718 window->allow_grow = (allow_grow != FALSE);
1720 g_object_freeze_notify (G_OBJECT (window));
1721 g_object_notify (G_OBJECT (window), "allow-shrink");
1722 g_object_notify (G_OBJECT (window), "allow-grow");
1723 g_object_notify (G_OBJECT (window), "resizable");
1724 g_object_thaw_notify (G_OBJECT (window));
1726 gtk_widget_queue_resize_no_redraw (GTK_WIDGET (window));
1730 gtk_window_set_policy (GtkWindow *window,
1731 gboolean allow_shrink,
1732 gboolean allow_grow,
1733 gboolean auto_shrink)
1735 g_return_if_fail (GTK_IS_WINDOW (window));
1737 gtk_window_set_policy_internal (window, allow_shrink, allow_grow, auto_shrink);
1741 handle_keys_changed (gpointer data)
1745 window = GTK_WINDOW (data);
1747 if (window->keys_changed_handler)
1749 g_source_remove (window->keys_changed_handler);
1750 window->keys_changed_handler = 0;
1753 g_signal_emit (window, window_signals[KEYS_CHANGED], 0);
1759 gtk_window_notify_keys_changed (GtkWindow *window)
1761 if (!window->keys_changed_handler)
1762 window->keys_changed_handler = gdk_threads_add_idle (handle_keys_changed, window);
1766 * gtk_window_add_accel_group:
1767 * @window: window to attach accelerator group to
1768 * @accel_group: a #GtkAccelGroup
1770 * Associate @accel_group with @window, such that calling
1771 * gtk_accel_groups_activate() on @window will activate accelerators
1775 gtk_window_add_accel_group (GtkWindow *window,
1776 GtkAccelGroup *accel_group)
1778 g_return_if_fail (GTK_IS_WINDOW (window));
1779 g_return_if_fail (GTK_IS_ACCEL_GROUP (accel_group));
1781 _gtk_accel_group_attach (accel_group, G_OBJECT (window));
1782 g_signal_connect_object (accel_group, "accel-changed",
1783 G_CALLBACK (gtk_window_notify_keys_changed),
1784 window, G_CONNECT_SWAPPED);
1785 gtk_window_notify_keys_changed (window);
1789 * gtk_window_remove_accel_group:
1790 * @window: a #GtkWindow
1791 * @accel_group: a #GtkAccelGroup
1793 * Reverses the effects of gtk_window_add_accel_group().
1796 gtk_window_remove_accel_group (GtkWindow *window,
1797 GtkAccelGroup *accel_group)
1799 g_return_if_fail (GTK_IS_WINDOW (window));
1800 g_return_if_fail (GTK_IS_ACCEL_GROUP (accel_group));
1802 g_signal_handlers_disconnect_by_func (accel_group,
1803 gtk_window_notify_keys_changed,
1805 _gtk_accel_group_detach (accel_group, G_OBJECT (window));
1806 gtk_window_notify_keys_changed (window);
1809 static GtkMnemonicHash *
1810 gtk_window_get_mnemonic_hash (GtkWindow *window,
1813 GtkWindowPrivate *private = GTK_WINDOW_GET_PRIVATE (window);
1814 if (!private->mnemonic_hash && create)
1815 private->mnemonic_hash = _gtk_mnemonic_hash_new ();
1817 return private->mnemonic_hash;
1821 * gtk_window_add_mnemonic:
1822 * @window: a #GtkWindow
1823 * @keyval: the mnemonic
1824 * @target: the widget that gets activated by the mnemonic
1826 * Adds a mnemonic to this window.
1829 gtk_window_add_mnemonic (GtkWindow *window,
1833 g_return_if_fail (GTK_IS_WINDOW (window));
1834 g_return_if_fail (GTK_IS_WIDGET (target));
1836 _gtk_mnemonic_hash_add (gtk_window_get_mnemonic_hash (window, TRUE),
1838 gtk_window_notify_keys_changed (window);
1842 * gtk_window_remove_mnemonic:
1843 * @window: a #GtkWindow
1844 * @keyval: the mnemonic
1845 * @target: the widget that gets activated by the mnemonic
1847 * Removes a mnemonic from this window.
1850 gtk_window_remove_mnemonic (GtkWindow *window,
1854 g_return_if_fail (GTK_IS_WINDOW (window));
1855 g_return_if_fail (GTK_IS_WIDGET (target));
1857 _gtk_mnemonic_hash_remove (gtk_window_get_mnemonic_hash (window, TRUE),
1859 gtk_window_notify_keys_changed (window);
1863 * gtk_window_mnemonic_activate:
1864 * @window: a #GtkWindow
1865 * @keyval: the mnemonic
1866 * @modifier: the modifiers
1867 * @returns: %TRUE if the activation is done.
1869 * Activates the targets associated with the mnemonic.
1872 gtk_window_mnemonic_activate (GtkWindow *window,
1874 GdkModifierType modifier)
1876 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
1878 if (window->mnemonic_modifier == (modifier & gtk_accelerator_get_default_mod_mask ()))
1880 GtkMnemonicHash *mnemonic_hash = gtk_window_get_mnemonic_hash (window, FALSE);
1882 return _gtk_mnemonic_hash_activate (mnemonic_hash, keyval);
1889 * gtk_window_set_mnemonic_modifier:
1890 * @window: a #GtkWindow
1891 * @modifier: the modifier mask used to activate
1892 * mnemonics on this window.
1894 * Sets the mnemonic modifier for this window.
1897 gtk_window_set_mnemonic_modifier (GtkWindow *window,
1898 GdkModifierType modifier)
1900 g_return_if_fail (GTK_IS_WINDOW (window));
1901 g_return_if_fail ((modifier & ~GDK_MODIFIER_MASK) == 0);
1903 window->mnemonic_modifier = modifier;
1904 gtk_window_notify_keys_changed (window);
1908 * gtk_window_get_mnemonic_modifier:
1909 * @window: a #GtkWindow
1911 * Returns the mnemonic modifier for this window. See
1912 * gtk_window_set_mnemonic_modifier().
1914 * Return value: the modifier mask used to activate
1915 * mnemonics on this window.
1918 gtk_window_get_mnemonic_modifier (GtkWindow *window)
1920 g_return_val_if_fail (GTK_IS_WINDOW (window), 0);
1922 return window->mnemonic_modifier;
1926 * gtk_window_set_position:
1927 * @window: a #GtkWindow.
1928 * @position: a position constraint.
1930 * Sets a position constraint for this window. If the old or new
1931 * constraint is %GTK_WIN_POS_CENTER_ALWAYS, this will also cause
1932 * the window to be repositioned to satisfy the new constraint.
1935 gtk_window_set_position (GtkWindow *window,
1936 GtkWindowPosition position)
1938 g_return_if_fail (GTK_IS_WINDOW (window));
1940 if (position == GTK_WIN_POS_CENTER_ALWAYS ||
1941 window->position == GTK_WIN_POS_CENTER_ALWAYS)
1943 GtkWindowGeometryInfo *info;
1945 info = gtk_window_get_geometry_info (window, TRUE);
1947 /* this flag causes us to re-request the CENTER_ALWAYS
1948 * constraint in gtk_window_move_resize(), see
1949 * comment in that function.
1951 info->position_constraints_changed = TRUE;
1953 gtk_widget_queue_resize_no_redraw (GTK_WIDGET (window));
1956 window->position = position;
1958 g_object_notify (G_OBJECT (window), "window-position");
1962 * gtk_window_activate_focus:
1963 * @window: a #GtkWindow
1965 * Activates the current focused widget within the window.
1967 * Return value: %TRUE if a widget got activated.
1970 gtk_window_activate_focus (GtkWindow *window)
1972 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
1974 if (window->focus_widget && gtk_widget_is_sensitive (window->focus_widget))
1975 return gtk_widget_activate (window->focus_widget);
1981 * gtk_window_get_focus:
1982 * @window: a #GtkWindow
1984 * Retrieves the current focused widget within the window.
1985 * Note that this is the widget that would have the focus
1986 * if the toplevel window focused; if the toplevel window
1987 * is not focused then <literal>gtk_widget_has_focus (widget)</literal> will
1988 * not be %TRUE for the widget.
1990 * Return value: (transfer none): the currently focused widget, or %NULL if there is none.
1993 gtk_window_get_focus (GtkWindow *window)
1995 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
1997 return window->focus_widget;
2001 * gtk_window_activate_default:
2002 * @window: a #GtkWindow
2004 * Activates the default widget for the window, unless the current
2005 * focused widget has been configured to receive the default action
2006 * (see gtk_widget_set_receives_default()), in which case the
2007 * focused widget is activated.
2009 * Return value: %TRUE if a widget got activated.
2012 gtk_window_activate_default (GtkWindow *window)
2014 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
2016 if (window->default_widget && gtk_widget_is_sensitive (window->default_widget) &&
2017 (!window->focus_widget || !gtk_widget_get_receives_default (window->focus_widget)))
2018 return gtk_widget_activate (window->default_widget);
2019 else if (window->focus_widget && gtk_widget_is_sensitive (window->focus_widget))
2020 return gtk_widget_activate (window->focus_widget);
2026 * gtk_window_set_modal:
2027 * @window: a #GtkWindow
2028 * @modal: whether the window is modal
2030 * Sets a window modal or non-modal. Modal windows prevent interaction
2031 * with other windows in the same application. To keep modal dialogs
2032 * on top of main application windows, use
2033 * gtk_window_set_transient_for() to make the dialog transient for the
2034 * parent; most <link linkend="gtk-X11-arch">window managers</link>
2035 * will then disallow lowering the dialog below the parent.
2040 gtk_window_set_modal (GtkWindow *window,
2045 g_return_if_fail (GTK_IS_WINDOW (window));
2047 modal = modal != FALSE;
2048 if (window->modal == modal)
2051 window->modal = modal;
2052 widget = GTK_WIDGET (window);
2054 /* adjust desired modality state */
2055 if (gtk_widget_get_realized (widget))
2058 gdk_window_set_modal_hint (widget->window, TRUE);
2060 gdk_window_set_modal_hint (widget->window, FALSE);
2063 if (gtk_widget_get_visible (widget))
2066 gtk_grab_add (widget);
2068 gtk_grab_remove (widget);
2071 g_object_notify (G_OBJECT (window), "modal");
2075 * gtk_window_get_modal:
2076 * @window: a #GtkWindow
2078 * Returns whether the window is modal. See gtk_window_set_modal().
2080 * Return value: %TRUE if the window is set to be modal and
2081 * establishes a grab when shown
2084 gtk_window_get_modal (GtkWindow *window)
2086 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
2088 return window->modal;
2092 * gtk_window_list_toplevels:
2094 * Returns a list of all existing toplevel windows. The widgets
2095 * in the list are not individually referenced. If you want
2096 * to iterate through the list and perform actions involving
2097 * callbacks that might destroy the widgets, you <emphasis>must</emphasis> call
2098 * <literal>g_list_foreach (result, (GFunc)g_object_ref, NULL)</literal> first, and
2099 * then unref all the widgets afterwards.
2101 * Return value: (element-type GtkWidget) (transfer container): list of toplevel widgets
2104 gtk_window_list_toplevels (void)
2109 for (slist = toplevel_list; slist; slist = slist->next)
2110 list = g_list_prepend (list, slist->data);
2116 gtk_window_add_embedded_xid (GtkWindow *window, GdkNativeWindow xid)
2118 GList *embedded_windows;
2120 g_return_if_fail (GTK_IS_WINDOW (window));
2122 embedded_windows = g_object_get_qdata (G_OBJECT (window), quark_gtk_embedded);
2123 if (embedded_windows)
2124 g_object_steal_qdata (G_OBJECT (window), quark_gtk_embedded);
2125 embedded_windows = g_list_prepend (embedded_windows,
2126 GUINT_TO_POINTER (xid));
2128 g_object_set_qdata_full (G_OBJECT (window), quark_gtk_embedded,
2131 (GDestroyNotify) g_list_free : NULL);
2135 gtk_window_remove_embedded_xid (GtkWindow *window, GdkNativeWindow xid)
2137 GList *embedded_windows;
2140 g_return_if_fail (GTK_IS_WINDOW (window));
2142 embedded_windows = g_object_get_qdata (G_OBJECT (window), quark_gtk_embedded);
2143 if (embedded_windows)
2144 g_object_steal_qdata (G_OBJECT (window), quark_gtk_embedded);
2146 node = g_list_find (embedded_windows, GUINT_TO_POINTER (xid));
2149 embedded_windows = g_list_remove_link (embedded_windows, node);
2150 g_list_free_1 (node);
2153 g_object_set_qdata_full (G_OBJECT (window), quark_gtk_embedded,
2156 (GDestroyNotify) g_list_free : NULL);
2160 _gtk_window_reposition (GtkWindow *window,
2164 g_return_if_fail (GTK_IS_WINDOW (window));
2166 gtk_window_move (window, x, y);
2170 gtk_window_dispose (GObject *object)
2172 GtkWindow *window = GTK_WINDOW (object);
2174 gtk_window_set_focus (window, NULL);
2175 gtk_window_set_default (window, NULL);
2177 G_OBJECT_CLASS (gtk_window_parent_class)->dispose (object);
2181 parent_destroyed_callback (GtkWindow *parent, GtkWindow *child)
2183 gtk_widget_destroy (GTK_WIDGET (child));
2187 connect_parent_destroyed (GtkWindow *window)
2189 if (window->transient_parent)
2191 g_signal_connect (window->transient_parent,
2193 G_CALLBACK (parent_destroyed_callback),
2199 disconnect_parent_destroyed (GtkWindow *window)
2201 if (window->transient_parent)
2203 g_signal_handlers_disconnect_by_func (window->transient_parent,
2204 parent_destroyed_callback,
2210 gtk_window_transient_parent_realized (GtkWidget *parent,
2213 if (gtk_widget_get_realized (GTK_WIDGET (window)))
2214 gdk_window_set_transient_for (window->window, parent->window);
2218 gtk_window_transient_parent_unrealized (GtkWidget *parent,
2221 if (gtk_widget_get_realized (GTK_WIDGET (window)))
2222 gdk_property_delete (window->window,
2223 gdk_atom_intern_static_string ("WM_TRANSIENT_FOR"));
2227 gtk_window_transient_parent_screen_changed (GtkWindow *parent,
2231 gtk_window_set_screen (window, parent->screen);
2235 gtk_window_unset_transient_for (GtkWindow *window)
2237 GtkWindowPrivate *priv = GTK_WINDOW_GET_PRIVATE (window);
2239 if (window->transient_parent)
2241 g_signal_handlers_disconnect_by_func (window->transient_parent,
2242 gtk_window_transient_parent_realized,
2244 g_signal_handlers_disconnect_by_func (window->transient_parent,
2245 gtk_window_transient_parent_unrealized,
2247 g_signal_handlers_disconnect_by_func (window->transient_parent,
2248 gtk_window_transient_parent_screen_changed,
2250 g_signal_handlers_disconnect_by_func (window->transient_parent,
2251 gtk_widget_destroyed,
2252 &window->transient_parent);
2254 if (window->destroy_with_parent)
2255 disconnect_parent_destroyed (window);
2257 window->transient_parent = NULL;
2259 if (priv->transient_parent_group)
2261 priv->transient_parent_group = FALSE;
2262 gtk_window_group_remove_window (window->group,
2269 * gtk_window_set_transient_for:
2270 * @window: a #GtkWindow
2271 * @parent: (allow-none): parent window
2273 * Dialog windows should be set transient for the main application
2274 * window they were spawned from. This allows <link
2275 * linkend="gtk-X11-arch">window managers</link> to e.g. keep the
2276 * dialog on top of the main window, or center the dialog over the
2277 * main window. gtk_dialog_new_with_buttons() and other convenience
2278 * functions in GTK+ will sometimes call
2279 * gtk_window_set_transient_for() on your behalf.
2281 * On Windows, this function puts the child window on top of the parent,
2282 * much as the window manager would have done on X.
2286 gtk_window_set_transient_for (GtkWindow *window,
2289 GtkWindowPrivate *priv;
2291 g_return_if_fail (GTK_IS_WINDOW (window));
2292 g_return_if_fail (parent == NULL || GTK_IS_WINDOW (parent));
2293 g_return_if_fail (window != parent);
2295 priv = GTK_WINDOW_GET_PRIVATE (window);
2297 if (window->transient_parent)
2299 if (gtk_widget_get_realized (GTK_WIDGET (window)) &&
2300 gtk_widget_get_realized (GTK_WIDGET (window->transient_parent)) &&
2301 (!parent || !gtk_widget_get_realized (GTK_WIDGET (parent))))
2302 gtk_window_transient_parent_unrealized (GTK_WIDGET (window->transient_parent),
2303 GTK_WIDGET (window));
2305 gtk_window_unset_transient_for (window);
2308 window->transient_parent = parent;
2312 g_signal_connect (parent, "destroy",
2313 G_CALLBACK (gtk_widget_destroyed),
2314 &window->transient_parent);
2315 g_signal_connect (parent, "realize",
2316 G_CALLBACK (gtk_window_transient_parent_realized),
2318 g_signal_connect (parent, "unrealize",
2319 G_CALLBACK (gtk_window_transient_parent_unrealized),
2321 g_signal_connect (parent, "notify::screen",
2322 G_CALLBACK (gtk_window_transient_parent_screen_changed),
2325 gtk_window_set_screen (window, parent->screen);
2327 if (window->destroy_with_parent)
2328 connect_parent_destroyed (window);
2330 if (gtk_widget_get_realized (GTK_WIDGET (window)) &&
2331 gtk_widget_get_realized (GTK_WIDGET (parent)))
2332 gtk_window_transient_parent_realized (GTK_WIDGET (parent),
2333 GTK_WIDGET (window));
2337 gtk_window_group_add_window (parent->group, window);
2338 priv->transient_parent_group = TRUE;
2344 * gtk_window_get_transient_for:
2345 * @window: a #GtkWindow
2347 * Fetches the transient parent for this window. See
2348 * gtk_window_set_transient_for().
2350 * Return value: (transfer none): the transient parent for this window, or %NULL
2351 * if no transient parent has been set.
2354 gtk_window_get_transient_for (GtkWindow *window)
2356 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
2358 return window->transient_parent;
2362 * gtk_window_set_opacity:
2363 * @window: a #GtkWindow
2364 * @opacity: desired opacity, between 0 and 1
2366 * Request the windowing system to make @window partially transparent,
2367 * with opacity 0 being fully transparent and 1 fully opaque. (Values
2368 * of the opacity parameter are clamped to the [0,1] range.) On X11
2369 * this has any effect only on X screens with a compositing manager
2370 * running. See gtk_widget_is_composited(). On Windows it should work
2373 * Note that setting a window's opacity after the window has been
2374 * shown causes it to flicker once on Windows.
2379 gtk_window_set_opacity (GtkWindow *window,
2382 GtkWindowPrivate *priv;
2384 g_return_if_fail (GTK_IS_WINDOW (window));
2386 priv = GTK_WINDOW_GET_PRIVATE (window);
2390 else if (opacity > 1.0)
2393 priv->opacity_set = TRUE;
2394 priv->opacity = opacity;
2396 if (gtk_widget_get_realized (GTK_WIDGET (window)))
2397 gdk_window_set_opacity (GTK_WIDGET (window)->window, priv->opacity);
2401 * gtk_window_get_opacity:
2402 * @window: a #GtkWindow
2404 * Fetches the requested opacity for this window. See
2405 * gtk_window_set_opacity().
2407 * Return value: the requested opacity for this window.
2412 gtk_window_get_opacity (GtkWindow *window)
2414 GtkWindowPrivate *priv;
2416 g_return_val_if_fail (GTK_IS_WINDOW (window), 0.0);
2418 priv = GTK_WINDOW_GET_PRIVATE (window);
2420 return priv->opacity;
2424 * gtk_window_set_type_hint:
2425 * @window: a #GtkWindow
2426 * @hint: the window type
2428 * By setting the type hint for the window, you allow the window
2429 * manager to decorate and handle the window in a way which is
2430 * suitable to the function of the window in your application.
2432 * This function should be called before the window becomes visible.
2434 * gtk_dialog_new_with_buttons() and other convenience functions in GTK+
2435 * will sometimes call gtk_window_set_type_hint() on your behalf.
2439 gtk_window_set_type_hint (GtkWindow *window,
2440 GdkWindowTypeHint hint)
2442 GtkWindowPrivate *priv;
2444 g_return_if_fail (GTK_IS_WINDOW (window));
2445 g_return_if_fail (!gtk_widget_get_mapped (GTK_WIDGET (window)));
2447 priv = GTK_WINDOW_GET_PRIVATE (window);
2449 if (hint < GDK_WINDOW_TYPE_HINT_DROPDOWN_MENU)
2450 window->type_hint = hint;
2452 window->type_hint = GDK_WINDOW_TYPE_HINT_NORMAL;
2454 priv->reset_type_hint = TRUE;
2455 priv->type_hint = hint;
2459 * gtk_window_get_type_hint:
2460 * @window: a #GtkWindow
2462 * Gets the type hint for this window. See gtk_window_set_type_hint().
2464 * Return value: the type hint for @window.
2467 gtk_window_get_type_hint (GtkWindow *window)
2469 GtkWindowPrivate *priv;
2471 g_return_val_if_fail (GTK_IS_WINDOW (window), GDK_WINDOW_TYPE_HINT_NORMAL);
2473 priv = GTK_WINDOW_GET_PRIVATE (window);
2475 return priv->type_hint;
2479 * gtk_window_set_skip_taskbar_hint:
2480 * @window: a #GtkWindow
2481 * @setting: %TRUE to keep this window from appearing in the task bar
2483 * Windows may set a hint asking the desktop environment not to display
2484 * the window in the task bar. This function sets this hint.
2489 gtk_window_set_skip_taskbar_hint (GtkWindow *window,
2492 GtkWindowPrivate *priv;
2494 g_return_if_fail (GTK_IS_WINDOW (window));
2496 priv = GTK_WINDOW_GET_PRIVATE (window);
2498 setting = setting != FALSE;
2500 if (priv->skips_taskbar != setting)
2502 priv->skips_taskbar = setting;
2503 if (gtk_widget_get_realized (GTK_WIDGET (window)))
2504 gdk_window_set_skip_taskbar_hint (GTK_WIDGET (window)->window,
2505 priv->skips_taskbar);
2506 g_object_notify (G_OBJECT (window), "skip-taskbar-hint");
2511 * gtk_window_get_skip_taskbar_hint:
2512 * @window: a #GtkWindow
2514 * Gets the value set by gtk_window_set_skip_taskbar_hint()
2516 * Return value: %TRUE if window shouldn't be in taskbar
2521 gtk_window_get_skip_taskbar_hint (GtkWindow *window)
2523 GtkWindowPrivate *priv;
2525 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
2527 priv = GTK_WINDOW_GET_PRIVATE (window);
2529 return priv->skips_taskbar;
2533 * gtk_window_set_skip_pager_hint:
2534 * @window: a #GtkWindow
2535 * @setting: %TRUE to keep this window from appearing in the pager
2537 * Windows may set a hint asking the desktop environment not to display
2538 * the window in the pager. This function sets this hint.
2539 * (A "pager" is any desktop navigation tool such as a workspace
2540 * switcher that displays a thumbnail representation of the windows
2546 gtk_window_set_skip_pager_hint (GtkWindow *window,
2549 GtkWindowPrivate *priv;
2551 g_return_if_fail (GTK_IS_WINDOW (window));
2553 priv = GTK_WINDOW_GET_PRIVATE (window);
2555 setting = setting != FALSE;
2557 if (priv->skips_pager != setting)
2559 priv->skips_pager = setting;
2560 if (gtk_widget_get_realized (GTK_WIDGET (window)))
2561 gdk_window_set_skip_pager_hint (GTK_WIDGET (window)->window,
2563 g_object_notify (G_OBJECT (window), "skip-pager-hint");
2568 * gtk_window_get_skip_pager_hint:
2569 * @window: a #GtkWindow
2571 * Gets the value set by gtk_window_set_skip_pager_hint().
2573 * Return value: %TRUE if window shouldn't be in pager
2578 gtk_window_get_skip_pager_hint (GtkWindow *window)
2580 GtkWindowPrivate *priv;
2582 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
2584 priv = GTK_WINDOW_GET_PRIVATE (window);
2586 return priv->skips_pager;
2590 * gtk_window_set_urgency_hint:
2591 * @window: a #GtkWindow
2592 * @setting: %TRUE to mark this window as urgent
2594 * Windows may set a hint asking the desktop environment to draw
2595 * the users attention to the window. This function sets this hint.
2600 gtk_window_set_urgency_hint (GtkWindow *window,
2603 GtkWindowPrivate *priv;
2605 g_return_if_fail (GTK_IS_WINDOW (window));
2607 priv = GTK_WINDOW_GET_PRIVATE (window);
2609 setting = setting != FALSE;
2611 if (priv->urgent != setting)
2613 priv->urgent = setting;
2614 if (gtk_widget_get_realized (GTK_WIDGET (window)))
2615 gdk_window_set_urgency_hint (GTK_WIDGET (window)->window,
2617 g_object_notify (G_OBJECT (window), "urgency-hint");
2622 * gtk_window_get_urgency_hint:
2623 * @window: a #GtkWindow
2625 * Gets the value set by gtk_window_set_urgency_hint()
2627 * Return value: %TRUE if window is urgent
2632 gtk_window_get_urgency_hint (GtkWindow *window)
2634 GtkWindowPrivate *priv;
2636 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
2638 priv = GTK_WINDOW_GET_PRIVATE (window);
2640 return priv->urgent;
2644 * gtk_window_set_accept_focus:
2645 * @window: a #GtkWindow
2646 * @setting: %TRUE to let this window receive input focus
2648 * Windows may set a hint asking the desktop environment not to receive
2649 * the input focus. This function sets this hint.
2654 gtk_window_set_accept_focus (GtkWindow *window,
2657 GtkWindowPrivate *priv;
2659 g_return_if_fail (GTK_IS_WINDOW (window));
2661 priv = GTK_WINDOW_GET_PRIVATE (window);
2663 setting = setting != FALSE;
2665 if (priv->accept_focus != setting)
2667 priv->accept_focus = setting;
2668 if (gtk_widget_get_realized (GTK_WIDGET (window)))
2669 gdk_window_set_accept_focus (GTK_WIDGET (window)->window,
2670 priv->accept_focus);
2671 g_object_notify (G_OBJECT (window), "accept-focus");
2676 * gtk_window_get_accept_focus:
2677 * @window: a #GtkWindow
2679 * Gets the value set by gtk_window_set_accept_focus().
2681 * Return value: %TRUE if window should receive the input focus
2686 gtk_window_get_accept_focus (GtkWindow *window)
2688 GtkWindowPrivate *priv;
2690 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
2692 priv = GTK_WINDOW_GET_PRIVATE (window);
2694 return priv->accept_focus;
2698 * gtk_window_set_focus_on_map:
2699 * @window: a #GtkWindow
2700 * @setting: %TRUE to let this window receive input focus on map
2702 * Windows may set a hint asking the desktop environment not to receive
2703 * the input focus when the window is mapped. This function sets this
2709 gtk_window_set_focus_on_map (GtkWindow *window,
2712 GtkWindowPrivate *priv;
2714 g_return_if_fail (GTK_IS_WINDOW (window));
2716 priv = GTK_WINDOW_GET_PRIVATE (window);
2718 setting = setting != FALSE;
2720 if (priv->focus_on_map != setting)
2722 priv->focus_on_map = setting;
2723 if (gtk_widget_get_realized (GTK_WIDGET (window)))
2724 gdk_window_set_focus_on_map (GTK_WIDGET (window)->window,
2725 priv->focus_on_map);
2726 g_object_notify (G_OBJECT (window), "focus-on-map");
2731 * gtk_window_get_focus_on_map:
2732 * @window: a #GtkWindow
2734 * Gets the value set by gtk_window_set_focus_on_map().
2736 * Return value: %TRUE if window should receive the input focus when
2742 gtk_window_get_focus_on_map (GtkWindow *window)
2744 GtkWindowPrivate *priv;
2746 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
2748 priv = GTK_WINDOW_GET_PRIVATE (window);
2750 return priv->focus_on_map;
2754 * gtk_window_set_destroy_with_parent:
2755 * @window: a #GtkWindow
2756 * @setting: whether to destroy @window with its transient parent
2758 * If @setting is %TRUE, then destroying the transient parent of @window
2759 * will also destroy @window itself. This is useful for dialogs that
2760 * shouldn't persist beyond the lifetime of the main window they're
2761 * associated with, for example.
2764 gtk_window_set_destroy_with_parent (GtkWindow *window,
2767 g_return_if_fail (GTK_IS_WINDOW (window));
2769 if (window->destroy_with_parent == (setting != FALSE))
2772 if (window->destroy_with_parent)
2774 disconnect_parent_destroyed (window);
2778 connect_parent_destroyed (window);
2781 window->destroy_with_parent = setting;
2783 g_object_notify (G_OBJECT (window), "destroy-with-parent");
2787 * gtk_window_get_destroy_with_parent:
2788 * @window: a #GtkWindow
2790 * Returns whether the window will be destroyed with its transient parent. See
2791 * gtk_window_set_destroy_with_parent ().
2793 * Return value: %TRUE if the window will be destroyed with its transient parent.
2796 gtk_window_get_destroy_with_parent (GtkWindow *window)
2798 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
2800 return window->destroy_with_parent;
2803 static GtkWindowGeometryInfo*
2804 gtk_window_get_geometry_info (GtkWindow *window,
2807 GtkWindowGeometryInfo *info;
2809 info = window->geometry_info;
2810 if (!info && create)
2812 info = g_new0 (GtkWindowGeometryInfo, 1);
2814 info->default_width = -1;
2815 info->default_height = -1;
2816 info->resize_width = -1;
2817 info->resize_height = -1;
2818 info->initial_x = 0;
2819 info->initial_y = 0;
2820 info->initial_pos_set = FALSE;
2821 info->default_is_geometry = FALSE;
2822 info->position_constraints_changed = FALSE;
2823 info->last.configure_request.x = 0;
2824 info->last.configure_request.y = 0;
2825 info->last.configure_request.width = -1;
2826 info->last.configure_request.height = -1;
2827 info->widget = NULL;
2829 window->geometry_info = info;
2836 * gtk_window_set_geometry_hints:
2837 * @window: a #GtkWindow
2838 * @geometry_widget: widget the geometry hints will be applied to
2839 * @geometry: struct containing geometry information
2840 * @geom_mask: mask indicating which struct fields should be paid attention to
2842 * This function sets up hints about how a window can be resized by
2843 * the user. You can set a minimum and maximum size; allowed resize
2844 * increments (e.g. for xterm, you can only resize by the size of a
2845 * character); aspect ratios; and more. See the #GdkGeometry struct.
2849 gtk_window_set_geometry_hints (GtkWindow *window,
2850 GtkWidget *geometry_widget,
2851 GdkGeometry *geometry,
2852 GdkWindowHints geom_mask)
2854 GtkWindowGeometryInfo *info;
2856 g_return_if_fail (GTK_IS_WINDOW (window));
2857 g_return_if_fail (geometry_widget == NULL || GTK_IS_WIDGET (geometry_widget));
2859 info = gtk_window_get_geometry_info (window, TRUE);
2862 g_signal_handlers_disconnect_by_func (info->widget,
2863 gtk_widget_destroyed,
2866 info->widget = geometry_widget;
2868 g_signal_connect (geometry_widget, "destroy",
2869 G_CALLBACK (gtk_widget_destroyed),
2873 info->geometry = *geometry;
2875 /* We store gravity in window->gravity not in the hints. */
2876 info->mask = geom_mask & ~(GDK_HINT_WIN_GRAVITY);
2878 if (geom_mask & GDK_HINT_WIN_GRAVITY)
2880 gtk_window_set_gravity (window, geometry->win_gravity);
2883 gtk_widget_queue_resize_no_redraw (GTK_WIDGET (window));
2887 * gtk_window_set_decorated:
2888 * @window: a #GtkWindow
2889 * @setting: %TRUE to decorate the window
2891 * By default, windows are decorated with a title bar, resize
2892 * controls, etc. Some <link linkend="gtk-X11-arch">window
2893 * managers</link> allow GTK+ to disable these decorations, creating a
2894 * borderless window. If you set the decorated property to %FALSE
2895 * using this function, GTK+ will do its best to convince the window
2896 * manager not to decorate the window. Depending on the system, this
2897 * function may not have any effect when called on a window that is
2898 * already visible, so you should call it before calling gtk_window_show().
2900 * On Windows, this function always works, since there's no window manager
2905 gtk_window_set_decorated (GtkWindow *window,
2908 g_return_if_fail (GTK_IS_WINDOW (window));
2910 setting = setting != FALSE;
2912 if (setting == window->decorated)
2915 window->decorated = setting;
2917 if (GTK_WIDGET (window)->window)
2919 if (window->decorated)
2920 gdk_window_set_decorations (GTK_WIDGET (window)->window,
2923 gdk_window_set_decorations (GTK_WIDGET (window)->window,
2927 g_object_notify (G_OBJECT (window), "decorated");
2931 * gtk_window_get_decorated:
2932 * @window: a #GtkWindow
2934 * Returns whether the window has been set to have decorations
2935 * such as a title bar via gtk_window_set_decorated().
2937 * Return value: %TRUE if the window has been set to have decorations
2940 gtk_window_get_decorated (GtkWindow *window)
2942 g_return_val_if_fail (GTK_IS_WINDOW (window), TRUE);
2944 return window->decorated;
2948 * gtk_window_set_deletable:
2949 * @window: a #GtkWindow
2950 * @setting: %TRUE to decorate the window as deletable
2952 * By default, windows have a close button in the window frame. Some
2953 * <link linkend="gtk-X11-arch">window managers</link> allow GTK+ to
2954 * disable this button. If you set the deletable property to %FALSE
2955 * using this function, GTK+ will do its best to convince the window
2956 * manager not to show a close button. Depending on the system, this
2957 * function may not have any effect when called on a window that is
2958 * already visible, so you should call it before calling gtk_window_show().
2960 * On Windows, this function always works, since there's no window manager
2966 gtk_window_set_deletable (GtkWindow *window,
2969 GtkWindowPrivate *priv;
2971 g_return_if_fail (GTK_IS_WINDOW (window));
2973 priv = GTK_WINDOW_GET_PRIVATE (window);
2975 setting = setting != FALSE;
2977 if (setting == priv->deletable)
2980 priv->deletable = setting;
2982 if (GTK_WIDGET (window)->window)
2984 if (priv->deletable)
2985 gdk_window_set_functions (GTK_WIDGET (window)->window,
2988 gdk_window_set_functions (GTK_WIDGET (window)->window,
2989 GDK_FUNC_ALL | GDK_FUNC_CLOSE);
2992 g_object_notify (G_OBJECT (window), "deletable");
2996 * gtk_window_get_deletable:
2997 * @window: a #GtkWindow
2999 * Returns whether the window has been set to have a close button
3000 * via gtk_window_set_deletable().
3002 * Return value: %TRUE if the window has been set to have a close button
3007 gtk_window_get_deletable (GtkWindow *window)
3009 GtkWindowPrivate *priv;
3011 g_return_val_if_fail (GTK_IS_WINDOW (window), TRUE);
3013 priv = GTK_WINDOW_GET_PRIVATE (window);
3015 return priv->deletable;
3018 static GtkWindowIconInfo*
3019 get_icon_info (GtkWindow *window)
3021 return g_object_get_qdata (G_OBJECT (window), quark_gtk_window_icon_info);
3025 free_icon_info (GtkWindowIconInfo *info)
3027 g_free (info->icon_name);
3028 g_slice_free (GtkWindowIconInfo, info);
3032 static GtkWindowIconInfo*
3033 ensure_icon_info (GtkWindow *window)
3035 GtkWindowIconInfo *info;
3037 info = get_icon_info (window);
3041 info = g_slice_new0 (GtkWindowIconInfo);
3042 g_object_set_qdata_full (G_OBJECT (window),
3043 quark_gtk_window_icon_info,
3045 (GDestroyNotify)free_icon_info);
3057 static ScreenIconInfo *
3058 get_screen_icon_info (GdkScreen *screen)
3060 ScreenIconInfo *info = g_object_get_qdata (G_OBJECT (screen),
3061 quark_gtk_window_default_icon_pixmap);
3064 info = g_slice_new0 (ScreenIconInfo);
3065 g_object_set_qdata (G_OBJECT (screen),
3066 quark_gtk_window_default_icon_pixmap, info);
3069 if (info->serial != default_icon_serial)
3073 g_object_remove_weak_pointer (G_OBJECT (info->pixmap), (gpointer*)&info->pixmap);
3074 info->pixmap = NULL;
3079 g_object_remove_weak_pointer (G_OBJECT (info->mask), (gpointer*)&info->mask);
3083 info->serial = default_icon_serial;
3090 get_pixmap_and_mask (GdkWindow *window,
3091 GtkWindowIconInfo *parent_info,
3092 gboolean is_default_list,
3094 GdkPixmap **pmap_return,
3095 GdkBitmap **mask_return)
3097 GdkScreen *screen = gdk_drawable_get_screen (window);
3098 ScreenIconInfo *default_icon_info = get_screen_icon_info (screen);
3099 GdkPixbuf *best_icon;
3103 *pmap_return = NULL;
3104 *mask_return = NULL;
3106 if (is_default_list &&
3107 default_icon_info->pixmap != NULL)
3109 /* Use shared icon pixmap for all windows on this screen.
3111 if (default_icon_info->pixmap)
3112 g_object_ref (default_icon_info->pixmap);
3113 if (default_icon_info->mask)
3114 g_object_ref (default_icon_info->mask);
3116 *pmap_return = default_icon_info->pixmap;
3117 *mask_return = default_icon_info->mask;
3119 else if (parent_info && parent_info->icon_pixmap)
3121 if (parent_info->icon_pixmap)
3122 g_object_ref (parent_info->icon_pixmap);
3123 if (parent_info->icon_mask)
3124 g_object_ref (parent_info->icon_mask);
3126 *pmap_return = parent_info->icon_pixmap;
3127 *mask_return = parent_info->icon_mask;
3131 #define IDEAL_SIZE 48
3133 best_size = G_MAXINT;
3135 tmp_list = icon_list;
3136 while (tmp_list != NULL)
3138 GdkPixbuf *pixbuf = tmp_list->data;
3141 /* average width and height - if someone passes in a rectangular
3142 * icon they deserve what they get.
3144 this = gdk_pixbuf_get_width (pixbuf) + gdk_pixbuf_get_height (pixbuf);
3147 if (best_icon == NULL)
3154 /* icon is better if it's 32 pixels or larger, and closer to
3155 * the ideal size than the current best.
3158 (ABS (best_size - IDEAL_SIZE) <
3159 ABS (this - IDEAL_SIZE)))
3166 tmp_list = tmp_list->next;
3170 gdk_pixbuf_render_pixmap_and_mask_for_colormap (best_icon,
3171 gdk_screen_get_system_colormap (screen),
3176 /* Save pmap/mask for others to use if appropriate */
3179 parent_info->icon_pixmap = *pmap_return;
3180 parent_info->icon_mask = *mask_return;
3182 if (parent_info->icon_pixmap)
3183 g_object_ref (parent_info->icon_pixmap);
3184 if (parent_info->icon_mask)
3185 g_object_ref (parent_info->icon_mask);
3187 else if (is_default_list)
3189 default_icon_info->pixmap = *pmap_return;
3190 default_icon_info->mask = *mask_return;
3192 if (default_icon_info->pixmap)
3193 g_object_add_weak_pointer (G_OBJECT (default_icon_info->pixmap),
3194 (gpointer*)&default_icon_info->pixmap);
3195 if (default_icon_info->mask)
3196 g_object_add_weak_pointer (G_OBJECT (default_icon_info->mask),
3197 (gpointer*)&default_icon_info->mask);
3203 icon_list_from_theme (GtkWidget *widget,
3208 GtkIconTheme *icon_theme;
3213 icon_theme = gtk_icon_theme_get_for_screen (gtk_widget_get_screen (widget));
3215 sizes = gtk_icon_theme_get_icon_sizes (icon_theme, name);
3218 for (i = 0; sizes[i]; i++)
3221 * We need an EWMH extension to handle scalable icons
3222 * by passing their name to the WM. For now just use a
3226 icon = gtk_icon_theme_load_icon (icon_theme, name,
3229 icon = gtk_icon_theme_load_icon (icon_theme, name,
3232 list = g_list_append (list, icon);
3242 gtk_window_realize_icon (GtkWindow *window)
3245 GtkWindowIconInfo *info;
3248 widget = GTK_WIDGET (window);
3250 g_return_if_fail (widget->window != NULL);
3252 /* no point setting an icon on override-redirect */
3253 if (window->type == GTK_WINDOW_POPUP)
3258 info = ensure_icon_info (window);
3263 g_return_if_fail (info->icon_pixmap == NULL);
3264 g_return_if_fail (info->icon_mask == NULL);
3266 info->using_default_icon = FALSE;
3267 info->using_parent_icon = FALSE;
3268 info->using_themed_icon = FALSE;
3270 icon_list = info->icon_list;
3272 /* Look up themed icon */
3273 if (icon_list == NULL && info->icon_name)
3275 icon_list = icon_list_from_theme (widget, info->icon_name);
3277 info->using_themed_icon = TRUE;
3280 /* Inherit from transient parent */
3281 if (icon_list == NULL && window->transient_parent)
3283 icon_list = ensure_icon_info (window->transient_parent)->icon_list;
3285 info->using_parent_icon = TRUE;
3288 /* Inherit from default */
3289 if (icon_list == NULL)
3291 icon_list = default_icon_list;
3293 info->using_default_icon = TRUE;
3296 /* Look up themed icon */
3297 if (icon_list == NULL && default_icon_name)
3299 icon_list = icon_list_from_theme (widget, default_icon_name);
3300 info->using_default_icon = TRUE;
3301 info->using_themed_icon = TRUE;
3304 gdk_window_set_icon_list (widget->window, icon_list);
3306 get_pixmap_and_mask (widget->window,
3307 info->using_parent_icon ? ensure_icon_info (window->transient_parent) : NULL,
3308 info->using_default_icon,
3313 /* This is a slight ICCCM violation since it's a color pixmap not
3314 * a bitmap, but everyone does it.
3316 gdk_window_set_icon (widget->window,
3321 info->realized = TRUE;
3323 if (info->using_themed_icon)
3325 GtkIconTheme *icon_theme;
3327 g_list_foreach (icon_list, (GFunc) g_object_unref, NULL);
3328 g_list_free (icon_list);
3330 icon_theme = gtk_icon_theme_get_for_screen (gtk_widget_get_screen (GTK_WIDGET (window)));
3331 g_signal_connect (icon_theme, "changed",
3332 G_CALLBACK (update_themed_icon), window);
3337 gtk_window_unrealize_icon (GtkWindow *window)
3339 GtkWindowIconInfo *info;
3341 info = get_icon_info (window);
3346 if (info->icon_pixmap)
3347 g_object_unref (info->icon_pixmap);
3349 if (info->icon_mask)
3350 g_object_unref (info->icon_mask);
3352 info->icon_pixmap = NULL;
3353 info->icon_mask = NULL;
3355 if (info->using_themed_icon)
3357 GtkIconTheme *icon_theme;
3359 icon_theme = gtk_icon_theme_get_for_screen (gtk_widget_get_screen (GTK_WIDGET (window)));
3361 g_signal_handlers_disconnect_by_func (icon_theme, update_themed_icon, window);
3364 /* We don't clear the properties on the window, just figure the
3365 * window is going away.
3368 info->realized = FALSE;
3373 * gtk_window_set_icon_list:
3374 * @window: a #GtkWindow
3375 * @list: list of #GdkPixbuf
3377 * Sets up the icon representing a #GtkWindow. The icon is used when
3378 * the window is minimized (also known as iconified). Some window
3379 * managers or desktop environments may also place it in the window
3380 * frame, or display it in other contexts.
3382 * gtk_window_set_icon_list() allows you to pass in the same icon in
3383 * several hand-drawn sizes. The list should contain the natural sizes
3384 * your icon is available in; that is, don't scale the image before
3385 * passing it to GTK+. Scaling is postponed until the last minute,
3386 * when the desired final size is known, to allow best quality.
3388 * By passing several sizes, you may improve the final image quality
3389 * of the icon, by reducing or eliminating automatic image scaling.
3391 * Recommended sizes to provide: 16x16, 32x32, 48x48 at minimum, and
3392 * larger images (64x64, 128x128) if you have them.
3394 * See also gtk_window_set_default_icon_list() to set the icon
3395 * for all windows in your application in one go.
3397 * Note that transient windows (those who have been set transient for another
3398 * window using gtk_window_set_transient_for()) will inherit their
3399 * icon from their transient parent. So there's no need to explicitly
3400 * set the icon on transient windows.
3403 gtk_window_set_icon_list (GtkWindow *window,
3406 GtkWindowIconInfo *info;
3408 g_return_if_fail (GTK_IS_WINDOW (window));
3410 info = ensure_icon_info (window);
3412 if (info->icon_list == list) /* check for NULL mostly */
3415 g_list_foreach (list,
3416 (GFunc) g_object_ref, NULL);
3418 g_list_foreach (info->icon_list,
3419 (GFunc) g_object_unref, NULL);
3421 g_list_free (info->icon_list);
3423 info->icon_list = g_list_copy (list);
3425 g_object_notify (G_OBJECT (window), "icon");
3427 gtk_window_unrealize_icon (window);
3429 if (gtk_widget_get_realized (GTK_WIDGET (window)))
3430 gtk_window_realize_icon (window);
3432 /* We could try to update our transient children, but I don't think
3433 * it's really worth it. If we did it, the best way would probably
3434 * be to have children connect to notify::icon-list
3439 * gtk_window_get_icon_list:
3440 * @window: a #GtkWindow
3442 * Retrieves the list of icons set by gtk_window_set_icon_list().
3443 * The list is copied, but the reference count on each
3444 * member won't be incremented.
3446 * Return value: (element-type GdkPixbuf) (transfer container): copy of window's icon list
3449 gtk_window_get_icon_list (GtkWindow *window)
3451 GtkWindowIconInfo *info;
3453 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
3455 info = get_icon_info (window);
3458 return g_list_copy (info->icon_list);
3464 * gtk_window_set_icon:
3465 * @window: a #GtkWindow
3466 * @icon: (allow-none): icon image, or %NULL
3468 * Sets up the icon representing a #GtkWindow. This icon is used when
3469 * the window is minimized (also known as iconified). Some window
3470 * managers or desktop environments may also place it in the window
3471 * frame, or display it in other contexts.
3473 * The icon should be provided in whatever size it was naturally
3474 * drawn; that is, don't scale the image before passing it to
3475 * GTK+. Scaling is postponed until the last minute, when the desired
3476 * final size is known, to allow best quality.
3478 * If you have your icon hand-drawn in multiple sizes, use
3479 * gtk_window_set_icon_list(). Then the best size will be used.
3481 * This function is equivalent to calling gtk_window_set_icon_list()
3482 * with a 1-element list.
3484 * See also gtk_window_set_default_icon_list() to set the icon
3485 * for all windows in your application in one go.
3488 gtk_window_set_icon (GtkWindow *window,
3493 g_return_if_fail (GTK_IS_WINDOW (window));
3494 g_return_if_fail (icon == NULL || GDK_IS_PIXBUF (icon));
3499 list = g_list_append (list, icon);
3501 gtk_window_set_icon_list (window, list);
3507 update_themed_icon (GtkIconTheme *icon_theme,
3510 g_object_notify (G_OBJECT (window), "icon");
3512 gtk_window_unrealize_icon (window);
3514 if (gtk_widget_get_realized (GTK_WIDGET (window)))
3515 gtk_window_realize_icon (window);
3519 * gtk_window_set_icon_name:
3520 * @window: a #GtkWindow
3521 * @name: (allow-none): the name of the themed icon
3523 * Sets the icon for the window from a named themed icon. See
3524 * the docs for #GtkIconTheme for more details.
3526 * Note that this has nothing to do with the WM_ICON_NAME
3527 * property which is mentioned in the ICCCM.
3532 gtk_window_set_icon_name (GtkWindow *window,
3535 GtkWindowIconInfo *info;
3538 g_return_if_fail (GTK_IS_WINDOW (window));
3540 info = ensure_icon_info (window);
3542 if (g_strcmp0 (info->icon_name, name) == 0)
3545 tmp = info->icon_name;
3546 info->icon_name = g_strdup (name);
3549 g_list_foreach (info->icon_list, (GFunc) g_object_unref, NULL);
3550 g_list_free (info->icon_list);
3551 info->icon_list = NULL;
3553 update_themed_icon (NULL, window);
3555 g_object_notify (G_OBJECT (window), "icon-name");
3559 * gtk_window_get_icon_name:
3560 * @window: a #GtkWindow
3562 * Returns the name of the themed icon for the window,
3563 * see gtk_window_set_icon_name().
3565 * Returns: the icon name or %NULL if the window has
3571 gtk_window_get_icon_name (GtkWindow *window)
3573 GtkWindowIconInfo *info;
3575 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
3577 info = ensure_icon_info (window);
3579 return info->icon_name;
3583 * gtk_window_get_icon:
3584 * @window: a #GtkWindow
3586 * Gets the value set by gtk_window_set_icon() (or if you've
3587 * called gtk_window_set_icon_list(), gets the first icon in
3590 * Return value: (transfer none): icon for window
3593 gtk_window_get_icon (GtkWindow *window)
3595 GtkWindowIconInfo *info;
3597 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
3599 info = get_icon_info (window);
3600 if (info && info->icon_list)
3601 return GDK_PIXBUF (info->icon_list->data);
3606 /* Load pixbuf, printing warning on failure if error == NULL
3609 load_pixbuf_verbosely (const char *filename,
3612 GError *local_err = NULL;
3615 pixbuf = gdk_pixbuf_new_from_file (filename, &local_err);
3623 g_warning ("Error loading icon from file '%s':\n\t%s",
3624 filename, local_err->message);
3625 g_error_free (local_err);
3633 * gtk_window_set_icon_from_file:
3634 * @window: a #GtkWindow
3635 * @filename: location of icon file
3636 * @err: (allow-none): location to store error, or %NULL.
3638 * Sets the icon for @window.
3639 * Warns on failure if @err is %NULL.
3641 * This function is equivalent to calling gtk_window_set_icon()
3642 * with a pixbuf created by loading the image from @filename.
3644 * Returns: %TRUE if setting the icon succeeded.
3649 gtk_window_set_icon_from_file (GtkWindow *window,
3650 const gchar *filename,
3653 GdkPixbuf *pixbuf = load_pixbuf_verbosely (filename, err);
3657 gtk_window_set_icon (window, pixbuf);
3658 g_object_unref (pixbuf);
3667 * gtk_window_set_default_icon_list:
3668 * @list: a list of #GdkPixbuf
3670 * Sets an icon list to be used as fallback for windows that haven't
3671 * had gtk_window_set_icon_list() called on them to set up a
3672 * window-specific icon list. This function allows you to set up the
3673 * icon for all windows in your app at once.
3675 * See gtk_window_set_icon_list() for more details.
3679 gtk_window_set_default_icon_list (GList *list)
3683 if (list == default_icon_list)
3686 /* Update serial so we don't used cached pixmaps/masks
3688 default_icon_serial++;
3690 g_list_foreach (list,
3691 (GFunc) g_object_ref, NULL);
3693 g_list_foreach (default_icon_list,
3694 (GFunc) g_object_unref, NULL);
3696 g_list_free (default_icon_list);
3698 default_icon_list = g_list_copy (list);
3700 /* Update all toplevels */
3701 toplevels = gtk_window_list_toplevels ();
3702 tmp_list = toplevels;
3703 while (tmp_list != NULL)
3705 GtkWindowIconInfo *info;
3706 GtkWindow *w = tmp_list->data;
3708 info = get_icon_info (w);
3709 if (info && info->using_default_icon)
3711 gtk_window_unrealize_icon (w);
3712 if (gtk_widget_get_realized (GTK_WIDGET (w)))
3713 gtk_window_realize_icon (w);
3716 tmp_list = tmp_list->next;
3718 g_list_free (toplevels);
3722 * gtk_window_set_default_icon:
3725 * Sets an icon to be used as fallback for windows that haven't
3726 * had gtk_window_set_icon() called on them from a pixbuf.
3731 gtk_window_set_default_icon (GdkPixbuf *icon)
3735 g_return_if_fail (GDK_IS_PIXBUF (icon));
3737 list = g_list_prepend (NULL, icon);
3738 gtk_window_set_default_icon_list (list);
3743 * gtk_window_set_default_icon_name:
3744 * @name: the name of the themed icon
3746 * Sets an icon to be used as fallback for windows that haven't
3747 * had gtk_window_set_icon_list() called on them from a named
3748 * themed icon, see gtk_window_set_icon_name().
3753 gtk_window_set_default_icon_name (const gchar *name)
3758 /* Update serial so we don't used cached pixmaps/masks
3760 default_icon_serial++;
3762 g_free (default_icon_name);
3763 default_icon_name = g_strdup (name);
3765 g_list_foreach (default_icon_list,
3766 (GFunc) g_object_unref, NULL);
3768 g_list_free (default_icon_list);
3769 default_icon_list = NULL;
3771 /* Update all toplevels */
3772 toplevels = gtk_window_list_toplevels ();
3773 tmp_list = toplevels;
3774 while (tmp_list != NULL)
3776 GtkWindowIconInfo *info;
3777 GtkWindow *w = tmp_list->data;
3779 info = get_icon_info (w);
3780 if (info && info->using_default_icon && info->using_themed_icon)
3782 gtk_window_unrealize_icon (w);
3783 if (gtk_widget_get_realized (GTK_WIDGET (w)))
3784 gtk_window_realize_icon (w);
3787 tmp_list = tmp_list->next;
3789 g_list_free (toplevels);
3793 * gtk_window_get_default_icon_name:
3795 * Returns the fallback icon name for windows that has been set
3796 * with gtk_window_set_default_icon_name(). The returned
3797 * string is owned by GTK+ and should not be modified. It
3798 * is only valid until the next call to
3799 * gtk_window_set_default_icon_name().
3801 * Returns: the fallback icon name for windows
3806 gtk_window_get_default_icon_name (void)
3808 return default_icon_name;
3812 * gtk_window_set_default_icon_from_file:
3813 * @filename: location of icon file
3814 * @err: (allow-none): location to store error, or %NULL.
3816 * Sets an icon to be used as fallback for windows that haven't
3817 * had gtk_window_set_icon_list() called on them from a file
3818 * on disk. Warns on failure if @err is %NULL.
3820 * Returns: %TRUE if setting the icon succeeded.
3825 gtk_window_set_default_icon_from_file (const gchar *filename,
3828 GdkPixbuf *pixbuf = load_pixbuf_verbosely (filename, err);
3832 gtk_window_set_default_icon (pixbuf);
3833 g_object_unref (pixbuf);
3842 * gtk_window_get_default_icon_list:
3844 * Gets the value set by gtk_window_set_default_icon_list().
3845 * The list is a copy and should be freed with g_list_free(),
3846 * but the pixbufs in the list have not had their reference count
3849 * Return value: copy of default icon list
3852 gtk_window_get_default_icon_list (void)
3854 return g_list_copy (default_icon_list);
3858 gtk_window_set_default_size_internal (GtkWindow *window,
3859 gboolean change_width,
3861 gboolean change_height,
3863 gboolean is_geometry)
3865 GtkWindowGeometryInfo *info;
3867 g_return_if_fail (change_width == FALSE || width >= -1);
3868 g_return_if_fail (change_height == FALSE || height >= -1);
3870 info = gtk_window_get_geometry_info (window, TRUE);
3872 g_object_freeze_notify (G_OBJECT (window));
3874 info->default_is_geometry = is_geometry != FALSE;
3884 info->default_width = width;
3886 g_object_notify (G_OBJECT (window), "default-width");
3897 info->default_height = height;
3899 g_object_notify (G_OBJECT (window), "default-height");
3902 g_object_thaw_notify (G_OBJECT (window));
3904 gtk_widget_queue_resize_no_redraw (GTK_WIDGET (window));
3908 * gtk_window_set_default_size:
3909 * @window: a #GtkWindow
3910 * @width: width in pixels, or -1 to unset the default width
3911 * @height: height in pixels, or -1 to unset the default height
3913 * Sets the default size of a window. If the window's "natural" size
3914 * (its size request) is larger than the default, the default will be
3915 * ignored. More generally, if the default size does not obey the
3916 * geometry hints for the window (gtk_window_set_geometry_hints() can
3917 * be used to set these explicitly), the default size will be clamped
3918 * to the nearest permitted size.
3920 * Unlike gtk_widget_set_size_request(), which sets a size request for
3921 * a widget and thus would keep users from shrinking the window, this
3922 * function only sets the initial size, just as if the user had
3923 * resized the window themselves. Users can still shrink the window
3924 * again as they normally would. Setting a default size of -1 means to
3925 * use the "natural" default size (the size request of the window).
3927 * For more control over a window's initial size and how resizing works,
3928 * investigate gtk_window_set_geometry_hints().
3930 * For some uses, gtk_window_resize() is a more appropriate function.
3931 * gtk_window_resize() changes the current size of the window, rather
3932 * than the size to be used on initial display. gtk_window_resize() always
3933 * affects the window itself, not the geometry widget.
3935 * The default size of a window only affects the first time a window is
3936 * shown; if a window is hidden and re-shown, it will remember the size
3937 * it had prior to hiding, rather than using the default size.
3939 * Windows can't actually be 0x0 in size, they must be at least 1x1, but
3940 * passing 0 for @width and @height is OK, resulting in a 1x1 default size.
3943 gtk_window_set_default_size (GtkWindow *window,
3947 g_return_if_fail (GTK_IS_WINDOW (window));
3948 g_return_if_fail (width >= -1);
3949 g_return_if_fail (height >= -1);
3951 gtk_window_set_default_size_internal (window, TRUE, width, TRUE, height, FALSE);
3955 * gtk_window_get_default_size:
3956 * @window: a #GtkWindow
3957 * @width: (allow-none): location to store the default width, or %NULL
3958 * @height: (allow-none): location to store the default height, or %NULL
3960 * Gets the default size of the window. A value of -1 for the width or
3961 * height indicates that a default size has not been explicitly set
3962 * for that dimension, so the "natural" size of the window will be
3967 gtk_window_get_default_size (GtkWindow *window,
3971 GtkWindowGeometryInfo *info;
3973 g_return_if_fail (GTK_IS_WINDOW (window));
3975 info = gtk_window_get_geometry_info (window, FALSE);
3978 *width = info ? info->default_width : -1;
3981 *height = info ? info->default_height : -1;
3985 * gtk_window_resize:
3986 * @window: a #GtkWindow
3987 * @width: width in pixels to resize the window to
3988 * @height: height in pixels to resize the window to
3990 * Resizes the window as if the user had done so, obeying geometry
3991 * constraints. The default geometry constraint is that windows may
3992 * not be smaller than their size request; to override this
3993 * constraint, call gtk_widget_set_size_request() to set the window's
3994 * request to a smaller value.
3996 * If gtk_window_resize() is called before showing a window for the
3997 * first time, it overrides any default size set with
3998 * gtk_window_set_default_size().
4000 * Windows may not be resized smaller than 1 by 1 pixels.
4004 gtk_window_resize (GtkWindow *window,
4008 GtkWindowGeometryInfo *info;
4010 g_return_if_fail (GTK_IS_WINDOW (window));
4011 g_return_if_fail (width > 0);
4012 g_return_if_fail (height > 0);
4014 info = gtk_window_get_geometry_info (window, TRUE);
4016 info->resize_width = width;
4017 info->resize_height = height;
4019 gtk_widget_queue_resize_no_redraw (GTK_WIDGET (window));
4023 * gtk_window_get_size:
4024 * @window: a #GtkWindow
4025 * @width: (allow-none): (out): return location for width, or %NULL
4026 * @height: (allow-none): (out): return location for height, or %NULL
4028 * Obtains the current size of @window. If @window is not onscreen,
4029 * it returns the size GTK+ will suggest to the <link
4030 * linkend="gtk-X11-arch">window manager</link> for the initial window
4031 * size (but this is not reliably the same as the size the window
4032 * manager will actually select). The size obtained by
4033 * gtk_window_get_size() is the last size received in a
4034 * #GdkEventConfigure, that is, GTK+ uses its locally-stored size,
4035 * rather than querying the X server for the size. As a result, if you
4036 * call gtk_window_resize() then immediately call
4037 * gtk_window_get_size(), the size won't have taken effect yet. After
4038 * the window manager processes the resize request, GTK+ receives
4039 * notification that the size has changed via a configure event, and
4040 * the size of the window gets updated.
4042 * Note 1: Nearly any use of this function creates a race condition,
4043 * because the size of the window may change between the time that you
4044 * get the size and the time that you perform some action assuming
4045 * that size is the current size. To avoid race conditions, connect to
4046 * "configure-event" on the window and adjust your size-dependent
4047 * state to match the size delivered in the #GdkEventConfigure.
4049 * Note 2: The returned size does <emphasis>not</emphasis> include the
4050 * size of the window manager decorations (aka the window frame or
4051 * border). Those are not drawn by GTK+ and GTK+ has no reliable
4052 * method of determining their size.
4054 * Note 3: If you are getting a window size in order to position
4055 * the window onscreen, there may be a better way. The preferred
4056 * way is to simply set the window's semantic type with
4057 * gtk_window_set_type_hint(), which allows the window manager to
4058 * e.g. center dialogs. Also, if you set the transient parent of
4059 * dialogs with gtk_window_set_transient_for() window managers
4060 * will often center the dialog over its parent window. It's
4061 * much preferred to let the window manager handle these
4062 * things rather than doing it yourself, because all apps will
4063 * behave consistently and according to user prefs if the window
4064 * manager handles it. Also, the window manager can take the size
4065 * of the window decorations/border into account, while your
4066 * application cannot.
4068 * In any case, if you insist on application-specified window
4069 * positioning, there's <emphasis>still</emphasis> a better way than
4070 * doing it yourself - gtk_window_set_position() will frequently
4071 * handle the details for you.
4075 gtk_window_get_size (GtkWindow *window,
4081 g_return_if_fail (GTK_IS_WINDOW (window));
4083 if (width == NULL && height == NULL)
4086 if (gtk_widget_get_mapped (GTK_WIDGET (window)))
4088 gdk_drawable_get_size (GTK_WIDGET (window)->window,
4093 GdkRectangle configure_request;
4095 gtk_window_compute_configure_request (window,
4099 w = configure_request.width;
4100 h = configure_request.height;
4111 * @window: a #GtkWindow
4112 * @x: X coordinate to move window to
4113 * @y: Y coordinate to move window to
4115 * Asks the <link linkend="gtk-X11-arch">window manager</link> to move
4116 * @window to the given position. Window managers are free to ignore
4117 * this; most window managers ignore requests for initial window
4118 * positions (instead using a user-defined placement algorithm) and
4119 * honor requests after the window has already been shown.
4121 * Note: the position is the position of the gravity-determined
4122 * reference point for the window. The gravity determines two things:
4123 * first, the location of the reference point in root window
4124 * coordinates; and second, which point on the window is positioned at
4125 * the reference point.
4127 * By default the gravity is #GDK_GRAVITY_NORTH_WEST, so the reference
4128 * point is simply the @x, @y supplied to gtk_window_move(). The
4129 * top-left corner of the window decorations (aka window frame or
4130 * border) will be placed at @x, @y. Therefore, to position a window
4131 * at the top left of the screen, you want to use the default gravity
4132 * (which is #GDK_GRAVITY_NORTH_WEST) and move the window to 0,0.
4134 * To position a window at the bottom right corner of the screen, you
4135 * would set #GDK_GRAVITY_SOUTH_EAST, which means that the reference
4136 * point is at @x + the window width and @y + the window height, and
4137 * the bottom-right corner of the window border will be placed at that
4138 * reference point. So, to place a window in the bottom right corner
4139 * you would first set gravity to south east, then write:
4140 * <literal>gtk_window_move (window, gdk_screen_width () - window_width,
4141 * gdk_screen_height () - window_height)</literal> (note that this
4142 * example does not take multi-head scenarios into account).
4144 * The Extended Window Manager Hints specification at <ulink
4145 * url="http://www.freedesktop.org/Standards/wm-spec">
4146 * http://www.freedesktop.org/Standards/wm-spec</ulink> has a
4147 * nice table of gravities in the "implementation notes" section.
4149 * The gtk_window_get_position() documentation may also be relevant.
4152 gtk_window_move (GtkWindow *window,
4156 GtkWindowGeometryInfo *info;
4159 g_return_if_fail (GTK_IS_WINDOW (window));
4161 widget = GTK_WIDGET (window);
4163 info = gtk_window_get_geometry_info (window, TRUE);
4165 if (gtk_widget_get_mapped (widget))
4167 /* we have now sent a request with this position
4168 * with currently-active constraints, so toggle flag.
4170 info->position_constraints_changed = FALSE;
4172 /* we only constrain if mapped - if not mapped,
4173 * then gtk_window_compute_configure_request()
4174 * will apply the constraints later, and we
4175 * don't want to lose information about
4176 * what position the user set before then.
4177 * i.e. if you do a move() then turn off POS_CENTER
4178 * then show the window, your move() will work.
4180 gtk_window_constrain_position (window,
4181 widget->allocation.width,
4182 widget->allocation.height,
4185 /* Note that this request doesn't go through our standard request
4186 * framework, e.g. doesn't increment configure_request_count,
4187 * doesn't set info->last, etc.; that's because
4188 * we don't save the info needed to arrive at this same request
4191 * To gtk_window_move_resize(), this will end up looking exactly
4192 * the same as the position being changed by the window
4196 /* FIXME are we handling gravity properly for framed windows? */
4198 gdk_window_move (window->frame,
4199 x - window->frame_left,
4200 y - window->frame_top);
4202 gdk_window_move (GTK_WIDGET (window)->window,
4207 /* Save this position to apply on mapping */
4208 info->initial_x = x;
4209 info->initial_y = y;
4210 info->initial_pos_set = TRUE;
4215 * gtk_window_get_position:
4216 * @window: a #GtkWindow
4217 * @root_x: return location for X coordinate of gravity-determined reference point
4218 * @root_y: return location for Y coordinate of gravity-determined reference point
4220 * This function returns the position you need to pass to
4221 * gtk_window_move() to keep @window in its current position. This
4222 * means that the meaning of the returned value varies with window
4223 * gravity. See gtk_window_move() for more details.
4225 * If you haven't changed the window gravity, its gravity will be
4226 * #GDK_GRAVITY_NORTH_WEST. This means that gtk_window_get_position()
4227 * gets the position of the top-left corner of the window manager
4228 * frame for the window. gtk_window_move() sets the position of this
4229 * same top-left corner.
4231 * gtk_window_get_position() is not 100% reliable because the X Window System
4232 * does not specify a way to obtain the geometry of the
4233 * decorations placed on a window by the window manager.
4234 * Thus GTK+ is using a "best guess" that works with most
4237 * Moreover, nearly all window managers are historically broken with
4238 * respect to their handling of window gravity. So moving a window to
4239 * its current position as returned by gtk_window_get_position() tends
4240 * to result in moving the window slightly. Window managers are
4241 * slowly getting better over time.
4243 * If a window has gravity #GDK_GRAVITY_STATIC the window manager
4244 * frame is not relevant, and thus gtk_window_get_position() will
4245 * always produce accurate results. However you can't use static
4246 * gravity to do things like place a window in a corner of the screen,
4247 * because static gravity ignores the window manager decorations.
4249 * If you are saving and restoring your application's window
4250 * positions, you should know that it's impossible for applications to
4251 * do this without getting it somewhat wrong because applications do
4252 * not have sufficient knowledge of window manager state. The Correct
4253 * Mechanism is to support the session management protocol (see the
4254 * "GnomeClient" object in the GNOME libraries for example) and allow
4255 * the window manager to save your window sizes and positions.
4260 gtk_window_get_position (GtkWindow *window,
4266 g_return_if_fail (GTK_IS_WINDOW (window));
4268 widget = GTK_WIDGET (window);
4270 if (window->gravity == GDK_GRAVITY_STATIC)
4272 if (gtk_widget_get_mapped (widget))
4274 /* This does a server round-trip, which is sort of wrong;
4275 * but a server round-trip is inevitable for
4276 * gdk_window_get_frame_extents() in the usual
4277 * NorthWestGravity case below, so not sure what else to
4278 * do. We should likely be consistent about whether we get
4279 * the client-side info or the server-side info.
4281 gdk_window_get_origin (widget->window, root_x, root_y);
4285 GdkRectangle configure_request;
4287 gtk_window_compute_configure_request (window,
4291 *root_x = configure_request.x;
4292 *root_y = configure_request.y;
4297 GdkRectangle frame_extents;
4302 if (gtk_widget_get_mapped (widget))
4305 gdk_window_get_frame_extents (window->frame, &frame_extents);
4307 gdk_window_get_frame_extents (widget->window, &frame_extents);
4308 x = frame_extents.x;
4309 y = frame_extents.y;
4310 gtk_window_get_size (window, &w, &h);
4314 /* We just say the frame has 0 size on all sides.
4315 * Not sure what else to do.
4317 gtk_window_compute_configure_request (window,
4320 x = frame_extents.x;
4321 y = frame_extents.y;
4322 w = frame_extents.width;
4323 h = frame_extents.height;
4326 switch (window->gravity)
4328 case GDK_GRAVITY_NORTH:
4329 case GDK_GRAVITY_CENTER:
4330 case GDK_GRAVITY_SOUTH:
4331 /* Find center of frame. */
4332 x += frame_extents.width / 2;
4333 /* Center client window on that point. */
4337 case GDK_GRAVITY_SOUTH_EAST:
4338 case GDK_GRAVITY_EAST:
4339 case GDK_GRAVITY_NORTH_EAST:
4340 /* Find right edge of frame */
4341 x += frame_extents.width;
4342 /* Align left edge of client at that point. */
4349 switch (window->gravity)
4351 case GDK_GRAVITY_WEST:
4352 case GDK_GRAVITY_CENTER:
4353 case GDK_GRAVITY_EAST:
4354 /* Find center of frame. */
4355 y += frame_extents.height / 2;
4356 /* Center client window there. */
4359 case GDK_GRAVITY_SOUTH_WEST:
4360 case GDK_GRAVITY_SOUTH:
4361 case GDK_GRAVITY_SOUTH_EAST:
4362 /* Find south edge of frame */
4363 y += frame_extents.height;
4364 /* Place bottom edge of client there */
4379 * gtk_window_reshow_with_initial_size:
4380 * @window: a #GtkWindow
4382 * Hides @window, then reshows it, resetting the
4383 * default size and position of the window. Used
4384 * by GUI builders only.
4387 gtk_window_reshow_with_initial_size (GtkWindow *window)
4391 g_return_if_fail (GTK_IS_WINDOW (window));
4393 widget = GTK_WIDGET (window);
4395 gtk_widget_hide (widget);
4396 gtk_widget_unrealize (widget);
4397 gtk_widget_show (widget);
4401 gtk_window_destroy (GtkObject *object)
4403 GtkWindow *window = GTK_WINDOW (object);
4405 toplevel_list = g_slist_remove (toplevel_list, window);
4407 if (window->transient_parent)
4408 gtk_window_set_transient_for (window, NULL);
4410 /* frees the icons */
4411 gtk_window_set_icon_list (window, NULL);
4413 if (window->has_user_ref_count)
4415 window->has_user_ref_count = FALSE;
4416 g_object_unref (window);
4420 gtk_window_group_remove_window (window->group, window);
4422 gtk_window_free_key_hash (window);
4424 GTK_OBJECT_CLASS (gtk_window_parent_class)->destroy (object);
4428 gtk_window_finalize (GObject *object)
4430 GtkWindow *window = GTK_WINDOW (object);
4431 GtkWindowPrivate *priv = GTK_WINDOW_GET_PRIVATE (window);
4432 GtkMnemonicHash *mnemonic_hash;
4434 g_free (window->title);
4435 g_free (window->wmclass_name);
4436 g_free (window->wmclass_class);
4437 g_free (window->wm_role);
4439 mnemonic_hash = gtk_window_get_mnemonic_hash (window, FALSE);
4441 _gtk_mnemonic_hash_free (mnemonic_hash);
4443 if (window->geometry_info)
4445 if (window->geometry_info->widget)
4446 g_signal_handlers_disconnect_by_func (window->geometry_info->widget,
4447 gtk_widget_destroyed,
4448 &window->geometry_info->widget);
4449 g_free (window->geometry_info);
4452 if (window->keys_changed_handler)
4454 g_source_remove (window->keys_changed_handler);
4455 window->keys_changed_handler = 0;
4459 g_signal_handlers_disconnect_by_func (window->screen,
4460 gtk_window_on_composited_changed, window);
4462 g_free (priv->startup_id);
4464 G_OBJECT_CLASS (gtk_window_parent_class)->finalize (object);
4468 gtk_window_show (GtkWidget *widget)
4470 GtkWindow *window = GTK_WINDOW (widget);
4471 GtkContainer *container = GTK_CONTAINER (window);
4472 gboolean need_resize;
4474 GTK_WIDGET_SET_FLAGS (widget, GTK_VISIBLE);
4476 need_resize = container->need_resize || !gtk_widget_get_realized (widget);
4477 container->need_resize = FALSE;
4481 GtkWindowGeometryInfo *info = gtk_window_get_geometry_info (window, TRUE);
4482 GtkAllocation allocation = { 0, 0 };
4483 GdkRectangle configure_request;
4484 GdkGeometry new_geometry;
4486 gboolean was_realized;
4488 /* We are going to go ahead and perform this configure request
4489 * and then emulate a configure notify by going ahead and
4490 * doing a size allocate. Sort of a synchronous
4491 * mini-copy of gtk_window_move_resize() here.
4493 gtk_window_compute_configure_request (window,
4498 /* We update this because we are going to go ahead
4499 * and gdk_window_resize() below, rather than
4502 info->last.configure_request.width = configure_request.width;
4503 info->last.configure_request.height = configure_request.height;
4505 /* and allocate the window - this is normally done
4506 * in move_resize in response to configure notify
4508 allocation.width = configure_request.width;
4509 allocation.height = configure_request.height;
4510 gtk_widget_size_allocate (widget, &allocation);
4512 /* Then we guarantee we have a realize */
4513 was_realized = FALSE;
4514 if (!gtk_widget_get_realized (widget))
4516 gtk_widget_realize (widget);
4517 was_realized = TRUE;
4520 /* Must be done after the windows are realized,
4521 * so that the decorations can be read
4523 gtk_decorated_window_calculate_frame_size (window);
4525 /* We only send configure request if we didn't just finish
4526 * creating the window; if we just created the window
4527 * then we created it with widget->allocation anyhow.
4530 gdk_window_move_resize (widget->window,
4531 configure_request.x,
4532 configure_request.y,
4533 configure_request.width,
4534 configure_request.height);
4537 gtk_container_check_resize (container);
4539 gtk_widget_map (widget);
4541 /* Try to make sure that we have some focused widget
4543 if (!window->focus_widget && !GTK_IS_PLUG (window))
4544 gtk_window_move_focus (window, GTK_DIR_TAB_FORWARD);
4547 gtk_grab_add (widget);
4551 gtk_window_hide (GtkWidget *widget)
4553 GtkWindow *window = GTK_WINDOW (widget);
4555 GTK_WIDGET_UNSET_FLAGS (widget, GTK_VISIBLE);
4556 gtk_widget_unmap (widget);
4559 gtk_grab_remove (widget);
4563 gtk_window_map (GtkWidget *widget)
4565 GtkWindow *window = GTK_WINDOW (widget);
4566 GtkWindowPrivate *priv = GTK_WINDOW_GET_PRIVATE (window);
4567 GdkWindow *toplevel;
4568 gboolean auto_mnemonics;
4570 GTK_WIDGET_SET_FLAGS (widget, GTK_MAPPED);
4572 if (window->bin.child &&
4573 gtk_widget_get_visible (window->bin.child) &&
4574 !gtk_widget_get_mapped (window->bin.child))
4575 gtk_widget_map (window->bin.child);
4578 toplevel = window->frame;
4580 toplevel = widget->window;
4582 if (window->maximize_initially)
4583 gdk_window_maximize (toplevel);
4585 gdk_window_unmaximize (toplevel);
4587 if (window->stick_initially)
4588 gdk_window_stick (toplevel);
4590 gdk_window_unstick (toplevel);
4592 if (window->iconify_initially)
4593 gdk_window_iconify (toplevel);
4595 gdk_window_deiconify (toplevel);
4597 if (priv->fullscreen_initially)
4598 gdk_window_fullscreen (toplevel);
4600 gdk_window_unfullscreen (toplevel);
4602 gdk_window_set_keep_above (toplevel, priv->above_initially);
4604 gdk_window_set_keep_below (toplevel, priv->below_initially);
4606 /* No longer use the default settings */
4607 window->need_default_size = FALSE;
4608 window->need_default_position = FALSE;
4610 if (priv->reset_type_hint)
4612 /* We should only reset the type hint when the application
4613 * used gtk_window_set_type_hint() to change the hint.
4614 * Some applications use X directly to change the properties;
4615 * in that case, we shouldn't overwrite what they did.
4617 gdk_window_set_type_hint (widget->window, priv->type_hint);
4618 priv->reset_type_hint = FALSE;
4621 gdk_window_show (widget->window);
4624 gdk_window_show (window->frame);
4626 if (!disable_startup_notification)
4628 /* Do we have a custom startup-notification id? */
4629 if (priv->startup_id != NULL)
4631 /* Make sure we have a "real" id */
4632 if (!startup_id_is_fake (priv->startup_id))
4633 gdk_notify_startup_complete_with_id (priv->startup_id);
4635 g_free (priv->startup_id);
4636 priv->startup_id = NULL;
4638 else if (!sent_startup_notification)
4640 sent_startup_notification = TRUE;
4641 gdk_notify_startup_complete ();
4645 /* if auto-mnemonics is enabled and mnemonics visible is not already set
4646 * (as in the case of popup menus), then hide mnemonics initially
4648 g_object_get (gtk_widget_get_settings (widget), "gtk-auto-mnemonics",
4649 &auto_mnemonics, NULL);
4650 if (auto_mnemonics && !priv->mnemonics_visible_set)
4651 gtk_window_set_mnemonics_visible (window, FALSE);
4655 gtk_window_map_event (GtkWidget *widget,
4658 if (!gtk_widget_get_mapped (widget))
4660 /* we should be be unmapped, but are getting a MapEvent, this may happen
4661 * to toplevel XWindows if mapping was intercepted by a window manager
4662 * and an unmap request occoured while the MapRequestEvent was still
4663 * being handled. we work around this situaiton here by re-requesting
4664 * the window being unmapped. more details can be found in:
4665 * http://bugzilla.gnome.org/show_bug.cgi?id=316180
4667 gdk_window_hide (widget->window);
4673 gtk_window_unmap (GtkWidget *widget)
4675 GtkWindow *window = GTK_WINDOW (widget);
4676 GtkWindowPrivate *priv = GTK_WINDOW_GET_PRIVATE (widget);
4677 GtkWindowGeometryInfo *info;
4678 GdkWindowState state;
4680 GTK_WIDGET_UNSET_FLAGS (widget, GTK_MAPPED);
4682 gdk_window_withdraw (window->frame);
4684 gdk_window_withdraw (widget->window);
4686 window->configure_request_count = 0;
4687 window->configure_notify_received = FALSE;
4689 /* on unmap, we reset the default positioning of the window,
4690 * so it's placed again, but we don't reset the default
4691 * size of the window, so it's remembered.
4693 window->need_default_position = TRUE;
4695 info = gtk_window_get_geometry_info (window, FALSE);
4698 info->initial_pos_set = FALSE;
4699 info->position_constraints_changed = FALSE;
4702 state = gdk_window_get_state (widget->window);
4703 window->iconify_initially = (state & GDK_WINDOW_STATE_ICONIFIED) != 0;
4704 window->maximize_initially = (state & GDK_WINDOW_STATE_MAXIMIZED) != 0;
4705 window->stick_initially = (state & GDK_WINDOW_STATE_STICKY) != 0;
4706 priv->above_initially = (state & GDK_WINDOW_STATE_ABOVE) != 0;
4707 priv->below_initially = (state & GDK_WINDOW_STATE_BELOW) != 0;
4711 gtk_window_realize (GtkWidget *widget)
4714 GdkWindow *parent_window;
4715 GdkWindowAttr attributes;
4716 gint attributes_mask;
4717 GtkWindowPrivate *priv;
4719 window = GTK_WINDOW (widget);
4720 priv = GTK_WINDOW_GET_PRIVATE (window);
4722 /* ensure widget tree is properly size allocated */
4723 if (widget->allocation.x == -1 &&
4724 widget->allocation.y == -1 &&
4725 widget->allocation.width == 1 &&
4726 widget->allocation.height == 1)
4728 GtkRequisition requisition;
4729 GtkAllocation allocation = { 0, 0, 200, 200 };
4731 gtk_widget_size_request (widget, &requisition);
4732 if (requisition.width || requisition.height)
4734 /* non-empty window */
4735 allocation.width = requisition.width;
4736 allocation.height = requisition.height;
4738 gtk_widget_size_allocate (widget, &allocation);
4740 _gtk_container_queue_resize (GTK_CONTAINER (widget));
4742 g_return_if_fail (!gtk_widget_get_realized (widget));
4745 GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED);
4747 switch (window->type)
4749 case GTK_WINDOW_TOPLEVEL:
4750 attributes.window_type = GDK_WINDOW_TOPLEVEL;
4752 case GTK_WINDOW_POPUP:
4753 attributes.window_type = GDK_WINDOW_TEMP;
4756 g_warning (G_STRLOC": Unknown window type %d!", window->type);
4760 attributes.title = window->title;
4761 attributes.wmclass_name = window->wmclass_name;
4762 attributes.wmclass_class = window->wmclass_class;
4763 attributes.wclass = GDK_INPUT_OUTPUT;
4764 attributes.visual = gtk_widget_get_visual (widget);
4765 attributes.colormap = gtk_widget_get_colormap (widget);
4767 if (window->has_frame)
4769 attributes.width = widget->allocation.width + window->frame_left + window->frame_right;
4770 attributes.height = widget->allocation.height + window->frame_top + window->frame_bottom;
4771 attributes.event_mask = (GDK_EXPOSURE_MASK |
4772 GDK_KEY_PRESS_MASK |
4773 GDK_ENTER_NOTIFY_MASK |
4774 GDK_LEAVE_NOTIFY_MASK |
4775 GDK_FOCUS_CHANGE_MASK |
4776 GDK_STRUCTURE_MASK |
4777 GDK_BUTTON_MOTION_MASK |
4778 GDK_POINTER_MOTION_HINT_MASK |
4779 GDK_BUTTON_PRESS_MASK |
4780 GDK_BUTTON_RELEASE_MASK);
4782 attributes_mask = GDK_WA_VISUAL | GDK_WA_COLORMAP;
4784 window->frame = gdk_window_new (gtk_widget_get_root_window (widget),
4785 &attributes, attributes_mask);
4787 if (priv->opacity_set)
4788 gdk_window_set_opacity (window->frame, priv->opacity);
4790 gdk_window_set_user_data (window->frame, widget);
4792 attributes.window_type = GDK_WINDOW_CHILD;
4793 attributes.x = window->frame_left;
4794 attributes.y = window->frame_top;
4796 attributes_mask = GDK_WA_X | GDK_WA_Y;
4798 parent_window = window->frame;
4800 g_signal_connect (window,
4802 G_CALLBACK (gtk_window_event),
4807 attributes_mask = 0;
4808 parent_window = gtk_widget_get_root_window (widget);
4811 attributes.width = widget->allocation.width;
4812 attributes.height = widget->allocation.height;
4813 attributes.event_mask = gtk_widget_get_events (widget);
4814 attributes.event_mask |= (GDK_EXPOSURE_MASK |
4815 GDK_KEY_PRESS_MASK |
4816 GDK_KEY_RELEASE_MASK |
4817 GDK_ENTER_NOTIFY_MASK |
4818 GDK_LEAVE_NOTIFY_MASK |
4819 GDK_FOCUS_CHANGE_MASK |
4820 GDK_STRUCTURE_MASK);
4821 attributes.type_hint = priv->type_hint;
4823 attributes_mask |= GDK_WA_VISUAL | GDK_WA_COLORMAP | GDK_WA_TYPE_HINT;
4824 attributes_mask |= (window->title ? GDK_WA_TITLE : 0);
4825 attributes_mask |= (window->wmclass_name ? GDK_WA_WMCLASS : 0);
4827 widget->window = gdk_window_new (parent_window, &attributes, attributes_mask);
4829 if (!window->has_frame && priv->opacity_set)
4830 gdk_window_set_opacity (widget->window, priv->opacity);
4832 gdk_window_enable_synchronized_configure (widget->window);
4834 gdk_window_set_user_data (widget->window, window);
4836 widget->style = gtk_style_attach (widget->style, widget->window);
4837 gtk_style_set_background (widget->style, widget->window, GTK_STATE_NORMAL);
4839 gtk_style_set_background (widget->style, window->frame, GTK_STATE_NORMAL);
4841 /* This is a bad hack to set the window background. */
4842 gtk_window_paint (widget, NULL);
4844 if (window->transient_parent &&
4845 gtk_widget_get_realized (GTK_WIDGET (window->transient_parent)))
4846 gdk_window_set_transient_for (widget->window,
4847 GTK_WIDGET (window->transient_parent)->window);
4849 if (window->wm_role)
4850 gdk_window_set_role (widget->window, window->wm_role);
4852 if (!window->decorated)
4853 gdk_window_set_decorations (widget->window, 0);
4855 if (!priv->deletable)
4856 gdk_window_set_functions (widget->window, GDK_FUNC_ALL | GDK_FUNC_CLOSE);
4858 if (gtk_window_get_skip_pager_hint (window))
4859 gdk_window_set_skip_pager_hint (widget->window, TRUE);
4861 if (gtk_window_get_skip_taskbar_hint (window))
4862 gdk_window_set_skip_taskbar_hint (widget->window, TRUE);
4864 if (gtk_window_get_accept_focus (window))
4865 gdk_window_set_accept_focus (widget->window, TRUE);
4867 gdk_window_set_accept_focus (widget->window, FALSE);
4869 if (gtk_window_get_focus_on_map (window))
4870 gdk_window_set_focus_on_map (widget->window, TRUE);
4872 gdk_window_set_focus_on_map (widget->window, FALSE);
4875 gdk_window_set_modal_hint (widget->window, TRUE);
4877 gdk_window_set_modal_hint (widget->window, FALSE);
4879 if (priv->startup_id)
4881 #ifdef GDK_WINDOWING_X11
4882 guint32 timestamp = extract_time_from_startup_id (priv->startup_id);
4883 if (timestamp != GDK_CURRENT_TIME)
4884 gdk_x11_window_set_user_time (widget->window, timestamp);
4886 if (!startup_id_is_fake (priv->startup_id))
4887 gdk_window_set_startup_id (widget->window, priv->startup_id);
4891 gtk_window_realize_icon (window);
4895 gtk_window_unrealize (GtkWidget *widget)
4898 GtkWindowGeometryInfo *info;
4900 window = GTK_WINDOW (widget);
4902 /* On unrealize, we reset the size of the window such
4903 * that we will re-apply the default sizing stuff
4904 * next time we show the window.
4906 * Default positioning is reset on unmap, instead of unrealize.
4908 window->need_default_size = TRUE;
4909 info = gtk_window_get_geometry_info (window, FALSE);
4912 info->resize_width = -1;
4913 info->resize_height = -1;
4914 info->last.configure_request.x = 0;
4915 info->last.configure_request.y = 0;
4916 info->last.configure_request.width = -1;
4917 info->last.configure_request.height = -1;
4918 /* be sure we reset geom hints on re-realize */
4919 info->last.flags = 0;
4924 gdk_window_set_user_data (window->frame, NULL);
4925 gdk_window_destroy (window->frame);
4926 window->frame = NULL;
4930 gtk_window_unrealize_icon (window);
4932 GTK_WIDGET_CLASS (gtk_window_parent_class)->unrealize (widget);
4936 gtk_window_size_request (GtkWidget *widget,
4937 GtkRequisition *requisition)
4942 window = GTK_WINDOW (widget);
4943 bin = GTK_BIN (window);
4945 requisition->width = GTK_CONTAINER (window)->border_width * 2;
4946 requisition->height = GTK_CONTAINER (window)->border_width * 2;
4948 if (bin->child && gtk_widget_get_visible (bin->child))
4950 GtkRequisition child_requisition;
4952 gtk_widget_size_request (bin->child, &child_requisition);
4954 requisition->width += child_requisition.width;
4955 requisition->height += child_requisition.height;
4960 gtk_window_size_allocate (GtkWidget *widget,
4961 GtkAllocation *allocation)
4964 GtkAllocation child_allocation;
4966 window = GTK_WINDOW (widget);
4967 widget->allocation = *allocation;
4969 if (window->bin.child && gtk_widget_get_visible (window->bin.child))
4971 child_allocation.x = GTK_CONTAINER (window)->border_width;
4972 child_allocation.y = GTK_CONTAINER (window)->border_width;
4973 child_allocation.width =
4974 MAX (1, (gint)allocation->width - child_allocation.x * 2);
4975 child_allocation.height =
4976 MAX (1, (gint)allocation->height - child_allocation.y * 2);
4978 gtk_widget_size_allocate (window->bin.child, &child_allocation);
4981 if (gtk_widget_get_realized (widget) && window->frame)
4983 gdk_window_resize (window->frame,
4984 allocation->width + window->frame_left + window->frame_right,
4985 allocation->height + window->frame_top + window->frame_bottom);
4990 gtk_window_event (GtkWidget *widget, GdkEvent *event)
4993 gboolean return_val;
4995 window = GTK_WINDOW (widget);
4997 if (window->frame && (event->any.window == window->frame))
4999 if ((event->type != GDK_KEY_PRESS) &&
5000 (event->type != GDK_KEY_RELEASE) &&
5001 (event->type != GDK_FOCUS_CHANGE))
5003 g_signal_stop_emission_by_name (widget, "event");
5005 g_signal_emit (widget, window_signals[FRAME_EVENT], 0, event, &return_val);
5010 g_object_unref (event->any.window);
5011 event->any.window = g_object_ref (widget->window);
5019 gtk_window_frame_event (GtkWindow *window, GdkEvent *event)
5021 GdkEventConfigure *configure_event;
5024 switch (event->type)
5027 configure_event = (GdkEventConfigure *)event;
5029 /* Invalidate the decorations */
5032 rect.width = configure_event->width;
5033 rect.height = configure_event->height;
5035 gdk_window_invalidate_rect (window->frame, &rect, FALSE);
5037 /* Pass on the (modified) configure event */
5038 configure_event->width -= window->frame_left + window->frame_right;
5039 configure_event->height -= window->frame_top + window->frame_bottom;
5040 return gtk_window_configure_event (GTK_WIDGET (window), configure_event);
5049 gtk_window_configure_event (GtkWidget *widget,
5050 GdkEventConfigure *event)
5052 GtkWindow *window = GTK_WINDOW (widget);
5053 gboolean expected_reply = window->configure_request_count > 0;
5055 /* window->configure_request_count incremented for each
5056 * configure request, and decremented to a min of 0 for
5057 * each configure notify.
5059 * All it means is that we know we will get at least
5060 * window->configure_request_count more configure notifies.
5061 * We could get more configure notifies than that; some
5062 * of the configure notifies we get may be unrelated to
5063 * the configure requests. But we will get at least
5064 * window->configure_request_count notifies.
5067 if (window->configure_request_count > 0)
5069 window->configure_request_count -= 1;
5070 gdk_window_thaw_toplevel_updates_libgtk_only (widget->window);
5073 /* As an optimization, we avoid a resize when possible.
5075 * The only times we can avoid a resize are:
5076 * - we know only the position changed, not the size
5077 * - we know we have made more requests and so will get more
5078 * notifies and can wait to resize when we get them
5081 if (!expected_reply &&
5082 (widget->allocation.width == event->width &&
5083 widget->allocation.height == event->height))
5085 gdk_window_configure_finished (widget->window);
5090 * If we do need to resize, we do that by:
5091 * - filling in widget->allocation with the new size
5092 * - setting configure_notify_received to TRUE
5093 * for use in gtk_window_move_resize()
5094 * - queueing a resize, leading to invocation of
5095 * gtk_window_move_resize() in an idle handler
5099 window->configure_notify_received = TRUE;
5101 widget->allocation.width = event->width;
5102 widget->allocation.height = event->height;
5104 _gtk_container_queue_resize (GTK_CONTAINER (widget));
5109 /* the accel_key and accel_mods fields of the key have to be setup
5110 * upon calling this function. it'll then return whether that key
5111 * is at all used as accelerator, and if so will OR in the
5112 * accel_flags member of the key.
5115 _gtk_window_query_nonaccels (GtkWindow *window,
5117 GdkModifierType accel_mods)
5119 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
5121 /* movement keys are considered locked accels */
5124 static const guint bindings[] = {
5125 GDK_space, GDK_KP_Space, GDK_Return, GDK_ISO_Enter, GDK_KP_Enter, GDK_Up, GDK_KP_Up, GDK_Down, GDK_KP_Down,
5126 GDK_Left, GDK_KP_Left, GDK_Right, GDK_KP_Right, GDK_Tab, GDK_KP_Tab, GDK_ISO_Left_Tab,
5130 for (i = 0; i < G_N_ELEMENTS (bindings); i++)
5131 if (bindings[i] == accel_key)
5135 /* mnemonics are considered locked accels */
5136 if (accel_mods == window->mnemonic_modifier)
5138 GtkMnemonicHash *mnemonic_hash = gtk_window_get_mnemonic_hash (window, FALSE);
5139 if (mnemonic_hash && _gtk_mnemonic_hash_lookup (mnemonic_hash, accel_key))
5147 * gtk_window_propagate_key_event:
5148 * @window: a #GtkWindow
5149 * @event: a #GdkEventKey
5151 * Propagate a key press or release event to the focus widget and
5152 * up the focus container chain until a widget handles @event.
5153 * This is normally called by the default ::key_press_event and
5154 * ::key_release_event handlers for toplevel windows,
5155 * however in some cases it may be useful to call this directly when
5156 * overriding the standard key handling for a toplevel window.
5158 * Return value: %TRUE if a widget in the focus chain handled the event.
5163 gtk_window_propagate_key_event (GtkWindow *window,
5166 gboolean handled = FALSE;
5167 GtkWidget *widget, *focus;
5169 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
5171 widget = GTK_WIDGET (window);
5172 focus = window->focus_widget;
5174 g_object_ref (focus);
5177 focus && focus != widget &&
5178 gtk_widget_get_toplevel (focus) == widget)
5182 if (gtk_widget_is_sensitive (focus))
5183 handled = gtk_widget_event (focus, (GdkEvent*) event);
5185 parent = focus->parent;
5187 g_object_ref (parent);
5189 g_object_unref (focus);
5195 g_object_unref (focus);
5201 gtk_window_key_press_event (GtkWidget *widget,
5204 GtkWindow *window = GTK_WINDOW (widget);
5205 gboolean handled = FALSE;
5207 /* handle mnemonics and accelerators */
5209 handled = gtk_window_activate_key (window, event);
5211 /* handle focus widget key events */
5213 handled = gtk_window_propagate_key_event (window, event);
5215 /* Chain up, invokes binding set */
5217 handled = GTK_WIDGET_CLASS (gtk_window_parent_class)->key_press_event (widget, event);
5223 gtk_window_key_release_event (GtkWidget *widget,
5226 GtkWindow *window = GTK_WINDOW (widget);
5227 gboolean handled = FALSE;
5229 /* handle focus widget key events */
5231 handled = gtk_window_propagate_key_event (window, event);
5233 /* Chain up, invokes binding set */
5235 handled = GTK_WIDGET_CLASS (gtk_window_parent_class)->key_release_event (widget, event);
5241 gtk_window_real_activate_default (GtkWindow *window)
5243 gtk_window_activate_default (window);
5247 gtk_window_real_activate_focus (GtkWindow *window)
5249 gtk_window_activate_focus (window);
5253 gtk_window_move_focus (GtkWindow *window,
5254 GtkDirectionType dir)
5256 gtk_widget_child_focus (GTK_WIDGET (window), dir);
5258 if (!GTK_CONTAINER (window)->focus_child)
5259 gtk_window_set_focus (window, NULL);
5263 gtk_window_enter_notify_event (GtkWidget *widget,
5264 GdkEventCrossing *event)
5270 gtk_window_leave_notify_event (GtkWidget *widget,
5271 GdkEventCrossing *event)
5277 do_focus_change (GtkWidget *widget,
5280 GdkEvent *fevent = gdk_event_new (GDK_FOCUS_CHANGE);
5282 g_object_ref (widget);
5285 GTK_WIDGET_SET_FLAGS (widget, GTK_HAS_FOCUS);
5287 GTK_WIDGET_UNSET_FLAGS (widget, GTK_HAS_FOCUS);
5289 fevent->focus_change.type = GDK_FOCUS_CHANGE;
5290 fevent->focus_change.window = widget->window;
5292 g_object_ref (widget->window);
5293 fevent->focus_change.in = in;
5295 gtk_widget_event (widget, fevent);
5297 g_object_notify (G_OBJECT (widget), "has-focus");
5299 g_object_unref (widget);
5300 gdk_event_free (fevent);
5304 gtk_window_focus_in_event (GtkWidget *widget,
5305 GdkEventFocus *event)
5307 GtkWindow *window = GTK_WINDOW (widget);
5309 /* It appears spurious focus in events can occur when
5310 * the window is hidden. So we'll just check to see if
5311 * the window is visible before actually handling the
5314 if (gtk_widget_get_visible (widget))
5316 _gtk_window_set_has_toplevel_focus (window, TRUE);
5317 _gtk_window_set_is_active (window, TRUE);
5324 gtk_window_focus_out_event (GtkWidget *widget,
5325 GdkEventFocus *event)
5327 GtkWindow *window = GTK_WINDOW (widget);
5328 gboolean auto_mnemonics;
5330 _gtk_window_set_has_toplevel_focus (window, FALSE);
5331 _gtk_window_set_is_active (window, FALSE);
5333 /* set the mnemonic-visible property to false */
5334 g_object_get (gtk_widget_get_settings (widget),
5335 "gtk-auto-mnemonics", &auto_mnemonics, NULL);
5337 gtk_window_set_mnemonics_visible (window, FALSE);
5342 static GdkAtom atom_rcfiles = GDK_NONE;
5343 static GdkAtom atom_iconthemes = GDK_NONE;
5346 send_client_message_to_embedded_windows (GtkWidget *widget,
5347 GdkAtom message_type)
5349 GList *embedded_windows;
5351 embedded_windows = g_object_get_qdata (G_OBJECT (widget), quark_gtk_embedded);
5352 if (embedded_windows)
5354 GdkEvent *send_event = gdk_event_new (GDK_CLIENT_EVENT);
5357 for (i = 0; i < 5; i++)
5358 send_event->client.data.l[i] = 0;
5359 send_event->client.data_format = 32;
5360 send_event->client.message_type = message_type;
5362 while (embedded_windows)
5364 GdkNativeWindow xid = GDK_GPOINTER_TO_NATIVE_WINDOW(embedded_windows->data);
5365 gdk_event_send_client_message_for_display (gtk_widget_get_display (widget), send_event, xid);
5366 embedded_windows = embedded_windows->next;
5369 gdk_event_free (send_event);
5374 gtk_window_client_event (GtkWidget *widget,
5375 GdkEventClient *event)
5379 atom_rcfiles = gdk_atom_intern_static_string ("_GTK_READ_RCFILES");
5380 atom_iconthemes = gdk_atom_intern_static_string ("_GTK_LOAD_ICONTHEMES");
5383 if (event->message_type == atom_rcfiles)
5385 send_client_message_to_embedded_windows (widget, atom_rcfiles);
5386 gtk_rc_reparse_all_for_settings (gtk_widget_get_settings (widget), FALSE);
5389 if (event->message_type == atom_iconthemes)
5391 send_client_message_to_embedded_windows (widget, atom_iconthemes);
5392 _gtk_icon_theme_check_reload (gtk_widget_get_display (widget));
5399 gtk_window_check_resize (GtkContainer *container)
5401 if (gtk_widget_get_visible (GTK_WIDGET (container)))
5402 gtk_window_move_resize (GTK_WINDOW (container));
5406 gtk_window_focus (GtkWidget *widget,
5407 GtkDirectionType direction)
5411 GtkContainer *container;
5412 GtkWidget *old_focus_child;
5415 container = GTK_CONTAINER (widget);
5416 window = GTK_WINDOW (widget);
5417 bin = GTK_BIN (widget);
5419 old_focus_child = container->focus_child;
5421 /* We need a special implementation here to deal properly with wrapping
5422 * around in the tab chain without the danger of going into an
5425 if (old_focus_child)
5427 if (gtk_widget_child_focus (old_focus_child, direction))
5431 if (window->focus_widget)
5433 if (direction == GTK_DIR_LEFT ||
5434 direction == GTK_DIR_RIGHT ||
5435 direction == GTK_DIR_UP ||
5436 direction == GTK_DIR_DOWN)
5441 /* Wrapped off the end, clear the focus setting for the toplpevel */
5442 parent = window->focus_widget->parent;
5445 gtk_container_set_focus_child (GTK_CONTAINER (parent), NULL);
5446 parent = GTK_WIDGET (parent)->parent;
5449 gtk_window_set_focus (GTK_WINDOW (container), NULL);
5452 /* Now try to focus the first widget in the window */
5455 if (gtk_widget_child_focus (bin->child, direction))
5463 gtk_window_real_set_focus (GtkWindow *window,
5466 GtkWidget *old_focus = window->focus_widget;
5467 gboolean had_default = FALSE;
5468 gboolean focus_had_default = FALSE;
5469 gboolean old_focus_had_default = FALSE;
5473 g_object_ref (old_focus);
5474 g_object_freeze_notify (G_OBJECT (old_focus));
5475 old_focus_had_default = gtk_widget_has_default (old_focus);
5479 g_object_ref (focus);
5480 g_object_freeze_notify (G_OBJECT (focus));
5481 focus_had_default = gtk_widget_has_default (focus);
5484 if (window->default_widget)
5485 had_default = gtk_widget_has_default (window->default_widget);
5487 if (window->focus_widget)
5489 if (gtk_widget_get_receives_default (window->focus_widget) &&
5490 (window->focus_widget != window->default_widget))
5492 GTK_WIDGET_UNSET_FLAGS (window->focus_widget, GTK_HAS_DEFAULT);
5493 gtk_widget_queue_draw (window->focus_widget);
5495 if (window->default_widget)
5496 GTK_WIDGET_SET_FLAGS (window->default_widget, GTK_HAS_DEFAULT);
5499 window->focus_widget = NULL;
5501 if (window->has_focus)
5502 do_focus_change (old_focus, FALSE);
5504 g_object_notify (G_OBJECT (old_focus), "is-focus");
5507 /* The above notifications may have set a new focus widget,
5508 * if so, we don't want to override it.
5510 if (focus && !window->focus_widget)
5512 window->focus_widget = focus;
5514 if (gtk_widget_get_receives_default (window->focus_widget) &&
5515 (window->focus_widget != window->default_widget))
5517 if (gtk_widget_get_can_default (window->focus_widget))
5518 GTK_WIDGET_SET_FLAGS (window->focus_widget, GTK_HAS_DEFAULT);
5520 if (window->default_widget)
5521 GTK_WIDGET_UNSET_FLAGS (window->default_widget, GTK_HAS_DEFAULT);
5524 if (window->has_focus)
5525 do_focus_change (window->focus_widget, TRUE);
5527 g_object_notify (G_OBJECT (window->focus_widget), "is-focus");
5530 /* If the default widget changed, a redraw will have been queued
5531 * on the old and new default widgets by gtk_window_set_default(), so
5532 * we only have to worry about the case where it didn't change.
5533 * We'll sometimes queue a draw twice on the new widget but that
5536 if (window->default_widget &&
5537 (had_default != gtk_widget_has_default (window->default_widget)))
5538 gtk_widget_queue_draw (window->default_widget);
5542 if (old_focus_had_default != gtk_widget_has_default (old_focus))
5543 gtk_widget_queue_draw (old_focus);
5545 g_object_thaw_notify (G_OBJECT (old_focus));
5546 g_object_unref (old_focus);
5550 if (focus_had_default != gtk_widget_has_default (focus))
5551 gtk_widget_queue_draw (focus);
5553 g_object_thaw_notify (G_OBJECT (focus));
5554 g_object_unref (focus);
5559 * _gtk_window_unset_focus_and_default:
5560 * @window: a #GtkWindow
5561 * @widget: a widget inside of @window
5563 * Checks whether the focus and default widgets of @window are
5564 * @widget or a descendent of @widget, and if so, unset them.
5567 _gtk_window_unset_focus_and_default (GtkWindow *window,
5573 g_object_ref (window);
5574 g_object_ref (widget);
5576 if (GTK_CONTAINER (widget->parent)->focus_child == widget)
5578 child = window->focus_widget;
5580 while (child && child != widget)
5581 child = child->parent;
5583 if (child == widget)
5584 gtk_window_set_focus (GTK_WINDOW (window), NULL);
5587 child = window->default_widget;
5589 while (child && child != widget)
5590 child = child->parent;
5592 if (child == widget)
5593 gtk_window_set_default (window, NULL);
5595 g_object_unref (widget);
5596 g_object_unref (window);
5599 /*********************************
5600 * Functions related to resizing *
5601 *********************************/
5603 /* This function doesn't constrain to geometry hints */
5605 gtk_window_compute_configure_request_size (GtkWindow *window,
5609 GtkRequisition requisition;
5610 GtkWindowGeometryInfo *info;
5614 * - we've done a size request
5617 widget = GTK_WIDGET (window);
5619 info = gtk_window_get_geometry_info (window, FALSE);
5621 if (window->need_default_size)
5623 gtk_widget_get_child_requisition (widget, &requisition);
5625 /* Default to requisition */
5626 *width = requisition.width;
5627 *height = requisition.height;
5629 /* If window is empty so requests 0, default to random nonzero size */
5630 if (*width == 0 && *height == 0)
5636 /* Override requisition with default size */
5640 gint base_width = 0;
5641 gint base_height = 0;
5643 gint min_height = 0;
5645 gint height_inc = 1;
5647 if (info->default_is_geometry &&
5648 (info->default_width > 0 || info->default_height > 0))
5650 GdkGeometry geometry;
5653 gtk_window_compute_hints (window, &geometry, &flags);
5655 if (flags & GDK_HINT_BASE_SIZE)
5657 base_width = geometry.base_width;
5658 base_height = geometry.base_height;
5660 if (flags & GDK_HINT_MIN_SIZE)
5662 min_width = geometry.min_width;
5663 min_height = geometry.min_height;
5665 if (flags & GDK_HINT_RESIZE_INC)
5667 width_inc = geometry.width_inc;
5668 height_inc = geometry.height_inc;
5672 if (info->default_width > 0)
5673 *width = MAX (info->default_width * width_inc + base_width, min_width);
5675 if (info->default_height > 0)
5676 *height = MAX (info->default_height * height_inc + base_height, min_height);
5681 /* Default to keeping current size */
5682 *width = widget->allocation.width;
5683 *height = widget->allocation.height;
5686 /* Override any size with gtk_window_resize() values */
5689 if (info->resize_width > 0)
5690 *width = info->resize_width;
5692 if (info->resize_height > 0)
5693 *height = info->resize_height;
5696 /* Don't ever request zero width or height, its not supported by
5697 gdk. The size allocation code will round it to 1 anyway but if
5698 we do it then the value returned from this function will is
5699 not comparable to the size allocation read from the GtkWindow. */
5700 *width = MAX (*width, 1);
5701 *height = MAX (*height, 1);
5704 static GtkWindowPosition
5705 get_effective_position (GtkWindow *window)
5707 GtkWindowPosition pos = window->position;
5709 if (pos == GTK_WIN_POS_CENTER_ON_PARENT &&
5710 (window->transient_parent == NULL ||
5711 !gtk_widget_get_mapped (GTK_WIDGET (window->transient_parent))))
5712 pos = GTK_WIN_POS_NONE;
5718 get_center_monitor_of_window (GtkWindow *window)
5720 /* We could try to sort out the relative positions of the monitors and
5721 * stuff, or we could just be losers and assume you have a row
5722 * or column of monitors.
5724 return gdk_screen_get_n_monitors (gtk_window_check_screen (window)) / 2;
5728 get_monitor_containing_pointer (GtkWindow *window)
5732 GdkScreen *window_screen;
5733 GdkScreen *pointer_screen;
5735 window_screen = gtk_window_check_screen (window);
5736 gdk_display_get_pointer (gdk_screen_get_display (window_screen),
5740 if (pointer_screen == window_screen)
5741 monitor_num = gdk_screen_get_monitor_at_point (pointer_screen, px, py);
5749 center_window_on_monitor (GtkWindow *window,
5755 GdkRectangle monitor;
5758 monitor_num = get_monitor_containing_pointer (window);
5760 if (monitor_num == -1)
5761 monitor_num = get_center_monitor_of_window (window);
5763 gdk_screen_get_monitor_geometry (gtk_window_check_screen (window),
5764 monitor_num, &monitor);
5766 *x = (monitor.width - w) / 2 + monitor.x;
5767 *y = (monitor.height - h) / 2 + monitor.y;
5769 /* Be sure we aren't off the monitor, ignoring _NET_WM_STRUT
5770 * and WM decorations.
5784 if (extent > clamp_extent)
5786 *base = clamp_base + clamp_extent/2 - extent/2;
5787 else if (*base < clamp_base)
5789 else if (*base + extent > clamp_base + clamp_extent)
5790 *base = clamp_base + clamp_extent - extent;
5794 clamp_window_to_rectangle (gint *x,
5798 const GdkRectangle *rect)
5800 #ifdef DEBUGGING_OUTPUT
5801 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);
5804 /* If it is too large, center it. If it fits on the monitor but is
5805 * partially outside, move it to the closest edge. Do this
5806 * separately in x and y directions.
5808 clamp (x, w, rect->x, rect->width);
5809 clamp (y, h, rect->y, rect->height);
5810 #ifdef DEBUGGING_OUTPUT
5811 g_print (" ==> %+d%+d: %dx%d\n", *x, *y, w, h);
5817 gtk_window_compute_configure_request (GtkWindow *window,
5818 GdkRectangle *request,
5819 GdkGeometry *geometry,
5822 GdkGeometry new_geometry;
5826 GtkWindowPosition pos;
5827 GtkWidget *parent_widget;
5828 GtkWindowGeometryInfo *info;
5832 widget = GTK_WIDGET (window);
5834 screen = gtk_window_check_screen (window);
5836 gtk_widget_size_request (widget, NULL);
5837 gtk_window_compute_configure_request_size (window, (guint *)&w, (guint *)&h);
5839 gtk_window_compute_hints (window, &new_geometry, &new_flags);
5840 gtk_window_constrain_size (window,
5841 &new_geometry, new_flags,
5845 parent_widget = (GtkWidget*) window->transient_parent;
5847 pos = get_effective_position (window);
5848 info = gtk_window_get_geometry_info (window, FALSE);
5850 /* by default, don't change position requested */
5853 x = info->last.configure_request.x;
5854 y = info->last.configure_request.y;
5863 if (window->need_default_position)
5866 /* FIXME this all interrelates with window gravity.
5867 * For most of them I think we want to set GRAVITY_CENTER.
5869 * Not sure how to go about that.
5874 /* here we are only handling CENTER_ALWAYS
5875 * as it relates to default positioning,
5876 * where it's equivalent to simply CENTER
5878 case GTK_WIN_POS_CENTER_ALWAYS:
5879 case GTK_WIN_POS_CENTER:
5880 center_window_on_monitor (window, w, h, &x, &y);
5883 case GTK_WIN_POS_CENTER_ON_PARENT:
5886 GdkRectangle monitor;
5889 g_assert (gtk_widget_get_mapped (parent_widget)); /* established earlier */
5891 if (parent_widget->window != NULL)
5892 monitor_num = gdk_screen_get_monitor_at_window (screen,
5893 parent_widget->window);
5897 gdk_window_get_origin (parent_widget->window,
5900 x = ox + (parent_widget->allocation.width - w) / 2;
5901 y = oy + (parent_widget->allocation.height - h) / 2;
5903 /* Clamp onto current monitor, ignoring _NET_WM_STRUT and
5904 * WM decorations. If parent wasn't on a monitor, just
5907 if (monitor_num >= 0)
5909 gdk_screen_get_monitor_geometry (screen, monitor_num, &monitor);
5910 clamp_window_to_rectangle (&x, &y, w, h, &monitor);
5915 case GTK_WIN_POS_MOUSE:
5917 gint screen_width = gdk_screen_get_width (screen);
5918 gint screen_height = gdk_screen_get_height (screen);
5920 GdkRectangle monitor;
5921 GdkScreen *pointer_screen;
5924 gdk_display_get_pointer (gdk_screen_get_display (screen),
5928 if (pointer_screen == screen)
5929 monitor_num = gdk_screen_get_monitor_at_point (screen, px, py);
5935 x = CLAMP (x, 0, screen_width - w);
5936 y = CLAMP (y, 0, screen_height - h);
5938 /* Clamp onto current monitor, ignoring _NET_WM_STRUT and
5939 * WM decorations. Don't try to figure out what's going
5940 * on if the mouse wasn't inside a monitor.
5942 if (monitor_num >= 0)
5944 gdk_screen_get_monitor_geometry (screen, monitor_num, &monitor);
5945 clamp_window_to_rectangle (&x, &y, w, h, &monitor);
5953 } /* if (window->need_default_position) */
5955 if (window->need_default_position && info &&
5956 info->initial_pos_set)
5958 x = info->initial_x;
5959 y = info->initial_y;
5960 gtk_window_constrain_position (window, w, h, &x, &y);
5966 request->height = h;
5969 *geometry = new_geometry;
5975 gtk_window_constrain_position (GtkWindow *window,
5981 /* See long comments in gtk_window_move_resize()
5982 * on when it's safe to call this function.
5984 if (window->position == GTK_WIN_POS_CENTER_ALWAYS)
5986 gint center_x, center_y;
5988 center_window_on_monitor (window, new_width, new_height, ¢er_x, ¢er_y);
5996 gtk_window_move_resize (GtkWindow *window)
6000 * First we determine whether any information has changed that would
6001 * cause us to revise our last configure request. If we would send
6002 * a different configure request from last time, then
6003 * configure_request_size_changed = TRUE or
6004 * configure_request_pos_changed = TRUE. configure_request_size_changed
6005 * may be true due to new hints, a gtk_window_resize(), or whatever.
6006 * configure_request_pos_changed may be true due to gtk_window_set_position()
6007 * or gtk_window_move().
6009 * If the configure request has changed, we send off a new one. To
6010 * ensure GTK+ invariants are maintained (resize queue does what it
6011 * should), we go ahead and size_allocate the requested size in this
6014 * If the configure request has not changed, we don't ever resend
6015 * it, because it could mean fighting the user or window manager.
6018 * To prepare the configure request, we come up with a base size/pos:
6019 * - the one from gtk_window_move()/gtk_window_resize()
6020 * - else default_width, default_height if we haven't ever
6022 * - else the size request if we haven't ever been mapped,
6023 * as a substitute default size
6024 * - else the current size of the window, as received from
6025 * configure notifies (i.e. the current allocation)
6027 * If GTK_WIN_POS_CENTER_ALWAYS is active, we constrain
6028 * the position request to be centered.
6031 GtkContainer *container;
6032 GtkWindowGeometryInfo *info;
6033 GdkGeometry new_geometry;
6035 GdkRectangle new_request;
6036 gboolean configure_request_size_changed;
6037 gboolean configure_request_pos_changed;
6038 gboolean hints_changed; /* do we need to send these again */
6039 GtkWindowLastGeometryInfo saved_last_info;
6041 widget = GTK_WIDGET (window);
6042 container = GTK_CONTAINER (widget);
6043 info = gtk_window_get_geometry_info (window, TRUE);
6045 configure_request_size_changed = FALSE;
6046 configure_request_pos_changed = FALSE;
6048 gtk_window_compute_configure_request (window, &new_request,
6049 &new_geometry, &new_flags);
6051 /* This check implies the invariant that we never set info->last
6052 * without setting the hints and sending off a configure request.
6054 * If we change info->last without sending the request, we may
6057 if (info->last.configure_request.x != new_request.x ||
6058 info->last.configure_request.y != new_request.y)
6059 configure_request_pos_changed = TRUE;
6061 if ((info->last.configure_request.width != new_request.width ||
6062 info->last.configure_request.height != new_request.height))
6063 configure_request_size_changed = TRUE;
6065 hints_changed = FALSE;
6067 if (!gtk_window_compare_hints (&info->last.geometry, info->last.flags,
6068 &new_geometry, new_flags))
6070 hints_changed = TRUE;
6073 /* Position Constraints
6074 * ====================
6076 * POS_CENTER_ALWAYS is conceptually a constraint rather than
6077 * a default. The other POS_ values are used only when the
6078 * window is shown, not after that.
6080 * However, we can't implement a position constraint as
6081 * "anytime the window size changes, center the window"
6082 * because this may well end up fighting the WM or user. In
6083 * fact it gets in an infinite loop with at least one WM.
6085 * Basically, applications are in no way in a position to
6086 * constrain the position of a window, with one exception:
6087 * override redirect windows. (Really the intended purpose
6088 * of CENTER_ALWAYS anyhow, I would think.)
6090 * So the way we implement this "constraint" is to say that when WE
6091 * cause a move or resize, i.e. we make a configure request changing
6092 * window size, we recompute the CENTER_ALWAYS position to reflect
6093 * the new window size, and include it in our request. Also, if we
6094 * just turned on CENTER_ALWAYS we snap to center with a new
6095 * request. Otherwise, if we are just NOTIFIED of a move or resize
6096 * done by someone else e.g. the window manager, we do NOT send a
6097 * new configure request.
6099 * For override redirect windows, this works fine; all window
6100 * sizes are from our configure requests. For managed windows,
6101 * it is at least semi-sane, though who knows what the
6102 * app author is thinking.
6105 /* This condition should be kept in sync with the condition later on
6106 * that determines whether we send a configure request. i.e. we
6107 * should do this position constraining anytime we were going to
6108 * send a configure request anyhow, plus when constraints have
6111 if (configure_request_pos_changed ||
6112 configure_request_size_changed ||
6114 info->position_constraints_changed)
6116 /* We request the constrained position if:
6117 * - we were changing position, and need to clamp
6118 * the change to the constraint
6119 * - we're changing the size anyway
6120 * - set_position() was called to toggle CENTER_ALWAYS on
6123 gtk_window_constrain_position (window,
6129 /* Update whether we need to request a move */
6130 if (info->last.configure_request.x != new_request.x ||
6131 info->last.configure_request.y != new_request.y)
6132 configure_request_pos_changed = TRUE;
6134 configure_request_pos_changed = FALSE;
6138 if (window->type == GTK_WINDOW_TOPLEVEL)
6140 int notify_x, notify_y;
6142 /* this is the position from the last configure notify */
6143 gdk_window_get_position (widget->window, ¬ify_x, ¬ify_y);
6145 g_message ("--- %s ---\n"
6146 "last : %d,%d\t%d x %d\n"
6147 "this : %d,%d\t%d x %d\n"
6148 "alloc : %d,%d\t%d x %d\n"
6150 "resize: \t%d x %d\n"
6151 "size_changed: %d pos_changed: %d hints_changed: %d\n"
6152 "configure_notify_received: %d\n"
6153 "configure_request_count: %d\n"
6154 "position_constraints_changed: %d\n",
6155 window->title ? window->title : "(no title)",
6156 info->last.configure_request.x,
6157 info->last.configure_request.y,
6158 info->last.configure_request.width,
6159 info->last.configure_request.height,
6165 widget->allocation.width,
6166 widget->allocation.height,
6167 widget->requisition.width,
6168 widget->requisition.height,
6170 info->resize_height,
6171 configure_request_pos_changed,
6172 configure_request_size_changed,
6174 window->configure_notify_received,
6175 window->configure_request_count,
6176 info->position_constraints_changed);
6180 saved_last_info = info->last;
6181 info->last.geometry = new_geometry;
6182 info->last.flags = new_flags;
6183 info->last.configure_request = new_request;
6185 /* need to set PPosition so the WM will look at our position,
6186 * but we don't want to count PPosition coming and going as a hints
6187 * change for future iterations. So we saved info->last prior to
6191 /* Also, if the initial position was explicitly set, then we always
6192 * toggle on PPosition. This makes gtk_window_move(window, 0, 0)
6196 /* Also, we toggle on PPosition if GTK_WIN_POS_ is in use and
6197 * this is an initial map
6200 if ((configure_request_pos_changed ||
6201 info->initial_pos_set ||
6202 (window->need_default_position &&
6203 get_effective_position (window) != GTK_WIN_POS_NONE)) &&
6204 (new_flags & GDK_HINT_POS) == 0)
6206 new_flags |= GDK_HINT_POS;
6207 hints_changed = TRUE;
6210 /* Set hints if necessary
6213 gdk_window_set_geometry_hints (widget->window,
6217 /* handle resizing/moving and widget tree allocation
6219 if (window->configure_notify_received)
6221 GtkAllocation allocation;
6223 /* If we have received a configure event since
6224 * the last time in this function, we need to
6225 * accept our new size and size_allocate child widgets.
6226 * (see gtk_window_configure_event() for more details).
6228 * 1 or more configure notifies may have been received.
6229 * Also, configure_notify_received will only be TRUE
6230 * if all expected configure notifies have been received
6231 * (one per configure request), as an optimization.
6234 window->configure_notify_received = FALSE;
6236 /* gtk_window_configure_event() filled in widget->allocation */
6237 allocation = widget->allocation;
6238 gtk_widget_size_allocate (widget, &allocation);
6240 gdk_window_process_updates (widget->window, TRUE);
6242 gdk_window_configure_finished (widget->window);
6244 /* If the configure request changed, it means that
6246 * 1) coincidentally changed hints or widget properties
6247 * impacting the configure request before getting
6248 * a configure notify, or
6249 * 2) some broken widget is changing its size request
6250 * during size allocation, resulting in
6251 * a false appearance of changed configure request.
6253 * For 1), we could just go ahead and ask for the
6254 * new size right now, but doing that for 2)
6255 * might well be fighting the user (and can even
6256 * trigger a loop). Since we really don't want to
6257 * do that, we requeue a resize in hopes that
6258 * by the time it gets handled, the child has seen
6259 * the light and is willing to go along with the
6260 * new size. (this happens for the zvt widget, since
6261 * the size_allocate() above will have stored the
6262 * requisition corresponding to the new size in the
6265 * This doesn't buy us anything for 1), but it shouldn't
6266 * hurt us too badly, since it is what would have
6267 * happened if we had gotten the configure event before
6268 * the new size had been set.
6271 if (configure_request_size_changed ||
6272 configure_request_pos_changed)
6274 /* Don't change the recorded last info after all, because we
6275 * haven't actually updated to the new info yet - we decided
6276 * to postpone our configure request until later.
6278 info->last = saved_last_info;
6280 gtk_widget_queue_resize_no_redraw (widget); /* migth recurse for GTK_RESIZE_IMMEDIATE */
6283 return; /* Bail out, we didn't really process the move/resize */
6285 else if ((configure_request_size_changed || hints_changed) &&
6286 (widget->allocation.width != new_request.width ||
6287 widget->allocation.height != new_request.height))
6290 /* We are in one of the following situations:
6291 * A. configure_request_size_changed
6292 * our requisition has changed and we need a different window size,
6293 * so we request it from the window manager.
6294 * B. !configure_request_size_changed && hints_changed
6295 * the window manager rejects our size, but we have just changed the
6296 * window manager hints, so there's a chance our request will
6297 * be honoured this time, so we try again.
6299 * However, if the new requisition is the same as the current allocation,
6300 * we don't request it again, since we won't get a ConfigureNotify back from
6301 * the window manager unless it decides to change our requisition. If
6302 * we don't get the ConfigureNotify back, the resize queue will never be run.
6305 /* Now send the configure request */
6306 if (configure_request_pos_changed)
6310 gdk_window_move_resize (window->frame,
6311 new_request.x - window->frame_left,
6312 new_request.y - window->frame_top,
6313 new_request.width + window->frame_left + window->frame_right,
6314 new_request.height + window->frame_top + window->frame_bottom);
6315 gdk_window_resize (widget->window,
6316 new_request.width, new_request.height);
6319 gdk_window_move_resize (widget->window,
6320 new_request.x, new_request.y,
6321 new_request.width, new_request.height);
6323 else /* only size changed */
6326 gdk_window_resize (window->frame,
6327 new_request.width + window->frame_left + window->frame_right,
6328 new_request.height + window->frame_top + window->frame_bottom);
6329 gdk_window_resize (widget->window,
6330 new_request.width, new_request.height);
6333 if (window->type == GTK_WINDOW_POPUP)
6335 GtkAllocation allocation;
6337 /* Directly size allocate for override redirect (popup) windows. */
6340 allocation.width = new_request.width;
6341 allocation.height = new_request.height;
6343 gtk_widget_size_allocate (widget, &allocation);
6345 gdk_window_process_updates (widget->window, TRUE);
6347 if (container->resize_mode == GTK_RESIZE_QUEUE)
6348 gtk_widget_queue_draw (widget);
6352 /* Increment the number of have-not-yet-received-notify requests */
6353 window->configure_request_count += 1;
6354 gdk_window_freeze_toplevel_updates_libgtk_only (widget->window);
6356 /* for GTK_RESIZE_QUEUE toplevels, we are now awaiting a new
6357 * configure event in response to our resizing request.
6358 * the configure event will cause a new resize with
6359 * ->configure_notify_received=TRUE.
6360 * until then, we want to
6361 * - discard expose events
6362 * - coalesce resizes for our children
6363 * - defer any window resizes until the configure event arrived
6364 * to achieve this, we queue a resize for the window, but remove its
6365 * resizing handler, so resizing will not be handled from the next
6366 * idle handler but when the configure event arrives.
6368 * FIXME: we should also dequeue the pending redraws here, since
6369 * we handle those ourselves upon ->configure_notify_received==TRUE.
6371 if (container->resize_mode == GTK_RESIZE_QUEUE)
6373 gtk_widget_queue_resize_no_redraw (widget);
6374 _gtk_container_dequeue_resize_handler (container);
6380 /* Handle any position changes.
6382 if (configure_request_pos_changed)
6386 gdk_window_move (window->frame,
6387 new_request.x - window->frame_left,
6388 new_request.y - window->frame_top);
6391 gdk_window_move (widget->window,
6392 new_request.x, new_request.y);
6395 /* And run the resize queue.
6397 gtk_container_resize_children (container);
6400 /* We have now processed a move/resize since the last position
6401 * constraint change, setting of the initial position, or resize.
6402 * (Not resetting these flags here can lead to infinite loops for
6403 * GTK_RESIZE_IMMEDIATE containers)
6405 info->position_constraints_changed = FALSE;
6406 info->initial_pos_set = FALSE;
6407 info->resize_width = -1;
6408 info->resize_height = -1;
6411 /* Compare two sets of Geometry hints for equality.
6414 gtk_window_compare_hints (GdkGeometry *geometry_a,
6416 GdkGeometry *geometry_b,
6419 if (flags_a != flags_b)
6422 if ((flags_a & GDK_HINT_MIN_SIZE) &&
6423 (geometry_a->min_width != geometry_b->min_width ||
6424 geometry_a->min_height != geometry_b->min_height))
6427 if ((flags_a & GDK_HINT_MAX_SIZE) &&
6428 (geometry_a->max_width != geometry_b->max_width ||
6429 geometry_a->max_height != geometry_b->max_height))
6432 if ((flags_a & GDK_HINT_BASE_SIZE) &&
6433 (geometry_a->base_width != geometry_b->base_width ||
6434 geometry_a->base_height != geometry_b->base_height))
6437 if ((flags_a & GDK_HINT_ASPECT) &&
6438 (geometry_a->min_aspect != geometry_b->min_aspect ||
6439 geometry_a->max_aspect != geometry_b->max_aspect))
6442 if ((flags_a & GDK_HINT_RESIZE_INC) &&
6443 (geometry_a->width_inc != geometry_b->width_inc ||
6444 geometry_a->height_inc != geometry_b->height_inc))
6447 if ((flags_a & GDK_HINT_WIN_GRAVITY) &&
6448 geometry_a->win_gravity != geometry_b->win_gravity)
6455 _gtk_window_constrain_size (GtkWindow *window,
6461 GtkWindowGeometryInfo *info;
6463 g_return_if_fail (GTK_IS_WINDOW (window));
6465 info = window->geometry_info;
6468 GdkWindowHints flags = info->last.flags;
6469 GdkGeometry *geometry = &info->last.geometry;
6471 gtk_window_constrain_size (window,
6482 gtk_window_constrain_size (GtkWindow *window,
6483 GdkGeometry *geometry,
6490 gdk_window_constrain_size (geometry, flags, width, height,
6491 new_width, new_height);
6494 /* Compute the set of geometry hints and flags for a window
6495 * based on the application set geometry, and requisiition
6496 * of the window. gtk_widget_size_request() must have been
6500 gtk_window_compute_hints (GtkWindow *window,
6501 GdkGeometry *new_geometry,
6505 gint extra_width = 0;
6506 gint extra_height = 0;
6507 GtkWindowGeometryInfo *geometry_info;
6508 GtkRequisition requisition;
6510 widget = GTK_WIDGET (window);
6512 gtk_widget_get_child_requisition (widget, &requisition);
6513 geometry_info = gtk_window_get_geometry_info (GTK_WINDOW (widget), FALSE);
6517 *new_flags = geometry_info->mask;
6518 *new_geometry = geometry_info->geometry;
6525 if (geometry_info && geometry_info->widget)
6527 GtkRequisition child_requisition;
6529 /* FIXME: This really isn't right. It gets the min size wrong and forces
6530 * callers to do horrible hacks like set a huge usize on the child requisition
6531 * to get the base size right. We really want to find the answers to:
6533 * - If the geometry widget was infinitely big, how much extra space
6534 * would be needed for the stuff around it.
6536 * - If the geometry widget was infinitely small, how big would the
6537 * window still have to be.
6539 * Finding these answers would be a bit of a mess here. (Bug #68668)
6541 gtk_widget_get_child_requisition (geometry_info->widget, &child_requisition);
6543 extra_width = widget->requisition.width - child_requisition.width;
6544 extra_height = widget->requisition.height - child_requisition.height;
6547 /* We don't want to set GDK_HINT_POS in here, we just set it
6548 * in gtk_window_move_resize() when we want the position
6552 if (*new_flags & GDK_HINT_BASE_SIZE)
6554 new_geometry->base_width += extra_width;
6555 new_geometry->base_height += extra_height;
6557 else if (!(*new_flags & GDK_HINT_MIN_SIZE) &&
6558 (*new_flags & GDK_HINT_RESIZE_INC) &&
6559 ((extra_width != 0) || (extra_height != 0)))
6561 *new_flags |= GDK_HINT_BASE_SIZE;
6563 new_geometry->base_width = extra_width;
6564 new_geometry->base_height = extra_height;
6567 if (*new_flags & GDK_HINT_MIN_SIZE)
6569 if (new_geometry->min_width < 0)
6570 new_geometry->min_width = requisition.width;
6572 new_geometry->min_width += extra_width;
6574 if (new_geometry->min_height < 0)
6575 new_geometry->min_height = requisition.height;
6577 new_geometry->min_height += extra_height;
6579 else if (!window->allow_shrink)
6581 *new_flags |= GDK_HINT_MIN_SIZE;
6583 new_geometry->min_width = requisition.width;
6584 new_geometry->min_height = requisition.height;
6587 if (*new_flags & GDK_HINT_MAX_SIZE)
6589 if (new_geometry->max_width < 0)
6590 new_geometry->max_width = requisition.width;
6592 new_geometry->max_width += extra_width;
6594 if (new_geometry->max_height < 0)
6595 new_geometry->max_height = requisition.height;
6597 new_geometry->max_height += extra_height;
6599 else if (!window->allow_grow)
6601 *new_flags |= GDK_HINT_MAX_SIZE;
6603 new_geometry->max_width = requisition.width;
6604 new_geometry->max_height = requisition.height;
6607 *new_flags |= GDK_HINT_WIN_GRAVITY;
6608 new_geometry->win_gravity = window->gravity;
6611 /***********************
6612 * Redrawing functions *
6613 ***********************/
6616 gtk_window_paint (GtkWidget *widget,
6619 gtk_paint_flat_box (widget->style, widget->window, GTK_STATE_NORMAL,
6620 GTK_SHADOW_NONE, area, widget, "base", 0, 0, -1, -1);
6624 gtk_window_expose (GtkWidget *widget,
6625 GdkEventExpose *event)
6627 if (!gtk_widget_get_app_paintable (widget))
6628 gtk_window_paint (widget, &event->area);
6630 if (GTK_WIDGET_CLASS (gtk_window_parent_class)->expose_event)
6631 return GTK_WIDGET_CLASS (gtk_window_parent_class)->expose_event (widget, event);
6637 * gtk_window_set_has_frame:
6638 * @window: a #GtkWindow
6639 * @setting: a boolean
6641 * (Note: this is a special-purpose function for the framebuffer port,
6642 * that causes GTK+ to draw its own window border. For most applications,
6643 * you want gtk_window_set_decorated() instead, which tells the window
6644 * manager whether to draw the window border.)
6646 * If this function is called on a window with setting of %TRUE, before
6647 * it is realized or showed, it will have a "frame" window around
6648 * @window->window, accessible in @window->frame. Using the signal
6649 * frame_event you can receive all events targeted at the frame.
6651 * This function is used by the linux-fb port to implement managed
6652 * windows, but it could conceivably be used by X-programs that
6653 * want to do their own window decorations.
6657 gtk_window_set_has_frame (GtkWindow *window,
6660 g_return_if_fail (GTK_IS_WINDOW (window));
6661 g_return_if_fail (!gtk_widget_get_realized (GTK_WIDGET (window)));
6663 window->has_frame = setting != FALSE;
6667 * gtk_window_get_has_frame:
6668 * @window: a #GtkWindow
6670 * Accessor for whether the window has a frame window exterior to
6671 * @window->window. Gets the value set by gtk_window_set_has_frame ().
6673 * Return value: %TRUE if a frame has been added to the window
6674 * via gtk_window_set_has_frame().
6677 gtk_window_get_has_frame (GtkWindow *window)
6679 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
6681 return window->has_frame;
6685 * gtk_window_set_frame_dimensions:
6686 * @window: a #GtkWindow that has a frame
6687 * @left: The width of the left border
6688 * @top: The height of the top border
6689 * @right: The width of the right border
6690 * @bottom: The height of the bottom border
6692 * (Note: this is a special-purpose function intended for the framebuffer
6693 * port; see gtk_window_set_has_frame(). It will have no effect on the
6694 * window border drawn by the window manager, which is the normal
6695 * case when using the X Window system.)
6697 * For windows with frames (see gtk_window_set_has_frame()) this function
6698 * can be used to change the size of the frame border.
6701 gtk_window_set_frame_dimensions (GtkWindow *window,
6709 g_return_if_fail (GTK_IS_WINDOW (window));
6711 widget = GTK_WIDGET (window);
6713 if (window->frame_left == left &&
6714 window->frame_top == top &&
6715 window->frame_right == right &&
6716 window->frame_bottom == bottom)
6719 window->frame_left = left;
6720 window->frame_top = top;
6721 window->frame_right = right;
6722 window->frame_bottom = bottom;
6724 if (gtk_widget_get_realized (widget) && window->frame)
6726 gint width = widget->allocation.width + left + right;
6727 gint height = widget->allocation.height + top + bottom;
6728 gdk_window_resize (window->frame, width, height);
6729 gtk_decorated_window_move_resize_window (window,
6731 widget->allocation.width,
6732 widget->allocation.height);
6737 * gtk_window_present:
6738 * @window: a #GtkWindow
6740 * Presents a window to the user. This may mean raising the window
6741 * in the stacking order, deiconifying it, moving it to the current
6742 * desktop, and/or giving it the keyboard focus, possibly dependent
6743 * on the user's platform, window manager, and preferences.
6745 * If @window is hidden, this function calls gtk_widget_show()
6748 * This function should be used when the user tries to open a window
6749 * that's already open. Say for example the preferences dialog is
6750 * currently open, and the user chooses Preferences from the menu
6751 * a second time; use gtk_window_present() to move the already-open dialog
6752 * where the user can see it.
6754 * If you are calling this function in response to a user interaction,
6755 * it is preferable to use gtk_window_present_with_time().
6759 gtk_window_present (GtkWindow *window)
6761 gtk_window_present_with_time (window, GDK_CURRENT_TIME);
6765 * gtk_window_present_with_time:
6766 * @window: a #GtkWindow
6767 * @timestamp: the timestamp of the user interaction (typically a
6768 * button or key press event) which triggered this call
6770 * Presents a window to the user in response to a user interaction.
6771 * If you need to present a window without a timestamp, use
6772 * gtk_window_present(). See gtk_window_present() for details.
6777 gtk_window_present_with_time (GtkWindow *window,
6782 g_return_if_fail (GTK_IS_WINDOW (window));
6784 widget = GTK_WIDGET (window);
6786 if (gtk_widget_get_visible (widget))
6788 g_assert (widget->window != NULL);
6790 gdk_window_show (widget->window);
6792 /* Translate a timestamp of GDK_CURRENT_TIME appropriately */
6793 if (timestamp == GDK_CURRENT_TIME)
6795 #ifdef GDK_WINDOWING_X11
6796 GdkDisplay *display;
6798 display = gtk_widget_get_display (GTK_WIDGET (window));
6799 timestamp = gdk_x11_display_get_user_time (display);
6801 timestamp = gtk_get_current_event_time ();
6805 gdk_window_focus (widget->window, timestamp);
6809 gtk_widget_show (widget);
6814 * gtk_window_iconify:
6815 * @window: a #GtkWindow
6817 * Asks to iconify (i.e. minimize) the specified @window. Note that
6818 * you shouldn't assume the window is definitely iconified afterward,
6819 * because other entities (e.g. the user or <link
6820 * linkend="gtk-X11-arch">window manager</link>) could deiconify it
6821 * again, or there may not be a window manager in which case
6822 * iconification isn't possible, etc. But normally the window will end
6823 * up iconified. Just don't write code that crashes if not.
6825 * It's permitted to call this function before showing a window,
6826 * in which case the window will be iconified before it ever appears
6829 * You can track iconification via the "window-state-event" signal
6834 gtk_window_iconify (GtkWindow *window)
6837 GdkWindow *toplevel;
6839 g_return_if_fail (GTK_IS_WINDOW (window));
6841 widget = GTK_WIDGET (window);
6843 window->iconify_initially = TRUE;
6846 toplevel = window->frame;
6848 toplevel = widget->window;
6850 if (toplevel != NULL)
6851 gdk_window_iconify (toplevel);
6855 * gtk_window_deiconify:
6856 * @window: a #GtkWindow
6858 * Asks to deiconify (i.e. unminimize) the specified @window. Note
6859 * that you shouldn't assume the window is definitely deiconified
6860 * afterward, because other entities (e.g. the user or <link
6861 * linkend="gtk-X11-arch">window manager</link>) could iconify it
6862 * again before your code which assumes deiconification gets to run.
6864 * You can track iconification via the "window-state-event" signal
6868 gtk_window_deiconify (GtkWindow *window)
6871 GdkWindow *toplevel;
6873 g_return_if_fail (GTK_IS_WINDOW (window));
6875 widget = GTK_WIDGET (window);
6877 window->iconify_initially = FALSE;
6880 toplevel = window->frame;
6882 toplevel = widget->window;
6884 if (toplevel != NULL)
6885 gdk_window_deiconify (toplevel);
6890 * @window: a #GtkWindow
6892 * Asks to stick @window, which means that it will appear on all user
6893 * desktops. Note that you shouldn't assume the window is definitely
6894 * stuck afterward, because other entities (e.g. the user or <link
6895 * linkend="gtk-X11-arch">window manager</link>) could unstick it
6896 * again, and some window managers do not support sticking
6897 * windows. But normally the window will end up stuck. Just don't
6898 * write code that crashes if not.
6900 * It's permitted to call this function before showing a window.
6902 * You can track stickiness via the "window-state-event" signal
6907 gtk_window_stick (GtkWindow *window)
6910 GdkWindow *toplevel;
6912 g_return_if_fail (GTK_IS_WINDOW (window));
6914 widget = GTK_WIDGET (window);
6916 window->stick_initially = TRUE;
6919 toplevel = window->frame;
6921 toplevel = widget->window;
6923 if (toplevel != NULL)
6924 gdk_window_stick (toplevel);
6928 * gtk_window_unstick:
6929 * @window: a #GtkWindow
6931 * Asks to unstick @window, which means that it will appear on only
6932 * one of the user's desktops. Note that you shouldn't assume the
6933 * window is definitely unstuck afterward, because other entities
6934 * (e.g. the user or <link linkend="gtk-X11-arch">window
6935 * manager</link>) could stick it again. But normally the window will
6936 * end up stuck. Just don't write code that crashes if not.
6938 * You can track stickiness via the "window-state-event" signal
6943 gtk_window_unstick (GtkWindow *window)
6946 GdkWindow *toplevel;
6948 g_return_if_fail (GTK_IS_WINDOW (window));
6950 widget = GTK_WIDGET (window);
6952 window->stick_initially = FALSE;
6955 toplevel = window->frame;
6957 toplevel = widget->window;
6959 if (toplevel != NULL)
6960 gdk_window_unstick (toplevel);
6964 * gtk_window_maximize:
6965 * @window: a #GtkWindow
6967 * Asks to maximize @window, so that it becomes full-screen. Note that
6968 * you shouldn't assume the window is definitely maximized afterward,
6969 * because other entities (e.g. the user or <link
6970 * linkend="gtk-X11-arch">window manager</link>) could unmaximize it
6971 * again, and not all window managers support maximization. But
6972 * normally the window will end up maximized. Just don't write code
6973 * that crashes if not.
6975 * It's permitted to call this function before showing a window,
6976 * in which case the window will be maximized when it appears onscreen
6979 * You can track maximization via the "window-state-event" signal
6984 gtk_window_maximize (GtkWindow *window)
6987 GdkWindow *toplevel;
6989 g_return_if_fail (GTK_IS_WINDOW (window));
6991 widget = GTK_WIDGET (window);
6993 window->maximize_initially = TRUE;
6996 toplevel = window->frame;
6998 toplevel = widget->window;
7000 if (toplevel != NULL)
7001 gdk_window_maximize (toplevel);
7005 * gtk_window_unmaximize:
7006 * @window: a #GtkWindow
7008 * Asks to unmaximize @window. Note that you shouldn't assume the
7009 * window is definitely unmaximized afterward, because other entities
7010 * (e.g. the user or <link linkend="gtk-X11-arch">window
7011 * manager</link>) could maximize it again, and not all window
7012 * managers honor requests to unmaximize. But normally the window will
7013 * end up unmaximized. Just don't write code that crashes if not.
7015 * You can track maximization via the "window-state-event" signal
7020 gtk_window_unmaximize (GtkWindow *window)
7023 GdkWindow *toplevel;
7025 g_return_if_fail (GTK_IS_WINDOW (window));
7027 widget = GTK_WIDGET (window);
7029 window->maximize_initially = FALSE;
7032 toplevel = window->frame;
7034 toplevel = widget->window;
7036 if (toplevel != NULL)
7037 gdk_window_unmaximize (toplevel);
7041 * gtk_window_fullscreen:
7042 * @window: a #GtkWindow
7044 * Asks to place @window in the fullscreen state. Note that you
7045 * shouldn't assume the window is definitely full screen afterward,
7046 * because other entities (e.g. the user or <link
7047 * linkend="gtk-X11-arch">window manager</link>) could unfullscreen it
7048 * again, and not all window managers honor requests to fullscreen
7049 * windows. But normally the window will end up fullscreen. Just
7050 * don't write code that crashes if not.
7052 * You can track the fullscreen state via the "window-state-event" signal
7058 gtk_window_fullscreen (GtkWindow *window)
7061 GdkWindow *toplevel;
7062 GtkWindowPrivate *priv;
7064 g_return_if_fail (GTK_IS_WINDOW (window));
7066 widget = GTK_WIDGET (window);
7067 priv = GTK_WINDOW_GET_PRIVATE (window);
7069 priv->fullscreen_initially = TRUE;
7072 toplevel = window->frame;
7074 toplevel = widget->window;
7076 if (toplevel != NULL)
7077 gdk_window_fullscreen (toplevel);
7081 * gtk_window_unfullscreen:
7082 * @window: a #GtkWindow
7084 * Asks to toggle off the fullscreen state for @window. Note that you
7085 * shouldn't assume the window is definitely not full screen
7086 * afterward, because other entities (e.g. the user or <link
7087 * linkend="gtk-X11-arch">window manager</link>) could fullscreen it
7088 * again, and not all window managers honor requests to unfullscreen
7089 * windows. But normally the window will end up restored to its normal
7090 * state. Just don't write code that crashes if not.
7092 * You can track the fullscreen state via the "window-state-event" signal
7098 gtk_window_unfullscreen (GtkWindow *window)
7101 GdkWindow *toplevel;
7102 GtkWindowPrivate *priv;
7104 g_return_if_fail (GTK_IS_WINDOW (window));
7106 widget = GTK_WIDGET (window);
7107 priv = GTK_WINDOW_GET_PRIVATE (window);
7109 priv->fullscreen_initially = FALSE;
7112 toplevel = window->frame;
7114 toplevel = widget->window;
7116 if (toplevel != NULL)
7117 gdk_window_unfullscreen (toplevel);
7121 * gtk_window_set_keep_above:
7122 * @window: a #GtkWindow
7123 * @setting: whether to keep @window above other windows
7125 * Asks to keep @window above, so that it stays on top. Note that
7126 * you shouldn't assume the window is definitely above afterward,
7127 * because other entities (e.g. the user or <link
7128 * linkend="gtk-X11-arch">window manager</link>) could not keep it above,
7129 * and not all window managers support keeping windows above. But
7130 * normally the window will end kept above. Just don't write code
7131 * that crashes if not.
7133 * It's permitted to call this function before showing a window,
7134 * in which case the window will be kept above when it appears onscreen
7137 * You can track the above state via the "window-state-event" signal
7140 * Note that, according to the <ulink
7141 * url="http://www.freedesktop.org/Standards/wm-spec">Extended Window
7142 * Manager Hints</ulink> specification, the above state is mainly meant
7143 * for user preferences and should not be used by applications e.g. for
7144 * drawing attention to their dialogs.
7149 gtk_window_set_keep_above (GtkWindow *window,
7153 GtkWindowPrivate *priv;
7154 GdkWindow *toplevel;
7156 g_return_if_fail (GTK_IS_WINDOW (window));
7158 widget = GTK_WIDGET (window);
7159 priv = GTK_WINDOW_GET_PRIVATE (window);
7161 priv->above_initially = setting != FALSE;
7163 priv->below_initially = FALSE;
7166 toplevel = window->frame;
7168 toplevel = widget->window;
7170 if (toplevel != NULL)
7171 gdk_window_set_keep_above (toplevel, setting);
7175 * gtk_window_set_keep_below:
7176 * @window: a #GtkWindow
7177 * @setting: whether to keep @window below other windows
7179 * Asks to keep @window below, so that it stays in bottom. Note that
7180 * you shouldn't assume the window is definitely below afterward,
7181 * because other entities (e.g. the user or <link
7182 * linkend="gtk-X11-arch">window manager</link>) could not keep it below,
7183 * and not all window managers support putting windows below. But
7184 * normally the window will be kept below. Just don't write code
7185 * that crashes if not.
7187 * It's permitted to call this function before showing a window,
7188 * in which case the window will be kept below when it appears onscreen
7191 * You can track the below state via the "window-state-event" signal
7194 * Note that, according to the <ulink
7195 * url="http://www.freedesktop.org/Standards/wm-spec">Extended Window
7196 * Manager Hints</ulink> specification, the above state is mainly meant
7197 * for user preferences and should not be used by applications e.g. for
7198 * drawing attention to their dialogs.
7203 gtk_window_set_keep_below (GtkWindow *window,
7207 GtkWindowPrivate *priv;
7208 GdkWindow *toplevel;
7210 g_return_if_fail (GTK_IS_WINDOW (window));
7212 widget = GTK_WIDGET (window);
7213 priv = GTK_WINDOW_GET_PRIVATE (window);
7215 priv->below_initially = setting != FALSE;
7217 priv->above_initially = FALSE;
7220 toplevel = window->frame;
7222 toplevel = widget->window;
7224 if (toplevel != NULL)
7225 gdk_window_set_keep_below (toplevel, setting);
7229 * gtk_window_set_resizable:
7230 * @window: a #GtkWindow
7231 * @resizable: %TRUE if the user can resize this window
7233 * Sets whether the user can resize a window. Windows are user resizable
7237 gtk_window_set_resizable (GtkWindow *window,
7240 g_return_if_fail (GTK_IS_WINDOW (window));
7242 gtk_window_set_policy_internal (window, FALSE, resizable, FALSE);
7246 * gtk_window_get_resizable:
7247 * @window: a #GtkWindow
7249 * Gets the value set by gtk_window_set_resizable().
7251 * Return value: %TRUE if the user can resize the window
7254 gtk_window_get_resizable (GtkWindow *window)
7256 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
7258 /* allow_grow is most likely to indicate the semantic concept we
7259 * mean by "resizable" (and will be a reliable indicator if
7260 * set_policy() hasn't been called)
7262 return window->allow_grow;
7266 * gtk_window_set_gravity:
7267 * @window: a #GtkWindow
7268 * @gravity: window gravity
7270 * Window gravity defines the meaning of coordinates passed to
7271 * gtk_window_move(). See gtk_window_move() and #GdkGravity for
7274 * The default window gravity is #GDK_GRAVITY_NORTH_WEST which will
7275 * typically "do what you mean."
7279 gtk_window_set_gravity (GtkWindow *window,
7282 g_return_if_fail (GTK_IS_WINDOW (window));
7284 if (gravity != window->gravity)
7286 window->gravity = gravity;
7288 /* gtk_window_move_resize() will adapt gravity
7290 gtk_widget_queue_resize_no_redraw (GTK_WIDGET (window));
7292 g_object_notify (G_OBJECT (window), "gravity");
7297 * gtk_window_get_gravity:
7298 * @window: a #GtkWindow
7300 * Gets the value set by gtk_window_set_gravity().
7302 * Return value: (transfer none): window gravity
7305 gtk_window_get_gravity (GtkWindow *window)
7307 g_return_val_if_fail (GTK_IS_WINDOW (window), 0);
7309 return window->gravity;
7313 * gtk_window_begin_resize_drag:
7314 * @window: a #GtkWindow
7315 * @button: mouse button that initiated the drag
7316 * @edge: position of the resize control
7317 * @root_x: X position where the user clicked to initiate the drag, in root window coordinates
7318 * @root_y: Y position where the user clicked to initiate the drag
7319 * @timestamp: timestamp from the click event that initiated the drag
7321 * Starts resizing a window. This function is used if an application
7322 * has window resizing controls. When GDK can support it, the resize
7323 * will be done using the standard mechanism for the <link
7324 * linkend="gtk-X11-arch">window manager</link> or windowing
7325 * system. Otherwise, GDK will try to emulate window resizing,
7326 * potentially not all that well, depending on the windowing system.
7330 gtk_window_begin_resize_drag (GtkWindow *window,
7338 GdkWindow *toplevel;
7340 g_return_if_fail (GTK_IS_WINDOW (window));
7341 widget = GTK_WIDGET (window);
7342 g_return_if_fail (gtk_widget_get_visible (widget));
7345 toplevel = window->frame;
7347 toplevel = widget->window;
7349 gdk_window_begin_resize_drag (toplevel,
7356 * gtk_window_get_frame_dimensions:
7357 * @window: a #GtkWindow
7358 * @left: (allow-none): location to store the width of the frame at the left, or %NULL
7359 * @top: (allow-none): location to store the height of the frame at the top, or %NULL
7360 * @right: (allow-none): location to store the width of the frame at the returns, or %NULL
7361 * @bottom: (allow-none): location to store the height of the frame at the bottom, or %NULL
7363 * (Note: this is a special-purpose function intended for the
7364 * framebuffer port; see gtk_window_set_has_frame(). It will not
7365 * return the size of the window border drawn by the <link
7366 * linkend="gtk-X11-arch">window manager</link>, which is the normal
7367 * case when using a windowing system. See
7368 * gdk_window_get_frame_extents() to get the standard window border
7371 * Retrieves the dimensions of the frame window for this toplevel.
7372 * See gtk_window_set_has_frame(), gtk_window_set_frame_dimensions().
7375 gtk_window_get_frame_dimensions (GtkWindow *window,
7381 g_return_if_fail (GTK_IS_WINDOW (window));
7384 *left = window->frame_left;
7386 *top = window->frame_top;
7388 *right = window->frame_right;
7390 *bottom = window->frame_bottom;
7394 * gtk_window_begin_move_drag:
7395 * @window: a #GtkWindow
7396 * @button: mouse button that initiated the drag
7397 * @root_x: X position where the user clicked to initiate the drag, in root window coordinates
7398 * @root_y: Y position where the user clicked to initiate the drag
7399 * @timestamp: timestamp from the click event that initiated the drag
7401 * Starts moving a window. This function is used if an application has
7402 * window movement grips. When GDK can support it, the window movement
7403 * will be done using the standard mechanism for the <link
7404 * linkend="gtk-X11-arch">window manager</link> or windowing
7405 * system. Otherwise, GDK will try to emulate window movement,
7406 * potentially not all that well, depending on the windowing system.
7410 gtk_window_begin_move_drag (GtkWindow *window,
7417 GdkWindow *toplevel;
7419 g_return_if_fail (GTK_IS_WINDOW (window));
7420 widget = GTK_WIDGET (window);
7421 g_return_if_fail (gtk_widget_get_visible (widget));
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_get_mapped (widget);
7465 gtk_widget_unmap (widget);
7466 if (gtk_widget_get_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: (allow-none): 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_is_toplevel (GTK_WIDGET (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_is_toplevel (GTK_WIDGET (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;
8476 /* gtk_window_get_mnemonics_visible:
8477 * @window: a #GtkWindow
8479 * Gets the value of the #GtkWindow:mnemonics-visible property.
8481 * Returns: %TRUE if mnemonics are supposed to be visible
8487 gtk_window_get_mnemonics_visible (GtkWindow *window)
8489 GtkWindowPrivate *priv;
8491 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
8493 priv = GTK_WINDOW_GET_PRIVATE (window);
8495 return priv->mnemonics_visible;
8499 * gtk_window_set_mnemonics_visible:
8500 * @window: a #GtkWindow
8501 * @setting: the new value
8503 * Sets the #GtkWindow:mnemonics-visible property.
8508 gtk_window_set_mnemonics_visible (GtkWindow *window,
8511 GtkWindowPrivate *priv;
8513 g_return_if_fail (GTK_IS_WINDOW (window));
8515 priv = GTK_WINDOW_GET_PRIVATE (window);
8517 setting = setting != FALSE;
8519 if (priv->mnemonics_visible != setting)
8521 priv->mnemonics_visible = setting;
8522 g_object_notify (G_OBJECT (window), "mnemonics-visible");
8525 priv->mnemonics_visible_set = TRUE;
8528 #if defined (G_OS_WIN32) && !defined (_WIN64)
8530 #undef gtk_window_set_icon_from_file
8533 gtk_window_set_icon_from_file (GtkWindow *window,
8534 const gchar *filename,
8537 gchar *utf8_filename = g_locale_to_utf8 (filename, -1, NULL, NULL, err);
8540 if (utf8_filename == NULL)
8543 retval = gtk_window_set_icon_from_file_utf8 (window, utf8_filename, err);
8545 g_free (utf8_filename);
8550 #undef gtk_window_set_default_icon_from_file
8553 gtk_window_set_default_icon_from_file (const gchar *filename,
8556 gchar *utf8_filename = g_locale_to_utf8 (filename, -1, NULL, NULL, err);
8559 if (utf8_filename == NULL)
8562 retval = gtk_window_set_default_icon_from_file_utf8 (utf8_filename, err);
8564 g_free (utf8_filename);
8571 #define __GTK_WINDOW_C__
8572 #include "gtkaliasdef.c"