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 = GTK_WINDOW_GET_PRIVATE (window);
1521 g_return_if_fail (GTK_IS_WINDOW (window));
1523 g_free (priv->startup_id);
1524 priv->startup_id = g_strdup (startup_id);
1526 if (GTK_WIDGET_REALIZED (window))
1528 guint32 timestamp = extract_time_from_startup_id (priv->startup_id);
1530 #ifdef GDK_WINDOWING_X11
1531 if (timestamp != GDK_CURRENT_TIME)
1532 gdk_x11_window_set_user_time (GTK_WIDGET (window)->window, timestamp);
1535 /* Here we differentiate real and "fake" startup notification IDs,
1536 * constructed on purpose just to pass interaction timestamp
1538 if (startup_id_is_fake (priv->startup_id))
1539 gtk_window_present_with_time (window, timestamp);
1542 gdk_window_set_startup_id (GTK_WIDGET (window)->window,
1545 /* If window is mapped, terminate the startup-notification too */
1546 if (GTK_WIDGET_MAPPED (window) && !disable_startup_notification)
1547 gdk_notify_startup_complete_with_id (priv->startup_id);
1551 g_object_notify (G_OBJECT (window), "startup-id");
1555 * gtk_window_get_role:
1556 * @window: a #GtkWindow
1558 * Returns the role of the window. See gtk_window_set_role() for
1559 * further explanation.
1561 * Return value: the role of the window if set, or %NULL. The
1562 * returned is owned by the widget and must not be modified
1565 G_CONST_RETURN gchar *
1566 gtk_window_get_role (GtkWindow *window)
1568 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
1570 return window->wm_role;
1574 * gtk_window_set_focus:
1575 * @window: a #GtkWindow
1576 * @focus: (allow-none): widget to be the new focus widget, or %NULL to unset
1577 * any focus widget for the toplevel window.
1579 * If @focus is not the current focus widget, and is focusable, sets
1580 * it as the focus widget for the window. If @focus is %NULL, unsets
1581 * the focus widget for this window. To set the focus to a particular
1582 * widget in the toplevel, it is usually more convenient to use
1583 * gtk_widget_grab_focus() instead of this function.
1586 gtk_window_set_focus (GtkWindow *window,
1589 g_return_if_fail (GTK_IS_WINDOW (window));
1592 g_return_if_fail (GTK_IS_WIDGET (focus));
1593 g_return_if_fail (GTK_WIDGET_CAN_FOCUS (focus));
1597 gtk_widget_grab_focus (focus);
1600 /* Clear the existing focus chain, so that when we focus into
1601 * the window again, we start at the beginnning.
1603 GtkWidget *widget = window->focus_widget;
1606 while (widget->parent)
1608 widget = widget->parent;
1609 gtk_container_set_focus_child (GTK_CONTAINER (widget), NULL);
1613 _gtk_window_internal_set_focus (window, NULL);
1618 _gtk_window_internal_set_focus (GtkWindow *window,
1621 g_return_if_fail (GTK_IS_WINDOW (window));
1623 if ((window->focus_widget != focus) ||
1624 (focus && !GTK_WIDGET_HAS_FOCUS (focus)))
1625 g_signal_emit (window, window_signals[SET_FOCUS], 0, focus);
1629 * gtk_window_set_default:
1630 * @window: a #GtkWindow
1631 * @default_widget: (allow-none): widget to be the default, or %NULL to unset the
1632 * default widget for the toplevel.
1634 * The default widget is the widget that's activated when the user
1635 * presses Enter in a dialog (for example). This function sets or
1636 * unsets the default widget for a #GtkWindow about. When setting
1637 * (rather than unsetting) the default widget it's generally easier to
1638 * call gtk_widget_grab_focus() on the widget. Before making a widget
1639 * the default widget, you must set the #GTK_CAN_DEFAULT flag on the
1640 * widget you'd like to make the default using GTK_WIDGET_SET_FLAGS().
1643 gtk_window_set_default (GtkWindow *window,
1644 GtkWidget *default_widget)
1646 g_return_if_fail (GTK_IS_WINDOW (window));
1649 g_return_if_fail (GTK_WIDGET_CAN_DEFAULT (default_widget));
1651 if (window->default_widget != default_widget)
1653 GtkWidget *old_default_widget = NULL;
1656 g_object_ref (default_widget);
1658 if (window->default_widget)
1660 old_default_widget = window->default_widget;
1662 if (window->focus_widget != window->default_widget ||
1663 !GTK_WIDGET_RECEIVES_DEFAULT (window->default_widget))
1664 GTK_WIDGET_UNSET_FLAGS (window->default_widget, GTK_HAS_DEFAULT);
1665 gtk_widget_queue_draw (window->default_widget);
1668 window->default_widget = default_widget;
1670 if (window->default_widget)
1672 if (window->focus_widget == NULL ||
1673 !GTK_WIDGET_RECEIVES_DEFAULT (window->focus_widget))
1674 GTK_WIDGET_SET_FLAGS (window->default_widget, GTK_HAS_DEFAULT);
1675 gtk_widget_queue_draw (window->default_widget);
1678 if (old_default_widget)
1679 g_object_notify (G_OBJECT (old_default_widget), "has-default");
1683 g_object_notify (G_OBJECT (default_widget), "has-default");
1684 g_object_unref (default_widget);
1690 * gtk_window_get_default_widget:
1691 * @window: a #GtkWindow
1693 * Returns the default widget for @window. See gtk_window_set_default()
1696 * Returns: the default widget, or %NULL if there is none.
1701 gtk_window_get_default_widget (GtkWindow *window)
1703 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
1705 return window->default_widget;
1709 gtk_window_set_policy_internal (GtkWindow *window,
1710 gboolean allow_shrink,
1711 gboolean allow_grow,
1712 gboolean auto_shrink)
1714 window->allow_shrink = (allow_shrink != FALSE);
1715 window->allow_grow = (allow_grow != FALSE);
1717 g_object_freeze_notify (G_OBJECT (window));
1718 g_object_notify (G_OBJECT (window), "allow-shrink");
1719 g_object_notify (G_OBJECT (window), "allow-grow");
1720 g_object_notify (G_OBJECT (window), "resizable");
1721 g_object_thaw_notify (G_OBJECT (window));
1723 gtk_widget_queue_resize_no_redraw (GTK_WIDGET (window));
1727 gtk_window_set_policy (GtkWindow *window,
1728 gboolean allow_shrink,
1729 gboolean allow_grow,
1730 gboolean auto_shrink)
1732 g_return_if_fail (GTK_IS_WINDOW (window));
1734 gtk_window_set_policy_internal (window, allow_shrink, allow_grow, auto_shrink);
1738 handle_keys_changed (gpointer data)
1742 window = GTK_WINDOW (data);
1744 if (window->keys_changed_handler)
1746 g_source_remove (window->keys_changed_handler);
1747 window->keys_changed_handler = 0;
1750 g_signal_emit (window, window_signals[KEYS_CHANGED], 0);
1756 gtk_window_notify_keys_changed (GtkWindow *window)
1758 if (!window->keys_changed_handler)
1759 window->keys_changed_handler = gdk_threads_add_idle (handle_keys_changed, window);
1763 * gtk_window_add_accel_group:
1764 * @window: window to attach accelerator group to
1765 * @accel_group: a #GtkAccelGroup
1767 * Associate @accel_group with @window, such that calling
1768 * gtk_accel_groups_activate() on @window will activate accelerators
1772 gtk_window_add_accel_group (GtkWindow *window,
1773 GtkAccelGroup *accel_group)
1775 g_return_if_fail (GTK_IS_WINDOW (window));
1776 g_return_if_fail (GTK_IS_ACCEL_GROUP (accel_group));
1778 _gtk_accel_group_attach (accel_group, G_OBJECT (window));
1779 g_signal_connect_object (accel_group, "accel-changed",
1780 G_CALLBACK (gtk_window_notify_keys_changed),
1781 window, G_CONNECT_SWAPPED);
1782 gtk_window_notify_keys_changed (window);
1786 * gtk_window_remove_accel_group:
1787 * @window: a #GtkWindow
1788 * @accel_group: a #GtkAccelGroup
1790 * Reverses the effects of gtk_window_add_accel_group().
1793 gtk_window_remove_accel_group (GtkWindow *window,
1794 GtkAccelGroup *accel_group)
1796 g_return_if_fail (GTK_IS_WINDOW (window));
1797 g_return_if_fail (GTK_IS_ACCEL_GROUP (accel_group));
1799 g_signal_handlers_disconnect_by_func (accel_group,
1800 gtk_window_notify_keys_changed,
1802 _gtk_accel_group_detach (accel_group, G_OBJECT (window));
1803 gtk_window_notify_keys_changed (window);
1806 static GtkMnemonicHash *
1807 gtk_window_get_mnemonic_hash (GtkWindow *window,
1810 GtkWindowPrivate *private = GTK_WINDOW_GET_PRIVATE (window);
1811 if (!private->mnemonic_hash && create)
1812 private->mnemonic_hash = _gtk_mnemonic_hash_new ();
1814 return private->mnemonic_hash;
1818 * gtk_window_add_mnemonic:
1819 * @window: a #GtkWindow
1820 * @keyval: the mnemonic
1821 * @target: the widget that gets activated by the mnemonic
1823 * Adds a mnemonic to this window.
1826 gtk_window_add_mnemonic (GtkWindow *window,
1830 g_return_if_fail (GTK_IS_WINDOW (window));
1831 g_return_if_fail (GTK_IS_WIDGET (target));
1833 _gtk_mnemonic_hash_add (gtk_window_get_mnemonic_hash (window, TRUE),
1835 gtk_window_notify_keys_changed (window);
1839 * gtk_window_remove_mnemonic:
1840 * @window: a #GtkWindow
1841 * @keyval: the mnemonic
1842 * @target: the widget that gets activated by the mnemonic
1844 * Removes a mnemonic from this window.
1847 gtk_window_remove_mnemonic (GtkWindow *window,
1851 g_return_if_fail (GTK_IS_WINDOW (window));
1852 g_return_if_fail (GTK_IS_WIDGET (target));
1854 _gtk_mnemonic_hash_remove (gtk_window_get_mnemonic_hash (window, TRUE),
1856 gtk_window_notify_keys_changed (window);
1860 * gtk_window_mnemonic_activate:
1861 * @window: a #GtkWindow
1862 * @keyval: the mnemonic
1863 * @modifier: the modifiers
1864 * @returns: %TRUE if the activation is done.
1866 * Activates the targets associated with the mnemonic.
1869 gtk_window_mnemonic_activate (GtkWindow *window,
1871 GdkModifierType modifier)
1873 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
1875 if (window->mnemonic_modifier == (modifier & gtk_accelerator_get_default_mod_mask ()))
1877 GtkMnemonicHash *mnemonic_hash = gtk_window_get_mnemonic_hash (window, FALSE);
1879 return _gtk_mnemonic_hash_activate (mnemonic_hash, keyval);
1886 * gtk_window_set_mnemonic_modifier:
1887 * @window: a #GtkWindow
1888 * @modifier: the modifier mask used to activate
1889 * mnemonics on this window.
1891 * Sets the mnemonic modifier for this window.
1894 gtk_window_set_mnemonic_modifier (GtkWindow *window,
1895 GdkModifierType modifier)
1897 g_return_if_fail (GTK_IS_WINDOW (window));
1898 g_return_if_fail ((modifier & ~GDK_MODIFIER_MASK) == 0);
1900 window->mnemonic_modifier = modifier;
1901 gtk_window_notify_keys_changed (window);
1905 * gtk_window_get_mnemonic_modifier:
1906 * @window: a #GtkWindow
1908 * Returns the mnemonic modifier for this window. See
1909 * gtk_window_set_mnemonic_modifier().
1911 * Return value: the modifier mask used to activate
1912 * mnemonics on this window.
1915 gtk_window_get_mnemonic_modifier (GtkWindow *window)
1917 g_return_val_if_fail (GTK_IS_WINDOW (window), 0);
1919 return window->mnemonic_modifier;
1923 * gtk_window_set_position:
1924 * @window: a #GtkWindow.
1925 * @position: a position constraint.
1927 * Sets a position constraint for this window. If the old or new
1928 * constraint is %GTK_WIN_POS_CENTER_ALWAYS, this will also cause
1929 * the window to be repositioned to satisfy the new constraint.
1932 gtk_window_set_position (GtkWindow *window,
1933 GtkWindowPosition position)
1935 g_return_if_fail (GTK_IS_WINDOW (window));
1937 if (position == GTK_WIN_POS_CENTER_ALWAYS ||
1938 window->position == GTK_WIN_POS_CENTER_ALWAYS)
1940 GtkWindowGeometryInfo *info;
1942 info = gtk_window_get_geometry_info (window, TRUE);
1944 /* this flag causes us to re-request the CENTER_ALWAYS
1945 * constraint in gtk_window_move_resize(), see
1946 * comment in that function.
1948 info->position_constraints_changed = TRUE;
1950 gtk_widget_queue_resize_no_redraw (GTK_WIDGET (window));
1953 window->position = position;
1955 g_object_notify (G_OBJECT (window), "window-position");
1959 * gtk_window_activate_focus:
1960 * @window: a #GtkWindow
1962 * Activates the current focused widget within the window.
1964 * Return value: %TRUE if a widget got activated.
1967 gtk_window_activate_focus (GtkWindow *window)
1969 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
1971 if (window->focus_widget && GTK_WIDGET_IS_SENSITIVE (window->focus_widget))
1972 return gtk_widget_activate (window->focus_widget);
1978 * gtk_window_get_focus:
1979 * @window: a #GtkWindow
1981 * Retrieves the current focused widget within the window.
1982 * Note that this is the widget that would have the focus
1983 * if the toplevel window focused; if the toplevel window
1984 * is not focused then <literal>GTK_WIDGET_HAS_FOCUS (widget)</literal> will
1985 * not be %TRUE for the widget.
1987 * Return value: (transfer none): the currently focused widget, or %NULL if there is none.
1990 gtk_window_get_focus (GtkWindow *window)
1992 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
1994 return window->focus_widget;
1998 * gtk_window_activate_default:
1999 * @window: a #GtkWindow
2001 * Activates the default widget for the window, unless the current
2002 * focused widget has been configured to receive the default action
2003 * (see #GTK_RECEIVES_DEFAULT in #GtkWidgetFlags), in which case the
2004 * focused widget is activated.
2006 * Return value: %TRUE if a widget got activated.
2009 gtk_window_activate_default (GtkWindow *window)
2011 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
2013 if (window->default_widget && GTK_WIDGET_IS_SENSITIVE (window->default_widget) &&
2014 (!window->focus_widget || !GTK_WIDGET_RECEIVES_DEFAULT (window->focus_widget)))
2015 return gtk_widget_activate (window->default_widget);
2016 else if (window->focus_widget && GTK_WIDGET_IS_SENSITIVE (window->focus_widget))
2017 return gtk_widget_activate (window->focus_widget);
2023 * gtk_window_set_modal:
2024 * @window: a #GtkWindow
2025 * @modal: whether the window is modal
2027 * Sets a window modal or non-modal. Modal windows prevent interaction
2028 * with other windows in the same application. To keep modal dialogs
2029 * on top of main application windows, use
2030 * gtk_window_set_transient_for() to make the dialog transient for the
2031 * parent; most <link linkend="gtk-X11-arch">window managers</link>
2032 * will then disallow lowering the dialog below the parent.
2037 gtk_window_set_modal (GtkWindow *window,
2040 g_return_if_fail (GTK_IS_WINDOW (window));
2042 modal = modal != FALSE;
2043 if (window->modal == modal)
2046 window->modal = modal;
2048 /* adjust desired modality state */
2049 if (GTK_WIDGET_REALIZED (window))
2051 GtkWidget *widget = GTK_WIDGET (window);
2054 gdk_window_set_modal_hint (widget->window, TRUE);
2056 gdk_window_set_modal_hint (widget->window, FALSE);
2059 if (GTK_WIDGET_VISIBLE (window))
2062 gtk_grab_add (GTK_WIDGET (window));
2064 gtk_grab_remove (GTK_WIDGET (window));
2067 g_object_notify (G_OBJECT (window), "modal");
2071 * gtk_window_get_modal:
2072 * @window: a #GtkWindow
2074 * Returns whether the window is modal. See gtk_window_set_modal().
2076 * Return value: %TRUE if the window is set to be modal and
2077 * establishes a grab when shown
2080 gtk_window_get_modal (GtkWindow *window)
2082 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
2084 return window->modal;
2088 * gtk_window_list_toplevels:
2090 * Returns a list of all existing toplevel windows. The widgets
2091 * in the list are not individually referenced. If you want
2092 * to iterate through the list and perform actions involving
2093 * callbacks that might destroy the widgets, you <emphasis>must</emphasis> call
2094 * <literal>g_list_foreach (result, (GFunc)g_object_ref, NULL)</literal> first, and
2095 * then unref all the widgets afterwards.
2097 * Return value: (element-type GtkWidget) (transfer container): list of toplevel widgets
2100 gtk_window_list_toplevels (void)
2105 for (slist = toplevel_list; slist; slist = slist->next)
2106 list = g_list_prepend (list, slist->data);
2112 gtk_window_add_embedded_xid (GtkWindow *window, GdkNativeWindow xid)
2114 GList *embedded_windows;
2116 g_return_if_fail (GTK_IS_WINDOW (window));
2118 embedded_windows = g_object_get_qdata (G_OBJECT (window), quark_gtk_embedded);
2119 if (embedded_windows)
2120 g_object_steal_qdata (G_OBJECT (window), quark_gtk_embedded);
2121 embedded_windows = g_list_prepend (embedded_windows,
2122 GUINT_TO_POINTER (xid));
2124 g_object_set_qdata_full (G_OBJECT (window), quark_gtk_embedded,
2127 (GDestroyNotify) g_list_free : NULL);
2131 gtk_window_remove_embedded_xid (GtkWindow *window, GdkNativeWindow xid)
2133 GList *embedded_windows;
2136 g_return_if_fail (GTK_IS_WINDOW (window));
2138 embedded_windows = g_object_get_qdata (G_OBJECT (window), quark_gtk_embedded);
2139 if (embedded_windows)
2140 g_object_steal_qdata (G_OBJECT (window), quark_gtk_embedded);
2142 node = g_list_find (embedded_windows, GUINT_TO_POINTER (xid));
2145 embedded_windows = g_list_remove_link (embedded_windows, node);
2146 g_list_free_1 (node);
2149 g_object_set_qdata_full (G_OBJECT (window), quark_gtk_embedded,
2152 (GDestroyNotify) g_list_free : NULL);
2156 _gtk_window_reposition (GtkWindow *window,
2160 g_return_if_fail (GTK_IS_WINDOW (window));
2162 gtk_window_move (window, x, y);
2166 gtk_window_dispose (GObject *object)
2168 GtkWindow *window = GTK_WINDOW (object);
2170 gtk_window_set_focus (window, NULL);
2171 gtk_window_set_default (window, NULL);
2173 G_OBJECT_CLASS (gtk_window_parent_class)->dispose (object);
2177 parent_destroyed_callback (GtkWindow *parent, GtkWindow *child)
2179 gtk_widget_destroy (GTK_WIDGET (child));
2183 connect_parent_destroyed (GtkWindow *window)
2185 if (window->transient_parent)
2187 g_signal_connect (window->transient_parent,
2189 G_CALLBACK (parent_destroyed_callback),
2195 disconnect_parent_destroyed (GtkWindow *window)
2197 if (window->transient_parent)
2199 g_signal_handlers_disconnect_by_func (window->transient_parent,
2200 parent_destroyed_callback,
2206 gtk_window_transient_parent_realized (GtkWidget *parent,
2209 if (GTK_WIDGET_REALIZED (window))
2210 gdk_window_set_transient_for (window->window, parent->window);
2214 gtk_window_transient_parent_unrealized (GtkWidget *parent,
2217 if (GTK_WIDGET_REALIZED (window))
2218 gdk_property_delete (window->window,
2219 gdk_atom_intern_static_string ("WM_TRANSIENT_FOR"));
2223 gtk_window_transient_parent_screen_changed (GtkWindow *parent,
2227 gtk_window_set_screen (window, parent->screen);
2231 gtk_window_unset_transient_for (GtkWindow *window)
2233 GtkWindowPrivate *priv = GTK_WINDOW_GET_PRIVATE (window);
2235 if (window->transient_parent)
2237 g_signal_handlers_disconnect_by_func (window->transient_parent,
2238 gtk_window_transient_parent_realized,
2240 g_signal_handlers_disconnect_by_func (window->transient_parent,
2241 gtk_window_transient_parent_unrealized,
2243 g_signal_handlers_disconnect_by_func (window->transient_parent,
2244 gtk_window_transient_parent_screen_changed,
2246 g_signal_handlers_disconnect_by_func (window->transient_parent,
2247 gtk_widget_destroyed,
2248 &window->transient_parent);
2250 if (window->destroy_with_parent)
2251 disconnect_parent_destroyed (window);
2253 window->transient_parent = NULL;
2255 if (priv->transient_parent_group)
2257 priv->transient_parent_group = FALSE;
2258 gtk_window_group_remove_window (window->group,
2265 * gtk_window_set_transient_for:
2266 * @window: a #GtkWindow
2267 * @parent: (allow-none): parent window
2269 * Dialog windows should be set transient for the main application
2270 * window they were spawned from. This allows <link
2271 * linkend="gtk-X11-arch">window managers</link> to e.g. keep the
2272 * dialog on top of the main window, or center the dialog over the
2273 * main window. gtk_dialog_new_with_buttons() and other convenience
2274 * functions in GTK+ will sometimes call
2275 * gtk_window_set_transient_for() on your behalf.
2277 * On Windows, this function puts the child window on top of the parent,
2278 * much as the window manager would have done on X.
2282 gtk_window_set_transient_for (GtkWindow *window,
2285 GtkWindowPrivate *priv = GTK_WINDOW_GET_PRIVATE (window);
2287 g_return_if_fail (GTK_IS_WINDOW (window));
2288 g_return_if_fail (parent == NULL || GTK_IS_WINDOW (parent));
2289 g_return_if_fail (window != parent);
2291 if (window->transient_parent)
2293 if (GTK_WIDGET_REALIZED (window) &&
2294 GTK_WIDGET_REALIZED (window->transient_parent) &&
2295 (!parent || !GTK_WIDGET_REALIZED (parent)))
2296 gtk_window_transient_parent_unrealized (GTK_WIDGET (window->transient_parent),
2297 GTK_WIDGET (window));
2299 gtk_window_unset_transient_for (window);
2302 window->transient_parent = parent;
2306 g_signal_connect (parent, "destroy",
2307 G_CALLBACK (gtk_widget_destroyed),
2308 &window->transient_parent);
2309 g_signal_connect (parent, "realize",
2310 G_CALLBACK (gtk_window_transient_parent_realized),
2312 g_signal_connect (parent, "unrealize",
2313 G_CALLBACK (gtk_window_transient_parent_unrealized),
2315 g_signal_connect (parent, "notify::screen",
2316 G_CALLBACK (gtk_window_transient_parent_screen_changed),
2319 gtk_window_set_screen (window, parent->screen);
2321 if (window->destroy_with_parent)
2322 connect_parent_destroyed (window);
2324 if (GTK_WIDGET_REALIZED (window) &&
2325 GTK_WIDGET_REALIZED (parent))
2326 gtk_window_transient_parent_realized (GTK_WIDGET (parent),
2327 GTK_WIDGET (window));
2331 gtk_window_group_add_window (parent->group, window);
2332 priv->transient_parent_group = TRUE;
2338 * gtk_window_get_transient_for:
2339 * @window: a #GtkWindow
2341 * Fetches the transient parent for this window. See
2342 * gtk_window_set_transient_for().
2344 * Return value: (transfer none): the transient parent for this window, or %NULL
2345 * if no transient parent has been set.
2348 gtk_window_get_transient_for (GtkWindow *window)
2350 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
2352 return window->transient_parent;
2356 * gtk_window_set_opacity:
2357 * @window: a #GtkWindow
2358 * @opacity: desired opacity, between 0 and 1
2360 * Request the windowing system to make @window partially transparent,
2361 * with opacity 0 being fully transparent and 1 fully opaque. (Values
2362 * of the opacity parameter are clamped to the [0,1] range.) On X11
2363 * this has any effect only on X screens with a compositing manager
2364 * running. See gtk_widget_is_composited(). On Windows it should work
2367 * Note that setting a window's opacity after the window has been
2368 * shown causes it to flicker once on Windows.
2373 gtk_window_set_opacity (GtkWindow *window,
2376 GtkWindowPrivate *priv;
2378 g_return_if_fail (GTK_IS_WINDOW (window));
2380 priv = GTK_WINDOW_GET_PRIVATE (window);
2384 else if (opacity > 1.0)
2387 priv->opacity_set = TRUE;
2388 priv->opacity = opacity;
2390 if (GTK_WIDGET_REALIZED (window))
2391 gdk_window_set_opacity (GTK_WIDGET (window)->window, priv->opacity);
2395 * gtk_window_get_opacity:
2396 * @window: a #GtkWindow
2398 * Fetches the requested opacity for this window. See
2399 * gtk_window_set_opacity().
2401 * Return value: the requested opacity for this window.
2406 gtk_window_get_opacity (GtkWindow *window)
2408 GtkWindowPrivate *priv;
2410 g_return_val_if_fail (GTK_IS_WINDOW (window), 0.0);
2412 priv = GTK_WINDOW_GET_PRIVATE (window);
2414 return priv->opacity;
2418 * gtk_window_set_type_hint:
2419 * @window: a #GtkWindow
2420 * @hint: the window type
2422 * By setting the type hint for the window, you allow the window
2423 * manager to decorate and handle the window in a way which is
2424 * suitable to the function of the window in your application.
2426 * This function should be called before the window becomes visible.
2428 * gtk_dialog_new_with_buttons() and other convenience functions in GTK+
2429 * will sometimes call gtk_window_set_type_hint() on your behalf.
2433 gtk_window_set_type_hint (GtkWindow *window,
2434 GdkWindowTypeHint hint)
2436 GtkWindowPrivate *priv;
2438 g_return_if_fail (GTK_IS_WINDOW (window));
2439 g_return_if_fail (!GTK_WIDGET_MAPPED (window));
2441 priv = GTK_WINDOW_GET_PRIVATE (window);
2443 if (hint < GDK_WINDOW_TYPE_HINT_DROPDOWN_MENU)
2444 window->type_hint = hint;
2446 window->type_hint = GDK_WINDOW_TYPE_HINT_NORMAL;
2448 priv->reset_type_hint = TRUE;
2449 priv->type_hint = hint;
2453 * gtk_window_get_type_hint:
2454 * @window: a #GtkWindow
2456 * Gets the type hint for this window. See gtk_window_set_type_hint().
2458 * Return value: the type hint for @window.
2461 gtk_window_get_type_hint (GtkWindow *window)
2463 GtkWindowPrivate *priv;
2465 g_return_val_if_fail (GTK_IS_WINDOW (window), GDK_WINDOW_TYPE_HINT_NORMAL);
2467 priv = GTK_WINDOW_GET_PRIVATE (window);
2469 return priv->type_hint;
2473 * gtk_window_set_skip_taskbar_hint:
2474 * @window: a #GtkWindow
2475 * @setting: %TRUE to keep this window from appearing in the task bar
2477 * Windows may set a hint asking the desktop environment not to display
2478 * the window in the task bar. This function sets this hint.
2483 gtk_window_set_skip_taskbar_hint (GtkWindow *window,
2486 GtkWindowPrivate *priv;
2488 g_return_if_fail (GTK_IS_WINDOW (window));
2490 priv = GTK_WINDOW_GET_PRIVATE (window);
2492 setting = setting != FALSE;
2494 if (priv->skips_taskbar != setting)
2496 priv->skips_taskbar = setting;
2497 if (GTK_WIDGET_REALIZED (window))
2498 gdk_window_set_skip_taskbar_hint (GTK_WIDGET (window)->window,
2499 priv->skips_taskbar);
2500 g_object_notify (G_OBJECT (window), "skip-taskbar-hint");
2505 * gtk_window_get_skip_taskbar_hint:
2506 * @window: a #GtkWindow
2508 * Gets the value set by gtk_window_set_skip_taskbar_hint()
2510 * Return value: %TRUE if window shouldn't be in taskbar
2515 gtk_window_get_skip_taskbar_hint (GtkWindow *window)
2517 GtkWindowPrivate *priv;
2519 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
2521 priv = GTK_WINDOW_GET_PRIVATE (window);
2523 return priv->skips_taskbar;
2527 * gtk_window_set_skip_pager_hint:
2528 * @window: a #GtkWindow
2529 * @setting: %TRUE to keep this window from appearing in the pager
2531 * Windows may set a hint asking the desktop environment not to display
2532 * the window in the pager. This function sets this hint.
2533 * (A "pager" is any desktop navigation tool such as a workspace
2534 * switcher that displays a thumbnail representation of the windows
2540 gtk_window_set_skip_pager_hint (GtkWindow *window,
2543 GtkWindowPrivate *priv;
2545 g_return_if_fail (GTK_IS_WINDOW (window));
2547 priv = GTK_WINDOW_GET_PRIVATE (window);
2549 setting = setting != FALSE;
2551 if (priv->skips_pager != setting)
2553 priv->skips_pager = setting;
2554 if (GTK_WIDGET_REALIZED (window))
2555 gdk_window_set_skip_pager_hint (GTK_WIDGET (window)->window,
2557 g_object_notify (G_OBJECT (window), "skip-pager-hint");
2562 * gtk_window_get_skip_pager_hint:
2563 * @window: a #GtkWindow
2565 * Gets the value set by gtk_window_set_skip_pager_hint().
2567 * Return value: %TRUE if window shouldn't be in pager
2572 gtk_window_get_skip_pager_hint (GtkWindow *window)
2574 GtkWindowPrivate *priv;
2576 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
2578 priv = GTK_WINDOW_GET_PRIVATE (window);
2580 return priv->skips_pager;
2584 * gtk_window_set_urgency_hint:
2585 * @window: a #GtkWindow
2586 * @setting: %TRUE to mark this window as urgent
2588 * Windows may set a hint asking the desktop environment to draw
2589 * the users attention to the window. This function sets this hint.
2594 gtk_window_set_urgency_hint (GtkWindow *window,
2597 GtkWindowPrivate *priv;
2599 g_return_if_fail (GTK_IS_WINDOW (window));
2601 priv = GTK_WINDOW_GET_PRIVATE (window);
2603 setting = setting != FALSE;
2605 if (priv->urgent != setting)
2607 priv->urgent = setting;
2608 if (GTK_WIDGET_REALIZED (window))
2609 gdk_window_set_urgency_hint (GTK_WIDGET (window)->window,
2611 g_object_notify (G_OBJECT (window), "urgency-hint");
2616 * gtk_window_get_urgency_hint:
2617 * @window: a #GtkWindow
2619 * Gets the value set by gtk_window_set_urgency_hint()
2621 * Return value: %TRUE if window is urgent
2626 gtk_window_get_urgency_hint (GtkWindow *window)
2628 GtkWindowPrivate *priv;
2630 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
2632 priv = GTK_WINDOW_GET_PRIVATE (window);
2634 return priv->urgent;
2638 * gtk_window_set_accept_focus:
2639 * @window: a #GtkWindow
2640 * @setting: %TRUE to let this window receive input focus
2642 * Windows may set a hint asking the desktop environment not to receive
2643 * the input focus. This function sets this hint.
2648 gtk_window_set_accept_focus (GtkWindow *window,
2651 GtkWindowPrivate *priv;
2653 g_return_if_fail (GTK_IS_WINDOW (window));
2655 priv = GTK_WINDOW_GET_PRIVATE (window);
2657 setting = setting != FALSE;
2659 if (priv->accept_focus != setting)
2661 priv->accept_focus = setting;
2662 if (GTK_WIDGET_REALIZED (window))
2663 gdk_window_set_accept_focus (GTK_WIDGET (window)->window,
2664 priv->accept_focus);
2665 g_object_notify (G_OBJECT (window), "accept-focus");
2670 * gtk_window_get_accept_focus:
2671 * @window: a #GtkWindow
2673 * Gets the value set by gtk_window_set_accept_focus().
2675 * Return value: %TRUE if window should receive the input focus
2680 gtk_window_get_accept_focus (GtkWindow *window)
2682 GtkWindowPrivate *priv;
2684 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
2686 priv = GTK_WINDOW_GET_PRIVATE (window);
2688 return priv->accept_focus;
2692 * gtk_window_set_focus_on_map:
2693 * @window: a #GtkWindow
2694 * @setting: %TRUE to let this window receive input focus on map
2696 * Windows may set a hint asking the desktop environment not to receive
2697 * the input focus when the window is mapped. This function sets this
2703 gtk_window_set_focus_on_map (GtkWindow *window,
2706 GtkWindowPrivate *priv;
2708 g_return_if_fail (GTK_IS_WINDOW (window));
2710 priv = GTK_WINDOW_GET_PRIVATE (window);
2712 setting = setting != FALSE;
2714 if (priv->focus_on_map != setting)
2716 priv->focus_on_map = setting;
2717 if (GTK_WIDGET_REALIZED (window))
2718 gdk_window_set_focus_on_map (GTK_WIDGET (window)->window,
2719 priv->focus_on_map);
2720 g_object_notify (G_OBJECT (window), "focus-on-map");
2725 * gtk_window_get_focus_on_map:
2726 * @window: a #GtkWindow
2728 * Gets the value set by gtk_window_set_focus_on_map().
2730 * Return value: %TRUE if window should receive the input focus when
2736 gtk_window_get_focus_on_map (GtkWindow *window)
2738 GtkWindowPrivate *priv;
2740 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
2742 priv = GTK_WINDOW_GET_PRIVATE (window);
2744 return priv->focus_on_map;
2748 * gtk_window_set_destroy_with_parent:
2749 * @window: a #GtkWindow
2750 * @setting: whether to destroy @window with its transient parent
2752 * If @setting is %TRUE, then destroying the transient parent of @window
2753 * will also destroy @window itself. This is useful for dialogs that
2754 * shouldn't persist beyond the lifetime of the main window they're
2755 * associated with, for example.
2758 gtk_window_set_destroy_with_parent (GtkWindow *window,
2761 g_return_if_fail (GTK_IS_WINDOW (window));
2763 if (window->destroy_with_parent == (setting != FALSE))
2766 if (window->destroy_with_parent)
2768 disconnect_parent_destroyed (window);
2772 connect_parent_destroyed (window);
2775 window->destroy_with_parent = setting;
2777 g_object_notify (G_OBJECT (window), "destroy-with-parent");
2781 * gtk_window_get_destroy_with_parent:
2782 * @window: a #GtkWindow
2784 * Returns whether the window will be destroyed with its transient parent. See
2785 * gtk_window_set_destroy_with_parent ().
2787 * Return value: %TRUE if the window will be destroyed with its transient parent.
2790 gtk_window_get_destroy_with_parent (GtkWindow *window)
2792 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
2794 return window->destroy_with_parent;
2797 static GtkWindowGeometryInfo*
2798 gtk_window_get_geometry_info (GtkWindow *window,
2801 GtkWindowGeometryInfo *info;
2803 info = window->geometry_info;
2804 if (!info && create)
2806 info = g_new0 (GtkWindowGeometryInfo, 1);
2808 info->default_width = -1;
2809 info->default_height = -1;
2810 info->resize_width = -1;
2811 info->resize_height = -1;
2812 info->initial_x = 0;
2813 info->initial_y = 0;
2814 info->initial_pos_set = FALSE;
2815 info->default_is_geometry = FALSE;
2816 info->position_constraints_changed = FALSE;
2817 info->last.configure_request.x = 0;
2818 info->last.configure_request.y = 0;
2819 info->last.configure_request.width = -1;
2820 info->last.configure_request.height = -1;
2821 info->widget = NULL;
2823 window->geometry_info = info;
2830 * gtk_window_set_geometry_hints:
2831 * @window: a #GtkWindow
2832 * @geometry_widget: widget the geometry hints will be applied to
2833 * @geometry: struct containing geometry information
2834 * @geom_mask: mask indicating which struct fields should be paid attention to
2836 * This function sets up hints about how a window can be resized by
2837 * the user. You can set a minimum and maximum size; allowed resize
2838 * increments (e.g. for xterm, you can only resize by the size of a
2839 * character); aspect ratios; and more. See the #GdkGeometry struct.
2843 gtk_window_set_geometry_hints (GtkWindow *window,
2844 GtkWidget *geometry_widget,
2845 GdkGeometry *geometry,
2846 GdkWindowHints geom_mask)
2848 GtkWindowGeometryInfo *info;
2850 g_return_if_fail (GTK_IS_WINDOW (window));
2851 g_return_if_fail (geometry_widget == NULL || GTK_IS_WIDGET (geometry_widget));
2853 info = gtk_window_get_geometry_info (window, TRUE);
2856 g_signal_handlers_disconnect_by_func (info->widget,
2857 gtk_widget_destroyed,
2860 info->widget = geometry_widget;
2862 g_signal_connect (geometry_widget, "destroy",
2863 G_CALLBACK (gtk_widget_destroyed),
2867 info->geometry = *geometry;
2869 /* We store gravity in window->gravity not in the hints. */
2870 info->mask = geom_mask & ~(GDK_HINT_WIN_GRAVITY);
2872 if (geom_mask & GDK_HINT_WIN_GRAVITY)
2874 gtk_window_set_gravity (window, geometry->win_gravity);
2877 gtk_widget_queue_resize_no_redraw (GTK_WIDGET (window));
2881 * gtk_window_set_decorated:
2882 * @window: a #GtkWindow
2883 * @setting: %TRUE to decorate the window
2885 * By default, windows are decorated with a title bar, resize
2886 * controls, etc. Some <link linkend="gtk-X11-arch">window
2887 * managers</link> allow GTK+ to disable these decorations, creating a
2888 * borderless window. If you set the decorated property to %FALSE
2889 * using this function, GTK+ will do its best to convince the window
2890 * manager not to decorate the window. Depending on the system, this
2891 * function may not have any effect when called on a window that is
2892 * already visible, so you should call it before calling gtk_window_show().
2894 * On Windows, this function always works, since there's no window manager
2899 gtk_window_set_decorated (GtkWindow *window,
2902 g_return_if_fail (GTK_IS_WINDOW (window));
2904 setting = setting != FALSE;
2906 if (setting == window->decorated)
2909 window->decorated = setting;
2911 if (GTK_WIDGET (window)->window)
2913 if (window->decorated)
2914 gdk_window_set_decorations (GTK_WIDGET (window)->window,
2917 gdk_window_set_decorations (GTK_WIDGET (window)->window,
2921 g_object_notify (G_OBJECT (window), "decorated");
2925 * gtk_window_get_decorated:
2926 * @window: a #GtkWindow
2928 * Returns whether the window has been set to have decorations
2929 * such as a title bar via gtk_window_set_decorated().
2931 * Return value: %TRUE if the window has been set to have decorations
2934 gtk_window_get_decorated (GtkWindow *window)
2936 g_return_val_if_fail (GTK_IS_WINDOW (window), TRUE);
2938 return window->decorated;
2942 * gtk_window_set_deletable:
2943 * @window: a #GtkWindow
2944 * @setting: %TRUE to decorate the window as deletable
2946 * By default, windows have a close button in the window frame. Some
2947 * <link linkend="gtk-X11-arch">window managers</link> allow GTK+ to
2948 * disable this button. If you set the deletable property to %FALSE
2949 * using this function, GTK+ will do its best to convince the window
2950 * manager not to show a close button. Depending on the system, this
2951 * function may not have any effect when called on a window that is
2952 * already visible, so you should call it before calling gtk_window_show().
2954 * On Windows, this function always works, since there's no window manager
2960 gtk_window_set_deletable (GtkWindow *window,
2963 GtkWindowPrivate *priv;
2965 g_return_if_fail (GTK_IS_WINDOW (window));
2967 priv = GTK_WINDOW_GET_PRIVATE (window);
2969 setting = setting != FALSE;
2971 if (setting == priv->deletable)
2974 priv->deletable = setting;
2976 if (GTK_WIDGET (window)->window)
2978 if (priv->deletable)
2979 gdk_window_set_functions (GTK_WIDGET (window)->window,
2982 gdk_window_set_functions (GTK_WIDGET (window)->window,
2983 GDK_FUNC_ALL | GDK_FUNC_CLOSE);
2986 g_object_notify (G_OBJECT (window), "deletable");
2990 * gtk_window_get_deletable:
2991 * @window: a #GtkWindow
2993 * Returns whether the window has been set to have a close button
2994 * via gtk_window_set_deletable().
2996 * Return value: %TRUE if the window has been set to have a close button
3001 gtk_window_get_deletable (GtkWindow *window)
3003 GtkWindowPrivate *priv;
3005 g_return_val_if_fail (GTK_IS_WINDOW (window), TRUE);
3007 priv = GTK_WINDOW_GET_PRIVATE (window);
3009 return priv->deletable;
3012 static GtkWindowIconInfo*
3013 get_icon_info (GtkWindow *window)
3015 return g_object_get_qdata (G_OBJECT (window), quark_gtk_window_icon_info);
3019 free_icon_info (GtkWindowIconInfo *info)
3021 g_free (info->icon_name);
3022 g_slice_free (GtkWindowIconInfo, info);
3026 static GtkWindowIconInfo*
3027 ensure_icon_info (GtkWindow *window)
3029 GtkWindowIconInfo *info;
3031 info = get_icon_info (window);
3035 info = g_slice_new0 (GtkWindowIconInfo);
3036 g_object_set_qdata_full (G_OBJECT (window),
3037 quark_gtk_window_icon_info,
3039 (GDestroyNotify)free_icon_info);
3051 static ScreenIconInfo *
3052 get_screen_icon_info (GdkScreen *screen)
3054 ScreenIconInfo *info = g_object_get_qdata (G_OBJECT (screen),
3055 quark_gtk_window_default_icon_pixmap);
3058 info = g_slice_new0 (ScreenIconInfo);
3059 g_object_set_qdata (G_OBJECT (screen),
3060 quark_gtk_window_default_icon_pixmap, info);
3063 if (info->serial != default_icon_serial)
3067 g_object_remove_weak_pointer (G_OBJECT (info->pixmap), (gpointer*)&info->pixmap);
3068 info->pixmap = NULL;
3073 g_object_remove_weak_pointer (G_OBJECT (info->mask), (gpointer*)&info->mask);
3077 info->serial = default_icon_serial;
3084 get_pixmap_and_mask (GdkWindow *window,
3085 GtkWindowIconInfo *parent_info,
3086 gboolean is_default_list,
3088 GdkPixmap **pmap_return,
3089 GdkBitmap **mask_return)
3091 GdkScreen *screen = gdk_drawable_get_screen (window);
3092 ScreenIconInfo *default_icon_info = get_screen_icon_info (screen);
3093 GdkPixbuf *best_icon;
3097 *pmap_return = NULL;
3098 *mask_return = NULL;
3100 if (is_default_list &&
3101 default_icon_info->pixmap != NULL)
3103 /* Use shared icon pixmap for all windows on this screen.
3105 if (default_icon_info->pixmap)
3106 g_object_ref (default_icon_info->pixmap);
3107 if (default_icon_info->mask)
3108 g_object_ref (default_icon_info->mask);
3110 *pmap_return = default_icon_info->pixmap;
3111 *mask_return = default_icon_info->mask;
3113 else if (parent_info && parent_info->icon_pixmap)
3115 if (parent_info->icon_pixmap)
3116 g_object_ref (parent_info->icon_pixmap);
3117 if (parent_info->icon_mask)
3118 g_object_ref (parent_info->icon_mask);
3120 *pmap_return = parent_info->icon_pixmap;
3121 *mask_return = parent_info->icon_mask;
3125 #define IDEAL_SIZE 48
3127 best_size = G_MAXINT;
3129 tmp_list = icon_list;
3130 while (tmp_list != NULL)
3132 GdkPixbuf *pixbuf = tmp_list->data;
3135 /* average width and height - if someone passes in a rectangular
3136 * icon they deserve what they get.
3138 this = gdk_pixbuf_get_width (pixbuf) + gdk_pixbuf_get_height (pixbuf);
3141 if (best_icon == NULL)
3148 /* icon is better if it's 32 pixels or larger, and closer to
3149 * the ideal size than the current best.
3152 (ABS (best_size - IDEAL_SIZE) <
3153 ABS (this - IDEAL_SIZE)))
3160 tmp_list = tmp_list->next;
3164 gdk_pixbuf_render_pixmap_and_mask_for_colormap (best_icon,
3165 gdk_screen_get_system_colormap (screen),
3170 /* Save pmap/mask for others to use if appropriate */
3173 parent_info->icon_pixmap = *pmap_return;
3174 parent_info->icon_mask = *mask_return;
3176 if (parent_info->icon_pixmap)
3177 g_object_ref (parent_info->icon_pixmap);
3178 if (parent_info->icon_mask)
3179 g_object_ref (parent_info->icon_mask);
3181 else if (is_default_list)
3183 default_icon_info->pixmap = *pmap_return;
3184 default_icon_info->mask = *mask_return;
3186 if (default_icon_info->pixmap)
3187 g_object_add_weak_pointer (G_OBJECT (default_icon_info->pixmap),
3188 (gpointer*)&default_icon_info->pixmap);
3189 if (default_icon_info->mask)
3190 g_object_add_weak_pointer (G_OBJECT (default_icon_info->mask),
3191 (gpointer*)&default_icon_info->mask);
3197 icon_list_from_theme (GtkWidget *widget,
3202 GtkIconTheme *icon_theme;
3207 icon_theme = gtk_icon_theme_get_for_screen (gtk_widget_get_screen (widget));
3209 sizes = gtk_icon_theme_get_icon_sizes (icon_theme, name);
3212 for (i = 0; sizes[i]; i++)
3215 * We need an EWMH extension to handle scalable icons
3216 * by passing their name to the WM. For now just use a
3220 icon = gtk_icon_theme_load_icon (icon_theme, name,
3223 icon = gtk_icon_theme_load_icon (icon_theme, name,
3226 list = g_list_append (list, icon);
3236 gtk_window_realize_icon (GtkWindow *window)
3239 GtkWindowIconInfo *info;
3242 widget = GTK_WIDGET (window);
3244 g_return_if_fail (widget->window != NULL);
3246 /* no point setting an icon on override-redirect */
3247 if (window->type == GTK_WINDOW_POPUP)
3252 info = ensure_icon_info (window);
3257 g_return_if_fail (info->icon_pixmap == NULL);
3258 g_return_if_fail (info->icon_mask == NULL);
3260 info->using_default_icon = FALSE;
3261 info->using_parent_icon = FALSE;
3262 info->using_themed_icon = FALSE;
3264 icon_list = info->icon_list;
3266 /* Look up themed icon */
3267 if (icon_list == NULL && info->icon_name)
3269 icon_list = icon_list_from_theme (widget, info->icon_name);
3271 info->using_themed_icon = TRUE;
3274 /* Inherit from transient parent */
3275 if (icon_list == NULL && window->transient_parent)
3277 icon_list = ensure_icon_info (window->transient_parent)->icon_list;
3279 info->using_parent_icon = TRUE;
3282 /* Inherit from default */
3283 if (icon_list == NULL)
3285 icon_list = default_icon_list;
3287 info->using_default_icon = TRUE;
3290 /* Look up themed icon */
3291 if (icon_list == NULL && default_icon_name)
3293 icon_list = icon_list_from_theme (widget, default_icon_name);
3294 info->using_default_icon = TRUE;
3295 info->using_themed_icon = TRUE;
3298 gdk_window_set_icon_list (widget->window, icon_list);
3300 get_pixmap_and_mask (widget->window,
3301 info->using_parent_icon ? ensure_icon_info (window->transient_parent) : NULL,
3302 info->using_default_icon,
3307 /* This is a slight ICCCM violation since it's a color pixmap not
3308 * a bitmap, but everyone does it.
3310 gdk_window_set_icon (widget->window,
3315 info->realized = TRUE;
3317 if (info->using_themed_icon)
3319 GtkIconTheme *icon_theme;
3321 g_list_foreach (icon_list, (GFunc) g_object_unref, NULL);
3322 g_list_free (icon_list);
3324 icon_theme = gtk_icon_theme_get_for_screen (gtk_widget_get_screen (GTK_WIDGET (window)));
3325 g_signal_connect (icon_theme, "changed",
3326 G_CALLBACK (update_themed_icon), window);
3331 gtk_window_unrealize_icon (GtkWindow *window)
3333 GtkWindowIconInfo *info;
3335 info = get_icon_info (window);
3340 if (info->icon_pixmap)
3341 g_object_unref (info->icon_pixmap);
3343 if (info->icon_mask)
3344 g_object_unref (info->icon_mask);
3346 info->icon_pixmap = NULL;
3347 info->icon_mask = NULL;
3349 if (info->using_themed_icon)
3351 GtkIconTheme *icon_theme;
3353 icon_theme = gtk_icon_theme_get_for_screen (gtk_widget_get_screen (GTK_WIDGET (window)));
3355 g_signal_handlers_disconnect_by_func (icon_theme, update_themed_icon, window);
3358 /* We don't clear the properties on the window, just figure the
3359 * window is going away.
3362 info->realized = FALSE;
3367 * gtk_window_set_icon_list:
3368 * @window: a #GtkWindow
3369 * @list: list of #GdkPixbuf
3371 * Sets up the icon representing a #GtkWindow. The icon is used when
3372 * the window is minimized (also known as iconified). Some window
3373 * managers or desktop environments may also place it in the window
3374 * frame, or display it in other contexts.
3376 * gtk_window_set_icon_list() allows you to pass in the same icon in
3377 * several hand-drawn sizes. The list should contain the natural sizes
3378 * your icon is available in; that is, don't scale the image before
3379 * passing it to GTK+. Scaling is postponed until the last minute,
3380 * when the desired final size is known, to allow best quality.
3382 * By passing several sizes, you may improve the final image quality
3383 * of the icon, by reducing or eliminating automatic image scaling.
3385 * Recommended sizes to provide: 16x16, 32x32, 48x48 at minimum, and
3386 * larger images (64x64, 128x128) if you have them.
3388 * See also gtk_window_set_default_icon_list() to set the icon
3389 * for all windows in your application in one go.
3391 * Note that transient windows (those who have been set transient for another
3392 * window using gtk_window_set_transient_for()) will inherit their
3393 * icon from their transient parent. So there's no need to explicitly
3394 * set the icon on transient windows.
3397 gtk_window_set_icon_list (GtkWindow *window,
3400 GtkWindowIconInfo *info;
3402 g_return_if_fail (GTK_IS_WINDOW (window));
3404 info = ensure_icon_info (window);
3406 if (info->icon_list == list) /* check for NULL mostly */
3409 g_list_foreach (list,
3410 (GFunc) g_object_ref, NULL);
3412 g_list_foreach (info->icon_list,
3413 (GFunc) g_object_unref, NULL);
3415 g_list_free (info->icon_list);
3417 info->icon_list = g_list_copy (list);
3419 g_object_notify (G_OBJECT (window), "icon");
3421 gtk_window_unrealize_icon (window);
3423 if (GTK_WIDGET_REALIZED (window))
3424 gtk_window_realize_icon (window);
3426 /* We could try to update our transient children, but I don't think
3427 * it's really worth it. If we did it, the best way would probably
3428 * be to have children connect to notify::icon-list
3433 * gtk_window_get_icon_list:
3434 * @window: a #GtkWindow
3436 * Retrieves the list of icons set by gtk_window_set_icon_list().
3437 * The list is copied, but the reference count on each
3438 * member won't be incremented.
3440 * Return value: (element-type GdkPixbuf) (transfer container): copy of window's icon list
3443 gtk_window_get_icon_list (GtkWindow *window)
3445 GtkWindowIconInfo *info;
3447 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
3449 info = get_icon_info (window);
3452 return g_list_copy (info->icon_list);
3458 * gtk_window_set_icon:
3459 * @window: a #GtkWindow
3460 * @icon: (allow-none): icon image, or %NULL
3462 * Sets up the icon representing a #GtkWindow. This icon is used when
3463 * the window is minimized (also known as iconified). Some window
3464 * managers or desktop environments may also place it in the window
3465 * frame, or display it in other contexts.
3467 * The icon should be provided in whatever size it was naturally
3468 * drawn; that is, don't scale the image before passing it to
3469 * GTK+. Scaling is postponed until the last minute, when the desired
3470 * final size is known, to allow best quality.
3472 * If you have your icon hand-drawn in multiple sizes, use
3473 * gtk_window_set_icon_list(). Then the best size will be used.
3475 * This function is equivalent to calling gtk_window_set_icon_list()
3476 * with a 1-element list.
3478 * See also gtk_window_set_default_icon_list() to set the icon
3479 * for all windows in your application in one go.
3482 gtk_window_set_icon (GtkWindow *window,
3487 g_return_if_fail (GTK_IS_WINDOW (window));
3488 g_return_if_fail (icon == NULL || GDK_IS_PIXBUF (icon));
3493 list = g_list_append (list, icon);
3495 gtk_window_set_icon_list (window, list);
3501 update_themed_icon (GtkIconTheme *icon_theme,
3504 g_object_notify (G_OBJECT (window), "icon");
3506 gtk_window_unrealize_icon (window);
3508 if (GTK_WIDGET_REALIZED (window))
3509 gtk_window_realize_icon (window);
3513 * gtk_window_set_icon_name:
3514 * @window: a #GtkWindow
3515 * @name: (allow-none): the name of the themed icon
3517 * Sets the icon for the window from a named themed icon. See
3518 * the docs for #GtkIconTheme for more details.
3520 * Note that this has nothing to do with the WM_ICON_NAME
3521 * property which is mentioned in the ICCCM.
3526 gtk_window_set_icon_name (GtkWindow *window,
3529 GtkWindowIconInfo *info;
3532 g_return_if_fail (GTK_IS_WINDOW (window));
3534 info = ensure_icon_info (window);
3536 if (g_strcmp0 (info->icon_name, name) == 0)
3539 tmp = info->icon_name;
3540 info->icon_name = g_strdup (name);
3543 g_list_foreach (info->icon_list, (GFunc) g_object_unref, NULL);
3544 g_list_free (info->icon_list);
3545 info->icon_list = NULL;
3547 update_themed_icon (NULL, window);
3549 g_object_notify (G_OBJECT (window), "icon-name");
3553 * gtk_window_get_icon_name:
3554 * @window: a #GtkWindow
3556 * Returns the name of the themed icon for the window,
3557 * see gtk_window_set_icon_name().
3559 * Returns: the icon name or %NULL if the window has
3564 G_CONST_RETURN gchar *
3565 gtk_window_get_icon_name (GtkWindow *window)
3567 GtkWindowIconInfo *info;
3569 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
3571 info = ensure_icon_info (window);
3573 return info->icon_name;
3577 * gtk_window_get_icon:
3578 * @window: a #GtkWindow
3580 * Gets the value set by gtk_window_set_icon() (or if you've
3581 * called gtk_window_set_icon_list(), gets the first icon in
3584 * Return value: (transfer none): icon for window
3587 gtk_window_get_icon (GtkWindow *window)
3589 GtkWindowIconInfo *info;
3591 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
3593 info = get_icon_info (window);
3594 if (info && info->icon_list)
3595 return GDK_PIXBUF (info->icon_list->data);
3600 /* Load pixbuf, printing warning on failure if error == NULL
3603 load_pixbuf_verbosely (const char *filename,
3606 GError *local_err = NULL;
3609 pixbuf = gdk_pixbuf_new_from_file (filename, &local_err);
3617 g_warning ("Error loading icon from file '%s':\n\t%s",
3618 filename, local_err->message);
3619 g_error_free (local_err);
3627 * gtk_window_set_icon_from_file:
3628 * @window: a #GtkWindow
3629 * @filename: location of icon file
3630 * @err: location to store error, or %NULL.
3632 * Sets the icon for @window.
3633 * Warns on failure if @err is %NULL.
3635 * This function is equivalent to calling gtk_window_set_icon()
3636 * with a pixbuf created by loading the image from @filename.
3638 * Returns: %TRUE if setting the icon succeeded.
3643 gtk_window_set_icon_from_file (GtkWindow *window,
3644 const gchar *filename,
3647 GdkPixbuf *pixbuf = load_pixbuf_verbosely (filename, err);
3651 gtk_window_set_icon (window, pixbuf);
3652 g_object_unref (pixbuf);
3661 * gtk_window_set_default_icon_list:
3662 * @list: a list of #GdkPixbuf
3664 * Sets an icon list to be used as fallback for windows that haven't
3665 * had gtk_window_set_icon_list() called on them to set up a
3666 * window-specific icon list. This function allows you to set up the
3667 * icon for all windows in your app at once.
3669 * See gtk_window_set_icon_list() for more details.
3673 gtk_window_set_default_icon_list (GList *list)
3677 if (list == default_icon_list)
3680 /* Update serial so we don't used cached pixmaps/masks
3682 default_icon_serial++;
3684 g_list_foreach (list,
3685 (GFunc) g_object_ref, NULL);
3687 g_list_foreach (default_icon_list,
3688 (GFunc) g_object_unref, NULL);
3690 g_list_free (default_icon_list);
3692 default_icon_list = g_list_copy (list);
3694 /* Update all toplevels */
3695 toplevels = gtk_window_list_toplevels ();
3696 tmp_list = toplevels;
3697 while (tmp_list != NULL)
3699 GtkWindowIconInfo *info;
3700 GtkWindow *w = tmp_list->data;
3702 info = get_icon_info (w);
3703 if (info && info->using_default_icon)
3705 gtk_window_unrealize_icon (w);
3706 if (GTK_WIDGET_REALIZED (w))
3707 gtk_window_realize_icon (w);
3710 tmp_list = tmp_list->next;
3712 g_list_free (toplevels);
3716 * gtk_window_set_default_icon:
3719 * Sets an icon to be used as fallback for windows that haven't
3720 * had gtk_window_set_icon() called on them from a pixbuf.
3725 gtk_window_set_default_icon (GdkPixbuf *icon)
3729 g_return_if_fail (GDK_IS_PIXBUF (icon));
3731 list = g_list_prepend (NULL, icon);
3732 gtk_window_set_default_icon_list (list);
3737 * gtk_window_set_default_icon_name:
3738 * @name: the name of the themed icon
3740 * Sets an icon to be used as fallback for windows that haven't
3741 * had gtk_window_set_icon_list() called on them from a named
3742 * themed icon, see gtk_window_set_icon_name().
3747 gtk_window_set_default_icon_name (const gchar *name)
3752 /* Update serial so we don't used cached pixmaps/masks
3754 default_icon_serial++;
3756 g_free (default_icon_name);
3757 default_icon_name = g_strdup (name);
3759 g_list_foreach (default_icon_list,
3760 (GFunc) g_object_unref, NULL);
3762 g_list_free (default_icon_list);
3763 default_icon_list = NULL;
3765 /* Update all toplevels */
3766 toplevels = gtk_window_list_toplevels ();
3767 tmp_list = toplevels;
3768 while (tmp_list != NULL)
3770 GtkWindowIconInfo *info;
3771 GtkWindow *w = tmp_list->data;
3773 info = get_icon_info (w);
3774 if (info && info->using_default_icon && info->using_themed_icon)
3776 gtk_window_unrealize_icon (w);
3777 if (GTK_WIDGET_REALIZED (w))
3778 gtk_window_realize_icon (w);
3781 tmp_list = tmp_list->next;
3783 g_list_free (toplevels);
3787 * gtk_window_get_default_icon_name:
3789 * Returns the fallback icon name for windows that has been set
3790 * with gtk_window_set_default_icon_name(). The returned
3791 * string is owned by GTK+ and should not be modified. It
3792 * is only valid until the next call to
3793 * gtk_window_set_default_icon_name().
3795 * Returns: the fallback icon name for windows
3800 gtk_window_get_default_icon_name (void)
3802 return default_icon_name;
3806 * gtk_window_set_default_icon_from_file:
3807 * @filename: location of icon file
3808 * @err: location to store error, or %NULL.
3810 * Sets an icon to be used as fallback for windows that haven't
3811 * had gtk_window_set_icon_list() called on them from a file
3812 * on disk. Warns on failure if @err is %NULL.
3814 * Returns: %TRUE if setting the icon succeeded.
3819 gtk_window_set_default_icon_from_file (const gchar *filename,
3822 GdkPixbuf *pixbuf = load_pixbuf_verbosely (filename, err);
3826 gtk_window_set_default_icon (pixbuf);
3827 g_object_unref (pixbuf);
3836 * gtk_window_get_default_icon_list:
3838 * Gets the value set by gtk_window_set_default_icon_list().
3839 * The list is a copy and should be freed with g_list_free(),
3840 * but the pixbufs in the list have not had their reference count
3843 * Return value: copy of default icon list
3846 gtk_window_get_default_icon_list (void)
3848 return g_list_copy (default_icon_list);
3852 gtk_window_set_default_size_internal (GtkWindow *window,
3853 gboolean change_width,
3855 gboolean change_height,
3857 gboolean is_geometry)
3859 GtkWindowGeometryInfo *info;
3861 g_return_if_fail (change_width == FALSE || width >= -1);
3862 g_return_if_fail (change_height == FALSE || height >= -1);
3864 info = gtk_window_get_geometry_info (window, TRUE);
3866 g_object_freeze_notify (G_OBJECT (window));
3868 info->default_is_geometry = is_geometry != FALSE;
3878 info->default_width = width;
3880 g_object_notify (G_OBJECT (window), "default-width");
3891 info->default_height = height;
3893 g_object_notify (G_OBJECT (window), "default-height");
3896 g_object_thaw_notify (G_OBJECT (window));
3898 gtk_widget_queue_resize_no_redraw (GTK_WIDGET (window));
3902 * gtk_window_set_default_size:
3903 * @window: a #GtkWindow
3904 * @width: width in pixels, or -1 to unset the default width
3905 * @height: height in pixels, or -1 to unset the default height
3907 * Sets the default size of a window. If the window's "natural" size
3908 * (its size request) is larger than the default, the default will be
3909 * ignored. More generally, if the default size does not obey the
3910 * geometry hints for the window (gtk_window_set_geometry_hints() can
3911 * be used to set these explicitly), the default size will be clamped
3912 * to the nearest permitted size.
3914 * Unlike gtk_widget_set_size_request(), which sets a size request for
3915 * a widget and thus would keep users from shrinking the window, this
3916 * function only sets the initial size, just as if the user had
3917 * resized the window themselves. Users can still shrink the window
3918 * again as they normally would. Setting a default size of -1 means to
3919 * use the "natural" default size (the size request of the window).
3921 * For more control over a window's initial size and how resizing works,
3922 * investigate gtk_window_set_geometry_hints().
3924 * For some uses, gtk_window_resize() is a more appropriate function.
3925 * gtk_window_resize() changes the current size of the window, rather
3926 * than the size to be used on initial display. gtk_window_resize() always
3927 * affects the window itself, not the geometry widget.
3929 * The default size of a window only affects the first time a window is
3930 * shown; if a window is hidden and re-shown, it will remember the size
3931 * it had prior to hiding, rather than using the default size.
3933 * Windows can't actually be 0x0 in size, they must be at least 1x1, but
3934 * passing 0 for @width and @height is OK, resulting in a 1x1 default size.
3937 gtk_window_set_default_size (GtkWindow *window,
3941 g_return_if_fail (GTK_IS_WINDOW (window));
3942 g_return_if_fail (width >= -1);
3943 g_return_if_fail (height >= -1);
3945 gtk_window_set_default_size_internal (window, TRUE, width, TRUE, height, FALSE);
3949 * gtk_window_get_default_size:
3950 * @window: a #GtkWindow
3951 * @width: location to store the default width, or %NULL
3952 * @height: location to store the default height, or %NULL
3954 * Gets the default size of the window. A value of -1 for the width or
3955 * height indicates that a default size has not been explicitly set
3956 * for that dimension, so the "natural" size of the window will be
3961 gtk_window_get_default_size (GtkWindow *window,
3965 GtkWindowGeometryInfo *info;
3967 g_return_if_fail (GTK_IS_WINDOW (window));
3969 info = gtk_window_get_geometry_info (window, FALSE);
3972 *width = info ? info->default_width : -1;
3975 *height = info ? info->default_height : -1;
3979 * gtk_window_resize:
3980 * @window: a #GtkWindow
3981 * @width: width in pixels to resize the window to
3982 * @height: height in pixels to resize the window to
3984 * Resizes the window as if the user had done so, obeying geometry
3985 * constraints. The default geometry constraint is that windows may
3986 * not be smaller than their size request; to override this
3987 * constraint, call gtk_widget_set_size_request() to set the window's
3988 * request to a smaller value.
3990 * If gtk_window_resize() is called before showing a window for the
3991 * first time, it overrides any default size set with
3992 * gtk_window_set_default_size().
3994 * Windows may not be resized smaller than 1 by 1 pixels.
3998 gtk_window_resize (GtkWindow *window,
4002 GtkWindowGeometryInfo *info;
4004 g_return_if_fail (GTK_IS_WINDOW (window));
4005 g_return_if_fail (width > 0);
4006 g_return_if_fail (height > 0);
4008 info = gtk_window_get_geometry_info (window, TRUE);
4010 info->resize_width = width;
4011 info->resize_height = height;
4013 gtk_widget_queue_resize_no_redraw (GTK_WIDGET (window));
4017 * gtk_window_get_size:
4018 * @window: a #GtkWindow
4019 * @width: (out): return location for width, or %NULL
4020 * @height: (out): return location for height, or %NULL
4022 * Obtains the current size of @window. If @window is not onscreen,
4023 * it returns the size GTK+ will suggest to the <link
4024 * linkend="gtk-X11-arch">window manager</link> for the initial window
4025 * size (but this is not reliably the same as the size the window
4026 * manager will actually select). The size obtained by
4027 * gtk_window_get_size() is the last size received in a
4028 * #GdkEventConfigure, that is, GTK+ uses its locally-stored size,
4029 * rather than querying the X server for the size. As a result, if you
4030 * call gtk_window_resize() then immediately call
4031 * gtk_window_get_size(), the size won't have taken effect yet. After
4032 * the window manager processes the resize request, GTK+ receives
4033 * notification that the size has changed via a configure event, and
4034 * the size of the window gets updated.
4036 * Note 1: Nearly any use of this function creates a race condition,
4037 * because the size of the window may change between the time that you
4038 * get the size and the time that you perform some action assuming
4039 * that size is the current size. To avoid race conditions, connect to
4040 * "configure-event" on the window and adjust your size-dependent
4041 * state to match the size delivered in the #GdkEventConfigure.
4043 * Note 2: The returned size does <emphasis>not</emphasis> include the
4044 * size of the window manager decorations (aka the window frame or
4045 * border). Those are not drawn by GTK+ and GTK+ has no reliable
4046 * method of determining their size.
4048 * Note 3: If you are getting a window size in order to position
4049 * the window onscreen, there may be a better way. The preferred
4050 * way is to simply set the window's semantic type with
4051 * gtk_window_set_type_hint(), which allows the window manager to
4052 * e.g. center dialogs. Also, if you set the transient parent of
4053 * dialogs with gtk_window_set_transient_for() window managers
4054 * will often center the dialog over its parent window. It's
4055 * much preferred to let the window manager handle these
4056 * things rather than doing it yourself, because all apps will
4057 * behave consistently and according to user prefs if the window
4058 * manager handles it. Also, the window manager can take the size
4059 * of the window decorations/border into account, while your
4060 * application cannot.
4062 * In any case, if you insist on application-specified window
4063 * positioning, there's <emphasis>still</emphasis> a better way than
4064 * doing it yourself - gtk_window_set_position() will frequently
4065 * handle the details for you.
4069 gtk_window_get_size (GtkWindow *window,
4075 g_return_if_fail (GTK_IS_WINDOW (window));
4077 if (width == NULL && height == NULL)
4080 if (GTK_WIDGET_MAPPED (window))
4082 gdk_drawable_get_size (GTK_WIDGET (window)->window,
4087 GdkRectangle configure_request;
4089 gtk_window_compute_configure_request (window,
4093 w = configure_request.width;
4094 h = configure_request.height;
4105 * @window: a #GtkWindow
4106 * @x: X coordinate to move window to
4107 * @y: Y coordinate to move window to
4109 * Asks the <link linkend="gtk-X11-arch">window manager</link> to move
4110 * @window to the given position. Window managers are free to ignore
4111 * this; most window managers ignore requests for initial window
4112 * positions (instead using a user-defined placement algorithm) and
4113 * honor requests after the window has already been shown.
4115 * Note: the position is the position of the gravity-determined
4116 * reference point for the window. The gravity determines two things:
4117 * first, the location of the reference point in root window
4118 * coordinates; and second, which point on the window is positioned at
4119 * the reference point.
4121 * By default the gravity is #GDK_GRAVITY_NORTH_WEST, so the reference
4122 * point is simply the @x, @y supplied to gtk_window_move(). The
4123 * top-left corner of the window decorations (aka window frame or
4124 * border) will be placed at @x, @y. Therefore, to position a window
4125 * at the top left of the screen, you want to use the default gravity
4126 * (which is #GDK_GRAVITY_NORTH_WEST) and move the window to 0,0.
4128 * To position a window at the bottom right corner of the screen, you
4129 * would set #GDK_GRAVITY_SOUTH_EAST, which means that the reference
4130 * point is at @x + the window width and @y + the window height, and
4131 * the bottom-right corner of the window border will be placed at that
4132 * reference point. So, to place a window in the bottom right corner
4133 * you would first set gravity to south east, then write:
4134 * <literal>gtk_window_move (window, gdk_screen_width () - window_width,
4135 * gdk_screen_height () - window_height)</literal> (note that this
4136 * example does not take multi-head scenarios into account).
4138 * The Extended Window Manager Hints specification at <ulink
4139 * url="http://www.freedesktop.org/Standards/wm-spec">
4140 * http://www.freedesktop.org/Standards/wm-spec</ulink> has a
4141 * nice table of gravities in the "implementation notes" section.
4143 * The gtk_window_get_position() documentation may also be relevant.
4146 gtk_window_move (GtkWindow *window,
4150 GtkWindowGeometryInfo *info;
4153 g_return_if_fail (GTK_IS_WINDOW (window));
4155 widget = GTK_WIDGET (window);
4157 info = gtk_window_get_geometry_info (window, TRUE);
4159 if (GTK_WIDGET_MAPPED (window))
4161 /* we have now sent a request with this position
4162 * with currently-active constraints, so toggle flag.
4164 info->position_constraints_changed = FALSE;
4166 /* we only constrain if mapped - if not mapped,
4167 * then gtk_window_compute_configure_request()
4168 * will apply the constraints later, and we
4169 * don't want to lose information about
4170 * what position the user set before then.
4171 * i.e. if you do a move() then turn off POS_CENTER
4172 * then show the window, your move() will work.
4174 gtk_window_constrain_position (window,
4175 widget->allocation.width,
4176 widget->allocation.height,
4179 /* Note that this request doesn't go through our standard request
4180 * framework, e.g. doesn't increment configure_request_count,
4181 * doesn't set info->last, etc.; that's because
4182 * we don't save the info needed to arrive at this same request
4185 * To gtk_window_move_resize(), this will end up looking exactly
4186 * the same as the position being changed by the window
4190 /* FIXME are we handling gravity properly for framed windows? */
4192 gdk_window_move (window->frame,
4193 x - window->frame_left,
4194 y - window->frame_top);
4196 gdk_window_move (GTK_WIDGET (window)->window,
4201 /* Save this position to apply on mapping */
4202 info->initial_x = x;
4203 info->initial_y = y;
4204 info->initial_pos_set = TRUE;
4209 * gtk_window_get_position:
4210 * @window: a #GtkWindow
4211 * @root_x: return location for X coordinate of gravity-determined reference point
4212 * @root_y: return location for Y coordinate of gravity-determined reference point
4214 * This function returns the position you need to pass to
4215 * gtk_window_move() to keep @window in its current position. This
4216 * means that the meaning of the returned value varies with window
4217 * gravity. See gtk_window_move() for more details.
4219 * If you haven't changed the window gravity, its gravity will be
4220 * #GDK_GRAVITY_NORTH_WEST. This means that gtk_window_get_position()
4221 * gets the position of the top-left corner of the window manager
4222 * frame for the window. gtk_window_move() sets the position of this
4223 * same top-left corner.
4225 * gtk_window_get_position() is not 100% reliable because the X Window System
4226 * does not specify a way to obtain the geometry of the
4227 * decorations placed on a window by the window manager.
4228 * Thus GTK+ is using a "best guess" that works with most
4231 * Moreover, nearly all window managers are historically broken with
4232 * respect to their handling of window gravity. So moving a window to
4233 * its current position as returned by gtk_window_get_position() tends
4234 * to result in moving the window slightly. Window managers are
4235 * slowly getting better over time.
4237 * If a window has gravity #GDK_GRAVITY_STATIC the window manager
4238 * frame is not relevant, and thus gtk_window_get_position() will
4239 * always produce accurate results. However you can't use static
4240 * gravity to do things like place a window in a corner of the screen,
4241 * because static gravity ignores the window manager decorations.
4243 * If you are saving and restoring your application's window
4244 * positions, you should know that it's impossible for applications to
4245 * do this without getting it somewhat wrong because applications do
4246 * not have sufficient knowledge of window manager state. The Correct
4247 * Mechanism is to support the session management protocol (see the
4248 * "GnomeClient" object in the GNOME libraries for example) and allow
4249 * the window manager to save your window sizes and positions.
4254 gtk_window_get_position (GtkWindow *window,
4260 g_return_if_fail (GTK_IS_WINDOW (window));
4262 widget = GTK_WIDGET (window);
4264 if (window->gravity == GDK_GRAVITY_STATIC)
4266 if (GTK_WIDGET_MAPPED (widget))
4268 /* This does a server round-trip, which is sort of wrong;
4269 * but a server round-trip is inevitable for
4270 * gdk_window_get_frame_extents() in the usual
4271 * NorthWestGravity case below, so not sure what else to
4272 * do. We should likely be consistent about whether we get
4273 * the client-side info or the server-side info.
4275 gdk_window_get_origin (widget->window, root_x, root_y);
4279 GdkRectangle configure_request;
4281 gtk_window_compute_configure_request (window,
4285 *root_x = configure_request.x;
4286 *root_y = configure_request.y;
4291 GdkRectangle frame_extents;
4296 if (GTK_WIDGET_MAPPED (widget))
4299 gdk_window_get_frame_extents (window->frame, &frame_extents);
4301 gdk_window_get_frame_extents (widget->window, &frame_extents);
4302 x = frame_extents.x;
4303 y = frame_extents.y;
4304 gtk_window_get_size (window, &w, &h);
4308 /* We just say the frame has 0 size on all sides.
4309 * Not sure what else to do.
4311 gtk_window_compute_configure_request (window,
4314 x = frame_extents.x;
4315 y = frame_extents.y;
4316 w = frame_extents.width;
4317 h = frame_extents.height;
4320 switch (window->gravity)
4322 case GDK_GRAVITY_NORTH:
4323 case GDK_GRAVITY_CENTER:
4324 case GDK_GRAVITY_SOUTH:
4325 /* Find center of frame. */
4326 x += frame_extents.width / 2;
4327 /* Center client window on that point. */
4331 case GDK_GRAVITY_SOUTH_EAST:
4332 case GDK_GRAVITY_EAST:
4333 case GDK_GRAVITY_NORTH_EAST:
4334 /* Find right edge of frame */
4335 x += frame_extents.width;
4336 /* Align left edge of client at that point. */
4343 switch (window->gravity)
4345 case GDK_GRAVITY_WEST:
4346 case GDK_GRAVITY_CENTER:
4347 case GDK_GRAVITY_EAST:
4348 /* Find center of frame. */
4349 y += frame_extents.height / 2;
4350 /* Center client window there. */
4353 case GDK_GRAVITY_SOUTH_WEST:
4354 case GDK_GRAVITY_SOUTH:
4355 case GDK_GRAVITY_SOUTH_EAST:
4356 /* Find south edge of frame */
4357 y += frame_extents.height;
4358 /* Place bottom edge of client there */
4373 * gtk_window_reshow_with_initial_size:
4374 * @window: a #GtkWindow
4376 * Hides @window, then reshows it, resetting the
4377 * default size and position of the window. Used
4378 * by GUI builders only.
4381 gtk_window_reshow_with_initial_size (GtkWindow *window)
4385 g_return_if_fail (GTK_IS_WINDOW (window));
4387 widget = GTK_WIDGET (window);
4389 gtk_widget_hide (widget);
4390 gtk_widget_unrealize (widget);
4391 gtk_widget_show (widget);
4395 gtk_window_destroy (GtkObject *object)
4397 GtkWindow *window = GTK_WINDOW (object);
4399 toplevel_list = g_slist_remove (toplevel_list, window);
4401 if (window->transient_parent)
4402 gtk_window_set_transient_for (window, NULL);
4404 /* frees the icons */
4405 gtk_window_set_icon_list (window, NULL);
4407 if (window->has_user_ref_count)
4409 window->has_user_ref_count = FALSE;
4410 g_object_unref (window);
4414 gtk_window_group_remove_window (window->group, window);
4416 gtk_window_free_key_hash (window);
4418 GTK_OBJECT_CLASS (gtk_window_parent_class)->destroy (object);
4422 gtk_window_finalize (GObject *object)
4424 GtkWindow *window = GTK_WINDOW (object);
4425 GtkWindowPrivate *priv = GTK_WINDOW_GET_PRIVATE (window);
4426 GtkMnemonicHash *mnemonic_hash;
4428 g_free (window->title);
4429 g_free (window->wmclass_name);
4430 g_free (window->wmclass_class);
4431 g_free (window->wm_role);
4433 mnemonic_hash = gtk_window_get_mnemonic_hash (window, FALSE);
4435 _gtk_mnemonic_hash_free (mnemonic_hash);
4437 if (window->geometry_info)
4439 if (window->geometry_info->widget)
4440 g_signal_handlers_disconnect_by_func (window->geometry_info->widget,
4441 gtk_widget_destroyed,
4442 &window->geometry_info->widget);
4443 g_free (window->geometry_info);
4446 if (window->keys_changed_handler)
4448 g_source_remove (window->keys_changed_handler);
4449 window->keys_changed_handler = 0;
4453 g_signal_handlers_disconnect_by_func (window->screen,
4454 gtk_window_on_composited_changed, window);
4456 g_free (priv->startup_id);
4458 G_OBJECT_CLASS (gtk_window_parent_class)->finalize (object);
4462 gtk_window_show (GtkWidget *widget)
4464 GtkWindow *window = GTK_WINDOW (widget);
4465 GtkContainer *container = GTK_CONTAINER (window);
4466 gboolean need_resize;
4468 GTK_WIDGET_SET_FLAGS (widget, GTK_VISIBLE);
4470 need_resize = container->need_resize || !GTK_WIDGET_REALIZED (widget);
4471 container->need_resize = FALSE;
4475 GtkWindowGeometryInfo *info = gtk_window_get_geometry_info (window, TRUE);
4476 GtkAllocation allocation = { 0, 0 };
4477 GdkRectangle configure_request;
4478 GdkGeometry new_geometry;
4480 gboolean was_realized;
4482 /* We are going to go ahead and perform this configure request
4483 * and then emulate a configure notify by going ahead and
4484 * doing a size allocate. Sort of a synchronous
4485 * mini-copy of gtk_window_move_resize() here.
4487 gtk_window_compute_configure_request (window,
4492 /* We update this because we are going to go ahead
4493 * and gdk_window_resize() below, rather than
4496 info->last.configure_request.width = configure_request.width;
4497 info->last.configure_request.height = configure_request.height;
4499 /* and allocate the window - this is normally done
4500 * in move_resize in response to configure notify
4502 allocation.width = configure_request.width;
4503 allocation.height = configure_request.height;
4504 gtk_widget_size_allocate (widget, &allocation);
4506 /* Then we guarantee we have a realize */
4507 was_realized = FALSE;
4508 if (!GTK_WIDGET_REALIZED (widget))
4510 gtk_widget_realize (widget);
4511 was_realized = TRUE;
4514 /* Must be done after the windows are realized,
4515 * so that the decorations can be read
4517 gtk_decorated_window_calculate_frame_size (window);
4519 /* We only send configure request if we didn't just finish
4520 * creating the window; if we just created the window
4521 * then we created it with widget->allocation anyhow.
4524 gdk_window_move_resize (widget->window,
4525 configure_request.x,
4526 configure_request.y,
4527 configure_request.width,
4528 configure_request.height);
4531 gtk_container_check_resize (container);
4533 gtk_widget_map (widget);
4535 /* Try to make sure that we have some focused widget
4537 if (!window->focus_widget && !GTK_IS_PLUG (window))
4538 gtk_window_move_focus (window, GTK_DIR_TAB_FORWARD);
4541 gtk_grab_add (widget);
4545 gtk_window_hide (GtkWidget *widget)
4547 GtkWindow *window = GTK_WINDOW (widget);
4549 GTK_WIDGET_UNSET_FLAGS (widget, GTK_VISIBLE);
4550 gtk_widget_unmap (widget);
4553 gtk_grab_remove (widget);
4557 gtk_window_map (GtkWidget *widget)
4559 GtkWindow *window = GTK_WINDOW (widget);
4560 GtkWindowPrivate *priv = GTK_WINDOW_GET_PRIVATE (window);
4561 GdkWindow *toplevel;
4562 gboolean auto_mnemonics;
4564 GTK_WIDGET_SET_FLAGS (widget, GTK_MAPPED);
4566 if (window->bin.child &&
4567 GTK_WIDGET_VISIBLE (window->bin.child) &&
4568 !GTK_WIDGET_MAPPED (window->bin.child))
4569 gtk_widget_map (window->bin.child);
4572 toplevel = window->frame;
4574 toplevel = widget->window;
4576 if (window->maximize_initially)
4577 gdk_window_maximize (toplevel);
4579 gdk_window_unmaximize (toplevel);
4581 if (window->stick_initially)
4582 gdk_window_stick (toplevel);
4584 gdk_window_unstick (toplevel);
4586 if (window->iconify_initially)
4587 gdk_window_iconify (toplevel);
4589 gdk_window_deiconify (toplevel);
4591 if (priv->fullscreen_initially)
4592 gdk_window_fullscreen (toplevel);
4594 gdk_window_unfullscreen (toplevel);
4596 gdk_window_set_keep_above (toplevel, priv->above_initially);
4598 gdk_window_set_keep_below (toplevel, priv->below_initially);
4600 /* No longer use the default settings */
4601 window->need_default_size = FALSE;
4602 window->need_default_position = FALSE;
4604 if (priv->reset_type_hint)
4606 /* We should only reset the type hint when the application
4607 * used gtk_window_set_type_hint() to change the hint.
4608 * Some applications use X directly to change the properties;
4609 * in that case, we shouldn't overwrite what they did.
4611 gdk_window_set_type_hint (widget->window, priv->type_hint);
4612 priv->reset_type_hint = FALSE;
4615 gdk_window_show (widget->window);
4618 gdk_window_show (window->frame);
4620 if (!disable_startup_notification)
4622 /* Do we have a custom startup-notification id? */
4623 if (priv->startup_id != NULL)
4625 /* Make sure we have a "real" id */
4626 if (!startup_id_is_fake (priv->startup_id))
4627 gdk_notify_startup_complete_with_id (priv->startup_id);
4629 g_free (priv->startup_id);
4630 priv->startup_id = NULL;
4632 else if (!sent_startup_notification)
4634 sent_startup_notification = TRUE;
4635 gdk_notify_startup_complete ();
4639 /* if auto-mnemonics is enabled and mnemonics visible is not already set
4640 * (as in the case of popup menus), then hide mnemonics initially
4642 g_object_get (gtk_widget_get_settings (widget), "gtk-auto-mnemonics",
4643 &auto_mnemonics, NULL);
4644 if (auto_mnemonics && !priv->mnemonics_visible_set)
4645 gtk_window_set_mnemonics_visible (window, FALSE);
4649 gtk_window_map_event (GtkWidget *widget,
4652 if (!GTK_WIDGET_MAPPED (widget))
4654 /* we should be be unmapped, but are getting a MapEvent, this may happen
4655 * to toplevel XWindows if mapping was intercepted by a window manager
4656 * and an unmap request occoured while the MapRequestEvent was still
4657 * being handled. we work around this situaiton here by re-requesting
4658 * the window being unmapped. more details can be found in:
4659 * http://bugzilla.gnome.org/show_bug.cgi?id=316180
4661 gdk_window_hide (widget->window);
4667 gtk_window_unmap (GtkWidget *widget)
4669 GtkWindow *window = GTK_WINDOW (widget);
4670 GtkWindowPrivate *priv = GTK_WINDOW_GET_PRIVATE (widget);
4671 GtkWindowGeometryInfo *info;
4672 GdkWindowState state;
4674 GTK_WIDGET_UNSET_FLAGS (widget, GTK_MAPPED);
4676 gdk_window_withdraw (window->frame);
4678 gdk_window_withdraw (widget->window);
4680 window->configure_request_count = 0;
4681 window->configure_notify_received = FALSE;
4683 /* on unmap, we reset the default positioning of the window,
4684 * so it's placed again, but we don't reset the default
4685 * size of the window, so it's remembered.
4687 window->need_default_position = TRUE;
4689 info = gtk_window_get_geometry_info (window, FALSE);
4692 info->initial_pos_set = FALSE;
4693 info->position_constraints_changed = FALSE;
4696 state = gdk_window_get_state (widget->window);
4697 window->iconify_initially = (state & GDK_WINDOW_STATE_ICONIFIED) != 0;
4698 window->maximize_initially = (state & GDK_WINDOW_STATE_MAXIMIZED) != 0;
4699 window->stick_initially = (state & GDK_WINDOW_STATE_STICKY) != 0;
4700 priv->above_initially = (state & GDK_WINDOW_STATE_ABOVE) != 0;
4701 priv->below_initially = (state & GDK_WINDOW_STATE_BELOW) != 0;
4705 gtk_window_realize (GtkWidget *widget)
4708 GdkWindow *parent_window;
4709 GdkWindowAttr attributes;
4710 gint attributes_mask;
4711 GtkWindowPrivate *priv;
4713 window = GTK_WINDOW (widget);
4714 priv = GTK_WINDOW_GET_PRIVATE (window);
4716 /* ensure widget tree is properly size allocated */
4717 if (widget->allocation.x == -1 &&
4718 widget->allocation.y == -1 &&
4719 widget->allocation.width == 1 &&
4720 widget->allocation.height == 1)
4722 GtkRequisition requisition;
4723 GtkAllocation allocation = { 0, 0, 200, 200 };
4725 gtk_widget_size_request (widget, &requisition);
4726 if (requisition.width || requisition.height)
4728 /* non-empty window */
4729 allocation.width = requisition.width;
4730 allocation.height = requisition.height;
4732 gtk_widget_size_allocate (widget, &allocation);
4734 _gtk_container_queue_resize (GTK_CONTAINER (widget));
4736 g_return_if_fail (!GTK_WIDGET_REALIZED (widget));
4739 GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED);
4741 switch (window->type)
4743 case GTK_WINDOW_TOPLEVEL:
4744 attributes.window_type = GDK_WINDOW_TOPLEVEL;
4746 case GTK_WINDOW_POPUP:
4747 attributes.window_type = GDK_WINDOW_TEMP;
4750 g_warning (G_STRLOC": Unknown window type %d!", window->type);
4754 attributes.title = window->title;
4755 attributes.wmclass_name = window->wmclass_name;
4756 attributes.wmclass_class = window->wmclass_class;
4757 attributes.wclass = GDK_INPUT_OUTPUT;
4758 attributes.visual = gtk_widget_get_visual (widget);
4759 attributes.colormap = gtk_widget_get_colormap (widget);
4761 if (window->has_frame)
4763 attributes.width = widget->allocation.width + window->frame_left + window->frame_right;
4764 attributes.height = widget->allocation.height + window->frame_top + window->frame_bottom;
4765 attributes.event_mask = (GDK_EXPOSURE_MASK |
4766 GDK_KEY_PRESS_MASK |
4767 GDK_ENTER_NOTIFY_MASK |
4768 GDK_LEAVE_NOTIFY_MASK |
4769 GDK_FOCUS_CHANGE_MASK |
4770 GDK_STRUCTURE_MASK |
4771 GDK_BUTTON_MOTION_MASK |
4772 GDK_POINTER_MOTION_HINT_MASK |
4773 GDK_BUTTON_PRESS_MASK |
4774 GDK_BUTTON_RELEASE_MASK);
4776 attributes_mask = GDK_WA_VISUAL | GDK_WA_COLORMAP;
4778 window->frame = gdk_window_new (gtk_widget_get_root_window (widget),
4779 &attributes, attributes_mask);
4781 if (priv->opacity_set)
4782 gdk_window_set_opacity (window->frame, priv->opacity);
4784 gdk_window_set_user_data (window->frame, widget);
4786 attributes.window_type = GDK_WINDOW_CHILD;
4787 attributes.x = window->frame_left;
4788 attributes.y = window->frame_top;
4790 attributes_mask = GDK_WA_X | GDK_WA_Y;
4792 parent_window = window->frame;
4794 g_signal_connect (window,
4796 G_CALLBACK (gtk_window_event),
4801 attributes_mask = 0;
4802 parent_window = gtk_widget_get_root_window (widget);
4805 attributes.width = widget->allocation.width;
4806 attributes.height = widget->allocation.height;
4807 attributes.event_mask = gtk_widget_get_events (widget);
4808 attributes.event_mask |= (GDK_EXPOSURE_MASK |
4809 GDK_KEY_PRESS_MASK |
4810 GDK_KEY_RELEASE_MASK |
4811 GDK_ENTER_NOTIFY_MASK |
4812 GDK_LEAVE_NOTIFY_MASK |
4813 GDK_FOCUS_CHANGE_MASK |
4814 GDK_STRUCTURE_MASK);
4815 attributes.type_hint = priv->type_hint;
4817 attributes_mask |= GDK_WA_VISUAL | GDK_WA_COLORMAP | GDK_WA_TYPE_HINT;
4818 attributes_mask |= (window->title ? GDK_WA_TITLE : 0);
4819 attributes_mask |= (window->wmclass_name ? GDK_WA_WMCLASS : 0);
4821 widget->window = gdk_window_new (parent_window, &attributes, attributes_mask);
4823 if (!window->has_frame && priv->opacity_set)
4824 gdk_window_set_opacity (widget->window, priv->opacity);
4826 gdk_window_enable_synchronized_configure (widget->window);
4828 gdk_window_set_user_data (widget->window, window);
4830 widget->style = gtk_style_attach (widget->style, widget->window);
4831 gtk_style_set_background (widget->style, widget->window, GTK_STATE_NORMAL);
4833 gtk_style_set_background (widget->style, window->frame, GTK_STATE_NORMAL);
4835 /* This is a bad hack to set the window background. */
4836 gtk_window_paint (widget, NULL);
4838 if (window->transient_parent &&
4839 GTK_WIDGET_REALIZED (window->transient_parent))
4840 gdk_window_set_transient_for (widget->window,
4841 GTK_WIDGET (window->transient_parent)->window);
4843 if (window->wm_role)
4844 gdk_window_set_role (widget->window, window->wm_role);
4846 if (!window->decorated)
4847 gdk_window_set_decorations (widget->window, 0);
4849 if (!priv->deletable)
4850 gdk_window_set_functions (widget->window, GDK_FUNC_ALL | GDK_FUNC_CLOSE);
4852 if (gtk_window_get_skip_pager_hint (window))
4853 gdk_window_set_skip_pager_hint (widget->window, TRUE);
4855 if (gtk_window_get_skip_taskbar_hint (window))
4856 gdk_window_set_skip_taskbar_hint (widget->window, TRUE);
4858 if (gtk_window_get_accept_focus (window))
4859 gdk_window_set_accept_focus (widget->window, TRUE);
4861 gdk_window_set_accept_focus (widget->window, FALSE);
4863 if (gtk_window_get_focus_on_map (window))
4864 gdk_window_set_focus_on_map (widget->window, TRUE);
4866 gdk_window_set_focus_on_map (widget->window, FALSE);
4869 gdk_window_set_modal_hint (widget->window, TRUE);
4871 gdk_window_set_modal_hint (widget->window, FALSE);
4873 if (priv->startup_id)
4875 #ifdef GDK_WINDOWING_X11
4876 guint32 timestamp = extract_time_from_startup_id (priv->startup_id);
4877 if (timestamp != GDK_CURRENT_TIME)
4878 gdk_x11_window_set_user_time (widget->window, timestamp);
4880 if (!startup_id_is_fake (priv->startup_id))
4881 gdk_window_set_startup_id (widget->window, priv->startup_id);
4885 gtk_window_realize_icon (window);
4889 gtk_window_unrealize (GtkWidget *widget)
4892 GtkWindowGeometryInfo *info;
4894 window = GTK_WINDOW (widget);
4896 /* On unrealize, we reset the size of the window such
4897 * that we will re-apply the default sizing stuff
4898 * next time we show the window.
4900 * Default positioning is reset on unmap, instead of unrealize.
4902 window->need_default_size = TRUE;
4903 info = gtk_window_get_geometry_info (window, FALSE);
4906 info->resize_width = -1;
4907 info->resize_height = -1;
4908 info->last.configure_request.x = 0;
4909 info->last.configure_request.y = 0;
4910 info->last.configure_request.width = -1;
4911 info->last.configure_request.height = -1;
4912 /* be sure we reset geom hints on re-realize */
4913 info->last.flags = 0;
4918 gdk_window_set_user_data (window->frame, NULL);
4919 gdk_window_destroy (window->frame);
4920 window->frame = NULL;
4924 gtk_window_unrealize_icon (window);
4926 GTK_WIDGET_CLASS (gtk_window_parent_class)->unrealize (widget);
4930 gtk_window_size_request (GtkWidget *widget,
4931 GtkRequisition *requisition)
4936 window = GTK_WINDOW (widget);
4937 bin = GTK_BIN (window);
4939 requisition->width = GTK_CONTAINER (window)->border_width * 2;
4940 requisition->height = GTK_CONTAINER (window)->border_width * 2;
4942 if (bin->child && GTK_WIDGET_VISIBLE (bin->child))
4944 GtkRequisition child_requisition;
4946 gtk_widget_size_request (bin->child, &child_requisition);
4948 requisition->width += child_requisition.width;
4949 requisition->height += child_requisition.height;
4954 gtk_window_size_allocate (GtkWidget *widget,
4955 GtkAllocation *allocation)
4958 GtkAllocation child_allocation;
4960 window = GTK_WINDOW (widget);
4961 widget->allocation = *allocation;
4963 if (window->bin.child && GTK_WIDGET_VISIBLE (window->bin.child))
4965 child_allocation.x = GTK_CONTAINER (window)->border_width;
4966 child_allocation.y = GTK_CONTAINER (window)->border_width;
4967 child_allocation.width =
4968 MAX (1, (gint)allocation->width - child_allocation.x * 2);
4969 child_allocation.height =
4970 MAX (1, (gint)allocation->height - child_allocation.y * 2);
4972 gtk_widget_size_allocate (window->bin.child, &child_allocation);
4975 if (GTK_WIDGET_REALIZED (widget) && window->frame)
4977 gdk_window_resize (window->frame,
4978 allocation->width + window->frame_left + window->frame_right,
4979 allocation->height + window->frame_top + window->frame_bottom);
4984 gtk_window_event (GtkWidget *widget, GdkEvent *event)
4987 gboolean return_val;
4989 window = GTK_WINDOW (widget);
4991 if (window->frame && (event->any.window == window->frame))
4993 if ((event->type != GDK_KEY_PRESS) &&
4994 (event->type != GDK_KEY_RELEASE) &&
4995 (event->type != GDK_FOCUS_CHANGE))
4997 g_signal_stop_emission_by_name (widget, "event");
4999 g_signal_emit (widget, window_signals[FRAME_EVENT], 0, event, &return_val);
5004 g_object_unref (event->any.window);
5005 event->any.window = g_object_ref (widget->window);
5013 gtk_window_frame_event (GtkWindow *window, GdkEvent *event)
5015 GdkEventConfigure *configure_event;
5018 switch (event->type)
5021 configure_event = (GdkEventConfigure *)event;
5023 /* Invalidate the decorations */
5026 rect.width = configure_event->width;
5027 rect.height = configure_event->height;
5029 gdk_window_invalidate_rect (window->frame, &rect, FALSE);
5031 /* Pass on the (modified) configure event */
5032 configure_event->width -= window->frame_left + window->frame_right;
5033 configure_event->height -= window->frame_top + window->frame_bottom;
5034 return gtk_window_configure_event (GTK_WIDGET (window), configure_event);
5043 gtk_window_configure_event (GtkWidget *widget,
5044 GdkEventConfigure *event)
5046 GtkWindow *window = GTK_WINDOW (widget);
5047 gboolean expected_reply = window->configure_request_count > 0;
5049 /* window->configure_request_count incremented for each
5050 * configure request, and decremented to a min of 0 for
5051 * each configure notify.
5053 * All it means is that we know we will get at least
5054 * window->configure_request_count more configure notifies.
5055 * We could get more configure notifies than that; some
5056 * of the configure notifies we get may be unrelated to
5057 * the configure requests. But we will get at least
5058 * window->configure_request_count notifies.
5061 if (window->configure_request_count > 0)
5063 window->configure_request_count -= 1;
5064 gdk_window_thaw_toplevel_updates_libgtk_only (widget->window);
5067 /* As an optimization, we avoid a resize when possible.
5069 * The only times we can avoid a resize are:
5070 * - we know only the position changed, not the size
5071 * - we know we have made more requests and so will get more
5072 * notifies and can wait to resize when we get them
5075 if (!expected_reply &&
5076 (widget->allocation.width == event->width &&
5077 widget->allocation.height == event->height))
5079 gdk_window_configure_finished (widget->window);
5084 * If we do need to resize, we do that by:
5085 * - filling in widget->allocation with the new size
5086 * - setting configure_notify_received to TRUE
5087 * for use in gtk_window_move_resize()
5088 * - queueing a resize, leading to invocation of
5089 * gtk_window_move_resize() in an idle handler
5093 window->configure_notify_received = TRUE;
5095 widget->allocation.width = event->width;
5096 widget->allocation.height = event->height;
5098 _gtk_container_queue_resize (GTK_CONTAINER (widget));
5103 /* the accel_key and accel_mods fields of the key have to be setup
5104 * upon calling this function. it'll then return whether that key
5105 * is at all used as accelerator, and if so will OR in the
5106 * accel_flags member of the key.
5109 _gtk_window_query_nonaccels (GtkWindow *window,
5111 GdkModifierType accel_mods)
5113 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
5115 /* movement keys are considered locked accels */
5118 static const guint bindings[] = {
5119 GDK_space, GDK_KP_Space, GDK_Return, GDK_ISO_Enter, GDK_KP_Enter, GDK_Up, GDK_KP_Up, GDK_Down, GDK_KP_Down,
5120 GDK_Left, GDK_KP_Left, GDK_Right, GDK_KP_Right, GDK_Tab, GDK_KP_Tab, GDK_ISO_Left_Tab,
5124 for (i = 0; i < G_N_ELEMENTS (bindings); i++)
5125 if (bindings[i] == accel_key)
5129 /* mnemonics are considered locked accels */
5130 if (accel_mods == window->mnemonic_modifier)
5132 GtkMnemonicHash *mnemonic_hash = gtk_window_get_mnemonic_hash (window, FALSE);
5133 if (mnemonic_hash && _gtk_mnemonic_hash_lookup (mnemonic_hash, accel_key))
5141 * gtk_window_propagate_key_event:
5142 * @window: a #GtkWindow
5143 * @event: a #GdkEventKey
5145 * Propagate a key press or release event to the focus widget and
5146 * up the focus container chain until a widget handles @event.
5147 * This is normally called by the default ::key_press_event and
5148 * ::key_release_event handlers for toplevel windows,
5149 * however in some cases it may be useful to call this directly when
5150 * overriding the standard key handling for a toplevel window.
5152 * Return value: %TRUE if a widget in the focus chain handled the event.
5157 gtk_window_propagate_key_event (GtkWindow *window,
5160 gboolean handled = FALSE;
5161 GtkWidget *widget, *focus;
5163 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
5165 widget = GTK_WIDGET (window);
5166 focus = window->focus_widget;
5168 g_object_ref (focus);
5171 focus && focus != widget &&
5172 gtk_widget_get_toplevel (focus) == widget)
5176 if (GTK_WIDGET_IS_SENSITIVE (focus))
5177 handled = gtk_widget_event (focus, (GdkEvent*) event);
5179 parent = focus->parent;
5181 g_object_ref (parent);
5183 g_object_unref (focus);
5189 g_object_unref (focus);
5195 gtk_window_key_press_event (GtkWidget *widget,
5198 GtkWindow *window = GTK_WINDOW (widget);
5199 gboolean handled = FALSE;
5201 /* handle mnemonics and accelerators */
5203 handled = gtk_window_activate_key (window, event);
5205 /* handle focus widget key events */
5207 handled = gtk_window_propagate_key_event (window, event);
5209 /* Chain up, invokes binding set */
5211 handled = GTK_WIDGET_CLASS (gtk_window_parent_class)->key_press_event (widget, event);
5217 gtk_window_key_release_event (GtkWidget *widget,
5220 GtkWindow *window = GTK_WINDOW (widget);
5221 gboolean handled = FALSE;
5223 /* handle focus widget key events */
5225 handled = gtk_window_propagate_key_event (window, event);
5227 /* Chain up, invokes binding set */
5229 handled = GTK_WIDGET_CLASS (gtk_window_parent_class)->key_release_event (widget, event);
5235 gtk_window_real_activate_default (GtkWindow *window)
5237 gtk_window_activate_default (window);
5241 gtk_window_real_activate_focus (GtkWindow *window)
5243 gtk_window_activate_focus (window);
5247 gtk_window_move_focus (GtkWindow *window,
5248 GtkDirectionType dir)
5250 gtk_widget_child_focus (GTK_WIDGET (window), dir);
5252 if (!GTK_CONTAINER (window)->focus_child)
5253 gtk_window_set_focus (window, NULL);
5257 gtk_window_enter_notify_event (GtkWidget *widget,
5258 GdkEventCrossing *event)
5264 gtk_window_leave_notify_event (GtkWidget *widget,
5265 GdkEventCrossing *event)
5271 do_focus_change (GtkWidget *widget,
5274 GdkEvent *fevent = gdk_event_new (GDK_FOCUS_CHANGE);
5276 g_object_ref (widget);
5279 GTK_WIDGET_SET_FLAGS (widget, GTK_HAS_FOCUS);
5281 GTK_WIDGET_UNSET_FLAGS (widget, GTK_HAS_FOCUS);
5283 fevent->focus_change.type = GDK_FOCUS_CHANGE;
5284 fevent->focus_change.window = widget->window;
5286 g_object_ref (widget->window);
5287 fevent->focus_change.in = in;
5289 gtk_widget_event (widget, fevent);
5291 g_object_notify (G_OBJECT (widget), "has-focus");
5293 g_object_unref (widget);
5294 gdk_event_free (fevent);
5298 gtk_window_focus_in_event (GtkWidget *widget,
5299 GdkEventFocus *event)
5301 GtkWindow *window = GTK_WINDOW (widget);
5303 /* It appears spurious focus in events can occur when
5304 * the window is hidden. So we'll just check to see if
5305 * the window is visible before actually handling the
5308 if (GTK_WIDGET_VISIBLE (widget))
5310 _gtk_window_set_has_toplevel_focus (window, TRUE);
5311 _gtk_window_set_is_active (window, TRUE);
5318 gtk_window_focus_out_event (GtkWidget *widget,
5319 GdkEventFocus *event)
5321 GtkWindow *window = GTK_WINDOW (widget);
5322 gboolean auto_mnemonics;
5324 _gtk_window_set_has_toplevel_focus (window, FALSE);
5325 _gtk_window_set_is_active (window, FALSE);
5327 /* set the mnemonic-visible property to false */
5328 g_object_get (gtk_widget_get_settings (widget),
5329 "gtk-auto-mnemonics", &auto_mnemonics, NULL);
5331 gtk_window_set_mnemonics_visible (window, FALSE);
5336 static GdkAtom atom_rcfiles = GDK_NONE;
5337 static GdkAtom atom_iconthemes = GDK_NONE;
5340 send_client_message_to_embedded_windows (GtkWidget *widget,
5341 GdkAtom message_type)
5343 GList *embedded_windows;
5345 embedded_windows = g_object_get_qdata (G_OBJECT (widget), quark_gtk_embedded);
5346 if (embedded_windows)
5348 GdkEvent *send_event = gdk_event_new (GDK_CLIENT_EVENT);
5351 for (i = 0; i < 5; i++)
5352 send_event->client.data.l[i] = 0;
5353 send_event->client.data_format = 32;
5354 send_event->client.message_type = message_type;
5356 while (embedded_windows)
5358 GdkNativeWindow xid = GDK_GPOINTER_TO_NATIVE_WINDOW(embedded_windows->data);
5359 gdk_event_send_client_message_for_display (gtk_widget_get_display (widget), send_event, xid);
5360 embedded_windows = embedded_windows->next;
5363 gdk_event_free (send_event);
5368 gtk_window_client_event (GtkWidget *widget,
5369 GdkEventClient *event)
5373 atom_rcfiles = gdk_atom_intern_static_string ("_GTK_READ_RCFILES");
5374 atom_iconthemes = gdk_atom_intern_static_string ("_GTK_LOAD_ICONTHEMES");
5377 if (event->message_type == atom_rcfiles)
5379 send_client_message_to_embedded_windows (widget, atom_rcfiles);
5380 gtk_rc_reparse_all_for_settings (gtk_widget_get_settings (widget), FALSE);
5383 if (event->message_type == atom_iconthemes)
5385 send_client_message_to_embedded_windows (widget, atom_iconthemes);
5386 _gtk_icon_theme_check_reload (gtk_widget_get_display (widget));
5393 gtk_window_check_resize (GtkContainer *container)
5395 GtkWindow *window = GTK_WINDOW (container);
5397 if (GTK_WIDGET_VISIBLE (container))
5398 gtk_window_move_resize (window);
5402 gtk_window_focus (GtkWidget *widget,
5403 GtkDirectionType direction)
5407 GtkContainer *container;
5408 GtkWidget *old_focus_child;
5411 container = GTK_CONTAINER (widget);
5412 window = GTK_WINDOW (widget);
5413 bin = GTK_BIN (widget);
5415 old_focus_child = container->focus_child;
5417 /* We need a special implementation here to deal properly with wrapping
5418 * around in the tab chain without the danger of going into an
5421 if (old_focus_child)
5423 if (gtk_widget_child_focus (old_focus_child, direction))
5427 if (window->focus_widget)
5429 if (direction == GTK_DIR_LEFT ||
5430 direction == GTK_DIR_RIGHT ||
5431 direction == GTK_DIR_UP ||
5432 direction == GTK_DIR_DOWN)
5437 /* Wrapped off the end, clear the focus setting for the toplpevel */
5438 parent = window->focus_widget->parent;
5441 gtk_container_set_focus_child (GTK_CONTAINER (parent), NULL);
5442 parent = GTK_WIDGET (parent)->parent;
5445 gtk_window_set_focus (GTK_WINDOW (container), NULL);
5448 /* Now try to focus the first widget in the window */
5451 if (gtk_widget_child_focus (bin->child, direction))
5459 gtk_window_real_set_focus (GtkWindow *window,
5462 GtkWidget *old_focus = window->focus_widget;
5463 gboolean had_default = FALSE;
5464 gboolean focus_had_default = FALSE;
5465 gboolean old_focus_had_default = FALSE;
5469 g_object_ref (old_focus);
5470 g_object_freeze_notify (G_OBJECT (old_focus));
5471 old_focus_had_default = GTK_WIDGET_HAS_DEFAULT (old_focus);
5475 g_object_ref (focus);
5476 g_object_freeze_notify (G_OBJECT (focus));
5477 focus_had_default = GTK_WIDGET_HAS_DEFAULT (focus);
5480 if (window->default_widget)
5481 had_default = GTK_WIDGET_HAS_DEFAULT (window->default_widget);
5483 if (window->focus_widget)
5485 if (GTK_WIDGET_RECEIVES_DEFAULT (window->focus_widget) &&
5486 (window->focus_widget != window->default_widget))
5488 GTK_WIDGET_UNSET_FLAGS (window->focus_widget, GTK_HAS_DEFAULT);
5489 gtk_widget_queue_draw (window->focus_widget);
5491 if (window->default_widget)
5492 GTK_WIDGET_SET_FLAGS (window->default_widget, GTK_HAS_DEFAULT);
5495 window->focus_widget = NULL;
5497 if (window->has_focus)
5498 do_focus_change (old_focus, FALSE);
5500 g_object_notify (G_OBJECT (old_focus), "is-focus");
5503 /* The above notifications may have set a new focus widget,
5504 * if so, we don't want to override it.
5506 if (focus && !window->focus_widget)
5508 window->focus_widget = focus;
5510 if (GTK_WIDGET_RECEIVES_DEFAULT (window->focus_widget) &&
5511 (window->focus_widget != window->default_widget))
5513 if (GTK_WIDGET_CAN_DEFAULT (window->focus_widget))
5514 GTK_WIDGET_SET_FLAGS (window->focus_widget, GTK_HAS_DEFAULT);
5516 if (window->default_widget)
5517 GTK_WIDGET_UNSET_FLAGS (window->default_widget, GTK_HAS_DEFAULT);
5520 if (window->has_focus)
5521 do_focus_change (window->focus_widget, TRUE);
5523 g_object_notify (G_OBJECT (window->focus_widget), "is-focus");
5526 /* If the default widget changed, a redraw will have been queued
5527 * on the old and new default widgets by gtk_window_set_default(), so
5528 * we only have to worry about the case where it didn't change.
5529 * We'll sometimes queue a draw twice on the new widget but that
5532 if (window->default_widget &&
5533 (had_default != GTK_WIDGET_HAS_DEFAULT (window->default_widget)))
5534 gtk_widget_queue_draw (window->default_widget);
5538 if (old_focus_had_default != GTK_WIDGET_HAS_DEFAULT (old_focus))
5539 gtk_widget_queue_draw (old_focus);
5541 g_object_thaw_notify (G_OBJECT (old_focus));
5542 g_object_unref (old_focus);
5546 if (focus_had_default != GTK_WIDGET_HAS_DEFAULT (focus))
5547 gtk_widget_queue_draw (focus);
5549 g_object_thaw_notify (G_OBJECT (focus));
5550 g_object_unref (focus);
5555 * _gtk_window_unset_focus_and_default:
5556 * @window: a #GtkWindow
5557 * @widget: a widget inside of @window
5559 * Checks whether the focus and default widgets of @window are
5560 * @widget or a descendent of @widget, and if so, unset them.
5563 _gtk_window_unset_focus_and_default (GtkWindow *window,
5569 g_object_ref (window);
5570 g_object_ref (widget);
5572 if (GTK_CONTAINER (widget->parent)->focus_child == widget)
5574 child = window->focus_widget;
5576 while (child && child != widget)
5577 child = child->parent;
5579 if (child == widget)
5580 gtk_window_set_focus (GTK_WINDOW (window), NULL);
5583 child = window->default_widget;
5585 while (child && child != widget)
5586 child = child->parent;
5588 if (child == widget)
5589 gtk_window_set_default (window, NULL);
5591 g_object_unref (widget);
5592 g_object_unref (window);
5595 /*********************************
5596 * Functions related to resizing *
5597 *********************************/
5599 /* This function doesn't constrain to geometry hints */
5601 gtk_window_compute_configure_request_size (GtkWindow *window,
5605 GtkRequisition requisition;
5606 GtkWindowGeometryInfo *info;
5610 * - we've done a size request
5613 widget = GTK_WIDGET (window);
5615 info = gtk_window_get_geometry_info (window, FALSE);
5617 if (window->need_default_size)
5619 gtk_widget_get_child_requisition (widget, &requisition);
5621 /* Default to requisition */
5622 *width = requisition.width;
5623 *height = requisition.height;
5625 /* If window is empty so requests 0, default to random nonzero size */
5626 if (*width == 0 && *height == 0)
5632 /* Override requisition with default size */
5636 gint base_width = 0;
5637 gint base_height = 0;
5639 gint min_height = 0;
5641 gint height_inc = 1;
5643 if (info->default_is_geometry &&
5644 (info->default_width > 0 || info->default_height > 0))
5646 GdkGeometry geometry;
5649 gtk_window_compute_hints (window, &geometry, &flags);
5651 if (flags & GDK_HINT_BASE_SIZE)
5653 base_width = geometry.base_width;
5654 base_height = geometry.base_height;
5656 if (flags & GDK_HINT_MIN_SIZE)
5658 min_width = geometry.min_width;
5659 min_height = geometry.min_height;
5661 if (flags & GDK_HINT_RESIZE_INC)
5663 width_inc = geometry.width_inc;
5664 height_inc = geometry.height_inc;
5668 if (info->default_width > 0)
5669 *width = MAX (info->default_width * width_inc + base_width, min_width);
5671 if (info->default_height > 0)
5672 *height = MAX (info->default_height * height_inc + base_height, min_height);
5677 /* Default to keeping current size */
5678 *width = widget->allocation.width;
5679 *height = widget->allocation.height;
5682 /* Override any size with gtk_window_resize() values */
5685 if (info->resize_width > 0)
5686 *width = info->resize_width;
5688 if (info->resize_height > 0)
5689 *height = info->resize_height;
5692 /* Don't ever request zero width or height, its not supported by
5693 gdk. The size allocation code will round it to 1 anyway but if
5694 we do it then the value returned from this function will is
5695 not comparable to the size allocation read from the GtkWindow. */
5696 *width = MAX (*width, 1);
5697 *height = MAX (*height, 1);
5700 static GtkWindowPosition
5701 get_effective_position (GtkWindow *window)
5703 GtkWindowPosition pos = window->position;
5704 if (pos == GTK_WIN_POS_CENTER_ON_PARENT &&
5705 (window->transient_parent == NULL ||
5706 !GTK_WIDGET_MAPPED (window->transient_parent)))
5707 pos = GTK_WIN_POS_NONE;
5713 get_center_monitor_of_window (GtkWindow *window)
5715 /* We could try to sort out the relative positions of the monitors and
5716 * stuff, or we could just be losers and assume you have a row
5717 * or column of monitors.
5719 return gdk_screen_get_n_monitors (gtk_window_check_screen (window)) / 2;
5723 get_monitor_containing_pointer (GtkWindow *window)
5727 GdkScreen *window_screen;
5728 GdkScreen *pointer_screen;
5730 window_screen = gtk_window_check_screen (window);
5731 gdk_display_get_pointer (gdk_screen_get_display (window_screen),
5735 if (pointer_screen == window_screen)
5736 monitor_num = gdk_screen_get_monitor_at_point (pointer_screen, px, py);
5744 center_window_on_monitor (GtkWindow *window,
5750 GdkRectangle monitor;
5753 monitor_num = get_monitor_containing_pointer (window);
5755 if (monitor_num == -1)
5756 monitor_num = get_center_monitor_of_window (window);
5758 gdk_screen_get_monitor_geometry (gtk_window_check_screen (window),
5759 monitor_num, &monitor);
5761 *x = (monitor.width - w) / 2 + monitor.x;
5762 *y = (monitor.height - h) / 2 + monitor.y;
5764 /* Be sure we aren't off the monitor, ignoring _NET_WM_STRUT
5765 * and WM decorations.
5779 if (extent > clamp_extent)
5781 *base = clamp_base + clamp_extent/2 - extent/2;
5782 else if (*base < clamp_base)
5784 else if (*base + extent > clamp_base + clamp_extent)
5785 *base = clamp_base + clamp_extent - extent;
5789 clamp_window_to_rectangle (gint *x,
5793 const GdkRectangle *rect)
5795 #ifdef DEBUGGING_OUTPUT
5796 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);
5799 /* If it is too large, center it. If it fits on the monitor but is
5800 * partially outside, move it to the closest edge. Do this
5801 * separately in x and y directions.
5803 clamp (x, w, rect->x, rect->width);
5804 clamp (y, h, rect->y, rect->height);
5805 #ifdef DEBUGGING_OUTPUT
5806 g_print (" ==> %+d%+d: %dx%d\n", *x, *y, w, h);
5812 gtk_window_compute_configure_request (GtkWindow *window,
5813 GdkRectangle *request,
5814 GdkGeometry *geometry,
5817 GdkGeometry new_geometry;
5821 GtkWindowPosition pos;
5822 GtkWidget *parent_widget;
5823 GtkWindowGeometryInfo *info;
5827 widget = GTK_WIDGET (window);
5829 screen = gtk_window_check_screen (window);
5831 gtk_widget_size_request (widget, NULL);
5832 gtk_window_compute_configure_request_size (window, (guint *)&w, (guint *)&h);
5834 gtk_window_compute_hints (window, &new_geometry, &new_flags);
5835 gtk_window_constrain_size (window,
5836 &new_geometry, new_flags,
5840 parent_widget = (GtkWidget*) window->transient_parent;
5842 pos = get_effective_position (window);
5843 info = gtk_window_get_geometry_info (window, FALSE);
5845 /* by default, don't change position requested */
5848 x = info->last.configure_request.x;
5849 y = info->last.configure_request.y;
5858 if (window->need_default_position)
5861 /* FIXME this all interrelates with window gravity.
5862 * For most of them I think we want to set GRAVITY_CENTER.
5864 * Not sure how to go about that.
5869 /* here we are only handling CENTER_ALWAYS
5870 * as it relates to default positioning,
5871 * where it's equivalent to simply CENTER
5873 case GTK_WIN_POS_CENTER_ALWAYS:
5874 case GTK_WIN_POS_CENTER:
5875 center_window_on_monitor (window, w, h, &x, &y);
5878 case GTK_WIN_POS_CENTER_ON_PARENT:
5881 GdkRectangle monitor;
5884 g_assert (GTK_WIDGET_MAPPED (parent_widget)); /* established earlier */
5886 if (parent_widget->window != NULL)
5887 monitor_num = gdk_screen_get_monitor_at_window (screen,
5888 parent_widget->window);
5892 gdk_window_get_origin (parent_widget->window,
5895 x = ox + (parent_widget->allocation.width - w) / 2;
5896 y = oy + (parent_widget->allocation.height - h) / 2;
5898 /* Clamp onto current monitor, ignoring _NET_WM_STRUT and
5899 * WM decorations. If parent wasn't on a monitor, just
5902 if (monitor_num >= 0)
5904 gdk_screen_get_monitor_geometry (screen, monitor_num, &monitor);
5905 clamp_window_to_rectangle (&x, &y, w, h, &monitor);
5910 case GTK_WIN_POS_MOUSE:
5912 gint screen_width = gdk_screen_get_width (screen);
5913 gint screen_height = gdk_screen_get_height (screen);
5915 GdkRectangle monitor;
5916 GdkScreen *pointer_screen;
5919 gdk_display_get_pointer (gdk_screen_get_display (screen),
5923 if (pointer_screen == screen)
5924 monitor_num = gdk_screen_get_monitor_at_point (screen, px, py);
5930 x = CLAMP (x, 0, screen_width - w);
5931 y = CLAMP (y, 0, screen_height - h);
5933 /* Clamp onto current monitor, ignoring _NET_WM_STRUT and
5934 * WM decorations. Don't try to figure out what's going
5935 * on if the mouse wasn't inside a monitor.
5937 if (monitor_num >= 0)
5939 gdk_screen_get_monitor_geometry (screen, monitor_num, &monitor);
5940 clamp_window_to_rectangle (&x, &y, w, h, &monitor);
5948 } /* if (window->need_default_position) */
5950 if (window->need_default_position && info &&
5951 info->initial_pos_set)
5953 x = info->initial_x;
5954 y = info->initial_y;
5955 gtk_window_constrain_position (window, w, h, &x, &y);
5961 request->height = h;
5964 *geometry = new_geometry;
5970 gtk_window_constrain_position (GtkWindow *window,
5976 /* See long comments in gtk_window_move_resize()
5977 * on when it's safe to call this function.
5979 if (window->position == GTK_WIN_POS_CENTER_ALWAYS)
5981 gint center_x, center_y;
5983 center_window_on_monitor (window, new_width, new_height, ¢er_x, ¢er_y);
5991 gtk_window_move_resize (GtkWindow *window)
5995 * First we determine whether any information has changed that would
5996 * cause us to revise our last configure request. If we would send
5997 * a different configure request from last time, then
5998 * configure_request_size_changed = TRUE or
5999 * configure_request_pos_changed = TRUE. configure_request_size_changed
6000 * may be true due to new hints, a gtk_window_resize(), or whatever.
6001 * configure_request_pos_changed may be true due to gtk_window_set_position()
6002 * or gtk_window_move().
6004 * If the configure request has changed, we send off a new one. To
6005 * ensure GTK+ invariants are maintained (resize queue does what it
6006 * should), we go ahead and size_allocate the requested size in this
6009 * If the configure request has not changed, we don't ever resend
6010 * it, because it could mean fighting the user or window manager.
6013 * To prepare the configure request, we come up with a base size/pos:
6014 * - the one from gtk_window_move()/gtk_window_resize()
6015 * - else default_width, default_height if we haven't ever
6017 * - else the size request if we haven't ever been mapped,
6018 * as a substitute default size
6019 * - else the current size of the window, as received from
6020 * configure notifies (i.e. the current allocation)
6022 * If GTK_WIN_POS_CENTER_ALWAYS is active, we constrain
6023 * the position request to be centered.
6026 GtkContainer *container;
6027 GtkWindowGeometryInfo *info;
6028 GdkGeometry new_geometry;
6030 GdkRectangle new_request;
6031 gboolean configure_request_size_changed;
6032 gboolean configure_request_pos_changed;
6033 gboolean hints_changed; /* do we need to send these again */
6034 GtkWindowLastGeometryInfo saved_last_info;
6036 widget = GTK_WIDGET (window);
6037 container = GTK_CONTAINER (widget);
6038 info = gtk_window_get_geometry_info (window, TRUE);
6040 configure_request_size_changed = FALSE;
6041 configure_request_pos_changed = FALSE;
6043 gtk_window_compute_configure_request (window, &new_request,
6044 &new_geometry, &new_flags);
6046 /* This check implies the invariant that we never set info->last
6047 * without setting the hints and sending off a configure request.
6049 * If we change info->last without sending the request, we may
6052 if (info->last.configure_request.x != new_request.x ||
6053 info->last.configure_request.y != new_request.y)
6054 configure_request_pos_changed = TRUE;
6056 if ((info->last.configure_request.width != new_request.width ||
6057 info->last.configure_request.height != new_request.height))
6058 configure_request_size_changed = TRUE;
6060 hints_changed = FALSE;
6062 if (!gtk_window_compare_hints (&info->last.geometry, info->last.flags,
6063 &new_geometry, new_flags))
6065 hints_changed = TRUE;
6068 /* Position Constraints
6069 * ====================
6071 * POS_CENTER_ALWAYS is conceptually a constraint rather than
6072 * a default. The other POS_ values are used only when the
6073 * window is shown, not after that.
6075 * However, we can't implement a position constraint as
6076 * "anytime the window size changes, center the window"
6077 * because this may well end up fighting the WM or user. In
6078 * fact it gets in an infinite loop with at least one WM.
6080 * Basically, applications are in no way in a position to
6081 * constrain the position of a window, with one exception:
6082 * override redirect windows. (Really the intended purpose
6083 * of CENTER_ALWAYS anyhow, I would think.)
6085 * So the way we implement this "constraint" is to say that when WE
6086 * cause a move or resize, i.e. we make a configure request changing
6087 * window size, we recompute the CENTER_ALWAYS position to reflect
6088 * the new window size, and include it in our request. Also, if we
6089 * just turned on CENTER_ALWAYS we snap to center with a new
6090 * request. Otherwise, if we are just NOTIFIED of a move or resize
6091 * done by someone else e.g. the window manager, we do NOT send a
6092 * new configure request.
6094 * For override redirect windows, this works fine; all window
6095 * sizes are from our configure requests. For managed windows,
6096 * it is at least semi-sane, though who knows what the
6097 * app author is thinking.
6100 /* This condition should be kept in sync with the condition later on
6101 * that determines whether we send a configure request. i.e. we
6102 * should do this position constraining anytime we were going to
6103 * send a configure request anyhow, plus when constraints have
6106 if (configure_request_pos_changed ||
6107 configure_request_size_changed ||
6109 info->position_constraints_changed)
6111 /* We request the constrained position if:
6112 * - we were changing position, and need to clamp
6113 * the change to the constraint
6114 * - we're changing the size anyway
6115 * - set_position() was called to toggle CENTER_ALWAYS on
6118 gtk_window_constrain_position (window,
6124 /* Update whether we need to request a move */
6125 if (info->last.configure_request.x != new_request.x ||
6126 info->last.configure_request.y != new_request.y)
6127 configure_request_pos_changed = TRUE;
6129 configure_request_pos_changed = FALSE;
6133 if (window->type == GTK_WINDOW_TOPLEVEL)
6135 int notify_x, notify_y;
6137 /* this is the position from the last configure notify */
6138 gdk_window_get_position (widget->window, ¬ify_x, ¬ify_y);
6140 g_message ("--- %s ---\n"
6141 "last : %d,%d\t%d x %d\n"
6142 "this : %d,%d\t%d x %d\n"
6143 "alloc : %d,%d\t%d x %d\n"
6145 "resize: \t%d x %d\n"
6146 "size_changed: %d pos_changed: %d hints_changed: %d\n"
6147 "configure_notify_received: %d\n"
6148 "configure_request_count: %d\n"
6149 "position_constraints_changed: %d\n",
6150 window->title ? window->title : "(no title)",
6151 info->last.configure_request.x,
6152 info->last.configure_request.y,
6153 info->last.configure_request.width,
6154 info->last.configure_request.height,
6160 widget->allocation.width,
6161 widget->allocation.height,
6162 widget->requisition.width,
6163 widget->requisition.height,
6165 info->resize_height,
6166 configure_request_pos_changed,
6167 configure_request_size_changed,
6169 window->configure_notify_received,
6170 window->configure_request_count,
6171 info->position_constraints_changed);
6175 saved_last_info = info->last;
6176 info->last.geometry = new_geometry;
6177 info->last.flags = new_flags;
6178 info->last.configure_request = new_request;
6180 /* need to set PPosition so the WM will look at our position,
6181 * but we don't want to count PPosition coming and going as a hints
6182 * change for future iterations. So we saved info->last prior to
6186 /* Also, if the initial position was explicitly set, then we always
6187 * toggle on PPosition. This makes gtk_window_move(window, 0, 0)
6191 /* Also, we toggle on PPosition if GTK_WIN_POS_ is in use and
6192 * this is an initial map
6195 if ((configure_request_pos_changed ||
6196 info->initial_pos_set ||
6197 (window->need_default_position &&
6198 get_effective_position (window) != GTK_WIN_POS_NONE)) &&
6199 (new_flags & GDK_HINT_POS) == 0)
6201 new_flags |= GDK_HINT_POS;
6202 hints_changed = TRUE;
6205 /* Set hints if necessary
6208 gdk_window_set_geometry_hints (widget->window,
6212 /* handle resizing/moving and widget tree allocation
6214 if (window->configure_notify_received)
6216 GtkAllocation allocation;
6218 /* If we have received a configure event since
6219 * the last time in this function, we need to
6220 * accept our new size and size_allocate child widgets.
6221 * (see gtk_window_configure_event() for more details).
6223 * 1 or more configure notifies may have been received.
6224 * Also, configure_notify_received will only be TRUE
6225 * if all expected configure notifies have been received
6226 * (one per configure request), as an optimization.
6229 window->configure_notify_received = FALSE;
6231 /* gtk_window_configure_event() filled in widget->allocation */
6232 allocation = widget->allocation;
6233 gtk_widget_size_allocate (widget, &allocation);
6235 gdk_window_process_updates (widget->window, TRUE);
6237 gdk_window_configure_finished (widget->window);
6239 /* If the configure request changed, it means that
6241 * 1) coincidentally changed hints or widget properties
6242 * impacting the configure request before getting
6243 * a configure notify, or
6244 * 2) some broken widget is changing its size request
6245 * during size allocation, resulting in
6246 * a false appearance of changed configure request.
6248 * For 1), we could just go ahead and ask for the
6249 * new size right now, but doing that for 2)
6250 * might well be fighting the user (and can even
6251 * trigger a loop). Since we really don't want to
6252 * do that, we requeue a resize in hopes that
6253 * by the time it gets handled, the child has seen
6254 * the light and is willing to go along with the
6255 * new size. (this happens for the zvt widget, since
6256 * the size_allocate() above will have stored the
6257 * requisition corresponding to the new size in the
6260 * This doesn't buy us anything for 1), but it shouldn't
6261 * hurt us too badly, since it is what would have
6262 * happened if we had gotten the configure event before
6263 * the new size had been set.
6266 if (configure_request_size_changed ||
6267 configure_request_pos_changed)
6269 /* Don't change the recorded last info after all, because we
6270 * haven't actually updated to the new info yet - we decided
6271 * to postpone our configure request until later.
6273 info->last = saved_last_info;
6275 gtk_widget_queue_resize_no_redraw (widget); /* migth recurse for GTK_RESIZE_IMMEDIATE */
6278 return; /* Bail out, we didn't really process the move/resize */
6280 else if ((configure_request_size_changed || hints_changed) &&
6281 (widget->allocation.width != new_request.width ||
6282 widget->allocation.height != new_request.height))
6285 /* We are in one of the following situations:
6286 * A. configure_request_size_changed
6287 * our requisition has changed and we need a different window size,
6288 * so we request it from the window manager.
6289 * B. !configure_request_size_changed && hints_changed
6290 * the window manager rejects our size, but we have just changed the
6291 * window manager hints, so there's a chance our request will
6292 * be honoured this time, so we try again.
6294 * However, if the new requisition is the same as the current allocation,
6295 * we don't request it again, since we won't get a ConfigureNotify back from
6296 * the window manager unless it decides to change our requisition. If
6297 * we don't get the ConfigureNotify back, the resize queue will never be run.
6300 /* Now send the configure request */
6301 if (configure_request_pos_changed)
6305 gdk_window_move_resize (window->frame,
6306 new_request.x - window->frame_left,
6307 new_request.y - window->frame_top,
6308 new_request.width + window->frame_left + window->frame_right,
6309 new_request.height + window->frame_top + window->frame_bottom);
6310 gdk_window_resize (widget->window,
6311 new_request.width, new_request.height);
6314 gdk_window_move_resize (widget->window,
6315 new_request.x, new_request.y,
6316 new_request.width, new_request.height);
6318 else /* only size changed */
6321 gdk_window_resize (window->frame,
6322 new_request.width + window->frame_left + window->frame_right,
6323 new_request.height + window->frame_top + window->frame_bottom);
6324 gdk_window_resize (widget->window,
6325 new_request.width, new_request.height);
6328 if (window->type == GTK_WINDOW_POPUP)
6330 GtkAllocation allocation;
6332 /* Directly size allocate for override redirect (popup) windows. */
6335 allocation.width = new_request.width;
6336 allocation.height = new_request.height;
6338 gtk_widget_size_allocate (widget, &allocation);
6340 gdk_window_process_updates (widget->window, TRUE);
6342 if (container->resize_mode == GTK_RESIZE_QUEUE)
6343 gtk_widget_queue_draw (widget);
6347 /* Increment the number of have-not-yet-received-notify requests */
6348 window->configure_request_count += 1;
6349 gdk_window_freeze_toplevel_updates_libgtk_only (widget->window);
6351 /* for GTK_RESIZE_QUEUE toplevels, we are now awaiting a new
6352 * configure event in response to our resizing request.
6353 * the configure event will cause a new resize with
6354 * ->configure_notify_received=TRUE.
6355 * until then, we want to
6356 * - discard expose events
6357 * - coalesce resizes for our children
6358 * - defer any window resizes until the configure event arrived
6359 * to achieve this, we queue a resize for the window, but remove its
6360 * resizing handler, so resizing will not be handled from the next
6361 * idle handler but when the configure event arrives.
6363 * FIXME: we should also dequeue the pending redraws here, since
6364 * we handle those ourselves upon ->configure_notify_received==TRUE.
6366 if (container->resize_mode == GTK_RESIZE_QUEUE)
6368 gtk_widget_queue_resize_no_redraw (widget);
6369 _gtk_container_dequeue_resize_handler (container);
6375 /* Handle any position changes.
6377 if (configure_request_pos_changed)
6381 gdk_window_move (window->frame,
6382 new_request.x - window->frame_left,
6383 new_request.y - window->frame_top);
6386 gdk_window_move (widget->window,
6387 new_request.x, new_request.y);
6390 /* And run the resize queue.
6392 gtk_container_resize_children (container);
6395 /* We have now processed a move/resize since the last position
6396 * constraint change, setting of the initial position, or resize.
6397 * (Not resetting these flags here can lead to infinite loops for
6398 * GTK_RESIZE_IMMEDIATE containers)
6400 info->position_constraints_changed = FALSE;
6401 info->initial_pos_set = FALSE;
6402 info->resize_width = -1;
6403 info->resize_height = -1;
6406 /* Compare two sets of Geometry hints for equality.
6409 gtk_window_compare_hints (GdkGeometry *geometry_a,
6411 GdkGeometry *geometry_b,
6414 if (flags_a != flags_b)
6417 if ((flags_a & GDK_HINT_MIN_SIZE) &&
6418 (geometry_a->min_width != geometry_b->min_width ||
6419 geometry_a->min_height != geometry_b->min_height))
6422 if ((flags_a & GDK_HINT_MAX_SIZE) &&
6423 (geometry_a->max_width != geometry_b->max_width ||
6424 geometry_a->max_height != geometry_b->max_height))
6427 if ((flags_a & GDK_HINT_BASE_SIZE) &&
6428 (geometry_a->base_width != geometry_b->base_width ||
6429 geometry_a->base_height != geometry_b->base_height))
6432 if ((flags_a & GDK_HINT_ASPECT) &&
6433 (geometry_a->min_aspect != geometry_b->min_aspect ||
6434 geometry_a->max_aspect != geometry_b->max_aspect))
6437 if ((flags_a & GDK_HINT_RESIZE_INC) &&
6438 (geometry_a->width_inc != geometry_b->width_inc ||
6439 geometry_a->height_inc != geometry_b->height_inc))
6442 if ((flags_a & GDK_HINT_WIN_GRAVITY) &&
6443 geometry_a->win_gravity != geometry_b->win_gravity)
6450 _gtk_window_constrain_size (GtkWindow *window,
6456 GtkWindowGeometryInfo *info;
6458 g_return_if_fail (GTK_IS_WINDOW (window));
6460 info = window->geometry_info;
6463 GdkWindowHints flags = info->last.flags;
6464 GdkGeometry *geometry = &info->last.geometry;
6466 gtk_window_constrain_size (window,
6477 gtk_window_constrain_size (GtkWindow *window,
6478 GdkGeometry *geometry,
6485 gdk_window_constrain_size (geometry, flags, width, height,
6486 new_width, new_height);
6489 /* Compute the set of geometry hints and flags for a window
6490 * based on the application set geometry, and requisiition
6491 * of the window. gtk_widget_size_request() must have been
6495 gtk_window_compute_hints (GtkWindow *window,
6496 GdkGeometry *new_geometry,
6500 gint extra_width = 0;
6501 gint extra_height = 0;
6502 GtkWindowGeometryInfo *geometry_info;
6503 GtkRequisition requisition;
6505 widget = GTK_WIDGET (window);
6507 gtk_widget_get_child_requisition (widget, &requisition);
6508 geometry_info = gtk_window_get_geometry_info (GTK_WINDOW (widget), FALSE);
6512 *new_flags = geometry_info->mask;
6513 *new_geometry = geometry_info->geometry;
6520 if (geometry_info && geometry_info->widget)
6522 GtkRequisition child_requisition;
6524 /* FIXME: This really isn't right. It gets the min size wrong and forces
6525 * callers to do horrible hacks like set a huge usize on the child requisition
6526 * to get the base size right. We really want to find the answers to:
6528 * - If the geometry widget was infinitely big, how much extra space
6529 * would be needed for the stuff around it.
6531 * - If the geometry widget was infinitely small, how big would the
6532 * window still have to be.
6534 * Finding these answers would be a bit of a mess here. (Bug #68668)
6536 gtk_widget_get_child_requisition (geometry_info->widget, &child_requisition);
6538 extra_width = widget->requisition.width - child_requisition.width;
6539 extra_height = widget->requisition.height - child_requisition.height;
6542 /* We don't want to set GDK_HINT_POS in here, we just set it
6543 * in gtk_window_move_resize() when we want the position
6547 if (*new_flags & GDK_HINT_BASE_SIZE)
6549 new_geometry->base_width += extra_width;
6550 new_geometry->base_height += extra_height;
6552 else if (!(*new_flags & GDK_HINT_MIN_SIZE) &&
6553 (*new_flags & GDK_HINT_RESIZE_INC) &&
6554 ((extra_width != 0) || (extra_height != 0)))
6556 *new_flags |= GDK_HINT_BASE_SIZE;
6558 new_geometry->base_width = extra_width;
6559 new_geometry->base_height = extra_height;
6562 if (*new_flags & GDK_HINT_MIN_SIZE)
6564 if (new_geometry->min_width < 0)
6565 new_geometry->min_width = requisition.width;
6567 new_geometry->min_width += extra_width;
6569 if (new_geometry->min_height < 0)
6570 new_geometry->min_height = requisition.height;
6572 new_geometry->min_height += extra_height;
6574 else if (!window->allow_shrink)
6576 *new_flags |= GDK_HINT_MIN_SIZE;
6578 new_geometry->min_width = requisition.width;
6579 new_geometry->min_height = requisition.height;
6582 if (*new_flags & GDK_HINT_MAX_SIZE)
6584 if (new_geometry->max_width < 0)
6585 new_geometry->max_width = requisition.width;
6587 new_geometry->max_width += extra_width;
6589 if (new_geometry->max_height < 0)
6590 new_geometry->max_height = requisition.height;
6592 new_geometry->max_height += extra_height;
6594 else if (!window->allow_grow)
6596 *new_flags |= GDK_HINT_MAX_SIZE;
6598 new_geometry->max_width = requisition.width;
6599 new_geometry->max_height = requisition.height;
6602 *new_flags |= GDK_HINT_WIN_GRAVITY;
6603 new_geometry->win_gravity = window->gravity;
6606 /***********************
6607 * Redrawing functions *
6608 ***********************/
6611 gtk_window_paint (GtkWidget *widget,
6614 gtk_paint_flat_box (widget->style, widget->window, GTK_STATE_NORMAL,
6615 GTK_SHADOW_NONE, area, widget, "base", 0, 0, -1, -1);
6619 gtk_window_expose (GtkWidget *widget,
6620 GdkEventExpose *event)
6622 if (!GTK_WIDGET_APP_PAINTABLE (widget))
6623 gtk_window_paint (widget, &event->area);
6625 if (GTK_WIDGET_CLASS (gtk_window_parent_class)->expose_event)
6626 return GTK_WIDGET_CLASS (gtk_window_parent_class)->expose_event (widget, event);
6632 * gtk_window_set_has_frame:
6633 * @window: a #GtkWindow
6634 * @setting: a boolean
6636 * (Note: this is a special-purpose function for the framebuffer port,
6637 * that causes GTK+ to draw its own window border. For most applications,
6638 * you want gtk_window_set_decorated() instead, which tells the window
6639 * manager whether to draw the window border.)
6641 * If this function is called on a window with setting of %TRUE, before
6642 * it is realized or showed, it will have a "frame" window around
6643 * @window->window, accessible in @window->frame. Using the signal
6644 * frame_event you can receive all events targeted at the frame.
6646 * This function is used by the linux-fb port to implement managed
6647 * windows, but it could conceivably be used by X-programs that
6648 * want to do their own window decorations.
6652 gtk_window_set_has_frame (GtkWindow *window,
6655 g_return_if_fail (GTK_IS_WINDOW (window));
6656 g_return_if_fail (!GTK_WIDGET_REALIZED (window));
6658 window->has_frame = setting != FALSE;
6662 * gtk_window_get_has_frame:
6663 * @window: a #GtkWindow
6665 * Accessor for whether the window has a frame window exterior to
6666 * @window->window. Gets the value set by gtk_window_set_has_frame ().
6668 * Return value: %TRUE if a frame has been added to the window
6669 * via gtk_window_set_has_frame().
6672 gtk_window_get_has_frame (GtkWindow *window)
6674 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
6676 return window->has_frame;
6680 * gtk_window_set_frame_dimensions:
6681 * @window: a #GtkWindow that has a frame
6682 * @left: The width of the left border
6683 * @top: The height of the top border
6684 * @right: The width of the right border
6685 * @bottom: The height of the bottom border
6687 * (Note: this is a special-purpose function intended for the framebuffer
6688 * port; see gtk_window_set_has_frame(). It will have no effect on the
6689 * window border drawn by the window manager, which is the normal
6690 * case when using the X Window system.)
6692 * For windows with frames (see gtk_window_set_has_frame()) this function
6693 * can be used to change the size of the frame border.
6696 gtk_window_set_frame_dimensions (GtkWindow *window,
6704 g_return_if_fail (GTK_IS_WINDOW (window));
6706 widget = GTK_WIDGET (window);
6708 if (window->frame_left == left &&
6709 window->frame_top == top &&
6710 window->frame_right == right &&
6711 window->frame_bottom == bottom)
6714 window->frame_left = left;
6715 window->frame_top = top;
6716 window->frame_right = right;
6717 window->frame_bottom = bottom;
6719 if (GTK_WIDGET_REALIZED (widget) && window->frame)
6721 gint width = widget->allocation.width + left + right;
6722 gint height = widget->allocation.height + top + bottom;
6723 gdk_window_resize (window->frame, width, height);
6724 gtk_decorated_window_move_resize_window (window,
6726 widget->allocation.width,
6727 widget->allocation.height);
6732 * gtk_window_present:
6733 * @window: a #GtkWindow
6735 * Presents a window to the user. This may mean raising the window
6736 * in the stacking order, deiconifying it, moving it to the current
6737 * desktop, and/or giving it the keyboard focus, possibly dependent
6738 * on the user's platform, window manager, and preferences.
6740 * If @window is hidden, this function calls gtk_widget_show()
6743 * This function should be used when the user tries to open a window
6744 * that's already open. Say for example the preferences dialog is
6745 * currently open, and the user chooses Preferences from the menu
6746 * a second time; use gtk_window_present() to move the already-open dialog
6747 * where the user can see it.
6749 * If you are calling this function in response to a user interaction,
6750 * it is preferable to use gtk_window_present_with_time().
6754 gtk_window_present (GtkWindow *window)
6756 gtk_window_present_with_time (window, GDK_CURRENT_TIME);
6760 * gtk_window_present_with_time:
6761 * @window: a #GtkWindow
6762 * @timestamp: the timestamp of the user interaction (typically a
6763 * button or key press event) which triggered this call
6765 * Presents a window to the user in response to a user interaction.
6766 * If you need to present a window without a timestamp, use
6767 * gtk_window_present(). See gtk_window_present() for details.
6772 gtk_window_present_with_time (GtkWindow *window,
6777 g_return_if_fail (GTK_IS_WINDOW (window));
6779 widget = GTK_WIDGET (window);
6781 if (GTK_WIDGET_VISIBLE (window))
6783 g_assert (widget->window != NULL);
6785 gdk_window_show (widget->window);
6787 /* Translate a timestamp of GDK_CURRENT_TIME appropriately */
6788 if (timestamp == GDK_CURRENT_TIME)
6790 #ifdef GDK_WINDOWING_X11
6791 GdkDisplay *display;
6793 display = gtk_widget_get_display (GTK_WIDGET (window));
6794 timestamp = gdk_x11_display_get_user_time (display);
6796 timestamp = gtk_get_current_event_time ();
6800 gdk_window_focus (widget->window, timestamp);
6804 gtk_widget_show (widget);
6809 * gtk_window_iconify:
6810 * @window: a #GtkWindow
6812 * Asks to iconify (i.e. minimize) the specified @window. Note that
6813 * you shouldn't assume the window is definitely iconified afterward,
6814 * because other entities (e.g. the user or <link
6815 * linkend="gtk-X11-arch">window manager</link>) could deiconify it
6816 * again, or there may not be a window manager in which case
6817 * iconification isn't possible, etc. But normally the window will end
6818 * up iconified. Just don't write code that crashes if not.
6820 * It's permitted to call this function before showing a window,
6821 * in which case the window will be iconified before it ever appears
6824 * You can track iconification via the "window-state-event" signal
6829 gtk_window_iconify (GtkWindow *window)
6832 GdkWindow *toplevel;
6834 g_return_if_fail (GTK_IS_WINDOW (window));
6836 widget = GTK_WIDGET (window);
6838 window->iconify_initially = TRUE;
6841 toplevel = window->frame;
6843 toplevel = widget->window;
6845 if (toplevel != NULL)
6846 gdk_window_iconify (toplevel);
6850 * gtk_window_deiconify:
6851 * @window: a #GtkWindow
6853 * Asks to deiconify (i.e. unminimize) the specified @window. Note
6854 * that you shouldn't assume the window is definitely deiconified
6855 * afterward, because other entities (e.g. the user or <link
6856 * linkend="gtk-X11-arch">window manager</link>) could iconify it
6857 * again before your code which assumes deiconification gets to run.
6859 * You can track iconification via the "window-state-event" signal
6863 gtk_window_deiconify (GtkWindow *window)
6866 GdkWindow *toplevel;
6868 g_return_if_fail (GTK_IS_WINDOW (window));
6870 widget = GTK_WIDGET (window);
6872 window->iconify_initially = FALSE;
6875 toplevel = window->frame;
6877 toplevel = widget->window;
6879 if (toplevel != NULL)
6880 gdk_window_deiconify (toplevel);
6885 * @window: a #GtkWindow
6887 * Asks to stick @window, which means that it will appear on all user
6888 * desktops. Note that you shouldn't assume the window is definitely
6889 * stuck afterward, because other entities (e.g. the user or <link
6890 * linkend="gtk-X11-arch">window manager</link>) could unstick it
6891 * again, and some window managers do not support sticking
6892 * windows. But normally the window will end up stuck. Just don't
6893 * write code that crashes if not.
6895 * It's permitted to call this function before showing a window.
6897 * You can track stickiness via the "window-state-event" signal
6902 gtk_window_stick (GtkWindow *window)
6905 GdkWindow *toplevel;
6907 g_return_if_fail (GTK_IS_WINDOW (window));
6909 widget = GTK_WIDGET (window);
6911 window->stick_initially = TRUE;
6914 toplevel = window->frame;
6916 toplevel = widget->window;
6918 if (toplevel != NULL)
6919 gdk_window_stick (toplevel);
6923 * gtk_window_unstick:
6924 * @window: a #GtkWindow
6926 * Asks to unstick @window, which means that it will appear on only
6927 * one of the user's desktops. Note that you shouldn't assume the
6928 * window is definitely unstuck afterward, because other entities
6929 * (e.g. the user or <link linkend="gtk-X11-arch">window
6930 * manager</link>) could stick it again. But normally the window will
6931 * end up stuck. Just don't write code that crashes if not.
6933 * You can track stickiness via the "window-state-event" signal
6938 gtk_window_unstick (GtkWindow *window)
6941 GdkWindow *toplevel;
6943 g_return_if_fail (GTK_IS_WINDOW (window));
6945 widget = GTK_WIDGET (window);
6947 window->stick_initially = FALSE;
6950 toplevel = window->frame;
6952 toplevel = widget->window;
6954 if (toplevel != NULL)
6955 gdk_window_unstick (toplevel);
6959 * gtk_window_maximize:
6960 * @window: a #GtkWindow
6962 * Asks to maximize @window, so that it becomes full-screen. Note that
6963 * you shouldn't assume the window is definitely maximized afterward,
6964 * because other entities (e.g. the user or <link
6965 * linkend="gtk-X11-arch">window manager</link>) could unmaximize it
6966 * again, and not all window managers support maximization. But
6967 * normally the window will end up maximized. Just don't write code
6968 * that crashes if not.
6970 * It's permitted to call this function before showing a window,
6971 * in which case the window will be maximized when it appears onscreen
6974 * You can track maximization via the "window-state-event" signal
6979 gtk_window_maximize (GtkWindow *window)
6982 GdkWindow *toplevel;
6984 g_return_if_fail (GTK_IS_WINDOW (window));
6986 widget = GTK_WIDGET (window);
6988 window->maximize_initially = TRUE;
6991 toplevel = window->frame;
6993 toplevel = widget->window;
6995 if (toplevel != NULL)
6996 gdk_window_maximize (toplevel);
7000 * gtk_window_unmaximize:
7001 * @window: a #GtkWindow
7003 * Asks to unmaximize @window. Note that you shouldn't assume the
7004 * window is definitely unmaximized afterward, because other entities
7005 * (e.g. the user or <link linkend="gtk-X11-arch">window
7006 * manager</link>) could maximize it again, and not all window
7007 * managers honor requests to unmaximize. But normally the window will
7008 * end up unmaximized. Just don't write code that crashes if not.
7010 * You can track maximization via the "window-state-event" signal
7015 gtk_window_unmaximize (GtkWindow *window)
7018 GdkWindow *toplevel;
7020 g_return_if_fail (GTK_IS_WINDOW (window));
7022 widget = GTK_WIDGET (window);
7024 window->maximize_initially = FALSE;
7027 toplevel = window->frame;
7029 toplevel = widget->window;
7031 if (toplevel != NULL)
7032 gdk_window_unmaximize (toplevel);
7036 * gtk_window_fullscreen:
7037 * @window: a #GtkWindow
7039 * Asks to place @window in the fullscreen state. Note that you
7040 * shouldn't assume the window is definitely full screen afterward,
7041 * because other entities (e.g. the user or <link
7042 * linkend="gtk-X11-arch">window manager</link>) could unfullscreen it
7043 * again, and not all window managers honor requests to fullscreen
7044 * windows. But normally the window will end up fullscreen. Just
7045 * don't write code that crashes if not.
7047 * You can track the fullscreen state via the "window-state-event" signal
7053 gtk_window_fullscreen (GtkWindow *window)
7056 GdkWindow *toplevel;
7057 GtkWindowPrivate *priv;
7059 g_return_if_fail (GTK_IS_WINDOW (window));
7061 widget = GTK_WIDGET (window);
7062 priv = GTK_WINDOW_GET_PRIVATE (window);
7064 priv->fullscreen_initially = TRUE;
7067 toplevel = window->frame;
7069 toplevel = widget->window;
7071 if (toplevel != NULL)
7072 gdk_window_fullscreen (toplevel);
7076 * gtk_window_unfullscreen:
7077 * @window: a #GtkWindow
7079 * Asks to toggle off the fullscreen state for @window. Note that you
7080 * shouldn't assume the window is definitely not full screen
7081 * afterward, because other entities (e.g. the user or <link
7082 * linkend="gtk-X11-arch">window manager</link>) could fullscreen it
7083 * again, and not all window managers honor requests to unfullscreen
7084 * windows. But normally the window will end up restored to its normal
7085 * state. Just don't write code that crashes if not.
7087 * You can track the fullscreen state via the "window-state-event" signal
7093 gtk_window_unfullscreen (GtkWindow *window)
7096 GdkWindow *toplevel;
7097 GtkWindowPrivate *priv;
7099 g_return_if_fail (GTK_IS_WINDOW (window));
7101 widget = GTK_WIDGET (window);
7102 priv = GTK_WINDOW_GET_PRIVATE (window);
7104 priv->fullscreen_initially = FALSE;
7107 toplevel = window->frame;
7109 toplevel = widget->window;
7111 if (toplevel != NULL)
7112 gdk_window_unfullscreen (toplevel);
7116 * gtk_window_set_keep_above:
7117 * @window: a #GtkWindow
7118 * @setting: whether to keep @window above other windows
7120 * Asks to keep @window above, so that it stays on top. Note that
7121 * you shouldn't assume the window is definitely above afterward,
7122 * because other entities (e.g. the user or <link
7123 * linkend="gtk-X11-arch">window manager</link>) could not keep it above,
7124 * and not all window managers support keeping windows above. But
7125 * normally the window will end kept above. Just don't write code
7126 * that crashes if not.
7128 * It's permitted to call this function before showing a window,
7129 * in which case the window will be kept above when it appears onscreen
7132 * You can track the above state via the "window-state-event" signal
7135 * Note that, according to the <ulink
7136 * url="http://www.freedesktop.org/Standards/wm-spec">Extended Window
7137 * Manager Hints</ulink> specification, the above state is mainly meant
7138 * for user preferences and should not be used by applications e.g. for
7139 * drawing attention to their dialogs.
7144 gtk_window_set_keep_above (GtkWindow *window,
7148 GtkWindowPrivate *priv;
7149 GdkWindow *toplevel;
7151 g_return_if_fail (GTK_IS_WINDOW (window));
7153 widget = GTK_WIDGET (window);
7154 priv = GTK_WINDOW_GET_PRIVATE (window);
7156 priv->above_initially = setting != FALSE;
7158 priv->below_initially = FALSE;
7161 toplevel = window->frame;
7163 toplevel = widget->window;
7165 if (toplevel != NULL)
7166 gdk_window_set_keep_above (toplevel, setting);
7170 * gtk_window_set_keep_below:
7171 * @window: a #GtkWindow
7172 * @setting: whether to keep @window below other windows
7174 * Asks to keep @window below, so that it stays in bottom. Note that
7175 * you shouldn't assume the window is definitely below afterward,
7176 * because other entities (e.g. the user or <link
7177 * linkend="gtk-X11-arch">window manager</link>) could not keep it below,
7178 * and not all window managers support putting windows below. But
7179 * normally the window will be kept below. Just don't write code
7180 * that crashes if not.
7182 * It's permitted to call this function before showing a window,
7183 * in which case the window will be kept below when it appears onscreen
7186 * You can track the below state via the "window-state-event" signal
7189 * Note that, according to the <ulink
7190 * url="http://www.freedesktop.org/Standards/wm-spec">Extended Window
7191 * Manager Hints</ulink> specification, the above state is mainly meant
7192 * for user preferences and should not be used by applications e.g. for
7193 * drawing attention to their dialogs.
7198 gtk_window_set_keep_below (GtkWindow *window,
7202 GtkWindowPrivate *priv;
7203 GdkWindow *toplevel;
7205 g_return_if_fail (GTK_IS_WINDOW (window));
7207 widget = GTK_WIDGET (window);
7208 priv = GTK_WINDOW_GET_PRIVATE (window);
7210 priv->below_initially = setting != FALSE;
7212 priv->above_initially = FALSE;
7215 toplevel = window->frame;
7217 toplevel = widget->window;
7219 if (toplevel != NULL)
7220 gdk_window_set_keep_below (toplevel, setting);
7224 * gtk_window_set_resizable:
7225 * @window: a #GtkWindow
7226 * @resizable: %TRUE if the user can resize this window
7228 * Sets whether the user can resize a window. Windows are user resizable
7232 gtk_window_set_resizable (GtkWindow *window,
7235 g_return_if_fail (GTK_IS_WINDOW (window));
7237 gtk_window_set_policy_internal (window, FALSE, resizable, FALSE);
7241 * gtk_window_get_resizable:
7242 * @window: a #GtkWindow
7244 * Gets the value set by gtk_window_set_resizable().
7246 * Return value: %TRUE if the user can resize the window
7249 gtk_window_get_resizable (GtkWindow *window)
7251 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
7253 /* allow_grow is most likely to indicate the semantic concept we
7254 * mean by "resizable" (and will be a reliable indicator if
7255 * set_policy() hasn't been called)
7257 return window->allow_grow;
7261 * gtk_window_set_gravity:
7262 * @window: a #GtkWindow
7263 * @gravity: window gravity
7265 * Window gravity defines the meaning of coordinates passed to
7266 * gtk_window_move(). See gtk_window_move() and #GdkGravity for
7269 * The default window gravity is #GDK_GRAVITY_NORTH_WEST which will
7270 * typically "do what you mean."
7274 gtk_window_set_gravity (GtkWindow *window,
7277 g_return_if_fail (GTK_IS_WINDOW (window));
7279 if (gravity != window->gravity)
7281 window->gravity = gravity;
7283 /* gtk_window_move_resize() will adapt gravity
7285 gtk_widget_queue_resize_no_redraw (GTK_WIDGET (window));
7287 g_object_notify (G_OBJECT (window), "gravity");
7292 * gtk_window_get_gravity:
7293 * @window: a #GtkWindow
7295 * Gets the value set by gtk_window_set_gravity().
7297 * Return value: (transfer none): window gravity
7300 gtk_window_get_gravity (GtkWindow *window)
7302 g_return_val_if_fail (GTK_IS_WINDOW (window), 0);
7304 return window->gravity;
7308 * gtk_window_begin_resize_drag:
7309 * @window: a #GtkWindow
7310 * @button: mouse button that initiated the drag
7311 * @edge: position of the resize control
7312 * @root_x: X position where the user clicked to initiate the drag, in root window coordinates
7313 * @root_y: Y position where the user clicked to initiate the drag
7314 * @timestamp: timestamp from the click event that initiated the drag
7316 * Starts resizing a window. This function is used if an application
7317 * has window resizing controls. When GDK can support it, the resize
7318 * will be done using the standard mechanism for the <link
7319 * linkend="gtk-X11-arch">window manager</link> or windowing
7320 * system. Otherwise, GDK will try to emulate window resizing,
7321 * potentially not all that well, depending on the windowing system.
7325 gtk_window_begin_resize_drag (GtkWindow *window,
7333 GdkWindow *toplevel;
7335 g_return_if_fail (GTK_IS_WINDOW (window));
7336 g_return_if_fail (GTK_WIDGET_VISIBLE (window));
7338 widget = GTK_WIDGET (window);
7341 toplevel = window->frame;
7343 toplevel = widget->window;
7345 gdk_window_begin_resize_drag (toplevel,
7352 * gtk_window_get_frame_dimensions:
7353 * @window: a #GtkWindow
7354 * @left: location to store the width of the frame at the left, or %NULL
7355 * @top: location to store the height of the frame at the top, or %NULL
7356 * @right: location to store the width of the frame at the returns, or %NULL
7357 * @bottom: location to store the height of the frame at the bottom, or %NULL
7359 * (Note: this is a special-purpose function intended for the
7360 * framebuffer port; see gtk_window_set_has_frame(). It will not
7361 * return the size of the window border drawn by the <link
7362 * linkend="gtk-X11-arch">window manager</link>, which is the normal
7363 * case when using a windowing system. See
7364 * gdk_window_get_frame_extents() to get the standard window border
7367 * Retrieves the dimensions of the frame window for this toplevel.
7368 * See gtk_window_set_has_frame(), gtk_window_set_frame_dimensions().
7371 gtk_window_get_frame_dimensions (GtkWindow *window,
7377 g_return_if_fail (GTK_IS_WINDOW (window));
7380 *left = window->frame_left;
7382 *top = window->frame_top;
7384 *right = window->frame_right;
7386 *bottom = window->frame_bottom;
7390 * gtk_window_begin_move_drag:
7391 * @window: a #GtkWindow
7392 * @button: mouse button that initiated the drag
7393 * @root_x: X position where the user clicked to initiate the drag, in root window coordinates
7394 * @root_y: Y position where the user clicked to initiate the drag
7395 * @timestamp: timestamp from the click event that initiated the drag
7397 * Starts moving a window. This function is used if an application has
7398 * window movement grips. When GDK can support it, the window movement
7399 * will be done using the standard mechanism for the <link
7400 * linkend="gtk-X11-arch">window manager</link> or windowing
7401 * system. Otherwise, GDK will try to emulate window movement,
7402 * potentially not all that well, depending on the windowing system.
7406 gtk_window_begin_move_drag (GtkWindow *window,
7413 GdkWindow *toplevel;
7415 g_return_if_fail (GTK_IS_WINDOW (window));
7416 g_return_if_fail (GTK_WIDGET_VISIBLE (window));
7418 widget = GTK_WIDGET (window);
7421 toplevel = window->frame;
7423 toplevel = widget->window;
7425 gdk_window_begin_move_drag (toplevel,
7432 * gtk_window_set_screen:
7433 * @window: a #GtkWindow.
7434 * @screen: a #GdkScreen.
7436 * Sets the #GdkScreen where the @window is displayed; if
7437 * the window is already mapped, it will be unmapped, and
7438 * then remapped on the new screen.
7443 gtk_window_set_screen (GtkWindow *window,
7447 GdkScreen *previous_screen;
7448 gboolean was_mapped;
7450 g_return_if_fail (GTK_IS_WINDOW (window));
7451 g_return_if_fail (GDK_IS_SCREEN (screen));
7453 if (screen == window->screen)
7456 widget = GTK_WIDGET (window);
7458 previous_screen = window->screen;
7459 was_mapped = GTK_WIDGET_MAPPED (widget);
7462 gtk_widget_unmap (widget);
7463 if (GTK_WIDGET_REALIZED (widget))
7464 gtk_widget_unrealize (widget);
7466 gtk_window_free_key_hash (window);
7467 window->screen = screen;
7468 gtk_widget_reset_rc_styles (widget);
7469 if (screen != previous_screen)
7471 g_signal_handlers_disconnect_by_func (previous_screen,
7472 gtk_window_on_composited_changed, window);
7473 g_signal_connect (screen, "composited-changed",
7474 G_CALLBACK (gtk_window_on_composited_changed), window);
7476 _gtk_widget_propagate_screen_changed (widget, previous_screen);
7477 _gtk_widget_propagate_composited_changed (widget);
7479 g_object_notify (G_OBJECT (window), "screen");
7482 gtk_widget_map (widget);
7486 gtk_window_on_composited_changed (GdkScreen *screen,
7489 gtk_widget_queue_draw (GTK_WIDGET (window));
7491 _gtk_widget_propagate_composited_changed (GTK_WIDGET (window));
7495 gtk_window_check_screen (GtkWindow *window)
7498 return window->screen;
7501 g_warning ("Screen for GtkWindow not set; you must always set\n"
7502 "a screen for a GtkWindow before using the window");
7508 * gtk_window_get_screen:
7509 * @window: a #GtkWindow.
7511 * Returns the #GdkScreen associated with @window.
7513 * Return value: (transfer none): a #GdkScreen.
7518 gtk_window_get_screen (GtkWindow *window)
7520 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
7522 return window->screen;
7526 * gtk_window_is_active:
7527 * @window: a #GtkWindow
7529 * Returns whether the window is part of the current active toplevel.
7530 * (That is, the toplevel window receiving keystrokes.)
7531 * The return value is %TRUE if the window is active toplevel
7532 * itself, but also if it is, say, a #GtkPlug embedded in the active toplevel.
7533 * You might use this function if you wanted to draw a widget
7534 * differently in an active window from a widget in an inactive window.
7535 * See gtk_window_has_toplevel_focus()
7537 * Return value: %TRUE if the window part of the current active window.
7542 gtk_window_is_active (GtkWindow *window)
7544 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
7546 return window->is_active;
7550 * gtk_window_has_toplevel_focus:
7551 * @window: a #GtkWindow
7553 * Returns whether the input focus is within this GtkWindow.
7554 * For real toplevel windows, this is identical to gtk_window_is_active(),
7555 * but for embedded windows, like #GtkPlug, the results will differ.
7557 * Return value: %TRUE if the input focus is within this GtkWindow
7562 gtk_window_has_toplevel_focus (GtkWindow *window)
7564 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
7566 return window->has_toplevel_focus;
7570 gtk_window_group_class_init (GtkWindowGroupClass *klass)
7575 gtk_window_group_get_type (void)
7577 static GType window_group_type = 0;
7579 if (!window_group_type)
7581 const GTypeInfo window_group_info =
7583 sizeof (GtkWindowGroupClass),
7584 NULL, /* base_init */
7585 NULL, /* base_finalize */
7586 (GClassInitFunc) gtk_window_group_class_init,
7587 NULL, /* class_finalize */
7588 NULL, /* class_data */
7589 sizeof (GtkWindowGroup),
7590 0, /* n_preallocs */
7591 (GInstanceInitFunc) NULL,
7594 window_group_type = g_type_register_static (G_TYPE_OBJECT, I_("GtkWindowGroup"),
7595 &window_group_info, 0);
7598 return window_group_type;
7602 * gtk_window_group_new:
7604 * Creates a new #GtkWindowGroup object. Grabs added with
7605 * gtk_grab_add() only affect windows within the same #GtkWindowGroup.
7607 * Return value: a new #GtkWindowGroup.
7610 gtk_window_group_new (void)
7612 return g_object_new (GTK_TYPE_WINDOW_GROUP, NULL);
7616 window_group_cleanup_grabs (GtkWindowGroup *group,
7620 GSList *to_remove = NULL;
7622 tmp_list = group->grabs;
7625 if (gtk_widget_get_toplevel (tmp_list->data) == (GtkWidget*) window)
7626 to_remove = g_slist_prepend (to_remove, g_object_ref (tmp_list->data));
7627 tmp_list = tmp_list->next;
7632 gtk_grab_remove (to_remove->data);
7633 g_object_unref (to_remove->data);
7634 to_remove = g_slist_delete_link (to_remove, to_remove);
7639 * gtk_window_group_add_window:
7640 * @window_group: a #GtkWindowGroup
7641 * @window: the #GtkWindow to add
7643 * Adds a window to a #GtkWindowGroup.
7646 gtk_window_group_add_window (GtkWindowGroup *window_group,
7649 g_return_if_fail (GTK_IS_WINDOW_GROUP (window_group));
7650 g_return_if_fail (GTK_IS_WINDOW (window));
7652 if (window->group != window_group)
7654 g_object_ref (window);
7655 g_object_ref (window_group);
7658 gtk_window_group_remove_window (window->group, window);
7660 window_group_cleanup_grabs (gtk_window_get_group (NULL), window);
7662 window->group = window_group;
7664 g_object_unref (window);
7669 * gtk_window_group_remove_window:
7670 * @window_group: a #GtkWindowGroup
7671 * @window: the #GtkWindow to remove
7673 * Removes a window from a #GtkWindowGroup.
7676 gtk_window_group_remove_window (GtkWindowGroup *window_group,
7679 g_return_if_fail (GTK_IS_WINDOW_GROUP (window_group));
7680 g_return_if_fail (GTK_IS_WINDOW (window));
7681 g_return_if_fail (window->group == window_group);
7683 g_object_ref (window);
7685 window_group_cleanup_grabs (window_group, window);
7686 window->group = NULL;
7688 g_object_unref (window_group);
7689 g_object_unref (window);
7693 * gtk_window_group_list_windows:
7694 * @window_group: a #GtkWindowGroup
7696 * Returns a list of the #GtkWindows that belong to @window_group.
7698 * Returns: (element-type GtkWidget) (transfer container): A newly-allocated list of
7699 * windows inside the group.
7704 gtk_window_group_list_windows (GtkWindowGroup *window_group)
7706 GList *toplevels, *toplevel, *group_windows;
7708 g_return_val_if_fail (GTK_IS_WINDOW_GROUP (window_group), NULL);
7710 group_windows = NULL;
7711 toplevels = gtk_window_list_toplevels ();
7713 for (toplevel = toplevels; toplevel; toplevel = toplevel->next)
7715 GtkWindow *window = toplevel->data;
7717 if (window_group == window->group)
7718 group_windows = g_list_prepend (group_windows, window);
7721 return g_list_reverse (group_windows);
7725 * gtk_window_get_group:
7726 * @window: a #GtkWindow, or %NULL
7728 * Returns the group for @window or the default group, if
7729 * @window is %NULL or if @window does not have an explicit
7732 * Returns: (transfer none): the #GtkWindowGroup for a window or the default group
7737 gtk_window_get_group (GtkWindow *window)
7739 if (window && window->group)
7740 return window->group;
7743 static GtkWindowGroup *default_group = NULL;
7746 default_group = gtk_window_group_new ();
7748 return default_group;
7752 /* Return the current grab widget of the given group
7755 _gtk_window_group_get_current_grab (GtkWindowGroup *window_group)
7757 if (window_group->grabs)
7758 return GTK_WIDGET (window_group->grabs->data);
7763 Derived from XParseGeometry() in XFree86
7765 Copyright 1985, 1986, 1987,1998 The Open Group
7767 All Rights Reserved.
7769 The above copyright notice and this permission notice shall be included
7770 in all copies or substantial portions of the Software.
7772 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
7773 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
7774 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
7775 IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
7776 OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
7777 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
7778 OTHER DEALINGS IN THE SOFTWARE.
7780 Except as contained in this notice, the name of The Open Group shall
7781 not be used in advertising or otherwise to promote the sale, use or
7782 other dealings in this Software without prior written authorization
7783 from The Open Group.
7788 * XParseGeometry parses strings of the form
7789 * "=<width>x<height>{+-}<xoffset>{+-}<yoffset>", where
7790 * width, height, xoffset, and yoffset are unsigned integers.
7791 * Example: "=80x24+300-49"
7792 * The equal sign is optional.
7793 * It returns a bitmask that indicates which of the four values
7794 * were actually found in the string. For each value found,
7795 * the corresponding argument is updated; for each value
7796 * not found, the corresponding argument is left unchanged.
7799 /* The following code is from Xlib, and is minimally modified, so we
7800 * can track any upstream changes if required. Don't change this
7801 * code. Or if you do, put in a huge comment marking which thing
7806 read_int (gchar *string,
7814 else if (*string == '-')
7820 for (; (*string >= '0') && (*string <= '9'); string++)
7822 result = (result * 10) + (*string - '0');
7834 * Bitmask returned by XParseGeometry(). Each bit tells if the corresponding
7835 * value (x, y, width, height) was found in the parsed string.
7837 #define NoValue 0x0000
7838 #define XValue 0x0001
7839 #define YValue 0x0002
7840 #define WidthValue 0x0004
7841 #define HeightValue 0x0008
7842 #define AllValues 0x000F
7843 #define XNegative 0x0010
7844 #define YNegative 0x0020
7846 /* Try not to reformat/modify, so we can compare/sync with X sources */
7848 gtk_XParseGeometry (const char *string,
7851 unsigned int *width,
7852 unsigned int *height)
7856 unsigned int tempWidth, tempHeight;
7858 char *nextCharacter;
7860 /* These initializations are just to silence gcc */
7866 if ( (string == NULL) || (*string == '\0')) return(mask);
7868 string++; /* ignore possible '=' at beg of geometry spec */
7870 strind = (char *)string;
7871 if (*strind != '+' && *strind != '-' && *strind != 'x') {
7872 tempWidth = read_int(strind, &nextCharacter);
7873 if (strind == nextCharacter)
7875 strind = nextCharacter;
7879 if (*strind == 'x' || *strind == 'X') {
7881 tempHeight = read_int(strind, &nextCharacter);
7882 if (strind == nextCharacter)
7884 strind = nextCharacter;
7885 mask |= HeightValue;
7888 if ((*strind == '+') || (*strind == '-')) {
7889 if (*strind == '-') {
7891 tempX = -read_int(strind, &nextCharacter);
7892 if (strind == nextCharacter)
7894 strind = nextCharacter;
7900 tempX = read_int(strind, &nextCharacter);
7901 if (strind == nextCharacter)
7903 strind = nextCharacter;
7906 if ((*strind == '+') || (*strind == '-')) {
7907 if (*strind == '-') {
7909 tempY = -read_int(strind, &nextCharacter);
7910 if (strind == nextCharacter)
7912 strind = nextCharacter;
7919 tempY = read_int(strind, &nextCharacter);
7920 if (strind == nextCharacter)
7922 strind = nextCharacter;
7928 /* If strind isn't at the end of the string the it's an invalid
7929 geometry specification. */
7931 if (*strind != '\0') return (0);
7937 if (mask & WidthValue)
7939 if (mask & HeightValue)
7940 *height = tempHeight;
7945 * gtk_window_parse_geometry:
7946 * @window: a #GtkWindow
7947 * @geometry: geometry string
7949 * Parses a standard X Window System geometry string - see the
7950 * manual page for X (type 'man X') for details on this.
7951 * gtk_window_parse_geometry() does work on all GTK+ ports
7952 * including Win32 but is primarily intended for an X environment.
7954 * If either a size or a position can be extracted from the
7955 * geometry string, gtk_window_parse_geometry() returns %TRUE
7956 * and calls gtk_window_set_default_size() and/or gtk_window_move()
7957 * to resize/move the window.
7959 * If gtk_window_parse_geometry() returns %TRUE, it will also
7960 * set the #GDK_HINT_USER_POS and/or #GDK_HINT_USER_SIZE hints
7961 * indicating to the window manager that the size/position of
7962 * the window was user-specified. This causes most window
7963 * managers to honor the geometry.
7965 * Note that for gtk_window_parse_geometry() to work as expected, it has
7966 * to be called when the window has its "final" size, i.e. after calling
7967 * gtk_widget_show_all() on the contents and gtk_window_set_geometry_hints()
7970 * #include <gtk/gtk.h>
7973 * fill_with_content (GtkWidget *vbox)
7975 * /* fill with content... */
7979 * main (int argc, char *argv[])
7981 * GtkWidget *window, *vbox;
7982 * GdkGeometry size_hints = {
7983 * 100, 50, 0, 0, 100, 50, 10, 10, 0.0, 0.0, GDK_GRAVITY_NORTH_WEST
7986 * gtk_init (&argc, &argv);
7988 * window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
7989 * vbox = gtk_vbox_new (FALSE, 0);
7991 * gtk_container_add (GTK_CONTAINER (window), vbox);
7992 * fill_with_content (vbox);
7993 * gtk_widget_show_all (vbox);
7995 * gtk_window_set_geometry_hints (GTK_WINDOW (window),
7998 * GDK_HINT_MIN_SIZE |
7999 * GDK_HINT_BASE_SIZE |
8000 * GDK_HINT_RESIZE_INC);
8004 * if (!gtk_window_parse_geometry (GTK_WINDOW (window), argv[1]))
8005 * fprintf (stderr, "Failed to parse '%s'\n", argv[1]);
8008 * gtk_widget_show_all (window);
8015 * Return value: %TRUE if string was parsed successfully
8018 gtk_window_parse_geometry (GtkWindow *window,
8019 const gchar *geometry)
8021 gint result, x = 0, y = 0;
8024 gboolean size_set, pos_set;
8027 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
8028 g_return_val_if_fail (geometry != NULL, FALSE);
8030 screen = gtk_window_check_screen (window);
8032 result = gtk_XParseGeometry (geometry, &x, &y, &w, &h);
8035 if ((result & WidthValue) || (result & HeightValue))
8037 gtk_window_set_default_size_internal (window,
8038 TRUE, result & WidthValue ? w : -1,
8039 TRUE, result & HeightValue ? h : -1,
8044 gtk_window_get_size (window, (gint *)&w, (gint *)&h);
8046 grav = GDK_GRAVITY_NORTH_WEST;
8048 if ((result & XNegative) && (result & YNegative))
8049 grav = GDK_GRAVITY_SOUTH_EAST;
8050 else if (result & XNegative)
8051 grav = GDK_GRAVITY_NORTH_EAST;
8052 else if (result & YNegative)
8053 grav = GDK_GRAVITY_SOUTH_WEST;
8055 if ((result & XValue) == 0)
8058 if ((result & YValue) == 0)
8061 if (grav == GDK_GRAVITY_SOUTH_WEST ||
8062 grav == GDK_GRAVITY_SOUTH_EAST)
8063 y = gdk_screen_get_height (screen) - h + y;
8065 if (grav == GDK_GRAVITY_SOUTH_EAST ||
8066 grav == GDK_GRAVITY_NORTH_EAST)
8067 x = gdk_screen_get_width (screen) - w + x;
8069 /* we don't let you put a window offscreen; maybe some people would
8070 * prefer to be able to, but it's kind of a bogus thing to do.
8079 if ((result & XValue) || (result & YValue))
8081 gtk_window_set_gravity (window, grav);
8082 gtk_window_move (window, x, y);
8086 if (size_set || pos_set)
8088 /* Set USSize, USPosition hints */
8089 GtkWindowGeometryInfo *info;
8091 info = gtk_window_get_geometry_info (window, TRUE);
8094 info->mask |= GDK_HINT_USER_POS;
8096 info->mask |= GDK_HINT_USER_SIZE;
8103 gtk_window_mnemonic_hash_foreach (guint keyval,
8109 GtkWindowKeysForeachFunc func;
8113 (*info->func) (info->window, keyval, info->window->mnemonic_modifier, TRUE, info->func_data);
8117 _gtk_window_keys_foreach (GtkWindow *window,
8118 GtkWindowKeysForeachFunc func,
8122 GtkMnemonicHash *mnemonic_hash;
8126 GtkWindowKeysForeachFunc func;
8130 info.window = window;
8132 info.func_data = func_data;
8134 mnemonic_hash = gtk_window_get_mnemonic_hash (window, FALSE);
8136 _gtk_mnemonic_hash_foreach (mnemonic_hash,
8137 gtk_window_mnemonic_hash_foreach, &info);
8139 groups = gtk_accel_groups_from_object (G_OBJECT (window));
8142 GtkAccelGroup *group = groups->data;
8145 for (i = 0; i < group->n_accels; i++)
8147 GtkAccelKey *key = &group->priv_accels[i].key;
8150 (*func) (window, key->accel_key, key->accel_mods, FALSE, func_data);
8153 groups = groups->next;
8158 gtk_window_keys_changed (GtkWindow *window)
8160 gtk_window_free_key_hash (window);
8161 gtk_window_get_key_hash (window);
8164 typedef struct _GtkWindowKeyEntry GtkWindowKeyEntry;
8166 struct _GtkWindowKeyEntry
8170 guint is_mnemonic : 1;
8174 window_key_entry_destroy (gpointer data)
8176 g_slice_free (GtkWindowKeyEntry, data);
8180 add_to_key_hash (GtkWindow *window,
8182 GdkModifierType modifiers,
8183 gboolean is_mnemonic,
8186 GtkKeyHash *key_hash = data;
8188 GtkWindowKeyEntry *entry = g_slice_new (GtkWindowKeyEntry);
8190 entry->keyval = keyval;
8191 entry->modifiers = modifiers;
8192 entry->is_mnemonic = is_mnemonic;
8194 /* GtkAccelGroup stores lowercased accelerators. To deal
8195 * with this, if <Shift> was specified, uppercase.
8197 if (modifiers & GDK_SHIFT_MASK)
8199 if (keyval == GDK_Tab)
8200 keyval = GDK_ISO_Left_Tab;
8202 keyval = gdk_keyval_to_upper (keyval);
8205 _gtk_key_hash_add_entry (key_hash, keyval, entry->modifiers, entry);
8209 gtk_window_get_key_hash (GtkWindow *window)
8211 GdkScreen *screen = gtk_window_check_screen (window);
8212 GtkKeyHash *key_hash = g_object_get_qdata (G_OBJECT (window), quark_gtk_window_key_hash);
8217 key_hash = _gtk_key_hash_new (gdk_keymap_get_for_display (gdk_screen_get_display (screen)),
8218 (GDestroyNotify)window_key_entry_destroy);
8219 _gtk_window_keys_foreach (window, add_to_key_hash, key_hash);
8220 g_object_set_qdata (G_OBJECT (window), quark_gtk_window_key_hash, key_hash);
8226 gtk_window_free_key_hash (GtkWindow *window)
8228 GtkKeyHash *key_hash = g_object_get_qdata (G_OBJECT (window), quark_gtk_window_key_hash);
8231 _gtk_key_hash_free (key_hash);
8232 g_object_set_qdata (G_OBJECT (window), quark_gtk_window_key_hash, NULL);
8237 * gtk_window_activate_key:
8238 * @window: a #GtkWindow
8239 * @event: a #GdkEventKey
8241 * Activates mnemonics and accelerators for this #GtkWindow. This is normally
8242 * called by the default ::key_press_event handler for toplevel windows,
8243 * however in some cases it may be useful to call this directly when
8244 * overriding the standard key handling for a toplevel window.
8246 * Return value: %TRUE if a mnemonic or accelerator was found and activated.
8251 gtk_window_activate_key (GtkWindow *window,
8254 GtkKeyHash *key_hash;
8255 GtkWindowKeyEntry *found_entry = NULL;
8256 gboolean enable_mnemonics;
8257 gboolean enable_accels;
8259 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
8260 g_return_val_if_fail (event != NULL, FALSE);
8262 key_hash = gtk_window_get_key_hash (window);
8267 GSList *entries = _gtk_key_hash_lookup (key_hash,
8268 event->hardware_keycode,
8270 gtk_accelerator_get_default_mod_mask (),
8273 g_object_get (gtk_widget_get_settings (GTK_WIDGET (window)),
8274 "gtk-enable-mnemonics", &enable_mnemonics,
8275 "gtk-enable-accels", &enable_accels,
8278 for (tmp_list = entries; tmp_list; tmp_list = tmp_list->next)
8280 GtkWindowKeyEntry *entry = tmp_list->data;
8281 if (entry->is_mnemonic)
8283 if (enable_mnemonics)
8285 found_entry = entry;
8291 if (enable_accels && !found_entry)
8293 found_entry = entry;
8298 g_slist_free (entries);
8303 if (found_entry->is_mnemonic)
8305 if (enable_mnemonics)
8306 return gtk_window_mnemonic_activate (window, found_entry->keyval,
8307 found_entry->modifiers);
8312 return gtk_accel_groups_activate (G_OBJECT (window), found_entry->keyval,
8313 found_entry->modifiers);
8321 window_update_has_focus (GtkWindow *window)
8323 GtkWidget *widget = GTK_WIDGET (window);
8324 gboolean has_focus = window->has_toplevel_focus && window->is_active;
8326 if (has_focus != window->has_focus)
8328 window->has_focus = has_focus;
8332 if (window->focus_widget &&
8333 window->focus_widget != widget &&
8334 !GTK_WIDGET_HAS_FOCUS (window->focus_widget))
8335 do_focus_change (window->focus_widget, TRUE);
8339 if (window->focus_widget &&
8340 window->focus_widget != widget &&
8341 GTK_WIDGET_HAS_FOCUS (window->focus_widget))
8342 do_focus_change (window->focus_widget, FALSE);
8348 * _gtk_window_set_is_active:
8349 * @window: a #GtkWindow
8350 * @is_active: %TRUE if the window is in the currently active toplevel
8352 * Internal function that sets whether the #GtkWindow is part
8353 * of the currently active toplevel window (taking into account inter-process
8357 _gtk_window_set_is_active (GtkWindow *window,
8360 g_return_if_fail (GTK_IS_WINDOW (window));
8362 is_active = is_active != FALSE;
8364 if (is_active != window->is_active)
8366 window->is_active = is_active;
8367 window_update_has_focus (window);
8369 g_object_notify (G_OBJECT (window), "is-active");
8374 * _gtk_window_set_is_toplevel:
8375 * @window: a #GtkWindow
8376 * @is_toplevel: %TRUE if the window is still a real toplevel (nominally a
8377 * parent of the root window); %FALSE if it is not (for example, for an
8378 * in-process, parented GtkPlug)
8380 * Internal function used by #GtkPlug when it gets parented/unparented by a
8381 * #GtkSocket. This keeps the @window's #GTK_TOPLEVEL flag in sync with the
8382 * global list of toplevel windows.
8385 _gtk_window_set_is_toplevel (GtkWindow *window,
8386 gboolean is_toplevel)
8388 if (gtk_widget_is_toplevel (GTK_WIDGET (window)))
8389 g_assert (g_slist_find (toplevel_list, window) != NULL);
8391 g_assert (g_slist_find (toplevel_list, window) == NULL);
8393 if (is_toplevel == gtk_widget_is_toplevel (GTK_WIDGET (window)))
8398 GTK_WIDGET_SET_FLAGS (window, GTK_TOPLEVEL);
8399 toplevel_list = g_slist_prepend (toplevel_list, window);
8403 GTK_WIDGET_UNSET_FLAGS (window, GTK_TOPLEVEL);
8404 toplevel_list = g_slist_remove (toplevel_list, window);
8409 * _gtk_window_set_has_toplevel_focus:
8410 * @window: a #GtkWindow
8411 * @has_toplevel_focus: %TRUE if the in
8413 * Internal function that sets whether the keyboard focus for the
8414 * toplevel window (taking into account inter-process embedding.)
8417 _gtk_window_set_has_toplevel_focus (GtkWindow *window,
8418 gboolean has_toplevel_focus)
8420 g_return_if_fail (GTK_IS_WINDOW (window));
8422 has_toplevel_focus = has_toplevel_focus != FALSE;
8424 if (has_toplevel_focus != window->has_toplevel_focus)
8426 window->has_toplevel_focus = has_toplevel_focus;
8427 window_update_has_focus (window);
8429 g_object_notify (G_OBJECT (window), "has-toplevel-focus");
8434 * gtk_window_set_auto_startup_notification:
8435 * @setting: %TRUE to automatically do startup notification
8437 * By default, after showing the first #GtkWindow, GTK+ calls
8438 * gdk_notify_startup_complete(). Call this function to disable
8439 * the automatic startup notification. You might do this if your
8440 * first window is a splash screen, and you want to delay notification
8441 * until after your real main window has been shown, for example.
8443 * In that example, you would disable startup notification
8444 * temporarily, show your splash screen, then re-enable it so that
8445 * showing the main window would automatically result in notification.
8450 gtk_window_set_auto_startup_notification (gboolean setting)
8452 disable_startup_notification = !setting;
8456 * gtk_window_get_window_type:
8457 * @window: a #GtkWindow
8459 * Gets the type of the window. See #GtkWindowType.
8461 * Return value: the type of the window
8466 gtk_window_get_window_type (GtkWindow *window)
8468 g_return_val_if_fail (GTK_IS_WINDOW (window), GTK_WINDOW_TOPLEVEL);
8470 return window->type;
8474 gtk_window_get_mnemonics_visible (GtkWindow *window)
8476 GtkWindowPrivate *priv;
8478 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
8480 priv = GTK_WINDOW_GET_PRIVATE (window);
8482 return priv->mnemonics_visible;
8486 gtk_window_set_mnemonics_visible (GtkWindow *window,
8489 GtkWindowPrivate *priv;
8491 g_return_if_fail (GTK_IS_WINDOW (window));
8493 priv = GTK_WINDOW_GET_PRIVATE (window);
8495 setting = setting != FALSE;
8497 if (priv->mnemonics_visible != setting)
8499 priv->mnemonics_visible = setting;
8500 g_object_notify (G_OBJECT (window), "mnemonics-visible");
8503 priv->mnemonics_visible_set = TRUE;
8506 #if defined (G_OS_WIN32) && !defined (_WIN64)
8508 #undef gtk_window_set_icon_from_file
8511 gtk_window_set_icon_from_file (GtkWindow *window,
8512 const gchar *filename,
8515 gchar *utf8_filename = g_locale_to_utf8 (filename, -1, NULL, NULL, err);
8518 if (utf8_filename == NULL)
8521 retval = gtk_window_set_icon_from_file_utf8 (window, utf8_filename, err);
8523 g_free (utf8_filename);
8528 #undef gtk_window_set_default_icon_from_file
8531 gtk_window_set_default_icon_from_file (const gchar *filename,
8534 gchar *utf8_filename = g_locale_to_utf8 (filename, -1, NULL, NULL, err);
8537 if (utf8_filename == NULL)
8540 retval = gtk_window_set_default_icon_from_file_utf8 (utf8_filename, err);
8542 g_free (utf8_filename);
8549 #define __GTK_WINDOW_C__
8550 #include "gtkaliasdef.c"