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 "gtkiconfactory.h"
46 #include "gtkicontheme.h"
47 #include "gtkmarshalers.h"
49 #include "gtkbuildable.h"
52 #ifdef GDK_WINDOWING_X11
81 PROP_DESTROY_WITH_PARENT,
86 PROP_SKIP_TASKBAR_HINT,
97 /* Readonly properties */
99 PROP_HAS_TOPLEVEL_FOCUS,
101 /* Writeonly properties */
110 GdkPixmap *icon_pixmap;
111 GdkPixmap *icon_mask;
114 guint using_default_icon : 1;
115 guint using_parent_icon : 1;
116 guint using_themed_icon : 1;
120 GdkGeometry geometry; /* Last set of geometry hints we set */
121 GdkWindowHints flags;
122 GdkRectangle configure_request;
123 } GtkWindowLastGeometryInfo;
125 struct _GtkWindowGeometryInfo
127 /* Properties that the app has set on the window
129 GdkGeometry geometry; /* Geometry hints */
131 GtkWidget *widget; /* subwidget to which hints apply */
132 /* from last gtk_window_resize () - if > 0, indicates that
133 * we should resize to this size.
138 /* From last gtk_window_move () prior to mapping -
139 * only used if initial_pos_set
144 /* Default size - used only the FIRST time we map a window,
149 /* whether to use initial_x, initial_y */
150 guint initial_pos_set : 1;
151 /* CENTER_ALWAYS or other position constraint changed since
152 * we sent the last configure request.
154 guint position_constraints_changed : 1;
156 /* if true, default_width, height come from gtk_window_parse_geometry,
157 * and thus should be multiplied by the increments and affect the
158 * geometry widget only
160 guint default_is_geometry : 1;
162 GtkWindowLastGeometryInfo last;
165 #define GTK_WINDOW_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GTK_TYPE_WINDOW, GtkWindowPrivate))
167 typedef struct _GtkWindowPrivate GtkWindowPrivate;
169 struct _GtkWindowPrivate
171 GtkMnemonicHash *mnemonic_hash;
173 guint above_initially : 1;
174 guint below_initially : 1;
175 guint fullscreen_initially : 1;
176 guint skips_taskbar : 1;
177 guint skips_pager : 1;
179 guint accept_focus : 1;
180 guint focus_on_map : 1;
182 guint transient_parent_group : 1;
184 guint reset_type_hint : 1;
185 guint opacity_set : 1;
186 guint builder_visible : 1;
188 GdkWindowTypeHint type_hint;
195 static void gtk_window_dispose (GObject *object);
196 static void gtk_window_destroy (GtkObject *object);
197 static void gtk_window_finalize (GObject *object);
198 static void gtk_window_show (GtkWidget *widget);
199 static void gtk_window_hide (GtkWidget *widget);
200 static void gtk_window_map (GtkWidget *widget);
201 static void gtk_window_unmap (GtkWidget *widget);
202 static void gtk_window_realize (GtkWidget *widget);
203 static void gtk_window_unrealize (GtkWidget *widget);
204 static void gtk_window_size_request (GtkWidget *widget,
205 GtkRequisition *requisition);
206 static void gtk_window_size_allocate (GtkWidget *widget,
207 GtkAllocation *allocation);
208 static gint gtk_window_event (GtkWidget *widget,
210 static gboolean gtk_window_map_event (GtkWidget *widget,
212 static gboolean gtk_window_frame_event (GtkWindow *window,
214 static gint gtk_window_configure_event (GtkWidget *widget,
215 GdkEventConfigure *event);
216 static gint gtk_window_key_press_event (GtkWidget *widget,
218 static gint gtk_window_key_release_event (GtkWidget *widget,
220 static gint gtk_window_enter_notify_event (GtkWidget *widget,
221 GdkEventCrossing *event);
222 static gint gtk_window_leave_notify_event (GtkWidget *widget,
223 GdkEventCrossing *event);
224 static gint gtk_window_focus_in_event (GtkWidget *widget,
225 GdkEventFocus *event);
226 static gint gtk_window_focus_out_event (GtkWidget *widget,
227 GdkEventFocus *event);
228 static gint gtk_window_client_event (GtkWidget *widget,
229 GdkEventClient *event);
230 static void gtk_window_check_resize (GtkContainer *container);
231 static gint gtk_window_focus (GtkWidget *widget,
232 GtkDirectionType direction);
233 static void gtk_window_real_set_focus (GtkWindow *window,
236 static void gtk_window_real_activate_default (GtkWindow *window);
237 static void gtk_window_real_activate_focus (GtkWindow *window);
238 static void gtk_window_move_focus (GtkWindow *window,
239 GtkDirectionType dir);
240 static void gtk_window_keys_changed (GtkWindow *window);
241 static void gtk_window_paint (GtkWidget *widget,
243 static gint gtk_window_expose (GtkWidget *widget,
244 GdkEventExpose *event);
245 static void gtk_window_unset_transient_for (GtkWindow *window);
246 static void gtk_window_transient_parent_realized (GtkWidget *parent,
248 static void gtk_window_transient_parent_unrealized (GtkWidget *parent,
251 static GdkScreen *gtk_window_check_screen (GtkWindow *window);
253 static GtkWindowGeometryInfo* gtk_window_get_geometry_info (GtkWindow *window,
256 static void gtk_window_move_resize (GtkWindow *window);
257 static gboolean gtk_window_compare_hints (GdkGeometry *geometry_a,
259 GdkGeometry *geometry_b,
261 static void gtk_window_constrain_size (GtkWindow *window,
262 GdkGeometry *geometry,
268 static void gtk_window_constrain_position (GtkWindow *window,
273 static void gtk_window_compute_hints (GtkWindow *window,
274 GdkGeometry *new_geometry,
276 static void gtk_window_compute_configure_request (GtkWindow *window,
277 GdkRectangle *request,
278 GdkGeometry *geometry,
281 static void gtk_window_set_default_size_internal (GtkWindow *window,
282 gboolean change_width,
284 gboolean change_height,
286 gboolean is_geometry);
288 static void update_themed_icon (GtkIconTheme *theme,
290 static GList *icon_list_from_theme (GtkWidget *widget,
292 static void gtk_window_realize_icon (GtkWindow *window);
293 static void gtk_window_unrealize_icon (GtkWindow *window);
295 static void gtk_window_notify_keys_changed (GtkWindow *window);
296 static GtkKeyHash *gtk_window_get_key_hash (GtkWindow *window);
297 static void gtk_window_free_key_hash (GtkWindow *window);
298 static void gtk_window_on_composited_changed (GdkScreen *screen,
301 static GSList *toplevel_list = NULL;
302 static guint window_signals[LAST_SIGNAL] = { 0 };
303 static GList *default_icon_list = NULL;
304 static gchar *default_icon_name = NULL;
305 static guint default_icon_serial = 0;
306 static gboolean disable_startup_notification = FALSE;
307 static gboolean sent_startup_notification = FALSE;
309 static GQuark quark_gtk_embedded = 0;
310 static GQuark quark_gtk_window_key_hash = 0;
311 static GQuark quark_gtk_window_default_icon_pixmap = 0;
312 static GQuark quark_gtk_window_icon_info = 0;
314 static GtkBuildableIface *parent_buildable_iface;
316 static void gtk_window_set_property (GObject *object,
320 static void gtk_window_get_property (GObject *object,
326 static void gtk_window_buildable_interface_init (GtkBuildableIface *iface);
327 static void gtk_window_buildable_set_buildable_property (GtkBuildable *buildable,
330 const GValue *value);
331 static void gtk_window_buildable_parser_finished (GtkBuildable *buildable,
332 GtkBuilder *builder);
335 G_DEFINE_TYPE_WITH_CODE (GtkWindow, gtk_window, GTK_TYPE_BIN,
336 G_IMPLEMENT_INTERFACE (GTK_TYPE_BUILDABLE,
337 gtk_window_buildable_interface_init))
340 add_tab_bindings (GtkBindingSet *binding_set,
341 GdkModifierType modifiers,
342 GtkDirectionType direction)
344 gtk_binding_entry_add_signal (binding_set, GDK_Tab, modifiers,
346 GTK_TYPE_DIRECTION_TYPE, direction);
347 gtk_binding_entry_add_signal (binding_set, GDK_KP_Tab, modifiers,
349 GTK_TYPE_DIRECTION_TYPE, direction);
353 add_arrow_bindings (GtkBindingSet *binding_set,
355 GtkDirectionType direction)
357 guint keypad_keysym = keysym - GDK_Left + GDK_KP_Left;
359 gtk_binding_entry_add_signal (binding_set, keysym, 0,
361 GTK_TYPE_DIRECTION_TYPE, direction);
362 gtk_binding_entry_add_signal (binding_set, keysym, GDK_CONTROL_MASK,
364 GTK_TYPE_DIRECTION_TYPE, direction);
365 gtk_binding_entry_add_signal (binding_set, keypad_keysym, 0,
367 GTK_TYPE_DIRECTION_TYPE, direction);
368 gtk_binding_entry_add_signal (binding_set, keypad_keysym, GDK_CONTROL_MASK,
370 GTK_TYPE_DIRECTION_TYPE, direction);
374 extract_time_from_startup_id (const gchar* startup_id)
376 gchar *timestr = g_strrstr (startup_id, "_TIME");
377 guint32 retval = GDK_CURRENT_TIME;
384 /* Skip past the "_TIME" part */
387 timestamp = strtoul (timestr, &end, 0);
388 if (end != timestr && errno == 0)
396 startup_id_is_fake (const gchar* startup_id)
398 return strncmp (startup_id, "_TIME", 5) == 0;
402 gtk_window_class_init (GtkWindowClass *klass)
404 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
405 GtkObjectClass *object_class;
406 GtkWidgetClass *widget_class;
407 GtkContainerClass *container_class;
408 GtkBindingSet *binding_set;
410 object_class = (GtkObjectClass*) klass;
411 widget_class = (GtkWidgetClass*) klass;
412 container_class = (GtkContainerClass*) klass;
414 quark_gtk_embedded = g_quark_from_static_string ("gtk-embedded");
415 quark_gtk_window_key_hash = g_quark_from_static_string ("gtk-window-key-hash");
416 quark_gtk_window_default_icon_pixmap = g_quark_from_static_string ("gtk-window-default-icon-pixmap");
417 quark_gtk_window_icon_info = g_quark_from_static_string ("gtk-window-icon-info");
419 gobject_class->dispose = gtk_window_dispose;
420 gobject_class->finalize = gtk_window_finalize;
422 gobject_class->set_property = gtk_window_set_property;
423 gobject_class->get_property = gtk_window_get_property;
425 object_class->destroy = gtk_window_destroy;
427 widget_class->show = gtk_window_show;
428 widget_class->hide = gtk_window_hide;
429 widget_class->map = gtk_window_map;
430 widget_class->map_event = gtk_window_map_event;
431 widget_class->unmap = gtk_window_unmap;
432 widget_class->realize = gtk_window_realize;
433 widget_class->unrealize = gtk_window_unrealize;
434 widget_class->size_request = gtk_window_size_request;
435 widget_class->size_allocate = gtk_window_size_allocate;
436 widget_class->configure_event = gtk_window_configure_event;
437 widget_class->key_press_event = gtk_window_key_press_event;
438 widget_class->key_release_event = gtk_window_key_release_event;
439 widget_class->enter_notify_event = gtk_window_enter_notify_event;
440 widget_class->leave_notify_event = gtk_window_leave_notify_event;
441 widget_class->focus_in_event = gtk_window_focus_in_event;
442 widget_class->focus_out_event = gtk_window_focus_out_event;
443 widget_class->client_event = gtk_window_client_event;
444 widget_class->focus = gtk_window_focus;
446 widget_class->expose_event = gtk_window_expose;
448 container_class->check_resize = gtk_window_check_resize;
450 klass->set_focus = gtk_window_real_set_focus;
451 klass->frame_event = gtk_window_frame_event;
453 klass->activate_default = gtk_window_real_activate_default;
454 klass->activate_focus = gtk_window_real_activate_focus;
455 klass->move_focus = gtk_window_move_focus;
456 klass->keys_changed = gtk_window_keys_changed;
458 g_type_class_add_private (gobject_class, sizeof (GtkWindowPrivate));
461 g_object_class_install_property (gobject_class,
463 g_param_spec_enum ("type",
465 P_("The type of the window"),
466 GTK_TYPE_WINDOW_TYPE,
468 GTK_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
470 g_object_class_install_property (gobject_class,
472 g_param_spec_string ("title",
474 P_("The title of the window"),
476 GTK_PARAM_READWRITE));
478 g_object_class_install_property (gobject_class,
480 g_param_spec_string ("role",
482 P_("Unique identifier for the window to be used when restoring a session"),
484 GTK_PARAM_READWRITE));
487 * GtkWindow:startup-id:
489 * The :startup-id is a write-only property for setting window's
490 * startup notification identifier. See gtk_window_set_startup_id()
495 g_object_class_install_property (gobject_class,
497 g_param_spec_string ("startup-id",
499 P_("Unique startup identifier for the window used by startup-notification"),
501 GTK_PARAM_WRITABLE));
503 g_object_class_install_property (gobject_class,
505 g_param_spec_boolean ("allow-shrink",
507 /* xgettext:no-c-format */
508 P_("If TRUE, the window has no mimimum size. Setting this to TRUE is 99% of the time a bad idea"),
510 GTK_PARAM_READWRITE));
512 g_object_class_install_property (gobject_class,
514 g_param_spec_boolean ("allow-grow",
516 P_("If TRUE, users can expand the window beyond its minimum size"),
518 GTK_PARAM_READWRITE));
520 g_object_class_install_property (gobject_class,
522 g_param_spec_boolean ("resizable",
524 P_("If TRUE, users can resize the window"),
526 GTK_PARAM_READWRITE));
528 g_object_class_install_property (gobject_class,
530 g_param_spec_boolean ("modal",
532 P_("If TRUE, the window is modal (other windows are not usable while this one is up)"),
534 GTK_PARAM_READWRITE));
536 g_object_class_install_property (gobject_class,
538 g_param_spec_enum ("window-position",
539 P_("Window Position"),
540 P_("The initial position of the window"),
541 GTK_TYPE_WINDOW_POSITION,
543 GTK_PARAM_READWRITE));
545 g_object_class_install_property (gobject_class,
547 g_param_spec_int ("default-width",
549 P_("The default width of the window, used when initially showing the window"),
553 GTK_PARAM_READWRITE));
555 g_object_class_install_property (gobject_class,
557 g_param_spec_int ("default-height",
558 P_("Default Height"),
559 P_("The default height of the window, used when initially showing the window"),
563 GTK_PARAM_READWRITE));
565 g_object_class_install_property (gobject_class,
566 PROP_DESTROY_WITH_PARENT,
567 g_param_spec_boolean ("destroy-with-parent",
568 P_("Destroy with Parent"),
569 P_("If this window should be destroyed when the parent is destroyed"),
571 GTK_PARAM_READWRITE));
573 g_object_class_install_property (gobject_class,
575 g_param_spec_object ("icon",
577 P_("Icon for this window"),
579 GTK_PARAM_READWRITE));
582 * GtkWindow:icon-name:
584 * The :icon-name property specifies the name of the themed icon to
585 * use as the window icon. See #GtkIconTheme for more details.
589 g_object_class_install_property (gobject_class,
591 g_param_spec_string ("icon-name",
593 P_("Name of the themed icon for this window"),
595 GTK_PARAM_READWRITE));
597 g_object_class_install_property (gobject_class,
599 g_param_spec_object ("screen",
601 P_("The screen where this window will be displayed"),
603 GTK_PARAM_READWRITE));
605 g_object_class_install_property (gobject_class,
607 g_param_spec_boolean ("is-active",
609 P_("Whether the toplevel is the current active window"),
611 GTK_PARAM_READABLE));
613 g_object_class_install_property (gobject_class,
614 PROP_HAS_TOPLEVEL_FOCUS,
615 g_param_spec_boolean ("has-toplevel-focus",
616 P_("Focus in Toplevel"),
617 P_("Whether the input focus is within this GtkWindow"),
619 GTK_PARAM_READABLE));
621 g_object_class_install_property (gobject_class,
623 g_param_spec_enum ("type-hint",
625 P_("Hint to help the desktop environment understand what kind of window this is and how to treat it."),
626 GDK_TYPE_WINDOW_TYPE_HINT,
627 GDK_WINDOW_TYPE_HINT_NORMAL,
628 GTK_PARAM_READWRITE));
630 g_object_class_install_property (gobject_class,
631 PROP_SKIP_TASKBAR_HINT,
632 g_param_spec_boolean ("skip-taskbar-hint",
634 P_("TRUE if the window should not be in the task bar."),
636 GTK_PARAM_READWRITE));
638 g_object_class_install_property (gobject_class,
639 PROP_SKIP_PAGER_HINT,
640 g_param_spec_boolean ("skip-pager-hint",
642 P_("TRUE if the window should not be in the pager."),
644 GTK_PARAM_READWRITE));
646 g_object_class_install_property (gobject_class,
648 g_param_spec_boolean ("urgency-hint",
650 P_("TRUE if the window should be brought to the user's attention."),
652 GTK_PARAM_READWRITE));
655 * GtkWindow:accept-focus-hint:
657 * Whether the window should receive the input focus.
661 g_object_class_install_property (gobject_class,
663 g_param_spec_boolean ("accept-focus",
665 P_("TRUE if the window should receive the input focus."),
667 GTK_PARAM_READWRITE));
670 * GtkWindow:focus-on-map-hint:
672 * Whether the window should receive the input focus when mapped.
676 g_object_class_install_property (gobject_class,
678 g_param_spec_boolean ("focus-on-map",
680 P_("TRUE if the window should receive the input focus when mapped."),
682 GTK_PARAM_READWRITE));
685 * GtkWindow:decorated:
687 * Whether the window should be decorated by the window manager.
691 g_object_class_install_property (gobject_class,
693 g_param_spec_boolean ("decorated",
695 P_("Whether the window should be decorated by the window manager"),
697 GTK_PARAM_READWRITE));
700 * GtkWindow:deletable:
702 * Whether the window frame should have a close button.
706 g_object_class_install_property (gobject_class,
708 g_param_spec_boolean ("deletable",
710 P_("Whether the window frame should have a close button"),
712 GTK_PARAM_READWRITE));
718 * The window gravity of the window. See gtk_window_move() and #GdkGravity for
719 * more details about window gravity.
723 g_object_class_install_property (gobject_class,
725 g_param_spec_enum ("gravity",
727 P_("The window gravity of the window"),
729 GDK_GRAVITY_NORTH_WEST,
730 GTK_PARAM_READWRITE));
734 * GtkWindow:transient-for:
736 * The transient parent of the window. See gtk_window_set_transient_for() for
737 * more details about transient windows.
741 g_object_class_install_property (gobject_class,
743 g_param_spec_object ("transient-for",
744 P_("Transient for Window"),
745 P_("The transient parent of the dialog"),
747 GTK_PARAM_READWRITE| G_PARAM_CONSTRUCT));
751 * The requested opacity of the window. See gtk_window_set_opacity() for
752 * more details about window opacity.
756 g_object_class_install_property (gobject_class,
758 g_param_spec_double ("opacity",
759 P_("Opacity for Window"),
760 P_("The opacity of the window, from 0 to 1"),
764 GTK_PARAM_READWRITE));
766 window_signals[SET_FOCUS] =
767 g_signal_new (I_("set_focus"),
768 G_TYPE_FROM_CLASS (gobject_class),
770 G_STRUCT_OFFSET (GtkWindowClass, set_focus),
772 _gtk_marshal_VOID__OBJECT,
776 window_signals[FRAME_EVENT] =
777 g_signal_new (I_("frame_event"),
778 G_TYPE_FROM_CLASS (gobject_class),
780 G_STRUCT_OFFSET(GtkWindowClass, frame_event),
781 _gtk_boolean_handled_accumulator, NULL,
782 _gtk_marshal_BOOLEAN__BOXED,
786 window_signals[ACTIVATE_FOCUS] =
787 g_signal_new (I_("activate_focus"),
788 G_TYPE_FROM_CLASS (gobject_class),
789 G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
790 G_STRUCT_OFFSET (GtkWindowClass, activate_focus),
792 _gtk_marshal_VOID__VOID,
796 window_signals[ACTIVATE_DEFAULT] =
797 g_signal_new (I_("activate_default"),
798 G_TYPE_FROM_CLASS (gobject_class),
799 G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
800 G_STRUCT_OFFSET (GtkWindowClass, activate_default),
802 _gtk_marshal_VOID__VOID,
806 window_signals[KEYS_CHANGED] =
807 g_signal_new (I_("keys_changed"),
808 G_TYPE_FROM_CLASS (gobject_class),
810 G_STRUCT_OFFSET (GtkWindowClass, keys_changed),
812 _gtk_marshal_VOID__VOID,
820 binding_set = gtk_binding_set_by_class (klass);
822 gtk_binding_entry_add_signal (binding_set, GDK_space, 0,
823 "activate_focus", 0);
824 gtk_binding_entry_add_signal (binding_set, GDK_KP_Space, 0,
825 "activate_focus", 0);
827 gtk_binding_entry_add_signal (binding_set, GDK_Return, 0,
828 "activate_default", 0);
829 gtk_binding_entry_add_signal (binding_set, GDK_ISO_Enter, 0,
830 "activate_default", 0);
831 gtk_binding_entry_add_signal (binding_set, GDK_KP_Enter, 0,
832 "activate_default", 0);
834 add_arrow_bindings (binding_set, GDK_Up, GTK_DIR_UP);
835 add_arrow_bindings (binding_set, GDK_Down, GTK_DIR_DOWN);
836 add_arrow_bindings (binding_set, GDK_Left, GTK_DIR_LEFT);
837 add_arrow_bindings (binding_set, GDK_Right, GTK_DIR_RIGHT);
839 add_tab_bindings (binding_set, 0, GTK_DIR_TAB_FORWARD);
840 add_tab_bindings (binding_set, GDK_CONTROL_MASK, GTK_DIR_TAB_FORWARD);
841 add_tab_bindings (binding_set, GDK_SHIFT_MASK, GTK_DIR_TAB_BACKWARD);
842 add_tab_bindings (binding_set, GDK_CONTROL_MASK | GDK_SHIFT_MASK, GTK_DIR_TAB_BACKWARD);
846 gtk_window_init (GtkWindow *window)
848 GdkColormap *colormap;
849 GtkWindowPrivate *priv = GTK_WINDOW_GET_PRIVATE (window);
851 GTK_WIDGET_UNSET_FLAGS (window, GTK_NO_WINDOW);
852 GTK_WIDGET_SET_FLAGS (window, GTK_TOPLEVEL);
854 GTK_PRIVATE_SET_FLAG (window, GTK_ANCHORED);
856 gtk_container_set_resize_mode (GTK_CONTAINER (window), GTK_RESIZE_QUEUE);
858 window->title = NULL;
859 window->wmclass_name = g_strdup (g_get_prgname ());
860 window->wmclass_class = g_strdup (gdk_get_program_class ());
861 window->wm_role = NULL;
862 window->geometry_info = NULL;
863 window->type = GTK_WINDOW_TOPLEVEL;
864 window->focus_widget = NULL;
865 window->default_widget = NULL;
866 window->configure_request_count = 0;
867 window->allow_shrink = FALSE;
868 window->allow_grow = TRUE;
869 window->configure_notify_received = FALSE;
870 window->position = GTK_WIN_POS_NONE;
871 window->need_default_size = TRUE;
872 window->need_default_position = TRUE;
873 window->modal = FALSE;
874 window->frame = NULL;
875 window->has_frame = FALSE;
876 window->frame_left = 0;
877 window->frame_right = 0;
878 window->frame_top = 0;
879 window->frame_bottom = 0;
880 window->type_hint = GDK_WINDOW_TYPE_HINT_NORMAL;
881 window->gravity = GDK_GRAVITY_NORTH_WEST;
882 window->decorated = TRUE;
883 window->mnemonic_modifier = GDK_MOD1_MASK;
884 window->screen = gdk_screen_get_default ();
886 priv->accept_focus = TRUE;
887 priv->focus_on_map = TRUE;
888 priv->deletable = TRUE;
889 priv->type_hint = GDK_WINDOW_TYPE_HINT_NORMAL;
891 priv->startup_id = NULL;
893 colormap = _gtk_widget_peek_colormap ();
895 gtk_widget_set_colormap (GTK_WIDGET (window), colormap);
897 g_object_ref_sink (window);
898 window->has_user_ref_count = TRUE;
899 toplevel_list = g_slist_prepend (toplevel_list, window);
901 gtk_decorated_window_init (window);
903 g_signal_connect (window->screen, "composited_changed",
904 G_CALLBACK (gtk_window_on_composited_changed), window);
908 gtk_window_set_property (GObject *object,
915 window = GTK_WINDOW (object);
920 window->type = g_value_get_enum (value);
923 gtk_window_set_title (window, g_value_get_string (value));
926 gtk_window_set_role (window, g_value_get_string (value));
928 case PROP_STARTUP_ID:
929 gtk_window_set_startup_id (window, g_value_get_string (value));
931 case PROP_ALLOW_SHRINK:
932 window->allow_shrink = g_value_get_boolean (value);
933 gtk_widget_queue_resize (GTK_WIDGET (window));
935 case PROP_ALLOW_GROW:
936 window->allow_grow = g_value_get_boolean (value);
937 gtk_widget_queue_resize (GTK_WIDGET (window));
938 g_object_notify (G_OBJECT (window), "resizable");
941 window->allow_grow = g_value_get_boolean (value);
942 gtk_widget_queue_resize (GTK_WIDGET (window));
943 g_object_notify (G_OBJECT (window), "allow-grow");
946 gtk_window_set_modal (window, g_value_get_boolean (value));
949 gtk_window_set_position (window, g_value_get_enum (value));
951 case PROP_DEFAULT_WIDTH:
952 gtk_window_set_default_size_internal (window,
953 TRUE, g_value_get_int (value),
956 case PROP_DEFAULT_HEIGHT:
957 gtk_window_set_default_size_internal (window,
959 TRUE, g_value_get_int (value), FALSE);
961 case PROP_DESTROY_WITH_PARENT:
962 gtk_window_set_destroy_with_parent (window, g_value_get_boolean (value));
965 gtk_window_set_icon (window,
966 g_value_get_object (value));
969 gtk_window_set_icon_name (window, g_value_get_string (value));
972 gtk_window_set_screen (window, g_value_get_object (value));
975 gtk_window_set_type_hint (window,
976 g_value_get_enum (value));
978 case PROP_SKIP_TASKBAR_HINT:
979 gtk_window_set_skip_taskbar_hint (window,
980 g_value_get_boolean (value));
982 case PROP_SKIP_PAGER_HINT:
983 gtk_window_set_skip_pager_hint (window,
984 g_value_get_boolean (value));
986 case PROP_URGENCY_HINT:
987 gtk_window_set_urgency_hint (window,
988 g_value_get_boolean (value));
990 case PROP_ACCEPT_FOCUS:
991 gtk_window_set_accept_focus (window,
992 g_value_get_boolean (value));
994 case PROP_FOCUS_ON_MAP:
995 gtk_window_set_focus_on_map (window,
996 g_value_get_boolean (value));
999 gtk_window_set_decorated (window, g_value_get_boolean (value));
1001 case PROP_DELETABLE:
1002 gtk_window_set_deletable (window, g_value_get_boolean (value));
1005 gtk_window_set_gravity (window, g_value_get_enum (value));
1007 case PROP_TRANSIENT_FOR:
1008 gtk_window_set_transient_for (window, g_value_get_object (value));
1011 gtk_window_set_opacity (window, g_value_get_double (value));
1014 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1020 gtk_window_get_property (GObject *object,
1026 GtkWindowPrivate *priv;
1028 window = GTK_WINDOW (object);
1029 priv = GTK_WINDOW_GET_PRIVATE (window);
1033 GtkWindowGeometryInfo *info;
1035 g_value_set_enum (value, window->type);
1038 g_value_set_string (value, window->wm_role);
1041 g_value_set_string (value, window->title);
1043 case PROP_ALLOW_SHRINK:
1044 g_value_set_boolean (value, window->allow_shrink);
1046 case PROP_ALLOW_GROW:
1047 g_value_set_boolean (value, window->allow_grow);
1049 case PROP_RESIZABLE:
1050 g_value_set_boolean (value, window->allow_grow);
1053 g_value_set_boolean (value, window->modal);
1056 g_value_set_enum (value, window->position);
1058 case PROP_DEFAULT_WIDTH:
1059 info = gtk_window_get_geometry_info (window, FALSE);
1061 g_value_set_int (value, -1);
1063 g_value_set_int (value, info->default_width);
1065 case PROP_DEFAULT_HEIGHT:
1066 info = gtk_window_get_geometry_info (window, FALSE);
1068 g_value_set_int (value, -1);
1070 g_value_set_int (value, info->default_height);
1072 case PROP_DESTROY_WITH_PARENT:
1073 g_value_set_boolean (value, window->destroy_with_parent);
1076 g_value_set_object (value, gtk_window_get_icon (window));
1078 case PROP_ICON_NAME:
1079 g_value_set_string (value, gtk_window_get_icon_name (window));
1082 g_value_set_object (value, window->screen);
1084 case PROP_IS_ACTIVE:
1085 g_value_set_boolean (value, window->is_active);
1087 case PROP_HAS_TOPLEVEL_FOCUS:
1088 g_value_set_boolean (value, window->has_toplevel_focus);
1090 case PROP_TYPE_HINT:
1091 g_value_set_enum (value, priv->type_hint);
1093 case PROP_SKIP_TASKBAR_HINT:
1094 g_value_set_boolean (value,
1095 gtk_window_get_skip_taskbar_hint (window));
1097 case PROP_SKIP_PAGER_HINT:
1098 g_value_set_boolean (value,
1099 gtk_window_get_skip_pager_hint (window));
1101 case PROP_URGENCY_HINT:
1102 g_value_set_boolean (value,
1103 gtk_window_get_urgency_hint (window));
1105 case PROP_ACCEPT_FOCUS:
1106 g_value_set_boolean (value,
1107 gtk_window_get_accept_focus (window));
1109 case PROP_FOCUS_ON_MAP:
1110 g_value_set_boolean (value,
1111 gtk_window_get_focus_on_map (window));
1113 case PROP_DECORATED:
1114 g_value_set_boolean (value, gtk_window_get_decorated (window));
1116 case PROP_DELETABLE:
1117 g_value_set_boolean (value, gtk_window_get_deletable (window));
1120 g_value_set_enum (value, gtk_window_get_gravity (window));
1122 case PROP_TRANSIENT_FOR:
1123 g_value_set_object (value, gtk_window_get_transient_for (window));
1126 g_value_set_double (value, gtk_window_get_opacity (window));
1129 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1135 gtk_window_buildable_interface_init (GtkBuildableIface *iface)
1137 parent_buildable_iface = g_type_interface_peek_parent (iface);
1138 iface->set_buildable_property = gtk_window_buildable_set_buildable_property;
1139 iface->parser_finished = gtk_window_buildable_parser_finished;
1144 gtk_window_buildable_set_buildable_property (GtkBuildable *buildable,
1145 GtkBuilder *builder,
1147 const GValue *value)
1149 GtkWindowPrivate *priv = GTK_WINDOW_GET_PRIVATE (buildable);
1151 if (strcmp (name, "visible") == 0 && g_value_get_boolean (value))
1152 priv->builder_visible = TRUE;
1154 parent_buildable_iface->set_buildable_property (buildable, builder, name, value);
1158 gtk_window_buildable_parser_finished (GtkBuildable *buildable,
1159 GtkBuilder *builder)
1161 GtkWindowPrivate *priv = GTK_WINDOW_GET_PRIVATE (buildable);
1163 if (priv->builder_visible)
1164 gtk_widget_show (GTK_WIDGET (buildable));
1169 * @type: type of window
1171 * Creates a new #GtkWindow, which is a toplevel window that can
1172 * contain other widgets. Nearly always, the type of the window should
1173 * be #GTK_WINDOW_TOPLEVEL. If you're implementing something like a
1174 * popup menu from scratch (which is a bad idea, just use #GtkMenu),
1175 * you might use #GTK_WINDOW_POPUP. #GTK_WINDOW_POPUP is not for
1176 * dialogs, though in some other toolkits dialogs are called "popups".
1177 * In GTK+, #GTK_WINDOW_POPUP means a pop-up menu or pop-up tooltip.
1178 * On X11, popup windows are not controlled by the <link
1179 * linkend="gtk-X11-arch">window manager</link>.
1181 * If you simply want an undecorated window (no window borders), use
1182 * gtk_window_set_decorated(), don't use #GTK_WINDOW_POPUP.
1184 * Return value: a new #GtkWindow.
1187 gtk_window_new (GtkWindowType type)
1191 g_return_val_if_fail (type >= GTK_WINDOW_TOPLEVEL && type <= GTK_WINDOW_POPUP, NULL);
1193 window = g_object_new (GTK_TYPE_WINDOW, NULL);
1195 window->type = type;
1197 return GTK_WIDGET (window);
1201 * gtk_window_set_title:
1202 * @window: a #GtkWindow
1203 * @title: title of the window
1205 * Sets the title of the #GtkWindow. The title of a window will be
1206 * displayed in its title bar; on the X Window System, the title bar
1207 * is rendered by the <link linkend="gtk-X11-arch">window
1208 * manager</link>, so exactly how the title appears to users may vary
1209 * according to a user's exact configuration. The title should help a
1210 * user distinguish this window from other windows they may have
1211 * open. A good title might include the application name and current
1212 * document filename, for example.
1216 gtk_window_set_title (GtkWindow *window,
1221 g_return_if_fail (GTK_IS_WINDOW (window));
1223 new_title = g_strdup (title);
1224 g_free (window->title);
1225 window->title = new_title;
1227 if (GTK_WIDGET_REALIZED (window))
1229 gdk_window_set_title (GTK_WIDGET (window)->window, window->title);
1231 gtk_decorated_window_set_title (window, title);
1234 g_object_notify (G_OBJECT (window), "title");
1238 * gtk_window_get_title:
1239 * @window: a #GtkWindow
1241 * Retrieves the title of the window. See gtk_window_set_title().
1243 * Return value: the title of the window, or %NULL if none has
1244 * been set explicitely. The returned string is owned by the widget
1245 * and must not be modified or freed.
1247 G_CONST_RETURN gchar *
1248 gtk_window_get_title (GtkWindow *window)
1250 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
1252 return window->title;
1256 * gtk_window_set_wmclass:
1257 * @window: a #GtkWindow
1258 * @wmclass_name: window name hint
1259 * @wmclass_class: window class hint
1261 * Don't use this function. It sets the X Window System "class" and
1262 * "name" hints for a window. According to the ICCCM, you should
1263 * always set these to the same value for all windows in an
1264 * application, and GTK+ sets them to that value by default, so calling
1265 * this function is sort of pointless. However, you may want to call
1266 * gtk_window_set_role() on each window in your application, for the
1267 * benefit of the session manager. Setting the role allows the window
1268 * manager to restore window positions when loading a saved session.
1272 gtk_window_set_wmclass (GtkWindow *window,
1273 const gchar *wmclass_name,
1274 const gchar *wmclass_class)
1276 g_return_if_fail (GTK_IS_WINDOW (window));
1278 g_free (window->wmclass_name);
1279 window->wmclass_name = g_strdup (wmclass_name);
1281 g_free (window->wmclass_class);
1282 window->wmclass_class = g_strdup (wmclass_class);
1284 if (GTK_WIDGET_REALIZED (window))
1285 g_warning ("gtk_window_set_wmclass: shouldn't set wmclass after window is realized!\n");
1289 * gtk_window_set_role:
1290 * @window: a #GtkWindow
1291 * @role: unique identifier for the window to be used when restoring a session
1293 * This function is only useful on X11, not with other GTK+ targets.
1295 * In combination with the window title, the window role allows a
1296 * <link linkend="gtk-X11-arch">window manager</link> to identify "the
1297 * same" window when an application is restarted. So for example you
1298 * might set the "toolbox" role on your app's toolbox window, so that
1299 * when the user restarts their session, the window manager can put
1300 * the toolbox back in the same place.
1302 * If a window already has a unique title, you don't need to set the
1303 * role, since the WM can use the title to identify the window when
1304 * restoring the session.
1308 gtk_window_set_role (GtkWindow *window,
1313 g_return_if_fail (GTK_IS_WINDOW (window));
1315 new_role = g_strdup (role);
1316 g_free (window->wm_role);
1317 window->wm_role = new_role;
1319 if (GTK_WIDGET_REALIZED (window))
1320 gdk_window_set_role (GTK_WIDGET (window)->window, window->wm_role);
1322 g_object_notify (G_OBJECT (window), "role");
1326 * gtk_window_set_startup_id:
1327 * @window: a #GtkWindow
1328 * @startup_id: a string with startup-notification identifier
1330 * Startup notification identifiers are used by desktop environment to
1331 * track application startup, to provide user feedback and other
1332 * features. This function changes the corresponding property on the
1333 * underlying GdkWindow. Normally, startup identifier is managed
1334 * automatically and you should only use this function in special cases
1335 * like transferring focus from other processes. You should use this
1336 * function before calling gtk_window_present() or any equivalent
1337 * function generating a window map event.
1339 * This function is only useful on X11, not with other GTK+ targets.
1344 gtk_window_set_startup_id (GtkWindow *window,
1345 const gchar *startup_id)
1347 GtkWindowPrivate *priv = GTK_WINDOW_GET_PRIVATE (window);
1349 g_return_if_fail (GTK_IS_WINDOW (window));
1351 g_free (priv->startup_id);
1352 priv->startup_id = g_strdup (startup_id);
1354 if (GTK_WIDGET_REALIZED (window))
1356 /* Here we differentiate real and "fake" startup notification IDs,
1357 * constructed on purpose just to pass interaction timestamp
1359 if (startup_id_is_fake (priv->startup_id))
1361 guint32 timestamp = extract_time_from_startup_id (priv->startup_id);
1363 gtk_window_present_with_time (window, timestamp);
1367 gdk_window_set_startup_id (GTK_WIDGET (window)->window,
1370 /* If window is mapped, terminate the startup-notification too */
1371 if (GTK_WIDGET_MAPPED (window) && !disable_startup_notification)
1372 gdk_notify_startup_complete_with_id (priv->startup_id);
1376 g_object_notify (G_OBJECT (window), "startup-id");
1380 * gtk_window_get_role:
1381 * @window: a #GtkWindow
1383 * Returns the role of the window. See gtk_window_set_role() for
1384 * further explanation.
1386 * Return value: the role of the window if set, or %NULL. The
1387 * returned is owned by the widget and must not be modified
1390 G_CONST_RETURN gchar *
1391 gtk_window_get_role (GtkWindow *window)
1393 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
1395 return window->wm_role;
1399 * gtk_window_set_focus:
1400 * @window: a #GtkWindow
1401 * @focus: widget to be the new focus widget, or %NULL to unset
1402 * any focus widget for the toplevel window.
1404 * If @focus is not the current focus widget, and is focusable, sets
1405 * it as the focus widget for the window. If @focus is %NULL, unsets
1406 * the focus widget for this window. To set the focus to a particular
1407 * widget in the toplevel, it is usually more convenient to use
1408 * gtk_widget_grab_focus() instead of this function.
1411 gtk_window_set_focus (GtkWindow *window,
1414 g_return_if_fail (GTK_IS_WINDOW (window));
1417 g_return_if_fail (GTK_IS_WIDGET (focus));
1418 g_return_if_fail (GTK_WIDGET_CAN_FOCUS (focus));
1422 gtk_widget_grab_focus (focus);
1425 /* Clear the existing focus chain, so that when we focus into
1426 * the window again, we start at the beginnning.
1428 GtkWidget *widget = window->focus_widget;
1431 while (widget->parent)
1433 widget = widget->parent;
1434 gtk_container_set_focus_child (GTK_CONTAINER (widget), NULL);
1438 _gtk_window_internal_set_focus (window, NULL);
1443 _gtk_window_internal_set_focus (GtkWindow *window,
1446 g_return_if_fail (GTK_IS_WINDOW (window));
1448 if ((window->focus_widget != focus) ||
1449 (focus && !GTK_WIDGET_HAS_FOCUS (focus)))
1450 g_signal_emit (window, window_signals[SET_FOCUS], 0, focus);
1454 * gtk_window_set_default:
1455 * @window: a #GtkWindow
1456 * @default_widget: widget to be the default, or %NULL to unset the
1457 * default widget for the toplevel.
1459 * The default widget is the widget that's activated when the user
1460 * presses Enter in a dialog (for example). This function sets or
1461 * unsets the default widget for a #GtkWindow about. When setting
1462 * (rather than unsetting) the default widget it's generally easier to
1463 * call gtk_widget_grab_focus() on the widget. Before making a widget
1464 * the default widget, you must set the #GTK_CAN_DEFAULT flag on the
1465 * widget you'd like to make the default using GTK_WIDGET_SET_FLAGS().
1468 gtk_window_set_default (GtkWindow *window,
1469 GtkWidget *default_widget)
1471 g_return_if_fail (GTK_IS_WINDOW (window));
1474 g_return_if_fail (GTK_WIDGET_CAN_DEFAULT (default_widget));
1476 if (window->default_widget != default_widget)
1478 GtkWidget *old_default_widget = NULL;
1481 g_object_ref (default_widget);
1483 if (window->default_widget)
1485 old_default_widget = window->default_widget;
1487 if (window->focus_widget != window->default_widget ||
1488 !GTK_WIDGET_RECEIVES_DEFAULT (window->default_widget))
1489 GTK_WIDGET_UNSET_FLAGS (window->default_widget, GTK_HAS_DEFAULT);
1490 gtk_widget_queue_draw (window->default_widget);
1493 window->default_widget = default_widget;
1495 if (window->default_widget)
1497 if (window->focus_widget == NULL ||
1498 !GTK_WIDGET_RECEIVES_DEFAULT (window->focus_widget))
1499 GTK_WIDGET_SET_FLAGS (window->default_widget, GTK_HAS_DEFAULT);
1500 gtk_widget_queue_draw (window->default_widget);
1503 if (old_default_widget)
1504 g_object_notify (G_OBJECT (old_default_widget), "has-default");
1508 g_object_notify (G_OBJECT (default_widget), "has-default");
1509 g_object_unref (default_widget);
1515 gtk_window_set_policy (GtkWindow *window,
1516 gboolean allow_shrink,
1517 gboolean allow_grow,
1518 gboolean auto_shrink)
1520 g_return_if_fail (GTK_IS_WINDOW (window));
1522 window->allow_shrink = (allow_shrink != FALSE);
1523 window->allow_grow = (allow_grow != FALSE);
1525 g_object_freeze_notify (G_OBJECT (window));
1526 g_object_notify (G_OBJECT (window), "allow-shrink");
1527 g_object_notify (G_OBJECT (window), "allow-grow");
1528 g_object_notify (G_OBJECT (window), "resizable");
1529 g_object_thaw_notify (G_OBJECT (window));
1531 gtk_widget_queue_resize (GTK_WIDGET (window));
1535 handle_keys_changed (gpointer data)
1539 window = GTK_WINDOW (data);
1541 if (window->keys_changed_handler)
1543 g_source_remove (window->keys_changed_handler);
1544 window->keys_changed_handler = 0;
1547 g_signal_emit (window, window_signals[KEYS_CHANGED], 0);
1553 gtk_window_notify_keys_changed (GtkWindow *window)
1555 if (!window->keys_changed_handler)
1556 window->keys_changed_handler = gdk_threads_add_idle (handle_keys_changed, window);
1560 * gtk_window_add_accel_group:
1561 * @window: window to attach accelerator group to
1562 * @accel_group: a #GtkAccelGroup
1564 * Associate @accel_group with @window, such that calling
1565 * gtk_accel_groups_activate() on @window will activate accelerators
1569 gtk_window_add_accel_group (GtkWindow *window,
1570 GtkAccelGroup *accel_group)
1572 g_return_if_fail (GTK_IS_WINDOW (window));
1573 g_return_if_fail (GTK_IS_ACCEL_GROUP (accel_group));
1575 _gtk_accel_group_attach (accel_group, G_OBJECT (window));
1576 g_signal_connect_object (accel_group, "accel_changed",
1577 G_CALLBACK (gtk_window_notify_keys_changed),
1578 window, G_CONNECT_SWAPPED);
1579 gtk_window_notify_keys_changed (window);
1583 * gtk_window_remove_accel_group:
1584 * @window: a #GtkWindow
1585 * @accel_group: a #GtkAccelGroup
1587 * Reverses the effects of gtk_window_add_accel_group().
1590 gtk_window_remove_accel_group (GtkWindow *window,
1591 GtkAccelGroup *accel_group)
1593 g_return_if_fail (GTK_IS_WINDOW (window));
1594 g_return_if_fail (GTK_IS_ACCEL_GROUP (accel_group));
1596 g_signal_handlers_disconnect_by_func (accel_group,
1597 gtk_window_notify_keys_changed,
1599 _gtk_accel_group_detach (accel_group, G_OBJECT (window));
1600 gtk_window_notify_keys_changed (window);
1603 static GtkMnemonicHash *
1604 gtk_window_get_mnemonic_hash (GtkWindow *window,
1607 GtkWindowPrivate *private = GTK_WINDOW_GET_PRIVATE (window);
1608 if (!private->mnemonic_hash && create)
1609 private->mnemonic_hash = _gtk_mnemonic_hash_new ();
1611 return private->mnemonic_hash;
1615 * gtk_window_add_mnemonic:
1616 * @window: a #GtkWindow
1617 * @keyval: the mnemonic
1618 * @target: the widget that gets activated by the mnemonic
1620 * Adds a mnemonic to this window.
1623 gtk_window_add_mnemonic (GtkWindow *window,
1627 g_return_if_fail (GTK_IS_WINDOW (window));
1628 g_return_if_fail (GTK_IS_WIDGET (target));
1630 _gtk_mnemonic_hash_add (gtk_window_get_mnemonic_hash (window, TRUE),
1632 gtk_window_notify_keys_changed (window);
1636 * gtk_window_remove_mnemonic:
1637 * @window: a #GtkWindow
1638 * @keyval: the mnemonic
1639 * @target: the widget that gets activated by the mnemonic
1641 * Removes a mnemonic from this window.
1644 gtk_window_remove_mnemonic (GtkWindow *window,
1648 g_return_if_fail (GTK_IS_WINDOW (window));
1649 g_return_if_fail (GTK_IS_WIDGET (target));
1651 _gtk_mnemonic_hash_remove (gtk_window_get_mnemonic_hash (window, TRUE),
1653 gtk_window_notify_keys_changed (window);
1657 * gtk_window_mnemonic_activate:
1658 * @window: a #GtkWindow
1659 * @keyval: the mnemonic
1660 * @modifier: the modifiers
1661 * @returns: %TRUE if the activation is done.
1663 * Activates the targets associated with the mnemonic.
1666 gtk_window_mnemonic_activate (GtkWindow *window,
1668 GdkModifierType modifier)
1670 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
1672 if (window->mnemonic_modifier == (modifier & gtk_accelerator_get_default_mod_mask ()))
1674 GtkMnemonicHash *mnemonic_hash = gtk_window_get_mnemonic_hash (window, FALSE);
1676 return _gtk_mnemonic_hash_activate (mnemonic_hash, keyval);
1683 * gtk_window_set_mnemonic_modifier:
1684 * @window: a #GtkWindow
1685 * @modifier: the modifier mask used to activate
1686 * mnemonics on this window.
1688 * Sets the mnemonic modifier for this window.
1691 gtk_window_set_mnemonic_modifier (GtkWindow *window,
1692 GdkModifierType modifier)
1694 g_return_if_fail (GTK_IS_WINDOW (window));
1695 g_return_if_fail ((modifier & ~GDK_MODIFIER_MASK) == 0);
1697 window->mnemonic_modifier = modifier;
1698 gtk_window_notify_keys_changed (window);
1702 * gtk_window_get_mnemonic_modifier:
1703 * @window: a #GtkWindow
1705 * Returns the mnemonic modifier for this window. See
1706 * gtk_window_set_mnemonic_modifier().
1708 * Return value: the modifier mask used to activate
1709 * mnemonics on this window.
1712 gtk_window_get_mnemonic_modifier (GtkWindow *window)
1714 g_return_val_if_fail (GTK_IS_WINDOW (window), 0);
1716 return window->mnemonic_modifier;
1720 * gtk_window_set_position:
1721 * @window: a #GtkWindow.
1722 * @position: a position constraint.
1724 * Sets a position constraint for this window. If the old or new
1725 * constraint is %GTK_WIN_POS_CENTER_ALWAYS, this will also cause
1726 * the window to be repositioned to satisfy the new constraint.
1729 gtk_window_set_position (GtkWindow *window,
1730 GtkWindowPosition position)
1732 g_return_if_fail (GTK_IS_WINDOW (window));
1734 if (position == GTK_WIN_POS_CENTER_ALWAYS ||
1735 window->position == GTK_WIN_POS_CENTER_ALWAYS)
1737 GtkWindowGeometryInfo *info;
1739 info = gtk_window_get_geometry_info (window, TRUE);
1741 /* this flag causes us to re-request the CENTER_ALWAYS
1742 * constraint in gtk_window_move_resize(), see
1743 * comment in that function.
1745 info->position_constraints_changed = TRUE;
1747 gtk_widget_queue_resize (GTK_WIDGET (window));
1750 window->position = position;
1752 g_object_notify (G_OBJECT (window), "window-position");
1756 * gtk_window_activate_focus:
1757 * @window: a #GtkWindow
1759 * Activates the current focused widget within the window.
1761 * Return value: %TRUE if a widget got activated.
1764 gtk_window_activate_focus (GtkWindow *window)
1766 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
1768 if (window->focus_widget && GTK_WIDGET_IS_SENSITIVE (window->focus_widget))
1769 return gtk_widget_activate (window->focus_widget);
1775 * gtk_window_get_focus:
1776 * @window: a #GtkWindow
1778 * Retrieves the current focused widget within the window.
1779 * Note that this is the widget that would have the focus
1780 * if the toplevel window focused; if the toplevel window
1781 * is not focused then <literal>GTK_WIDGET_HAS_FOCUS (widget)</literal> will
1782 * not be %TRUE for the widget.
1784 * Return value: the currently focused widget, or %NULL if there is none.
1787 gtk_window_get_focus (GtkWindow *window)
1789 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
1791 return window->focus_widget;
1795 * gtk_window_activate_default:
1796 * @window: a #GtkWindow
1798 * Activates the default widget for the window, unless the current
1799 * focused widget has been configured to receive the default action
1800 * (see #GTK_RECEIVES_DEFAULT in #GtkWidgetFlags), in which case the
1801 * focused widget is activated.
1803 * Return value: %TRUE if a widget got activated.
1806 gtk_window_activate_default (GtkWindow *window)
1808 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
1810 if (window->default_widget && GTK_WIDGET_IS_SENSITIVE (window->default_widget) &&
1811 (!window->focus_widget || !GTK_WIDGET_RECEIVES_DEFAULT (window->focus_widget)))
1812 return gtk_widget_activate (window->default_widget);
1813 else if (window->focus_widget && GTK_WIDGET_IS_SENSITIVE (window->focus_widget))
1814 return gtk_widget_activate (window->focus_widget);
1820 * gtk_window_set_modal:
1821 * @window: a #GtkWindow
1822 * @modal: whether the window is modal
1824 * Sets a window modal or non-modal. Modal windows prevent interaction
1825 * with other windows in the same application. To keep modal dialogs
1826 * on top of main application windows, use
1827 * gtk_window_set_transient_for() to make the dialog transient for the
1828 * parent; most <link linkend="gtk-X11-arch">window managers</link>
1829 * will then disallow lowering the dialog below the parent.
1834 gtk_window_set_modal (GtkWindow *window,
1837 g_return_if_fail (GTK_IS_WINDOW (window));
1839 modal = modal != FALSE;
1840 if (window->modal == modal)
1843 window->modal = modal;
1845 /* adjust desired modality state */
1846 if (GTK_WIDGET_REALIZED (window))
1848 GtkWidget *widget = GTK_WIDGET (window);
1851 gdk_window_set_modal_hint (widget->window, TRUE);
1853 gdk_window_set_modal_hint (widget->window, FALSE);
1856 if (GTK_WIDGET_VISIBLE (window))
1859 gtk_grab_add (GTK_WIDGET (window));
1861 gtk_grab_remove (GTK_WIDGET (window));
1864 g_object_notify (G_OBJECT (window), "modal");
1868 * gtk_window_get_modal:
1869 * @window: a #GtkWindow
1871 * Returns whether the window is modal. See gtk_window_set_modal().
1873 * Return value: %TRUE if the window is set to be modal and
1874 * establishes a grab when shown
1877 gtk_window_get_modal (GtkWindow *window)
1879 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
1881 return window->modal;
1885 * gtk_window_list_toplevels:
1887 * Returns a list of all existing toplevel windows. The widgets
1888 * in the list are not individually referenced. If you want
1889 * to iterate through the list and perform actions involving
1890 * callbacks that might destroy the widgets, you <emphasis>must</emphasis> call
1891 * <literal>g_list_foreach (result, (GFunc)g_object_ref, NULL)</literal> first, and
1892 * then unref all the widgets afterwards.
1894 * Return value: list of toplevel widgets
1897 gtk_window_list_toplevels (void)
1902 for (slist = toplevel_list; slist; slist = slist->next)
1903 list = g_list_prepend (list, slist->data);
1909 gtk_window_add_embedded_xid (GtkWindow *window, guint xid)
1911 GList *embedded_windows;
1913 g_return_if_fail (GTK_IS_WINDOW (window));
1915 embedded_windows = g_object_get_qdata (G_OBJECT (window), quark_gtk_embedded);
1916 if (embedded_windows)
1917 g_object_steal_qdata (G_OBJECT (window), quark_gtk_embedded);
1918 embedded_windows = g_list_prepend (embedded_windows,
1919 GUINT_TO_POINTER (xid));
1921 g_object_set_qdata_full (G_OBJECT (window), quark_gtk_embedded,
1924 (GDestroyNotify) g_list_free : NULL);
1928 gtk_window_remove_embedded_xid (GtkWindow *window, guint xid)
1930 GList *embedded_windows;
1933 g_return_if_fail (GTK_IS_WINDOW (window));
1935 embedded_windows = g_object_get_qdata (G_OBJECT (window), quark_gtk_embedded);
1936 if (embedded_windows)
1937 g_object_steal_qdata (G_OBJECT (window), quark_gtk_embedded);
1939 node = g_list_find (embedded_windows, GUINT_TO_POINTER (xid));
1942 embedded_windows = g_list_remove_link (embedded_windows, node);
1943 g_list_free_1 (node);
1946 g_object_set_qdata_full (G_OBJECT (window), quark_gtk_embedded,
1949 (GDestroyNotify) g_list_free : NULL);
1953 _gtk_window_reposition (GtkWindow *window,
1957 g_return_if_fail (GTK_IS_WINDOW (window));
1959 gtk_window_move (window, x, y);
1963 gtk_window_dispose (GObject *object)
1965 GtkWindow *window = GTK_WINDOW (object);
1967 gtk_window_set_focus (window, NULL);
1968 gtk_window_set_default (window, NULL);
1970 G_OBJECT_CLASS (gtk_window_parent_class)->dispose (object);
1974 parent_destroyed_callback (GtkWindow *parent, GtkWindow *child)
1976 gtk_widget_destroy (GTK_WIDGET (child));
1980 connect_parent_destroyed (GtkWindow *window)
1982 if (window->transient_parent)
1984 g_signal_connect (window->transient_parent,
1986 G_CALLBACK (parent_destroyed_callback),
1992 disconnect_parent_destroyed (GtkWindow *window)
1994 if (window->transient_parent)
1996 g_signal_handlers_disconnect_by_func (window->transient_parent,
1997 parent_destroyed_callback,
2003 gtk_window_transient_parent_realized (GtkWidget *parent,
2006 if (GTK_WIDGET_REALIZED (window))
2007 gdk_window_set_transient_for (window->window, parent->window);
2011 gtk_window_transient_parent_unrealized (GtkWidget *parent,
2014 if (GTK_WIDGET_REALIZED (window))
2015 gdk_property_delete (window->window,
2016 gdk_atom_intern_static_string ("WM_TRANSIENT_FOR"));
2020 gtk_window_transient_parent_screen_changed (GtkWindow *parent,
2024 gtk_window_set_screen (window, parent->screen);
2028 gtk_window_unset_transient_for (GtkWindow *window)
2030 GtkWindowPrivate *priv = GTK_WINDOW_GET_PRIVATE (window);
2032 if (window->transient_parent)
2034 if (priv->transient_parent_group)
2035 gtk_window_group_remove_window (window->group,
2038 g_signal_handlers_disconnect_by_func (window->transient_parent,
2039 gtk_window_transient_parent_realized,
2041 g_signal_handlers_disconnect_by_func (window->transient_parent,
2042 gtk_window_transient_parent_unrealized,
2044 g_signal_handlers_disconnect_by_func (window->transient_parent,
2045 gtk_window_transient_parent_screen_changed,
2047 g_signal_handlers_disconnect_by_func (window->transient_parent,
2048 gtk_widget_destroyed,
2049 &window->transient_parent);
2051 if (window->destroy_with_parent)
2052 disconnect_parent_destroyed (window);
2054 window->transient_parent = NULL;
2055 priv->transient_parent_group = FALSE;
2060 * gtk_window_set_transient_for:
2061 * @window: a #GtkWindow
2062 * @parent: parent window
2064 * Dialog windows should be set transient for the main application
2065 * window they were spawned from. This allows <link
2066 * linkend="gtk-X11-arch">window managers</link> to e.g. keep the
2067 * dialog on top of the main window, or center the dialog over the
2068 * main window. gtk_dialog_new_with_buttons() and other convenience
2069 * functions in GTK+ will sometimes call
2070 * gtk_window_set_transient_for() on your behalf.
2072 * On Windows, this function puts the child window on top of the parent,
2073 * much as the window manager would have done on X.
2077 gtk_window_set_transient_for (GtkWindow *window,
2080 GtkWindowPrivate *priv = GTK_WINDOW_GET_PRIVATE (window);
2082 g_return_if_fail (GTK_IS_WINDOW (window));
2083 g_return_if_fail (parent == NULL || GTK_IS_WINDOW (parent));
2084 g_return_if_fail (window != parent);
2086 if (window->transient_parent)
2088 if (GTK_WIDGET_REALIZED (window) &&
2089 GTK_WIDGET_REALIZED (window->transient_parent) &&
2090 (!parent || !GTK_WIDGET_REALIZED (parent)))
2091 gtk_window_transient_parent_unrealized (GTK_WIDGET (window->transient_parent),
2092 GTK_WIDGET (window));
2094 gtk_window_unset_transient_for (window);
2097 window->transient_parent = parent;
2101 g_signal_connect (parent, "destroy",
2102 G_CALLBACK (gtk_widget_destroyed),
2103 &window->transient_parent);
2104 g_signal_connect (parent, "realize",
2105 G_CALLBACK (gtk_window_transient_parent_realized),
2107 g_signal_connect (parent, "unrealize",
2108 G_CALLBACK (gtk_window_transient_parent_unrealized),
2110 g_signal_connect (parent, "notify::screen",
2111 G_CALLBACK (gtk_window_transient_parent_screen_changed),
2114 gtk_window_set_screen (window, parent->screen);
2116 if (window->destroy_with_parent)
2117 connect_parent_destroyed (window);
2119 if (GTK_WIDGET_REALIZED (window) &&
2120 GTK_WIDGET_REALIZED (parent))
2121 gtk_window_transient_parent_realized (GTK_WIDGET (parent),
2122 GTK_WIDGET (window));
2126 gtk_window_group_add_window (parent->group, window);
2127 priv->transient_parent_group = TRUE;
2133 * gtk_window_get_transient_for:
2134 * @window: a #GtkWindow
2136 * Fetches the transient parent for this window. See
2137 * gtk_window_set_transient_for().
2139 * Return value: the transient parent for this window, or %NULL
2140 * if no transient parent has been set.
2143 gtk_window_get_transient_for (GtkWindow *window)
2145 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
2147 return window->transient_parent;
2151 * gtk_window_set_opacity:
2152 * @window: a #GtkWindow
2153 * @opacity: desired opacity, between 0 and 1
2155 * Request the windowing system to make @window partially transparent,
2156 * with opacity 0 being fully transparent and 1 fully opaque. (Values
2157 * of the opacity parameter are clamped to the [0,1] range.) On X11
2158 * this has any effect only on X screens with a compositing manager
2159 * running. See gtk_widget_is_composited(). On Windows it should work
2162 * Note that setting a window's opacity after the window has been
2163 * shown causes it to flicker once on Windows.
2168 gtk_window_set_opacity (GtkWindow *window,
2171 GtkWindowPrivate *priv;
2173 g_return_if_fail (GTK_IS_WINDOW (window));
2175 priv = GTK_WINDOW_GET_PRIVATE (window);
2179 else if (opacity > 1.0)
2182 priv->opacity_set = TRUE;
2183 priv->opacity = opacity;
2185 if (GTK_WIDGET_REALIZED (window))
2186 gdk_window_set_opacity (GTK_WIDGET (window)->window, priv->opacity);
2190 * gtk_window_get_opacity:
2191 * @window: a #GtkWindow
2193 * Fetches the requested opacity for this window. See
2194 * gtk_window_set_opacity().
2196 * Return value: the requested opacity for this window.
2201 gtk_window_get_opacity (GtkWindow *window)
2203 GtkWindowPrivate *priv;
2205 g_return_val_if_fail (GTK_IS_WINDOW (window), 0.0);
2207 priv = GTK_WINDOW_GET_PRIVATE (window);
2209 return priv->opacity;
2213 * gtk_window_set_type_hint:
2214 * @window: a #GtkWindow
2215 * @hint: the window type
2217 * By setting the type hint for the window, you allow the window
2218 * manager to decorate and handle the window in a way which is
2219 * suitable to the function of the window in your application.
2221 * This function should be called before the window becomes visible.
2223 * gtk_dialog_new_with_buttons() and other convenience functions in GTK+
2224 * will sometimes call gtk_window_set_type_hint() on your behalf.
2228 gtk_window_set_type_hint (GtkWindow *window,
2229 GdkWindowTypeHint hint)
2231 GtkWindowPrivate *priv;
2233 g_return_if_fail (GTK_IS_WINDOW (window));
2234 g_return_if_fail (!GTK_WIDGET_VISIBLE (window));
2236 priv = GTK_WINDOW_GET_PRIVATE (window);
2238 if (hint < GDK_WINDOW_TYPE_HINT_DROPDOWN_MENU)
2239 window->type_hint = hint;
2241 window->type_hint = GDK_WINDOW_TYPE_HINT_NORMAL;
2243 priv->reset_type_hint = TRUE;
2244 priv->type_hint = hint;
2248 * gtk_window_get_type_hint:
2249 * @window: a #GtkWindow
2251 * Gets the type hint for this window. See gtk_window_set_type_hint().
2253 * Return value: the type hint for @window.
2256 gtk_window_get_type_hint (GtkWindow *window)
2258 GtkWindowPrivate *priv;
2260 g_return_val_if_fail (GTK_IS_WINDOW (window), GDK_WINDOW_TYPE_HINT_NORMAL);
2262 priv = GTK_WINDOW_GET_PRIVATE (window);
2264 return priv->type_hint;
2268 * gtk_window_set_skip_taskbar_hint:
2269 * @window: a #GtkWindow
2270 * @setting: %TRUE to keep this window from appearing in the task bar
2272 * Windows may set a hint asking the desktop environment not to display
2273 * the window in the task bar. This function sets this hint.
2278 gtk_window_set_skip_taskbar_hint (GtkWindow *window,
2281 GtkWindowPrivate *priv;
2283 g_return_if_fail (GTK_IS_WINDOW (window));
2285 priv = GTK_WINDOW_GET_PRIVATE (window);
2287 setting = setting != FALSE;
2289 if (priv->skips_taskbar != setting)
2291 priv->skips_taskbar = setting;
2292 if (GTK_WIDGET_REALIZED (window))
2293 gdk_window_set_skip_taskbar_hint (GTK_WIDGET (window)->window,
2294 priv->skips_taskbar);
2295 g_object_notify (G_OBJECT (window), "skip-taskbar-hint");
2300 * gtk_window_get_skip_taskbar_hint:
2301 * @window: a #GtkWindow
2303 * Gets the value set by gtk_window_set_skip_taskbar_hint()
2305 * Return value: %TRUE if window shouldn't be in taskbar
2310 gtk_window_get_skip_taskbar_hint (GtkWindow *window)
2312 GtkWindowPrivate *priv;
2314 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
2316 priv = GTK_WINDOW_GET_PRIVATE (window);
2318 return priv->skips_taskbar;
2322 * gtk_window_set_skip_pager_hint:
2323 * @window: a #GtkWindow
2324 * @setting: %TRUE to keep this window from appearing in the pager
2326 * Windows may set a hint asking the desktop environment not to display
2327 * the window in the pager. This function sets this hint.
2328 * (A "pager" is any desktop navigation tool such as a workspace
2329 * switcher that displays a thumbnail representation of the windows
2335 gtk_window_set_skip_pager_hint (GtkWindow *window,
2338 GtkWindowPrivate *priv;
2340 g_return_if_fail (GTK_IS_WINDOW (window));
2342 priv = GTK_WINDOW_GET_PRIVATE (window);
2344 setting = setting != FALSE;
2346 if (priv->skips_pager != setting)
2348 priv->skips_pager = setting;
2349 if (GTK_WIDGET_REALIZED (window))
2350 gdk_window_set_skip_pager_hint (GTK_WIDGET (window)->window,
2352 g_object_notify (G_OBJECT (window), "skip-pager-hint");
2357 * gtk_window_get_skip_pager_hint:
2358 * @window: a #GtkWindow
2360 * Gets the value set by gtk_window_set_skip_pager_hint().
2362 * Return value: %TRUE if window shouldn't be in pager
2367 gtk_window_get_skip_pager_hint (GtkWindow *window)
2369 GtkWindowPrivate *priv;
2371 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
2373 priv = GTK_WINDOW_GET_PRIVATE (window);
2375 return priv->skips_pager;
2379 * gtk_window_set_urgency_hint:
2380 * @window: a #GtkWindow
2381 * @setting: %TRUE to mark this window as urgent
2383 * Windows may set a hint asking the desktop environment to draw
2384 * the users attention to the window. This function sets this hint.
2389 gtk_window_set_urgency_hint (GtkWindow *window,
2392 GtkWindowPrivate *priv;
2394 g_return_if_fail (GTK_IS_WINDOW (window));
2396 priv = GTK_WINDOW_GET_PRIVATE (window);
2398 setting = setting != FALSE;
2400 if (priv->urgent != setting)
2402 priv->urgent = setting;
2403 if (GTK_WIDGET_REALIZED (window))
2404 gdk_window_set_urgency_hint (GTK_WIDGET (window)->window,
2406 g_object_notify (G_OBJECT (window), "urgency-hint");
2411 * gtk_window_get_urgency_hint:
2412 * @window: a #GtkWindow
2414 * Gets the value set by gtk_window_set_urgency_hint()
2416 * Return value: %TRUE if window is urgent
2421 gtk_window_get_urgency_hint (GtkWindow *window)
2423 GtkWindowPrivate *priv;
2425 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
2427 priv = GTK_WINDOW_GET_PRIVATE (window);
2429 return priv->urgent;
2433 * gtk_window_set_accept_focus:
2434 * @window: a #GtkWindow
2435 * @setting: %TRUE to let this window receive input focus
2437 * Windows may set a hint asking the desktop environment not to receive
2438 * the input focus. This function sets this hint.
2443 gtk_window_set_accept_focus (GtkWindow *window,
2446 GtkWindowPrivate *priv;
2448 g_return_if_fail (GTK_IS_WINDOW (window));
2450 priv = GTK_WINDOW_GET_PRIVATE (window);
2452 setting = setting != FALSE;
2454 if (priv->accept_focus != setting)
2456 priv->accept_focus = setting;
2457 if (GTK_WIDGET_REALIZED (window))
2458 gdk_window_set_accept_focus (GTK_WIDGET (window)->window,
2459 priv->accept_focus);
2460 g_object_notify (G_OBJECT (window), "accept-focus");
2465 * gtk_window_get_accept_focus:
2466 * @window: a #GtkWindow
2468 * Gets the value set by gtk_window_set_accept_focus().
2470 * Return value: %TRUE if window should receive the input focus
2475 gtk_window_get_accept_focus (GtkWindow *window)
2477 GtkWindowPrivate *priv;
2479 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
2481 priv = GTK_WINDOW_GET_PRIVATE (window);
2483 return priv->accept_focus;
2487 * gtk_window_set_focus_on_map:
2488 * @window: a #GtkWindow
2489 * @setting: %TRUE to let this window receive input focus on map
2491 * Windows may set a hint asking the desktop environment not to receive
2492 * the input focus when the window is mapped. This function sets this
2498 gtk_window_set_focus_on_map (GtkWindow *window,
2501 GtkWindowPrivate *priv;
2503 g_return_if_fail (GTK_IS_WINDOW (window));
2505 priv = GTK_WINDOW_GET_PRIVATE (window);
2507 setting = setting != FALSE;
2509 if (priv->focus_on_map != setting)
2511 priv->focus_on_map = setting;
2512 if (GTK_WIDGET_REALIZED (window))
2513 gdk_window_set_focus_on_map (GTK_WIDGET (window)->window,
2514 priv->focus_on_map);
2515 g_object_notify (G_OBJECT (window), "focus-on-map");
2520 * gtk_window_get_focus_on_map:
2521 * @window: a #GtkWindow
2523 * Gets the value set by gtk_window_set_focus_on_map().
2525 * Return value: %TRUE if window should receive the input focus when
2531 gtk_window_get_focus_on_map (GtkWindow *window)
2533 GtkWindowPrivate *priv;
2535 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
2537 priv = GTK_WINDOW_GET_PRIVATE (window);
2539 return priv->focus_on_map;
2543 * gtk_window_set_destroy_with_parent:
2544 * @window: a #GtkWindow
2545 * @setting: whether to destroy @window with its transient parent
2547 * If @setting is %TRUE, then destroying the transient parent of @window
2548 * will also destroy @window itself. This is useful for dialogs that
2549 * shouldn't persist beyond the lifetime of the main window they're
2550 * associated with, for example.
2553 gtk_window_set_destroy_with_parent (GtkWindow *window,
2556 g_return_if_fail (GTK_IS_WINDOW (window));
2558 if (window->destroy_with_parent == (setting != FALSE))
2561 if (window->destroy_with_parent)
2563 disconnect_parent_destroyed (window);
2567 connect_parent_destroyed (window);
2570 window->destroy_with_parent = setting;
2572 g_object_notify (G_OBJECT (window), "destroy-with-parent");
2576 * gtk_window_get_destroy_with_parent:
2577 * @window: a #GtkWindow
2579 * Returns whether the window will be destroyed with its transient parent. See
2580 * gtk_window_set_destroy_with_parent ().
2582 * Return value: %TRUE if the window will be destroyed with its transient parent.
2585 gtk_window_get_destroy_with_parent (GtkWindow *window)
2587 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
2589 return window->destroy_with_parent;
2592 static GtkWindowGeometryInfo*
2593 gtk_window_get_geometry_info (GtkWindow *window,
2596 GtkWindowGeometryInfo *info;
2598 info = window->geometry_info;
2599 if (!info && create)
2601 info = g_new0 (GtkWindowGeometryInfo, 1);
2603 info->default_width = -1;
2604 info->default_height = -1;
2605 info->resize_width = -1;
2606 info->resize_height = -1;
2607 info->initial_x = 0;
2608 info->initial_y = 0;
2609 info->initial_pos_set = FALSE;
2610 info->default_is_geometry = FALSE;
2611 info->position_constraints_changed = FALSE;
2612 info->last.configure_request.x = 0;
2613 info->last.configure_request.y = 0;
2614 info->last.configure_request.width = -1;
2615 info->last.configure_request.height = -1;
2616 info->widget = NULL;
2618 window->geometry_info = info;
2625 * gtk_window_set_geometry_hints:
2626 * @window: a #GtkWindow
2627 * @geometry_widget: widget the geometry hints will be applied to
2628 * @geometry: struct containing geometry information
2629 * @geom_mask: mask indicating which struct fields should be paid attention to
2631 * This function sets up hints about how a window can be resized by
2632 * the user. You can set a minimum and maximum size; allowed resize
2633 * increments (e.g. for xterm, you can only resize by the size of a
2634 * character); aspect ratios; and more. See the #GdkGeometry struct.
2638 gtk_window_set_geometry_hints (GtkWindow *window,
2639 GtkWidget *geometry_widget,
2640 GdkGeometry *geometry,
2641 GdkWindowHints geom_mask)
2643 GtkWindowGeometryInfo *info;
2645 g_return_if_fail (GTK_IS_WINDOW (window));
2646 g_return_if_fail (geometry_widget == NULL || GTK_IS_WIDGET (geometry_widget));
2648 info = gtk_window_get_geometry_info (window, TRUE);
2651 g_signal_handlers_disconnect_by_func (info->widget,
2652 gtk_widget_destroyed,
2655 info->widget = geometry_widget;
2657 g_signal_connect (geometry_widget, "destroy",
2658 G_CALLBACK (gtk_widget_destroyed),
2662 info->geometry = *geometry;
2664 /* We store gravity in window->gravity not in the hints. */
2665 info->mask = geom_mask & ~(GDK_HINT_WIN_GRAVITY);
2667 if (geom_mask & GDK_HINT_WIN_GRAVITY)
2669 gtk_window_set_gravity (window, geometry->win_gravity);
2672 gtk_widget_queue_resize (GTK_WIDGET (window));
2676 * gtk_window_set_decorated:
2677 * @window: a #GtkWindow
2678 * @setting: %TRUE to decorate the window
2680 * By default, windows are decorated with a title bar, resize
2681 * controls, etc. Some <link linkend="gtk-X11-arch">window
2682 * managers</link> allow GTK+ to disable these decorations, creating a
2683 * borderless window. If you set the decorated property to %FALSE
2684 * using this function, GTK+ will do its best to convince the window
2685 * manager not to decorate the window. Depending on the system, this
2686 * function may not have any effect when called on a window that is
2687 * already visible, so you should call it before calling gtk_window_show().
2689 * On Windows, this function always works, since there's no window manager
2694 gtk_window_set_decorated (GtkWindow *window,
2697 g_return_if_fail (GTK_IS_WINDOW (window));
2699 setting = setting != FALSE;
2701 if (setting == window->decorated)
2704 window->decorated = setting;
2706 if (GTK_WIDGET (window)->window)
2708 if (window->decorated)
2709 gdk_window_set_decorations (GTK_WIDGET (window)->window,
2712 gdk_window_set_decorations (GTK_WIDGET (window)->window,
2716 g_object_notify (G_OBJECT (window), "decorated");
2720 * gtk_window_get_decorated:
2721 * @window: a #GtkWindow
2723 * Returns whether the window has been set to have decorations
2724 * such as a title bar via gtk_window_set_decorated().
2726 * Return value: %TRUE if the window has been set to have decorations
2729 gtk_window_get_decorated (GtkWindow *window)
2731 g_return_val_if_fail (GTK_IS_WINDOW (window), TRUE);
2733 return window->decorated;
2737 * gtk_window_set_deletable:
2738 * @window: a #GtkWindow
2739 * @setting: %TRUE to decorate the window as deletable
2741 * By default, windows have a close button in the window frame. Some
2742 * <link linkend="gtk-X11-arch">window managers</link> allow GTK+ to
2743 * disable this button. If you set the deletable property to %FALSE
2744 * using this function, GTK+ will do its best to convince the window
2745 * manager not to show a close button. Depending on the system, this
2746 * function may not have any effect when called on a window that is
2747 * already visible, so you should call it before calling gtk_window_show().
2749 * On Windows, this function always works, since there's no window manager
2755 gtk_window_set_deletable (GtkWindow *window,
2758 GtkWindowPrivate *priv;
2760 g_return_if_fail (GTK_IS_WINDOW (window));
2762 priv = GTK_WINDOW_GET_PRIVATE (window);
2764 setting = setting != FALSE;
2766 if (setting == priv->deletable)
2769 priv->deletable = setting;
2771 if (GTK_WIDGET (window)->window)
2773 if (priv->deletable)
2774 gdk_window_set_functions (GTK_WIDGET (window)->window,
2777 gdk_window_set_functions (GTK_WIDGET (window)->window,
2778 GDK_FUNC_ALL | GDK_FUNC_CLOSE);
2781 g_object_notify (G_OBJECT (window), "deletable");
2785 * gtk_window_get_deletable:
2786 * @window: a #GtkWindow
2788 * Returns whether the window has been set to have a close button
2789 * via gtk_window_set_deletable().
2791 * Return value: %TRUE if the window has been set to have a close button
2796 gtk_window_get_deletable (GtkWindow *window)
2798 GtkWindowPrivate *priv;
2800 g_return_val_if_fail (GTK_IS_WINDOW (window), TRUE);
2802 priv = GTK_WINDOW_GET_PRIVATE (window);
2804 return priv->deletable;
2807 static GtkWindowIconInfo*
2808 get_icon_info (GtkWindow *window)
2810 return g_object_get_qdata (G_OBJECT (window), quark_gtk_window_icon_info);
2814 free_icon_info (GtkWindowIconInfo *info)
2816 g_free (info->icon_name);
2817 g_slice_free (GtkWindowIconInfo, info);
2821 static GtkWindowIconInfo*
2822 ensure_icon_info (GtkWindow *window)
2824 GtkWindowIconInfo *info;
2826 info = get_icon_info (window);
2830 info = g_slice_new0 (GtkWindowIconInfo);
2831 g_object_set_qdata_full (G_OBJECT (window),
2832 quark_gtk_window_icon_info,
2834 (GDestroyNotify)free_icon_info);
2846 static ScreenIconInfo *
2847 get_screen_icon_info (GdkScreen *screen)
2849 ScreenIconInfo *info = g_object_get_qdata (G_OBJECT (screen),
2850 quark_gtk_window_default_icon_pixmap);
2853 info = g_slice_new0 (ScreenIconInfo);
2854 g_object_set_qdata (G_OBJECT (screen),
2855 quark_gtk_window_default_icon_pixmap, info);
2858 if (info->serial != default_icon_serial)
2862 g_object_remove_weak_pointer (G_OBJECT (info->pixmap), (gpointer*)&info->pixmap);
2863 info->pixmap = NULL;
2868 g_object_remove_weak_pointer (G_OBJECT (info->mask), (gpointer*)&info->mask);
2872 info->serial = default_icon_serial;
2879 get_pixmap_and_mask (GdkWindow *window,
2880 GtkWindowIconInfo *parent_info,
2881 gboolean is_default_list,
2883 GdkPixmap **pmap_return,
2884 GdkBitmap **mask_return)
2886 GdkScreen *screen = gdk_drawable_get_screen (window);
2887 ScreenIconInfo *default_icon_info = get_screen_icon_info (screen);
2888 GdkPixbuf *best_icon;
2892 *pmap_return = NULL;
2893 *mask_return = NULL;
2895 if (is_default_list &&
2896 default_icon_info->pixmap != NULL)
2898 /* Use shared icon pixmap for all windows on this screen.
2900 if (default_icon_info->pixmap)
2901 g_object_ref (default_icon_info->pixmap);
2902 if (default_icon_info->mask)
2903 g_object_ref (default_icon_info->mask);
2905 *pmap_return = default_icon_info->pixmap;
2906 *mask_return = default_icon_info->mask;
2908 else if (parent_info && parent_info->icon_pixmap)
2910 if (parent_info->icon_pixmap)
2911 g_object_ref (parent_info->icon_pixmap);
2912 if (parent_info->icon_mask)
2913 g_object_ref (parent_info->icon_mask);
2915 *pmap_return = parent_info->icon_pixmap;
2916 *mask_return = parent_info->icon_mask;
2920 #define IDEAL_SIZE 48
2922 best_size = G_MAXINT;
2924 tmp_list = icon_list;
2925 while (tmp_list != NULL)
2927 GdkPixbuf *pixbuf = tmp_list->data;
2930 /* average width and height - if someone passes in a rectangular
2931 * icon they deserve what they get.
2933 this = gdk_pixbuf_get_width (pixbuf) + gdk_pixbuf_get_height (pixbuf);
2936 if (best_icon == NULL)
2943 /* icon is better if it's 32 pixels or larger, and closer to
2944 * the ideal size than the current best.
2947 (ABS (best_size - IDEAL_SIZE) <
2948 ABS (this - IDEAL_SIZE)))
2955 tmp_list = tmp_list->next;
2959 gdk_pixbuf_render_pixmap_and_mask_for_colormap (best_icon,
2960 gdk_screen_get_system_colormap (screen),
2965 /* Save pmap/mask for others to use if appropriate */
2968 parent_info->icon_pixmap = *pmap_return;
2969 parent_info->icon_mask = *mask_return;
2971 if (parent_info->icon_pixmap)
2972 g_object_ref (parent_info->icon_pixmap);
2973 if (parent_info->icon_mask)
2974 g_object_ref (parent_info->icon_mask);
2976 else if (is_default_list)
2978 default_icon_info->pixmap = *pmap_return;
2979 default_icon_info->mask = *mask_return;
2981 if (default_icon_info->pixmap)
2982 g_object_add_weak_pointer (G_OBJECT (default_icon_info->pixmap),
2983 (gpointer*)&default_icon_info->pixmap);
2984 if (default_icon_info->mask)
2985 g_object_add_weak_pointer (G_OBJECT (default_icon_info->mask),
2986 (gpointer*)&default_icon_info->mask);
2992 icon_list_from_theme (GtkWidget *widget,
2997 GtkIconTheme *icon_theme;
3002 icon_theme = gtk_icon_theme_get_for_screen (gtk_widget_get_screen (widget));
3004 sizes = gtk_icon_theme_get_icon_sizes (icon_theme, name);
3007 for (i = 0; sizes[i]; i++)
3010 * We need an EWMH extension to handle scalable icons
3011 * by passing their name to the WM. For now just use a
3015 icon = gtk_icon_theme_load_icon (icon_theme, name,
3018 icon = gtk_icon_theme_load_icon (icon_theme, name,
3021 list = g_list_append (list, icon);
3031 gtk_window_realize_icon (GtkWindow *window)
3034 GtkWindowIconInfo *info;
3037 widget = GTK_WIDGET (window);
3039 g_return_if_fail (widget->window != NULL);
3041 /* no point setting an icon on override-redirect */
3042 if (window->type == GTK_WINDOW_POPUP)
3047 info = ensure_icon_info (window);
3052 g_return_if_fail (info->icon_pixmap == NULL);
3053 g_return_if_fail (info->icon_mask == NULL);
3055 info->using_default_icon = FALSE;
3056 info->using_parent_icon = FALSE;
3057 info->using_themed_icon = FALSE;
3059 icon_list = info->icon_list;
3061 /* Look up themed icon */
3062 if (icon_list == NULL && info->icon_name)
3064 icon_list = icon_list_from_theme (widget, info->icon_name);
3066 info->using_themed_icon = TRUE;
3069 /* Inherit from transient parent */
3070 if (icon_list == NULL && window->transient_parent)
3072 icon_list = ensure_icon_info (window->transient_parent)->icon_list;
3074 info->using_parent_icon = TRUE;
3077 /* Inherit from default */
3078 if (icon_list == NULL)
3080 icon_list = default_icon_list;
3082 info->using_default_icon = TRUE;
3085 /* Look up themed icon */
3086 if (icon_list == NULL && default_icon_name)
3088 icon_list = icon_list_from_theme (widget, default_icon_name);
3089 info->using_default_icon = TRUE;
3090 info->using_themed_icon = TRUE;
3093 gdk_window_set_icon_list (widget->window, icon_list);
3095 get_pixmap_and_mask (widget->window,
3096 info->using_parent_icon ? ensure_icon_info (window->transient_parent) : NULL,
3097 info->using_default_icon,
3102 /* This is a slight ICCCM violation since it's a color pixmap not
3103 * a bitmap, but everyone does it.
3105 gdk_window_set_icon (widget->window,
3110 info->realized = TRUE;
3112 if (info->using_themed_icon)
3114 GtkIconTheme *icon_theme;
3116 g_list_foreach (icon_list, (GFunc) g_object_unref, NULL);
3117 g_list_free (icon_list);
3119 icon_theme = gtk_icon_theme_get_for_screen (gtk_widget_get_screen (GTK_WIDGET (window)));
3120 g_signal_connect (icon_theme, "changed",
3121 G_CALLBACK (update_themed_icon), window);
3126 gtk_window_unrealize_icon (GtkWindow *window)
3128 GtkWindowIconInfo *info;
3130 info = get_icon_info (window);
3135 if (info->icon_pixmap)
3136 g_object_unref (info->icon_pixmap);
3138 if (info->icon_mask)
3139 g_object_unref (info->icon_mask);
3141 info->icon_pixmap = NULL;
3142 info->icon_mask = NULL;
3144 if (info->using_themed_icon)
3146 GtkIconTheme *icon_theme;
3148 icon_theme = gtk_icon_theme_get_for_screen (gtk_widget_get_screen (GTK_WIDGET (window)));
3150 g_signal_handlers_disconnect_by_func (icon_theme, update_themed_icon, window);
3153 /* We don't clear the properties on the window, just figure the
3154 * window is going away.
3157 info->realized = FALSE;
3162 * gtk_window_set_icon_list:
3163 * @window: a #GtkWindow
3164 * @list: list of #GdkPixbuf
3166 * Sets up the icon representing a #GtkWindow. The icon is used when
3167 * the window is minimized (also known as iconified). Some window
3168 * managers or desktop environments may also place it in the window
3169 * frame, or display it in other contexts.
3171 * gtk_window_set_icon_list() allows you to pass in the same icon in
3172 * several hand-drawn sizes. The list should contain the natural sizes
3173 * your icon is available in; that is, don't scale the image before
3174 * passing it to GTK+. Scaling is postponed until the last minute,
3175 * when the desired final size is known, to allow best quality.
3177 * By passing several sizes, you may improve the final image quality
3178 * of the icon, by reducing or eliminating automatic image scaling.
3180 * Recommended sizes to provide: 16x16, 32x32, 48x48 at minimum, and
3181 * larger images (64x64, 128x128) if you have them.
3183 * See also gtk_window_set_default_icon_list() to set the icon
3184 * for all windows in your application in one go.
3186 * Note that transient windows (those who have been set transient for another
3187 * window using gtk_window_set_transient_for()) will inherit their
3188 * icon from their transient parent. So there's no need to explicitly
3189 * set the icon on transient windows.
3192 gtk_window_set_icon_list (GtkWindow *window,
3195 GtkWindowIconInfo *info;
3197 g_return_if_fail (GTK_IS_WINDOW (window));
3199 info = ensure_icon_info (window);
3201 if (info->icon_list == list) /* check for NULL mostly */
3204 g_list_foreach (list,
3205 (GFunc) g_object_ref, NULL);
3207 g_list_foreach (info->icon_list,
3208 (GFunc) g_object_unref, NULL);
3210 g_list_free (info->icon_list);
3212 info->icon_list = g_list_copy (list);
3214 g_object_notify (G_OBJECT (window), "icon");
3216 gtk_window_unrealize_icon (window);
3218 if (GTK_WIDGET_REALIZED (window))
3219 gtk_window_realize_icon (window);
3221 /* We could try to update our transient children, but I don't think
3222 * it's really worth it. If we did it, the best way would probably
3223 * be to have children connect to notify::icon-list
3228 * gtk_window_get_icon_list:
3229 * @window: a #GtkWindow
3231 * Retrieves the list of icons set by gtk_window_set_icon_list().
3232 * The list is copied, but the reference count on each
3233 * member won't be incremented.
3235 * Return value: copy of window's icon list
3238 gtk_window_get_icon_list (GtkWindow *window)
3240 GtkWindowIconInfo *info;
3242 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
3244 info = get_icon_info (window);
3247 return g_list_copy (info->icon_list);
3253 * gtk_window_set_icon:
3254 * @window: a #GtkWindow
3255 * @icon: icon image, or %NULL
3257 * Sets up the icon representing a #GtkWindow. This icon is used when
3258 * the window is minimized (also known as iconified). Some window
3259 * managers or desktop environments may also place it in the window
3260 * frame, or display it in other contexts.
3262 * The icon should be provided in whatever size it was naturally
3263 * drawn; that is, don't scale the image before passing it to
3264 * GTK+. Scaling is postponed until the last minute, when the desired
3265 * final size is known, to allow best quality.
3267 * If you have your icon hand-drawn in multiple sizes, use
3268 * gtk_window_set_icon_list(). Then the best size will be used.
3270 * This function is equivalent to calling gtk_window_set_icon_list()
3271 * with a 1-element list.
3273 * See also gtk_window_set_default_icon_list() to set the icon
3274 * for all windows in your application in one go.
3277 gtk_window_set_icon (GtkWindow *window,
3282 g_return_if_fail (GTK_IS_WINDOW (window));
3283 g_return_if_fail (icon == NULL || GDK_IS_PIXBUF (icon));
3288 list = g_list_append (list, icon);
3290 gtk_window_set_icon_list (window, list);
3296 update_themed_icon (GtkIconTheme *icon_theme,
3299 g_object_notify (G_OBJECT (window), "icon");
3301 gtk_window_unrealize_icon (window);
3303 if (GTK_WIDGET_REALIZED (window))
3304 gtk_window_realize_icon (window);
3308 * gtk_window_set_icon_name:
3309 * @window: a #GtkWindow
3310 * @name: the name of the themed icon
3312 * Sets the icon for the window from a named themed icon. See
3313 * the docs for #GtkIconTheme for more details.
3315 * Note that this has nothing to do with the WM_ICON_NAME
3316 * property which is mentioned in the ICCCM.
3321 gtk_window_set_icon_name (GtkWindow *window,
3324 GtkWindowIconInfo *info;
3327 g_return_if_fail (GTK_IS_WINDOW (window));
3329 info = ensure_icon_info (window);
3331 tmp = info->icon_name;
3332 info->icon_name = g_strdup (name);
3335 g_list_foreach (info->icon_list, (GFunc) g_object_unref, NULL);
3336 g_list_free (info->icon_list);
3337 info->icon_list = NULL;
3339 update_themed_icon (NULL, window);
3341 g_object_notify (G_OBJECT (window), "icon-name");
3345 * gtk_window_get_icon_name:
3346 * @window: a #GtkWindow
3348 * Returns the name of the themed icon for the window,
3349 * see gtk_window_set_icon_name().
3351 * Returns: the icon name or %NULL if the window has
3356 G_CONST_RETURN gchar *
3357 gtk_window_get_icon_name (GtkWindow *window)
3359 GtkWindowIconInfo *info;
3361 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
3363 info = ensure_icon_info (window);
3365 return info->icon_name;
3369 * gtk_window_get_icon:
3370 * @window: a #GtkWindow
3372 * Gets the value set by gtk_window_set_icon() (or if you've
3373 * called gtk_window_set_icon_list(), gets the first icon in
3376 * Return value: icon for window
3379 gtk_window_get_icon (GtkWindow *window)
3381 GtkWindowIconInfo *info;
3383 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
3385 info = get_icon_info (window);
3386 if (info && info->icon_list)
3387 return GDK_PIXBUF (info->icon_list->data);
3392 /* Load pixbuf, printing warning on failure if error == NULL
3395 load_pixbuf_verbosely (const char *filename,
3398 GError *local_err = NULL;
3401 pixbuf = gdk_pixbuf_new_from_file (filename, &local_err);
3409 g_warning ("Error loading icon from file '%s':\n\t%s",
3410 filename, local_err->message);
3411 g_error_free (local_err);
3419 * gtk_window_set_icon_from_file:
3420 * @window: a #GtkWindow
3421 * @filename: location of icon file
3422 * @err: location to store error, or %NULL.
3424 * Sets the icon for @window.
3425 * Warns on failure if @err is %NULL.
3427 * This function is equivalent to calling gtk_window_set_icon()
3428 * with a pixbuf created by loading the image from @filename.
3430 * Returns: %TRUE if setting the icon succeeded.
3435 gtk_window_set_icon_from_file (GtkWindow *window,
3436 const gchar *filename,
3439 GdkPixbuf *pixbuf = load_pixbuf_verbosely (filename, err);
3443 gtk_window_set_icon (window, pixbuf);
3444 g_object_unref (pixbuf);
3453 * gtk_window_set_default_icon_list:
3454 * @list: a list of #GdkPixbuf
3456 * Sets an icon list to be used as fallback for windows that haven't
3457 * had gtk_window_set_icon_list() called on them to set up a
3458 * window-specific icon list. This function allows you to set up the
3459 * icon for all windows in your app at once.
3461 * See gtk_window_set_icon_list() for more details.
3465 gtk_window_set_default_icon_list (GList *list)
3469 if (list == default_icon_list)
3472 /* Update serial so we don't used cached pixmaps/masks
3474 default_icon_serial++;
3476 g_list_foreach (list,
3477 (GFunc) g_object_ref, NULL);
3479 g_list_foreach (default_icon_list,
3480 (GFunc) g_object_unref, NULL);
3482 g_list_free (default_icon_list);
3484 default_icon_list = g_list_copy (list);
3486 /* Update all toplevels */
3487 toplevels = gtk_window_list_toplevels ();
3488 tmp_list = toplevels;
3489 while (tmp_list != NULL)
3491 GtkWindowIconInfo *info;
3492 GtkWindow *w = tmp_list->data;
3494 info = get_icon_info (w);
3495 if (info && info->using_default_icon)
3497 gtk_window_unrealize_icon (w);
3498 if (GTK_WIDGET_REALIZED (w))
3499 gtk_window_realize_icon (w);
3502 tmp_list = tmp_list->next;
3504 g_list_free (toplevels);
3508 * gtk_window_set_default_icon:
3511 * Sets an icon to be used as fallback for windows that haven't
3512 * had gtk_window_set_icon() called on them from a pixbuf.
3517 gtk_window_set_default_icon (GdkPixbuf *icon)
3521 g_return_if_fail (GDK_IS_PIXBUF (icon));
3523 list = g_list_prepend (NULL, icon);
3524 gtk_window_set_default_icon_list (list);
3529 * gtk_window_set_default_icon_name:
3530 * @name: the name of the themed icon
3532 * Sets an icon to be used as fallback for windows that haven't
3533 * had gtk_window_set_icon_list() called on them from a named
3534 * themed icon, see gtk_window_set_icon_name().
3539 gtk_window_set_default_icon_name (const gchar *name)
3544 /* Update serial so we don't used cached pixmaps/masks
3546 default_icon_serial++;
3548 g_free (default_icon_name);
3549 default_icon_name = g_strdup (name);
3551 g_list_foreach (default_icon_list,
3552 (GFunc) g_object_unref, NULL);
3554 g_list_free (default_icon_list);
3555 default_icon_list = NULL;
3557 /* Update all toplevels */
3558 toplevels = gtk_window_list_toplevels ();
3559 tmp_list = toplevels;
3560 while (tmp_list != NULL)
3562 GtkWindowIconInfo *info;
3563 GtkWindow *w = tmp_list->data;
3565 info = get_icon_info (w);
3566 if (info && info->using_default_icon && info->using_themed_icon)
3568 gtk_window_unrealize_icon (w);
3569 if (GTK_WIDGET_REALIZED (w))
3570 gtk_window_realize_icon (w);
3573 tmp_list = tmp_list->next;
3575 g_list_free (toplevels);
3579 * gtk_window_set_default_icon_from_file:
3580 * @filename: location of icon file
3581 * @err: location to store error, or %NULL.
3583 * Sets an icon to be used as fallback for windows that haven't
3584 * had gtk_window_set_icon_list() called on them from a file
3585 * on disk. Warns on failure if @err is %NULL.
3587 * Returns: %TRUE if setting the icon succeeded.
3592 gtk_window_set_default_icon_from_file (const gchar *filename,
3595 GdkPixbuf *pixbuf = load_pixbuf_verbosely (filename, err);
3599 gtk_window_set_default_icon (pixbuf);
3600 g_object_unref (pixbuf);
3609 * gtk_window_get_default_icon_list:
3611 * Gets the value set by gtk_window_set_default_icon_list().
3612 * The list is a copy and should be freed with g_list_free(),
3613 * but the pixbufs in the list have not had their reference count
3616 * Return value: copy of default icon list
3619 gtk_window_get_default_icon_list (void)
3621 return g_list_copy (default_icon_list);
3625 gtk_window_set_default_size_internal (GtkWindow *window,
3626 gboolean change_width,
3628 gboolean change_height,
3630 gboolean is_geometry)
3632 GtkWindowGeometryInfo *info;
3634 g_return_if_fail (change_width == FALSE || width >= -1);
3635 g_return_if_fail (change_height == FALSE || height >= -1);
3637 info = gtk_window_get_geometry_info (window, TRUE);
3639 g_object_freeze_notify (G_OBJECT (window));
3641 info->default_is_geometry = is_geometry != FALSE;
3651 info->default_width = width;
3653 g_object_notify (G_OBJECT (window), "default-width");
3664 info->default_height = height;
3666 g_object_notify (G_OBJECT (window), "default-height");
3669 g_object_thaw_notify (G_OBJECT (window));
3671 gtk_widget_queue_resize (GTK_WIDGET (window));
3675 * gtk_window_set_default_size:
3676 * @window: a #GtkWindow
3677 * @width: width in pixels, or -1 to unset the default width
3678 * @height: height in pixels, or -1 to unset the default height
3680 * Sets the default size of a window. If the window's "natural" size
3681 * (its size request) is larger than the default, the default will be
3682 * ignored. More generally, if the default size does not obey the
3683 * geometry hints for the window (gtk_window_set_geometry_hints() can
3684 * be used to set these explicitly), the default size will be clamped
3685 * to the nearest permitted size.
3687 * Unlike gtk_widget_set_size_request(), which sets a size request for
3688 * a widget and thus would keep users from shrinking the window, this
3689 * function only sets the initial size, just as if the user had
3690 * resized the window themselves. Users can still shrink the window
3691 * again as they normally would. Setting a default size of -1 means to
3692 * use the "natural" default size (the size request of the window).
3694 * For more control over a window's initial size and how resizing works,
3695 * investigate gtk_window_set_geometry_hints().
3697 * For some uses, gtk_window_resize() is a more appropriate function.
3698 * gtk_window_resize() changes the current size of the window, rather
3699 * than the size to be used on initial display. gtk_window_resize() always
3700 * affects the window itself, not the geometry widget.
3702 * The default size of a window only affects the first time a window is
3703 * shown; if a window is hidden and re-shown, it will remember the size
3704 * it had prior to hiding, rather than using the default size.
3706 * Windows can't actually be 0x0 in size, they must be at least 1x1, but
3707 * passing 0 for @width and @height is OK, resulting in a 1x1 default size.
3710 gtk_window_set_default_size (GtkWindow *window,
3714 g_return_if_fail (GTK_IS_WINDOW (window));
3715 g_return_if_fail (width >= -1);
3716 g_return_if_fail (height >= -1);
3718 gtk_window_set_default_size_internal (window, TRUE, width, TRUE, height, FALSE);
3722 * gtk_window_get_default_size:
3723 * @window: a #GtkWindow
3724 * @width: location to store the default width, or %NULL
3725 * @height: location to store the default height, or %NULL
3727 * Gets the default size of the window. A value of -1 for the width or
3728 * height indicates that a default size has not been explicitly set
3729 * for that dimension, so the "natural" size of the window will be
3734 gtk_window_get_default_size (GtkWindow *window,
3738 GtkWindowGeometryInfo *info;
3740 g_return_if_fail (GTK_IS_WINDOW (window));
3742 info = gtk_window_get_geometry_info (window, FALSE);
3745 *width = info ? info->default_width : -1;
3748 *height = info ? info->default_height : -1;
3752 * gtk_window_resize:
3753 * @window: a #GtkWindow
3754 * @width: width in pixels to resize the window to
3755 * @height: height in pixels to resize the window to
3757 * Resizes the window as if the user had done so, obeying geometry
3758 * constraints. The default geometry constraint is that windows may
3759 * not be smaller than their size request; to override this
3760 * constraint, call gtk_widget_set_size_request() to set the window's
3761 * request to a smaller value.
3763 * If gtk_window_resize() is called before showing a window for the
3764 * first time, it overrides any default size set with
3765 * gtk_window_set_default_size().
3767 * Windows may not be resized smaller than 1 by 1 pixels.
3771 gtk_window_resize (GtkWindow *window,
3775 GtkWindowGeometryInfo *info;
3777 g_return_if_fail (GTK_IS_WINDOW (window));
3778 g_return_if_fail (width > 0);
3779 g_return_if_fail (height > 0);
3781 info = gtk_window_get_geometry_info (window, TRUE);
3783 info->resize_width = width;
3784 info->resize_height = height;
3786 gtk_widget_queue_resize (GTK_WIDGET (window));
3790 * gtk_window_get_size:
3791 * @window: a #GtkWindow
3792 * @width: return location for width, or %NULL
3793 * @height: return location for height, or %NULL
3795 * Obtains the current size of @window. If @window is not onscreen,
3796 * it returns the size GTK+ will suggest to the <link
3797 * linkend="gtk-X11-arch">window manager</link> for the initial window
3798 * size (but this is not reliably the same as the size the window
3799 * manager will actually select). The size obtained by
3800 * gtk_window_get_size() is the last size received in a
3801 * #GdkEventConfigure, that is, GTK+ uses its locally-stored size,
3802 * rather than querying the X server for the size. As a result, if you
3803 * call gtk_window_resize() then immediately call
3804 * gtk_window_get_size(), the size won't have taken effect yet. After
3805 * the window manager processes the resize request, GTK+ receives
3806 * notification that the size has changed via a configure event, and
3807 * the size of the window gets updated.
3809 * Note 1: Nearly any use of this function creates a race condition,
3810 * because the size of the window may change between the time that you
3811 * get the size and the time that you perform some action assuming
3812 * that size is the current size. To avoid race conditions, connect to
3813 * "configure_event" on the window and adjust your size-dependent
3814 * state to match the size delivered in the #GdkEventConfigure.
3816 * Note 2: The returned size does <emphasis>not</emphasis> include the
3817 * size of the window manager decorations (aka the window frame or
3818 * border). Those are not drawn by GTK+ and GTK+ has no reliable
3819 * method of determining their size.
3821 * Note 3: If you are getting a window size in order to position
3822 * the window onscreen, there may be a better way. The preferred
3823 * way is to simply set the window's semantic type with
3824 * gtk_window_set_type_hint(), which allows the window manager to
3825 * e.g. center dialogs. Also, if you set the transient parent of
3826 * dialogs with gtk_window_set_transient_for() window managers
3827 * will often center the dialog over its parent window. It's
3828 * much preferred to let the window manager handle these
3829 * things rather than doing it yourself, because all apps will
3830 * behave consistently and according to user prefs if the window
3831 * manager handles it. Also, the window manager can take the size
3832 * of the window decorations/border into account, while your
3833 * application cannot.
3835 * In any case, if you insist on application-specified window
3836 * positioning, there's <emphasis>still</emphasis> a better way than
3837 * doing it yourself - gtk_window_set_position() will frequently
3838 * handle the details for you.
3842 gtk_window_get_size (GtkWindow *window,
3848 g_return_if_fail (GTK_IS_WINDOW (window));
3850 if (width == NULL && height == NULL)
3853 if (GTK_WIDGET_MAPPED (window))
3855 gdk_drawable_get_size (GTK_WIDGET (window)->window,
3860 GdkRectangle configure_request;
3862 gtk_window_compute_configure_request (window,
3866 w = configure_request.width;
3867 h = configure_request.height;
3878 * @window: a #GtkWindow
3879 * @x: X coordinate to move window to
3880 * @y: Y coordinate to move window to
3882 * Asks the <link linkend="gtk-X11-arch">window manager</link> to move
3883 * @window to the given position. Window managers are free to ignore
3884 * this; most window managers ignore requests for initial window
3885 * positions (instead using a user-defined placement algorithm) and
3886 * honor requests after the window has already been shown.
3888 * Note: the position is the position of the gravity-determined
3889 * reference point for the window. The gravity determines two things:
3890 * first, the location of the reference point in root window
3891 * coordinates; and second, which point on the window is positioned at
3892 * the reference point.
3894 * By default the gravity is #GDK_GRAVITY_NORTH_WEST, so the reference
3895 * point is simply the @x, @y supplied to gtk_window_move(). The
3896 * top-left corner of the window decorations (aka window frame or
3897 * border) will be placed at @x, @y. Therefore, to position a window
3898 * at the top left of the screen, you want to use the default gravity
3899 * (which is #GDK_GRAVITY_NORTH_WEST) and move the window to 0,0.
3901 * To position a window at the bottom right corner of the screen, you
3902 * would set #GDK_GRAVITY_SOUTH_EAST, which means that the reference
3903 * point is at @x + the window width and @y + the window height, and
3904 * the bottom-right corner of the window border will be placed at that
3905 * reference point. So, to place a window in the bottom right corner
3906 * you would first set gravity to south east, then write:
3907 * <literal>gtk_window_move (window, gdk_screen_width () - window_width,
3908 * gdk_screen_height () - window_height)</literal> (note that this
3909 * example does not take multi-head scenarios into account).
3911 * The Extended Window Manager Hints specification at <ulink
3912 * url="http://www.freedesktop.org/Standards/wm-spec">
3913 * http://www.freedesktop.org/Standards/wm-spec</ulink> has a
3914 * nice table of gravities in the "implementation notes" section.
3916 * The gtk_window_get_position() documentation may also be relevant.
3919 gtk_window_move (GtkWindow *window,
3923 GtkWindowGeometryInfo *info;
3926 g_return_if_fail (GTK_IS_WINDOW (window));
3928 widget = GTK_WIDGET (window);
3930 info = gtk_window_get_geometry_info (window, TRUE);
3932 if (GTK_WIDGET_MAPPED (window))
3934 /* we have now sent a request with this position
3935 * with currently-active constraints, so toggle flag.
3937 info->position_constraints_changed = FALSE;
3939 /* we only constrain if mapped - if not mapped,
3940 * then gtk_window_compute_configure_request()
3941 * will apply the constraints later, and we
3942 * don't want to lose information about
3943 * what position the user set before then.
3944 * i.e. if you do a move() then turn off POS_CENTER
3945 * then show the window, your move() will work.
3947 gtk_window_constrain_position (window,
3948 widget->allocation.width,
3949 widget->allocation.height,
3952 /* Note that this request doesn't go through our standard request
3953 * framework, e.g. doesn't increment configure_request_count,
3954 * doesn't set info->last, etc.; that's because
3955 * we don't save the info needed to arrive at this same request
3958 * To gtk_window_move_resize(), this will end up looking exactly
3959 * the same as the position being changed by the window
3963 /* FIXME are we handling gravity properly for framed windows? */
3965 gdk_window_move (window->frame,
3966 x - window->frame_left,
3967 y - window->frame_top);
3969 gdk_window_move (GTK_WIDGET (window)->window,
3974 /* Save this position to apply on mapping */
3975 info->initial_x = x;
3976 info->initial_y = y;
3977 info->initial_pos_set = TRUE;
3982 * gtk_window_get_position:
3983 * @window: a #GtkWindow
3984 * @root_x: return location for X coordinate of gravity-determined reference p\oint
3985 * @root_y: return location for Y coordinate of gravity-determined reference p\oint
3987 * This function returns the position you need to pass to
3988 * gtk_window_move() to keep @window in its current position. This
3989 * means that the meaning of the returned value varies with window
3990 * gravity. See gtk_window_move() for more details.
3992 * If you haven't changed the window gravity, its gravity will be
3993 * #GDK_GRAVITY_NORTH_WEST. This means that gtk_window_get_position()
3994 * gets the position of the top-left corner of the window manager
3995 * frame for the window. gtk_window_move() sets the position of this
3996 * same top-left corner.
3998 * gtk_window_get_position() is not 100% reliable because the X Window System
3999 * does not specify a way to obtain the geometry of the
4000 * decorations placed on a window by the window manager.
4001 * Thus GTK+ is using a "best guess" that works with most
4004 * Moreover, nearly all window managers are historically broken with
4005 * respect to their handling of window gravity. So moving a window to
4006 * its current position as returned by gtk_window_get_position() tends
4007 * to result in moving the window slightly. Window managers are
4008 * slowly getting better over time.
4010 * If a window has gravity #GDK_GRAVITY_STATIC the window manager
4011 * frame is not relevant, and thus gtk_window_get_position() will
4012 * always produce accurate results. However you can't use static
4013 * gravity to do things like place a window in a corner of the screen,
4014 * because static gravity ignores the window manager decorations.
4016 * If you are saving and restoring your application's window
4017 * positions, you should know that it's impossible for applications to
4018 * do this without getting it somewhat wrong because applications do
4019 * not have sufficient knowledge of window manager state. The Correct
4020 * Mechanism is to support the session management protocol (see the
4021 * "GnomeClient" object in the GNOME libraries for example) and allow
4022 * the window manager to save your window sizes and positions.
4027 gtk_window_get_position (GtkWindow *window,
4033 g_return_if_fail (GTK_IS_WINDOW (window));
4035 widget = GTK_WIDGET (window);
4037 if (window->gravity == GDK_GRAVITY_STATIC)
4039 if (GTK_WIDGET_MAPPED (widget))
4041 /* This does a server round-trip, which is sort of wrong;
4042 * but a server round-trip is inevitable for
4043 * gdk_window_get_frame_extents() in the usual
4044 * NorthWestGravity case below, so not sure what else to
4045 * do. We should likely be consistent about whether we get
4046 * the client-side info or the server-side info.
4048 gdk_window_get_origin (widget->window, root_x, root_y);
4052 GdkRectangle configure_request;
4054 gtk_window_compute_configure_request (window,
4058 *root_x = configure_request.x;
4059 *root_y = configure_request.y;
4064 GdkRectangle frame_extents;
4069 if (GTK_WIDGET_MAPPED (widget))
4072 gdk_window_get_frame_extents (window->frame, &frame_extents);
4074 gdk_window_get_frame_extents (widget->window, &frame_extents);
4075 x = frame_extents.x;
4076 y = frame_extents.y;
4077 gtk_window_get_size (window, &w, &h);
4081 /* We just say the frame has 0 size on all sides.
4082 * Not sure what else to do.
4084 gtk_window_compute_configure_request (window,
4087 x = frame_extents.x;
4088 y = frame_extents.y;
4089 w = frame_extents.width;
4090 h = frame_extents.height;
4093 switch (window->gravity)
4095 case GDK_GRAVITY_NORTH:
4096 case GDK_GRAVITY_CENTER:
4097 case GDK_GRAVITY_SOUTH:
4098 /* Find center of frame. */
4099 x += frame_extents.width / 2;
4100 /* Center client window on that point. */
4104 case GDK_GRAVITY_SOUTH_EAST:
4105 case GDK_GRAVITY_EAST:
4106 case GDK_GRAVITY_NORTH_EAST:
4107 /* Find right edge of frame */
4108 x += frame_extents.width;
4109 /* Align left edge of client at that point. */
4116 switch (window->gravity)
4118 case GDK_GRAVITY_WEST:
4119 case GDK_GRAVITY_CENTER:
4120 case GDK_GRAVITY_EAST:
4121 /* Find center of frame. */
4122 y += frame_extents.height / 2;
4123 /* Center client window there. */
4126 case GDK_GRAVITY_SOUTH_WEST:
4127 case GDK_GRAVITY_SOUTH:
4128 case GDK_GRAVITY_SOUTH_EAST:
4129 /* Find south edge of frame */
4130 y += frame_extents.height;
4131 /* Place bottom edge of client there */
4146 * gtk_window_reshow_with_initial_size:
4147 * @window: a #GtkWindow
4149 * Hides @window, then reshows it, resetting the
4150 * default size and position of the window. Used
4151 * by GUI builders only.
4154 gtk_window_reshow_with_initial_size (GtkWindow *window)
4158 g_return_if_fail (GTK_IS_WINDOW (window));
4160 widget = GTK_WIDGET (window);
4162 gtk_widget_hide (widget);
4163 gtk_widget_unrealize (widget);
4164 gtk_widget_show (widget);
4168 gtk_window_destroy (GtkObject *object)
4170 GtkWindow *window = GTK_WINDOW (object);
4172 toplevel_list = g_slist_remove (toplevel_list, window);
4174 if (window->transient_parent)
4175 gtk_window_set_transient_for (window, NULL);
4177 /* frees the icons */
4178 gtk_window_set_icon_list (window, NULL);
4180 if (window->has_user_ref_count)
4182 window->has_user_ref_count = FALSE;
4183 g_object_unref (window);
4187 gtk_window_group_remove_window (window->group, window);
4189 gtk_window_free_key_hash (window);
4191 GTK_OBJECT_CLASS (gtk_window_parent_class)->destroy (object);
4195 gtk_window_finalize (GObject *object)
4197 GtkWindow *window = GTK_WINDOW (object);
4198 GtkMnemonicHash *mnemonic_hash;
4200 g_free (window->title);
4201 g_free (window->wmclass_name);
4202 g_free (window->wmclass_class);
4203 g_free (window->wm_role);
4205 mnemonic_hash = gtk_window_get_mnemonic_hash (window, FALSE);
4207 _gtk_mnemonic_hash_free (mnemonic_hash);
4209 if (window->geometry_info)
4211 if (window->geometry_info->widget)
4212 g_signal_handlers_disconnect_by_func (window->geometry_info->widget,
4213 gtk_widget_destroyed,
4214 &window->geometry_info->widget);
4215 g_free (window->geometry_info);
4218 if (window->keys_changed_handler)
4220 g_source_remove (window->keys_changed_handler);
4221 window->keys_changed_handler = 0;
4226 g_signal_handlers_disconnect_by_func (window->screen,
4227 gtk_window_on_composited_changed, window);
4230 G_OBJECT_CLASS (gtk_window_parent_class)->finalize (object);
4234 gtk_window_show (GtkWidget *widget)
4236 GtkWindow *window = GTK_WINDOW (widget);
4237 GtkContainer *container = GTK_CONTAINER (window);
4238 gboolean need_resize;
4240 GTK_WIDGET_SET_FLAGS (widget, GTK_VISIBLE);
4242 need_resize = container->need_resize || !GTK_WIDGET_REALIZED (widget);
4243 container->need_resize = FALSE;
4247 GtkWindowGeometryInfo *info = gtk_window_get_geometry_info (window, TRUE);
4248 GtkAllocation allocation = { 0, 0 };
4249 GdkRectangle configure_request;
4250 GdkGeometry new_geometry;
4252 gboolean was_realized;
4254 /* We are going to go ahead and perform this configure request
4255 * and then emulate a configure notify by going ahead and
4256 * doing a size allocate. Sort of a synchronous
4257 * mini-copy of gtk_window_move_resize() here.
4259 gtk_window_compute_configure_request (window,
4264 /* We update this because we are going to go ahead
4265 * and gdk_window_resize() below, rather than
4268 info->last.configure_request.width = configure_request.width;
4269 info->last.configure_request.height = configure_request.height;
4271 /* and allocate the window - this is normally done
4272 * in move_resize in response to configure notify
4274 allocation.width = configure_request.width;
4275 allocation.height = configure_request.height;
4276 gtk_widget_size_allocate (widget, &allocation);
4278 /* Then we guarantee we have a realize */
4279 was_realized = FALSE;
4280 if (!GTK_WIDGET_REALIZED (widget))
4282 gtk_widget_realize (widget);
4283 was_realized = TRUE;
4286 /* Must be done after the windows are realized,
4287 * so that the decorations can be read
4289 gtk_decorated_window_calculate_frame_size (window);
4291 /* We only send configure request if we didn't just finish
4292 * creating the window; if we just created the window
4293 * then we created it with widget->allocation anyhow.
4296 gdk_window_move_resize (widget->window,
4297 configure_request.x,
4298 configure_request.y,
4299 configure_request.width,
4300 configure_request.height);
4303 gtk_container_check_resize (container);
4305 gtk_widget_map (widget);
4307 /* Try to make sure that we have some focused widget
4309 if (!window->focus_widget && !GTK_IS_PLUG (window))
4310 gtk_window_move_focus (window, GTK_DIR_TAB_FORWARD);
4313 gtk_grab_add (widget);
4317 gtk_window_hide (GtkWidget *widget)
4319 GtkWindow *window = GTK_WINDOW (widget);
4321 GTK_WIDGET_UNSET_FLAGS (widget, GTK_VISIBLE);
4322 gtk_widget_unmap (widget);
4325 gtk_grab_remove (widget);
4329 gtk_window_map (GtkWidget *widget)
4331 GtkWindow *window = GTK_WINDOW (widget);
4332 GtkWindowPrivate *priv = GTK_WINDOW_GET_PRIVATE (window);
4333 GdkWindow *toplevel;
4335 GTK_WIDGET_SET_FLAGS (widget, GTK_MAPPED);
4337 if (window->bin.child &&
4338 GTK_WIDGET_VISIBLE (window->bin.child) &&
4339 !GTK_WIDGET_MAPPED (window->bin.child))
4340 gtk_widget_map (window->bin.child);
4343 toplevel = window->frame;
4345 toplevel = widget->window;
4347 if (window->maximize_initially)
4348 gdk_window_maximize (toplevel);
4350 gdk_window_unmaximize (toplevel);
4352 if (window->stick_initially)
4353 gdk_window_stick (toplevel);
4355 gdk_window_unstick (toplevel);
4357 if (window->iconify_initially)
4358 gdk_window_iconify (toplevel);
4360 gdk_window_deiconify (toplevel);
4362 if (priv->fullscreen_initially)
4363 gdk_window_fullscreen (toplevel);
4365 gdk_window_unfullscreen (toplevel);
4367 gdk_window_set_keep_above (toplevel, priv->above_initially);
4369 gdk_window_set_keep_below (toplevel, priv->below_initially);
4371 /* No longer use the default settings */
4372 window->need_default_size = FALSE;
4373 window->need_default_position = FALSE;
4375 if (priv->reset_type_hint)
4377 /* We should only reset the type hint when the application
4378 * used gtk_window_set_type_hint() to change the hint.
4379 * Some applications use X directly to change the properties;
4380 * in that case, we shouldn't overwrite what they did.
4382 gdk_window_set_type_hint (widget->window, priv->type_hint);
4383 priv->reset_type_hint = FALSE;
4386 gdk_window_show (widget->window);
4389 gdk_window_show (window->frame);
4391 if (!disable_startup_notification)
4393 /* Do we have a custom startup-notification id? */
4394 if (priv->startup_id != NULL)
4396 /* Make sure we have a "real" id */
4397 if (!startup_id_is_fake (priv->startup_id))
4398 gdk_notify_startup_complete_with_id (priv->startup_id);
4400 priv->startup_id = NULL;
4402 else if (!sent_startup_notification)
4404 sent_startup_notification = TRUE;
4405 gdk_notify_startup_complete ();
4411 gtk_window_map_event (GtkWidget *widget,
4414 if (!GTK_WIDGET_MAPPED (widget))
4416 /* we should be be unmapped, but are getting a MapEvent, this may happen
4417 * to toplevel XWindows if mapping was intercepted by a window manager
4418 * and an unmap request occoured while the MapRequestEvent was still
4419 * being handled. we work around this situaiton here by re-requesting
4420 * the window being unmapped. more details can be found in:
4421 * http://bugzilla.gnome.org/show_bug.cgi?id=316180
4423 gdk_window_hide (widget->window);
4429 gtk_window_unmap (GtkWidget *widget)
4431 GtkWindow *window = GTK_WINDOW (widget);
4432 GtkWindowPrivate *priv = GTK_WINDOW_GET_PRIVATE (widget);
4433 GtkWindowGeometryInfo *info;
4434 GdkWindowState state;
4436 GTK_WIDGET_UNSET_FLAGS (widget, GTK_MAPPED);
4438 gdk_window_withdraw (window->frame);
4440 gdk_window_withdraw (widget->window);
4442 window->configure_request_count = 0;
4443 window->configure_notify_received = FALSE;
4445 /* on unmap, we reset the default positioning of the window,
4446 * so it's placed again, but we don't reset the default
4447 * size of the window, so it's remembered.
4449 window->need_default_position = TRUE;
4451 info = gtk_window_get_geometry_info (window, FALSE);
4454 info->initial_pos_set = FALSE;
4455 info->position_constraints_changed = FALSE;
4458 state = gdk_window_get_state (widget->window);
4459 window->iconify_initially = (state & GDK_WINDOW_STATE_ICONIFIED) != 0;
4460 window->maximize_initially = (state & GDK_WINDOW_STATE_MAXIMIZED) != 0;
4461 window->stick_initially = (state & GDK_WINDOW_STATE_STICKY) != 0;
4462 priv->above_initially = (state & GDK_WINDOW_STATE_ABOVE) != 0;
4463 priv->below_initially = (state & GDK_WINDOW_STATE_BELOW) != 0;
4467 gtk_window_realize (GtkWidget *widget)
4470 GdkWindow *parent_window;
4471 GdkWindowAttr attributes;
4472 gint attributes_mask;
4473 GtkWindowPrivate *priv;
4475 window = GTK_WINDOW (widget);
4476 priv = GTK_WINDOW_GET_PRIVATE (window);
4478 /* ensure widget tree is properly size allocated */
4479 if (widget->allocation.x == -1 &&
4480 widget->allocation.y == -1 &&
4481 widget->allocation.width == 1 &&
4482 widget->allocation.height == 1)
4484 GtkRequisition requisition;
4485 GtkAllocation allocation = { 0, 0, 200, 200 };
4487 gtk_widget_size_request (widget, &requisition);
4488 if (requisition.width || requisition.height)
4490 /* non-empty window */
4491 allocation.width = requisition.width;
4492 allocation.height = requisition.height;
4494 gtk_widget_size_allocate (widget, &allocation);
4496 _gtk_container_queue_resize (GTK_CONTAINER (widget));
4498 g_return_if_fail (!GTK_WIDGET_REALIZED (widget));
4501 GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED);
4503 switch (window->type)
4505 case GTK_WINDOW_TOPLEVEL:
4506 attributes.window_type = GDK_WINDOW_TOPLEVEL;
4508 case GTK_WINDOW_POPUP:
4509 attributes.window_type = GDK_WINDOW_TEMP;
4512 g_warning (G_STRLOC": Unknown window type %d!", window->type);
4516 attributes.title = window->title;
4517 attributes.wmclass_name = window->wmclass_name;
4518 attributes.wmclass_class = window->wmclass_class;
4519 attributes.wclass = GDK_INPUT_OUTPUT;
4520 attributes.visual = gtk_widget_get_visual (widget);
4521 attributes.colormap = gtk_widget_get_colormap (widget);
4523 if (window->has_frame)
4525 attributes.width = widget->allocation.width + window->frame_left + window->frame_right;
4526 attributes.height = widget->allocation.height + window->frame_top + window->frame_bottom;
4527 attributes.event_mask = (GDK_EXPOSURE_MASK |
4528 GDK_KEY_PRESS_MASK |
4529 GDK_ENTER_NOTIFY_MASK |
4530 GDK_LEAVE_NOTIFY_MASK |
4531 GDK_FOCUS_CHANGE_MASK |
4532 GDK_STRUCTURE_MASK |
4533 GDK_BUTTON_MOTION_MASK |
4534 GDK_POINTER_MOTION_HINT_MASK |
4535 GDK_BUTTON_PRESS_MASK |
4536 GDK_BUTTON_RELEASE_MASK);
4538 attributes_mask = GDK_WA_VISUAL | GDK_WA_COLORMAP;
4540 window->frame = gdk_window_new (gtk_widget_get_root_window (widget),
4541 &attributes, attributes_mask);
4543 if (priv->opacity_set)
4544 gdk_window_set_opacity (window->frame, priv->opacity);
4546 gdk_window_set_user_data (window->frame, widget);
4548 attributes.window_type = GDK_WINDOW_CHILD;
4549 attributes.x = window->frame_left;
4550 attributes.y = window->frame_top;
4552 attributes_mask = GDK_WA_X | GDK_WA_Y;
4554 parent_window = window->frame;
4556 g_signal_connect (window,
4558 G_CALLBACK (gtk_window_event),
4563 attributes_mask = 0;
4564 parent_window = gtk_widget_get_root_window (widget);
4567 attributes.width = widget->allocation.width;
4568 attributes.height = widget->allocation.height;
4569 attributes.event_mask = gtk_widget_get_events (widget);
4570 attributes.event_mask |= (GDK_EXPOSURE_MASK |
4571 GDK_KEY_PRESS_MASK |
4572 GDK_KEY_RELEASE_MASK |
4573 GDK_ENTER_NOTIFY_MASK |
4574 GDK_LEAVE_NOTIFY_MASK |
4575 GDK_FOCUS_CHANGE_MASK |
4576 GDK_STRUCTURE_MASK);
4577 attributes.type_hint = priv->type_hint;
4579 attributes_mask |= GDK_WA_VISUAL | GDK_WA_COLORMAP | GDK_WA_TYPE_HINT;
4580 attributes_mask |= (window->title ? GDK_WA_TITLE : 0);
4581 attributes_mask |= (window->wmclass_name ? GDK_WA_WMCLASS : 0);
4583 widget->window = gdk_window_new (parent_window, &attributes, attributes_mask);
4585 if (!window->has_frame && priv->opacity_set)
4586 gdk_window_set_opacity (widget->window, priv->opacity);
4588 gdk_window_enable_synchronized_configure (widget->window);
4590 gdk_window_set_user_data (widget->window, window);
4592 widget->style = gtk_style_attach (widget->style, widget->window);
4593 gtk_style_set_background (widget->style, widget->window, GTK_STATE_NORMAL);
4595 gtk_style_set_background (widget->style, window->frame, GTK_STATE_NORMAL);
4597 /* This is a bad hack to set the window background. */
4598 gtk_window_paint (widget, NULL);
4600 if (window->transient_parent &&
4601 GTK_WIDGET_REALIZED (window->transient_parent))
4602 gdk_window_set_transient_for (widget->window,
4603 GTK_WIDGET (window->transient_parent)->window);
4605 if (window->wm_role)
4606 gdk_window_set_role (widget->window, window->wm_role);
4608 if (!window->decorated)
4609 gdk_window_set_decorations (widget->window, 0);
4611 if (!priv->deletable)
4612 gdk_window_set_functions (widget->window, GDK_FUNC_ALL | GDK_FUNC_CLOSE);
4614 if (gtk_window_get_skip_pager_hint (window))
4615 gdk_window_set_skip_pager_hint (widget->window, TRUE);
4617 if (gtk_window_get_skip_taskbar_hint (window))
4618 gdk_window_set_skip_taskbar_hint (widget->window, TRUE);
4620 if (gtk_window_get_accept_focus (window))
4621 gdk_window_set_accept_focus (widget->window, TRUE);
4623 gdk_window_set_accept_focus (widget->window, FALSE);
4625 if (gtk_window_get_focus_on_map (window))
4626 gdk_window_set_focus_on_map (widget->window, TRUE);
4628 gdk_window_set_focus_on_map (widget->window, FALSE);
4631 gdk_window_set_modal_hint (widget->window, TRUE);
4633 gdk_window_set_modal_hint (widget->window, FALSE);
4635 if (priv->startup_id)
4637 #ifdef GDK_WINDOWING_X11
4638 guint32 timestamp = extract_time_from_startup_id (priv->startup_id);
4639 if (timestamp != GDK_CURRENT_TIME)
4640 gdk_x11_window_set_user_time (widget->window, timestamp);
4642 if (!startup_id_is_fake (priv->startup_id))
4643 gdk_window_set_startup_id (widget->window, priv->startup_id);
4647 gtk_window_realize_icon (window);
4651 gtk_window_unrealize (GtkWidget *widget)
4654 GtkWindowGeometryInfo *info;
4656 window = GTK_WINDOW (widget);
4658 /* On unrealize, we reset the size of the window such
4659 * that we will re-apply the default sizing stuff
4660 * next time we show the window.
4662 * Default positioning is reset on unmap, instead of unrealize.
4664 window->need_default_size = TRUE;
4665 info = gtk_window_get_geometry_info (window, FALSE);
4668 info->resize_width = -1;
4669 info->resize_height = -1;
4670 info->last.configure_request.x = 0;
4671 info->last.configure_request.y = 0;
4672 info->last.configure_request.width = -1;
4673 info->last.configure_request.height = -1;
4674 /* be sure we reset geom hints on re-realize */
4675 info->last.flags = 0;
4680 gdk_window_set_user_data (window->frame, NULL);
4681 gdk_window_destroy (window->frame);
4682 window->frame = NULL;
4686 gtk_window_unrealize_icon (window);
4688 (* GTK_WIDGET_CLASS (gtk_window_parent_class)->unrealize) (widget);
4692 gtk_window_size_request (GtkWidget *widget,
4693 GtkRequisition *requisition)
4698 window = GTK_WINDOW (widget);
4699 bin = GTK_BIN (window);
4701 requisition->width = GTK_CONTAINER (window)->border_width * 2;
4702 requisition->height = GTK_CONTAINER (window)->border_width * 2;
4704 if (bin->child && GTK_WIDGET_VISIBLE (bin->child))
4706 GtkRequisition child_requisition;
4708 gtk_widget_size_request (bin->child, &child_requisition);
4710 requisition->width += child_requisition.width;
4711 requisition->height += child_requisition.height;
4716 gtk_window_size_allocate (GtkWidget *widget,
4717 GtkAllocation *allocation)
4720 GtkAllocation child_allocation;
4722 window = GTK_WINDOW (widget);
4723 widget->allocation = *allocation;
4725 if (window->bin.child && GTK_WIDGET_VISIBLE (window->bin.child))
4727 child_allocation.x = GTK_CONTAINER (window)->border_width;
4728 child_allocation.y = GTK_CONTAINER (window)->border_width;
4729 child_allocation.width =
4730 MAX (1, (gint)allocation->width - child_allocation.x * 2);
4731 child_allocation.height =
4732 MAX (1, (gint)allocation->height - child_allocation.y * 2);
4734 gtk_widget_size_allocate (window->bin.child, &child_allocation);
4737 if (GTK_WIDGET_REALIZED (widget) && window->frame)
4739 gdk_window_resize (window->frame,
4740 allocation->width + window->frame_left + window->frame_right,
4741 allocation->height + window->frame_top + window->frame_bottom);
4746 gtk_window_event (GtkWidget *widget, GdkEvent *event)
4749 gboolean return_val;
4751 window = GTK_WINDOW (widget);
4753 if (window->frame && (event->any.window == window->frame))
4755 if ((event->type != GDK_KEY_PRESS) &&
4756 (event->type != GDK_KEY_RELEASE) &&
4757 (event->type != GDK_FOCUS_CHANGE))
4759 g_signal_stop_emission_by_name (widget, "event");
4761 g_signal_emit (widget, window_signals[FRAME_EVENT], 0, event, &return_val);
4766 g_object_unref (event->any.window);
4767 event->any.window = g_object_ref (widget->window);
4775 gtk_window_frame_event (GtkWindow *window, GdkEvent *event)
4777 GdkEventConfigure *configure_event;
4780 switch (event->type)
4783 configure_event = (GdkEventConfigure *)event;
4785 /* Invalidate the decorations */
4788 rect.width = configure_event->width;
4789 rect.height = configure_event->height;
4791 gdk_window_invalidate_rect (window->frame, &rect, FALSE);
4793 /* Pass on the (modified) configure event */
4794 configure_event->width -= window->frame_left + window->frame_right;
4795 configure_event->height -= window->frame_top + window->frame_bottom;
4796 return gtk_window_configure_event (GTK_WIDGET (window), configure_event);
4805 gtk_window_configure_event (GtkWidget *widget,
4806 GdkEventConfigure *event)
4808 GtkWindow *window = GTK_WINDOW (widget);
4809 gboolean expected_reply = window->configure_request_count > 0;
4811 /* window->configure_request_count incremented for each
4812 * configure request, and decremented to a min of 0 for
4813 * each configure notify.
4815 * All it means is that we know we will get at least
4816 * window->configure_request_count more configure notifies.
4817 * We could get more configure notifies than that; some
4818 * of the configure notifies we get may be unrelated to
4819 * the configure requests. But we will get at least
4820 * window->configure_request_count notifies.
4823 if (window->configure_request_count > 0)
4825 window->configure_request_count -= 1;
4826 gdk_window_thaw_toplevel_updates_libgtk_only (widget->window);
4829 /* As an optimization, we avoid a resize when possible.
4831 * The only times we can avoid a resize are:
4832 * - we know only the position changed, not the size
4833 * - we know we have made more requests and so will get more
4834 * notifies and can wait to resize when we get them
4837 if (!expected_reply &&
4838 (widget->allocation.width == event->width &&
4839 widget->allocation.height == event->height))
4841 gdk_window_configure_finished (widget->window);
4846 * If we do need to resize, we do that by:
4847 * - filling in widget->allocation with the new size
4848 * - setting configure_notify_received to TRUE
4849 * for use in gtk_window_move_resize()
4850 * - queueing a resize, leading to invocation of
4851 * gtk_window_move_resize() in an idle handler
4855 window->configure_notify_received = TRUE;
4857 widget->allocation.width = event->width;
4858 widget->allocation.height = event->height;
4860 _gtk_container_queue_resize (GTK_CONTAINER (widget));
4865 /* the accel_key and accel_mods fields of the key have to be setup
4866 * upon calling this function. it'll then return whether that key
4867 * is at all used as accelerator, and if so will OR in the
4868 * accel_flags member of the key.
4871 _gtk_window_query_nonaccels (GtkWindow *window,
4873 GdkModifierType accel_mods)
4875 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
4877 /* movement keys are considered locked accels */
4880 static const guint bindings[] = {
4881 GDK_space, GDK_KP_Space, GDK_Return, GDK_ISO_Enter, GDK_KP_Enter, GDK_Up, GDK_KP_Up, GDK_Down, GDK_KP_Down,
4882 GDK_Left, GDK_KP_Left, GDK_Right, GDK_KP_Right, GDK_Tab, GDK_KP_Tab, GDK_ISO_Left_Tab,
4886 for (i = 0; i < G_N_ELEMENTS (bindings); i++)
4887 if (bindings[i] == accel_key)
4891 /* mnemonics are considered locked accels */
4892 if (accel_mods == window->mnemonic_modifier)
4894 GtkMnemonicHash *mnemonic_hash = gtk_window_get_mnemonic_hash (window, FALSE);
4895 if (mnemonic_hash && _gtk_mnemonic_hash_lookup (mnemonic_hash, accel_key))
4903 * gtk_window_propagate_key_event:
4904 * @window: a #GtkWindow
4905 * @event: a #GdkEventKey
4907 * Propagate a key press or release event to the focus widget and
4908 * up the focus container chain until a widget handles @event.
4909 * This is normally called by the default ::key_press_event and
4910 * ::key_release_event handlers for toplevel windows,
4911 * however in some cases it may be useful to call this directly when
4912 * overriding the standard key handling for a toplevel window.
4914 * Return value: %TRUE if a widget in the focus chain handled the event.
4917 gtk_window_propagate_key_event (GtkWindow *window,
4920 gboolean handled = FALSE;
4921 GtkWidget *widget, *focus;
4923 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
4925 widget = GTK_WIDGET (window);
4926 focus = window->focus_widget;
4928 g_object_ref (focus);
4931 focus && focus != widget &&
4932 gtk_widget_get_toplevel (focus) == widget)
4936 if (GTK_WIDGET_IS_SENSITIVE (focus))
4937 handled = gtk_widget_event (focus, (GdkEvent*) event);
4939 parent = focus->parent;
4941 g_object_ref (parent);
4943 g_object_unref (focus);
4949 g_object_unref (focus);
4955 gtk_window_key_press_event (GtkWidget *widget,
4958 GtkWindow *window = GTK_WINDOW (widget);
4959 gboolean handled = FALSE;
4961 /* handle mnemonics and accelerators */
4963 handled = gtk_window_activate_key (window, event);
4965 /* handle focus widget key events */
4967 handled = gtk_window_propagate_key_event (window, event);
4969 /* Chain up, invokes binding set */
4971 handled = GTK_WIDGET_CLASS (gtk_window_parent_class)->key_press_event (widget, event);
4977 gtk_window_key_release_event (GtkWidget *widget,
4980 GtkWindow *window = GTK_WINDOW (widget);
4981 gboolean handled = FALSE;
4983 /* handle focus widget key events */
4985 handled = gtk_window_propagate_key_event (window, event);
4987 /* Chain up, invokes binding set */
4989 handled = GTK_WIDGET_CLASS (gtk_window_parent_class)->key_release_event (widget, event);
4995 gtk_window_real_activate_default (GtkWindow *window)
4997 gtk_window_activate_default (window);
5001 gtk_window_real_activate_focus (GtkWindow *window)
5003 gtk_window_activate_focus (window);
5007 gtk_window_move_focus (GtkWindow *window,
5008 GtkDirectionType dir)
5010 gtk_widget_child_focus (GTK_WIDGET (window), dir);
5012 if (!GTK_CONTAINER (window)->focus_child)
5013 gtk_window_set_focus (window, NULL);
5017 gtk_window_enter_notify_event (GtkWidget *widget,
5018 GdkEventCrossing *event)
5024 gtk_window_leave_notify_event (GtkWidget *widget,
5025 GdkEventCrossing *event)
5031 do_focus_change (GtkWidget *widget,
5034 GdkEvent *fevent = gdk_event_new (GDK_FOCUS_CHANGE);
5036 g_object_ref (widget);
5039 GTK_WIDGET_SET_FLAGS (widget, GTK_HAS_FOCUS);
5041 GTK_WIDGET_UNSET_FLAGS (widget, GTK_HAS_FOCUS);
5043 fevent->focus_change.type = GDK_FOCUS_CHANGE;
5044 fevent->focus_change.window = widget->window;
5046 g_object_ref (widget->window);
5047 fevent->focus_change.in = in;
5049 gtk_widget_event (widget, fevent);
5051 g_object_notify (G_OBJECT (widget), "has-focus");
5053 g_object_unref (widget);
5054 gdk_event_free (fevent);
5058 gtk_window_focus_in_event (GtkWidget *widget,
5059 GdkEventFocus *event)
5061 GtkWindow *window = GTK_WINDOW (widget);
5063 /* It appears spurious focus in events can occur when
5064 * the window is hidden. So we'll just check to see if
5065 * the window is visible before actually handling the
5068 if (GTK_WIDGET_VISIBLE (widget))
5070 _gtk_window_set_has_toplevel_focus (window, TRUE);
5071 _gtk_window_set_is_active (window, TRUE);
5078 gtk_window_focus_out_event (GtkWidget *widget,
5079 GdkEventFocus *event)
5081 GtkWindow *window = GTK_WINDOW (widget);
5083 _gtk_window_set_has_toplevel_focus (window, FALSE);
5084 _gtk_window_set_is_active (window, FALSE);
5089 static GdkAtom atom_rcfiles = GDK_NONE;
5090 static GdkAtom atom_iconthemes = GDK_NONE;
5093 send_client_message_to_embedded_windows (GtkWidget *widget,
5094 GdkAtom message_type)
5096 GList *embedded_windows;
5098 embedded_windows = g_object_get_qdata (G_OBJECT (widget), quark_gtk_embedded);
5099 if (embedded_windows)
5101 GdkEvent *send_event = gdk_event_new (GDK_CLIENT_EVENT);
5104 for (i = 0; i < 5; i++)
5105 send_event->client.data.l[i] = 0;
5106 send_event->client.data_format = 32;
5107 send_event->client.message_type = message_type;
5109 while (embedded_windows)
5111 guint xid = GPOINTER_TO_UINT (embedded_windows->data);
5112 gdk_event_send_client_message_for_display (gtk_widget_get_display (widget), send_event, xid);
5113 embedded_windows = embedded_windows->next;
5116 gdk_event_free (send_event);
5121 gtk_window_client_event (GtkWidget *widget,
5122 GdkEventClient *event)
5126 atom_rcfiles = gdk_atom_intern_static_string ("_GTK_READ_RCFILES");
5127 atom_iconthemes = gdk_atom_intern_static_string ("_GTK_LOAD_ICONTHEMES");
5130 if (event->message_type == atom_rcfiles)
5132 send_client_message_to_embedded_windows (widget, atom_rcfiles);
5133 gtk_rc_reparse_all_for_settings (gtk_widget_get_settings (widget), FALSE);
5136 if (event->message_type == atom_iconthemes)
5138 send_client_message_to_embedded_windows (widget, atom_iconthemes);
5139 _gtk_icon_theme_check_reload (gtk_widget_get_display (widget));
5146 gtk_window_check_resize (GtkContainer *container)
5148 GtkWindow *window = GTK_WINDOW (container);
5150 if (GTK_WIDGET_VISIBLE (container))
5151 gtk_window_move_resize (window);
5155 gtk_window_focus (GtkWidget *widget,
5156 GtkDirectionType direction)
5160 GtkContainer *container;
5161 GtkWidget *old_focus_child;
5164 container = GTK_CONTAINER (widget);
5165 window = GTK_WINDOW (widget);
5166 bin = GTK_BIN (widget);
5168 old_focus_child = container->focus_child;
5170 /* We need a special implementation here to deal properly with wrapping
5171 * around in the tab chain without the danger of going into an
5174 if (old_focus_child)
5176 if (gtk_widget_child_focus (old_focus_child, direction))
5180 if (window->focus_widget)
5182 if (direction == GTK_DIR_LEFT ||
5183 direction == GTK_DIR_RIGHT ||
5184 direction == GTK_DIR_UP ||
5185 direction == GTK_DIR_DOWN)
5190 /* Wrapped off the end, clear the focus setting for the toplpevel */
5191 parent = window->focus_widget->parent;
5194 gtk_container_set_focus_child (GTK_CONTAINER (parent), NULL);
5195 parent = GTK_WIDGET (parent)->parent;
5198 gtk_window_set_focus (GTK_WINDOW (container), NULL);
5201 /* Now try to focus the first widget in the window */
5204 if (gtk_widget_child_focus (bin->child, direction))
5212 gtk_window_real_set_focus (GtkWindow *window,
5215 GtkWidget *old_focus = window->focus_widget;
5216 gboolean had_default = FALSE;
5217 gboolean focus_had_default = FALSE;
5218 gboolean old_focus_had_default = FALSE;
5222 g_object_ref (old_focus);
5223 g_object_freeze_notify (G_OBJECT (old_focus));
5224 old_focus_had_default = GTK_WIDGET_HAS_DEFAULT (old_focus);
5228 g_object_ref (focus);
5229 g_object_freeze_notify (G_OBJECT (focus));
5230 focus_had_default = GTK_WIDGET_HAS_DEFAULT (focus);
5233 if (window->default_widget)
5234 had_default = GTK_WIDGET_HAS_DEFAULT (window->default_widget);
5236 if (window->focus_widget)
5238 if (GTK_WIDGET_RECEIVES_DEFAULT (window->focus_widget) &&
5239 (window->focus_widget != window->default_widget))
5241 GTK_WIDGET_UNSET_FLAGS (window->focus_widget, GTK_HAS_DEFAULT);
5242 gtk_widget_queue_draw (window->focus_widget);
5244 if (window->default_widget)
5245 GTK_WIDGET_SET_FLAGS (window->default_widget, GTK_HAS_DEFAULT);
5248 window->focus_widget = NULL;
5250 if (window->has_focus)
5251 do_focus_change (old_focus, FALSE);
5253 g_object_notify (G_OBJECT (old_focus), "is-focus");
5256 /* The above notifications may have set a new focus widget,
5257 * if so, we don't want to override it.
5259 if (focus && !window->focus_widget)
5261 window->focus_widget = focus;
5263 if (GTK_WIDGET_RECEIVES_DEFAULT (window->focus_widget) &&
5264 (window->focus_widget != window->default_widget))
5266 if (GTK_WIDGET_CAN_DEFAULT (window->focus_widget))
5267 GTK_WIDGET_SET_FLAGS (window->focus_widget, GTK_HAS_DEFAULT);
5269 if (window->default_widget)
5270 GTK_WIDGET_UNSET_FLAGS (window->default_widget, GTK_HAS_DEFAULT);
5273 if (window->has_focus)
5274 do_focus_change (window->focus_widget, TRUE);
5276 g_object_notify (G_OBJECT (window->focus_widget), "is-focus");
5279 /* If the default widget changed, a redraw will have been queued
5280 * on the old and new default widgets by gtk_window_set_default(), so
5281 * we only have to worry about the case where it didn't change.
5282 * We'll sometimes queue a draw twice on the new widget but that
5285 if (window->default_widget &&
5286 (had_default != GTK_WIDGET_HAS_DEFAULT (window->default_widget)))
5287 gtk_widget_queue_draw (window->default_widget);
5291 if (old_focus_had_default != GTK_WIDGET_HAS_DEFAULT (old_focus))
5292 gtk_widget_queue_draw (old_focus);
5294 g_object_thaw_notify (G_OBJECT (old_focus));
5295 g_object_unref (old_focus);
5299 if (focus_had_default != GTK_WIDGET_HAS_DEFAULT (focus))
5300 gtk_widget_queue_draw (focus);
5302 g_object_thaw_notify (G_OBJECT (focus));
5303 g_object_unref (focus);
5308 * _gtk_window_unset_focus_and_default:
5309 * @window: a #GtkWindow
5310 * @widget: a widget inside of @window
5312 * Checks whether the focus and default widgets of @window are
5313 * @widget or a descendent of @widget, and if so, unset them.
5316 _gtk_window_unset_focus_and_default (GtkWindow *window,
5322 g_object_ref (window);
5323 g_object_ref (widget);
5325 if (GTK_CONTAINER (widget->parent)->focus_child == widget)
5327 child = window->focus_widget;
5329 while (child && child != widget)
5330 child = child->parent;
5332 if (child == widget)
5333 gtk_window_set_focus (GTK_WINDOW (window), NULL);
5336 child = window->default_widget;
5338 while (child && child != widget)
5339 child = child->parent;
5341 if (child == widget)
5342 gtk_window_set_default (window, NULL);
5344 g_object_unref (widget);
5345 g_object_unref (window);
5348 /*********************************
5349 * Functions related to resizing *
5350 *********************************/
5352 /* This function doesn't constrain to geometry hints */
5354 gtk_window_compute_configure_request_size (GtkWindow *window,
5358 GtkRequisition requisition;
5359 GtkWindowGeometryInfo *info;
5363 * - we've done a size request
5366 widget = GTK_WIDGET (window);
5368 info = gtk_window_get_geometry_info (window, FALSE);
5370 if (window->need_default_size)
5372 gtk_widget_get_child_requisition (widget, &requisition);
5374 /* Default to requisition */
5375 *width = requisition.width;
5376 *height = requisition.height;
5378 /* If window is empty so requests 0, default to random nonzero size */
5379 if (*width == 0 && *height == 0)
5385 /* Override requisition with default size */
5389 gint base_width = 0;
5390 gint base_height = 0;
5392 gint min_height = 0;
5394 gint height_inc = 1;
5396 if (info->default_is_geometry &&
5397 (info->default_width > 0 || info->default_height > 0))
5399 GdkGeometry geometry;
5402 gtk_window_compute_hints (window, &geometry, &flags);
5404 if (flags & GDK_HINT_BASE_SIZE)
5406 base_width = geometry.base_width;
5407 base_height = geometry.base_height;
5409 if (flags & GDK_HINT_MIN_SIZE)
5411 min_width = geometry.min_width;
5412 min_height = geometry.min_height;
5414 if (flags & GDK_HINT_RESIZE_INC)
5416 width_inc = geometry.width_inc;
5417 height_inc = geometry.height_inc;
5421 if (info->default_width > 0)
5422 *width = MAX (info->default_width * width_inc + base_width, min_width);
5424 if (info->default_height > 0)
5425 *height = MAX (info->default_height * height_inc + base_height, min_height);
5430 /* Default to keeping current size */
5431 *width = widget->allocation.width;
5432 *height = widget->allocation.height;
5435 /* Override any size with gtk_window_resize() values */
5438 if (info->resize_width > 0)
5439 *width = info->resize_width;
5441 if (info->resize_height > 0)
5442 *height = info->resize_height;
5446 static GtkWindowPosition
5447 get_effective_position (GtkWindow *window)
5449 GtkWindowPosition pos = window->position;
5450 if (pos == GTK_WIN_POS_CENTER_ON_PARENT &&
5451 (window->transient_parent == NULL ||
5452 !GTK_WIDGET_MAPPED (window->transient_parent)))
5453 pos = GTK_WIN_POS_NONE;
5459 get_center_monitor_of_window (GtkWindow *window)
5461 /* We could try to sort out the relative positions of the monitors and
5462 * stuff, or we could just be losers and assume you have a row
5463 * or column of monitors.
5465 return gdk_screen_get_n_monitors (gtk_window_check_screen (window)) / 2;
5469 get_monitor_containing_pointer (GtkWindow *window)
5473 GdkScreen *window_screen;
5474 GdkScreen *pointer_screen;
5476 window_screen = gtk_window_check_screen (window);
5477 gdk_display_get_pointer (gdk_screen_get_display (window_screen),
5481 if (pointer_screen == window_screen)
5482 monitor_num = gdk_screen_get_monitor_at_point (pointer_screen, px, py);
5490 center_window_on_monitor (GtkWindow *window,
5496 GdkRectangle monitor;
5499 monitor_num = get_monitor_containing_pointer (window);
5501 if (monitor_num == -1)
5502 monitor_num = get_center_monitor_of_window (window);
5504 gdk_screen_get_monitor_geometry (gtk_window_check_screen (window),
5505 monitor_num, &monitor);
5507 *x = (monitor.width - w) / 2 + monitor.x;
5508 *y = (monitor.height - h) / 2 + monitor.y;
5510 /* Be sure we aren't off the monitor, ignoring _NET_WM_STRUT
5511 * and WM decorations.
5525 if (extent > clamp_extent)
5527 *base = clamp_base + clamp_extent/2 - extent/2;
5528 else if (*base < clamp_base)
5530 else if (*base + extent > clamp_base + clamp_extent)
5531 *base = clamp_base + clamp_extent - extent;
5535 clamp_window_to_rectangle (gint *x,
5539 const GdkRectangle *rect)
5541 #ifdef DEBUGGING_OUTPUT
5542 g_print ("%s: %+d%+d %dx%d: %+d%+d: %dx%d", __FUNCTION__, rect->x, rect->y, rect->width, rect->height, *x, *y, w, h);
5545 /* If it is too large, center it. If it fits on the monitor but is
5546 * partially outside, move it to the closest edge. Do this
5547 * separately in x and y directions.
5549 clamp (x, w, rect->x, rect->width);
5550 clamp (y, h, rect->y, rect->height);
5551 #ifdef DEBUGGING_OUTPUT
5552 g_print (" ==> %+d%+d: %dx%d\n", *x, *y, w, h);
5558 gtk_window_compute_configure_request (GtkWindow *window,
5559 GdkRectangle *request,
5560 GdkGeometry *geometry,
5563 GdkGeometry new_geometry;
5567 GtkWindowPosition pos;
5568 GtkWidget *parent_widget;
5569 GtkWindowGeometryInfo *info;
5573 widget = GTK_WIDGET (window);
5575 screen = gtk_window_check_screen (window);
5577 gtk_widget_size_request (widget, NULL);
5578 gtk_window_compute_configure_request_size (window, (guint *)&w, (guint *)&h);
5580 gtk_window_compute_hints (window, &new_geometry, &new_flags);
5581 gtk_window_constrain_size (window,
5582 &new_geometry, new_flags,
5586 parent_widget = (GtkWidget*) window->transient_parent;
5588 pos = get_effective_position (window);
5589 info = gtk_window_get_geometry_info (window, FALSE);
5591 /* by default, don't change position requested */
5594 x = info->last.configure_request.x;
5595 y = info->last.configure_request.y;
5604 if (window->need_default_position)
5607 /* FIXME this all interrelates with window gravity.
5608 * For most of them I think we want to set GRAVITY_CENTER.
5610 * Not sure how to go about that.
5615 /* here we are only handling CENTER_ALWAYS
5616 * as it relates to default positioning,
5617 * where it's equivalent to simply CENTER
5619 case GTK_WIN_POS_CENTER_ALWAYS:
5620 case GTK_WIN_POS_CENTER:
5621 center_window_on_monitor (window, w, h, &x, &y);
5624 case GTK_WIN_POS_CENTER_ON_PARENT:
5627 GdkRectangle monitor;
5630 g_assert (GTK_WIDGET_MAPPED (parent_widget)); /* established earlier */
5632 if (parent_widget->window != NULL)
5633 monitor_num = gdk_screen_get_monitor_at_window (screen,
5634 parent_widget->window);
5638 gdk_window_get_origin (parent_widget->window,
5641 x = ox + (parent_widget->allocation.width - w) / 2;
5642 y = oy + (parent_widget->allocation.height - h) / 2;
5644 /* Clamp onto current monitor, ignoring _NET_WM_STRUT and
5645 * WM decorations. If parent wasn't on a monitor, just
5648 if (monitor_num >= 0)
5650 gdk_screen_get_monitor_geometry (screen, monitor_num, &monitor);
5651 clamp_window_to_rectangle (&x, &y, w, h, &monitor);
5656 case GTK_WIN_POS_MOUSE:
5658 gint screen_width = gdk_screen_get_width (screen);
5659 gint screen_height = gdk_screen_get_height (screen);
5661 GdkRectangle monitor;
5662 GdkScreen *pointer_screen;
5665 gdk_display_get_pointer (gdk_screen_get_display (screen),
5669 if (pointer_screen == screen)
5670 monitor_num = gdk_screen_get_monitor_at_point (screen, px, py);
5676 x = CLAMP (x, 0, screen_width - w);
5677 y = CLAMP (y, 0, screen_height - h);
5679 /* Clamp onto current monitor, ignoring _NET_WM_STRUT and
5680 * WM decorations. Don't try to figure out what's going
5681 * on if the mouse wasn't inside a monitor.
5683 if (monitor_num >= 0)
5685 gdk_screen_get_monitor_geometry (screen, monitor_num, &monitor);
5686 clamp_window_to_rectangle (&x, &y, w, h, &monitor);
5694 } /* if (window->need_default_position) */
5696 if (window->need_default_position && info &&
5697 info->initial_pos_set)
5699 x = info->initial_x;
5700 y = info->initial_y;
5701 gtk_window_constrain_position (window, w, h, &x, &y);
5707 request->height = h;
5710 *geometry = new_geometry;
5716 gtk_window_constrain_position (GtkWindow *window,
5722 /* See long comments in gtk_window_move_resize()
5723 * on when it's safe to call this function.
5725 if (window->position == GTK_WIN_POS_CENTER_ALWAYS)
5727 gint center_x, center_y;
5729 center_window_on_monitor (window, new_width, new_height, ¢er_x, ¢er_y);
5737 gtk_window_move_resize (GtkWindow *window)
5741 * First we determine whether any information has changed that would
5742 * cause us to revise our last configure request. If we would send
5743 * a different configure request from last time, then
5744 * configure_request_size_changed = TRUE or
5745 * configure_request_pos_changed = TRUE. configure_request_size_changed
5746 * may be true due to new hints, a gtk_window_resize(), or whatever.
5747 * configure_request_pos_changed may be true due to gtk_window_set_position()
5748 * or gtk_window_move().
5750 * If the configure request has changed, we send off a new one. To
5751 * ensure GTK+ invariants are maintained (resize queue does what it
5752 * should), we go ahead and size_allocate the requested size in this
5755 * If the configure request has not changed, we don't ever resend
5756 * it, because it could mean fighting the user or window manager.
5759 * To prepare the configure request, we come up with a base size/pos:
5760 * - the one from gtk_window_move()/gtk_window_resize()
5761 * - else default_width, default_height if we haven't ever
5763 * - else the size request if we haven't ever been mapped,
5764 * as a substitute default size
5765 * - else the current size of the window, as received from
5766 * configure notifies (i.e. the current allocation)
5768 * If GTK_WIN_POS_CENTER_ALWAYS is active, we constrain
5769 * the position request to be centered.
5772 GtkContainer *container;
5773 GtkWindowGeometryInfo *info;
5774 GdkGeometry new_geometry;
5776 GdkRectangle new_request;
5777 gboolean configure_request_size_changed;
5778 gboolean configure_request_pos_changed;
5779 gboolean hints_changed; /* do we need to send these again */
5780 GtkWindowLastGeometryInfo saved_last_info;
5782 widget = GTK_WIDGET (window);
5783 container = GTK_CONTAINER (widget);
5784 info = gtk_window_get_geometry_info (window, TRUE);
5786 configure_request_size_changed = FALSE;
5787 configure_request_pos_changed = FALSE;
5789 gtk_window_compute_configure_request (window, &new_request,
5790 &new_geometry, &new_flags);
5792 /* This check implies the invariant that we never set info->last
5793 * without setting the hints and sending off a configure request.
5795 * If we change info->last without sending the request, we may
5798 if (info->last.configure_request.x != new_request.x ||
5799 info->last.configure_request.y != new_request.y)
5800 configure_request_pos_changed = TRUE;
5802 if ((info->last.configure_request.width != new_request.width ||
5803 info->last.configure_request.height != new_request.height))
5804 configure_request_size_changed = TRUE;
5806 hints_changed = FALSE;
5808 if (!gtk_window_compare_hints (&info->last.geometry, info->last.flags,
5809 &new_geometry, new_flags))
5811 hints_changed = TRUE;
5814 /* Position Constraints
5815 * ====================
5817 * POS_CENTER_ALWAYS is conceptually a constraint rather than
5818 * a default. The other POS_ values are used only when the
5819 * window is shown, not after that.
5821 * However, we can't implement a position constraint as
5822 * "anytime the window size changes, center the window"
5823 * because this may well end up fighting the WM or user. In
5824 * fact it gets in an infinite loop with at least one WM.
5826 * Basically, applications are in no way in a position to
5827 * constrain the position of a window, with one exception:
5828 * override redirect windows. (Really the intended purpose
5829 * of CENTER_ALWAYS anyhow, I would think.)
5831 * So the way we implement this "constraint" is to say that when WE
5832 * cause a move or resize, i.e. we make a configure request changing
5833 * window size, we recompute the CENTER_ALWAYS position to reflect
5834 * the new window size, and include it in our request. Also, if we
5835 * just turned on CENTER_ALWAYS we snap to center with a new
5836 * request. Otherwise, if we are just NOTIFIED of a move or resize
5837 * done by someone else e.g. the window manager, we do NOT send a
5838 * new configure request.
5840 * For override redirect windows, this works fine; all window
5841 * sizes are from our configure requests. For managed windows,
5842 * it is at least semi-sane, though who knows what the
5843 * app author is thinking.
5846 /* This condition should be kept in sync with the condition later on
5847 * that determines whether we send a configure request. i.e. we
5848 * should do this position constraining anytime we were going to
5849 * send a configure request anyhow, plus when constraints have
5852 if (configure_request_pos_changed ||
5853 configure_request_size_changed ||
5855 info->position_constraints_changed)
5857 /* We request the constrained position if:
5858 * - we were changing position, and need to clamp
5859 * the change to the constraint
5860 * - we're changing the size anyway
5861 * - set_position() was called to toggle CENTER_ALWAYS on
5864 gtk_window_constrain_position (window,
5870 /* Update whether we need to request a move */
5871 if (info->last.configure_request.x != new_request.x ||
5872 info->last.configure_request.y != new_request.y)
5873 configure_request_pos_changed = TRUE;
5875 configure_request_pos_changed = FALSE;
5879 if (window->type == GTK_WINDOW_TOPLEVEL)
5881 int notify_x, notify_y;
5883 /* this is the position from the last configure notify */
5884 gdk_window_get_position (widget->window, ¬ify_x, ¬ify_y);
5886 g_message ("--- %s ---\n"
5887 "last : %d,%d\t%d x %d\n"
5888 "this : %d,%d\t%d x %d\n"
5889 "alloc : %d,%d\t%d x %d\n"
5891 "resize: \t%d x %d\n"
5892 "size_changed: %d pos_changed: %d hints_changed: %d\n"
5893 "configure_notify_received: %d\n"
5894 "configure_request_count: %d\n"
5895 "position_constraints_changed: %d\n",
5896 window->title ? window->title : "(no title)",
5897 info->last.configure_request.x,
5898 info->last.configure_request.y,
5899 info->last.configure_request.width,
5900 info->last.configure_request.height,
5906 widget->allocation.width,
5907 widget->allocation.height,
5908 widget->requisition.width,
5909 widget->requisition.height,
5911 info->resize_height,
5912 configure_request_pos_changed,
5913 configure_request_size_changed,
5915 window->configure_notify_received,
5916 window->configure_request_count,
5917 info->position_constraints_changed);
5921 saved_last_info = info->last;
5922 info->last.geometry = new_geometry;
5923 info->last.flags = new_flags;
5924 info->last.configure_request = new_request;
5926 /* need to set PPosition so the WM will look at our position,
5927 * but we don't want to count PPosition coming and going as a hints
5928 * change for future iterations. So we saved info->last prior to
5932 /* Also, if the initial position was explicitly set, then we always
5933 * toggle on PPosition. This makes gtk_window_move(window, 0, 0)
5937 /* Also, we toggle on PPosition if GTK_WIN_POS_ is in use and
5938 * this is an initial map
5941 if ((configure_request_pos_changed ||
5942 info->initial_pos_set ||
5943 (window->need_default_position &&
5944 get_effective_position (window) != GTK_WIN_POS_NONE)) &&
5945 (new_flags & GDK_HINT_POS) == 0)
5947 new_flags |= GDK_HINT_POS;
5948 hints_changed = TRUE;
5951 /* Set hints if necessary
5954 gdk_window_set_geometry_hints (widget->window,
5958 /* handle resizing/moving and widget tree allocation
5960 if (window->configure_notify_received)
5962 GtkAllocation allocation;
5964 /* If we have received a configure event since
5965 * the last time in this function, we need to
5966 * accept our new size and size_allocate child widgets.
5967 * (see gtk_window_configure_event() for more details).
5969 * 1 or more configure notifies may have been received.
5970 * Also, configure_notify_received will only be TRUE
5971 * if all expected configure notifies have been received
5972 * (one per configure request), as an optimization.
5975 window->configure_notify_received = FALSE;
5977 /* gtk_window_configure_event() filled in widget->allocation */
5978 allocation = widget->allocation;
5979 gtk_widget_size_allocate (widget, &allocation);
5981 gdk_window_process_updates (widget->window, TRUE);
5983 gdk_window_configure_finished (widget->window);
5985 /* If the configure request changed, it means that
5987 * 1) coincidentally changed hints or widget properties
5988 * impacting the configure request before getting
5989 * a configure notify, or
5990 * 2) some broken widget is changing its size request
5991 * during size allocation, resulting in
5992 * a false appearance of changed configure request.
5994 * For 1), we could just go ahead and ask for the
5995 * new size right now, but doing that for 2)
5996 * might well be fighting the user (and can even
5997 * trigger a loop). Since we really don't want to
5998 * do that, we requeue a resize in hopes that
5999 * by the time it gets handled, the child has seen
6000 * the light and is willing to go along with the
6001 * new size. (this happens for the zvt widget, since
6002 * the size_allocate() above will have stored the
6003 * requisition corresponding to the new size in the
6006 * This doesn't buy us anything for 1), but it shouldn't
6007 * hurt us too badly, since it is what would have
6008 * happened if we had gotten the configure event before
6009 * the new size had been set.
6012 if (configure_request_size_changed ||
6013 configure_request_pos_changed)
6015 /* Don't change the recorded last info after all, because we
6016 * haven't actually updated to the new info yet - we decided
6017 * to postpone our configure request until later.
6019 info->last = saved_last_info;
6021 gtk_widget_queue_resize (widget); /* migth recurse for GTK_RESIZE_IMMEDIATE */
6024 return; /* Bail out, we didn't really process the move/resize */
6026 else if ((configure_request_size_changed || hints_changed) &&
6027 (widget->allocation.width != new_request.width ||
6028 widget->allocation.height != new_request.height))
6031 /* We are in one of the following situations:
6032 * A. configure_request_size_changed
6033 * our requisition has changed and we need a different window size,
6034 * so we request it from the window manager.
6035 * B. !configure_request_size_changed && hints_changed
6036 * the window manager rejects our size, but we have just changed the
6037 * window manager hints, so there's a chance our request will
6038 * be honoured this time, so we try again.
6040 * However, if the new requisition is the same as the current allocation,
6041 * we don't request it again, since we won't get a ConfigureNotify back from
6042 * the window manager unless it decides to change our requisition. If
6043 * we don't get the ConfigureNotify back, the resize queue will never be run.
6046 /* Now send the configure request */
6047 if (configure_request_pos_changed)
6051 gdk_window_move_resize (window->frame,
6052 new_request.x - window->frame_left,
6053 new_request.y - window->frame_top,
6054 new_request.width + window->frame_left + window->frame_right,
6055 new_request.height + window->frame_top + window->frame_bottom);
6056 gdk_window_resize (widget->window,
6057 new_request.width, new_request.height);
6060 gdk_window_move_resize (widget->window,
6061 new_request.x, new_request.y,
6062 new_request.width, new_request.height);
6064 else /* only size changed */
6067 gdk_window_resize (window->frame,
6068 new_request.width + window->frame_left + window->frame_right,
6069 new_request.height + window->frame_top + window->frame_bottom);
6070 gdk_window_resize (widget->window,
6071 new_request.width, new_request.height);
6074 if (window->type == GTK_WINDOW_POPUP)
6076 GtkAllocation allocation;
6078 /* Directly size allocate for override redirect (popup) windows. */
6081 allocation.width = new_request.width;
6082 allocation.height = new_request.height;
6084 gtk_widget_size_allocate (widget, &allocation);
6086 gdk_window_process_updates (widget->window, TRUE);
6088 if (container->resize_mode == GTK_RESIZE_QUEUE)
6089 gtk_widget_queue_draw (widget);
6093 /* Increment the number of have-not-yet-received-notify requests */
6094 window->configure_request_count += 1;
6095 gdk_window_freeze_toplevel_updates_libgtk_only (widget->window);
6097 /* for GTK_RESIZE_QUEUE toplevels, we are now awaiting a new
6098 * configure event in response to our resizing request.
6099 * the configure event will cause a new resize with
6100 * ->configure_notify_received=TRUE.
6101 * until then, we want to
6102 * - discard expose events
6103 * - coalesce resizes for our children
6104 * - defer any window resizes until the configure event arrived
6105 * to achieve this, we queue a resize for the window, but remove its
6106 * resizing handler, so resizing will not be handled from the next
6107 * idle handler but when the configure event arrives.
6109 * FIXME: we should also dequeue the pending redraws here, since
6110 * we handle those ourselves upon ->configure_notify_received==TRUE.
6112 if (container->resize_mode == GTK_RESIZE_QUEUE)
6114 gtk_widget_queue_resize (widget);
6115 _gtk_container_dequeue_resize_handler (container);
6121 /* Handle any position changes.
6123 if (configure_request_pos_changed)
6127 gdk_window_move (window->frame,
6128 new_request.x - window->frame_left,
6129 new_request.y - window->frame_top);
6132 gdk_window_move (widget->window,
6133 new_request.x, new_request.y);
6136 /* And run the resize queue.
6138 gtk_container_resize_children (container);
6141 /* We have now processed a move/resize since the last position
6142 * constraint change, setting of the initial position, or resize.
6143 * (Not resetting these flags here can lead to infinite loops for
6144 * GTK_RESIZE_IMMEDIATE containers)
6146 info->position_constraints_changed = FALSE;
6147 info->initial_pos_set = FALSE;
6148 info->resize_width = -1;
6149 info->resize_height = -1;
6152 /* Compare two sets of Geometry hints for equality.
6155 gtk_window_compare_hints (GdkGeometry *geometry_a,
6157 GdkGeometry *geometry_b,
6160 if (flags_a != flags_b)
6163 if ((flags_a & GDK_HINT_MIN_SIZE) &&
6164 (geometry_a->min_width != geometry_b->min_width ||
6165 geometry_a->min_height != geometry_b->min_height))
6168 if ((flags_a & GDK_HINT_MAX_SIZE) &&
6169 (geometry_a->max_width != geometry_b->max_width ||
6170 geometry_a->max_height != geometry_b->max_height))
6173 if ((flags_a & GDK_HINT_BASE_SIZE) &&
6174 (geometry_a->base_width != geometry_b->base_width ||
6175 geometry_a->base_height != geometry_b->base_height))
6178 if ((flags_a & GDK_HINT_ASPECT) &&
6179 (geometry_a->min_aspect != geometry_b->min_aspect ||
6180 geometry_a->max_aspect != geometry_b->max_aspect))
6183 if ((flags_a & GDK_HINT_RESIZE_INC) &&
6184 (geometry_a->width_inc != geometry_b->width_inc ||
6185 geometry_a->height_inc != geometry_b->height_inc))
6188 if ((flags_a & GDK_HINT_WIN_GRAVITY) &&
6189 geometry_a->win_gravity != geometry_b->win_gravity)
6196 _gtk_window_constrain_size (GtkWindow *window,
6202 GtkWindowGeometryInfo *info;
6204 g_return_if_fail (GTK_IS_WINDOW (window));
6206 info = window->geometry_info;
6209 GdkWindowHints flags = info->last.flags;
6210 GdkGeometry *geometry = &info->last.geometry;
6212 gtk_window_constrain_size (window,
6223 gtk_window_constrain_size (GtkWindow *window,
6224 GdkGeometry *geometry,
6231 gdk_window_constrain_size (geometry, flags, width, height,
6232 new_width, new_height);
6235 /* Compute the set of geometry hints and flags for a window
6236 * based on the application set geometry, and requisiition
6237 * of the window. gtk_widget_size_request() must have been
6241 gtk_window_compute_hints (GtkWindow *window,
6242 GdkGeometry *new_geometry,
6246 gint extra_width = 0;
6247 gint extra_height = 0;
6248 GtkWindowGeometryInfo *geometry_info;
6249 GtkRequisition requisition;
6251 widget = GTK_WIDGET (window);
6253 gtk_widget_get_child_requisition (widget, &requisition);
6254 geometry_info = gtk_window_get_geometry_info (GTK_WINDOW (widget), FALSE);
6258 *new_flags = geometry_info->mask;
6259 *new_geometry = geometry_info->geometry;
6266 if (geometry_info && geometry_info->widget)
6268 GtkRequisition child_requisition;
6270 /* FIXME: This really isn't right. It gets the min size wrong and forces
6271 * callers to do horrible hacks like set a huge usize on the child requisition
6272 * to get the base size right. We really want to find the answers to:
6274 * - If the geometry widget was infinitely big, how much extra space
6275 * would be needed for the stuff around it.
6277 * - If the geometry widget was infinitely small, how big would the
6278 * window still have to be.
6280 * Finding these answers would be a bit of a mess here. (Bug #68668)
6282 gtk_widget_get_child_requisition (geometry_info->widget, &child_requisition);
6284 extra_width = widget->requisition.width - child_requisition.width;
6285 extra_height = widget->requisition.height - child_requisition.height;
6288 /* We don't want to set GDK_HINT_POS in here, we just set it
6289 * in gtk_window_move_resize() when we want the position
6293 if (*new_flags & GDK_HINT_BASE_SIZE)
6295 new_geometry->base_width += extra_width;
6296 new_geometry->base_height += extra_height;
6298 else if (!(*new_flags & GDK_HINT_MIN_SIZE) &&
6299 (*new_flags & GDK_HINT_RESIZE_INC) &&
6300 ((extra_width != 0) || (extra_height != 0)))
6302 *new_flags |= GDK_HINT_BASE_SIZE;
6304 new_geometry->base_width = extra_width;
6305 new_geometry->base_height = extra_height;
6308 if (*new_flags & GDK_HINT_MIN_SIZE)
6310 if (new_geometry->min_width < 0)
6311 new_geometry->min_width = requisition.width;
6313 new_geometry->min_width += extra_width;
6315 if (new_geometry->min_height < 0)
6316 new_geometry->min_height = requisition.height;
6318 new_geometry->min_height += extra_height;
6320 else if (!window->allow_shrink)
6322 *new_flags |= GDK_HINT_MIN_SIZE;
6324 new_geometry->min_width = requisition.width;
6325 new_geometry->min_height = requisition.height;
6328 if (*new_flags & GDK_HINT_MAX_SIZE)
6330 if (new_geometry->max_width < 0)
6331 new_geometry->max_width = requisition.width;
6333 new_geometry->max_width += extra_width;
6335 if (new_geometry->max_height < 0)
6336 new_geometry->max_height = requisition.height;
6338 new_geometry->max_height += extra_height;
6340 else if (!window->allow_grow)
6342 *new_flags |= GDK_HINT_MAX_SIZE;
6344 new_geometry->max_width = requisition.width;
6345 new_geometry->max_height = requisition.height;
6348 *new_flags |= GDK_HINT_WIN_GRAVITY;
6349 new_geometry->win_gravity = window->gravity;
6352 /***********************
6353 * Redrawing functions *
6354 ***********************/
6357 gtk_window_paint (GtkWidget *widget,
6360 gtk_paint_flat_box (widget->style, widget->window, GTK_STATE_NORMAL,
6361 GTK_SHADOW_NONE, area, widget, "base", 0, 0, -1, -1);
6365 gtk_window_expose (GtkWidget *widget,
6366 GdkEventExpose *event)
6368 if (!GTK_WIDGET_APP_PAINTABLE (widget))
6369 gtk_window_paint (widget, &event->area);
6371 if (GTK_WIDGET_CLASS (gtk_window_parent_class)->expose_event)
6372 return GTK_WIDGET_CLASS (gtk_window_parent_class)->expose_event (widget, event);
6378 * gtk_window_set_has_frame:
6379 * @window: a #GtkWindow
6380 * @setting: a boolean
6382 * (Note: this is a special-purpose function for the framebuffer port,
6383 * that causes GTK+ to draw its own window border. For most applications,
6384 * you want gtk_window_set_decorated() instead, which tells the window
6385 * manager whether to draw the window border.)
6387 * If this function is called on a window with setting of %TRUE, before
6388 * it is realized or showed, it will have a "frame" window around
6389 * @window->window, accessible in @window->frame. Using the signal
6390 * frame_event you can receive all events targeted at the frame.
6392 * This function is used by the linux-fb port to implement managed
6393 * windows, but it could conceivably be used by X-programs that
6394 * want to do their own window decorations.
6398 gtk_window_set_has_frame (GtkWindow *window,
6401 g_return_if_fail (GTK_IS_WINDOW (window));
6402 g_return_if_fail (!GTK_WIDGET_REALIZED (window));
6404 window->has_frame = setting != FALSE;
6408 * gtk_window_get_has_frame:
6409 * @window: a #GtkWindow
6411 * Accessor for whether the window has a frame window exterior to
6412 * @window->window. Gets the value set by gtk_window_set_has_frame ().
6414 * Return value: %TRUE if a frame has been added to the window
6415 * via gtk_window_set_has_frame().
6418 gtk_window_get_has_frame (GtkWindow *window)
6420 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
6422 return window->has_frame;
6426 * gtk_window_set_frame_dimensions:
6427 * @window: a #GtkWindow that has a frame
6428 * @left: The width of the left border
6429 * @top: The height of the top border
6430 * @right: The width of the right border
6431 * @bottom: The height of the bottom border
6433 * (Note: this is a special-purpose function intended for the framebuffer
6434 * port; see gtk_window_set_has_frame(). It will have no effect on the
6435 * window border drawn by the window manager, which is the normal
6436 * case when using the X Window system.)
6438 * For windows with frames (see gtk_window_set_has_frame()) this function
6439 * can be used to change the size of the frame border.
6442 gtk_window_set_frame_dimensions (GtkWindow *window,
6450 g_return_if_fail (GTK_IS_WINDOW (window));
6452 widget = GTK_WIDGET (window);
6454 if (window->frame_left == left &&
6455 window->frame_top == top &&
6456 window->frame_right == right &&
6457 window->frame_bottom == bottom)
6460 window->frame_left = left;
6461 window->frame_top = top;
6462 window->frame_right = right;
6463 window->frame_bottom = bottom;
6465 if (GTK_WIDGET_REALIZED (widget) && window->frame)
6467 gint width = widget->allocation.width + left + right;
6468 gint height = widget->allocation.height + top + bottom;
6469 gdk_window_resize (window->frame, width, height);
6470 gtk_decorated_window_move_resize_window (window,
6472 widget->allocation.width,
6473 widget->allocation.height);
6478 * gtk_window_present:
6479 * @window: a #GtkWindow
6481 * Presents a window to the user. This may mean raising the window
6482 * in the stacking order, deiconifying it, moving it to the current
6483 * desktop, and/or giving it the keyboard focus, possibly dependent
6484 * on the user's platform, window manager, and preferences.
6486 * If @window is hidden, this function calls gtk_widget_show()
6489 * This function should be used when the user tries to open a window
6490 * that's already open. Say for example the preferences dialog is
6491 * currently open, and the user chooses Preferences from the menu
6492 * a second time; use gtk_window_present() to move the already-open dialog
6493 * where the user can see it.
6495 * If you are calling this function in response to a user interaction,
6496 * it is preferable to use gtk_window_present_with_time().
6500 gtk_window_present (GtkWindow *window)
6502 gtk_window_present_with_time (window, GDK_CURRENT_TIME);
6506 * gtk_window_present_with_time:
6507 * @window: a #GtkWindow
6508 * @timestamp: the timestamp of the user interaction (typically a
6509 * button or key press event) which triggered this call
6511 * Presents a window to the user in response to a user interaction.
6512 * If you need to present a window without a timestamp, use
6513 * gtk_window_present(). See gtk_window_present() for details.
6518 gtk_window_present_with_time (GtkWindow *window,
6523 g_return_if_fail (GTK_IS_WINDOW (window));
6525 widget = GTK_WIDGET (window);
6527 if (GTK_WIDGET_VISIBLE (window))
6529 g_assert (widget->window != NULL);
6531 gdk_window_show (widget->window);
6533 /* Translate a timestamp of GDK_CURRENT_TIME appropriately */
6534 if (timestamp == GDK_CURRENT_TIME)
6536 #ifdef GDK_WINDOWING_X11
6537 GdkDisplay *display;
6539 display = gtk_widget_get_display (GTK_WIDGET (window));
6540 timestamp = gdk_x11_display_get_user_time (display);
6542 timestamp = gtk_get_current_event_time ();
6546 gdk_window_focus (widget->window, timestamp);
6550 gtk_widget_show (widget);
6555 * gtk_window_iconify:
6556 * @window: a #GtkWindow
6558 * Asks to iconify (i.e. minimize) the specified @window. Note that
6559 * you shouldn't assume the window is definitely iconified afterward,
6560 * because other entities (e.g. the user or <link
6561 * linkend="gtk-X11-arch">window manager</link>) could deiconify it
6562 * again, or there may not be a window manager in which case
6563 * iconification isn't possible, etc. But normally the window will end
6564 * up iconified. Just don't write code that crashes if not.
6566 * It's permitted to call this function before showing a window,
6567 * in which case the window will be iconified before it ever appears
6570 * You can track iconification via the "window_state_event" signal
6575 gtk_window_iconify (GtkWindow *window)
6578 GdkWindow *toplevel;
6580 g_return_if_fail (GTK_IS_WINDOW (window));
6582 widget = GTK_WIDGET (window);
6584 window->iconify_initially = TRUE;
6587 toplevel = window->frame;
6589 toplevel = widget->window;
6591 if (toplevel != NULL)
6592 gdk_window_iconify (toplevel);
6596 * gtk_window_deiconify:
6597 * @window: a #GtkWindow
6599 * Asks to deiconify (i.e. unminimize) the specified @window. Note
6600 * that you shouldn't assume the window is definitely deiconified
6601 * afterward, because other entities (e.g. the user or <link
6602 * linkend="gtk-X11-arch">window manager</link>) could iconify it
6603 * again before your code which assumes deiconification gets to run.
6605 * You can track iconification via the "window_state_event" signal
6609 gtk_window_deiconify (GtkWindow *window)
6612 GdkWindow *toplevel;
6614 g_return_if_fail (GTK_IS_WINDOW (window));
6616 widget = GTK_WIDGET (window);
6618 window->iconify_initially = FALSE;
6621 toplevel = window->frame;
6623 toplevel = widget->window;
6625 if (toplevel != NULL)
6626 gdk_window_deiconify (toplevel);
6631 * @window: a #GtkWindow
6633 * Asks to stick @window, which means that it will appear on all user
6634 * desktops. Note that you shouldn't assume the window is definitely
6635 * stuck afterward, because other entities (e.g. the user or <link
6636 * linkend="gtk-X11-arch">window manager</link>) could unstick it
6637 * again, and some window managers do not support sticking
6638 * windows. But normally the window will end up stuck. Just don't
6639 * write code that crashes if not.
6641 * It's permitted to call this function before showing a window.
6643 * You can track stickiness via the "window_state_event" signal
6648 gtk_window_stick (GtkWindow *window)
6651 GdkWindow *toplevel;
6653 g_return_if_fail (GTK_IS_WINDOW (window));
6655 widget = GTK_WIDGET (window);
6657 window->stick_initially = TRUE;
6660 toplevel = window->frame;
6662 toplevel = widget->window;
6664 if (toplevel != NULL)
6665 gdk_window_stick (toplevel);
6669 * gtk_window_unstick:
6670 * @window: a #GtkWindow
6672 * Asks to unstick @window, which means that it will appear on only
6673 * one of the user's desktops. Note that you shouldn't assume the
6674 * window is definitely unstuck afterward, because other entities
6675 * (e.g. the user or <link linkend="gtk-X11-arch">window
6676 * manager</link>) could stick it again. But normally the window will
6677 * end up stuck. Just don't write code that crashes if not.
6679 * You can track stickiness via the "window_state_event" signal
6684 gtk_window_unstick (GtkWindow *window)
6687 GdkWindow *toplevel;
6689 g_return_if_fail (GTK_IS_WINDOW (window));
6691 widget = GTK_WIDGET (window);
6693 window->stick_initially = FALSE;
6696 toplevel = window->frame;
6698 toplevel = widget->window;
6700 if (toplevel != NULL)
6701 gdk_window_unstick (toplevel);
6705 * gtk_window_maximize:
6706 * @window: a #GtkWindow
6708 * Asks to maximize @window, so that it becomes full-screen. Note that
6709 * you shouldn't assume the window is definitely maximized afterward,
6710 * because other entities (e.g. the user or <link
6711 * linkend="gtk-X11-arch">window manager</link>) could unmaximize it
6712 * again, and not all window managers support maximization. But
6713 * normally the window will end up maximized. Just don't write code
6714 * that crashes if not.
6716 * It's permitted to call this function before showing a window,
6717 * in which case the window will be maximized when it appears onscreen
6720 * You can track maximization via the "window_state_event" signal
6725 gtk_window_maximize (GtkWindow *window)
6728 GdkWindow *toplevel;
6730 g_return_if_fail (GTK_IS_WINDOW (window));
6732 widget = GTK_WIDGET (window);
6734 window->maximize_initially = TRUE;
6737 toplevel = window->frame;
6739 toplevel = widget->window;
6741 if (toplevel != NULL)
6742 gdk_window_maximize (toplevel);
6746 * gtk_window_unmaximize:
6747 * @window: a #GtkWindow
6749 * Asks to unmaximize @window. Note that you shouldn't assume the
6750 * window is definitely unmaximized afterward, because other entities
6751 * (e.g. the user or <link linkend="gtk-X11-arch">window
6752 * manager</link>) could maximize it again, and not all window
6753 * managers honor requests to unmaximize. But normally the window will
6754 * end up unmaximized. Just don't write code that crashes if not.
6756 * You can track maximization via the "window_state_event" signal
6761 gtk_window_unmaximize (GtkWindow *window)
6764 GdkWindow *toplevel;
6766 g_return_if_fail (GTK_IS_WINDOW (window));
6768 widget = GTK_WIDGET (window);
6770 window->maximize_initially = FALSE;
6773 toplevel = window->frame;
6775 toplevel = widget->window;
6777 if (toplevel != NULL)
6778 gdk_window_unmaximize (toplevel);
6782 * gtk_window_fullscreen:
6783 * @window: a #GtkWindow
6785 * Asks to place @window in the fullscreen state. Note that you
6786 * shouldn't assume the window is definitely full screen afterward,
6787 * because other entities (e.g. the user or <link
6788 * linkend="gtk-X11-arch">window manager</link>) could unfullscreen it
6789 * again, and not all window managers honor requests to fullscreen
6790 * windows. But normally the window will end up fullscreen. Just
6791 * don't write code that crashes if not.
6793 * You can track the fullscreen state via the "window_state_event" signal
6799 gtk_window_fullscreen (GtkWindow *window)
6802 GdkWindow *toplevel;
6803 GtkWindowPrivate *priv;
6805 g_return_if_fail (GTK_IS_WINDOW (window));
6807 widget = GTK_WIDGET (window);
6808 priv = GTK_WINDOW_GET_PRIVATE (window);
6810 priv->fullscreen_initially = TRUE;
6813 toplevel = window->frame;
6815 toplevel = widget->window;
6817 if (toplevel != NULL)
6818 gdk_window_fullscreen (toplevel);
6822 * gtk_window_unfullscreen:
6823 * @window: a #GtkWindow
6825 * Asks to toggle off the fullscreen state for @window. Note that you
6826 * shouldn't assume the window is definitely not full screen
6827 * afterward, because other entities (e.g. the user or <link
6828 * linkend="gtk-X11-arch">window manager</link>) could fullscreen it
6829 * again, and not all window managers honor requests to unfullscreen
6830 * windows. But normally the window will end up restored to its normal
6831 * state. Just don't write code that crashes if not.
6833 * You can track the fullscreen state via the "window_state_event" signal
6839 gtk_window_unfullscreen (GtkWindow *window)
6842 GdkWindow *toplevel;
6843 GtkWindowPrivate *priv;
6845 g_return_if_fail (GTK_IS_WINDOW (window));
6847 widget = GTK_WIDGET (window);
6848 priv = GTK_WINDOW_GET_PRIVATE (window);
6850 priv->fullscreen_initially = FALSE;
6853 toplevel = window->frame;
6855 toplevel = widget->window;
6857 if (toplevel != NULL)
6858 gdk_window_unfullscreen (toplevel);
6862 * gtk_window_set_keep_above:
6863 * @window: a #GtkWindow
6864 * @setting: whether to keep @window above other windows
6866 * Asks to keep @window above, so that it stays on top. Note that
6867 * you shouldn't assume the window is definitely above afterward,
6868 * because other entities (e.g. the user or <link
6869 * linkend="gtk-X11-arch">window manager</link>) could not keep it above,
6870 * and not all window managers support keeping windows above. But
6871 * normally the window will end kept above. Just don't write code
6872 * that crashes if not.
6874 * It's permitted to call this function before showing a window,
6875 * in which case the window will be kept above when it appears onscreen
6878 * You can track the above state via the "window_state_event" signal
6881 * Note that, according to the <ulink
6882 * url="http://www.freedesktop.org/Standards/wm-spec">Extended Window
6883 * Manager Hints</ulink> specification, the above state is mainly meant
6884 * for user preferences and should not be used by applications e.g. for
6885 * drawing attention to their dialogs.
6890 gtk_window_set_keep_above (GtkWindow *window,
6894 GtkWindowPrivate *priv;
6895 GdkWindow *toplevel;
6897 g_return_if_fail (GTK_IS_WINDOW (window));
6899 widget = GTK_WIDGET (window);
6900 priv = GTK_WINDOW_GET_PRIVATE (window);
6902 priv->above_initially = setting != FALSE;
6904 priv->below_initially = FALSE;
6907 toplevel = window->frame;
6909 toplevel = widget->window;
6911 if (toplevel != NULL)
6912 gdk_window_set_keep_above (toplevel, setting);
6916 * gtk_window_set_keep_below:
6917 * @window: a #GtkWindow
6918 * @setting: whether to keep @window below other windows
6920 * Asks to keep @window below, so that it stays in bottom. Note that
6921 * you shouldn't assume the window is definitely below afterward,
6922 * because other entities (e.g. the user or <link
6923 * linkend="gtk-X11-arch">window manager</link>) could not keep it below,
6924 * and not all window managers support putting windows below. But
6925 * normally the window will be kept below. Just don't write code
6926 * that crashes if not.
6928 * It's permitted to call this function before showing a window,
6929 * in which case the window will be kept below when it appears onscreen
6932 * You can track the below state via the "window_state_event" signal
6935 * Note that, according to the <ulink
6936 * url="http://www.freedesktop.org/Standards/wm-spec">Extended Window
6937 * Manager Hints</ulink> specification, the above state is mainly meant
6938 * for user preferences and should not be used by applications e.g. for
6939 * drawing attention to their dialogs.
6944 gtk_window_set_keep_below (GtkWindow *window,
6948 GtkWindowPrivate *priv;
6949 GdkWindow *toplevel;
6951 g_return_if_fail (GTK_IS_WINDOW (window));
6953 widget = GTK_WIDGET (window);
6954 priv = GTK_WINDOW_GET_PRIVATE (window);
6956 priv->below_initially = setting != FALSE;
6958 priv->above_initially = FALSE;
6961 toplevel = window->frame;
6963 toplevel = widget->window;
6965 if (toplevel != NULL)
6966 gdk_window_set_keep_below (toplevel, setting);
6970 * gtk_window_set_resizable:
6971 * @window: a #GtkWindow
6972 * @resizable: %TRUE if the user can resize this window
6974 * Sets whether the user can resize a window. Windows are user resizable
6978 gtk_window_set_resizable (GtkWindow *window,
6981 g_return_if_fail (GTK_IS_WINDOW (window));
6983 gtk_window_set_policy (window, FALSE, resizable, FALSE);
6987 * gtk_window_get_resizable:
6988 * @window: a #GtkWindow
6990 * Gets the value set by gtk_window_set_resizable().
6992 * Return value: %TRUE if the user can resize the window
6995 gtk_window_get_resizable (GtkWindow *window)
6997 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
6999 /* allow_grow is most likely to indicate the semantic concept we
7000 * mean by "resizable" (and will be a reliable indicator if
7001 * set_policy() hasn't been called)
7003 return window->allow_grow;
7007 * gtk_window_set_gravity:
7008 * @window: a #GtkWindow
7009 * @gravity: window gravity
7011 * Window gravity defines the meaning of coordinates passed to
7012 * gtk_window_move(). See gtk_window_move() and #GdkGravity for
7015 * The default window gravity is #GDK_GRAVITY_NORTH_WEST which will
7016 * typically "do what you mean."
7020 gtk_window_set_gravity (GtkWindow *window,
7023 g_return_if_fail (GTK_IS_WINDOW (window));
7025 if (gravity != window->gravity)
7027 window->gravity = gravity;
7029 /* gtk_window_move_resize() will adapt gravity
7031 gtk_widget_queue_resize (GTK_WIDGET (window));
7033 g_object_notify (G_OBJECT (window), "gravity");
7038 * gtk_window_get_gravity:
7039 * @window: a #GtkWindow
7041 * Gets the value set by gtk_window_set_gravity().
7043 * Return value: window gravity
7046 gtk_window_get_gravity (GtkWindow *window)
7048 g_return_val_if_fail (GTK_IS_WINDOW (window), 0);
7050 return window->gravity;
7054 * gtk_window_begin_resize_drag:
7055 * @window: a #GtkWindow
7056 * @button: mouse button that initiated the drag
7057 * @edge: position of the resize control
7058 * @root_x: X position where the user clicked to initiate the drag, in root window coordinates
7059 * @root_y: Y position where the user clicked to initiate the drag
7060 * @timestamp: timestamp from the click event that initiated the drag
7062 * Starts resizing a window. This function is used if an application
7063 * has window resizing controls. When GDK can support it, the resize
7064 * will be done using the standard mechanism for the <link
7065 * linkend="gtk-X11-arch">window manager</link> or windowing
7066 * system. Otherwise, GDK will try to emulate window resizing,
7067 * potentially not all that well, depending on the windowing system.
7071 gtk_window_begin_resize_drag (GtkWindow *window,
7079 GdkWindow *toplevel;
7081 g_return_if_fail (GTK_IS_WINDOW (window));
7082 g_return_if_fail (GTK_WIDGET_VISIBLE (window));
7084 widget = GTK_WIDGET (window);
7087 toplevel = window->frame;
7089 toplevel = widget->window;
7091 gdk_window_begin_resize_drag (toplevel,
7098 * gtk_window_get_frame_dimensions:
7099 * @window: a #GtkWindow
7100 * @left: location to store the width of the frame at the left, or %NULL
7101 * @top: location to store the height of the frame at the top, or %NULL
7102 * @right: location to store the width of the frame at the returns, or %NULL
7103 * @bottom: location to store the height of the frame at the bottom, or %NULL
7105 * (Note: this is a special-purpose function intended for the
7106 * framebuffer port; see gtk_window_set_has_frame(). It will not
7107 * return the size of the window border drawn by the <link
7108 * linkend="gtk-X11-arch">window manager</link>, which is the normal
7109 * case when using a windowing system. See
7110 * gdk_window_get_frame_extents() to get the standard window border
7113 * Retrieves the dimensions of the frame window for this toplevel.
7114 * See gtk_window_set_has_frame(), gtk_window_set_frame_dimensions().
7117 gtk_window_get_frame_dimensions (GtkWindow *window,
7123 g_return_if_fail (GTK_IS_WINDOW (window));
7126 *left = window->frame_left;
7128 *top = window->frame_top;
7130 *right = window->frame_right;
7132 *bottom = window->frame_bottom;
7136 * gtk_window_begin_move_drag:
7137 * @window: a #GtkWindow
7138 * @button: mouse button that initiated the drag
7139 * @root_x: X position where the user clicked to initiate the drag, in root window coordinates
7140 * @root_y: Y position where the user clicked to initiate the drag
7141 * @timestamp: timestamp from the click event that initiated the drag
7143 * Starts moving a window. This function is used if an application has
7144 * window movement grips. When GDK can support it, the window movement
7145 * will be done using the standard mechanism for the <link
7146 * linkend="gtk-X11-arch">window manager</link> or windowing
7147 * system. Otherwise, GDK will try to emulate window movement,
7148 * potentially not all that well, depending on the windowing system.
7152 gtk_window_begin_move_drag (GtkWindow *window,
7159 GdkWindow *toplevel;
7161 g_return_if_fail (GTK_IS_WINDOW (window));
7162 g_return_if_fail (GTK_WIDGET_VISIBLE (window));
7164 widget = GTK_WIDGET (window);
7167 toplevel = window->frame;
7169 toplevel = widget->window;
7171 gdk_window_begin_move_drag (toplevel,
7178 * gtk_window_set_screen:
7179 * @window: a #GtkWindow.
7180 * @screen: a #GdkScreen.
7182 * Sets the #GdkScreen where the @window is displayed; if
7183 * the window is already mapped, it will be unmapped, and
7184 * then remapped on the new screen.
7189 gtk_window_set_screen (GtkWindow *window,
7193 GdkScreen *previous_screen;
7194 gboolean was_mapped;
7196 g_return_if_fail (GTK_IS_WINDOW (window));
7197 g_return_if_fail (GDK_IS_SCREEN (screen));
7199 if (screen == window->screen)
7202 widget = GTK_WIDGET (window);
7204 previous_screen = window->screen;
7205 was_mapped = GTK_WIDGET_MAPPED (widget);
7208 gtk_widget_unmap (widget);
7209 if (GTK_WIDGET_REALIZED (widget))
7210 gtk_widget_unrealize (widget);
7212 gtk_window_free_key_hash (window);
7213 window->screen = screen;
7214 gtk_widget_reset_rc_styles (widget);
7215 if (screen != previous_screen)
7217 g_signal_handlers_disconnect_by_func (previous_screen,
7218 gtk_window_on_composited_changed, window);
7219 g_signal_connect (screen, "composited_changed",
7220 G_CALLBACK (gtk_window_on_composited_changed), window);
7222 _gtk_widget_propagate_screen_changed (widget, previous_screen);
7223 _gtk_widget_propagate_composited_changed (widget);
7225 g_object_notify (G_OBJECT (window), "screen");
7228 gtk_widget_map (widget);
7232 gtk_window_on_composited_changed (GdkScreen *screen,
7235 gtk_widget_queue_draw (GTK_WIDGET (window));
7237 _gtk_widget_propagate_composited_changed (GTK_WIDGET (window));
7241 gtk_window_check_screen (GtkWindow *window)
7244 return window->screen;
7247 g_warning ("Screen for GtkWindow not set; you must always set\n"
7248 "a screen for a GtkWindow before using the window");
7254 * gtk_window_get_screen:
7255 * @window: a #GtkWindow.
7257 * Returns the #GdkScreen associated with @window.
7259 * Return value: a #GdkScreen.
7264 gtk_window_get_screen (GtkWindow *window)
7266 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
7268 return window->screen;
7272 * gtk_window_is_active:
7273 * @window: a #GtkWindow
7275 * Returns whether the window is part of the current active toplevel.
7276 * (That is, the toplevel window receiving keystrokes.)
7277 * The return value is %TRUE if the window is active toplevel
7278 * itself, but also if it is, say, a #GtkPlug embedded in the active toplevel.
7279 * You might use this function if you wanted to draw a widget
7280 * differently in an active window from a widget in an inactive window.
7281 * See gtk_window_has_toplevel_focus()
7283 * Return value: %TRUE if the window part of the current active window.
7288 gtk_window_is_active (GtkWindow *window)
7290 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
7292 return window->is_active;
7296 * gtk_window_has_toplevel_focus:
7297 * @window: a #GtkWindow
7299 * Returns whether the input focus is within this GtkWindow.
7300 * For real toplevel windows, this is identical to gtk_window_is_active(),
7301 * but for embedded windows, like #GtkPlug, the results will differ.
7303 * Return value: %TRUE if the input focus is within this GtkWindow
7308 gtk_window_has_toplevel_focus (GtkWindow *window)
7310 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
7312 return window->has_toplevel_focus;
7316 gtk_window_group_class_init (GtkWindowGroupClass *klass)
7321 gtk_window_group_get_type (void)
7323 static GType window_group_type = 0;
7325 if (!window_group_type)
7327 const GTypeInfo window_group_info =
7329 sizeof (GtkWindowGroupClass),
7330 NULL, /* base_init */
7331 NULL, /* base_finalize */
7332 (GClassInitFunc) gtk_window_group_class_init,
7333 NULL, /* class_finalize */
7334 NULL, /* class_data */
7335 sizeof (GtkWindowGroup),
7336 0, /* n_preallocs */
7337 (GInstanceInitFunc) NULL,
7340 window_group_type = g_type_register_static (G_TYPE_OBJECT, I_("GtkWindowGroup"),
7341 &window_group_info, 0);
7344 return window_group_type;
7348 * gtk_window_group_new:
7350 * Creates a new #GtkWindowGroup object. Grabs added with
7351 * gtk_grab_add() only affect windows within the same #GtkWindowGroup.
7353 * Return value: a new #GtkWindowGroup.
7356 gtk_window_group_new (void)
7358 return g_object_new (GTK_TYPE_WINDOW_GROUP, NULL);
7362 window_group_cleanup_grabs (GtkWindowGroup *group,
7366 GSList *to_remove = NULL;
7368 tmp_list = group->grabs;
7371 if (gtk_widget_get_toplevel (tmp_list->data) == (GtkWidget*) window)
7372 to_remove = g_slist_prepend (to_remove, g_object_ref (tmp_list->data));
7373 tmp_list = tmp_list->next;
7378 gtk_grab_remove (to_remove->data);
7379 g_object_unref (to_remove->data);
7380 to_remove = g_slist_delete_link (to_remove, to_remove);
7385 * gtk_window_group_add_window:
7386 * @window_group: a #GtkWindowGroup
7387 * @window: the #GtkWindow to add
7389 * Adds a window to a #GtkWindowGroup.
7392 gtk_window_group_add_window (GtkWindowGroup *window_group,
7395 g_return_if_fail (GTK_IS_WINDOW_GROUP (window_group));
7396 g_return_if_fail (GTK_IS_WINDOW (window));
7398 if (window->group != window_group)
7400 g_object_ref (window);
7401 g_object_ref (window_group);
7404 gtk_window_group_remove_window (window->group, window);
7406 window_group_cleanup_grabs (gtk_window_get_group (NULL), window);
7408 window->group = window_group;
7410 g_object_unref (window);
7415 * gtk_window_group_remove_window:
7416 * @window_group: a #GtkWindowGroup
7417 * @window: the #GtkWindow to remove
7419 * Removes a window from a #GtkWindowGroup.
7422 gtk_window_group_remove_window (GtkWindowGroup *window_group,
7425 g_return_if_fail (GTK_IS_WINDOW_GROUP (window_group));
7426 g_return_if_fail (GTK_IS_WINDOW (window));
7427 g_return_if_fail (window->group == window_group);
7429 g_object_ref (window);
7431 window_group_cleanup_grabs (window_group, window);
7432 window->group = NULL;
7434 g_object_unref (window_group);
7435 g_object_unref (window);
7439 * gtk_window_get_group:
7440 * @window: a #GtkWindow, or %NULL
7442 * Returns the group for @window or the default group, if
7443 * @window is %NULL or if @window does not have an explicit
7446 * Returns: the #GtkWindowGroup for a window or the default group
7451 gtk_window_get_group (GtkWindow *window)
7453 if (window && window->group)
7454 return window->group;
7457 static GtkWindowGroup *default_group = NULL;
7460 default_group = gtk_window_group_new ();
7462 return default_group;
7466 /* Return the current grab widget of the given group
7469 _gtk_window_group_get_current_grab (GtkWindowGroup *window_group)
7471 if (window_group->grabs)
7472 return GTK_WIDGET (window_group->grabs->data);
7477 Derived from XParseGeometry() in XFree86
7479 Copyright 1985, 1986, 1987,1998 The Open Group
7481 All Rights Reserved.
7483 The above copyright notice and this permission notice shall be included
7484 in all copies or substantial portions of the Software.
7486 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
7487 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
7488 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
7489 IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
7490 OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
7491 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
7492 OTHER DEALINGS IN THE SOFTWARE.
7494 Except as contained in this notice, the name of The Open Group shall
7495 not be used in advertising or otherwise to promote the sale, use or
7496 other dealings in this Software without prior written authorization
7497 from The Open Group.
7502 * XParseGeometry parses strings of the form
7503 * "=<width>x<height>{+-}<xoffset>{+-}<yoffset>", where
7504 * width, height, xoffset, and yoffset are unsigned integers.
7505 * Example: "=80x24+300-49"
7506 * The equal sign is optional.
7507 * It returns a bitmask that indicates which of the four values
7508 * were actually found in the string. For each value found,
7509 * the corresponding argument is updated; for each value
7510 * not found, the corresponding argument is left unchanged.
7513 /* The following code is from Xlib, and is minimally modified, so we
7514 * can track any upstream changes if required. Don't change this
7515 * code. Or if you do, put in a huge comment marking which thing
7520 read_int (gchar *string,
7528 else if (*string == '-')
7534 for (; (*string >= '0') && (*string <= '9'); string++)
7536 result = (result * 10) + (*string - '0');
7548 * Bitmask returned by XParseGeometry(). Each bit tells if the corresponding
7549 * value (x, y, width, height) was found in the parsed string.
7551 #define NoValue 0x0000
7552 #define XValue 0x0001
7553 #define YValue 0x0002
7554 #define WidthValue 0x0004
7555 #define HeightValue 0x0008
7556 #define AllValues 0x000F
7557 #define XNegative 0x0010
7558 #define YNegative 0x0020
7560 /* Try not to reformat/modify, so we can compare/sync with X sources */
7562 gtk_XParseGeometry (const char *string,
7565 unsigned int *width,
7566 unsigned int *height)
7570 unsigned int tempWidth, tempHeight;
7572 char *nextCharacter;
7574 /* These initializations are just to silence gcc */
7580 if ( (string == NULL) || (*string == '\0')) return(mask);
7582 string++; /* ignore possible '=' at beg of geometry spec */
7584 strind = (char *)string;
7585 if (*strind != '+' && *strind != '-' && *strind != 'x') {
7586 tempWidth = read_int(strind, &nextCharacter);
7587 if (strind == nextCharacter)
7589 strind = nextCharacter;
7593 if (*strind == 'x' || *strind == 'X') {
7595 tempHeight = read_int(strind, &nextCharacter);
7596 if (strind == nextCharacter)
7598 strind = nextCharacter;
7599 mask |= HeightValue;
7602 if ((*strind == '+') || (*strind == '-')) {
7603 if (*strind == '-') {
7605 tempX = -read_int(strind, &nextCharacter);
7606 if (strind == nextCharacter)
7608 strind = nextCharacter;
7614 tempX = read_int(strind, &nextCharacter);
7615 if (strind == nextCharacter)
7617 strind = nextCharacter;
7620 if ((*strind == '+') || (*strind == '-')) {
7621 if (*strind == '-') {
7623 tempY = -read_int(strind, &nextCharacter);
7624 if (strind == nextCharacter)
7626 strind = nextCharacter;
7633 tempY = read_int(strind, &nextCharacter);
7634 if (strind == nextCharacter)
7636 strind = nextCharacter;
7642 /* If strind isn't at the end of the string the it's an invalid
7643 geometry specification. */
7645 if (*strind != '\0') return (0);
7651 if (mask & WidthValue)
7653 if (mask & HeightValue)
7654 *height = tempHeight;
7659 * gtk_window_parse_geometry:
7660 * @window: a #GtkWindow
7661 * @geometry: geometry string
7663 * Parses a standard X Window System geometry string - see the
7664 * manual page for X (type 'man X') for details on this.
7665 * gtk_window_parse_geometry() does work on all GTK+ ports
7666 * including Win32 but is primarily intended for an X environment.
7668 * If either a size or a position can be extracted from the
7669 * geometry string, gtk_window_parse_geometry() returns %TRUE
7670 * and calls gtk_window_set_default_size() and/or gtk_window_move()
7671 * to resize/move the window.
7673 * If gtk_window_parse_geometry() returns %TRUE, it will also
7674 * set the #GDK_HINT_USER_POS and/or #GDK_HINT_USER_SIZE hints
7675 * indicating to the window manager that the size/position of
7676 * the window was user-specified. This causes most window
7677 * managers to honor the geometry.
7679 * Note that for gtk_window_parse_geometry() to work as expected, it has
7680 * to be called when the window has its "final" size, i.e. after calling
7681 * gtk_widget_show_all() on the contents and gtk_window_set_geometry_hints()
7684 * #include <gtk/gtk.h>
7687 * fill_with_content (GtkWidget *vbox)
7689 * /* fill with content... */
7693 * main (int argc, char *argv[])
7695 * GtkWidget *window, *vbox;
7696 * GdkGeometry size_hints = {
7697 * 100, 50, 0, 0, 100, 50, 10, 10, 0.0, 0.0, GDK_GRAVITY_NORTH_WEST
7700 * gtk_init (&argc, &argv);
7702 * window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
7703 * vbox = gtk_vbox_new (FALSE, 0);
7705 * gtk_container_add (GTK_CONTAINER (window), vbox);
7706 * fill_with_content (vbox);
7707 * gtk_widget_show_all (vbox);
7709 * gtk_window_set_geometry_hints (GTK_WINDOW (window),
7712 * GDK_HINT_MIN_SIZE |
7713 * GDK_HINT_BASE_SIZE |
7714 * GDK_HINT_RESIZE_INC);
7718 * if (!gtk_window_parse_geometry (GTK_WINDOW (window), argv[1]))
7719 * fprintf (stderr, "Failed to parse '%s'\n", argv[1]);
7722 * gtk_widget_show_all (window);
7729 * Return value: %TRUE if string was parsed successfully
7732 gtk_window_parse_geometry (GtkWindow *window,
7733 const gchar *geometry)
7735 gint result, x = 0, y = 0;
7738 gboolean size_set, pos_set;
7741 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
7742 g_return_val_if_fail (geometry != NULL, FALSE);
7744 screen = gtk_window_check_screen (window);
7746 result = gtk_XParseGeometry (geometry, &x, &y, &w, &h);
7749 if ((result & WidthValue) || (result & HeightValue))
7751 gtk_window_set_default_size_internal (window,
7752 TRUE, result & WidthValue ? w : -1,
7753 TRUE, result & HeightValue ? h : -1,
7758 gtk_window_get_size (window, (gint *)&w, (gint *)&h);
7760 grav = GDK_GRAVITY_NORTH_WEST;
7762 if ((result & XNegative) && (result & YNegative))
7763 grav = GDK_GRAVITY_SOUTH_EAST;
7764 else if (result & XNegative)
7765 grav = GDK_GRAVITY_NORTH_EAST;
7766 else if (result & YNegative)
7767 grav = GDK_GRAVITY_SOUTH_WEST;
7769 if ((result & XValue) == 0)
7772 if ((result & YValue) == 0)
7775 if (grav == GDK_GRAVITY_SOUTH_WEST ||
7776 grav == GDK_GRAVITY_SOUTH_EAST)
7777 y = gdk_screen_get_height (screen) - h + y;
7779 if (grav == GDK_GRAVITY_SOUTH_EAST ||
7780 grav == GDK_GRAVITY_NORTH_EAST)
7781 x = gdk_screen_get_width (screen) - w + x;
7783 /* we don't let you put a window offscreen; maybe some people would
7784 * prefer to be able to, but it's kind of a bogus thing to do.
7793 if ((result & XValue) || (result & YValue))
7795 gtk_window_set_gravity (window, grav);
7796 gtk_window_move (window, x, y);
7800 if (size_set || pos_set)
7802 /* Set USSize, USPosition hints */
7803 GtkWindowGeometryInfo *info;
7805 info = gtk_window_get_geometry_info (window, TRUE);
7808 info->mask |= GDK_HINT_USER_POS;
7810 info->mask |= GDK_HINT_USER_SIZE;
7817 gtk_window_mnemonic_hash_foreach (guint keyval,
7823 GtkWindowKeysForeachFunc func;
7827 (*info->func) (info->window, keyval, info->window->mnemonic_modifier, TRUE, info->func_data);
7831 _gtk_window_keys_foreach (GtkWindow *window,
7832 GtkWindowKeysForeachFunc func,
7836 GtkMnemonicHash *mnemonic_hash;
7840 GtkWindowKeysForeachFunc func;
7844 info.window = window;
7846 info.func_data = func_data;
7848 mnemonic_hash = gtk_window_get_mnemonic_hash (window, FALSE);
7850 _gtk_mnemonic_hash_foreach (mnemonic_hash,
7851 gtk_window_mnemonic_hash_foreach, &info);
7853 groups = gtk_accel_groups_from_object (G_OBJECT (window));
7856 GtkAccelGroup *group = groups->data;
7859 for (i = 0; i < group->n_accels; i++)
7861 GtkAccelKey *key = &group->priv_accels[i].key;
7864 (*func) (window, key->accel_key, key->accel_mods, FALSE, func_data);
7867 groups = groups->next;
7872 gtk_window_keys_changed (GtkWindow *window)
7874 gtk_window_free_key_hash (window);
7875 gtk_window_get_key_hash (window);
7878 typedef struct _GtkWindowKeyEntry GtkWindowKeyEntry;
7880 struct _GtkWindowKeyEntry
7884 guint is_mnemonic : 1;
7888 window_key_entry_destroy (gpointer data)
7890 g_slice_free (GtkWindowKeyEntry, data);
7894 add_to_key_hash (GtkWindow *window,
7896 GdkModifierType modifiers,
7897 gboolean is_mnemonic,
7900 GtkKeyHash *key_hash = data;
7902 GtkWindowKeyEntry *entry = g_slice_new (GtkWindowKeyEntry);
7904 entry->keyval = keyval;
7905 entry->modifiers = modifiers;
7906 entry->is_mnemonic = is_mnemonic;
7908 /* GtkAccelGroup stores lowercased accelerators. To deal
7909 * with this, if <Shift> was specified, uppercase.
7911 if (modifiers & GDK_SHIFT_MASK)
7913 if (keyval == GDK_Tab)
7914 keyval = GDK_ISO_Left_Tab;
7916 keyval = gdk_keyval_to_upper (keyval);
7919 _gtk_key_hash_add_entry (key_hash, keyval, entry->modifiers, entry);
7923 gtk_window_get_key_hash (GtkWindow *window)
7925 GdkScreen *screen = gtk_window_check_screen (window);
7926 GtkKeyHash *key_hash = g_object_get_qdata (G_OBJECT (window), quark_gtk_window_key_hash);
7931 key_hash = _gtk_key_hash_new (gdk_keymap_get_for_display (gdk_screen_get_display (screen)),
7932 (GDestroyNotify)window_key_entry_destroy);
7933 _gtk_window_keys_foreach (window, add_to_key_hash, key_hash);
7934 g_object_set_qdata (G_OBJECT (window), quark_gtk_window_key_hash, key_hash);
7940 gtk_window_free_key_hash (GtkWindow *window)
7942 GtkKeyHash *key_hash = g_object_get_qdata (G_OBJECT (window), quark_gtk_window_key_hash);
7945 _gtk_key_hash_free (key_hash);
7946 g_object_set_qdata (G_OBJECT (window), quark_gtk_window_key_hash, NULL);
7951 * gtk_window_activate_key:
7952 * @window: a #GtkWindow
7953 * @event: a #GdkEventKey
7955 * Activates mnemonics and accelerators for this #GtkWindow. This is normally
7956 * called by the default ::key_press_event handler for toplevel windows,
7957 * however in some cases it may be useful to call this directly when
7958 * overriding the standard key handling for a toplevel window.
7960 * Return value: %TRUE if a mnemonic or accelerator was found and activated.
7963 gtk_window_activate_key (GtkWindow *window,
7966 GtkKeyHash *key_hash;
7967 GtkWindowKeyEntry *found_entry = NULL;
7969 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
7970 g_return_val_if_fail (event != NULL, FALSE);
7972 key_hash = gtk_window_get_key_hash (window);
7976 GSList *entries = _gtk_key_hash_lookup (key_hash,
7977 event->hardware_keycode,
7979 gtk_accelerator_get_default_mod_mask (),
7983 for (tmp_list = entries; tmp_list; tmp_list = tmp_list->next)
7985 GtkWindowKeyEntry *entry = tmp_list->data;
7986 if (entry->is_mnemonic)
7988 found_entry = entry;
7993 if (!found_entry && entries)
7994 found_entry = entries->data;
7996 g_slist_free (entries);
8001 gboolean enable_mnemonics;
8002 gboolean enable_accels;
8004 g_object_get (gtk_widget_get_settings (GTK_WIDGET (window)),
8005 "gtk-enable-mnemonics", &enable_mnemonics,
8006 "gtk-enable-accels", &enable_accels,
8009 if (found_entry->is_mnemonic)
8011 if (enable_mnemonics)
8012 return gtk_window_mnemonic_activate (window, found_entry->keyval,
8013 found_entry->modifiers);
8018 return gtk_accel_groups_activate (G_OBJECT (window), found_entry->keyval,
8019 found_entry->modifiers);
8027 window_update_has_focus (GtkWindow *window)
8029 GtkWidget *widget = GTK_WIDGET (window);
8030 gboolean has_focus = window->has_toplevel_focus && window->is_active;
8032 if (has_focus != window->has_focus)
8034 window->has_focus = has_focus;
8038 if (window->focus_widget &&
8039 window->focus_widget != widget &&
8040 !GTK_WIDGET_HAS_FOCUS (window->focus_widget))
8041 do_focus_change (window->focus_widget, TRUE);
8045 if (window->focus_widget &&
8046 window->focus_widget != widget &&
8047 GTK_WIDGET_HAS_FOCUS (window->focus_widget))
8048 do_focus_change (window->focus_widget, FALSE);
8054 * _gtk_window_set_is_active:
8055 * @window: a #GtkWindow
8056 * @is_active: %TRUE if the window is in the currently active toplevel
8058 * Internal function that sets whether the #GtkWindow is part
8059 * of the currently active toplevel window (taking into account inter-process
8063 _gtk_window_set_is_active (GtkWindow *window,
8066 g_return_if_fail (GTK_IS_WINDOW (window));
8068 is_active = is_active != FALSE;
8070 if (is_active != window->is_active)
8072 window->is_active = is_active;
8073 window_update_has_focus (window);
8075 g_object_notify (G_OBJECT (window), "is-active");
8080 * _gtk_window_set_has_toplevel_focus:
8081 * @window: a #GtkWindow
8082 * @has_toplevel_focus: %TRUE if the in
8084 * Internal function that sets whether the keyboard focus for the
8085 * toplevel window (taking into account inter-process embedding.)
8088 _gtk_window_set_has_toplevel_focus (GtkWindow *window,
8089 gboolean has_toplevel_focus)
8091 g_return_if_fail (GTK_IS_WINDOW (window));
8093 has_toplevel_focus = has_toplevel_focus != FALSE;
8095 if (has_toplevel_focus != window->has_toplevel_focus)
8097 window->has_toplevel_focus = has_toplevel_focus;
8098 window_update_has_focus (window);
8100 g_object_notify (G_OBJECT (window), "has-toplevel-focus");
8105 * gtk_window_set_auto_startup_notification:
8106 * @setting: %TRUE to automatically do startup notification
8108 * By default, after showing the first #GtkWindow, GTK+ calls
8109 * gdk_notify_startup_complete(). Call this function to disable
8110 * the automatic startup notification. You might do this if your
8111 * first window is a splash screen, and you want to delay notification
8112 * until after your real main window has been shown, for example.
8114 * In that example, you would disable startup notification
8115 * temporarily, show your splash screen, then re-enable it so that
8116 * showing the main window would automatically result in notification.
8121 gtk_window_set_auto_startup_notification (gboolean setting)
8123 disable_startup_notification = !setting;
8128 #undef gtk_window_set_icon_from_file
8131 gtk_window_set_icon_from_file (GtkWindow *window,
8132 const gchar *filename,
8135 gchar *utf8_filename = g_locale_to_utf8 (filename, -1, NULL, NULL, err);
8138 if (utf8_filename == NULL)
8141 retval = gtk_window_set_icon_from_file_utf8 (window, utf8_filename, err);
8143 g_free (utf8_filename);
8148 #undef gtk_window_set_default_icon_from_file
8151 gtk_window_set_default_icon_from_file (const gchar *filename,
8154 gchar *utf8_filename = g_locale_to_utf8 (filename, -1, NULL, NULL, err);
8157 if (utf8_filename == NULL)
8160 retval = gtk_window_set_default_icon_from_file_utf8 (utf8_filename, err);
8162 g_free (utf8_filename);
8169 #define __GTK_WINDOW_C__
8170 #include "gtkaliasdef.c"