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_set_has_window (GTK_WIDGET (window), TRUE);
904 _gtk_widget_set_is_toplevel (GTK_WIDGET (window), TRUE);
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_set_has_default (window->default_widget, FALSE);
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_has_default (window->default_widget, TRUE);
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, or %NULL
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 * Passing %NULL for @parent unsets the current transient window.
2283 * On Windows, this function puts the child window on top of the parent,
2284 * much as the window manager would have done on X.
2287 gtk_window_set_transient_for (GtkWindow *window,
2290 GtkWindowPrivate *priv;
2292 g_return_if_fail (GTK_IS_WINDOW (window));
2293 g_return_if_fail (parent == NULL || GTK_IS_WINDOW (parent));
2294 g_return_if_fail (window != parent);
2296 priv = GTK_WINDOW_GET_PRIVATE (window);
2298 if (window->transient_parent)
2300 if (gtk_widget_get_realized (GTK_WIDGET (window)) &&
2301 gtk_widget_get_realized (GTK_WIDGET (window->transient_parent)) &&
2302 (!parent || !gtk_widget_get_realized (GTK_WIDGET (parent))))
2303 gtk_window_transient_parent_unrealized (GTK_WIDGET (window->transient_parent),
2304 GTK_WIDGET (window));
2306 gtk_window_unset_transient_for (window);
2309 window->transient_parent = parent;
2313 g_signal_connect (parent, "destroy",
2314 G_CALLBACK (gtk_widget_destroyed),
2315 &window->transient_parent);
2316 g_signal_connect (parent, "realize",
2317 G_CALLBACK (gtk_window_transient_parent_realized),
2319 g_signal_connect (parent, "unrealize",
2320 G_CALLBACK (gtk_window_transient_parent_unrealized),
2322 g_signal_connect (parent, "notify::screen",
2323 G_CALLBACK (gtk_window_transient_parent_screen_changed),
2326 gtk_window_set_screen (window, parent->screen);
2328 if (window->destroy_with_parent)
2329 connect_parent_destroyed (window);
2331 if (gtk_widget_get_realized (GTK_WIDGET (window)) &&
2332 gtk_widget_get_realized (GTK_WIDGET (parent)))
2333 gtk_window_transient_parent_realized (GTK_WIDGET (parent),
2334 GTK_WIDGET (window));
2338 gtk_window_group_add_window (parent->group, window);
2339 priv->transient_parent_group = TRUE;
2345 * gtk_window_get_transient_for:
2346 * @window: a #GtkWindow
2348 * Fetches the transient parent for this window. See
2349 * gtk_window_set_transient_for().
2351 * Return value: (transfer none): the transient parent for this window, or %NULL
2352 * if no transient parent has been set.
2355 gtk_window_get_transient_for (GtkWindow *window)
2357 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
2359 return window->transient_parent;
2363 * gtk_window_set_opacity:
2364 * @window: a #GtkWindow
2365 * @opacity: desired opacity, between 0 and 1
2367 * Request the windowing system to make @window partially transparent,
2368 * with opacity 0 being fully transparent and 1 fully opaque. (Values
2369 * of the opacity parameter are clamped to the [0,1] range.) On X11
2370 * this has any effect only on X screens with a compositing manager
2371 * running. See gtk_widget_is_composited(). On Windows it should work
2374 * Note that setting a window's opacity after the window has been
2375 * shown causes it to flicker once on Windows.
2380 gtk_window_set_opacity (GtkWindow *window,
2383 GtkWindowPrivate *priv;
2385 g_return_if_fail (GTK_IS_WINDOW (window));
2387 priv = GTK_WINDOW_GET_PRIVATE (window);
2391 else if (opacity > 1.0)
2394 priv->opacity_set = TRUE;
2395 priv->opacity = opacity;
2397 if (gtk_widget_get_realized (GTK_WIDGET (window)))
2398 gdk_window_set_opacity (GTK_WIDGET (window)->window, priv->opacity);
2402 * gtk_window_get_opacity:
2403 * @window: a #GtkWindow
2405 * Fetches the requested opacity for this window. See
2406 * gtk_window_set_opacity().
2408 * Return value: the requested opacity for this window.
2413 gtk_window_get_opacity (GtkWindow *window)
2415 GtkWindowPrivate *priv;
2417 g_return_val_if_fail (GTK_IS_WINDOW (window), 0.0);
2419 priv = GTK_WINDOW_GET_PRIVATE (window);
2421 return priv->opacity;
2425 * gtk_window_set_type_hint:
2426 * @window: a #GtkWindow
2427 * @hint: the window type
2429 * By setting the type hint for the window, you allow the window
2430 * manager to decorate and handle the window in a way which is
2431 * suitable to the function of the window in your application.
2433 * This function should be called before the window becomes visible.
2435 * gtk_dialog_new_with_buttons() and other convenience functions in GTK+
2436 * will sometimes call gtk_window_set_type_hint() on your behalf.
2440 gtk_window_set_type_hint (GtkWindow *window,
2441 GdkWindowTypeHint hint)
2443 GtkWindowPrivate *priv;
2445 g_return_if_fail (GTK_IS_WINDOW (window));
2446 g_return_if_fail (!gtk_widget_get_mapped (GTK_WIDGET (window)));
2448 priv = GTK_WINDOW_GET_PRIVATE (window);
2450 if (hint < GDK_WINDOW_TYPE_HINT_DROPDOWN_MENU)
2451 window->type_hint = hint;
2453 window->type_hint = GDK_WINDOW_TYPE_HINT_NORMAL;
2455 priv->reset_type_hint = TRUE;
2456 priv->type_hint = hint;
2460 * gtk_window_get_type_hint:
2461 * @window: a #GtkWindow
2463 * Gets the type hint for this window. See gtk_window_set_type_hint().
2465 * Return value: the type hint for @window.
2468 gtk_window_get_type_hint (GtkWindow *window)
2470 GtkWindowPrivate *priv;
2472 g_return_val_if_fail (GTK_IS_WINDOW (window), GDK_WINDOW_TYPE_HINT_NORMAL);
2474 priv = GTK_WINDOW_GET_PRIVATE (window);
2476 return priv->type_hint;
2480 * gtk_window_set_skip_taskbar_hint:
2481 * @window: a #GtkWindow
2482 * @setting: %TRUE to keep this window from appearing in the task bar
2484 * Windows may set a hint asking the desktop environment not to display
2485 * the window in the task bar. This function sets this hint.
2490 gtk_window_set_skip_taskbar_hint (GtkWindow *window,
2493 GtkWindowPrivate *priv;
2495 g_return_if_fail (GTK_IS_WINDOW (window));
2497 priv = GTK_WINDOW_GET_PRIVATE (window);
2499 setting = setting != FALSE;
2501 if (priv->skips_taskbar != setting)
2503 priv->skips_taskbar = setting;
2504 if (gtk_widget_get_realized (GTK_WIDGET (window)))
2505 gdk_window_set_skip_taskbar_hint (GTK_WIDGET (window)->window,
2506 priv->skips_taskbar);
2507 g_object_notify (G_OBJECT (window), "skip-taskbar-hint");
2512 * gtk_window_get_skip_taskbar_hint:
2513 * @window: a #GtkWindow
2515 * Gets the value set by gtk_window_set_skip_taskbar_hint()
2517 * Return value: %TRUE if window shouldn't be in taskbar
2522 gtk_window_get_skip_taskbar_hint (GtkWindow *window)
2524 GtkWindowPrivate *priv;
2526 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
2528 priv = GTK_WINDOW_GET_PRIVATE (window);
2530 return priv->skips_taskbar;
2534 * gtk_window_set_skip_pager_hint:
2535 * @window: a #GtkWindow
2536 * @setting: %TRUE to keep this window from appearing in the pager
2538 * Windows may set a hint asking the desktop environment not to display
2539 * the window in the pager. This function sets this hint.
2540 * (A "pager" is any desktop navigation tool such as a workspace
2541 * switcher that displays a thumbnail representation of the windows
2547 gtk_window_set_skip_pager_hint (GtkWindow *window,
2550 GtkWindowPrivate *priv;
2552 g_return_if_fail (GTK_IS_WINDOW (window));
2554 priv = GTK_WINDOW_GET_PRIVATE (window);
2556 setting = setting != FALSE;
2558 if (priv->skips_pager != setting)
2560 priv->skips_pager = setting;
2561 if (gtk_widget_get_realized (GTK_WIDGET (window)))
2562 gdk_window_set_skip_pager_hint (GTK_WIDGET (window)->window,
2564 g_object_notify (G_OBJECT (window), "skip-pager-hint");
2569 * gtk_window_get_skip_pager_hint:
2570 * @window: a #GtkWindow
2572 * Gets the value set by gtk_window_set_skip_pager_hint().
2574 * Return value: %TRUE if window shouldn't be in pager
2579 gtk_window_get_skip_pager_hint (GtkWindow *window)
2581 GtkWindowPrivate *priv;
2583 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
2585 priv = GTK_WINDOW_GET_PRIVATE (window);
2587 return priv->skips_pager;
2591 * gtk_window_set_urgency_hint:
2592 * @window: a #GtkWindow
2593 * @setting: %TRUE to mark this window as urgent
2595 * Windows may set a hint asking the desktop environment to draw
2596 * the users attention to the window. This function sets this hint.
2601 gtk_window_set_urgency_hint (GtkWindow *window,
2604 GtkWindowPrivate *priv;
2606 g_return_if_fail (GTK_IS_WINDOW (window));
2608 priv = GTK_WINDOW_GET_PRIVATE (window);
2610 setting = setting != FALSE;
2612 if (priv->urgent != setting)
2614 priv->urgent = setting;
2615 if (gtk_widget_get_realized (GTK_WIDGET (window)))
2616 gdk_window_set_urgency_hint (GTK_WIDGET (window)->window,
2618 g_object_notify (G_OBJECT (window), "urgency-hint");
2623 * gtk_window_get_urgency_hint:
2624 * @window: a #GtkWindow
2626 * Gets the value set by gtk_window_set_urgency_hint()
2628 * Return value: %TRUE if window is urgent
2633 gtk_window_get_urgency_hint (GtkWindow *window)
2635 GtkWindowPrivate *priv;
2637 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
2639 priv = GTK_WINDOW_GET_PRIVATE (window);
2641 return priv->urgent;
2645 * gtk_window_set_accept_focus:
2646 * @window: a #GtkWindow
2647 * @setting: %TRUE to let this window receive input focus
2649 * Windows may set a hint asking the desktop environment not to receive
2650 * the input focus. This function sets this hint.
2655 gtk_window_set_accept_focus (GtkWindow *window,
2658 GtkWindowPrivate *priv;
2660 g_return_if_fail (GTK_IS_WINDOW (window));
2662 priv = GTK_WINDOW_GET_PRIVATE (window);
2664 setting = setting != FALSE;
2666 if (priv->accept_focus != setting)
2668 priv->accept_focus = setting;
2669 if (gtk_widget_get_realized (GTK_WIDGET (window)))
2670 gdk_window_set_accept_focus (GTK_WIDGET (window)->window,
2671 priv->accept_focus);
2672 g_object_notify (G_OBJECT (window), "accept-focus");
2677 * gtk_window_get_accept_focus:
2678 * @window: a #GtkWindow
2680 * Gets the value set by gtk_window_set_accept_focus().
2682 * Return value: %TRUE if window should receive the input focus
2687 gtk_window_get_accept_focus (GtkWindow *window)
2689 GtkWindowPrivate *priv;
2691 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
2693 priv = GTK_WINDOW_GET_PRIVATE (window);
2695 return priv->accept_focus;
2699 * gtk_window_set_focus_on_map:
2700 * @window: a #GtkWindow
2701 * @setting: %TRUE to let this window receive input focus on map
2703 * Windows may set a hint asking the desktop environment not to receive
2704 * the input focus when the window is mapped. This function sets this
2710 gtk_window_set_focus_on_map (GtkWindow *window,
2713 GtkWindowPrivate *priv;
2715 g_return_if_fail (GTK_IS_WINDOW (window));
2717 priv = GTK_WINDOW_GET_PRIVATE (window);
2719 setting = setting != FALSE;
2721 if (priv->focus_on_map != setting)
2723 priv->focus_on_map = setting;
2724 if (gtk_widget_get_realized (GTK_WIDGET (window)))
2725 gdk_window_set_focus_on_map (GTK_WIDGET (window)->window,
2726 priv->focus_on_map);
2727 g_object_notify (G_OBJECT (window), "focus-on-map");
2732 * gtk_window_get_focus_on_map:
2733 * @window: a #GtkWindow
2735 * Gets the value set by gtk_window_set_focus_on_map().
2737 * Return value: %TRUE if window should receive the input focus when
2743 gtk_window_get_focus_on_map (GtkWindow *window)
2745 GtkWindowPrivate *priv;
2747 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
2749 priv = GTK_WINDOW_GET_PRIVATE (window);
2751 return priv->focus_on_map;
2755 * gtk_window_set_destroy_with_parent:
2756 * @window: a #GtkWindow
2757 * @setting: whether to destroy @window with its transient parent
2759 * If @setting is %TRUE, then destroying the transient parent of @window
2760 * will also destroy @window itself. This is useful for dialogs that
2761 * shouldn't persist beyond the lifetime of the main window they're
2762 * associated with, for example.
2765 gtk_window_set_destroy_with_parent (GtkWindow *window,
2768 g_return_if_fail (GTK_IS_WINDOW (window));
2770 if (window->destroy_with_parent == (setting != FALSE))
2773 if (window->destroy_with_parent)
2775 disconnect_parent_destroyed (window);
2779 connect_parent_destroyed (window);
2782 window->destroy_with_parent = setting;
2784 g_object_notify (G_OBJECT (window), "destroy-with-parent");
2788 * gtk_window_get_destroy_with_parent:
2789 * @window: a #GtkWindow
2791 * Returns whether the window will be destroyed with its transient parent. See
2792 * gtk_window_set_destroy_with_parent ().
2794 * Return value: %TRUE if the window will be destroyed with its transient parent.
2797 gtk_window_get_destroy_with_parent (GtkWindow *window)
2799 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
2801 return window->destroy_with_parent;
2804 static GtkWindowGeometryInfo*
2805 gtk_window_get_geometry_info (GtkWindow *window,
2808 GtkWindowGeometryInfo *info;
2810 info = window->geometry_info;
2811 if (!info && create)
2813 info = g_new0 (GtkWindowGeometryInfo, 1);
2815 info->default_width = -1;
2816 info->default_height = -1;
2817 info->resize_width = -1;
2818 info->resize_height = -1;
2819 info->initial_x = 0;
2820 info->initial_y = 0;
2821 info->initial_pos_set = FALSE;
2822 info->default_is_geometry = FALSE;
2823 info->position_constraints_changed = FALSE;
2824 info->last.configure_request.x = 0;
2825 info->last.configure_request.y = 0;
2826 info->last.configure_request.width = -1;
2827 info->last.configure_request.height = -1;
2828 info->widget = NULL;
2830 window->geometry_info = info;
2837 * gtk_window_set_geometry_hints:
2838 * @window: a #GtkWindow
2839 * @geometry_widget: widget the geometry hints will be applied to
2840 * @geometry: struct containing geometry information
2841 * @geom_mask: mask indicating which struct fields should be paid attention to
2843 * This function sets up hints about how a window can be resized by
2844 * the user. You can set a minimum and maximum size; allowed resize
2845 * increments (e.g. for xterm, you can only resize by the size of a
2846 * character); aspect ratios; and more. See the #GdkGeometry struct.
2850 gtk_window_set_geometry_hints (GtkWindow *window,
2851 GtkWidget *geometry_widget,
2852 GdkGeometry *geometry,
2853 GdkWindowHints geom_mask)
2855 GtkWindowGeometryInfo *info;
2857 g_return_if_fail (GTK_IS_WINDOW (window));
2858 g_return_if_fail (geometry_widget == NULL || GTK_IS_WIDGET (geometry_widget));
2860 info = gtk_window_get_geometry_info (window, TRUE);
2863 g_signal_handlers_disconnect_by_func (info->widget,
2864 gtk_widget_destroyed,
2867 info->widget = geometry_widget;
2869 g_signal_connect (geometry_widget, "destroy",
2870 G_CALLBACK (gtk_widget_destroyed),
2874 info->geometry = *geometry;
2876 /* We store gravity in window->gravity not in the hints. */
2877 info->mask = geom_mask & ~(GDK_HINT_WIN_GRAVITY);
2879 if (geom_mask & GDK_HINT_WIN_GRAVITY)
2881 gtk_window_set_gravity (window, geometry->win_gravity);
2884 gtk_widget_queue_resize_no_redraw (GTK_WIDGET (window));
2888 * gtk_window_set_decorated:
2889 * @window: a #GtkWindow
2890 * @setting: %TRUE to decorate the window
2892 * By default, windows are decorated with a title bar, resize
2893 * controls, etc. Some <link linkend="gtk-X11-arch">window
2894 * managers</link> allow GTK+ to disable these decorations, creating a
2895 * borderless window. If you set the decorated property to %FALSE
2896 * using this function, GTK+ will do its best to convince the window
2897 * manager not to decorate the window. Depending on the system, this
2898 * function may not have any effect when called on a window that is
2899 * already visible, so you should call it before calling gtk_window_show().
2901 * On Windows, this function always works, since there's no window manager
2906 gtk_window_set_decorated (GtkWindow *window,
2909 g_return_if_fail (GTK_IS_WINDOW (window));
2911 setting = setting != FALSE;
2913 if (setting == window->decorated)
2916 window->decorated = setting;
2918 if (GTK_WIDGET (window)->window)
2920 if (window->decorated)
2921 gdk_window_set_decorations (GTK_WIDGET (window)->window,
2924 gdk_window_set_decorations (GTK_WIDGET (window)->window,
2928 g_object_notify (G_OBJECT (window), "decorated");
2932 * gtk_window_get_decorated:
2933 * @window: a #GtkWindow
2935 * Returns whether the window has been set to have decorations
2936 * such as a title bar via gtk_window_set_decorated().
2938 * Return value: %TRUE if the window has been set to have decorations
2941 gtk_window_get_decorated (GtkWindow *window)
2943 g_return_val_if_fail (GTK_IS_WINDOW (window), TRUE);
2945 return window->decorated;
2949 * gtk_window_set_deletable:
2950 * @window: a #GtkWindow
2951 * @setting: %TRUE to decorate the window as deletable
2953 * By default, windows have a close button in the window frame. Some
2954 * <link linkend="gtk-X11-arch">window managers</link> allow GTK+ to
2955 * disable this button. If you set the deletable property to %FALSE
2956 * using this function, GTK+ will do its best to convince the window
2957 * manager not to show a close button. Depending on the system, this
2958 * function may not have any effect when called on a window that is
2959 * already visible, so you should call it before calling gtk_window_show().
2961 * On Windows, this function always works, since there's no window manager
2967 gtk_window_set_deletable (GtkWindow *window,
2970 GtkWindowPrivate *priv;
2972 g_return_if_fail (GTK_IS_WINDOW (window));
2974 priv = GTK_WINDOW_GET_PRIVATE (window);
2976 setting = setting != FALSE;
2978 if (setting == priv->deletable)
2981 priv->deletable = setting;
2983 if (GTK_WIDGET (window)->window)
2985 if (priv->deletable)
2986 gdk_window_set_functions (GTK_WIDGET (window)->window,
2989 gdk_window_set_functions (GTK_WIDGET (window)->window,
2990 GDK_FUNC_ALL | GDK_FUNC_CLOSE);
2993 g_object_notify (G_OBJECT (window), "deletable");
2997 * gtk_window_get_deletable:
2998 * @window: a #GtkWindow
3000 * Returns whether the window has been set to have a close button
3001 * via gtk_window_set_deletable().
3003 * Return value: %TRUE if the window has been set to have a close button
3008 gtk_window_get_deletable (GtkWindow *window)
3010 GtkWindowPrivate *priv;
3012 g_return_val_if_fail (GTK_IS_WINDOW (window), TRUE);
3014 priv = GTK_WINDOW_GET_PRIVATE (window);
3016 return priv->deletable;
3019 static GtkWindowIconInfo*
3020 get_icon_info (GtkWindow *window)
3022 return g_object_get_qdata (G_OBJECT (window), quark_gtk_window_icon_info);
3026 free_icon_info (GtkWindowIconInfo *info)
3028 g_free (info->icon_name);
3029 g_slice_free (GtkWindowIconInfo, info);
3033 static GtkWindowIconInfo*
3034 ensure_icon_info (GtkWindow *window)
3036 GtkWindowIconInfo *info;
3038 info = get_icon_info (window);
3042 info = g_slice_new0 (GtkWindowIconInfo);
3043 g_object_set_qdata_full (G_OBJECT (window),
3044 quark_gtk_window_icon_info,
3046 (GDestroyNotify)free_icon_info);
3058 static ScreenIconInfo *
3059 get_screen_icon_info (GdkScreen *screen)
3061 ScreenIconInfo *info = g_object_get_qdata (G_OBJECT (screen),
3062 quark_gtk_window_default_icon_pixmap);
3065 info = g_slice_new0 (ScreenIconInfo);
3066 g_object_set_qdata (G_OBJECT (screen),
3067 quark_gtk_window_default_icon_pixmap, info);
3070 if (info->serial != default_icon_serial)
3074 g_object_remove_weak_pointer (G_OBJECT (info->pixmap), (gpointer*)&info->pixmap);
3075 info->pixmap = NULL;
3080 g_object_remove_weak_pointer (G_OBJECT (info->mask), (gpointer*)&info->mask);
3084 info->serial = default_icon_serial;
3091 get_pixmap_and_mask (GdkWindow *window,
3092 GtkWindowIconInfo *parent_info,
3093 gboolean is_default_list,
3095 GdkPixmap **pmap_return,
3096 GdkBitmap **mask_return)
3098 GdkScreen *screen = gdk_drawable_get_screen (window);
3099 ScreenIconInfo *default_icon_info = get_screen_icon_info (screen);
3100 GdkPixbuf *best_icon;
3104 *pmap_return = NULL;
3105 *mask_return = NULL;
3107 if (is_default_list &&
3108 default_icon_info->pixmap != NULL)
3110 /* Use shared icon pixmap for all windows on this screen.
3112 if (default_icon_info->pixmap)
3113 g_object_ref (default_icon_info->pixmap);
3114 if (default_icon_info->mask)
3115 g_object_ref (default_icon_info->mask);
3117 *pmap_return = default_icon_info->pixmap;
3118 *mask_return = default_icon_info->mask;
3120 else if (parent_info && parent_info->icon_pixmap)
3122 if (parent_info->icon_pixmap)
3123 g_object_ref (parent_info->icon_pixmap);
3124 if (parent_info->icon_mask)
3125 g_object_ref (parent_info->icon_mask);
3127 *pmap_return = parent_info->icon_pixmap;
3128 *mask_return = parent_info->icon_mask;
3132 #define IDEAL_SIZE 48
3134 best_size = G_MAXINT;
3136 tmp_list = icon_list;
3137 while (tmp_list != NULL)
3139 GdkPixbuf *pixbuf = tmp_list->data;
3142 /* average width and height - if someone passes in a rectangular
3143 * icon they deserve what they get.
3145 this = gdk_pixbuf_get_width (pixbuf) + gdk_pixbuf_get_height (pixbuf);
3148 if (best_icon == NULL)
3155 /* icon is better if it's 32 pixels or larger, and closer to
3156 * the ideal size than the current best.
3159 (ABS (best_size - IDEAL_SIZE) <
3160 ABS (this - IDEAL_SIZE)))
3167 tmp_list = tmp_list->next;
3171 gdk_pixbuf_render_pixmap_and_mask_for_colormap (best_icon,
3172 gdk_screen_get_system_colormap (screen),
3177 /* Save pmap/mask for others to use if appropriate */
3180 parent_info->icon_pixmap = *pmap_return;
3181 parent_info->icon_mask = *mask_return;
3183 if (parent_info->icon_pixmap)
3184 g_object_ref (parent_info->icon_pixmap);
3185 if (parent_info->icon_mask)
3186 g_object_ref (parent_info->icon_mask);
3188 else if (is_default_list)
3190 default_icon_info->pixmap = *pmap_return;
3191 default_icon_info->mask = *mask_return;
3193 if (default_icon_info->pixmap)
3194 g_object_add_weak_pointer (G_OBJECT (default_icon_info->pixmap),
3195 (gpointer*)&default_icon_info->pixmap);
3196 if (default_icon_info->mask)
3197 g_object_add_weak_pointer (G_OBJECT (default_icon_info->mask),
3198 (gpointer*)&default_icon_info->mask);
3204 icon_list_from_theme (GtkWidget *widget,
3209 GtkIconTheme *icon_theme;
3214 icon_theme = gtk_icon_theme_get_for_screen (gtk_widget_get_screen (widget));
3216 sizes = gtk_icon_theme_get_icon_sizes (icon_theme, name);
3219 for (i = 0; sizes[i]; i++)
3222 * We need an EWMH extension to handle scalable icons
3223 * by passing their name to the WM. For now just use a
3227 icon = gtk_icon_theme_load_icon (icon_theme, name,
3230 icon = gtk_icon_theme_load_icon (icon_theme, name,
3233 list = g_list_append (list, icon);
3243 gtk_window_realize_icon (GtkWindow *window)
3246 GtkWindowIconInfo *info;
3249 widget = GTK_WIDGET (window);
3251 g_return_if_fail (widget->window != NULL);
3253 /* no point setting an icon on override-redirect */
3254 if (window->type == GTK_WINDOW_POPUP)
3259 info = ensure_icon_info (window);
3264 g_return_if_fail (info->icon_pixmap == NULL);
3265 g_return_if_fail (info->icon_mask == NULL);
3267 info->using_default_icon = FALSE;
3268 info->using_parent_icon = FALSE;
3269 info->using_themed_icon = FALSE;
3271 icon_list = info->icon_list;
3273 /* Look up themed icon */
3274 if (icon_list == NULL && info->icon_name)
3276 icon_list = icon_list_from_theme (widget, info->icon_name);
3278 info->using_themed_icon = TRUE;
3281 /* Inherit from transient parent */
3282 if (icon_list == NULL && window->transient_parent)
3284 icon_list = ensure_icon_info (window->transient_parent)->icon_list;
3286 info->using_parent_icon = TRUE;
3289 /* Inherit from default */
3290 if (icon_list == NULL)
3292 icon_list = default_icon_list;
3294 info->using_default_icon = TRUE;
3297 /* Look up themed icon */
3298 if (icon_list == NULL && default_icon_name)
3300 icon_list = icon_list_from_theme (widget, default_icon_name);
3301 info->using_default_icon = TRUE;
3302 info->using_themed_icon = TRUE;
3305 gdk_window_set_icon_list (widget->window, icon_list);
3307 get_pixmap_and_mask (widget->window,
3308 info->using_parent_icon ? ensure_icon_info (window->transient_parent) : NULL,
3309 info->using_default_icon,
3314 /* This is a slight ICCCM violation since it's a color pixmap not
3315 * a bitmap, but everyone does it.
3317 gdk_window_set_icon (widget->window,
3322 info->realized = TRUE;
3324 if (info->using_themed_icon)
3326 GtkIconTheme *icon_theme;
3328 g_list_foreach (icon_list, (GFunc) g_object_unref, NULL);
3329 g_list_free (icon_list);
3331 icon_theme = gtk_icon_theme_get_for_screen (gtk_widget_get_screen (GTK_WIDGET (window)));
3332 g_signal_connect (icon_theme, "changed",
3333 G_CALLBACK (update_themed_icon), window);
3338 gtk_window_unrealize_icon (GtkWindow *window)
3340 GtkWindowIconInfo *info;
3342 info = get_icon_info (window);
3347 if (info->icon_pixmap)
3348 g_object_unref (info->icon_pixmap);
3350 if (info->icon_mask)
3351 g_object_unref (info->icon_mask);
3353 info->icon_pixmap = NULL;
3354 info->icon_mask = NULL;
3356 if (info->using_themed_icon)
3358 GtkIconTheme *icon_theme;
3360 icon_theme = gtk_icon_theme_get_for_screen (gtk_widget_get_screen (GTK_WIDGET (window)));
3362 g_signal_handlers_disconnect_by_func (icon_theme, update_themed_icon, window);
3365 /* We don't clear the properties on the window, just figure the
3366 * window is going away.
3369 info->realized = FALSE;
3374 * gtk_window_set_icon_list:
3375 * @window: a #GtkWindow
3376 * @list: list of #GdkPixbuf
3378 * Sets up the icon representing a #GtkWindow. The icon is used when
3379 * the window is minimized (also known as iconified). Some window
3380 * managers or desktop environments may also place it in the window
3381 * frame, or display it in other contexts.
3383 * gtk_window_set_icon_list() allows you to pass in the same icon in
3384 * several hand-drawn sizes. The list should contain the natural sizes
3385 * your icon is available in; that is, don't scale the image before
3386 * passing it to GTK+. Scaling is postponed until the last minute,
3387 * when the desired final size is known, to allow best quality.
3389 * By passing several sizes, you may improve the final image quality
3390 * of the icon, by reducing or eliminating automatic image scaling.
3392 * Recommended sizes to provide: 16x16, 32x32, 48x48 at minimum, and
3393 * larger images (64x64, 128x128) if you have them.
3395 * See also gtk_window_set_default_icon_list() to set the icon
3396 * for all windows in your application in one go.
3398 * Note that transient windows (those who have been set transient for another
3399 * window using gtk_window_set_transient_for()) will inherit their
3400 * icon from their transient parent. So there's no need to explicitly
3401 * set the icon on transient windows.
3404 gtk_window_set_icon_list (GtkWindow *window,
3407 GtkWindowIconInfo *info;
3409 g_return_if_fail (GTK_IS_WINDOW (window));
3411 info = ensure_icon_info (window);
3413 if (info->icon_list == list) /* check for NULL mostly */
3416 g_list_foreach (list,
3417 (GFunc) g_object_ref, NULL);
3419 g_list_foreach (info->icon_list,
3420 (GFunc) g_object_unref, NULL);
3422 g_list_free (info->icon_list);
3424 info->icon_list = g_list_copy (list);
3426 g_object_notify (G_OBJECT (window), "icon");
3428 gtk_window_unrealize_icon (window);
3430 if (gtk_widget_get_realized (GTK_WIDGET (window)))
3431 gtk_window_realize_icon (window);
3433 /* We could try to update our transient children, but I don't think
3434 * it's really worth it. If we did it, the best way would probably
3435 * be to have children connect to notify::icon-list
3440 * gtk_window_get_icon_list:
3441 * @window: a #GtkWindow
3443 * Retrieves the list of icons set by gtk_window_set_icon_list().
3444 * The list is copied, but the reference count on each
3445 * member won't be incremented.
3447 * Return value: (element-type GdkPixbuf) (transfer container): copy of window's icon list
3450 gtk_window_get_icon_list (GtkWindow *window)
3452 GtkWindowIconInfo *info;
3454 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
3456 info = get_icon_info (window);
3459 return g_list_copy (info->icon_list);
3465 * gtk_window_set_icon:
3466 * @window: a #GtkWindow
3467 * @icon: (allow-none): icon image, or %NULL
3469 * Sets up the icon representing a #GtkWindow. This icon is used when
3470 * the window is minimized (also known as iconified). Some window
3471 * managers or desktop environments may also place it in the window
3472 * frame, or display it in other contexts.
3474 * The icon should be provided in whatever size it was naturally
3475 * drawn; that is, don't scale the image before passing it to
3476 * GTK+. Scaling is postponed until the last minute, when the desired
3477 * final size is known, to allow best quality.
3479 * If you have your icon hand-drawn in multiple sizes, use
3480 * gtk_window_set_icon_list(). Then the best size will be used.
3482 * This function is equivalent to calling gtk_window_set_icon_list()
3483 * with a 1-element list.
3485 * See also gtk_window_set_default_icon_list() to set the icon
3486 * for all windows in your application in one go.
3489 gtk_window_set_icon (GtkWindow *window,
3494 g_return_if_fail (GTK_IS_WINDOW (window));
3495 g_return_if_fail (icon == NULL || GDK_IS_PIXBUF (icon));
3500 list = g_list_append (list, icon);
3502 gtk_window_set_icon_list (window, list);
3508 update_themed_icon (GtkIconTheme *icon_theme,
3511 g_object_notify (G_OBJECT (window), "icon");
3513 gtk_window_unrealize_icon (window);
3515 if (gtk_widget_get_realized (GTK_WIDGET (window)))
3516 gtk_window_realize_icon (window);
3520 * gtk_window_set_icon_name:
3521 * @window: a #GtkWindow
3522 * @name: (allow-none): the name of the themed icon
3524 * Sets the icon for the window from a named themed icon. See
3525 * the docs for #GtkIconTheme for more details.
3527 * Note that this has nothing to do with the WM_ICON_NAME
3528 * property which is mentioned in the ICCCM.
3533 gtk_window_set_icon_name (GtkWindow *window,
3536 GtkWindowIconInfo *info;
3539 g_return_if_fail (GTK_IS_WINDOW (window));
3541 info = ensure_icon_info (window);
3543 if (g_strcmp0 (info->icon_name, name) == 0)
3546 tmp = info->icon_name;
3547 info->icon_name = g_strdup (name);
3550 g_list_foreach (info->icon_list, (GFunc) g_object_unref, NULL);
3551 g_list_free (info->icon_list);
3552 info->icon_list = NULL;
3554 update_themed_icon (NULL, window);
3556 g_object_notify (G_OBJECT (window), "icon-name");
3560 * gtk_window_get_icon_name:
3561 * @window: a #GtkWindow
3563 * Returns the name of the themed icon for the window,
3564 * see gtk_window_set_icon_name().
3566 * Returns: the icon name or %NULL if the window has
3572 gtk_window_get_icon_name (GtkWindow *window)
3574 GtkWindowIconInfo *info;
3576 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
3578 info = ensure_icon_info (window);
3580 return info->icon_name;
3584 * gtk_window_get_icon:
3585 * @window: a #GtkWindow
3587 * Gets the value set by gtk_window_set_icon() (or if you've
3588 * called gtk_window_set_icon_list(), gets the first icon in
3591 * Return value: (transfer none): icon for window
3594 gtk_window_get_icon (GtkWindow *window)
3596 GtkWindowIconInfo *info;
3598 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
3600 info = get_icon_info (window);
3601 if (info && info->icon_list)
3602 return GDK_PIXBUF (info->icon_list->data);
3607 /* Load pixbuf, printing warning on failure if error == NULL
3610 load_pixbuf_verbosely (const char *filename,
3613 GError *local_err = NULL;
3616 pixbuf = gdk_pixbuf_new_from_file (filename, &local_err);
3624 g_warning ("Error loading icon from file '%s':\n\t%s",
3625 filename, local_err->message);
3626 g_error_free (local_err);
3634 * gtk_window_set_icon_from_file:
3635 * @window: a #GtkWindow
3636 * @filename: location of icon file
3637 * @err: (allow-none): location to store error, or %NULL.
3639 * Sets the icon for @window.
3640 * Warns on failure if @err is %NULL.
3642 * This function is equivalent to calling gtk_window_set_icon()
3643 * with a pixbuf created by loading the image from @filename.
3645 * Returns: %TRUE if setting the icon succeeded.
3650 gtk_window_set_icon_from_file (GtkWindow *window,
3651 const gchar *filename,
3654 GdkPixbuf *pixbuf = load_pixbuf_verbosely (filename, err);
3658 gtk_window_set_icon (window, pixbuf);
3659 g_object_unref (pixbuf);
3668 * gtk_window_set_default_icon_list:
3669 * @list: a list of #GdkPixbuf
3671 * Sets an icon list to be used as fallback for windows that haven't
3672 * had gtk_window_set_icon_list() called on them to set up a
3673 * window-specific icon list. This function allows you to set up the
3674 * icon for all windows in your app at once.
3676 * See gtk_window_set_icon_list() for more details.
3680 gtk_window_set_default_icon_list (GList *list)
3684 if (list == default_icon_list)
3687 /* Update serial so we don't used cached pixmaps/masks
3689 default_icon_serial++;
3691 g_list_foreach (list,
3692 (GFunc) g_object_ref, NULL);
3694 g_list_foreach (default_icon_list,
3695 (GFunc) g_object_unref, NULL);
3697 g_list_free (default_icon_list);
3699 default_icon_list = g_list_copy (list);
3701 /* Update all toplevels */
3702 toplevels = gtk_window_list_toplevels ();
3703 tmp_list = toplevels;
3704 while (tmp_list != NULL)
3706 GtkWindowIconInfo *info;
3707 GtkWindow *w = tmp_list->data;
3709 info = get_icon_info (w);
3710 if (info && info->using_default_icon)
3712 gtk_window_unrealize_icon (w);
3713 if (gtk_widget_get_realized (GTK_WIDGET (w)))
3714 gtk_window_realize_icon (w);
3717 tmp_list = tmp_list->next;
3719 g_list_free (toplevels);
3723 * gtk_window_set_default_icon:
3726 * Sets an icon to be used as fallback for windows that haven't
3727 * had gtk_window_set_icon() called on them from a pixbuf.
3732 gtk_window_set_default_icon (GdkPixbuf *icon)
3736 g_return_if_fail (GDK_IS_PIXBUF (icon));
3738 list = g_list_prepend (NULL, icon);
3739 gtk_window_set_default_icon_list (list);
3744 * gtk_window_set_default_icon_name:
3745 * @name: the name of the themed icon
3747 * Sets an icon to be used as fallback for windows that haven't
3748 * had gtk_window_set_icon_list() called on them from a named
3749 * themed icon, see gtk_window_set_icon_name().
3754 gtk_window_set_default_icon_name (const gchar *name)
3759 /* Update serial so we don't used cached pixmaps/masks
3761 default_icon_serial++;
3763 g_free (default_icon_name);
3764 default_icon_name = g_strdup (name);
3766 g_list_foreach (default_icon_list,
3767 (GFunc) g_object_unref, NULL);
3769 g_list_free (default_icon_list);
3770 default_icon_list = NULL;
3772 /* Update all toplevels */
3773 toplevels = gtk_window_list_toplevels ();
3774 tmp_list = toplevels;
3775 while (tmp_list != NULL)
3777 GtkWindowIconInfo *info;
3778 GtkWindow *w = tmp_list->data;
3780 info = get_icon_info (w);
3781 if (info && info->using_default_icon && info->using_themed_icon)
3783 gtk_window_unrealize_icon (w);
3784 if (gtk_widget_get_realized (GTK_WIDGET (w)))
3785 gtk_window_realize_icon (w);
3788 tmp_list = tmp_list->next;
3790 g_list_free (toplevels);
3794 * gtk_window_get_default_icon_name:
3796 * Returns the fallback icon name for windows that has been set
3797 * with gtk_window_set_default_icon_name(). The returned
3798 * string is owned by GTK+ and should not be modified. It
3799 * is only valid until the next call to
3800 * gtk_window_set_default_icon_name().
3802 * Returns: the fallback icon name for windows
3807 gtk_window_get_default_icon_name (void)
3809 return default_icon_name;
3813 * gtk_window_set_default_icon_from_file:
3814 * @filename: location of icon file
3815 * @err: (allow-none): location to store error, or %NULL.
3817 * Sets an icon to be used as fallback for windows that haven't
3818 * had gtk_window_set_icon_list() called on them from a file
3819 * on disk. Warns on failure if @err is %NULL.
3821 * Returns: %TRUE if setting the icon succeeded.
3826 gtk_window_set_default_icon_from_file (const gchar *filename,
3829 GdkPixbuf *pixbuf = load_pixbuf_verbosely (filename, err);
3833 gtk_window_set_default_icon (pixbuf);
3834 g_object_unref (pixbuf);
3843 * gtk_window_get_default_icon_list:
3845 * Gets the value set by gtk_window_set_default_icon_list().
3846 * The list is a copy and should be freed with g_list_free(),
3847 * but the pixbufs in the list have not had their reference count
3850 * Return value: copy of default icon list
3853 gtk_window_get_default_icon_list (void)
3855 return g_list_copy (default_icon_list);
3859 gtk_window_set_default_size_internal (GtkWindow *window,
3860 gboolean change_width,
3862 gboolean change_height,
3864 gboolean is_geometry)
3866 GtkWindowGeometryInfo *info;
3868 g_return_if_fail (change_width == FALSE || width >= -1);
3869 g_return_if_fail (change_height == FALSE || height >= -1);
3871 info = gtk_window_get_geometry_info (window, TRUE);
3873 g_object_freeze_notify (G_OBJECT (window));
3875 info->default_is_geometry = is_geometry != FALSE;
3885 info->default_width = width;
3887 g_object_notify (G_OBJECT (window), "default-width");
3898 info->default_height = height;
3900 g_object_notify (G_OBJECT (window), "default-height");
3903 g_object_thaw_notify (G_OBJECT (window));
3905 gtk_widget_queue_resize_no_redraw (GTK_WIDGET (window));
3909 * gtk_window_set_default_size:
3910 * @window: a #GtkWindow
3911 * @width: width in pixels, or -1 to unset the default width
3912 * @height: height in pixels, or -1 to unset the default height
3914 * Sets the default size of a window. If the window's "natural" size
3915 * (its size request) is larger than the default, the default will be
3916 * ignored. More generally, if the default size does not obey the
3917 * geometry hints for the window (gtk_window_set_geometry_hints() can
3918 * be used to set these explicitly), the default size will be clamped
3919 * to the nearest permitted size.
3921 * Unlike gtk_widget_set_size_request(), which sets a size request for
3922 * a widget and thus would keep users from shrinking the window, this
3923 * function only sets the initial size, just as if the user had
3924 * resized the window themselves. Users can still shrink the window
3925 * again as they normally would. Setting a default size of -1 means to
3926 * use the "natural" default size (the size request of the window).
3928 * For more control over a window's initial size and how resizing works,
3929 * investigate gtk_window_set_geometry_hints().
3931 * For some uses, gtk_window_resize() is a more appropriate function.
3932 * gtk_window_resize() changes the current size of the window, rather
3933 * than the size to be used on initial display. gtk_window_resize() always
3934 * affects the window itself, not the geometry widget.
3936 * The default size of a window only affects the first time a window is
3937 * shown; if a window is hidden and re-shown, it will remember the size
3938 * it had prior to hiding, rather than using the default size.
3940 * Windows can't actually be 0x0 in size, they must be at least 1x1, but
3941 * passing 0 for @width and @height is OK, resulting in a 1x1 default size.
3944 gtk_window_set_default_size (GtkWindow *window,
3948 g_return_if_fail (GTK_IS_WINDOW (window));
3949 g_return_if_fail (width >= -1);
3950 g_return_if_fail (height >= -1);
3952 gtk_window_set_default_size_internal (window, TRUE, width, TRUE, height, FALSE);
3956 * gtk_window_get_default_size:
3957 * @window: a #GtkWindow
3958 * @width: (allow-none): location to store the default width, or %NULL
3959 * @height: (allow-none): location to store the default height, or %NULL
3961 * Gets the default size of the window. A value of -1 for the width or
3962 * height indicates that a default size has not been explicitly set
3963 * for that dimension, so the "natural" size of the window will be
3968 gtk_window_get_default_size (GtkWindow *window,
3972 GtkWindowGeometryInfo *info;
3974 g_return_if_fail (GTK_IS_WINDOW (window));
3976 info = gtk_window_get_geometry_info (window, FALSE);
3979 *width = info ? info->default_width : -1;
3982 *height = info ? info->default_height : -1;
3986 * gtk_window_resize:
3987 * @window: a #GtkWindow
3988 * @width: width in pixels to resize the window to
3989 * @height: height in pixels to resize the window to
3991 * Resizes the window as if the user had done so, obeying geometry
3992 * constraints. The default geometry constraint is that windows may
3993 * not be smaller than their size request; to override this
3994 * constraint, call gtk_widget_set_size_request() to set the window's
3995 * request to a smaller value.
3997 * If gtk_window_resize() is called before showing a window for the
3998 * first time, it overrides any default size set with
3999 * gtk_window_set_default_size().
4001 * Windows may not be resized smaller than 1 by 1 pixels.
4005 gtk_window_resize (GtkWindow *window,
4009 GtkWindowGeometryInfo *info;
4011 g_return_if_fail (GTK_IS_WINDOW (window));
4012 g_return_if_fail (width > 0);
4013 g_return_if_fail (height > 0);
4015 info = gtk_window_get_geometry_info (window, TRUE);
4017 info->resize_width = width;
4018 info->resize_height = height;
4020 gtk_widget_queue_resize_no_redraw (GTK_WIDGET (window));
4024 * gtk_window_get_size:
4025 * @window: a #GtkWindow
4026 * @width: (allow-none): (out): return location for width, or %NULL
4027 * @height: (allow-none): (out): return location for height, or %NULL
4029 * Obtains the current size of @window. If @window is not onscreen,
4030 * it returns the size GTK+ will suggest to the <link
4031 * linkend="gtk-X11-arch">window manager</link> for the initial window
4032 * size (but this is not reliably the same as the size the window
4033 * manager will actually select). The size obtained by
4034 * gtk_window_get_size() is the last size received in a
4035 * #GdkEventConfigure, that is, GTK+ uses its locally-stored size,
4036 * rather than querying the X server for the size. As a result, if you
4037 * call gtk_window_resize() then immediately call
4038 * gtk_window_get_size(), the size won't have taken effect yet. After
4039 * the window manager processes the resize request, GTK+ receives
4040 * notification that the size has changed via a configure event, and
4041 * the size of the window gets updated.
4043 * Note 1: Nearly any use of this function creates a race condition,
4044 * because the size of the window may change between the time that you
4045 * get the size and the time that you perform some action assuming
4046 * that size is the current size. To avoid race conditions, connect to
4047 * "configure-event" on the window and adjust your size-dependent
4048 * state to match the size delivered in the #GdkEventConfigure.
4050 * Note 2: The returned size does <emphasis>not</emphasis> include the
4051 * size of the window manager decorations (aka the window frame or
4052 * border). Those are not drawn by GTK+ and GTK+ has no reliable
4053 * method of determining their size.
4055 * Note 3: If you are getting a window size in order to position
4056 * the window onscreen, there may be a better way. The preferred
4057 * way is to simply set the window's semantic type with
4058 * gtk_window_set_type_hint(), which allows the window manager to
4059 * e.g. center dialogs. Also, if you set the transient parent of
4060 * dialogs with gtk_window_set_transient_for() window managers
4061 * will often center the dialog over its parent window. It's
4062 * much preferred to let the window manager handle these
4063 * things rather than doing it yourself, because all apps will
4064 * behave consistently and according to user prefs if the window
4065 * manager handles it. Also, the window manager can take the size
4066 * of the window decorations/border into account, while your
4067 * application cannot.
4069 * In any case, if you insist on application-specified window
4070 * positioning, there's <emphasis>still</emphasis> a better way than
4071 * doing it yourself - gtk_window_set_position() will frequently
4072 * handle the details for you.
4076 gtk_window_get_size (GtkWindow *window,
4082 g_return_if_fail (GTK_IS_WINDOW (window));
4084 if (width == NULL && height == NULL)
4087 if (gtk_widget_get_mapped (GTK_WIDGET (window)))
4089 gdk_drawable_get_size (GTK_WIDGET (window)->window,
4094 GdkRectangle configure_request;
4096 gtk_window_compute_configure_request (window,
4100 w = configure_request.width;
4101 h = configure_request.height;
4112 * @window: a #GtkWindow
4113 * @x: X coordinate to move window to
4114 * @y: Y coordinate to move window to
4116 * Asks the <link linkend="gtk-X11-arch">window manager</link> to move
4117 * @window to the given position. Window managers are free to ignore
4118 * this; most window managers ignore requests for initial window
4119 * positions (instead using a user-defined placement algorithm) and
4120 * honor requests after the window has already been shown.
4122 * Note: the position is the position of the gravity-determined
4123 * reference point for the window. The gravity determines two things:
4124 * first, the location of the reference point in root window
4125 * coordinates; and second, which point on the window is positioned at
4126 * the reference point.
4128 * By default the gravity is #GDK_GRAVITY_NORTH_WEST, so the reference
4129 * point is simply the @x, @y supplied to gtk_window_move(). The
4130 * top-left corner of the window decorations (aka window frame or
4131 * border) will be placed at @x, @y. Therefore, to position a window
4132 * at the top left of the screen, you want to use the default gravity
4133 * (which is #GDK_GRAVITY_NORTH_WEST) and move the window to 0,0.
4135 * To position a window at the bottom right corner of the screen, you
4136 * would set #GDK_GRAVITY_SOUTH_EAST, which means that the reference
4137 * point is at @x + the window width and @y + the window height, and
4138 * the bottom-right corner of the window border will be placed at that
4139 * reference point. So, to place a window in the bottom right corner
4140 * you would first set gravity to south east, then write:
4141 * <literal>gtk_window_move (window, gdk_screen_width () - window_width,
4142 * gdk_screen_height () - window_height)</literal> (note that this
4143 * example does not take multi-head scenarios into account).
4145 * The Extended Window Manager Hints specification at <ulink
4146 * url="http://www.freedesktop.org/Standards/wm-spec">
4147 * http://www.freedesktop.org/Standards/wm-spec</ulink> has a
4148 * nice table of gravities in the "implementation notes" section.
4150 * The gtk_window_get_position() documentation may also be relevant.
4153 gtk_window_move (GtkWindow *window,
4157 GtkWindowGeometryInfo *info;
4160 g_return_if_fail (GTK_IS_WINDOW (window));
4162 widget = GTK_WIDGET (window);
4164 info = gtk_window_get_geometry_info (window, TRUE);
4166 if (gtk_widget_get_mapped (widget))
4168 /* we have now sent a request with this position
4169 * with currently-active constraints, so toggle flag.
4171 info->position_constraints_changed = FALSE;
4173 /* we only constrain if mapped - if not mapped,
4174 * then gtk_window_compute_configure_request()
4175 * will apply the constraints later, and we
4176 * don't want to lose information about
4177 * what position the user set before then.
4178 * i.e. if you do a move() then turn off POS_CENTER
4179 * then show the window, your move() will work.
4181 gtk_window_constrain_position (window,
4182 widget->allocation.width,
4183 widget->allocation.height,
4186 /* Note that this request doesn't go through our standard request
4187 * framework, e.g. doesn't increment configure_request_count,
4188 * doesn't set info->last, etc.; that's because
4189 * we don't save the info needed to arrive at this same request
4192 * To gtk_window_move_resize(), this will end up looking exactly
4193 * the same as the position being changed by the window
4197 /* FIXME are we handling gravity properly for framed windows? */
4199 gdk_window_move (window->frame,
4200 x - window->frame_left,
4201 y - window->frame_top);
4203 gdk_window_move (GTK_WIDGET (window)->window,
4208 /* Save this position to apply on mapping */
4209 info->initial_x = x;
4210 info->initial_y = y;
4211 info->initial_pos_set = TRUE;
4216 * gtk_window_get_position:
4217 * @window: a #GtkWindow
4218 * @root_x: return location for X coordinate of gravity-determined reference point
4219 * @root_y: return location for Y coordinate of gravity-determined reference point
4221 * This function returns the position you need to pass to
4222 * gtk_window_move() to keep @window in its current position. This
4223 * means that the meaning of the returned value varies with window
4224 * gravity. See gtk_window_move() for more details.
4226 * If you haven't changed the window gravity, its gravity will be
4227 * #GDK_GRAVITY_NORTH_WEST. This means that gtk_window_get_position()
4228 * gets the position of the top-left corner of the window manager
4229 * frame for the window. gtk_window_move() sets the position of this
4230 * same top-left corner.
4232 * gtk_window_get_position() is not 100% reliable because the X Window System
4233 * does not specify a way to obtain the geometry of the
4234 * decorations placed on a window by the window manager.
4235 * Thus GTK+ is using a "best guess" that works with most
4238 * Moreover, nearly all window managers are historically broken with
4239 * respect to their handling of window gravity. So moving a window to
4240 * its current position as returned by gtk_window_get_position() tends
4241 * to result in moving the window slightly. Window managers are
4242 * slowly getting better over time.
4244 * If a window has gravity #GDK_GRAVITY_STATIC the window manager
4245 * frame is not relevant, and thus gtk_window_get_position() will
4246 * always produce accurate results. However you can't use static
4247 * gravity to do things like place a window in a corner of the screen,
4248 * because static gravity ignores the window manager decorations.
4250 * If you are saving and restoring your application's window
4251 * positions, you should know that it's impossible for applications to
4252 * do this without getting it somewhat wrong because applications do
4253 * not have sufficient knowledge of window manager state. The Correct
4254 * Mechanism is to support the session management protocol (see the
4255 * "GnomeClient" object in the GNOME libraries for example) and allow
4256 * the window manager to save your window sizes and positions.
4261 gtk_window_get_position (GtkWindow *window,
4267 g_return_if_fail (GTK_IS_WINDOW (window));
4269 widget = GTK_WIDGET (window);
4271 if (window->gravity == GDK_GRAVITY_STATIC)
4273 if (gtk_widget_get_mapped (widget))
4275 /* This does a server round-trip, which is sort of wrong;
4276 * but a server round-trip is inevitable for
4277 * gdk_window_get_frame_extents() in the usual
4278 * NorthWestGravity case below, so not sure what else to
4279 * do. We should likely be consistent about whether we get
4280 * the client-side info or the server-side info.
4282 gdk_window_get_origin (widget->window, root_x, root_y);
4286 GdkRectangle configure_request;
4288 gtk_window_compute_configure_request (window,
4292 *root_x = configure_request.x;
4293 *root_y = configure_request.y;
4298 GdkRectangle frame_extents;
4303 if (gtk_widget_get_mapped (widget))
4306 gdk_window_get_frame_extents (window->frame, &frame_extents);
4308 gdk_window_get_frame_extents (widget->window, &frame_extents);
4309 x = frame_extents.x;
4310 y = frame_extents.y;
4311 gtk_window_get_size (window, &w, &h);
4315 /* We just say the frame has 0 size on all sides.
4316 * Not sure what else to do.
4318 gtk_window_compute_configure_request (window,
4321 x = frame_extents.x;
4322 y = frame_extents.y;
4323 w = frame_extents.width;
4324 h = frame_extents.height;
4327 switch (window->gravity)
4329 case GDK_GRAVITY_NORTH:
4330 case GDK_GRAVITY_CENTER:
4331 case GDK_GRAVITY_SOUTH:
4332 /* Find center of frame. */
4333 x += frame_extents.width / 2;
4334 /* Center client window on that point. */
4338 case GDK_GRAVITY_SOUTH_EAST:
4339 case GDK_GRAVITY_EAST:
4340 case GDK_GRAVITY_NORTH_EAST:
4341 /* Find right edge of frame */
4342 x += frame_extents.width;
4343 /* Align left edge of client at that point. */
4350 switch (window->gravity)
4352 case GDK_GRAVITY_WEST:
4353 case GDK_GRAVITY_CENTER:
4354 case GDK_GRAVITY_EAST:
4355 /* Find center of frame. */
4356 y += frame_extents.height / 2;
4357 /* Center client window there. */
4360 case GDK_GRAVITY_SOUTH_WEST:
4361 case GDK_GRAVITY_SOUTH:
4362 case GDK_GRAVITY_SOUTH_EAST:
4363 /* Find south edge of frame */
4364 y += frame_extents.height;
4365 /* Place bottom edge of client there */
4380 * gtk_window_reshow_with_initial_size:
4381 * @window: a #GtkWindow
4383 * Hides @window, then reshows it, resetting the
4384 * default size and position of the window. Used
4385 * by GUI builders only.
4388 gtk_window_reshow_with_initial_size (GtkWindow *window)
4392 g_return_if_fail (GTK_IS_WINDOW (window));
4394 widget = GTK_WIDGET (window);
4396 gtk_widget_hide (widget);
4397 gtk_widget_unrealize (widget);
4398 gtk_widget_show (widget);
4402 gtk_window_destroy (GtkObject *object)
4404 GtkWindow *window = GTK_WINDOW (object);
4406 toplevel_list = g_slist_remove (toplevel_list, window);
4408 if (window->transient_parent)
4409 gtk_window_set_transient_for (window, NULL);
4411 /* frees the icons */
4412 gtk_window_set_icon_list (window, NULL);
4414 if (window->has_user_ref_count)
4416 window->has_user_ref_count = FALSE;
4417 g_object_unref (window);
4421 gtk_window_group_remove_window (window->group, window);
4423 gtk_window_free_key_hash (window);
4425 GTK_OBJECT_CLASS (gtk_window_parent_class)->destroy (object);
4429 gtk_window_finalize (GObject *object)
4431 GtkWindow *window = GTK_WINDOW (object);
4432 GtkWindowPrivate *priv = GTK_WINDOW_GET_PRIVATE (window);
4433 GtkMnemonicHash *mnemonic_hash;
4435 g_free (window->title);
4436 g_free (window->wmclass_name);
4437 g_free (window->wmclass_class);
4438 g_free (window->wm_role);
4440 mnemonic_hash = gtk_window_get_mnemonic_hash (window, FALSE);
4442 _gtk_mnemonic_hash_free (mnemonic_hash);
4444 if (window->geometry_info)
4446 if (window->geometry_info->widget)
4447 g_signal_handlers_disconnect_by_func (window->geometry_info->widget,
4448 gtk_widget_destroyed,
4449 &window->geometry_info->widget);
4450 g_free (window->geometry_info);
4453 if (window->keys_changed_handler)
4455 g_source_remove (window->keys_changed_handler);
4456 window->keys_changed_handler = 0;
4460 g_signal_handlers_disconnect_by_func (window->screen,
4461 gtk_window_on_composited_changed, window);
4463 g_free (priv->startup_id);
4465 G_OBJECT_CLASS (gtk_window_parent_class)->finalize (object);
4469 gtk_window_show (GtkWidget *widget)
4471 GtkWindow *window = GTK_WINDOW (widget);
4472 GtkContainer *container = GTK_CONTAINER (window);
4473 gboolean need_resize;
4475 GTK_WIDGET_SET_FLAGS (widget, GTK_VISIBLE);
4477 need_resize = container->need_resize || !gtk_widget_get_realized (widget);
4478 container->need_resize = FALSE;
4482 GtkWindowGeometryInfo *info = gtk_window_get_geometry_info (window, TRUE);
4483 GtkAllocation allocation = { 0, 0 };
4484 GdkRectangle configure_request;
4485 GdkGeometry new_geometry;
4487 gboolean was_realized;
4489 /* We are going to go ahead and perform this configure request
4490 * and then emulate a configure notify by going ahead and
4491 * doing a size allocate. Sort of a synchronous
4492 * mini-copy of gtk_window_move_resize() here.
4494 gtk_window_compute_configure_request (window,
4499 /* We update this because we are going to go ahead
4500 * and gdk_window_resize() below, rather than
4503 info->last.configure_request.width = configure_request.width;
4504 info->last.configure_request.height = configure_request.height;
4506 /* and allocate the window - this is normally done
4507 * in move_resize in response to configure notify
4509 allocation.width = configure_request.width;
4510 allocation.height = configure_request.height;
4511 gtk_widget_size_allocate (widget, &allocation);
4513 /* Then we guarantee we have a realize */
4514 was_realized = FALSE;
4515 if (!gtk_widget_get_realized (widget))
4517 gtk_widget_realize (widget);
4518 was_realized = TRUE;
4521 /* Must be done after the windows are realized,
4522 * so that the decorations can be read
4524 gtk_decorated_window_calculate_frame_size (window);
4526 /* We only send configure request if we didn't just finish
4527 * creating the window; if we just created the window
4528 * then we created it with widget->allocation anyhow.
4531 gdk_window_move_resize (widget->window,
4532 configure_request.x,
4533 configure_request.y,
4534 configure_request.width,
4535 configure_request.height);
4538 gtk_container_check_resize (container);
4540 gtk_widget_map (widget);
4542 /* Try to make sure that we have some focused widget
4544 if (!window->focus_widget && !GTK_IS_PLUG (window))
4545 gtk_window_move_focus (window, GTK_DIR_TAB_FORWARD);
4548 gtk_grab_add (widget);
4552 gtk_window_hide (GtkWidget *widget)
4554 GtkWindow *window = GTK_WINDOW (widget);
4556 GTK_WIDGET_UNSET_FLAGS (widget, GTK_VISIBLE);
4557 gtk_widget_unmap (widget);
4560 gtk_grab_remove (widget);
4564 gtk_window_map (GtkWidget *widget)
4566 GtkWindow *window = GTK_WINDOW (widget);
4567 GtkWindowPrivate *priv = GTK_WINDOW_GET_PRIVATE (window);
4568 GdkWindow *toplevel;
4569 gboolean auto_mnemonics;
4571 gtk_widget_set_mapped (widget, TRUE);
4573 if (window->bin.child &&
4574 gtk_widget_get_visible (window->bin.child) &&
4575 !gtk_widget_get_mapped (window->bin.child))
4576 gtk_widget_map (window->bin.child);
4579 toplevel = window->frame;
4581 toplevel = widget->window;
4583 if (window->maximize_initially)
4584 gdk_window_maximize (toplevel);
4586 gdk_window_unmaximize (toplevel);
4588 if (window->stick_initially)
4589 gdk_window_stick (toplevel);
4591 gdk_window_unstick (toplevel);
4593 if (window->iconify_initially)
4594 gdk_window_iconify (toplevel);
4596 gdk_window_deiconify (toplevel);
4598 if (priv->fullscreen_initially)
4599 gdk_window_fullscreen (toplevel);
4601 gdk_window_unfullscreen (toplevel);
4603 gdk_window_set_keep_above (toplevel, priv->above_initially);
4605 gdk_window_set_keep_below (toplevel, priv->below_initially);
4607 /* No longer use the default settings */
4608 window->need_default_size = FALSE;
4609 window->need_default_position = FALSE;
4611 if (priv->reset_type_hint)
4613 /* We should only reset the type hint when the application
4614 * used gtk_window_set_type_hint() to change the hint.
4615 * Some applications use X directly to change the properties;
4616 * in that case, we shouldn't overwrite what they did.
4618 gdk_window_set_type_hint (widget->window, priv->type_hint);
4619 priv->reset_type_hint = FALSE;
4622 gdk_window_show (widget->window);
4625 gdk_window_show (window->frame);
4627 if (!disable_startup_notification)
4629 /* Do we have a custom startup-notification id? */
4630 if (priv->startup_id != NULL)
4632 /* Make sure we have a "real" id */
4633 if (!startup_id_is_fake (priv->startup_id))
4634 gdk_notify_startup_complete_with_id (priv->startup_id);
4636 g_free (priv->startup_id);
4637 priv->startup_id = NULL;
4639 else if (!sent_startup_notification)
4641 sent_startup_notification = TRUE;
4642 gdk_notify_startup_complete ();
4646 /* if auto-mnemonics is enabled and mnemonics visible is not already set
4647 * (as in the case of popup menus), then hide mnemonics initially
4649 g_object_get (gtk_widget_get_settings (widget), "gtk-auto-mnemonics",
4650 &auto_mnemonics, NULL);
4651 if (auto_mnemonics && !priv->mnemonics_visible_set)
4652 gtk_window_set_mnemonics_visible (window, FALSE);
4656 gtk_window_map_event (GtkWidget *widget,
4659 if (!gtk_widget_get_mapped (widget))
4661 /* we should be be unmapped, but are getting a MapEvent, this may happen
4662 * to toplevel XWindows if mapping was intercepted by a window manager
4663 * and an unmap request occoured while the MapRequestEvent was still
4664 * being handled. we work around this situaiton here by re-requesting
4665 * the window being unmapped. more details can be found in:
4666 * http://bugzilla.gnome.org/show_bug.cgi?id=316180
4668 gdk_window_hide (widget->window);
4674 gtk_window_unmap (GtkWidget *widget)
4676 GtkWindow *window = GTK_WINDOW (widget);
4677 GtkWindowPrivate *priv = GTK_WINDOW_GET_PRIVATE (widget);
4678 GtkWindowGeometryInfo *info;
4679 GdkWindowState state;
4681 gtk_widget_set_mapped (widget, FALSE);
4683 gdk_window_withdraw (window->frame);
4685 gdk_window_withdraw (widget->window);
4687 window->configure_request_count = 0;
4688 window->configure_notify_received = FALSE;
4690 /* on unmap, we reset the default positioning of the window,
4691 * so it's placed again, but we don't reset the default
4692 * size of the window, so it's remembered.
4694 window->need_default_position = TRUE;
4696 info = gtk_window_get_geometry_info (window, FALSE);
4699 info->initial_pos_set = FALSE;
4700 info->position_constraints_changed = FALSE;
4703 state = gdk_window_get_state (widget->window);
4704 window->iconify_initially = (state & GDK_WINDOW_STATE_ICONIFIED) != 0;
4705 window->maximize_initially = (state & GDK_WINDOW_STATE_MAXIMIZED) != 0;
4706 window->stick_initially = (state & GDK_WINDOW_STATE_STICKY) != 0;
4707 priv->above_initially = (state & GDK_WINDOW_STATE_ABOVE) != 0;
4708 priv->below_initially = (state & GDK_WINDOW_STATE_BELOW) != 0;
4712 gtk_window_realize (GtkWidget *widget)
4715 GdkWindow *parent_window;
4716 GdkWindowAttr attributes;
4717 gint attributes_mask;
4718 GtkWindowPrivate *priv;
4720 window = GTK_WINDOW (widget);
4721 priv = GTK_WINDOW_GET_PRIVATE (window);
4723 /* ensure widget tree is properly size allocated */
4724 if (widget->allocation.x == -1 &&
4725 widget->allocation.y == -1 &&
4726 widget->allocation.width == 1 &&
4727 widget->allocation.height == 1)
4729 GtkRequisition requisition;
4730 GtkAllocation allocation = { 0, 0, 200, 200 };
4732 gtk_widget_size_request (widget, &requisition);
4733 if (requisition.width || requisition.height)
4735 /* non-empty window */
4736 allocation.width = requisition.width;
4737 allocation.height = requisition.height;
4739 gtk_widget_size_allocate (widget, &allocation);
4741 _gtk_container_queue_resize (GTK_CONTAINER (widget));
4743 g_return_if_fail (!gtk_widget_get_realized (widget));
4746 gtk_widget_set_realized (widget, TRUE);
4748 switch (window->type)
4750 case GTK_WINDOW_TOPLEVEL:
4751 attributes.window_type = GDK_WINDOW_TOPLEVEL;
4753 case GTK_WINDOW_POPUP:
4754 attributes.window_type = GDK_WINDOW_TEMP;
4757 g_warning (G_STRLOC": Unknown window type %d!", window->type);
4761 attributes.title = window->title;
4762 attributes.wmclass_name = window->wmclass_name;
4763 attributes.wmclass_class = window->wmclass_class;
4764 attributes.wclass = GDK_INPUT_OUTPUT;
4765 attributes.visual = gtk_widget_get_visual (widget);
4766 attributes.colormap = gtk_widget_get_colormap (widget);
4768 if (window->has_frame)
4770 attributes.width = widget->allocation.width + window->frame_left + window->frame_right;
4771 attributes.height = widget->allocation.height + window->frame_top + window->frame_bottom;
4772 attributes.event_mask = (GDK_EXPOSURE_MASK |
4773 GDK_KEY_PRESS_MASK |
4774 GDK_ENTER_NOTIFY_MASK |
4775 GDK_LEAVE_NOTIFY_MASK |
4776 GDK_FOCUS_CHANGE_MASK |
4777 GDK_STRUCTURE_MASK |
4778 GDK_BUTTON_MOTION_MASK |
4779 GDK_POINTER_MOTION_HINT_MASK |
4780 GDK_BUTTON_PRESS_MASK |
4781 GDK_BUTTON_RELEASE_MASK);
4783 attributes_mask = GDK_WA_VISUAL | GDK_WA_COLORMAP;
4785 window->frame = gdk_window_new (gtk_widget_get_root_window (widget),
4786 &attributes, attributes_mask);
4788 if (priv->opacity_set)
4789 gdk_window_set_opacity (window->frame, priv->opacity);
4791 gdk_window_set_user_data (window->frame, widget);
4793 attributes.window_type = GDK_WINDOW_CHILD;
4794 attributes.x = window->frame_left;
4795 attributes.y = window->frame_top;
4797 attributes_mask = GDK_WA_X | GDK_WA_Y;
4799 parent_window = window->frame;
4801 g_signal_connect (window,
4803 G_CALLBACK (gtk_window_event),
4808 attributes_mask = 0;
4809 parent_window = gtk_widget_get_root_window (widget);
4812 attributes.width = widget->allocation.width;
4813 attributes.height = widget->allocation.height;
4814 attributes.event_mask = gtk_widget_get_events (widget);
4815 attributes.event_mask |= (GDK_EXPOSURE_MASK |
4816 GDK_KEY_PRESS_MASK |
4817 GDK_KEY_RELEASE_MASK |
4818 GDK_ENTER_NOTIFY_MASK |
4819 GDK_LEAVE_NOTIFY_MASK |
4820 GDK_FOCUS_CHANGE_MASK |
4821 GDK_STRUCTURE_MASK);
4822 attributes.type_hint = priv->type_hint;
4824 attributes_mask |= GDK_WA_VISUAL | GDK_WA_COLORMAP | GDK_WA_TYPE_HINT;
4825 attributes_mask |= (window->title ? GDK_WA_TITLE : 0);
4826 attributes_mask |= (window->wmclass_name ? GDK_WA_WMCLASS : 0);
4828 widget->window = gdk_window_new (parent_window, &attributes, attributes_mask);
4830 if (!window->has_frame && priv->opacity_set)
4831 gdk_window_set_opacity (widget->window, priv->opacity);
4833 gdk_window_enable_synchronized_configure (widget->window);
4835 gdk_window_set_user_data (widget->window, window);
4837 widget->style = gtk_style_attach (widget->style, widget->window);
4838 gtk_style_set_background (widget->style, widget->window, GTK_STATE_NORMAL);
4840 gtk_style_set_background (widget->style, window->frame, GTK_STATE_NORMAL);
4842 /* This is a bad hack to set the window background. */
4843 gtk_window_paint (widget, NULL);
4845 if (window->transient_parent &&
4846 gtk_widget_get_realized (GTK_WIDGET (window->transient_parent)))
4847 gdk_window_set_transient_for (widget->window,
4848 GTK_WIDGET (window->transient_parent)->window);
4850 if (window->wm_role)
4851 gdk_window_set_role (widget->window, window->wm_role);
4853 if (!window->decorated)
4854 gdk_window_set_decorations (widget->window, 0);
4856 if (!priv->deletable)
4857 gdk_window_set_functions (widget->window, GDK_FUNC_ALL | GDK_FUNC_CLOSE);
4859 if (gtk_window_get_skip_pager_hint (window))
4860 gdk_window_set_skip_pager_hint (widget->window, TRUE);
4862 if (gtk_window_get_skip_taskbar_hint (window))
4863 gdk_window_set_skip_taskbar_hint (widget->window, TRUE);
4865 if (gtk_window_get_accept_focus (window))
4866 gdk_window_set_accept_focus (widget->window, TRUE);
4868 gdk_window_set_accept_focus (widget->window, FALSE);
4870 if (gtk_window_get_focus_on_map (window))
4871 gdk_window_set_focus_on_map (widget->window, TRUE);
4873 gdk_window_set_focus_on_map (widget->window, FALSE);
4876 gdk_window_set_modal_hint (widget->window, TRUE);
4878 gdk_window_set_modal_hint (widget->window, FALSE);
4880 if (priv->startup_id)
4882 #ifdef GDK_WINDOWING_X11
4883 guint32 timestamp = extract_time_from_startup_id (priv->startup_id);
4884 if (timestamp != GDK_CURRENT_TIME)
4885 gdk_x11_window_set_user_time (widget->window, timestamp);
4887 if (!startup_id_is_fake (priv->startup_id))
4888 gdk_window_set_startup_id (widget->window, priv->startup_id);
4892 gtk_window_realize_icon (window);
4896 gtk_window_unrealize (GtkWidget *widget)
4899 GtkWindowGeometryInfo *info;
4901 window = GTK_WINDOW (widget);
4903 /* On unrealize, we reset the size of the window such
4904 * that we will re-apply the default sizing stuff
4905 * next time we show the window.
4907 * Default positioning is reset on unmap, instead of unrealize.
4909 window->need_default_size = TRUE;
4910 info = gtk_window_get_geometry_info (window, FALSE);
4913 info->resize_width = -1;
4914 info->resize_height = -1;
4915 info->last.configure_request.x = 0;
4916 info->last.configure_request.y = 0;
4917 info->last.configure_request.width = -1;
4918 info->last.configure_request.height = -1;
4919 /* be sure we reset geom hints on re-realize */
4920 info->last.flags = 0;
4925 gdk_window_set_user_data (window->frame, NULL);
4926 gdk_window_destroy (window->frame);
4927 window->frame = NULL;
4931 gtk_window_unrealize_icon (window);
4933 GTK_WIDGET_CLASS (gtk_window_parent_class)->unrealize (widget);
4937 gtk_window_size_request (GtkWidget *widget,
4938 GtkRequisition *requisition)
4943 window = GTK_WINDOW (widget);
4944 bin = GTK_BIN (window);
4946 requisition->width = GTK_CONTAINER (window)->border_width * 2;
4947 requisition->height = GTK_CONTAINER (window)->border_width * 2;
4949 if (bin->child && gtk_widget_get_visible (bin->child))
4951 GtkRequisition child_requisition;
4953 gtk_widget_size_request (bin->child, &child_requisition);
4955 requisition->width += child_requisition.width;
4956 requisition->height += child_requisition.height;
4961 gtk_window_size_allocate (GtkWidget *widget,
4962 GtkAllocation *allocation)
4965 GtkAllocation child_allocation;
4967 window = GTK_WINDOW (widget);
4968 widget->allocation = *allocation;
4970 if (window->bin.child && gtk_widget_get_visible (window->bin.child))
4972 child_allocation.x = GTK_CONTAINER (window)->border_width;
4973 child_allocation.y = GTK_CONTAINER (window)->border_width;
4974 child_allocation.width =
4975 MAX (1, (gint)allocation->width - child_allocation.x * 2);
4976 child_allocation.height =
4977 MAX (1, (gint)allocation->height - child_allocation.y * 2);
4979 gtk_widget_size_allocate (window->bin.child, &child_allocation);
4982 if (gtk_widget_get_realized (widget) && window->frame)
4984 gdk_window_resize (window->frame,
4985 allocation->width + window->frame_left + window->frame_right,
4986 allocation->height + window->frame_top + window->frame_bottom);
4991 gtk_window_event (GtkWidget *widget, GdkEvent *event)
4994 gboolean return_val;
4996 window = GTK_WINDOW (widget);
4998 if (window->frame && (event->any.window == window->frame))
5000 if ((event->type != GDK_KEY_PRESS) &&
5001 (event->type != GDK_KEY_RELEASE) &&
5002 (event->type != GDK_FOCUS_CHANGE))
5004 g_signal_stop_emission_by_name (widget, "event");
5006 g_signal_emit (widget, window_signals[FRAME_EVENT], 0, event, &return_val);
5011 g_object_unref (event->any.window);
5012 event->any.window = g_object_ref (widget->window);
5020 gtk_window_frame_event (GtkWindow *window, GdkEvent *event)
5022 GdkEventConfigure *configure_event;
5025 switch (event->type)
5028 configure_event = (GdkEventConfigure *)event;
5030 /* Invalidate the decorations */
5033 rect.width = configure_event->width;
5034 rect.height = configure_event->height;
5036 gdk_window_invalidate_rect (window->frame, &rect, FALSE);
5038 /* Pass on the (modified) configure event */
5039 configure_event->width -= window->frame_left + window->frame_right;
5040 configure_event->height -= window->frame_top + window->frame_bottom;
5041 return gtk_window_configure_event (GTK_WIDGET (window), configure_event);
5050 gtk_window_configure_event (GtkWidget *widget,
5051 GdkEventConfigure *event)
5053 GtkWindow *window = GTK_WINDOW (widget);
5054 gboolean expected_reply = window->configure_request_count > 0;
5056 /* window->configure_request_count incremented for each
5057 * configure request, and decremented to a min of 0 for
5058 * each configure notify.
5060 * All it means is that we know we will get at least
5061 * window->configure_request_count more configure notifies.
5062 * We could get more configure notifies than that; some
5063 * of the configure notifies we get may be unrelated to
5064 * the configure requests. But we will get at least
5065 * window->configure_request_count notifies.
5068 if (window->configure_request_count > 0)
5070 window->configure_request_count -= 1;
5071 gdk_window_thaw_toplevel_updates_libgtk_only (widget->window);
5074 /* As an optimization, we avoid a resize when possible.
5076 * The only times we can avoid a resize are:
5077 * - we know only the position changed, not the size
5078 * - we know we have made more requests and so will get more
5079 * notifies and can wait to resize when we get them
5082 if (!expected_reply &&
5083 (widget->allocation.width == event->width &&
5084 widget->allocation.height == event->height))
5086 gdk_window_configure_finished (widget->window);
5091 * If we do need to resize, we do that by:
5092 * - filling in widget->allocation with the new size
5093 * - setting configure_notify_received to TRUE
5094 * for use in gtk_window_move_resize()
5095 * - queueing a resize, leading to invocation of
5096 * gtk_window_move_resize() in an idle handler
5100 window->configure_notify_received = TRUE;
5102 widget->allocation.width = event->width;
5103 widget->allocation.height = event->height;
5105 _gtk_container_queue_resize (GTK_CONTAINER (widget));
5110 /* the accel_key and accel_mods fields of the key have to be setup
5111 * upon calling this function. it'll then return whether that key
5112 * is at all used as accelerator, and if so will OR in the
5113 * accel_flags member of the key.
5116 _gtk_window_query_nonaccels (GtkWindow *window,
5118 GdkModifierType accel_mods)
5120 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
5122 /* movement keys are considered locked accels */
5125 static const guint bindings[] = {
5126 GDK_space, GDK_KP_Space, GDK_Return, GDK_ISO_Enter, GDK_KP_Enter, GDK_Up, GDK_KP_Up, GDK_Down, GDK_KP_Down,
5127 GDK_Left, GDK_KP_Left, GDK_Right, GDK_KP_Right, GDK_Tab, GDK_KP_Tab, GDK_ISO_Left_Tab,
5131 for (i = 0; i < G_N_ELEMENTS (bindings); i++)
5132 if (bindings[i] == accel_key)
5136 /* mnemonics are considered locked accels */
5137 if (accel_mods == window->mnemonic_modifier)
5139 GtkMnemonicHash *mnemonic_hash = gtk_window_get_mnemonic_hash (window, FALSE);
5140 if (mnemonic_hash && _gtk_mnemonic_hash_lookup (mnemonic_hash, accel_key))
5148 * gtk_window_propagate_key_event:
5149 * @window: a #GtkWindow
5150 * @event: a #GdkEventKey
5152 * Propagate a key press or release event to the focus widget and
5153 * up the focus container chain until a widget handles @event.
5154 * This is normally called by the default ::key_press_event and
5155 * ::key_release_event handlers for toplevel windows,
5156 * however in some cases it may be useful to call this directly when
5157 * overriding the standard key handling for a toplevel window.
5159 * Return value: %TRUE if a widget in the focus chain handled the event.
5164 gtk_window_propagate_key_event (GtkWindow *window,
5167 gboolean handled = FALSE;
5168 GtkWidget *widget, *focus;
5170 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
5172 widget = GTK_WIDGET (window);
5173 focus = window->focus_widget;
5175 g_object_ref (focus);
5178 focus && focus != widget &&
5179 gtk_widget_get_toplevel (focus) == widget)
5183 if (gtk_widget_is_sensitive (focus))
5184 handled = gtk_widget_event (focus, (GdkEvent*) event);
5186 parent = focus->parent;
5188 g_object_ref (parent);
5190 g_object_unref (focus);
5196 g_object_unref (focus);
5202 gtk_window_key_press_event (GtkWidget *widget,
5205 GtkWindow *window = GTK_WINDOW (widget);
5206 gboolean handled = FALSE;
5208 /* handle mnemonics and accelerators */
5210 handled = gtk_window_activate_key (window, event);
5212 /* handle focus widget key events */
5214 handled = gtk_window_propagate_key_event (window, event);
5216 /* Chain up, invokes binding set */
5218 handled = GTK_WIDGET_CLASS (gtk_window_parent_class)->key_press_event (widget, event);
5224 gtk_window_key_release_event (GtkWidget *widget,
5227 GtkWindow *window = GTK_WINDOW (widget);
5228 gboolean handled = FALSE;
5230 /* handle focus widget key events */
5232 handled = gtk_window_propagate_key_event (window, event);
5234 /* Chain up, invokes binding set */
5236 handled = GTK_WIDGET_CLASS (gtk_window_parent_class)->key_release_event (widget, event);
5242 gtk_window_real_activate_default (GtkWindow *window)
5244 gtk_window_activate_default (window);
5248 gtk_window_real_activate_focus (GtkWindow *window)
5250 gtk_window_activate_focus (window);
5254 gtk_window_move_focus (GtkWindow *window,
5255 GtkDirectionType dir)
5257 gtk_widget_child_focus (GTK_WIDGET (window), dir);
5259 if (!GTK_CONTAINER (window)->focus_child)
5260 gtk_window_set_focus (window, NULL);
5264 gtk_window_enter_notify_event (GtkWidget *widget,
5265 GdkEventCrossing *event)
5271 gtk_window_leave_notify_event (GtkWidget *widget,
5272 GdkEventCrossing *event)
5278 do_focus_change (GtkWidget *widget,
5281 GdkEvent *fevent = gdk_event_new (GDK_FOCUS_CHANGE);
5283 fevent->focus_change.type = GDK_FOCUS_CHANGE;
5284 fevent->focus_change.window = widget->window;
5285 fevent->focus_change.in = in;
5287 g_object_ref (widget->window);
5289 gtk_widget_send_focus_change (widget, fevent);
5291 gdk_event_free (fevent);
5295 gtk_window_focus_in_event (GtkWidget *widget,
5296 GdkEventFocus *event)
5298 GtkWindow *window = GTK_WINDOW (widget);
5300 /* It appears spurious focus in events can occur when
5301 * the window is hidden. So we'll just check to see if
5302 * the window is visible before actually handling the
5305 if (gtk_widget_get_visible (widget))
5307 _gtk_window_set_has_toplevel_focus (window, TRUE);
5308 _gtk_window_set_is_active (window, TRUE);
5315 gtk_window_focus_out_event (GtkWidget *widget,
5316 GdkEventFocus *event)
5318 GtkWindow *window = GTK_WINDOW (widget);
5319 gboolean auto_mnemonics;
5321 _gtk_window_set_has_toplevel_focus (window, FALSE);
5322 _gtk_window_set_is_active (window, FALSE);
5324 /* set the mnemonic-visible property to false */
5325 g_object_get (gtk_widget_get_settings (widget),
5326 "gtk-auto-mnemonics", &auto_mnemonics, NULL);
5328 gtk_window_set_mnemonics_visible (window, FALSE);
5333 static GdkAtom atom_rcfiles = GDK_NONE;
5334 static GdkAtom atom_iconthemes = GDK_NONE;
5337 send_client_message_to_embedded_windows (GtkWidget *widget,
5338 GdkAtom message_type)
5340 GList *embedded_windows;
5342 embedded_windows = g_object_get_qdata (G_OBJECT (widget), quark_gtk_embedded);
5343 if (embedded_windows)
5345 GdkEvent *send_event = gdk_event_new (GDK_CLIENT_EVENT);
5348 for (i = 0; i < 5; i++)
5349 send_event->client.data.l[i] = 0;
5350 send_event->client.data_format = 32;
5351 send_event->client.message_type = message_type;
5353 while (embedded_windows)
5355 GdkNativeWindow xid = GDK_GPOINTER_TO_NATIVE_WINDOW(embedded_windows->data);
5356 gdk_event_send_client_message_for_display (gtk_widget_get_display (widget), send_event, xid);
5357 embedded_windows = embedded_windows->next;
5360 gdk_event_free (send_event);
5365 gtk_window_client_event (GtkWidget *widget,
5366 GdkEventClient *event)
5370 atom_rcfiles = gdk_atom_intern_static_string ("_GTK_READ_RCFILES");
5371 atom_iconthemes = gdk_atom_intern_static_string ("_GTK_LOAD_ICONTHEMES");
5374 if (event->message_type == atom_rcfiles)
5376 send_client_message_to_embedded_windows (widget, atom_rcfiles);
5377 gtk_rc_reparse_all_for_settings (gtk_widget_get_settings (widget), FALSE);
5380 if (event->message_type == atom_iconthemes)
5382 send_client_message_to_embedded_windows (widget, atom_iconthemes);
5383 _gtk_icon_theme_check_reload (gtk_widget_get_display (widget));
5390 gtk_window_check_resize (GtkContainer *container)
5392 if (gtk_widget_get_visible (GTK_WIDGET (container)))
5393 gtk_window_move_resize (GTK_WINDOW (container));
5397 gtk_window_focus (GtkWidget *widget,
5398 GtkDirectionType direction)
5402 GtkContainer *container;
5403 GtkWidget *old_focus_child;
5406 container = GTK_CONTAINER (widget);
5407 window = GTK_WINDOW (widget);
5408 bin = GTK_BIN (widget);
5410 old_focus_child = container->focus_child;
5412 /* We need a special implementation here to deal properly with wrapping
5413 * around in the tab chain without the danger of going into an
5416 if (old_focus_child)
5418 if (gtk_widget_child_focus (old_focus_child, direction))
5422 if (window->focus_widget)
5424 if (direction == GTK_DIR_LEFT ||
5425 direction == GTK_DIR_RIGHT ||
5426 direction == GTK_DIR_UP ||
5427 direction == GTK_DIR_DOWN)
5432 /* Wrapped off the end, clear the focus setting for the toplpevel */
5433 parent = window->focus_widget->parent;
5436 gtk_container_set_focus_child (GTK_CONTAINER (parent), NULL);
5437 parent = GTK_WIDGET (parent)->parent;
5440 gtk_window_set_focus (GTK_WINDOW (container), NULL);
5443 /* Now try to focus the first widget in the window */
5446 if (gtk_widget_child_focus (bin->child, direction))
5454 gtk_window_real_set_focus (GtkWindow *window,
5457 GtkWidget *old_focus = window->focus_widget;
5458 gboolean had_default = FALSE;
5459 gboolean focus_had_default = FALSE;
5460 gboolean old_focus_had_default = FALSE;
5464 g_object_ref (old_focus);
5465 g_object_freeze_notify (G_OBJECT (old_focus));
5466 old_focus_had_default = gtk_widget_has_default (old_focus);
5470 g_object_ref (focus);
5471 g_object_freeze_notify (G_OBJECT (focus));
5472 focus_had_default = gtk_widget_has_default (focus);
5475 if (window->default_widget)
5476 had_default = gtk_widget_has_default (window->default_widget);
5478 if (window->focus_widget)
5480 if (gtk_widget_get_receives_default (window->focus_widget) &&
5481 (window->focus_widget != window->default_widget))
5483 _gtk_widget_set_has_default (window->focus_widget, FALSE);
5484 gtk_widget_queue_draw (window->focus_widget);
5486 if (window->default_widget)
5487 _gtk_widget_set_has_default (window->default_widget, TRUE);
5490 window->focus_widget = NULL;
5492 if (window->has_focus)
5493 do_focus_change (old_focus, FALSE);
5495 g_object_notify (G_OBJECT (old_focus), "is-focus");
5498 /* The above notifications may have set a new focus widget,
5499 * if so, we don't want to override it.
5501 if (focus && !window->focus_widget)
5503 window->focus_widget = focus;
5505 if (gtk_widget_get_receives_default (window->focus_widget) &&
5506 (window->focus_widget != window->default_widget))
5508 if (gtk_widget_get_can_default (window->focus_widget))
5509 _gtk_widget_set_has_default (window->focus_widget, TRUE);
5511 if (window->default_widget)
5512 _gtk_widget_set_has_default (window->default_widget, FALSE);
5515 if (window->has_focus)
5516 do_focus_change (window->focus_widget, TRUE);
5518 g_object_notify (G_OBJECT (window->focus_widget), "is-focus");
5521 /* If the default widget changed, a redraw will have been queued
5522 * on the old and new default widgets by gtk_window_set_default(), so
5523 * we only have to worry about the case where it didn't change.
5524 * We'll sometimes queue a draw twice on the new widget but that
5527 if (window->default_widget &&
5528 (had_default != gtk_widget_has_default (window->default_widget)))
5529 gtk_widget_queue_draw (window->default_widget);
5533 if (old_focus_had_default != gtk_widget_has_default (old_focus))
5534 gtk_widget_queue_draw (old_focus);
5536 g_object_thaw_notify (G_OBJECT (old_focus));
5537 g_object_unref (old_focus);
5541 if (focus_had_default != gtk_widget_has_default (focus))
5542 gtk_widget_queue_draw (focus);
5544 g_object_thaw_notify (G_OBJECT (focus));
5545 g_object_unref (focus);
5550 * _gtk_window_unset_focus_and_default:
5551 * @window: a #GtkWindow
5552 * @widget: a widget inside of @window
5554 * Checks whether the focus and default widgets of @window are
5555 * @widget or a descendent of @widget, and if so, unset them.
5558 _gtk_window_unset_focus_and_default (GtkWindow *window,
5564 g_object_ref (window);
5565 g_object_ref (widget);
5567 if (GTK_CONTAINER (widget->parent)->focus_child == widget)
5569 child = window->focus_widget;
5571 while (child && child != widget)
5572 child = child->parent;
5574 if (child == widget)
5575 gtk_window_set_focus (GTK_WINDOW (window), NULL);
5578 child = window->default_widget;
5580 while (child && child != widget)
5581 child = child->parent;
5583 if (child == widget)
5584 gtk_window_set_default (window, NULL);
5586 g_object_unref (widget);
5587 g_object_unref (window);
5590 /*********************************
5591 * Functions related to resizing *
5592 *********************************/
5594 /* This function doesn't constrain to geometry hints */
5596 gtk_window_compute_configure_request_size (GtkWindow *window,
5600 GtkRequisition requisition;
5601 GtkWindowGeometryInfo *info;
5605 * - we've done a size request
5608 widget = GTK_WIDGET (window);
5610 info = gtk_window_get_geometry_info (window, FALSE);
5612 if (window->need_default_size)
5614 gtk_widget_get_child_requisition (widget, &requisition);
5616 /* Default to requisition */
5617 *width = requisition.width;
5618 *height = requisition.height;
5620 /* If window is empty so requests 0, default to random nonzero size */
5621 if (*width == 0 && *height == 0)
5627 /* Override requisition with default size */
5631 gint base_width = 0;
5632 gint base_height = 0;
5634 gint min_height = 0;
5636 gint height_inc = 1;
5638 if (info->default_is_geometry &&
5639 (info->default_width > 0 || info->default_height > 0))
5641 GdkGeometry geometry;
5644 gtk_window_compute_hints (window, &geometry, &flags);
5646 if (flags & GDK_HINT_BASE_SIZE)
5648 base_width = geometry.base_width;
5649 base_height = geometry.base_height;
5651 if (flags & GDK_HINT_MIN_SIZE)
5653 min_width = geometry.min_width;
5654 min_height = geometry.min_height;
5656 if (flags & GDK_HINT_RESIZE_INC)
5658 width_inc = geometry.width_inc;
5659 height_inc = geometry.height_inc;
5663 if (info->default_width > 0)
5664 *width = MAX (info->default_width * width_inc + base_width, min_width);
5666 if (info->default_height > 0)
5667 *height = MAX (info->default_height * height_inc + base_height, min_height);
5672 /* Default to keeping current size */
5673 *width = widget->allocation.width;
5674 *height = widget->allocation.height;
5677 /* Override any size with gtk_window_resize() values */
5680 if (info->resize_width > 0)
5681 *width = info->resize_width;
5683 if (info->resize_height > 0)
5684 *height = info->resize_height;
5687 /* Don't ever request zero width or height, its not supported by
5688 gdk. The size allocation code will round it to 1 anyway but if
5689 we do it then the value returned from this function will is
5690 not comparable to the size allocation read from the GtkWindow. */
5691 *width = MAX (*width, 1);
5692 *height = MAX (*height, 1);
5695 static GtkWindowPosition
5696 get_effective_position (GtkWindow *window)
5698 GtkWindowPosition pos = window->position;
5700 if (pos == GTK_WIN_POS_CENTER_ON_PARENT &&
5701 (window->transient_parent == NULL ||
5702 !gtk_widget_get_mapped (GTK_WIDGET (window->transient_parent))))
5703 pos = GTK_WIN_POS_NONE;
5709 get_center_monitor_of_window (GtkWindow *window)
5711 /* We could try to sort out the relative positions of the monitors and
5712 * stuff, or we could just be losers and assume you have a row
5713 * or column of monitors.
5715 return gdk_screen_get_n_monitors (gtk_window_check_screen (window)) / 2;
5719 get_monitor_containing_pointer (GtkWindow *window)
5723 GdkScreen *window_screen;
5724 GdkScreen *pointer_screen;
5726 window_screen = gtk_window_check_screen (window);
5727 gdk_display_get_pointer (gdk_screen_get_display (window_screen),
5731 if (pointer_screen == window_screen)
5732 monitor_num = gdk_screen_get_monitor_at_point (pointer_screen, px, py);
5740 center_window_on_monitor (GtkWindow *window,
5746 GdkRectangle monitor;
5749 monitor_num = get_monitor_containing_pointer (window);
5751 if (monitor_num == -1)
5752 monitor_num = get_center_monitor_of_window (window);
5754 gdk_screen_get_monitor_geometry (gtk_window_check_screen (window),
5755 monitor_num, &monitor);
5757 *x = (monitor.width - w) / 2 + monitor.x;
5758 *y = (monitor.height - h) / 2 + monitor.y;
5760 /* Be sure we aren't off the monitor, ignoring _NET_WM_STRUT
5761 * and WM decorations.
5775 if (extent > clamp_extent)
5777 *base = clamp_base + clamp_extent/2 - extent/2;
5778 else if (*base < clamp_base)
5780 else if (*base + extent > clamp_base + clamp_extent)
5781 *base = clamp_base + clamp_extent - extent;
5785 clamp_window_to_rectangle (gint *x,
5789 const GdkRectangle *rect)
5791 #ifdef DEBUGGING_OUTPUT
5792 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);
5795 /* If it is too large, center it. If it fits on the monitor but is
5796 * partially outside, move it to the closest edge. Do this
5797 * separately in x and y directions.
5799 clamp (x, w, rect->x, rect->width);
5800 clamp (y, h, rect->y, rect->height);
5801 #ifdef DEBUGGING_OUTPUT
5802 g_print (" ==> %+d%+d: %dx%d\n", *x, *y, w, h);
5808 gtk_window_compute_configure_request (GtkWindow *window,
5809 GdkRectangle *request,
5810 GdkGeometry *geometry,
5813 GdkGeometry new_geometry;
5817 GtkWindowPosition pos;
5818 GtkWidget *parent_widget;
5819 GtkWindowGeometryInfo *info;
5823 widget = GTK_WIDGET (window);
5825 screen = gtk_window_check_screen (window);
5827 gtk_widget_size_request (widget, NULL);
5828 gtk_window_compute_configure_request_size (window, (guint *)&w, (guint *)&h);
5830 gtk_window_compute_hints (window, &new_geometry, &new_flags);
5831 gtk_window_constrain_size (window,
5832 &new_geometry, new_flags,
5836 parent_widget = (GtkWidget*) window->transient_parent;
5838 pos = get_effective_position (window);
5839 info = gtk_window_get_geometry_info (window, FALSE);
5841 /* by default, don't change position requested */
5844 x = info->last.configure_request.x;
5845 y = info->last.configure_request.y;
5854 if (window->need_default_position)
5857 /* FIXME this all interrelates with window gravity.
5858 * For most of them I think we want to set GRAVITY_CENTER.
5860 * Not sure how to go about that.
5865 /* here we are only handling CENTER_ALWAYS
5866 * as it relates to default positioning,
5867 * where it's equivalent to simply CENTER
5869 case GTK_WIN_POS_CENTER_ALWAYS:
5870 case GTK_WIN_POS_CENTER:
5871 center_window_on_monitor (window, w, h, &x, &y);
5874 case GTK_WIN_POS_CENTER_ON_PARENT:
5877 GdkRectangle monitor;
5880 g_assert (gtk_widget_get_mapped (parent_widget)); /* established earlier */
5882 if (parent_widget->window != NULL)
5883 monitor_num = gdk_screen_get_monitor_at_window (screen,
5884 parent_widget->window);
5888 gdk_window_get_origin (parent_widget->window,
5891 x = ox + (parent_widget->allocation.width - w) / 2;
5892 y = oy + (parent_widget->allocation.height - h) / 2;
5894 /* Clamp onto current monitor, ignoring _NET_WM_STRUT and
5895 * WM decorations. If parent wasn't on a monitor, just
5898 if (monitor_num >= 0)
5900 gdk_screen_get_monitor_geometry (screen, monitor_num, &monitor);
5901 clamp_window_to_rectangle (&x, &y, w, h, &monitor);
5906 case GTK_WIN_POS_MOUSE:
5908 gint screen_width = gdk_screen_get_width (screen);
5909 gint screen_height = gdk_screen_get_height (screen);
5911 GdkRectangle monitor;
5912 GdkScreen *pointer_screen;
5915 gdk_display_get_pointer (gdk_screen_get_display (screen),
5919 if (pointer_screen == screen)
5920 monitor_num = gdk_screen_get_monitor_at_point (screen, px, py);
5926 x = CLAMP (x, 0, screen_width - w);
5927 y = CLAMP (y, 0, screen_height - h);
5929 /* Clamp onto current monitor, ignoring _NET_WM_STRUT and
5930 * WM decorations. Don't try to figure out what's going
5931 * on if the mouse wasn't inside a monitor.
5933 if (monitor_num >= 0)
5935 gdk_screen_get_monitor_geometry (screen, monitor_num, &monitor);
5936 clamp_window_to_rectangle (&x, &y, w, h, &monitor);
5944 } /* if (window->need_default_position) */
5946 if (window->need_default_position && info &&
5947 info->initial_pos_set)
5949 x = info->initial_x;
5950 y = info->initial_y;
5951 gtk_window_constrain_position (window, w, h, &x, &y);
5957 request->height = h;
5960 *geometry = new_geometry;
5966 gtk_window_constrain_position (GtkWindow *window,
5972 /* See long comments in gtk_window_move_resize()
5973 * on when it's safe to call this function.
5975 if (window->position == GTK_WIN_POS_CENTER_ALWAYS)
5977 gint center_x, center_y;
5979 center_window_on_monitor (window, new_width, new_height, ¢er_x, ¢er_y);
5987 gtk_window_move_resize (GtkWindow *window)
5991 * First we determine whether any information has changed that would
5992 * cause us to revise our last configure request. If we would send
5993 * a different configure request from last time, then
5994 * configure_request_size_changed = TRUE or
5995 * configure_request_pos_changed = TRUE. configure_request_size_changed
5996 * may be true due to new hints, a gtk_window_resize(), or whatever.
5997 * configure_request_pos_changed may be true due to gtk_window_set_position()
5998 * or gtk_window_move().
6000 * If the configure request has changed, we send off a new one. To
6001 * ensure GTK+ invariants are maintained (resize queue does what it
6002 * should), we go ahead and size_allocate the requested size in this
6005 * If the configure request has not changed, we don't ever resend
6006 * it, because it could mean fighting the user or window manager.
6009 * To prepare the configure request, we come up with a base size/pos:
6010 * - the one from gtk_window_move()/gtk_window_resize()
6011 * - else default_width, default_height if we haven't ever
6013 * - else the size request if we haven't ever been mapped,
6014 * as a substitute default size
6015 * - else the current size of the window, as received from
6016 * configure notifies (i.e. the current allocation)
6018 * If GTK_WIN_POS_CENTER_ALWAYS is active, we constrain
6019 * the position request to be centered.
6022 GtkContainer *container;
6023 GtkWindowGeometryInfo *info;
6024 GdkGeometry new_geometry;
6026 GdkRectangle new_request;
6027 gboolean configure_request_size_changed;
6028 gboolean configure_request_pos_changed;
6029 gboolean hints_changed; /* do we need to send these again */
6030 GtkWindowLastGeometryInfo saved_last_info;
6032 widget = GTK_WIDGET (window);
6033 container = GTK_CONTAINER (widget);
6034 info = gtk_window_get_geometry_info (window, TRUE);
6036 configure_request_size_changed = FALSE;
6037 configure_request_pos_changed = FALSE;
6039 gtk_window_compute_configure_request (window, &new_request,
6040 &new_geometry, &new_flags);
6042 /* This check implies the invariant that we never set info->last
6043 * without setting the hints and sending off a configure request.
6045 * If we change info->last without sending the request, we may
6048 if (info->last.configure_request.x != new_request.x ||
6049 info->last.configure_request.y != new_request.y)
6050 configure_request_pos_changed = TRUE;
6052 if ((info->last.configure_request.width != new_request.width ||
6053 info->last.configure_request.height != new_request.height))
6054 configure_request_size_changed = TRUE;
6056 hints_changed = FALSE;
6058 if (!gtk_window_compare_hints (&info->last.geometry, info->last.flags,
6059 &new_geometry, new_flags))
6061 hints_changed = TRUE;
6064 /* Position Constraints
6065 * ====================
6067 * POS_CENTER_ALWAYS is conceptually a constraint rather than
6068 * a default. The other POS_ values are used only when the
6069 * window is shown, not after that.
6071 * However, we can't implement a position constraint as
6072 * "anytime the window size changes, center the window"
6073 * because this may well end up fighting the WM or user. In
6074 * fact it gets in an infinite loop with at least one WM.
6076 * Basically, applications are in no way in a position to
6077 * constrain the position of a window, with one exception:
6078 * override redirect windows. (Really the intended purpose
6079 * of CENTER_ALWAYS anyhow, I would think.)
6081 * So the way we implement this "constraint" is to say that when WE
6082 * cause a move or resize, i.e. we make a configure request changing
6083 * window size, we recompute the CENTER_ALWAYS position to reflect
6084 * the new window size, and include it in our request. Also, if we
6085 * just turned on CENTER_ALWAYS we snap to center with a new
6086 * request. Otherwise, if we are just NOTIFIED of a move or resize
6087 * done by someone else e.g. the window manager, we do NOT send a
6088 * new configure request.
6090 * For override redirect windows, this works fine; all window
6091 * sizes are from our configure requests. For managed windows,
6092 * it is at least semi-sane, though who knows what the
6093 * app author is thinking.
6096 /* This condition should be kept in sync with the condition later on
6097 * that determines whether we send a configure request. i.e. we
6098 * should do this position constraining anytime we were going to
6099 * send a configure request anyhow, plus when constraints have
6102 if (configure_request_pos_changed ||
6103 configure_request_size_changed ||
6105 info->position_constraints_changed)
6107 /* We request the constrained position if:
6108 * - we were changing position, and need to clamp
6109 * the change to the constraint
6110 * - we're changing the size anyway
6111 * - set_position() was called to toggle CENTER_ALWAYS on
6114 gtk_window_constrain_position (window,
6120 /* Update whether we need to request a move */
6121 if (info->last.configure_request.x != new_request.x ||
6122 info->last.configure_request.y != new_request.y)
6123 configure_request_pos_changed = TRUE;
6125 configure_request_pos_changed = FALSE;
6129 if (window->type == GTK_WINDOW_TOPLEVEL)
6131 int notify_x, notify_y;
6133 /* this is the position from the last configure notify */
6134 gdk_window_get_position (widget->window, ¬ify_x, ¬ify_y);
6136 g_message ("--- %s ---\n"
6137 "last : %d,%d\t%d x %d\n"
6138 "this : %d,%d\t%d x %d\n"
6139 "alloc : %d,%d\t%d x %d\n"
6141 "resize: \t%d x %d\n"
6142 "size_changed: %d pos_changed: %d hints_changed: %d\n"
6143 "configure_notify_received: %d\n"
6144 "configure_request_count: %d\n"
6145 "position_constraints_changed: %d\n",
6146 window->title ? window->title : "(no title)",
6147 info->last.configure_request.x,
6148 info->last.configure_request.y,
6149 info->last.configure_request.width,
6150 info->last.configure_request.height,
6156 widget->allocation.width,
6157 widget->allocation.height,
6158 widget->requisition.width,
6159 widget->requisition.height,
6161 info->resize_height,
6162 configure_request_pos_changed,
6163 configure_request_size_changed,
6165 window->configure_notify_received,
6166 window->configure_request_count,
6167 info->position_constraints_changed);
6171 saved_last_info = info->last;
6172 info->last.geometry = new_geometry;
6173 info->last.flags = new_flags;
6174 info->last.configure_request = new_request;
6176 /* need to set PPosition so the WM will look at our position,
6177 * but we don't want to count PPosition coming and going as a hints
6178 * change for future iterations. So we saved info->last prior to
6182 /* Also, if the initial position was explicitly set, then we always
6183 * toggle on PPosition. This makes gtk_window_move(window, 0, 0)
6187 /* Also, we toggle on PPosition if GTK_WIN_POS_ is in use and
6188 * this is an initial map
6191 if ((configure_request_pos_changed ||
6192 info->initial_pos_set ||
6193 (window->need_default_position &&
6194 get_effective_position (window) != GTK_WIN_POS_NONE)) &&
6195 (new_flags & GDK_HINT_POS) == 0)
6197 new_flags |= GDK_HINT_POS;
6198 hints_changed = TRUE;
6201 /* Set hints if necessary
6204 gdk_window_set_geometry_hints (widget->window,
6208 /* handle resizing/moving and widget tree allocation
6210 if (window->configure_notify_received)
6212 GtkAllocation allocation;
6214 /* If we have received a configure event since
6215 * the last time in this function, we need to
6216 * accept our new size and size_allocate child widgets.
6217 * (see gtk_window_configure_event() for more details).
6219 * 1 or more configure notifies may have been received.
6220 * Also, configure_notify_received will only be TRUE
6221 * if all expected configure notifies have been received
6222 * (one per configure request), as an optimization.
6225 window->configure_notify_received = FALSE;
6227 /* gtk_window_configure_event() filled in widget->allocation */
6228 allocation = widget->allocation;
6229 gtk_widget_size_allocate (widget, &allocation);
6231 gdk_window_process_updates (widget->window, TRUE);
6233 gdk_window_configure_finished (widget->window);
6235 /* If the configure request changed, it means that
6237 * 1) coincidentally changed hints or widget properties
6238 * impacting the configure request before getting
6239 * a configure notify, or
6240 * 2) some broken widget is changing its size request
6241 * during size allocation, resulting in
6242 * a false appearance of changed configure request.
6244 * For 1), we could just go ahead and ask for the
6245 * new size right now, but doing that for 2)
6246 * might well be fighting the user (and can even
6247 * trigger a loop). Since we really don't want to
6248 * do that, we requeue a resize in hopes that
6249 * by the time it gets handled, the child has seen
6250 * the light and is willing to go along with the
6251 * new size. (this happens for the zvt widget, since
6252 * the size_allocate() above will have stored the
6253 * requisition corresponding to the new size in the
6256 * This doesn't buy us anything for 1), but it shouldn't
6257 * hurt us too badly, since it is what would have
6258 * happened if we had gotten the configure event before
6259 * the new size had been set.
6262 if (configure_request_size_changed ||
6263 configure_request_pos_changed)
6265 /* Don't change the recorded last info after all, because we
6266 * haven't actually updated to the new info yet - we decided
6267 * to postpone our configure request until later.
6269 info->last = saved_last_info;
6271 gtk_widget_queue_resize_no_redraw (widget); /* migth recurse for GTK_RESIZE_IMMEDIATE */
6274 return; /* Bail out, we didn't really process the move/resize */
6276 else if ((configure_request_size_changed || hints_changed) &&
6277 (widget->allocation.width != new_request.width ||
6278 widget->allocation.height != new_request.height))
6281 /* We are in one of the following situations:
6282 * A. configure_request_size_changed
6283 * our requisition has changed and we need a different window size,
6284 * so we request it from the window manager.
6285 * B. !configure_request_size_changed && hints_changed
6286 * the window manager rejects our size, but we have just changed the
6287 * window manager hints, so there's a chance our request will
6288 * be honoured this time, so we try again.
6290 * However, if the new requisition is the same as the current allocation,
6291 * we don't request it again, since we won't get a ConfigureNotify back from
6292 * the window manager unless it decides to change our requisition. If
6293 * we don't get the ConfigureNotify back, the resize queue will never be run.
6296 /* Now send the configure request */
6297 if (configure_request_pos_changed)
6301 gdk_window_move_resize (window->frame,
6302 new_request.x - window->frame_left,
6303 new_request.y - window->frame_top,
6304 new_request.width + window->frame_left + window->frame_right,
6305 new_request.height + window->frame_top + window->frame_bottom);
6306 gdk_window_resize (widget->window,
6307 new_request.width, new_request.height);
6310 gdk_window_move_resize (widget->window,
6311 new_request.x, new_request.y,
6312 new_request.width, new_request.height);
6314 else /* only size changed */
6317 gdk_window_resize (window->frame,
6318 new_request.width + window->frame_left + window->frame_right,
6319 new_request.height + window->frame_top + window->frame_bottom);
6320 gdk_window_resize (widget->window,
6321 new_request.width, new_request.height);
6324 if (window->type == GTK_WINDOW_POPUP)
6326 GtkAllocation allocation;
6328 /* Directly size allocate for override redirect (popup) windows. */
6331 allocation.width = new_request.width;
6332 allocation.height = new_request.height;
6334 gtk_widget_size_allocate (widget, &allocation);
6336 gdk_window_process_updates (widget->window, TRUE);
6338 if (container->resize_mode == GTK_RESIZE_QUEUE)
6339 gtk_widget_queue_draw (widget);
6343 /* Increment the number of have-not-yet-received-notify requests */
6344 window->configure_request_count += 1;
6345 gdk_window_freeze_toplevel_updates_libgtk_only (widget->window);
6347 /* for GTK_RESIZE_QUEUE toplevels, we are now awaiting a new
6348 * configure event in response to our resizing request.
6349 * the configure event will cause a new resize with
6350 * ->configure_notify_received=TRUE.
6351 * until then, we want to
6352 * - discard expose events
6353 * - coalesce resizes for our children
6354 * - defer any window resizes until the configure event arrived
6355 * to achieve this, we queue a resize for the window, but remove its
6356 * resizing handler, so resizing will not be handled from the next
6357 * idle handler but when the configure event arrives.
6359 * FIXME: we should also dequeue the pending redraws here, since
6360 * we handle those ourselves upon ->configure_notify_received==TRUE.
6362 if (container->resize_mode == GTK_RESIZE_QUEUE)
6364 gtk_widget_queue_resize_no_redraw (widget);
6365 _gtk_container_dequeue_resize_handler (container);
6371 /* Handle any position changes.
6373 if (configure_request_pos_changed)
6377 gdk_window_move (window->frame,
6378 new_request.x - window->frame_left,
6379 new_request.y - window->frame_top);
6382 gdk_window_move (widget->window,
6383 new_request.x, new_request.y);
6386 /* And run the resize queue.
6388 gtk_container_resize_children (container);
6391 /* We have now processed a move/resize since the last position
6392 * constraint change, setting of the initial position, or resize.
6393 * (Not resetting these flags here can lead to infinite loops for
6394 * GTK_RESIZE_IMMEDIATE containers)
6396 info->position_constraints_changed = FALSE;
6397 info->initial_pos_set = FALSE;
6398 info->resize_width = -1;
6399 info->resize_height = -1;
6402 /* Compare two sets of Geometry hints for equality.
6405 gtk_window_compare_hints (GdkGeometry *geometry_a,
6407 GdkGeometry *geometry_b,
6410 if (flags_a != flags_b)
6413 if ((flags_a & GDK_HINT_MIN_SIZE) &&
6414 (geometry_a->min_width != geometry_b->min_width ||
6415 geometry_a->min_height != geometry_b->min_height))
6418 if ((flags_a & GDK_HINT_MAX_SIZE) &&
6419 (geometry_a->max_width != geometry_b->max_width ||
6420 geometry_a->max_height != geometry_b->max_height))
6423 if ((flags_a & GDK_HINT_BASE_SIZE) &&
6424 (geometry_a->base_width != geometry_b->base_width ||
6425 geometry_a->base_height != geometry_b->base_height))
6428 if ((flags_a & GDK_HINT_ASPECT) &&
6429 (geometry_a->min_aspect != geometry_b->min_aspect ||
6430 geometry_a->max_aspect != geometry_b->max_aspect))
6433 if ((flags_a & GDK_HINT_RESIZE_INC) &&
6434 (geometry_a->width_inc != geometry_b->width_inc ||
6435 geometry_a->height_inc != geometry_b->height_inc))
6438 if ((flags_a & GDK_HINT_WIN_GRAVITY) &&
6439 geometry_a->win_gravity != geometry_b->win_gravity)
6446 _gtk_window_constrain_size (GtkWindow *window,
6452 GtkWindowGeometryInfo *info;
6454 g_return_if_fail (GTK_IS_WINDOW (window));
6456 info = window->geometry_info;
6459 GdkWindowHints flags = info->last.flags;
6460 GdkGeometry *geometry = &info->last.geometry;
6462 gtk_window_constrain_size (window,
6473 gtk_window_constrain_size (GtkWindow *window,
6474 GdkGeometry *geometry,
6481 gdk_window_constrain_size (geometry, flags, width, height,
6482 new_width, new_height);
6485 /* Compute the set of geometry hints and flags for a window
6486 * based on the application set geometry, and requisiition
6487 * of the window. gtk_widget_size_request() must have been
6491 gtk_window_compute_hints (GtkWindow *window,
6492 GdkGeometry *new_geometry,
6496 gint extra_width = 0;
6497 gint extra_height = 0;
6498 GtkWindowGeometryInfo *geometry_info;
6499 GtkRequisition requisition;
6501 widget = GTK_WIDGET (window);
6503 gtk_widget_get_child_requisition (widget, &requisition);
6504 geometry_info = gtk_window_get_geometry_info (GTK_WINDOW (widget), FALSE);
6508 *new_flags = geometry_info->mask;
6509 *new_geometry = geometry_info->geometry;
6516 if (geometry_info && geometry_info->widget)
6518 GtkRequisition child_requisition;
6520 /* FIXME: This really isn't right. It gets the min size wrong and forces
6521 * callers to do horrible hacks like set a huge usize on the child requisition
6522 * to get the base size right. We really want to find the answers to:
6524 * - If the geometry widget was infinitely big, how much extra space
6525 * would be needed for the stuff around it.
6527 * - If the geometry widget was infinitely small, how big would the
6528 * window still have to be.
6530 * Finding these answers would be a bit of a mess here. (Bug #68668)
6532 gtk_widget_get_child_requisition (geometry_info->widget, &child_requisition);
6534 extra_width = widget->requisition.width - child_requisition.width;
6535 extra_height = widget->requisition.height - child_requisition.height;
6538 /* We don't want to set GDK_HINT_POS in here, we just set it
6539 * in gtk_window_move_resize() when we want the position
6543 if (*new_flags & GDK_HINT_BASE_SIZE)
6545 new_geometry->base_width += extra_width;
6546 new_geometry->base_height += extra_height;
6548 else if (!(*new_flags & GDK_HINT_MIN_SIZE) &&
6549 (*new_flags & GDK_HINT_RESIZE_INC) &&
6550 ((extra_width != 0) || (extra_height != 0)))
6552 *new_flags |= GDK_HINT_BASE_SIZE;
6554 new_geometry->base_width = extra_width;
6555 new_geometry->base_height = extra_height;
6558 if (*new_flags & GDK_HINT_MIN_SIZE)
6560 if (new_geometry->min_width < 0)
6561 new_geometry->min_width = requisition.width;
6563 new_geometry->min_width += extra_width;
6565 if (new_geometry->min_height < 0)
6566 new_geometry->min_height = requisition.height;
6568 new_geometry->min_height += extra_height;
6570 else if (!window->allow_shrink)
6572 *new_flags |= GDK_HINT_MIN_SIZE;
6574 new_geometry->min_width = requisition.width;
6575 new_geometry->min_height = requisition.height;
6578 if (*new_flags & GDK_HINT_MAX_SIZE)
6580 if (new_geometry->max_width < 0)
6581 new_geometry->max_width = requisition.width;
6583 new_geometry->max_width += extra_width;
6585 if (new_geometry->max_height < 0)
6586 new_geometry->max_height = requisition.height;
6588 new_geometry->max_height += extra_height;
6590 else if (!window->allow_grow)
6592 *new_flags |= GDK_HINT_MAX_SIZE;
6594 new_geometry->max_width = requisition.width;
6595 new_geometry->max_height = requisition.height;
6598 *new_flags |= GDK_HINT_WIN_GRAVITY;
6599 new_geometry->win_gravity = window->gravity;
6602 /***********************
6603 * Redrawing functions *
6604 ***********************/
6607 gtk_window_paint (GtkWidget *widget,
6610 gtk_paint_flat_box (widget->style, widget->window, GTK_STATE_NORMAL,
6611 GTK_SHADOW_NONE, area, widget, "base", 0, 0, -1, -1);
6615 gtk_window_expose (GtkWidget *widget,
6616 GdkEventExpose *event)
6618 if (!gtk_widget_get_app_paintable (widget))
6619 gtk_window_paint (widget, &event->area);
6621 if (GTK_WIDGET_CLASS (gtk_window_parent_class)->expose_event)
6622 return GTK_WIDGET_CLASS (gtk_window_parent_class)->expose_event (widget, event);
6628 * gtk_window_set_has_frame:
6629 * @window: a #GtkWindow
6630 * @setting: a boolean
6632 * (Note: this is a special-purpose function for the framebuffer port,
6633 * that causes GTK+ to draw its own window border. For most applications,
6634 * you want gtk_window_set_decorated() instead, which tells the window
6635 * manager whether to draw the window border.)
6637 * If this function is called on a window with setting of %TRUE, before
6638 * it is realized or showed, it will have a "frame" window around
6639 * @window->window, accessible in @window->frame. Using the signal
6640 * frame_event you can receive all events targeted at the frame.
6642 * This function is used by the linux-fb port to implement managed
6643 * windows, but it could conceivably be used by X-programs that
6644 * want to do their own window decorations.
6648 gtk_window_set_has_frame (GtkWindow *window,
6651 g_return_if_fail (GTK_IS_WINDOW (window));
6652 g_return_if_fail (!gtk_widget_get_realized (GTK_WIDGET (window)));
6654 window->has_frame = setting != FALSE;
6658 * gtk_window_get_has_frame:
6659 * @window: a #GtkWindow
6661 * Accessor for whether the window has a frame window exterior to
6662 * @window->window. Gets the value set by gtk_window_set_has_frame ().
6664 * Return value: %TRUE if a frame has been added to the window
6665 * via gtk_window_set_has_frame().
6668 gtk_window_get_has_frame (GtkWindow *window)
6670 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
6672 return window->has_frame;
6676 * gtk_window_set_frame_dimensions:
6677 * @window: a #GtkWindow that has a frame
6678 * @left: The width of the left border
6679 * @top: The height of the top border
6680 * @right: The width of the right border
6681 * @bottom: The height of the bottom border
6683 * (Note: this is a special-purpose function intended for the framebuffer
6684 * port; see gtk_window_set_has_frame(). It will have no effect on the
6685 * window border drawn by the window manager, which is the normal
6686 * case when using the X Window system.)
6688 * For windows with frames (see gtk_window_set_has_frame()) this function
6689 * can be used to change the size of the frame border.
6692 gtk_window_set_frame_dimensions (GtkWindow *window,
6700 g_return_if_fail (GTK_IS_WINDOW (window));
6702 widget = GTK_WIDGET (window);
6704 if (window->frame_left == left &&
6705 window->frame_top == top &&
6706 window->frame_right == right &&
6707 window->frame_bottom == bottom)
6710 window->frame_left = left;
6711 window->frame_top = top;
6712 window->frame_right = right;
6713 window->frame_bottom = bottom;
6715 if (gtk_widget_get_realized (widget) && window->frame)
6717 gint width = widget->allocation.width + left + right;
6718 gint height = widget->allocation.height + top + bottom;
6719 gdk_window_resize (window->frame, width, height);
6720 gtk_decorated_window_move_resize_window (window,
6722 widget->allocation.width,
6723 widget->allocation.height);
6728 * gtk_window_present:
6729 * @window: a #GtkWindow
6731 * Presents a window to the user. This may mean raising the window
6732 * in the stacking order, deiconifying it, moving it to the current
6733 * desktop, and/or giving it the keyboard focus, possibly dependent
6734 * on the user's platform, window manager, and preferences.
6736 * If @window is hidden, this function calls gtk_widget_show()
6739 * This function should be used when the user tries to open a window
6740 * that's already open. Say for example the preferences dialog is
6741 * currently open, and the user chooses Preferences from the menu
6742 * a second time; use gtk_window_present() to move the already-open dialog
6743 * where the user can see it.
6745 * If you are calling this function in response to a user interaction,
6746 * it is preferable to use gtk_window_present_with_time().
6750 gtk_window_present (GtkWindow *window)
6752 gtk_window_present_with_time (window, GDK_CURRENT_TIME);
6756 * gtk_window_present_with_time:
6757 * @window: a #GtkWindow
6758 * @timestamp: the timestamp of the user interaction (typically a
6759 * button or key press event) which triggered this call
6761 * Presents a window to the user in response to a user interaction.
6762 * If you need to present a window without a timestamp, use
6763 * gtk_window_present(). See gtk_window_present() for details.
6768 gtk_window_present_with_time (GtkWindow *window,
6773 g_return_if_fail (GTK_IS_WINDOW (window));
6775 widget = GTK_WIDGET (window);
6777 if (gtk_widget_get_visible (widget))
6779 g_assert (widget->window != NULL);
6781 gdk_window_show (widget->window);
6783 /* Translate a timestamp of GDK_CURRENT_TIME appropriately */
6784 if (timestamp == GDK_CURRENT_TIME)
6786 #ifdef GDK_WINDOWING_X11
6787 GdkDisplay *display;
6789 display = gtk_widget_get_display (GTK_WIDGET (window));
6790 timestamp = gdk_x11_display_get_user_time (display);
6792 timestamp = gtk_get_current_event_time ();
6796 gdk_window_focus (widget->window, timestamp);
6800 gtk_widget_show (widget);
6805 * gtk_window_iconify:
6806 * @window: a #GtkWindow
6808 * Asks to iconify (i.e. minimize) the specified @window. Note that
6809 * you shouldn't assume the window is definitely iconified afterward,
6810 * because other entities (e.g. the user or <link
6811 * linkend="gtk-X11-arch">window manager</link>) could deiconify it
6812 * again, or there may not be a window manager in which case
6813 * iconification isn't possible, etc. But normally the window will end
6814 * up iconified. Just don't write code that crashes if not.
6816 * It's permitted to call this function before showing a window,
6817 * in which case the window will be iconified before it ever appears
6820 * You can track iconification via the "window-state-event" signal
6825 gtk_window_iconify (GtkWindow *window)
6828 GdkWindow *toplevel;
6830 g_return_if_fail (GTK_IS_WINDOW (window));
6832 widget = GTK_WIDGET (window);
6834 window->iconify_initially = TRUE;
6837 toplevel = window->frame;
6839 toplevel = widget->window;
6841 if (toplevel != NULL)
6842 gdk_window_iconify (toplevel);
6846 * gtk_window_deiconify:
6847 * @window: a #GtkWindow
6849 * Asks to deiconify (i.e. unminimize) the specified @window. Note
6850 * that you shouldn't assume the window is definitely deiconified
6851 * afterward, because other entities (e.g. the user or <link
6852 * linkend="gtk-X11-arch">window manager</link>) could iconify it
6853 * again before your code which assumes deiconification gets to run.
6855 * You can track iconification via the "window-state-event" signal
6859 gtk_window_deiconify (GtkWindow *window)
6862 GdkWindow *toplevel;
6864 g_return_if_fail (GTK_IS_WINDOW (window));
6866 widget = GTK_WIDGET (window);
6868 window->iconify_initially = FALSE;
6871 toplevel = window->frame;
6873 toplevel = widget->window;
6875 if (toplevel != NULL)
6876 gdk_window_deiconify (toplevel);
6881 * @window: a #GtkWindow
6883 * Asks to stick @window, which means that it will appear on all user
6884 * desktops. Note that you shouldn't assume the window is definitely
6885 * stuck afterward, because other entities (e.g. the user or <link
6886 * linkend="gtk-X11-arch">window manager</link>) could unstick it
6887 * again, and some window managers do not support sticking
6888 * windows. But normally the window will end up stuck. Just don't
6889 * write code that crashes if not.
6891 * It's permitted to call this function before showing a window.
6893 * You can track stickiness via the "window-state-event" signal
6898 gtk_window_stick (GtkWindow *window)
6901 GdkWindow *toplevel;
6903 g_return_if_fail (GTK_IS_WINDOW (window));
6905 widget = GTK_WIDGET (window);
6907 window->stick_initially = TRUE;
6910 toplevel = window->frame;
6912 toplevel = widget->window;
6914 if (toplevel != NULL)
6915 gdk_window_stick (toplevel);
6919 * gtk_window_unstick:
6920 * @window: a #GtkWindow
6922 * Asks to unstick @window, which means that it will appear on only
6923 * one of the user's desktops. Note that you shouldn't assume the
6924 * window is definitely unstuck afterward, because other entities
6925 * (e.g. the user or <link linkend="gtk-X11-arch">window
6926 * manager</link>) could stick it again. But normally the window will
6927 * end up stuck. Just don't write code that crashes if not.
6929 * You can track stickiness via the "window-state-event" signal
6934 gtk_window_unstick (GtkWindow *window)
6937 GdkWindow *toplevel;
6939 g_return_if_fail (GTK_IS_WINDOW (window));
6941 widget = GTK_WIDGET (window);
6943 window->stick_initially = FALSE;
6946 toplevel = window->frame;
6948 toplevel = widget->window;
6950 if (toplevel != NULL)
6951 gdk_window_unstick (toplevel);
6955 * gtk_window_maximize:
6956 * @window: a #GtkWindow
6958 * Asks to maximize @window, so that it becomes full-screen. Note that
6959 * you shouldn't assume the window is definitely maximized afterward,
6960 * because other entities (e.g. the user or <link
6961 * linkend="gtk-X11-arch">window manager</link>) could unmaximize it
6962 * again, and not all window managers support maximization. But
6963 * normally the window will end up maximized. Just don't write code
6964 * that crashes if not.
6966 * It's permitted to call this function before showing a window,
6967 * in which case the window will be maximized when it appears onscreen
6970 * You can track maximization via the "window-state-event" signal
6975 gtk_window_maximize (GtkWindow *window)
6978 GdkWindow *toplevel;
6980 g_return_if_fail (GTK_IS_WINDOW (window));
6982 widget = GTK_WIDGET (window);
6984 window->maximize_initially = TRUE;
6987 toplevel = window->frame;
6989 toplevel = widget->window;
6991 if (toplevel != NULL)
6992 gdk_window_maximize (toplevel);
6996 * gtk_window_unmaximize:
6997 * @window: a #GtkWindow
6999 * Asks to unmaximize @window. Note that you shouldn't assume the
7000 * window is definitely unmaximized afterward, because other entities
7001 * (e.g. the user or <link linkend="gtk-X11-arch">window
7002 * manager</link>) could maximize it again, and not all window
7003 * managers honor requests to unmaximize. But normally the window will
7004 * end up unmaximized. Just don't write code that crashes if not.
7006 * You can track maximization via the "window-state-event" signal
7011 gtk_window_unmaximize (GtkWindow *window)
7014 GdkWindow *toplevel;
7016 g_return_if_fail (GTK_IS_WINDOW (window));
7018 widget = GTK_WIDGET (window);
7020 window->maximize_initially = FALSE;
7023 toplevel = window->frame;
7025 toplevel = widget->window;
7027 if (toplevel != NULL)
7028 gdk_window_unmaximize (toplevel);
7032 * gtk_window_fullscreen:
7033 * @window: a #GtkWindow
7035 * Asks to place @window in the fullscreen state. Note that you
7036 * shouldn't assume the window is definitely full screen afterward,
7037 * because other entities (e.g. the user or <link
7038 * linkend="gtk-X11-arch">window manager</link>) could unfullscreen it
7039 * again, and not all window managers honor requests to fullscreen
7040 * windows. But normally the window will end up fullscreen. Just
7041 * don't write code that crashes if not.
7043 * You can track the fullscreen state via the "window-state-event" signal
7049 gtk_window_fullscreen (GtkWindow *window)
7052 GdkWindow *toplevel;
7053 GtkWindowPrivate *priv;
7055 g_return_if_fail (GTK_IS_WINDOW (window));
7057 widget = GTK_WIDGET (window);
7058 priv = GTK_WINDOW_GET_PRIVATE (window);
7060 priv->fullscreen_initially = TRUE;
7063 toplevel = window->frame;
7065 toplevel = widget->window;
7067 if (toplevel != NULL)
7068 gdk_window_fullscreen (toplevel);
7072 * gtk_window_unfullscreen:
7073 * @window: a #GtkWindow
7075 * Asks to toggle off the fullscreen state for @window. Note that you
7076 * shouldn't assume the window is definitely not full screen
7077 * afterward, because other entities (e.g. the user or <link
7078 * linkend="gtk-X11-arch">window manager</link>) could fullscreen it
7079 * again, and not all window managers honor requests to unfullscreen
7080 * windows. But normally the window will end up restored to its normal
7081 * state. Just don't write code that crashes if not.
7083 * You can track the fullscreen state via the "window-state-event" signal
7089 gtk_window_unfullscreen (GtkWindow *window)
7092 GdkWindow *toplevel;
7093 GtkWindowPrivate *priv;
7095 g_return_if_fail (GTK_IS_WINDOW (window));
7097 widget = GTK_WIDGET (window);
7098 priv = GTK_WINDOW_GET_PRIVATE (window);
7100 priv->fullscreen_initially = FALSE;
7103 toplevel = window->frame;
7105 toplevel = widget->window;
7107 if (toplevel != NULL)
7108 gdk_window_unfullscreen (toplevel);
7112 * gtk_window_set_keep_above:
7113 * @window: a #GtkWindow
7114 * @setting: whether to keep @window above other windows
7116 * Asks to keep @window above, so that it stays on top. Note that
7117 * you shouldn't assume the window is definitely above afterward,
7118 * because other entities (e.g. the user or <link
7119 * linkend="gtk-X11-arch">window manager</link>) could not keep it above,
7120 * and not all window managers support keeping windows above. But
7121 * normally the window will end kept above. Just don't write code
7122 * that crashes if not.
7124 * It's permitted to call this function before showing a window,
7125 * in which case the window will be kept above when it appears onscreen
7128 * You can track the above state via the "window-state-event" signal
7131 * Note that, according to the <ulink
7132 * url="http://www.freedesktop.org/Standards/wm-spec">Extended Window
7133 * Manager Hints</ulink> specification, the above state is mainly meant
7134 * for user preferences and should not be used by applications e.g. for
7135 * drawing attention to their dialogs.
7140 gtk_window_set_keep_above (GtkWindow *window,
7144 GtkWindowPrivate *priv;
7145 GdkWindow *toplevel;
7147 g_return_if_fail (GTK_IS_WINDOW (window));
7149 widget = GTK_WIDGET (window);
7150 priv = GTK_WINDOW_GET_PRIVATE (window);
7152 priv->above_initially = setting != FALSE;
7154 priv->below_initially = FALSE;
7157 toplevel = window->frame;
7159 toplevel = widget->window;
7161 if (toplevel != NULL)
7162 gdk_window_set_keep_above (toplevel, setting);
7166 * gtk_window_set_keep_below:
7167 * @window: a #GtkWindow
7168 * @setting: whether to keep @window below other windows
7170 * Asks to keep @window below, so that it stays in bottom. Note that
7171 * you shouldn't assume the window is definitely below afterward,
7172 * because other entities (e.g. the user or <link
7173 * linkend="gtk-X11-arch">window manager</link>) could not keep it below,
7174 * and not all window managers support putting windows below. But
7175 * normally the window will be kept below. Just don't write code
7176 * that crashes if not.
7178 * It's permitted to call this function before showing a window,
7179 * in which case the window will be kept below when it appears onscreen
7182 * You can track the below state via the "window-state-event" signal
7185 * Note that, according to the <ulink
7186 * url="http://www.freedesktop.org/Standards/wm-spec">Extended Window
7187 * Manager Hints</ulink> specification, the above state is mainly meant
7188 * for user preferences and should not be used by applications e.g. for
7189 * drawing attention to their dialogs.
7194 gtk_window_set_keep_below (GtkWindow *window,
7198 GtkWindowPrivate *priv;
7199 GdkWindow *toplevel;
7201 g_return_if_fail (GTK_IS_WINDOW (window));
7203 widget = GTK_WIDGET (window);
7204 priv = GTK_WINDOW_GET_PRIVATE (window);
7206 priv->below_initially = setting != FALSE;
7208 priv->above_initially = FALSE;
7211 toplevel = window->frame;
7213 toplevel = widget->window;
7215 if (toplevel != NULL)
7216 gdk_window_set_keep_below (toplevel, setting);
7220 * gtk_window_set_resizable:
7221 * @window: a #GtkWindow
7222 * @resizable: %TRUE if the user can resize this window
7224 * Sets whether the user can resize a window. Windows are user resizable
7228 gtk_window_set_resizable (GtkWindow *window,
7231 g_return_if_fail (GTK_IS_WINDOW (window));
7233 gtk_window_set_policy_internal (window, FALSE, resizable, FALSE);
7237 * gtk_window_get_resizable:
7238 * @window: a #GtkWindow
7240 * Gets the value set by gtk_window_set_resizable().
7242 * Return value: %TRUE if the user can resize the window
7245 gtk_window_get_resizable (GtkWindow *window)
7247 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
7249 /* allow_grow is most likely to indicate the semantic concept we
7250 * mean by "resizable" (and will be a reliable indicator if
7251 * set_policy() hasn't been called)
7253 return window->allow_grow;
7257 * gtk_window_set_gravity:
7258 * @window: a #GtkWindow
7259 * @gravity: window gravity
7261 * Window gravity defines the meaning of coordinates passed to
7262 * gtk_window_move(). See gtk_window_move() and #GdkGravity for
7265 * The default window gravity is #GDK_GRAVITY_NORTH_WEST which will
7266 * typically "do what you mean."
7270 gtk_window_set_gravity (GtkWindow *window,
7273 g_return_if_fail (GTK_IS_WINDOW (window));
7275 if (gravity != window->gravity)
7277 window->gravity = gravity;
7279 /* gtk_window_move_resize() will adapt gravity
7281 gtk_widget_queue_resize_no_redraw (GTK_WIDGET (window));
7283 g_object_notify (G_OBJECT (window), "gravity");
7288 * gtk_window_get_gravity:
7289 * @window: a #GtkWindow
7291 * Gets the value set by gtk_window_set_gravity().
7293 * Return value: (transfer none): window gravity
7296 gtk_window_get_gravity (GtkWindow *window)
7298 g_return_val_if_fail (GTK_IS_WINDOW (window), 0);
7300 return window->gravity;
7304 * gtk_window_begin_resize_drag:
7305 * @window: a #GtkWindow
7306 * @button: mouse button that initiated the drag
7307 * @edge: position of the resize control
7308 * @root_x: X position where the user clicked to initiate the drag, in root window coordinates
7309 * @root_y: Y position where the user clicked to initiate the drag
7310 * @timestamp: timestamp from the click event that initiated the drag
7312 * Starts resizing a window. This function is used if an application
7313 * has window resizing controls. When GDK can support it, the resize
7314 * will be done using the standard mechanism for the <link
7315 * linkend="gtk-X11-arch">window manager</link> or windowing
7316 * system. Otherwise, GDK will try to emulate window resizing,
7317 * potentially not all that well, depending on the windowing system.
7321 gtk_window_begin_resize_drag (GtkWindow *window,
7329 GdkWindow *toplevel;
7331 g_return_if_fail (GTK_IS_WINDOW (window));
7332 widget = GTK_WIDGET (window);
7333 g_return_if_fail (gtk_widget_get_visible (widget));
7336 toplevel = window->frame;
7338 toplevel = widget->window;
7340 gdk_window_begin_resize_drag (toplevel,
7347 * gtk_window_get_frame_dimensions:
7348 * @window: a #GtkWindow
7349 * @left: (allow-none): location to store the width of the frame at the left, or %NULL
7350 * @top: (allow-none): location to store the height of the frame at the top, or %NULL
7351 * @right: (allow-none): location to store the width of the frame at the returns, or %NULL
7352 * @bottom: (allow-none): location to store the height of the frame at the bottom, or %NULL
7354 * (Note: this is a special-purpose function intended for the
7355 * framebuffer port; see gtk_window_set_has_frame(). It will not
7356 * return the size of the window border drawn by the <link
7357 * linkend="gtk-X11-arch">window manager</link>, which is the normal
7358 * case when using a windowing system. See
7359 * gdk_window_get_frame_extents() to get the standard window border
7362 * Retrieves the dimensions of the frame window for this toplevel.
7363 * See gtk_window_set_has_frame(), gtk_window_set_frame_dimensions().
7366 gtk_window_get_frame_dimensions (GtkWindow *window,
7372 g_return_if_fail (GTK_IS_WINDOW (window));
7375 *left = window->frame_left;
7377 *top = window->frame_top;
7379 *right = window->frame_right;
7381 *bottom = window->frame_bottom;
7385 * gtk_window_begin_move_drag:
7386 * @window: a #GtkWindow
7387 * @button: mouse button that initiated the drag
7388 * @root_x: X position where the user clicked to initiate the drag, in root window coordinates
7389 * @root_y: Y position where the user clicked to initiate the drag
7390 * @timestamp: timestamp from the click event that initiated the drag
7392 * Starts moving a window. This function is used if an application has
7393 * window movement grips. When GDK can support it, the window movement
7394 * will be done using the standard mechanism for the <link
7395 * linkend="gtk-X11-arch">window manager</link> or windowing
7396 * system. Otherwise, GDK will try to emulate window movement,
7397 * potentially not all that well, depending on the windowing system.
7401 gtk_window_begin_move_drag (GtkWindow *window,
7408 GdkWindow *toplevel;
7410 g_return_if_fail (GTK_IS_WINDOW (window));
7411 widget = GTK_WIDGET (window);
7412 g_return_if_fail (gtk_widget_get_visible (widget));
7415 toplevel = window->frame;
7417 toplevel = widget->window;
7419 gdk_window_begin_move_drag (toplevel,
7426 * gtk_window_set_screen:
7427 * @window: a #GtkWindow.
7428 * @screen: a #GdkScreen.
7430 * Sets the #GdkScreen where the @window is displayed; if
7431 * the window is already mapped, it will be unmapped, and
7432 * then remapped on the new screen.
7437 gtk_window_set_screen (GtkWindow *window,
7441 GdkScreen *previous_screen;
7442 gboolean was_mapped;
7444 g_return_if_fail (GTK_IS_WINDOW (window));
7445 g_return_if_fail (GDK_IS_SCREEN (screen));
7447 if (screen == window->screen)
7450 widget = GTK_WIDGET (window);
7452 previous_screen = window->screen;
7453 was_mapped = gtk_widget_get_mapped (widget);
7456 gtk_widget_unmap (widget);
7457 if (gtk_widget_get_realized (widget))
7458 gtk_widget_unrealize (widget);
7460 gtk_window_free_key_hash (window);
7461 window->screen = screen;
7462 gtk_widget_reset_rc_styles (widget);
7463 if (screen != previous_screen)
7465 g_signal_handlers_disconnect_by_func (previous_screen,
7466 gtk_window_on_composited_changed, window);
7467 g_signal_connect (screen, "composited-changed",
7468 G_CALLBACK (gtk_window_on_composited_changed), window);
7470 _gtk_widget_propagate_screen_changed (widget, previous_screen);
7471 _gtk_widget_propagate_composited_changed (widget);
7473 g_object_notify (G_OBJECT (window), "screen");
7476 gtk_widget_map (widget);
7480 gtk_window_on_composited_changed (GdkScreen *screen,
7483 gtk_widget_queue_draw (GTK_WIDGET (window));
7485 _gtk_widget_propagate_composited_changed (GTK_WIDGET (window));
7489 gtk_window_check_screen (GtkWindow *window)
7492 return window->screen;
7495 g_warning ("Screen for GtkWindow not set; you must always set\n"
7496 "a screen for a GtkWindow before using the window");
7502 * gtk_window_get_screen:
7503 * @window: a #GtkWindow.
7505 * Returns the #GdkScreen associated with @window.
7507 * Return value: (transfer none): a #GdkScreen.
7512 gtk_window_get_screen (GtkWindow *window)
7514 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
7516 return window->screen;
7520 * gtk_window_is_active:
7521 * @window: a #GtkWindow
7523 * Returns whether the window is part of the current active toplevel.
7524 * (That is, the toplevel window receiving keystrokes.)
7525 * The return value is %TRUE if the window is active toplevel
7526 * itself, but also if it is, say, a #GtkPlug embedded in the active toplevel.
7527 * You might use this function if you wanted to draw a widget
7528 * differently in an active window from a widget in an inactive window.
7529 * See gtk_window_has_toplevel_focus()
7531 * Return value: %TRUE if the window part of the current active window.
7536 gtk_window_is_active (GtkWindow *window)
7538 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
7540 return window->is_active;
7544 * gtk_window_has_toplevel_focus:
7545 * @window: a #GtkWindow
7547 * Returns whether the input focus is within this GtkWindow.
7548 * For real toplevel windows, this is identical to gtk_window_is_active(),
7549 * but for embedded windows, like #GtkPlug, the results will differ.
7551 * Return value: %TRUE if the input focus is within this GtkWindow
7556 gtk_window_has_toplevel_focus (GtkWindow *window)
7558 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
7560 return window->has_toplevel_focus;
7564 gtk_window_group_class_init (GtkWindowGroupClass *klass)
7569 gtk_window_group_get_type (void)
7571 static GType window_group_type = 0;
7573 if (!window_group_type)
7575 const GTypeInfo window_group_info =
7577 sizeof (GtkWindowGroupClass),
7578 NULL, /* base_init */
7579 NULL, /* base_finalize */
7580 (GClassInitFunc) gtk_window_group_class_init,
7581 NULL, /* class_finalize */
7582 NULL, /* class_data */
7583 sizeof (GtkWindowGroup),
7584 0, /* n_preallocs */
7585 (GInstanceInitFunc) NULL,
7588 window_group_type = g_type_register_static (G_TYPE_OBJECT, I_("GtkWindowGroup"),
7589 &window_group_info, 0);
7592 return window_group_type;
7596 * gtk_window_group_new:
7598 * Creates a new #GtkWindowGroup object. Grabs added with
7599 * gtk_grab_add() only affect windows within the same #GtkWindowGroup.
7601 * Return value: a new #GtkWindowGroup.
7604 gtk_window_group_new (void)
7606 return g_object_new (GTK_TYPE_WINDOW_GROUP, NULL);
7610 window_group_cleanup_grabs (GtkWindowGroup *group,
7614 GSList *to_remove = NULL;
7616 tmp_list = group->grabs;
7619 if (gtk_widget_get_toplevel (tmp_list->data) == (GtkWidget*) window)
7620 to_remove = g_slist_prepend (to_remove, g_object_ref (tmp_list->data));
7621 tmp_list = tmp_list->next;
7626 gtk_grab_remove (to_remove->data);
7627 g_object_unref (to_remove->data);
7628 to_remove = g_slist_delete_link (to_remove, to_remove);
7633 * gtk_window_group_add_window:
7634 * @window_group: a #GtkWindowGroup
7635 * @window: the #GtkWindow to add
7637 * Adds a window to a #GtkWindowGroup.
7640 gtk_window_group_add_window (GtkWindowGroup *window_group,
7643 g_return_if_fail (GTK_IS_WINDOW_GROUP (window_group));
7644 g_return_if_fail (GTK_IS_WINDOW (window));
7646 if (window->group != window_group)
7648 g_object_ref (window);
7649 g_object_ref (window_group);
7652 gtk_window_group_remove_window (window->group, window);
7654 window_group_cleanup_grabs (gtk_window_get_group (NULL), window);
7656 window->group = window_group;
7658 g_object_unref (window);
7663 * gtk_window_group_remove_window:
7664 * @window_group: a #GtkWindowGroup
7665 * @window: the #GtkWindow to remove
7667 * Removes a window from a #GtkWindowGroup.
7670 gtk_window_group_remove_window (GtkWindowGroup *window_group,
7673 g_return_if_fail (GTK_IS_WINDOW_GROUP (window_group));
7674 g_return_if_fail (GTK_IS_WINDOW (window));
7675 g_return_if_fail (window->group == window_group);
7677 g_object_ref (window);
7679 window_group_cleanup_grabs (window_group, window);
7680 window->group = NULL;
7682 g_object_unref (window_group);
7683 g_object_unref (window);
7687 * gtk_window_group_list_windows:
7688 * @window_group: a #GtkWindowGroup
7690 * Returns a list of the #GtkWindows that belong to @window_group.
7692 * Returns: (element-type GtkWidget) (transfer container): A newly-allocated list of
7693 * windows inside the group.
7698 gtk_window_group_list_windows (GtkWindowGroup *window_group)
7700 GList *toplevels, *toplevel, *group_windows;
7702 g_return_val_if_fail (GTK_IS_WINDOW_GROUP (window_group), NULL);
7704 group_windows = NULL;
7705 toplevels = gtk_window_list_toplevels ();
7707 for (toplevel = toplevels; toplevel; toplevel = toplevel->next)
7709 GtkWindow *window = toplevel->data;
7711 if (window_group == window->group)
7712 group_windows = g_list_prepend (group_windows, window);
7715 return g_list_reverse (group_windows);
7719 * gtk_window_get_group:
7720 * @window: (allow-none): a #GtkWindow, or %NULL
7722 * Returns the group for @window or the default group, if
7723 * @window is %NULL or if @window does not have an explicit
7726 * Returns: (transfer none): the #GtkWindowGroup for a window or the default group
7731 gtk_window_get_group (GtkWindow *window)
7733 if (window && window->group)
7734 return window->group;
7737 static GtkWindowGroup *default_group = NULL;
7740 default_group = gtk_window_group_new ();
7742 return default_group;
7746 /* Return the current grab widget of the given group
7749 _gtk_window_group_get_current_grab (GtkWindowGroup *window_group)
7751 if (window_group->grabs)
7752 return GTK_WIDGET (window_group->grabs->data);
7757 Derived from XParseGeometry() in XFree86
7759 Copyright 1985, 1986, 1987,1998 The Open Group
7761 All Rights Reserved.
7763 The above copyright notice and this permission notice shall be included
7764 in all copies or substantial portions of the Software.
7766 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
7767 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
7768 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
7769 IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
7770 OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
7771 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
7772 OTHER DEALINGS IN THE SOFTWARE.
7774 Except as contained in this notice, the name of The Open Group shall
7775 not be used in advertising or otherwise to promote the sale, use or
7776 other dealings in this Software without prior written authorization
7777 from The Open Group.
7782 * XParseGeometry parses strings of the form
7783 * "=<width>x<height>{+-}<xoffset>{+-}<yoffset>", where
7784 * width, height, xoffset, and yoffset are unsigned integers.
7785 * Example: "=80x24+300-49"
7786 * The equal sign is optional.
7787 * It returns a bitmask that indicates which of the four values
7788 * were actually found in the string. For each value found,
7789 * the corresponding argument is updated; for each value
7790 * not found, the corresponding argument is left unchanged.
7793 /* The following code is from Xlib, and is minimally modified, so we
7794 * can track any upstream changes if required. Don't change this
7795 * code. Or if you do, put in a huge comment marking which thing
7800 read_int (gchar *string,
7808 else if (*string == '-')
7814 for (; (*string >= '0') && (*string <= '9'); string++)
7816 result = (result * 10) + (*string - '0');
7828 * Bitmask returned by XParseGeometry(). Each bit tells if the corresponding
7829 * value (x, y, width, height) was found in the parsed string.
7831 #define NoValue 0x0000
7832 #define XValue 0x0001
7833 #define YValue 0x0002
7834 #define WidthValue 0x0004
7835 #define HeightValue 0x0008
7836 #define AllValues 0x000F
7837 #define XNegative 0x0010
7838 #define YNegative 0x0020
7840 /* Try not to reformat/modify, so we can compare/sync with X sources */
7842 gtk_XParseGeometry (const char *string,
7845 unsigned int *width,
7846 unsigned int *height)
7850 unsigned int tempWidth, tempHeight;
7852 char *nextCharacter;
7854 /* These initializations are just to silence gcc */
7860 if ( (string == NULL) || (*string == '\0')) return(mask);
7862 string++; /* ignore possible '=' at beg of geometry spec */
7864 strind = (char *)string;
7865 if (*strind != '+' && *strind != '-' && *strind != 'x') {
7866 tempWidth = read_int(strind, &nextCharacter);
7867 if (strind == nextCharacter)
7869 strind = nextCharacter;
7873 if (*strind == 'x' || *strind == 'X') {
7875 tempHeight = read_int(strind, &nextCharacter);
7876 if (strind == nextCharacter)
7878 strind = nextCharacter;
7879 mask |= HeightValue;
7882 if ((*strind == '+') || (*strind == '-')) {
7883 if (*strind == '-') {
7885 tempX = -read_int(strind, &nextCharacter);
7886 if (strind == nextCharacter)
7888 strind = nextCharacter;
7894 tempX = read_int(strind, &nextCharacter);
7895 if (strind == nextCharacter)
7897 strind = nextCharacter;
7900 if ((*strind == '+') || (*strind == '-')) {
7901 if (*strind == '-') {
7903 tempY = -read_int(strind, &nextCharacter);
7904 if (strind == nextCharacter)
7906 strind = nextCharacter;
7913 tempY = read_int(strind, &nextCharacter);
7914 if (strind == nextCharacter)
7916 strind = nextCharacter;
7922 /* If strind isn't at the end of the string the it's an invalid
7923 geometry specification. */
7925 if (*strind != '\0') return (0);
7931 if (mask & WidthValue)
7933 if (mask & HeightValue)
7934 *height = tempHeight;
7939 * gtk_window_parse_geometry:
7940 * @window: a #GtkWindow
7941 * @geometry: geometry string
7943 * Parses a standard X Window System geometry string - see the
7944 * manual page for X (type 'man X') for details on this.
7945 * gtk_window_parse_geometry() does work on all GTK+ ports
7946 * including Win32 but is primarily intended for an X environment.
7948 * If either a size or a position can be extracted from the
7949 * geometry string, gtk_window_parse_geometry() returns %TRUE
7950 * and calls gtk_window_set_default_size() and/or gtk_window_move()
7951 * to resize/move the window.
7953 * If gtk_window_parse_geometry() returns %TRUE, it will also
7954 * set the #GDK_HINT_USER_POS and/or #GDK_HINT_USER_SIZE hints
7955 * indicating to the window manager that the size/position of
7956 * the window was user-specified. This causes most window
7957 * managers to honor the geometry.
7959 * Note that for gtk_window_parse_geometry() to work as expected, it has
7960 * to be called when the window has its "final" size, i.e. after calling
7961 * gtk_widget_show_all() on the contents and gtk_window_set_geometry_hints()
7964 * #include <gtk/gtk.h>
7967 * fill_with_content (GtkWidget *vbox)
7969 * /* fill with content... */
7973 * main (int argc, char *argv[])
7975 * GtkWidget *window, *vbox;
7976 * GdkGeometry size_hints = {
7977 * 100, 50, 0, 0, 100, 50, 10, 10, 0.0, 0.0, GDK_GRAVITY_NORTH_WEST
7980 * gtk_init (&argc, &argv);
7982 * window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
7983 * vbox = gtk_vbox_new (FALSE, 0);
7985 * gtk_container_add (GTK_CONTAINER (window), vbox);
7986 * fill_with_content (vbox);
7987 * gtk_widget_show_all (vbox);
7989 * gtk_window_set_geometry_hints (GTK_WINDOW (window),
7992 * GDK_HINT_MIN_SIZE |
7993 * GDK_HINT_BASE_SIZE |
7994 * GDK_HINT_RESIZE_INC);
7998 * if (!gtk_window_parse_geometry (GTK_WINDOW (window), argv[1]))
7999 * fprintf (stderr, "Failed to parse '%s'\n", argv[1]);
8002 * gtk_widget_show_all (window);
8009 * Return value: %TRUE if string was parsed successfully
8012 gtk_window_parse_geometry (GtkWindow *window,
8013 const gchar *geometry)
8015 gint result, x = 0, y = 0;
8018 gboolean size_set, pos_set;
8021 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
8022 g_return_val_if_fail (geometry != NULL, FALSE);
8024 screen = gtk_window_check_screen (window);
8026 result = gtk_XParseGeometry (geometry, &x, &y, &w, &h);
8029 if ((result & WidthValue) || (result & HeightValue))
8031 gtk_window_set_default_size_internal (window,
8032 TRUE, result & WidthValue ? w : -1,
8033 TRUE, result & HeightValue ? h : -1,
8038 gtk_window_get_size (window, (gint *)&w, (gint *)&h);
8040 grav = GDK_GRAVITY_NORTH_WEST;
8042 if ((result & XNegative) && (result & YNegative))
8043 grav = GDK_GRAVITY_SOUTH_EAST;
8044 else if (result & XNegative)
8045 grav = GDK_GRAVITY_NORTH_EAST;
8046 else if (result & YNegative)
8047 grav = GDK_GRAVITY_SOUTH_WEST;
8049 if ((result & XValue) == 0)
8052 if ((result & YValue) == 0)
8055 if (grav == GDK_GRAVITY_SOUTH_WEST ||
8056 grav == GDK_GRAVITY_SOUTH_EAST)
8057 y = gdk_screen_get_height (screen) - h + y;
8059 if (grav == GDK_GRAVITY_SOUTH_EAST ||
8060 grav == GDK_GRAVITY_NORTH_EAST)
8061 x = gdk_screen_get_width (screen) - w + x;
8063 /* we don't let you put a window offscreen; maybe some people would
8064 * prefer to be able to, but it's kind of a bogus thing to do.
8073 if ((result & XValue) || (result & YValue))
8075 gtk_window_set_gravity (window, grav);
8076 gtk_window_move (window, x, y);
8080 if (size_set || pos_set)
8082 /* Set USSize, USPosition hints */
8083 GtkWindowGeometryInfo *info;
8085 info = gtk_window_get_geometry_info (window, TRUE);
8088 info->mask |= GDK_HINT_USER_POS;
8090 info->mask |= GDK_HINT_USER_SIZE;
8097 gtk_window_mnemonic_hash_foreach (guint keyval,
8103 GtkWindowKeysForeachFunc func;
8107 (*info->func) (info->window, keyval, info->window->mnemonic_modifier, TRUE, info->func_data);
8111 _gtk_window_keys_foreach (GtkWindow *window,
8112 GtkWindowKeysForeachFunc func,
8116 GtkMnemonicHash *mnemonic_hash;
8120 GtkWindowKeysForeachFunc func;
8124 info.window = window;
8126 info.func_data = func_data;
8128 mnemonic_hash = gtk_window_get_mnemonic_hash (window, FALSE);
8130 _gtk_mnemonic_hash_foreach (mnemonic_hash,
8131 gtk_window_mnemonic_hash_foreach, &info);
8133 groups = gtk_accel_groups_from_object (G_OBJECT (window));
8136 GtkAccelGroup *group = groups->data;
8139 for (i = 0; i < group->n_accels; i++)
8141 GtkAccelKey *key = &group->priv_accels[i].key;
8144 (*func) (window, key->accel_key, key->accel_mods, FALSE, func_data);
8147 groups = groups->next;
8152 gtk_window_keys_changed (GtkWindow *window)
8154 gtk_window_free_key_hash (window);
8155 gtk_window_get_key_hash (window);
8158 typedef struct _GtkWindowKeyEntry GtkWindowKeyEntry;
8160 struct _GtkWindowKeyEntry
8164 guint is_mnemonic : 1;
8168 window_key_entry_destroy (gpointer data)
8170 g_slice_free (GtkWindowKeyEntry, data);
8174 add_to_key_hash (GtkWindow *window,
8176 GdkModifierType modifiers,
8177 gboolean is_mnemonic,
8180 GtkKeyHash *key_hash = data;
8182 GtkWindowKeyEntry *entry = g_slice_new (GtkWindowKeyEntry);
8184 entry->keyval = keyval;
8185 entry->modifiers = modifiers;
8186 entry->is_mnemonic = is_mnemonic;
8188 /* GtkAccelGroup stores lowercased accelerators. To deal
8189 * with this, if <Shift> was specified, uppercase.
8191 if (modifiers & GDK_SHIFT_MASK)
8193 if (keyval == GDK_Tab)
8194 keyval = GDK_ISO_Left_Tab;
8196 keyval = gdk_keyval_to_upper (keyval);
8199 _gtk_key_hash_add_entry (key_hash, keyval, entry->modifiers, entry);
8203 gtk_window_get_key_hash (GtkWindow *window)
8205 GdkScreen *screen = gtk_window_check_screen (window);
8206 GtkKeyHash *key_hash = g_object_get_qdata (G_OBJECT (window), quark_gtk_window_key_hash);
8211 key_hash = _gtk_key_hash_new (gdk_keymap_get_for_display (gdk_screen_get_display (screen)),
8212 (GDestroyNotify)window_key_entry_destroy);
8213 _gtk_window_keys_foreach (window, add_to_key_hash, key_hash);
8214 g_object_set_qdata (G_OBJECT (window), quark_gtk_window_key_hash, key_hash);
8220 gtk_window_free_key_hash (GtkWindow *window)
8222 GtkKeyHash *key_hash = g_object_get_qdata (G_OBJECT (window), quark_gtk_window_key_hash);
8225 _gtk_key_hash_free (key_hash);
8226 g_object_set_qdata (G_OBJECT (window), quark_gtk_window_key_hash, NULL);
8231 * gtk_window_activate_key:
8232 * @window: a #GtkWindow
8233 * @event: a #GdkEventKey
8235 * Activates mnemonics and accelerators for this #GtkWindow. This is normally
8236 * called by the default ::key_press_event handler for toplevel windows,
8237 * however in some cases it may be useful to call this directly when
8238 * overriding the standard key handling for a toplevel window.
8240 * Return value: %TRUE if a mnemonic or accelerator was found and activated.
8245 gtk_window_activate_key (GtkWindow *window,
8248 GtkKeyHash *key_hash;
8249 GtkWindowKeyEntry *found_entry = NULL;
8250 gboolean enable_mnemonics;
8251 gboolean enable_accels;
8253 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
8254 g_return_val_if_fail (event != NULL, FALSE);
8256 key_hash = gtk_window_get_key_hash (window);
8261 GSList *entries = _gtk_key_hash_lookup (key_hash,
8262 event->hardware_keycode,
8264 gtk_accelerator_get_default_mod_mask (),
8267 g_object_get (gtk_widget_get_settings (GTK_WIDGET (window)),
8268 "gtk-enable-mnemonics", &enable_mnemonics,
8269 "gtk-enable-accels", &enable_accels,
8272 for (tmp_list = entries; tmp_list; tmp_list = tmp_list->next)
8274 GtkWindowKeyEntry *entry = tmp_list->data;
8275 if (entry->is_mnemonic)
8277 if (enable_mnemonics)
8279 found_entry = entry;
8285 if (enable_accels && !found_entry)
8287 found_entry = entry;
8292 g_slist_free (entries);
8297 if (found_entry->is_mnemonic)
8299 if (enable_mnemonics)
8300 return gtk_window_mnemonic_activate (window, found_entry->keyval,
8301 found_entry->modifiers);
8306 return gtk_accel_groups_activate (G_OBJECT (window), found_entry->keyval,
8307 found_entry->modifiers);
8315 window_update_has_focus (GtkWindow *window)
8317 GtkWidget *widget = GTK_WIDGET (window);
8318 gboolean has_focus = window->has_toplevel_focus && window->is_active;
8320 if (has_focus != window->has_focus)
8322 window->has_focus = has_focus;
8326 if (window->focus_widget &&
8327 window->focus_widget != widget &&
8328 !gtk_widget_has_focus (window->focus_widget))
8329 do_focus_change (window->focus_widget, TRUE);
8333 if (window->focus_widget &&
8334 window->focus_widget != widget &&
8335 gtk_widget_has_focus (window->focus_widget))
8336 do_focus_change (window->focus_widget, FALSE);
8342 * _gtk_window_set_is_active:
8343 * @window: a #GtkWindow
8344 * @is_active: %TRUE if the window is in the currently active toplevel
8346 * Internal function that sets whether the #GtkWindow is part
8347 * of the currently active toplevel window (taking into account inter-process
8351 _gtk_window_set_is_active (GtkWindow *window,
8354 g_return_if_fail (GTK_IS_WINDOW (window));
8356 is_active = is_active != FALSE;
8358 if (is_active != window->is_active)
8360 window->is_active = is_active;
8361 window_update_has_focus (window);
8363 g_object_notify (G_OBJECT (window), "is-active");
8368 * _gtk_window_set_is_toplevel:
8369 * @window: a #GtkWindow
8370 * @is_toplevel: %TRUE if the window is still a real toplevel (nominally a
8371 * parent of the root window); %FALSE if it is not (for example, for an
8372 * in-process, parented GtkPlug)
8374 * Internal function used by #GtkPlug when it gets parented/unparented by a
8375 * #GtkSocket. This keeps the @window's #GTK_TOPLEVEL flag in sync with the
8376 * global list of toplevel windows.
8379 _gtk_window_set_is_toplevel (GtkWindow *window,
8380 gboolean is_toplevel)
8384 widget = GTK_WIDGET (window);
8386 if (gtk_widget_is_toplevel (widget))
8387 g_assert (g_slist_find (toplevel_list, window) != NULL);
8389 g_assert (g_slist_find (toplevel_list, window) == NULL);
8391 if (is_toplevel == gtk_widget_is_toplevel (widget))
8396 _gtk_widget_set_is_toplevel (widget, TRUE);
8397 toplevel_list = g_slist_prepend (toplevel_list, window);
8401 _gtk_widget_set_is_toplevel (widget, FALSE);
8402 toplevel_list = g_slist_remove (toplevel_list, window);
8407 * _gtk_window_set_has_toplevel_focus:
8408 * @window: a #GtkWindow
8409 * @has_toplevel_focus: %TRUE if the in
8411 * Internal function that sets whether the keyboard focus for the
8412 * toplevel window (taking into account inter-process embedding.)
8415 _gtk_window_set_has_toplevel_focus (GtkWindow *window,
8416 gboolean has_toplevel_focus)
8418 g_return_if_fail (GTK_IS_WINDOW (window));
8420 has_toplevel_focus = has_toplevel_focus != FALSE;
8422 if (has_toplevel_focus != window->has_toplevel_focus)
8424 window->has_toplevel_focus = has_toplevel_focus;
8425 window_update_has_focus (window);
8427 g_object_notify (G_OBJECT (window), "has-toplevel-focus");
8432 * gtk_window_set_auto_startup_notification:
8433 * @setting: %TRUE to automatically do startup notification
8435 * By default, after showing the first #GtkWindow, GTK+ calls
8436 * gdk_notify_startup_complete(). Call this function to disable
8437 * the automatic startup notification. You might do this if your
8438 * first window is a splash screen, and you want to delay notification
8439 * until after your real main window has been shown, for example.
8441 * In that example, you would disable startup notification
8442 * temporarily, show your splash screen, then re-enable it so that
8443 * showing the main window would automatically result in notification.
8448 gtk_window_set_auto_startup_notification (gboolean setting)
8450 disable_startup_notification = !setting;
8454 * gtk_window_get_window_type:
8455 * @window: a #GtkWindow
8457 * Gets the type of the window. See #GtkWindowType.
8459 * Return value: the type of the window
8464 gtk_window_get_window_type (GtkWindow *window)
8466 g_return_val_if_fail (GTK_IS_WINDOW (window), GTK_WINDOW_TOPLEVEL);
8468 return window->type;
8471 /* gtk_window_get_mnemonics_visible:
8472 * @window: a #GtkWindow
8474 * Gets the value of the #GtkWindow:mnemonics-visible property.
8476 * Returns: %TRUE if mnemonics are supposed to be visible
8482 gtk_window_get_mnemonics_visible (GtkWindow *window)
8484 GtkWindowPrivate *priv;
8486 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
8488 priv = GTK_WINDOW_GET_PRIVATE (window);
8490 return priv->mnemonics_visible;
8494 * gtk_window_set_mnemonics_visible:
8495 * @window: a #GtkWindow
8496 * @setting: the new value
8498 * Sets the #GtkWindow:mnemonics-visible property.
8503 gtk_window_set_mnemonics_visible (GtkWindow *window,
8506 GtkWindowPrivate *priv;
8508 g_return_if_fail (GTK_IS_WINDOW (window));
8510 priv = GTK_WINDOW_GET_PRIVATE (window);
8512 setting = setting != FALSE;
8514 if (priv->mnemonics_visible != setting)
8516 priv->mnemonics_visible = setting;
8517 g_object_notify (G_OBJECT (window), "mnemonics-visible");
8520 priv->mnemonics_visible_set = TRUE;
8523 #if defined (G_OS_WIN32) && !defined (_WIN64)
8525 #undef gtk_window_set_icon_from_file
8528 gtk_window_set_icon_from_file (GtkWindow *window,
8529 const gchar *filename,
8532 gchar *utf8_filename = g_locale_to_utf8 (filename, -1, NULL, NULL, err);
8535 if (utf8_filename == NULL)
8538 retval = gtk_window_set_icon_from_file_utf8 (window, utf8_filename, err);
8540 g_free (utf8_filename);
8545 #undef gtk_window_set_default_icon_from_file
8548 gtk_window_set_default_icon_from_file (const gchar *filename,
8551 gchar *utf8_filename = g_locale_to_utf8 (filename, -1, NULL, NULL, err);
8554 if (utf8_filename == NULL)
8557 retval = gtk_window_set_default_icon_from_file_utf8 (utf8_filename, err);
8559 g_free (utf8_filename);
8566 #define __GTK_WINDOW_C__
8567 #include "gtkaliasdef.c"