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);
830 gtk_binding_entry_add_signal (binding_set, GDK_KP_Enter, 0,
831 "activate_default", 0);
833 add_arrow_bindings (binding_set, GDK_Up, GTK_DIR_UP);
834 add_arrow_bindings (binding_set, GDK_Down, GTK_DIR_DOWN);
835 add_arrow_bindings (binding_set, GDK_Left, GTK_DIR_LEFT);
836 add_arrow_bindings (binding_set, GDK_Right, GTK_DIR_RIGHT);
838 add_tab_bindings (binding_set, 0, GTK_DIR_TAB_FORWARD);
839 add_tab_bindings (binding_set, GDK_CONTROL_MASK, GTK_DIR_TAB_FORWARD);
840 add_tab_bindings (binding_set, GDK_SHIFT_MASK, GTK_DIR_TAB_BACKWARD);
841 add_tab_bindings (binding_set, GDK_CONTROL_MASK | GDK_SHIFT_MASK, GTK_DIR_TAB_BACKWARD);
845 gtk_window_init (GtkWindow *window)
847 GdkColormap *colormap;
848 GtkWindowPrivate *priv = GTK_WINDOW_GET_PRIVATE (window);
850 GTK_WIDGET_UNSET_FLAGS (window, GTK_NO_WINDOW);
851 GTK_WIDGET_SET_FLAGS (window, GTK_TOPLEVEL);
853 GTK_PRIVATE_SET_FLAG (window, GTK_ANCHORED);
855 gtk_container_set_resize_mode (GTK_CONTAINER (window), GTK_RESIZE_QUEUE);
857 window->title = NULL;
858 window->wmclass_name = g_strdup (g_get_prgname ());
859 window->wmclass_class = g_strdup (gdk_get_program_class ());
860 window->wm_role = NULL;
861 window->geometry_info = NULL;
862 window->type = GTK_WINDOW_TOPLEVEL;
863 window->focus_widget = NULL;
864 window->default_widget = NULL;
865 window->configure_request_count = 0;
866 window->allow_shrink = FALSE;
867 window->allow_grow = TRUE;
868 window->configure_notify_received = FALSE;
869 window->position = GTK_WIN_POS_NONE;
870 window->need_default_size = TRUE;
871 window->need_default_position = TRUE;
872 window->modal = FALSE;
873 window->frame = NULL;
874 window->has_frame = FALSE;
875 window->frame_left = 0;
876 window->frame_right = 0;
877 window->frame_top = 0;
878 window->frame_bottom = 0;
879 window->type_hint = GDK_WINDOW_TYPE_HINT_NORMAL;
880 window->gravity = GDK_GRAVITY_NORTH_WEST;
881 window->decorated = TRUE;
882 window->mnemonic_modifier = GDK_MOD1_MASK;
883 window->screen = gdk_screen_get_default ();
885 priv->accept_focus = TRUE;
886 priv->focus_on_map = TRUE;
887 priv->deletable = TRUE;
888 priv->type_hint = GDK_WINDOW_TYPE_HINT_NORMAL;
890 priv->startup_id = NULL;
892 colormap = _gtk_widget_peek_colormap ();
894 gtk_widget_set_colormap (GTK_WIDGET (window), colormap);
896 g_object_ref_sink (window);
897 window->has_user_ref_count = TRUE;
898 toplevel_list = g_slist_prepend (toplevel_list, window);
900 gtk_decorated_window_init (window);
902 g_signal_connect (window->screen, "composited_changed",
903 G_CALLBACK (gtk_window_on_composited_changed), window);
907 gtk_window_set_property (GObject *object,
914 window = GTK_WINDOW (object);
919 window->type = g_value_get_enum (value);
922 gtk_window_set_title (window, g_value_get_string (value));
925 gtk_window_set_role (window, g_value_get_string (value));
927 case PROP_STARTUP_ID:
928 gtk_window_set_startup_id (window, g_value_get_string (value));
930 case PROP_ALLOW_SHRINK:
931 window->allow_shrink = g_value_get_boolean (value);
932 gtk_widget_queue_resize (GTK_WIDGET (window));
934 case PROP_ALLOW_GROW:
935 window->allow_grow = g_value_get_boolean (value);
936 gtk_widget_queue_resize (GTK_WIDGET (window));
937 g_object_notify (G_OBJECT (window), "resizable");
940 window->allow_grow = g_value_get_boolean (value);
941 gtk_widget_queue_resize (GTK_WIDGET (window));
942 g_object_notify (G_OBJECT (window), "allow-grow");
945 gtk_window_set_modal (window, g_value_get_boolean (value));
948 gtk_window_set_position (window, g_value_get_enum (value));
950 case PROP_DEFAULT_WIDTH:
951 gtk_window_set_default_size_internal (window,
952 TRUE, g_value_get_int (value),
955 case PROP_DEFAULT_HEIGHT:
956 gtk_window_set_default_size_internal (window,
958 TRUE, g_value_get_int (value), FALSE);
960 case PROP_DESTROY_WITH_PARENT:
961 gtk_window_set_destroy_with_parent (window, g_value_get_boolean (value));
964 gtk_window_set_icon (window,
965 g_value_get_object (value));
968 gtk_window_set_icon_name (window, g_value_get_string (value));
971 gtk_window_set_screen (window, g_value_get_object (value));
974 gtk_window_set_type_hint (window,
975 g_value_get_enum (value));
977 case PROP_SKIP_TASKBAR_HINT:
978 gtk_window_set_skip_taskbar_hint (window,
979 g_value_get_boolean (value));
981 case PROP_SKIP_PAGER_HINT:
982 gtk_window_set_skip_pager_hint (window,
983 g_value_get_boolean (value));
985 case PROP_URGENCY_HINT:
986 gtk_window_set_urgency_hint (window,
987 g_value_get_boolean (value));
989 case PROP_ACCEPT_FOCUS:
990 gtk_window_set_accept_focus (window,
991 g_value_get_boolean (value));
993 case PROP_FOCUS_ON_MAP:
994 gtk_window_set_focus_on_map (window,
995 g_value_get_boolean (value));
998 gtk_window_set_decorated (window, g_value_get_boolean (value));
1000 case PROP_DELETABLE:
1001 gtk_window_set_deletable (window, g_value_get_boolean (value));
1004 gtk_window_set_gravity (window, g_value_get_enum (value));
1006 case PROP_TRANSIENT_FOR:
1007 gtk_window_set_transient_for (window, g_value_get_object (value));
1010 gtk_window_set_opacity (window, g_value_get_double (value));
1018 gtk_window_get_property (GObject *object,
1024 GtkWindowPrivate *priv;
1026 window = GTK_WINDOW (object);
1027 priv = GTK_WINDOW_GET_PRIVATE (window);
1031 GtkWindowGeometryInfo *info;
1033 g_value_set_enum (value, window->type);
1036 g_value_set_string (value, window->wm_role);
1039 g_value_set_string (value, window->title);
1041 case PROP_ALLOW_SHRINK:
1042 g_value_set_boolean (value, window->allow_shrink);
1044 case PROP_ALLOW_GROW:
1045 g_value_set_boolean (value, window->allow_grow);
1047 case PROP_RESIZABLE:
1048 g_value_set_boolean (value, window->allow_grow);
1051 g_value_set_boolean (value, window->modal);
1054 g_value_set_enum (value, window->position);
1056 case PROP_DEFAULT_WIDTH:
1057 info = gtk_window_get_geometry_info (window, FALSE);
1059 g_value_set_int (value, -1);
1061 g_value_set_int (value, info->default_width);
1063 case PROP_DEFAULT_HEIGHT:
1064 info = gtk_window_get_geometry_info (window, FALSE);
1066 g_value_set_int (value, -1);
1068 g_value_set_int (value, info->default_height);
1070 case PROP_DESTROY_WITH_PARENT:
1071 g_value_set_boolean (value, window->destroy_with_parent);
1074 g_value_set_object (value, gtk_window_get_icon (window));
1076 case PROP_ICON_NAME:
1077 g_value_set_string (value, gtk_window_get_icon_name (window));
1080 g_value_set_object (value, window->screen);
1082 case PROP_IS_ACTIVE:
1083 g_value_set_boolean (value, window->is_active);
1085 case PROP_HAS_TOPLEVEL_FOCUS:
1086 g_value_set_boolean (value, window->has_toplevel_focus);
1088 case PROP_TYPE_HINT:
1089 g_value_set_enum (value, priv->type_hint);
1091 case PROP_SKIP_TASKBAR_HINT:
1092 g_value_set_boolean (value,
1093 gtk_window_get_skip_taskbar_hint (window));
1095 case PROP_SKIP_PAGER_HINT:
1096 g_value_set_boolean (value,
1097 gtk_window_get_skip_pager_hint (window));
1099 case PROP_URGENCY_HINT:
1100 g_value_set_boolean (value,
1101 gtk_window_get_urgency_hint (window));
1103 case PROP_ACCEPT_FOCUS:
1104 g_value_set_boolean (value,
1105 gtk_window_get_accept_focus (window));
1107 case PROP_FOCUS_ON_MAP:
1108 g_value_set_boolean (value,
1109 gtk_window_get_focus_on_map (window));
1111 case PROP_DECORATED:
1112 g_value_set_boolean (value, gtk_window_get_decorated (window));
1114 case PROP_DELETABLE:
1115 g_value_set_boolean (value, gtk_window_get_deletable (window));
1118 g_value_set_enum (value, gtk_window_get_gravity (window));
1120 case PROP_TRANSIENT_FOR:
1121 g_value_set_object (value, gtk_window_get_transient_for (window));
1124 g_value_set_double (value, gtk_window_get_opacity (window));
1127 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1133 gtk_window_buildable_interface_init (GtkBuildableIface *iface)
1135 parent_buildable_iface = g_type_interface_peek_parent (iface);
1136 iface->set_buildable_property = gtk_window_buildable_set_buildable_property;
1137 iface->parser_finished = gtk_window_buildable_parser_finished;
1142 gtk_window_buildable_set_buildable_property (GtkBuildable *buildable,
1143 GtkBuilder *builder,
1145 const GValue *value)
1147 GtkWindowPrivate *priv = GTK_WINDOW_GET_PRIVATE (buildable);
1149 if (strcmp (name, "visible") == 0 && g_value_get_boolean (value))
1150 priv->builder_visible = TRUE;
1152 parent_buildable_iface->set_buildable_property (buildable, builder, name, value);
1156 gtk_window_buildable_parser_finished (GtkBuildable *buildable,
1157 GtkBuilder *builder)
1159 GtkWindowPrivate *priv = GTK_WINDOW_GET_PRIVATE (buildable);
1161 if (priv->builder_visible)
1162 gtk_widget_show (GTK_WIDGET (buildable));
1167 * @type: type of window
1169 * Creates a new #GtkWindow, which is a toplevel window that can
1170 * contain other widgets. Nearly always, the type of the window should
1171 * be #GTK_WINDOW_TOPLEVEL. If you're implementing something like a
1172 * popup menu from scratch (which is a bad idea, just use #GtkMenu),
1173 * you might use #GTK_WINDOW_POPUP. #GTK_WINDOW_POPUP is not for
1174 * dialogs, though in some other toolkits dialogs are called "popups".
1175 * In GTK+, #GTK_WINDOW_POPUP means a pop-up menu or pop-up tooltip.
1176 * On X11, popup windows are not controlled by the <link
1177 * linkend="gtk-X11-arch">window manager</link>.
1179 * If you simply want an undecorated window (no window borders), use
1180 * gtk_window_set_decorated(), don't use #GTK_WINDOW_POPUP.
1182 * Return value: a new #GtkWindow.
1185 gtk_window_new (GtkWindowType type)
1189 g_return_val_if_fail (type >= GTK_WINDOW_TOPLEVEL && type <= GTK_WINDOW_POPUP, NULL);
1191 window = g_object_new (GTK_TYPE_WINDOW, NULL);
1193 window->type = type;
1195 return GTK_WIDGET (window);
1199 * gtk_window_set_title:
1200 * @window: a #GtkWindow
1201 * @title: title of the window
1203 * Sets the title of the #GtkWindow. The title of a window will be
1204 * displayed in its title bar; on the X Window System, the title bar
1205 * is rendered by the <link linkend="gtk-X11-arch">window
1206 * manager</link>, so exactly how the title appears to users may vary
1207 * according to a user's exact configuration. The title should help a
1208 * user distinguish this window from other windows they may have
1209 * open. A good title might include the application name and current
1210 * document filename, for example.
1214 gtk_window_set_title (GtkWindow *window,
1219 g_return_if_fail (GTK_IS_WINDOW (window));
1221 new_title = g_strdup (title);
1222 g_free (window->title);
1223 window->title = new_title;
1225 if (GTK_WIDGET_REALIZED (window))
1227 gdk_window_set_title (GTK_WIDGET (window)->window, window->title);
1229 gtk_decorated_window_set_title (window, title);
1232 g_object_notify (G_OBJECT (window), "title");
1236 * gtk_window_get_title:
1237 * @window: a #GtkWindow
1239 * Retrieves the title of the window. See gtk_window_set_title().
1241 * Return value: the title of the window, or %NULL if none has
1242 * been set explicitely. The returned string is owned by the widget
1243 * and must not be modified or freed.
1245 G_CONST_RETURN gchar *
1246 gtk_window_get_title (GtkWindow *window)
1248 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
1250 return window->title;
1254 * gtk_window_set_wmclass:
1255 * @window: a #GtkWindow
1256 * @wmclass_name: window name hint
1257 * @wmclass_class: window class hint
1259 * Don't use this function. It sets the X Window System "class" and
1260 * "name" hints for a window. According to the ICCCM, you should
1261 * always set these to the same value for all windows in an
1262 * application, and GTK+ sets them to that value by default, so calling
1263 * this function is sort of pointless. However, you may want to call
1264 * gtk_window_set_role() on each window in your application, for the
1265 * benefit of the session manager. Setting the role allows the window
1266 * manager to restore window positions when loading a saved session.
1270 gtk_window_set_wmclass (GtkWindow *window,
1271 const gchar *wmclass_name,
1272 const gchar *wmclass_class)
1274 g_return_if_fail (GTK_IS_WINDOW (window));
1276 g_free (window->wmclass_name);
1277 window->wmclass_name = g_strdup (wmclass_name);
1279 g_free (window->wmclass_class);
1280 window->wmclass_class = g_strdup (wmclass_class);
1282 if (GTK_WIDGET_REALIZED (window))
1283 g_warning ("gtk_window_set_wmclass: shouldn't set wmclass after window is realized!\n");
1287 * gtk_window_set_role:
1288 * @window: a #GtkWindow
1289 * @role: unique identifier for the window to be used when restoring a session
1291 * This function is only useful on X11, not with other GTK+ targets.
1293 * In combination with the window title, the window role allows a
1294 * <link linkend="gtk-X11-arch">window manager</link> to identify "the
1295 * same" window when an application is restarted. So for example you
1296 * might set the "toolbox" role on your app's toolbox window, so that
1297 * when the user restarts their session, the window manager can put
1298 * the toolbox back in the same place.
1300 * If a window already has a unique title, you don't need to set the
1301 * role, since the WM can use the title to identify the window when
1302 * restoring the session.
1306 gtk_window_set_role (GtkWindow *window,
1311 g_return_if_fail (GTK_IS_WINDOW (window));
1313 new_role = g_strdup (role);
1314 g_free (window->wm_role);
1315 window->wm_role = new_role;
1317 if (GTK_WIDGET_REALIZED (window))
1318 gdk_window_set_role (GTK_WIDGET (window)->window, window->wm_role);
1320 g_object_notify (G_OBJECT (window), "role");
1324 * gtk_window_set_startup_id:
1325 * @window: a #GtkWindow
1326 * @startup_id: a string with startup-notification identifier
1328 * Startup notification identifiers are used by desktop environment to
1329 * track application startup, to provide user feedback and other
1330 * features. This function changes the corresponding property on the
1331 * underlying GdkWindow. Normally, startup identifier is managed
1332 * automatically and you should only use this function in special cases
1333 * like transferring focus from other processes. You should use this
1334 * function before calling gtk_window_present() or any equivalent
1335 * function generating a window map event.
1337 * This function is only useful on X11, not with other GTK+ targets.
1342 gtk_window_set_startup_id (GtkWindow *window,
1343 const gchar *startup_id)
1345 GtkWindowPrivate *priv = GTK_WINDOW_GET_PRIVATE (window);
1347 g_return_if_fail (GTK_IS_WINDOW (window));
1349 g_free (priv->startup_id);
1350 priv->startup_id = g_strdup (startup_id);
1352 if (GTK_WIDGET_REALIZED (window))
1354 /* Here we differentiate real and "fake" startup notification IDs,
1355 * constructed on purpose just to pass interaction timestamp
1357 if (startup_id_is_fake (priv->startup_id))
1359 guint32 timestamp = extract_time_from_startup_id (priv->startup_id);
1361 gtk_window_present_with_time (window, timestamp);
1365 gdk_window_set_startup_id (GTK_WIDGET (window)->window,
1368 /* If window is mapped, terminate the startup-notification too */
1369 if (GTK_WIDGET_MAPPED (window) && !disable_startup_notification)
1370 gdk_notify_startup_complete_with_id (priv->startup_id);
1374 g_object_notify (G_OBJECT (window), "startup-id");
1378 * gtk_window_get_role:
1379 * @window: a #GtkWindow
1381 * Returns the role of the window. See gtk_window_set_role() for
1382 * further explanation.
1384 * Return value: the role of the window if set, or %NULL. The
1385 * returned is owned by the widget and must not be modified
1388 G_CONST_RETURN gchar *
1389 gtk_window_get_role (GtkWindow *window)
1391 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
1393 return window->wm_role;
1397 * gtk_window_set_focus:
1398 * @window: a #GtkWindow
1399 * @focus: widget to be the new focus widget, or %NULL to unset
1400 * any focus widget for the toplevel window.
1402 * If @focus is not the current focus widget, and is focusable, sets
1403 * it as the focus widget for the window. If @focus is %NULL, unsets
1404 * the focus widget for this window. To set the focus to a particular
1405 * widget in the toplevel, it is usually more convenient to use
1406 * gtk_widget_grab_focus() instead of this function.
1409 gtk_window_set_focus (GtkWindow *window,
1412 g_return_if_fail (GTK_IS_WINDOW (window));
1415 g_return_if_fail (GTK_IS_WIDGET (focus));
1416 g_return_if_fail (GTK_WIDGET_CAN_FOCUS (focus));
1420 gtk_widget_grab_focus (focus);
1423 /* Clear the existing focus chain, so that when we focus into
1424 * the window again, we start at the beginnning.
1426 GtkWidget *widget = window->focus_widget;
1429 while (widget->parent)
1431 widget = widget->parent;
1432 gtk_container_set_focus_child (GTK_CONTAINER (widget), NULL);
1436 _gtk_window_internal_set_focus (window, NULL);
1441 _gtk_window_internal_set_focus (GtkWindow *window,
1444 g_return_if_fail (GTK_IS_WINDOW (window));
1446 if ((window->focus_widget != focus) ||
1447 (focus && !GTK_WIDGET_HAS_FOCUS (focus)))
1448 g_signal_emit (window, window_signals[SET_FOCUS], 0, focus);
1452 * gtk_window_set_default:
1453 * @window: a #GtkWindow
1454 * @default_widget: widget to be the default, or %NULL to unset the
1455 * default widget for the toplevel.
1457 * The default widget is the widget that's activated when the user
1458 * presses Enter in a dialog (for example). This function sets or
1459 * unsets the default widget for a #GtkWindow about. When setting
1460 * (rather than unsetting) the default widget it's generally easier to
1461 * call gtk_widget_grab_focus() on the widget. Before making a widget
1462 * the default widget, you must set the #GTK_CAN_DEFAULT flag on the
1463 * widget you'd like to make the default using GTK_WIDGET_SET_FLAGS().
1466 gtk_window_set_default (GtkWindow *window,
1467 GtkWidget *default_widget)
1469 g_return_if_fail (GTK_IS_WINDOW (window));
1472 g_return_if_fail (GTK_WIDGET_CAN_DEFAULT (default_widget));
1474 if (window->default_widget != default_widget)
1476 GtkWidget *old_default_widget = NULL;
1479 g_object_ref (default_widget);
1481 if (window->default_widget)
1483 old_default_widget = window->default_widget;
1485 if (window->focus_widget != window->default_widget ||
1486 !GTK_WIDGET_RECEIVES_DEFAULT (window->default_widget))
1487 GTK_WIDGET_UNSET_FLAGS (window->default_widget, GTK_HAS_DEFAULT);
1488 gtk_widget_queue_draw (window->default_widget);
1491 window->default_widget = default_widget;
1493 if (window->default_widget)
1495 if (window->focus_widget == NULL ||
1496 !GTK_WIDGET_RECEIVES_DEFAULT (window->focus_widget))
1497 GTK_WIDGET_SET_FLAGS (window->default_widget, GTK_HAS_DEFAULT);
1498 gtk_widget_queue_draw (window->default_widget);
1501 if (old_default_widget)
1502 g_object_notify (G_OBJECT (old_default_widget), "has-default");
1506 g_object_notify (G_OBJECT (default_widget), "has-default");
1507 g_object_unref (default_widget);
1513 gtk_window_set_policy (GtkWindow *window,
1514 gboolean allow_shrink,
1515 gboolean allow_grow,
1516 gboolean auto_shrink)
1518 g_return_if_fail (GTK_IS_WINDOW (window));
1520 window->allow_shrink = (allow_shrink != FALSE);
1521 window->allow_grow = (allow_grow != FALSE);
1523 g_object_freeze_notify (G_OBJECT (window));
1524 g_object_notify (G_OBJECT (window), "allow-shrink");
1525 g_object_notify (G_OBJECT (window), "allow-grow");
1526 g_object_notify (G_OBJECT (window), "resizable");
1527 g_object_thaw_notify (G_OBJECT (window));
1529 gtk_widget_queue_resize (GTK_WIDGET (window));
1533 handle_keys_changed (gpointer data)
1537 window = GTK_WINDOW (data);
1539 if (window->keys_changed_handler)
1541 g_source_remove (window->keys_changed_handler);
1542 window->keys_changed_handler = 0;
1545 g_signal_emit (window, window_signals[KEYS_CHANGED], 0);
1551 gtk_window_notify_keys_changed (GtkWindow *window)
1553 if (!window->keys_changed_handler)
1554 window->keys_changed_handler = gdk_threads_add_idle (handle_keys_changed, window);
1558 * gtk_window_add_accel_group:
1559 * @window: window to attach accelerator group to
1560 * @accel_group: a #GtkAccelGroup
1562 * Associate @accel_group with @window, such that calling
1563 * gtk_accel_groups_activate() on @window will activate accelerators
1567 gtk_window_add_accel_group (GtkWindow *window,
1568 GtkAccelGroup *accel_group)
1570 g_return_if_fail (GTK_IS_WINDOW (window));
1571 g_return_if_fail (GTK_IS_ACCEL_GROUP (accel_group));
1573 _gtk_accel_group_attach (accel_group, G_OBJECT (window));
1574 g_signal_connect_object (accel_group, "accel_changed",
1575 G_CALLBACK (gtk_window_notify_keys_changed),
1576 window, G_CONNECT_SWAPPED);
1577 gtk_window_notify_keys_changed (window);
1581 * gtk_window_remove_accel_group:
1582 * @window: a #GtkWindow
1583 * @accel_group: a #GtkAccelGroup
1585 * Reverses the effects of gtk_window_add_accel_group().
1588 gtk_window_remove_accel_group (GtkWindow *window,
1589 GtkAccelGroup *accel_group)
1591 g_return_if_fail (GTK_IS_WINDOW (window));
1592 g_return_if_fail (GTK_IS_ACCEL_GROUP (accel_group));
1594 g_signal_handlers_disconnect_by_func (accel_group,
1595 gtk_window_notify_keys_changed,
1597 _gtk_accel_group_detach (accel_group, G_OBJECT (window));
1598 gtk_window_notify_keys_changed (window);
1601 static GtkMnemonicHash *
1602 gtk_window_get_mnemonic_hash (GtkWindow *window,
1605 GtkWindowPrivate *private = GTK_WINDOW_GET_PRIVATE (window);
1606 if (!private->mnemonic_hash && create)
1607 private->mnemonic_hash = _gtk_mnemonic_hash_new ();
1609 return private->mnemonic_hash;
1613 * gtk_window_add_mnemonic:
1614 * @window: a #GtkWindow
1615 * @keyval: the mnemonic
1616 * @target: the widget that gets activated by the mnemonic
1618 * Adds a mnemonic to this window.
1621 gtk_window_add_mnemonic (GtkWindow *window,
1625 g_return_if_fail (GTK_IS_WINDOW (window));
1626 g_return_if_fail (GTK_IS_WIDGET (target));
1628 _gtk_mnemonic_hash_add (gtk_window_get_mnemonic_hash (window, TRUE),
1630 gtk_window_notify_keys_changed (window);
1634 * gtk_window_remove_mnemonic:
1635 * @window: a #GtkWindow
1636 * @keyval: the mnemonic
1637 * @target: the widget that gets activated by the mnemonic
1639 * Removes a mnemonic from this window.
1642 gtk_window_remove_mnemonic (GtkWindow *window,
1646 g_return_if_fail (GTK_IS_WINDOW (window));
1647 g_return_if_fail (GTK_IS_WIDGET (target));
1649 _gtk_mnemonic_hash_remove (gtk_window_get_mnemonic_hash (window, TRUE),
1651 gtk_window_notify_keys_changed (window);
1655 * gtk_window_mnemonic_activate:
1656 * @window: a #GtkWindow
1657 * @keyval: the mnemonic
1658 * @modifier: the modifiers
1659 * @returns: %TRUE if the activation is done.
1661 * Activates the targets associated with the mnemonic.
1664 gtk_window_mnemonic_activate (GtkWindow *window,
1666 GdkModifierType modifier)
1668 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
1670 if (window->mnemonic_modifier == (modifier & gtk_accelerator_get_default_mod_mask ()))
1672 GtkMnemonicHash *mnemonic_hash = gtk_window_get_mnemonic_hash (window, FALSE);
1674 return _gtk_mnemonic_hash_activate (mnemonic_hash, keyval);
1681 * gtk_window_set_mnemonic_modifier:
1682 * @window: a #GtkWindow
1683 * @modifier: the modifier mask used to activate
1684 * mnemonics on this window.
1686 * Sets the mnemonic modifier for this window.
1689 gtk_window_set_mnemonic_modifier (GtkWindow *window,
1690 GdkModifierType modifier)
1692 g_return_if_fail (GTK_IS_WINDOW (window));
1693 g_return_if_fail ((modifier & ~GDK_MODIFIER_MASK) == 0);
1695 window->mnemonic_modifier = modifier;
1696 gtk_window_notify_keys_changed (window);
1700 * gtk_window_get_mnemonic_modifier:
1701 * @window: a #GtkWindow
1703 * Returns the mnemonic modifier for this window. See
1704 * gtk_window_set_mnemonic_modifier().
1706 * Return value: the modifier mask used to activate
1707 * mnemonics on this window.
1710 gtk_window_get_mnemonic_modifier (GtkWindow *window)
1712 g_return_val_if_fail (GTK_IS_WINDOW (window), 0);
1714 return window->mnemonic_modifier;
1718 * gtk_window_set_position:
1719 * @window: a #GtkWindow.
1720 * @position: a position constraint.
1722 * Sets a position constraint for this window. If the old or new
1723 * constraint is %GTK_WIN_POS_CENTER_ALWAYS, this will also cause
1724 * the window to be repositioned to satisfy the new constraint.
1727 gtk_window_set_position (GtkWindow *window,
1728 GtkWindowPosition position)
1730 g_return_if_fail (GTK_IS_WINDOW (window));
1732 if (position == GTK_WIN_POS_CENTER_ALWAYS ||
1733 window->position == GTK_WIN_POS_CENTER_ALWAYS)
1735 GtkWindowGeometryInfo *info;
1737 info = gtk_window_get_geometry_info (window, TRUE);
1739 /* this flag causes us to re-request the CENTER_ALWAYS
1740 * constraint in gtk_window_move_resize(), see
1741 * comment in that function.
1743 info->position_constraints_changed = TRUE;
1745 gtk_widget_queue_resize (GTK_WIDGET (window));
1748 window->position = position;
1750 g_object_notify (G_OBJECT (window), "window-position");
1754 * gtk_window_activate_focus:
1755 * @window: a #GtkWindow
1757 * Activates the current focused widget within the window.
1759 * Return value: %TRUE if a widget got activated.
1762 gtk_window_activate_focus (GtkWindow *window)
1764 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
1766 if (window->focus_widget && GTK_WIDGET_IS_SENSITIVE (window->focus_widget))
1767 return gtk_widget_activate (window->focus_widget);
1773 * gtk_window_get_focus:
1774 * @window: a #GtkWindow
1776 * Retrieves the current focused widget within the window.
1777 * Note that this is the widget that would have the focus
1778 * if the toplevel window focused; if the toplevel window
1779 * is not focused then <literal>GTK_WIDGET_HAS_FOCUS (widget)</literal> will
1780 * not be %TRUE for the widget.
1782 * Return value: the currently focused widget, or %NULL if there is none.
1785 gtk_window_get_focus (GtkWindow *window)
1787 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
1789 return window->focus_widget;
1793 * gtk_window_activate_default:
1794 * @window: a #GtkWindow
1796 * Activates the default widget for the window, unless the current
1797 * focused widget has been configured to receive the default action
1798 * (see #GTK_RECEIVES_DEFAULT in #GtkWidgetFlags), in which case the
1799 * focused widget is activated.
1801 * Return value: %TRUE if a widget got activated.
1804 gtk_window_activate_default (GtkWindow *window)
1806 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
1808 if (window->default_widget && GTK_WIDGET_IS_SENSITIVE (window->default_widget) &&
1809 (!window->focus_widget || !GTK_WIDGET_RECEIVES_DEFAULT (window->focus_widget)))
1810 return gtk_widget_activate (window->default_widget);
1811 else if (window->focus_widget && GTK_WIDGET_IS_SENSITIVE (window->focus_widget))
1812 return gtk_widget_activate (window->focus_widget);
1818 * gtk_window_set_modal:
1819 * @window: a #GtkWindow
1820 * @modal: whether the window is modal
1822 * Sets a window modal or non-modal. Modal windows prevent interaction
1823 * with other windows in the same application. To keep modal dialogs
1824 * on top of main application windows, use
1825 * gtk_window_set_transient_for() to make the dialog transient for the
1826 * parent; most <link linkend="gtk-X11-arch">window managers</link>
1827 * will then disallow lowering the dialog below the parent.
1832 gtk_window_set_modal (GtkWindow *window,
1835 g_return_if_fail (GTK_IS_WINDOW (window));
1837 modal = modal != FALSE;
1838 if (window->modal == modal)
1841 window->modal = modal;
1843 /* adjust desired modality state */
1844 if (GTK_WIDGET_REALIZED (window))
1846 GtkWidget *widget = GTK_WIDGET (window);
1849 gdk_window_set_modal_hint (widget->window, TRUE);
1851 gdk_window_set_modal_hint (widget->window, FALSE);
1854 if (GTK_WIDGET_VISIBLE (window))
1857 gtk_grab_add (GTK_WIDGET (window));
1859 gtk_grab_remove (GTK_WIDGET (window));
1862 g_object_notify (G_OBJECT (window), "modal");
1866 * gtk_window_get_modal:
1867 * @window: a #GtkWindow
1869 * Returns whether the window is modal. See gtk_window_set_modal().
1871 * Return value: %TRUE if the window is set to be modal and
1872 * establishes a grab when shown
1875 gtk_window_get_modal (GtkWindow *window)
1877 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
1879 return window->modal;
1883 * gtk_window_list_toplevels:
1885 * Returns a list of all existing toplevel windows. The widgets
1886 * in the list are not individually referenced. If you want
1887 * to iterate through the list and perform actions involving
1888 * callbacks that might destroy the widgets, you <emphasis>must</emphasis> call
1889 * <literal>g_list_foreach (result, (GFunc)g_object_ref, NULL)</literal> first, and
1890 * then unref all the widgets afterwards.
1892 * Return value: list of toplevel widgets
1895 gtk_window_list_toplevels (void)
1900 for (slist = toplevel_list; slist; slist = slist->next)
1901 list = g_list_prepend (list, slist->data);
1907 gtk_window_add_embedded_xid (GtkWindow *window, guint xid)
1909 GList *embedded_windows;
1911 g_return_if_fail (GTK_IS_WINDOW (window));
1913 embedded_windows = g_object_get_qdata (G_OBJECT (window), quark_gtk_embedded);
1914 if (embedded_windows)
1915 g_object_steal_qdata (G_OBJECT (window), quark_gtk_embedded);
1916 embedded_windows = g_list_prepend (embedded_windows,
1917 GUINT_TO_POINTER (xid));
1919 g_object_set_qdata_full (G_OBJECT (window), quark_gtk_embedded,
1922 (GDestroyNotify) g_list_free : NULL);
1926 gtk_window_remove_embedded_xid (GtkWindow *window, guint xid)
1928 GList *embedded_windows;
1931 g_return_if_fail (GTK_IS_WINDOW (window));
1933 embedded_windows = g_object_get_qdata (G_OBJECT (window), quark_gtk_embedded);
1934 if (embedded_windows)
1935 g_object_steal_qdata (G_OBJECT (window), quark_gtk_embedded);
1937 node = g_list_find (embedded_windows, GUINT_TO_POINTER (xid));
1940 embedded_windows = g_list_remove_link (embedded_windows, node);
1941 g_list_free_1 (node);
1944 g_object_set_qdata_full (G_OBJECT (window), quark_gtk_embedded,
1947 (GDestroyNotify) g_list_free : NULL);
1951 _gtk_window_reposition (GtkWindow *window,
1955 g_return_if_fail (GTK_IS_WINDOW (window));
1957 gtk_window_move (window, x, y);
1961 gtk_window_dispose (GObject *object)
1963 GtkWindow *window = GTK_WINDOW (object);
1965 gtk_window_set_focus (window, NULL);
1966 gtk_window_set_default (window, NULL);
1968 G_OBJECT_CLASS (gtk_window_parent_class)->dispose (object);
1972 parent_destroyed_callback (GtkWindow *parent, GtkWindow *child)
1974 gtk_widget_destroy (GTK_WIDGET (child));
1978 connect_parent_destroyed (GtkWindow *window)
1980 if (window->transient_parent)
1982 g_signal_connect (window->transient_parent,
1984 G_CALLBACK (parent_destroyed_callback),
1990 disconnect_parent_destroyed (GtkWindow *window)
1992 if (window->transient_parent)
1994 g_signal_handlers_disconnect_by_func (window->transient_parent,
1995 parent_destroyed_callback,
2001 gtk_window_transient_parent_realized (GtkWidget *parent,
2004 if (GTK_WIDGET_REALIZED (window))
2005 gdk_window_set_transient_for (window->window, parent->window);
2009 gtk_window_transient_parent_unrealized (GtkWidget *parent,
2012 if (GTK_WIDGET_REALIZED (window))
2013 gdk_property_delete (window->window,
2014 gdk_atom_intern_static_string ("WM_TRANSIENT_FOR"));
2018 gtk_window_transient_parent_screen_changed (GtkWindow *parent,
2022 gtk_window_set_screen (window, parent->screen);
2026 gtk_window_unset_transient_for (GtkWindow *window)
2028 GtkWindowPrivate *priv = GTK_WINDOW_GET_PRIVATE (window);
2030 if (window->transient_parent)
2032 if (priv->transient_parent_group)
2033 gtk_window_group_remove_window (window->group,
2036 g_signal_handlers_disconnect_by_func (window->transient_parent,
2037 gtk_window_transient_parent_realized,
2039 g_signal_handlers_disconnect_by_func (window->transient_parent,
2040 gtk_window_transient_parent_unrealized,
2042 g_signal_handlers_disconnect_by_func (window->transient_parent,
2043 gtk_window_transient_parent_screen_changed,
2045 g_signal_handlers_disconnect_by_func (window->transient_parent,
2046 gtk_widget_destroyed,
2047 &window->transient_parent);
2049 if (window->destroy_with_parent)
2050 disconnect_parent_destroyed (window);
2052 window->transient_parent = NULL;
2053 priv->transient_parent_group = FALSE;
2058 * gtk_window_set_transient_for:
2059 * @window: a #GtkWindow
2060 * @parent: parent window
2062 * Dialog windows should be set transient for the main application
2063 * window they were spawned from. This allows <link
2064 * linkend="gtk-X11-arch">window managers</link> to e.g. keep the
2065 * dialog on top of the main window, or center the dialog over the
2066 * main window. gtk_dialog_new_with_buttons() and other convenience
2067 * functions in GTK+ will sometimes call
2068 * gtk_window_set_transient_for() on your behalf.
2070 * On Windows, this function puts the child window on top of the parent,
2071 * much as the window manager would have done on X.
2075 gtk_window_set_transient_for (GtkWindow *window,
2078 GtkWindowPrivate *priv = GTK_WINDOW_GET_PRIVATE (window);
2080 g_return_if_fail (GTK_IS_WINDOW (window));
2081 g_return_if_fail (parent == NULL || GTK_IS_WINDOW (parent));
2082 g_return_if_fail (window != parent);
2084 if (window->transient_parent)
2086 if (GTK_WIDGET_REALIZED (window) &&
2087 GTK_WIDGET_REALIZED (window->transient_parent) &&
2088 (!parent || !GTK_WIDGET_REALIZED (parent)))
2089 gtk_window_transient_parent_unrealized (GTK_WIDGET (window->transient_parent),
2090 GTK_WIDGET (window));
2092 gtk_window_unset_transient_for (window);
2095 window->transient_parent = parent;
2099 g_signal_connect (parent, "destroy",
2100 G_CALLBACK (gtk_widget_destroyed),
2101 &window->transient_parent);
2102 g_signal_connect (parent, "realize",
2103 G_CALLBACK (gtk_window_transient_parent_realized),
2105 g_signal_connect (parent, "unrealize",
2106 G_CALLBACK (gtk_window_transient_parent_unrealized),
2108 g_signal_connect (parent, "notify::screen",
2109 G_CALLBACK (gtk_window_transient_parent_screen_changed),
2112 gtk_window_set_screen (window, parent->screen);
2114 if (window->destroy_with_parent)
2115 connect_parent_destroyed (window);
2117 if (GTK_WIDGET_REALIZED (window) &&
2118 GTK_WIDGET_REALIZED (parent))
2119 gtk_window_transient_parent_realized (GTK_WIDGET (parent),
2120 GTK_WIDGET (window));
2124 gtk_window_group_add_window (parent->group, window);
2125 priv->transient_parent_group = TRUE;
2131 * gtk_window_get_transient_for:
2132 * @window: a #GtkWindow
2134 * Fetches the transient parent for this window. See
2135 * gtk_window_set_transient_for().
2137 * Return value: the transient parent for this window, or %NULL
2138 * if no transient parent has been set.
2141 gtk_window_get_transient_for (GtkWindow *window)
2143 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
2145 return window->transient_parent;
2149 * gtk_window_set_opacity:
2150 * @window: a #GtkWindow
2151 * @opacity: desired opacity, between 0 and 1
2153 * Request the windowing system to make @window partially transparent,
2154 * with opacity 0 being fully transparent and 1 fully opaque. (Values
2155 * of the opacity parameter are clamped to the [0,1] range.) On X11
2156 * this has any effect only on X screens with a compositing manager
2157 * running. See gtk_widget_is_composited(). On Windows it should work
2160 * Note that setting a window's opacity after the window has been
2161 * shown causes it to flicker once on Windows.
2166 gtk_window_set_opacity (GtkWindow *window,
2169 GtkWindowPrivate *priv;
2171 g_return_if_fail (GTK_IS_WINDOW (window));
2173 priv = GTK_WINDOW_GET_PRIVATE (window);
2177 else if (opacity > 1.0)
2180 priv->opacity_set = TRUE;
2181 priv->opacity = opacity;
2183 if (GTK_WIDGET_REALIZED (window))
2184 gdk_window_set_opacity (GTK_WIDGET (window)->window, priv->opacity);
2188 * gtk_window_get_opacity:
2189 * @window: a #GtkWindow
2191 * Fetches the requested opacity for this window. See
2192 * gtk_window_set_opacity().
2194 * Return value: the requested opacity for this window.
2199 gtk_window_get_opacity (GtkWindow *window)
2201 GtkWindowPrivate *priv;
2203 g_return_val_if_fail (GTK_IS_WINDOW (window), 0.0);
2205 priv = GTK_WINDOW_GET_PRIVATE (window);
2207 return priv->opacity;
2211 * gtk_window_set_type_hint:
2212 * @window: a #GtkWindow
2213 * @hint: the window type
2215 * By setting the type hint for the window, you allow the window
2216 * manager to decorate and handle the window in a way which is
2217 * suitable to the function of the window in your application.
2219 * This function should be called before the window becomes visible.
2221 * gtk_dialog_new_with_buttons() and other convenience functions in GTK+
2222 * will sometimes call gtk_window_set_type_hint() on your behalf.
2226 gtk_window_set_type_hint (GtkWindow *window,
2227 GdkWindowTypeHint hint)
2229 GtkWindowPrivate *priv;
2231 g_return_if_fail (GTK_IS_WINDOW (window));
2232 g_return_if_fail (!GTK_WIDGET_VISIBLE (window));
2234 priv = GTK_WINDOW_GET_PRIVATE (window);
2236 if (hint < GDK_WINDOW_TYPE_HINT_DROPDOWN_MENU)
2237 window->type_hint = hint;
2239 window->type_hint = GDK_WINDOW_TYPE_HINT_NORMAL;
2241 priv->reset_type_hint = TRUE;
2242 priv->type_hint = hint;
2246 * gtk_window_get_type_hint:
2247 * @window: a #GtkWindow
2249 * Gets the type hint for this window. See gtk_window_set_type_hint().
2251 * Return value: the type hint for @window.
2254 gtk_window_get_type_hint (GtkWindow *window)
2256 GtkWindowPrivate *priv;
2258 g_return_val_if_fail (GTK_IS_WINDOW (window), GDK_WINDOW_TYPE_HINT_NORMAL);
2260 priv = GTK_WINDOW_GET_PRIVATE (window);
2262 return priv->type_hint;
2266 * gtk_window_set_skip_taskbar_hint:
2267 * @window: a #GtkWindow
2268 * @setting: %TRUE to keep this window from appearing in the task bar
2270 * Windows may set a hint asking the desktop environment not to display
2271 * the window in the task bar. This function sets this hint.
2276 gtk_window_set_skip_taskbar_hint (GtkWindow *window,
2279 GtkWindowPrivate *priv;
2281 g_return_if_fail (GTK_IS_WINDOW (window));
2283 priv = GTK_WINDOW_GET_PRIVATE (window);
2285 setting = setting != FALSE;
2287 if (priv->skips_taskbar != setting)
2289 priv->skips_taskbar = setting;
2290 if (GTK_WIDGET_REALIZED (window))
2291 gdk_window_set_skip_taskbar_hint (GTK_WIDGET (window)->window,
2292 priv->skips_taskbar);
2293 g_object_notify (G_OBJECT (window), "skip-taskbar-hint");
2298 * gtk_window_get_skip_taskbar_hint:
2299 * @window: a #GtkWindow
2301 * Gets the value set by gtk_window_set_skip_taskbar_hint()
2303 * Return value: %TRUE if window shouldn't be in taskbar
2308 gtk_window_get_skip_taskbar_hint (GtkWindow *window)
2310 GtkWindowPrivate *priv;
2312 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
2314 priv = GTK_WINDOW_GET_PRIVATE (window);
2316 return priv->skips_taskbar;
2320 * gtk_window_set_skip_pager_hint:
2321 * @window: a #GtkWindow
2322 * @setting: %TRUE to keep this window from appearing in the pager
2324 * Windows may set a hint asking the desktop environment not to display
2325 * the window in the pager. This function sets this hint.
2326 * (A "pager" is any desktop navigation tool such as a workspace
2327 * switcher that displays a thumbnail representation of the windows
2333 gtk_window_set_skip_pager_hint (GtkWindow *window,
2336 GtkWindowPrivate *priv;
2338 g_return_if_fail (GTK_IS_WINDOW (window));
2340 priv = GTK_WINDOW_GET_PRIVATE (window);
2342 setting = setting != FALSE;
2344 if (priv->skips_pager != setting)
2346 priv->skips_pager = setting;
2347 if (GTK_WIDGET_REALIZED (window))
2348 gdk_window_set_skip_pager_hint (GTK_WIDGET (window)->window,
2350 g_object_notify (G_OBJECT (window), "skip-pager-hint");
2355 * gtk_window_get_skip_pager_hint:
2356 * @window: a #GtkWindow
2358 * Gets the value set by gtk_window_set_skip_pager_hint().
2360 * Return value: %TRUE if window shouldn't be in pager
2365 gtk_window_get_skip_pager_hint (GtkWindow *window)
2367 GtkWindowPrivate *priv;
2369 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
2371 priv = GTK_WINDOW_GET_PRIVATE (window);
2373 return priv->skips_pager;
2377 * gtk_window_set_urgency_hint:
2378 * @window: a #GtkWindow
2379 * @setting: %TRUE to mark this window as urgent
2381 * Windows may set a hint asking the desktop environment to draw
2382 * the users attention to the window. This function sets this hint.
2387 gtk_window_set_urgency_hint (GtkWindow *window,
2390 GtkWindowPrivate *priv;
2392 g_return_if_fail (GTK_IS_WINDOW (window));
2394 priv = GTK_WINDOW_GET_PRIVATE (window);
2396 setting = setting != FALSE;
2398 if (priv->urgent != setting)
2400 priv->urgent = setting;
2401 if (GTK_WIDGET_REALIZED (window))
2402 gdk_window_set_urgency_hint (GTK_WIDGET (window)->window,
2404 g_object_notify (G_OBJECT (window), "urgency-hint");
2409 * gtk_window_get_urgency_hint:
2410 * @window: a #GtkWindow
2412 * Gets the value set by gtk_window_set_urgency_hint()
2414 * Return value: %TRUE if window is urgent
2419 gtk_window_get_urgency_hint (GtkWindow *window)
2421 GtkWindowPrivate *priv;
2423 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
2425 priv = GTK_WINDOW_GET_PRIVATE (window);
2427 return priv->urgent;
2431 * gtk_window_set_accept_focus:
2432 * @window: a #GtkWindow
2433 * @setting: %TRUE to let this window receive input focus
2435 * Windows may set a hint asking the desktop environment not to receive
2436 * the input focus. This function sets this hint.
2441 gtk_window_set_accept_focus (GtkWindow *window,
2444 GtkWindowPrivate *priv;
2446 g_return_if_fail (GTK_IS_WINDOW (window));
2448 priv = GTK_WINDOW_GET_PRIVATE (window);
2450 setting = setting != FALSE;
2452 if (priv->accept_focus != setting)
2454 priv->accept_focus = setting;
2455 if (GTK_WIDGET_REALIZED (window))
2456 gdk_window_set_accept_focus (GTK_WIDGET (window)->window,
2457 priv->accept_focus);
2458 g_object_notify (G_OBJECT (window), "accept-focus");
2463 * gtk_window_get_accept_focus:
2464 * @window: a #GtkWindow
2466 * Gets the value set by gtk_window_set_accept_focus().
2468 * Return value: %TRUE if window should receive the input focus
2473 gtk_window_get_accept_focus (GtkWindow *window)
2475 GtkWindowPrivate *priv;
2477 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
2479 priv = GTK_WINDOW_GET_PRIVATE (window);
2481 return priv->accept_focus;
2485 * gtk_window_set_focus_on_map:
2486 * @window: a #GtkWindow
2487 * @setting: %TRUE to let this window receive input focus on map
2489 * Windows may set a hint asking the desktop environment not to receive
2490 * the input focus when the window is mapped. This function sets this
2496 gtk_window_set_focus_on_map (GtkWindow *window,
2499 GtkWindowPrivate *priv;
2501 g_return_if_fail (GTK_IS_WINDOW (window));
2503 priv = GTK_WINDOW_GET_PRIVATE (window);
2505 setting = setting != FALSE;
2507 if (priv->focus_on_map != setting)
2509 priv->focus_on_map = setting;
2510 if (GTK_WIDGET_REALIZED (window))
2511 gdk_window_set_focus_on_map (GTK_WIDGET (window)->window,
2512 priv->focus_on_map);
2513 g_object_notify (G_OBJECT (window), "focus-on-map");
2518 * gtk_window_get_focus_on_map:
2519 * @window: a #GtkWindow
2521 * Gets the value set by gtk_window_set_focus_on_map().
2523 * Return value: %TRUE if window should receive the input focus when
2529 gtk_window_get_focus_on_map (GtkWindow *window)
2531 GtkWindowPrivate *priv;
2533 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
2535 priv = GTK_WINDOW_GET_PRIVATE (window);
2537 return priv->focus_on_map;
2541 * gtk_window_set_destroy_with_parent:
2542 * @window: a #GtkWindow
2543 * @setting: whether to destroy @window with its transient parent
2545 * If @setting is %TRUE, then destroying the transient parent of @window
2546 * will also destroy @window itself. This is useful for dialogs that
2547 * shouldn't persist beyond the lifetime of the main window they're
2548 * associated with, for example.
2551 gtk_window_set_destroy_with_parent (GtkWindow *window,
2554 g_return_if_fail (GTK_IS_WINDOW (window));
2556 if (window->destroy_with_parent == (setting != FALSE))
2559 if (window->destroy_with_parent)
2561 disconnect_parent_destroyed (window);
2565 connect_parent_destroyed (window);
2568 window->destroy_with_parent = setting;
2570 g_object_notify (G_OBJECT (window), "destroy-with-parent");
2574 * gtk_window_get_destroy_with_parent:
2575 * @window: a #GtkWindow
2577 * Returns whether the window will be destroyed with its transient parent. See
2578 * gtk_window_set_destroy_with_parent ().
2580 * Return value: %TRUE if the window will be destroyed with its transient parent.
2583 gtk_window_get_destroy_with_parent (GtkWindow *window)
2585 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
2587 return window->destroy_with_parent;
2590 static GtkWindowGeometryInfo*
2591 gtk_window_get_geometry_info (GtkWindow *window,
2594 GtkWindowGeometryInfo *info;
2596 info = window->geometry_info;
2597 if (!info && create)
2599 info = g_new0 (GtkWindowGeometryInfo, 1);
2601 info->default_width = -1;
2602 info->default_height = -1;
2603 info->resize_width = -1;
2604 info->resize_height = -1;
2605 info->initial_x = 0;
2606 info->initial_y = 0;
2607 info->initial_pos_set = FALSE;
2608 info->default_is_geometry = FALSE;
2609 info->position_constraints_changed = FALSE;
2610 info->last.configure_request.x = 0;
2611 info->last.configure_request.y = 0;
2612 info->last.configure_request.width = -1;
2613 info->last.configure_request.height = -1;
2614 info->widget = NULL;
2616 window->geometry_info = info;
2623 * gtk_window_set_geometry_hints:
2624 * @window: a #GtkWindow
2625 * @geometry_widget: widget the geometry hints will be applied to
2626 * @geometry: struct containing geometry information
2627 * @geom_mask: mask indicating which struct fields should be paid attention to
2629 * This function sets up hints about how a window can be resized by
2630 * the user. You can set a minimum and maximum size; allowed resize
2631 * increments (e.g. for xterm, you can only resize by the size of a
2632 * character); aspect ratios; and more. See the #GdkGeometry struct.
2636 gtk_window_set_geometry_hints (GtkWindow *window,
2637 GtkWidget *geometry_widget,
2638 GdkGeometry *geometry,
2639 GdkWindowHints geom_mask)
2641 GtkWindowGeometryInfo *info;
2643 g_return_if_fail (GTK_IS_WINDOW (window));
2644 g_return_if_fail (geometry_widget == NULL || GTK_IS_WIDGET (geometry_widget));
2646 info = gtk_window_get_geometry_info (window, TRUE);
2649 g_signal_handlers_disconnect_by_func (info->widget,
2650 gtk_widget_destroyed,
2653 info->widget = geometry_widget;
2655 g_signal_connect (geometry_widget, "destroy",
2656 G_CALLBACK (gtk_widget_destroyed),
2660 info->geometry = *geometry;
2662 /* We store gravity in window->gravity not in the hints. */
2663 info->mask = geom_mask & ~(GDK_HINT_WIN_GRAVITY);
2665 if (geom_mask & GDK_HINT_WIN_GRAVITY)
2667 gtk_window_set_gravity (window, geometry->win_gravity);
2670 gtk_widget_queue_resize (GTK_WIDGET (window));
2674 * gtk_window_set_decorated:
2675 * @window: a #GtkWindow
2676 * @setting: %TRUE to decorate the window
2678 * By default, windows are decorated with a title bar, resize
2679 * controls, etc. Some <link linkend="gtk-X11-arch">window
2680 * managers</link> allow GTK+ to disable these decorations, creating a
2681 * borderless window. If you set the decorated property to %FALSE
2682 * using this function, GTK+ will do its best to convince the window
2683 * manager not to decorate the window. Depending on the system, this
2684 * function may not have any effect when called on a window that is
2685 * already visible, so you should call it before calling gtk_window_show().
2687 * On Windows, this function always works, since there's no window manager
2692 gtk_window_set_decorated (GtkWindow *window,
2695 g_return_if_fail (GTK_IS_WINDOW (window));
2697 setting = setting != FALSE;
2699 if (setting == window->decorated)
2702 window->decorated = setting;
2704 if (GTK_WIDGET (window)->window)
2706 if (window->decorated)
2707 gdk_window_set_decorations (GTK_WIDGET (window)->window,
2710 gdk_window_set_decorations (GTK_WIDGET (window)->window,
2714 g_object_notify (G_OBJECT (window), "decorated");
2718 * gtk_window_get_decorated:
2719 * @window: a #GtkWindow
2721 * Returns whether the window has been set to have decorations
2722 * such as a title bar via gtk_window_set_decorated().
2724 * Return value: %TRUE if the window has been set to have decorations
2727 gtk_window_get_decorated (GtkWindow *window)
2729 g_return_val_if_fail (GTK_IS_WINDOW (window), TRUE);
2731 return window->decorated;
2735 * gtk_window_set_deletable:
2736 * @window: a #GtkWindow
2737 * @setting: %TRUE to decorate the window as deletable
2739 * By default, windows have a close button in the window frame. Some
2740 * <link linkend="gtk-X11-arch">window managers</link> allow GTK+ to
2741 * disable this button. If you set the deletable property to %FALSE
2742 * using this function, GTK+ will do its best to convince the window
2743 * manager not to show a close button. Depending on the system, this
2744 * function may not have any effect when called on a window that is
2745 * already visible, so you should call it before calling gtk_window_show().
2747 * On Windows, this function always works, since there's no window manager
2753 gtk_window_set_deletable (GtkWindow *window,
2756 GtkWindowPrivate *priv;
2758 g_return_if_fail (GTK_IS_WINDOW (window));
2760 priv = GTK_WINDOW_GET_PRIVATE (window);
2762 setting = setting != FALSE;
2764 if (setting == priv->deletable)
2767 priv->deletable = setting;
2769 if (GTK_WIDGET (window)->window)
2771 if (priv->deletable)
2772 gdk_window_set_functions (GTK_WIDGET (window)->window,
2775 gdk_window_set_functions (GTK_WIDGET (window)->window,
2776 GDK_FUNC_ALL | GDK_FUNC_CLOSE);
2779 g_object_notify (G_OBJECT (window), "deletable");
2783 * gtk_window_get_deletable:
2784 * @window: a #GtkWindow
2786 * Returns whether the window has been set to have a close button
2787 * via gtk_window_set_deletable().
2789 * Return value: %TRUE if the window has been set to have a close button
2794 gtk_window_get_deletable (GtkWindow *window)
2796 GtkWindowPrivate *priv;
2798 g_return_val_if_fail (GTK_IS_WINDOW (window), TRUE);
2800 priv = GTK_WINDOW_GET_PRIVATE (window);
2802 return priv->deletable;
2805 static GtkWindowIconInfo*
2806 get_icon_info (GtkWindow *window)
2808 return g_object_get_qdata (G_OBJECT (window), quark_gtk_window_icon_info);
2812 free_icon_info (GtkWindowIconInfo *info)
2814 g_free (info->icon_name);
2815 g_slice_free (GtkWindowIconInfo, info);
2819 static GtkWindowIconInfo*
2820 ensure_icon_info (GtkWindow *window)
2822 GtkWindowIconInfo *info;
2824 info = get_icon_info (window);
2828 info = g_slice_new0 (GtkWindowIconInfo);
2829 g_object_set_qdata_full (G_OBJECT (window),
2830 quark_gtk_window_icon_info,
2832 (GDestroyNotify)free_icon_info);
2844 static ScreenIconInfo *
2845 get_screen_icon_info (GdkScreen *screen)
2847 ScreenIconInfo *info = g_object_get_qdata (G_OBJECT (screen),
2848 quark_gtk_window_default_icon_pixmap);
2851 info = g_slice_new0 (ScreenIconInfo);
2852 g_object_set_qdata (G_OBJECT (screen),
2853 quark_gtk_window_default_icon_pixmap, info);
2856 if (info->serial != default_icon_serial)
2860 g_object_remove_weak_pointer (G_OBJECT (info->pixmap), (gpointer*)&info->pixmap);
2861 info->pixmap = NULL;
2866 g_object_remove_weak_pointer (G_OBJECT (info->mask), (gpointer*)&info->mask);
2870 info->serial = default_icon_serial;
2877 get_pixmap_and_mask (GdkWindow *window,
2878 GtkWindowIconInfo *parent_info,
2879 gboolean is_default_list,
2881 GdkPixmap **pmap_return,
2882 GdkBitmap **mask_return)
2884 GdkScreen *screen = gdk_drawable_get_screen (window);
2885 ScreenIconInfo *default_icon_info = get_screen_icon_info (screen);
2886 GdkPixbuf *best_icon;
2890 *pmap_return = NULL;
2891 *mask_return = NULL;
2893 if (is_default_list &&
2894 default_icon_info->pixmap != NULL)
2896 /* Use shared icon pixmap for all windows on this screen.
2898 if (default_icon_info->pixmap)
2899 g_object_ref (default_icon_info->pixmap);
2900 if (default_icon_info->mask)
2901 g_object_ref (default_icon_info->mask);
2903 *pmap_return = default_icon_info->pixmap;
2904 *mask_return = default_icon_info->mask;
2906 else if (parent_info && parent_info->icon_pixmap)
2908 if (parent_info->icon_pixmap)
2909 g_object_ref (parent_info->icon_pixmap);
2910 if (parent_info->icon_mask)
2911 g_object_ref (parent_info->icon_mask);
2913 *pmap_return = parent_info->icon_pixmap;
2914 *mask_return = parent_info->icon_mask;
2918 #define IDEAL_SIZE 48
2920 best_size = G_MAXINT;
2922 tmp_list = icon_list;
2923 while (tmp_list != NULL)
2925 GdkPixbuf *pixbuf = tmp_list->data;
2928 /* average width and height - if someone passes in a rectangular
2929 * icon they deserve what they get.
2931 this = gdk_pixbuf_get_width (pixbuf) + gdk_pixbuf_get_height (pixbuf);
2934 if (best_icon == NULL)
2941 /* icon is better if it's 32 pixels or larger, and closer to
2942 * the ideal size than the current best.
2945 (ABS (best_size - IDEAL_SIZE) <
2946 ABS (this - IDEAL_SIZE)))
2953 tmp_list = tmp_list->next;
2957 gdk_pixbuf_render_pixmap_and_mask_for_colormap (best_icon,
2958 gdk_screen_get_system_colormap (screen),
2963 /* Save pmap/mask for others to use if appropriate */
2966 parent_info->icon_pixmap = *pmap_return;
2967 parent_info->icon_mask = *mask_return;
2969 if (parent_info->icon_pixmap)
2970 g_object_ref (parent_info->icon_pixmap);
2971 if (parent_info->icon_mask)
2972 g_object_ref (parent_info->icon_mask);
2974 else if (is_default_list)
2976 default_icon_info->pixmap = *pmap_return;
2977 default_icon_info->mask = *mask_return;
2979 if (default_icon_info->pixmap)
2980 g_object_add_weak_pointer (G_OBJECT (default_icon_info->pixmap),
2981 (gpointer*)&default_icon_info->pixmap);
2982 if (default_icon_info->mask)
2983 g_object_add_weak_pointer (G_OBJECT (default_icon_info->mask),
2984 (gpointer*)&default_icon_info->mask);
2990 icon_list_from_theme (GtkWidget *widget,
2995 GtkIconTheme *icon_theme;
3000 icon_theme = gtk_icon_theme_get_for_screen (gtk_widget_get_screen (widget));
3002 sizes = gtk_icon_theme_get_icon_sizes (icon_theme, name);
3005 for (i = 0; sizes[i]; i++)
3008 * We need an EWMH extension to handle scalable icons
3009 * by passing their name to the WM. For now just use a
3013 icon = gtk_icon_theme_load_icon (icon_theme, name,
3016 icon = gtk_icon_theme_load_icon (icon_theme, name,
3019 list = g_list_append (list, icon);
3029 gtk_window_realize_icon (GtkWindow *window)
3032 GtkWindowIconInfo *info;
3035 widget = GTK_WIDGET (window);
3037 g_return_if_fail (widget->window != NULL);
3039 /* no point setting an icon on override-redirect */
3040 if (window->type == GTK_WINDOW_POPUP)
3045 info = ensure_icon_info (window);
3050 g_return_if_fail (info->icon_pixmap == NULL);
3051 g_return_if_fail (info->icon_mask == NULL);
3053 info->using_default_icon = FALSE;
3054 info->using_parent_icon = FALSE;
3055 info->using_themed_icon = FALSE;
3057 icon_list = info->icon_list;
3059 /* Look up themed icon */
3060 if (icon_list == NULL && info->icon_name)
3062 icon_list = icon_list_from_theme (widget, info->icon_name);
3064 info->using_themed_icon = TRUE;
3067 /* Inherit from transient parent */
3068 if (icon_list == NULL && window->transient_parent)
3070 icon_list = ensure_icon_info (window->transient_parent)->icon_list;
3072 info->using_parent_icon = TRUE;
3075 /* Inherit from default */
3076 if (icon_list == NULL)
3078 icon_list = default_icon_list;
3080 info->using_default_icon = TRUE;
3083 /* Look up themed icon */
3084 if (icon_list == NULL && default_icon_name)
3086 icon_list = icon_list_from_theme (widget, default_icon_name);
3087 info->using_default_icon = TRUE;
3088 info->using_themed_icon = TRUE;
3091 gdk_window_set_icon_list (widget->window, icon_list);
3093 get_pixmap_and_mask (widget->window,
3094 info->using_parent_icon ? ensure_icon_info (window->transient_parent) : NULL,
3095 info->using_default_icon,
3100 /* This is a slight ICCCM violation since it's a color pixmap not
3101 * a bitmap, but everyone does it.
3103 gdk_window_set_icon (widget->window,
3108 info->realized = TRUE;
3110 if (info->using_themed_icon)
3112 GtkIconTheme *icon_theme;
3114 g_list_foreach (icon_list, (GFunc) g_object_unref, NULL);
3115 g_list_free (icon_list);
3117 icon_theme = gtk_icon_theme_get_for_screen (gtk_widget_get_screen (GTK_WIDGET (window)));
3118 g_signal_connect (icon_theme, "changed",
3119 G_CALLBACK (update_themed_icon), window);
3124 gtk_window_unrealize_icon (GtkWindow *window)
3126 GtkWindowIconInfo *info;
3128 info = get_icon_info (window);
3133 if (info->icon_pixmap)
3134 g_object_unref (info->icon_pixmap);
3136 if (info->icon_mask)
3137 g_object_unref (info->icon_mask);
3139 info->icon_pixmap = NULL;
3140 info->icon_mask = NULL;
3142 if (info->using_themed_icon)
3144 GtkIconTheme *icon_theme;
3146 icon_theme = gtk_icon_theme_get_for_screen (gtk_widget_get_screen (GTK_WIDGET (window)));
3148 g_signal_handlers_disconnect_by_func (icon_theme, update_themed_icon, window);
3151 /* We don't clear the properties on the window, just figure the
3152 * window is going away.
3155 info->realized = FALSE;
3160 * gtk_window_set_icon_list:
3161 * @window: a #GtkWindow
3162 * @list: list of #GdkPixbuf
3164 * Sets up the icon representing a #GtkWindow. The icon is used when
3165 * the window is minimized (also known as iconified). Some window
3166 * managers or desktop environments may also place it in the window
3167 * frame, or display it in other contexts.
3169 * gtk_window_set_icon_list() allows you to pass in the same icon in
3170 * several hand-drawn sizes. The list should contain the natural sizes
3171 * your icon is available in; that is, don't scale the image before
3172 * passing it to GTK+. Scaling is postponed until the last minute,
3173 * when the desired final size is known, to allow best quality.
3175 * By passing several sizes, you may improve the final image quality
3176 * of the icon, by reducing or eliminating automatic image scaling.
3178 * Recommended sizes to provide: 16x16, 32x32, 48x48 at minimum, and
3179 * larger images (64x64, 128x128) if you have them.
3181 * See also gtk_window_set_default_icon_list() to set the icon
3182 * for all windows in your application in one go.
3184 * Note that transient windows (those who have been set transient for another
3185 * window using gtk_window_set_transient_for()) will inherit their
3186 * icon from their transient parent. So there's no need to explicitly
3187 * set the icon on transient windows.
3190 gtk_window_set_icon_list (GtkWindow *window,
3193 GtkWindowIconInfo *info;
3195 g_return_if_fail (GTK_IS_WINDOW (window));
3197 info = ensure_icon_info (window);
3199 if (info->icon_list == list) /* check for NULL mostly */
3202 g_list_foreach (list,
3203 (GFunc) g_object_ref, NULL);
3205 g_list_foreach (info->icon_list,
3206 (GFunc) g_object_unref, NULL);
3208 g_list_free (info->icon_list);
3210 info->icon_list = g_list_copy (list);
3212 g_object_notify (G_OBJECT (window), "icon");
3214 gtk_window_unrealize_icon (window);
3216 if (GTK_WIDGET_REALIZED (window))
3217 gtk_window_realize_icon (window);
3219 /* We could try to update our transient children, but I don't think
3220 * it's really worth it. If we did it, the best way would probably
3221 * be to have children connect to notify::icon-list
3226 * gtk_window_get_icon_list:
3227 * @window: a #GtkWindow
3229 * Retrieves the list of icons set by gtk_window_set_icon_list().
3230 * The list is copied, but the reference count on each
3231 * member won't be incremented.
3233 * Return value: copy of window's icon list
3236 gtk_window_get_icon_list (GtkWindow *window)
3238 GtkWindowIconInfo *info;
3240 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
3242 info = get_icon_info (window);
3245 return g_list_copy (info->icon_list);
3251 * gtk_window_set_icon:
3252 * @window: a #GtkWindow
3253 * @icon: icon image, or %NULL
3255 * Sets up the icon representing a #GtkWindow. This icon is used when
3256 * the window is minimized (also known as iconified). Some window
3257 * managers or desktop environments may also place it in the window
3258 * frame, or display it in other contexts.
3260 * The icon should be provided in whatever size it was naturally
3261 * drawn; that is, don't scale the image before passing it to
3262 * GTK+. Scaling is postponed until the last minute, when the desired
3263 * final size is known, to allow best quality.
3265 * If you have your icon hand-drawn in multiple sizes, use
3266 * gtk_window_set_icon_list(). Then the best size will be used.
3268 * This function is equivalent to calling gtk_window_set_icon_list()
3269 * with a 1-element list.
3271 * See also gtk_window_set_default_icon_list() to set the icon
3272 * for all windows in your application in one go.
3275 gtk_window_set_icon (GtkWindow *window,
3280 g_return_if_fail (GTK_IS_WINDOW (window));
3281 g_return_if_fail (icon == NULL || GDK_IS_PIXBUF (icon));
3286 list = g_list_append (list, icon);
3288 gtk_window_set_icon_list (window, list);
3294 update_themed_icon (GtkIconTheme *icon_theme,
3297 g_object_notify (G_OBJECT (window), "icon");
3299 gtk_window_unrealize_icon (window);
3301 if (GTK_WIDGET_REALIZED (window))
3302 gtk_window_realize_icon (window);
3306 * gtk_window_set_icon_name:
3307 * @window: a #GtkWindow
3308 * @name: the name of the themed icon
3310 * Sets the icon for the window from a named themed icon. See
3311 * the docs for #GtkIconTheme for more details.
3313 * Note that this has nothing to do with the WM_ICON_NAME
3314 * property which is mentioned in the ICCCM.
3319 gtk_window_set_icon_name (GtkWindow *window,
3322 GtkWindowIconInfo *info;
3325 g_return_if_fail (GTK_IS_WINDOW (window));
3327 info = ensure_icon_info (window);
3329 tmp = info->icon_name;
3330 info->icon_name = g_strdup (name);
3333 g_list_foreach (info->icon_list, (GFunc) g_object_unref, NULL);
3334 g_list_free (info->icon_list);
3335 info->icon_list = NULL;
3337 update_themed_icon (NULL, window);
3339 g_object_notify (G_OBJECT (window), "icon-name");
3343 * gtk_window_get_icon_name:
3344 * @window: a #GtkWindow
3346 * Returns the name of the themed icon for the window,
3347 * see gtk_window_set_icon_name().
3349 * Returns: the icon name or %NULL if the window has
3354 G_CONST_RETURN gchar *
3355 gtk_window_get_icon_name (GtkWindow *window)
3357 GtkWindowIconInfo *info;
3359 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
3361 info = ensure_icon_info (window);
3363 return info->icon_name;
3367 * gtk_window_get_icon:
3368 * @window: a #GtkWindow
3370 * Gets the value set by gtk_window_set_icon() (or if you've
3371 * called gtk_window_set_icon_list(), gets the first icon in
3374 * Return value: icon for window
3377 gtk_window_get_icon (GtkWindow *window)
3379 GtkWindowIconInfo *info;
3381 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
3383 info = get_icon_info (window);
3384 if (info && info->icon_list)
3385 return GDK_PIXBUF (info->icon_list->data);
3390 /* Load pixbuf, printing warning on failure if error == NULL
3393 load_pixbuf_verbosely (const char *filename,
3396 GError *local_err = NULL;
3399 pixbuf = gdk_pixbuf_new_from_file (filename, &local_err);
3407 g_warning ("Error loading icon from file '%s':\n\t%s",
3408 filename, local_err->message);
3409 g_error_free (local_err);
3417 * gtk_window_set_icon_from_file:
3418 * @window: a #GtkWindow
3419 * @filename: location of icon file
3420 * @err: location to store error, or %NULL.
3422 * Sets the icon for @window.
3423 * Warns on failure if @err is %NULL.
3425 * This function is equivalent to calling gtk_window_set_icon()
3426 * with a pixbuf created by loading the image from @filename.
3428 * Returns: %TRUE if setting the icon succeeded.
3433 gtk_window_set_icon_from_file (GtkWindow *window,
3434 const gchar *filename,
3437 GdkPixbuf *pixbuf = load_pixbuf_verbosely (filename, err);
3441 gtk_window_set_icon (window, pixbuf);
3442 g_object_unref (pixbuf);
3451 * gtk_window_set_default_icon_list:
3452 * @list: a list of #GdkPixbuf
3454 * Sets an icon list to be used as fallback for windows that haven't
3455 * had gtk_window_set_icon_list() called on them to set up a
3456 * window-specific icon list. This function allows you to set up the
3457 * icon for all windows in your app at once.
3459 * See gtk_window_set_icon_list() for more details.
3463 gtk_window_set_default_icon_list (GList *list)
3467 if (list == default_icon_list)
3470 /* Update serial so we don't used cached pixmaps/masks
3472 default_icon_serial++;
3474 g_list_foreach (list,
3475 (GFunc) g_object_ref, NULL);
3477 g_list_foreach (default_icon_list,
3478 (GFunc) g_object_unref, NULL);
3480 g_list_free (default_icon_list);
3482 default_icon_list = g_list_copy (list);
3484 /* Update all toplevels */
3485 toplevels = gtk_window_list_toplevels ();
3486 tmp_list = toplevels;
3487 while (tmp_list != NULL)
3489 GtkWindowIconInfo *info;
3490 GtkWindow *w = tmp_list->data;
3492 info = get_icon_info (w);
3493 if (info && info->using_default_icon)
3495 gtk_window_unrealize_icon (w);
3496 if (GTK_WIDGET_REALIZED (w))
3497 gtk_window_realize_icon (w);
3500 tmp_list = tmp_list->next;
3502 g_list_free (toplevels);
3506 * gtk_window_set_default_icon:
3509 * Sets an icon to be used as fallback for windows that haven't
3510 * had gtk_window_set_icon() called on them from a pixbuf.
3515 gtk_window_set_default_icon (GdkPixbuf *icon)
3519 g_return_if_fail (GDK_IS_PIXBUF (icon));
3521 list = g_list_prepend (NULL, icon);
3522 gtk_window_set_default_icon_list (list);
3527 * gtk_window_set_default_icon_name:
3528 * @name: the name of the themed icon
3530 * Sets an icon to be used as fallback for windows that haven't
3531 * had gtk_window_set_icon_list() called on them from a named
3532 * themed icon, see gtk_window_set_icon_name().
3537 gtk_window_set_default_icon_name (const gchar *name)
3542 /* Update serial so we don't used cached pixmaps/masks
3544 default_icon_serial++;
3546 g_free (default_icon_name);
3547 default_icon_name = g_strdup (name);
3549 g_list_foreach (default_icon_list,
3550 (GFunc) g_object_unref, NULL);
3552 g_list_free (default_icon_list);
3553 default_icon_list = NULL;
3555 /* Update all toplevels */
3556 toplevels = gtk_window_list_toplevels ();
3557 tmp_list = toplevels;
3558 while (tmp_list != NULL)
3560 GtkWindowIconInfo *info;
3561 GtkWindow *w = tmp_list->data;
3563 info = get_icon_info (w);
3564 if (info && info->using_default_icon && info->using_themed_icon)
3566 gtk_window_unrealize_icon (w);
3567 if (GTK_WIDGET_REALIZED (w))
3568 gtk_window_realize_icon (w);
3571 tmp_list = tmp_list->next;
3573 g_list_free (toplevels);
3577 * gtk_window_set_default_icon_from_file:
3578 * @filename: location of icon file
3579 * @err: location to store error, or %NULL.
3581 * Sets an icon to be used as fallback for windows that haven't
3582 * had gtk_window_set_icon_list() called on them from a file
3583 * on disk. Warns on failure if @err is %NULL.
3585 * Returns: %TRUE if setting the icon succeeded.
3590 gtk_window_set_default_icon_from_file (const gchar *filename,
3593 GdkPixbuf *pixbuf = load_pixbuf_verbosely (filename, err);
3597 gtk_window_set_default_icon (pixbuf);
3598 g_object_unref (pixbuf);
3607 * gtk_window_get_default_icon_list:
3609 * Gets the value set by gtk_window_set_default_icon_list().
3610 * The list is a copy and should be freed with g_list_free(),
3611 * but the pixbufs in the list have not had their reference count
3614 * Return value: copy of default icon list
3617 gtk_window_get_default_icon_list (void)
3619 return g_list_copy (default_icon_list);
3623 gtk_window_set_default_size_internal (GtkWindow *window,
3624 gboolean change_width,
3626 gboolean change_height,
3628 gboolean is_geometry)
3630 GtkWindowGeometryInfo *info;
3632 g_return_if_fail (change_width == FALSE || width >= -1);
3633 g_return_if_fail (change_height == FALSE || height >= -1);
3635 info = gtk_window_get_geometry_info (window, TRUE);
3637 g_object_freeze_notify (G_OBJECT (window));
3639 info->default_is_geometry = is_geometry != FALSE;
3649 info->default_width = width;
3651 g_object_notify (G_OBJECT (window), "default-width");
3662 info->default_height = height;
3664 g_object_notify (G_OBJECT (window), "default-height");
3667 g_object_thaw_notify (G_OBJECT (window));
3669 gtk_widget_queue_resize (GTK_WIDGET (window));
3673 * gtk_window_set_default_size:
3674 * @window: a #GtkWindow
3675 * @width: width in pixels, or -1 to unset the default width
3676 * @height: height in pixels, or -1 to unset the default height
3678 * Sets the default size of a window. If the window's "natural" size
3679 * (its size request) is larger than the default, the default will be
3680 * ignored. More generally, if the default size does not obey the
3681 * geometry hints for the window (gtk_window_set_geometry_hints() can
3682 * be used to set these explicitly), the default size will be clamped
3683 * to the nearest permitted size.
3685 * Unlike gtk_widget_set_size_request(), which sets a size request for
3686 * a widget and thus would keep users from shrinking the window, this
3687 * function only sets the initial size, just as if the user had
3688 * resized the window themselves. Users can still shrink the window
3689 * again as they normally would. Setting a default size of -1 means to
3690 * use the "natural" default size (the size request of the window).
3692 * For more control over a window's initial size and how resizing works,
3693 * investigate gtk_window_set_geometry_hints().
3695 * For some uses, gtk_window_resize() is a more appropriate function.
3696 * gtk_window_resize() changes the current size of the window, rather
3697 * than the size to be used on initial display. gtk_window_resize() always
3698 * affects the window itself, not the geometry widget.
3700 * The default size of a window only affects the first time a window is
3701 * shown; if a window is hidden and re-shown, it will remember the size
3702 * it had prior to hiding, rather than using the default size.
3704 * Windows can't actually be 0x0 in size, they must be at least 1x1, but
3705 * passing 0 for @width and @height is OK, resulting in a 1x1 default size.
3708 gtk_window_set_default_size (GtkWindow *window,
3712 g_return_if_fail (GTK_IS_WINDOW (window));
3713 g_return_if_fail (width >= -1);
3714 g_return_if_fail (height >= -1);
3716 gtk_window_set_default_size_internal (window, TRUE, width, TRUE, height, FALSE);
3720 * gtk_window_get_default_size:
3721 * @window: a #GtkWindow
3722 * @width: location to store the default width, or %NULL
3723 * @height: location to store the default height, or %NULL
3725 * Gets the default size of the window. A value of -1 for the width or
3726 * height indicates that a default size has not been explicitly set
3727 * for that dimension, so the "natural" size of the window will be
3732 gtk_window_get_default_size (GtkWindow *window,
3736 GtkWindowGeometryInfo *info;
3738 g_return_if_fail (GTK_IS_WINDOW (window));
3740 info = gtk_window_get_geometry_info (window, FALSE);
3743 *width = info ? info->default_width : -1;
3746 *height = info ? info->default_height : -1;
3750 * gtk_window_resize:
3751 * @window: a #GtkWindow
3752 * @width: width in pixels to resize the window to
3753 * @height: height in pixels to resize the window to
3755 * Resizes the window as if the user had done so, obeying geometry
3756 * constraints. The default geometry constraint is that windows may
3757 * not be smaller than their size request; to override this
3758 * constraint, call gtk_widget_set_size_request() to set the window's
3759 * request to a smaller value.
3761 * If gtk_window_resize() is called before showing a window for the
3762 * first time, it overrides any default size set with
3763 * gtk_window_set_default_size().
3765 * Windows may not be resized smaller than 1 by 1 pixels.
3769 gtk_window_resize (GtkWindow *window,
3773 GtkWindowGeometryInfo *info;
3775 g_return_if_fail (GTK_IS_WINDOW (window));
3776 g_return_if_fail (width > 0);
3777 g_return_if_fail (height > 0);
3779 info = gtk_window_get_geometry_info (window, TRUE);
3781 info->resize_width = width;
3782 info->resize_height = height;
3784 gtk_widget_queue_resize (GTK_WIDGET (window));
3788 * gtk_window_get_size:
3789 * @window: a #GtkWindow
3790 * @width: return location for width, or %NULL
3791 * @height: return location for height, or %NULL
3793 * Obtains the current size of @window. If @window is not onscreen,
3794 * it returns the size GTK+ will suggest to the <link
3795 * linkend="gtk-X11-arch">window manager</link> for the initial window
3796 * size (but this is not reliably the same as the size the window
3797 * manager will actually select). The size obtained by
3798 * gtk_window_get_size() is the last size received in a
3799 * #GdkEventConfigure, that is, GTK+ uses its locally-stored size,
3800 * rather than querying the X server for the size. As a result, if you
3801 * call gtk_window_resize() then immediately call
3802 * gtk_window_get_size(), the size won't have taken effect yet. After
3803 * the window manager processes the resize request, GTK+ receives
3804 * notification that the size has changed via a configure event, and
3805 * the size of the window gets updated.
3807 * Note 1: Nearly any use of this function creates a race condition,
3808 * because the size of the window may change between the time that you
3809 * get the size and the time that you perform some action assuming
3810 * that size is the current size. To avoid race conditions, connect to
3811 * "configure_event" on the window and adjust your size-dependent
3812 * state to match the size delivered in the #GdkEventConfigure.
3814 * Note 2: The returned size does <emphasis>not</emphasis> include the
3815 * size of the window manager decorations (aka the window frame or
3816 * border). Those are not drawn by GTK+ and GTK+ has no reliable
3817 * method of determining their size.
3819 * Note 3: If you are getting a window size in order to position
3820 * the window onscreen, there may be a better way. The preferred
3821 * way is to simply set the window's semantic type with
3822 * gtk_window_set_type_hint(), which allows the window manager to
3823 * e.g. center dialogs. Also, if you set the transient parent of
3824 * dialogs with gtk_window_set_transient_for() window managers
3825 * will often center the dialog over its parent window. It's
3826 * much preferred to let the window manager handle these
3827 * things rather than doing it yourself, because all apps will
3828 * behave consistently and according to user prefs if the window
3829 * manager handles it. Also, the window manager can take the size
3830 * of the window decorations/border into account, while your
3831 * application cannot.
3833 * In any case, if you insist on application-specified window
3834 * positioning, there's <emphasis>still</emphasis> a better way than
3835 * doing it yourself - gtk_window_set_position() will frequently
3836 * handle the details for you.
3840 gtk_window_get_size (GtkWindow *window,
3846 g_return_if_fail (GTK_IS_WINDOW (window));
3848 if (width == NULL && height == NULL)
3851 if (GTK_WIDGET_MAPPED (window))
3853 gdk_drawable_get_size (GTK_WIDGET (window)->window,
3858 GdkRectangle configure_request;
3860 gtk_window_compute_configure_request (window,
3864 w = configure_request.width;
3865 h = configure_request.height;
3876 * @window: a #GtkWindow
3877 * @x: X coordinate to move window to
3878 * @y: Y coordinate to move window to
3880 * Asks the <link linkend="gtk-X11-arch">window manager</link> to move
3881 * @window to the given position. Window managers are free to ignore
3882 * this; most window managers ignore requests for initial window
3883 * positions (instead using a user-defined placement algorithm) and
3884 * honor requests after the window has already been shown.
3886 * Note: the position is the position of the gravity-determined
3887 * reference point for the window. The gravity determines two things:
3888 * first, the location of the reference point in root window
3889 * coordinates; and second, which point on the window is positioned at
3890 * the reference point.
3892 * By default the gravity is #GDK_GRAVITY_NORTH_WEST, so the reference
3893 * point is simply the @x, @y supplied to gtk_window_move(). The
3894 * top-left corner of the window decorations (aka window frame or
3895 * border) will be placed at @x, @y. Therefore, to position a window
3896 * at the top left of the screen, you want to use the default gravity
3897 * (which is #GDK_GRAVITY_NORTH_WEST) and move the window to 0,0.
3899 * To position a window at the bottom right corner of the screen, you
3900 * would set #GDK_GRAVITY_SOUTH_EAST, which means that the reference
3901 * point is at @x + the window width and @y + the window height, and
3902 * the bottom-right corner of the window border will be placed at that
3903 * reference point. So, to place a window in the bottom right corner
3904 * you would first set gravity to south east, then write:
3905 * <literal>gtk_window_move (window, gdk_screen_width () - window_width,
3906 * gdk_screen_height () - window_height)</literal> (note that this
3907 * example does not take multi-head scenarios into account).
3909 * The Extended Window Manager Hints specification at <ulink
3910 * url="http://www.freedesktop.org/Standards/wm-spec">
3911 * http://www.freedesktop.org/Standards/wm-spec</ulink> has a
3912 * nice table of gravities in the "implementation notes" section.
3914 * The gtk_window_get_position() documentation may also be relevant.
3917 gtk_window_move (GtkWindow *window,
3921 GtkWindowGeometryInfo *info;
3924 g_return_if_fail (GTK_IS_WINDOW (window));
3926 widget = GTK_WIDGET (window);
3928 info = gtk_window_get_geometry_info (window, TRUE);
3930 if (GTK_WIDGET_MAPPED (window))
3932 /* we have now sent a request with this position
3933 * with currently-active constraints, so toggle flag.
3935 info->position_constraints_changed = FALSE;
3937 /* we only constrain if mapped - if not mapped,
3938 * then gtk_window_compute_configure_request()
3939 * will apply the constraints later, and we
3940 * don't want to lose information about
3941 * what position the user set before then.
3942 * i.e. if you do a move() then turn off POS_CENTER
3943 * then show the window, your move() will work.
3945 gtk_window_constrain_position (window,
3946 widget->allocation.width,
3947 widget->allocation.height,
3950 /* Note that this request doesn't go through our standard request
3951 * framework, e.g. doesn't increment configure_request_count,
3952 * doesn't set info->last, etc.; that's because
3953 * we don't save the info needed to arrive at this same request
3956 * To gtk_window_move_resize(), this will end up looking exactly
3957 * the same as the position being changed by the window
3961 /* FIXME are we handling gravity properly for framed windows? */
3963 gdk_window_move (window->frame,
3964 x - window->frame_left,
3965 y - window->frame_top);
3967 gdk_window_move (GTK_WIDGET (window)->window,
3972 /* Save this position to apply on mapping */
3973 info->initial_x = x;
3974 info->initial_y = y;
3975 info->initial_pos_set = TRUE;
3980 * gtk_window_get_position:
3981 * @window: a #GtkWindow
3982 * @root_x: return location for X coordinate of gravity-determined reference p\oint
3983 * @root_y: return location for Y coordinate of gravity-determined reference p\oint
3985 * This function returns the position you need to pass to
3986 * gtk_window_move() to keep @window in its current position. This
3987 * means that the meaning of the returned value varies with window
3988 * gravity. See gtk_window_move() for more details.
3990 * If you haven't changed the window gravity, its gravity will be
3991 * #GDK_GRAVITY_NORTH_WEST. This means that gtk_window_get_position()
3992 * gets the position of the top-left corner of the window manager
3993 * frame for the window. gtk_window_move() sets the position of this
3994 * same top-left corner.
3996 * gtk_window_get_position() is not 100% reliable because the X Window System
3997 * does not specify a way to obtain the geometry of the
3998 * decorations placed on a window by the window manager.
3999 * Thus GTK+ is using a "best guess" that works with most
4002 * Moreover, nearly all window managers are historically broken with
4003 * respect to their handling of window gravity. So moving a window to
4004 * its current position as returned by gtk_window_get_position() tends
4005 * to result in moving the window slightly. Window managers are
4006 * slowly getting better over time.
4008 * If a window has gravity #GDK_GRAVITY_STATIC the window manager
4009 * frame is not relevant, and thus gtk_window_get_position() will
4010 * always produce accurate results. However you can't use static
4011 * gravity to do things like place a window in a corner of the screen,
4012 * because static gravity ignores the window manager decorations.
4014 * If you are saving and restoring your application's window
4015 * positions, you should know that it's impossible for applications to
4016 * do this without getting it somewhat wrong because applications do
4017 * not have sufficient knowledge of window manager state. The Correct
4018 * Mechanism is to support the session management protocol (see the
4019 * "GnomeClient" object in the GNOME libraries for example) and allow
4020 * the window manager to save your window sizes and positions.
4025 gtk_window_get_position (GtkWindow *window,
4031 g_return_if_fail (GTK_IS_WINDOW (window));
4033 widget = GTK_WIDGET (window);
4035 if (window->gravity == GDK_GRAVITY_STATIC)
4037 if (GTK_WIDGET_MAPPED (widget))
4039 /* This does a server round-trip, which is sort of wrong;
4040 * but a server round-trip is inevitable for
4041 * gdk_window_get_frame_extents() in the usual
4042 * NorthWestGravity case below, so not sure what else to
4043 * do. We should likely be consistent about whether we get
4044 * the client-side info or the server-side info.
4046 gdk_window_get_origin (widget->window, root_x, root_y);
4050 GdkRectangle configure_request;
4052 gtk_window_compute_configure_request (window,
4056 *root_x = configure_request.x;
4057 *root_y = configure_request.y;
4062 GdkRectangle frame_extents;
4067 if (GTK_WIDGET_MAPPED (widget))
4070 gdk_window_get_frame_extents (window->frame, &frame_extents);
4072 gdk_window_get_frame_extents (widget->window, &frame_extents);
4073 x = frame_extents.x;
4074 y = frame_extents.y;
4075 gtk_window_get_size (window, &w, &h);
4079 /* We just say the frame has 0 size on all sides.
4080 * Not sure what else to do.
4082 gtk_window_compute_configure_request (window,
4085 x = frame_extents.x;
4086 y = frame_extents.y;
4087 w = frame_extents.width;
4088 h = frame_extents.height;
4091 switch (window->gravity)
4093 case GDK_GRAVITY_NORTH:
4094 case GDK_GRAVITY_CENTER:
4095 case GDK_GRAVITY_SOUTH:
4096 /* Find center of frame. */
4097 x += frame_extents.width / 2;
4098 /* Center client window on that point. */
4102 case GDK_GRAVITY_SOUTH_EAST:
4103 case GDK_GRAVITY_EAST:
4104 case GDK_GRAVITY_NORTH_EAST:
4105 /* Find right edge of frame */
4106 x += frame_extents.width;
4107 /* Align left edge of client at that point. */
4114 switch (window->gravity)
4116 case GDK_GRAVITY_WEST:
4117 case GDK_GRAVITY_CENTER:
4118 case GDK_GRAVITY_EAST:
4119 /* Find center of frame. */
4120 y += frame_extents.height / 2;
4121 /* Center client window there. */
4124 case GDK_GRAVITY_SOUTH_WEST:
4125 case GDK_GRAVITY_SOUTH:
4126 case GDK_GRAVITY_SOUTH_EAST:
4127 /* Find south edge of frame */
4128 y += frame_extents.height;
4129 /* Place bottom edge of client there */
4144 * gtk_window_reshow_with_initial_size:
4145 * @window: a #GtkWindow
4147 * Hides @window, then reshows it, resetting the
4148 * default size and position of the window. Used
4149 * by GUI builders only.
4152 gtk_window_reshow_with_initial_size (GtkWindow *window)
4156 g_return_if_fail (GTK_IS_WINDOW (window));
4158 widget = GTK_WIDGET (window);
4160 gtk_widget_hide (widget);
4161 gtk_widget_unrealize (widget);
4162 gtk_widget_show (widget);
4166 gtk_window_destroy (GtkObject *object)
4168 GtkWindow *window = GTK_WINDOW (object);
4170 toplevel_list = g_slist_remove (toplevel_list, window);
4172 if (window->transient_parent)
4173 gtk_window_set_transient_for (window, NULL);
4175 /* frees the icons */
4176 gtk_window_set_icon_list (window, NULL);
4178 if (window->has_user_ref_count)
4180 window->has_user_ref_count = FALSE;
4181 g_object_unref (window);
4185 gtk_window_group_remove_window (window->group, window);
4187 gtk_window_free_key_hash (window);
4189 GTK_OBJECT_CLASS (gtk_window_parent_class)->destroy (object);
4193 gtk_window_finalize (GObject *object)
4195 GtkWindow *window = GTK_WINDOW (object);
4196 GtkMnemonicHash *mnemonic_hash;
4198 g_free (window->title);
4199 g_free (window->wmclass_name);
4200 g_free (window->wmclass_class);
4201 g_free (window->wm_role);
4203 mnemonic_hash = gtk_window_get_mnemonic_hash (window, FALSE);
4205 _gtk_mnemonic_hash_free (mnemonic_hash);
4207 if (window->geometry_info)
4209 if (window->geometry_info->widget)
4210 g_signal_handlers_disconnect_by_func (window->geometry_info->widget,
4211 gtk_widget_destroyed,
4212 &window->geometry_info->widget);
4213 g_free (window->geometry_info);
4216 if (window->keys_changed_handler)
4218 g_source_remove (window->keys_changed_handler);
4219 window->keys_changed_handler = 0;
4224 g_signal_handlers_disconnect_by_func (window->screen,
4225 gtk_window_on_composited_changed, window);
4228 G_OBJECT_CLASS (gtk_window_parent_class)->finalize (object);
4232 gtk_window_show (GtkWidget *widget)
4234 GtkWindow *window = GTK_WINDOW (widget);
4235 GtkContainer *container = GTK_CONTAINER (window);
4236 gboolean need_resize;
4238 GTK_WIDGET_SET_FLAGS (widget, GTK_VISIBLE);
4240 need_resize = container->need_resize || !GTK_WIDGET_REALIZED (widget);
4241 container->need_resize = FALSE;
4245 GtkWindowGeometryInfo *info = gtk_window_get_geometry_info (window, TRUE);
4246 GtkAllocation allocation = { 0, 0 };
4247 GdkRectangle configure_request;
4248 GdkGeometry new_geometry;
4250 gboolean was_realized;
4252 /* We are going to go ahead and perform this configure request
4253 * and then emulate a configure notify by going ahead and
4254 * doing a size allocate. Sort of a synchronous
4255 * mini-copy of gtk_window_move_resize() here.
4257 gtk_window_compute_configure_request (window,
4262 /* We update this because we are going to go ahead
4263 * and gdk_window_resize() below, rather than
4266 info->last.configure_request.width = configure_request.width;
4267 info->last.configure_request.height = configure_request.height;
4269 /* and allocate the window - this is normally done
4270 * in move_resize in response to configure notify
4272 allocation.width = configure_request.width;
4273 allocation.height = configure_request.height;
4274 gtk_widget_size_allocate (widget, &allocation);
4276 /* Then we guarantee we have a realize */
4277 was_realized = FALSE;
4278 if (!GTK_WIDGET_REALIZED (widget))
4280 gtk_widget_realize (widget);
4281 was_realized = TRUE;
4284 /* Must be done after the windows are realized,
4285 * so that the decorations can be read
4287 gtk_decorated_window_calculate_frame_size (window);
4289 /* We only send configure request if we didn't just finish
4290 * creating the window; if we just created the window
4291 * then we created it with widget->allocation anyhow.
4294 gdk_window_move_resize (widget->window,
4295 configure_request.x,
4296 configure_request.y,
4297 configure_request.width,
4298 configure_request.height);
4301 gtk_container_check_resize (container);
4303 gtk_widget_map (widget);
4305 /* Try to make sure that we have some focused widget
4307 if (!window->focus_widget && !GTK_IS_PLUG (window))
4308 gtk_window_move_focus (window, GTK_DIR_TAB_FORWARD);
4311 gtk_grab_add (widget);
4315 gtk_window_hide (GtkWidget *widget)
4317 GtkWindow *window = GTK_WINDOW (widget);
4319 GTK_WIDGET_UNSET_FLAGS (widget, GTK_VISIBLE);
4320 gtk_widget_unmap (widget);
4323 gtk_grab_remove (widget);
4327 gtk_window_map (GtkWidget *widget)
4329 GtkWindow *window = GTK_WINDOW (widget);
4330 GtkWindowPrivate *priv = GTK_WINDOW_GET_PRIVATE (window);
4331 GdkWindow *toplevel;
4333 GTK_WIDGET_SET_FLAGS (widget, GTK_MAPPED);
4335 if (window->bin.child &&
4336 GTK_WIDGET_VISIBLE (window->bin.child) &&
4337 !GTK_WIDGET_MAPPED (window->bin.child))
4338 gtk_widget_map (window->bin.child);
4341 toplevel = window->frame;
4343 toplevel = widget->window;
4345 if (window->maximize_initially)
4346 gdk_window_maximize (toplevel);
4348 gdk_window_unmaximize (toplevel);
4350 if (window->stick_initially)
4351 gdk_window_stick (toplevel);
4353 gdk_window_unstick (toplevel);
4355 if (window->iconify_initially)
4356 gdk_window_iconify (toplevel);
4358 gdk_window_deiconify (toplevel);
4360 if (priv->fullscreen_initially)
4361 gdk_window_fullscreen (toplevel);
4363 gdk_window_unfullscreen (toplevel);
4365 gdk_window_set_keep_above (toplevel, priv->above_initially);
4367 gdk_window_set_keep_below (toplevel, priv->below_initially);
4369 /* No longer use the default settings */
4370 window->need_default_size = FALSE;
4371 window->need_default_position = FALSE;
4373 if (priv->reset_type_hint)
4375 /* We should only reset the type hint when the application
4376 * used gtk_window_set_type_hint() to change the hint.
4377 * Some applications use X directly to change the properties;
4378 * in that case, we shouldn't overwrite what they did.
4380 gdk_window_set_type_hint (widget->window, priv->type_hint);
4381 priv->reset_type_hint = FALSE;
4384 gdk_window_show (widget->window);
4387 gdk_window_show (window->frame);
4389 if (!disable_startup_notification)
4391 /* Do we have a custom startup-notification id? */
4392 if (priv->startup_id != NULL)
4394 /* Make sure we have a "real" id */
4395 if (!startup_id_is_fake (priv->startup_id))
4396 gdk_notify_startup_complete_with_id (priv->startup_id);
4398 priv->startup_id = NULL;
4400 else if (!sent_startup_notification)
4402 sent_startup_notification = TRUE;
4403 gdk_notify_startup_complete ();
4409 gtk_window_map_event (GtkWidget *widget,
4412 if (!GTK_WIDGET_MAPPED (widget))
4414 /* we should be be unmapped, but are getting a MapEvent, this may happen
4415 * to toplevel XWindows if mapping was intercepted by a window manager
4416 * and an unmap request occoured while the MapRequestEvent was still
4417 * being handled. we work around this situaiton here by re-requesting
4418 * the window being unmapped. more details can be found in:
4419 * http://bugzilla.gnome.org/show_bug.cgi?id=316180
4421 gdk_window_hide (widget->window);
4427 gtk_window_unmap (GtkWidget *widget)
4429 GtkWindow *window = GTK_WINDOW (widget);
4430 GtkWindowPrivate *priv = GTK_WINDOW_GET_PRIVATE (widget);
4431 GtkWindowGeometryInfo *info;
4432 GdkWindowState state;
4434 GTK_WIDGET_UNSET_FLAGS (widget, GTK_MAPPED);
4436 gdk_window_withdraw (window->frame);
4438 gdk_window_withdraw (widget->window);
4440 window->configure_request_count = 0;
4441 window->configure_notify_received = FALSE;
4443 /* on unmap, we reset the default positioning of the window,
4444 * so it's placed again, but we don't reset the default
4445 * size of the window, so it's remembered.
4447 window->need_default_position = TRUE;
4449 info = gtk_window_get_geometry_info (window, FALSE);
4452 info->initial_pos_set = FALSE;
4453 info->position_constraints_changed = FALSE;
4456 state = gdk_window_get_state (widget->window);
4457 window->iconify_initially = (state & GDK_WINDOW_STATE_ICONIFIED) != 0;
4458 window->maximize_initially = (state & GDK_WINDOW_STATE_MAXIMIZED) != 0;
4459 window->stick_initially = (state & GDK_WINDOW_STATE_STICKY) != 0;
4460 priv->above_initially = (state & GDK_WINDOW_STATE_ABOVE) != 0;
4461 priv->below_initially = (state & GDK_WINDOW_STATE_BELOW) != 0;
4465 gtk_window_realize (GtkWidget *widget)
4468 GdkWindow *parent_window;
4469 GdkWindowAttr attributes;
4470 gint attributes_mask;
4471 GtkWindowPrivate *priv;
4473 window = GTK_WINDOW (widget);
4474 priv = GTK_WINDOW_GET_PRIVATE (window);
4476 /* ensure widget tree is properly size allocated */
4477 if (widget->allocation.x == -1 &&
4478 widget->allocation.y == -1 &&
4479 widget->allocation.width == 1 &&
4480 widget->allocation.height == 1)
4482 GtkRequisition requisition;
4483 GtkAllocation allocation = { 0, 0, 200, 200 };
4485 gtk_widget_size_request (widget, &requisition);
4486 if (requisition.width || requisition.height)
4488 /* non-empty window */
4489 allocation.width = requisition.width;
4490 allocation.height = requisition.height;
4492 gtk_widget_size_allocate (widget, &allocation);
4494 _gtk_container_queue_resize (GTK_CONTAINER (widget));
4496 g_return_if_fail (!GTK_WIDGET_REALIZED (widget));
4499 GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED);
4501 switch (window->type)
4503 case GTK_WINDOW_TOPLEVEL:
4504 attributes.window_type = GDK_WINDOW_TOPLEVEL;
4506 case GTK_WINDOW_POPUP:
4507 attributes.window_type = GDK_WINDOW_TEMP;
4510 g_warning (G_STRLOC": Unknown window type %d!", window->type);
4514 attributes.title = window->title;
4515 attributes.wmclass_name = window->wmclass_name;
4516 attributes.wmclass_class = window->wmclass_class;
4517 attributes.wclass = GDK_INPUT_OUTPUT;
4518 attributes.visual = gtk_widget_get_visual (widget);
4519 attributes.colormap = gtk_widget_get_colormap (widget);
4521 if (window->has_frame)
4523 attributes.width = widget->allocation.width + window->frame_left + window->frame_right;
4524 attributes.height = widget->allocation.height + window->frame_top + window->frame_bottom;
4525 attributes.event_mask = (GDK_EXPOSURE_MASK |
4526 GDK_KEY_PRESS_MASK |
4527 GDK_ENTER_NOTIFY_MASK |
4528 GDK_LEAVE_NOTIFY_MASK |
4529 GDK_FOCUS_CHANGE_MASK |
4530 GDK_STRUCTURE_MASK |
4531 GDK_BUTTON_MOTION_MASK |
4532 GDK_POINTER_MOTION_HINT_MASK |
4533 GDK_BUTTON_PRESS_MASK |
4534 GDK_BUTTON_RELEASE_MASK);
4536 attributes_mask = GDK_WA_VISUAL | GDK_WA_COLORMAP;
4538 window->frame = gdk_window_new (gtk_widget_get_root_window (widget),
4539 &attributes, attributes_mask);
4541 if (priv->opacity_set)
4542 gdk_window_set_opacity (window->frame, priv->opacity);
4544 gdk_window_set_user_data (window->frame, widget);
4546 attributes.window_type = GDK_WINDOW_CHILD;
4547 attributes.x = window->frame_left;
4548 attributes.y = window->frame_top;
4550 attributes_mask = GDK_WA_X | GDK_WA_Y;
4552 parent_window = window->frame;
4554 g_signal_connect (window,
4556 G_CALLBACK (gtk_window_event),
4561 attributes_mask = 0;
4562 parent_window = gtk_widget_get_root_window (widget);
4565 attributes.width = widget->allocation.width;
4566 attributes.height = widget->allocation.height;
4567 attributes.event_mask = gtk_widget_get_events (widget);
4568 attributes.event_mask |= (GDK_EXPOSURE_MASK |
4569 GDK_KEY_PRESS_MASK |
4570 GDK_KEY_RELEASE_MASK |
4571 GDK_ENTER_NOTIFY_MASK |
4572 GDK_LEAVE_NOTIFY_MASK |
4573 GDK_FOCUS_CHANGE_MASK |
4574 GDK_STRUCTURE_MASK);
4575 attributes.type_hint = priv->type_hint;
4577 attributes_mask |= GDK_WA_VISUAL | GDK_WA_COLORMAP | GDK_WA_TYPE_HINT;
4578 attributes_mask |= (window->title ? GDK_WA_TITLE : 0);
4579 attributes_mask |= (window->wmclass_name ? GDK_WA_WMCLASS : 0);
4581 widget->window = gdk_window_new (parent_window, &attributes, attributes_mask);
4583 if (!window->has_frame && priv->opacity_set)
4584 gdk_window_set_opacity (widget->window, priv->opacity);
4586 gdk_window_enable_synchronized_configure (widget->window);
4588 gdk_window_set_user_data (widget->window, window);
4590 widget->style = gtk_style_attach (widget->style, widget->window);
4591 gtk_style_set_background (widget->style, widget->window, GTK_STATE_NORMAL);
4593 gtk_style_set_background (widget->style, window->frame, GTK_STATE_NORMAL);
4595 /* This is a bad hack to set the window background. */
4596 gtk_window_paint (widget, NULL);
4598 if (window->transient_parent &&
4599 GTK_WIDGET_REALIZED (window->transient_parent))
4600 gdk_window_set_transient_for (widget->window,
4601 GTK_WIDGET (window->transient_parent)->window);
4603 if (window->wm_role)
4604 gdk_window_set_role (widget->window, window->wm_role);
4606 if (!window->decorated)
4607 gdk_window_set_decorations (widget->window, 0);
4609 if (!priv->deletable)
4610 gdk_window_set_functions (widget->window, GDK_FUNC_ALL | GDK_FUNC_CLOSE);
4612 if (gtk_window_get_skip_pager_hint (window))
4613 gdk_window_set_skip_pager_hint (widget->window, TRUE);
4615 if (gtk_window_get_skip_taskbar_hint (window))
4616 gdk_window_set_skip_taskbar_hint (widget->window, TRUE);
4618 if (gtk_window_get_accept_focus (window))
4619 gdk_window_set_accept_focus (widget->window, TRUE);
4621 gdk_window_set_accept_focus (widget->window, FALSE);
4623 if (gtk_window_get_focus_on_map (window))
4624 gdk_window_set_focus_on_map (widget->window, TRUE);
4626 gdk_window_set_focus_on_map (widget->window, FALSE);
4629 gdk_window_set_modal_hint (widget->window, TRUE);
4631 gdk_window_set_modal_hint (widget->window, FALSE);
4633 if (priv->startup_id)
4635 #ifdef GDK_WINDOWING_X11
4636 guint32 timestamp = extract_time_from_startup_id (priv->startup_id);
4637 if (timestamp != GDK_CURRENT_TIME)
4638 gdk_x11_window_set_user_time (widget->window, timestamp);
4640 if (!startup_id_is_fake (priv->startup_id))
4641 gdk_window_set_startup_id (widget->window, priv->startup_id);
4645 gtk_window_realize_icon (window);
4649 gtk_window_unrealize (GtkWidget *widget)
4652 GtkWindowGeometryInfo *info;
4654 window = GTK_WINDOW (widget);
4656 /* On unrealize, we reset the size of the window such
4657 * that we will re-apply the default sizing stuff
4658 * next time we show the window.
4660 * Default positioning is reset on unmap, instead of unrealize.
4662 window->need_default_size = TRUE;
4663 info = gtk_window_get_geometry_info (window, FALSE);
4666 info->resize_width = -1;
4667 info->resize_height = -1;
4668 info->last.configure_request.x = 0;
4669 info->last.configure_request.y = 0;
4670 info->last.configure_request.width = -1;
4671 info->last.configure_request.height = -1;
4672 /* be sure we reset geom hints on re-realize */
4673 info->last.flags = 0;
4678 gdk_window_set_user_data (window->frame, NULL);
4679 gdk_window_destroy (window->frame);
4680 window->frame = NULL;
4684 gtk_window_unrealize_icon (window);
4686 (* GTK_WIDGET_CLASS (gtk_window_parent_class)->unrealize) (widget);
4690 gtk_window_size_request (GtkWidget *widget,
4691 GtkRequisition *requisition)
4696 window = GTK_WINDOW (widget);
4697 bin = GTK_BIN (window);
4699 requisition->width = GTK_CONTAINER (window)->border_width * 2;
4700 requisition->height = GTK_CONTAINER (window)->border_width * 2;
4702 if (bin->child && GTK_WIDGET_VISIBLE (bin->child))
4704 GtkRequisition child_requisition;
4706 gtk_widget_size_request (bin->child, &child_requisition);
4708 requisition->width += child_requisition.width;
4709 requisition->height += child_requisition.height;
4714 gtk_window_size_allocate (GtkWidget *widget,
4715 GtkAllocation *allocation)
4718 GtkAllocation child_allocation;
4720 window = GTK_WINDOW (widget);
4721 widget->allocation = *allocation;
4723 if (window->bin.child && GTK_WIDGET_VISIBLE (window->bin.child))
4725 child_allocation.x = GTK_CONTAINER (window)->border_width;
4726 child_allocation.y = GTK_CONTAINER (window)->border_width;
4727 child_allocation.width =
4728 MAX (1, (gint)allocation->width - child_allocation.x * 2);
4729 child_allocation.height =
4730 MAX (1, (gint)allocation->height - child_allocation.y * 2);
4732 gtk_widget_size_allocate (window->bin.child, &child_allocation);
4735 if (GTK_WIDGET_REALIZED (widget) && window->frame)
4737 gdk_window_resize (window->frame,
4738 allocation->width + window->frame_left + window->frame_right,
4739 allocation->height + window->frame_top + window->frame_bottom);
4744 gtk_window_event (GtkWidget *widget, GdkEvent *event)
4747 gboolean return_val;
4749 window = GTK_WINDOW (widget);
4751 if (window->frame && (event->any.window == window->frame))
4753 if ((event->type != GDK_KEY_PRESS) &&
4754 (event->type != GDK_KEY_RELEASE) &&
4755 (event->type != GDK_FOCUS_CHANGE))
4757 g_signal_stop_emission_by_name (widget, "event");
4759 g_signal_emit (widget, window_signals[FRAME_EVENT], 0, event, &return_val);
4764 g_object_unref (event->any.window);
4765 event->any.window = g_object_ref (widget->window);
4773 gtk_window_frame_event (GtkWindow *window, GdkEvent *event)
4775 GdkEventConfigure *configure_event;
4778 switch (event->type)
4781 configure_event = (GdkEventConfigure *)event;
4783 /* Invalidate the decorations */
4786 rect.width = configure_event->width;
4787 rect.height = configure_event->height;
4789 gdk_window_invalidate_rect (window->frame, &rect, FALSE);
4791 /* Pass on the (modified) configure event */
4792 configure_event->width -= window->frame_left + window->frame_right;
4793 configure_event->height -= window->frame_top + window->frame_bottom;
4794 return gtk_window_configure_event (GTK_WIDGET (window), configure_event);
4803 gtk_window_configure_event (GtkWidget *widget,
4804 GdkEventConfigure *event)
4806 GtkWindow *window = GTK_WINDOW (widget);
4807 gboolean expected_reply = window->configure_request_count > 0;
4809 /* window->configure_request_count incremented for each
4810 * configure request, and decremented to a min of 0 for
4811 * each configure notify.
4813 * All it means is that we know we will get at least
4814 * window->configure_request_count more configure notifies.
4815 * We could get more configure notifies than that; some
4816 * of the configure notifies we get may be unrelated to
4817 * the configure requests. But we will get at least
4818 * window->configure_request_count notifies.
4821 if (window->configure_request_count > 0)
4823 window->configure_request_count -= 1;
4824 gdk_window_thaw_toplevel_updates_libgtk_only (widget->window);
4827 /* As an optimization, we avoid a resize when possible.
4829 * The only times we can avoid a resize are:
4830 * - we know only the position changed, not the size
4831 * - we know we have made more requests and so will get more
4832 * notifies and can wait to resize when we get them
4835 if (!expected_reply &&
4836 (widget->allocation.width == event->width &&
4837 widget->allocation.height == event->height))
4839 gdk_window_configure_finished (widget->window);
4844 * If we do need to resize, we do that by:
4845 * - filling in widget->allocation with the new size
4846 * - setting configure_notify_received to TRUE
4847 * for use in gtk_window_move_resize()
4848 * - queueing a resize, leading to invocation of
4849 * gtk_window_move_resize() in an idle handler
4853 window->configure_notify_received = TRUE;
4855 widget->allocation.width = event->width;
4856 widget->allocation.height = event->height;
4858 _gtk_container_queue_resize (GTK_CONTAINER (widget));
4863 /* the accel_key and accel_mods fields of the key have to be setup
4864 * upon calling this function. it'll then return whether that key
4865 * is at all used as accelerator, and if so will OR in the
4866 * accel_flags member of the key.
4869 _gtk_window_query_nonaccels (GtkWindow *window,
4871 GdkModifierType accel_mods)
4873 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
4875 /* movement keys are considered locked accels */
4878 static const guint bindings[] = {
4879 GDK_space, GDK_KP_Space, GDK_Return, GDK_KP_Enter, GDK_Up, GDK_KP_Up, GDK_Down, GDK_KP_Down,
4880 GDK_Left, GDK_KP_Left, GDK_Right, GDK_KP_Right, GDK_Tab, GDK_KP_Tab, GDK_ISO_Left_Tab,
4884 for (i = 0; i < G_N_ELEMENTS (bindings); i++)
4885 if (bindings[i] == accel_key)
4889 /* mnemonics are considered locked accels */
4890 if (accel_mods == window->mnemonic_modifier)
4892 GtkMnemonicHash *mnemonic_hash = gtk_window_get_mnemonic_hash (window, FALSE);
4893 if (mnemonic_hash && _gtk_mnemonic_hash_lookup (mnemonic_hash, accel_key))
4901 * gtk_window_propagate_key_event:
4902 * @window: a #GtkWindow
4903 * @event: a #GdkEventKey
4905 * Propagate a key press or release event to the focus widget and
4906 * up the focus container chain until a widget handles @event.
4907 * This is normally called by the default ::key_press_event and
4908 * ::key_release_event handlers for toplevel windows,
4909 * however in some cases it may be useful to call this directly when
4910 * overriding the standard key handling for a toplevel window.
4912 * Return value: %TRUE if a widget in the focus chain handled the event.
4915 gtk_window_propagate_key_event (GtkWindow *window,
4918 gboolean handled = FALSE;
4919 GtkWidget *widget, *focus;
4921 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
4923 widget = GTK_WIDGET (window);
4924 focus = window->focus_widget;
4926 g_object_ref (focus);
4929 focus && focus != widget &&
4930 gtk_widget_get_toplevel (focus) == widget)
4934 if (GTK_WIDGET_IS_SENSITIVE (focus))
4935 handled = gtk_widget_event (focus, (GdkEvent*) event);
4937 parent = focus->parent;
4939 g_object_ref (parent);
4941 g_object_unref (focus);
4947 g_object_unref (focus);
4953 gtk_window_key_press_event (GtkWidget *widget,
4956 GtkWindow *window = GTK_WINDOW (widget);
4957 gboolean handled = FALSE;
4959 /* handle mnemonics and accelerators */
4961 handled = gtk_window_activate_key (window, event);
4963 /* handle focus widget key events */
4965 handled = gtk_window_propagate_key_event (window, event);
4967 /* Chain up, invokes binding set */
4969 handled = GTK_WIDGET_CLASS (gtk_window_parent_class)->key_press_event (widget, event);
4975 gtk_window_key_release_event (GtkWidget *widget,
4978 GtkWindow *window = GTK_WINDOW (widget);
4979 gboolean handled = FALSE;
4981 /* handle focus widget key events */
4983 handled = gtk_window_propagate_key_event (window, event);
4985 /* Chain up, invokes binding set */
4987 handled = GTK_WIDGET_CLASS (gtk_window_parent_class)->key_release_event (widget, event);
4993 gtk_window_real_activate_default (GtkWindow *window)
4995 gtk_window_activate_default (window);
4999 gtk_window_real_activate_focus (GtkWindow *window)
5001 gtk_window_activate_focus (window);
5005 gtk_window_move_focus (GtkWindow *window,
5006 GtkDirectionType dir)
5008 gtk_widget_child_focus (GTK_WIDGET (window), dir);
5010 if (!GTK_CONTAINER (window)->focus_child)
5011 gtk_window_set_focus (window, NULL);
5015 gtk_window_enter_notify_event (GtkWidget *widget,
5016 GdkEventCrossing *event)
5022 gtk_window_leave_notify_event (GtkWidget *widget,
5023 GdkEventCrossing *event)
5029 do_focus_change (GtkWidget *widget,
5032 GdkEvent *fevent = gdk_event_new (GDK_FOCUS_CHANGE);
5034 g_object_ref (widget);
5037 GTK_WIDGET_SET_FLAGS (widget, GTK_HAS_FOCUS);
5039 GTK_WIDGET_UNSET_FLAGS (widget, GTK_HAS_FOCUS);
5041 fevent->focus_change.type = GDK_FOCUS_CHANGE;
5042 fevent->focus_change.window = widget->window;
5044 g_object_ref (widget->window);
5045 fevent->focus_change.in = in;
5047 gtk_widget_event (widget, fevent);
5049 g_object_notify (G_OBJECT (widget), "has-focus");
5051 g_object_unref (widget);
5052 gdk_event_free (fevent);
5056 gtk_window_focus_in_event (GtkWidget *widget,
5057 GdkEventFocus *event)
5059 GtkWindow *window = GTK_WINDOW (widget);
5061 /* It appears spurious focus in events can occur when
5062 * the window is hidden. So we'll just check to see if
5063 * the window is visible before actually handling the
5066 if (GTK_WIDGET_VISIBLE (widget))
5068 _gtk_window_set_has_toplevel_focus (window, TRUE);
5069 _gtk_window_set_is_active (window, TRUE);
5076 gtk_window_focus_out_event (GtkWidget *widget,
5077 GdkEventFocus *event)
5079 GtkWindow *window = GTK_WINDOW (widget);
5081 _gtk_window_set_has_toplevel_focus (window, FALSE);
5082 _gtk_window_set_is_active (window, FALSE);
5087 static GdkAtom atom_rcfiles = GDK_NONE;
5088 static GdkAtom atom_iconthemes = GDK_NONE;
5091 send_client_message_to_embedded_windows (GtkWidget *widget,
5092 GdkAtom message_type)
5094 GList *embedded_windows;
5096 embedded_windows = g_object_get_qdata (G_OBJECT (widget), quark_gtk_embedded);
5097 if (embedded_windows)
5099 GdkEvent *send_event = gdk_event_new (GDK_CLIENT_EVENT);
5102 for (i = 0; i < 5; i++)
5103 send_event->client.data.l[i] = 0;
5104 send_event->client.data_format = 32;
5105 send_event->client.message_type = message_type;
5107 while (embedded_windows)
5109 guint xid = GPOINTER_TO_UINT (embedded_windows->data);
5110 gdk_event_send_client_message_for_display (gtk_widget_get_display (widget), send_event, xid);
5111 embedded_windows = embedded_windows->next;
5114 gdk_event_free (send_event);
5119 gtk_window_client_event (GtkWidget *widget,
5120 GdkEventClient *event)
5124 atom_rcfiles = gdk_atom_intern_static_string ("_GTK_READ_RCFILES");
5125 atom_iconthemes = gdk_atom_intern_static_string ("_GTK_LOAD_ICONTHEMES");
5128 if (event->message_type == atom_rcfiles)
5130 send_client_message_to_embedded_windows (widget, atom_rcfiles);
5131 gtk_rc_reparse_all_for_settings (gtk_widget_get_settings (widget), FALSE);
5134 if (event->message_type == atom_iconthemes)
5136 send_client_message_to_embedded_windows (widget, atom_iconthemes);
5137 _gtk_icon_theme_check_reload (gtk_widget_get_display (widget));
5144 gtk_window_check_resize (GtkContainer *container)
5146 GtkWindow *window = GTK_WINDOW (container);
5148 if (GTK_WIDGET_VISIBLE (container))
5149 gtk_window_move_resize (window);
5153 gtk_window_focus (GtkWidget *widget,
5154 GtkDirectionType direction)
5158 GtkContainer *container;
5159 GtkWidget *old_focus_child;
5162 container = GTK_CONTAINER (widget);
5163 window = GTK_WINDOW (widget);
5164 bin = GTK_BIN (widget);
5166 old_focus_child = container->focus_child;
5168 /* We need a special implementation here to deal properly with wrapping
5169 * around in the tab chain without the danger of going into an
5172 if (old_focus_child)
5174 if (gtk_widget_child_focus (old_focus_child, direction))
5178 if (window->focus_widget)
5180 if (direction == GTK_DIR_LEFT ||
5181 direction == GTK_DIR_RIGHT ||
5182 direction == GTK_DIR_UP ||
5183 direction == GTK_DIR_DOWN)
5188 /* Wrapped off the end, clear the focus setting for the toplpevel */
5189 parent = window->focus_widget->parent;
5192 gtk_container_set_focus_child (GTK_CONTAINER (parent), NULL);
5193 parent = GTK_WIDGET (parent)->parent;
5196 gtk_window_set_focus (GTK_WINDOW (container), NULL);
5199 /* Now try to focus the first widget in the window */
5202 if (gtk_widget_child_focus (bin->child, direction))
5210 gtk_window_real_set_focus (GtkWindow *window,
5213 GtkWidget *old_focus = window->focus_widget;
5214 gboolean had_default = FALSE;
5215 gboolean focus_had_default = FALSE;
5216 gboolean old_focus_had_default = FALSE;
5220 g_object_ref (old_focus);
5221 g_object_freeze_notify (G_OBJECT (old_focus));
5222 old_focus_had_default = GTK_WIDGET_HAS_DEFAULT (old_focus);
5226 g_object_ref (focus);
5227 g_object_freeze_notify (G_OBJECT (focus));
5228 focus_had_default = GTK_WIDGET_HAS_DEFAULT (focus);
5231 if (window->default_widget)
5232 had_default = GTK_WIDGET_HAS_DEFAULT (window->default_widget);
5234 if (window->focus_widget)
5236 if (GTK_WIDGET_RECEIVES_DEFAULT (window->focus_widget) &&
5237 (window->focus_widget != window->default_widget))
5239 GTK_WIDGET_UNSET_FLAGS (window->focus_widget, GTK_HAS_DEFAULT);
5240 gtk_widget_queue_draw (window->focus_widget);
5242 if (window->default_widget)
5243 GTK_WIDGET_SET_FLAGS (window->default_widget, GTK_HAS_DEFAULT);
5246 window->focus_widget = NULL;
5248 if (window->has_focus)
5249 do_focus_change (old_focus, FALSE);
5251 g_object_notify (G_OBJECT (old_focus), "is-focus");
5254 /* The above notifications may have set a new focus widget,
5255 * if so, we don't want to override it.
5257 if (focus && !window->focus_widget)
5259 window->focus_widget = focus;
5261 if (GTK_WIDGET_RECEIVES_DEFAULT (window->focus_widget) &&
5262 (window->focus_widget != window->default_widget))
5264 if (GTK_WIDGET_CAN_DEFAULT (window->focus_widget))
5265 GTK_WIDGET_SET_FLAGS (window->focus_widget, GTK_HAS_DEFAULT);
5267 if (window->default_widget)
5268 GTK_WIDGET_UNSET_FLAGS (window->default_widget, GTK_HAS_DEFAULT);
5271 if (window->has_focus)
5272 do_focus_change (window->focus_widget, TRUE);
5274 g_object_notify (G_OBJECT (window->focus_widget), "is-focus");
5277 /* If the default widget changed, a redraw will have been queued
5278 * on the old and new default widgets by gtk_window_set_default(), so
5279 * we only have to worry about the case where it didn't change.
5280 * We'll sometimes queue a draw twice on the new widget but that
5283 if (window->default_widget &&
5284 (had_default != GTK_WIDGET_HAS_DEFAULT (window->default_widget)))
5285 gtk_widget_queue_draw (window->default_widget);
5289 if (old_focus_had_default != GTK_WIDGET_HAS_DEFAULT (old_focus))
5290 gtk_widget_queue_draw (old_focus);
5292 g_object_thaw_notify (G_OBJECT (old_focus));
5293 g_object_unref (old_focus);
5297 if (focus_had_default != GTK_WIDGET_HAS_DEFAULT (focus))
5298 gtk_widget_queue_draw (focus);
5300 g_object_thaw_notify (G_OBJECT (focus));
5301 g_object_unref (focus);
5306 * _gtk_window_unset_focus_and_default:
5307 * @window: a #GtkWindow
5308 * @widget: a widget inside of @window
5310 * Checks whether the focus and default widgets of @window are
5311 * @widget or a descendent of @widget, and if so, unset them.
5314 _gtk_window_unset_focus_and_default (GtkWindow *window,
5320 g_object_ref (window);
5321 g_object_ref (widget);
5323 if (GTK_CONTAINER (widget->parent)->focus_child == widget)
5325 child = window->focus_widget;
5327 while (child && child != widget)
5328 child = child->parent;
5330 if (child == widget)
5331 gtk_window_set_focus (GTK_WINDOW (window), NULL);
5334 child = window->default_widget;
5336 while (child && child != widget)
5337 child = child->parent;
5339 if (child == widget)
5340 gtk_window_set_default (window, NULL);
5342 g_object_unref (widget);
5343 g_object_unref (window);
5346 /*********************************
5347 * Functions related to resizing *
5348 *********************************/
5350 /* This function doesn't constrain to geometry hints */
5352 gtk_window_compute_configure_request_size (GtkWindow *window,
5356 GtkRequisition requisition;
5357 GtkWindowGeometryInfo *info;
5361 * - we've done a size request
5364 widget = GTK_WIDGET (window);
5366 info = gtk_window_get_geometry_info (window, FALSE);
5368 if (window->need_default_size)
5370 gtk_widget_get_child_requisition (widget, &requisition);
5372 /* Default to requisition */
5373 *width = requisition.width;
5374 *height = requisition.height;
5376 /* If window is empty so requests 0, default to random nonzero size */
5377 if (*width == 0 && *height == 0)
5383 /* Override requisition with default size */
5387 gint base_width = 0;
5388 gint base_height = 0;
5390 gint min_height = 0;
5392 gint height_inc = 1;
5394 if (info->default_is_geometry &&
5395 (info->default_width > 0 || info->default_height > 0))
5397 GdkGeometry geometry;
5400 gtk_window_compute_hints (window, &geometry, &flags);
5402 if (flags & GDK_HINT_BASE_SIZE)
5404 base_width = geometry.base_width;
5405 base_height = geometry.base_height;
5407 if (flags & GDK_HINT_MIN_SIZE)
5409 min_width = geometry.min_width;
5410 min_height = geometry.min_height;
5412 if (flags & GDK_HINT_RESIZE_INC)
5414 width_inc = geometry.width_inc;
5415 height_inc = geometry.height_inc;
5419 if (info->default_width > 0)
5420 *width = MAX (info->default_width * width_inc + base_width, min_width);
5422 if (info->default_height > 0)
5423 *height = MAX (info->default_height * height_inc + base_height, min_height);
5428 /* Default to keeping current size */
5429 *width = widget->allocation.width;
5430 *height = widget->allocation.height;
5433 /* Override any size with gtk_window_resize() values */
5436 if (info->resize_width > 0)
5437 *width = info->resize_width;
5439 if (info->resize_height > 0)
5440 *height = info->resize_height;
5444 static GtkWindowPosition
5445 get_effective_position (GtkWindow *window)
5447 GtkWindowPosition pos = window->position;
5448 if (pos == GTK_WIN_POS_CENTER_ON_PARENT &&
5449 (window->transient_parent == NULL ||
5450 !GTK_WIDGET_MAPPED (window->transient_parent)))
5451 pos = GTK_WIN_POS_NONE;
5457 get_center_monitor_of_window (GtkWindow *window)
5459 /* We could try to sort out the relative positions of the monitors and
5460 * stuff, or we could just be losers and assume you have a row
5461 * or column of monitors.
5463 return gdk_screen_get_n_monitors (gtk_window_check_screen (window)) / 2;
5467 get_monitor_containing_pointer (GtkWindow *window)
5471 GdkScreen *window_screen;
5472 GdkScreen *pointer_screen;
5474 window_screen = gtk_window_check_screen (window);
5475 gdk_display_get_pointer (gdk_screen_get_display (window_screen),
5479 if (pointer_screen == window_screen)
5480 monitor_num = gdk_screen_get_monitor_at_point (pointer_screen, px, py);
5488 center_window_on_monitor (GtkWindow *window,
5494 GdkRectangle monitor;
5497 monitor_num = get_monitor_containing_pointer (window);
5499 if (monitor_num == -1)
5500 monitor_num = get_center_monitor_of_window (window);
5502 gdk_screen_get_monitor_geometry (gtk_window_check_screen (window),
5503 monitor_num, &monitor);
5505 *x = (monitor.width - w) / 2 + monitor.x;
5506 *y = (monitor.height - h) / 2 + monitor.y;
5508 /* Be sure we aren't off the monitor, ignoring _NET_WM_STRUT
5509 * and WM decorations.
5518 clamp_window_to_rectangle (gint *x,
5522 const GdkRectangle *rect)
5524 gint outside_w, outside_h;
5526 outside_w = (*x + w) - (rect->x + rect->width);
5530 outside_h = (*y + h) - (rect->y + rect->height);
5534 /* if larger than the screen, center on the screen. */
5536 *x += (rect->x - *x) / 2;
5538 *y += (rect->y - *y) / 2;
5543 gtk_window_compute_configure_request (GtkWindow *window,
5544 GdkRectangle *request,
5545 GdkGeometry *geometry,
5548 GdkGeometry new_geometry;
5552 GtkWindowPosition pos;
5553 GtkWidget *parent_widget;
5554 GtkWindowGeometryInfo *info;
5558 widget = GTK_WIDGET (window);
5560 screen = gtk_window_check_screen (window);
5562 gtk_widget_size_request (widget, NULL);
5563 gtk_window_compute_configure_request_size (window, (guint *)&w, (guint *)&h);
5565 gtk_window_compute_hints (window, &new_geometry, &new_flags);
5566 gtk_window_constrain_size (window,
5567 &new_geometry, new_flags,
5571 parent_widget = (GtkWidget*) window->transient_parent;
5573 pos = get_effective_position (window);
5574 info = gtk_window_get_geometry_info (window, FALSE);
5576 /* by default, don't change position requested */
5579 x = info->last.configure_request.x;
5580 y = info->last.configure_request.y;
5589 if (window->need_default_position)
5592 /* FIXME this all interrelates with window gravity.
5593 * For most of them I think we want to set GRAVITY_CENTER.
5595 * Not sure how to go about that.
5600 /* here we are only handling CENTER_ALWAYS
5601 * as it relates to default positioning,
5602 * where it's equivalent to simply CENTER
5604 case GTK_WIN_POS_CENTER_ALWAYS:
5605 case GTK_WIN_POS_CENTER:
5606 center_window_on_monitor (window, w, h, &x, &y);
5609 case GTK_WIN_POS_CENTER_ON_PARENT:
5612 GdkRectangle monitor;
5615 g_assert (GTK_WIDGET_MAPPED (parent_widget)); /* established earlier */
5617 if (parent_widget->window != NULL)
5618 monitor_num = gdk_screen_get_monitor_at_window (screen,
5619 parent_widget->window);
5623 gdk_window_get_origin (parent_widget->window,
5626 x = ox + (parent_widget->allocation.width - w) / 2;
5627 y = oy + (parent_widget->allocation.height - h) / 2;
5629 /* Clamp onto current monitor, ignoring _NET_WM_STRUT and
5630 * WM decorations. If parent wasn't on a monitor, just
5633 if (monitor_num >= 0)
5635 gdk_screen_get_monitor_geometry (screen, monitor_num, &monitor);
5636 clamp_window_to_rectangle (&x, &y, w, h, &monitor);
5641 case GTK_WIN_POS_MOUSE:
5643 gint screen_width = gdk_screen_get_width (screen);
5644 gint screen_height = gdk_screen_get_height (screen);
5646 GdkRectangle monitor;
5647 GdkScreen *pointer_screen;
5650 gdk_display_get_pointer (gdk_screen_get_display (screen),
5654 if (pointer_screen == screen)
5655 monitor_num = gdk_screen_get_monitor_at_point (screen, px, py);
5661 x = CLAMP (x, 0, screen_width - w);
5662 y = CLAMP (y, 0, screen_height - h);
5664 /* Clamp onto current monitor, ignoring _NET_WM_STRUT and
5665 * WM decorations. Don't try to figure out what's going
5666 * on if the mouse wasn't inside a monitor.
5668 if (monitor_num >= 0)
5670 gdk_screen_get_monitor_geometry (screen, monitor_num, &monitor);
5671 clamp_window_to_rectangle (&x, &y, w, h, &monitor);
5679 } /* if (window->need_default_position) */
5681 if (window->need_default_position && info &&
5682 info->initial_pos_set)
5684 x = info->initial_x;
5685 y = info->initial_y;
5686 gtk_window_constrain_position (window, w, h, &x, &y);
5692 request->height = h;
5695 *geometry = new_geometry;
5701 gtk_window_constrain_position (GtkWindow *window,
5707 /* See long comments in gtk_window_move_resize()
5708 * on when it's safe to call this function.
5710 if (window->position == GTK_WIN_POS_CENTER_ALWAYS)
5712 gint center_x, center_y;
5714 center_window_on_monitor (window, new_width, new_height, ¢er_x, ¢er_y);
5722 gtk_window_move_resize (GtkWindow *window)
5726 * First we determine whether any information has changed that would
5727 * cause us to revise our last configure request. If we would send
5728 * a different configure request from last time, then
5729 * configure_request_size_changed = TRUE or
5730 * configure_request_pos_changed = TRUE. configure_request_size_changed
5731 * may be true due to new hints, a gtk_window_resize(), or whatever.
5732 * configure_request_pos_changed may be true due to gtk_window_set_position()
5733 * or gtk_window_move().
5735 * If the configure request has changed, we send off a new one. To
5736 * ensure GTK+ invariants are maintained (resize queue does what it
5737 * should), we go ahead and size_allocate the requested size in this
5740 * If the configure request has not changed, we don't ever resend
5741 * it, because it could mean fighting the user or window manager.
5744 * To prepare the configure request, we come up with a base size/pos:
5745 * - the one from gtk_window_move()/gtk_window_resize()
5746 * - else default_width, default_height if we haven't ever
5748 * - else the size request if we haven't ever been mapped,
5749 * as a substitute default size
5750 * - else the current size of the window, as received from
5751 * configure notifies (i.e. the current allocation)
5753 * If GTK_WIN_POS_CENTER_ALWAYS is active, we constrain
5754 * the position request to be centered.
5757 GtkContainer *container;
5758 GtkWindowGeometryInfo *info;
5759 GdkGeometry new_geometry;
5761 GdkRectangle new_request;
5762 gboolean configure_request_size_changed;
5763 gboolean configure_request_pos_changed;
5764 gboolean hints_changed; /* do we need to send these again */
5765 GtkWindowLastGeometryInfo saved_last_info;
5767 widget = GTK_WIDGET (window);
5768 container = GTK_CONTAINER (widget);
5769 info = gtk_window_get_geometry_info (window, TRUE);
5771 configure_request_size_changed = FALSE;
5772 configure_request_pos_changed = FALSE;
5774 gtk_window_compute_configure_request (window, &new_request,
5775 &new_geometry, &new_flags);
5777 /* This check implies the invariant that we never set info->last
5778 * without setting the hints and sending off a configure request.
5780 * If we change info->last without sending the request, we may
5783 if (info->last.configure_request.x != new_request.x ||
5784 info->last.configure_request.y != new_request.y)
5785 configure_request_pos_changed = TRUE;
5787 if ((info->last.configure_request.width != new_request.width ||
5788 info->last.configure_request.height != new_request.height))
5789 configure_request_size_changed = TRUE;
5791 hints_changed = FALSE;
5793 if (!gtk_window_compare_hints (&info->last.geometry, info->last.flags,
5794 &new_geometry, new_flags))
5796 hints_changed = TRUE;
5799 /* Position Constraints
5800 * ====================
5802 * POS_CENTER_ALWAYS is conceptually a constraint rather than
5803 * a default. The other POS_ values are used only when the
5804 * window is shown, not after that.
5806 * However, we can't implement a position constraint as
5807 * "anytime the window size changes, center the window"
5808 * because this may well end up fighting the WM or user. In
5809 * fact it gets in an infinite loop with at least one WM.
5811 * Basically, applications are in no way in a position to
5812 * constrain the position of a window, with one exception:
5813 * override redirect windows. (Really the intended purpose
5814 * of CENTER_ALWAYS anyhow, I would think.)
5816 * So the way we implement this "constraint" is to say that when WE
5817 * cause a move or resize, i.e. we make a configure request changing
5818 * window size, we recompute the CENTER_ALWAYS position to reflect
5819 * the new window size, and include it in our request. Also, if we
5820 * just turned on CENTER_ALWAYS we snap to center with a new
5821 * request. Otherwise, if we are just NOTIFIED of a move or resize
5822 * done by someone else e.g. the window manager, we do NOT send a
5823 * new configure request.
5825 * For override redirect windows, this works fine; all window
5826 * sizes are from our configure requests. For managed windows,
5827 * it is at least semi-sane, though who knows what the
5828 * app author is thinking.
5831 /* This condition should be kept in sync with the condition later on
5832 * that determines whether we send a configure request. i.e. we
5833 * should do this position constraining anytime we were going to
5834 * send a configure request anyhow, plus when constraints have
5837 if (configure_request_pos_changed ||
5838 configure_request_size_changed ||
5840 info->position_constraints_changed)
5842 /* We request the constrained position if:
5843 * - we were changing position, and need to clamp
5844 * the change to the constraint
5845 * - we're changing the size anyway
5846 * - set_position() was called to toggle CENTER_ALWAYS on
5849 gtk_window_constrain_position (window,
5855 /* Update whether we need to request a move */
5856 if (info->last.configure_request.x != new_request.x ||
5857 info->last.configure_request.y != new_request.y)
5858 configure_request_pos_changed = TRUE;
5860 configure_request_pos_changed = FALSE;
5864 if (window->type == GTK_WINDOW_TOPLEVEL)
5866 int notify_x, notify_y;
5868 /* this is the position from the last configure notify */
5869 gdk_window_get_position (widget->window, ¬ify_x, ¬ify_y);
5871 g_message ("--- %s ---\n"
5872 "last : %d,%d\t%d x %d\n"
5873 "this : %d,%d\t%d x %d\n"
5874 "alloc : %d,%d\t%d x %d\n"
5876 "resize: \t%d x %d\n"
5877 "size_changed: %d pos_changed: %d hints_changed: %d\n"
5878 "configure_notify_received: %d\n"
5879 "configure_request_count: %d\n"
5880 "position_constraints_changed: %d\n",
5881 window->title ? window->title : "(no title)",
5882 info->last.configure_request.x,
5883 info->last.configure_request.y,
5884 info->last.configure_request.width,
5885 info->last.configure_request.height,
5891 widget->allocation.width,
5892 widget->allocation.height,
5893 widget->requisition.width,
5894 widget->requisition.height,
5896 info->resize_height,
5897 configure_request_pos_changed,
5898 configure_request_size_changed,
5900 window->configure_notify_received,
5901 window->configure_request_count,
5902 info->position_constraints_changed);
5906 saved_last_info = info->last;
5907 info->last.geometry = new_geometry;
5908 info->last.flags = new_flags;
5909 info->last.configure_request = new_request;
5911 /* need to set PPosition so the WM will look at our position,
5912 * but we don't want to count PPosition coming and going as a hints
5913 * change for future iterations. So we saved info->last prior to
5917 /* Also, if the initial position was explicitly set, then we always
5918 * toggle on PPosition. This makes gtk_window_move(window, 0, 0)
5922 /* Also, we toggle on PPosition if GTK_WIN_POS_ is in use and
5923 * this is an initial map
5926 if ((configure_request_pos_changed ||
5927 info->initial_pos_set ||
5928 (window->need_default_position &&
5929 get_effective_position (window) != GTK_WIN_POS_NONE)) &&
5930 (new_flags & GDK_HINT_POS) == 0)
5932 new_flags |= GDK_HINT_POS;
5933 hints_changed = TRUE;
5936 /* Set hints if necessary
5939 gdk_window_set_geometry_hints (widget->window,
5943 /* handle resizing/moving and widget tree allocation
5945 if (window->configure_notify_received)
5947 GtkAllocation allocation;
5949 /* If we have received a configure event since
5950 * the last time in this function, we need to
5951 * accept our new size and size_allocate child widgets.
5952 * (see gtk_window_configure_event() for more details).
5954 * 1 or more configure notifies may have been received.
5955 * Also, configure_notify_received will only be TRUE
5956 * if all expected configure notifies have been received
5957 * (one per configure request), as an optimization.
5960 window->configure_notify_received = FALSE;
5962 /* gtk_window_configure_event() filled in widget->allocation */
5963 allocation = widget->allocation;
5964 gtk_widget_size_allocate (widget, &allocation);
5966 gdk_window_process_updates (widget->window, TRUE);
5968 gdk_window_configure_finished (widget->window);
5970 /* If the configure request changed, it means that
5972 * 1) coincidentally changed hints or widget properties
5973 * impacting the configure request before getting
5974 * a configure notify, or
5975 * 2) some broken widget is changing its size request
5976 * during size allocation, resulting in
5977 * a false appearance of changed configure request.
5979 * For 1), we could just go ahead and ask for the
5980 * new size right now, but doing that for 2)
5981 * might well be fighting the user (and can even
5982 * trigger a loop). Since we really don't want to
5983 * do that, we requeue a resize in hopes that
5984 * by the time it gets handled, the child has seen
5985 * the light and is willing to go along with the
5986 * new size. (this happens for the zvt widget, since
5987 * the size_allocate() above will have stored the
5988 * requisition corresponding to the new size in the
5991 * This doesn't buy us anything for 1), but it shouldn't
5992 * hurt us too badly, since it is what would have
5993 * happened if we had gotten the configure event before
5994 * the new size had been set.
5997 if (configure_request_size_changed ||
5998 configure_request_pos_changed)
6000 /* Don't change the recorded last info after all, because we
6001 * haven't actually updated to the new info yet - we decided
6002 * to postpone our configure request until later.
6004 info->last = saved_last_info;
6006 gtk_widget_queue_resize (widget); /* migth recurse for GTK_RESIZE_IMMEDIATE */
6009 return; /* Bail out, we didn't really process the move/resize */
6011 else if ((configure_request_size_changed || hints_changed) &&
6012 (widget->allocation.width != new_request.width ||
6013 widget->allocation.height != new_request.height))
6016 /* We are in one of the following situations:
6017 * A. configure_request_size_changed
6018 * our requisition has changed and we need a different window size,
6019 * so we request it from the window manager.
6020 * B. !configure_request_size_changed && hints_changed
6021 * the window manager rejects our size, but we have just changed the
6022 * window manager hints, so there's a chance our request will
6023 * be honoured this time, so we try again.
6025 * However, if the new requisition is the same as the current allocation,
6026 * we don't request it again, since we won't get a ConfigureNotify back from
6027 * the window manager unless it decides to change our requisition. If
6028 * we don't get the ConfigureNotify back, the resize queue will never be run.
6031 /* Now send the configure request */
6032 if (configure_request_pos_changed)
6036 gdk_window_move_resize (window->frame,
6037 new_request.x - window->frame_left,
6038 new_request.y - window->frame_top,
6039 new_request.width + window->frame_left + window->frame_right,
6040 new_request.height + window->frame_top + window->frame_bottom);
6041 gdk_window_resize (widget->window,
6042 new_request.width, new_request.height);
6045 gdk_window_move_resize (widget->window,
6046 new_request.x, new_request.y,
6047 new_request.width, new_request.height);
6049 else /* only size changed */
6052 gdk_window_resize (window->frame,
6053 new_request.width + window->frame_left + window->frame_right,
6054 new_request.height + window->frame_top + window->frame_bottom);
6055 gdk_window_resize (widget->window,
6056 new_request.width, new_request.height);
6059 if (window->type == GTK_WINDOW_POPUP)
6061 GtkAllocation allocation;
6063 /* Directly size allocate for override redirect (popup) windows. */
6064 allocation.width = new_request.width;
6065 allocation.height = new_request.height;
6067 gtk_widget_size_allocate (widget, &allocation);
6069 gdk_window_process_updates (widget->window, TRUE);
6071 if (container->resize_mode == GTK_RESIZE_QUEUE)
6072 gtk_widget_queue_draw (widget);
6076 /* Increment the number of have-not-yet-received-notify requests */
6077 window->configure_request_count += 1;
6078 gdk_window_freeze_toplevel_updates_libgtk_only (widget->window);
6080 /* for GTK_RESIZE_QUEUE toplevels, we are now awaiting a new
6081 * configure event in response to our resizing request.
6082 * the configure event will cause a new resize with
6083 * ->configure_notify_received=TRUE.
6084 * until then, we want to
6085 * - discard expose events
6086 * - coalesce resizes for our children
6087 * - defer any window resizes until the configure event arrived
6088 * to achieve this, we queue a resize for the window, but remove its
6089 * resizing handler, so resizing will not be handled from the next
6090 * idle handler but when the configure event arrives.
6092 * FIXME: we should also dequeue the pending redraws here, since
6093 * we handle those ourselves upon ->configure_notify_received==TRUE.
6095 if (container->resize_mode == GTK_RESIZE_QUEUE)
6097 gtk_widget_queue_resize (widget);
6098 _gtk_container_dequeue_resize_handler (container);
6104 /* Handle any position changes.
6106 if (configure_request_pos_changed)
6110 gdk_window_move (window->frame,
6111 new_request.x - window->frame_left,
6112 new_request.y - window->frame_top);
6115 gdk_window_move (widget->window,
6116 new_request.x, new_request.y);
6119 /* And run the resize queue.
6121 gtk_container_resize_children (container);
6124 /* We have now processed a move/resize since the last position
6125 * constraint change, setting of the initial position, or resize.
6126 * (Not resetting these flags here can lead to infinite loops for
6127 * GTK_RESIZE_IMMEDIATE containers)
6129 info->position_constraints_changed = FALSE;
6130 info->initial_pos_set = FALSE;
6131 info->resize_width = -1;
6132 info->resize_height = -1;
6135 /* Compare two sets of Geometry hints for equality.
6138 gtk_window_compare_hints (GdkGeometry *geometry_a,
6140 GdkGeometry *geometry_b,
6143 if (flags_a != flags_b)
6146 if ((flags_a & GDK_HINT_MIN_SIZE) &&
6147 (geometry_a->min_width != geometry_b->min_width ||
6148 geometry_a->min_height != geometry_b->min_height))
6151 if ((flags_a & GDK_HINT_MAX_SIZE) &&
6152 (geometry_a->max_width != geometry_b->max_width ||
6153 geometry_a->max_height != geometry_b->max_height))
6156 if ((flags_a & GDK_HINT_BASE_SIZE) &&
6157 (geometry_a->base_width != geometry_b->base_width ||
6158 geometry_a->base_height != geometry_b->base_height))
6161 if ((flags_a & GDK_HINT_ASPECT) &&
6162 (geometry_a->min_aspect != geometry_b->min_aspect ||
6163 geometry_a->max_aspect != geometry_b->max_aspect))
6166 if ((flags_a & GDK_HINT_RESIZE_INC) &&
6167 (geometry_a->width_inc != geometry_b->width_inc ||
6168 geometry_a->height_inc != geometry_b->height_inc))
6171 if ((flags_a & GDK_HINT_WIN_GRAVITY) &&
6172 geometry_a->win_gravity != geometry_b->win_gravity)
6179 _gtk_window_constrain_size (GtkWindow *window,
6185 GtkWindowGeometryInfo *info;
6187 g_return_if_fail (GTK_IS_WINDOW (window));
6189 info = window->geometry_info;
6192 GdkWindowHints flags = info->last.flags;
6193 GdkGeometry *geometry = &info->last.geometry;
6195 gtk_window_constrain_size (window,
6206 gtk_window_constrain_size (GtkWindow *window,
6207 GdkGeometry *geometry,
6214 gdk_window_constrain_size (geometry, flags, width, height,
6215 new_width, new_height);
6218 /* Compute the set of geometry hints and flags for a window
6219 * based on the application set geometry, and requisiition
6220 * of the window. gtk_widget_size_request() must have been
6224 gtk_window_compute_hints (GtkWindow *window,
6225 GdkGeometry *new_geometry,
6229 gint extra_width = 0;
6230 gint extra_height = 0;
6231 GtkWindowGeometryInfo *geometry_info;
6232 GtkRequisition requisition;
6234 widget = GTK_WIDGET (window);
6236 gtk_widget_get_child_requisition (widget, &requisition);
6237 geometry_info = gtk_window_get_geometry_info (GTK_WINDOW (widget), FALSE);
6241 *new_flags = geometry_info->mask;
6242 *new_geometry = geometry_info->geometry;
6249 if (geometry_info && geometry_info->widget)
6251 GtkRequisition child_requisition;
6253 /* FIXME: This really isn't right. It gets the min size wrong and forces
6254 * callers to do horrible hacks like set a huge usize on the child requisition
6255 * to get the base size right. We really want to find the answers to:
6257 * - If the geometry widget was infinitely big, how much extra space
6258 * would be needed for the stuff around it.
6260 * - If the geometry widget was infinitely small, how big would the
6261 * window still have to be.
6263 * Finding these answers would be a bit of a mess here. (Bug #68668)
6265 gtk_widget_get_child_requisition (geometry_info->widget, &child_requisition);
6267 extra_width = widget->requisition.width - child_requisition.width;
6268 extra_height = widget->requisition.height - child_requisition.height;
6271 /* We don't want to set GDK_HINT_POS in here, we just set it
6272 * in gtk_window_move_resize() when we want the position
6276 if (*new_flags & GDK_HINT_BASE_SIZE)
6278 new_geometry->base_width += extra_width;
6279 new_geometry->base_height += extra_height;
6281 else if (!(*new_flags & GDK_HINT_MIN_SIZE) &&
6282 (*new_flags & GDK_HINT_RESIZE_INC) &&
6283 ((extra_width != 0) || (extra_height != 0)))
6285 *new_flags |= GDK_HINT_BASE_SIZE;
6287 new_geometry->base_width = extra_width;
6288 new_geometry->base_height = extra_height;
6291 if (*new_flags & GDK_HINT_MIN_SIZE)
6293 if (new_geometry->min_width < 0)
6294 new_geometry->min_width = requisition.width;
6296 new_geometry->min_width += extra_width;
6298 if (new_geometry->min_height < 0)
6299 new_geometry->min_height = requisition.height;
6301 new_geometry->min_height += extra_height;
6303 else if (!window->allow_shrink)
6305 *new_flags |= GDK_HINT_MIN_SIZE;
6307 new_geometry->min_width = requisition.width;
6308 new_geometry->min_height = requisition.height;
6311 if (*new_flags & GDK_HINT_MAX_SIZE)
6313 if (new_geometry->max_width < 0)
6314 new_geometry->max_width = requisition.width;
6316 new_geometry->max_width += extra_width;
6318 if (new_geometry->max_height < 0)
6319 new_geometry->max_height = requisition.height;
6321 new_geometry->max_height += extra_height;
6323 else if (!window->allow_grow)
6325 *new_flags |= GDK_HINT_MAX_SIZE;
6327 new_geometry->max_width = requisition.width;
6328 new_geometry->max_height = requisition.height;
6331 *new_flags |= GDK_HINT_WIN_GRAVITY;
6332 new_geometry->win_gravity = window->gravity;
6335 /***********************
6336 * Redrawing functions *
6337 ***********************/
6340 gtk_window_paint (GtkWidget *widget,
6343 gtk_paint_flat_box (widget->style, widget->window, GTK_STATE_NORMAL,
6344 GTK_SHADOW_NONE, area, widget, "base", 0, 0, -1, -1);
6348 gtk_window_expose (GtkWidget *widget,
6349 GdkEventExpose *event)
6351 if (!GTK_WIDGET_APP_PAINTABLE (widget))
6352 gtk_window_paint (widget, &event->area);
6354 if (GTK_WIDGET_CLASS (gtk_window_parent_class)->expose_event)
6355 return GTK_WIDGET_CLASS (gtk_window_parent_class)->expose_event (widget, event);
6361 * gtk_window_set_has_frame:
6362 * @window: a #GtkWindow
6363 * @setting: a boolean
6365 * (Note: this is a special-purpose function for the framebuffer port,
6366 * that causes GTK+ to draw its own window border. For most applications,
6367 * you want gtk_window_set_decorated() instead, which tells the window
6368 * manager whether to draw the window border.)
6370 * If this function is called on a window with setting of %TRUE, before
6371 * it is realized or showed, it will have a "frame" window around
6372 * @window->window, accessible in @window->frame. Using the signal
6373 * frame_event you can receive all events targeted at the frame.
6375 * This function is used by the linux-fb port to implement managed
6376 * windows, but it could conceivably be used by X-programs that
6377 * want to do their own window decorations.
6381 gtk_window_set_has_frame (GtkWindow *window,
6384 g_return_if_fail (GTK_IS_WINDOW (window));
6385 g_return_if_fail (!GTK_WIDGET_REALIZED (window));
6387 window->has_frame = setting != FALSE;
6391 * gtk_window_get_has_frame:
6392 * @window: a #GtkWindow
6394 * Accessor for whether the window has a frame window exterior to
6395 * @window->window. Gets the value set by gtk_window_set_has_frame ().
6397 * Return value: %TRUE if a frame has been added to the window
6398 * via gtk_window_set_has_frame().
6401 gtk_window_get_has_frame (GtkWindow *window)
6403 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
6405 return window->has_frame;
6409 * gtk_window_set_frame_dimensions:
6410 * @window: a #GtkWindow that has a frame
6411 * @left: The width of the left border
6412 * @top: The height of the top border
6413 * @right: The width of the right border
6414 * @bottom: The height of the bottom border
6416 * (Note: this is a special-purpose function intended for the framebuffer
6417 * port; see gtk_window_set_has_frame(). It will have no effect on the
6418 * window border drawn by the window manager, which is the normal
6419 * case when using the X Window system.)
6421 * For windows with frames (see gtk_window_set_has_frame()) this function
6422 * can be used to change the size of the frame border.
6425 gtk_window_set_frame_dimensions (GtkWindow *window,
6433 g_return_if_fail (GTK_IS_WINDOW (window));
6435 widget = GTK_WIDGET (window);
6437 if (window->frame_left == left &&
6438 window->frame_top == top &&
6439 window->frame_right == right &&
6440 window->frame_bottom == bottom)
6443 window->frame_left = left;
6444 window->frame_top = top;
6445 window->frame_right = right;
6446 window->frame_bottom = bottom;
6448 if (GTK_WIDGET_REALIZED (widget) && window->frame)
6450 gint width = widget->allocation.width + left + right;
6451 gint height = widget->allocation.height + top + bottom;
6452 gdk_window_resize (window->frame, width, height);
6453 gtk_decorated_window_move_resize_window (window,
6455 widget->allocation.width,
6456 widget->allocation.height);
6461 * gtk_window_present:
6462 * @window: a #GtkWindow
6464 * Presents a window to the user. This may mean raising the window
6465 * in the stacking order, deiconifying it, moving it to the current
6466 * desktop, and/or giving it the keyboard focus, possibly dependent
6467 * on the user's platform, window manager, and preferences.
6469 * If @window is hidden, this function calls gtk_widget_show()
6472 * This function should be used when the user tries to open a window
6473 * that's already open. Say for example the preferences dialog is
6474 * currently open, and the user chooses Preferences from the menu
6475 * a second time; use gtk_window_present() to move the already-open dialog
6476 * where the user can see it.
6478 * If you are calling this function in response to a user interaction,
6479 * it is preferable to use gtk_window_present_with_time().
6483 gtk_window_present (GtkWindow *window)
6485 gtk_window_present_with_time (window, GDK_CURRENT_TIME);
6489 * gtk_window_present_with_time:
6490 * @window: a #GtkWindow
6491 * @timestamp: the timestamp of the user interaction (typically a
6492 * button or key press event) which triggered this call
6494 * Presents a window to the user in response to a user interaction.
6495 * If you need to present a window without a timestamp, use
6496 * gtk_window_present(). See gtk_window_present() for details.
6501 gtk_window_present_with_time (GtkWindow *window,
6506 g_return_if_fail (GTK_IS_WINDOW (window));
6508 widget = GTK_WIDGET (window);
6510 if (GTK_WIDGET_VISIBLE (window))
6512 g_assert (widget->window != NULL);
6514 gdk_window_show (widget->window);
6516 /* Translate a timestamp of GDK_CURRENT_TIME appropriately */
6517 if (timestamp == GDK_CURRENT_TIME)
6519 #ifdef GDK_WINDOWING_X11
6520 GdkDisplay *display;
6522 display = gtk_widget_get_display (GTK_WIDGET (window));
6523 timestamp = gdk_x11_display_get_user_time (display);
6525 timestamp = gtk_get_current_event_time ();
6529 gdk_window_focus (widget->window, timestamp);
6533 gtk_widget_show (widget);
6538 * gtk_window_iconify:
6539 * @window: a #GtkWindow
6541 * Asks to iconify (i.e. minimize) the specified @window. Note that
6542 * you shouldn't assume the window is definitely iconified afterward,
6543 * because other entities (e.g. the user or <link
6544 * linkend="gtk-X11-arch">window manager</link>) could deiconify it
6545 * again, or there may not be a window manager in which case
6546 * iconification isn't possible, etc. But normally the window will end
6547 * up iconified. Just don't write code that crashes if not.
6549 * It's permitted to call this function before showing a window,
6550 * in which case the window will be iconified before it ever appears
6553 * You can track iconification via the "window_state_event" signal
6558 gtk_window_iconify (GtkWindow *window)
6561 GdkWindow *toplevel;
6563 g_return_if_fail (GTK_IS_WINDOW (window));
6565 widget = GTK_WIDGET (window);
6567 window->iconify_initially = TRUE;
6570 toplevel = window->frame;
6572 toplevel = widget->window;
6574 if (toplevel != NULL)
6575 gdk_window_iconify (toplevel);
6579 * gtk_window_deiconify:
6580 * @window: a #GtkWindow
6582 * Asks to deiconify (i.e. unminimize) the specified @window. Note
6583 * that you shouldn't assume the window is definitely deiconified
6584 * afterward, because other entities (e.g. the user or <link
6585 * linkend="gtk-X11-arch">window manager</link>) could iconify it
6586 * again before your code which assumes deiconification gets to run.
6588 * You can track iconification via the "window_state_event" signal
6592 gtk_window_deiconify (GtkWindow *window)
6595 GdkWindow *toplevel;
6597 g_return_if_fail (GTK_IS_WINDOW (window));
6599 widget = GTK_WIDGET (window);
6601 window->iconify_initially = FALSE;
6604 toplevel = window->frame;
6606 toplevel = widget->window;
6608 if (toplevel != NULL)
6609 gdk_window_deiconify (toplevel);
6614 * @window: a #GtkWindow
6616 * Asks to stick @window, which means that it will appear on all user
6617 * desktops. Note that you shouldn't assume the window is definitely
6618 * stuck afterward, because other entities (e.g. the user or <link
6619 * linkend="gtk-X11-arch">window manager</link>) could unstick it
6620 * again, and some window managers do not support sticking
6621 * windows. But normally the window will end up stuck. Just don't
6622 * write code that crashes if not.
6624 * It's permitted to call this function before showing a window.
6626 * You can track stickiness via the "window_state_event" signal
6631 gtk_window_stick (GtkWindow *window)
6634 GdkWindow *toplevel;
6636 g_return_if_fail (GTK_IS_WINDOW (window));
6638 widget = GTK_WIDGET (window);
6640 window->stick_initially = TRUE;
6643 toplevel = window->frame;
6645 toplevel = widget->window;
6647 if (toplevel != NULL)
6648 gdk_window_stick (toplevel);
6652 * gtk_window_unstick:
6653 * @window: a #GtkWindow
6655 * Asks to unstick @window, which means that it will appear on only
6656 * one of the user's desktops. Note that you shouldn't assume the
6657 * window is definitely unstuck afterward, because other entities
6658 * (e.g. the user or <link linkend="gtk-X11-arch">window
6659 * manager</link>) could stick it again. But normally the window will
6660 * end up stuck. Just don't write code that crashes if not.
6662 * You can track stickiness via the "window_state_event" signal
6667 gtk_window_unstick (GtkWindow *window)
6670 GdkWindow *toplevel;
6672 g_return_if_fail (GTK_IS_WINDOW (window));
6674 widget = GTK_WIDGET (window);
6676 window->stick_initially = FALSE;
6679 toplevel = window->frame;
6681 toplevel = widget->window;
6683 if (toplevel != NULL)
6684 gdk_window_unstick (toplevel);
6688 * gtk_window_maximize:
6689 * @window: a #GtkWindow
6691 * Asks to maximize @window, so that it becomes full-screen. Note that
6692 * you shouldn't assume the window is definitely maximized afterward,
6693 * because other entities (e.g. the user or <link
6694 * linkend="gtk-X11-arch">window manager</link>) could unmaximize it
6695 * again, and not all window managers support maximization. But
6696 * normally the window will end up maximized. Just don't write code
6697 * that crashes if not.
6699 * It's permitted to call this function before showing a window,
6700 * in which case the window will be maximized when it appears onscreen
6703 * You can track maximization via the "window_state_event" signal
6708 gtk_window_maximize (GtkWindow *window)
6711 GdkWindow *toplevel;
6713 g_return_if_fail (GTK_IS_WINDOW (window));
6715 widget = GTK_WIDGET (window);
6717 window->maximize_initially = TRUE;
6720 toplevel = window->frame;
6722 toplevel = widget->window;
6724 if (toplevel != NULL)
6725 gdk_window_maximize (toplevel);
6729 * gtk_window_unmaximize:
6730 * @window: a #GtkWindow
6732 * Asks to unmaximize @window. Note that you shouldn't assume the
6733 * window is definitely unmaximized afterward, because other entities
6734 * (e.g. the user or <link linkend="gtk-X11-arch">window
6735 * manager</link>) could maximize it again, and not all window
6736 * managers honor requests to unmaximize. But normally the window will
6737 * end up unmaximized. Just don't write code that crashes if not.
6739 * You can track maximization via the "window_state_event" signal
6744 gtk_window_unmaximize (GtkWindow *window)
6747 GdkWindow *toplevel;
6749 g_return_if_fail (GTK_IS_WINDOW (window));
6751 widget = GTK_WIDGET (window);
6753 window->maximize_initially = FALSE;
6756 toplevel = window->frame;
6758 toplevel = widget->window;
6760 if (toplevel != NULL)
6761 gdk_window_unmaximize (toplevel);
6765 * gtk_window_fullscreen:
6766 * @window: a #GtkWindow
6768 * Asks to place @window in the fullscreen state. Note that you
6769 * shouldn't assume the window is definitely full screen afterward,
6770 * because other entities (e.g. the user or <link
6771 * linkend="gtk-X11-arch">window manager</link>) could unfullscreen it
6772 * again, and not all window managers honor requests to fullscreen
6773 * windows. But normally the window will end up fullscreen. Just
6774 * don't write code that crashes if not.
6776 * You can track the fullscreen state via the "window_state_event" signal
6782 gtk_window_fullscreen (GtkWindow *window)
6785 GdkWindow *toplevel;
6786 GtkWindowPrivate *priv;
6788 g_return_if_fail (GTK_IS_WINDOW (window));
6790 widget = GTK_WIDGET (window);
6791 priv = GTK_WINDOW_GET_PRIVATE (window);
6793 priv->fullscreen_initially = TRUE;
6796 toplevel = window->frame;
6798 toplevel = widget->window;
6800 if (toplevel != NULL)
6801 gdk_window_fullscreen (toplevel);
6805 * gtk_window_unfullscreen:
6806 * @window: a #GtkWindow
6808 * Asks to toggle off the fullscreen state for @window. Note that you
6809 * shouldn't assume the window is definitely not full screen
6810 * afterward, because other entities (e.g. the user or <link
6811 * linkend="gtk-X11-arch">window manager</link>) could fullscreen it
6812 * again, and not all window managers honor requests to unfullscreen
6813 * windows. But normally the window will end up restored to its normal
6814 * state. Just don't write code that crashes if not.
6816 * You can track the fullscreen state via the "window_state_event" signal
6822 gtk_window_unfullscreen (GtkWindow *window)
6825 GdkWindow *toplevel;
6826 GtkWindowPrivate *priv;
6828 g_return_if_fail (GTK_IS_WINDOW (window));
6830 widget = GTK_WIDGET (window);
6831 priv = GTK_WINDOW_GET_PRIVATE (window);
6833 priv->fullscreen_initially = FALSE;
6836 toplevel = window->frame;
6838 toplevel = widget->window;
6840 if (toplevel != NULL)
6841 gdk_window_unfullscreen (toplevel);
6845 * gtk_window_set_keep_above:
6846 * @window: a #GtkWindow
6847 * @setting: whether to keep @window above other windows
6849 * Asks to keep @window above, so that it stays on top. Note that
6850 * you shouldn't assume the window is definitely above afterward,
6851 * because other entities (e.g. the user or <link
6852 * linkend="gtk-X11-arch">window manager</link>) could not keep it above,
6853 * and not all window managers support keeping windows above. But
6854 * normally the window will end kept above. Just don't write code
6855 * that crashes if not.
6857 * It's permitted to call this function before showing a window,
6858 * in which case the window will be kept above when it appears onscreen
6861 * You can track the above state via the "window_state_event" signal
6864 * Note that, according to the <ulink
6865 * url="http://www.freedesktop.org/Standards/wm-spec">Extended Window
6866 * Manager Hints</ulink> specification, the above state is mainly meant
6867 * for user preferences and should not be used by applications e.g. for
6868 * drawing attention to their dialogs.
6873 gtk_window_set_keep_above (GtkWindow *window,
6877 GtkWindowPrivate *priv;
6878 GdkWindow *toplevel;
6880 g_return_if_fail (GTK_IS_WINDOW (window));
6882 widget = GTK_WIDGET (window);
6883 priv = GTK_WINDOW_GET_PRIVATE (window);
6885 priv->above_initially = setting != FALSE;
6887 priv->below_initially = FALSE;
6890 toplevel = window->frame;
6892 toplevel = widget->window;
6894 if (toplevel != NULL)
6895 gdk_window_set_keep_above (toplevel, setting);
6899 * gtk_window_set_keep_below:
6900 * @window: a #GtkWindow
6901 * @setting: whether to keep @window below other windows
6903 * Asks to keep @window below, so that it stays in bottom. Note that
6904 * you shouldn't assume the window is definitely below afterward,
6905 * because other entities (e.g. the user or <link
6906 * linkend="gtk-X11-arch">window manager</link>) could not keep it below,
6907 * and not all window managers support putting windows below. But
6908 * normally the window will be kept below. Just don't write code
6909 * that crashes if not.
6911 * It's permitted to call this function before showing a window,
6912 * in which case the window will be kept below when it appears onscreen
6915 * You can track the below state via the "window_state_event" signal
6918 * Note that, according to the <ulink
6919 * url="http://www.freedesktop.org/Standards/wm-spec">Extended Window
6920 * Manager Hints</ulink> specification, the above state is mainly meant
6921 * for user preferences and should not be used by applications e.g. for
6922 * drawing attention to their dialogs.
6927 gtk_window_set_keep_below (GtkWindow *window,
6931 GtkWindowPrivate *priv;
6932 GdkWindow *toplevel;
6934 g_return_if_fail (GTK_IS_WINDOW (window));
6936 widget = GTK_WIDGET (window);
6937 priv = GTK_WINDOW_GET_PRIVATE (window);
6939 priv->below_initially = setting != FALSE;
6941 priv->above_initially = FALSE;
6944 toplevel = window->frame;
6946 toplevel = widget->window;
6948 if (toplevel != NULL)
6949 gdk_window_set_keep_below (toplevel, setting);
6953 * gtk_window_set_resizable:
6954 * @window: a #GtkWindow
6955 * @resizable: %TRUE if the user can resize this window
6957 * Sets whether the user can resize a window. Windows are user resizable
6961 gtk_window_set_resizable (GtkWindow *window,
6964 g_return_if_fail (GTK_IS_WINDOW (window));
6966 gtk_window_set_policy (window, FALSE, resizable, FALSE);
6970 * gtk_window_get_resizable:
6971 * @window: a #GtkWindow
6973 * Gets the value set by gtk_window_set_resizable().
6975 * Return value: %TRUE if the user can resize the window
6978 gtk_window_get_resizable (GtkWindow *window)
6980 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
6982 /* allow_grow is most likely to indicate the semantic concept we
6983 * mean by "resizable" (and will be a reliable indicator if
6984 * set_policy() hasn't been called)
6986 return window->allow_grow;
6990 * gtk_window_set_gravity:
6991 * @window: a #GtkWindow
6992 * @gravity: window gravity
6994 * Window gravity defines the meaning of coordinates passed to
6995 * gtk_window_move(). See gtk_window_move() and #GdkGravity for
6998 * The default window gravity is #GDK_GRAVITY_NORTH_WEST which will
6999 * typically "do what you mean."
7003 gtk_window_set_gravity (GtkWindow *window,
7006 g_return_if_fail (GTK_IS_WINDOW (window));
7008 if (gravity != window->gravity)
7010 window->gravity = gravity;
7012 /* gtk_window_move_resize() will adapt gravity
7014 gtk_widget_queue_resize (GTK_WIDGET (window));
7016 g_object_notify (G_OBJECT (window), "gravity");
7021 * gtk_window_get_gravity:
7022 * @window: a #GtkWindow
7024 * Gets the value set by gtk_window_set_gravity().
7026 * Return value: window gravity
7029 gtk_window_get_gravity (GtkWindow *window)
7031 g_return_val_if_fail (GTK_IS_WINDOW (window), 0);
7033 return window->gravity;
7037 * gtk_window_begin_resize_drag:
7038 * @window: a #GtkWindow
7039 * @button: mouse button that initiated the drag
7040 * @edge: position of the resize control
7041 * @root_x: X position where the user clicked to initiate the drag, in root window coordinates
7042 * @root_y: Y position where the user clicked to initiate the drag
7043 * @timestamp: timestamp from the click event that initiated the drag
7045 * Starts resizing a window. This function is used if an application
7046 * has window resizing controls. When GDK can support it, the resize
7047 * will be done using the standard mechanism for the <link
7048 * linkend="gtk-X11-arch">window manager</link> or windowing
7049 * system. Otherwise, GDK will try to emulate window resizing,
7050 * potentially not all that well, depending on the windowing system.
7054 gtk_window_begin_resize_drag (GtkWindow *window,
7062 GdkWindow *toplevel;
7064 g_return_if_fail (GTK_IS_WINDOW (window));
7065 g_return_if_fail (GTK_WIDGET_VISIBLE (window));
7067 widget = GTK_WIDGET (window);
7070 toplevel = window->frame;
7072 toplevel = widget->window;
7074 gdk_window_begin_resize_drag (toplevel,
7081 * gtk_window_get_frame_dimensions:
7082 * @window: a #GtkWindow
7083 * @left: location to store the width of the frame at the left, or %NULL
7084 * @top: location to store the height of the frame at the top, or %NULL
7085 * @right: location to store the width of the frame at the returns, or %NULL
7086 * @bottom: location to store the height of the frame at the bottom, or %NULL
7088 * (Note: this is a special-purpose function intended for the
7089 * framebuffer port; see gtk_window_set_has_frame(). It will not
7090 * return the size of the window border drawn by the <link
7091 * linkend="gtk-X11-arch">window manager</link>, which is the normal
7092 * case when using a windowing system. See
7093 * gdk_window_get_frame_extents() to get the standard window border
7096 * Retrieves the dimensions of the frame window for this toplevel.
7097 * See gtk_window_set_has_frame(), gtk_window_set_frame_dimensions().
7100 gtk_window_get_frame_dimensions (GtkWindow *window,
7106 g_return_if_fail (GTK_IS_WINDOW (window));
7109 *left = window->frame_left;
7111 *top = window->frame_top;
7113 *right = window->frame_right;
7115 *bottom = window->frame_bottom;
7119 * gtk_window_begin_move_drag:
7120 * @window: a #GtkWindow
7121 * @button: mouse button that initiated the drag
7122 * @root_x: X position where the user clicked to initiate the drag, in root window coordinates
7123 * @root_y: Y position where the user clicked to initiate the drag
7124 * @timestamp: timestamp from the click event that initiated the drag
7126 * Starts moving a window. This function is used if an application has
7127 * window movement grips. When GDK can support it, the window movement
7128 * will be done using the standard mechanism for the <link
7129 * linkend="gtk-X11-arch">window manager</link> or windowing
7130 * system. Otherwise, GDK will try to emulate window movement,
7131 * potentially not all that well, depending on the windowing system.
7135 gtk_window_begin_move_drag (GtkWindow *window,
7142 GdkWindow *toplevel;
7144 g_return_if_fail (GTK_IS_WINDOW (window));
7145 g_return_if_fail (GTK_WIDGET_VISIBLE (window));
7147 widget = GTK_WIDGET (window);
7150 toplevel = window->frame;
7152 toplevel = widget->window;
7154 gdk_window_begin_move_drag (toplevel,
7161 * gtk_window_set_screen:
7162 * @window: a #GtkWindow.
7163 * @screen: a #GdkScreen.
7165 * Sets the #GdkScreen where the @window is displayed; if
7166 * the window is already mapped, it will be unmapped, and
7167 * then remapped on the new screen.
7172 gtk_window_set_screen (GtkWindow *window,
7176 GdkScreen *previous_screen;
7177 gboolean was_mapped;
7179 g_return_if_fail (GTK_IS_WINDOW (window));
7180 g_return_if_fail (GDK_IS_SCREEN (screen));
7182 if (screen == window->screen)
7185 widget = GTK_WIDGET (window);
7187 previous_screen = window->screen;
7188 was_mapped = GTK_WIDGET_MAPPED (widget);
7191 gtk_widget_unmap (widget);
7192 if (GTK_WIDGET_REALIZED (widget))
7193 gtk_widget_unrealize (widget);
7195 gtk_window_free_key_hash (window);
7196 window->screen = screen;
7197 gtk_widget_reset_rc_styles (widget);
7198 if (screen != previous_screen)
7200 g_signal_handlers_disconnect_by_func (previous_screen,
7201 gtk_window_on_composited_changed, window);
7202 g_signal_connect (screen, "composited_changed",
7203 G_CALLBACK (gtk_window_on_composited_changed), window);
7205 _gtk_widget_propagate_screen_changed (widget, previous_screen);
7206 _gtk_widget_propagate_composited_changed (widget);
7208 g_object_notify (G_OBJECT (window), "screen");
7211 gtk_widget_map (widget);
7215 gtk_window_on_composited_changed (GdkScreen *screen,
7218 gtk_widget_queue_draw (GTK_WIDGET (window));
7220 _gtk_widget_propagate_composited_changed (GTK_WIDGET (window));
7224 gtk_window_check_screen (GtkWindow *window)
7227 return window->screen;
7230 g_warning ("Screen for GtkWindow not set; you must always set\n"
7231 "a screen for a GtkWindow before using the window");
7237 * gtk_window_get_screen:
7238 * @window: a #GtkWindow.
7240 * Returns the #GdkScreen associated with @window.
7242 * Return value: a #GdkScreen.
7247 gtk_window_get_screen (GtkWindow *window)
7249 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
7251 return window->screen;
7255 * gtk_window_is_active:
7256 * @window: a #GtkWindow
7258 * Returns whether the window is part of the current active toplevel.
7259 * (That is, the toplevel window receiving keystrokes.)
7260 * The return value is %TRUE if the window is active toplevel
7261 * itself, but also if it is, say, a #GtkPlug embedded in the active toplevel.
7262 * You might use this function if you wanted to draw a widget
7263 * differently in an active window from a widget in an inactive window.
7264 * See gtk_window_has_toplevel_focus()
7266 * Return value: %TRUE if the window part of the current active window.
7271 gtk_window_is_active (GtkWindow *window)
7273 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
7275 return window->is_active;
7279 * gtk_window_has_toplevel_focus:
7280 * @window: a #GtkWindow
7282 * Returns whether the input focus is within this GtkWindow.
7283 * For real toplevel windows, this is identical to gtk_window_is_active(),
7284 * but for embedded windows, like #GtkPlug, the results will differ.
7286 * Return value: %TRUE if the input focus is within this GtkWindow
7291 gtk_window_has_toplevel_focus (GtkWindow *window)
7293 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
7295 return window->has_toplevel_focus;
7299 gtk_window_group_class_init (GtkWindowGroupClass *klass)
7304 gtk_window_group_get_type (void)
7306 static GType window_group_type = 0;
7308 if (!window_group_type)
7310 const GTypeInfo window_group_info =
7312 sizeof (GtkWindowGroupClass),
7313 NULL, /* base_init */
7314 NULL, /* base_finalize */
7315 (GClassInitFunc) gtk_window_group_class_init,
7316 NULL, /* class_finalize */
7317 NULL, /* class_data */
7318 sizeof (GtkWindowGroup),
7319 0, /* n_preallocs */
7320 (GInstanceInitFunc) NULL,
7323 window_group_type = g_type_register_static (G_TYPE_OBJECT, I_("GtkWindowGroup"),
7324 &window_group_info, 0);
7327 return window_group_type;
7331 * gtk_window_group_new:
7333 * Creates a new #GtkWindowGroup object. Grabs added with
7334 * gtk_grab_add() only affect windows within the same #GtkWindowGroup.
7336 * Return value: a new #GtkWindowGroup.
7339 gtk_window_group_new (void)
7341 return g_object_new (GTK_TYPE_WINDOW_GROUP, NULL);
7345 window_group_cleanup_grabs (GtkWindowGroup *group,
7349 GSList *to_remove = NULL;
7351 tmp_list = group->grabs;
7354 if (gtk_widget_get_toplevel (tmp_list->data) == (GtkWidget*) window)
7355 to_remove = g_slist_prepend (to_remove, g_object_ref (tmp_list->data));
7356 tmp_list = tmp_list->next;
7361 gtk_grab_remove (to_remove->data);
7362 g_object_unref (to_remove->data);
7363 to_remove = g_slist_delete_link (to_remove, to_remove);
7368 * gtk_window_group_add_window:
7369 * @window_group: a #GtkWindowGroup
7370 * @window: the #GtkWindow to add
7372 * Adds a window to a #GtkWindowGroup.
7375 gtk_window_group_add_window (GtkWindowGroup *window_group,
7378 g_return_if_fail (GTK_IS_WINDOW_GROUP (window_group));
7379 g_return_if_fail (GTK_IS_WINDOW (window));
7381 if (window->group != window_group)
7383 g_object_ref (window);
7384 g_object_ref (window_group);
7387 gtk_window_group_remove_window (window->group, window);
7389 window_group_cleanup_grabs (gtk_window_get_group (NULL), window);
7391 window->group = window_group;
7393 g_object_unref (window);
7398 * gtk_window_group_remove_window:
7399 * @window_group: a #GtkWindowGroup
7400 * @window: the #GtkWindow to remove
7402 * Removes a window from a #GtkWindowGroup.
7405 gtk_window_group_remove_window (GtkWindowGroup *window_group,
7408 g_return_if_fail (GTK_IS_WINDOW_GROUP (window_group));
7409 g_return_if_fail (GTK_IS_WINDOW (window));
7410 g_return_if_fail (window->group == window_group);
7412 g_object_ref (window);
7414 window_group_cleanup_grabs (window_group, window);
7415 window->group = NULL;
7417 g_object_unref (window_group);
7418 g_object_unref (window);
7422 * gtk_window_get_group:
7423 * @window: a #GtkWindow, or %NULL
7425 * Returns the group for @window or the default group, if
7426 * @window is %NULL or if @window does not have an explicit
7429 * Returns: the #GtkWindowGroup for a window or the default group
7434 gtk_window_get_group (GtkWindow *window)
7436 if (window && window->group)
7437 return window->group;
7440 static GtkWindowGroup *default_group = NULL;
7443 default_group = gtk_window_group_new ();
7445 return default_group;
7449 /* Return the current grab widget of the given group
7452 _gtk_window_group_get_current_grab (GtkWindowGroup *window_group)
7454 if (window_group->grabs)
7455 return GTK_WIDGET (window_group->grabs->data);
7460 Derived from XParseGeometry() in XFree86
7462 Copyright 1985, 1986, 1987,1998 The Open Group
7464 All Rights Reserved.
7466 The above copyright notice and this permission notice shall be included
7467 in all copies or substantial portions of the Software.
7469 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
7470 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
7471 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
7472 IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
7473 OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
7474 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
7475 OTHER DEALINGS IN THE SOFTWARE.
7477 Except as contained in this notice, the name of The Open Group shall
7478 not be used in advertising or otherwise to promote the sale, use or
7479 other dealings in this Software without prior written authorization
7480 from The Open Group.
7485 * XParseGeometry parses strings of the form
7486 * "=<width>x<height>{+-}<xoffset>{+-}<yoffset>", where
7487 * width, height, xoffset, and yoffset are unsigned integers.
7488 * Example: "=80x24+300-49"
7489 * The equal sign is optional.
7490 * It returns a bitmask that indicates which of the four values
7491 * were actually found in the string. For each value found,
7492 * the corresponding argument is updated; for each value
7493 * not found, the corresponding argument is left unchanged.
7496 /* The following code is from Xlib, and is minimally modified, so we
7497 * can track any upstream changes if required. Don't change this
7498 * code. Or if you do, put in a huge comment marking which thing
7503 read_int (gchar *string,
7511 else if (*string == '-')
7517 for (; (*string >= '0') && (*string <= '9'); string++)
7519 result = (result * 10) + (*string - '0');
7531 * Bitmask returned by XParseGeometry(). Each bit tells if the corresponding
7532 * value (x, y, width, height) was found in the parsed string.
7534 #define NoValue 0x0000
7535 #define XValue 0x0001
7536 #define YValue 0x0002
7537 #define WidthValue 0x0004
7538 #define HeightValue 0x0008
7539 #define AllValues 0x000F
7540 #define XNegative 0x0010
7541 #define YNegative 0x0020
7543 /* Try not to reformat/modify, so we can compare/sync with X sources */
7545 gtk_XParseGeometry (const char *string,
7548 unsigned int *width,
7549 unsigned int *height)
7553 unsigned int tempWidth, tempHeight;
7555 char *nextCharacter;
7557 /* These initializations are just to silence gcc */
7563 if ( (string == NULL) || (*string == '\0')) return(mask);
7565 string++; /* ignore possible '=' at beg of geometry spec */
7567 strind = (char *)string;
7568 if (*strind != '+' && *strind != '-' && *strind != 'x') {
7569 tempWidth = read_int(strind, &nextCharacter);
7570 if (strind == nextCharacter)
7572 strind = nextCharacter;
7576 if (*strind == 'x' || *strind == 'X') {
7578 tempHeight = read_int(strind, &nextCharacter);
7579 if (strind == nextCharacter)
7581 strind = nextCharacter;
7582 mask |= HeightValue;
7585 if ((*strind == '+') || (*strind == '-')) {
7586 if (*strind == '-') {
7588 tempX = -read_int(strind, &nextCharacter);
7589 if (strind == nextCharacter)
7591 strind = nextCharacter;
7597 tempX = read_int(strind, &nextCharacter);
7598 if (strind == nextCharacter)
7600 strind = nextCharacter;
7603 if ((*strind == '+') || (*strind == '-')) {
7604 if (*strind == '-') {
7606 tempY = -read_int(strind, &nextCharacter);
7607 if (strind == nextCharacter)
7609 strind = nextCharacter;
7616 tempY = read_int(strind, &nextCharacter);
7617 if (strind == nextCharacter)
7619 strind = nextCharacter;
7625 /* If strind isn't at the end of the string the it's an invalid
7626 geometry specification. */
7628 if (*strind != '\0') return (0);
7634 if (mask & WidthValue)
7636 if (mask & HeightValue)
7637 *height = tempHeight;
7642 * gtk_window_parse_geometry:
7643 * @window: a #GtkWindow
7644 * @geometry: geometry string
7646 * Parses a standard X Window System geometry string - see the
7647 * manual page for X (type 'man X') for details on this.
7648 * gtk_window_parse_geometry() does work on all GTK+ ports
7649 * including Win32 but is primarily intended for an X environment.
7651 * If either a size or a position can be extracted from the
7652 * geometry string, gtk_window_parse_geometry() returns %TRUE
7653 * and calls gtk_window_set_default_size() and/or gtk_window_move()
7654 * to resize/move the window.
7656 * If gtk_window_parse_geometry() returns %TRUE, it will also
7657 * set the #GDK_HINT_USER_POS and/or #GDK_HINT_USER_SIZE hints
7658 * indicating to the window manager that the size/position of
7659 * the window was user-specified. This causes most window
7660 * managers to honor the geometry.
7662 * Note that for gtk_window_parse_geometry() to work as expected, it has
7663 * to be called when the window has its "final" size, i.e. after calling
7664 * gtk_widget_show_all() on the contents and gtk_window_set_geometry_hints()
7667 * <informalexample><programlisting>
7668 * #include <gtk/gtk.h>
7671 * fill_with_content (GtkWidget *vbox)
7673 * /<!-- -->* fill with content... *<!-- -->/
7677 * main (int argc, char *argv[])
7679 * GtkWidget *window, *vbox;
7680 * GdkGeometry size_hints = {
7681 * 100, 50, 0, 0, 100, 50, 10, 10, 0.0, 0.0, GDK_GRAVITY_NORTH_WEST
7684 * gtk_init (&argc, &argv);
7686 * window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
7687 * vbox = gtk_vbox_new (FALSE, 0);
7689 * gtk_container_add (GTK_CONTAINER (window), vbox);
7690 * fill_with_content (vbox);
7691 * gtk_widget_show_all (vbox);
7693 * gtk_window_set_geometry_hints (GTK_WINDOW (window),
7696 * GDK_HINT_MIN_SIZE |
7697 * GDK_HINT_BASE_SIZE |
7698 * GDK_HINT_RESIZE_INC);
7702 * if (!gtk_window_parse_geometry (GTK_WINDOW (window), argv[1]))
7703 * fprintf (stderr, "Failed to parse '%s'\n", argv[1]);
7706 * gtk_widget_show_all (window);
7711 * </programlisting></informalexample>
7713 * Return value: %TRUE if string was parsed successfully
7716 gtk_window_parse_geometry (GtkWindow *window,
7717 const gchar *geometry)
7719 gint result, x = 0, y = 0;
7722 gboolean size_set, pos_set;
7725 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
7726 g_return_val_if_fail (geometry != NULL, FALSE);
7728 screen = gtk_window_check_screen (window);
7730 result = gtk_XParseGeometry (geometry, &x, &y, &w, &h);
7733 if ((result & WidthValue) || (result & HeightValue))
7735 gtk_window_set_default_size_internal (window,
7736 TRUE, result & WidthValue ? w : -1,
7737 TRUE, result & HeightValue ? h : -1,
7742 gtk_window_get_size (window, (gint *)&w, (gint *)&h);
7744 grav = GDK_GRAVITY_NORTH_WEST;
7746 if ((result & XNegative) && (result & YNegative))
7747 grav = GDK_GRAVITY_SOUTH_EAST;
7748 else if (result & XNegative)
7749 grav = GDK_GRAVITY_NORTH_EAST;
7750 else if (result & YNegative)
7751 grav = GDK_GRAVITY_SOUTH_WEST;
7753 if ((result & XValue) == 0)
7756 if ((result & YValue) == 0)
7759 if (grav == GDK_GRAVITY_SOUTH_WEST ||
7760 grav == GDK_GRAVITY_SOUTH_EAST)
7761 y = gdk_screen_get_height (screen) - h + y;
7763 if (grav == GDK_GRAVITY_SOUTH_EAST ||
7764 grav == GDK_GRAVITY_NORTH_EAST)
7765 x = gdk_screen_get_width (screen) - w + x;
7767 /* we don't let you put a window offscreen; maybe some people would
7768 * prefer to be able to, but it's kind of a bogus thing to do.
7777 if ((result & XValue) || (result & YValue))
7779 gtk_window_set_gravity (window, grav);
7780 gtk_window_move (window, x, y);
7784 if (size_set || pos_set)
7786 /* Set USSize, USPosition hints */
7787 GtkWindowGeometryInfo *info;
7789 info = gtk_window_get_geometry_info (window, TRUE);
7792 info->mask |= GDK_HINT_USER_POS;
7794 info->mask |= GDK_HINT_USER_SIZE;
7801 gtk_window_mnemonic_hash_foreach (guint keyval,
7807 GtkWindowKeysForeachFunc func;
7811 (*info->func) (info->window, keyval, info->window->mnemonic_modifier, TRUE, info->func_data);
7815 _gtk_window_keys_foreach (GtkWindow *window,
7816 GtkWindowKeysForeachFunc func,
7820 GtkMnemonicHash *mnemonic_hash;
7824 GtkWindowKeysForeachFunc func;
7828 info.window = window;
7830 info.func_data = func_data;
7832 mnemonic_hash = gtk_window_get_mnemonic_hash (window, FALSE);
7834 _gtk_mnemonic_hash_foreach (mnemonic_hash,
7835 gtk_window_mnemonic_hash_foreach, &info);
7837 groups = gtk_accel_groups_from_object (G_OBJECT (window));
7840 GtkAccelGroup *group = groups->data;
7843 for (i = 0; i < group->n_accels; i++)
7845 GtkAccelKey *key = &group->priv_accels[i].key;
7848 (*func) (window, key->accel_key, key->accel_mods, FALSE, func_data);
7851 groups = groups->next;
7856 gtk_window_keys_changed (GtkWindow *window)
7858 gtk_window_free_key_hash (window);
7859 gtk_window_get_key_hash (window);
7862 typedef struct _GtkWindowKeyEntry GtkWindowKeyEntry;
7864 struct _GtkWindowKeyEntry
7868 guint is_mnemonic : 1;
7872 window_key_entry_destroy (gpointer data)
7874 g_slice_free (GtkWindowKeyEntry, data);
7878 add_to_key_hash (GtkWindow *window,
7880 GdkModifierType modifiers,
7881 gboolean is_mnemonic,
7884 GtkKeyHash *key_hash = data;
7886 GtkWindowKeyEntry *entry = g_slice_new (GtkWindowKeyEntry);
7888 entry->keyval = keyval;
7889 entry->modifiers = modifiers;
7890 entry->is_mnemonic = is_mnemonic;
7892 /* GtkAccelGroup stores lowercased accelerators. To deal
7893 * with this, if <Shift> was specified, uppercase.
7895 if (modifiers & GDK_SHIFT_MASK)
7897 if (keyval == GDK_Tab)
7898 keyval = GDK_ISO_Left_Tab;
7900 keyval = gdk_keyval_to_upper (keyval);
7903 _gtk_key_hash_add_entry (key_hash, keyval, entry->modifiers, entry);
7907 gtk_window_get_key_hash (GtkWindow *window)
7909 GdkScreen *screen = gtk_window_check_screen (window);
7910 GtkKeyHash *key_hash = g_object_get_qdata (G_OBJECT (window), quark_gtk_window_key_hash);
7915 key_hash = _gtk_key_hash_new (gdk_keymap_get_for_display (gdk_screen_get_display (screen)),
7916 (GDestroyNotify)window_key_entry_destroy);
7917 _gtk_window_keys_foreach (window, add_to_key_hash, key_hash);
7918 g_object_set_qdata (G_OBJECT (window), quark_gtk_window_key_hash, key_hash);
7924 gtk_window_free_key_hash (GtkWindow *window)
7926 GtkKeyHash *key_hash = g_object_get_qdata (G_OBJECT (window), quark_gtk_window_key_hash);
7929 _gtk_key_hash_free (key_hash);
7930 g_object_set_qdata (G_OBJECT (window), quark_gtk_window_key_hash, NULL);
7935 * gtk_window_activate_key:
7936 * @window: a #GtkWindow
7937 * @event: a #GdkEventKey
7939 * Activates mnemonics and accelerators for this #GtkWindow. This is normally
7940 * called by the default ::key_press_event handler for toplevel windows,
7941 * however in some cases it may be useful to call this directly when
7942 * overriding the standard key handling for a toplevel window.
7944 * Return value: %TRUE if a mnemonic or accelerator was found and activated.
7947 gtk_window_activate_key (GtkWindow *window,
7950 GtkKeyHash *key_hash = g_object_get_qdata (G_OBJECT (window), quark_gtk_window_key_hash);
7951 GtkWindowKeyEntry *found_entry = NULL;
7955 gtk_window_keys_changed (window);
7956 key_hash = g_object_get_qdata (G_OBJECT (window), quark_gtk_window_key_hash);
7961 GSList *entries = _gtk_key_hash_lookup (key_hash,
7962 event->hardware_keycode,
7964 gtk_accelerator_get_default_mod_mask (),
7968 for (tmp_list = entries; tmp_list; tmp_list = tmp_list->next)
7970 GtkWindowKeyEntry *entry = tmp_list->data;
7971 if (entry->is_mnemonic)
7973 found_entry = entry;
7978 if (!found_entry && entries)
7979 found_entry = entries->data;
7981 g_slist_free (entries);
7986 gboolean enable_mnemonics;
7987 gboolean enable_accels;
7989 g_object_get (gtk_widget_get_settings (GTK_WIDGET (window)),
7990 "gtk-enable-mnemonics", &enable_mnemonics,
7991 "gtk-enable-accels", &enable_accels,
7994 if (found_entry->is_mnemonic)
7996 if (enable_mnemonics)
7997 return gtk_window_mnemonic_activate (window, found_entry->keyval,
7998 found_entry->modifiers);
8003 return gtk_accel_groups_activate (G_OBJECT (window), found_entry->keyval,
8004 found_entry->modifiers);
8012 window_update_has_focus (GtkWindow *window)
8014 GtkWidget *widget = GTK_WIDGET (window);
8015 gboolean has_focus = window->has_toplevel_focus && window->is_active;
8017 if (has_focus != window->has_focus)
8019 window->has_focus = has_focus;
8023 if (window->focus_widget &&
8024 window->focus_widget != widget &&
8025 !GTK_WIDGET_HAS_FOCUS (window->focus_widget))
8026 do_focus_change (window->focus_widget, TRUE);
8030 if (window->focus_widget &&
8031 window->focus_widget != widget &&
8032 GTK_WIDGET_HAS_FOCUS (window->focus_widget))
8033 do_focus_change (window->focus_widget, FALSE);
8039 * _gtk_window_set_is_active:
8040 * @window: a #GtkWindow
8041 * @is_active: %TRUE if the window is in the currently active toplevel
8043 * Internal function that sets whether the #GtkWindow is part
8044 * of the currently active toplevel window (taking into account inter-process
8048 _gtk_window_set_is_active (GtkWindow *window,
8051 g_return_if_fail (GTK_IS_WINDOW (window));
8053 is_active = is_active != FALSE;
8055 if (is_active != window->is_active)
8057 window->is_active = is_active;
8058 window_update_has_focus (window);
8060 g_object_notify (G_OBJECT (window), "is-active");
8065 * _gtk_window_set_has_toplevel_focus:
8066 * @window: a #GtkWindow
8067 * @has_toplevel_focus: %TRUE if the in
8069 * Internal function that sets whether the keyboard focus for the
8070 * toplevel window (taking into account inter-process embedding.)
8073 _gtk_window_set_has_toplevel_focus (GtkWindow *window,
8074 gboolean has_toplevel_focus)
8076 g_return_if_fail (GTK_IS_WINDOW (window));
8078 has_toplevel_focus = has_toplevel_focus != FALSE;
8080 if (has_toplevel_focus != window->has_toplevel_focus)
8082 window->has_toplevel_focus = has_toplevel_focus;
8083 window_update_has_focus (window);
8085 g_object_notify (G_OBJECT (window), "has-toplevel-focus");
8090 * gtk_window_set_auto_startup_notification:
8091 * @setting: %TRUE to automatically do startup notification
8093 * By default, after showing the first #GtkWindow, GTK+ calls
8094 * gdk_notify_startup_complete(). Call this function to disable
8095 * the automatic startup notification. You might do this if your
8096 * first window is a splash screen, and you want to delay notification
8097 * until after your real main window has been shown, for example.
8099 * In that example, you would disable startup notification
8100 * temporarily, show your splash screen, then re-enable it so that
8101 * showing the main window would automatically result in notification.
8106 gtk_window_set_auto_startup_notification (gboolean setting)
8108 disable_startup_notification = !setting;
8113 #undef gtk_window_set_icon_from_file
8116 gtk_window_set_icon_from_file (GtkWindow *window,
8117 const gchar *filename,
8120 gchar *utf8_filename = g_locale_to_utf8 (filename, -1, NULL, NULL, err);
8123 if (utf8_filename == NULL)
8126 retval = gtk_window_set_icon_from_file_utf8 (window, utf8_filename, err);
8128 g_free (utf8_filename);
8133 #undef gtk_window_set_default_icon_from_file
8136 gtk_window_set_default_icon_from_file (const gchar *filename,
8139 gchar *utf8_filename = g_locale_to_utf8 (filename, -1, NULL, NULL, err);
8142 if (utf8_filename == NULL)
8145 retval = gtk_window_set_default_icon_from_file_utf8 (utf8_filename, err);
8147 g_free (utf8_filename);
8154 #define __GTK_WINDOW_C__
8155 #include "gtkaliasdef.c"