1 /* GTK - The GIMP Toolkit
2 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
21 * Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
22 * file for a list of people on the GTK+ Team. See the ChangeLog
23 * files for a list of changes. These files are distributed with
24 * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
33 #include "gdk/gdkkeysyms.h"
37 #include "gtkprivate.h"
39 #include "gtkwindow.h"
40 #include "gtkwindow-decorate.h"
41 #include "gtkbindings.h"
42 #include "gtkkeyhash.h"
44 #include "gtkmnemonichash.h"
45 #include "gtkmenubar.h"
46 #include "gtkiconfactory.h"
47 #include "gtkicontheme.h"
48 #include "gtkmarshalers.h"
50 #include "gtkbuildable.h"
53 #ifdef GDK_WINDOWING_X11
82 PROP_DESTROY_WITH_PARENT,
87 PROP_SKIP_TASKBAR_HINT,
98 /* Readonly properties */
100 PROP_HAS_TOPLEVEL_FOCUS,
102 /* Writeonly properties */
105 PROP_MNEMONICS_VISIBLE,
113 GdkPixmap *icon_pixmap;
114 GdkPixmap *icon_mask;
117 guint using_default_icon : 1;
118 guint using_parent_icon : 1;
119 guint using_themed_icon : 1;
123 GdkGeometry geometry; /* Last set of geometry hints we set */
124 GdkWindowHints flags;
125 GdkRectangle configure_request;
126 } GtkWindowLastGeometryInfo;
128 struct _GtkWindowGeometryInfo
130 /* Properties that the app has set on the window
132 GdkGeometry geometry; /* Geometry hints */
134 GtkWidget *widget; /* subwidget to which hints apply */
135 /* from last gtk_window_resize () - if > 0, indicates that
136 * we should resize to this size.
141 /* From last gtk_window_move () prior to mapping -
142 * only used if initial_pos_set
147 /* Default size - used only the FIRST time we map a window,
152 /* whether to use initial_x, initial_y */
153 guint initial_pos_set : 1;
154 /* CENTER_ALWAYS or other position constraint changed since
155 * we sent the last configure request.
157 guint position_constraints_changed : 1;
159 /* if true, default_width, height come from gtk_window_parse_geometry,
160 * and thus should be multiplied by the increments and affect the
161 * geometry widget only
163 guint default_is_geometry : 1;
165 GtkWindowLastGeometryInfo last;
168 #define GTK_WINDOW_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GTK_TYPE_WINDOW, GtkWindowPrivate))
170 typedef struct _GtkWindowPrivate GtkWindowPrivate;
172 struct _GtkWindowPrivate
174 GtkMnemonicHash *mnemonic_hash;
176 guint above_initially : 1;
177 guint below_initially : 1;
178 guint fullscreen_initially : 1;
179 guint skips_taskbar : 1;
180 guint skips_pager : 1;
182 guint accept_focus : 1;
183 guint focus_on_map : 1;
185 guint transient_parent_group : 1;
187 guint reset_type_hint : 1;
188 guint opacity_set : 1;
189 guint builder_visible : 1;
191 guint mnemonics_visible : 1;
192 guint mnemonics_visible_set : 1;
194 GdkWindowTypeHint type_hint;
201 static void gtk_window_dispose (GObject *object);
202 static void gtk_window_destroy (GtkObject *object);
203 static void gtk_window_finalize (GObject *object);
204 static void gtk_window_show (GtkWidget *widget);
205 static void gtk_window_hide (GtkWidget *widget);
206 static void gtk_window_map (GtkWidget *widget);
207 static void gtk_window_unmap (GtkWidget *widget);
208 static void gtk_window_realize (GtkWidget *widget);
209 static void gtk_window_unrealize (GtkWidget *widget);
210 static void gtk_window_size_request (GtkWidget *widget,
211 GtkRequisition *requisition);
212 static void gtk_window_size_allocate (GtkWidget *widget,
213 GtkAllocation *allocation);
214 static gint gtk_window_event (GtkWidget *widget,
216 static gboolean gtk_window_map_event (GtkWidget *widget,
218 static gboolean gtk_window_frame_event (GtkWindow *window,
220 static gint gtk_window_configure_event (GtkWidget *widget,
221 GdkEventConfigure *event);
222 static gint gtk_window_key_press_event (GtkWidget *widget,
224 static gint gtk_window_key_release_event (GtkWidget *widget,
226 static gint gtk_window_enter_notify_event (GtkWidget *widget,
227 GdkEventCrossing *event);
228 static gint gtk_window_leave_notify_event (GtkWidget *widget,
229 GdkEventCrossing *event);
230 static gint gtk_window_focus_in_event (GtkWidget *widget,
231 GdkEventFocus *event);
232 static gint gtk_window_focus_out_event (GtkWidget *widget,
233 GdkEventFocus *event);
234 static gint gtk_window_client_event (GtkWidget *widget,
235 GdkEventClient *event);
236 static void gtk_window_check_resize (GtkContainer *container);
237 static gint gtk_window_focus (GtkWidget *widget,
238 GtkDirectionType direction);
239 static void gtk_window_real_set_focus (GtkWindow *window,
242 static void gtk_window_real_activate_default (GtkWindow *window);
243 static void gtk_window_real_activate_focus (GtkWindow *window);
244 static void gtk_window_move_focus (GtkWindow *window,
245 GtkDirectionType dir);
246 static void gtk_window_keys_changed (GtkWindow *window);
247 static void gtk_window_paint (GtkWidget *widget,
249 static gint gtk_window_expose (GtkWidget *widget,
250 GdkEventExpose *event);
251 static void gtk_window_unset_transient_for (GtkWindow *window);
252 static void gtk_window_transient_parent_realized (GtkWidget *parent,
254 static void gtk_window_transient_parent_unrealized (GtkWidget *parent,
257 static GdkScreen *gtk_window_check_screen (GtkWindow *window);
259 static GtkWindowGeometryInfo* gtk_window_get_geometry_info (GtkWindow *window,
262 static void gtk_window_move_resize (GtkWindow *window);
263 static gboolean gtk_window_compare_hints (GdkGeometry *geometry_a,
265 GdkGeometry *geometry_b,
267 static void gtk_window_constrain_size (GtkWindow *window,
268 GdkGeometry *geometry,
274 static void gtk_window_constrain_position (GtkWindow *window,
279 static void gtk_window_compute_hints (GtkWindow *window,
280 GdkGeometry *new_geometry,
282 static void gtk_window_compute_configure_request (GtkWindow *window,
283 GdkRectangle *request,
284 GdkGeometry *geometry,
287 static void gtk_window_set_default_size_internal (GtkWindow *window,
288 gboolean change_width,
290 gboolean change_height,
292 gboolean is_geometry);
294 static void update_themed_icon (GtkIconTheme *theme,
296 static GList *icon_list_from_theme (GtkWidget *widget,
298 static void gtk_window_realize_icon (GtkWindow *window);
299 static void gtk_window_unrealize_icon (GtkWindow *window);
301 static void gtk_window_notify_keys_changed (GtkWindow *window);
302 static GtkKeyHash *gtk_window_get_key_hash (GtkWindow *window);
303 static void gtk_window_free_key_hash (GtkWindow *window);
304 static void gtk_window_on_composited_changed (GdkScreen *screen,
307 static GSList *toplevel_list = NULL;
308 static guint window_signals[LAST_SIGNAL] = { 0 };
309 static GList *default_icon_list = NULL;
310 static gchar *default_icon_name = NULL;
311 static guint default_icon_serial = 0;
312 static gboolean disable_startup_notification = FALSE;
313 static gboolean sent_startup_notification = FALSE;
315 static GQuark quark_gtk_embedded = 0;
316 static GQuark quark_gtk_window_key_hash = 0;
317 static GQuark quark_gtk_window_default_icon_pixmap = 0;
318 static GQuark quark_gtk_window_icon_info = 0;
319 static GQuark quark_gtk_buildable_accels = 0;
321 static GtkBuildableIface *parent_buildable_iface;
323 static void gtk_window_set_property (GObject *object,
327 static void gtk_window_get_property (GObject *object,
333 static void gtk_window_buildable_interface_init (GtkBuildableIface *iface);
334 static void gtk_window_buildable_set_buildable_property (GtkBuildable *buildable,
337 const GValue *value);
338 static void gtk_window_buildable_parser_finished (GtkBuildable *buildable,
339 GtkBuilder *builder);
340 static gboolean gtk_window_buildable_custom_tag_start (GtkBuildable *buildable,
343 const gchar *tagname,
344 GMarkupParser *parser,
346 static void gtk_window_buildable_custom_finished (GtkBuildable *buildable,
349 const gchar *tagname,
353 G_DEFINE_TYPE_WITH_CODE (GtkWindow, gtk_window, GTK_TYPE_BIN,
354 G_IMPLEMENT_INTERFACE (GTK_TYPE_BUILDABLE,
355 gtk_window_buildable_interface_init))
358 add_tab_bindings (GtkBindingSet *binding_set,
359 GdkModifierType modifiers,
360 GtkDirectionType direction)
362 gtk_binding_entry_add_signal (binding_set, GDK_Tab, modifiers,
364 GTK_TYPE_DIRECTION_TYPE, direction);
365 gtk_binding_entry_add_signal (binding_set, GDK_KP_Tab, modifiers,
367 GTK_TYPE_DIRECTION_TYPE, direction);
371 add_arrow_bindings (GtkBindingSet *binding_set,
373 GtkDirectionType direction)
375 guint keypad_keysym = keysym - GDK_Left + GDK_KP_Left;
377 gtk_binding_entry_add_signal (binding_set, keysym, 0,
379 GTK_TYPE_DIRECTION_TYPE, direction);
380 gtk_binding_entry_add_signal (binding_set, keysym, GDK_CONTROL_MASK,
382 GTK_TYPE_DIRECTION_TYPE, direction);
383 gtk_binding_entry_add_signal (binding_set, keypad_keysym, 0,
385 GTK_TYPE_DIRECTION_TYPE, direction);
386 gtk_binding_entry_add_signal (binding_set, keypad_keysym, GDK_CONTROL_MASK,
388 GTK_TYPE_DIRECTION_TYPE, direction);
392 extract_time_from_startup_id (const gchar* startup_id)
394 gchar *timestr = g_strrstr (startup_id, "_TIME");
395 guint32 retval = GDK_CURRENT_TIME;
402 /* Skip past the "_TIME" part */
406 timestamp = strtoul (timestr, &end, 0);
407 if (end != timestr && errno == 0)
415 startup_id_is_fake (const gchar* startup_id)
417 return strncmp (startup_id, "_TIME", 5) == 0;
421 gtk_window_class_init (GtkWindowClass *klass)
423 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
424 GtkObjectClass *object_class;
425 GtkWidgetClass *widget_class;
426 GtkContainerClass *container_class;
427 GtkBindingSet *binding_set;
429 object_class = (GtkObjectClass*) klass;
430 widget_class = (GtkWidgetClass*) klass;
431 container_class = (GtkContainerClass*) klass;
433 quark_gtk_embedded = g_quark_from_static_string ("gtk-embedded");
434 quark_gtk_window_key_hash = g_quark_from_static_string ("gtk-window-key-hash");
435 quark_gtk_window_default_icon_pixmap = g_quark_from_static_string ("gtk-window-default-icon-pixmap");
436 quark_gtk_window_icon_info = g_quark_from_static_string ("gtk-window-icon-info");
437 quark_gtk_buildable_accels = g_quark_from_static_string ("gtk-window-buildable-accels");
439 gobject_class->dispose = gtk_window_dispose;
440 gobject_class->finalize = gtk_window_finalize;
442 gobject_class->set_property = gtk_window_set_property;
443 gobject_class->get_property = gtk_window_get_property;
445 object_class->destroy = gtk_window_destroy;
447 widget_class->show = gtk_window_show;
448 widget_class->hide = gtk_window_hide;
449 widget_class->map = gtk_window_map;
450 widget_class->map_event = gtk_window_map_event;
451 widget_class->unmap = gtk_window_unmap;
452 widget_class->realize = gtk_window_realize;
453 widget_class->unrealize = gtk_window_unrealize;
454 widget_class->size_request = gtk_window_size_request;
455 widget_class->size_allocate = gtk_window_size_allocate;
456 widget_class->configure_event = gtk_window_configure_event;
457 widget_class->key_press_event = gtk_window_key_press_event;
458 widget_class->key_release_event = gtk_window_key_release_event;
459 widget_class->enter_notify_event = gtk_window_enter_notify_event;
460 widget_class->leave_notify_event = gtk_window_leave_notify_event;
461 widget_class->focus_in_event = gtk_window_focus_in_event;
462 widget_class->focus_out_event = gtk_window_focus_out_event;
463 widget_class->client_event = gtk_window_client_event;
464 widget_class->focus = gtk_window_focus;
465 widget_class->expose_event = gtk_window_expose;
467 container_class->check_resize = gtk_window_check_resize;
469 klass->set_focus = gtk_window_real_set_focus;
470 klass->frame_event = gtk_window_frame_event;
472 klass->activate_default = gtk_window_real_activate_default;
473 klass->activate_focus = gtk_window_real_activate_focus;
474 klass->move_focus = gtk_window_move_focus;
475 klass->keys_changed = gtk_window_keys_changed;
477 g_type_class_add_private (gobject_class, sizeof (GtkWindowPrivate));
480 g_object_class_install_property (gobject_class,
482 g_param_spec_enum ("type",
484 P_("The type of the window"),
485 GTK_TYPE_WINDOW_TYPE,
487 GTK_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
489 g_object_class_install_property (gobject_class,
491 g_param_spec_string ("title",
493 P_("The title of the window"),
495 GTK_PARAM_READWRITE));
497 g_object_class_install_property (gobject_class,
499 g_param_spec_string ("role",
501 P_("Unique identifier for the window to be used when restoring a session"),
503 GTK_PARAM_READWRITE));
506 * GtkWindow:startup-id:
508 * The :startup-id is a write-only property for setting window's
509 * startup notification identifier. See gtk_window_set_startup_id()
514 g_object_class_install_property (gobject_class,
516 g_param_spec_string ("startup-id",
518 P_("Unique startup identifier for the window used by startup-notification"),
520 GTK_PARAM_WRITABLE));
522 g_object_class_install_property (gobject_class,
524 g_param_spec_boolean ("allow-shrink",
526 /* xgettext:no-c-format */
527 P_("If TRUE, the window has no mimimum size. Setting this to TRUE is 99% of the time a bad idea"),
529 GTK_PARAM_READWRITE));
531 g_object_class_install_property (gobject_class,
533 g_param_spec_boolean ("allow-grow",
535 P_("If TRUE, users can expand the window beyond its minimum size"),
537 GTK_PARAM_READWRITE));
539 g_object_class_install_property (gobject_class,
541 g_param_spec_boolean ("resizable",
543 P_("If TRUE, users can resize the window"),
545 GTK_PARAM_READWRITE));
547 g_object_class_install_property (gobject_class,
549 g_param_spec_boolean ("modal",
551 P_("If TRUE, the window is modal (other windows are not usable while this one is up)"),
553 GTK_PARAM_READWRITE));
555 g_object_class_install_property (gobject_class,
557 g_param_spec_enum ("window-position",
558 P_("Window Position"),
559 P_("The initial position of the window"),
560 GTK_TYPE_WINDOW_POSITION,
562 GTK_PARAM_READWRITE));
564 g_object_class_install_property (gobject_class,
566 g_param_spec_int ("default-width",
568 P_("The default width of the window, used when initially showing the window"),
572 GTK_PARAM_READWRITE));
574 g_object_class_install_property (gobject_class,
576 g_param_spec_int ("default-height",
577 P_("Default Height"),
578 P_("The default height of the window, used when initially showing the window"),
582 GTK_PARAM_READWRITE));
584 g_object_class_install_property (gobject_class,
585 PROP_DESTROY_WITH_PARENT,
586 g_param_spec_boolean ("destroy-with-parent",
587 P_("Destroy with Parent"),
588 P_("If this window should be destroyed when the parent is destroyed"),
590 GTK_PARAM_READWRITE));
592 g_object_class_install_property (gobject_class,
594 g_param_spec_object ("icon",
596 P_("Icon for this window"),
598 GTK_PARAM_READWRITE));
599 g_object_class_install_property (gobject_class,
600 PROP_MNEMONICS_VISIBLE,
601 g_param_spec_boolean ("mnemonics-visible",
602 P_("Mnemonics Visible"),
603 P_("Whether mnemonics are currently visible in this window"),
605 GTK_PARAM_READWRITE));
608 * GtkWindow:icon-name:
610 * The :icon-name property specifies the name of the themed icon to
611 * use as the window icon. See #GtkIconTheme for more details.
615 g_object_class_install_property (gobject_class,
617 g_param_spec_string ("icon-name",
619 P_("Name of the themed icon for this window"),
621 GTK_PARAM_READWRITE));
623 g_object_class_install_property (gobject_class,
625 g_param_spec_object ("screen",
627 P_("The screen where this window will be displayed"),
629 GTK_PARAM_READWRITE));
631 g_object_class_install_property (gobject_class,
633 g_param_spec_boolean ("is-active",
635 P_("Whether the toplevel is the current active window"),
637 GTK_PARAM_READABLE));
639 g_object_class_install_property (gobject_class,
640 PROP_HAS_TOPLEVEL_FOCUS,
641 g_param_spec_boolean ("has-toplevel-focus",
642 P_("Focus in Toplevel"),
643 P_("Whether the input focus is within this GtkWindow"),
645 GTK_PARAM_READABLE));
647 g_object_class_install_property (gobject_class,
649 g_param_spec_enum ("type-hint",
651 P_("Hint to help the desktop environment understand what kind of window this is and how to treat it."),
652 GDK_TYPE_WINDOW_TYPE_HINT,
653 GDK_WINDOW_TYPE_HINT_NORMAL,
654 GTK_PARAM_READWRITE));
656 g_object_class_install_property (gobject_class,
657 PROP_SKIP_TASKBAR_HINT,
658 g_param_spec_boolean ("skip-taskbar-hint",
660 P_("TRUE if the window should not be in the task bar."),
662 GTK_PARAM_READWRITE));
664 g_object_class_install_property (gobject_class,
665 PROP_SKIP_PAGER_HINT,
666 g_param_spec_boolean ("skip-pager-hint",
668 P_("TRUE if the window should not be in the pager."),
670 GTK_PARAM_READWRITE));
672 g_object_class_install_property (gobject_class,
674 g_param_spec_boolean ("urgency-hint",
676 P_("TRUE if the window should be brought to the user's attention."),
678 GTK_PARAM_READWRITE));
681 * GtkWindow:accept-focus:
683 * Whether the window should receive the input focus.
687 g_object_class_install_property (gobject_class,
689 g_param_spec_boolean ("accept-focus",
691 P_("TRUE if the window should receive the input focus."),
693 GTK_PARAM_READWRITE));
696 * GtkWindow:focus-on-map:
698 * Whether the window should receive the input focus when mapped.
702 g_object_class_install_property (gobject_class,
704 g_param_spec_boolean ("focus-on-map",
706 P_("TRUE if the window should receive the input focus when mapped."),
708 GTK_PARAM_READWRITE));
711 * GtkWindow:decorated:
713 * Whether the window should be decorated by the window manager.
717 g_object_class_install_property (gobject_class,
719 g_param_spec_boolean ("decorated",
721 P_("Whether the window should be decorated by the window manager"),
723 GTK_PARAM_READWRITE));
726 * GtkWindow:deletable:
728 * Whether the window frame should have a close button.
732 g_object_class_install_property (gobject_class,
734 g_param_spec_boolean ("deletable",
736 P_("Whether the window frame should have a close button"),
738 GTK_PARAM_READWRITE));
744 * The window gravity of the window. See gtk_window_move() and #GdkGravity for
745 * more details about window gravity.
749 g_object_class_install_property (gobject_class,
751 g_param_spec_enum ("gravity",
753 P_("The window gravity of the window"),
755 GDK_GRAVITY_NORTH_WEST,
756 GTK_PARAM_READWRITE));
760 * GtkWindow:transient-for:
762 * The transient parent of the window. See gtk_window_set_transient_for() for
763 * more details about transient windows.
767 g_object_class_install_property (gobject_class,
769 g_param_spec_object ("transient-for",
770 P_("Transient for Window"),
771 P_("The transient parent of the dialog"),
773 GTK_PARAM_READWRITE| G_PARAM_CONSTRUCT));
778 * The requested opacity of the window. See gtk_window_set_opacity() for
779 * more details about window opacity.
783 g_object_class_install_property (gobject_class,
785 g_param_spec_double ("opacity",
786 P_("Opacity for Window"),
787 P_("The opacity of the window, from 0 to 1"),
791 GTK_PARAM_READWRITE));
793 window_signals[SET_FOCUS] =
794 g_signal_new (I_("set-focus"),
795 G_TYPE_FROM_CLASS (gobject_class),
797 G_STRUCT_OFFSET (GtkWindowClass, set_focus),
799 _gtk_marshal_VOID__OBJECT,
803 window_signals[FRAME_EVENT] =
804 g_signal_new (I_("frame-event"),
805 G_TYPE_FROM_CLASS (gobject_class),
807 G_STRUCT_OFFSET(GtkWindowClass, frame_event),
808 _gtk_boolean_handled_accumulator, NULL,
809 _gtk_marshal_BOOLEAN__BOXED,
814 * GtkWindow::activate-focus:
815 * @window: the window which received the signal
817 * The ::activate-default signal is a
818 * <link linkend="keybinding-signals">keybinding signal</link>
819 * which gets emitted when the user activates the currently
820 * focused widget of @window.
822 window_signals[ACTIVATE_FOCUS] =
823 g_signal_new (I_("activate-focus"),
824 G_TYPE_FROM_CLASS (gobject_class),
825 G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
826 G_STRUCT_OFFSET (GtkWindowClass, activate_focus),
828 _gtk_marshal_VOID__VOID,
833 * GtkWindow::activate-default:
834 * @window: the window which received the signal
836 * The ::activate-default signal is a
837 * <link linkend="keybinding-signals">keybinding signal</link>
838 * which gets emitted when the user activates the default widget
841 window_signals[ACTIVATE_DEFAULT] =
842 g_signal_new (I_("activate-default"),
843 G_TYPE_FROM_CLASS (gobject_class),
844 G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
845 G_STRUCT_OFFSET (GtkWindowClass, activate_default),
847 _gtk_marshal_VOID__VOID,
852 * GtkWindow::keys-changed:
853 * @window: the window which received the signal
855 * The ::keys-changed signal gets emitted when the set of accelerators
856 * or mnemonics that are associated with @window changes.
858 window_signals[KEYS_CHANGED] =
859 g_signal_new (I_("keys-changed"),
860 G_TYPE_FROM_CLASS (gobject_class),
862 G_STRUCT_OFFSET (GtkWindowClass, keys_changed),
864 _gtk_marshal_VOID__VOID,
872 binding_set = gtk_binding_set_by_class (klass);
874 gtk_binding_entry_add_signal (binding_set, GDK_space, 0,
875 "activate-focus", 0);
876 gtk_binding_entry_add_signal (binding_set, GDK_KP_Space, 0,
877 "activate-focus", 0);
879 gtk_binding_entry_add_signal (binding_set, GDK_Return, 0,
880 "activate-default", 0);
881 gtk_binding_entry_add_signal (binding_set, GDK_ISO_Enter, 0,
882 "activate-default", 0);
883 gtk_binding_entry_add_signal (binding_set, GDK_KP_Enter, 0,
884 "activate-default", 0);
886 add_arrow_bindings (binding_set, GDK_Up, GTK_DIR_UP);
887 add_arrow_bindings (binding_set, GDK_Down, GTK_DIR_DOWN);
888 add_arrow_bindings (binding_set, GDK_Left, GTK_DIR_LEFT);
889 add_arrow_bindings (binding_set, GDK_Right, GTK_DIR_RIGHT);
891 add_tab_bindings (binding_set, 0, GTK_DIR_TAB_FORWARD);
892 add_tab_bindings (binding_set, GDK_CONTROL_MASK, GTK_DIR_TAB_FORWARD);
893 add_tab_bindings (binding_set, GDK_SHIFT_MASK, GTK_DIR_TAB_BACKWARD);
894 add_tab_bindings (binding_set, GDK_CONTROL_MASK | GDK_SHIFT_MASK, GTK_DIR_TAB_BACKWARD);
898 gtk_window_init (GtkWindow *window)
900 GdkColormap *colormap;
901 GtkWindowPrivate *priv = GTK_WINDOW_GET_PRIVATE (window);
903 GTK_WIDGET_UNSET_FLAGS (window, GTK_NO_WINDOW);
904 GTK_WIDGET_SET_FLAGS (window, GTK_TOPLEVEL);
906 GTK_PRIVATE_SET_FLAG (window, GTK_ANCHORED);
908 gtk_container_set_resize_mode (GTK_CONTAINER (window), GTK_RESIZE_QUEUE);
910 window->title = NULL;
911 window->wmclass_name = g_strdup (g_get_prgname ());
912 window->wmclass_class = g_strdup (gdk_get_program_class ());
913 window->wm_role = NULL;
914 window->geometry_info = NULL;
915 window->type = GTK_WINDOW_TOPLEVEL;
916 window->focus_widget = NULL;
917 window->default_widget = NULL;
918 window->configure_request_count = 0;
919 window->allow_shrink = FALSE;
920 window->allow_grow = TRUE;
921 window->configure_notify_received = FALSE;
922 window->position = GTK_WIN_POS_NONE;
923 window->need_default_size = TRUE;
924 window->need_default_position = TRUE;
925 window->modal = FALSE;
926 window->frame = NULL;
927 window->has_frame = FALSE;
928 window->frame_left = 0;
929 window->frame_right = 0;
930 window->frame_top = 0;
931 window->frame_bottom = 0;
932 window->type_hint = GDK_WINDOW_TYPE_HINT_NORMAL;
933 window->gravity = GDK_GRAVITY_NORTH_WEST;
934 window->decorated = TRUE;
935 window->mnemonic_modifier = GDK_MOD1_MASK;
936 window->screen = gdk_screen_get_default ();
938 priv->accept_focus = TRUE;
939 priv->focus_on_map = TRUE;
940 priv->deletable = TRUE;
941 priv->type_hint = GDK_WINDOW_TYPE_HINT_NORMAL;
943 priv->startup_id = NULL;
944 priv->mnemonics_visible = TRUE;
946 colormap = _gtk_widget_peek_colormap ();
948 gtk_widget_set_colormap (GTK_WIDGET (window), colormap);
950 g_object_ref_sink (window);
951 window->has_user_ref_count = TRUE;
952 toplevel_list = g_slist_prepend (toplevel_list, window);
954 gtk_decorated_window_init (window);
956 g_signal_connect (window->screen, "composited-changed",
957 G_CALLBACK (gtk_window_on_composited_changed), window);
961 gtk_window_set_property (GObject *object,
967 GtkWindowPrivate *priv;
969 window = GTK_WINDOW (object);
971 priv = GTK_WINDOW_GET_PRIVATE (window);
976 window->type = g_value_get_enum (value);
979 gtk_window_set_title (window, g_value_get_string (value));
982 gtk_window_set_role (window, g_value_get_string (value));
984 case PROP_STARTUP_ID:
985 gtk_window_set_startup_id (window, g_value_get_string (value));
987 case PROP_ALLOW_SHRINK:
988 window->allow_shrink = g_value_get_boolean (value);
989 gtk_widget_queue_resize (GTK_WIDGET (window));
991 case PROP_ALLOW_GROW:
992 window->allow_grow = g_value_get_boolean (value);
993 gtk_widget_queue_resize (GTK_WIDGET (window));
994 g_object_notify (G_OBJECT (window), "resizable");
997 window->allow_grow = g_value_get_boolean (value);
998 gtk_widget_queue_resize (GTK_WIDGET (window));
999 g_object_notify (G_OBJECT (window), "allow-grow");
1002 gtk_window_set_modal (window, g_value_get_boolean (value));
1005 gtk_window_set_position (window, g_value_get_enum (value));
1007 case PROP_DEFAULT_WIDTH:
1008 gtk_window_set_default_size_internal (window,
1009 TRUE, g_value_get_int (value),
1012 case PROP_DEFAULT_HEIGHT:
1013 gtk_window_set_default_size_internal (window,
1015 TRUE, g_value_get_int (value), FALSE);
1017 case PROP_DESTROY_WITH_PARENT:
1018 gtk_window_set_destroy_with_parent (window, g_value_get_boolean (value));
1021 gtk_window_set_icon (window,
1022 g_value_get_object (value));
1024 case PROP_ICON_NAME:
1025 gtk_window_set_icon_name (window, g_value_get_string (value));
1028 gtk_window_set_screen (window, g_value_get_object (value));
1030 case PROP_TYPE_HINT:
1031 gtk_window_set_type_hint (window,
1032 g_value_get_enum (value));
1034 case PROP_SKIP_TASKBAR_HINT:
1035 gtk_window_set_skip_taskbar_hint (window,
1036 g_value_get_boolean (value));
1038 case PROP_SKIP_PAGER_HINT:
1039 gtk_window_set_skip_pager_hint (window,
1040 g_value_get_boolean (value));
1042 case PROP_URGENCY_HINT:
1043 gtk_window_set_urgency_hint (window,
1044 g_value_get_boolean (value));
1046 case PROP_ACCEPT_FOCUS:
1047 gtk_window_set_accept_focus (window,
1048 g_value_get_boolean (value));
1050 case PROP_FOCUS_ON_MAP:
1051 gtk_window_set_focus_on_map (window,
1052 g_value_get_boolean (value));
1054 case PROP_DECORATED:
1055 gtk_window_set_decorated (window, g_value_get_boolean (value));
1057 case PROP_DELETABLE:
1058 gtk_window_set_deletable (window, g_value_get_boolean (value));
1061 gtk_window_set_gravity (window, g_value_get_enum (value));
1063 case PROP_TRANSIENT_FOR:
1064 gtk_window_set_transient_for (window, g_value_get_object (value));
1067 gtk_window_set_opacity (window, g_value_get_double (value));
1069 case PROP_MNEMONICS_VISIBLE:
1070 gtk_window_set_mnemonics_visible (window, g_value_get_boolean (value));
1073 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1079 gtk_window_get_property (GObject *object,
1085 GtkWindowPrivate *priv;
1087 window = GTK_WINDOW (object);
1088 priv = GTK_WINDOW_GET_PRIVATE (window);
1092 GtkWindowGeometryInfo *info;
1094 g_value_set_enum (value, window->type);
1097 g_value_set_string (value, window->wm_role);
1100 g_value_set_string (value, window->title);
1102 case PROP_ALLOW_SHRINK:
1103 g_value_set_boolean (value, window->allow_shrink);
1105 case PROP_ALLOW_GROW:
1106 g_value_set_boolean (value, window->allow_grow);
1108 case PROP_RESIZABLE:
1109 g_value_set_boolean (value, window->allow_grow);
1112 g_value_set_boolean (value, window->modal);
1115 g_value_set_enum (value, window->position);
1117 case PROP_DEFAULT_WIDTH:
1118 info = gtk_window_get_geometry_info (window, FALSE);
1120 g_value_set_int (value, -1);
1122 g_value_set_int (value, info->default_width);
1124 case PROP_DEFAULT_HEIGHT:
1125 info = gtk_window_get_geometry_info (window, FALSE);
1127 g_value_set_int (value, -1);
1129 g_value_set_int (value, info->default_height);
1131 case PROP_DESTROY_WITH_PARENT:
1132 g_value_set_boolean (value, window->destroy_with_parent);
1135 g_value_set_object (value, gtk_window_get_icon (window));
1137 case PROP_ICON_NAME:
1138 g_value_set_string (value, gtk_window_get_icon_name (window));
1141 g_value_set_object (value, window->screen);
1143 case PROP_IS_ACTIVE:
1144 g_value_set_boolean (value, window->is_active);
1146 case PROP_HAS_TOPLEVEL_FOCUS:
1147 g_value_set_boolean (value, window->has_toplevel_focus);
1149 case PROP_TYPE_HINT:
1150 g_value_set_enum (value, priv->type_hint);
1152 case PROP_SKIP_TASKBAR_HINT:
1153 g_value_set_boolean (value,
1154 gtk_window_get_skip_taskbar_hint (window));
1156 case PROP_SKIP_PAGER_HINT:
1157 g_value_set_boolean (value,
1158 gtk_window_get_skip_pager_hint (window));
1160 case PROP_URGENCY_HINT:
1161 g_value_set_boolean (value,
1162 gtk_window_get_urgency_hint (window));
1164 case PROP_ACCEPT_FOCUS:
1165 g_value_set_boolean (value,
1166 gtk_window_get_accept_focus (window));
1168 case PROP_FOCUS_ON_MAP:
1169 g_value_set_boolean (value,
1170 gtk_window_get_focus_on_map (window));
1172 case PROP_DECORATED:
1173 g_value_set_boolean (value, gtk_window_get_decorated (window));
1175 case PROP_DELETABLE:
1176 g_value_set_boolean (value, gtk_window_get_deletable (window));
1179 g_value_set_enum (value, gtk_window_get_gravity (window));
1181 case PROP_TRANSIENT_FOR:
1182 g_value_set_object (value, gtk_window_get_transient_for (window));
1185 g_value_set_double (value, gtk_window_get_opacity (window));
1187 case PROP_MNEMONICS_VISIBLE:
1188 g_value_set_boolean (value, priv->mnemonics_visible);
1191 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1197 gtk_window_buildable_interface_init (GtkBuildableIface *iface)
1199 parent_buildable_iface = g_type_interface_peek_parent (iface);
1200 iface->set_buildable_property = gtk_window_buildable_set_buildable_property;
1201 iface->parser_finished = gtk_window_buildable_parser_finished;
1202 iface->custom_tag_start = gtk_window_buildable_custom_tag_start;
1203 iface->custom_finished = gtk_window_buildable_custom_finished;
1207 gtk_window_buildable_set_buildable_property (GtkBuildable *buildable,
1208 GtkBuilder *builder,
1210 const GValue *value)
1212 GtkWindowPrivate *priv = GTK_WINDOW_GET_PRIVATE (buildable);
1214 if (strcmp (name, "visible") == 0 && g_value_get_boolean (value))
1215 priv->builder_visible = TRUE;
1217 parent_buildable_iface->set_buildable_property (buildable, builder, name, value);
1221 gtk_window_buildable_parser_finished (GtkBuildable *buildable,
1222 GtkBuilder *builder)
1224 GtkWindowPrivate *priv = GTK_WINDOW_GET_PRIVATE (buildable);
1228 if (priv->builder_visible)
1229 gtk_widget_show (GTK_WIDGET (buildable));
1231 accels = g_object_get_qdata (G_OBJECT (buildable), quark_gtk_buildable_accels);
1232 for (l = accels; l; l = l->next)
1234 object = gtk_builder_get_object (builder, l->data);
1237 g_warning ("Unknown accel group %s specified in window %s",
1238 (const gchar*)l->data, gtk_buildable_get_name (buildable));
1241 gtk_window_add_accel_group (GTK_WINDOW (buildable),
1242 GTK_ACCEL_GROUP (object));
1246 g_object_set_qdata (G_OBJECT (buildable), quark_gtk_buildable_accels, NULL);
1248 parent_buildable_iface->parser_finished (buildable, builder);
1254 } GSListSubParserData;
1257 window_start_element (GMarkupParseContext *context,
1258 const gchar *element_name,
1259 const gchar **names,
1260 const gchar **values,
1265 GSListSubParserData *data = (GSListSubParserData*)user_data;
1267 if (strcmp (element_name, "group") == 0)
1269 for (i = 0; names[i]; i++)
1271 if (strcmp (names[i], "name") == 0)
1272 data->items = g_slist_prepend (data->items, g_strdup (values[i]));
1275 else if (strcmp (element_name, "accel-groups") == 0)
1278 g_warning ("Unsupported tag type for GtkWindow: %s\n",
1283 static const GMarkupParser window_parser =
1285 window_start_element
1289 gtk_window_buildable_custom_tag_start (GtkBuildable *buildable,
1290 GtkBuilder *builder,
1292 const gchar *tagname,
1293 GMarkupParser *parser,
1296 GSListSubParserData *parser_data;
1298 if (parent_buildable_iface->custom_tag_start (buildable, builder, child,
1299 tagname, parser, data))
1302 if (strcmp (tagname, "accel-groups") == 0)
1304 parser_data = g_slice_new0 (GSListSubParserData);
1305 parser_data->items = NULL;
1306 parser_data->object = G_OBJECT (buildable);
1308 *parser = window_parser;
1309 *data = parser_data;
1317 gtk_window_buildable_custom_finished (GtkBuildable *buildable,
1318 GtkBuilder *builder,
1320 const gchar *tagname,
1323 GSListSubParserData *data;
1325 parent_buildable_iface->custom_finished (buildable, builder, child,
1326 tagname, user_data);
1328 if (strcmp (tagname, "accel-groups") != 0)
1331 data = (GSListSubParserData*)user_data;
1333 g_object_set_qdata_full (G_OBJECT (buildable), quark_gtk_buildable_accels,
1334 data->items, (GDestroyNotify) g_slist_free);
1336 g_slice_free (GSListSubParserData, data);
1341 * @type: type of window
1343 * Creates a new #GtkWindow, which is a toplevel window that can
1344 * contain other widgets. Nearly always, the type of the window should
1345 * be #GTK_WINDOW_TOPLEVEL. If you're implementing something like a
1346 * popup menu from scratch (which is a bad idea, just use #GtkMenu),
1347 * you might use #GTK_WINDOW_POPUP. #GTK_WINDOW_POPUP is not for
1348 * dialogs, though in some other toolkits dialogs are called "popups".
1349 * In GTK+, #GTK_WINDOW_POPUP means a pop-up menu or pop-up tooltip.
1350 * On X11, popup windows are not controlled by the <link
1351 * linkend="gtk-X11-arch">window manager</link>.
1353 * If you simply want an undecorated window (no window borders), use
1354 * gtk_window_set_decorated(), don't use #GTK_WINDOW_POPUP.
1356 * Return value: a new #GtkWindow.
1359 gtk_window_new (GtkWindowType type)
1363 g_return_val_if_fail (type >= GTK_WINDOW_TOPLEVEL && type <= GTK_WINDOW_POPUP, NULL);
1365 window = g_object_new (GTK_TYPE_WINDOW, NULL);
1367 window->type = type;
1369 return GTK_WIDGET (window);
1373 * gtk_window_set_title:
1374 * @window: a #GtkWindow
1375 * @title: title of the window
1377 * Sets the title of the #GtkWindow. The title of a window will be
1378 * displayed in its title bar; on the X Window System, the title bar
1379 * is rendered by the <link linkend="gtk-X11-arch">window
1380 * manager</link>, so exactly how the title appears to users may vary
1381 * according to a user's exact configuration. The title should help a
1382 * user distinguish this window from other windows they may have
1383 * open. A good title might include the application name and current
1384 * document filename, for example.
1388 gtk_window_set_title (GtkWindow *window,
1393 g_return_if_fail (GTK_IS_WINDOW (window));
1395 new_title = g_strdup (title);
1396 g_free (window->title);
1397 window->title = new_title;
1399 if (GTK_WIDGET_REALIZED (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_REALIZED (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_REALIZED (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_REALIZED (window))
1530 guint32 timestamp = extract_time_from_startup_id (priv->startup_id);
1532 #ifdef GDK_WINDOWING_X11
1533 if (timestamp != GDK_CURRENT_TIME)
1534 gdk_x11_window_set_user_time (GTK_WIDGET (window)->window, timestamp);
1537 /* Here we differentiate real and "fake" startup notification IDs,
1538 * constructed on purpose just to pass interaction timestamp
1540 if (startup_id_is_fake (priv->startup_id))
1541 gtk_window_present_with_time (window, timestamp);
1544 gdk_window_set_startup_id (GTK_WIDGET (window)->window,
1547 /* If window is mapped, terminate the startup-notification too */
1548 if (gtk_widget_get_mapped (GTK_WIDGET (window)) &&
1549 !disable_startup_notification)
1550 gdk_notify_startup_complete_with_id (priv->startup_id);
1554 g_object_notify (G_OBJECT (window), "startup-id");
1558 * gtk_window_get_role:
1559 * @window: a #GtkWindow
1561 * Returns the role of the window. See gtk_window_set_role() for
1562 * further explanation.
1564 * Return value: the role of the window if set, or %NULL. The
1565 * returned is owned by the widget and must not be modified
1568 G_CONST_RETURN gchar *
1569 gtk_window_get_role (GtkWindow *window)
1571 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
1573 return window->wm_role;
1577 * gtk_window_set_focus:
1578 * @window: a #GtkWindow
1579 * @focus: (allow-none): widget to be the new focus widget, or %NULL to unset
1580 * any focus widget for the toplevel window.
1582 * If @focus is not the current focus widget, and is focusable, sets
1583 * it as the focus widget for the window. If @focus is %NULL, unsets
1584 * the focus widget for this window. To set the focus to a particular
1585 * widget in the toplevel, it is usually more convenient to use
1586 * gtk_widget_grab_focus() instead of this function.
1589 gtk_window_set_focus (GtkWindow *window,
1592 g_return_if_fail (GTK_IS_WINDOW (window));
1595 g_return_if_fail (GTK_IS_WIDGET (focus));
1596 g_return_if_fail (gtk_widget_get_can_focus (focus));
1600 gtk_widget_grab_focus (focus);
1603 /* Clear the existing focus chain, so that when we focus into
1604 * the window again, we start at the beginnning.
1606 GtkWidget *widget = window->focus_widget;
1609 while (widget->parent)
1611 widget = widget->parent;
1612 gtk_container_set_focus_child (GTK_CONTAINER (widget), NULL);
1616 _gtk_window_internal_set_focus (window, NULL);
1621 _gtk_window_internal_set_focus (GtkWindow *window,
1624 g_return_if_fail (GTK_IS_WINDOW (window));
1626 if ((window->focus_widget != focus) ||
1627 (focus && !gtk_widget_has_focus (focus)))
1628 g_signal_emit (window, window_signals[SET_FOCUS], 0, focus);
1632 * gtk_window_set_default:
1633 * @window: a #GtkWindow
1634 * @default_widget: (allow-none): widget to be the default, or %NULL to unset the
1635 * default widget for the toplevel.
1637 * The default widget is the widget that's activated when the user
1638 * presses Enter in a dialog (for example). This function sets or
1639 * unsets the default widget for a #GtkWindow about. When setting
1640 * (rather than unsetting) the default widget it's generally easier to
1641 * call gtk_widget_grab_focus() on the widget. Before making a widget
1642 * the default widget, you must set the #GTK_CAN_DEFAULT flag on the
1643 * widget you'd like to make the default using GTK_WIDGET_SET_FLAGS().
1646 gtk_window_set_default (GtkWindow *window,
1647 GtkWidget *default_widget)
1649 g_return_if_fail (GTK_IS_WINDOW (window));
1652 g_return_if_fail (gtk_widget_get_can_default (default_widget));
1654 if (window->default_widget != default_widget)
1656 GtkWidget *old_default_widget = NULL;
1659 g_object_ref (default_widget);
1661 if (window->default_widget)
1663 old_default_widget = window->default_widget;
1665 if (window->focus_widget != window->default_widget ||
1666 !gtk_widget_get_receives_default (window->default_widget))
1667 GTK_WIDGET_UNSET_FLAGS (window->default_widget, GTK_HAS_DEFAULT);
1668 gtk_widget_queue_draw (window->default_widget);
1671 window->default_widget = default_widget;
1673 if (window->default_widget)
1675 if (window->focus_widget == NULL ||
1676 !gtk_widget_get_receives_default (window->focus_widget))
1677 GTK_WIDGET_SET_FLAGS (window->default_widget, GTK_HAS_DEFAULT);
1678 gtk_widget_queue_draw (window->default_widget);
1681 if (old_default_widget)
1682 g_object_notify (G_OBJECT (old_default_widget), "has-default");
1686 g_object_notify (G_OBJECT (default_widget), "has-default");
1687 g_object_unref (default_widget);
1693 * gtk_window_get_default_widget:
1694 * @window: a #GtkWindow
1696 * Returns the default widget for @window. See gtk_window_set_default()
1699 * Returns: the default widget, or %NULL if there is none.
1704 gtk_window_get_default_widget (GtkWindow *window)
1706 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
1708 return window->default_widget;
1712 gtk_window_set_policy_internal (GtkWindow *window,
1713 gboolean allow_shrink,
1714 gboolean allow_grow,
1715 gboolean auto_shrink)
1717 window->allow_shrink = (allow_shrink != FALSE);
1718 window->allow_grow = (allow_grow != FALSE);
1720 g_object_freeze_notify (G_OBJECT (window));
1721 g_object_notify (G_OBJECT (window), "allow-shrink");
1722 g_object_notify (G_OBJECT (window), "allow-grow");
1723 g_object_notify (G_OBJECT (window), "resizable");
1724 g_object_thaw_notify (G_OBJECT (window));
1726 gtk_widget_queue_resize_no_redraw (GTK_WIDGET (window));
1730 gtk_window_set_policy (GtkWindow *window,
1731 gboolean allow_shrink,
1732 gboolean allow_grow,
1733 gboolean auto_shrink)
1735 g_return_if_fail (GTK_IS_WINDOW (window));
1737 gtk_window_set_policy_internal (window, allow_shrink, allow_grow, auto_shrink);
1741 handle_keys_changed (gpointer data)
1745 window = GTK_WINDOW (data);
1747 if (window->keys_changed_handler)
1749 g_source_remove (window->keys_changed_handler);
1750 window->keys_changed_handler = 0;
1753 g_signal_emit (window, window_signals[KEYS_CHANGED], 0);
1759 gtk_window_notify_keys_changed (GtkWindow *window)
1761 if (!window->keys_changed_handler)
1762 window->keys_changed_handler = gdk_threads_add_idle (handle_keys_changed, window);
1766 * gtk_window_add_accel_group:
1767 * @window: window to attach accelerator group to
1768 * @accel_group: a #GtkAccelGroup
1770 * Associate @accel_group with @window, such that calling
1771 * gtk_accel_groups_activate() on @window will activate accelerators
1775 gtk_window_add_accel_group (GtkWindow *window,
1776 GtkAccelGroup *accel_group)
1778 g_return_if_fail (GTK_IS_WINDOW (window));
1779 g_return_if_fail (GTK_IS_ACCEL_GROUP (accel_group));
1781 _gtk_accel_group_attach (accel_group, G_OBJECT (window));
1782 g_signal_connect_object (accel_group, "accel-changed",
1783 G_CALLBACK (gtk_window_notify_keys_changed),
1784 window, G_CONNECT_SWAPPED);
1785 gtk_window_notify_keys_changed (window);
1789 * gtk_window_remove_accel_group:
1790 * @window: a #GtkWindow
1791 * @accel_group: a #GtkAccelGroup
1793 * Reverses the effects of gtk_window_add_accel_group().
1796 gtk_window_remove_accel_group (GtkWindow *window,
1797 GtkAccelGroup *accel_group)
1799 g_return_if_fail (GTK_IS_WINDOW (window));
1800 g_return_if_fail (GTK_IS_ACCEL_GROUP (accel_group));
1802 g_signal_handlers_disconnect_by_func (accel_group,
1803 gtk_window_notify_keys_changed,
1805 _gtk_accel_group_detach (accel_group, G_OBJECT (window));
1806 gtk_window_notify_keys_changed (window);
1809 static GtkMnemonicHash *
1810 gtk_window_get_mnemonic_hash (GtkWindow *window,
1813 GtkWindowPrivate *private = GTK_WINDOW_GET_PRIVATE (window);
1814 if (!private->mnemonic_hash && create)
1815 private->mnemonic_hash = _gtk_mnemonic_hash_new ();
1817 return private->mnemonic_hash;
1821 * gtk_window_add_mnemonic:
1822 * @window: a #GtkWindow
1823 * @keyval: the mnemonic
1824 * @target: the widget that gets activated by the mnemonic
1826 * Adds a mnemonic to this window.
1829 gtk_window_add_mnemonic (GtkWindow *window,
1833 g_return_if_fail (GTK_IS_WINDOW (window));
1834 g_return_if_fail (GTK_IS_WIDGET (target));
1836 _gtk_mnemonic_hash_add (gtk_window_get_mnemonic_hash (window, TRUE),
1838 gtk_window_notify_keys_changed (window);
1842 * gtk_window_remove_mnemonic:
1843 * @window: a #GtkWindow
1844 * @keyval: the mnemonic
1845 * @target: the widget that gets activated by the mnemonic
1847 * Removes a mnemonic from this window.
1850 gtk_window_remove_mnemonic (GtkWindow *window,
1854 g_return_if_fail (GTK_IS_WINDOW (window));
1855 g_return_if_fail (GTK_IS_WIDGET (target));
1857 _gtk_mnemonic_hash_remove (gtk_window_get_mnemonic_hash (window, TRUE),
1859 gtk_window_notify_keys_changed (window);
1863 * gtk_window_mnemonic_activate:
1864 * @window: a #GtkWindow
1865 * @keyval: the mnemonic
1866 * @modifier: the modifiers
1867 * @returns: %TRUE if the activation is done.
1869 * Activates the targets associated with the mnemonic.
1872 gtk_window_mnemonic_activate (GtkWindow *window,
1874 GdkModifierType modifier)
1876 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
1878 if (window->mnemonic_modifier == (modifier & gtk_accelerator_get_default_mod_mask ()))
1880 GtkMnemonicHash *mnemonic_hash = gtk_window_get_mnemonic_hash (window, FALSE);
1882 return _gtk_mnemonic_hash_activate (mnemonic_hash, keyval);
1889 * gtk_window_set_mnemonic_modifier:
1890 * @window: a #GtkWindow
1891 * @modifier: the modifier mask used to activate
1892 * mnemonics on this window.
1894 * Sets the mnemonic modifier for this window.
1897 gtk_window_set_mnemonic_modifier (GtkWindow *window,
1898 GdkModifierType modifier)
1900 g_return_if_fail (GTK_IS_WINDOW (window));
1901 g_return_if_fail ((modifier & ~GDK_MODIFIER_MASK) == 0);
1903 window->mnemonic_modifier = modifier;
1904 gtk_window_notify_keys_changed (window);
1908 * gtk_window_get_mnemonic_modifier:
1909 * @window: a #GtkWindow
1911 * Returns the mnemonic modifier for this window. See
1912 * gtk_window_set_mnemonic_modifier().
1914 * Return value: the modifier mask used to activate
1915 * mnemonics on this window.
1918 gtk_window_get_mnemonic_modifier (GtkWindow *window)
1920 g_return_val_if_fail (GTK_IS_WINDOW (window), 0);
1922 return window->mnemonic_modifier;
1926 * gtk_window_set_position:
1927 * @window: a #GtkWindow.
1928 * @position: a position constraint.
1930 * Sets a position constraint for this window. If the old or new
1931 * constraint is %GTK_WIN_POS_CENTER_ALWAYS, this will also cause
1932 * the window to be repositioned to satisfy the new constraint.
1935 gtk_window_set_position (GtkWindow *window,
1936 GtkWindowPosition position)
1938 g_return_if_fail (GTK_IS_WINDOW (window));
1940 if (position == GTK_WIN_POS_CENTER_ALWAYS ||
1941 window->position == GTK_WIN_POS_CENTER_ALWAYS)
1943 GtkWindowGeometryInfo *info;
1945 info = gtk_window_get_geometry_info (window, TRUE);
1947 /* this flag causes us to re-request the CENTER_ALWAYS
1948 * constraint in gtk_window_move_resize(), see
1949 * comment in that function.
1951 info->position_constraints_changed = TRUE;
1953 gtk_widget_queue_resize_no_redraw (GTK_WIDGET (window));
1956 window->position = position;
1958 g_object_notify (G_OBJECT (window), "window-position");
1962 * gtk_window_activate_focus:
1963 * @window: a #GtkWindow
1965 * Activates the current focused widget within the window.
1967 * Return value: %TRUE if a widget got activated.
1970 gtk_window_activate_focus (GtkWindow *window)
1972 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
1974 if (window->focus_widget && gtk_widget_is_sensitive (window->focus_widget))
1975 return gtk_widget_activate (window->focus_widget);
1981 * gtk_window_get_focus:
1982 * @window: a #GtkWindow
1984 * Retrieves the current focused widget within the window.
1985 * Note that this is the widget that would have the focus
1986 * if the toplevel window focused; if the toplevel window
1987 * is not focused then <literal>gtk_widget_has_focus (widget)</literal> will
1988 * not be %TRUE for the widget.
1990 * Return value: (transfer none): the currently focused widget, or %NULL if there is none.
1993 gtk_window_get_focus (GtkWindow *window)
1995 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
1997 return window->focus_widget;
2001 * gtk_window_activate_default:
2002 * @window: a #GtkWindow
2004 * Activates the default widget for the window, unless the current
2005 * focused widget has been configured to receive the default action
2006 * (see gtk_widget_set_receives_default()), in which case the
2007 * focused widget is activated.
2009 * Return value: %TRUE if a widget got activated.
2012 gtk_window_activate_default (GtkWindow *window)
2014 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
2016 if (window->default_widget && gtk_widget_is_sensitive (window->default_widget) &&
2017 (!window->focus_widget || !gtk_widget_get_receives_default (window->focus_widget)))
2018 return gtk_widget_activate (window->default_widget);
2019 else if (window->focus_widget && gtk_widget_is_sensitive (window->focus_widget))
2020 return gtk_widget_activate (window->focus_widget);
2026 * gtk_window_set_modal:
2027 * @window: a #GtkWindow
2028 * @modal: whether the window is modal
2030 * Sets a window modal or non-modal. Modal windows prevent interaction
2031 * with other windows in the same application. To keep modal dialogs
2032 * on top of main application windows, use
2033 * gtk_window_set_transient_for() to make the dialog transient for the
2034 * parent; most <link linkend="gtk-X11-arch">window managers</link>
2035 * will then disallow lowering the dialog below the parent.
2040 gtk_window_set_modal (GtkWindow *window,
2045 g_return_if_fail (GTK_IS_WINDOW (window));
2047 modal = modal != FALSE;
2048 if (window->modal == modal)
2051 window->modal = modal;
2052 widget = GTK_WIDGET (window);
2054 /* adjust desired modality state */
2055 if (GTK_WIDGET_REALIZED (window))
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_REALIZED (window))
2214 gdk_window_set_transient_for (window->window, parent->window);
2218 gtk_window_transient_parent_unrealized (GtkWidget *parent,
2221 if (GTK_WIDGET_REALIZED (window))
2222 gdk_property_delete (window->window,
2223 gdk_atom_intern_static_string ("WM_TRANSIENT_FOR"));
2227 gtk_window_transient_parent_screen_changed (GtkWindow *parent,
2231 gtk_window_set_screen (window, parent->screen);
2235 gtk_window_unset_transient_for (GtkWindow *window)
2237 GtkWindowPrivate *priv = GTK_WINDOW_GET_PRIVATE (window);
2239 if (window->transient_parent)
2241 g_signal_handlers_disconnect_by_func (window->transient_parent,
2242 gtk_window_transient_parent_realized,
2244 g_signal_handlers_disconnect_by_func (window->transient_parent,
2245 gtk_window_transient_parent_unrealized,
2247 g_signal_handlers_disconnect_by_func (window->transient_parent,
2248 gtk_window_transient_parent_screen_changed,
2250 g_signal_handlers_disconnect_by_func (window->transient_parent,
2251 gtk_widget_destroyed,
2252 &window->transient_parent);
2254 if (window->destroy_with_parent)
2255 disconnect_parent_destroyed (window);
2257 window->transient_parent = NULL;
2259 if (priv->transient_parent_group)
2261 priv->transient_parent_group = FALSE;
2262 gtk_window_group_remove_window (window->group,
2269 * gtk_window_set_transient_for:
2270 * @window: a #GtkWindow
2271 * @parent: (allow-none): parent window
2273 * Dialog windows should be set transient for the main application
2274 * window they were spawned from. This allows <link
2275 * linkend="gtk-X11-arch">window managers</link> to e.g. keep the
2276 * dialog on top of the main window, or center the dialog over the
2277 * main window. gtk_dialog_new_with_buttons() and other convenience
2278 * functions in GTK+ will sometimes call
2279 * gtk_window_set_transient_for() on your behalf.
2281 * On Windows, this function puts the child window on top of the parent,
2282 * much as the window manager would have done on X.
2286 gtk_window_set_transient_for (GtkWindow *window,
2289 GtkWindowPrivate *priv = GTK_WINDOW_GET_PRIVATE (window);
2291 g_return_if_fail (GTK_IS_WINDOW (window));
2292 g_return_if_fail (parent == NULL || GTK_IS_WINDOW (parent));
2293 g_return_if_fail (window != parent);
2295 if (window->transient_parent)
2297 if (GTK_WIDGET_REALIZED (window) &&
2298 GTK_WIDGET_REALIZED (window->transient_parent) &&
2299 (!parent || !GTK_WIDGET_REALIZED (parent)))
2300 gtk_window_transient_parent_unrealized (GTK_WIDGET (window->transient_parent),
2301 GTK_WIDGET (window));
2303 gtk_window_unset_transient_for (window);
2306 window->transient_parent = parent;
2310 g_signal_connect (parent, "destroy",
2311 G_CALLBACK (gtk_widget_destroyed),
2312 &window->transient_parent);
2313 g_signal_connect (parent, "realize",
2314 G_CALLBACK (gtk_window_transient_parent_realized),
2316 g_signal_connect (parent, "unrealize",
2317 G_CALLBACK (gtk_window_transient_parent_unrealized),
2319 g_signal_connect (parent, "notify::screen",
2320 G_CALLBACK (gtk_window_transient_parent_screen_changed),
2323 gtk_window_set_screen (window, parent->screen);
2325 if (window->destroy_with_parent)
2326 connect_parent_destroyed (window);
2328 if (GTK_WIDGET_REALIZED (window) &&
2329 GTK_WIDGET_REALIZED (parent))
2330 gtk_window_transient_parent_realized (GTK_WIDGET (parent),
2331 GTK_WIDGET (window));
2335 gtk_window_group_add_window (parent->group, window);
2336 priv->transient_parent_group = TRUE;
2342 * gtk_window_get_transient_for:
2343 * @window: a #GtkWindow
2345 * Fetches the transient parent for this window. See
2346 * gtk_window_set_transient_for().
2348 * Return value: (transfer none): the transient parent for this window, or %NULL
2349 * if no transient parent has been set.
2352 gtk_window_get_transient_for (GtkWindow *window)
2354 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
2356 return window->transient_parent;
2360 * gtk_window_set_opacity:
2361 * @window: a #GtkWindow
2362 * @opacity: desired opacity, between 0 and 1
2364 * Request the windowing system to make @window partially transparent,
2365 * with opacity 0 being fully transparent and 1 fully opaque. (Values
2366 * of the opacity parameter are clamped to the [0,1] range.) On X11
2367 * this has any effect only on X screens with a compositing manager
2368 * running. See gtk_widget_is_composited(). On Windows it should work
2371 * Note that setting a window's opacity after the window has been
2372 * shown causes it to flicker once on Windows.
2377 gtk_window_set_opacity (GtkWindow *window,
2380 GtkWindowPrivate *priv;
2382 g_return_if_fail (GTK_IS_WINDOW (window));
2384 priv = GTK_WINDOW_GET_PRIVATE (window);
2388 else if (opacity > 1.0)
2391 priv->opacity_set = TRUE;
2392 priv->opacity = opacity;
2394 if (GTK_WIDGET_REALIZED (window))
2395 gdk_window_set_opacity (GTK_WIDGET (window)->window, priv->opacity);
2399 * gtk_window_get_opacity:
2400 * @window: a #GtkWindow
2402 * Fetches the requested opacity for this window. See
2403 * gtk_window_set_opacity().
2405 * Return value: the requested opacity for this window.
2410 gtk_window_get_opacity (GtkWindow *window)
2412 GtkWindowPrivate *priv;
2414 g_return_val_if_fail (GTK_IS_WINDOW (window), 0.0);
2416 priv = GTK_WINDOW_GET_PRIVATE (window);
2418 return priv->opacity;
2422 * gtk_window_set_type_hint:
2423 * @window: a #GtkWindow
2424 * @hint: the window type
2426 * By setting the type hint for the window, you allow the window
2427 * manager to decorate and handle the window in a way which is
2428 * suitable to the function of the window in your application.
2430 * This function should be called before the window becomes visible.
2432 * gtk_dialog_new_with_buttons() and other convenience functions in GTK+
2433 * will sometimes call gtk_window_set_type_hint() on your behalf.
2437 gtk_window_set_type_hint (GtkWindow *window,
2438 GdkWindowTypeHint hint)
2440 GtkWindowPrivate *priv;
2442 g_return_if_fail (GTK_IS_WINDOW (window));
2443 g_return_if_fail (!gtk_widget_get_mapped (GTK_WIDGET (window)));
2445 priv = GTK_WINDOW_GET_PRIVATE (window);
2447 if (hint < GDK_WINDOW_TYPE_HINT_DROPDOWN_MENU)
2448 window->type_hint = hint;
2450 window->type_hint = GDK_WINDOW_TYPE_HINT_NORMAL;
2452 priv->reset_type_hint = TRUE;
2453 priv->type_hint = hint;
2457 * gtk_window_get_type_hint:
2458 * @window: a #GtkWindow
2460 * Gets the type hint for this window. See gtk_window_set_type_hint().
2462 * Return value: the type hint for @window.
2465 gtk_window_get_type_hint (GtkWindow *window)
2467 GtkWindowPrivate *priv;
2469 g_return_val_if_fail (GTK_IS_WINDOW (window), GDK_WINDOW_TYPE_HINT_NORMAL);
2471 priv = GTK_WINDOW_GET_PRIVATE (window);
2473 return priv->type_hint;
2477 * gtk_window_set_skip_taskbar_hint:
2478 * @window: a #GtkWindow
2479 * @setting: %TRUE to keep this window from appearing in the task bar
2481 * Windows may set a hint asking the desktop environment not to display
2482 * the window in the task bar. This function sets this hint.
2487 gtk_window_set_skip_taskbar_hint (GtkWindow *window,
2490 GtkWindowPrivate *priv;
2492 g_return_if_fail (GTK_IS_WINDOW (window));
2494 priv = GTK_WINDOW_GET_PRIVATE (window);
2496 setting = setting != FALSE;
2498 if (priv->skips_taskbar != setting)
2500 priv->skips_taskbar = setting;
2501 if (GTK_WIDGET_REALIZED (window))
2502 gdk_window_set_skip_taskbar_hint (GTK_WIDGET (window)->window,
2503 priv->skips_taskbar);
2504 g_object_notify (G_OBJECT (window), "skip-taskbar-hint");
2509 * gtk_window_get_skip_taskbar_hint:
2510 * @window: a #GtkWindow
2512 * Gets the value set by gtk_window_set_skip_taskbar_hint()
2514 * Return value: %TRUE if window shouldn't be in taskbar
2519 gtk_window_get_skip_taskbar_hint (GtkWindow *window)
2521 GtkWindowPrivate *priv;
2523 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
2525 priv = GTK_WINDOW_GET_PRIVATE (window);
2527 return priv->skips_taskbar;
2531 * gtk_window_set_skip_pager_hint:
2532 * @window: a #GtkWindow
2533 * @setting: %TRUE to keep this window from appearing in the pager
2535 * Windows may set a hint asking the desktop environment not to display
2536 * the window in the pager. This function sets this hint.
2537 * (A "pager" is any desktop navigation tool such as a workspace
2538 * switcher that displays a thumbnail representation of the windows
2544 gtk_window_set_skip_pager_hint (GtkWindow *window,
2547 GtkWindowPrivate *priv;
2549 g_return_if_fail (GTK_IS_WINDOW (window));
2551 priv = GTK_WINDOW_GET_PRIVATE (window);
2553 setting = setting != FALSE;
2555 if (priv->skips_pager != setting)
2557 priv->skips_pager = setting;
2558 if (GTK_WIDGET_REALIZED (window))
2559 gdk_window_set_skip_pager_hint (GTK_WIDGET (window)->window,
2561 g_object_notify (G_OBJECT (window), "skip-pager-hint");
2566 * gtk_window_get_skip_pager_hint:
2567 * @window: a #GtkWindow
2569 * Gets the value set by gtk_window_set_skip_pager_hint().
2571 * Return value: %TRUE if window shouldn't be in pager
2576 gtk_window_get_skip_pager_hint (GtkWindow *window)
2578 GtkWindowPrivate *priv;
2580 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
2582 priv = GTK_WINDOW_GET_PRIVATE (window);
2584 return priv->skips_pager;
2588 * gtk_window_set_urgency_hint:
2589 * @window: a #GtkWindow
2590 * @setting: %TRUE to mark this window as urgent
2592 * Windows may set a hint asking the desktop environment to draw
2593 * the users attention to the window. This function sets this hint.
2598 gtk_window_set_urgency_hint (GtkWindow *window,
2601 GtkWindowPrivate *priv;
2603 g_return_if_fail (GTK_IS_WINDOW (window));
2605 priv = GTK_WINDOW_GET_PRIVATE (window);
2607 setting = setting != FALSE;
2609 if (priv->urgent != setting)
2611 priv->urgent = setting;
2612 if (GTK_WIDGET_REALIZED (window))
2613 gdk_window_set_urgency_hint (GTK_WIDGET (window)->window,
2615 g_object_notify (G_OBJECT (window), "urgency-hint");
2620 * gtk_window_get_urgency_hint:
2621 * @window: a #GtkWindow
2623 * Gets the value set by gtk_window_set_urgency_hint()
2625 * Return value: %TRUE if window is urgent
2630 gtk_window_get_urgency_hint (GtkWindow *window)
2632 GtkWindowPrivate *priv;
2634 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
2636 priv = GTK_WINDOW_GET_PRIVATE (window);
2638 return priv->urgent;
2642 * gtk_window_set_accept_focus:
2643 * @window: a #GtkWindow
2644 * @setting: %TRUE to let this window receive input focus
2646 * Windows may set a hint asking the desktop environment not to receive
2647 * the input focus. This function sets this hint.
2652 gtk_window_set_accept_focus (GtkWindow *window,
2655 GtkWindowPrivate *priv;
2657 g_return_if_fail (GTK_IS_WINDOW (window));
2659 priv = GTK_WINDOW_GET_PRIVATE (window);
2661 setting = setting != FALSE;
2663 if (priv->accept_focus != setting)
2665 priv->accept_focus = setting;
2666 if (GTK_WIDGET_REALIZED (window))
2667 gdk_window_set_accept_focus (GTK_WIDGET (window)->window,
2668 priv->accept_focus);
2669 g_object_notify (G_OBJECT (window), "accept-focus");
2674 * gtk_window_get_accept_focus:
2675 * @window: a #GtkWindow
2677 * Gets the value set by gtk_window_set_accept_focus().
2679 * Return value: %TRUE if window should receive the input focus
2684 gtk_window_get_accept_focus (GtkWindow *window)
2686 GtkWindowPrivate *priv;
2688 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
2690 priv = GTK_WINDOW_GET_PRIVATE (window);
2692 return priv->accept_focus;
2696 * gtk_window_set_focus_on_map:
2697 * @window: a #GtkWindow
2698 * @setting: %TRUE to let this window receive input focus on map
2700 * Windows may set a hint asking the desktop environment not to receive
2701 * the input focus when the window is mapped. This function sets this
2707 gtk_window_set_focus_on_map (GtkWindow *window,
2710 GtkWindowPrivate *priv;
2712 g_return_if_fail (GTK_IS_WINDOW (window));
2714 priv = GTK_WINDOW_GET_PRIVATE (window);
2716 setting = setting != FALSE;
2718 if (priv->focus_on_map != setting)
2720 priv->focus_on_map = setting;
2721 if (GTK_WIDGET_REALIZED (window))
2722 gdk_window_set_focus_on_map (GTK_WIDGET (window)->window,
2723 priv->focus_on_map);
2724 g_object_notify (G_OBJECT (window), "focus-on-map");
2729 * gtk_window_get_focus_on_map:
2730 * @window: a #GtkWindow
2732 * Gets the value set by gtk_window_set_focus_on_map().
2734 * Return value: %TRUE if window should receive the input focus when
2740 gtk_window_get_focus_on_map (GtkWindow *window)
2742 GtkWindowPrivate *priv;
2744 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
2746 priv = GTK_WINDOW_GET_PRIVATE (window);
2748 return priv->focus_on_map;
2752 * gtk_window_set_destroy_with_parent:
2753 * @window: a #GtkWindow
2754 * @setting: whether to destroy @window with its transient parent
2756 * If @setting is %TRUE, then destroying the transient parent of @window
2757 * will also destroy @window itself. This is useful for dialogs that
2758 * shouldn't persist beyond the lifetime of the main window they're
2759 * associated with, for example.
2762 gtk_window_set_destroy_with_parent (GtkWindow *window,
2765 g_return_if_fail (GTK_IS_WINDOW (window));
2767 if (window->destroy_with_parent == (setting != FALSE))
2770 if (window->destroy_with_parent)
2772 disconnect_parent_destroyed (window);
2776 connect_parent_destroyed (window);
2779 window->destroy_with_parent = setting;
2781 g_object_notify (G_OBJECT (window), "destroy-with-parent");
2785 * gtk_window_get_destroy_with_parent:
2786 * @window: a #GtkWindow
2788 * Returns whether the window will be destroyed with its transient parent. See
2789 * gtk_window_set_destroy_with_parent ().
2791 * Return value: %TRUE if the window will be destroyed with its transient parent.
2794 gtk_window_get_destroy_with_parent (GtkWindow *window)
2796 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
2798 return window->destroy_with_parent;
2801 static GtkWindowGeometryInfo*
2802 gtk_window_get_geometry_info (GtkWindow *window,
2805 GtkWindowGeometryInfo *info;
2807 info = window->geometry_info;
2808 if (!info && create)
2810 info = g_new0 (GtkWindowGeometryInfo, 1);
2812 info->default_width = -1;
2813 info->default_height = -1;
2814 info->resize_width = -1;
2815 info->resize_height = -1;
2816 info->initial_x = 0;
2817 info->initial_y = 0;
2818 info->initial_pos_set = FALSE;
2819 info->default_is_geometry = FALSE;
2820 info->position_constraints_changed = FALSE;
2821 info->last.configure_request.x = 0;
2822 info->last.configure_request.y = 0;
2823 info->last.configure_request.width = -1;
2824 info->last.configure_request.height = -1;
2825 info->widget = NULL;
2827 window->geometry_info = info;
2834 * gtk_window_set_geometry_hints:
2835 * @window: a #GtkWindow
2836 * @geometry_widget: widget the geometry hints will be applied to
2837 * @geometry: struct containing geometry information
2838 * @geom_mask: mask indicating which struct fields should be paid attention to
2840 * This function sets up hints about how a window can be resized by
2841 * the user. You can set a minimum and maximum size; allowed resize
2842 * increments (e.g. for xterm, you can only resize by the size of a
2843 * character); aspect ratios; and more. See the #GdkGeometry struct.
2847 gtk_window_set_geometry_hints (GtkWindow *window,
2848 GtkWidget *geometry_widget,
2849 GdkGeometry *geometry,
2850 GdkWindowHints geom_mask)
2852 GtkWindowGeometryInfo *info;
2854 g_return_if_fail (GTK_IS_WINDOW (window));
2855 g_return_if_fail (geometry_widget == NULL || GTK_IS_WIDGET (geometry_widget));
2857 info = gtk_window_get_geometry_info (window, TRUE);
2860 g_signal_handlers_disconnect_by_func (info->widget,
2861 gtk_widget_destroyed,
2864 info->widget = geometry_widget;
2866 g_signal_connect (geometry_widget, "destroy",
2867 G_CALLBACK (gtk_widget_destroyed),
2871 info->geometry = *geometry;
2873 /* We store gravity in window->gravity not in the hints. */
2874 info->mask = geom_mask & ~(GDK_HINT_WIN_GRAVITY);
2876 if (geom_mask & GDK_HINT_WIN_GRAVITY)
2878 gtk_window_set_gravity (window, geometry->win_gravity);
2881 gtk_widget_queue_resize_no_redraw (GTK_WIDGET (window));
2885 * gtk_window_set_decorated:
2886 * @window: a #GtkWindow
2887 * @setting: %TRUE to decorate the window
2889 * By default, windows are decorated with a title bar, resize
2890 * controls, etc. Some <link linkend="gtk-X11-arch">window
2891 * managers</link> allow GTK+ to disable these decorations, creating a
2892 * borderless window. If you set the decorated property to %FALSE
2893 * using this function, GTK+ will do its best to convince the window
2894 * manager not to decorate the window. Depending on the system, this
2895 * function may not have any effect when called on a window that is
2896 * already visible, so you should call it before calling gtk_window_show().
2898 * On Windows, this function always works, since there's no window manager
2903 gtk_window_set_decorated (GtkWindow *window,
2906 g_return_if_fail (GTK_IS_WINDOW (window));
2908 setting = setting != FALSE;
2910 if (setting == window->decorated)
2913 window->decorated = setting;
2915 if (GTK_WIDGET (window)->window)
2917 if (window->decorated)
2918 gdk_window_set_decorations (GTK_WIDGET (window)->window,
2921 gdk_window_set_decorations (GTK_WIDGET (window)->window,
2925 g_object_notify (G_OBJECT (window), "decorated");
2929 * gtk_window_get_decorated:
2930 * @window: a #GtkWindow
2932 * Returns whether the window has been set to have decorations
2933 * such as a title bar via gtk_window_set_decorated().
2935 * Return value: %TRUE if the window has been set to have decorations
2938 gtk_window_get_decorated (GtkWindow *window)
2940 g_return_val_if_fail (GTK_IS_WINDOW (window), TRUE);
2942 return window->decorated;
2946 * gtk_window_set_deletable:
2947 * @window: a #GtkWindow
2948 * @setting: %TRUE to decorate the window as deletable
2950 * By default, windows have a close button in the window frame. Some
2951 * <link linkend="gtk-X11-arch">window managers</link> allow GTK+ to
2952 * disable this button. If you set the deletable property to %FALSE
2953 * using this function, GTK+ will do its best to convince the window
2954 * manager not to show a close button. Depending on the system, this
2955 * function may not have any effect when called on a window that is
2956 * already visible, so you should call it before calling gtk_window_show().
2958 * On Windows, this function always works, since there's no window manager
2964 gtk_window_set_deletable (GtkWindow *window,
2967 GtkWindowPrivate *priv;
2969 g_return_if_fail (GTK_IS_WINDOW (window));
2971 priv = GTK_WINDOW_GET_PRIVATE (window);
2973 setting = setting != FALSE;
2975 if (setting == priv->deletable)
2978 priv->deletable = setting;
2980 if (GTK_WIDGET (window)->window)
2982 if (priv->deletable)
2983 gdk_window_set_functions (GTK_WIDGET (window)->window,
2986 gdk_window_set_functions (GTK_WIDGET (window)->window,
2987 GDK_FUNC_ALL | GDK_FUNC_CLOSE);
2990 g_object_notify (G_OBJECT (window), "deletable");
2994 * gtk_window_get_deletable:
2995 * @window: a #GtkWindow
2997 * Returns whether the window has been set to have a close button
2998 * via gtk_window_set_deletable().
3000 * Return value: %TRUE if the window has been set to have a close button
3005 gtk_window_get_deletable (GtkWindow *window)
3007 GtkWindowPrivate *priv;
3009 g_return_val_if_fail (GTK_IS_WINDOW (window), TRUE);
3011 priv = GTK_WINDOW_GET_PRIVATE (window);
3013 return priv->deletable;
3016 static GtkWindowIconInfo*
3017 get_icon_info (GtkWindow *window)
3019 return g_object_get_qdata (G_OBJECT (window), quark_gtk_window_icon_info);
3023 free_icon_info (GtkWindowIconInfo *info)
3025 g_free (info->icon_name);
3026 g_slice_free (GtkWindowIconInfo, info);
3030 static GtkWindowIconInfo*
3031 ensure_icon_info (GtkWindow *window)
3033 GtkWindowIconInfo *info;
3035 info = get_icon_info (window);
3039 info = g_slice_new0 (GtkWindowIconInfo);
3040 g_object_set_qdata_full (G_OBJECT (window),
3041 quark_gtk_window_icon_info,
3043 (GDestroyNotify)free_icon_info);
3055 static ScreenIconInfo *
3056 get_screen_icon_info (GdkScreen *screen)
3058 ScreenIconInfo *info = g_object_get_qdata (G_OBJECT (screen),
3059 quark_gtk_window_default_icon_pixmap);
3062 info = g_slice_new0 (ScreenIconInfo);
3063 g_object_set_qdata (G_OBJECT (screen),
3064 quark_gtk_window_default_icon_pixmap, info);
3067 if (info->serial != default_icon_serial)
3071 g_object_remove_weak_pointer (G_OBJECT (info->pixmap), (gpointer*)&info->pixmap);
3072 info->pixmap = NULL;
3077 g_object_remove_weak_pointer (G_OBJECT (info->mask), (gpointer*)&info->mask);
3081 info->serial = default_icon_serial;
3088 get_pixmap_and_mask (GdkWindow *window,
3089 GtkWindowIconInfo *parent_info,
3090 gboolean is_default_list,
3092 GdkPixmap **pmap_return,
3093 GdkBitmap **mask_return)
3095 GdkScreen *screen = gdk_drawable_get_screen (window);
3096 ScreenIconInfo *default_icon_info = get_screen_icon_info (screen);
3097 GdkPixbuf *best_icon;
3101 *pmap_return = NULL;
3102 *mask_return = NULL;
3104 if (is_default_list &&
3105 default_icon_info->pixmap != NULL)
3107 /* Use shared icon pixmap for all windows on this screen.
3109 if (default_icon_info->pixmap)
3110 g_object_ref (default_icon_info->pixmap);
3111 if (default_icon_info->mask)
3112 g_object_ref (default_icon_info->mask);
3114 *pmap_return = default_icon_info->pixmap;
3115 *mask_return = default_icon_info->mask;
3117 else if (parent_info && parent_info->icon_pixmap)
3119 if (parent_info->icon_pixmap)
3120 g_object_ref (parent_info->icon_pixmap);
3121 if (parent_info->icon_mask)
3122 g_object_ref (parent_info->icon_mask);
3124 *pmap_return = parent_info->icon_pixmap;
3125 *mask_return = parent_info->icon_mask;
3129 #define IDEAL_SIZE 48
3131 best_size = G_MAXINT;
3133 tmp_list = icon_list;
3134 while (tmp_list != NULL)
3136 GdkPixbuf *pixbuf = tmp_list->data;
3139 /* average width and height - if someone passes in a rectangular
3140 * icon they deserve what they get.
3142 this = gdk_pixbuf_get_width (pixbuf) + gdk_pixbuf_get_height (pixbuf);
3145 if (best_icon == NULL)
3152 /* icon is better if it's 32 pixels or larger, and closer to
3153 * the ideal size than the current best.
3156 (ABS (best_size - IDEAL_SIZE) <
3157 ABS (this - IDEAL_SIZE)))
3164 tmp_list = tmp_list->next;
3168 gdk_pixbuf_render_pixmap_and_mask_for_colormap (best_icon,
3169 gdk_screen_get_system_colormap (screen),
3174 /* Save pmap/mask for others to use if appropriate */
3177 parent_info->icon_pixmap = *pmap_return;
3178 parent_info->icon_mask = *mask_return;
3180 if (parent_info->icon_pixmap)
3181 g_object_ref (parent_info->icon_pixmap);
3182 if (parent_info->icon_mask)
3183 g_object_ref (parent_info->icon_mask);
3185 else if (is_default_list)
3187 default_icon_info->pixmap = *pmap_return;
3188 default_icon_info->mask = *mask_return;
3190 if (default_icon_info->pixmap)
3191 g_object_add_weak_pointer (G_OBJECT (default_icon_info->pixmap),
3192 (gpointer*)&default_icon_info->pixmap);
3193 if (default_icon_info->mask)
3194 g_object_add_weak_pointer (G_OBJECT (default_icon_info->mask),
3195 (gpointer*)&default_icon_info->mask);
3201 icon_list_from_theme (GtkWidget *widget,
3206 GtkIconTheme *icon_theme;
3211 icon_theme = gtk_icon_theme_get_for_screen (gtk_widget_get_screen (widget));
3213 sizes = gtk_icon_theme_get_icon_sizes (icon_theme, name);
3216 for (i = 0; sizes[i]; i++)
3219 * We need an EWMH extension to handle scalable icons
3220 * by passing their name to the WM. For now just use a
3224 icon = gtk_icon_theme_load_icon (icon_theme, name,
3227 icon = gtk_icon_theme_load_icon (icon_theme, name,
3230 list = g_list_append (list, icon);
3240 gtk_window_realize_icon (GtkWindow *window)
3243 GtkWindowIconInfo *info;
3246 widget = GTK_WIDGET (window);
3248 g_return_if_fail (widget->window != NULL);
3250 /* no point setting an icon on override-redirect */
3251 if (window->type == GTK_WINDOW_POPUP)
3256 info = ensure_icon_info (window);
3261 g_return_if_fail (info->icon_pixmap == NULL);
3262 g_return_if_fail (info->icon_mask == NULL);
3264 info->using_default_icon = FALSE;
3265 info->using_parent_icon = FALSE;
3266 info->using_themed_icon = FALSE;
3268 icon_list = info->icon_list;
3270 /* Look up themed icon */
3271 if (icon_list == NULL && info->icon_name)
3273 icon_list = icon_list_from_theme (widget, info->icon_name);
3275 info->using_themed_icon = TRUE;
3278 /* Inherit from transient parent */
3279 if (icon_list == NULL && window->transient_parent)
3281 icon_list = ensure_icon_info (window->transient_parent)->icon_list;
3283 info->using_parent_icon = TRUE;
3286 /* Inherit from default */
3287 if (icon_list == NULL)
3289 icon_list = default_icon_list;
3291 info->using_default_icon = TRUE;
3294 /* Look up themed icon */
3295 if (icon_list == NULL && default_icon_name)
3297 icon_list = icon_list_from_theme (widget, default_icon_name);
3298 info->using_default_icon = TRUE;
3299 info->using_themed_icon = TRUE;
3302 gdk_window_set_icon_list (widget->window, icon_list);
3304 get_pixmap_and_mask (widget->window,
3305 info->using_parent_icon ? ensure_icon_info (window->transient_parent) : NULL,
3306 info->using_default_icon,
3311 /* This is a slight ICCCM violation since it's a color pixmap not
3312 * a bitmap, but everyone does it.
3314 gdk_window_set_icon (widget->window,
3319 info->realized = TRUE;
3321 if (info->using_themed_icon)
3323 GtkIconTheme *icon_theme;
3325 g_list_foreach (icon_list, (GFunc) g_object_unref, NULL);
3326 g_list_free (icon_list);
3328 icon_theme = gtk_icon_theme_get_for_screen (gtk_widget_get_screen (GTK_WIDGET (window)));
3329 g_signal_connect (icon_theme, "changed",
3330 G_CALLBACK (update_themed_icon), window);
3335 gtk_window_unrealize_icon (GtkWindow *window)
3337 GtkWindowIconInfo *info;
3339 info = get_icon_info (window);
3344 if (info->icon_pixmap)
3345 g_object_unref (info->icon_pixmap);
3347 if (info->icon_mask)
3348 g_object_unref (info->icon_mask);
3350 info->icon_pixmap = NULL;
3351 info->icon_mask = NULL;
3353 if (info->using_themed_icon)
3355 GtkIconTheme *icon_theme;
3357 icon_theme = gtk_icon_theme_get_for_screen (gtk_widget_get_screen (GTK_WIDGET (window)));
3359 g_signal_handlers_disconnect_by_func (icon_theme, update_themed_icon, window);
3362 /* We don't clear the properties on the window, just figure the
3363 * window is going away.
3366 info->realized = FALSE;
3371 * gtk_window_set_icon_list:
3372 * @window: a #GtkWindow
3373 * @list: list of #GdkPixbuf
3375 * Sets up the icon representing a #GtkWindow. The icon is used when
3376 * the window is minimized (also known as iconified). Some window
3377 * managers or desktop environments may also place it in the window
3378 * frame, or display it in other contexts.
3380 * gtk_window_set_icon_list() allows you to pass in the same icon in
3381 * several hand-drawn sizes. The list should contain the natural sizes
3382 * your icon is available in; that is, don't scale the image before
3383 * passing it to GTK+. Scaling is postponed until the last minute,
3384 * when the desired final size is known, to allow best quality.
3386 * By passing several sizes, you may improve the final image quality
3387 * of the icon, by reducing or eliminating automatic image scaling.
3389 * Recommended sizes to provide: 16x16, 32x32, 48x48 at minimum, and
3390 * larger images (64x64, 128x128) if you have them.
3392 * See also gtk_window_set_default_icon_list() to set the icon
3393 * for all windows in your application in one go.
3395 * Note that transient windows (those who have been set transient for another
3396 * window using gtk_window_set_transient_for()) will inherit their
3397 * icon from their transient parent. So there's no need to explicitly
3398 * set the icon on transient windows.
3401 gtk_window_set_icon_list (GtkWindow *window,
3404 GtkWindowIconInfo *info;
3406 g_return_if_fail (GTK_IS_WINDOW (window));
3408 info = ensure_icon_info (window);
3410 if (info->icon_list == list) /* check for NULL mostly */
3413 g_list_foreach (list,
3414 (GFunc) g_object_ref, NULL);
3416 g_list_foreach (info->icon_list,
3417 (GFunc) g_object_unref, NULL);
3419 g_list_free (info->icon_list);
3421 info->icon_list = g_list_copy (list);
3423 g_object_notify (G_OBJECT (window), "icon");
3425 gtk_window_unrealize_icon (window);
3427 if (GTK_WIDGET_REALIZED (window))
3428 gtk_window_realize_icon (window);
3430 /* We could try to update our transient children, but I don't think
3431 * it's really worth it. If we did it, the best way would probably
3432 * be to have children connect to notify::icon-list
3437 * gtk_window_get_icon_list:
3438 * @window: a #GtkWindow
3440 * Retrieves the list of icons set by gtk_window_set_icon_list().
3441 * The list is copied, but the reference count on each
3442 * member won't be incremented.
3444 * Return value: (element-type GdkPixbuf) (transfer container): copy of window's icon list
3447 gtk_window_get_icon_list (GtkWindow *window)
3449 GtkWindowIconInfo *info;
3451 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
3453 info = get_icon_info (window);
3456 return g_list_copy (info->icon_list);
3462 * gtk_window_set_icon:
3463 * @window: a #GtkWindow
3464 * @icon: (allow-none): icon image, or %NULL
3466 * Sets up the icon representing a #GtkWindow. This icon is used when
3467 * the window is minimized (also known as iconified). Some window
3468 * managers or desktop environments may also place it in the window
3469 * frame, or display it in other contexts.
3471 * The icon should be provided in whatever size it was naturally
3472 * drawn; that is, don't scale the image before passing it to
3473 * GTK+. Scaling is postponed until the last minute, when the desired
3474 * final size is known, to allow best quality.
3476 * If you have your icon hand-drawn in multiple sizes, use
3477 * gtk_window_set_icon_list(). Then the best size will be used.
3479 * This function is equivalent to calling gtk_window_set_icon_list()
3480 * with a 1-element list.
3482 * See also gtk_window_set_default_icon_list() to set the icon
3483 * for all windows in your application in one go.
3486 gtk_window_set_icon (GtkWindow *window,
3491 g_return_if_fail (GTK_IS_WINDOW (window));
3492 g_return_if_fail (icon == NULL || GDK_IS_PIXBUF (icon));
3497 list = g_list_append (list, icon);
3499 gtk_window_set_icon_list (window, list);
3505 update_themed_icon (GtkIconTheme *icon_theme,
3508 g_object_notify (G_OBJECT (window), "icon");
3510 gtk_window_unrealize_icon (window);
3512 if (GTK_WIDGET_REALIZED (window))
3513 gtk_window_realize_icon (window);
3517 * gtk_window_set_icon_name:
3518 * @window: a #GtkWindow
3519 * @name: (allow-none): the name of the themed icon
3521 * Sets the icon for the window from a named themed icon. See
3522 * the docs for #GtkIconTheme for more details.
3524 * Note that this has nothing to do with the WM_ICON_NAME
3525 * property which is mentioned in the ICCCM.
3530 gtk_window_set_icon_name (GtkWindow *window,
3533 GtkWindowIconInfo *info;
3536 g_return_if_fail (GTK_IS_WINDOW (window));
3538 info = ensure_icon_info (window);
3540 if (g_strcmp0 (info->icon_name, name) == 0)
3543 tmp = info->icon_name;
3544 info->icon_name = g_strdup (name);
3547 g_list_foreach (info->icon_list, (GFunc) g_object_unref, NULL);
3548 g_list_free (info->icon_list);
3549 info->icon_list = NULL;
3551 update_themed_icon (NULL, window);
3553 g_object_notify (G_OBJECT (window), "icon-name");
3557 * gtk_window_get_icon_name:
3558 * @window: a #GtkWindow
3560 * Returns the name of the themed icon for the window,
3561 * see gtk_window_set_icon_name().
3563 * Returns: the icon name or %NULL if the window has
3569 gtk_window_get_icon_name (GtkWindow *window)
3571 GtkWindowIconInfo *info;
3573 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
3575 info = ensure_icon_info (window);
3577 return info->icon_name;
3581 * gtk_window_get_icon:
3582 * @window: a #GtkWindow
3584 * Gets the value set by gtk_window_set_icon() (or if you've
3585 * called gtk_window_set_icon_list(), gets the first icon in
3588 * Return value: (transfer none): icon for window
3591 gtk_window_get_icon (GtkWindow *window)
3593 GtkWindowIconInfo *info;
3595 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
3597 info = get_icon_info (window);
3598 if (info && info->icon_list)
3599 return GDK_PIXBUF (info->icon_list->data);
3604 /* Load pixbuf, printing warning on failure if error == NULL
3607 load_pixbuf_verbosely (const char *filename,
3610 GError *local_err = NULL;
3613 pixbuf = gdk_pixbuf_new_from_file (filename, &local_err);
3621 g_warning ("Error loading icon from file '%s':\n\t%s",
3622 filename, local_err->message);
3623 g_error_free (local_err);
3631 * gtk_window_set_icon_from_file:
3632 * @window: a #GtkWindow
3633 * @filename: location of icon file
3634 * @err: (allow-none): location to store error, or %NULL.
3636 * Sets the icon for @window.
3637 * Warns on failure if @err is %NULL.
3639 * This function is equivalent to calling gtk_window_set_icon()
3640 * with a pixbuf created by loading the image from @filename.
3642 * Returns: %TRUE if setting the icon succeeded.
3647 gtk_window_set_icon_from_file (GtkWindow *window,
3648 const gchar *filename,
3651 GdkPixbuf *pixbuf = load_pixbuf_verbosely (filename, err);
3655 gtk_window_set_icon (window, pixbuf);
3656 g_object_unref (pixbuf);
3665 * gtk_window_set_default_icon_list:
3666 * @list: a list of #GdkPixbuf
3668 * Sets an icon list to be used as fallback for windows that haven't
3669 * had gtk_window_set_icon_list() called on them to set up a
3670 * window-specific icon list. This function allows you to set up the
3671 * icon for all windows in your app at once.
3673 * See gtk_window_set_icon_list() for more details.
3677 gtk_window_set_default_icon_list (GList *list)
3681 if (list == default_icon_list)
3684 /* Update serial so we don't used cached pixmaps/masks
3686 default_icon_serial++;
3688 g_list_foreach (list,
3689 (GFunc) g_object_ref, NULL);
3691 g_list_foreach (default_icon_list,
3692 (GFunc) g_object_unref, NULL);
3694 g_list_free (default_icon_list);
3696 default_icon_list = g_list_copy (list);
3698 /* Update all toplevels */
3699 toplevels = gtk_window_list_toplevels ();
3700 tmp_list = toplevels;
3701 while (tmp_list != NULL)
3703 GtkWindowIconInfo *info;
3704 GtkWindow *w = tmp_list->data;
3706 info = get_icon_info (w);
3707 if (info && info->using_default_icon)
3709 gtk_window_unrealize_icon (w);
3710 if (GTK_WIDGET_REALIZED (w))
3711 gtk_window_realize_icon (w);
3714 tmp_list = tmp_list->next;
3716 g_list_free (toplevels);
3720 * gtk_window_set_default_icon:
3723 * Sets an icon to be used as fallback for windows that haven't
3724 * had gtk_window_set_icon() called on them from a pixbuf.
3729 gtk_window_set_default_icon (GdkPixbuf *icon)
3733 g_return_if_fail (GDK_IS_PIXBUF (icon));
3735 list = g_list_prepend (NULL, icon);
3736 gtk_window_set_default_icon_list (list);
3741 * gtk_window_set_default_icon_name:
3742 * @name: the name of the themed icon
3744 * Sets an icon to be used as fallback for windows that haven't
3745 * had gtk_window_set_icon_list() called on them from a named
3746 * themed icon, see gtk_window_set_icon_name().
3751 gtk_window_set_default_icon_name (const gchar *name)
3756 /* Update serial so we don't used cached pixmaps/masks
3758 default_icon_serial++;
3760 g_free (default_icon_name);
3761 default_icon_name = g_strdup (name);
3763 g_list_foreach (default_icon_list,
3764 (GFunc) g_object_unref, NULL);
3766 g_list_free (default_icon_list);
3767 default_icon_list = NULL;
3769 /* Update all toplevels */
3770 toplevels = gtk_window_list_toplevels ();
3771 tmp_list = toplevels;
3772 while (tmp_list != NULL)
3774 GtkWindowIconInfo *info;
3775 GtkWindow *w = tmp_list->data;
3777 info = get_icon_info (w);
3778 if (info && info->using_default_icon && info->using_themed_icon)
3780 gtk_window_unrealize_icon (w);
3781 if (GTK_WIDGET_REALIZED (w))
3782 gtk_window_realize_icon (w);
3785 tmp_list = tmp_list->next;
3787 g_list_free (toplevels);
3791 * gtk_window_get_default_icon_name:
3793 * Returns the fallback icon name for windows that has been set
3794 * with gtk_window_set_default_icon_name(). The returned
3795 * string is owned by GTK+ and should not be modified. It
3796 * is only valid until the next call to
3797 * gtk_window_set_default_icon_name().
3799 * Returns: the fallback icon name for windows
3804 gtk_window_get_default_icon_name (void)
3806 return default_icon_name;
3810 * gtk_window_set_default_icon_from_file:
3811 * @filename: location of icon file
3812 * @err: (allow-none): location to store error, or %NULL.
3814 * Sets an icon to be used as fallback for windows that haven't
3815 * had gtk_window_set_icon_list() called on them from a file
3816 * on disk. Warns on failure if @err is %NULL.
3818 * Returns: %TRUE if setting the icon succeeded.
3823 gtk_window_set_default_icon_from_file (const gchar *filename,
3826 GdkPixbuf *pixbuf = load_pixbuf_verbosely (filename, err);
3830 gtk_window_set_default_icon (pixbuf);
3831 g_object_unref (pixbuf);
3840 * gtk_window_get_default_icon_list:
3842 * Gets the value set by gtk_window_set_default_icon_list().
3843 * The list is a copy and should be freed with g_list_free(),
3844 * but the pixbufs in the list have not had their reference count
3847 * Return value: copy of default icon list
3850 gtk_window_get_default_icon_list (void)
3852 return g_list_copy (default_icon_list);
3856 gtk_window_set_default_size_internal (GtkWindow *window,
3857 gboolean change_width,
3859 gboolean change_height,
3861 gboolean is_geometry)
3863 GtkWindowGeometryInfo *info;
3865 g_return_if_fail (change_width == FALSE || width >= -1);
3866 g_return_if_fail (change_height == FALSE || height >= -1);
3868 info = gtk_window_get_geometry_info (window, TRUE);
3870 g_object_freeze_notify (G_OBJECT (window));
3872 info->default_is_geometry = is_geometry != FALSE;
3882 info->default_width = width;
3884 g_object_notify (G_OBJECT (window), "default-width");
3895 info->default_height = height;
3897 g_object_notify (G_OBJECT (window), "default-height");
3900 g_object_thaw_notify (G_OBJECT (window));
3902 gtk_widget_queue_resize_no_redraw (GTK_WIDGET (window));
3906 * gtk_window_set_default_size:
3907 * @window: a #GtkWindow
3908 * @width: width in pixels, or -1 to unset the default width
3909 * @height: height in pixels, or -1 to unset the default height
3911 * Sets the default size of a window. If the window's "natural" size
3912 * (its size request) is larger than the default, the default will be
3913 * ignored. More generally, if the default size does not obey the
3914 * geometry hints for the window (gtk_window_set_geometry_hints() can
3915 * be used to set these explicitly), the default size will be clamped
3916 * to the nearest permitted size.
3918 * Unlike gtk_widget_set_size_request(), which sets a size request for
3919 * a widget and thus would keep users from shrinking the window, this
3920 * function only sets the initial size, just as if the user had
3921 * resized the window themselves. Users can still shrink the window
3922 * again as they normally would. Setting a default size of -1 means to
3923 * use the "natural" default size (the size request of the window).
3925 * For more control over a window's initial size and how resizing works,
3926 * investigate gtk_window_set_geometry_hints().
3928 * For some uses, gtk_window_resize() is a more appropriate function.
3929 * gtk_window_resize() changes the current size of the window, rather
3930 * than the size to be used on initial display. gtk_window_resize() always
3931 * affects the window itself, not the geometry widget.
3933 * The default size of a window only affects the first time a window is
3934 * shown; if a window is hidden and re-shown, it will remember the size
3935 * it had prior to hiding, rather than using the default size.
3937 * Windows can't actually be 0x0 in size, they must be at least 1x1, but
3938 * passing 0 for @width and @height is OK, resulting in a 1x1 default size.
3941 gtk_window_set_default_size (GtkWindow *window,
3945 g_return_if_fail (GTK_IS_WINDOW (window));
3946 g_return_if_fail (width >= -1);
3947 g_return_if_fail (height >= -1);
3949 gtk_window_set_default_size_internal (window, TRUE, width, TRUE, height, FALSE);
3953 * gtk_window_get_default_size:
3954 * @window: a #GtkWindow
3955 * @width: (allow-none): location to store the default width, or %NULL
3956 * @height: (allow-none): location to store the default height, or %NULL
3958 * Gets the default size of the window. A value of -1 for the width or
3959 * height indicates that a default size has not been explicitly set
3960 * for that dimension, so the "natural" size of the window will be
3965 gtk_window_get_default_size (GtkWindow *window,
3969 GtkWindowGeometryInfo *info;
3971 g_return_if_fail (GTK_IS_WINDOW (window));
3973 info = gtk_window_get_geometry_info (window, FALSE);
3976 *width = info ? info->default_width : -1;
3979 *height = info ? info->default_height : -1;
3983 * gtk_window_resize:
3984 * @window: a #GtkWindow
3985 * @width: width in pixels to resize the window to
3986 * @height: height in pixels to resize the window to
3988 * Resizes the window as if the user had done so, obeying geometry
3989 * constraints. The default geometry constraint is that windows may
3990 * not be smaller than their size request; to override this
3991 * constraint, call gtk_widget_set_size_request() to set the window's
3992 * request to a smaller value.
3994 * If gtk_window_resize() is called before showing a window for the
3995 * first time, it overrides any default size set with
3996 * gtk_window_set_default_size().
3998 * Windows may not be resized smaller than 1 by 1 pixels.
4002 gtk_window_resize (GtkWindow *window,
4006 GtkWindowGeometryInfo *info;
4008 g_return_if_fail (GTK_IS_WINDOW (window));
4009 g_return_if_fail (width > 0);
4010 g_return_if_fail (height > 0);
4012 info = gtk_window_get_geometry_info (window, TRUE);
4014 info->resize_width = width;
4015 info->resize_height = height;
4017 gtk_widget_queue_resize_no_redraw (GTK_WIDGET (window));
4021 * gtk_window_get_size:
4022 * @window: a #GtkWindow
4023 * @width: (allow-none): (out): return location for width, or %NULL
4024 * @height: (allow-none): (out): return location for height, or %NULL
4026 * Obtains the current size of @window. If @window is not onscreen,
4027 * it returns the size GTK+ will suggest to the <link
4028 * linkend="gtk-X11-arch">window manager</link> for the initial window
4029 * size (but this is not reliably the same as the size the window
4030 * manager will actually select). The size obtained by
4031 * gtk_window_get_size() is the last size received in a
4032 * #GdkEventConfigure, that is, GTK+ uses its locally-stored size,
4033 * rather than querying the X server for the size. As a result, if you
4034 * call gtk_window_resize() then immediately call
4035 * gtk_window_get_size(), the size won't have taken effect yet. After
4036 * the window manager processes the resize request, GTK+ receives
4037 * notification that the size has changed via a configure event, and
4038 * the size of the window gets updated.
4040 * Note 1: Nearly any use of this function creates a race condition,
4041 * because the size of the window may change between the time that you
4042 * get the size and the time that you perform some action assuming
4043 * that size is the current size. To avoid race conditions, connect to
4044 * "configure-event" on the window and adjust your size-dependent
4045 * state to match the size delivered in the #GdkEventConfigure.
4047 * Note 2: The returned size does <emphasis>not</emphasis> include the
4048 * size of the window manager decorations (aka the window frame or
4049 * border). Those are not drawn by GTK+ and GTK+ has no reliable
4050 * method of determining their size.
4052 * Note 3: If you are getting a window size in order to position
4053 * the window onscreen, there may be a better way. The preferred
4054 * way is to simply set the window's semantic type with
4055 * gtk_window_set_type_hint(), which allows the window manager to
4056 * e.g. center dialogs. Also, if you set the transient parent of
4057 * dialogs with gtk_window_set_transient_for() window managers
4058 * will often center the dialog over its parent window. It's
4059 * much preferred to let the window manager handle these
4060 * things rather than doing it yourself, because all apps will
4061 * behave consistently and according to user prefs if the window
4062 * manager handles it. Also, the window manager can take the size
4063 * of the window decorations/border into account, while your
4064 * application cannot.
4066 * In any case, if you insist on application-specified window
4067 * positioning, there's <emphasis>still</emphasis> a better way than
4068 * doing it yourself - gtk_window_set_position() will frequently
4069 * handle the details for you.
4073 gtk_window_get_size (GtkWindow *window,
4079 g_return_if_fail (GTK_IS_WINDOW (window));
4081 if (width == NULL && height == NULL)
4084 if (gtk_widget_get_mapped (GTK_WIDGET (window)))
4086 gdk_drawable_get_size (GTK_WIDGET (window)->window,
4091 GdkRectangle configure_request;
4093 gtk_window_compute_configure_request (window,
4097 w = configure_request.width;
4098 h = configure_request.height;
4109 * @window: a #GtkWindow
4110 * @x: X coordinate to move window to
4111 * @y: Y coordinate to move window to
4113 * Asks the <link linkend="gtk-X11-arch">window manager</link> to move
4114 * @window to the given position. Window managers are free to ignore
4115 * this; most window managers ignore requests for initial window
4116 * positions (instead using a user-defined placement algorithm) and
4117 * honor requests after the window has already been shown.
4119 * Note: the position is the position of the gravity-determined
4120 * reference point for the window. The gravity determines two things:
4121 * first, the location of the reference point in root window
4122 * coordinates; and second, which point on the window is positioned at
4123 * the reference point.
4125 * By default the gravity is #GDK_GRAVITY_NORTH_WEST, so the reference
4126 * point is simply the @x, @y supplied to gtk_window_move(). The
4127 * top-left corner of the window decorations (aka window frame or
4128 * border) will be placed at @x, @y. Therefore, to position a window
4129 * at the top left of the screen, you want to use the default gravity
4130 * (which is #GDK_GRAVITY_NORTH_WEST) and move the window to 0,0.
4132 * To position a window at the bottom right corner of the screen, you
4133 * would set #GDK_GRAVITY_SOUTH_EAST, which means that the reference
4134 * point is at @x + the window width and @y + the window height, and
4135 * the bottom-right corner of the window border will be placed at that
4136 * reference point. So, to place a window in the bottom right corner
4137 * you would first set gravity to south east, then write:
4138 * <literal>gtk_window_move (window, gdk_screen_width () - window_width,
4139 * gdk_screen_height () - window_height)</literal> (note that this
4140 * example does not take multi-head scenarios into account).
4142 * The Extended Window Manager Hints specification at <ulink
4143 * url="http://www.freedesktop.org/Standards/wm-spec">
4144 * http://www.freedesktop.org/Standards/wm-spec</ulink> has a
4145 * nice table of gravities in the "implementation notes" section.
4147 * The gtk_window_get_position() documentation may also be relevant.
4150 gtk_window_move (GtkWindow *window,
4154 GtkWindowGeometryInfo *info;
4157 g_return_if_fail (GTK_IS_WINDOW (window));
4159 widget = GTK_WIDGET (window);
4161 info = gtk_window_get_geometry_info (window, TRUE);
4163 if (gtk_widget_get_mapped (widget))
4165 /* we have now sent a request with this position
4166 * with currently-active constraints, so toggle flag.
4168 info->position_constraints_changed = FALSE;
4170 /* we only constrain if mapped - if not mapped,
4171 * then gtk_window_compute_configure_request()
4172 * will apply the constraints later, and we
4173 * don't want to lose information about
4174 * what position the user set before then.
4175 * i.e. if you do a move() then turn off POS_CENTER
4176 * then show the window, your move() will work.
4178 gtk_window_constrain_position (window,
4179 widget->allocation.width,
4180 widget->allocation.height,
4183 /* Note that this request doesn't go through our standard request
4184 * framework, e.g. doesn't increment configure_request_count,
4185 * doesn't set info->last, etc.; that's because
4186 * we don't save the info needed to arrive at this same request
4189 * To gtk_window_move_resize(), this will end up looking exactly
4190 * the same as the position being changed by the window
4194 /* FIXME are we handling gravity properly for framed windows? */
4196 gdk_window_move (window->frame,
4197 x - window->frame_left,
4198 y - window->frame_top);
4200 gdk_window_move (GTK_WIDGET (window)->window,
4205 /* Save this position to apply on mapping */
4206 info->initial_x = x;
4207 info->initial_y = y;
4208 info->initial_pos_set = TRUE;
4213 * gtk_window_get_position:
4214 * @window: a #GtkWindow
4215 * @root_x: return location for X coordinate of gravity-determined reference point
4216 * @root_y: return location for Y coordinate of gravity-determined reference point
4218 * This function returns the position you need to pass to
4219 * gtk_window_move() to keep @window in its current position. This
4220 * means that the meaning of the returned value varies with window
4221 * gravity. See gtk_window_move() for more details.
4223 * If you haven't changed the window gravity, its gravity will be
4224 * #GDK_GRAVITY_NORTH_WEST. This means that gtk_window_get_position()
4225 * gets the position of the top-left corner of the window manager
4226 * frame for the window. gtk_window_move() sets the position of this
4227 * same top-left corner.
4229 * gtk_window_get_position() is not 100% reliable because the X Window System
4230 * does not specify a way to obtain the geometry of the
4231 * decorations placed on a window by the window manager.
4232 * Thus GTK+ is using a "best guess" that works with most
4235 * Moreover, nearly all window managers are historically broken with
4236 * respect to their handling of window gravity. So moving a window to
4237 * its current position as returned by gtk_window_get_position() tends
4238 * to result in moving the window slightly. Window managers are
4239 * slowly getting better over time.
4241 * If a window has gravity #GDK_GRAVITY_STATIC the window manager
4242 * frame is not relevant, and thus gtk_window_get_position() will
4243 * always produce accurate results. However you can't use static
4244 * gravity to do things like place a window in a corner of the screen,
4245 * because static gravity ignores the window manager decorations.
4247 * If you are saving and restoring your application's window
4248 * positions, you should know that it's impossible for applications to
4249 * do this without getting it somewhat wrong because applications do
4250 * not have sufficient knowledge of window manager state. The Correct
4251 * Mechanism is to support the session management protocol (see the
4252 * "GnomeClient" object in the GNOME libraries for example) and allow
4253 * the window manager to save your window sizes and positions.
4258 gtk_window_get_position (GtkWindow *window,
4264 g_return_if_fail (GTK_IS_WINDOW (window));
4266 widget = GTK_WIDGET (window);
4268 if (window->gravity == GDK_GRAVITY_STATIC)
4270 if (gtk_widget_get_mapped (widget))
4272 /* This does a server round-trip, which is sort of wrong;
4273 * but a server round-trip is inevitable for
4274 * gdk_window_get_frame_extents() in the usual
4275 * NorthWestGravity case below, so not sure what else to
4276 * do. We should likely be consistent about whether we get
4277 * the client-side info or the server-side info.
4279 gdk_window_get_origin (widget->window, root_x, root_y);
4283 GdkRectangle configure_request;
4285 gtk_window_compute_configure_request (window,
4289 *root_x = configure_request.x;
4290 *root_y = configure_request.y;
4295 GdkRectangle frame_extents;
4300 if (gtk_widget_get_mapped (widget))
4303 gdk_window_get_frame_extents (window->frame, &frame_extents);
4305 gdk_window_get_frame_extents (widget->window, &frame_extents);
4306 x = frame_extents.x;
4307 y = frame_extents.y;
4308 gtk_window_get_size (window, &w, &h);
4312 /* We just say the frame has 0 size on all sides.
4313 * Not sure what else to do.
4315 gtk_window_compute_configure_request (window,
4318 x = frame_extents.x;
4319 y = frame_extents.y;
4320 w = frame_extents.width;
4321 h = frame_extents.height;
4324 switch (window->gravity)
4326 case GDK_GRAVITY_NORTH:
4327 case GDK_GRAVITY_CENTER:
4328 case GDK_GRAVITY_SOUTH:
4329 /* Find center of frame. */
4330 x += frame_extents.width / 2;
4331 /* Center client window on that point. */
4335 case GDK_GRAVITY_SOUTH_EAST:
4336 case GDK_GRAVITY_EAST:
4337 case GDK_GRAVITY_NORTH_EAST:
4338 /* Find right edge of frame */
4339 x += frame_extents.width;
4340 /* Align left edge of client at that point. */
4347 switch (window->gravity)
4349 case GDK_GRAVITY_WEST:
4350 case GDK_GRAVITY_CENTER:
4351 case GDK_GRAVITY_EAST:
4352 /* Find center of frame. */
4353 y += frame_extents.height / 2;
4354 /* Center client window there. */
4357 case GDK_GRAVITY_SOUTH_WEST:
4358 case GDK_GRAVITY_SOUTH:
4359 case GDK_GRAVITY_SOUTH_EAST:
4360 /* Find south edge of frame */
4361 y += frame_extents.height;
4362 /* Place bottom edge of client there */
4377 * gtk_window_reshow_with_initial_size:
4378 * @window: a #GtkWindow
4380 * Hides @window, then reshows it, resetting the
4381 * default size and position of the window. Used
4382 * by GUI builders only.
4385 gtk_window_reshow_with_initial_size (GtkWindow *window)
4389 g_return_if_fail (GTK_IS_WINDOW (window));
4391 widget = GTK_WIDGET (window);
4393 gtk_widget_hide (widget);
4394 gtk_widget_unrealize (widget);
4395 gtk_widget_show (widget);
4399 gtk_window_destroy (GtkObject *object)
4401 GtkWindow *window = GTK_WINDOW (object);
4403 toplevel_list = g_slist_remove (toplevel_list, window);
4405 if (window->transient_parent)
4406 gtk_window_set_transient_for (window, NULL);
4408 /* frees the icons */
4409 gtk_window_set_icon_list (window, NULL);
4411 if (window->has_user_ref_count)
4413 window->has_user_ref_count = FALSE;
4414 g_object_unref (window);
4418 gtk_window_group_remove_window (window->group, window);
4420 gtk_window_free_key_hash (window);
4422 GTK_OBJECT_CLASS (gtk_window_parent_class)->destroy (object);
4426 gtk_window_finalize (GObject *object)
4428 GtkWindow *window = GTK_WINDOW (object);
4429 GtkWindowPrivate *priv = GTK_WINDOW_GET_PRIVATE (window);
4430 GtkMnemonicHash *mnemonic_hash;
4432 g_free (window->title);
4433 g_free (window->wmclass_name);
4434 g_free (window->wmclass_class);
4435 g_free (window->wm_role);
4437 mnemonic_hash = gtk_window_get_mnemonic_hash (window, FALSE);
4439 _gtk_mnemonic_hash_free (mnemonic_hash);
4441 if (window->geometry_info)
4443 if (window->geometry_info->widget)
4444 g_signal_handlers_disconnect_by_func (window->geometry_info->widget,
4445 gtk_widget_destroyed,
4446 &window->geometry_info->widget);
4447 g_free (window->geometry_info);
4450 if (window->keys_changed_handler)
4452 g_source_remove (window->keys_changed_handler);
4453 window->keys_changed_handler = 0;
4457 g_signal_handlers_disconnect_by_func (window->screen,
4458 gtk_window_on_composited_changed, window);
4460 g_free (priv->startup_id);
4462 G_OBJECT_CLASS (gtk_window_parent_class)->finalize (object);
4466 gtk_window_show (GtkWidget *widget)
4468 GtkWindow *window = GTK_WINDOW (widget);
4469 GtkContainer *container = GTK_CONTAINER (window);
4470 gboolean need_resize;
4472 GTK_WIDGET_SET_FLAGS (widget, GTK_VISIBLE);
4474 need_resize = container->need_resize || !GTK_WIDGET_REALIZED (widget);
4475 container->need_resize = FALSE;
4479 GtkWindowGeometryInfo *info = gtk_window_get_geometry_info (window, TRUE);
4480 GtkAllocation allocation = { 0, 0 };
4481 GdkRectangle configure_request;
4482 GdkGeometry new_geometry;
4484 gboolean was_realized;
4486 /* We are going to go ahead and perform this configure request
4487 * and then emulate a configure notify by going ahead and
4488 * doing a size allocate. Sort of a synchronous
4489 * mini-copy of gtk_window_move_resize() here.
4491 gtk_window_compute_configure_request (window,
4496 /* We update this because we are going to go ahead
4497 * and gdk_window_resize() below, rather than
4500 info->last.configure_request.width = configure_request.width;
4501 info->last.configure_request.height = configure_request.height;
4503 /* and allocate the window - this is normally done
4504 * in move_resize in response to configure notify
4506 allocation.width = configure_request.width;
4507 allocation.height = configure_request.height;
4508 gtk_widget_size_allocate (widget, &allocation);
4510 /* Then we guarantee we have a realize */
4511 was_realized = FALSE;
4512 if (!GTK_WIDGET_REALIZED (widget))
4514 gtk_widget_realize (widget);
4515 was_realized = TRUE;
4518 /* Must be done after the windows are realized,
4519 * so that the decorations can be read
4521 gtk_decorated_window_calculate_frame_size (window);
4523 /* We only send configure request if we didn't just finish
4524 * creating the window; if we just created the window
4525 * then we created it with widget->allocation anyhow.
4528 gdk_window_move_resize (widget->window,
4529 configure_request.x,
4530 configure_request.y,
4531 configure_request.width,
4532 configure_request.height);
4535 gtk_container_check_resize (container);
4537 gtk_widget_map (widget);
4539 /* Try to make sure that we have some focused widget
4541 if (!window->focus_widget && !GTK_IS_PLUG (window))
4542 gtk_window_move_focus (window, GTK_DIR_TAB_FORWARD);
4545 gtk_grab_add (widget);
4549 gtk_window_hide (GtkWidget *widget)
4551 GtkWindow *window = GTK_WINDOW (widget);
4553 GTK_WIDGET_UNSET_FLAGS (widget, GTK_VISIBLE);
4554 gtk_widget_unmap (widget);
4557 gtk_grab_remove (widget);
4561 gtk_window_map (GtkWidget *widget)
4563 GtkWindow *window = GTK_WINDOW (widget);
4564 GtkWindowPrivate *priv = GTK_WINDOW_GET_PRIVATE (window);
4565 GdkWindow *toplevel;
4566 gboolean auto_mnemonics;
4568 GTK_WIDGET_SET_FLAGS (widget, GTK_MAPPED);
4570 if (window->bin.child &&
4571 gtk_widget_get_visible (window->bin.child) &&
4572 !gtk_widget_get_mapped (window->bin.child))
4573 gtk_widget_map (window->bin.child);
4576 toplevel = window->frame;
4578 toplevel = widget->window;
4580 if (window->maximize_initially)
4581 gdk_window_maximize (toplevel);
4583 gdk_window_unmaximize (toplevel);
4585 if (window->stick_initially)
4586 gdk_window_stick (toplevel);
4588 gdk_window_unstick (toplevel);
4590 if (window->iconify_initially)
4591 gdk_window_iconify (toplevel);
4593 gdk_window_deiconify (toplevel);
4595 if (priv->fullscreen_initially)
4596 gdk_window_fullscreen (toplevel);
4598 gdk_window_unfullscreen (toplevel);
4600 gdk_window_set_keep_above (toplevel, priv->above_initially);
4602 gdk_window_set_keep_below (toplevel, priv->below_initially);
4604 /* No longer use the default settings */
4605 window->need_default_size = FALSE;
4606 window->need_default_position = FALSE;
4608 if (priv->reset_type_hint)
4610 /* We should only reset the type hint when the application
4611 * used gtk_window_set_type_hint() to change the hint.
4612 * Some applications use X directly to change the properties;
4613 * in that case, we shouldn't overwrite what they did.
4615 gdk_window_set_type_hint (widget->window, priv->type_hint);
4616 priv->reset_type_hint = FALSE;
4619 gdk_window_show (widget->window);
4622 gdk_window_show (window->frame);
4624 if (!disable_startup_notification)
4626 /* Do we have a custom startup-notification id? */
4627 if (priv->startup_id != NULL)
4629 /* Make sure we have a "real" id */
4630 if (!startup_id_is_fake (priv->startup_id))
4631 gdk_notify_startup_complete_with_id (priv->startup_id);
4633 g_free (priv->startup_id);
4634 priv->startup_id = NULL;
4636 else if (!sent_startup_notification)
4638 sent_startup_notification = TRUE;
4639 gdk_notify_startup_complete ();
4643 /* if auto-mnemonics is enabled and mnemonics visible is not already set
4644 * (as in the case of popup menus), then hide mnemonics initially
4646 g_object_get (gtk_widget_get_settings (widget), "gtk-auto-mnemonics",
4647 &auto_mnemonics, NULL);
4648 if (auto_mnemonics && !priv->mnemonics_visible_set)
4649 gtk_window_set_mnemonics_visible (window, FALSE);
4653 gtk_window_map_event (GtkWidget *widget,
4656 if (!gtk_widget_get_mapped (widget))
4658 /* we should be be unmapped, but are getting a MapEvent, this may happen
4659 * to toplevel XWindows if mapping was intercepted by a window manager
4660 * and an unmap request occoured while the MapRequestEvent was still
4661 * being handled. we work around this situaiton here by re-requesting
4662 * the window being unmapped. more details can be found in:
4663 * http://bugzilla.gnome.org/show_bug.cgi?id=316180
4665 gdk_window_hide (widget->window);
4671 gtk_window_unmap (GtkWidget *widget)
4673 GtkWindow *window = GTK_WINDOW (widget);
4674 GtkWindowPrivate *priv = GTK_WINDOW_GET_PRIVATE (widget);
4675 GtkWindowGeometryInfo *info;
4676 GdkWindowState state;
4678 GTK_WIDGET_UNSET_FLAGS (widget, GTK_MAPPED);
4680 gdk_window_withdraw (window->frame);
4682 gdk_window_withdraw (widget->window);
4684 window->configure_request_count = 0;
4685 window->configure_notify_received = FALSE;
4687 /* on unmap, we reset the default positioning of the window,
4688 * so it's placed again, but we don't reset the default
4689 * size of the window, so it's remembered.
4691 window->need_default_position = TRUE;
4693 info = gtk_window_get_geometry_info (window, FALSE);
4696 info->initial_pos_set = FALSE;
4697 info->position_constraints_changed = FALSE;
4700 state = gdk_window_get_state (widget->window);
4701 window->iconify_initially = (state & GDK_WINDOW_STATE_ICONIFIED) != 0;
4702 window->maximize_initially = (state & GDK_WINDOW_STATE_MAXIMIZED) != 0;
4703 window->stick_initially = (state & GDK_WINDOW_STATE_STICKY) != 0;
4704 priv->above_initially = (state & GDK_WINDOW_STATE_ABOVE) != 0;
4705 priv->below_initially = (state & GDK_WINDOW_STATE_BELOW) != 0;
4709 gtk_window_realize (GtkWidget *widget)
4712 GdkWindow *parent_window;
4713 GdkWindowAttr attributes;
4714 gint attributes_mask;
4715 GtkWindowPrivate *priv;
4717 window = GTK_WINDOW (widget);
4718 priv = GTK_WINDOW_GET_PRIVATE (window);
4720 /* ensure widget tree is properly size allocated */
4721 if (widget->allocation.x == -1 &&
4722 widget->allocation.y == -1 &&
4723 widget->allocation.width == 1 &&
4724 widget->allocation.height == 1)
4726 GtkRequisition requisition;
4727 GtkAllocation allocation = { 0, 0, 200, 200 };
4729 gtk_widget_size_request (widget, &requisition);
4730 if (requisition.width || requisition.height)
4732 /* non-empty window */
4733 allocation.width = requisition.width;
4734 allocation.height = requisition.height;
4736 gtk_widget_size_allocate (widget, &allocation);
4738 _gtk_container_queue_resize (GTK_CONTAINER (widget));
4740 g_return_if_fail (!GTK_WIDGET_REALIZED (widget));
4743 GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED);
4745 switch (window->type)
4747 case GTK_WINDOW_TOPLEVEL:
4748 attributes.window_type = GDK_WINDOW_TOPLEVEL;
4750 case GTK_WINDOW_POPUP:
4751 attributes.window_type = GDK_WINDOW_TEMP;
4754 g_warning (G_STRLOC": Unknown window type %d!", window->type);
4758 attributes.title = window->title;
4759 attributes.wmclass_name = window->wmclass_name;
4760 attributes.wmclass_class = window->wmclass_class;
4761 attributes.wclass = GDK_INPUT_OUTPUT;
4762 attributes.visual = gtk_widget_get_visual (widget);
4763 attributes.colormap = gtk_widget_get_colormap (widget);
4765 if (window->has_frame)
4767 attributes.width = widget->allocation.width + window->frame_left + window->frame_right;
4768 attributes.height = widget->allocation.height + window->frame_top + window->frame_bottom;
4769 attributes.event_mask = (GDK_EXPOSURE_MASK |
4770 GDK_KEY_PRESS_MASK |
4771 GDK_ENTER_NOTIFY_MASK |
4772 GDK_LEAVE_NOTIFY_MASK |
4773 GDK_FOCUS_CHANGE_MASK |
4774 GDK_STRUCTURE_MASK |
4775 GDK_BUTTON_MOTION_MASK |
4776 GDK_POINTER_MOTION_HINT_MASK |
4777 GDK_BUTTON_PRESS_MASK |
4778 GDK_BUTTON_RELEASE_MASK);
4780 attributes_mask = GDK_WA_VISUAL | GDK_WA_COLORMAP;
4782 window->frame = gdk_window_new (gtk_widget_get_root_window (widget),
4783 &attributes, attributes_mask);
4785 if (priv->opacity_set)
4786 gdk_window_set_opacity (window->frame, priv->opacity);
4788 gdk_window_set_user_data (window->frame, widget);
4790 attributes.window_type = GDK_WINDOW_CHILD;
4791 attributes.x = window->frame_left;
4792 attributes.y = window->frame_top;
4794 attributes_mask = GDK_WA_X | GDK_WA_Y;
4796 parent_window = window->frame;
4798 g_signal_connect (window,
4800 G_CALLBACK (gtk_window_event),
4805 attributes_mask = 0;
4806 parent_window = gtk_widget_get_root_window (widget);
4809 attributes.width = widget->allocation.width;
4810 attributes.height = widget->allocation.height;
4811 attributes.event_mask = gtk_widget_get_events (widget);
4812 attributes.event_mask |= (GDK_EXPOSURE_MASK |
4813 GDK_KEY_PRESS_MASK |
4814 GDK_KEY_RELEASE_MASK |
4815 GDK_ENTER_NOTIFY_MASK |
4816 GDK_LEAVE_NOTIFY_MASK |
4817 GDK_FOCUS_CHANGE_MASK |
4818 GDK_STRUCTURE_MASK);
4819 attributes.type_hint = priv->type_hint;
4821 attributes_mask |= GDK_WA_VISUAL | GDK_WA_COLORMAP | GDK_WA_TYPE_HINT;
4822 attributes_mask |= (window->title ? GDK_WA_TITLE : 0);
4823 attributes_mask |= (window->wmclass_name ? GDK_WA_WMCLASS : 0);
4825 widget->window = gdk_window_new (parent_window, &attributes, attributes_mask);
4827 if (!window->has_frame && priv->opacity_set)
4828 gdk_window_set_opacity (widget->window, priv->opacity);
4830 gdk_window_enable_synchronized_configure (widget->window);
4832 gdk_window_set_user_data (widget->window, window);
4834 widget->style = gtk_style_attach (widget->style, widget->window);
4835 gtk_style_set_background (widget->style, widget->window, GTK_STATE_NORMAL);
4837 gtk_style_set_background (widget->style, window->frame, GTK_STATE_NORMAL);
4839 /* This is a bad hack to set the window background. */
4840 gtk_window_paint (widget, NULL);
4842 if (window->transient_parent &&
4843 GTK_WIDGET_REALIZED (window->transient_parent))
4844 gdk_window_set_transient_for (widget->window,
4845 GTK_WIDGET (window->transient_parent)->window);
4847 if (window->wm_role)
4848 gdk_window_set_role (widget->window, window->wm_role);
4850 if (!window->decorated)
4851 gdk_window_set_decorations (widget->window, 0);
4853 if (!priv->deletable)
4854 gdk_window_set_functions (widget->window, GDK_FUNC_ALL | GDK_FUNC_CLOSE);
4856 if (gtk_window_get_skip_pager_hint (window))
4857 gdk_window_set_skip_pager_hint (widget->window, TRUE);
4859 if (gtk_window_get_skip_taskbar_hint (window))
4860 gdk_window_set_skip_taskbar_hint (widget->window, TRUE);
4862 if (gtk_window_get_accept_focus (window))
4863 gdk_window_set_accept_focus (widget->window, TRUE);
4865 gdk_window_set_accept_focus (widget->window, FALSE);
4867 if (gtk_window_get_focus_on_map (window))
4868 gdk_window_set_focus_on_map (widget->window, TRUE);
4870 gdk_window_set_focus_on_map (widget->window, FALSE);
4873 gdk_window_set_modal_hint (widget->window, TRUE);
4875 gdk_window_set_modal_hint (widget->window, FALSE);
4877 if (priv->startup_id)
4879 #ifdef GDK_WINDOWING_X11
4880 guint32 timestamp = extract_time_from_startup_id (priv->startup_id);
4881 if (timestamp != GDK_CURRENT_TIME)
4882 gdk_x11_window_set_user_time (widget->window, timestamp);
4884 if (!startup_id_is_fake (priv->startup_id))
4885 gdk_window_set_startup_id (widget->window, priv->startup_id);
4889 gtk_window_realize_icon (window);
4893 gtk_window_unrealize (GtkWidget *widget)
4896 GtkWindowGeometryInfo *info;
4898 window = GTK_WINDOW (widget);
4900 /* On unrealize, we reset the size of the window such
4901 * that we will re-apply the default sizing stuff
4902 * next time we show the window.
4904 * Default positioning is reset on unmap, instead of unrealize.
4906 window->need_default_size = TRUE;
4907 info = gtk_window_get_geometry_info (window, FALSE);
4910 info->resize_width = -1;
4911 info->resize_height = -1;
4912 info->last.configure_request.x = 0;
4913 info->last.configure_request.y = 0;
4914 info->last.configure_request.width = -1;
4915 info->last.configure_request.height = -1;
4916 /* be sure we reset geom hints on re-realize */
4917 info->last.flags = 0;
4922 gdk_window_set_user_data (window->frame, NULL);
4923 gdk_window_destroy (window->frame);
4924 window->frame = NULL;
4928 gtk_window_unrealize_icon (window);
4930 GTK_WIDGET_CLASS (gtk_window_parent_class)->unrealize (widget);
4934 gtk_window_size_request (GtkWidget *widget,
4935 GtkRequisition *requisition)
4940 window = GTK_WINDOW (widget);
4941 bin = GTK_BIN (window);
4943 requisition->width = GTK_CONTAINER (window)->border_width * 2;
4944 requisition->height = GTK_CONTAINER (window)->border_width * 2;
4946 if (bin->child && gtk_widget_get_visible (bin->child))
4948 GtkRequisition child_requisition;
4950 gtk_widget_size_request (bin->child, &child_requisition);
4952 requisition->width += child_requisition.width;
4953 requisition->height += child_requisition.height;
4958 gtk_window_size_allocate (GtkWidget *widget,
4959 GtkAllocation *allocation)
4962 GtkAllocation child_allocation;
4964 window = GTK_WINDOW (widget);
4965 widget->allocation = *allocation;
4967 if (window->bin.child && gtk_widget_get_visible (window->bin.child))
4969 child_allocation.x = GTK_CONTAINER (window)->border_width;
4970 child_allocation.y = GTK_CONTAINER (window)->border_width;
4971 child_allocation.width =
4972 MAX (1, (gint)allocation->width - child_allocation.x * 2);
4973 child_allocation.height =
4974 MAX (1, (gint)allocation->height - child_allocation.y * 2);
4976 gtk_widget_size_allocate (window->bin.child, &child_allocation);
4979 if (GTK_WIDGET_REALIZED (widget) && window->frame)
4981 gdk_window_resize (window->frame,
4982 allocation->width + window->frame_left + window->frame_right,
4983 allocation->height + window->frame_top + window->frame_bottom);
4988 gtk_window_event (GtkWidget *widget, GdkEvent *event)
4991 gboolean return_val;
4993 window = GTK_WINDOW (widget);
4995 if (window->frame && (event->any.window == window->frame))
4997 if ((event->type != GDK_KEY_PRESS) &&
4998 (event->type != GDK_KEY_RELEASE) &&
4999 (event->type != GDK_FOCUS_CHANGE))
5001 g_signal_stop_emission_by_name (widget, "event");
5003 g_signal_emit (widget, window_signals[FRAME_EVENT], 0, event, &return_val);
5008 g_object_unref (event->any.window);
5009 event->any.window = g_object_ref (widget->window);
5017 gtk_window_frame_event (GtkWindow *window, GdkEvent *event)
5019 GdkEventConfigure *configure_event;
5022 switch (event->type)
5025 configure_event = (GdkEventConfigure *)event;
5027 /* Invalidate the decorations */
5030 rect.width = configure_event->width;
5031 rect.height = configure_event->height;
5033 gdk_window_invalidate_rect (window->frame, &rect, FALSE);
5035 /* Pass on the (modified) configure event */
5036 configure_event->width -= window->frame_left + window->frame_right;
5037 configure_event->height -= window->frame_top + window->frame_bottom;
5038 return gtk_window_configure_event (GTK_WIDGET (window), configure_event);
5047 gtk_window_configure_event (GtkWidget *widget,
5048 GdkEventConfigure *event)
5050 GtkWindow *window = GTK_WINDOW (widget);
5051 gboolean expected_reply = window->configure_request_count > 0;
5053 /* window->configure_request_count incremented for each
5054 * configure request, and decremented to a min of 0 for
5055 * each configure notify.
5057 * All it means is that we know we will get at least
5058 * window->configure_request_count more configure notifies.
5059 * We could get more configure notifies than that; some
5060 * of the configure notifies we get may be unrelated to
5061 * the configure requests. But we will get at least
5062 * window->configure_request_count notifies.
5065 if (window->configure_request_count > 0)
5067 window->configure_request_count -= 1;
5068 gdk_window_thaw_toplevel_updates_libgtk_only (widget->window);
5071 /* As an optimization, we avoid a resize when possible.
5073 * The only times we can avoid a resize are:
5074 * - we know only the position changed, not the size
5075 * - we know we have made more requests and so will get more
5076 * notifies and can wait to resize when we get them
5079 if (!expected_reply &&
5080 (widget->allocation.width == event->width &&
5081 widget->allocation.height == event->height))
5083 gdk_window_configure_finished (widget->window);
5088 * If we do need to resize, we do that by:
5089 * - filling in widget->allocation with the new size
5090 * - setting configure_notify_received to TRUE
5091 * for use in gtk_window_move_resize()
5092 * - queueing a resize, leading to invocation of
5093 * gtk_window_move_resize() in an idle handler
5097 window->configure_notify_received = TRUE;
5099 widget->allocation.width = event->width;
5100 widget->allocation.height = event->height;
5102 _gtk_container_queue_resize (GTK_CONTAINER (widget));
5107 /* the accel_key and accel_mods fields of the key have to be setup
5108 * upon calling this function. it'll then return whether that key
5109 * is at all used as accelerator, and if so will OR in the
5110 * accel_flags member of the key.
5113 _gtk_window_query_nonaccels (GtkWindow *window,
5115 GdkModifierType accel_mods)
5117 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
5119 /* movement keys are considered locked accels */
5122 static const guint bindings[] = {
5123 GDK_space, GDK_KP_Space, GDK_Return, GDK_ISO_Enter, GDK_KP_Enter, GDK_Up, GDK_KP_Up, GDK_Down, GDK_KP_Down,
5124 GDK_Left, GDK_KP_Left, GDK_Right, GDK_KP_Right, GDK_Tab, GDK_KP_Tab, GDK_ISO_Left_Tab,
5128 for (i = 0; i < G_N_ELEMENTS (bindings); i++)
5129 if (bindings[i] == accel_key)
5133 /* mnemonics are considered locked accels */
5134 if (accel_mods == window->mnemonic_modifier)
5136 GtkMnemonicHash *mnemonic_hash = gtk_window_get_mnemonic_hash (window, FALSE);
5137 if (mnemonic_hash && _gtk_mnemonic_hash_lookup (mnemonic_hash, accel_key))
5145 * gtk_window_propagate_key_event:
5146 * @window: a #GtkWindow
5147 * @event: a #GdkEventKey
5149 * Propagate a key press or release event to the focus widget and
5150 * up the focus container chain until a widget handles @event.
5151 * This is normally called by the default ::key_press_event and
5152 * ::key_release_event handlers for toplevel windows,
5153 * however in some cases it may be useful to call this directly when
5154 * overriding the standard key handling for a toplevel window.
5156 * Return value: %TRUE if a widget in the focus chain handled the event.
5161 gtk_window_propagate_key_event (GtkWindow *window,
5164 gboolean handled = FALSE;
5165 GtkWidget *widget, *focus;
5167 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
5169 widget = GTK_WIDGET (window);
5170 focus = window->focus_widget;
5172 g_object_ref (focus);
5175 focus && focus != widget &&
5176 gtk_widget_get_toplevel (focus) == widget)
5180 if (gtk_widget_is_sensitive (focus))
5181 handled = gtk_widget_event (focus, (GdkEvent*) event);
5183 parent = focus->parent;
5185 g_object_ref (parent);
5187 g_object_unref (focus);
5193 g_object_unref (focus);
5199 gtk_window_key_press_event (GtkWidget *widget,
5202 GtkWindow *window = GTK_WINDOW (widget);
5203 gboolean handled = FALSE;
5205 /* handle mnemonics and accelerators */
5207 handled = gtk_window_activate_key (window, event);
5209 /* handle focus widget key events */
5211 handled = gtk_window_propagate_key_event (window, event);
5213 /* Chain up, invokes binding set */
5215 handled = GTK_WIDGET_CLASS (gtk_window_parent_class)->key_press_event (widget, event);
5221 gtk_window_key_release_event (GtkWidget *widget,
5224 GtkWindow *window = GTK_WINDOW (widget);
5225 gboolean handled = FALSE;
5227 /* handle focus widget key events */
5229 handled = gtk_window_propagate_key_event (window, event);
5231 /* Chain up, invokes binding set */
5233 handled = GTK_WIDGET_CLASS (gtk_window_parent_class)->key_release_event (widget, event);
5239 gtk_window_real_activate_default (GtkWindow *window)
5241 gtk_window_activate_default (window);
5245 gtk_window_real_activate_focus (GtkWindow *window)
5247 gtk_window_activate_focus (window);
5251 gtk_window_move_focus (GtkWindow *window,
5252 GtkDirectionType dir)
5254 gtk_widget_child_focus (GTK_WIDGET (window), dir);
5256 if (!GTK_CONTAINER (window)->focus_child)
5257 gtk_window_set_focus (window, NULL);
5261 gtk_window_enter_notify_event (GtkWidget *widget,
5262 GdkEventCrossing *event)
5268 gtk_window_leave_notify_event (GtkWidget *widget,
5269 GdkEventCrossing *event)
5275 do_focus_change (GtkWidget *widget,
5278 GdkEvent *fevent = gdk_event_new (GDK_FOCUS_CHANGE);
5280 g_object_ref (widget);
5283 GTK_WIDGET_SET_FLAGS (widget, GTK_HAS_FOCUS);
5285 GTK_WIDGET_UNSET_FLAGS (widget, GTK_HAS_FOCUS);
5287 fevent->focus_change.type = GDK_FOCUS_CHANGE;
5288 fevent->focus_change.window = widget->window;
5290 g_object_ref (widget->window);
5291 fevent->focus_change.in = in;
5293 gtk_widget_event (widget, fevent);
5295 g_object_notify (G_OBJECT (widget), "has-focus");
5297 g_object_unref (widget);
5298 gdk_event_free (fevent);
5302 gtk_window_focus_in_event (GtkWidget *widget,
5303 GdkEventFocus *event)
5305 GtkWindow *window = GTK_WINDOW (widget);
5307 /* It appears spurious focus in events can occur when
5308 * the window is hidden. So we'll just check to see if
5309 * the window is visible before actually handling the
5312 if (gtk_widget_get_visible (widget))
5314 _gtk_window_set_has_toplevel_focus (window, TRUE);
5315 _gtk_window_set_is_active (window, TRUE);
5322 gtk_window_focus_out_event (GtkWidget *widget,
5323 GdkEventFocus *event)
5325 GtkWindow *window = GTK_WINDOW (widget);
5326 gboolean auto_mnemonics;
5328 _gtk_window_set_has_toplevel_focus (window, FALSE);
5329 _gtk_window_set_is_active (window, FALSE);
5331 /* set the mnemonic-visible property to false */
5332 g_object_get (gtk_widget_get_settings (widget),
5333 "gtk-auto-mnemonics", &auto_mnemonics, NULL);
5335 gtk_window_set_mnemonics_visible (window, FALSE);
5340 static GdkAtom atom_rcfiles = GDK_NONE;
5341 static GdkAtom atom_iconthemes = GDK_NONE;
5344 send_client_message_to_embedded_windows (GtkWidget *widget,
5345 GdkAtom message_type)
5347 GList *embedded_windows;
5349 embedded_windows = g_object_get_qdata (G_OBJECT (widget), quark_gtk_embedded);
5350 if (embedded_windows)
5352 GdkEvent *send_event = gdk_event_new (GDK_CLIENT_EVENT);
5355 for (i = 0; i < 5; i++)
5356 send_event->client.data.l[i] = 0;
5357 send_event->client.data_format = 32;
5358 send_event->client.message_type = message_type;
5360 while (embedded_windows)
5362 GdkNativeWindow xid = GDK_GPOINTER_TO_NATIVE_WINDOW(embedded_windows->data);
5363 gdk_event_send_client_message_for_display (gtk_widget_get_display (widget), send_event, xid);
5364 embedded_windows = embedded_windows->next;
5367 gdk_event_free (send_event);
5372 gtk_window_client_event (GtkWidget *widget,
5373 GdkEventClient *event)
5377 atom_rcfiles = gdk_atom_intern_static_string ("_GTK_READ_RCFILES");
5378 atom_iconthemes = gdk_atom_intern_static_string ("_GTK_LOAD_ICONTHEMES");
5381 if (event->message_type == atom_rcfiles)
5383 send_client_message_to_embedded_windows (widget, atom_rcfiles);
5384 gtk_rc_reparse_all_for_settings (gtk_widget_get_settings (widget), FALSE);
5387 if (event->message_type == atom_iconthemes)
5389 send_client_message_to_embedded_windows (widget, atom_iconthemes);
5390 _gtk_icon_theme_check_reload (gtk_widget_get_display (widget));
5397 gtk_window_check_resize (GtkContainer *container)
5399 if (gtk_widget_get_visible (GTK_WIDGET (container)))
5400 gtk_window_move_resize (GTK_WINDOW (container));
5404 gtk_window_focus (GtkWidget *widget,
5405 GtkDirectionType direction)
5409 GtkContainer *container;
5410 GtkWidget *old_focus_child;
5413 container = GTK_CONTAINER (widget);
5414 window = GTK_WINDOW (widget);
5415 bin = GTK_BIN (widget);
5417 old_focus_child = container->focus_child;
5419 /* We need a special implementation here to deal properly with wrapping
5420 * around in the tab chain without the danger of going into an
5423 if (old_focus_child)
5425 if (gtk_widget_child_focus (old_focus_child, direction))
5429 if (window->focus_widget)
5431 if (direction == GTK_DIR_LEFT ||
5432 direction == GTK_DIR_RIGHT ||
5433 direction == GTK_DIR_UP ||
5434 direction == GTK_DIR_DOWN)
5439 /* Wrapped off the end, clear the focus setting for the toplpevel */
5440 parent = window->focus_widget->parent;
5443 gtk_container_set_focus_child (GTK_CONTAINER (parent), NULL);
5444 parent = GTK_WIDGET (parent)->parent;
5447 gtk_window_set_focus (GTK_WINDOW (container), NULL);
5450 /* Now try to focus the first widget in the window */
5453 if (gtk_widget_child_focus (bin->child, direction))
5461 gtk_window_real_set_focus (GtkWindow *window,
5464 GtkWidget *old_focus = window->focus_widget;
5465 gboolean had_default = FALSE;
5466 gboolean focus_had_default = FALSE;
5467 gboolean old_focus_had_default = FALSE;
5471 g_object_ref (old_focus);
5472 g_object_freeze_notify (G_OBJECT (old_focus));
5473 old_focus_had_default = gtk_widget_has_default (old_focus);
5477 g_object_ref (focus);
5478 g_object_freeze_notify (G_OBJECT (focus));
5479 focus_had_default = gtk_widget_has_default (focus);
5482 if (window->default_widget)
5483 had_default = gtk_widget_has_default (window->default_widget);
5485 if (window->focus_widget)
5487 if (gtk_widget_get_receives_default (window->focus_widget) &&
5488 (window->focus_widget != window->default_widget))
5490 GTK_WIDGET_UNSET_FLAGS (window->focus_widget, GTK_HAS_DEFAULT);
5491 gtk_widget_queue_draw (window->focus_widget);
5493 if (window->default_widget)
5494 GTK_WIDGET_SET_FLAGS (window->default_widget, GTK_HAS_DEFAULT);
5497 window->focus_widget = NULL;
5499 if (window->has_focus)
5500 do_focus_change (old_focus, FALSE);
5502 g_object_notify (G_OBJECT (old_focus), "is-focus");
5505 /* The above notifications may have set a new focus widget,
5506 * if so, we don't want to override it.
5508 if (focus && !window->focus_widget)
5510 window->focus_widget = focus;
5512 if (gtk_widget_get_receives_default (window->focus_widget) &&
5513 (window->focus_widget != window->default_widget))
5515 if (gtk_widget_get_can_default (window->focus_widget))
5516 GTK_WIDGET_SET_FLAGS (window->focus_widget, GTK_HAS_DEFAULT);
5518 if (window->default_widget)
5519 GTK_WIDGET_UNSET_FLAGS (window->default_widget, GTK_HAS_DEFAULT);
5522 if (window->has_focus)
5523 do_focus_change (window->focus_widget, TRUE);
5525 g_object_notify (G_OBJECT (window->focus_widget), "is-focus");
5528 /* If the default widget changed, a redraw will have been queued
5529 * on the old and new default widgets by gtk_window_set_default(), so
5530 * we only have to worry about the case where it didn't change.
5531 * We'll sometimes queue a draw twice on the new widget but that
5534 if (window->default_widget &&
5535 (had_default != gtk_widget_has_default (window->default_widget)))
5536 gtk_widget_queue_draw (window->default_widget);
5540 if (old_focus_had_default != gtk_widget_has_default (old_focus))
5541 gtk_widget_queue_draw (old_focus);
5543 g_object_thaw_notify (G_OBJECT (old_focus));
5544 g_object_unref (old_focus);
5548 if (focus_had_default != gtk_widget_has_default (focus))
5549 gtk_widget_queue_draw (focus);
5551 g_object_thaw_notify (G_OBJECT (focus));
5552 g_object_unref (focus);
5557 * _gtk_window_unset_focus_and_default:
5558 * @window: a #GtkWindow
5559 * @widget: a widget inside of @window
5561 * Checks whether the focus and default widgets of @window are
5562 * @widget or a descendent of @widget, and if so, unset them.
5565 _gtk_window_unset_focus_and_default (GtkWindow *window,
5571 g_object_ref (window);
5572 g_object_ref (widget);
5574 if (GTK_CONTAINER (widget->parent)->focus_child == widget)
5576 child = window->focus_widget;
5578 while (child && child != widget)
5579 child = child->parent;
5581 if (child == widget)
5582 gtk_window_set_focus (GTK_WINDOW (window), NULL);
5585 child = window->default_widget;
5587 while (child && child != widget)
5588 child = child->parent;
5590 if (child == widget)
5591 gtk_window_set_default (window, NULL);
5593 g_object_unref (widget);
5594 g_object_unref (window);
5597 /*********************************
5598 * Functions related to resizing *
5599 *********************************/
5601 /* This function doesn't constrain to geometry hints */
5603 gtk_window_compute_configure_request_size (GtkWindow *window,
5607 GtkRequisition requisition;
5608 GtkWindowGeometryInfo *info;
5612 * - we've done a size request
5615 widget = GTK_WIDGET (window);
5617 info = gtk_window_get_geometry_info (window, FALSE);
5619 if (window->need_default_size)
5621 gtk_widget_get_child_requisition (widget, &requisition);
5623 /* Default to requisition */
5624 *width = requisition.width;
5625 *height = requisition.height;
5627 /* If window is empty so requests 0, default to random nonzero size */
5628 if (*width == 0 && *height == 0)
5634 /* Override requisition with default size */
5638 gint base_width = 0;
5639 gint base_height = 0;
5641 gint min_height = 0;
5643 gint height_inc = 1;
5645 if (info->default_is_geometry &&
5646 (info->default_width > 0 || info->default_height > 0))
5648 GdkGeometry geometry;
5651 gtk_window_compute_hints (window, &geometry, &flags);
5653 if (flags & GDK_HINT_BASE_SIZE)
5655 base_width = geometry.base_width;
5656 base_height = geometry.base_height;
5658 if (flags & GDK_HINT_MIN_SIZE)
5660 min_width = geometry.min_width;
5661 min_height = geometry.min_height;
5663 if (flags & GDK_HINT_RESIZE_INC)
5665 width_inc = geometry.width_inc;
5666 height_inc = geometry.height_inc;
5670 if (info->default_width > 0)
5671 *width = MAX (info->default_width * width_inc + base_width, min_width);
5673 if (info->default_height > 0)
5674 *height = MAX (info->default_height * height_inc + base_height, min_height);
5679 /* Default to keeping current size */
5680 *width = widget->allocation.width;
5681 *height = widget->allocation.height;
5684 /* Override any size with gtk_window_resize() values */
5687 if (info->resize_width > 0)
5688 *width = info->resize_width;
5690 if (info->resize_height > 0)
5691 *height = info->resize_height;
5694 /* Don't ever request zero width or height, its not supported by
5695 gdk. The size allocation code will round it to 1 anyway but if
5696 we do it then the value returned from this function will is
5697 not comparable to the size allocation read from the GtkWindow. */
5698 *width = MAX (*width, 1);
5699 *height = MAX (*height, 1);
5702 static GtkWindowPosition
5703 get_effective_position (GtkWindow *window)
5705 GtkWindowPosition pos = window->position;
5707 if (pos == GTK_WIN_POS_CENTER_ON_PARENT &&
5708 (window->transient_parent == NULL ||
5709 !gtk_widget_get_mapped (GTK_WIDGET (window->transient_parent))))
5710 pos = GTK_WIN_POS_NONE;
5716 get_center_monitor_of_window (GtkWindow *window)
5718 /* We could try to sort out the relative positions of the monitors and
5719 * stuff, or we could just be losers and assume you have a row
5720 * or column of monitors.
5722 return gdk_screen_get_n_monitors (gtk_window_check_screen (window)) / 2;
5726 get_monitor_containing_pointer (GtkWindow *window)
5730 GdkScreen *window_screen;
5731 GdkScreen *pointer_screen;
5733 window_screen = gtk_window_check_screen (window);
5734 gdk_display_get_pointer (gdk_screen_get_display (window_screen),
5738 if (pointer_screen == window_screen)
5739 monitor_num = gdk_screen_get_monitor_at_point (pointer_screen, px, py);
5747 center_window_on_monitor (GtkWindow *window,
5753 GdkRectangle monitor;
5756 monitor_num = get_monitor_containing_pointer (window);
5758 if (monitor_num == -1)
5759 monitor_num = get_center_monitor_of_window (window);
5761 gdk_screen_get_monitor_geometry (gtk_window_check_screen (window),
5762 monitor_num, &monitor);
5764 *x = (monitor.width - w) / 2 + monitor.x;
5765 *y = (monitor.height - h) / 2 + monitor.y;
5767 /* Be sure we aren't off the monitor, ignoring _NET_WM_STRUT
5768 * and WM decorations.
5782 if (extent > clamp_extent)
5784 *base = clamp_base + clamp_extent/2 - extent/2;
5785 else if (*base < clamp_base)
5787 else if (*base + extent > clamp_base + clamp_extent)
5788 *base = clamp_base + clamp_extent - extent;
5792 clamp_window_to_rectangle (gint *x,
5796 const GdkRectangle *rect)
5798 #ifdef DEBUGGING_OUTPUT
5799 g_print ("%s: %+d%+d %dx%d: %+d%+d: %dx%d", G_STRFUNC, rect->x, rect->y, rect->width, rect->height, *x, *y, w, h);
5802 /* If it is too large, center it. If it fits on the monitor but is
5803 * partially outside, move it to the closest edge. Do this
5804 * separately in x and y directions.
5806 clamp (x, w, rect->x, rect->width);
5807 clamp (y, h, rect->y, rect->height);
5808 #ifdef DEBUGGING_OUTPUT
5809 g_print (" ==> %+d%+d: %dx%d\n", *x, *y, w, h);
5815 gtk_window_compute_configure_request (GtkWindow *window,
5816 GdkRectangle *request,
5817 GdkGeometry *geometry,
5820 GdkGeometry new_geometry;
5824 GtkWindowPosition pos;
5825 GtkWidget *parent_widget;
5826 GtkWindowGeometryInfo *info;
5830 widget = GTK_WIDGET (window);
5832 screen = gtk_window_check_screen (window);
5834 gtk_widget_size_request (widget, NULL);
5835 gtk_window_compute_configure_request_size (window, (guint *)&w, (guint *)&h);
5837 gtk_window_compute_hints (window, &new_geometry, &new_flags);
5838 gtk_window_constrain_size (window,
5839 &new_geometry, new_flags,
5843 parent_widget = (GtkWidget*) window->transient_parent;
5845 pos = get_effective_position (window);
5846 info = gtk_window_get_geometry_info (window, FALSE);
5848 /* by default, don't change position requested */
5851 x = info->last.configure_request.x;
5852 y = info->last.configure_request.y;
5861 if (window->need_default_position)
5864 /* FIXME this all interrelates with window gravity.
5865 * For most of them I think we want to set GRAVITY_CENTER.
5867 * Not sure how to go about that.
5872 /* here we are only handling CENTER_ALWAYS
5873 * as it relates to default positioning,
5874 * where it's equivalent to simply CENTER
5876 case GTK_WIN_POS_CENTER_ALWAYS:
5877 case GTK_WIN_POS_CENTER:
5878 center_window_on_monitor (window, w, h, &x, &y);
5881 case GTK_WIN_POS_CENTER_ON_PARENT:
5884 GdkRectangle monitor;
5887 g_assert (gtk_widget_get_mapped (parent_widget)); /* established earlier */
5889 if (parent_widget->window != NULL)
5890 monitor_num = gdk_screen_get_monitor_at_window (screen,
5891 parent_widget->window);
5895 gdk_window_get_origin (parent_widget->window,
5898 x = ox + (parent_widget->allocation.width - w) / 2;
5899 y = oy + (parent_widget->allocation.height - h) / 2;
5901 /* Clamp onto current monitor, ignoring _NET_WM_STRUT and
5902 * WM decorations. If parent wasn't on a monitor, just
5905 if (monitor_num >= 0)
5907 gdk_screen_get_monitor_geometry (screen, monitor_num, &monitor);
5908 clamp_window_to_rectangle (&x, &y, w, h, &monitor);
5913 case GTK_WIN_POS_MOUSE:
5915 gint screen_width = gdk_screen_get_width (screen);
5916 gint screen_height = gdk_screen_get_height (screen);
5918 GdkRectangle monitor;
5919 GdkScreen *pointer_screen;
5922 gdk_display_get_pointer (gdk_screen_get_display (screen),
5926 if (pointer_screen == screen)
5927 monitor_num = gdk_screen_get_monitor_at_point (screen, px, py);
5933 x = CLAMP (x, 0, screen_width - w);
5934 y = CLAMP (y, 0, screen_height - h);
5936 /* Clamp onto current monitor, ignoring _NET_WM_STRUT and
5937 * WM decorations. Don't try to figure out what's going
5938 * on if the mouse wasn't inside a monitor.
5940 if (monitor_num >= 0)
5942 gdk_screen_get_monitor_geometry (screen, monitor_num, &monitor);
5943 clamp_window_to_rectangle (&x, &y, w, h, &monitor);
5951 } /* if (window->need_default_position) */
5953 if (window->need_default_position && info &&
5954 info->initial_pos_set)
5956 x = info->initial_x;
5957 y = info->initial_y;
5958 gtk_window_constrain_position (window, w, h, &x, &y);
5964 request->height = h;
5967 *geometry = new_geometry;
5973 gtk_window_constrain_position (GtkWindow *window,
5979 /* See long comments in gtk_window_move_resize()
5980 * on when it's safe to call this function.
5982 if (window->position == GTK_WIN_POS_CENTER_ALWAYS)
5984 gint center_x, center_y;
5986 center_window_on_monitor (window, new_width, new_height, ¢er_x, ¢er_y);
5994 gtk_window_move_resize (GtkWindow *window)
5998 * First we determine whether any information has changed that would
5999 * cause us to revise our last configure request. If we would send
6000 * a different configure request from last time, then
6001 * configure_request_size_changed = TRUE or
6002 * configure_request_pos_changed = TRUE. configure_request_size_changed
6003 * may be true due to new hints, a gtk_window_resize(), or whatever.
6004 * configure_request_pos_changed may be true due to gtk_window_set_position()
6005 * or gtk_window_move().
6007 * If the configure request has changed, we send off a new one. To
6008 * ensure GTK+ invariants are maintained (resize queue does what it
6009 * should), we go ahead and size_allocate the requested size in this
6012 * If the configure request has not changed, we don't ever resend
6013 * it, because it could mean fighting the user or window manager.
6016 * To prepare the configure request, we come up with a base size/pos:
6017 * - the one from gtk_window_move()/gtk_window_resize()
6018 * - else default_width, default_height if we haven't ever
6020 * - else the size request if we haven't ever been mapped,
6021 * as a substitute default size
6022 * - else the current size of the window, as received from
6023 * configure notifies (i.e. the current allocation)
6025 * If GTK_WIN_POS_CENTER_ALWAYS is active, we constrain
6026 * the position request to be centered.
6029 GtkContainer *container;
6030 GtkWindowGeometryInfo *info;
6031 GdkGeometry new_geometry;
6033 GdkRectangle new_request;
6034 gboolean configure_request_size_changed;
6035 gboolean configure_request_pos_changed;
6036 gboolean hints_changed; /* do we need to send these again */
6037 GtkWindowLastGeometryInfo saved_last_info;
6039 widget = GTK_WIDGET (window);
6040 container = GTK_CONTAINER (widget);
6041 info = gtk_window_get_geometry_info (window, TRUE);
6043 configure_request_size_changed = FALSE;
6044 configure_request_pos_changed = FALSE;
6046 gtk_window_compute_configure_request (window, &new_request,
6047 &new_geometry, &new_flags);
6049 /* This check implies the invariant that we never set info->last
6050 * without setting the hints and sending off a configure request.
6052 * If we change info->last without sending the request, we may
6055 if (info->last.configure_request.x != new_request.x ||
6056 info->last.configure_request.y != new_request.y)
6057 configure_request_pos_changed = TRUE;
6059 if ((info->last.configure_request.width != new_request.width ||
6060 info->last.configure_request.height != new_request.height))
6061 configure_request_size_changed = TRUE;
6063 hints_changed = FALSE;
6065 if (!gtk_window_compare_hints (&info->last.geometry, info->last.flags,
6066 &new_geometry, new_flags))
6068 hints_changed = TRUE;
6071 /* Position Constraints
6072 * ====================
6074 * POS_CENTER_ALWAYS is conceptually a constraint rather than
6075 * a default. The other POS_ values are used only when the
6076 * window is shown, not after that.
6078 * However, we can't implement a position constraint as
6079 * "anytime the window size changes, center the window"
6080 * because this may well end up fighting the WM or user. In
6081 * fact it gets in an infinite loop with at least one WM.
6083 * Basically, applications are in no way in a position to
6084 * constrain the position of a window, with one exception:
6085 * override redirect windows. (Really the intended purpose
6086 * of CENTER_ALWAYS anyhow, I would think.)
6088 * So the way we implement this "constraint" is to say that when WE
6089 * cause a move or resize, i.e. we make a configure request changing
6090 * window size, we recompute the CENTER_ALWAYS position to reflect
6091 * the new window size, and include it in our request. Also, if we
6092 * just turned on CENTER_ALWAYS we snap to center with a new
6093 * request. Otherwise, if we are just NOTIFIED of a move or resize
6094 * done by someone else e.g. the window manager, we do NOT send a
6095 * new configure request.
6097 * For override redirect windows, this works fine; all window
6098 * sizes are from our configure requests. For managed windows,
6099 * it is at least semi-sane, though who knows what the
6100 * app author is thinking.
6103 /* This condition should be kept in sync with the condition later on
6104 * that determines whether we send a configure request. i.e. we
6105 * should do this position constraining anytime we were going to
6106 * send a configure request anyhow, plus when constraints have
6109 if (configure_request_pos_changed ||
6110 configure_request_size_changed ||
6112 info->position_constraints_changed)
6114 /* We request the constrained position if:
6115 * - we were changing position, and need to clamp
6116 * the change to the constraint
6117 * - we're changing the size anyway
6118 * - set_position() was called to toggle CENTER_ALWAYS on
6121 gtk_window_constrain_position (window,
6127 /* Update whether we need to request a move */
6128 if (info->last.configure_request.x != new_request.x ||
6129 info->last.configure_request.y != new_request.y)
6130 configure_request_pos_changed = TRUE;
6132 configure_request_pos_changed = FALSE;
6136 if (window->type == GTK_WINDOW_TOPLEVEL)
6138 int notify_x, notify_y;
6140 /* this is the position from the last configure notify */
6141 gdk_window_get_position (widget->window, ¬ify_x, ¬ify_y);
6143 g_message ("--- %s ---\n"
6144 "last : %d,%d\t%d x %d\n"
6145 "this : %d,%d\t%d x %d\n"
6146 "alloc : %d,%d\t%d x %d\n"
6148 "resize: \t%d x %d\n"
6149 "size_changed: %d pos_changed: %d hints_changed: %d\n"
6150 "configure_notify_received: %d\n"
6151 "configure_request_count: %d\n"
6152 "position_constraints_changed: %d\n",
6153 window->title ? window->title : "(no title)",
6154 info->last.configure_request.x,
6155 info->last.configure_request.y,
6156 info->last.configure_request.width,
6157 info->last.configure_request.height,
6163 widget->allocation.width,
6164 widget->allocation.height,
6165 widget->requisition.width,
6166 widget->requisition.height,
6168 info->resize_height,
6169 configure_request_pos_changed,
6170 configure_request_size_changed,
6172 window->configure_notify_received,
6173 window->configure_request_count,
6174 info->position_constraints_changed);
6178 saved_last_info = info->last;
6179 info->last.geometry = new_geometry;
6180 info->last.flags = new_flags;
6181 info->last.configure_request = new_request;
6183 /* need to set PPosition so the WM will look at our position,
6184 * but we don't want to count PPosition coming and going as a hints
6185 * change for future iterations. So we saved info->last prior to
6189 /* Also, if the initial position was explicitly set, then we always
6190 * toggle on PPosition. This makes gtk_window_move(window, 0, 0)
6194 /* Also, we toggle on PPosition if GTK_WIN_POS_ is in use and
6195 * this is an initial map
6198 if ((configure_request_pos_changed ||
6199 info->initial_pos_set ||
6200 (window->need_default_position &&
6201 get_effective_position (window) != GTK_WIN_POS_NONE)) &&
6202 (new_flags & GDK_HINT_POS) == 0)
6204 new_flags |= GDK_HINT_POS;
6205 hints_changed = TRUE;
6208 /* Set hints if necessary
6211 gdk_window_set_geometry_hints (widget->window,
6215 /* handle resizing/moving and widget tree allocation
6217 if (window->configure_notify_received)
6219 GtkAllocation allocation;
6221 /* If we have received a configure event since
6222 * the last time in this function, we need to
6223 * accept our new size and size_allocate child widgets.
6224 * (see gtk_window_configure_event() for more details).
6226 * 1 or more configure notifies may have been received.
6227 * Also, configure_notify_received will only be TRUE
6228 * if all expected configure notifies have been received
6229 * (one per configure request), as an optimization.
6232 window->configure_notify_received = FALSE;
6234 /* gtk_window_configure_event() filled in widget->allocation */
6235 allocation = widget->allocation;
6236 gtk_widget_size_allocate (widget, &allocation);
6238 gdk_window_process_updates (widget->window, TRUE);
6240 gdk_window_configure_finished (widget->window);
6242 /* If the configure request changed, it means that
6244 * 1) coincidentally changed hints or widget properties
6245 * impacting the configure request before getting
6246 * a configure notify, or
6247 * 2) some broken widget is changing its size request
6248 * during size allocation, resulting in
6249 * a false appearance of changed configure request.
6251 * For 1), we could just go ahead and ask for the
6252 * new size right now, but doing that for 2)
6253 * might well be fighting the user (and can even
6254 * trigger a loop). Since we really don't want to
6255 * do that, we requeue a resize in hopes that
6256 * by the time it gets handled, the child has seen
6257 * the light and is willing to go along with the
6258 * new size. (this happens for the zvt widget, since
6259 * the size_allocate() above will have stored the
6260 * requisition corresponding to the new size in the
6263 * This doesn't buy us anything for 1), but it shouldn't
6264 * hurt us too badly, since it is what would have
6265 * happened if we had gotten the configure event before
6266 * the new size had been set.
6269 if (configure_request_size_changed ||
6270 configure_request_pos_changed)
6272 /* Don't change the recorded last info after all, because we
6273 * haven't actually updated to the new info yet - we decided
6274 * to postpone our configure request until later.
6276 info->last = saved_last_info;
6278 gtk_widget_queue_resize_no_redraw (widget); /* migth recurse for GTK_RESIZE_IMMEDIATE */
6281 return; /* Bail out, we didn't really process the move/resize */
6283 else if ((configure_request_size_changed || hints_changed) &&
6284 (widget->allocation.width != new_request.width ||
6285 widget->allocation.height != new_request.height))
6288 /* We are in one of the following situations:
6289 * A. configure_request_size_changed
6290 * our requisition has changed and we need a different window size,
6291 * so we request it from the window manager.
6292 * B. !configure_request_size_changed && hints_changed
6293 * the window manager rejects our size, but we have just changed the
6294 * window manager hints, so there's a chance our request will
6295 * be honoured this time, so we try again.
6297 * However, if the new requisition is the same as the current allocation,
6298 * we don't request it again, since we won't get a ConfigureNotify back from
6299 * the window manager unless it decides to change our requisition. If
6300 * we don't get the ConfigureNotify back, the resize queue will never be run.
6303 /* Now send the configure request */
6304 if (configure_request_pos_changed)
6308 gdk_window_move_resize (window->frame,
6309 new_request.x - window->frame_left,
6310 new_request.y - window->frame_top,
6311 new_request.width + window->frame_left + window->frame_right,
6312 new_request.height + window->frame_top + window->frame_bottom);
6313 gdk_window_resize (widget->window,
6314 new_request.width, new_request.height);
6317 gdk_window_move_resize (widget->window,
6318 new_request.x, new_request.y,
6319 new_request.width, new_request.height);
6321 else /* only size changed */
6324 gdk_window_resize (window->frame,
6325 new_request.width + window->frame_left + window->frame_right,
6326 new_request.height + window->frame_top + window->frame_bottom);
6327 gdk_window_resize (widget->window,
6328 new_request.width, new_request.height);
6331 if (window->type == GTK_WINDOW_POPUP)
6333 GtkAllocation allocation;
6335 /* Directly size allocate for override redirect (popup) windows. */
6338 allocation.width = new_request.width;
6339 allocation.height = new_request.height;
6341 gtk_widget_size_allocate (widget, &allocation);
6343 gdk_window_process_updates (widget->window, TRUE);
6345 if (container->resize_mode == GTK_RESIZE_QUEUE)
6346 gtk_widget_queue_draw (widget);
6350 /* Increment the number of have-not-yet-received-notify requests */
6351 window->configure_request_count += 1;
6352 gdk_window_freeze_toplevel_updates_libgtk_only (widget->window);
6354 /* for GTK_RESIZE_QUEUE toplevels, we are now awaiting a new
6355 * configure event in response to our resizing request.
6356 * the configure event will cause a new resize with
6357 * ->configure_notify_received=TRUE.
6358 * until then, we want to
6359 * - discard expose events
6360 * - coalesce resizes for our children
6361 * - defer any window resizes until the configure event arrived
6362 * to achieve this, we queue a resize for the window, but remove its
6363 * resizing handler, so resizing will not be handled from the next
6364 * idle handler but when the configure event arrives.
6366 * FIXME: we should also dequeue the pending redraws here, since
6367 * we handle those ourselves upon ->configure_notify_received==TRUE.
6369 if (container->resize_mode == GTK_RESIZE_QUEUE)
6371 gtk_widget_queue_resize_no_redraw (widget);
6372 _gtk_container_dequeue_resize_handler (container);
6378 /* Handle any position changes.
6380 if (configure_request_pos_changed)
6384 gdk_window_move (window->frame,
6385 new_request.x - window->frame_left,
6386 new_request.y - window->frame_top);
6389 gdk_window_move (widget->window,
6390 new_request.x, new_request.y);
6393 /* And run the resize queue.
6395 gtk_container_resize_children (container);
6398 /* We have now processed a move/resize since the last position
6399 * constraint change, setting of the initial position, or resize.
6400 * (Not resetting these flags here can lead to infinite loops for
6401 * GTK_RESIZE_IMMEDIATE containers)
6403 info->position_constraints_changed = FALSE;
6404 info->initial_pos_set = FALSE;
6405 info->resize_width = -1;
6406 info->resize_height = -1;
6409 /* Compare two sets of Geometry hints for equality.
6412 gtk_window_compare_hints (GdkGeometry *geometry_a,
6414 GdkGeometry *geometry_b,
6417 if (flags_a != flags_b)
6420 if ((flags_a & GDK_HINT_MIN_SIZE) &&
6421 (geometry_a->min_width != geometry_b->min_width ||
6422 geometry_a->min_height != geometry_b->min_height))
6425 if ((flags_a & GDK_HINT_MAX_SIZE) &&
6426 (geometry_a->max_width != geometry_b->max_width ||
6427 geometry_a->max_height != geometry_b->max_height))
6430 if ((flags_a & GDK_HINT_BASE_SIZE) &&
6431 (geometry_a->base_width != geometry_b->base_width ||
6432 geometry_a->base_height != geometry_b->base_height))
6435 if ((flags_a & GDK_HINT_ASPECT) &&
6436 (geometry_a->min_aspect != geometry_b->min_aspect ||
6437 geometry_a->max_aspect != geometry_b->max_aspect))
6440 if ((flags_a & GDK_HINT_RESIZE_INC) &&
6441 (geometry_a->width_inc != geometry_b->width_inc ||
6442 geometry_a->height_inc != geometry_b->height_inc))
6445 if ((flags_a & GDK_HINT_WIN_GRAVITY) &&
6446 geometry_a->win_gravity != geometry_b->win_gravity)
6453 _gtk_window_constrain_size (GtkWindow *window,
6459 GtkWindowGeometryInfo *info;
6461 g_return_if_fail (GTK_IS_WINDOW (window));
6463 info = window->geometry_info;
6466 GdkWindowHints flags = info->last.flags;
6467 GdkGeometry *geometry = &info->last.geometry;
6469 gtk_window_constrain_size (window,
6480 gtk_window_constrain_size (GtkWindow *window,
6481 GdkGeometry *geometry,
6488 gdk_window_constrain_size (geometry, flags, width, height,
6489 new_width, new_height);
6492 /* Compute the set of geometry hints and flags for a window
6493 * based on the application set geometry, and requisiition
6494 * of the window. gtk_widget_size_request() must have been
6498 gtk_window_compute_hints (GtkWindow *window,
6499 GdkGeometry *new_geometry,
6503 gint extra_width = 0;
6504 gint extra_height = 0;
6505 GtkWindowGeometryInfo *geometry_info;
6506 GtkRequisition requisition;
6508 widget = GTK_WIDGET (window);
6510 gtk_widget_get_child_requisition (widget, &requisition);
6511 geometry_info = gtk_window_get_geometry_info (GTK_WINDOW (widget), FALSE);
6515 *new_flags = geometry_info->mask;
6516 *new_geometry = geometry_info->geometry;
6523 if (geometry_info && geometry_info->widget)
6525 GtkRequisition child_requisition;
6527 /* FIXME: This really isn't right. It gets the min size wrong and forces
6528 * callers to do horrible hacks like set a huge usize on the child requisition
6529 * to get the base size right. We really want to find the answers to:
6531 * - If the geometry widget was infinitely big, how much extra space
6532 * would be needed for the stuff around it.
6534 * - If the geometry widget was infinitely small, how big would the
6535 * window still have to be.
6537 * Finding these answers would be a bit of a mess here. (Bug #68668)
6539 gtk_widget_get_child_requisition (geometry_info->widget, &child_requisition);
6541 extra_width = widget->requisition.width - child_requisition.width;
6542 extra_height = widget->requisition.height - child_requisition.height;
6545 /* We don't want to set GDK_HINT_POS in here, we just set it
6546 * in gtk_window_move_resize() when we want the position
6550 if (*new_flags & GDK_HINT_BASE_SIZE)
6552 new_geometry->base_width += extra_width;
6553 new_geometry->base_height += extra_height;
6555 else if (!(*new_flags & GDK_HINT_MIN_SIZE) &&
6556 (*new_flags & GDK_HINT_RESIZE_INC) &&
6557 ((extra_width != 0) || (extra_height != 0)))
6559 *new_flags |= GDK_HINT_BASE_SIZE;
6561 new_geometry->base_width = extra_width;
6562 new_geometry->base_height = extra_height;
6565 if (*new_flags & GDK_HINT_MIN_SIZE)
6567 if (new_geometry->min_width < 0)
6568 new_geometry->min_width = requisition.width;
6570 new_geometry->min_width += extra_width;
6572 if (new_geometry->min_height < 0)
6573 new_geometry->min_height = requisition.height;
6575 new_geometry->min_height += extra_height;
6577 else if (!window->allow_shrink)
6579 *new_flags |= GDK_HINT_MIN_SIZE;
6581 new_geometry->min_width = requisition.width;
6582 new_geometry->min_height = requisition.height;
6585 if (*new_flags & GDK_HINT_MAX_SIZE)
6587 if (new_geometry->max_width < 0)
6588 new_geometry->max_width = requisition.width;
6590 new_geometry->max_width += extra_width;
6592 if (new_geometry->max_height < 0)
6593 new_geometry->max_height = requisition.height;
6595 new_geometry->max_height += extra_height;
6597 else if (!window->allow_grow)
6599 *new_flags |= GDK_HINT_MAX_SIZE;
6601 new_geometry->max_width = requisition.width;
6602 new_geometry->max_height = requisition.height;
6605 *new_flags |= GDK_HINT_WIN_GRAVITY;
6606 new_geometry->win_gravity = window->gravity;
6609 /***********************
6610 * Redrawing functions *
6611 ***********************/
6614 gtk_window_paint (GtkWidget *widget,
6617 gtk_paint_flat_box (widget->style, widget->window, GTK_STATE_NORMAL,
6618 GTK_SHADOW_NONE, area, widget, "base", 0, 0, -1, -1);
6622 gtk_window_expose (GtkWidget *widget,
6623 GdkEventExpose *event)
6625 if (!gtk_widget_get_app_paintable (widget))
6626 gtk_window_paint (widget, &event->area);
6628 if (GTK_WIDGET_CLASS (gtk_window_parent_class)->expose_event)
6629 return GTK_WIDGET_CLASS (gtk_window_parent_class)->expose_event (widget, event);
6635 * gtk_window_set_has_frame:
6636 * @window: a #GtkWindow
6637 * @setting: a boolean
6639 * (Note: this is a special-purpose function for the framebuffer port,
6640 * that causes GTK+ to draw its own window border. For most applications,
6641 * you want gtk_window_set_decorated() instead, which tells the window
6642 * manager whether to draw the window border.)
6644 * If this function is called on a window with setting of %TRUE, before
6645 * it is realized or showed, it will have a "frame" window around
6646 * @window->window, accessible in @window->frame. Using the signal
6647 * frame_event you can receive all events targeted at the frame.
6649 * This function is used by the linux-fb port to implement managed
6650 * windows, but it could conceivably be used by X-programs that
6651 * want to do their own window decorations.
6655 gtk_window_set_has_frame (GtkWindow *window,
6658 g_return_if_fail (GTK_IS_WINDOW (window));
6659 g_return_if_fail (!GTK_WIDGET_REALIZED (window));
6661 window->has_frame = setting != FALSE;
6665 * gtk_window_get_has_frame:
6666 * @window: a #GtkWindow
6668 * Accessor for whether the window has a frame window exterior to
6669 * @window->window. Gets the value set by gtk_window_set_has_frame ().
6671 * Return value: %TRUE if a frame has been added to the window
6672 * via gtk_window_set_has_frame().
6675 gtk_window_get_has_frame (GtkWindow *window)
6677 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
6679 return window->has_frame;
6683 * gtk_window_set_frame_dimensions:
6684 * @window: a #GtkWindow that has a frame
6685 * @left: The width of the left border
6686 * @top: The height of the top border
6687 * @right: The width of the right border
6688 * @bottom: The height of the bottom border
6690 * (Note: this is a special-purpose function intended for the framebuffer
6691 * port; see gtk_window_set_has_frame(). It will have no effect on the
6692 * window border drawn by the window manager, which is the normal
6693 * case when using the X Window system.)
6695 * For windows with frames (see gtk_window_set_has_frame()) this function
6696 * can be used to change the size of the frame border.
6699 gtk_window_set_frame_dimensions (GtkWindow *window,
6707 g_return_if_fail (GTK_IS_WINDOW (window));
6709 widget = GTK_WIDGET (window);
6711 if (window->frame_left == left &&
6712 window->frame_top == top &&
6713 window->frame_right == right &&
6714 window->frame_bottom == bottom)
6717 window->frame_left = left;
6718 window->frame_top = top;
6719 window->frame_right = right;
6720 window->frame_bottom = bottom;
6722 if (GTK_WIDGET_REALIZED (widget) && window->frame)
6724 gint width = widget->allocation.width + left + right;
6725 gint height = widget->allocation.height + top + bottom;
6726 gdk_window_resize (window->frame, width, height);
6727 gtk_decorated_window_move_resize_window (window,
6729 widget->allocation.width,
6730 widget->allocation.height);
6735 * gtk_window_present:
6736 * @window: a #GtkWindow
6738 * Presents a window to the user. This may mean raising the window
6739 * in the stacking order, deiconifying it, moving it to the current
6740 * desktop, and/or giving it the keyboard focus, possibly dependent
6741 * on the user's platform, window manager, and preferences.
6743 * If @window is hidden, this function calls gtk_widget_show()
6746 * This function should be used when the user tries to open a window
6747 * that's already open. Say for example the preferences dialog is
6748 * currently open, and the user chooses Preferences from the menu
6749 * a second time; use gtk_window_present() to move the already-open dialog
6750 * where the user can see it.
6752 * If you are calling this function in response to a user interaction,
6753 * it is preferable to use gtk_window_present_with_time().
6757 gtk_window_present (GtkWindow *window)
6759 gtk_window_present_with_time (window, GDK_CURRENT_TIME);
6763 * gtk_window_present_with_time:
6764 * @window: a #GtkWindow
6765 * @timestamp: the timestamp of the user interaction (typically a
6766 * button or key press event) which triggered this call
6768 * Presents a window to the user in response to a user interaction.
6769 * If you need to present a window without a timestamp, use
6770 * gtk_window_present(). See gtk_window_present() for details.
6775 gtk_window_present_with_time (GtkWindow *window,
6780 g_return_if_fail (GTK_IS_WINDOW (window));
6782 widget = GTK_WIDGET (window);
6784 if (gtk_widget_get_visible (widget))
6786 g_assert (widget->window != NULL);
6788 gdk_window_show (widget->window);
6790 /* Translate a timestamp of GDK_CURRENT_TIME appropriately */
6791 if (timestamp == GDK_CURRENT_TIME)
6793 #ifdef GDK_WINDOWING_X11
6794 GdkDisplay *display;
6796 display = gtk_widget_get_display (GTK_WIDGET (window));
6797 timestamp = gdk_x11_display_get_user_time (display);
6799 timestamp = gtk_get_current_event_time ();
6803 gdk_window_focus (widget->window, timestamp);
6807 gtk_widget_show (widget);
6812 * gtk_window_iconify:
6813 * @window: a #GtkWindow
6815 * Asks to iconify (i.e. minimize) the specified @window. Note that
6816 * you shouldn't assume the window is definitely iconified afterward,
6817 * because other entities (e.g. the user or <link
6818 * linkend="gtk-X11-arch">window manager</link>) could deiconify it
6819 * again, or there may not be a window manager in which case
6820 * iconification isn't possible, etc. But normally the window will end
6821 * up iconified. Just don't write code that crashes if not.
6823 * It's permitted to call this function before showing a window,
6824 * in which case the window will be iconified before it ever appears
6827 * You can track iconification via the "window-state-event" signal
6832 gtk_window_iconify (GtkWindow *window)
6835 GdkWindow *toplevel;
6837 g_return_if_fail (GTK_IS_WINDOW (window));
6839 widget = GTK_WIDGET (window);
6841 window->iconify_initially = TRUE;
6844 toplevel = window->frame;
6846 toplevel = widget->window;
6848 if (toplevel != NULL)
6849 gdk_window_iconify (toplevel);
6853 * gtk_window_deiconify:
6854 * @window: a #GtkWindow
6856 * Asks to deiconify (i.e. unminimize) the specified @window. Note
6857 * that you shouldn't assume the window is definitely deiconified
6858 * afterward, because other entities (e.g. the user or <link
6859 * linkend="gtk-X11-arch">window manager</link>) could iconify it
6860 * again before your code which assumes deiconification gets to run.
6862 * You can track iconification via the "window-state-event" signal
6866 gtk_window_deiconify (GtkWindow *window)
6869 GdkWindow *toplevel;
6871 g_return_if_fail (GTK_IS_WINDOW (window));
6873 widget = GTK_WIDGET (window);
6875 window->iconify_initially = FALSE;
6878 toplevel = window->frame;
6880 toplevel = widget->window;
6882 if (toplevel != NULL)
6883 gdk_window_deiconify (toplevel);
6888 * @window: a #GtkWindow
6890 * Asks to stick @window, which means that it will appear on all user
6891 * desktops. Note that you shouldn't assume the window is definitely
6892 * stuck afterward, because other entities (e.g. the user or <link
6893 * linkend="gtk-X11-arch">window manager</link>) could unstick it
6894 * again, and some window managers do not support sticking
6895 * windows. But normally the window will end up stuck. Just don't
6896 * write code that crashes if not.
6898 * It's permitted to call this function before showing a window.
6900 * You can track stickiness via the "window-state-event" signal
6905 gtk_window_stick (GtkWindow *window)
6908 GdkWindow *toplevel;
6910 g_return_if_fail (GTK_IS_WINDOW (window));
6912 widget = GTK_WIDGET (window);
6914 window->stick_initially = TRUE;
6917 toplevel = window->frame;
6919 toplevel = widget->window;
6921 if (toplevel != NULL)
6922 gdk_window_stick (toplevel);
6926 * gtk_window_unstick:
6927 * @window: a #GtkWindow
6929 * Asks to unstick @window, which means that it will appear on only
6930 * one of the user's desktops. Note that you shouldn't assume the
6931 * window is definitely unstuck afterward, because other entities
6932 * (e.g. the user or <link linkend="gtk-X11-arch">window
6933 * manager</link>) could stick it again. But normally the window will
6934 * end up stuck. Just don't write code that crashes if not.
6936 * You can track stickiness via the "window-state-event" signal
6941 gtk_window_unstick (GtkWindow *window)
6944 GdkWindow *toplevel;
6946 g_return_if_fail (GTK_IS_WINDOW (window));
6948 widget = GTK_WIDGET (window);
6950 window->stick_initially = FALSE;
6953 toplevel = window->frame;
6955 toplevel = widget->window;
6957 if (toplevel != NULL)
6958 gdk_window_unstick (toplevel);
6962 * gtk_window_maximize:
6963 * @window: a #GtkWindow
6965 * Asks to maximize @window, so that it becomes full-screen. Note that
6966 * you shouldn't assume the window is definitely maximized afterward,
6967 * because other entities (e.g. the user or <link
6968 * linkend="gtk-X11-arch">window manager</link>) could unmaximize it
6969 * again, and not all window managers support maximization. But
6970 * normally the window will end up maximized. Just don't write code
6971 * that crashes if not.
6973 * It's permitted to call this function before showing a window,
6974 * in which case the window will be maximized when it appears onscreen
6977 * You can track maximization via the "window-state-event" signal
6982 gtk_window_maximize (GtkWindow *window)
6985 GdkWindow *toplevel;
6987 g_return_if_fail (GTK_IS_WINDOW (window));
6989 widget = GTK_WIDGET (window);
6991 window->maximize_initially = TRUE;
6994 toplevel = window->frame;
6996 toplevel = widget->window;
6998 if (toplevel != NULL)
6999 gdk_window_maximize (toplevel);
7003 * gtk_window_unmaximize:
7004 * @window: a #GtkWindow
7006 * Asks to unmaximize @window. Note that you shouldn't assume the
7007 * window is definitely unmaximized afterward, because other entities
7008 * (e.g. the user or <link linkend="gtk-X11-arch">window
7009 * manager</link>) could maximize it again, and not all window
7010 * managers honor requests to unmaximize. But normally the window will
7011 * end up unmaximized. Just don't write code that crashes if not.
7013 * You can track maximization via the "window-state-event" signal
7018 gtk_window_unmaximize (GtkWindow *window)
7021 GdkWindow *toplevel;
7023 g_return_if_fail (GTK_IS_WINDOW (window));
7025 widget = GTK_WIDGET (window);
7027 window->maximize_initially = FALSE;
7030 toplevel = window->frame;
7032 toplevel = widget->window;
7034 if (toplevel != NULL)
7035 gdk_window_unmaximize (toplevel);
7039 * gtk_window_fullscreen:
7040 * @window: a #GtkWindow
7042 * Asks to place @window in the fullscreen state. Note that you
7043 * shouldn't assume the window is definitely full screen afterward,
7044 * because other entities (e.g. the user or <link
7045 * linkend="gtk-X11-arch">window manager</link>) could unfullscreen it
7046 * again, and not all window managers honor requests to fullscreen
7047 * windows. But normally the window will end up fullscreen. Just
7048 * don't write code that crashes if not.
7050 * You can track the fullscreen state via the "window-state-event" signal
7056 gtk_window_fullscreen (GtkWindow *window)
7059 GdkWindow *toplevel;
7060 GtkWindowPrivate *priv;
7062 g_return_if_fail (GTK_IS_WINDOW (window));
7064 widget = GTK_WIDGET (window);
7065 priv = GTK_WINDOW_GET_PRIVATE (window);
7067 priv->fullscreen_initially = TRUE;
7070 toplevel = window->frame;
7072 toplevel = widget->window;
7074 if (toplevel != NULL)
7075 gdk_window_fullscreen (toplevel);
7079 * gtk_window_unfullscreen:
7080 * @window: a #GtkWindow
7082 * Asks to toggle off the fullscreen state for @window. Note that you
7083 * shouldn't assume the window is definitely not full screen
7084 * afterward, because other entities (e.g. the user or <link
7085 * linkend="gtk-X11-arch">window manager</link>) could fullscreen it
7086 * again, and not all window managers honor requests to unfullscreen
7087 * windows. But normally the window will end up restored to its normal
7088 * state. Just don't write code that crashes if not.
7090 * You can track the fullscreen state via the "window-state-event" signal
7096 gtk_window_unfullscreen (GtkWindow *window)
7099 GdkWindow *toplevel;
7100 GtkWindowPrivate *priv;
7102 g_return_if_fail (GTK_IS_WINDOW (window));
7104 widget = GTK_WIDGET (window);
7105 priv = GTK_WINDOW_GET_PRIVATE (window);
7107 priv->fullscreen_initially = FALSE;
7110 toplevel = window->frame;
7112 toplevel = widget->window;
7114 if (toplevel != NULL)
7115 gdk_window_unfullscreen (toplevel);
7119 * gtk_window_set_keep_above:
7120 * @window: a #GtkWindow
7121 * @setting: whether to keep @window above other windows
7123 * Asks to keep @window above, so that it stays on top. Note that
7124 * you shouldn't assume the window is definitely above afterward,
7125 * because other entities (e.g. the user or <link
7126 * linkend="gtk-X11-arch">window manager</link>) could not keep it above,
7127 * and not all window managers support keeping windows above. But
7128 * normally the window will end kept above. Just don't write code
7129 * that crashes if not.
7131 * It's permitted to call this function before showing a window,
7132 * in which case the window will be kept above when it appears onscreen
7135 * You can track the above state via the "window-state-event" signal
7138 * Note that, according to the <ulink
7139 * url="http://www.freedesktop.org/Standards/wm-spec">Extended Window
7140 * Manager Hints</ulink> specification, the above state is mainly meant
7141 * for user preferences and should not be used by applications e.g. for
7142 * drawing attention to their dialogs.
7147 gtk_window_set_keep_above (GtkWindow *window,
7151 GtkWindowPrivate *priv;
7152 GdkWindow *toplevel;
7154 g_return_if_fail (GTK_IS_WINDOW (window));
7156 widget = GTK_WIDGET (window);
7157 priv = GTK_WINDOW_GET_PRIVATE (window);
7159 priv->above_initially = setting != FALSE;
7161 priv->below_initially = FALSE;
7164 toplevel = window->frame;
7166 toplevel = widget->window;
7168 if (toplevel != NULL)
7169 gdk_window_set_keep_above (toplevel, setting);
7173 * gtk_window_set_keep_below:
7174 * @window: a #GtkWindow
7175 * @setting: whether to keep @window below other windows
7177 * Asks to keep @window below, so that it stays in bottom. Note that
7178 * you shouldn't assume the window is definitely below afterward,
7179 * because other entities (e.g. the user or <link
7180 * linkend="gtk-X11-arch">window manager</link>) could not keep it below,
7181 * and not all window managers support putting windows below. But
7182 * normally the window will be kept below. Just don't write code
7183 * that crashes if not.
7185 * It's permitted to call this function before showing a window,
7186 * in which case the window will be kept below when it appears onscreen
7189 * You can track the below state via the "window-state-event" signal
7192 * Note that, according to the <ulink
7193 * url="http://www.freedesktop.org/Standards/wm-spec">Extended Window
7194 * Manager Hints</ulink> specification, the above state is mainly meant
7195 * for user preferences and should not be used by applications e.g. for
7196 * drawing attention to their dialogs.
7201 gtk_window_set_keep_below (GtkWindow *window,
7205 GtkWindowPrivate *priv;
7206 GdkWindow *toplevel;
7208 g_return_if_fail (GTK_IS_WINDOW (window));
7210 widget = GTK_WIDGET (window);
7211 priv = GTK_WINDOW_GET_PRIVATE (window);
7213 priv->below_initially = setting != FALSE;
7215 priv->above_initially = FALSE;
7218 toplevel = window->frame;
7220 toplevel = widget->window;
7222 if (toplevel != NULL)
7223 gdk_window_set_keep_below (toplevel, setting);
7227 * gtk_window_set_resizable:
7228 * @window: a #GtkWindow
7229 * @resizable: %TRUE if the user can resize this window
7231 * Sets whether the user can resize a window. Windows are user resizable
7235 gtk_window_set_resizable (GtkWindow *window,
7238 g_return_if_fail (GTK_IS_WINDOW (window));
7240 gtk_window_set_policy_internal (window, FALSE, resizable, FALSE);
7244 * gtk_window_get_resizable:
7245 * @window: a #GtkWindow
7247 * Gets the value set by gtk_window_set_resizable().
7249 * Return value: %TRUE if the user can resize the window
7252 gtk_window_get_resizable (GtkWindow *window)
7254 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
7256 /* allow_grow is most likely to indicate the semantic concept we
7257 * mean by "resizable" (and will be a reliable indicator if
7258 * set_policy() hasn't been called)
7260 return window->allow_grow;
7264 * gtk_window_set_gravity:
7265 * @window: a #GtkWindow
7266 * @gravity: window gravity
7268 * Window gravity defines the meaning of coordinates passed to
7269 * gtk_window_move(). See gtk_window_move() and #GdkGravity for
7272 * The default window gravity is #GDK_GRAVITY_NORTH_WEST which will
7273 * typically "do what you mean."
7277 gtk_window_set_gravity (GtkWindow *window,
7280 g_return_if_fail (GTK_IS_WINDOW (window));
7282 if (gravity != window->gravity)
7284 window->gravity = gravity;
7286 /* gtk_window_move_resize() will adapt gravity
7288 gtk_widget_queue_resize_no_redraw (GTK_WIDGET (window));
7290 g_object_notify (G_OBJECT (window), "gravity");
7295 * gtk_window_get_gravity:
7296 * @window: a #GtkWindow
7298 * Gets the value set by gtk_window_set_gravity().
7300 * Return value: (transfer none): window gravity
7303 gtk_window_get_gravity (GtkWindow *window)
7305 g_return_val_if_fail (GTK_IS_WINDOW (window), 0);
7307 return window->gravity;
7311 * gtk_window_begin_resize_drag:
7312 * @window: a #GtkWindow
7313 * @button: mouse button that initiated the drag
7314 * @edge: position of the resize control
7315 * @root_x: X position where the user clicked to initiate the drag, in root window coordinates
7316 * @root_y: Y position where the user clicked to initiate the drag
7317 * @timestamp: timestamp from the click event that initiated the drag
7319 * Starts resizing a window. This function is used if an application
7320 * has window resizing controls. When GDK can support it, the resize
7321 * will be done using the standard mechanism for the <link
7322 * linkend="gtk-X11-arch">window manager</link> or windowing
7323 * system. Otherwise, GDK will try to emulate window resizing,
7324 * potentially not all that well, depending on the windowing system.
7328 gtk_window_begin_resize_drag (GtkWindow *window,
7336 GdkWindow *toplevel;
7338 g_return_if_fail (GTK_IS_WINDOW (window));
7339 widget = GTK_WIDGET (window);
7340 g_return_if_fail (gtk_widget_get_visible (widget));
7343 toplevel = window->frame;
7345 toplevel = widget->window;
7347 gdk_window_begin_resize_drag (toplevel,
7354 * gtk_window_get_frame_dimensions:
7355 * @window: a #GtkWindow
7356 * @left: (allow-none): location to store the width of the frame at the left, or %NULL
7357 * @top: (allow-none): location to store the height of the frame at the top, or %NULL
7358 * @right: (allow-none): location to store the width of the frame at the returns, or %NULL
7359 * @bottom: (allow-none): location to store the height of the frame at the bottom, or %NULL
7361 * (Note: this is a special-purpose function intended for the
7362 * framebuffer port; see gtk_window_set_has_frame(). It will not
7363 * return the size of the window border drawn by the <link
7364 * linkend="gtk-X11-arch">window manager</link>, which is the normal
7365 * case when using a windowing system. See
7366 * gdk_window_get_frame_extents() to get the standard window border
7369 * Retrieves the dimensions of the frame window for this toplevel.
7370 * See gtk_window_set_has_frame(), gtk_window_set_frame_dimensions().
7373 gtk_window_get_frame_dimensions (GtkWindow *window,
7379 g_return_if_fail (GTK_IS_WINDOW (window));
7382 *left = window->frame_left;
7384 *top = window->frame_top;
7386 *right = window->frame_right;
7388 *bottom = window->frame_bottom;
7392 * gtk_window_begin_move_drag:
7393 * @window: a #GtkWindow
7394 * @button: mouse button that initiated the drag
7395 * @root_x: X position where the user clicked to initiate the drag, in root window coordinates
7396 * @root_y: Y position where the user clicked to initiate the drag
7397 * @timestamp: timestamp from the click event that initiated the drag
7399 * Starts moving a window. This function is used if an application has
7400 * window movement grips. When GDK can support it, the window movement
7401 * will be done using the standard mechanism for the <link
7402 * linkend="gtk-X11-arch">window manager</link> or windowing
7403 * system. Otherwise, GDK will try to emulate window movement,
7404 * potentially not all that well, depending on the windowing system.
7408 gtk_window_begin_move_drag (GtkWindow *window,
7415 GdkWindow *toplevel;
7417 g_return_if_fail (GTK_IS_WINDOW (window));
7418 widget = GTK_WIDGET (window);
7419 g_return_if_fail (gtk_widget_get_visible (widget));
7422 toplevel = window->frame;
7424 toplevel = widget->window;
7426 gdk_window_begin_move_drag (toplevel,
7433 * gtk_window_set_screen:
7434 * @window: a #GtkWindow.
7435 * @screen: a #GdkScreen.
7437 * Sets the #GdkScreen where the @window is displayed; if
7438 * the window is already mapped, it will be unmapped, and
7439 * then remapped on the new screen.
7444 gtk_window_set_screen (GtkWindow *window,
7448 GdkScreen *previous_screen;
7449 gboolean was_mapped;
7451 g_return_if_fail (GTK_IS_WINDOW (window));
7452 g_return_if_fail (GDK_IS_SCREEN (screen));
7454 if (screen == window->screen)
7457 widget = GTK_WIDGET (window);
7459 previous_screen = window->screen;
7460 was_mapped = gtk_widget_get_mapped (widget);
7463 gtk_widget_unmap (widget);
7464 if (GTK_WIDGET_REALIZED (widget))
7465 gtk_widget_unrealize (widget);
7467 gtk_window_free_key_hash (window);
7468 window->screen = screen;
7469 gtk_widget_reset_rc_styles (widget);
7470 if (screen != previous_screen)
7472 g_signal_handlers_disconnect_by_func (previous_screen,
7473 gtk_window_on_composited_changed, window);
7474 g_signal_connect (screen, "composited-changed",
7475 G_CALLBACK (gtk_window_on_composited_changed), window);
7477 _gtk_widget_propagate_screen_changed (widget, previous_screen);
7478 _gtk_widget_propagate_composited_changed (widget);
7480 g_object_notify (G_OBJECT (window), "screen");
7483 gtk_widget_map (widget);
7487 gtk_window_on_composited_changed (GdkScreen *screen,
7490 gtk_widget_queue_draw (GTK_WIDGET (window));
7492 _gtk_widget_propagate_composited_changed (GTK_WIDGET (window));
7496 gtk_window_check_screen (GtkWindow *window)
7499 return window->screen;
7502 g_warning ("Screen for GtkWindow not set; you must always set\n"
7503 "a screen for a GtkWindow before using the window");
7509 * gtk_window_get_screen:
7510 * @window: a #GtkWindow.
7512 * Returns the #GdkScreen associated with @window.
7514 * Return value: (transfer none): a #GdkScreen.
7519 gtk_window_get_screen (GtkWindow *window)
7521 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
7523 return window->screen;
7527 * gtk_window_is_active:
7528 * @window: a #GtkWindow
7530 * Returns whether the window is part of the current active toplevel.
7531 * (That is, the toplevel window receiving keystrokes.)
7532 * The return value is %TRUE if the window is active toplevel
7533 * itself, but also if it is, say, a #GtkPlug embedded in the active toplevel.
7534 * You might use this function if you wanted to draw a widget
7535 * differently in an active window from a widget in an inactive window.
7536 * See gtk_window_has_toplevel_focus()
7538 * Return value: %TRUE if the window part of the current active window.
7543 gtk_window_is_active (GtkWindow *window)
7545 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
7547 return window->is_active;
7551 * gtk_window_has_toplevel_focus:
7552 * @window: a #GtkWindow
7554 * Returns whether the input focus is within this GtkWindow.
7555 * For real toplevel windows, this is identical to gtk_window_is_active(),
7556 * but for embedded windows, like #GtkPlug, the results will differ.
7558 * Return value: %TRUE if the input focus is within this GtkWindow
7563 gtk_window_has_toplevel_focus (GtkWindow *window)
7565 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
7567 return window->has_toplevel_focus;
7571 gtk_window_group_class_init (GtkWindowGroupClass *klass)
7576 gtk_window_group_get_type (void)
7578 static GType window_group_type = 0;
7580 if (!window_group_type)
7582 const GTypeInfo window_group_info =
7584 sizeof (GtkWindowGroupClass),
7585 NULL, /* base_init */
7586 NULL, /* base_finalize */
7587 (GClassInitFunc) gtk_window_group_class_init,
7588 NULL, /* class_finalize */
7589 NULL, /* class_data */
7590 sizeof (GtkWindowGroup),
7591 0, /* n_preallocs */
7592 (GInstanceInitFunc) NULL,
7595 window_group_type = g_type_register_static (G_TYPE_OBJECT, I_("GtkWindowGroup"),
7596 &window_group_info, 0);
7599 return window_group_type;
7603 * gtk_window_group_new:
7605 * Creates a new #GtkWindowGroup object. Grabs added with
7606 * gtk_grab_add() only affect windows within the same #GtkWindowGroup.
7608 * Return value: a new #GtkWindowGroup.
7611 gtk_window_group_new (void)
7613 return g_object_new (GTK_TYPE_WINDOW_GROUP, NULL);
7617 window_group_cleanup_grabs (GtkWindowGroup *group,
7621 GSList *to_remove = NULL;
7623 tmp_list = group->grabs;
7626 if (gtk_widget_get_toplevel (tmp_list->data) == (GtkWidget*) window)
7627 to_remove = g_slist_prepend (to_remove, g_object_ref (tmp_list->data));
7628 tmp_list = tmp_list->next;
7633 gtk_grab_remove (to_remove->data);
7634 g_object_unref (to_remove->data);
7635 to_remove = g_slist_delete_link (to_remove, to_remove);
7640 * gtk_window_group_add_window:
7641 * @window_group: a #GtkWindowGroup
7642 * @window: the #GtkWindow to add
7644 * Adds a window to a #GtkWindowGroup.
7647 gtk_window_group_add_window (GtkWindowGroup *window_group,
7650 g_return_if_fail (GTK_IS_WINDOW_GROUP (window_group));
7651 g_return_if_fail (GTK_IS_WINDOW (window));
7653 if (window->group != window_group)
7655 g_object_ref (window);
7656 g_object_ref (window_group);
7659 gtk_window_group_remove_window (window->group, window);
7661 window_group_cleanup_grabs (gtk_window_get_group (NULL), window);
7663 window->group = window_group;
7665 g_object_unref (window);
7670 * gtk_window_group_remove_window:
7671 * @window_group: a #GtkWindowGroup
7672 * @window: the #GtkWindow to remove
7674 * Removes a window from a #GtkWindowGroup.
7677 gtk_window_group_remove_window (GtkWindowGroup *window_group,
7680 g_return_if_fail (GTK_IS_WINDOW_GROUP (window_group));
7681 g_return_if_fail (GTK_IS_WINDOW (window));
7682 g_return_if_fail (window->group == window_group);
7684 g_object_ref (window);
7686 window_group_cleanup_grabs (window_group, window);
7687 window->group = NULL;
7689 g_object_unref (window_group);
7690 g_object_unref (window);
7694 * gtk_window_group_list_windows:
7695 * @window_group: a #GtkWindowGroup
7697 * Returns a list of the #GtkWindows that belong to @window_group.
7699 * Returns: (element-type GtkWidget) (transfer container): A newly-allocated list of
7700 * windows inside the group.
7705 gtk_window_group_list_windows (GtkWindowGroup *window_group)
7707 GList *toplevels, *toplevel, *group_windows;
7709 g_return_val_if_fail (GTK_IS_WINDOW_GROUP (window_group), NULL);
7711 group_windows = NULL;
7712 toplevels = gtk_window_list_toplevels ();
7714 for (toplevel = toplevels; toplevel; toplevel = toplevel->next)
7716 GtkWindow *window = toplevel->data;
7718 if (window_group == window->group)
7719 group_windows = g_list_prepend (group_windows, window);
7722 return g_list_reverse (group_windows);
7726 * gtk_window_get_group:
7727 * @window: (allow-none): a #GtkWindow, or %NULL
7729 * Returns the group for @window or the default group, if
7730 * @window is %NULL or if @window does not have an explicit
7733 * Returns: (transfer none): the #GtkWindowGroup for a window or the default group
7738 gtk_window_get_group (GtkWindow *window)
7740 if (window && window->group)
7741 return window->group;
7744 static GtkWindowGroup *default_group = NULL;
7747 default_group = gtk_window_group_new ();
7749 return default_group;
7753 /* Return the current grab widget of the given group
7756 _gtk_window_group_get_current_grab (GtkWindowGroup *window_group)
7758 if (window_group->grabs)
7759 return GTK_WIDGET (window_group->grabs->data);
7764 Derived from XParseGeometry() in XFree86
7766 Copyright 1985, 1986, 1987,1998 The Open Group
7768 All Rights Reserved.
7770 The above copyright notice and this permission notice shall be included
7771 in all copies or substantial portions of the Software.
7773 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
7774 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
7775 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
7776 IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
7777 OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
7778 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
7779 OTHER DEALINGS IN THE SOFTWARE.
7781 Except as contained in this notice, the name of The Open Group shall
7782 not be used in advertising or otherwise to promote the sale, use or
7783 other dealings in this Software without prior written authorization
7784 from The Open Group.
7789 * XParseGeometry parses strings of the form
7790 * "=<width>x<height>{+-}<xoffset>{+-}<yoffset>", where
7791 * width, height, xoffset, and yoffset are unsigned integers.
7792 * Example: "=80x24+300-49"
7793 * The equal sign is optional.
7794 * It returns a bitmask that indicates which of the four values
7795 * were actually found in the string. For each value found,
7796 * the corresponding argument is updated; for each value
7797 * not found, the corresponding argument is left unchanged.
7800 /* The following code is from Xlib, and is minimally modified, so we
7801 * can track any upstream changes if required. Don't change this
7802 * code. Or if you do, put in a huge comment marking which thing
7807 read_int (gchar *string,
7815 else if (*string == '-')
7821 for (; (*string >= '0') && (*string <= '9'); string++)
7823 result = (result * 10) + (*string - '0');
7835 * Bitmask returned by XParseGeometry(). Each bit tells if the corresponding
7836 * value (x, y, width, height) was found in the parsed string.
7838 #define NoValue 0x0000
7839 #define XValue 0x0001
7840 #define YValue 0x0002
7841 #define WidthValue 0x0004
7842 #define HeightValue 0x0008
7843 #define AllValues 0x000F
7844 #define XNegative 0x0010
7845 #define YNegative 0x0020
7847 /* Try not to reformat/modify, so we can compare/sync with X sources */
7849 gtk_XParseGeometry (const char *string,
7852 unsigned int *width,
7853 unsigned int *height)
7857 unsigned int tempWidth, tempHeight;
7859 char *nextCharacter;
7861 /* These initializations are just to silence gcc */
7867 if ( (string == NULL) || (*string == '\0')) return(mask);
7869 string++; /* ignore possible '=' at beg of geometry spec */
7871 strind = (char *)string;
7872 if (*strind != '+' && *strind != '-' && *strind != 'x') {
7873 tempWidth = read_int(strind, &nextCharacter);
7874 if (strind == nextCharacter)
7876 strind = nextCharacter;
7880 if (*strind == 'x' || *strind == 'X') {
7882 tempHeight = read_int(strind, &nextCharacter);
7883 if (strind == nextCharacter)
7885 strind = nextCharacter;
7886 mask |= HeightValue;
7889 if ((*strind == '+') || (*strind == '-')) {
7890 if (*strind == '-') {
7892 tempX = -read_int(strind, &nextCharacter);
7893 if (strind == nextCharacter)
7895 strind = nextCharacter;
7901 tempX = read_int(strind, &nextCharacter);
7902 if (strind == nextCharacter)
7904 strind = nextCharacter;
7907 if ((*strind == '+') || (*strind == '-')) {
7908 if (*strind == '-') {
7910 tempY = -read_int(strind, &nextCharacter);
7911 if (strind == nextCharacter)
7913 strind = nextCharacter;
7920 tempY = read_int(strind, &nextCharacter);
7921 if (strind == nextCharacter)
7923 strind = nextCharacter;
7929 /* If strind isn't at the end of the string the it's an invalid
7930 geometry specification. */
7932 if (*strind != '\0') return (0);
7938 if (mask & WidthValue)
7940 if (mask & HeightValue)
7941 *height = tempHeight;
7946 * gtk_window_parse_geometry:
7947 * @window: a #GtkWindow
7948 * @geometry: geometry string
7950 * Parses a standard X Window System geometry string - see the
7951 * manual page for X (type 'man X') for details on this.
7952 * gtk_window_parse_geometry() does work on all GTK+ ports
7953 * including Win32 but is primarily intended for an X environment.
7955 * If either a size or a position can be extracted from the
7956 * geometry string, gtk_window_parse_geometry() returns %TRUE
7957 * and calls gtk_window_set_default_size() and/or gtk_window_move()
7958 * to resize/move the window.
7960 * If gtk_window_parse_geometry() returns %TRUE, it will also
7961 * set the #GDK_HINT_USER_POS and/or #GDK_HINT_USER_SIZE hints
7962 * indicating to the window manager that the size/position of
7963 * the window was user-specified. This causes most window
7964 * managers to honor the geometry.
7966 * Note that for gtk_window_parse_geometry() to work as expected, it has
7967 * to be called when the window has its "final" size, i.e. after calling
7968 * gtk_widget_show_all() on the contents and gtk_window_set_geometry_hints()
7971 * #include <gtk/gtk.h>
7974 * fill_with_content (GtkWidget *vbox)
7976 * /* fill with content... */
7980 * main (int argc, char *argv[])
7982 * GtkWidget *window, *vbox;
7983 * GdkGeometry size_hints = {
7984 * 100, 50, 0, 0, 100, 50, 10, 10, 0.0, 0.0, GDK_GRAVITY_NORTH_WEST
7987 * gtk_init (&argc, &argv);
7989 * window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
7990 * vbox = gtk_vbox_new (FALSE, 0);
7992 * gtk_container_add (GTK_CONTAINER (window), vbox);
7993 * fill_with_content (vbox);
7994 * gtk_widget_show_all (vbox);
7996 * gtk_window_set_geometry_hints (GTK_WINDOW (window),
7999 * GDK_HINT_MIN_SIZE |
8000 * GDK_HINT_BASE_SIZE |
8001 * GDK_HINT_RESIZE_INC);
8005 * if (!gtk_window_parse_geometry (GTK_WINDOW (window), argv[1]))
8006 * fprintf (stderr, "Failed to parse '%s'\n", argv[1]);
8009 * gtk_widget_show_all (window);
8016 * Return value: %TRUE if string was parsed successfully
8019 gtk_window_parse_geometry (GtkWindow *window,
8020 const gchar *geometry)
8022 gint result, x = 0, y = 0;
8025 gboolean size_set, pos_set;
8028 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
8029 g_return_val_if_fail (geometry != NULL, FALSE);
8031 screen = gtk_window_check_screen (window);
8033 result = gtk_XParseGeometry (geometry, &x, &y, &w, &h);
8036 if ((result & WidthValue) || (result & HeightValue))
8038 gtk_window_set_default_size_internal (window,
8039 TRUE, result & WidthValue ? w : -1,
8040 TRUE, result & HeightValue ? h : -1,
8045 gtk_window_get_size (window, (gint *)&w, (gint *)&h);
8047 grav = GDK_GRAVITY_NORTH_WEST;
8049 if ((result & XNegative) && (result & YNegative))
8050 grav = GDK_GRAVITY_SOUTH_EAST;
8051 else if (result & XNegative)
8052 grav = GDK_GRAVITY_NORTH_EAST;
8053 else if (result & YNegative)
8054 grav = GDK_GRAVITY_SOUTH_WEST;
8056 if ((result & XValue) == 0)
8059 if ((result & YValue) == 0)
8062 if (grav == GDK_GRAVITY_SOUTH_WEST ||
8063 grav == GDK_GRAVITY_SOUTH_EAST)
8064 y = gdk_screen_get_height (screen) - h + y;
8066 if (grav == GDK_GRAVITY_SOUTH_EAST ||
8067 grav == GDK_GRAVITY_NORTH_EAST)
8068 x = gdk_screen_get_width (screen) - w + x;
8070 /* we don't let you put a window offscreen; maybe some people would
8071 * prefer to be able to, but it's kind of a bogus thing to do.
8080 if ((result & XValue) || (result & YValue))
8082 gtk_window_set_gravity (window, grav);
8083 gtk_window_move (window, x, y);
8087 if (size_set || pos_set)
8089 /* Set USSize, USPosition hints */
8090 GtkWindowGeometryInfo *info;
8092 info = gtk_window_get_geometry_info (window, TRUE);
8095 info->mask |= GDK_HINT_USER_POS;
8097 info->mask |= GDK_HINT_USER_SIZE;
8104 gtk_window_mnemonic_hash_foreach (guint keyval,
8110 GtkWindowKeysForeachFunc func;
8114 (*info->func) (info->window, keyval, info->window->mnemonic_modifier, TRUE, info->func_data);
8118 _gtk_window_keys_foreach (GtkWindow *window,
8119 GtkWindowKeysForeachFunc func,
8123 GtkMnemonicHash *mnemonic_hash;
8127 GtkWindowKeysForeachFunc func;
8131 info.window = window;
8133 info.func_data = func_data;
8135 mnemonic_hash = gtk_window_get_mnemonic_hash (window, FALSE);
8137 _gtk_mnemonic_hash_foreach (mnemonic_hash,
8138 gtk_window_mnemonic_hash_foreach, &info);
8140 groups = gtk_accel_groups_from_object (G_OBJECT (window));
8143 GtkAccelGroup *group = groups->data;
8146 for (i = 0; i < group->n_accels; i++)
8148 GtkAccelKey *key = &group->priv_accels[i].key;
8151 (*func) (window, key->accel_key, key->accel_mods, FALSE, func_data);
8154 groups = groups->next;
8159 gtk_window_keys_changed (GtkWindow *window)
8161 gtk_window_free_key_hash (window);
8162 gtk_window_get_key_hash (window);
8165 typedef struct _GtkWindowKeyEntry GtkWindowKeyEntry;
8167 struct _GtkWindowKeyEntry
8171 guint is_mnemonic : 1;
8175 window_key_entry_destroy (gpointer data)
8177 g_slice_free (GtkWindowKeyEntry, data);
8181 add_to_key_hash (GtkWindow *window,
8183 GdkModifierType modifiers,
8184 gboolean is_mnemonic,
8187 GtkKeyHash *key_hash = data;
8189 GtkWindowKeyEntry *entry = g_slice_new (GtkWindowKeyEntry);
8191 entry->keyval = keyval;
8192 entry->modifiers = modifiers;
8193 entry->is_mnemonic = is_mnemonic;
8195 /* GtkAccelGroup stores lowercased accelerators. To deal
8196 * with this, if <Shift> was specified, uppercase.
8198 if (modifiers & GDK_SHIFT_MASK)
8200 if (keyval == GDK_Tab)
8201 keyval = GDK_ISO_Left_Tab;
8203 keyval = gdk_keyval_to_upper (keyval);
8206 _gtk_key_hash_add_entry (key_hash, keyval, entry->modifiers, entry);
8210 gtk_window_get_key_hash (GtkWindow *window)
8212 GdkScreen *screen = gtk_window_check_screen (window);
8213 GtkKeyHash *key_hash = g_object_get_qdata (G_OBJECT (window), quark_gtk_window_key_hash);
8218 key_hash = _gtk_key_hash_new (gdk_keymap_get_for_display (gdk_screen_get_display (screen)),
8219 (GDestroyNotify)window_key_entry_destroy);
8220 _gtk_window_keys_foreach (window, add_to_key_hash, key_hash);
8221 g_object_set_qdata (G_OBJECT (window), quark_gtk_window_key_hash, key_hash);
8227 gtk_window_free_key_hash (GtkWindow *window)
8229 GtkKeyHash *key_hash = g_object_get_qdata (G_OBJECT (window), quark_gtk_window_key_hash);
8232 _gtk_key_hash_free (key_hash);
8233 g_object_set_qdata (G_OBJECT (window), quark_gtk_window_key_hash, NULL);
8238 * gtk_window_activate_key:
8239 * @window: a #GtkWindow
8240 * @event: a #GdkEventKey
8242 * Activates mnemonics and accelerators for this #GtkWindow. This is normally
8243 * called by the default ::key_press_event handler for toplevel windows,
8244 * however in some cases it may be useful to call this directly when
8245 * overriding the standard key handling for a toplevel window.
8247 * Return value: %TRUE if a mnemonic or accelerator was found and activated.
8252 gtk_window_activate_key (GtkWindow *window,
8255 GtkKeyHash *key_hash;
8256 GtkWindowKeyEntry *found_entry = NULL;
8257 gboolean enable_mnemonics;
8258 gboolean enable_accels;
8260 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
8261 g_return_val_if_fail (event != NULL, FALSE);
8263 key_hash = gtk_window_get_key_hash (window);
8268 GSList *entries = _gtk_key_hash_lookup (key_hash,
8269 event->hardware_keycode,
8271 gtk_accelerator_get_default_mod_mask (),
8274 g_object_get (gtk_widget_get_settings (GTK_WIDGET (window)),
8275 "gtk-enable-mnemonics", &enable_mnemonics,
8276 "gtk-enable-accels", &enable_accels,
8279 for (tmp_list = entries; tmp_list; tmp_list = tmp_list->next)
8281 GtkWindowKeyEntry *entry = tmp_list->data;
8282 if (entry->is_mnemonic)
8284 if (enable_mnemonics)
8286 found_entry = entry;
8292 if (enable_accels && !found_entry)
8294 found_entry = entry;
8299 g_slist_free (entries);
8304 if (found_entry->is_mnemonic)
8306 if (enable_mnemonics)
8307 return gtk_window_mnemonic_activate (window, found_entry->keyval,
8308 found_entry->modifiers);
8313 return gtk_accel_groups_activate (G_OBJECT (window), found_entry->keyval,
8314 found_entry->modifiers);
8322 window_update_has_focus (GtkWindow *window)
8324 GtkWidget *widget = GTK_WIDGET (window);
8325 gboolean has_focus = window->has_toplevel_focus && window->is_active;
8327 if (has_focus != window->has_focus)
8329 window->has_focus = has_focus;
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, TRUE);
8340 if (window->focus_widget &&
8341 window->focus_widget != widget &&
8342 gtk_widget_has_focus (window->focus_widget))
8343 do_focus_change (window->focus_widget, FALSE);
8349 * _gtk_window_set_is_active:
8350 * @window: a #GtkWindow
8351 * @is_active: %TRUE if the window is in the currently active toplevel
8353 * Internal function that sets whether the #GtkWindow is part
8354 * of the currently active toplevel window (taking into account inter-process
8358 _gtk_window_set_is_active (GtkWindow *window,
8361 g_return_if_fail (GTK_IS_WINDOW (window));
8363 is_active = is_active != FALSE;
8365 if (is_active != window->is_active)
8367 window->is_active = is_active;
8368 window_update_has_focus (window);
8370 g_object_notify (G_OBJECT (window), "is-active");
8375 * _gtk_window_set_is_toplevel:
8376 * @window: a #GtkWindow
8377 * @is_toplevel: %TRUE if the window is still a real toplevel (nominally a
8378 * parent of the root window); %FALSE if it is not (for example, for an
8379 * in-process, parented GtkPlug)
8381 * Internal function used by #GtkPlug when it gets parented/unparented by a
8382 * #GtkSocket. This keeps the @window's #GTK_TOPLEVEL flag in sync with the
8383 * global list of toplevel windows.
8386 _gtk_window_set_is_toplevel (GtkWindow *window,
8387 gboolean is_toplevel)
8389 if (gtk_widget_is_toplevel (GTK_WIDGET (window)))
8390 g_assert (g_slist_find (toplevel_list, window) != NULL);
8392 g_assert (g_slist_find (toplevel_list, window) == NULL);
8394 if (is_toplevel == gtk_widget_is_toplevel (GTK_WIDGET (window)))
8399 GTK_WIDGET_SET_FLAGS (window, GTK_TOPLEVEL);
8400 toplevel_list = g_slist_prepend (toplevel_list, window);
8404 GTK_WIDGET_UNSET_FLAGS (window, GTK_TOPLEVEL);
8405 toplevel_list = g_slist_remove (toplevel_list, window);
8410 * _gtk_window_set_has_toplevel_focus:
8411 * @window: a #GtkWindow
8412 * @has_toplevel_focus: %TRUE if the in
8414 * Internal function that sets whether the keyboard focus for the
8415 * toplevel window (taking into account inter-process embedding.)
8418 _gtk_window_set_has_toplevel_focus (GtkWindow *window,
8419 gboolean has_toplevel_focus)
8421 g_return_if_fail (GTK_IS_WINDOW (window));
8423 has_toplevel_focus = has_toplevel_focus != FALSE;
8425 if (has_toplevel_focus != window->has_toplevel_focus)
8427 window->has_toplevel_focus = has_toplevel_focus;
8428 window_update_has_focus (window);
8430 g_object_notify (G_OBJECT (window), "has-toplevel-focus");
8435 * gtk_window_set_auto_startup_notification:
8436 * @setting: %TRUE to automatically do startup notification
8438 * By default, after showing the first #GtkWindow, GTK+ calls
8439 * gdk_notify_startup_complete(). Call this function to disable
8440 * the automatic startup notification. You might do this if your
8441 * first window is a splash screen, and you want to delay notification
8442 * until after your real main window has been shown, for example.
8444 * In that example, you would disable startup notification
8445 * temporarily, show your splash screen, then re-enable it so that
8446 * showing the main window would automatically result in notification.
8451 gtk_window_set_auto_startup_notification (gboolean setting)
8453 disable_startup_notification = !setting;
8457 * gtk_window_get_window_type:
8458 * @window: a #GtkWindow
8460 * Gets the type of the window. See #GtkWindowType.
8462 * Return value: the type of the window
8467 gtk_window_get_window_type (GtkWindow *window)
8469 g_return_val_if_fail (GTK_IS_WINDOW (window), GTK_WINDOW_TOPLEVEL);
8471 return window->type;
8474 /* gtk_window_get_mnemonics_visible:
8475 * @window: a #GtkWindow
8477 * Gets the value of the #GtkWindow:mnemonics-visible property.
8479 * Returns: %TRUE if mnemonics are supposed to be visible
8485 gtk_window_get_mnemonics_visible (GtkWindow *window)
8487 GtkWindowPrivate *priv;
8489 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
8491 priv = GTK_WINDOW_GET_PRIVATE (window);
8493 return priv->mnemonics_visible;
8497 * gtk_window_set_mnemonics_visible:
8498 * @window: a #GtkWindow
8499 * @setting: the new value
8501 * Sets the #GtkWindow:mnemonics-visible property.
8506 gtk_window_set_mnemonics_visible (GtkWindow *window,
8509 GtkWindowPrivate *priv;
8511 g_return_if_fail (GTK_IS_WINDOW (window));
8513 priv = GTK_WINDOW_GET_PRIVATE (window);
8515 setting = setting != FALSE;
8517 if (priv->mnemonics_visible != setting)
8519 priv->mnemonics_visible = setting;
8520 g_object_notify (G_OBJECT (window), "mnemonics-visible");
8523 priv->mnemonics_visible_set = TRUE;
8526 #if defined (G_OS_WIN32) && !defined (_WIN64)
8528 #undef gtk_window_set_icon_from_file
8531 gtk_window_set_icon_from_file (GtkWindow *window,
8532 const gchar *filename,
8535 gchar *utf8_filename = g_locale_to_utf8 (filename, -1, NULL, NULL, err);
8538 if (utf8_filename == NULL)
8541 retval = gtk_window_set_icon_from_file_utf8 (window, utf8_filename, err);
8543 g_free (utf8_filename);
8548 #undef gtk_window_set_default_icon_from_file
8551 gtk_window_set_default_icon_from_file (const gchar *filename,
8554 gchar *utf8_filename = g_locale_to_utf8 (filename, -1, NULL, NULL, err);
8557 if (utf8_filename == NULL)
8560 retval = gtk_window_set_default_icon_from_file_utf8 (utf8_filename, err);
8562 g_free (utf8_filename);
8569 #define __GTK_WINDOW_C__
8570 #include "gtkaliasdef.c"