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_get_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_get_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_get_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_get_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_widget_set_receives_default()), 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_get_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,
2042 g_return_if_fail (GTK_IS_WINDOW (window));
2044 modal = modal != FALSE;
2045 if (window->modal == modal)
2048 window->modal = modal;
2049 widget = GTK_WIDGET (window);
2051 /* adjust desired modality state */
2052 if (GTK_WIDGET_REALIZED (window))
2055 gdk_window_set_modal_hint (widget->window, TRUE);
2057 gdk_window_set_modal_hint (widget->window, FALSE);
2060 if (gtk_widget_get_visible (widget))
2063 gtk_grab_add (widget);
2065 gtk_grab_remove (widget);
2068 g_object_notify (G_OBJECT (window), "modal");
2072 * gtk_window_get_modal:
2073 * @window: a #GtkWindow
2075 * Returns whether the window is modal. See gtk_window_set_modal().
2077 * Return value: %TRUE if the window is set to be modal and
2078 * establishes a grab when shown
2081 gtk_window_get_modal (GtkWindow *window)
2083 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
2085 return window->modal;
2089 * gtk_window_list_toplevels:
2091 * Returns a list of all existing toplevel windows. The widgets
2092 * in the list are not individually referenced. If you want
2093 * to iterate through the list and perform actions involving
2094 * callbacks that might destroy the widgets, you <emphasis>must</emphasis> call
2095 * <literal>g_list_foreach (result, (GFunc)g_object_ref, NULL)</literal> first, and
2096 * then unref all the widgets afterwards.
2098 * Return value: (element-type GtkWidget) (transfer container): list of toplevel widgets
2101 gtk_window_list_toplevels (void)
2106 for (slist = toplevel_list; slist; slist = slist->next)
2107 list = g_list_prepend (list, slist->data);
2113 gtk_window_add_embedded_xid (GtkWindow *window, GdkNativeWindow xid)
2115 GList *embedded_windows;
2117 g_return_if_fail (GTK_IS_WINDOW (window));
2119 embedded_windows = g_object_get_qdata (G_OBJECT (window), quark_gtk_embedded);
2120 if (embedded_windows)
2121 g_object_steal_qdata (G_OBJECT (window), quark_gtk_embedded);
2122 embedded_windows = g_list_prepend (embedded_windows,
2123 GUINT_TO_POINTER (xid));
2125 g_object_set_qdata_full (G_OBJECT (window), quark_gtk_embedded,
2128 (GDestroyNotify) g_list_free : NULL);
2132 gtk_window_remove_embedded_xid (GtkWindow *window, GdkNativeWindow xid)
2134 GList *embedded_windows;
2137 g_return_if_fail (GTK_IS_WINDOW (window));
2139 embedded_windows = g_object_get_qdata (G_OBJECT (window), quark_gtk_embedded);
2140 if (embedded_windows)
2141 g_object_steal_qdata (G_OBJECT (window), quark_gtk_embedded);
2143 node = g_list_find (embedded_windows, GUINT_TO_POINTER (xid));
2146 embedded_windows = g_list_remove_link (embedded_windows, node);
2147 g_list_free_1 (node);
2150 g_object_set_qdata_full (G_OBJECT (window), quark_gtk_embedded,
2153 (GDestroyNotify) g_list_free : NULL);
2157 _gtk_window_reposition (GtkWindow *window,
2161 g_return_if_fail (GTK_IS_WINDOW (window));
2163 gtk_window_move (window, x, y);
2167 gtk_window_dispose (GObject *object)
2169 GtkWindow *window = GTK_WINDOW (object);
2171 gtk_window_set_focus (window, NULL);
2172 gtk_window_set_default (window, NULL);
2174 G_OBJECT_CLASS (gtk_window_parent_class)->dispose (object);
2178 parent_destroyed_callback (GtkWindow *parent, GtkWindow *child)
2180 gtk_widget_destroy (GTK_WIDGET (child));
2184 connect_parent_destroyed (GtkWindow *window)
2186 if (window->transient_parent)
2188 g_signal_connect (window->transient_parent,
2190 G_CALLBACK (parent_destroyed_callback),
2196 disconnect_parent_destroyed (GtkWindow *window)
2198 if (window->transient_parent)
2200 g_signal_handlers_disconnect_by_func (window->transient_parent,
2201 parent_destroyed_callback,
2207 gtk_window_transient_parent_realized (GtkWidget *parent,
2210 if (GTK_WIDGET_REALIZED (window))
2211 gdk_window_set_transient_for (window->window, parent->window);
2215 gtk_window_transient_parent_unrealized (GtkWidget *parent,
2218 if (GTK_WIDGET_REALIZED (window))
2219 gdk_property_delete (window->window,
2220 gdk_atom_intern_static_string ("WM_TRANSIENT_FOR"));
2224 gtk_window_transient_parent_screen_changed (GtkWindow *parent,
2228 gtk_window_set_screen (window, parent->screen);
2232 gtk_window_unset_transient_for (GtkWindow *window)
2234 GtkWindowPrivate *priv = GTK_WINDOW_GET_PRIVATE (window);
2236 if (window->transient_parent)
2238 g_signal_handlers_disconnect_by_func (window->transient_parent,
2239 gtk_window_transient_parent_realized,
2241 g_signal_handlers_disconnect_by_func (window->transient_parent,
2242 gtk_window_transient_parent_unrealized,
2244 g_signal_handlers_disconnect_by_func (window->transient_parent,
2245 gtk_window_transient_parent_screen_changed,
2247 g_signal_handlers_disconnect_by_func (window->transient_parent,
2248 gtk_widget_destroyed,
2249 &window->transient_parent);
2251 if (window->destroy_with_parent)
2252 disconnect_parent_destroyed (window);
2254 window->transient_parent = NULL;
2256 if (priv->transient_parent_group)
2258 priv->transient_parent_group = FALSE;
2259 gtk_window_group_remove_window (window->group,
2266 * gtk_window_set_transient_for:
2267 * @window: a #GtkWindow
2268 * @parent: (allow-none): parent window
2270 * Dialog windows should be set transient for the main application
2271 * window they were spawned from. This allows <link
2272 * linkend="gtk-X11-arch">window managers</link> to e.g. keep the
2273 * dialog on top of the main window, or center the dialog over the
2274 * main window. gtk_dialog_new_with_buttons() and other convenience
2275 * functions in GTK+ will sometimes call
2276 * gtk_window_set_transient_for() on your behalf.
2278 * On Windows, this function puts the child window on top of the parent,
2279 * much as the window manager would have done on X.
2283 gtk_window_set_transient_for (GtkWindow *window,
2286 GtkWindowPrivate *priv = GTK_WINDOW_GET_PRIVATE (window);
2288 g_return_if_fail (GTK_IS_WINDOW (window));
2289 g_return_if_fail (parent == NULL || GTK_IS_WINDOW (parent));
2290 g_return_if_fail (window != parent);
2292 if (window->transient_parent)
2294 if (GTK_WIDGET_REALIZED (window) &&
2295 GTK_WIDGET_REALIZED (window->transient_parent) &&
2296 (!parent || !GTK_WIDGET_REALIZED (parent)))
2297 gtk_window_transient_parent_unrealized (GTK_WIDGET (window->transient_parent),
2298 GTK_WIDGET (window));
2300 gtk_window_unset_transient_for (window);
2303 window->transient_parent = parent;
2307 g_signal_connect (parent, "destroy",
2308 G_CALLBACK (gtk_widget_destroyed),
2309 &window->transient_parent);
2310 g_signal_connect (parent, "realize",
2311 G_CALLBACK (gtk_window_transient_parent_realized),
2313 g_signal_connect (parent, "unrealize",
2314 G_CALLBACK (gtk_window_transient_parent_unrealized),
2316 g_signal_connect (parent, "notify::screen",
2317 G_CALLBACK (gtk_window_transient_parent_screen_changed),
2320 gtk_window_set_screen (window, parent->screen);
2322 if (window->destroy_with_parent)
2323 connect_parent_destroyed (window);
2325 if (GTK_WIDGET_REALIZED (window) &&
2326 GTK_WIDGET_REALIZED (parent))
2327 gtk_window_transient_parent_realized (GTK_WIDGET (parent),
2328 GTK_WIDGET (window));
2332 gtk_window_group_add_window (parent->group, window);
2333 priv->transient_parent_group = TRUE;
2339 * gtk_window_get_transient_for:
2340 * @window: a #GtkWindow
2342 * Fetches the transient parent for this window. See
2343 * gtk_window_set_transient_for().
2345 * Return value: (transfer none): the transient parent for this window, or %NULL
2346 * if no transient parent has been set.
2349 gtk_window_get_transient_for (GtkWindow *window)
2351 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
2353 return window->transient_parent;
2357 * gtk_window_set_opacity:
2358 * @window: a #GtkWindow
2359 * @opacity: desired opacity, between 0 and 1
2361 * Request the windowing system to make @window partially transparent,
2362 * with opacity 0 being fully transparent and 1 fully opaque. (Values
2363 * of the opacity parameter are clamped to the [0,1] range.) On X11
2364 * this has any effect only on X screens with a compositing manager
2365 * running. See gtk_widget_is_composited(). On Windows it should work
2368 * Note that setting a window's opacity after the window has been
2369 * shown causes it to flicker once on Windows.
2374 gtk_window_set_opacity (GtkWindow *window,
2377 GtkWindowPrivate *priv;
2379 g_return_if_fail (GTK_IS_WINDOW (window));
2381 priv = GTK_WINDOW_GET_PRIVATE (window);
2385 else if (opacity > 1.0)
2388 priv->opacity_set = TRUE;
2389 priv->opacity = opacity;
2391 if (GTK_WIDGET_REALIZED (window))
2392 gdk_window_set_opacity (GTK_WIDGET (window)->window, priv->opacity);
2396 * gtk_window_get_opacity:
2397 * @window: a #GtkWindow
2399 * Fetches the requested opacity for this window. See
2400 * gtk_window_set_opacity().
2402 * Return value: the requested opacity for this window.
2407 gtk_window_get_opacity (GtkWindow *window)
2409 GtkWindowPrivate *priv;
2411 g_return_val_if_fail (GTK_IS_WINDOW (window), 0.0);
2413 priv = GTK_WINDOW_GET_PRIVATE (window);
2415 return priv->opacity;
2419 * gtk_window_set_type_hint:
2420 * @window: a #GtkWindow
2421 * @hint: the window type
2423 * By setting the type hint for the window, you allow the window
2424 * manager to decorate and handle the window in a way which is
2425 * suitable to the function of the window in your application.
2427 * This function should be called before the window becomes visible.
2429 * gtk_dialog_new_with_buttons() and other convenience functions in GTK+
2430 * will sometimes call gtk_window_set_type_hint() on your behalf.
2434 gtk_window_set_type_hint (GtkWindow *window,
2435 GdkWindowTypeHint hint)
2437 GtkWindowPrivate *priv;
2439 g_return_if_fail (GTK_IS_WINDOW (window));
2440 g_return_if_fail (!GTK_WIDGET_MAPPED (window));
2442 priv = GTK_WINDOW_GET_PRIVATE (window);
2444 if (hint < GDK_WINDOW_TYPE_HINT_DROPDOWN_MENU)
2445 window->type_hint = hint;
2447 window->type_hint = GDK_WINDOW_TYPE_HINT_NORMAL;
2449 priv->reset_type_hint = TRUE;
2450 priv->type_hint = hint;
2454 * gtk_window_get_type_hint:
2455 * @window: a #GtkWindow
2457 * Gets the type hint for this window. See gtk_window_set_type_hint().
2459 * Return value: the type hint for @window.
2462 gtk_window_get_type_hint (GtkWindow *window)
2464 GtkWindowPrivate *priv;
2466 g_return_val_if_fail (GTK_IS_WINDOW (window), GDK_WINDOW_TYPE_HINT_NORMAL);
2468 priv = GTK_WINDOW_GET_PRIVATE (window);
2470 return priv->type_hint;
2474 * gtk_window_set_skip_taskbar_hint:
2475 * @window: a #GtkWindow
2476 * @setting: %TRUE to keep this window from appearing in the task bar
2478 * Windows may set a hint asking the desktop environment not to display
2479 * the window in the task bar. This function sets this hint.
2484 gtk_window_set_skip_taskbar_hint (GtkWindow *window,
2487 GtkWindowPrivate *priv;
2489 g_return_if_fail (GTK_IS_WINDOW (window));
2491 priv = GTK_WINDOW_GET_PRIVATE (window);
2493 setting = setting != FALSE;
2495 if (priv->skips_taskbar != setting)
2497 priv->skips_taskbar = setting;
2498 if (GTK_WIDGET_REALIZED (window))
2499 gdk_window_set_skip_taskbar_hint (GTK_WIDGET (window)->window,
2500 priv->skips_taskbar);
2501 g_object_notify (G_OBJECT (window), "skip-taskbar-hint");
2506 * gtk_window_get_skip_taskbar_hint:
2507 * @window: a #GtkWindow
2509 * Gets the value set by gtk_window_set_skip_taskbar_hint()
2511 * Return value: %TRUE if window shouldn't be in taskbar
2516 gtk_window_get_skip_taskbar_hint (GtkWindow *window)
2518 GtkWindowPrivate *priv;
2520 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
2522 priv = GTK_WINDOW_GET_PRIVATE (window);
2524 return priv->skips_taskbar;
2528 * gtk_window_set_skip_pager_hint:
2529 * @window: a #GtkWindow
2530 * @setting: %TRUE to keep this window from appearing in the pager
2532 * Windows may set a hint asking the desktop environment not to display
2533 * the window in the pager. This function sets this hint.
2534 * (A "pager" is any desktop navigation tool such as a workspace
2535 * switcher that displays a thumbnail representation of the windows
2541 gtk_window_set_skip_pager_hint (GtkWindow *window,
2544 GtkWindowPrivate *priv;
2546 g_return_if_fail (GTK_IS_WINDOW (window));
2548 priv = GTK_WINDOW_GET_PRIVATE (window);
2550 setting = setting != FALSE;
2552 if (priv->skips_pager != setting)
2554 priv->skips_pager = setting;
2555 if (GTK_WIDGET_REALIZED (window))
2556 gdk_window_set_skip_pager_hint (GTK_WIDGET (window)->window,
2558 g_object_notify (G_OBJECT (window), "skip-pager-hint");
2563 * gtk_window_get_skip_pager_hint:
2564 * @window: a #GtkWindow
2566 * Gets the value set by gtk_window_set_skip_pager_hint().
2568 * Return value: %TRUE if window shouldn't be in pager
2573 gtk_window_get_skip_pager_hint (GtkWindow *window)
2575 GtkWindowPrivate *priv;
2577 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
2579 priv = GTK_WINDOW_GET_PRIVATE (window);
2581 return priv->skips_pager;
2585 * gtk_window_set_urgency_hint:
2586 * @window: a #GtkWindow
2587 * @setting: %TRUE to mark this window as urgent
2589 * Windows may set a hint asking the desktop environment to draw
2590 * the users attention to the window. This function sets this hint.
2595 gtk_window_set_urgency_hint (GtkWindow *window,
2598 GtkWindowPrivate *priv;
2600 g_return_if_fail (GTK_IS_WINDOW (window));
2602 priv = GTK_WINDOW_GET_PRIVATE (window);
2604 setting = setting != FALSE;
2606 if (priv->urgent != setting)
2608 priv->urgent = setting;
2609 if (GTK_WIDGET_REALIZED (window))
2610 gdk_window_set_urgency_hint (GTK_WIDGET (window)->window,
2612 g_object_notify (G_OBJECT (window), "urgency-hint");
2617 * gtk_window_get_urgency_hint:
2618 * @window: a #GtkWindow
2620 * Gets the value set by gtk_window_set_urgency_hint()
2622 * Return value: %TRUE if window is urgent
2627 gtk_window_get_urgency_hint (GtkWindow *window)
2629 GtkWindowPrivate *priv;
2631 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
2633 priv = GTK_WINDOW_GET_PRIVATE (window);
2635 return priv->urgent;
2639 * gtk_window_set_accept_focus:
2640 * @window: a #GtkWindow
2641 * @setting: %TRUE to let this window receive input focus
2643 * Windows may set a hint asking the desktop environment not to receive
2644 * the input focus. This function sets this hint.
2649 gtk_window_set_accept_focus (GtkWindow *window,
2652 GtkWindowPrivate *priv;
2654 g_return_if_fail (GTK_IS_WINDOW (window));
2656 priv = GTK_WINDOW_GET_PRIVATE (window);
2658 setting = setting != FALSE;
2660 if (priv->accept_focus != setting)
2662 priv->accept_focus = setting;
2663 if (GTK_WIDGET_REALIZED (window))
2664 gdk_window_set_accept_focus (GTK_WIDGET (window)->window,
2665 priv->accept_focus);
2666 g_object_notify (G_OBJECT (window), "accept-focus");
2671 * gtk_window_get_accept_focus:
2672 * @window: a #GtkWindow
2674 * Gets the value set by gtk_window_set_accept_focus().
2676 * Return value: %TRUE if window should receive the input focus
2681 gtk_window_get_accept_focus (GtkWindow *window)
2683 GtkWindowPrivate *priv;
2685 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
2687 priv = GTK_WINDOW_GET_PRIVATE (window);
2689 return priv->accept_focus;
2693 * gtk_window_set_focus_on_map:
2694 * @window: a #GtkWindow
2695 * @setting: %TRUE to let this window receive input focus on map
2697 * Windows may set a hint asking the desktop environment not to receive
2698 * the input focus when the window is mapped. This function sets this
2704 gtk_window_set_focus_on_map (GtkWindow *window,
2707 GtkWindowPrivate *priv;
2709 g_return_if_fail (GTK_IS_WINDOW (window));
2711 priv = GTK_WINDOW_GET_PRIVATE (window);
2713 setting = setting != FALSE;
2715 if (priv->focus_on_map != setting)
2717 priv->focus_on_map = setting;
2718 if (GTK_WIDGET_REALIZED (window))
2719 gdk_window_set_focus_on_map (GTK_WIDGET (window)->window,
2720 priv->focus_on_map);
2721 g_object_notify (G_OBJECT (window), "focus-on-map");
2726 * gtk_window_get_focus_on_map:
2727 * @window: a #GtkWindow
2729 * Gets the value set by gtk_window_set_focus_on_map().
2731 * Return value: %TRUE if window should receive the input focus when
2737 gtk_window_get_focus_on_map (GtkWindow *window)
2739 GtkWindowPrivate *priv;
2741 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
2743 priv = GTK_WINDOW_GET_PRIVATE (window);
2745 return priv->focus_on_map;
2749 * gtk_window_set_destroy_with_parent:
2750 * @window: a #GtkWindow
2751 * @setting: whether to destroy @window with its transient parent
2753 * If @setting is %TRUE, then destroying the transient parent of @window
2754 * will also destroy @window itself. This is useful for dialogs that
2755 * shouldn't persist beyond the lifetime of the main window they're
2756 * associated with, for example.
2759 gtk_window_set_destroy_with_parent (GtkWindow *window,
2762 g_return_if_fail (GTK_IS_WINDOW (window));
2764 if (window->destroy_with_parent == (setting != FALSE))
2767 if (window->destroy_with_parent)
2769 disconnect_parent_destroyed (window);
2773 connect_parent_destroyed (window);
2776 window->destroy_with_parent = setting;
2778 g_object_notify (G_OBJECT (window), "destroy-with-parent");
2782 * gtk_window_get_destroy_with_parent:
2783 * @window: a #GtkWindow
2785 * Returns whether the window will be destroyed with its transient parent. See
2786 * gtk_window_set_destroy_with_parent ().
2788 * Return value: %TRUE if the window will be destroyed with its transient parent.
2791 gtk_window_get_destroy_with_parent (GtkWindow *window)
2793 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
2795 return window->destroy_with_parent;
2798 static GtkWindowGeometryInfo*
2799 gtk_window_get_geometry_info (GtkWindow *window,
2802 GtkWindowGeometryInfo *info;
2804 info = window->geometry_info;
2805 if (!info && create)
2807 info = g_new0 (GtkWindowGeometryInfo, 1);
2809 info->default_width = -1;
2810 info->default_height = -1;
2811 info->resize_width = -1;
2812 info->resize_height = -1;
2813 info->initial_x = 0;
2814 info->initial_y = 0;
2815 info->initial_pos_set = FALSE;
2816 info->default_is_geometry = FALSE;
2817 info->position_constraints_changed = FALSE;
2818 info->last.configure_request.x = 0;
2819 info->last.configure_request.y = 0;
2820 info->last.configure_request.width = -1;
2821 info->last.configure_request.height = -1;
2822 info->widget = NULL;
2824 window->geometry_info = info;
2831 * gtk_window_set_geometry_hints:
2832 * @window: a #GtkWindow
2833 * @geometry_widget: widget the geometry hints will be applied to
2834 * @geometry: struct containing geometry information
2835 * @geom_mask: mask indicating which struct fields should be paid attention to
2837 * This function sets up hints about how a window can be resized by
2838 * the user. You can set a minimum and maximum size; allowed resize
2839 * increments (e.g. for xterm, you can only resize by the size of a
2840 * character); aspect ratios; and more. See the #GdkGeometry struct.
2844 gtk_window_set_geometry_hints (GtkWindow *window,
2845 GtkWidget *geometry_widget,
2846 GdkGeometry *geometry,
2847 GdkWindowHints geom_mask)
2849 GtkWindowGeometryInfo *info;
2851 g_return_if_fail (GTK_IS_WINDOW (window));
2852 g_return_if_fail (geometry_widget == NULL || GTK_IS_WIDGET (geometry_widget));
2854 info = gtk_window_get_geometry_info (window, TRUE);
2857 g_signal_handlers_disconnect_by_func (info->widget,
2858 gtk_widget_destroyed,
2861 info->widget = geometry_widget;
2863 g_signal_connect (geometry_widget, "destroy",
2864 G_CALLBACK (gtk_widget_destroyed),
2868 info->geometry = *geometry;
2870 /* We store gravity in window->gravity not in the hints. */
2871 info->mask = geom_mask & ~(GDK_HINT_WIN_GRAVITY);
2873 if (geom_mask & GDK_HINT_WIN_GRAVITY)
2875 gtk_window_set_gravity (window, geometry->win_gravity);
2878 gtk_widget_queue_resize_no_redraw (GTK_WIDGET (window));
2882 * gtk_window_set_decorated:
2883 * @window: a #GtkWindow
2884 * @setting: %TRUE to decorate the window
2886 * By default, windows are decorated with a title bar, resize
2887 * controls, etc. Some <link linkend="gtk-X11-arch">window
2888 * managers</link> allow GTK+ to disable these decorations, creating a
2889 * borderless window. If you set the decorated property to %FALSE
2890 * using this function, GTK+ will do its best to convince the window
2891 * manager not to decorate the window. Depending on the system, this
2892 * function may not have any effect when called on a window that is
2893 * already visible, so you should call it before calling gtk_window_show().
2895 * On Windows, this function always works, since there's no window manager
2900 gtk_window_set_decorated (GtkWindow *window,
2903 g_return_if_fail (GTK_IS_WINDOW (window));
2905 setting = setting != FALSE;
2907 if (setting == window->decorated)
2910 window->decorated = setting;
2912 if (GTK_WIDGET (window)->window)
2914 if (window->decorated)
2915 gdk_window_set_decorations (GTK_WIDGET (window)->window,
2918 gdk_window_set_decorations (GTK_WIDGET (window)->window,
2922 g_object_notify (G_OBJECT (window), "decorated");
2926 * gtk_window_get_decorated:
2927 * @window: a #GtkWindow
2929 * Returns whether the window has been set to have decorations
2930 * such as a title bar via gtk_window_set_decorated().
2932 * Return value: %TRUE if the window has been set to have decorations
2935 gtk_window_get_decorated (GtkWindow *window)
2937 g_return_val_if_fail (GTK_IS_WINDOW (window), TRUE);
2939 return window->decorated;
2943 * gtk_window_set_deletable:
2944 * @window: a #GtkWindow
2945 * @setting: %TRUE to decorate the window as deletable
2947 * By default, windows have a close button in the window frame. Some
2948 * <link linkend="gtk-X11-arch">window managers</link> allow GTK+ to
2949 * disable this button. If you set the deletable property to %FALSE
2950 * using this function, GTK+ will do its best to convince the window
2951 * manager not to show a close button. Depending on the system, this
2952 * function may not have any effect when called on a window that is
2953 * already visible, so you should call it before calling gtk_window_show().
2955 * On Windows, this function always works, since there's no window manager
2961 gtk_window_set_deletable (GtkWindow *window,
2964 GtkWindowPrivate *priv;
2966 g_return_if_fail (GTK_IS_WINDOW (window));
2968 priv = GTK_WINDOW_GET_PRIVATE (window);
2970 setting = setting != FALSE;
2972 if (setting == priv->deletable)
2975 priv->deletable = setting;
2977 if (GTK_WIDGET (window)->window)
2979 if (priv->deletable)
2980 gdk_window_set_functions (GTK_WIDGET (window)->window,
2983 gdk_window_set_functions (GTK_WIDGET (window)->window,
2984 GDK_FUNC_ALL | GDK_FUNC_CLOSE);
2987 g_object_notify (G_OBJECT (window), "deletable");
2991 * gtk_window_get_deletable:
2992 * @window: a #GtkWindow
2994 * Returns whether the window has been set to have a close button
2995 * via gtk_window_set_deletable().
2997 * Return value: %TRUE if the window has been set to have a close button
3002 gtk_window_get_deletable (GtkWindow *window)
3004 GtkWindowPrivate *priv;
3006 g_return_val_if_fail (GTK_IS_WINDOW (window), TRUE);
3008 priv = GTK_WINDOW_GET_PRIVATE (window);
3010 return priv->deletable;
3013 static GtkWindowIconInfo*
3014 get_icon_info (GtkWindow *window)
3016 return g_object_get_qdata (G_OBJECT (window), quark_gtk_window_icon_info);
3020 free_icon_info (GtkWindowIconInfo *info)
3022 g_free (info->icon_name);
3023 g_slice_free (GtkWindowIconInfo, info);
3027 static GtkWindowIconInfo*
3028 ensure_icon_info (GtkWindow *window)
3030 GtkWindowIconInfo *info;
3032 info = get_icon_info (window);
3036 info = g_slice_new0 (GtkWindowIconInfo);
3037 g_object_set_qdata_full (G_OBJECT (window),
3038 quark_gtk_window_icon_info,
3040 (GDestroyNotify)free_icon_info);
3052 static ScreenIconInfo *
3053 get_screen_icon_info (GdkScreen *screen)
3055 ScreenIconInfo *info = g_object_get_qdata (G_OBJECT (screen),
3056 quark_gtk_window_default_icon_pixmap);
3059 info = g_slice_new0 (ScreenIconInfo);
3060 g_object_set_qdata (G_OBJECT (screen),
3061 quark_gtk_window_default_icon_pixmap, info);
3064 if (info->serial != default_icon_serial)
3068 g_object_remove_weak_pointer (G_OBJECT (info->pixmap), (gpointer*)&info->pixmap);
3069 info->pixmap = NULL;
3074 g_object_remove_weak_pointer (G_OBJECT (info->mask), (gpointer*)&info->mask);
3078 info->serial = default_icon_serial;
3085 get_pixmap_and_mask (GdkWindow *window,
3086 GtkWindowIconInfo *parent_info,
3087 gboolean is_default_list,
3089 GdkPixmap **pmap_return,
3090 GdkBitmap **mask_return)
3092 GdkScreen *screen = gdk_drawable_get_screen (window);
3093 ScreenIconInfo *default_icon_info = get_screen_icon_info (screen);
3094 GdkPixbuf *best_icon;
3098 *pmap_return = NULL;
3099 *mask_return = NULL;
3101 if (is_default_list &&
3102 default_icon_info->pixmap != NULL)
3104 /* Use shared icon pixmap for all windows on this screen.
3106 if (default_icon_info->pixmap)
3107 g_object_ref (default_icon_info->pixmap);
3108 if (default_icon_info->mask)
3109 g_object_ref (default_icon_info->mask);
3111 *pmap_return = default_icon_info->pixmap;
3112 *mask_return = default_icon_info->mask;
3114 else if (parent_info && parent_info->icon_pixmap)
3116 if (parent_info->icon_pixmap)
3117 g_object_ref (parent_info->icon_pixmap);
3118 if (parent_info->icon_mask)
3119 g_object_ref (parent_info->icon_mask);
3121 *pmap_return = parent_info->icon_pixmap;
3122 *mask_return = parent_info->icon_mask;
3126 #define IDEAL_SIZE 48
3128 best_size = G_MAXINT;
3130 tmp_list = icon_list;
3131 while (tmp_list != NULL)
3133 GdkPixbuf *pixbuf = tmp_list->data;
3136 /* average width and height - if someone passes in a rectangular
3137 * icon they deserve what they get.
3139 this = gdk_pixbuf_get_width (pixbuf) + gdk_pixbuf_get_height (pixbuf);
3142 if (best_icon == NULL)
3149 /* icon is better if it's 32 pixels or larger, and closer to
3150 * the ideal size than the current best.
3153 (ABS (best_size - IDEAL_SIZE) <
3154 ABS (this - IDEAL_SIZE)))
3161 tmp_list = tmp_list->next;
3165 gdk_pixbuf_render_pixmap_and_mask_for_colormap (best_icon,
3166 gdk_screen_get_system_colormap (screen),
3171 /* Save pmap/mask for others to use if appropriate */
3174 parent_info->icon_pixmap = *pmap_return;
3175 parent_info->icon_mask = *mask_return;
3177 if (parent_info->icon_pixmap)
3178 g_object_ref (parent_info->icon_pixmap);
3179 if (parent_info->icon_mask)
3180 g_object_ref (parent_info->icon_mask);
3182 else if (is_default_list)
3184 default_icon_info->pixmap = *pmap_return;
3185 default_icon_info->mask = *mask_return;
3187 if (default_icon_info->pixmap)
3188 g_object_add_weak_pointer (G_OBJECT (default_icon_info->pixmap),
3189 (gpointer*)&default_icon_info->pixmap);
3190 if (default_icon_info->mask)
3191 g_object_add_weak_pointer (G_OBJECT (default_icon_info->mask),
3192 (gpointer*)&default_icon_info->mask);
3198 icon_list_from_theme (GtkWidget *widget,
3203 GtkIconTheme *icon_theme;
3208 icon_theme = gtk_icon_theme_get_for_screen (gtk_widget_get_screen (widget));
3210 sizes = gtk_icon_theme_get_icon_sizes (icon_theme, name);
3213 for (i = 0; sizes[i]; i++)
3216 * We need an EWMH extension to handle scalable icons
3217 * by passing their name to the WM. For now just use a
3221 icon = gtk_icon_theme_load_icon (icon_theme, name,
3224 icon = gtk_icon_theme_load_icon (icon_theme, name,
3227 list = g_list_append (list, icon);
3237 gtk_window_realize_icon (GtkWindow *window)
3240 GtkWindowIconInfo *info;
3243 widget = GTK_WIDGET (window);
3245 g_return_if_fail (widget->window != NULL);
3247 /* no point setting an icon on override-redirect */
3248 if (window->type == GTK_WINDOW_POPUP)
3253 info = ensure_icon_info (window);
3258 g_return_if_fail (info->icon_pixmap == NULL);
3259 g_return_if_fail (info->icon_mask == NULL);
3261 info->using_default_icon = FALSE;
3262 info->using_parent_icon = FALSE;
3263 info->using_themed_icon = FALSE;
3265 icon_list = info->icon_list;
3267 /* Look up themed icon */
3268 if (icon_list == NULL && info->icon_name)
3270 icon_list = icon_list_from_theme (widget, info->icon_name);
3272 info->using_themed_icon = TRUE;
3275 /* Inherit from transient parent */
3276 if (icon_list == NULL && window->transient_parent)
3278 icon_list = ensure_icon_info (window->transient_parent)->icon_list;
3280 info->using_parent_icon = TRUE;
3283 /* Inherit from default */
3284 if (icon_list == NULL)
3286 icon_list = default_icon_list;
3288 info->using_default_icon = TRUE;
3291 /* Look up themed icon */
3292 if (icon_list == NULL && default_icon_name)
3294 icon_list = icon_list_from_theme (widget, default_icon_name);
3295 info->using_default_icon = TRUE;
3296 info->using_themed_icon = TRUE;
3299 gdk_window_set_icon_list (widget->window, icon_list);
3301 get_pixmap_and_mask (widget->window,
3302 info->using_parent_icon ? ensure_icon_info (window->transient_parent) : NULL,
3303 info->using_default_icon,
3308 /* This is a slight ICCCM violation since it's a color pixmap not
3309 * a bitmap, but everyone does it.
3311 gdk_window_set_icon (widget->window,
3316 info->realized = TRUE;
3318 if (info->using_themed_icon)
3320 GtkIconTheme *icon_theme;
3322 g_list_foreach (icon_list, (GFunc) g_object_unref, NULL);
3323 g_list_free (icon_list);
3325 icon_theme = gtk_icon_theme_get_for_screen (gtk_widget_get_screen (GTK_WIDGET (window)));
3326 g_signal_connect (icon_theme, "changed",
3327 G_CALLBACK (update_themed_icon), window);
3332 gtk_window_unrealize_icon (GtkWindow *window)
3334 GtkWindowIconInfo *info;
3336 info = get_icon_info (window);
3341 if (info->icon_pixmap)
3342 g_object_unref (info->icon_pixmap);
3344 if (info->icon_mask)
3345 g_object_unref (info->icon_mask);
3347 info->icon_pixmap = NULL;
3348 info->icon_mask = NULL;
3350 if (info->using_themed_icon)
3352 GtkIconTheme *icon_theme;
3354 icon_theme = gtk_icon_theme_get_for_screen (gtk_widget_get_screen (GTK_WIDGET (window)));
3356 g_signal_handlers_disconnect_by_func (icon_theme, update_themed_icon, window);
3359 /* We don't clear the properties on the window, just figure the
3360 * window is going away.
3363 info->realized = FALSE;
3368 * gtk_window_set_icon_list:
3369 * @window: a #GtkWindow
3370 * @list: list of #GdkPixbuf
3372 * Sets up the icon representing a #GtkWindow. The icon is used when
3373 * the window is minimized (also known as iconified). Some window
3374 * managers or desktop environments may also place it in the window
3375 * frame, or display it in other contexts.
3377 * gtk_window_set_icon_list() allows you to pass in the same icon in
3378 * several hand-drawn sizes. The list should contain the natural sizes
3379 * your icon is available in; that is, don't scale the image before
3380 * passing it to GTK+. Scaling is postponed until the last minute,
3381 * when the desired final size is known, to allow best quality.
3383 * By passing several sizes, you may improve the final image quality
3384 * of the icon, by reducing or eliminating automatic image scaling.
3386 * Recommended sizes to provide: 16x16, 32x32, 48x48 at minimum, and
3387 * larger images (64x64, 128x128) if you have them.
3389 * See also gtk_window_set_default_icon_list() to set the icon
3390 * for all windows in your application in one go.
3392 * Note that transient windows (those who have been set transient for another
3393 * window using gtk_window_set_transient_for()) will inherit their
3394 * icon from their transient parent. So there's no need to explicitly
3395 * set the icon on transient windows.
3398 gtk_window_set_icon_list (GtkWindow *window,
3401 GtkWindowIconInfo *info;
3403 g_return_if_fail (GTK_IS_WINDOW (window));
3405 info = ensure_icon_info (window);
3407 if (info->icon_list == list) /* check for NULL mostly */
3410 g_list_foreach (list,
3411 (GFunc) g_object_ref, NULL);
3413 g_list_foreach (info->icon_list,
3414 (GFunc) g_object_unref, NULL);
3416 g_list_free (info->icon_list);
3418 info->icon_list = g_list_copy (list);
3420 g_object_notify (G_OBJECT (window), "icon");
3422 gtk_window_unrealize_icon (window);
3424 if (GTK_WIDGET_REALIZED (window))
3425 gtk_window_realize_icon (window);
3427 /* We could try to update our transient children, but I don't think
3428 * it's really worth it. If we did it, the best way would probably
3429 * be to have children connect to notify::icon-list
3434 * gtk_window_get_icon_list:
3435 * @window: a #GtkWindow
3437 * Retrieves the list of icons set by gtk_window_set_icon_list().
3438 * The list is copied, but the reference count on each
3439 * member won't be incremented.
3441 * Return value: (element-type GdkPixbuf) (transfer container): copy of window's icon list
3444 gtk_window_get_icon_list (GtkWindow *window)
3446 GtkWindowIconInfo *info;
3448 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
3450 info = get_icon_info (window);
3453 return g_list_copy (info->icon_list);
3459 * gtk_window_set_icon:
3460 * @window: a #GtkWindow
3461 * @icon: (allow-none): icon image, or %NULL
3463 * Sets up the icon representing a #GtkWindow. This icon is used when
3464 * the window is minimized (also known as iconified). Some window
3465 * managers or desktop environments may also place it in the window
3466 * frame, or display it in other contexts.
3468 * The icon should be provided in whatever size it was naturally
3469 * drawn; that is, don't scale the image before passing it to
3470 * GTK+. Scaling is postponed until the last minute, when the desired
3471 * final size is known, to allow best quality.
3473 * If you have your icon hand-drawn in multiple sizes, use
3474 * gtk_window_set_icon_list(). Then the best size will be used.
3476 * This function is equivalent to calling gtk_window_set_icon_list()
3477 * with a 1-element list.
3479 * See also gtk_window_set_default_icon_list() to set the icon
3480 * for all windows in your application in one go.
3483 gtk_window_set_icon (GtkWindow *window,
3488 g_return_if_fail (GTK_IS_WINDOW (window));
3489 g_return_if_fail (icon == NULL || GDK_IS_PIXBUF (icon));
3494 list = g_list_append (list, icon);
3496 gtk_window_set_icon_list (window, list);
3502 update_themed_icon (GtkIconTheme *icon_theme,
3505 g_object_notify (G_OBJECT (window), "icon");
3507 gtk_window_unrealize_icon (window);
3509 if (GTK_WIDGET_REALIZED (window))
3510 gtk_window_realize_icon (window);
3514 * gtk_window_set_icon_name:
3515 * @window: a #GtkWindow
3516 * @name: (allow-none): the name of the themed icon
3518 * Sets the icon for the window from a named themed icon. See
3519 * the docs for #GtkIconTheme for more details.
3521 * Note that this has nothing to do with the WM_ICON_NAME
3522 * property which is mentioned in the ICCCM.
3527 gtk_window_set_icon_name (GtkWindow *window,
3530 GtkWindowIconInfo *info;
3533 g_return_if_fail (GTK_IS_WINDOW (window));
3535 info = ensure_icon_info (window);
3537 if (g_strcmp0 (info->icon_name, name) == 0)
3540 tmp = info->icon_name;
3541 info->icon_name = g_strdup (name);
3544 g_list_foreach (info->icon_list, (GFunc) g_object_unref, NULL);
3545 g_list_free (info->icon_list);
3546 info->icon_list = NULL;
3548 update_themed_icon (NULL, window);
3550 g_object_notify (G_OBJECT (window), "icon-name");
3554 * gtk_window_get_icon_name:
3555 * @window: a #GtkWindow
3557 * Returns the name of the themed icon for the window,
3558 * see gtk_window_set_icon_name().
3560 * Returns: the icon name or %NULL if the window has
3566 gtk_window_get_icon_name (GtkWindow *window)
3568 GtkWindowIconInfo *info;
3570 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
3572 info = ensure_icon_info (window);
3574 return info->icon_name;
3578 * gtk_window_get_icon:
3579 * @window: a #GtkWindow
3581 * Gets the value set by gtk_window_set_icon() (or if you've
3582 * called gtk_window_set_icon_list(), gets the first icon in
3585 * Return value: (transfer none): icon for window
3588 gtk_window_get_icon (GtkWindow *window)
3590 GtkWindowIconInfo *info;
3592 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
3594 info = get_icon_info (window);
3595 if (info && info->icon_list)
3596 return GDK_PIXBUF (info->icon_list->data);
3601 /* Load pixbuf, printing warning on failure if error == NULL
3604 load_pixbuf_verbosely (const char *filename,
3607 GError *local_err = NULL;
3610 pixbuf = gdk_pixbuf_new_from_file (filename, &local_err);
3618 g_warning ("Error loading icon from file '%s':\n\t%s",
3619 filename, local_err->message);
3620 g_error_free (local_err);
3628 * gtk_window_set_icon_from_file:
3629 * @window: a #GtkWindow
3630 * @filename: location of icon file
3631 * @err: (allow-none): location to store error, or %NULL.
3633 * Sets the icon for @window.
3634 * Warns on failure if @err is %NULL.
3636 * This function is equivalent to calling gtk_window_set_icon()
3637 * with a pixbuf created by loading the image from @filename.
3639 * Returns: %TRUE if setting the icon succeeded.
3644 gtk_window_set_icon_from_file (GtkWindow *window,
3645 const gchar *filename,
3648 GdkPixbuf *pixbuf = load_pixbuf_verbosely (filename, err);
3652 gtk_window_set_icon (window, pixbuf);
3653 g_object_unref (pixbuf);
3662 * gtk_window_set_default_icon_list:
3663 * @list: a list of #GdkPixbuf
3665 * Sets an icon list to be used as fallback for windows that haven't
3666 * had gtk_window_set_icon_list() called on them to set up a
3667 * window-specific icon list. This function allows you to set up the
3668 * icon for all windows in your app at once.
3670 * See gtk_window_set_icon_list() for more details.
3674 gtk_window_set_default_icon_list (GList *list)
3678 if (list == default_icon_list)
3681 /* Update serial so we don't used cached pixmaps/masks
3683 default_icon_serial++;
3685 g_list_foreach (list,
3686 (GFunc) g_object_ref, NULL);
3688 g_list_foreach (default_icon_list,
3689 (GFunc) g_object_unref, NULL);
3691 g_list_free (default_icon_list);
3693 default_icon_list = g_list_copy (list);
3695 /* Update all toplevels */
3696 toplevels = gtk_window_list_toplevels ();
3697 tmp_list = toplevels;
3698 while (tmp_list != NULL)
3700 GtkWindowIconInfo *info;
3701 GtkWindow *w = tmp_list->data;
3703 info = get_icon_info (w);
3704 if (info && info->using_default_icon)
3706 gtk_window_unrealize_icon (w);
3707 if (GTK_WIDGET_REALIZED (w))
3708 gtk_window_realize_icon (w);
3711 tmp_list = tmp_list->next;
3713 g_list_free (toplevels);
3717 * gtk_window_set_default_icon:
3720 * Sets an icon to be used as fallback for windows that haven't
3721 * had gtk_window_set_icon() called on them from a pixbuf.
3726 gtk_window_set_default_icon (GdkPixbuf *icon)
3730 g_return_if_fail (GDK_IS_PIXBUF (icon));
3732 list = g_list_prepend (NULL, icon);
3733 gtk_window_set_default_icon_list (list);
3738 * gtk_window_set_default_icon_name:
3739 * @name: the name of the themed icon
3741 * Sets an icon to be used as fallback for windows that haven't
3742 * had gtk_window_set_icon_list() called on them from a named
3743 * themed icon, see gtk_window_set_icon_name().
3748 gtk_window_set_default_icon_name (const gchar *name)
3753 /* Update serial so we don't used cached pixmaps/masks
3755 default_icon_serial++;
3757 g_free (default_icon_name);
3758 default_icon_name = g_strdup (name);
3760 g_list_foreach (default_icon_list,
3761 (GFunc) g_object_unref, NULL);
3763 g_list_free (default_icon_list);
3764 default_icon_list = NULL;
3766 /* Update all toplevels */
3767 toplevels = gtk_window_list_toplevels ();
3768 tmp_list = toplevels;
3769 while (tmp_list != NULL)
3771 GtkWindowIconInfo *info;
3772 GtkWindow *w = tmp_list->data;
3774 info = get_icon_info (w);
3775 if (info && info->using_default_icon && info->using_themed_icon)
3777 gtk_window_unrealize_icon (w);
3778 if (GTK_WIDGET_REALIZED (w))
3779 gtk_window_realize_icon (w);
3782 tmp_list = tmp_list->next;
3784 g_list_free (toplevels);
3788 * gtk_window_get_default_icon_name:
3790 * Returns the fallback icon name for windows that has been set
3791 * with gtk_window_set_default_icon_name(). The returned
3792 * string is owned by GTK+ and should not be modified. It
3793 * is only valid until the next call to
3794 * gtk_window_set_default_icon_name().
3796 * Returns: the fallback icon name for windows
3801 gtk_window_get_default_icon_name (void)
3803 return default_icon_name;
3807 * gtk_window_set_default_icon_from_file:
3808 * @filename: location of icon file
3809 * @err: (allow-none): location to store error, or %NULL.
3811 * Sets an icon to be used as fallback for windows that haven't
3812 * had gtk_window_set_icon_list() called on them from a file
3813 * on disk. Warns on failure if @err is %NULL.
3815 * Returns: %TRUE if setting the icon succeeded.
3820 gtk_window_set_default_icon_from_file (const gchar *filename,
3823 GdkPixbuf *pixbuf = load_pixbuf_verbosely (filename, err);
3827 gtk_window_set_default_icon (pixbuf);
3828 g_object_unref (pixbuf);
3837 * gtk_window_get_default_icon_list:
3839 * Gets the value set by gtk_window_set_default_icon_list().
3840 * The list is a copy and should be freed with g_list_free(),
3841 * but the pixbufs in the list have not had their reference count
3844 * Return value: copy of default icon list
3847 gtk_window_get_default_icon_list (void)
3849 return g_list_copy (default_icon_list);
3853 gtk_window_set_default_size_internal (GtkWindow *window,
3854 gboolean change_width,
3856 gboolean change_height,
3858 gboolean is_geometry)
3860 GtkWindowGeometryInfo *info;
3862 g_return_if_fail (change_width == FALSE || width >= -1);
3863 g_return_if_fail (change_height == FALSE || height >= -1);
3865 info = gtk_window_get_geometry_info (window, TRUE);
3867 g_object_freeze_notify (G_OBJECT (window));
3869 info->default_is_geometry = is_geometry != FALSE;
3879 info->default_width = width;
3881 g_object_notify (G_OBJECT (window), "default-width");
3892 info->default_height = height;
3894 g_object_notify (G_OBJECT (window), "default-height");
3897 g_object_thaw_notify (G_OBJECT (window));
3899 gtk_widget_queue_resize_no_redraw (GTK_WIDGET (window));
3903 * gtk_window_set_default_size:
3904 * @window: a #GtkWindow
3905 * @width: width in pixels, or -1 to unset the default width
3906 * @height: height in pixels, or -1 to unset the default height
3908 * Sets the default size of a window. If the window's "natural" size
3909 * (its size request) is larger than the default, the default will be
3910 * ignored. More generally, if the default size does not obey the
3911 * geometry hints for the window (gtk_window_set_geometry_hints() can
3912 * be used to set these explicitly), the default size will be clamped
3913 * to the nearest permitted size.
3915 * Unlike gtk_widget_set_size_request(), which sets a size request for
3916 * a widget and thus would keep users from shrinking the window, this
3917 * function only sets the initial size, just as if the user had
3918 * resized the window themselves. Users can still shrink the window
3919 * again as they normally would. Setting a default size of -1 means to
3920 * use the "natural" default size (the size request of the window).
3922 * For more control over a window's initial size and how resizing works,
3923 * investigate gtk_window_set_geometry_hints().
3925 * For some uses, gtk_window_resize() is a more appropriate function.
3926 * gtk_window_resize() changes the current size of the window, rather
3927 * than the size to be used on initial display. gtk_window_resize() always
3928 * affects the window itself, not the geometry widget.
3930 * The default size of a window only affects the first time a window is
3931 * shown; if a window is hidden and re-shown, it will remember the size
3932 * it had prior to hiding, rather than using the default size.
3934 * Windows can't actually be 0x0 in size, they must be at least 1x1, but
3935 * passing 0 for @width and @height is OK, resulting in a 1x1 default size.
3938 gtk_window_set_default_size (GtkWindow *window,
3942 g_return_if_fail (GTK_IS_WINDOW (window));
3943 g_return_if_fail (width >= -1);
3944 g_return_if_fail (height >= -1);
3946 gtk_window_set_default_size_internal (window, TRUE, width, TRUE, height, FALSE);
3950 * gtk_window_get_default_size:
3951 * @window: a #GtkWindow
3952 * @width: (allow-none): location to store the default width, or %NULL
3953 * @height: (allow-none): location to store the default height, or %NULL
3955 * Gets the default size of the window. A value of -1 for the width or
3956 * height indicates that a default size has not been explicitly set
3957 * for that dimension, so the "natural" size of the window will be
3962 gtk_window_get_default_size (GtkWindow *window,
3966 GtkWindowGeometryInfo *info;
3968 g_return_if_fail (GTK_IS_WINDOW (window));
3970 info = gtk_window_get_geometry_info (window, FALSE);
3973 *width = info ? info->default_width : -1;
3976 *height = info ? info->default_height : -1;
3980 * gtk_window_resize:
3981 * @window: a #GtkWindow
3982 * @width: width in pixels to resize the window to
3983 * @height: height in pixels to resize the window to
3985 * Resizes the window as if the user had done so, obeying geometry
3986 * constraints. The default geometry constraint is that windows may
3987 * not be smaller than their size request; to override this
3988 * constraint, call gtk_widget_set_size_request() to set the window's
3989 * request to a smaller value.
3991 * If gtk_window_resize() is called before showing a window for the
3992 * first time, it overrides any default size set with
3993 * gtk_window_set_default_size().
3995 * Windows may not be resized smaller than 1 by 1 pixels.
3999 gtk_window_resize (GtkWindow *window,
4003 GtkWindowGeometryInfo *info;
4005 g_return_if_fail (GTK_IS_WINDOW (window));
4006 g_return_if_fail (width > 0);
4007 g_return_if_fail (height > 0);
4009 info = gtk_window_get_geometry_info (window, TRUE);
4011 info->resize_width = width;
4012 info->resize_height = height;
4014 gtk_widget_queue_resize_no_redraw (GTK_WIDGET (window));
4018 * gtk_window_get_size:
4019 * @window: a #GtkWindow
4020 * @width: (allow-none): (out): return location for width, or %NULL
4021 * @height: (allow-none): (out): return location for height, or %NULL
4023 * Obtains the current size of @window. If @window is not onscreen,
4024 * it returns the size GTK+ will suggest to the <link
4025 * linkend="gtk-X11-arch">window manager</link> for the initial window
4026 * size (but this is not reliably the same as the size the window
4027 * manager will actually select). The size obtained by
4028 * gtk_window_get_size() is the last size received in a
4029 * #GdkEventConfigure, that is, GTK+ uses its locally-stored size,
4030 * rather than querying the X server for the size. As a result, if you
4031 * call gtk_window_resize() then immediately call
4032 * gtk_window_get_size(), the size won't have taken effect yet. After
4033 * the window manager processes the resize request, GTK+ receives
4034 * notification that the size has changed via a configure event, and
4035 * the size of the window gets updated.
4037 * Note 1: Nearly any use of this function creates a race condition,
4038 * because the size of the window may change between the time that you
4039 * get the size and the time that you perform some action assuming
4040 * that size is the current size. To avoid race conditions, connect to
4041 * "configure-event" on the window and adjust your size-dependent
4042 * state to match the size delivered in the #GdkEventConfigure.
4044 * Note 2: The returned size does <emphasis>not</emphasis> include the
4045 * size of the window manager decorations (aka the window frame or
4046 * border). Those are not drawn by GTK+ and GTK+ has no reliable
4047 * method of determining their size.
4049 * Note 3: If you are getting a window size in order to position
4050 * the window onscreen, there may be a better way. The preferred
4051 * way is to simply set the window's semantic type with
4052 * gtk_window_set_type_hint(), which allows the window manager to
4053 * e.g. center dialogs. Also, if you set the transient parent of
4054 * dialogs with gtk_window_set_transient_for() window managers
4055 * will often center the dialog over its parent window. It's
4056 * much preferred to let the window manager handle these
4057 * things rather than doing it yourself, because all apps will
4058 * behave consistently and according to user prefs if the window
4059 * manager handles it. Also, the window manager can take the size
4060 * of the window decorations/border into account, while your
4061 * application cannot.
4063 * In any case, if you insist on application-specified window
4064 * positioning, there's <emphasis>still</emphasis> a better way than
4065 * doing it yourself - gtk_window_set_position() will frequently
4066 * handle the details for you.
4070 gtk_window_get_size (GtkWindow *window,
4076 g_return_if_fail (GTK_IS_WINDOW (window));
4078 if (width == NULL && height == NULL)
4081 if (GTK_WIDGET_MAPPED (window))
4083 gdk_drawable_get_size (GTK_WIDGET (window)->window,
4088 GdkRectangle configure_request;
4090 gtk_window_compute_configure_request (window,
4094 w = configure_request.width;
4095 h = configure_request.height;
4106 * @window: a #GtkWindow
4107 * @x: X coordinate to move window to
4108 * @y: Y coordinate to move window to
4110 * Asks the <link linkend="gtk-X11-arch">window manager</link> to move
4111 * @window to the given position. Window managers are free to ignore
4112 * this; most window managers ignore requests for initial window
4113 * positions (instead using a user-defined placement algorithm) and
4114 * honor requests after the window has already been shown.
4116 * Note: the position is the position of the gravity-determined
4117 * reference point for the window. The gravity determines two things:
4118 * first, the location of the reference point in root window
4119 * coordinates; and second, which point on the window is positioned at
4120 * the reference point.
4122 * By default the gravity is #GDK_GRAVITY_NORTH_WEST, so the reference
4123 * point is simply the @x, @y supplied to gtk_window_move(). The
4124 * top-left corner of the window decorations (aka window frame or
4125 * border) will be placed at @x, @y. Therefore, to position a window
4126 * at the top left of the screen, you want to use the default gravity
4127 * (which is #GDK_GRAVITY_NORTH_WEST) and move the window to 0,0.
4129 * To position a window at the bottom right corner of the screen, you
4130 * would set #GDK_GRAVITY_SOUTH_EAST, which means that the reference
4131 * point is at @x + the window width and @y + the window height, and
4132 * the bottom-right corner of the window border will be placed at that
4133 * reference point. So, to place a window in the bottom right corner
4134 * you would first set gravity to south east, then write:
4135 * <literal>gtk_window_move (window, gdk_screen_width () - window_width,
4136 * gdk_screen_height () - window_height)</literal> (note that this
4137 * example does not take multi-head scenarios into account).
4139 * The Extended Window Manager Hints specification at <ulink
4140 * url="http://www.freedesktop.org/Standards/wm-spec">
4141 * http://www.freedesktop.org/Standards/wm-spec</ulink> has a
4142 * nice table of gravities in the "implementation notes" section.
4144 * The gtk_window_get_position() documentation may also be relevant.
4147 gtk_window_move (GtkWindow *window,
4151 GtkWindowGeometryInfo *info;
4154 g_return_if_fail (GTK_IS_WINDOW (window));
4156 widget = GTK_WIDGET (window);
4158 info = gtk_window_get_geometry_info (window, TRUE);
4160 if (GTK_WIDGET_MAPPED (window))
4162 /* we have now sent a request with this position
4163 * with currently-active constraints, so toggle flag.
4165 info->position_constraints_changed = FALSE;
4167 /* we only constrain if mapped - if not mapped,
4168 * then gtk_window_compute_configure_request()
4169 * will apply the constraints later, and we
4170 * don't want to lose information about
4171 * what position the user set before then.
4172 * i.e. if you do a move() then turn off POS_CENTER
4173 * then show the window, your move() will work.
4175 gtk_window_constrain_position (window,
4176 widget->allocation.width,
4177 widget->allocation.height,
4180 /* Note that this request doesn't go through our standard request
4181 * framework, e.g. doesn't increment configure_request_count,
4182 * doesn't set info->last, etc.; that's because
4183 * we don't save the info needed to arrive at this same request
4186 * To gtk_window_move_resize(), this will end up looking exactly
4187 * the same as the position being changed by the window
4191 /* FIXME are we handling gravity properly for framed windows? */
4193 gdk_window_move (window->frame,
4194 x - window->frame_left,
4195 y - window->frame_top);
4197 gdk_window_move (GTK_WIDGET (window)->window,
4202 /* Save this position to apply on mapping */
4203 info->initial_x = x;
4204 info->initial_y = y;
4205 info->initial_pos_set = TRUE;
4210 * gtk_window_get_position:
4211 * @window: a #GtkWindow
4212 * @root_x: return location for X coordinate of gravity-determined reference point
4213 * @root_y: return location for Y coordinate of gravity-determined reference point
4215 * This function returns the position you need to pass to
4216 * gtk_window_move() to keep @window in its current position. This
4217 * means that the meaning of the returned value varies with window
4218 * gravity. See gtk_window_move() for more details.
4220 * If you haven't changed the window gravity, its gravity will be
4221 * #GDK_GRAVITY_NORTH_WEST. This means that gtk_window_get_position()
4222 * gets the position of the top-left corner of the window manager
4223 * frame for the window. gtk_window_move() sets the position of this
4224 * same top-left corner.
4226 * gtk_window_get_position() is not 100% reliable because the X Window System
4227 * does not specify a way to obtain the geometry of the
4228 * decorations placed on a window by the window manager.
4229 * Thus GTK+ is using a "best guess" that works with most
4232 * Moreover, nearly all window managers are historically broken with
4233 * respect to their handling of window gravity. So moving a window to
4234 * its current position as returned by gtk_window_get_position() tends
4235 * to result in moving the window slightly. Window managers are
4236 * slowly getting better over time.
4238 * If a window has gravity #GDK_GRAVITY_STATIC the window manager
4239 * frame is not relevant, and thus gtk_window_get_position() will
4240 * always produce accurate results. However you can't use static
4241 * gravity to do things like place a window in a corner of the screen,
4242 * because static gravity ignores the window manager decorations.
4244 * If you are saving and restoring your application's window
4245 * positions, you should know that it's impossible for applications to
4246 * do this without getting it somewhat wrong because applications do
4247 * not have sufficient knowledge of window manager state. The Correct
4248 * Mechanism is to support the session management protocol (see the
4249 * "GnomeClient" object in the GNOME libraries for example) and allow
4250 * the window manager to save your window sizes and positions.
4255 gtk_window_get_position (GtkWindow *window,
4261 g_return_if_fail (GTK_IS_WINDOW (window));
4263 widget = GTK_WIDGET (window);
4265 if (window->gravity == GDK_GRAVITY_STATIC)
4267 if (GTK_WIDGET_MAPPED (widget))
4269 /* This does a server round-trip, which is sort of wrong;
4270 * but a server round-trip is inevitable for
4271 * gdk_window_get_frame_extents() in the usual
4272 * NorthWestGravity case below, so not sure what else to
4273 * do. We should likely be consistent about whether we get
4274 * the client-side info or the server-side info.
4276 gdk_window_get_origin (widget->window, root_x, root_y);
4280 GdkRectangle configure_request;
4282 gtk_window_compute_configure_request (window,
4286 *root_x = configure_request.x;
4287 *root_y = configure_request.y;
4292 GdkRectangle frame_extents;
4297 if (GTK_WIDGET_MAPPED (widget))
4300 gdk_window_get_frame_extents (window->frame, &frame_extents);
4302 gdk_window_get_frame_extents (widget->window, &frame_extents);
4303 x = frame_extents.x;
4304 y = frame_extents.y;
4305 gtk_window_get_size (window, &w, &h);
4309 /* We just say the frame has 0 size on all sides.
4310 * Not sure what else to do.
4312 gtk_window_compute_configure_request (window,
4315 x = frame_extents.x;
4316 y = frame_extents.y;
4317 w = frame_extents.width;
4318 h = frame_extents.height;
4321 switch (window->gravity)
4323 case GDK_GRAVITY_NORTH:
4324 case GDK_GRAVITY_CENTER:
4325 case GDK_GRAVITY_SOUTH:
4326 /* Find center of frame. */
4327 x += frame_extents.width / 2;
4328 /* Center client window on that point. */
4332 case GDK_GRAVITY_SOUTH_EAST:
4333 case GDK_GRAVITY_EAST:
4334 case GDK_GRAVITY_NORTH_EAST:
4335 /* Find right edge of frame */
4336 x += frame_extents.width;
4337 /* Align left edge of client at that point. */
4344 switch (window->gravity)
4346 case GDK_GRAVITY_WEST:
4347 case GDK_GRAVITY_CENTER:
4348 case GDK_GRAVITY_EAST:
4349 /* Find center of frame. */
4350 y += frame_extents.height / 2;
4351 /* Center client window there. */
4354 case GDK_GRAVITY_SOUTH_WEST:
4355 case GDK_GRAVITY_SOUTH:
4356 case GDK_GRAVITY_SOUTH_EAST:
4357 /* Find south edge of frame */
4358 y += frame_extents.height;
4359 /* Place bottom edge of client there */
4374 * gtk_window_reshow_with_initial_size:
4375 * @window: a #GtkWindow
4377 * Hides @window, then reshows it, resetting the
4378 * default size and position of the window. Used
4379 * by GUI builders only.
4382 gtk_window_reshow_with_initial_size (GtkWindow *window)
4386 g_return_if_fail (GTK_IS_WINDOW (window));
4388 widget = GTK_WIDGET (window);
4390 gtk_widget_hide (widget);
4391 gtk_widget_unrealize (widget);
4392 gtk_widget_show (widget);
4396 gtk_window_destroy (GtkObject *object)
4398 GtkWindow *window = GTK_WINDOW (object);
4400 toplevel_list = g_slist_remove (toplevel_list, window);
4402 if (window->transient_parent)
4403 gtk_window_set_transient_for (window, NULL);
4405 /* frees the icons */
4406 gtk_window_set_icon_list (window, NULL);
4408 if (window->has_user_ref_count)
4410 window->has_user_ref_count = FALSE;
4411 g_object_unref (window);
4415 gtk_window_group_remove_window (window->group, window);
4417 gtk_window_free_key_hash (window);
4419 GTK_OBJECT_CLASS (gtk_window_parent_class)->destroy (object);
4423 gtk_window_finalize (GObject *object)
4425 GtkWindow *window = GTK_WINDOW (object);
4426 GtkWindowPrivate *priv = GTK_WINDOW_GET_PRIVATE (window);
4427 GtkMnemonicHash *mnemonic_hash;
4429 g_free (window->title);
4430 g_free (window->wmclass_name);
4431 g_free (window->wmclass_class);
4432 g_free (window->wm_role);
4434 mnemonic_hash = gtk_window_get_mnemonic_hash (window, FALSE);
4436 _gtk_mnemonic_hash_free (mnemonic_hash);
4438 if (window->geometry_info)
4440 if (window->geometry_info->widget)
4441 g_signal_handlers_disconnect_by_func (window->geometry_info->widget,
4442 gtk_widget_destroyed,
4443 &window->geometry_info->widget);
4444 g_free (window->geometry_info);
4447 if (window->keys_changed_handler)
4449 g_source_remove (window->keys_changed_handler);
4450 window->keys_changed_handler = 0;
4454 g_signal_handlers_disconnect_by_func (window->screen,
4455 gtk_window_on_composited_changed, window);
4457 g_free (priv->startup_id);
4459 G_OBJECT_CLASS (gtk_window_parent_class)->finalize (object);
4463 gtk_window_show (GtkWidget *widget)
4465 GtkWindow *window = GTK_WINDOW (widget);
4466 GtkContainer *container = GTK_CONTAINER (window);
4467 gboolean need_resize;
4469 GTK_WIDGET_SET_FLAGS (widget, GTK_VISIBLE);
4471 need_resize = container->need_resize || !GTK_WIDGET_REALIZED (widget);
4472 container->need_resize = FALSE;
4476 GtkWindowGeometryInfo *info = gtk_window_get_geometry_info (window, TRUE);
4477 GtkAllocation allocation = { 0, 0 };
4478 GdkRectangle configure_request;
4479 GdkGeometry new_geometry;
4481 gboolean was_realized;
4483 /* We are going to go ahead and perform this configure request
4484 * and then emulate a configure notify by going ahead and
4485 * doing a size allocate. Sort of a synchronous
4486 * mini-copy of gtk_window_move_resize() here.
4488 gtk_window_compute_configure_request (window,
4493 /* We update this because we are going to go ahead
4494 * and gdk_window_resize() below, rather than
4497 info->last.configure_request.width = configure_request.width;
4498 info->last.configure_request.height = configure_request.height;
4500 /* and allocate the window - this is normally done
4501 * in move_resize in response to configure notify
4503 allocation.width = configure_request.width;
4504 allocation.height = configure_request.height;
4505 gtk_widget_size_allocate (widget, &allocation);
4507 /* Then we guarantee we have a realize */
4508 was_realized = FALSE;
4509 if (!GTK_WIDGET_REALIZED (widget))
4511 gtk_widget_realize (widget);
4512 was_realized = TRUE;
4515 /* Must be done after the windows are realized,
4516 * so that the decorations can be read
4518 gtk_decorated_window_calculate_frame_size (window);
4520 /* We only send configure request if we didn't just finish
4521 * creating the window; if we just created the window
4522 * then we created it with widget->allocation anyhow.
4525 gdk_window_move_resize (widget->window,
4526 configure_request.x,
4527 configure_request.y,
4528 configure_request.width,
4529 configure_request.height);
4532 gtk_container_check_resize (container);
4534 gtk_widget_map (widget);
4536 /* Try to make sure that we have some focused widget
4538 if (!window->focus_widget && !GTK_IS_PLUG (window))
4539 gtk_window_move_focus (window, GTK_DIR_TAB_FORWARD);
4542 gtk_grab_add (widget);
4546 gtk_window_hide (GtkWidget *widget)
4548 GtkWindow *window = GTK_WINDOW (widget);
4550 GTK_WIDGET_UNSET_FLAGS (widget, GTK_VISIBLE);
4551 gtk_widget_unmap (widget);
4554 gtk_grab_remove (widget);
4558 gtk_window_map (GtkWidget *widget)
4560 GtkWindow *window = GTK_WINDOW (widget);
4561 GtkWindowPrivate *priv = GTK_WINDOW_GET_PRIVATE (window);
4562 GdkWindow *toplevel;
4563 gboolean auto_mnemonics;
4565 GTK_WIDGET_SET_FLAGS (widget, GTK_MAPPED);
4567 if (window->bin.child &&
4568 gtk_widget_get_visible (window->bin.child) &&
4569 !GTK_WIDGET_MAPPED (window->bin.child))
4570 gtk_widget_map (window->bin.child);
4573 toplevel = window->frame;
4575 toplevel = widget->window;
4577 if (window->maximize_initially)
4578 gdk_window_maximize (toplevel);
4580 gdk_window_unmaximize (toplevel);
4582 if (window->stick_initially)
4583 gdk_window_stick (toplevel);
4585 gdk_window_unstick (toplevel);
4587 if (window->iconify_initially)
4588 gdk_window_iconify (toplevel);
4590 gdk_window_deiconify (toplevel);
4592 if (priv->fullscreen_initially)
4593 gdk_window_fullscreen (toplevel);
4595 gdk_window_unfullscreen (toplevel);
4597 gdk_window_set_keep_above (toplevel, priv->above_initially);
4599 gdk_window_set_keep_below (toplevel, priv->below_initially);
4601 /* No longer use the default settings */
4602 window->need_default_size = FALSE;
4603 window->need_default_position = FALSE;
4605 if (priv->reset_type_hint)
4607 /* We should only reset the type hint when the application
4608 * used gtk_window_set_type_hint() to change the hint.
4609 * Some applications use X directly to change the properties;
4610 * in that case, we shouldn't overwrite what they did.
4612 gdk_window_set_type_hint (widget->window, priv->type_hint);
4613 priv->reset_type_hint = FALSE;
4616 gdk_window_show (widget->window);
4619 gdk_window_show (window->frame);
4621 if (!disable_startup_notification)
4623 /* Do we have a custom startup-notification id? */
4624 if (priv->startup_id != NULL)
4626 /* Make sure we have a "real" id */
4627 if (!startup_id_is_fake (priv->startup_id))
4628 gdk_notify_startup_complete_with_id (priv->startup_id);
4630 g_free (priv->startup_id);
4631 priv->startup_id = NULL;
4633 else if (!sent_startup_notification)
4635 sent_startup_notification = TRUE;
4636 gdk_notify_startup_complete ();
4640 /* if auto-mnemonics is enabled and mnemonics visible is not already set
4641 * (as in the case of popup menus), then hide mnemonics initially
4643 g_object_get (gtk_widget_get_settings (widget), "gtk-auto-mnemonics",
4644 &auto_mnemonics, NULL);
4645 if (auto_mnemonics && !priv->mnemonics_visible_set)
4646 gtk_window_set_mnemonics_visible (window, FALSE);
4650 gtk_window_map_event (GtkWidget *widget,
4653 if (!GTK_WIDGET_MAPPED (widget))
4655 /* we should be be unmapped, but are getting a MapEvent, this may happen
4656 * to toplevel XWindows if mapping was intercepted by a window manager
4657 * and an unmap request occoured while the MapRequestEvent was still
4658 * being handled. we work around this situaiton here by re-requesting
4659 * the window being unmapped. more details can be found in:
4660 * http://bugzilla.gnome.org/show_bug.cgi?id=316180
4662 gdk_window_hide (widget->window);
4668 gtk_window_unmap (GtkWidget *widget)
4670 GtkWindow *window = GTK_WINDOW (widget);
4671 GtkWindowPrivate *priv = GTK_WINDOW_GET_PRIVATE (widget);
4672 GtkWindowGeometryInfo *info;
4673 GdkWindowState state;
4675 GTK_WIDGET_UNSET_FLAGS (widget, GTK_MAPPED);
4677 gdk_window_withdraw (window->frame);
4679 gdk_window_withdraw (widget->window);
4681 window->configure_request_count = 0;
4682 window->configure_notify_received = FALSE;
4684 /* on unmap, we reset the default positioning of the window,
4685 * so it's placed again, but we don't reset the default
4686 * size of the window, so it's remembered.
4688 window->need_default_position = TRUE;
4690 info = gtk_window_get_geometry_info (window, FALSE);
4693 info->initial_pos_set = FALSE;
4694 info->position_constraints_changed = FALSE;
4697 state = gdk_window_get_state (widget->window);
4698 window->iconify_initially = (state & GDK_WINDOW_STATE_ICONIFIED) != 0;
4699 window->maximize_initially = (state & GDK_WINDOW_STATE_MAXIMIZED) != 0;
4700 window->stick_initially = (state & GDK_WINDOW_STATE_STICKY) != 0;
4701 priv->above_initially = (state & GDK_WINDOW_STATE_ABOVE) != 0;
4702 priv->below_initially = (state & GDK_WINDOW_STATE_BELOW) != 0;
4706 gtk_window_realize (GtkWidget *widget)
4709 GdkWindow *parent_window;
4710 GdkWindowAttr attributes;
4711 gint attributes_mask;
4712 GtkWindowPrivate *priv;
4714 window = GTK_WINDOW (widget);
4715 priv = GTK_WINDOW_GET_PRIVATE (window);
4717 /* ensure widget tree is properly size allocated */
4718 if (widget->allocation.x == -1 &&
4719 widget->allocation.y == -1 &&
4720 widget->allocation.width == 1 &&
4721 widget->allocation.height == 1)
4723 GtkRequisition requisition;
4724 GtkAllocation allocation = { 0, 0, 200, 200 };
4726 gtk_widget_size_request (widget, &requisition);
4727 if (requisition.width || requisition.height)
4729 /* non-empty window */
4730 allocation.width = requisition.width;
4731 allocation.height = requisition.height;
4733 gtk_widget_size_allocate (widget, &allocation);
4735 _gtk_container_queue_resize (GTK_CONTAINER (widget));
4737 g_return_if_fail (!GTK_WIDGET_REALIZED (widget));
4740 GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED);
4742 switch (window->type)
4744 case GTK_WINDOW_TOPLEVEL:
4745 attributes.window_type = GDK_WINDOW_TOPLEVEL;
4747 case GTK_WINDOW_POPUP:
4748 attributes.window_type = GDK_WINDOW_TEMP;
4751 g_warning (G_STRLOC": Unknown window type %d!", window->type);
4755 attributes.title = window->title;
4756 attributes.wmclass_name = window->wmclass_name;
4757 attributes.wmclass_class = window->wmclass_class;
4758 attributes.wclass = GDK_INPUT_OUTPUT;
4759 attributes.visual = gtk_widget_get_visual (widget);
4760 attributes.colormap = gtk_widget_get_colormap (widget);
4762 if (window->has_frame)
4764 attributes.width = widget->allocation.width + window->frame_left + window->frame_right;
4765 attributes.height = widget->allocation.height + window->frame_top + window->frame_bottom;
4766 attributes.event_mask = (GDK_EXPOSURE_MASK |
4767 GDK_KEY_PRESS_MASK |
4768 GDK_ENTER_NOTIFY_MASK |
4769 GDK_LEAVE_NOTIFY_MASK |
4770 GDK_FOCUS_CHANGE_MASK |
4771 GDK_STRUCTURE_MASK |
4772 GDK_BUTTON_MOTION_MASK |
4773 GDK_POINTER_MOTION_HINT_MASK |
4774 GDK_BUTTON_PRESS_MASK |
4775 GDK_BUTTON_RELEASE_MASK);
4777 attributes_mask = GDK_WA_VISUAL | GDK_WA_COLORMAP;
4779 window->frame = gdk_window_new (gtk_widget_get_root_window (widget),
4780 &attributes, attributes_mask);
4782 if (priv->opacity_set)
4783 gdk_window_set_opacity (window->frame, priv->opacity);
4785 gdk_window_set_user_data (window->frame, widget);
4787 attributes.window_type = GDK_WINDOW_CHILD;
4788 attributes.x = window->frame_left;
4789 attributes.y = window->frame_top;
4791 attributes_mask = GDK_WA_X | GDK_WA_Y;
4793 parent_window = window->frame;
4795 g_signal_connect (window,
4797 G_CALLBACK (gtk_window_event),
4802 attributes_mask = 0;
4803 parent_window = gtk_widget_get_root_window (widget);
4806 attributes.width = widget->allocation.width;
4807 attributes.height = widget->allocation.height;
4808 attributes.event_mask = gtk_widget_get_events (widget);
4809 attributes.event_mask |= (GDK_EXPOSURE_MASK |
4810 GDK_KEY_PRESS_MASK |
4811 GDK_KEY_RELEASE_MASK |
4812 GDK_ENTER_NOTIFY_MASK |
4813 GDK_LEAVE_NOTIFY_MASK |
4814 GDK_FOCUS_CHANGE_MASK |
4815 GDK_STRUCTURE_MASK);
4816 attributes.type_hint = priv->type_hint;
4818 attributes_mask |= GDK_WA_VISUAL | GDK_WA_COLORMAP | GDK_WA_TYPE_HINT;
4819 attributes_mask |= (window->title ? GDK_WA_TITLE : 0);
4820 attributes_mask |= (window->wmclass_name ? GDK_WA_WMCLASS : 0);
4822 widget->window = gdk_window_new (parent_window, &attributes, attributes_mask);
4824 if (!window->has_frame && priv->opacity_set)
4825 gdk_window_set_opacity (widget->window, priv->opacity);
4827 gdk_window_enable_synchronized_configure (widget->window);
4829 gdk_window_set_user_data (widget->window, window);
4831 widget->style = gtk_style_attach (widget->style, widget->window);
4832 gtk_style_set_background (widget->style, widget->window, GTK_STATE_NORMAL);
4834 gtk_style_set_background (widget->style, window->frame, GTK_STATE_NORMAL);
4836 /* This is a bad hack to set the window background. */
4837 gtk_window_paint (widget, NULL);
4839 if (window->transient_parent &&
4840 GTK_WIDGET_REALIZED (window->transient_parent))
4841 gdk_window_set_transient_for (widget->window,
4842 GTK_WIDGET (window->transient_parent)->window);
4844 if (window->wm_role)
4845 gdk_window_set_role (widget->window, window->wm_role);
4847 if (!window->decorated)
4848 gdk_window_set_decorations (widget->window, 0);
4850 if (!priv->deletable)
4851 gdk_window_set_functions (widget->window, GDK_FUNC_ALL | GDK_FUNC_CLOSE);
4853 if (gtk_window_get_skip_pager_hint (window))
4854 gdk_window_set_skip_pager_hint (widget->window, TRUE);
4856 if (gtk_window_get_skip_taskbar_hint (window))
4857 gdk_window_set_skip_taskbar_hint (widget->window, TRUE);
4859 if (gtk_window_get_accept_focus (window))
4860 gdk_window_set_accept_focus (widget->window, TRUE);
4862 gdk_window_set_accept_focus (widget->window, FALSE);
4864 if (gtk_window_get_focus_on_map (window))
4865 gdk_window_set_focus_on_map (widget->window, TRUE);
4867 gdk_window_set_focus_on_map (widget->window, FALSE);
4870 gdk_window_set_modal_hint (widget->window, TRUE);
4872 gdk_window_set_modal_hint (widget->window, FALSE);
4874 if (priv->startup_id)
4876 #ifdef GDK_WINDOWING_X11
4877 guint32 timestamp = extract_time_from_startup_id (priv->startup_id);
4878 if (timestamp != GDK_CURRENT_TIME)
4879 gdk_x11_window_set_user_time (widget->window, timestamp);
4881 if (!startup_id_is_fake (priv->startup_id))
4882 gdk_window_set_startup_id (widget->window, priv->startup_id);
4886 gtk_window_realize_icon (window);
4890 gtk_window_unrealize (GtkWidget *widget)
4893 GtkWindowGeometryInfo *info;
4895 window = GTK_WINDOW (widget);
4897 /* On unrealize, we reset the size of the window such
4898 * that we will re-apply the default sizing stuff
4899 * next time we show the window.
4901 * Default positioning is reset on unmap, instead of unrealize.
4903 window->need_default_size = TRUE;
4904 info = gtk_window_get_geometry_info (window, FALSE);
4907 info->resize_width = -1;
4908 info->resize_height = -1;
4909 info->last.configure_request.x = 0;
4910 info->last.configure_request.y = 0;
4911 info->last.configure_request.width = -1;
4912 info->last.configure_request.height = -1;
4913 /* be sure we reset geom hints on re-realize */
4914 info->last.flags = 0;
4919 gdk_window_set_user_data (window->frame, NULL);
4920 gdk_window_destroy (window->frame);
4921 window->frame = NULL;
4925 gtk_window_unrealize_icon (window);
4927 GTK_WIDGET_CLASS (gtk_window_parent_class)->unrealize (widget);
4931 gtk_window_size_request (GtkWidget *widget,
4932 GtkRequisition *requisition)
4937 window = GTK_WINDOW (widget);
4938 bin = GTK_BIN (window);
4940 requisition->width = GTK_CONTAINER (window)->border_width * 2;
4941 requisition->height = GTK_CONTAINER (window)->border_width * 2;
4943 if (bin->child && gtk_widget_get_visible (bin->child))
4945 GtkRequisition child_requisition;
4947 gtk_widget_size_request (bin->child, &child_requisition);
4949 requisition->width += child_requisition.width;
4950 requisition->height += child_requisition.height;
4955 gtk_window_size_allocate (GtkWidget *widget,
4956 GtkAllocation *allocation)
4959 GtkAllocation child_allocation;
4961 window = GTK_WINDOW (widget);
4962 widget->allocation = *allocation;
4964 if (window->bin.child && gtk_widget_get_visible (window->bin.child))
4966 child_allocation.x = GTK_CONTAINER (window)->border_width;
4967 child_allocation.y = GTK_CONTAINER (window)->border_width;
4968 child_allocation.width =
4969 MAX (1, (gint)allocation->width - child_allocation.x * 2);
4970 child_allocation.height =
4971 MAX (1, (gint)allocation->height - child_allocation.y * 2);
4973 gtk_widget_size_allocate (window->bin.child, &child_allocation);
4976 if (GTK_WIDGET_REALIZED (widget) && window->frame)
4978 gdk_window_resize (window->frame,
4979 allocation->width + window->frame_left + window->frame_right,
4980 allocation->height + window->frame_top + window->frame_bottom);
4985 gtk_window_event (GtkWidget *widget, GdkEvent *event)
4988 gboolean return_val;
4990 window = GTK_WINDOW (widget);
4992 if (window->frame && (event->any.window == window->frame))
4994 if ((event->type != GDK_KEY_PRESS) &&
4995 (event->type != GDK_KEY_RELEASE) &&
4996 (event->type != GDK_FOCUS_CHANGE))
4998 g_signal_stop_emission_by_name (widget, "event");
5000 g_signal_emit (widget, window_signals[FRAME_EVENT], 0, event, &return_val);
5005 g_object_unref (event->any.window);
5006 event->any.window = g_object_ref (widget->window);
5014 gtk_window_frame_event (GtkWindow *window, GdkEvent *event)
5016 GdkEventConfigure *configure_event;
5019 switch (event->type)
5022 configure_event = (GdkEventConfigure *)event;
5024 /* Invalidate the decorations */
5027 rect.width = configure_event->width;
5028 rect.height = configure_event->height;
5030 gdk_window_invalidate_rect (window->frame, &rect, FALSE);
5032 /* Pass on the (modified) configure event */
5033 configure_event->width -= window->frame_left + window->frame_right;
5034 configure_event->height -= window->frame_top + window->frame_bottom;
5035 return gtk_window_configure_event (GTK_WIDGET (window), configure_event);
5044 gtk_window_configure_event (GtkWidget *widget,
5045 GdkEventConfigure *event)
5047 GtkWindow *window = GTK_WINDOW (widget);
5048 gboolean expected_reply = window->configure_request_count > 0;
5050 /* window->configure_request_count incremented for each
5051 * configure request, and decremented to a min of 0 for
5052 * each configure notify.
5054 * All it means is that we know we will get at least
5055 * window->configure_request_count more configure notifies.
5056 * We could get more configure notifies than that; some
5057 * of the configure notifies we get may be unrelated to
5058 * the configure requests. But we will get at least
5059 * window->configure_request_count notifies.
5062 if (window->configure_request_count > 0)
5064 window->configure_request_count -= 1;
5065 gdk_window_thaw_toplevel_updates_libgtk_only (widget->window);
5068 /* As an optimization, we avoid a resize when possible.
5070 * The only times we can avoid a resize are:
5071 * - we know only the position changed, not the size
5072 * - we know we have made more requests and so will get more
5073 * notifies and can wait to resize when we get them
5076 if (!expected_reply &&
5077 (widget->allocation.width == event->width &&
5078 widget->allocation.height == event->height))
5080 gdk_window_configure_finished (widget->window);
5085 * If we do need to resize, we do that by:
5086 * - filling in widget->allocation with the new size
5087 * - setting configure_notify_received to TRUE
5088 * for use in gtk_window_move_resize()
5089 * - queueing a resize, leading to invocation of
5090 * gtk_window_move_resize() in an idle handler
5094 window->configure_notify_received = TRUE;
5096 widget->allocation.width = event->width;
5097 widget->allocation.height = event->height;
5099 _gtk_container_queue_resize (GTK_CONTAINER (widget));
5104 /* the accel_key and accel_mods fields of the key have to be setup
5105 * upon calling this function. it'll then return whether that key
5106 * is at all used as accelerator, and if so will OR in the
5107 * accel_flags member of the key.
5110 _gtk_window_query_nonaccels (GtkWindow *window,
5112 GdkModifierType accel_mods)
5114 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
5116 /* movement keys are considered locked accels */
5119 static const guint bindings[] = {
5120 GDK_space, GDK_KP_Space, GDK_Return, GDK_ISO_Enter, GDK_KP_Enter, GDK_Up, GDK_KP_Up, GDK_Down, GDK_KP_Down,
5121 GDK_Left, GDK_KP_Left, GDK_Right, GDK_KP_Right, GDK_Tab, GDK_KP_Tab, GDK_ISO_Left_Tab,
5125 for (i = 0; i < G_N_ELEMENTS (bindings); i++)
5126 if (bindings[i] == accel_key)
5130 /* mnemonics are considered locked accels */
5131 if (accel_mods == window->mnemonic_modifier)
5133 GtkMnemonicHash *mnemonic_hash = gtk_window_get_mnemonic_hash (window, FALSE);
5134 if (mnemonic_hash && _gtk_mnemonic_hash_lookup (mnemonic_hash, accel_key))
5142 * gtk_window_propagate_key_event:
5143 * @window: a #GtkWindow
5144 * @event: a #GdkEventKey
5146 * Propagate a key press or release event to the focus widget and
5147 * up the focus container chain until a widget handles @event.
5148 * This is normally called by the default ::key_press_event and
5149 * ::key_release_event handlers for toplevel windows,
5150 * however in some cases it may be useful to call this directly when
5151 * overriding the standard key handling for a toplevel window.
5153 * Return value: %TRUE if a widget in the focus chain handled the event.
5158 gtk_window_propagate_key_event (GtkWindow *window,
5161 gboolean handled = FALSE;
5162 GtkWidget *widget, *focus;
5164 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
5166 widget = GTK_WIDGET (window);
5167 focus = window->focus_widget;
5169 g_object_ref (focus);
5172 focus && focus != widget &&
5173 gtk_widget_get_toplevel (focus) == widget)
5177 if (gtk_widget_is_sensitive (focus))
5178 handled = gtk_widget_event (focus, (GdkEvent*) event);
5180 parent = focus->parent;
5182 g_object_ref (parent);
5184 g_object_unref (focus);
5190 g_object_unref (focus);
5196 gtk_window_key_press_event (GtkWidget *widget,
5199 GtkWindow *window = GTK_WINDOW (widget);
5200 gboolean handled = FALSE;
5202 /* handle mnemonics and accelerators */
5204 handled = gtk_window_activate_key (window, event);
5206 /* handle focus widget key events */
5208 handled = gtk_window_propagate_key_event (window, event);
5210 /* Chain up, invokes binding set */
5212 handled = GTK_WIDGET_CLASS (gtk_window_parent_class)->key_press_event (widget, event);
5218 gtk_window_key_release_event (GtkWidget *widget,
5221 GtkWindow *window = GTK_WINDOW (widget);
5222 gboolean handled = FALSE;
5224 /* handle focus widget key events */
5226 handled = gtk_window_propagate_key_event (window, event);
5228 /* Chain up, invokes binding set */
5230 handled = GTK_WIDGET_CLASS (gtk_window_parent_class)->key_release_event (widget, event);
5236 gtk_window_real_activate_default (GtkWindow *window)
5238 gtk_window_activate_default (window);
5242 gtk_window_real_activate_focus (GtkWindow *window)
5244 gtk_window_activate_focus (window);
5248 gtk_window_move_focus (GtkWindow *window,
5249 GtkDirectionType dir)
5251 gtk_widget_child_focus (GTK_WIDGET (window), dir);
5253 if (!GTK_CONTAINER (window)->focus_child)
5254 gtk_window_set_focus (window, NULL);
5258 gtk_window_enter_notify_event (GtkWidget *widget,
5259 GdkEventCrossing *event)
5265 gtk_window_leave_notify_event (GtkWidget *widget,
5266 GdkEventCrossing *event)
5272 do_focus_change (GtkWidget *widget,
5275 GdkEvent *fevent = gdk_event_new (GDK_FOCUS_CHANGE);
5277 g_object_ref (widget);
5280 GTK_WIDGET_SET_FLAGS (widget, GTK_HAS_FOCUS);
5282 GTK_WIDGET_UNSET_FLAGS (widget, GTK_HAS_FOCUS);
5284 fevent->focus_change.type = GDK_FOCUS_CHANGE;
5285 fevent->focus_change.window = widget->window;
5287 g_object_ref (widget->window);
5288 fevent->focus_change.in = in;
5290 gtk_widget_event (widget, fevent);
5292 g_object_notify (G_OBJECT (widget), "has-focus");
5294 g_object_unref (widget);
5295 gdk_event_free (fevent);
5299 gtk_window_focus_in_event (GtkWidget *widget,
5300 GdkEventFocus *event)
5302 GtkWindow *window = GTK_WINDOW (widget);
5304 /* It appears spurious focus in events can occur when
5305 * the window is hidden. So we'll just check to see if
5306 * the window is visible before actually handling the
5309 if (gtk_widget_get_visible (widget))
5311 _gtk_window_set_has_toplevel_focus (window, TRUE);
5312 _gtk_window_set_is_active (window, TRUE);
5319 gtk_window_focus_out_event (GtkWidget *widget,
5320 GdkEventFocus *event)
5322 GtkWindow *window = GTK_WINDOW (widget);
5323 gboolean auto_mnemonics;
5325 _gtk_window_set_has_toplevel_focus (window, FALSE);
5326 _gtk_window_set_is_active (window, FALSE);
5328 /* set the mnemonic-visible property to false */
5329 g_object_get (gtk_widget_get_settings (widget),
5330 "gtk-auto-mnemonics", &auto_mnemonics, NULL);
5332 gtk_window_set_mnemonics_visible (window, FALSE);
5337 static GdkAtom atom_rcfiles = GDK_NONE;
5338 static GdkAtom atom_iconthemes = GDK_NONE;
5341 send_client_message_to_embedded_windows (GtkWidget *widget,
5342 GdkAtom message_type)
5344 GList *embedded_windows;
5346 embedded_windows = g_object_get_qdata (G_OBJECT (widget), quark_gtk_embedded);
5347 if (embedded_windows)
5349 GdkEvent *send_event = gdk_event_new (GDK_CLIENT_EVENT);
5352 for (i = 0; i < 5; i++)
5353 send_event->client.data.l[i] = 0;
5354 send_event->client.data_format = 32;
5355 send_event->client.message_type = message_type;
5357 while (embedded_windows)
5359 GdkNativeWindow xid = GDK_GPOINTER_TO_NATIVE_WINDOW(embedded_windows->data);
5360 gdk_event_send_client_message_for_display (gtk_widget_get_display (widget), send_event, xid);
5361 embedded_windows = embedded_windows->next;
5364 gdk_event_free (send_event);
5369 gtk_window_client_event (GtkWidget *widget,
5370 GdkEventClient *event)
5374 atom_rcfiles = gdk_atom_intern_static_string ("_GTK_READ_RCFILES");
5375 atom_iconthemes = gdk_atom_intern_static_string ("_GTK_LOAD_ICONTHEMES");
5378 if (event->message_type == atom_rcfiles)
5380 send_client_message_to_embedded_windows (widget, atom_rcfiles);
5381 gtk_rc_reparse_all_for_settings (gtk_widget_get_settings (widget), FALSE);
5384 if (event->message_type == atom_iconthemes)
5386 send_client_message_to_embedded_windows (widget, atom_iconthemes);
5387 _gtk_icon_theme_check_reload (gtk_widget_get_display (widget));
5394 gtk_window_check_resize (GtkContainer *container)
5396 if (gtk_widget_get_visible (GTK_WIDGET (container)))
5397 gtk_window_move_resize (GTK_WINDOW (container));
5401 gtk_window_focus (GtkWidget *widget,
5402 GtkDirectionType direction)
5406 GtkContainer *container;
5407 GtkWidget *old_focus_child;
5410 container = GTK_CONTAINER (widget);
5411 window = GTK_WINDOW (widget);
5412 bin = GTK_BIN (widget);
5414 old_focus_child = container->focus_child;
5416 /* We need a special implementation here to deal properly with wrapping
5417 * around in the tab chain without the danger of going into an
5420 if (old_focus_child)
5422 if (gtk_widget_child_focus (old_focus_child, direction))
5426 if (window->focus_widget)
5428 if (direction == GTK_DIR_LEFT ||
5429 direction == GTK_DIR_RIGHT ||
5430 direction == GTK_DIR_UP ||
5431 direction == GTK_DIR_DOWN)
5436 /* Wrapped off the end, clear the focus setting for the toplpevel */
5437 parent = window->focus_widget->parent;
5440 gtk_container_set_focus_child (GTK_CONTAINER (parent), NULL);
5441 parent = GTK_WIDGET (parent)->parent;
5444 gtk_window_set_focus (GTK_WINDOW (container), NULL);
5447 /* Now try to focus the first widget in the window */
5450 if (gtk_widget_child_focus (bin->child, direction))
5458 gtk_window_real_set_focus (GtkWindow *window,
5461 GtkWidget *old_focus = window->focus_widget;
5462 gboolean had_default = FALSE;
5463 gboolean focus_had_default = FALSE;
5464 gboolean old_focus_had_default = FALSE;
5468 g_object_ref (old_focus);
5469 g_object_freeze_notify (G_OBJECT (old_focus));
5470 old_focus_had_default = gtk_widget_has_default (old_focus);
5474 g_object_ref (focus);
5475 g_object_freeze_notify (G_OBJECT (focus));
5476 focus_had_default = gtk_widget_has_default (focus);
5479 if (window->default_widget)
5480 had_default = gtk_widget_has_default (window->default_widget);
5482 if (window->focus_widget)
5484 if (gtk_widget_get_receives_default (window->focus_widget) &&
5485 (window->focus_widget != window->default_widget))
5487 GTK_WIDGET_UNSET_FLAGS (window->focus_widget, GTK_HAS_DEFAULT);
5488 gtk_widget_queue_draw (window->focus_widget);
5490 if (window->default_widget)
5491 GTK_WIDGET_SET_FLAGS (window->default_widget, GTK_HAS_DEFAULT);
5494 window->focus_widget = NULL;
5496 if (window->has_focus)
5497 do_focus_change (old_focus, FALSE);
5499 g_object_notify (G_OBJECT (old_focus), "is-focus");
5502 /* The above notifications may have set a new focus widget,
5503 * if so, we don't want to override it.
5505 if (focus && !window->focus_widget)
5507 window->focus_widget = focus;
5509 if (gtk_widget_get_receives_default (window->focus_widget) &&
5510 (window->focus_widget != window->default_widget))
5512 if (gtk_widget_get_can_default (window->focus_widget))
5513 GTK_WIDGET_SET_FLAGS (window->focus_widget, GTK_HAS_DEFAULT);
5515 if (window->default_widget)
5516 GTK_WIDGET_UNSET_FLAGS (window->default_widget, GTK_HAS_DEFAULT);
5519 if (window->has_focus)
5520 do_focus_change (window->focus_widget, TRUE);
5522 g_object_notify (G_OBJECT (window->focus_widget), "is-focus");
5525 /* If the default widget changed, a redraw will have been queued
5526 * on the old and new default widgets by gtk_window_set_default(), so
5527 * we only have to worry about the case where it didn't change.
5528 * We'll sometimes queue a draw twice on the new widget but that
5531 if (window->default_widget &&
5532 (had_default != gtk_widget_has_default (window->default_widget)))
5533 gtk_widget_queue_draw (window->default_widget);
5537 if (old_focus_had_default != gtk_widget_has_default (old_focus))
5538 gtk_widget_queue_draw (old_focus);
5540 g_object_thaw_notify (G_OBJECT (old_focus));
5541 g_object_unref (old_focus);
5545 if (focus_had_default != gtk_widget_has_default (focus))
5546 gtk_widget_queue_draw (focus);
5548 g_object_thaw_notify (G_OBJECT (focus));
5549 g_object_unref (focus);
5554 * _gtk_window_unset_focus_and_default:
5555 * @window: a #GtkWindow
5556 * @widget: a widget inside of @window
5558 * Checks whether the focus and default widgets of @window are
5559 * @widget or a descendent of @widget, and if so, unset them.
5562 _gtk_window_unset_focus_and_default (GtkWindow *window,
5568 g_object_ref (window);
5569 g_object_ref (widget);
5571 if (GTK_CONTAINER (widget->parent)->focus_child == widget)
5573 child = window->focus_widget;
5575 while (child && child != widget)
5576 child = child->parent;
5578 if (child == widget)
5579 gtk_window_set_focus (GTK_WINDOW (window), NULL);
5582 child = window->default_widget;
5584 while (child && child != widget)
5585 child = child->parent;
5587 if (child == widget)
5588 gtk_window_set_default (window, NULL);
5590 g_object_unref (widget);
5591 g_object_unref (window);
5594 /*********************************
5595 * Functions related to resizing *
5596 *********************************/
5598 /* This function doesn't constrain to geometry hints */
5600 gtk_window_compute_configure_request_size (GtkWindow *window,
5604 GtkRequisition requisition;
5605 GtkWindowGeometryInfo *info;
5609 * - we've done a size request
5612 widget = GTK_WIDGET (window);
5614 info = gtk_window_get_geometry_info (window, FALSE);
5616 if (window->need_default_size)
5618 gtk_widget_get_child_requisition (widget, &requisition);
5620 /* Default to requisition */
5621 *width = requisition.width;
5622 *height = requisition.height;
5624 /* If window is empty so requests 0, default to random nonzero size */
5625 if (*width == 0 && *height == 0)
5631 /* Override requisition with default size */
5635 gint base_width = 0;
5636 gint base_height = 0;
5638 gint min_height = 0;
5640 gint height_inc = 1;
5642 if (info->default_is_geometry &&
5643 (info->default_width > 0 || info->default_height > 0))
5645 GdkGeometry geometry;
5648 gtk_window_compute_hints (window, &geometry, &flags);
5650 if (flags & GDK_HINT_BASE_SIZE)
5652 base_width = geometry.base_width;
5653 base_height = geometry.base_height;
5655 if (flags & GDK_HINT_MIN_SIZE)
5657 min_width = geometry.min_width;
5658 min_height = geometry.min_height;
5660 if (flags & GDK_HINT_RESIZE_INC)
5662 width_inc = geometry.width_inc;
5663 height_inc = geometry.height_inc;
5667 if (info->default_width > 0)
5668 *width = MAX (info->default_width * width_inc + base_width, min_width);
5670 if (info->default_height > 0)
5671 *height = MAX (info->default_height * height_inc + base_height, min_height);
5676 /* Default to keeping current size */
5677 *width = widget->allocation.width;
5678 *height = widget->allocation.height;
5681 /* Override any size with gtk_window_resize() values */
5684 if (info->resize_width > 0)
5685 *width = info->resize_width;
5687 if (info->resize_height > 0)
5688 *height = info->resize_height;
5691 /* Don't ever request zero width or height, its not supported by
5692 gdk. The size allocation code will round it to 1 anyway but if
5693 we do it then the value returned from this function will is
5694 not comparable to the size allocation read from the GtkWindow. */
5695 *width = MAX (*width, 1);
5696 *height = MAX (*height, 1);
5699 static GtkWindowPosition
5700 get_effective_position (GtkWindow *window)
5702 GtkWindowPosition pos = window->position;
5703 if (pos == GTK_WIN_POS_CENTER_ON_PARENT &&
5704 (window->transient_parent == NULL ||
5705 !GTK_WIDGET_MAPPED (window->transient_parent)))
5706 pos = GTK_WIN_POS_NONE;
5712 get_center_monitor_of_window (GtkWindow *window)
5714 /* We could try to sort out the relative positions of the monitors and
5715 * stuff, or we could just be losers and assume you have a row
5716 * or column of monitors.
5718 return gdk_screen_get_n_monitors (gtk_window_check_screen (window)) / 2;
5722 get_monitor_containing_pointer (GtkWindow *window)
5726 GdkScreen *window_screen;
5727 GdkScreen *pointer_screen;
5729 window_screen = gtk_window_check_screen (window);
5730 gdk_display_get_pointer (gdk_screen_get_display (window_screen),
5734 if (pointer_screen == window_screen)
5735 monitor_num = gdk_screen_get_monitor_at_point (pointer_screen, px, py);
5743 center_window_on_monitor (GtkWindow *window,
5749 GdkRectangle monitor;
5752 monitor_num = get_monitor_containing_pointer (window);
5754 if (monitor_num == -1)
5755 monitor_num = get_center_monitor_of_window (window);
5757 gdk_screen_get_monitor_geometry (gtk_window_check_screen (window),
5758 monitor_num, &monitor);
5760 *x = (monitor.width - w) / 2 + monitor.x;
5761 *y = (monitor.height - h) / 2 + monitor.y;
5763 /* Be sure we aren't off the monitor, ignoring _NET_WM_STRUT
5764 * and WM decorations.
5778 if (extent > clamp_extent)
5780 *base = clamp_base + clamp_extent/2 - extent/2;
5781 else if (*base < clamp_base)
5783 else if (*base + extent > clamp_base + clamp_extent)
5784 *base = clamp_base + clamp_extent - extent;
5788 clamp_window_to_rectangle (gint *x,
5792 const GdkRectangle *rect)
5794 #ifdef DEBUGGING_OUTPUT
5795 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);
5798 /* If it is too large, center it. If it fits on the monitor but is
5799 * partially outside, move it to the closest edge. Do this
5800 * separately in x and y directions.
5802 clamp (x, w, rect->x, rect->width);
5803 clamp (y, h, rect->y, rect->height);
5804 #ifdef DEBUGGING_OUTPUT
5805 g_print (" ==> %+d%+d: %dx%d\n", *x, *y, w, h);
5811 gtk_window_compute_configure_request (GtkWindow *window,
5812 GdkRectangle *request,
5813 GdkGeometry *geometry,
5816 GdkGeometry new_geometry;
5820 GtkWindowPosition pos;
5821 GtkWidget *parent_widget;
5822 GtkWindowGeometryInfo *info;
5826 widget = GTK_WIDGET (window);
5828 screen = gtk_window_check_screen (window);
5830 gtk_widget_size_request (widget, NULL);
5831 gtk_window_compute_configure_request_size (window, (guint *)&w, (guint *)&h);
5833 gtk_window_compute_hints (window, &new_geometry, &new_flags);
5834 gtk_window_constrain_size (window,
5835 &new_geometry, new_flags,
5839 parent_widget = (GtkWidget*) window->transient_parent;
5841 pos = get_effective_position (window);
5842 info = gtk_window_get_geometry_info (window, FALSE);
5844 /* by default, don't change position requested */
5847 x = info->last.configure_request.x;
5848 y = info->last.configure_request.y;
5857 if (window->need_default_position)
5860 /* FIXME this all interrelates with window gravity.
5861 * For most of them I think we want to set GRAVITY_CENTER.
5863 * Not sure how to go about that.
5868 /* here we are only handling CENTER_ALWAYS
5869 * as it relates to default positioning,
5870 * where it's equivalent to simply CENTER
5872 case GTK_WIN_POS_CENTER_ALWAYS:
5873 case GTK_WIN_POS_CENTER:
5874 center_window_on_monitor (window, w, h, &x, &y);
5877 case GTK_WIN_POS_CENTER_ON_PARENT:
5880 GdkRectangle monitor;
5883 g_assert (GTK_WIDGET_MAPPED (parent_widget)); /* established earlier */
5885 if (parent_widget->window != NULL)
5886 monitor_num = gdk_screen_get_monitor_at_window (screen,
5887 parent_widget->window);
5891 gdk_window_get_origin (parent_widget->window,
5894 x = ox + (parent_widget->allocation.width - w) / 2;
5895 y = oy + (parent_widget->allocation.height - h) / 2;
5897 /* Clamp onto current monitor, ignoring _NET_WM_STRUT and
5898 * WM decorations. If parent wasn't on a monitor, just
5901 if (monitor_num >= 0)
5903 gdk_screen_get_monitor_geometry (screen, monitor_num, &monitor);
5904 clamp_window_to_rectangle (&x, &y, w, h, &monitor);
5909 case GTK_WIN_POS_MOUSE:
5911 gint screen_width = gdk_screen_get_width (screen);
5912 gint screen_height = gdk_screen_get_height (screen);
5914 GdkRectangle monitor;
5915 GdkScreen *pointer_screen;
5918 gdk_display_get_pointer (gdk_screen_get_display (screen),
5922 if (pointer_screen == screen)
5923 monitor_num = gdk_screen_get_monitor_at_point (screen, px, py);
5929 x = CLAMP (x, 0, screen_width - w);
5930 y = CLAMP (y, 0, screen_height - h);
5932 /* Clamp onto current monitor, ignoring _NET_WM_STRUT and
5933 * WM decorations. Don't try to figure out what's going
5934 * on if the mouse wasn't inside a monitor.
5936 if (monitor_num >= 0)
5938 gdk_screen_get_monitor_geometry (screen, monitor_num, &monitor);
5939 clamp_window_to_rectangle (&x, &y, w, h, &monitor);
5947 } /* if (window->need_default_position) */
5949 if (window->need_default_position && info &&
5950 info->initial_pos_set)
5952 x = info->initial_x;
5953 y = info->initial_y;
5954 gtk_window_constrain_position (window, w, h, &x, &y);
5960 request->height = h;
5963 *geometry = new_geometry;
5969 gtk_window_constrain_position (GtkWindow *window,
5975 /* See long comments in gtk_window_move_resize()
5976 * on when it's safe to call this function.
5978 if (window->position == GTK_WIN_POS_CENTER_ALWAYS)
5980 gint center_x, center_y;
5982 center_window_on_monitor (window, new_width, new_height, ¢er_x, ¢er_y);
5990 gtk_window_move_resize (GtkWindow *window)
5994 * First we determine whether any information has changed that would
5995 * cause us to revise our last configure request. If we would send
5996 * a different configure request from last time, then
5997 * configure_request_size_changed = TRUE or
5998 * configure_request_pos_changed = TRUE. configure_request_size_changed
5999 * may be true due to new hints, a gtk_window_resize(), or whatever.
6000 * configure_request_pos_changed may be true due to gtk_window_set_position()
6001 * or gtk_window_move().
6003 * If the configure request has changed, we send off a new one. To
6004 * ensure GTK+ invariants are maintained (resize queue does what it
6005 * should), we go ahead and size_allocate the requested size in this
6008 * If the configure request has not changed, we don't ever resend
6009 * it, because it could mean fighting the user or window manager.
6012 * To prepare the configure request, we come up with a base size/pos:
6013 * - the one from gtk_window_move()/gtk_window_resize()
6014 * - else default_width, default_height if we haven't ever
6016 * - else the size request if we haven't ever been mapped,
6017 * as a substitute default size
6018 * - else the current size of the window, as received from
6019 * configure notifies (i.e. the current allocation)
6021 * If GTK_WIN_POS_CENTER_ALWAYS is active, we constrain
6022 * the position request to be centered.
6025 GtkContainer *container;
6026 GtkWindowGeometryInfo *info;
6027 GdkGeometry new_geometry;
6029 GdkRectangle new_request;
6030 gboolean configure_request_size_changed;
6031 gboolean configure_request_pos_changed;
6032 gboolean hints_changed; /* do we need to send these again */
6033 GtkWindowLastGeometryInfo saved_last_info;
6035 widget = GTK_WIDGET (window);
6036 container = GTK_CONTAINER (widget);
6037 info = gtk_window_get_geometry_info (window, TRUE);
6039 configure_request_size_changed = FALSE;
6040 configure_request_pos_changed = FALSE;
6042 gtk_window_compute_configure_request (window, &new_request,
6043 &new_geometry, &new_flags);
6045 /* This check implies the invariant that we never set info->last
6046 * without setting the hints and sending off a configure request.
6048 * If we change info->last without sending the request, we may
6051 if (info->last.configure_request.x != new_request.x ||
6052 info->last.configure_request.y != new_request.y)
6053 configure_request_pos_changed = TRUE;
6055 if ((info->last.configure_request.width != new_request.width ||
6056 info->last.configure_request.height != new_request.height))
6057 configure_request_size_changed = TRUE;
6059 hints_changed = FALSE;
6061 if (!gtk_window_compare_hints (&info->last.geometry, info->last.flags,
6062 &new_geometry, new_flags))
6064 hints_changed = TRUE;
6067 /* Position Constraints
6068 * ====================
6070 * POS_CENTER_ALWAYS is conceptually a constraint rather than
6071 * a default. The other POS_ values are used only when the
6072 * window is shown, not after that.
6074 * However, we can't implement a position constraint as
6075 * "anytime the window size changes, center the window"
6076 * because this may well end up fighting the WM or user. In
6077 * fact it gets in an infinite loop with at least one WM.
6079 * Basically, applications are in no way in a position to
6080 * constrain the position of a window, with one exception:
6081 * override redirect windows. (Really the intended purpose
6082 * of CENTER_ALWAYS anyhow, I would think.)
6084 * So the way we implement this "constraint" is to say that when WE
6085 * cause a move or resize, i.e. we make a configure request changing
6086 * window size, we recompute the CENTER_ALWAYS position to reflect
6087 * the new window size, and include it in our request. Also, if we
6088 * just turned on CENTER_ALWAYS we snap to center with a new
6089 * request. Otherwise, if we are just NOTIFIED of a move or resize
6090 * done by someone else e.g. the window manager, we do NOT send a
6091 * new configure request.
6093 * For override redirect windows, this works fine; all window
6094 * sizes are from our configure requests. For managed windows,
6095 * it is at least semi-sane, though who knows what the
6096 * app author is thinking.
6099 /* This condition should be kept in sync with the condition later on
6100 * that determines whether we send a configure request. i.e. we
6101 * should do this position constraining anytime we were going to
6102 * send a configure request anyhow, plus when constraints have
6105 if (configure_request_pos_changed ||
6106 configure_request_size_changed ||
6108 info->position_constraints_changed)
6110 /* We request the constrained position if:
6111 * - we were changing position, and need to clamp
6112 * the change to the constraint
6113 * - we're changing the size anyway
6114 * - set_position() was called to toggle CENTER_ALWAYS on
6117 gtk_window_constrain_position (window,
6123 /* Update whether we need to request a move */
6124 if (info->last.configure_request.x != new_request.x ||
6125 info->last.configure_request.y != new_request.y)
6126 configure_request_pos_changed = TRUE;
6128 configure_request_pos_changed = FALSE;
6132 if (window->type == GTK_WINDOW_TOPLEVEL)
6134 int notify_x, notify_y;
6136 /* this is the position from the last configure notify */
6137 gdk_window_get_position (widget->window, ¬ify_x, ¬ify_y);
6139 g_message ("--- %s ---\n"
6140 "last : %d,%d\t%d x %d\n"
6141 "this : %d,%d\t%d x %d\n"
6142 "alloc : %d,%d\t%d x %d\n"
6144 "resize: \t%d x %d\n"
6145 "size_changed: %d pos_changed: %d hints_changed: %d\n"
6146 "configure_notify_received: %d\n"
6147 "configure_request_count: %d\n"
6148 "position_constraints_changed: %d\n",
6149 window->title ? window->title : "(no title)",
6150 info->last.configure_request.x,
6151 info->last.configure_request.y,
6152 info->last.configure_request.width,
6153 info->last.configure_request.height,
6159 widget->allocation.width,
6160 widget->allocation.height,
6161 widget->requisition.width,
6162 widget->requisition.height,
6164 info->resize_height,
6165 configure_request_pos_changed,
6166 configure_request_size_changed,
6168 window->configure_notify_received,
6169 window->configure_request_count,
6170 info->position_constraints_changed);
6174 saved_last_info = info->last;
6175 info->last.geometry = new_geometry;
6176 info->last.flags = new_flags;
6177 info->last.configure_request = new_request;
6179 /* need to set PPosition so the WM will look at our position,
6180 * but we don't want to count PPosition coming and going as a hints
6181 * change for future iterations. So we saved info->last prior to
6185 /* Also, if the initial position was explicitly set, then we always
6186 * toggle on PPosition. This makes gtk_window_move(window, 0, 0)
6190 /* Also, we toggle on PPosition if GTK_WIN_POS_ is in use and
6191 * this is an initial map
6194 if ((configure_request_pos_changed ||
6195 info->initial_pos_set ||
6196 (window->need_default_position &&
6197 get_effective_position (window) != GTK_WIN_POS_NONE)) &&
6198 (new_flags & GDK_HINT_POS) == 0)
6200 new_flags |= GDK_HINT_POS;
6201 hints_changed = TRUE;
6204 /* Set hints if necessary
6207 gdk_window_set_geometry_hints (widget->window,
6211 /* handle resizing/moving and widget tree allocation
6213 if (window->configure_notify_received)
6215 GtkAllocation allocation;
6217 /* If we have received a configure event since
6218 * the last time in this function, we need to
6219 * accept our new size and size_allocate child widgets.
6220 * (see gtk_window_configure_event() for more details).
6222 * 1 or more configure notifies may have been received.
6223 * Also, configure_notify_received will only be TRUE
6224 * if all expected configure notifies have been received
6225 * (one per configure request), as an optimization.
6228 window->configure_notify_received = FALSE;
6230 /* gtk_window_configure_event() filled in widget->allocation */
6231 allocation = widget->allocation;
6232 gtk_widget_size_allocate (widget, &allocation);
6234 gdk_window_process_updates (widget->window, TRUE);
6236 gdk_window_configure_finished (widget->window);
6238 /* If the configure request changed, it means that
6240 * 1) coincidentally changed hints or widget properties
6241 * impacting the configure request before getting
6242 * a configure notify, or
6243 * 2) some broken widget is changing its size request
6244 * during size allocation, resulting in
6245 * a false appearance of changed configure request.
6247 * For 1), we could just go ahead and ask for the
6248 * new size right now, but doing that for 2)
6249 * might well be fighting the user (and can even
6250 * trigger a loop). Since we really don't want to
6251 * do that, we requeue a resize in hopes that
6252 * by the time it gets handled, the child has seen
6253 * the light and is willing to go along with the
6254 * new size. (this happens for the zvt widget, since
6255 * the size_allocate() above will have stored the
6256 * requisition corresponding to the new size in the
6259 * This doesn't buy us anything for 1), but it shouldn't
6260 * hurt us too badly, since it is what would have
6261 * happened if we had gotten the configure event before
6262 * the new size had been set.
6265 if (configure_request_size_changed ||
6266 configure_request_pos_changed)
6268 /* Don't change the recorded last info after all, because we
6269 * haven't actually updated to the new info yet - we decided
6270 * to postpone our configure request until later.
6272 info->last = saved_last_info;
6274 gtk_widget_queue_resize_no_redraw (widget); /* migth recurse for GTK_RESIZE_IMMEDIATE */
6277 return; /* Bail out, we didn't really process the move/resize */
6279 else if ((configure_request_size_changed || hints_changed) &&
6280 (widget->allocation.width != new_request.width ||
6281 widget->allocation.height != new_request.height))
6284 /* We are in one of the following situations:
6285 * A. configure_request_size_changed
6286 * our requisition has changed and we need a different window size,
6287 * so we request it from the window manager.
6288 * B. !configure_request_size_changed && hints_changed
6289 * the window manager rejects our size, but we have just changed the
6290 * window manager hints, so there's a chance our request will
6291 * be honoured this time, so we try again.
6293 * However, if the new requisition is the same as the current allocation,
6294 * we don't request it again, since we won't get a ConfigureNotify back from
6295 * the window manager unless it decides to change our requisition. If
6296 * we don't get the ConfigureNotify back, the resize queue will never be run.
6299 /* Now send the configure request */
6300 if (configure_request_pos_changed)
6304 gdk_window_move_resize (window->frame,
6305 new_request.x - window->frame_left,
6306 new_request.y - window->frame_top,
6307 new_request.width + window->frame_left + window->frame_right,
6308 new_request.height + window->frame_top + window->frame_bottom);
6309 gdk_window_resize (widget->window,
6310 new_request.width, new_request.height);
6313 gdk_window_move_resize (widget->window,
6314 new_request.x, new_request.y,
6315 new_request.width, new_request.height);
6317 else /* only size changed */
6320 gdk_window_resize (window->frame,
6321 new_request.width + window->frame_left + window->frame_right,
6322 new_request.height + window->frame_top + window->frame_bottom);
6323 gdk_window_resize (widget->window,
6324 new_request.width, new_request.height);
6327 if (window->type == GTK_WINDOW_POPUP)
6329 GtkAllocation allocation;
6331 /* Directly size allocate for override redirect (popup) windows. */
6334 allocation.width = new_request.width;
6335 allocation.height = new_request.height;
6337 gtk_widget_size_allocate (widget, &allocation);
6339 gdk_window_process_updates (widget->window, TRUE);
6341 if (container->resize_mode == GTK_RESIZE_QUEUE)
6342 gtk_widget_queue_draw (widget);
6346 /* Increment the number of have-not-yet-received-notify requests */
6347 window->configure_request_count += 1;
6348 gdk_window_freeze_toplevel_updates_libgtk_only (widget->window);
6350 /* for GTK_RESIZE_QUEUE toplevels, we are now awaiting a new
6351 * configure event in response to our resizing request.
6352 * the configure event will cause a new resize with
6353 * ->configure_notify_received=TRUE.
6354 * until then, we want to
6355 * - discard expose events
6356 * - coalesce resizes for our children
6357 * - defer any window resizes until the configure event arrived
6358 * to achieve this, we queue a resize for the window, but remove its
6359 * resizing handler, so resizing will not be handled from the next
6360 * idle handler but when the configure event arrives.
6362 * FIXME: we should also dequeue the pending redraws here, since
6363 * we handle those ourselves upon ->configure_notify_received==TRUE.
6365 if (container->resize_mode == GTK_RESIZE_QUEUE)
6367 gtk_widget_queue_resize_no_redraw (widget);
6368 _gtk_container_dequeue_resize_handler (container);
6374 /* Handle any position changes.
6376 if (configure_request_pos_changed)
6380 gdk_window_move (window->frame,
6381 new_request.x - window->frame_left,
6382 new_request.y - window->frame_top);
6385 gdk_window_move (widget->window,
6386 new_request.x, new_request.y);
6389 /* And run the resize queue.
6391 gtk_container_resize_children (container);
6394 /* We have now processed a move/resize since the last position
6395 * constraint change, setting of the initial position, or resize.
6396 * (Not resetting these flags here can lead to infinite loops for
6397 * GTK_RESIZE_IMMEDIATE containers)
6399 info->position_constraints_changed = FALSE;
6400 info->initial_pos_set = FALSE;
6401 info->resize_width = -1;
6402 info->resize_height = -1;
6405 /* Compare two sets of Geometry hints for equality.
6408 gtk_window_compare_hints (GdkGeometry *geometry_a,
6410 GdkGeometry *geometry_b,
6413 if (flags_a != flags_b)
6416 if ((flags_a & GDK_HINT_MIN_SIZE) &&
6417 (geometry_a->min_width != geometry_b->min_width ||
6418 geometry_a->min_height != geometry_b->min_height))
6421 if ((flags_a & GDK_HINT_MAX_SIZE) &&
6422 (geometry_a->max_width != geometry_b->max_width ||
6423 geometry_a->max_height != geometry_b->max_height))
6426 if ((flags_a & GDK_HINT_BASE_SIZE) &&
6427 (geometry_a->base_width != geometry_b->base_width ||
6428 geometry_a->base_height != geometry_b->base_height))
6431 if ((flags_a & GDK_HINT_ASPECT) &&
6432 (geometry_a->min_aspect != geometry_b->min_aspect ||
6433 geometry_a->max_aspect != geometry_b->max_aspect))
6436 if ((flags_a & GDK_HINT_RESIZE_INC) &&
6437 (geometry_a->width_inc != geometry_b->width_inc ||
6438 geometry_a->height_inc != geometry_b->height_inc))
6441 if ((flags_a & GDK_HINT_WIN_GRAVITY) &&
6442 geometry_a->win_gravity != geometry_b->win_gravity)
6449 _gtk_window_constrain_size (GtkWindow *window,
6455 GtkWindowGeometryInfo *info;
6457 g_return_if_fail (GTK_IS_WINDOW (window));
6459 info = window->geometry_info;
6462 GdkWindowHints flags = info->last.flags;
6463 GdkGeometry *geometry = &info->last.geometry;
6465 gtk_window_constrain_size (window,
6476 gtk_window_constrain_size (GtkWindow *window,
6477 GdkGeometry *geometry,
6484 gdk_window_constrain_size (geometry, flags, width, height,
6485 new_width, new_height);
6488 /* Compute the set of geometry hints and flags for a window
6489 * based on the application set geometry, and requisiition
6490 * of the window. gtk_widget_size_request() must have been
6494 gtk_window_compute_hints (GtkWindow *window,
6495 GdkGeometry *new_geometry,
6499 gint extra_width = 0;
6500 gint extra_height = 0;
6501 GtkWindowGeometryInfo *geometry_info;
6502 GtkRequisition requisition;
6504 widget = GTK_WIDGET (window);
6506 gtk_widget_get_child_requisition (widget, &requisition);
6507 geometry_info = gtk_window_get_geometry_info (GTK_WINDOW (widget), FALSE);
6511 *new_flags = geometry_info->mask;
6512 *new_geometry = geometry_info->geometry;
6519 if (geometry_info && geometry_info->widget)
6521 GtkRequisition child_requisition;
6523 /* FIXME: This really isn't right. It gets the min size wrong and forces
6524 * callers to do horrible hacks like set a huge usize on the child requisition
6525 * to get the base size right. We really want to find the answers to:
6527 * - If the geometry widget was infinitely big, how much extra space
6528 * would be needed for the stuff around it.
6530 * - If the geometry widget was infinitely small, how big would the
6531 * window still have to be.
6533 * Finding these answers would be a bit of a mess here. (Bug #68668)
6535 gtk_widget_get_child_requisition (geometry_info->widget, &child_requisition);
6537 extra_width = widget->requisition.width - child_requisition.width;
6538 extra_height = widget->requisition.height - child_requisition.height;
6541 /* We don't want to set GDK_HINT_POS in here, we just set it
6542 * in gtk_window_move_resize() when we want the position
6546 if (*new_flags & GDK_HINT_BASE_SIZE)
6548 new_geometry->base_width += extra_width;
6549 new_geometry->base_height += extra_height;
6551 else if (!(*new_flags & GDK_HINT_MIN_SIZE) &&
6552 (*new_flags & GDK_HINT_RESIZE_INC) &&
6553 ((extra_width != 0) || (extra_height != 0)))
6555 *new_flags |= GDK_HINT_BASE_SIZE;
6557 new_geometry->base_width = extra_width;
6558 new_geometry->base_height = extra_height;
6561 if (*new_flags & GDK_HINT_MIN_SIZE)
6563 if (new_geometry->min_width < 0)
6564 new_geometry->min_width = requisition.width;
6566 new_geometry->min_width += extra_width;
6568 if (new_geometry->min_height < 0)
6569 new_geometry->min_height = requisition.height;
6571 new_geometry->min_height += extra_height;
6573 else if (!window->allow_shrink)
6575 *new_flags |= GDK_HINT_MIN_SIZE;
6577 new_geometry->min_width = requisition.width;
6578 new_geometry->min_height = requisition.height;
6581 if (*new_flags & GDK_HINT_MAX_SIZE)
6583 if (new_geometry->max_width < 0)
6584 new_geometry->max_width = requisition.width;
6586 new_geometry->max_width += extra_width;
6588 if (new_geometry->max_height < 0)
6589 new_geometry->max_height = requisition.height;
6591 new_geometry->max_height += extra_height;
6593 else if (!window->allow_grow)
6595 *new_flags |= GDK_HINT_MAX_SIZE;
6597 new_geometry->max_width = requisition.width;
6598 new_geometry->max_height = requisition.height;
6601 *new_flags |= GDK_HINT_WIN_GRAVITY;
6602 new_geometry->win_gravity = window->gravity;
6605 /***********************
6606 * Redrawing functions *
6607 ***********************/
6610 gtk_window_paint (GtkWidget *widget,
6613 gtk_paint_flat_box (widget->style, widget->window, GTK_STATE_NORMAL,
6614 GTK_SHADOW_NONE, area, widget, "base", 0, 0, -1, -1);
6618 gtk_window_expose (GtkWidget *widget,
6619 GdkEventExpose *event)
6621 if (!gtk_widget_get_app_paintable (widget))
6622 gtk_window_paint (widget, &event->area);
6624 if (GTK_WIDGET_CLASS (gtk_window_parent_class)->expose_event)
6625 return GTK_WIDGET_CLASS (gtk_window_parent_class)->expose_event (widget, event);
6631 * gtk_window_set_has_frame:
6632 * @window: a #GtkWindow
6633 * @setting: a boolean
6635 * (Note: this is a special-purpose function for the framebuffer port,
6636 * that causes GTK+ to draw its own window border. For most applications,
6637 * you want gtk_window_set_decorated() instead, which tells the window
6638 * manager whether to draw the window border.)
6640 * If this function is called on a window with setting of %TRUE, before
6641 * it is realized or showed, it will have a "frame" window around
6642 * @window->window, accessible in @window->frame. Using the signal
6643 * frame_event you can receive all events targeted at the frame.
6645 * This function is used by the linux-fb port to implement managed
6646 * windows, but it could conceivably be used by X-programs that
6647 * want to do their own window decorations.
6651 gtk_window_set_has_frame (GtkWindow *window,
6654 g_return_if_fail (GTK_IS_WINDOW (window));
6655 g_return_if_fail (!GTK_WIDGET_REALIZED (window));
6657 window->has_frame = setting != FALSE;
6661 * gtk_window_get_has_frame:
6662 * @window: a #GtkWindow
6664 * Accessor for whether the window has a frame window exterior to
6665 * @window->window. Gets the value set by gtk_window_set_has_frame ().
6667 * Return value: %TRUE if a frame has been added to the window
6668 * via gtk_window_set_has_frame().
6671 gtk_window_get_has_frame (GtkWindow *window)
6673 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
6675 return window->has_frame;
6679 * gtk_window_set_frame_dimensions:
6680 * @window: a #GtkWindow that has a frame
6681 * @left: The width of the left border
6682 * @top: The height of the top border
6683 * @right: The width of the right border
6684 * @bottom: The height of the bottom border
6686 * (Note: this is a special-purpose function intended for the framebuffer
6687 * port; see gtk_window_set_has_frame(). It will have no effect on the
6688 * window border drawn by the window manager, which is the normal
6689 * case when using the X Window system.)
6691 * For windows with frames (see gtk_window_set_has_frame()) this function
6692 * can be used to change the size of the frame border.
6695 gtk_window_set_frame_dimensions (GtkWindow *window,
6703 g_return_if_fail (GTK_IS_WINDOW (window));
6705 widget = GTK_WIDGET (window);
6707 if (window->frame_left == left &&
6708 window->frame_top == top &&
6709 window->frame_right == right &&
6710 window->frame_bottom == bottom)
6713 window->frame_left = left;
6714 window->frame_top = top;
6715 window->frame_right = right;
6716 window->frame_bottom = bottom;
6718 if (GTK_WIDGET_REALIZED (widget) && window->frame)
6720 gint width = widget->allocation.width + left + right;
6721 gint height = widget->allocation.height + top + bottom;
6722 gdk_window_resize (window->frame, width, height);
6723 gtk_decorated_window_move_resize_window (window,
6725 widget->allocation.width,
6726 widget->allocation.height);
6731 * gtk_window_present:
6732 * @window: a #GtkWindow
6734 * Presents a window to the user. This may mean raising the window
6735 * in the stacking order, deiconifying it, moving it to the current
6736 * desktop, and/or giving it the keyboard focus, possibly dependent
6737 * on the user's platform, window manager, and preferences.
6739 * If @window is hidden, this function calls gtk_widget_show()
6742 * This function should be used when the user tries to open a window
6743 * that's already open. Say for example the preferences dialog is
6744 * currently open, and the user chooses Preferences from the menu
6745 * a second time; use gtk_window_present() to move the already-open dialog
6746 * where the user can see it.
6748 * If you are calling this function in response to a user interaction,
6749 * it is preferable to use gtk_window_present_with_time().
6753 gtk_window_present (GtkWindow *window)
6755 gtk_window_present_with_time (window, GDK_CURRENT_TIME);
6759 * gtk_window_present_with_time:
6760 * @window: a #GtkWindow
6761 * @timestamp: the timestamp of the user interaction (typically a
6762 * button or key press event) which triggered this call
6764 * Presents a window to the user in response to a user interaction.
6765 * If you need to present a window without a timestamp, use
6766 * gtk_window_present(). See gtk_window_present() for details.
6771 gtk_window_present_with_time (GtkWindow *window,
6776 g_return_if_fail (GTK_IS_WINDOW (window));
6778 widget = GTK_WIDGET (window);
6780 if (gtk_widget_get_visible (widget))
6782 g_assert (widget->window != NULL);
6784 gdk_window_show (widget->window);
6786 /* Translate a timestamp of GDK_CURRENT_TIME appropriately */
6787 if (timestamp == GDK_CURRENT_TIME)
6789 #ifdef GDK_WINDOWING_X11
6790 GdkDisplay *display;
6792 display = gtk_widget_get_display (GTK_WIDGET (window));
6793 timestamp = gdk_x11_display_get_user_time (display);
6795 timestamp = gtk_get_current_event_time ();
6799 gdk_window_focus (widget->window, timestamp);
6803 gtk_widget_show (widget);
6808 * gtk_window_iconify:
6809 * @window: a #GtkWindow
6811 * Asks to iconify (i.e. minimize) the specified @window. Note that
6812 * you shouldn't assume the window is definitely iconified afterward,
6813 * because other entities (e.g. the user or <link
6814 * linkend="gtk-X11-arch">window manager</link>) could deiconify it
6815 * again, or there may not be a window manager in which case
6816 * iconification isn't possible, etc. But normally the window will end
6817 * up iconified. Just don't write code that crashes if not.
6819 * It's permitted to call this function before showing a window,
6820 * in which case the window will be iconified before it ever appears
6823 * You can track iconification via the "window-state-event" signal
6828 gtk_window_iconify (GtkWindow *window)
6831 GdkWindow *toplevel;
6833 g_return_if_fail (GTK_IS_WINDOW (window));
6835 widget = GTK_WIDGET (window);
6837 window->iconify_initially = TRUE;
6840 toplevel = window->frame;
6842 toplevel = widget->window;
6844 if (toplevel != NULL)
6845 gdk_window_iconify (toplevel);
6849 * gtk_window_deiconify:
6850 * @window: a #GtkWindow
6852 * Asks to deiconify (i.e. unminimize) the specified @window. Note
6853 * that you shouldn't assume the window is definitely deiconified
6854 * afterward, because other entities (e.g. the user or <link
6855 * linkend="gtk-X11-arch">window manager</link>) could iconify it
6856 * again before your code which assumes deiconification gets to run.
6858 * You can track iconification via the "window-state-event" signal
6862 gtk_window_deiconify (GtkWindow *window)
6865 GdkWindow *toplevel;
6867 g_return_if_fail (GTK_IS_WINDOW (window));
6869 widget = GTK_WIDGET (window);
6871 window->iconify_initially = FALSE;
6874 toplevel = window->frame;
6876 toplevel = widget->window;
6878 if (toplevel != NULL)
6879 gdk_window_deiconify (toplevel);
6884 * @window: a #GtkWindow
6886 * Asks to stick @window, which means that it will appear on all user
6887 * desktops. Note that you shouldn't assume the window is definitely
6888 * stuck afterward, because other entities (e.g. the user or <link
6889 * linkend="gtk-X11-arch">window manager</link>) could unstick it
6890 * again, and some window managers do not support sticking
6891 * windows. But normally the window will end up stuck. Just don't
6892 * write code that crashes if not.
6894 * It's permitted to call this function before showing a window.
6896 * You can track stickiness via the "window-state-event" signal
6901 gtk_window_stick (GtkWindow *window)
6904 GdkWindow *toplevel;
6906 g_return_if_fail (GTK_IS_WINDOW (window));
6908 widget = GTK_WIDGET (window);
6910 window->stick_initially = TRUE;
6913 toplevel = window->frame;
6915 toplevel = widget->window;
6917 if (toplevel != NULL)
6918 gdk_window_stick (toplevel);
6922 * gtk_window_unstick:
6923 * @window: a #GtkWindow
6925 * Asks to unstick @window, which means that it will appear on only
6926 * one of the user's desktops. Note that you shouldn't assume the
6927 * window is definitely unstuck afterward, because other entities
6928 * (e.g. the user or <link linkend="gtk-X11-arch">window
6929 * manager</link>) could stick it again. But normally the window will
6930 * end up stuck. Just don't write code that crashes if not.
6932 * You can track stickiness via the "window-state-event" signal
6937 gtk_window_unstick (GtkWindow *window)
6940 GdkWindow *toplevel;
6942 g_return_if_fail (GTK_IS_WINDOW (window));
6944 widget = GTK_WIDGET (window);
6946 window->stick_initially = FALSE;
6949 toplevel = window->frame;
6951 toplevel = widget->window;
6953 if (toplevel != NULL)
6954 gdk_window_unstick (toplevel);
6958 * gtk_window_maximize:
6959 * @window: a #GtkWindow
6961 * Asks to maximize @window, so that it becomes full-screen. Note that
6962 * you shouldn't assume the window is definitely maximized afterward,
6963 * because other entities (e.g. the user or <link
6964 * linkend="gtk-X11-arch">window manager</link>) could unmaximize it
6965 * again, and not all window managers support maximization. But
6966 * normally the window will end up maximized. Just don't write code
6967 * that crashes if not.
6969 * It's permitted to call this function before showing a window,
6970 * in which case the window will be maximized when it appears onscreen
6973 * You can track maximization via the "window-state-event" signal
6978 gtk_window_maximize (GtkWindow *window)
6981 GdkWindow *toplevel;
6983 g_return_if_fail (GTK_IS_WINDOW (window));
6985 widget = GTK_WIDGET (window);
6987 window->maximize_initially = TRUE;
6990 toplevel = window->frame;
6992 toplevel = widget->window;
6994 if (toplevel != NULL)
6995 gdk_window_maximize (toplevel);
6999 * gtk_window_unmaximize:
7000 * @window: a #GtkWindow
7002 * Asks to unmaximize @window. Note that you shouldn't assume the
7003 * window is definitely unmaximized afterward, because other entities
7004 * (e.g. the user or <link linkend="gtk-X11-arch">window
7005 * manager</link>) could maximize it again, and not all window
7006 * managers honor requests to unmaximize. But normally the window will
7007 * end up unmaximized. Just don't write code that crashes if not.
7009 * You can track maximization via the "window-state-event" signal
7014 gtk_window_unmaximize (GtkWindow *window)
7017 GdkWindow *toplevel;
7019 g_return_if_fail (GTK_IS_WINDOW (window));
7021 widget = GTK_WIDGET (window);
7023 window->maximize_initially = FALSE;
7026 toplevel = window->frame;
7028 toplevel = widget->window;
7030 if (toplevel != NULL)
7031 gdk_window_unmaximize (toplevel);
7035 * gtk_window_fullscreen:
7036 * @window: a #GtkWindow
7038 * Asks to place @window in the fullscreen state. Note that you
7039 * shouldn't assume the window is definitely full screen afterward,
7040 * because other entities (e.g. the user or <link
7041 * linkend="gtk-X11-arch">window manager</link>) could unfullscreen it
7042 * again, and not all window managers honor requests to fullscreen
7043 * windows. But normally the window will end up fullscreen. Just
7044 * don't write code that crashes if not.
7046 * You can track the fullscreen state via the "window-state-event" signal
7052 gtk_window_fullscreen (GtkWindow *window)
7055 GdkWindow *toplevel;
7056 GtkWindowPrivate *priv;
7058 g_return_if_fail (GTK_IS_WINDOW (window));
7060 widget = GTK_WIDGET (window);
7061 priv = GTK_WINDOW_GET_PRIVATE (window);
7063 priv->fullscreen_initially = TRUE;
7066 toplevel = window->frame;
7068 toplevel = widget->window;
7070 if (toplevel != NULL)
7071 gdk_window_fullscreen (toplevel);
7075 * gtk_window_unfullscreen:
7076 * @window: a #GtkWindow
7078 * Asks to toggle off the fullscreen state for @window. Note that you
7079 * shouldn't assume the window is definitely not full screen
7080 * afterward, because other entities (e.g. the user or <link
7081 * linkend="gtk-X11-arch">window manager</link>) could fullscreen it
7082 * again, and not all window managers honor requests to unfullscreen
7083 * windows. But normally the window will end up restored to its normal
7084 * state. Just don't write code that crashes if not.
7086 * You can track the fullscreen state via the "window-state-event" signal
7092 gtk_window_unfullscreen (GtkWindow *window)
7095 GdkWindow *toplevel;
7096 GtkWindowPrivate *priv;
7098 g_return_if_fail (GTK_IS_WINDOW (window));
7100 widget = GTK_WIDGET (window);
7101 priv = GTK_WINDOW_GET_PRIVATE (window);
7103 priv->fullscreen_initially = FALSE;
7106 toplevel = window->frame;
7108 toplevel = widget->window;
7110 if (toplevel != NULL)
7111 gdk_window_unfullscreen (toplevel);
7115 * gtk_window_set_keep_above:
7116 * @window: a #GtkWindow
7117 * @setting: whether to keep @window above other windows
7119 * Asks to keep @window above, so that it stays on top. Note that
7120 * you shouldn't assume the window is definitely above afterward,
7121 * because other entities (e.g. the user or <link
7122 * linkend="gtk-X11-arch">window manager</link>) could not keep it above,
7123 * and not all window managers support keeping windows above. But
7124 * normally the window will end kept above. Just don't write code
7125 * that crashes if not.
7127 * It's permitted to call this function before showing a window,
7128 * in which case the window will be kept above when it appears onscreen
7131 * You can track the above state via the "window-state-event" signal
7134 * Note that, according to the <ulink
7135 * url="http://www.freedesktop.org/Standards/wm-spec">Extended Window
7136 * Manager Hints</ulink> specification, the above state is mainly meant
7137 * for user preferences and should not be used by applications e.g. for
7138 * drawing attention to their dialogs.
7143 gtk_window_set_keep_above (GtkWindow *window,
7147 GtkWindowPrivate *priv;
7148 GdkWindow *toplevel;
7150 g_return_if_fail (GTK_IS_WINDOW (window));
7152 widget = GTK_WIDGET (window);
7153 priv = GTK_WINDOW_GET_PRIVATE (window);
7155 priv->above_initially = setting != FALSE;
7157 priv->below_initially = FALSE;
7160 toplevel = window->frame;
7162 toplevel = widget->window;
7164 if (toplevel != NULL)
7165 gdk_window_set_keep_above (toplevel, setting);
7169 * gtk_window_set_keep_below:
7170 * @window: a #GtkWindow
7171 * @setting: whether to keep @window below other windows
7173 * Asks to keep @window below, so that it stays in bottom. Note that
7174 * you shouldn't assume the window is definitely below afterward,
7175 * because other entities (e.g. the user or <link
7176 * linkend="gtk-X11-arch">window manager</link>) could not keep it below,
7177 * and not all window managers support putting windows below. But
7178 * normally the window will be kept below. Just don't write code
7179 * that crashes if not.
7181 * It's permitted to call this function before showing a window,
7182 * in which case the window will be kept below when it appears onscreen
7185 * You can track the below state via the "window-state-event" signal
7188 * Note that, according to the <ulink
7189 * url="http://www.freedesktop.org/Standards/wm-spec">Extended Window
7190 * Manager Hints</ulink> specification, the above state is mainly meant
7191 * for user preferences and should not be used by applications e.g. for
7192 * drawing attention to their dialogs.
7197 gtk_window_set_keep_below (GtkWindow *window,
7201 GtkWindowPrivate *priv;
7202 GdkWindow *toplevel;
7204 g_return_if_fail (GTK_IS_WINDOW (window));
7206 widget = GTK_WIDGET (window);
7207 priv = GTK_WINDOW_GET_PRIVATE (window);
7209 priv->below_initially = setting != FALSE;
7211 priv->above_initially = FALSE;
7214 toplevel = window->frame;
7216 toplevel = widget->window;
7218 if (toplevel != NULL)
7219 gdk_window_set_keep_below (toplevel, setting);
7223 * gtk_window_set_resizable:
7224 * @window: a #GtkWindow
7225 * @resizable: %TRUE if the user can resize this window
7227 * Sets whether the user can resize a window. Windows are user resizable
7231 gtk_window_set_resizable (GtkWindow *window,
7234 g_return_if_fail (GTK_IS_WINDOW (window));
7236 gtk_window_set_policy_internal (window, FALSE, resizable, FALSE);
7240 * gtk_window_get_resizable:
7241 * @window: a #GtkWindow
7243 * Gets the value set by gtk_window_set_resizable().
7245 * Return value: %TRUE if the user can resize the window
7248 gtk_window_get_resizable (GtkWindow *window)
7250 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
7252 /* allow_grow is most likely to indicate the semantic concept we
7253 * mean by "resizable" (and will be a reliable indicator if
7254 * set_policy() hasn't been called)
7256 return window->allow_grow;
7260 * gtk_window_set_gravity:
7261 * @window: a #GtkWindow
7262 * @gravity: window gravity
7264 * Window gravity defines the meaning of coordinates passed to
7265 * gtk_window_move(). See gtk_window_move() and #GdkGravity for
7268 * The default window gravity is #GDK_GRAVITY_NORTH_WEST which will
7269 * typically "do what you mean."
7273 gtk_window_set_gravity (GtkWindow *window,
7276 g_return_if_fail (GTK_IS_WINDOW (window));
7278 if (gravity != window->gravity)
7280 window->gravity = gravity;
7282 /* gtk_window_move_resize() will adapt gravity
7284 gtk_widget_queue_resize_no_redraw (GTK_WIDGET (window));
7286 g_object_notify (G_OBJECT (window), "gravity");
7291 * gtk_window_get_gravity:
7292 * @window: a #GtkWindow
7294 * Gets the value set by gtk_window_set_gravity().
7296 * Return value: (transfer none): window gravity
7299 gtk_window_get_gravity (GtkWindow *window)
7301 g_return_val_if_fail (GTK_IS_WINDOW (window), 0);
7303 return window->gravity;
7307 * gtk_window_begin_resize_drag:
7308 * @window: a #GtkWindow
7309 * @button: mouse button that initiated the drag
7310 * @edge: position of the resize control
7311 * @root_x: X position where the user clicked to initiate the drag, in root window coordinates
7312 * @root_y: Y position where the user clicked to initiate the drag
7313 * @timestamp: timestamp from the click event that initiated the drag
7315 * Starts resizing a window. This function is used if an application
7316 * has window resizing controls. When GDK can support it, the resize
7317 * will be done using the standard mechanism for the <link
7318 * linkend="gtk-X11-arch">window manager</link> or windowing
7319 * system. Otherwise, GDK will try to emulate window resizing,
7320 * potentially not all that well, depending on the windowing system.
7324 gtk_window_begin_resize_drag (GtkWindow *window,
7332 GdkWindow *toplevel;
7334 g_return_if_fail (GTK_IS_WINDOW (window));
7335 widget = GTK_WIDGET (window);
7336 g_return_if_fail (gtk_widget_get_visible (widget));
7339 toplevel = window->frame;
7341 toplevel = widget->window;
7343 gdk_window_begin_resize_drag (toplevel,
7350 * gtk_window_get_frame_dimensions:
7351 * @window: a #GtkWindow
7352 * @left: (allow-none): location to store the width of the frame at the left, or %NULL
7353 * @top: (allow-none): location to store the height of the frame at the top, or %NULL
7354 * @right: (allow-none): location to store the width of the frame at the returns, or %NULL
7355 * @bottom: (allow-none): location to store the height of the frame at the bottom, or %NULL
7357 * (Note: this is a special-purpose function intended for the
7358 * framebuffer port; see gtk_window_set_has_frame(). It will not
7359 * return the size of the window border drawn by the <link
7360 * linkend="gtk-X11-arch">window manager</link>, which is the normal
7361 * case when using a windowing system. See
7362 * gdk_window_get_frame_extents() to get the standard window border
7365 * Retrieves the dimensions of the frame window for this toplevel.
7366 * See gtk_window_set_has_frame(), gtk_window_set_frame_dimensions().
7369 gtk_window_get_frame_dimensions (GtkWindow *window,
7375 g_return_if_fail (GTK_IS_WINDOW (window));
7378 *left = window->frame_left;
7380 *top = window->frame_top;
7382 *right = window->frame_right;
7384 *bottom = window->frame_bottom;
7388 * gtk_window_begin_move_drag:
7389 * @window: a #GtkWindow
7390 * @button: mouse button that initiated the drag
7391 * @root_x: X position where the user clicked to initiate the drag, in root window coordinates
7392 * @root_y: Y position where the user clicked to initiate the drag
7393 * @timestamp: timestamp from the click event that initiated the drag
7395 * Starts moving a window. This function is used if an application has
7396 * window movement grips. When GDK can support it, the window movement
7397 * will be done using the standard mechanism for the <link
7398 * linkend="gtk-X11-arch">window manager</link> or windowing
7399 * system. Otherwise, GDK will try to emulate window movement,
7400 * potentially not all that well, depending on the windowing system.
7404 gtk_window_begin_move_drag (GtkWindow *window,
7411 GdkWindow *toplevel;
7413 g_return_if_fail (GTK_IS_WINDOW (window));
7414 widget = GTK_WIDGET (window);
7415 g_return_if_fail (gtk_widget_get_visible (widget));
7418 toplevel = window->frame;
7420 toplevel = widget->window;
7422 gdk_window_begin_move_drag (toplevel,
7429 * gtk_window_set_screen:
7430 * @window: a #GtkWindow.
7431 * @screen: a #GdkScreen.
7433 * Sets the #GdkScreen where the @window is displayed; if
7434 * the window is already mapped, it will be unmapped, and
7435 * then remapped on the new screen.
7440 gtk_window_set_screen (GtkWindow *window,
7444 GdkScreen *previous_screen;
7445 gboolean was_mapped;
7447 g_return_if_fail (GTK_IS_WINDOW (window));
7448 g_return_if_fail (GDK_IS_SCREEN (screen));
7450 if (screen == window->screen)
7453 widget = GTK_WIDGET (window);
7455 previous_screen = window->screen;
7456 was_mapped = GTK_WIDGET_MAPPED (widget);
7459 gtk_widget_unmap (widget);
7460 if (GTK_WIDGET_REALIZED (widget))
7461 gtk_widget_unrealize (widget);
7463 gtk_window_free_key_hash (window);
7464 window->screen = screen;
7465 gtk_widget_reset_rc_styles (widget);
7466 if (screen != previous_screen)
7468 g_signal_handlers_disconnect_by_func (previous_screen,
7469 gtk_window_on_composited_changed, window);
7470 g_signal_connect (screen, "composited-changed",
7471 G_CALLBACK (gtk_window_on_composited_changed), window);
7473 _gtk_widget_propagate_screen_changed (widget, previous_screen);
7474 _gtk_widget_propagate_composited_changed (widget);
7476 g_object_notify (G_OBJECT (window), "screen");
7479 gtk_widget_map (widget);
7483 gtk_window_on_composited_changed (GdkScreen *screen,
7486 gtk_widget_queue_draw (GTK_WIDGET (window));
7488 _gtk_widget_propagate_composited_changed (GTK_WIDGET (window));
7492 gtk_window_check_screen (GtkWindow *window)
7495 return window->screen;
7498 g_warning ("Screen for GtkWindow not set; you must always set\n"
7499 "a screen for a GtkWindow before using the window");
7505 * gtk_window_get_screen:
7506 * @window: a #GtkWindow.
7508 * Returns the #GdkScreen associated with @window.
7510 * Return value: (transfer none): a #GdkScreen.
7515 gtk_window_get_screen (GtkWindow *window)
7517 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
7519 return window->screen;
7523 * gtk_window_is_active:
7524 * @window: a #GtkWindow
7526 * Returns whether the window is part of the current active toplevel.
7527 * (That is, the toplevel window receiving keystrokes.)
7528 * The return value is %TRUE if the window is active toplevel
7529 * itself, but also if it is, say, a #GtkPlug embedded in the active toplevel.
7530 * You might use this function if you wanted to draw a widget
7531 * differently in an active window from a widget in an inactive window.
7532 * See gtk_window_has_toplevel_focus()
7534 * Return value: %TRUE if the window part of the current active window.
7539 gtk_window_is_active (GtkWindow *window)
7541 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
7543 return window->is_active;
7547 * gtk_window_has_toplevel_focus:
7548 * @window: a #GtkWindow
7550 * Returns whether the input focus is within this GtkWindow.
7551 * For real toplevel windows, this is identical to gtk_window_is_active(),
7552 * but for embedded windows, like #GtkPlug, the results will differ.
7554 * Return value: %TRUE if the input focus is within this GtkWindow
7559 gtk_window_has_toplevel_focus (GtkWindow *window)
7561 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
7563 return window->has_toplevel_focus;
7567 gtk_window_group_class_init (GtkWindowGroupClass *klass)
7572 gtk_window_group_get_type (void)
7574 static GType window_group_type = 0;
7576 if (!window_group_type)
7578 const GTypeInfo window_group_info =
7580 sizeof (GtkWindowGroupClass),
7581 NULL, /* base_init */
7582 NULL, /* base_finalize */
7583 (GClassInitFunc) gtk_window_group_class_init,
7584 NULL, /* class_finalize */
7585 NULL, /* class_data */
7586 sizeof (GtkWindowGroup),
7587 0, /* n_preallocs */
7588 (GInstanceInitFunc) NULL,
7591 window_group_type = g_type_register_static (G_TYPE_OBJECT, I_("GtkWindowGroup"),
7592 &window_group_info, 0);
7595 return window_group_type;
7599 * gtk_window_group_new:
7601 * Creates a new #GtkWindowGroup object. Grabs added with
7602 * gtk_grab_add() only affect windows within the same #GtkWindowGroup.
7604 * Return value: a new #GtkWindowGroup.
7607 gtk_window_group_new (void)
7609 return g_object_new (GTK_TYPE_WINDOW_GROUP, NULL);
7613 window_group_cleanup_grabs (GtkWindowGroup *group,
7617 GSList *to_remove = NULL;
7619 tmp_list = group->grabs;
7622 if (gtk_widget_get_toplevel (tmp_list->data) == (GtkWidget*) window)
7623 to_remove = g_slist_prepend (to_remove, g_object_ref (tmp_list->data));
7624 tmp_list = tmp_list->next;
7629 gtk_grab_remove (to_remove->data);
7630 g_object_unref (to_remove->data);
7631 to_remove = g_slist_delete_link (to_remove, to_remove);
7636 * gtk_window_group_add_window:
7637 * @window_group: a #GtkWindowGroup
7638 * @window: the #GtkWindow to add
7640 * Adds a window to a #GtkWindowGroup.
7643 gtk_window_group_add_window (GtkWindowGroup *window_group,
7646 g_return_if_fail (GTK_IS_WINDOW_GROUP (window_group));
7647 g_return_if_fail (GTK_IS_WINDOW (window));
7649 if (window->group != window_group)
7651 g_object_ref (window);
7652 g_object_ref (window_group);
7655 gtk_window_group_remove_window (window->group, window);
7657 window_group_cleanup_grabs (gtk_window_get_group (NULL), window);
7659 window->group = window_group;
7661 g_object_unref (window);
7666 * gtk_window_group_remove_window:
7667 * @window_group: a #GtkWindowGroup
7668 * @window: the #GtkWindow to remove
7670 * Removes a window from a #GtkWindowGroup.
7673 gtk_window_group_remove_window (GtkWindowGroup *window_group,
7676 g_return_if_fail (GTK_IS_WINDOW_GROUP (window_group));
7677 g_return_if_fail (GTK_IS_WINDOW (window));
7678 g_return_if_fail (window->group == window_group);
7680 g_object_ref (window);
7682 window_group_cleanup_grabs (window_group, window);
7683 window->group = NULL;
7685 g_object_unref (window_group);
7686 g_object_unref (window);
7690 * gtk_window_group_list_windows:
7691 * @window_group: a #GtkWindowGroup
7693 * Returns a list of the #GtkWindows that belong to @window_group.
7695 * Returns: (element-type GtkWidget) (transfer container): A newly-allocated list of
7696 * windows inside the group.
7701 gtk_window_group_list_windows (GtkWindowGroup *window_group)
7703 GList *toplevels, *toplevel, *group_windows;
7705 g_return_val_if_fail (GTK_IS_WINDOW_GROUP (window_group), NULL);
7707 group_windows = NULL;
7708 toplevels = gtk_window_list_toplevels ();
7710 for (toplevel = toplevels; toplevel; toplevel = toplevel->next)
7712 GtkWindow *window = toplevel->data;
7714 if (window_group == window->group)
7715 group_windows = g_list_prepend (group_windows, window);
7718 return g_list_reverse (group_windows);
7722 * gtk_window_get_group:
7723 * @window: (allow-none): a #GtkWindow, or %NULL
7725 * Returns the group for @window or the default group, if
7726 * @window is %NULL or if @window does not have an explicit
7729 * Returns: (transfer none): the #GtkWindowGroup for a window or the default group
7734 gtk_window_get_group (GtkWindow *window)
7736 if (window && window->group)
7737 return window->group;
7740 static GtkWindowGroup *default_group = NULL;
7743 default_group = gtk_window_group_new ();
7745 return default_group;
7749 /* Return the current grab widget of the given group
7752 _gtk_window_group_get_current_grab (GtkWindowGroup *window_group)
7754 if (window_group->grabs)
7755 return GTK_WIDGET (window_group->grabs->data);
7760 Derived from XParseGeometry() in XFree86
7762 Copyright 1985, 1986, 1987,1998 The Open Group
7764 All Rights Reserved.
7766 The above copyright notice and this permission notice shall be included
7767 in all copies or substantial portions of the Software.
7769 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
7770 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
7771 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
7772 IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
7773 OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
7774 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
7775 OTHER DEALINGS IN THE SOFTWARE.
7777 Except as contained in this notice, the name of The Open Group shall
7778 not be used in advertising or otherwise to promote the sale, use or
7779 other dealings in this Software without prior written authorization
7780 from The Open Group.
7785 * XParseGeometry parses strings of the form
7786 * "=<width>x<height>{+-}<xoffset>{+-}<yoffset>", where
7787 * width, height, xoffset, and yoffset are unsigned integers.
7788 * Example: "=80x24+300-49"
7789 * The equal sign is optional.
7790 * It returns a bitmask that indicates which of the four values
7791 * were actually found in the string. For each value found,
7792 * the corresponding argument is updated; for each value
7793 * not found, the corresponding argument is left unchanged.
7796 /* The following code is from Xlib, and is minimally modified, so we
7797 * can track any upstream changes if required. Don't change this
7798 * code. Or if you do, put in a huge comment marking which thing
7803 read_int (gchar *string,
7811 else if (*string == '-')
7817 for (; (*string >= '0') && (*string <= '9'); string++)
7819 result = (result * 10) + (*string - '0');
7831 * Bitmask returned by XParseGeometry(). Each bit tells if the corresponding
7832 * value (x, y, width, height) was found in the parsed string.
7834 #define NoValue 0x0000
7835 #define XValue 0x0001
7836 #define YValue 0x0002
7837 #define WidthValue 0x0004
7838 #define HeightValue 0x0008
7839 #define AllValues 0x000F
7840 #define XNegative 0x0010
7841 #define YNegative 0x0020
7843 /* Try not to reformat/modify, so we can compare/sync with X sources */
7845 gtk_XParseGeometry (const char *string,
7848 unsigned int *width,
7849 unsigned int *height)
7853 unsigned int tempWidth, tempHeight;
7855 char *nextCharacter;
7857 /* These initializations are just to silence gcc */
7863 if ( (string == NULL) || (*string == '\0')) return(mask);
7865 string++; /* ignore possible '=' at beg of geometry spec */
7867 strind = (char *)string;
7868 if (*strind != '+' && *strind != '-' && *strind != 'x') {
7869 tempWidth = read_int(strind, &nextCharacter);
7870 if (strind == nextCharacter)
7872 strind = nextCharacter;
7876 if (*strind == 'x' || *strind == 'X') {
7878 tempHeight = read_int(strind, &nextCharacter);
7879 if (strind == nextCharacter)
7881 strind = nextCharacter;
7882 mask |= HeightValue;
7885 if ((*strind == '+') || (*strind == '-')) {
7886 if (*strind == '-') {
7888 tempX = -read_int(strind, &nextCharacter);
7889 if (strind == nextCharacter)
7891 strind = nextCharacter;
7897 tempX = read_int(strind, &nextCharacter);
7898 if (strind == nextCharacter)
7900 strind = nextCharacter;
7903 if ((*strind == '+') || (*strind == '-')) {
7904 if (*strind == '-') {
7906 tempY = -read_int(strind, &nextCharacter);
7907 if (strind == nextCharacter)
7909 strind = nextCharacter;
7916 tempY = read_int(strind, &nextCharacter);
7917 if (strind == nextCharacter)
7919 strind = nextCharacter;
7925 /* If strind isn't at the end of the string the it's an invalid
7926 geometry specification. */
7928 if (*strind != '\0') return (0);
7934 if (mask & WidthValue)
7936 if (mask & HeightValue)
7937 *height = tempHeight;
7942 * gtk_window_parse_geometry:
7943 * @window: a #GtkWindow
7944 * @geometry: geometry string
7946 * Parses a standard X Window System geometry string - see the
7947 * manual page for X (type 'man X') for details on this.
7948 * gtk_window_parse_geometry() does work on all GTK+ ports
7949 * including Win32 but is primarily intended for an X environment.
7951 * If either a size or a position can be extracted from the
7952 * geometry string, gtk_window_parse_geometry() returns %TRUE
7953 * and calls gtk_window_set_default_size() and/or gtk_window_move()
7954 * to resize/move the window.
7956 * If gtk_window_parse_geometry() returns %TRUE, it will also
7957 * set the #GDK_HINT_USER_POS and/or #GDK_HINT_USER_SIZE hints
7958 * indicating to the window manager that the size/position of
7959 * the window was user-specified. This causes most window
7960 * managers to honor the geometry.
7962 * Note that for gtk_window_parse_geometry() to work as expected, it has
7963 * to be called when the window has its "final" size, i.e. after calling
7964 * gtk_widget_show_all() on the contents and gtk_window_set_geometry_hints()
7967 * #include <gtk/gtk.h>
7970 * fill_with_content (GtkWidget *vbox)
7972 * /* fill with content... */
7976 * main (int argc, char *argv[])
7978 * GtkWidget *window, *vbox;
7979 * GdkGeometry size_hints = {
7980 * 100, 50, 0, 0, 100, 50, 10, 10, 0.0, 0.0, GDK_GRAVITY_NORTH_WEST
7983 * gtk_init (&argc, &argv);
7985 * window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
7986 * vbox = gtk_vbox_new (FALSE, 0);
7988 * gtk_container_add (GTK_CONTAINER (window), vbox);
7989 * fill_with_content (vbox);
7990 * gtk_widget_show_all (vbox);
7992 * gtk_window_set_geometry_hints (GTK_WINDOW (window),
7995 * GDK_HINT_MIN_SIZE |
7996 * GDK_HINT_BASE_SIZE |
7997 * GDK_HINT_RESIZE_INC);
8001 * if (!gtk_window_parse_geometry (GTK_WINDOW (window), argv[1]))
8002 * fprintf (stderr, "Failed to parse '%s'\n", argv[1]);
8005 * gtk_widget_show_all (window);
8012 * Return value: %TRUE if string was parsed successfully
8015 gtk_window_parse_geometry (GtkWindow *window,
8016 const gchar *geometry)
8018 gint result, x = 0, y = 0;
8021 gboolean size_set, pos_set;
8024 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
8025 g_return_val_if_fail (geometry != NULL, FALSE);
8027 screen = gtk_window_check_screen (window);
8029 result = gtk_XParseGeometry (geometry, &x, &y, &w, &h);
8032 if ((result & WidthValue) || (result & HeightValue))
8034 gtk_window_set_default_size_internal (window,
8035 TRUE, result & WidthValue ? w : -1,
8036 TRUE, result & HeightValue ? h : -1,
8041 gtk_window_get_size (window, (gint *)&w, (gint *)&h);
8043 grav = GDK_GRAVITY_NORTH_WEST;
8045 if ((result & XNegative) && (result & YNegative))
8046 grav = GDK_GRAVITY_SOUTH_EAST;
8047 else if (result & XNegative)
8048 grav = GDK_GRAVITY_NORTH_EAST;
8049 else if (result & YNegative)
8050 grav = GDK_GRAVITY_SOUTH_WEST;
8052 if ((result & XValue) == 0)
8055 if ((result & YValue) == 0)
8058 if (grav == GDK_GRAVITY_SOUTH_WEST ||
8059 grav == GDK_GRAVITY_SOUTH_EAST)
8060 y = gdk_screen_get_height (screen) - h + y;
8062 if (grav == GDK_GRAVITY_SOUTH_EAST ||
8063 grav == GDK_GRAVITY_NORTH_EAST)
8064 x = gdk_screen_get_width (screen) - w + x;
8066 /* we don't let you put a window offscreen; maybe some people would
8067 * prefer to be able to, but it's kind of a bogus thing to do.
8076 if ((result & XValue) || (result & YValue))
8078 gtk_window_set_gravity (window, grav);
8079 gtk_window_move (window, x, y);
8083 if (size_set || pos_set)
8085 /* Set USSize, USPosition hints */
8086 GtkWindowGeometryInfo *info;
8088 info = gtk_window_get_geometry_info (window, TRUE);
8091 info->mask |= GDK_HINT_USER_POS;
8093 info->mask |= GDK_HINT_USER_SIZE;
8100 gtk_window_mnemonic_hash_foreach (guint keyval,
8106 GtkWindowKeysForeachFunc func;
8110 (*info->func) (info->window, keyval, info->window->mnemonic_modifier, TRUE, info->func_data);
8114 _gtk_window_keys_foreach (GtkWindow *window,
8115 GtkWindowKeysForeachFunc func,
8119 GtkMnemonicHash *mnemonic_hash;
8123 GtkWindowKeysForeachFunc func;
8127 info.window = window;
8129 info.func_data = func_data;
8131 mnemonic_hash = gtk_window_get_mnemonic_hash (window, FALSE);
8133 _gtk_mnemonic_hash_foreach (mnemonic_hash,
8134 gtk_window_mnemonic_hash_foreach, &info);
8136 groups = gtk_accel_groups_from_object (G_OBJECT (window));
8139 GtkAccelGroup *group = groups->data;
8142 for (i = 0; i < group->n_accels; i++)
8144 GtkAccelKey *key = &group->priv_accels[i].key;
8147 (*func) (window, key->accel_key, key->accel_mods, FALSE, func_data);
8150 groups = groups->next;
8155 gtk_window_keys_changed (GtkWindow *window)
8157 gtk_window_free_key_hash (window);
8158 gtk_window_get_key_hash (window);
8161 typedef struct _GtkWindowKeyEntry GtkWindowKeyEntry;
8163 struct _GtkWindowKeyEntry
8167 guint is_mnemonic : 1;
8171 window_key_entry_destroy (gpointer data)
8173 g_slice_free (GtkWindowKeyEntry, data);
8177 add_to_key_hash (GtkWindow *window,
8179 GdkModifierType modifiers,
8180 gboolean is_mnemonic,
8183 GtkKeyHash *key_hash = data;
8185 GtkWindowKeyEntry *entry = g_slice_new (GtkWindowKeyEntry);
8187 entry->keyval = keyval;
8188 entry->modifiers = modifiers;
8189 entry->is_mnemonic = is_mnemonic;
8191 /* GtkAccelGroup stores lowercased accelerators. To deal
8192 * with this, if <Shift> was specified, uppercase.
8194 if (modifiers & GDK_SHIFT_MASK)
8196 if (keyval == GDK_Tab)
8197 keyval = GDK_ISO_Left_Tab;
8199 keyval = gdk_keyval_to_upper (keyval);
8202 _gtk_key_hash_add_entry (key_hash, keyval, entry->modifiers, entry);
8206 gtk_window_get_key_hash (GtkWindow *window)
8208 GdkScreen *screen = gtk_window_check_screen (window);
8209 GtkKeyHash *key_hash = g_object_get_qdata (G_OBJECT (window), quark_gtk_window_key_hash);
8214 key_hash = _gtk_key_hash_new (gdk_keymap_get_for_display (gdk_screen_get_display (screen)),
8215 (GDestroyNotify)window_key_entry_destroy);
8216 _gtk_window_keys_foreach (window, add_to_key_hash, key_hash);
8217 g_object_set_qdata (G_OBJECT (window), quark_gtk_window_key_hash, key_hash);
8223 gtk_window_free_key_hash (GtkWindow *window)
8225 GtkKeyHash *key_hash = g_object_get_qdata (G_OBJECT (window), quark_gtk_window_key_hash);
8228 _gtk_key_hash_free (key_hash);
8229 g_object_set_qdata (G_OBJECT (window), quark_gtk_window_key_hash, NULL);
8234 * gtk_window_activate_key:
8235 * @window: a #GtkWindow
8236 * @event: a #GdkEventKey
8238 * Activates mnemonics and accelerators for this #GtkWindow. This is normally
8239 * called by the default ::key_press_event handler for toplevel windows,
8240 * however in some cases it may be useful to call this directly when
8241 * overriding the standard key handling for a toplevel window.
8243 * Return value: %TRUE if a mnemonic or accelerator was found and activated.
8248 gtk_window_activate_key (GtkWindow *window,
8251 GtkKeyHash *key_hash;
8252 GtkWindowKeyEntry *found_entry = NULL;
8253 gboolean enable_mnemonics;
8254 gboolean enable_accels;
8256 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
8257 g_return_val_if_fail (event != NULL, FALSE);
8259 key_hash = gtk_window_get_key_hash (window);
8264 GSList *entries = _gtk_key_hash_lookup (key_hash,
8265 event->hardware_keycode,
8267 gtk_accelerator_get_default_mod_mask (),
8270 g_object_get (gtk_widget_get_settings (GTK_WIDGET (window)),
8271 "gtk-enable-mnemonics", &enable_mnemonics,
8272 "gtk-enable-accels", &enable_accels,
8275 for (tmp_list = entries; tmp_list; tmp_list = tmp_list->next)
8277 GtkWindowKeyEntry *entry = tmp_list->data;
8278 if (entry->is_mnemonic)
8280 if (enable_mnemonics)
8282 found_entry = entry;
8288 if (enable_accels && !found_entry)
8290 found_entry = entry;
8295 g_slist_free (entries);
8300 if (found_entry->is_mnemonic)
8302 if (enable_mnemonics)
8303 return gtk_window_mnemonic_activate (window, found_entry->keyval,
8304 found_entry->modifiers);
8309 return gtk_accel_groups_activate (G_OBJECT (window), found_entry->keyval,
8310 found_entry->modifiers);
8318 window_update_has_focus (GtkWindow *window)
8320 GtkWidget *widget = GTK_WIDGET (window);
8321 gboolean has_focus = window->has_toplevel_focus && window->is_active;
8323 if (has_focus != window->has_focus)
8325 window->has_focus = has_focus;
8329 if (window->focus_widget &&
8330 window->focus_widget != widget &&
8331 !gtk_widget_has_focus (window->focus_widget))
8332 do_focus_change (window->focus_widget, TRUE);
8336 if (window->focus_widget &&
8337 window->focus_widget != widget &&
8338 gtk_widget_has_focus (window->focus_widget))
8339 do_focus_change (window->focus_widget, FALSE);
8345 * _gtk_window_set_is_active:
8346 * @window: a #GtkWindow
8347 * @is_active: %TRUE if the window is in the currently active toplevel
8349 * Internal function that sets whether the #GtkWindow is part
8350 * of the currently active toplevel window (taking into account inter-process
8354 _gtk_window_set_is_active (GtkWindow *window,
8357 g_return_if_fail (GTK_IS_WINDOW (window));
8359 is_active = is_active != FALSE;
8361 if (is_active != window->is_active)
8363 window->is_active = is_active;
8364 window_update_has_focus (window);
8366 g_object_notify (G_OBJECT (window), "is-active");
8371 * _gtk_window_set_is_toplevel:
8372 * @window: a #GtkWindow
8373 * @is_toplevel: %TRUE if the window is still a real toplevel (nominally a
8374 * parent of the root window); %FALSE if it is not (for example, for an
8375 * in-process, parented GtkPlug)
8377 * Internal function used by #GtkPlug when it gets parented/unparented by a
8378 * #GtkSocket. This keeps the @window's #GTK_TOPLEVEL flag in sync with the
8379 * global list of toplevel windows.
8382 _gtk_window_set_is_toplevel (GtkWindow *window,
8383 gboolean is_toplevel)
8385 if (gtk_widget_is_toplevel (GTK_WIDGET (window)))
8386 g_assert (g_slist_find (toplevel_list, window) != NULL);
8388 g_assert (g_slist_find (toplevel_list, window) == NULL);
8390 if (is_toplevel == gtk_widget_is_toplevel (GTK_WIDGET (window)))
8395 GTK_WIDGET_SET_FLAGS (window, GTK_TOPLEVEL);
8396 toplevel_list = g_slist_prepend (toplevel_list, window);
8400 GTK_WIDGET_UNSET_FLAGS (window, GTK_TOPLEVEL);
8401 toplevel_list = g_slist_remove (toplevel_list, window);
8406 * _gtk_window_set_has_toplevel_focus:
8407 * @window: a #GtkWindow
8408 * @has_toplevel_focus: %TRUE if the in
8410 * Internal function that sets whether the keyboard focus for the
8411 * toplevel window (taking into account inter-process embedding.)
8414 _gtk_window_set_has_toplevel_focus (GtkWindow *window,
8415 gboolean has_toplevel_focus)
8417 g_return_if_fail (GTK_IS_WINDOW (window));
8419 has_toplevel_focus = has_toplevel_focus != FALSE;
8421 if (has_toplevel_focus != window->has_toplevel_focus)
8423 window->has_toplevel_focus = has_toplevel_focus;
8424 window_update_has_focus (window);
8426 g_object_notify (G_OBJECT (window), "has-toplevel-focus");
8431 * gtk_window_set_auto_startup_notification:
8432 * @setting: %TRUE to automatically do startup notification
8434 * By default, after showing the first #GtkWindow, GTK+ calls
8435 * gdk_notify_startup_complete(). Call this function to disable
8436 * the automatic startup notification. You might do this if your
8437 * first window is a splash screen, and you want to delay notification
8438 * until after your real main window has been shown, for example.
8440 * In that example, you would disable startup notification
8441 * temporarily, show your splash screen, then re-enable it so that
8442 * showing the main window would automatically result in notification.
8447 gtk_window_set_auto_startup_notification (gboolean setting)
8449 disable_startup_notification = !setting;
8453 * gtk_window_get_window_type:
8454 * @window: a #GtkWindow
8456 * Gets the type of the window. See #GtkWindowType.
8458 * Return value: the type of the window
8463 gtk_window_get_window_type (GtkWindow *window)
8465 g_return_val_if_fail (GTK_IS_WINDOW (window), GTK_WINDOW_TOPLEVEL);
8467 return window->type;
8470 /* gtk_window_get_mnemonics_visible:
8471 * @window: a #GtkWindow
8473 * Gets the value of the #GtkWindow:mnemonics-visible property.
8475 * Returns: %TRUE if mnemonics are supposed to be visible
8481 gtk_window_get_mnemonics_visible (GtkWindow *window)
8483 GtkWindowPrivate *priv;
8485 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
8487 priv = GTK_WINDOW_GET_PRIVATE (window);
8489 return priv->mnemonics_visible;
8493 * gtk_window_set_mnemonics_visible:
8494 * @window: a #GtkWindow
8495 * @setting: the new value
8497 * Sets the #GtkWindow:mnemonics-visible property.
8502 gtk_window_set_mnemonics_visible (GtkWindow *window,
8505 GtkWindowPrivate *priv;
8507 g_return_if_fail (GTK_IS_WINDOW (window));
8509 priv = GTK_WINDOW_GET_PRIVATE (window);
8511 setting = setting != FALSE;
8513 if (priv->mnemonics_visible != setting)
8515 priv->mnemonics_visible = setting;
8516 g_object_notify (G_OBJECT (window), "mnemonics-visible");
8519 priv->mnemonics_visible_set = TRUE;
8522 #if defined (G_OS_WIN32) && !defined (_WIN64)
8524 #undef gtk_window_set_icon_from_file
8527 gtk_window_set_icon_from_file (GtkWindow *window,
8528 const gchar *filename,
8531 gchar *utf8_filename = g_locale_to_utf8 (filename, -1, NULL, NULL, err);
8534 if (utf8_filename == NULL)
8537 retval = gtk_window_set_icon_from_file_utf8 (window, utf8_filename, err);
8539 g_free (utf8_filename);
8544 #undef gtk_window_set_default_icon_from_file
8547 gtk_window_set_default_icon_from_file (const gchar *filename,
8550 gchar *utf8_filename = g_locale_to_utf8 (filename, -1, NULL, NULL, err);
8553 if (utf8_filename == NULL)
8556 retval = gtk_window_set_default_icon_from_file_utf8 (utf8_filename, err);
8558 g_free (utf8_filename);
8565 #define __GTK_WINDOW_C__
8566 #include "gtkaliasdef.c"