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));
1013 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1019 gtk_window_get_property (GObject *object,
1025 GtkWindowPrivate *priv;
1027 window = GTK_WINDOW (object);
1028 priv = GTK_WINDOW_GET_PRIVATE (window);
1032 GtkWindowGeometryInfo *info;
1034 g_value_set_enum (value, window->type);
1037 g_value_set_string (value, window->wm_role);
1040 g_value_set_string (value, window->title);
1042 case PROP_ALLOW_SHRINK:
1043 g_value_set_boolean (value, window->allow_shrink);
1045 case PROP_ALLOW_GROW:
1046 g_value_set_boolean (value, window->allow_grow);
1048 case PROP_RESIZABLE:
1049 g_value_set_boolean (value, window->allow_grow);
1052 g_value_set_boolean (value, window->modal);
1055 g_value_set_enum (value, window->position);
1057 case PROP_DEFAULT_WIDTH:
1058 info = gtk_window_get_geometry_info (window, FALSE);
1060 g_value_set_int (value, -1);
1062 g_value_set_int (value, info->default_width);
1064 case PROP_DEFAULT_HEIGHT:
1065 info = gtk_window_get_geometry_info (window, FALSE);
1067 g_value_set_int (value, -1);
1069 g_value_set_int (value, info->default_height);
1071 case PROP_DESTROY_WITH_PARENT:
1072 g_value_set_boolean (value, window->destroy_with_parent);
1075 g_value_set_object (value, gtk_window_get_icon (window));
1077 case PROP_ICON_NAME:
1078 g_value_set_string (value, gtk_window_get_icon_name (window));
1081 g_value_set_object (value, window->screen);
1083 case PROP_IS_ACTIVE:
1084 g_value_set_boolean (value, window->is_active);
1086 case PROP_HAS_TOPLEVEL_FOCUS:
1087 g_value_set_boolean (value, window->has_toplevel_focus);
1089 case PROP_TYPE_HINT:
1090 g_value_set_enum (value, priv->type_hint);
1092 case PROP_SKIP_TASKBAR_HINT:
1093 g_value_set_boolean (value,
1094 gtk_window_get_skip_taskbar_hint (window));
1096 case PROP_SKIP_PAGER_HINT:
1097 g_value_set_boolean (value,
1098 gtk_window_get_skip_pager_hint (window));
1100 case PROP_URGENCY_HINT:
1101 g_value_set_boolean (value,
1102 gtk_window_get_urgency_hint (window));
1104 case PROP_ACCEPT_FOCUS:
1105 g_value_set_boolean (value,
1106 gtk_window_get_accept_focus (window));
1108 case PROP_FOCUS_ON_MAP:
1109 g_value_set_boolean (value,
1110 gtk_window_get_focus_on_map (window));
1112 case PROP_DECORATED:
1113 g_value_set_boolean (value, gtk_window_get_decorated (window));
1115 case PROP_DELETABLE:
1116 g_value_set_boolean (value, gtk_window_get_deletable (window));
1119 g_value_set_enum (value, gtk_window_get_gravity (window));
1121 case PROP_TRANSIENT_FOR:
1122 g_value_set_object (value, gtk_window_get_transient_for (window));
1125 g_value_set_double (value, gtk_window_get_opacity (window));
1128 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1134 gtk_window_buildable_interface_init (GtkBuildableIface *iface)
1136 parent_buildable_iface = g_type_interface_peek_parent (iface);
1137 iface->set_buildable_property = gtk_window_buildable_set_buildable_property;
1138 iface->parser_finished = gtk_window_buildable_parser_finished;
1143 gtk_window_buildable_set_buildable_property (GtkBuildable *buildable,
1144 GtkBuilder *builder,
1146 const GValue *value)
1148 GtkWindowPrivate *priv = GTK_WINDOW_GET_PRIVATE (buildable);
1150 if (strcmp (name, "visible") == 0 && g_value_get_boolean (value))
1151 priv->builder_visible = TRUE;
1153 parent_buildable_iface->set_buildable_property (buildable, builder, name, value);
1157 gtk_window_buildable_parser_finished (GtkBuildable *buildable,
1158 GtkBuilder *builder)
1160 GtkWindowPrivate *priv = GTK_WINDOW_GET_PRIVATE (buildable);
1162 if (priv->builder_visible)
1163 gtk_widget_show (GTK_WIDGET (buildable));
1168 * @type: type of window
1170 * Creates a new #GtkWindow, which is a toplevel window that can
1171 * contain other widgets. Nearly always, the type of the window should
1172 * be #GTK_WINDOW_TOPLEVEL. If you're implementing something like a
1173 * popup menu from scratch (which is a bad idea, just use #GtkMenu),
1174 * you might use #GTK_WINDOW_POPUP. #GTK_WINDOW_POPUP is not for
1175 * dialogs, though in some other toolkits dialogs are called "popups".
1176 * In GTK+, #GTK_WINDOW_POPUP means a pop-up menu or pop-up tooltip.
1177 * On X11, popup windows are not controlled by the <link
1178 * linkend="gtk-X11-arch">window manager</link>.
1180 * If you simply want an undecorated window (no window borders), use
1181 * gtk_window_set_decorated(), don't use #GTK_WINDOW_POPUP.
1183 * Return value: a new #GtkWindow.
1186 gtk_window_new (GtkWindowType type)
1190 g_return_val_if_fail (type >= GTK_WINDOW_TOPLEVEL && type <= GTK_WINDOW_POPUP, NULL);
1192 window = g_object_new (GTK_TYPE_WINDOW, NULL);
1194 window->type = type;
1196 return GTK_WIDGET (window);
1200 * gtk_window_set_title:
1201 * @window: a #GtkWindow
1202 * @title: title of the window
1204 * Sets the title of the #GtkWindow. The title of a window will be
1205 * displayed in its title bar; on the X Window System, the title bar
1206 * is rendered by the <link linkend="gtk-X11-arch">window
1207 * manager</link>, so exactly how the title appears to users may vary
1208 * according to a user's exact configuration. The title should help a
1209 * user distinguish this window from other windows they may have
1210 * open. A good title might include the application name and current
1211 * document filename, for example.
1215 gtk_window_set_title (GtkWindow *window,
1220 g_return_if_fail (GTK_IS_WINDOW (window));
1222 new_title = g_strdup (title);
1223 g_free (window->title);
1224 window->title = new_title;
1226 if (GTK_WIDGET_REALIZED (window))
1228 gdk_window_set_title (GTK_WIDGET (window)->window, window->title);
1230 gtk_decorated_window_set_title (window, title);
1233 g_object_notify (G_OBJECT (window), "title");
1237 * gtk_window_get_title:
1238 * @window: a #GtkWindow
1240 * Retrieves the title of the window. See gtk_window_set_title().
1242 * Return value: the title of the window, or %NULL if none has
1243 * been set explicitely. The returned string is owned by the widget
1244 * and must not be modified or freed.
1246 G_CONST_RETURN gchar *
1247 gtk_window_get_title (GtkWindow *window)
1249 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
1251 return window->title;
1255 * gtk_window_set_wmclass:
1256 * @window: a #GtkWindow
1257 * @wmclass_name: window name hint
1258 * @wmclass_class: window class hint
1260 * Don't use this function. It sets the X Window System "class" and
1261 * "name" hints for a window. According to the ICCCM, you should
1262 * always set these to the same value for all windows in an
1263 * application, and GTK+ sets them to that value by default, so calling
1264 * this function is sort of pointless. However, you may want to call
1265 * gtk_window_set_role() on each window in your application, for the
1266 * benefit of the session manager. Setting the role allows the window
1267 * manager to restore window positions when loading a saved session.
1271 gtk_window_set_wmclass (GtkWindow *window,
1272 const gchar *wmclass_name,
1273 const gchar *wmclass_class)
1275 g_return_if_fail (GTK_IS_WINDOW (window));
1277 g_free (window->wmclass_name);
1278 window->wmclass_name = g_strdup (wmclass_name);
1280 g_free (window->wmclass_class);
1281 window->wmclass_class = g_strdup (wmclass_class);
1283 if (GTK_WIDGET_REALIZED (window))
1284 g_warning ("gtk_window_set_wmclass: shouldn't set wmclass after window is realized!\n");
1288 * gtk_window_set_role:
1289 * @window: a #GtkWindow
1290 * @role: unique identifier for the window to be used when restoring a session
1292 * This function is only useful on X11, not with other GTK+ targets.
1294 * In combination with the window title, the window role allows a
1295 * <link linkend="gtk-X11-arch">window manager</link> to identify "the
1296 * same" window when an application is restarted. So for example you
1297 * might set the "toolbox" role on your app's toolbox window, so that
1298 * when the user restarts their session, the window manager can put
1299 * the toolbox back in the same place.
1301 * If a window already has a unique title, you don't need to set the
1302 * role, since the WM can use the title to identify the window when
1303 * restoring the session.
1307 gtk_window_set_role (GtkWindow *window,
1312 g_return_if_fail (GTK_IS_WINDOW (window));
1314 new_role = g_strdup (role);
1315 g_free (window->wm_role);
1316 window->wm_role = new_role;
1318 if (GTK_WIDGET_REALIZED (window))
1319 gdk_window_set_role (GTK_WIDGET (window)->window, window->wm_role);
1321 g_object_notify (G_OBJECT (window), "role");
1325 * gtk_window_set_startup_id:
1326 * @window: a #GtkWindow
1327 * @startup_id: a string with startup-notification identifier
1329 * Startup notification identifiers are used by desktop environment to
1330 * track application startup, to provide user feedback and other
1331 * features. This function changes the corresponding property on the
1332 * underlying GdkWindow. Normally, startup identifier is managed
1333 * automatically and you should only use this function in special cases
1334 * like transferring focus from other processes. You should use this
1335 * function before calling gtk_window_present() or any equivalent
1336 * function generating a window map event.
1338 * This function is only useful on X11, not with other GTK+ targets.
1343 gtk_window_set_startup_id (GtkWindow *window,
1344 const gchar *startup_id)
1346 GtkWindowPrivate *priv = GTK_WINDOW_GET_PRIVATE (window);
1348 g_return_if_fail (GTK_IS_WINDOW (window));
1350 g_free (priv->startup_id);
1351 priv->startup_id = g_strdup (startup_id);
1353 if (GTK_WIDGET_REALIZED (window))
1355 /* Here we differentiate real and "fake" startup notification IDs,
1356 * constructed on purpose just to pass interaction timestamp
1358 if (startup_id_is_fake (priv->startup_id))
1360 guint32 timestamp = extract_time_from_startup_id (priv->startup_id);
1362 gtk_window_present_with_time (window, timestamp);
1366 gdk_window_set_startup_id (GTK_WIDGET (window)->window,
1369 /* If window is mapped, terminate the startup-notification too */
1370 if (GTK_WIDGET_MAPPED (window) && !disable_startup_notification)
1371 gdk_notify_startup_complete_with_id (priv->startup_id);
1375 g_object_notify (G_OBJECT (window), "startup-id");
1379 * gtk_window_get_role:
1380 * @window: a #GtkWindow
1382 * Returns the role of the window. See gtk_window_set_role() for
1383 * further explanation.
1385 * Return value: the role of the window if set, or %NULL. The
1386 * returned is owned by the widget and must not be modified
1389 G_CONST_RETURN gchar *
1390 gtk_window_get_role (GtkWindow *window)
1392 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
1394 return window->wm_role;
1398 * gtk_window_set_focus:
1399 * @window: a #GtkWindow
1400 * @focus: widget to be the new focus widget, or %NULL to unset
1401 * any focus widget for the toplevel window.
1403 * If @focus is not the current focus widget, and is focusable, sets
1404 * it as the focus widget for the window. If @focus is %NULL, unsets
1405 * the focus widget for this window. To set the focus to a particular
1406 * widget in the toplevel, it is usually more convenient to use
1407 * gtk_widget_grab_focus() instead of this function.
1410 gtk_window_set_focus (GtkWindow *window,
1413 g_return_if_fail (GTK_IS_WINDOW (window));
1416 g_return_if_fail (GTK_IS_WIDGET (focus));
1417 g_return_if_fail (GTK_WIDGET_CAN_FOCUS (focus));
1421 gtk_widget_grab_focus (focus);
1424 /* Clear the existing focus chain, so that when we focus into
1425 * the window again, we start at the beginnning.
1427 GtkWidget *widget = window->focus_widget;
1430 while (widget->parent)
1432 widget = widget->parent;
1433 gtk_container_set_focus_child (GTK_CONTAINER (widget), NULL);
1437 _gtk_window_internal_set_focus (window, NULL);
1442 _gtk_window_internal_set_focus (GtkWindow *window,
1445 g_return_if_fail (GTK_IS_WINDOW (window));
1447 if ((window->focus_widget != focus) ||
1448 (focus && !GTK_WIDGET_HAS_FOCUS (focus)))
1449 g_signal_emit (window, window_signals[SET_FOCUS], 0, focus);
1453 * gtk_window_set_default:
1454 * @window: a #GtkWindow
1455 * @default_widget: widget to be the default, or %NULL to unset the
1456 * default widget for the toplevel.
1458 * The default widget is the widget that's activated when the user
1459 * presses Enter in a dialog (for example). This function sets or
1460 * unsets the default widget for a #GtkWindow about. When setting
1461 * (rather than unsetting) the default widget it's generally easier to
1462 * call gtk_widget_grab_focus() on the widget. Before making a widget
1463 * the default widget, you must set the #GTK_CAN_DEFAULT flag on the
1464 * widget you'd like to make the default using GTK_WIDGET_SET_FLAGS().
1467 gtk_window_set_default (GtkWindow *window,
1468 GtkWidget *default_widget)
1470 g_return_if_fail (GTK_IS_WINDOW (window));
1473 g_return_if_fail (GTK_WIDGET_CAN_DEFAULT (default_widget));
1475 if (window->default_widget != default_widget)
1477 GtkWidget *old_default_widget = NULL;
1480 g_object_ref (default_widget);
1482 if (window->default_widget)
1484 old_default_widget = window->default_widget;
1486 if (window->focus_widget != window->default_widget ||
1487 !GTK_WIDGET_RECEIVES_DEFAULT (window->default_widget))
1488 GTK_WIDGET_UNSET_FLAGS (window->default_widget, GTK_HAS_DEFAULT);
1489 gtk_widget_queue_draw (window->default_widget);
1492 window->default_widget = default_widget;
1494 if (window->default_widget)
1496 if (window->focus_widget == NULL ||
1497 !GTK_WIDGET_RECEIVES_DEFAULT (window->focus_widget))
1498 GTK_WIDGET_SET_FLAGS (window->default_widget, GTK_HAS_DEFAULT);
1499 gtk_widget_queue_draw (window->default_widget);
1502 if (old_default_widget)
1503 g_object_notify (G_OBJECT (old_default_widget), "has-default");
1507 g_object_notify (G_OBJECT (default_widget), "has-default");
1508 g_object_unref (default_widget);
1514 gtk_window_set_policy (GtkWindow *window,
1515 gboolean allow_shrink,
1516 gboolean allow_grow,
1517 gboolean auto_shrink)
1519 g_return_if_fail (GTK_IS_WINDOW (window));
1521 window->allow_shrink = (allow_shrink != FALSE);
1522 window->allow_grow = (allow_grow != FALSE);
1524 g_object_freeze_notify (G_OBJECT (window));
1525 g_object_notify (G_OBJECT (window), "allow-shrink");
1526 g_object_notify (G_OBJECT (window), "allow-grow");
1527 g_object_notify (G_OBJECT (window), "resizable");
1528 g_object_thaw_notify (G_OBJECT (window));
1530 gtk_widget_queue_resize (GTK_WIDGET (window));
1534 handle_keys_changed (gpointer data)
1538 window = GTK_WINDOW (data);
1540 if (window->keys_changed_handler)
1542 g_source_remove (window->keys_changed_handler);
1543 window->keys_changed_handler = 0;
1546 g_signal_emit (window, window_signals[KEYS_CHANGED], 0);
1552 gtk_window_notify_keys_changed (GtkWindow *window)
1554 if (!window->keys_changed_handler)
1555 window->keys_changed_handler = gdk_threads_add_idle (handle_keys_changed, window);
1559 * gtk_window_add_accel_group:
1560 * @window: window to attach accelerator group to
1561 * @accel_group: a #GtkAccelGroup
1563 * Associate @accel_group with @window, such that calling
1564 * gtk_accel_groups_activate() on @window will activate accelerators
1568 gtk_window_add_accel_group (GtkWindow *window,
1569 GtkAccelGroup *accel_group)
1571 g_return_if_fail (GTK_IS_WINDOW (window));
1572 g_return_if_fail (GTK_IS_ACCEL_GROUP (accel_group));
1574 _gtk_accel_group_attach (accel_group, G_OBJECT (window));
1575 g_signal_connect_object (accel_group, "accel_changed",
1576 G_CALLBACK (gtk_window_notify_keys_changed),
1577 window, G_CONNECT_SWAPPED);
1578 gtk_window_notify_keys_changed (window);
1582 * gtk_window_remove_accel_group:
1583 * @window: a #GtkWindow
1584 * @accel_group: a #GtkAccelGroup
1586 * Reverses the effects of gtk_window_add_accel_group().
1589 gtk_window_remove_accel_group (GtkWindow *window,
1590 GtkAccelGroup *accel_group)
1592 g_return_if_fail (GTK_IS_WINDOW (window));
1593 g_return_if_fail (GTK_IS_ACCEL_GROUP (accel_group));
1595 g_signal_handlers_disconnect_by_func (accel_group,
1596 gtk_window_notify_keys_changed,
1598 _gtk_accel_group_detach (accel_group, G_OBJECT (window));
1599 gtk_window_notify_keys_changed (window);
1602 static GtkMnemonicHash *
1603 gtk_window_get_mnemonic_hash (GtkWindow *window,
1606 GtkWindowPrivate *private = GTK_WINDOW_GET_PRIVATE (window);
1607 if (!private->mnemonic_hash && create)
1608 private->mnemonic_hash = _gtk_mnemonic_hash_new ();
1610 return private->mnemonic_hash;
1614 * gtk_window_add_mnemonic:
1615 * @window: a #GtkWindow
1616 * @keyval: the mnemonic
1617 * @target: the widget that gets activated by the mnemonic
1619 * Adds a mnemonic to this window.
1622 gtk_window_add_mnemonic (GtkWindow *window,
1626 g_return_if_fail (GTK_IS_WINDOW (window));
1627 g_return_if_fail (GTK_IS_WIDGET (target));
1629 _gtk_mnemonic_hash_add (gtk_window_get_mnemonic_hash (window, TRUE),
1631 gtk_window_notify_keys_changed (window);
1635 * gtk_window_remove_mnemonic:
1636 * @window: a #GtkWindow
1637 * @keyval: the mnemonic
1638 * @target: the widget that gets activated by the mnemonic
1640 * Removes a mnemonic from this window.
1643 gtk_window_remove_mnemonic (GtkWindow *window,
1647 g_return_if_fail (GTK_IS_WINDOW (window));
1648 g_return_if_fail (GTK_IS_WIDGET (target));
1650 _gtk_mnemonic_hash_remove (gtk_window_get_mnemonic_hash (window, TRUE),
1652 gtk_window_notify_keys_changed (window);
1656 * gtk_window_mnemonic_activate:
1657 * @window: a #GtkWindow
1658 * @keyval: the mnemonic
1659 * @modifier: the modifiers
1660 * @returns: %TRUE if the activation is done.
1662 * Activates the targets associated with the mnemonic.
1665 gtk_window_mnemonic_activate (GtkWindow *window,
1667 GdkModifierType modifier)
1669 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
1671 if (window->mnemonic_modifier == (modifier & gtk_accelerator_get_default_mod_mask ()))
1673 GtkMnemonicHash *mnemonic_hash = gtk_window_get_mnemonic_hash (window, FALSE);
1675 return _gtk_mnemonic_hash_activate (mnemonic_hash, keyval);
1682 * gtk_window_set_mnemonic_modifier:
1683 * @window: a #GtkWindow
1684 * @modifier: the modifier mask used to activate
1685 * mnemonics on this window.
1687 * Sets the mnemonic modifier for this window.
1690 gtk_window_set_mnemonic_modifier (GtkWindow *window,
1691 GdkModifierType modifier)
1693 g_return_if_fail (GTK_IS_WINDOW (window));
1694 g_return_if_fail ((modifier & ~GDK_MODIFIER_MASK) == 0);
1696 window->mnemonic_modifier = modifier;
1697 gtk_window_notify_keys_changed (window);
1701 * gtk_window_get_mnemonic_modifier:
1702 * @window: a #GtkWindow
1704 * Returns the mnemonic modifier for this window. See
1705 * gtk_window_set_mnemonic_modifier().
1707 * Return value: the modifier mask used to activate
1708 * mnemonics on this window.
1711 gtk_window_get_mnemonic_modifier (GtkWindow *window)
1713 g_return_val_if_fail (GTK_IS_WINDOW (window), 0);
1715 return window->mnemonic_modifier;
1719 * gtk_window_set_position:
1720 * @window: a #GtkWindow.
1721 * @position: a position constraint.
1723 * Sets a position constraint for this window. If the old or new
1724 * constraint is %GTK_WIN_POS_CENTER_ALWAYS, this will also cause
1725 * the window to be repositioned to satisfy the new constraint.
1728 gtk_window_set_position (GtkWindow *window,
1729 GtkWindowPosition position)
1731 g_return_if_fail (GTK_IS_WINDOW (window));
1733 if (position == GTK_WIN_POS_CENTER_ALWAYS ||
1734 window->position == GTK_WIN_POS_CENTER_ALWAYS)
1736 GtkWindowGeometryInfo *info;
1738 info = gtk_window_get_geometry_info (window, TRUE);
1740 /* this flag causes us to re-request the CENTER_ALWAYS
1741 * constraint in gtk_window_move_resize(), see
1742 * comment in that function.
1744 info->position_constraints_changed = TRUE;
1746 gtk_widget_queue_resize (GTK_WIDGET (window));
1749 window->position = position;
1751 g_object_notify (G_OBJECT (window), "window-position");
1755 * gtk_window_activate_focus:
1756 * @window: a #GtkWindow
1758 * Activates the current focused widget within the window.
1760 * Return value: %TRUE if a widget got activated.
1763 gtk_window_activate_focus (GtkWindow *window)
1765 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
1767 if (window->focus_widget && GTK_WIDGET_IS_SENSITIVE (window->focus_widget))
1768 return gtk_widget_activate (window->focus_widget);
1774 * gtk_window_get_focus:
1775 * @window: a #GtkWindow
1777 * Retrieves the current focused widget within the window.
1778 * Note that this is the widget that would have the focus
1779 * if the toplevel window focused; if the toplevel window
1780 * is not focused then <literal>GTK_WIDGET_HAS_FOCUS (widget)</literal> will
1781 * not be %TRUE for the widget.
1783 * Return value: the currently focused widget, or %NULL if there is none.
1786 gtk_window_get_focus (GtkWindow *window)
1788 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
1790 return window->focus_widget;
1794 * gtk_window_activate_default:
1795 * @window: a #GtkWindow
1797 * Activates the default widget for the window, unless the current
1798 * focused widget has been configured to receive the default action
1799 * (see #GTK_RECEIVES_DEFAULT in #GtkWidgetFlags), in which case the
1800 * focused widget is activated.
1802 * Return value: %TRUE if a widget got activated.
1805 gtk_window_activate_default (GtkWindow *window)
1807 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
1809 if (window->default_widget && GTK_WIDGET_IS_SENSITIVE (window->default_widget) &&
1810 (!window->focus_widget || !GTK_WIDGET_RECEIVES_DEFAULT (window->focus_widget)))
1811 return gtk_widget_activate (window->default_widget);
1812 else if (window->focus_widget && GTK_WIDGET_IS_SENSITIVE (window->focus_widget))
1813 return gtk_widget_activate (window->focus_widget);
1819 * gtk_window_set_modal:
1820 * @window: a #GtkWindow
1821 * @modal: whether the window is modal
1823 * Sets a window modal or non-modal. Modal windows prevent interaction
1824 * with other windows in the same application. To keep modal dialogs
1825 * on top of main application windows, use
1826 * gtk_window_set_transient_for() to make the dialog transient for the
1827 * parent; most <link linkend="gtk-X11-arch">window managers</link>
1828 * will then disallow lowering the dialog below the parent.
1833 gtk_window_set_modal (GtkWindow *window,
1836 g_return_if_fail (GTK_IS_WINDOW (window));
1838 modal = modal != FALSE;
1839 if (window->modal == modal)
1842 window->modal = modal;
1844 /* adjust desired modality state */
1845 if (GTK_WIDGET_REALIZED (window))
1847 GtkWidget *widget = GTK_WIDGET (window);
1850 gdk_window_set_modal_hint (widget->window, TRUE);
1852 gdk_window_set_modal_hint (widget->window, FALSE);
1855 if (GTK_WIDGET_VISIBLE (window))
1858 gtk_grab_add (GTK_WIDGET (window));
1860 gtk_grab_remove (GTK_WIDGET (window));
1863 g_object_notify (G_OBJECT (window), "modal");
1867 * gtk_window_get_modal:
1868 * @window: a #GtkWindow
1870 * Returns whether the window is modal. See gtk_window_set_modal().
1872 * Return value: %TRUE if the window is set to be modal and
1873 * establishes a grab when shown
1876 gtk_window_get_modal (GtkWindow *window)
1878 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
1880 return window->modal;
1884 * gtk_window_list_toplevels:
1886 * Returns a list of all existing toplevel windows. The widgets
1887 * in the list are not individually referenced. If you want
1888 * to iterate through the list and perform actions involving
1889 * callbacks that might destroy the widgets, you <emphasis>must</emphasis> call
1890 * <literal>g_list_foreach (result, (GFunc)g_object_ref, NULL)</literal> first, and
1891 * then unref all the widgets afterwards.
1893 * Return value: list of toplevel widgets
1896 gtk_window_list_toplevels (void)
1901 for (slist = toplevel_list; slist; slist = slist->next)
1902 list = g_list_prepend (list, slist->data);
1908 gtk_window_add_embedded_xid (GtkWindow *window, guint xid)
1910 GList *embedded_windows;
1912 g_return_if_fail (GTK_IS_WINDOW (window));
1914 embedded_windows = g_object_get_qdata (G_OBJECT (window), quark_gtk_embedded);
1915 if (embedded_windows)
1916 g_object_steal_qdata (G_OBJECT (window), quark_gtk_embedded);
1917 embedded_windows = g_list_prepend (embedded_windows,
1918 GUINT_TO_POINTER (xid));
1920 g_object_set_qdata_full (G_OBJECT (window), quark_gtk_embedded,
1923 (GDestroyNotify) g_list_free : NULL);
1927 gtk_window_remove_embedded_xid (GtkWindow *window, guint xid)
1929 GList *embedded_windows;
1932 g_return_if_fail (GTK_IS_WINDOW (window));
1934 embedded_windows = g_object_get_qdata (G_OBJECT (window), quark_gtk_embedded);
1935 if (embedded_windows)
1936 g_object_steal_qdata (G_OBJECT (window), quark_gtk_embedded);
1938 node = g_list_find (embedded_windows, GUINT_TO_POINTER (xid));
1941 embedded_windows = g_list_remove_link (embedded_windows, node);
1942 g_list_free_1 (node);
1945 g_object_set_qdata_full (G_OBJECT (window), quark_gtk_embedded,
1948 (GDestroyNotify) g_list_free : NULL);
1952 _gtk_window_reposition (GtkWindow *window,
1956 g_return_if_fail (GTK_IS_WINDOW (window));
1958 gtk_window_move (window, x, y);
1962 gtk_window_dispose (GObject *object)
1964 GtkWindow *window = GTK_WINDOW (object);
1966 gtk_window_set_focus (window, NULL);
1967 gtk_window_set_default (window, NULL);
1969 G_OBJECT_CLASS (gtk_window_parent_class)->dispose (object);
1973 parent_destroyed_callback (GtkWindow *parent, GtkWindow *child)
1975 gtk_widget_destroy (GTK_WIDGET (child));
1979 connect_parent_destroyed (GtkWindow *window)
1981 if (window->transient_parent)
1983 g_signal_connect (window->transient_parent,
1985 G_CALLBACK (parent_destroyed_callback),
1991 disconnect_parent_destroyed (GtkWindow *window)
1993 if (window->transient_parent)
1995 g_signal_handlers_disconnect_by_func (window->transient_parent,
1996 parent_destroyed_callback,
2002 gtk_window_transient_parent_realized (GtkWidget *parent,
2005 if (GTK_WIDGET_REALIZED (window))
2006 gdk_window_set_transient_for (window->window, parent->window);
2010 gtk_window_transient_parent_unrealized (GtkWidget *parent,
2013 if (GTK_WIDGET_REALIZED (window))
2014 gdk_property_delete (window->window,
2015 gdk_atom_intern_static_string ("WM_TRANSIENT_FOR"));
2019 gtk_window_transient_parent_screen_changed (GtkWindow *parent,
2023 gtk_window_set_screen (window, parent->screen);
2027 gtk_window_unset_transient_for (GtkWindow *window)
2029 GtkWindowPrivate *priv = GTK_WINDOW_GET_PRIVATE (window);
2031 if (window->transient_parent)
2033 if (priv->transient_parent_group)
2034 gtk_window_group_remove_window (window->group,
2037 g_signal_handlers_disconnect_by_func (window->transient_parent,
2038 gtk_window_transient_parent_realized,
2040 g_signal_handlers_disconnect_by_func (window->transient_parent,
2041 gtk_window_transient_parent_unrealized,
2043 g_signal_handlers_disconnect_by_func (window->transient_parent,
2044 gtk_window_transient_parent_screen_changed,
2046 g_signal_handlers_disconnect_by_func (window->transient_parent,
2047 gtk_widget_destroyed,
2048 &window->transient_parent);
2050 if (window->destroy_with_parent)
2051 disconnect_parent_destroyed (window);
2053 window->transient_parent = NULL;
2054 priv->transient_parent_group = FALSE;
2059 * gtk_window_set_transient_for:
2060 * @window: a #GtkWindow
2061 * @parent: parent window
2063 * Dialog windows should be set transient for the main application
2064 * window they were spawned from. This allows <link
2065 * linkend="gtk-X11-arch">window managers</link> to e.g. keep the
2066 * dialog on top of the main window, or center the dialog over the
2067 * main window. gtk_dialog_new_with_buttons() and other convenience
2068 * functions in GTK+ will sometimes call
2069 * gtk_window_set_transient_for() on your behalf.
2071 * On Windows, this function puts the child window on top of the parent,
2072 * much as the window manager would have done on X.
2076 gtk_window_set_transient_for (GtkWindow *window,
2079 GtkWindowPrivate *priv = GTK_WINDOW_GET_PRIVATE (window);
2081 g_return_if_fail (GTK_IS_WINDOW (window));
2082 g_return_if_fail (parent == NULL || GTK_IS_WINDOW (parent));
2083 g_return_if_fail (window != parent);
2085 if (window->transient_parent)
2087 if (GTK_WIDGET_REALIZED (window) &&
2088 GTK_WIDGET_REALIZED (window->transient_parent) &&
2089 (!parent || !GTK_WIDGET_REALIZED (parent)))
2090 gtk_window_transient_parent_unrealized (GTK_WIDGET (window->transient_parent),
2091 GTK_WIDGET (window));
2093 gtk_window_unset_transient_for (window);
2096 window->transient_parent = parent;
2100 g_signal_connect (parent, "destroy",
2101 G_CALLBACK (gtk_widget_destroyed),
2102 &window->transient_parent);
2103 g_signal_connect (parent, "realize",
2104 G_CALLBACK (gtk_window_transient_parent_realized),
2106 g_signal_connect (parent, "unrealize",
2107 G_CALLBACK (gtk_window_transient_parent_unrealized),
2109 g_signal_connect (parent, "notify::screen",
2110 G_CALLBACK (gtk_window_transient_parent_screen_changed),
2113 gtk_window_set_screen (window, parent->screen);
2115 if (window->destroy_with_parent)
2116 connect_parent_destroyed (window);
2118 if (GTK_WIDGET_REALIZED (window) &&
2119 GTK_WIDGET_REALIZED (parent))
2120 gtk_window_transient_parent_realized (GTK_WIDGET (parent),
2121 GTK_WIDGET (window));
2125 gtk_window_group_add_window (parent->group, window);
2126 priv->transient_parent_group = TRUE;
2132 * gtk_window_get_transient_for:
2133 * @window: a #GtkWindow
2135 * Fetches the transient parent for this window. See
2136 * gtk_window_set_transient_for().
2138 * Return value: the transient parent for this window, or %NULL
2139 * if no transient parent has been set.
2142 gtk_window_get_transient_for (GtkWindow *window)
2144 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
2146 return window->transient_parent;
2150 * gtk_window_set_opacity:
2151 * @window: a #GtkWindow
2152 * @opacity: desired opacity, between 0 and 1
2154 * Request the windowing system to make @window partially transparent,
2155 * with opacity 0 being fully transparent and 1 fully opaque. (Values
2156 * of the opacity parameter are clamped to the [0,1] range.) On X11
2157 * this has any effect only on X screens with a compositing manager
2158 * running. See gtk_widget_is_composited(). On Windows it should work
2161 * Note that setting a window's opacity after the window has been
2162 * shown causes it to flicker once on Windows.
2167 gtk_window_set_opacity (GtkWindow *window,
2170 GtkWindowPrivate *priv;
2172 g_return_if_fail (GTK_IS_WINDOW (window));
2174 priv = GTK_WINDOW_GET_PRIVATE (window);
2178 else if (opacity > 1.0)
2181 priv->opacity_set = TRUE;
2182 priv->opacity = opacity;
2184 if (GTK_WIDGET_REALIZED (window))
2185 gdk_window_set_opacity (GTK_WIDGET (window)->window, priv->opacity);
2189 * gtk_window_get_opacity:
2190 * @window: a #GtkWindow
2192 * Fetches the requested opacity for this window. See
2193 * gtk_window_set_opacity().
2195 * Return value: the requested opacity for this window.
2200 gtk_window_get_opacity (GtkWindow *window)
2202 GtkWindowPrivate *priv;
2204 g_return_val_if_fail (GTK_IS_WINDOW (window), 0.0);
2206 priv = GTK_WINDOW_GET_PRIVATE (window);
2208 return priv->opacity;
2212 * gtk_window_set_type_hint:
2213 * @window: a #GtkWindow
2214 * @hint: the window type
2216 * By setting the type hint for the window, you allow the window
2217 * manager to decorate and handle the window in a way which is
2218 * suitable to the function of the window in your application.
2220 * This function should be called before the window becomes visible.
2222 * gtk_dialog_new_with_buttons() and other convenience functions in GTK+
2223 * will sometimes call gtk_window_set_type_hint() on your behalf.
2227 gtk_window_set_type_hint (GtkWindow *window,
2228 GdkWindowTypeHint hint)
2230 GtkWindowPrivate *priv;
2232 g_return_if_fail (GTK_IS_WINDOW (window));
2233 g_return_if_fail (!GTK_WIDGET_VISIBLE (window));
2235 priv = GTK_WINDOW_GET_PRIVATE (window);
2237 if (hint < GDK_WINDOW_TYPE_HINT_DROPDOWN_MENU)
2238 window->type_hint = hint;
2240 window->type_hint = GDK_WINDOW_TYPE_HINT_NORMAL;
2242 priv->reset_type_hint = TRUE;
2243 priv->type_hint = hint;
2247 * gtk_window_get_type_hint:
2248 * @window: a #GtkWindow
2250 * Gets the type hint for this window. See gtk_window_set_type_hint().
2252 * Return value: the type hint for @window.
2255 gtk_window_get_type_hint (GtkWindow *window)
2257 GtkWindowPrivate *priv;
2259 g_return_val_if_fail (GTK_IS_WINDOW (window), GDK_WINDOW_TYPE_HINT_NORMAL);
2261 priv = GTK_WINDOW_GET_PRIVATE (window);
2263 return priv->type_hint;
2267 * gtk_window_set_skip_taskbar_hint:
2268 * @window: a #GtkWindow
2269 * @setting: %TRUE to keep this window from appearing in the task bar
2271 * Windows may set a hint asking the desktop environment not to display
2272 * the window in the task bar. This function sets this hint.
2277 gtk_window_set_skip_taskbar_hint (GtkWindow *window,
2280 GtkWindowPrivate *priv;
2282 g_return_if_fail (GTK_IS_WINDOW (window));
2284 priv = GTK_WINDOW_GET_PRIVATE (window);
2286 setting = setting != FALSE;
2288 if (priv->skips_taskbar != setting)
2290 priv->skips_taskbar = setting;
2291 if (GTK_WIDGET_REALIZED (window))
2292 gdk_window_set_skip_taskbar_hint (GTK_WIDGET (window)->window,
2293 priv->skips_taskbar);
2294 g_object_notify (G_OBJECT (window), "skip-taskbar-hint");
2299 * gtk_window_get_skip_taskbar_hint:
2300 * @window: a #GtkWindow
2302 * Gets the value set by gtk_window_set_skip_taskbar_hint()
2304 * Return value: %TRUE if window shouldn't be in taskbar
2309 gtk_window_get_skip_taskbar_hint (GtkWindow *window)
2311 GtkWindowPrivate *priv;
2313 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
2315 priv = GTK_WINDOW_GET_PRIVATE (window);
2317 return priv->skips_taskbar;
2321 * gtk_window_set_skip_pager_hint:
2322 * @window: a #GtkWindow
2323 * @setting: %TRUE to keep this window from appearing in the pager
2325 * Windows may set a hint asking the desktop environment not to display
2326 * the window in the pager. This function sets this hint.
2327 * (A "pager" is any desktop navigation tool such as a workspace
2328 * switcher that displays a thumbnail representation of the windows
2334 gtk_window_set_skip_pager_hint (GtkWindow *window,
2337 GtkWindowPrivate *priv;
2339 g_return_if_fail (GTK_IS_WINDOW (window));
2341 priv = GTK_WINDOW_GET_PRIVATE (window);
2343 setting = setting != FALSE;
2345 if (priv->skips_pager != setting)
2347 priv->skips_pager = setting;
2348 if (GTK_WIDGET_REALIZED (window))
2349 gdk_window_set_skip_pager_hint (GTK_WIDGET (window)->window,
2351 g_object_notify (G_OBJECT (window), "skip-pager-hint");
2356 * gtk_window_get_skip_pager_hint:
2357 * @window: a #GtkWindow
2359 * Gets the value set by gtk_window_set_skip_pager_hint().
2361 * Return value: %TRUE if window shouldn't be in pager
2366 gtk_window_get_skip_pager_hint (GtkWindow *window)
2368 GtkWindowPrivate *priv;
2370 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
2372 priv = GTK_WINDOW_GET_PRIVATE (window);
2374 return priv->skips_pager;
2378 * gtk_window_set_urgency_hint:
2379 * @window: a #GtkWindow
2380 * @setting: %TRUE to mark this window as urgent
2382 * Windows may set a hint asking the desktop environment to draw
2383 * the users attention to the window. This function sets this hint.
2388 gtk_window_set_urgency_hint (GtkWindow *window,
2391 GtkWindowPrivate *priv;
2393 g_return_if_fail (GTK_IS_WINDOW (window));
2395 priv = GTK_WINDOW_GET_PRIVATE (window);
2397 setting = setting != FALSE;
2399 if (priv->urgent != setting)
2401 priv->urgent = setting;
2402 if (GTK_WIDGET_REALIZED (window))
2403 gdk_window_set_urgency_hint (GTK_WIDGET (window)->window,
2405 g_object_notify (G_OBJECT (window), "urgency-hint");
2410 * gtk_window_get_urgency_hint:
2411 * @window: a #GtkWindow
2413 * Gets the value set by gtk_window_set_urgency_hint()
2415 * Return value: %TRUE if window is urgent
2420 gtk_window_get_urgency_hint (GtkWindow *window)
2422 GtkWindowPrivate *priv;
2424 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
2426 priv = GTK_WINDOW_GET_PRIVATE (window);
2428 return priv->urgent;
2432 * gtk_window_set_accept_focus:
2433 * @window: a #GtkWindow
2434 * @setting: %TRUE to let this window receive input focus
2436 * Windows may set a hint asking the desktop environment not to receive
2437 * the input focus. This function sets this hint.
2442 gtk_window_set_accept_focus (GtkWindow *window,
2445 GtkWindowPrivate *priv;
2447 g_return_if_fail (GTK_IS_WINDOW (window));
2449 priv = GTK_WINDOW_GET_PRIVATE (window);
2451 setting = setting != FALSE;
2453 if (priv->accept_focus != setting)
2455 priv->accept_focus = setting;
2456 if (GTK_WIDGET_REALIZED (window))
2457 gdk_window_set_accept_focus (GTK_WIDGET (window)->window,
2458 priv->accept_focus);
2459 g_object_notify (G_OBJECT (window), "accept-focus");
2464 * gtk_window_get_accept_focus:
2465 * @window: a #GtkWindow
2467 * Gets the value set by gtk_window_set_accept_focus().
2469 * Return value: %TRUE if window should receive the input focus
2474 gtk_window_get_accept_focus (GtkWindow *window)
2476 GtkWindowPrivate *priv;
2478 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
2480 priv = GTK_WINDOW_GET_PRIVATE (window);
2482 return priv->accept_focus;
2486 * gtk_window_set_focus_on_map:
2487 * @window: a #GtkWindow
2488 * @setting: %TRUE to let this window receive input focus on map
2490 * Windows may set a hint asking the desktop environment not to receive
2491 * the input focus when the window is mapped. This function sets this
2497 gtk_window_set_focus_on_map (GtkWindow *window,
2500 GtkWindowPrivate *priv;
2502 g_return_if_fail (GTK_IS_WINDOW (window));
2504 priv = GTK_WINDOW_GET_PRIVATE (window);
2506 setting = setting != FALSE;
2508 if (priv->focus_on_map != setting)
2510 priv->focus_on_map = setting;
2511 if (GTK_WIDGET_REALIZED (window))
2512 gdk_window_set_focus_on_map (GTK_WIDGET (window)->window,
2513 priv->focus_on_map);
2514 g_object_notify (G_OBJECT (window), "focus-on-map");
2519 * gtk_window_get_focus_on_map:
2520 * @window: a #GtkWindow
2522 * Gets the value set by gtk_window_set_focus_on_map().
2524 * Return value: %TRUE if window should receive the input focus when
2530 gtk_window_get_focus_on_map (GtkWindow *window)
2532 GtkWindowPrivate *priv;
2534 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
2536 priv = GTK_WINDOW_GET_PRIVATE (window);
2538 return priv->focus_on_map;
2542 * gtk_window_set_destroy_with_parent:
2543 * @window: a #GtkWindow
2544 * @setting: whether to destroy @window with its transient parent
2546 * If @setting is %TRUE, then destroying the transient parent of @window
2547 * will also destroy @window itself. This is useful for dialogs that
2548 * shouldn't persist beyond the lifetime of the main window they're
2549 * associated with, for example.
2552 gtk_window_set_destroy_with_parent (GtkWindow *window,
2555 g_return_if_fail (GTK_IS_WINDOW (window));
2557 if (window->destroy_with_parent == (setting != FALSE))
2560 if (window->destroy_with_parent)
2562 disconnect_parent_destroyed (window);
2566 connect_parent_destroyed (window);
2569 window->destroy_with_parent = setting;
2571 g_object_notify (G_OBJECT (window), "destroy-with-parent");
2575 * gtk_window_get_destroy_with_parent:
2576 * @window: a #GtkWindow
2578 * Returns whether the window will be destroyed with its transient parent. See
2579 * gtk_window_set_destroy_with_parent ().
2581 * Return value: %TRUE if the window will be destroyed with its transient parent.
2584 gtk_window_get_destroy_with_parent (GtkWindow *window)
2586 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
2588 return window->destroy_with_parent;
2591 static GtkWindowGeometryInfo*
2592 gtk_window_get_geometry_info (GtkWindow *window,
2595 GtkWindowGeometryInfo *info;
2597 info = window->geometry_info;
2598 if (!info && create)
2600 info = g_new0 (GtkWindowGeometryInfo, 1);
2602 info->default_width = -1;
2603 info->default_height = -1;
2604 info->resize_width = -1;
2605 info->resize_height = -1;
2606 info->initial_x = 0;
2607 info->initial_y = 0;
2608 info->initial_pos_set = FALSE;
2609 info->default_is_geometry = FALSE;
2610 info->position_constraints_changed = FALSE;
2611 info->last.configure_request.x = 0;
2612 info->last.configure_request.y = 0;
2613 info->last.configure_request.width = -1;
2614 info->last.configure_request.height = -1;
2615 info->widget = NULL;
2617 window->geometry_info = info;
2624 * gtk_window_set_geometry_hints:
2625 * @window: a #GtkWindow
2626 * @geometry_widget: widget the geometry hints will be applied to
2627 * @geometry: struct containing geometry information
2628 * @geom_mask: mask indicating which struct fields should be paid attention to
2630 * This function sets up hints about how a window can be resized by
2631 * the user. You can set a minimum and maximum size; allowed resize
2632 * increments (e.g. for xterm, you can only resize by the size of a
2633 * character); aspect ratios; and more. See the #GdkGeometry struct.
2637 gtk_window_set_geometry_hints (GtkWindow *window,
2638 GtkWidget *geometry_widget,
2639 GdkGeometry *geometry,
2640 GdkWindowHints geom_mask)
2642 GtkWindowGeometryInfo *info;
2644 g_return_if_fail (GTK_IS_WINDOW (window));
2645 g_return_if_fail (geometry_widget == NULL || GTK_IS_WIDGET (geometry_widget));
2647 info = gtk_window_get_geometry_info (window, TRUE);
2650 g_signal_handlers_disconnect_by_func (info->widget,
2651 gtk_widget_destroyed,
2654 info->widget = geometry_widget;
2656 g_signal_connect (geometry_widget, "destroy",
2657 G_CALLBACK (gtk_widget_destroyed),
2661 info->geometry = *geometry;
2663 /* We store gravity in window->gravity not in the hints. */
2664 info->mask = geom_mask & ~(GDK_HINT_WIN_GRAVITY);
2666 if (geom_mask & GDK_HINT_WIN_GRAVITY)
2668 gtk_window_set_gravity (window, geometry->win_gravity);
2671 gtk_widget_queue_resize (GTK_WIDGET (window));
2675 * gtk_window_set_decorated:
2676 * @window: a #GtkWindow
2677 * @setting: %TRUE to decorate the window
2679 * By default, windows are decorated with a title bar, resize
2680 * controls, etc. Some <link linkend="gtk-X11-arch">window
2681 * managers</link> allow GTK+ to disable these decorations, creating a
2682 * borderless window. If you set the decorated property to %FALSE
2683 * using this function, GTK+ will do its best to convince the window
2684 * manager not to decorate the window. Depending on the system, this
2685 * function may not have any effect when called on a window that is
2686 * already visible, so you should call it before calling gtk_window_show().
2688 * On Windows, this function always works, since there's no window manager
2693 gtk_window_set_decorated (GtkWindow *window,
2696 g_return_if_fail (GTK_IS_WINDOW (window));
2698 setting = setting != FALSE;
2700 if (setting == window->decorated)
2703 window->decorated = setting;
2705 if (GTK_WIDGET (window)->window)
2707 if (window->decorated)
2708 gdk_window_set_decorations (GTK_WIDGET (window)->window,
2711 gdk_window_set_decorations (GTK_WIDGET (window)->window,
2715 g_object_notify (G_OBJECT (window), "decorated");
2719 * gtk_window_get_decorated:
2720 * @window: a #GtkWindow
2722 * Returns whether the window has been set to have decorations
2723 * such as a title bar via gtk_window_set_decorated().
2725 * Return value: %TRUE if the window has been set to have decorations
2728 gtk_window_get_decorated (GtkWindow *window)
2730 g_return_val_if_fail (GTK_IS_WINDOW (window), TRUE);
2732 return window->decorated;
2736 * gtk_window_set_deletable:
2737 * @window: a #GtkWindow
2738 * @setting: %TRUE to decorate the window as deletable
2740 * By default, windows have a close button in the window frame. Some
2741 * <link linkend="gtk-X11-arch">window managers</link> allow GTK+ to
2742 * disable this button. If you set the deletable property to %FALSE
2743 * using this function, GTK+ will do its best to convince the window
2744 * manager not to show a close button. Depending on the system, this
2745 * function may not have any effect when called on a window that is
2746 * already visible, so you should call it before calling gtk_window_show().
2748 * On Windows, this function always works, since there's no window manager
2754 gtk_window_set_deletable (GtkWindow *window,
2757 GtkWindowPrivate *priv;
2759 g_return_if_fail (GTK_IS_WINDOW (window));
2761 priv = GTK_WINDOW_GET_PRIVATE (window);
2763 setting = setting != FALSE;
2765 if (setting == priv->deletable)
2768 priv->deletable = setting;
2770 if (GTK_WIDGET (window)->window)
2772 if (priv->deletable)
2773 gdk_window_set_functions (GTK_WIDGET (window)->window,
2776 gdk_window_set_functions (GTK_WIDGET (window)->window,
2777 GDK_FUNC_ALL | GDK_FUNC_CLOSE);
2780 g_object_notify (G_OBJECT (window), "deletable");
2784 * gtk_window_get_deletable:
2785 * @window: a #GtkWindow
2787 * Returns whether the window has been set to have a close button
2788 * via gtk_window_set_deletable().
2790 * Return value: %TRUE if the window has been set to have a close button
2795 gtk_window_get_deletable (GtkWindow *window)
2797 GtkWindowPrivate *priv;
2799 g_return_val_if_fail (GTK_IS_WINDOW (window), TRUE);
2801 priv = GTK_WINDOW_GET_PRIVATE (window);
2803 return priv->deletable;
2806 static GtkWindowIconInfo*
2807 get_icon_info (GtkWindow *window)
2809 return g_object_get_qdata (G_OBJECT (window), quark_gtk_window_icon_info);
2813 free_icon_info (GtkWindowIconInfo *info)
2815 g_free (info->icon_name);
2816 g_slice_free (GtkWindowIconInfo, info);
2820 static GtkWindowIconInfo*
2821 ensure_icon_info (GtkWindow *window)
2823 GtkWindowIconInfo *info;
2825 info = get_icon_info (window);
2829 info = g_slice_new0 (GtkWindowIconInfo);
2830 g_object_set_qdata_full (G_OBJECT (window),
2831 quark_gtk_window_icon_info,
2833 (GDestroyNotify)free_icon_info);
2845 static ScreenIconInfo *
2846 get_screen_icon_info (GdkScreen *screen)
2848 ScreenIconInfo *info = g_object_get_qdata (G_OBJECT (screen),
2849 quark_gtk_window_default_icon_pixmap);
2852 info = g_slice_new0 (ScreenIconInfo);
2853 g_object_set_qdata (G_OBJECT (screen),
2854 quark_gtk_window_default_icon_pixmap, info);
2857 if (info->serial != default_icon_serial)
2861 g_object_remove_weak_pointer (G_OBJECT (info->pixmap), (gpointer*)&info->pixmap);
2862 info->pixmap = NULL;
2867 g_object_remove_weak_pointer (G_OBJECT (info->mask), (gpointer*)&info->mask);
2871 info->serial = default_icon_serial;
2878 get_pixmap_and_mask (GdkWindow *window,
2879 GtkWindowIconInfo *parent_info,
2880 gboolean is_default_list,
2882 GdkPixmap **pmap_return,
2883 GdkBitmap **mask_return)
2885 GdkScreen *screen = gdk_drawable_get_screen (window);
2886 ScreenIconInfo *default_icon_info = get_screen_icon_info (screen);
2887 GdkPixbuf *best_icon;
2891 *pmap_return = NULL;
2892 *mask_return = NULL;
2894 if (is_default_list &&
2895 default_icon_info->pixmap != NULL)
2897 /* Use shared icon pixmap for all windows on this screen.
2899 if (default_icon_info->pixmap)
2900 g_object_ref (default_icon_info->pixmap);
2901 if (default_icon_info->mask)
2902 g_object_ref (default_icon_info->mask);
2904 *pmap_return = default_icon_info->pixmap;
2905 *mask_return = default_icon_info->mask;
2907 else if (parent_info && parent_info->icon_pixmap)
2909 if (parent_info->icon_pixmap)
2910 g_object_ref (parent_info->icon_pixmap);
2911 if (parent_info->icon_mask)
2912 g_object_ref (parent_info->icon_mask);
2914 *pmap_return = parent_info->icon_pixmap;
2915 *mask_return = parent_info->icon_mask;
2919 #define IDEAL_SIZE 48
2921 best_size = G_MAXINT;
2923 tmp_list = icon_list;
2924 while (tmp_list != NULL)
2926 GdkPixbuf *pixbuf = tmp_list->data;
2929 /* average width and height - if someone passes in a rectangular
2930 * icon they deserve what they get.
2932 this = gdk_pixbuf_get_width (pixbuf) + gdk_pixbuf_get_height (pixbuf);
2935 if (best_icon == NULL)
2942 /* icon is better if it's 32 pixels or larger, and closer to
2943 * the ideal size than the current best.
2946 (ABS (best_size - IDEAL_SIZE) <
2947 ABS (this - IDEAL_SIZE)))
2954 tmp_list = tmp_list->next;
2958 gdk_pixbuf_render_pixmap_and_mask_for_colormap (best_icon,
2959 gdk_screen_get_system_colormap (screen),
2964 /* Save pmap/mask for others to use if appropriate */
2967 parent_info->icon_pixmap = *pmap_return;
2968 parent_info->icon_mask = *mask_return;
2970 if (parent_info->icon_pixmap)
2971 g_object_ref (parent_info->icon_pixmap);
2972 if (parent_info->icon_mask)
2973 g_object_ref (parent_info->icon_mask);
2975 else if (is_default_list)
2977 default_icon_info->pixmap = *pmap_return;
2978 default_icon_info->mask = *mask_return;
2980 if (default_icon_info->pixmap)
2981 g_object_add_weak_pointer (G_OBJECT (default_icon_info->pixmap),
2982 (gpointer*)&default_icon_info->pixmap);
2983 if (default_icon_info->mask)
2984 g_object_add_weak_pointer (G_OBJECT (default_icon_info->mask),
2985 (gpointer*)&default_icon_info->mask);
2991 icon_list_from_theme (GtkWidget *widget,
2996 GtkIconTheme *icon_theme;
3001 icon_theme = gtk_icon_theme_get_for_screen (gtk_widget_get_screen (widget));
3003 sizes = gtk_icon_theme_get_icon_sizes (icon_theme, name);
3006 for (i = 0; sizes[i]; i++)
3009 * We need an EWMH extension to handle scalable icons
3010 * by passing their name to the WM. For now just use a
3014 icon = gtk_icon_theme_load_icon (icon_theme, name,
3017 icon = gtk_icon_theme_load_icon (icon_theme, name,
3020 list = g_list_append (list, icon);
3030 gtk_window_realize_icon (GtkWindow *window)
3033 GtkWindowIconInfo *info;
3036 widget = GTK_WIDGET (window);
3038 g_return_if_fail (widget->window != NULL);
3040 /* no point setting an icon on override-redirect */
3041 if (window->type == GTK_WINDOW_POPUP)
3046 info = ensure_icon_info (window);
3051 g_return_if_fail (info->icon_pixmap == NULL);
3052 g_return_if_fail (info->icon_mask == NULL);
3054 info->using_default_icon = FALSE;
3055 info->using_parent_icon = FALSE;
3056 info->using_themed_icon = FALSE;
3058 icon_list = info->icon_list;
3060 /* Look up themed icon */
3061 if (icon_list == NULL && info->icon_name)
3063 icon_list = icon_list_from_theme (widget, info->icon_name);
3065 info->using_themed_icon = TRUE;
3068 /* Inherit from transient parent */
3069 if (icon_list == NULL && window->transient_parent)
3071 icon_list = ensure_icon_info (window->transient_parent)->icon_list;
3073 info->using_parent_icon = TRUE;
3076 /* Inherit from default */
3077 if (icon_list == NULL)
3079 icon_list = default_icon_list;
3081 info->using_default_icon = TRUE;
3084 /* Look up themed icon */
3085 if (icon_list == NULL && default_icon_name)
3087 icon_list = icon_list_from_theme (widget, default_icon_name);
3088 info->using_default_icon = TRUE;
3089 info->using_themed_icon = TRUE;
3092 gdk_window_set_icon_list (widget->window, icon_list);
3094 get_pixmap_and_mask (widget->window,
3095 info->using_parent_icon ? ensure_icon_info (window->transient_parent) : NULL,
3096 info->using_default_icon,
3101 /* This is a slight ICCCM violation since it's a color pixmap not
3102 * a bitmap, but everyone does it.
3104 gdk_window_set_icon (widget->window,
3109 info->realized = TRUE;
3111 if (info->using_themed_icon)
3113 GtkIconTheme *icon_theme;
3115 g_list_foreach (icon_list, (GFunc) g_object_unref, NULL);
3116 g_list_free (icon_list);
3118 icon_theme = gtk_icon_theme_get_for_screen (gtk_widget_get_screen (GTK_WIDGET (window)));
3119 g_signal_connect (icon_theme, "changed",
3120 G_CALLBACK (update_themed_icon), window);
3125 gtk_window_unrealize_icon (GtkWindow *window)
3127 GtkWindowIconInfo *info;
3129 info = get_icon_info (window);
3134 if (info->icon_pixmap)
3135 g_object_unref (info->icon_pixmap);
3137 if (info->icon_mask)
3138 g_object_unref (info->icon_mask);
3140 info->icon_pixmap = NULL;
3141 info->icon_mask = NULL;
3143 if (info->using_themed_icon)
3145 GtkIconTheme *icon_theme;
3147 icon_theme = gtk_icon_theme_get_for_screen (gtk_widget_get_screen (GTK_WIDGET (window)));
3149 g_signal_handlers_disconnect_by_func (icon_theme, update_themed_icon, window);
3152 /* We don't clear the properties on the window, just figure the
3153 * window is going away.
3156 info->realized = FALSE;
3161 * gtk_window_set_icon_list:
3162 * @window: a #GtkWindow
3163 * @list: list of #GdkPixbuf
3165 * Sets up the icon representing a #GtkWindow. The icon is used when
3166 * the window is minimized (also known as iconified). Some window
3167 * managers or desktop environments may also place it in the window
3168 * frame, or display it in other contexts.
3170 * gtk_window_set_icon_list() allows you to pass in the same icon in
3171 * several hand-drawn sizes. The list should contain the natural sizes
3172 * your icon is available in; that is, don't scale the image before
3173 * passing it to GTK+. Scaling is postponed until the last minute,
3174 * when the desired final size is known, to allow best quality.
3176 * By passing several sizes, you may improve the final image quality
3177 * of the icon, by reducing or eliminating automatic image scaling.
3179 * Recommended sizes to provide: 16x16, 32x32, 48x48 at minimum, and
3180 * larger images (64x64, 128x128) if you have them.
3182 * See also gtk_window_set_default_icon_list() to set the icon
3183 * for all windows in your application in one go.
3185 * Note that transient windows (those who have been set transient for another
3186 * window using gtk_window_set_transient_for()) will inherit their
3187 * icon from their transient parent. So there's no need to explicitly
3188 * set the icon on transient windows.
3191 gtk_window_set_icon_list (GtkWindow *window,
3194 GtkWindowIconInfo *info;
3196 g_return_if_fail (GTK_IS_WINDOW (window));
3198 info = ensure_icon_info (window);
3200 if (info->icon_list == list) /* check for NULL mostly */
3203 g_list_foreach (list,
3204 (GFunc) g_object_ref, NULL);
3206 g_list_foreach (info->icon_list,
3207 (GFunc) g_object_unref, NULL);
3209 g_list_free (info->icon_list);
3211 info->icon_list = g_list_copy (list);
3213 g_object_notify (G_OBJECT (window), "icon");
3215 gtk_window_unrealize_icon (window);
3217 if (GTK_WIDGET_REALIZED (window))
3218 gtk_window_realize_icon (window);
3220 /* We could try to update our transient children, but I don't think
3221 * it's really worth it. If we did it, the best way would probably
3222 * be to have children connect to notify::icon-list
3227 * gtk_window_get_icon_list:
3228 * @window: a #GtkWindow
3230 * Retrieves the list of icons set by gtk_window_set_icon_list().
3231 * The list is copied, but the reference count on each
3232 * member won't be incremented.
3234 * Return value: copy of window's icon list
3237 gtk_window_get_icon_list (GtkWindow *window)
3239 GtkWindowIconInfo *info;
3241 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
3243 info = get_icon_info (window);
3246 return g_list_copy (info->icon_list);
3252 * gtk_window_set_icon:
3253 * @window: a #GtkWindow
3254 * @icon: icon image, or %NULL
3256 * Sets up the icon representing a #GtkWindow. This icon is used when
3257 * the window is minimized (also known as iconified). Some window
3258 * managers or desktop environments may also place it in the window
3259 * frame, or display it in other contexts.
3261 * The icon should be provided in whatever size it was naturally
3262 * drawn; that is, don't scale the image before passing it to
3263 * GTK+. Scaling is postponed until the last minute, when the desired
3264 * final size is known, to allow best quality.
3266 * If you have your icon hand-drawn in multiple sizes, use
3267 * gtk_window_set_icon_list(). Then the best size will be used.
3269 * This function is equivalent to calling gtk_window_set_icon_list()
3270 * with a 1-element list.
3272 * See also gtk_window_set_default_icon_list() to set the icon
3273 * for all windows in your application in one go.
3276 gtk_window_set_icon (GtkWindow *window,
3281 g_return_if_fail (GTK_IS_WINDOW (window));
3282 g_return_if_fail (icon == NULL || GDK_IS_PIXBUF (icon));
3287 list = g_list_append (list, icon);
3289 gtk_window_set_icon_list (window, list);
3295 update_themed_icon (GtkIconTheme *icon_theme,
3298 g_object_notify (G_OBJECT (window), "icon");
3300 gtk_window_unrealize_icon (window);
3302 if (GTK_WIDGET_REALIZED (window))
3303 gtk_window_realize_icon (window);
3307 * gtk_window_set_icon_name:
3308 * @window: a #GtkWindow
3309 * @name: the name of the themed icon
3311 * Sets the icon for the window from a named themed icon. See
3312 * the docs for #GtkIconTheme for more details.
3314 * Note that this has nothing to do with the WM_ICON_NAME
3315 * property which is mentioned in the ICCCM.
3320 gtk_window_set_icon_name (GtkWindow *window,
3323 GtkWindowIconInfo *info;
3326 g_return_if_fail (GTK_IS_WINDOW (window));
3328 info = ensure_icon_info (window);
3330 tmp = info->icon_name;
3331 info->icon_name = g_strdup (name);
3334 g_list_foreach (info->icon_list, (GFunc) g_object_unref, NULL);
3335 g_list_free (info->icon_list);
3336 info->icon_list = NULL;
3338 update_themed_icon (NULL, window);
3340 g_object_notify (G_OBJECT (window), "icon-name");
3344 * gtk_window_get_icon_name:
3345 * @window: a #GtkWindow
3347 * Returns the name of the themed icon for the window,
3348 * see gtk_window_set_icon_name().
3350 * Returns: the icon name or %NULL if the window has
3355 G_CONST_RETURN gchar *
3356 gtk_window_get_icon_name (GtkWindow *window)
3358 GtkWindowIconInfo *info;
3360 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
3362 info = ensure_icon_info (window);
3364 return info->icon_name;
3368 * gtk_window_get_icon:
3369 * @window: a #GtkWindow
3371 * Gets the value set by gtk_window_set_icon() (or if you've
3372 * called gtk_window_set_icon_list(), gets the first icon in
3375 * Return value: icon for window
3378 gtk_window_get_icon (GtkWindow *window)
3380 GtkWindowIconInfo *info;
3382 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
3384 info = get_icon_info (window);
3385 if (info && info->icon_list)
3386 return GDK_PIXBUF (info->icon_list->data);
3391 /* Load pixbuf, printing warning on failure if error == NULL
3394 load_pixbuf_verbosely (const char *filename,
3397 GError *local_err = NULL;
3400 pixbuf = gdk_pixbuf_new_from_file (filename, &local_err);
3408 g_warning ("Error loading icon from file '%s':\n\t%s",
3409 filename, local_err->message);
3410 g_error_free (local_err);
3418 * gtk_window_set_icon_from_file:
3419 * @window: a #GtkWindow
3420 * @filename: location of icon file
3421 * @err: location to store error, or %NULL.
3423 * Sets the icon for @window.
3424 * Warns on failure if @err is %NULL.
3426 * This function is equivalent to calling gtk_window_set_icon()
3427 * with a pixbuf created by loading the image from @filename.
3429 * Returns: %TRUE if setting the icon succeeded.
3434 gtk_window_set_icon_from_file (GtkWindow *window,
3435 const gchar *filename,
3438 GdkPixbuf *pixbuf = load_pixbuf_verbosely (filename, err);
3442 gtk_window_set_icon (window, pixbuf);
3443 g_object_unref (pixbuf);
3452 * gtk_window_set_default_icon_list:
3453 * @list: a list of #GdkPixbuf
3455 * Sets an icon list to be used as fallback for windows that haven't
3456 * had gtk_window_set_icon_list() called on them to set up a
3457 * window-specific icon list. This function allows you to set up the
3458 * icon for all windows in your app at once.
3460 * See gtk_window_set_icon_list() for more details.
3464 gtk_window_set_default_icon_list (GList *list)
3468 if (list == default_icon_list)
3471 /* Update serial so we don't used cached pixmaps/masks
3473 default_icon_serial++;
3475 g_list_foreach (list,
3476 (GFunc) g_object_ref, NULL);
3478 g_list_foreach (default_icon_list,
3479 (GFunc) g_object_unref, NULL);
3481 g_list_free (default_icon_list);
3483 default_icon_list = g_list_copy (list);
3485 /* Update all toplevels */
3486 toplevels = gtk_window_list_toplevels ();
3487 tmp_list = toplevels;
3488 while (tmp_list != NULL)
3490 GtkWindowIconInfo *info;
3491 GtkWindow *w = tmp_list->data;
3493 info = get_icon_info (w);
3494 if (info && info->using_default_icon)
3496 gtk_window_unrealize_icon (w);
3497 if (GTK_WIDGET_REALIZED (w))
3498 gtk_window_realize_icon (w);
3501 tmp_list = tmp_list->next;
3503 g_list_free (toplevels);
3507 * gtk_window_set_default_icon:
3510 * Sets an icon to be used as fallback for windows that haven't
3511 * had gtk_window_set_icon() called on them from a pixbuf.
3516 gtk_window_set_default_icon (GdkPixbuf *icon)
3520 g_return_if_fail (GDK_IS_PIXBUF (icon));
3522 list = g_list_prepend (NULL, icon);
3523 gtk_window_set_default_icon_list (list);
3528 * gtk_window_set_default_icon_name:
3529 * @name: the name of the themed icon
3531 * Sets an icon to be used as fallback for windows that haven't
3532 * had gtk_window_set_icon_list() called on them from a named
3533 * themed icon, see gtk_window_set_icon_name().
3538 gtk_window_set_default_icon_name (const gchar *name)
3543 /* Update serial so we don't used cached pixmaps/masks
3545 default_icon_serial++;
3547 g_free (default_icon_name);
3548 default_icon_name = g_strdup (name);
3550 g_list_foreach (default_icon_list,
3551 (GFunc) g_object_unref, NULL);
3553 g_list_free (default_icon_list);
3554 default_icon_list = NULL;
3556 /* Update all toplevels */
3557 toplevels = gtk_window_list_toplevels ();
3558 tmp_list = toplevels;
3559 while (tmp_list != NULL)
3561 GtkWindowIconInfo *info;
3562 GtkWindow *w = tmp_list->data;
3564 info = get_icon_info (w);
3565 if (info && info->using_default_icon && info->using_themed_icon)
3567 gtk_window_unrealize_icon (w);
3568 if (GTK_WIDGET_REALIZED (w))
3569 gtk_window_realize_icon (w);
3572 tmp_list = tmp_list->next;
3574 g_list_free (toplevels);
3578 * gtk_window_set_default_icon_from_file:
3579 * @filename: location of icon file
3580 * @err: location to store error, or %NULL.
3582 * Sets an icon to be used as fallback for windows that haven't
3583 * had gtk_window_set_icon_list() called on them from a file
3584 * on disk. Warns on failure if @err is %NULL.
3586 * Returns: %TRUE if setting the icon succeeded.
3591 gtk_window_set_default_icon_from_file (const gchar *filename,
3594 GdkPixbuf *pixbuf = load_pixbuf_verbosely (filename, err);
3598 gtk_window_set_default_icon (pixbuf);
3599 g_object_unref (pixbuf);
3608 * gtk_window_get_default_icon_list:
3610 * Gets the value set by gtk_window_set_default_icon_list().
3611 * The list is a copy and should be freed with g_list_free(),
3612 * but the pixbufs in the list have not had their reference count
3615 * Return value: copy of default icon list
3618 gtk_window_get_default_icon_list (void)
3620 return g_list_copy (default_icon_list);
3624 gtk_window_set_default_size_internal (GtkWindow *window,
3625 gboolean change_width,
3627 gboolean change_height,
3629 gboolean is_geometry)
3631 GtkWindowGeometryInfo *info;
3633 g_return_if_fail (change_width == FALSE || width >= -1);
3634 g_return_if_fail (change_height == FALSE || height >= -1);
3636 info = gtk_window_get_geometry_info (window, TRUE);
3638 g_object_freeze_notify (G_OBJECT (window));
3640 info->default_is_geometry = is_geometry != FALSE;
3650 info->default_width = width;
3652 g_object_notify (G_OBJECT (window), "default-width");
3663 info->default_height = height;
3665 g_object_notify (G_OBJECT (window), "default-height");
3668 g_object_thaw_notify (G_OBJECT (window));
3670 gtk_widget_queue_resize (GTK_WIDGET (window));
3674 * gtk_window_set_default_size:
3675 * @window: a #GtkWindow
3676 * @width: width in pixels, or -1 to unset the default width
3677 * @height: height in pixels, or -1 to unset the default height
3679 * Sets the default size of a window. If the window's "natural" size
3680 * (its size request) is larger than the default, the default will be
3681 * ignored. More generally, if the default size does not obey the
3682 * geometry hints for the window (gtk_window_set_geometry_hints() can
3683 * be used to set these explicitly), the default size will be clamped
3684 * to the nearest permitted size.
3686 * Unlike gtk_widget_set_size_request(), which sets a size request for
3687 * a widget and thus would keep users from shrinking the window, this
3688 * function only sets the initial size, just as if the user had
3689 * resized the window themselves. Users can still shrink the window
3690 * again as they normally would. Setting a default size of -1 means to
3691 * use the "natural" default size (the size request of the window).
3693 * For more control over a window's initial size and how resizing works,
3694 * investigate gtk_window_set_geometry_hints().
3696 * For some uses, gtk_window_resize() is a more appropriate function.
3697 * gtk_window_resize() changes the current size of the window, rather
3698 * than the size to be used on initial display. gtk_window_resize() always
3699 * affects the window itself, not the geometry widget.
3701 * The default size of a window only affects the first time a window is
3702 * shown; if a window is hidden and re-shown, it will remember the size
3703 * it had prior to hiding, rather than using the default size.
3705 * Windows can't actually be 0x0 in size, they must be at least 1x1, but
3706 * passing 0 for @width and @height is OK, resulting in a 1x1 default size.
3709 gtk_window_set_default_size (GtkWindow *window,
3713 g_return_if_fail (GTK_IS_WINDOW (window));
3714 g_return_if_fail (width >= -1);
3715 g_return_if_fail (height >= -1);
3717 gtk_window_set_default_size_internal (window, TRUE, width, TRUE, height, FALSE);
3721 * gtk_window_get_default_size:
3722 * @window: a #GtkWindow
3723 * @width: location to store the default width, or %NULL
3724 * @height: location to store the default height, or %NULL
3726 * Gets the default size of the window. A value of -1 for the width or
3727 * height indicates that a default size has not been explicitly set
3728 * for that dimension, so the "natural" size of the window will be
3733 gtk_window_get_default_size (GtkWindow *window,
3737 GtkWindowGeometryInfo *info;
3739 g_return_if_fail (GTK_IS_WINDOW (window));
3741 info = gtk_window_get_geometry_info (window, FALSE);
3744 *width = info ? info->default_width : -1;
3747 *height = info ? info->default_height : -1;
3751 * gtk_window_resize:
3752 * @window: a #GtkWindow
3753 * @width: width in pixels to resize the window to
3754 * @height: height in pixels to resize the window to
3756 * Resizes the window as if the user had done so, obeying geometry
3757 * constraints. The default geometry constraint is that windows may
3758 * not be smaller than their size request; to override this
3759 * constraint, call gtk_widget_set_size_request() to set the window's
3760 * request to a smaller value.
3762 * If gtk_window_resize() is called before showing a window for the
3763 * first time, it overrides any default size set with
3764 * gtk_window_set_default_size().
3766 * Windows may not be resized smaller than 1 by 1 pixels.
3770 gtk_window_resize (GtkWindow *window,
3774 GtkWindowGeometryInfo *info;
3776 g_return_if_fail (GTK_IS_WINDOW (window));
3777 g_return_if_fail (width > 0);
3778 g_return_if_fail (height > 0);
3780 info = gtk_window_get_geometry_info (window, TRUE);
3782 info->resize_width = width;
3783 info->resize_height = height;
3785 gtk_widget_queue_resize (GTK_WIDGET (window));
3789 * gtk_window_get_size:
3790 * @window: a #GtkWindow
3791 * @width: return location for width, or %NULL
3792 * @height: return location for height, or %NULL
3794 * Obtains the current size of @window. If @window is not onscreen,
3795 * it returns the size GTK+ will suggest to the <link
3796 * linkend="gtk-X11-arch">window manager</link> for the initial window
3797 * size (but this is not reliably the same as the size the window
3798 * manager will actually select). The size obtained by
3799 * gtk_window_get_size() is the last size received in a
3800 * #GdkEventConfigure, that is, GTK+ uses its locally-stored size,
3801 * rather than querying the X server for the size. As a result, if you
3802 * call gtk_window_resize() then immediately call
3803 * gtk_window_get_size(), the size won't have taken effect yet. After
3804 * the window manager processes the resize request, GTK+ receives
3805 * notification that the size has changed via a configure event, and
3806 * the size of the window gets updated.
3808 * Note 1: Nearly any use of this function creates a race condition,
3809 * because the size of the window may change between the time that you
3810 * get the size and the time that you perform some action assuming
3811 * that size is the current size. To avoid race conditions, connect to
3812 * "configure_event" on the window and adjust your size-dependent
3813 * state to match the size delivered in the #GdkEventConfigure.
3815 * Note 2: The returned size does <emphasis>not</emphasis> include the
3816 * size of the window manager decorations (aka the window frame or
3817 * border). Those are not drawn by GTK+ and GTK+ has no reliable
3818 * method of determining their size.
3820 * Note 3: If you are getting a window size in order to position
3821 * the window onscreen, there may be a better way. The preferred
3822 * way is to simply set the window's semantic type with
3823 * gtk_window_set_type_hint(), which allows the window manager to
3824 * e.g. center dialogs. Also, if you set the transient parent of
3825 * dialogs with gtk_window_set_transient_for() window managers
3826 * will often center the dialog over its parent window. It's
3827 * much preferred to let the window manager handle these
3828 * things rather than doing it yourself, because all apps will
3829 * behave consistently and according to user prefs if the window
3830 * manager handles it. Also, the window manager can take the size
3831 * of the window decorations/border into account, while your
3832 * application cannot.
3834 * In any case, if you insist on application-specified window
3835 * positioning, there's <emphasis>still</emphasis> a better way than
3836 * doing it yourself - gtk_window_set_position() will frequently
3837 * handle the details for you.
3841 gtk_window_get_size (GtkWindow *window,
3847 g_return_if_fail (GTK_IS_WINDOW (window));
3849 if (width == NULL && height == NULL)
3852 if (GTK_WIDGET_MAPPED (window))
3854 gdk_drawable_get_size (GTK_WIDGET (window)->window,
3859 GdkRectangle configure_request;
3861 gtk_window_compute_configure_request (window,
3865 w = configure_request.width;
3866 h = configure_request.height;
3877 * @window: a #GtkWindow
3878 * @x: X coordinate to move window to
3879 * @y: Y coordinate to move window to
3881 * Asks the <link linkend="gtk-X11-arch">window manager</link> to move
3882 * @window to the given position. Window managers are free to ignore
3883 * this; most window managers ignore requests for initial window
3884 * positions (instead using a user-defined placement algorithm) and
3885 * honor requests after the window has already been shown.
3887 * Note: the position is the position of the gravity-determined
3888 * reference point for the window. The gravity determines two things:
3889 * first, the location of the reference point in root window
3890 * coordinates; and second, which point on the window is positioned at
3891 * the reference point.
3893 * By default the gravity is #GDK_GRAVITY_NORTH_WEST, so the reference
3894 * point is simply the @x, @y supplied to gtk_window_move(). The
3895 * top-left corner of the window decorations (aka window frame or
3896 * border) will be placed at @x, @y. Therefore, to position a window
3897 * at the top left of the screen, you want to use the default gravity
3898 * (which is #GDK_GRAVITY_NORTH_WEST) and move the window to 0,0.
3900 * To position a window at the bottom right corner of the screen, you
3901 * would set #GDK_GRAVITY_SOUTH_EAST, which means that the reference
3902 * point is at @x + the window width and @y + the window height, and
3903 * the bottom-right corner of the window border will be placed at that
3904 * reference point. So, to place a window in the bottom right corner
3905 * you would first set gravity to south east, then write:
3906 * <literal>gtk_window_move (window, gdk_screen_width () - window_width,
3907 * gdk_screen_height () - window_height)</literal> (note that this
3908 * example does not take multi-head scenarios into account).
3910 * The Extended Window Manager Hints specification at <ulink
3911 * url="http://www.freedesktop.org/Standards/wm-spec">
3912 * http://www.freedesktop.org/Standards/wm-spec</ulink> has a
3913 * nice table of gravities in the "implementation notes" section.
3915 * The gtk_window_get_position() documentation may also be relevant.
3918 gtk_window_move (GtkWindow *window,
3922 GtkWindowGeometryInfo *info;
3925 g_return_if_fail (GTK_IS_WINDOW (window));
3927 widget = GTK_WIDGET (window);
3929 info = gtk_window_get_geometry_info (window, TRUE);
3931 if (GTK_WIDGET_MAPPED (window))
3933 /* we have now sent a request with this position
3934 * with currently-active constraints, so toggle flag.
3936 info->position_constraints_changed = FALSE;
3938 /* we only constrain if mapped - if not mapped,
3939 * then gtk_window_compute_configure_request()
3940 * will apply the constraints later, and we
3941 * don't want to lose information about
3942 * what position the user set before then.
3943 * i.e. if you do a move() then turn off POS_CENTER
3944 * then show the window, your move() will work.
3946 gtk_window_constrain_position (window,
3947 widget->allocation.width,
3948 widget->allocation.height,
3951 /* Note that this request doesn't go through our standard request
3952 * framework, e.g. doesn't increment configure_request_count,
3953 * doesn't set info->last, etc.; that's because
3954 * we don't save the info needed to arrive at this same request
3957 * To gtk_window_move_resize(), this will end up looking exactly
3958 * the same as the position being changed by the window
3962 /* FIXME are we handling gravity properly for framed windows? */
3964 gdk_window_move (window->frame,
3965 x - window->frame_left,
3966 y - window->frame_top);
3968 gdk_window_move (GTK_WIDGET (window)->window,
3973 /* Save this position to apply on mapping */
3974 info->initial_x = x;
3975 info->initial_y = y;
3976 info->initial_pos_set = TRUE;
3981 * gtk_window_get_position:
3982 * @window: a #GtkWindow
3983 * @root_x: return location for X coordinate of gravity-determined reference p\oint
3984 * @root_y: return location for Y coordinate of gravity-determined reference p\oint
3986 * This function returns the position you need to pass to
3987 * gtk_window_move() to keep @window in its current position. This
3988 * means that the meaning of the returned value varies with window
3989 * gravity. See gtk_window_move() for more details.
3991 * If you haven't changed the window gravity, its gravity will be
3992 * #GDK_GRAVITY_NORTH_WEST. This means that gtk_window_get_position()
3993 * gets the position of the top-left corner of the window manager
3994 * frame for the window. gtk_window_move() sets the position of this
3995 * same top-left corner.
3997 * gtk_window_get_position() is not 100% reliable because the X Window System
3998 * does not specify a way to obtain the geometry of the
3999 * decorations placed on a window by the window manager.
4000 * Thus GTK+ is using a "best guess" that works with most
4003 * Moreover, nearly all window managers are historically broken with
4004 * respect to their handling of window gravity. So moving a window to
4005 * its current position as returned by gtk_window_get_position() tends
4006 * to result in moving the window slightly. Window managers are
4007 * slowly getting better over time.
4009 * If a window has gravity #GDK_GRAVITY_STATIC the window manager
4010 * frame is not relevant, and thus gtk_window_get_position() will
4011 * always produce accurate results. However you can't use static
4012 * gravity to do things like place a window in a corner of the screen,
4013 * because static gravity ignores the window manager decorations.
4015 * If you are saving and restoring your application's window
4016 * positions, you should know that it's impossible for applications to
4017 * do this without getting it somewhat wrong because applications do
4018 * not have sufficient knowledge of window manager state. The Correct
4019 * Mechanism is to support the session management protocol (see the
4020 * "GnomeClient" object in the GNOME libraries for example) and allow
4021 * the window manager to save your window sizes and positions.
4026 gtk_window_get_position (GtkWindow *window,
4032 g_return_if_fail (GTK_IS_WINDOW (window));
4034 widget = GTK_WIDGET (window);
4036 if (window->gravity == GDK_GRAVITY_STATIC)
4038 if (GTK_WIDGET_MAPPED (widget))
4040 /* This does a server round-trip, which is sort of wrong;
4041 * but a server round-trip is inevitable for
4042 * gdk_window_get_frame_extents() in the usual
4043 * NorthWestGravity case below, so not sure what else to
4044 * do. We should likely be consistent about whether we get
4045 * the client-side info or the server-side info.
4047 gdk_window_get_origin (widget->window, root_x, root_y);
4051 GdkRectangle configure_request;
4053 gtk_window_compute_configure_request (window,
4057 *root_x = configure_request.x;
4058 *root_y = configure_request.y;
4063 GdkRectangle frame_extents;
4068 if (GTK_WIDGET_MAPPED (widget))
4071 gdk_window_get_frame_extents (window->frame, &frame_extents);
4073 gdk_window_get_frame_extents (widget->window, &frame_extents);
4074 x = frame_extents.x;
4075 y = frame_extents.y;
4076 gtk_window_get_size (window, &w, &h);
4080 /* We just say the frame has 0 size on all sides.
4081 * Not sure what else to do.
4083 gtk_window_compute_configure_request (window,
4086 x = frame_extents.x;
4087 y = frame_extents.y;
4088 w = frame_extents.width;
4089 h = frame_extents.height;
4092 switch (window->gravity)
4094 case GDK_GRAVITY_NORTH:
4095 case GDK_GRAVITY_CENTER:
4096 case GDK_GRAVITY_SOUTH:
4097 /* Find center of frame. */
4098 x += frame_extents.width / 2;
4099 /* Center client window on that point. */
4103 case GDK_GRAVITY_SOUTH_EAST:
4104 case GDK_GRAVITY_EAST:
4105 case GDK_GRAVITY_NORTH_EAST:
4106 /* Find right edge of frame */
4107 x += frame_extents.width;
4108 /* Align left edge of client at that point. */
4115 switch (window->gravity)
4117 case GDK_GRAVITY_WEST:
4118 case GDK_GRAVITY_CENTER:
4119 case GDK_GRAVITY_EAST:
4120 /* Find center of frame. */
4121 y += frame_extents.height / 2;
4122 /* Center client window there. */
4125 case GDK_GRAVITY_SOUTH_WEST:
4126 case GDK_GRAVITY_SOUTH:
4127 case GDK_GRAVITY_SOUTH_EAST:
4128 /* Find south edge of frame */
4129 y += frame_extents.height;
4130 /* Place bottom edge of client there */
4145 * gtk_window_reshow_with_initial_size:
4146 * @window: a #GtkWindow
4148 * Hides @window, then reshows it, resetting the
4149 * default size and position of the window. Used
4150 * by GUI builders only.
4153 gtk_window_reshow_with_initial_size (GtkWindow *window)
4157 g_return_if_fail (GTK_IS_WINDOW (window));
4159 widget = GTK_WIDGET (window);
4161 gtk_widget_hide (widget);
4162 gtk_widget_unrealize (widget);
4163 gtk_widget_show (widget);
4167 gtk_window_destroy (GtkObject *object)
4169 GtkWindow *window = GTK_WINDOW (object);
4171 toplevel_list = g_slist_remove (toplevel_list, window);
4173 if (window->transient_parent)
4174 gtk_window_set_transient_for (window, NULL);
4176 /* frees the icons */
4177 gtk_window_set_icon_list (window, NULL);
4179 if (window->has_user_ref_count)
4181 window->has_user_ref_count = FALSE;
4182 g_object_unref (window);
4186 gtk_window_group_remove_window (window->group, window);
4188 gtk_window_free_key_hash (window);
4190 GTK_OBJECT_CLASS (gtk_window_parent_class)->destroy (object);
4194 gtk_window_finalize (GObject *object)
4196 GtkWindow *window = GTK_WINDOW (object);
4197 GtkMnemonicHash *mnemonic_hash;
4199 g_free (window->title);
4200 g_free (window->wmclass_name);
4201 g_free (window->wmclass_class);
4202 g_free (window->wm_role);
4204 mnemonic_hash = gtk_window_get_mnemonic_hash (window, FALSE);
4206 _gtk_mnemonic_hash_free (mnemonic_hash);
4208 if (window->geometry_info)
4210 if (window->geometry_info->widget)
4211 g_signal_handlers_disconnect_by_func (window->geometry_info->widget,
4212 gtk_widget_destroyed,
4213 &window->geometry_info->widget);
4214 g_free (window->geometry_info);
4217 if (window->keys_changed_handler)
4219 g_source_remove (window->keys_changed_handler);
4220 window->keys_changed_handler = 0;
4225 g_signal_handlers_disconnect_by_func (window->screen,
4226 gtk_window_on_composited_changed, window);
4229 G_OBJECT_CLASS (gtk_window_parent_class)->finalize (object);
4233 gtk_window_show (GtkWidget *widget)
4235 GtkWindow *window = GTK_WINDOW (widget);
4236 GtkContainer *container = GTK_CONTAINER (window);
4237 gboolean need_resize;
4239 GTK_WIDGET_SET_FLAGS (widget, GTK_VISIBLE);
4241 need_resize = container->need_resize || !GTK_WIDGET_REALIZED (widget);
4242 container->need_resize = FALSE;
4246 GtkWindowGeometryInfo *info = gtk_window_get_geometry_info (window, TRUE);
4247 GtkAllocation allocation = { 0, 0 };
4248 GdkRectangle configure_request;
4249 GdkGeometry new_geometry;
4251 gboolean was_realized;
4253 /* We are going to go ahead and perform this configure request
4254 * and then emulate a configure notify by going ahead and
4255 * doing a size allocate. Sort of a synchronous
4256 * mini-copy of gtk_window_move_resize() here.
4258 gtk_window_compute_configure_request (window,
4263 /* We update this because we are going to go ahead
4264 * and gdk_window_resize() below, rather than
4267 info->last.configure_request.width = configure_request.width;
4268 info->last.configure_request.height = configure_request.height;
4270 /* and allocate the window - this is normally done
4271 * in move_resize in response to configure notify
4273 allocation.width = configure_request.width;
4274 allocation.height = configure_request.height;
4275 gtk_widget_size_allocate (widget, &allocation);
4277 /* Then we guarantee we have a realize */
4278 was_realized = FALSE;
4279 if (!GTK_WIDGET_REALIZED (widget))
4281 gtk_widget_realize (widget);
4282 was_realized = TRUE;
4285 /* Must be done after the windows are realized,
4286 * so that the decorations can be read
4288 gtk_decorated_window_calculate_frame_size (window);
4290 /* We only send configure request if we didn't just finish
4291 * creating the window; if we just created the window
4292 * then we created it with widget->allocation anyhow.
4295 gdk_window_move_resize (widget->window,
4296 configure_request.x,
4297 configure_request.y,
4298 configure_request.width,
4299 configure_request.height);
4302 gtk_container_check_resize (container);
4304 gtk_widget_map (widget);
4306 /* Try to make sure that we have some focused widget
4308 if (!window->focus_widget && !GTK_IS_PLUG (window))
4309 gtk_window_move_focus (window, GTK_DIR_TAB_FORWARD);
4312 gtk_grab_add (widget);
4316 gtk_window_hide (GtkWidget *widget)
4318 GtkWindow *window = GTK_WINDOW (widget);
4320 GTK_WIDGET_UNSET_FLAGS (widget, GTK_VISIBLE);
4321 gtk_widget_unmap (widget);
4324 gtk_grab_remove (widget);
4328 gtk_window_map (GtkWidget *widget)
4330 GtkWindow *window = GTK_WINDOW (widget);
4331 GtkWindowPrivate *priv = GTK_WINDOW_GET_PRIVATE (window);
4332 GdkWindow *toplevel;
4334 GTK_WIDGET_SET_FLAGS (widget, GTK_MAPPED);
4336 if (window->bin.child &&
4337 GTK_WIDGET_VISIBLE (window->bin.child) &&
4338 !GTK_WIDGET_MAPPED (window->bin.child))
4339 gtk_widget_map (window->bin.child);
4342 toplevel = window->frame;
4344 toplevel = widget->window;
4346 if (window->maximize_initially)
4347 gdk_window_maximize (toplevel);
4349 gdk_window_unmaximize (toplevel);
4351 if (window->stick_initially)
4352 gdk_window_stick (toplevel);
4354 gdk_window_unstick (toplevel);
4356 if (window->iconify_initially)
4357 gdk_window_iconify (toplevel);
4359 gdk_window_deiconify (toplevel);
4361 if (priv->fullscreen_initially)
4362 gdk_window_fullscreen (toplevel);
4364 gdk_window_unfullscreen (toplevel);
4366 gdk_window_set_keep_above (toplevel, priv->above_initially);
4368 gdk_window_set_keep_below (toplevel, priv->below_initially);
4370 /* No longer use the default settings */
4371 window->need_default_size = FALSE;
4372 window->need_default_position = FALSE;
4374 if (priv->reset_type_hint)
4376 /* We should only reset the type hint when the application
4377 * used gtk_window_set_type_hint() to change the hint.
4378 * Some applications use X directly to change the properties;
4379 * in that case, we shouldn't overwrite what they did.
4381 gdk_window_set_type_hint (widget->window, priv->type_hint);
4382 priv->reset_type_hint = FALSE;
4385 gdk_window_show (widget->window);
4388 gdk_window_show (window->frame);
4390 if (!disable_startup_notification)
4392 /* Do we have a custom startup-notification id? */
4393 if (priv->startup_id != NULL)
4395 /* Make sure we have a "real" id */
4396 if (!startup_id_is_fake (priv->startup_id))
4397 gdk_notify_startup_complete_with_id (priv->startup_id);
4399 priv->startup_id = NULL;
4401 else if (!sent_startup_notification)
4403 sent_startup_notification = TRUE;
4404 gdk_notify_startup_complete ();
4410 gtk_window_map_event (GtkWidget *widget,
4413 if (!GTK_WIDGET_MAPPED (widget))
4415 /* we should be be unmapped, but are getting a MapEvent, this may happen
4416 * to toplevel XWindows if mapping was intercepted by a window manager
4417 * and an unmap request occoured while the MapRequestEvent was still
4418 * being handled. we work around this situaiton here by re-requesting
4419 * the window being unmapped. more details can be found in:
4420 * http://bugzilla.gnome.org/show_bug.cgi?id=316180
4422 gdk_window_hide (widget->window);
4428 gtk_window_unmap (GtkWidget *widget)
4430 GtkWindow *window = GTK_WINDOW (widget);
4431 GtkWindowPrivate *priv = GTK_WINDOW_GET_PRIVATE (widget);
4432 GtkWindowGeometryInfo *info;
4433 GdkWindowState state;
4435 GTK_WIDGET_UNSET_FLAGS (widget, GTK_MAPPED);
4437 gdk_window_withdraw (window->frame);
4439 gdk_window_withdraw (widget->window);
4441 window->configure_request_count = 0;
4442 window->configure_notify_received = FALSE;
4444 /* on unmap, we reset the default positioning of the window,
4445 * so it's placed again, but we don't reset the default
4446 * size of the window, so it's remembered.
4448 window->need_default_position = TRUE;
4450 info = gtk_window_get_geometry_info (window, FALSE);
4453 info->initial_pos_set = FALSE;
4454 info->position_constraints_changed = FALSE;
4457 state = gdk_window_get_state (widget->window);
4458 window->iconify_initially = (state & GDK_WINDOW_STATE_ICONIFIED) != 0;
4459 window->maximize_initially = (state & GDK_WINDOW_STATE_MAXIMIZED) != 0;
4460 window->stick_initially = (state & GDK_WINDOW_STATE_STICKY) != 0;
4461 priv->above_initially = (state & GDK_WINDOW_STATE_ABOVE) != 0;
4462 priv->below_initially = (state & GDK_WINDOW_STATE_BELOW) != 0;
4466 gtk_window_realize (GtkWidget *widget)
4469 GdkWindow *parent_window;
4470 GdkWindowAttr attributes;
4471 gint attributes_mask;
4472 GtkWindowPrivate *priv;
4474 window = GTK_WINDOW (widget);
4475 priv = GTK_WINDOW_GET_PRIVATE (window);
4477 /* ensure widget tree is properly size allocated */
4478 if (widget->allocation.x == -1 &&
4479 widget->allocation.y == -1 &&
4480 widget->allocation.width == 1 &&
4481 widget->allocation.height == 1)
4483 GtkRequisition requisition;
4484 GtkAllocation allocation = { 0, 0, 200, 200 };
4486 gtk_widget_size_request (widget, &requisition);
4487 if (requisition.width || requisition.height)
4489 /* non-empty window */
4490 allocation.width = requisition.width;
4491 allocation.height = requisition.height;
4493 gtk_widget_size_allocate (widget, &allocation);
4495 _gtk_container_queue_resize (GTK_CONTAINER (widget));
4497 g_return_if_fail (!GTK_WIDGET_REALIZED (widget));
4500 GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED);
4502 switch (window->type)
4504 case GTK_WINDOW_TOPLEVEL:
4505 attributes.window_type = GDK_WINDOW_TOPLEVEL;
4507 case GTK_WINDOW_POPUP:
4508 attributes.window_type = GDK_WINDOW_TEMP;
4511 g_warning (G_STRLOC": Unknown window type %d!", window->type);
4515 attributes.title = window->title;
4516 attributes.wmclass_name = window->wmclass_name;
4517 attributes.wmclass_class = window->wmclass_class;
4518 attributes.wclass = GDK_INPUT_OUTPUT;
4519 attributes.visual = gtk_widget_get_visual (widget);
4520 attributes.colormap = gtk_widget_get_colormap (widget);
4522 if (window->has_frame)
4524 attributes.width = widget->allocation.width + window->frame_left + window->frame_right;
4525 attributes.height = widget->allocation.height + window->frame_top + window->frame_bottom;
4526 attributes.event_mask = (GDK_EXPOSURE_MASK |
4527 GDK_KEY_PRESS_MASK |
4528 GDK_ENTER_NOTIFY_MASK |
4529 GDK_LEAVE_NOTIFY_MASK |
4530 GDK_FOCUS_CHANGE_MASK |
4531 GDK_STRUCTURE_MASK |
4532 GDK_BUTTON_MOTION_MASK |
4533 GDK_POINTER_MOTION_HINT_MASK |
4534 GDK_BUTTON_PRESS_MASK |
4535 GDK_BUTTON_RELEASE_MASK);
4537 attributes_mask = GDK_WA_VISUAL | GDK_WA_COLORMAP;
4539 window->frame = gdk_window_new (gtk_widget_get_root_window (widget),
4540 &attributes, attributes_mask);
4542 if (priv->opacity_set)
4543 gdk_window_set_opacity (window->frame, priv->opacity);
4545 gdk_window_set_user_data (window->frame, widget);
4547 attributes.window_type = GDK_WINDOW_CHILD;
4548 attributes.x = window->frame_left;
4549 attributes.y = window->frame_top;
4551 attributes_mask = GDK_WA_X | GDK_WA_Y;
4553 parent_window = window->frame;
4555 g_signal_connect (window,
4557 G_CALLBACK (gtk_window_event),
4562 attributes_mask = 0;
4563 parent_window = gtk_widget_get_root_window (widget);
4566 attributes.width = widget->allocation.width;
4567 attributes.height = widget->allocation.height;
4568 attributes.event_mask = gtk_widget_get_events (widget);
4569 attributes.event_mask |= (GDK_EXPOSURE_MASK |
4570 GDK_KEY_PRESS_MASK |
4571 GDK_KEY_RELEASE_MASK |
4572 GDK_ENTER_NOTIFY_MASK |
4573 GDK_LEAVE_NOTIFY_MASK |
4574 GDK_FOCUS_CHANGE_MASK |
4575 GDK_STRUCTURE_MASK);
4576 attributes.type_hint = priv->type_hint;
4578 attributes_mask |= GDK_WA_VISUAL | GDK_WA_COLORMAP | GDK_WA_TYPE_HINT;
4579 attributes_mask |= (window->title ? GDK_WA_TITLE : 0);
4580 attributes_mask |= (window->wmclass_name ? GDK_WA_WMCLASS : 0);
4582 widget->window = gdk_window_new (parent_window, &attributes, attributes_mask);
4584 if (!window->has_frame && priv->opacity_set)
4585 gdk_window_set_opacity (widget->window, priv->opacity);
4587 gdk_window_enable_synchronized_configure (widget->window);
4589 gdk_window_set_user_data (widget->window, window);
4591 widget->style = gtk_style_attach (widget->style, widget->window);
4592 gtk_style_set_background (widget->style, widget->window, GTK_STATE_NORMAL);
4594 gtk_style_set_background (widget->style, window->frame, GTK_STATE_NORMAL);
4596 /* This is a bad hack to set the window background. */
4597 gtk_window_paint (widget, NULL);
4599 if (window->transient_parent &&
4600 GTK_WIDGET_REALIZED (window->transient_parent))
4601 gdk_window_set_transient_for (widget->window,
4602 GTK_WIDGET (window->transient_parent)->window);
4604 if (window->wm_role)
4605 gdk_window_set_role (widget->window, window->wm_role);
4607 if (!window->decorated)
4608 gdk_window_set_decorations (widget->window, 0);
4610 if (!priv->deletable)
4611 gdk_window_set_functions (widget->window, GDK_FUNC_ALL | GDK_FUNC_CLOSE);
4613 if (gtk_window_get_skip_pager_hint (window))
4614 gdk_window_set_skip_pager_hint (widget->window, TRUE);
4616 if (gtk_window_get_skip_taskbar_hint (window))
4617 gdk_window_set_skip_taskbar_hint (widget->window, TRUE);
4619 if (gtk_window_get_accept_focus (window))
4620 gdk_window_set_accept_focus (widget->window, TRUE);
4622 gdk_window_set_accept_focus (widget->window, FALSE);
4624 if (gtk_window_get_focus_on_map (window))
4625 gdk_window_set_focus_on_map (widget->window, TRUE);
4627 gdk_window_set_focus_on_map (widget->window, FALSE);
4630 gdk_window_set_modal_hint (widget->window, TRUE);
4632 gdk_window_set_modal_hint (widget->window, FALSE);
4634 if (priv->startup_id)
4636 #ifdef GDK_WINDOWING_X11
4637 guint32 timestamp = extract_time_from_startup_id (priv->startup_id);
4638 if (timestamp != GDK_CURRENT_TIME)
4639 gdk_x11_window_set_user_time (widget->window, timestamp);
4641 if (!startup_id_is_fake (priv->startup_id))
4642 gdk_window_set_startup_id (widget->window, priv->startup_id);
4646 gtk_window_realize_icon (window);
4650 gtk_window_unrealize (GtkWidget *widget)
4653 GtkWindowGeometryInfo *info;
4655 window = GTK_WINDOW (widget);
4657 /* On unrealize, we reset the size of the window such
4658 * that we will re-apply the default sizing stuff
4659 * next time we show the window.
4661 * Default positioning is reset on unmap, instead of unrealize.
4663 window->need_default_size = TRUE;
4664 info = gtk_window_get_geometry_info (window, FALSE);
4667 info->resize_width = -1;
4668 info->resize_height = -1;
4669 info->last.configure_request.x = 0;
4670 info->last.configure_request.y = 0;
4671 info->last.configure_request.width = -1;
4672 info->last.configure_request.height = -1;
4673 /* be sure we reset geom hints on re-realize */
4674 info->last.flags = 0;
4679 gdk_window_set_user_data (window->frame, NULL);
4680 gdk_window_destroy (window->frame);
4681 window->frame = NULL;
4685 gtk_window_unrealize_icon (window);
4687 (* GTK_WIDGET_CLASS (gtk_window_parent_class)->unrealize) (widget);
4691 gtk_window_size_request (GtkWidget *widget,
4692 GtkRequisition *requisition)
4697 window = GTK_WINDOW (widget);
4698 bin = GTK_BIN (window);
4700 requisition->width = GTK_CONTAINER (window)->border_width * 2;
4701 requisition->height = GTK_CONTAINER (window)->border_width * 2;
4703 if (bin->child && GTK_WIDGET_VISIBLE (bin->child))
4705 GtkRequisition child_requisition;
4707 gtk_widget_size_request (bin->child, &child_requisition);
4709 requisition->width += child_requisition.width;
4710 requisition->height += child_requisition.height;
4715 gtk_window_size_allocate (GtkWidget *widget,
4716 GtkAllocation *allocation)
4719 GtkAllocation child_allocation;
4721 window = GTK_WINDOW (widget);
4722 widget->allocation = *allocation;
4724 if (window->bin.child && GTK_WIDGET_VISIBLE (window->bin.child))
4726 child_allocation.x = GTK_CONTAINER (window)->border_width;
4727 child_allocation.y = GTK_CONTAINER (window)->border_width;
4728 child_allocation.width =
4729 MAX (1, (gint)allocation->width - child_allocation.x * 2);
4730 child_allocation.height =
4731 MAX (1, (gint)allocation->height - child_allocation.y * 2);
4733 gtk_widget_size_allocate (window->bin.child, &child_allocation);
4736 if (GTK_WIDGET_REALIZED (widget) && window->frame)
4738 gdk_window_resize (window->frame,
4739 allocation->width + window->frame_left + window->frame_right,
4740 allocation->height + window->frame_top + window->frame_bottom);
4745 gtk_window_event (GtkWidget *widget, GdkEvent *event)
4748 gboolean return_val;
4750 window = GTK_WINDOW (widget);
4752 if (window->frame && (event->any.window == window->frame))
4754 if ((event->type != GDK_KEY_PRESS) &&
4755 (event->type != GDK_KEY_RELEASE) &&
4756 (event->type != GDK_FOCUS_CHANGE))
4758 g_signal_stop_emission_by_name (widget, "event");
4760 g_signal_emit (widget, window_signals[FRAME_EVENT], 0, event, &return_val);
4765 g_object_unref (event->any.window);
4766 event->any.window = g_object_ref (widget->window);
4774 gtk_window_frame_event (GtkWindow *window, GdkEvent *event)
4776 GdkEventConfigure *configure_event;
4779 switch (event->type)
4782 configure_event = (GdkEventConfigure *)event;
4784 /* Invalidate the decorations */
4787 rect.width = configure_event->width;
4788 rect.height = configure_event->height;
4790 gdk_window_invalidate_rect (window->frame, &rect, FALSE);
4792 /* Pass on the (modified) configure event */
4793 configure_event->width -= window->frame_left + window->frame_right;
4794 configure_event->height -= window->frame_top + window->frame_bottom;
4795 return gtk_window_configure_event (GTK_WIDGET (window), configure_event);
4804 gtk_window_configure_event (GtkWidget *widget,
4805 GdkEventConfigure *event)
4807 GtkWindow *window = GTK_WINDOW (widget);
4808 gboolean expected_reply = window->configure_request_count > 0;
4810 /* window->configure_request_count incremented for each
4811 * configure request, and decremented to a min of 0 for
4812 * each configure notify.
4814 * All it means is that we know we will get at least
4815 * window->configure_request_count more configure notifies.
4816 * We could get more configure notifies than that; some
4817 * of the configure notifies we get may be unrelated to
4818 * the configure requests. But we will get at least
4819 * window->configure_request_count notifies.
4822 if (window->configure_request_count > 0)
4824 window->configure_request_count -= 1;
4825 gdk_window_thaw_toplevel_updates_libgtk_only (widget->window);
4828 /* As an optimization, we avoid a resize when possible.
4830 * The only times we can avoid a resize are:
4831 * - we know only the position changed, not the size
4832 * - we know we have made more requests and so will get more
4833 * notifies and can wait to resize when we get them
4836 if (!expected_reply &&
4837 (widget->allocation.width == event->width &&
4838 widget->allocation.height == event->height))
4840 gdk_window_configure_finished (widget->window);
4845 * If we do need to resize, we do that by:
4846 * - filling in widget->allocation with the new size
4847 * - setting configure_notify_received to TRUE
4848 * for use in gtk_window_move_resize()
4849 * - queueing a resize, leading to invocation of
4850 * gtk_window_move_resize() in an idle handler
4854 window->configure_notify_received = TRUE;
4856 widget->allocation.width = event->width;
4857 widget->allocation.height = event->height;
4859 _gtk_container_queue_resize (GTK_CONTAINER (widget));
4864 /* the accel_key and accel_mods fields of the key have to be setup
4865 * upon calling this function. it'll then return whether that key
4866 * is at all used as accelerator, and if so will OR in the
4867 * accel_flags member of the key.
4870 _gtk_window_query_nonaccels (GtkWindow *window,
4872 GdkModifierType accel_mods)
4874 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
4876 /* movement keys are considered locked accels */
4879 static const guint bindings[] = {
4880 GDK_space, GDK_KP_Space, GDK_Return, GDK_KP_Enter, GDK_Up, GDK_KP_Up, GDK_Down, GDK_KP_Down,
4881 GDK_Left, GDK_KP_Left, GDK_Right, GDK_KP_Right, GDK_Tab, GDK_KP_Tab, GDK_ISO_Left_Tab,
4885 for (i = 0; i < G_N_ELEMENTS (bindings); i++)
4886 if (bindings[i] == accel_key)
4890 /* mnemonics are considered locked accels */
4891 if (accel_mods == window->mnemonic_modifier)
4893 GtkMnemonicHash *mnemonic_hash = gtk_window_get_mnemonic_hash (window, FALSE);
4894 if (mnemonic_hash && _gtk_mnemonic_hash_lookup (mnemonic_hash, accel_key))
4902 * gtk_window_propagate_key_event:
4903 * @window: a #GtkWindow
4904 * @event: a #GdkEventKey
4906 * Propagate a key press or release event to the focus widget and
4907 * up the focus container chain until a widget handles @event.
4908 * This is normally called by the default ::key_press_event and
4909 * ::key_release_event handlers for toplevel windows,
4910 * however in some cases it may be useful to call this directly when
4911 * overriding the standard key handling for a toplevel window.
4913 * Return value: %TRUE if a widget in the focus chain handled the event.
4916 gtk_window_propagate_key_event (GtkWindow *window,
4919 gboolean handled = FALSE;
4920 GtkWidget *widget, *focus;
4922 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
4924 widget = GTK_WIDGET (window);
4925 focus = window->focus_widget;
4927 g_object_ref (focus);
4930 focus && focus != widget &&
4931 gtk_widget_get_toplevel (focus) == widget)
4935 if (GTK_WIDGET_IS_SENSITIVE (focus))
4936 handled = gtk_widget_event (focus, (GdkEvent*) event);
4938 parent = focus->parent;
4940 g_object_ref (parent);
4942 g_object_unref (focus);
4948 g_object_unref (focus);
4954 gtk_window_key_press_event (GtkWidget *widget,
4957 GtkWindow *window = GTK_WINDOW (widget);
4958 gboolean handled = FALSE;
4960 /* handle mnemonics and accelerators */
4962 handled = gtk_window_activate_key (window, event);
4964 /* handle focus widget key events */
4966 handled = gtk_window_propagate_key_event (window, event);
4968 /* Chain up, invokes binding set */
4970 handled = GTK_WIDGET_CLASS (gtk_window_parent_class)->key_press_event (widget, event);
4976 gtk_window_key_release_event (GtkWidget *widget,
4979 GtkWindow *window = GTK_WINDOW (widget);
4980 gboolean handled = FALSE;
4982 /* handle focus widget key events */
4984 handled = gtk_window_propagate_key_event (window, event);
4986 /* Chain up, invokes binding set */
4988 handled = GTK_WIDGET_CLASS (gtk_window_parent_class)->key_release_event (widget, event);
4994 gtk_window_real_activate_default (GtkWindow *window)
4996 gtk_window_activate_default (window);
5000 gtk_window_real_activate_focus (GtkWindow *window)
5002 gtk_window_activate_focus (window);
5006 gtk_window_move_focus (GtkWindow *window,
5007 GtkDirectionType dir)
5009 gtk_widget_child_focus (GTK_WIDGET (window), dir);
5011 if (!GTK_CONTAINER (window)->focus_child)
5012 gtk_window_set_focus (window, NULL);
5016 gtk_window_enter_notify_event (GtkWidget *widget,
5017 GdkEventCrossing *event)
5023 gtk_window_leave_notify_event (GtkWidget *widget,
5024 GdkEventCrossing *event)
5030 do_focus_change (GtkWidget *widget,
5033 GdkEvent *fevent = gdk_event_new (GDK_FOCUS_CHANGE);
5035 g_object_ref (widget);
5038 GTK_WIDGET_SET_FLAGS (widget, GTK_HAS_FOCUS);
5040 GTK_WIDGET_UNSET_FLAGS (widget, GTK_HAS_FOCUS);
5042 fevent->focus_change.type = GDK_FOCUS_CHANGE;
5043 fevent->focus_change.window = widget->window;
5045 g_object_ref (widget->window);
5046 fevent->focus_change.in = in;
5048 gtk_widget_event (widget, fevent);
5050 g_object_notify (G_OBJECT (widget), "has-focus");
5052 g_object_unref (widget);
5053 gdk_event_free (fevent);
5057 gtk_window_focus_in_event (GtkWidget *widget,
5058 GdkEventFocus *event)
5060 GtkWindow *window = GTK_WINDOW (widget);
5062 /* It appears spurious focus in events can occur when
5063 * the window is hidden. So we'll just check to see if
5064 * the window is visible before actually handling the
5067 if (GTK_WIDGET_VISIBLE (widget))
5069 _gtk_window_set_has_toplevel_focus (window, TRUE);
5070 _gtk_window_set_is_active (window, TRUE);
5077 gtk_window_focus_out_event (GtkWidget *widget,
5078 GdkEventFocus *event)
5080 GtkWindow *window = GTK_WINDOW (widget);
5082 _gtk_window_set_has_toplevel_focus (window, FALSE);
5083 _gtk_window_set_is_active (window, FALSE);
5088 static GdkAtom atom_rcfiles = GDK_NONE;
5089 static GdkAtom atom_iconthemes = GDK_NONE;
5092 send_client_message_to_embedded_windows (GtkWidget *widget,
5093 GdkAtom message_type)
5095 GList *embedded_windows;
5097 embedded_windows = g_object_get_qdata (G_OBJECT (widget), quark_gtk_embedded);
5098 if (embedded_windows)
5100 GdkEvent *send_event = gdk_event_new (GDK_CLIENT_EVENT);
5103 for (i = 0; i < 5; i++)
5104 send_event->client.data.l[i] = 0;
5105 send_event->client.data_format = 32;
5106 send_event->client.message_type = message_type;
5108 while (embedded_windows)
5110 guint xid = GPOINTER_TO_UINT (embedded_windows->data);
5111 gdk_event_send_client_message_for_display (gtk_widget_get_display (widget), send_event, xid);
5112 embedded_windows = embedded_windows->next;
5115 gdk_event_free (send_event);
5120 gtk_window_client_event (GtkWidget *widget,
5121 GdkEventClient *event)
5125 atom_rcfiles = gdk_atom_intern_static_string ("_GTK_READ_RCFILES");
5126 atom_iconthemes = gdk_atom_intern_static_string ("_GTK_LOAD_ICONTHEMES");
5129 if (event->message_type == atom_rcfiles)
5131 send_client_message_to_embedded_windows (widget, atom_rcfiles);
5132 gtk_rc_reparse_all_for_settings (gtk_widget_get_settings (widget), FALSE);
5135 if (event->message_type == atom_iconthemes)
5137 send_client_message_to_embedded_windows (widget, atom_iconthemes);
5138 _gtk_icon_theme_check_reload (gtk_widget_get_display (widget));
5145 gtk_window_check_resize (GtkContainer *container)
5147 GtkWindow *window = GTK_WINDOW (container);
5149 if (GTK_WIDGET_VISIBLE (container))
5150 gtk_window_move_resize (window);
5154 gtk_window_focus (GtkWidget *widget,
5155 GtkDirectionType direction)
5159 GtkContainer *container;
5160 GtkWidget *old_focus_child;
5163 container = GTK_CONTAINER (widget);
5164 window = GTK_WINDOW (widget);
5165 bin = GTK_BIN (widget);
5167 old_focus_child = container->focus_child;
5169 /* We need a special implementation here to deal properly with wrapping
5170 * around in the tab chain without the danger of going into an
5173 if (old_focus_child)
5175 if (gtk_widget_child_focus (old_focus_child, direction))
5179 if (window->focus_widget)
5181 if (direction == GTK_DIR_LEFT ||
5182 direction == GTK_DIR_RIGHT ||
5183 direction == GTK_DIR_UP ||
5184 direction == GTK_DIR_DOWN)
5189 /* Wrapped off the end, clear the focus setting for the toplpevel */
5190 parent = window->focus_widget->parent;
5193 gtk_container_set_focus_child (GTK_CONTAINER (parent), NULL);
5194 parent = GTK_WIDGET (parent)->parent;
5197 gtk_window_set_focus (GTK_WINDOW (container), NULL);
5200 /* Now try to focus the first widget in the window */
5203 if (gtk_widget_child_focus (bin->child, direction))
5211 gtk_window_real_set_focus (GtkWindow *window,
5214 GtkWidget *old_focus = window->focus_widget;
5215 gboolean had_default = FALSE;
5216 gboolean focus_had_default = FALSE;
5217 gboolean old_focus_had_default = FALSE;
5221 g_object_ref (old_focus);
5222 g_object_freeze_notify (G_OBJECT (old_focus));
5223 old_focus_had_default = GTK_WIDGET_HAS_DEFAULT (old_focus);
5227 g_object_ref (focus);
5228 g_object_freeze_notify (G_OBJECT (focus));
5229 focus_had_default = GTK_WIDGET_HAS_DEFAULT (focus);
5232 if (window->default_widget)
5233 had_default = GTK_WIDGET_HAS_DEFAULT (window->default_widget);
5235 if (window->focus_widget)
5237 if (GTK_WIDGET_RECEIVES_DEFAULT (window->focus_widget) &&
5238 (window->focus_widget != window->default_widget))
5240 GTK_WIDGET_UNSET_FLAGS (window->focus_widget, GTK_HAS_DEFAULT);
5241 gtk_widget_queue_draw (window->focus_widget);
5243 if (window->default_widget)
5244 GTK_WIDGET_SET_FLAGS (window->default_widget, GTK_HAS_DEFAULT);
5247 window->focus_widget = NULL;
5249 if (window->has_focus)
5250 do_focus_change (old_focus, FALSE);
5252 g_object_notify (G_OBJECT (old_focus), "is-focus");
5255 /* The above notifications may have set a new focus widget,
5256 * if so, we don't want to override it.
5258 if (focus && !window->focus_widget)
5260 window->focus_widget = focus;
5262 if (GTK_WIDGET_RECEIVES_DEFAULT (window->focus_widget) &&
5263 (window->focus_widget != window->default_widget))
5265 if (GTK_WIDGET_CAN_DEFAULT (window->focus_widget))
5266 GTK_WIDGET_SET_FLAGS (window->focus_widget, GTK_HAS_DEFAULT);
5268 if (window->default_widget)
5269 GTK_WIDGET_UNSET_FLAGS (window->default_widget, GTK_HAS_DEFAULT);
5272 if (window->has_focus)
5273 do_focus_change (window->focus_widget, TRUE);
5275 g_object_notify (G_OBJECT (window->focus_widget), "is-focus");
5278 /* If the default widget changed, a redraw will have been queued
5279 * on the old and new default widgets by gtk_window_set_default(), so
5280 * we only have to worry about the case where it didn't change.
5281 * We'll sometimes queue a draw twice on the new widget but that
5284 if (window->default_widget &&
5285 (had_default != GTK_WIDGET_HAS_DEFAULT (window->default_widget)))
5286 gtk_widget_queue_draw (window->default_widget);
5290 if (old_focus_had_default != GTK_WIDGET_HAS_DEFAULT (old_focus))
5291 gtk_widget_queue_draw (old_focus);
5293 g_object_thaw_notify (G_OBJECT (old_focus));
5294 g_object_unref (old_focus);
5298 if (focus_had_default != GTK_WIDGET_HAS_DEFAULT (focus))
5299 gtk_widget_queue_draw (focus);
5301 g_object_thaw_notify (G_OBJECT (focus));
5302 g_object_unref (focus);
5307 * _gtk_window_unset_focus_and_default:
5308 * @window: a #GtkWindow
5309 * @widget: a widget inside of @window
5311 * Checks whether the focus and default widgets of @window are
5312 * @widget or a descendent of @widget, and if so, unset them.
5315 _gtk_window_unset_focus_and_default (GtkWindow *window,
5321 g_object_ref (window);
5322 g_object_ref (widget);
5324 if (GTK_CONTAINER (widget->parent)->focus_child == widget)
5326 child = window->focus_widget;
5328 while (child && child != widget)
5329 child = child->parent;
5331 if (child == widget)
5332 gtk_window_set_focus (GTK_WINDOW (window), NULL);
5335 child = window->default_widget;
5337 while (child && child != widget)
5338 child = child->parent;
5340 if (child == widget)
5341 gtk_window_set_default (window, NULL);
5343 g_object_unref (widget);
5344 g_object_unref (window);
5347 /*********************************
5348 * Functions related to resizing *
5349 *********************************/
5351 /* This function doesn't constrain to geometry hints */
5353 gtk_window_compute_configure_request_size (GtkWindow *window,
5357 GtkRequisition requisition;
5358 GtkWindowGeometryInfo *info;
5362 * - we've done a size request
5365 widget = GTK_WIDGET (window);
5367 info = gtk_window_get_geometry_info (window, FALSE);
5369 if (window->need_default_size)
5371 gtk_widget_get_child_requisition (widget, &requisition);
5373 /* Default to requisition */
5374 *width = requisition.width;
5375 *height = requisition.height;
5377 /* If window is empty so requests 0, default to random nonzero size */
5378 if (*width == 0 && *height == 0)
5384 /* Override requisition with default size */
5388 gint base_width = 0;
5389 gint base_height = 0;
5391 gint min_height = 0;
5393 gint height_inc = 1;
5395 if (info->default_is_geometry &&
5396 (info->default_width > 0 || info->default_height > 0))
5398 GdkGeometry geometry;
5401 gtk_window_compute_hints (window, &geometry, &flags);
5403 if (flags & GDK_HINT_BASE_SIZE)
5405 base_width = geometry.base_width;
5406 base_height = geometry.base_height;
5408 if (flags & GDK_HINT_MIN_SIZE)
5410 min_width = geometry.min_width;
5411 min_height = geometry.min_height;
5413 if (flags & GDK_HINT_RESIZE_INC)
5415 width_inc = geometry.width_inc;
5416 height_inc = geometry.height_inc;
5420 if (info->default_width > 0)
5421 *width = MAX (info->default_width * width_inc + base_width, min_width);
5423 if (info->default_height > 0)
5424 *height = MAX (info->default_height * height_inc + base_height, min_height);
5429 /* Default to keeping current size */
5430 *width = widget->allocation.width;
5431 *height = widget->allocation.height;
5434 /* Override any size with gtk_window_resize() values */
5437 if (info->resize_width > 0)
5438 *width = info->resize_width;
5440 if (info->resize_height > 0)
5441 *height = info->resize_height;
5445 static GtkWindowPosition
5446 get_effective_position (GtkWindow *window)
5448 GtkWindowPosition pos = window->position;
5449 if (pos == GTK_WIN_POS_CENTER_ON_PARENT &&
5450 (window->transient_parent == NULL ||
5451 !GTK_WIDGET_MAPPED (window->transient_parent)))
5452 pos = GTK_WIN_POS_NONE;
5458 get_center_monitor_of_window (GtkWindow *window)
5460 /* We could try to sort out the relative positions of the monitors and
5461 * stuff, or we could just be losers and assume you have a row
5462 * or column of monitors.
5464 return gdk_screen_get_n_monitors (gtk_window_check_screen (window)) / 2;
5468 get_monitor_containing_pointer (GtkWindow *window)
5472 GdkScreen *window_screen;
5473 GdkScreen *pointer_screen;
5475 window_screen = gtk_window_check_screen (window);
5476 gdk_display_get_pointer (gdk_screen_get_display (window_screen),
5480 if (pointer_screen == window_screen)
5481 monitor_num = gdk_screen_get_monitor_at_point (pointer_screen, px, py);
5489 center_window_on_monitor (GtkWindow *window,
5495 GdkRectangle monitor;
5498 monitor_num = get_monitor_containing_pointer (window);
5500 if (monitor_num == -1)
5501 monitor_num = get_center_monitor_of_window (window);
5503 gdk_screen_get_monitor_geometry (gtk_window_check_screen (window),
5504 monitor_num, &monitor);
5506 *x = (monitor.width - w) / 2 + monitor.x;
5507 *y = (monitor.height - h) / 2 + monitor.y;
5509 /* Be sure we aren't off the monitor, ignoring _NET_WM_STRUT
5510 * and WM decorations.
5519 clamp_window_to_rectangle (gint *x,
5523 const GdkRectangle *rect)
5525 gint outside_w, outside_h;
5527 outside_w = (*x + w) - (rect->x + rect->width);
5531 outside_h = (*y + h) - (rect->y + rect->height);
5535 /* if larger than the screen, center on the screen. */
5537 *x += (rect->x - *x) / 2;
5539 *y += (rect->y - *y) / 2;
5544 gtk_window_compute_configure_request (GtkWindow *window,
5545 GdkRectangle *request,
5546 GdkGeometry *geometry,
5549 GdkGeometry new_geometry;
5553 GtkWindowPosition pos;
5554 GtkWidget *parent_widget;
5555 GtkWindowGeometryInfo *info;
5559 widget = GTK_WIDGET (window);
5561 screen = gtk_window_check_screen (window);
5563 gtk_widget_size_request (widget, NULL);
5564 gtk_window_compute_configure_request_size (window, (guint *)&w, (guint *)&h);
5566 gtk_window_compute_hints (window, &new_geometry, &new_flags);
5567 gtk_window_constrain_size (window,
5568 &new_geometry, new_flags,
5572 parent_widget = (GtkWidget*) window->transient_parent;
5574 pos = get_effective_position (window);
5575 info = gtk_window_get_geometry_info (window, FALSE);
5577 /* by default, don't change position requested */
5580 x = info->last.configure_request.x;
5581 y = info->last.configure_request.y;
5590 if (window->need_default_position)
5593 /* FIXME this all interrelates with window gravity.
5594 * For most of them I think we want to set GRAVITY_CENTER.
5596 * Not sure how to go about that.
5601 /* here we are only handling CENTER_ALWAYS
5602 * as it relates to default positioning,
5603 * where it's equivalent to simply CENTER
5605 case GTK_WIN_POS_CENTER_ALWAYS:
5606 case GTK_WIN_POS_CENTER:
5607 center_window_on_monitor (window, w, h, &x, &y);
5610 case GTK_WIN_POS_CENTER_ON_PARENT:
5613 GdkRectangle monitor;
5616 g_assert (GTK_WIDGET_MAPPED (parent_widget)); /* established earlier */
5618 if (parent_widget->window != NULL)
5619 monitor_num = gdk_screen_get_monitor_at_window (screen,
5620 parent_widget->window);
5624 gdk_window_get_origin (parent_widget->window,
5627 x = ox + (parent_widget->allocation.width - w) / 2;
5628 y = oy + (parent_widget->allocation.height - h) / 2;
5630 /* Clamp onto current monitor, ignoring _NET_WM_STRUT and
5631 * WM decorations. If parent wasn't on a monitor, just
5634 if (monitor_num >= 0)
5636 gdk_screen_get_monitor_geometry (screen, monitor_num, &monitor);
5637 clamp_window_to_rectangle (&x, &y, w, h, &monitor);
5642 case GTK_WIN_POS_MOUSE:
5644 gint screen_width = gdk_screen_get_width (screen);
5645 gint screen_height = gdk_screen_get_height (screen);
5647 GdkRectangle monitor;
5648 GdkScreen *pointer_screen;
5651 gdk_display_get_pointer (gdk_screen_get_display (screen),
5655 if (pointer_screen == screen)
5656 monitor_num = gdk_screen_get_monitor_at_point (screen, px, py);
5662 x = CLAMP (x, 0, screen_width - w);
5663 y = CLAMP (y, 0, screen_height - h);
5665 /* Clamp onto current monitor, ignoring _NET_WM_STRUT and
5666 * WM decorations. Don't try to figure out what's going
5667 * on if the mouse wasn't inside a monitor.
5669 if (monitor_num >= 0)
5671 gdk_screen_get_monitor_geometry (screen, monitor_num, &monitor);
5672 clamp_window_to_rectangle (&x, &y, w, h, &monitor);
5680 } /* if (window->need_default_position) */
5682 if (window->need_default_position && info &&
5683 info->initial_pos_set)
5685 x = info->initial_x;
5686 y = info->initial_y;
5687 gtk_window_constrain_position (window, w, h, &x, &y);
5693 request->height = h;
5696 *geometry = new_geometry;
5702 gtk_window_constrain_position (GtkWindow *window,
5708 /* See long comments in gtk_window_move_resize()
5709 * on when it's safe to call this function.
5711 if (window->position == GTK_WIN_POS_CENTER_ALWAYS)
5713 gint center_x, center_y;
5715 center_window_on_monitor (window, new_width, new_height, ¢er_x, ¢er_y);
5723 gtk_window_move_resize (GtkWindow *window)
5727 * First we determine whether any information has changed that would
5728 * cause us to revise our last configure request. If we would send
5729 * a different configure request from last time, then
5730 * configure_request_size_changed = TRUE or
5731 * configure_request_pos_changed = TRUE. configure_request_size_changed
5732 * may be true due to new hints, a gtk_window_resize(), or whatever.
5733 * configure_request_pos_changed may be true due to gtk_window_set_position()
5734 * or gtk_window_move().
5736 * If the configure request has changed, we send off a new one. To
5737 * ensure GTK+ invariants are maintained (resize queue does what it
5738 * should), we go ahead and size_allocate the requested size in this
5741 * If the configure request has not changed, we don't ever resend
5742 * it, because it could mean fighting the user or window manager.
5745 * To prepare the configure request, we come up with a base size/pos:
5746 * - the one from gtk_window_move()/gtk_window_resize()
5747 * - else default_width, default_height if we haven't ever
5749 * - else the size request if we haven't ever been mapped,
5750 * as a substitute default size
5751 * - else the current size of the window, as received from
5752 * configure notifies (i.e. the current allocation)
5754 * If GTK_WIN_POS_CENTER_ALWAYS is active, we constrain
5755 * the position request to be centered.
5758 GtkContainer *container;
5759 GtkWindowGeometryInfo *info;
5760 GdkGeometry new_geometry;
5762 GdkRectangle new_request;
5763 gboolean configure_request_size_changed;
5764 gboolean configure_request_pos_changed;
5765 gboolean hints_changed; /* do we need to send these again */
5766 GtkWindowLastGeometryInfo saved_last_info;
5768 widget = GTK_WIDGET (window);
5769 container = GTK_CONTAINER (widget);
5770 info = gtk_window_get_geometry_info (window, TRUE);
5772 configure_request_size_changed = FALSE;
5773 configure_request_pos_changed = FALSE;
5775 gtk_window_compute_configure_request (window, &new_request,
5776 &new_geometry, &new_flags);
5778 /* This check implies the invariant that we never set info->last
5779 * without setting the hints and sending off a configure request.
5781 * If we change info->last without sending the request, we may
5784 if (info->last.configure_request.x != new_request.x ||
5785 info->last.configure_request.y != new_request.y)
5786 configure_request_pos_changed = TRUE;
5788 if ((info->last.configure_request.width != new_request.width ||
5789 info->last.configure_request.height != new_request.height))
5790 configure_request_size_changed = TRUE;
5792 hints_changed = FALSE;
5794 if (!gtk_window_compare_hints (&info->last.geometry, info->last.flags,
5795 &new_geometry, new_flags))
5797 hints_changed = TRUE;
5800 /* Position Constraints
5801 * ====================
5803 * POS_CENTER_ALWAYS is conceptually a constraint rather than
5804 * a default. The other POS_ values are used only when the
5805 * window is shown, not after that.
5807 * However, we can't implement a position constraint as
5808 * "anytime the window size changes, center the window"
5809 * because this may well end up fighting the WM or user. In
5810 * fact it gets in an infinite loop with at least one WM.
5812 * Basically, applications are in no way in a position to
5813 * constrain the position of a window, with one exception:
5814 * override redirect windows. (Really the intended purpose
5815 * of CENTER_ALWAYS anyhow, I would think.)
5817 * So the way we implement this "constraint" is to say that when WE
5818 * cause a move or resize, i.e. we make a configure request changing
5819 * window size, we recompute the CENTER_ALWAYS position to reflect
5820 * the new window size, and include it in our request. Also, if we
5821 * just turned on CENTER_ALWAYS we snap to center with a new
5822 * request. Otherwise, if we are just NOTIFIED of a move or resize
5823 * done by someone else e.g. the window manager, we do NOT send a
5824 * new configure request.
5826 * For override redirect windows, this works fine; all window
5827 * sizes are from our configure requests. For managed windows,
5828 * it is at least semi-sane, though who knows what the
5829 * app author is thinking.
5832 /* This condition should be kept in sync with the condition later on
5833 * that determines whether we send a configure request. i.e. we
5834 * should do this position constraining anytime we were going to
5835 * send a configure request anyhow, plus when constraints have
5838 if (configure_request_pos_changed ||
5839 configure_request_size_changed ||
5841 info->position_constraints_changed)
5843 /* We request the constrained position if:
5844 * - we were changing position, and need to clamp
5845 * the change to the constraint
5846 * - we're changing the size anyway
5847 * - set_position() was called to toggle CENTER_ALWAYS on
5850 gtk_window_constrain_position (window,
5856 /* Update whether we need to request a move */
5857 if (info->last.configure_request.x != new_request.x ||
5858 info->last.configure_request.y != new_request.y)
5859 configure_request_pos_changed = TRUE;
5861 configure_request_pos_changed = FALSE;
5865 if (window->type == GTK_WINDOW_TOPLEVEL)
5867 int notify_x, notify_y;
5869 /* this is the position from the last configure notify */
5870 gdk_window_get_position (widget->window, ¬ify_x, ¬ify_y);
5872 g_message ("--- %s ---\n"
5873 "last : %d,%d\t%d x %d\n"
5874 "this : %d,%d\t%d x %d\n"
5875 "alloc : %d,%d\t%d x %d\n"
5877 "resize: \t%d x %d\n"
5878 "size_changed: %d pos_changed: %d hints_changed: %d\n"
5879 "configure_notify_received: %d\n"
5880 "configure_request_count: %d\n"
5881 "position_constraints_changed: %d\n",
5882 window->title ? window->title : "(no title)",
5883 info->last.configure_request.x,
5884 info->last.configure_request.y,
5885 info->last.configure_request.width,
5886 info->last.configure_request.height,
5892 widget->allocation.width,
5893 widget->allocation.height,
5894 widget->requisition.width,
5895 widget->requisition.height,
5897 info->resize_height,
5898 configure_request_pos_changed,
5899 configure_request_size_changed,
5901 window->configure_notify_received,
5902 window->configure_request_count,
5903 info->position_constraints_changed);
5907 saved_last_info = info->last;
5908 info->last.geometry = new_geometry;
5909 info->last.flags = new_flags;
5910 info->last.configure_request = new_request;
5912 /* need to set PPosition so the WM will look at our position,
5913 * but we don't want to count PPosition coming and going as a hints
5914 * change for future iterations. So we saved info->last prior to
5918 /* Also, if the initial position was explicitly set, then we always
5919 * toggle on PPosition. This makes gtk_window_move(window, 0, 0)
5923 /* Also, we toggle on PPosition if GTK_WIN_POS_ is in use and
5924 * this is an initial map
5927 if ((configure_request_pos_changed ||
5928 info->initial_pos_set ||
5929 (window->need_default_position &&
5930 get_effective_position (window) != GTK_WIN_POS_NONE)) &&
5931 (new_flags & GDK_HINT_POS) == 0)
5933 new_flags |= GDK_HINT_POS;
5934 hints_changed = TRUE;
5937 /* Set hints if necessary
5940 gdk_window_set_geometry_hints (widget->window,
5944 /* handle resizing/moving and widget tree allocation
5946 if (window->configure_notify_received)
5948 GtkAllocation allocation;
5950 /* If we have received a configure event since
5951 * the last time in this function, we need to
5952 * accept our new size and size_allocate child widgets.
5953 * (see gtk_window_configure_event() for more details).
5955 * 1 or more configure notifies may have been received.
5956 * Also, configure_notify_received will only be TRUE
5957 * if all expected configure notifies have been received
5958 * (one per configure request), as an optimization.
5961 window->configure_notify_received = FALSE;
5963 /* gtk_window_configure_event() filled in widget->allocation */
5964 allocation = widget->allocation;
5965 gtk_widget_size_allocate (widget, &allocation);
5967 gdk_window_process_updates (widget->window, TRUE);
5969 gdk_window_configure_finished (widget->window);
5971 /* If the configure request changed, it means that
5973 * 1) coincidentally changed hints or widget properties
5974 * impacting the configure request before getting
5975 * a configure notify, or
5976 * 2) some broken widget is changing its size request
5977 * during size allocation, resulting in
5978 * a false appearance of changed configure request.
5980 * For 1), we could just go ahead and ask for the
5981 * new size right now, but doing that for 2)
5982 * might well be fighting the user (and can even
5983 * trigger a loop). Since we really don't want to
5984 * do that, we requeue a resize in hopes that
5985 * by the time it gets handled, the child has seen
5986 * the light and is willing to go along with the
5987 * new size. (this happens for the zvt widget, since
5988 * the size_allocate() above will have stored the
5989 * requisition corresponding to the new size in the
5992 * This doesn't buy us anything for 1), but it shouldn't
5993 * hurt us too badly, since it is what would have
5994 * happened if we had gotten the configure event before
5995 * the new size had been set.
5998 if (configure_request_size_changed ||
5999 configure_request_pos_changed)
6001 /* Don't change the recorded last info after all, because we
6002 * haven't actually updated to the new info yet - we decided
6003 * to postpone our configure request until later.
6005 info->last = saved_last_info;
6007 gtk_widget_queue_resize (widget); /* migth recurse for GTK_RESIZE_IMMEDIATE */
6010 return; /* Bail out, we didn't really process the move/resize */
6012 else if ((configure_request_size_changed || hints_changed) &&
6013 (widget->allocation.width != new_request.width ||
6014 widget->allocation.height != new_request.height))
6017 /* We are in one of the following situations:
6018 * A. configure_request_size_changed
6019 * our requisition has changed and we need a different window size,
6020 * so we request it from the window manager.
6021 * B. !configure_request_size_changed && hints_changed
6022 * the window manager rejects our size, but we have just changed the
6023 * window manager hints, so there's a chance our request will
6024 * be honoured this time, so we try again.
6026 * However, if the new requisition is the same as the current allocation,
6027 * we don't request it again, since we won't get a ConfigureNotify back from
6028 * the window manager unless it decides to change our requisition. If
6029 * we don't get the ConfigureNotify back, the resize queue will never be run.
6032 /* Now send the configure request */
6033 if (configure_request_pos_changed)
6037 gdk_window_move_resize (window->frame,
6038 new_request.x - window->frame_left,
6039 new_request.y - window->frame_top,
6040 new_request.width + window->frame_left + window->frame_right,
6041 new_request.height + window->frame_top + window->frame_bottom);
6042 gdk_window_resize (widget->window,
6043 new_request.width, new_request.height);
6046 gdk_window_move_resize (widget->window,
6047 new_request.x, new_request.y,
6048 new_request.width, new_request.height);
6050 else /* only size changed */
6053 gdk_window_resize (window->frame,
6054 new_request.width + window->frame_left + window->frame_right,
6055 new_request.height + window->frame_top + window->frame_bottom);
6056 gdk_window_resize (widget->window,
6057 new_request.width, new_request.height);
6060 if (window->type == GTK_WINDOW_POPUP)
6062 GtkAllocation allocation;
6064 /* Directly size allocate for override redirect (popup) windows. */
6067 allocation.width = new_request.width;
6068 allocation.height = new_request.height;
6070 gtk_widget_size_allocate (widget, &allocation);
6072 gdk_window_process_updates (widget->window, TRUE);
6074 if (container->resize_mode == GTK_RESIZE_QUEUE)
6075 gtk_widget_queue_draw (widget);
6079 /* Increment the number of have-not-yet-received-notify requests */
6080 window->configure_request_count += 1;
6081 gdk_window_freeze_toplevel_updates_libgtk_only (widget->window);
6083 /* for GTK_RESIZE_QUEUE toplevels, we are now awaiting a new
6084 * configure event in response to our resizing request.
6085 * the configure event will cause a new resize with
6086 * ->configure_notify_received=TRUE.
6087 * until then, we want to
6088 * - discard expose events
6089 * - coalesce resizes for our children
6090 * - defer any window resizes until the configure event arrived
6091 * to achieve this, we queue a resize for the window, but remove its
6092 * resizing handler, so resizing will not be handled from the next
6093 * idle handler but when the configure event arrives.
6095 * FIXME: we should also dequeue the pending redraws here, since
6096 * we handle those ourselves upon ->configure_notify_received==TRUE.
6098 if (container->resize_mode == GTK_RESIZE_QUEUE)
6100 gtk_widget_queue_resize (widget);
6101 _gtk_container_dequeue_resize_handler (container);
6107 /* Handle any position changes.
6109 if (configure_request_pos_changed)
6113 gdk_window_move (window->frame,
6114 new_request.x - window->frame_left,
6115 new_request.y - window->frame_top);
6118 gdk_window_move (widget->window,
6119 new_request.x, new_request.y);
6122 /* And run the resize queue.
6124 gtk_container_resize_children (container);
6127 /* We have now processed a move/resize since the last position
6128 * constraint change, setting of the initial position, or resize.
6129 * (Not resetting these flags here can lead to infinite loops for
6130 * GTK_RESIZE_IMMEDIATE containers)
6132 info->position_constraints_changed = FALSE;
6133 info->initial_pos_set = FALSE;
6134 info->resize_width = -1;
6135 info->resize_height = -1;
6138 /* Compare two sets of Geometry hints for equality.
6141 gtk_window_compare_hints (GdkGeometry *geometry_a,
6143 GdkGeometry *geometry_b,
6146 if (flags_a != flags_b)
6149 if ((flags_a & GDK_HINT_MIN_SIZE) &&
6150 (geometry_a->min_width != geometry_b->min_width ||
6151 geometry_a->min_height != geometry_b->min_height))
6154 if ((flags_a & GDK_HINT_MAX_SIZE) &&
6155 (geometry_a->max_width != geometry_b->max_width ||
6156 geometry_a->max_height != geometry_b->max_height))
6159 if ((flags_a & GDK_HINT_BASE_SIZE) &&
6160 (geometry_a->base_width != geometry_b->base_width ||
6161 geometry_a->base_height != geometry_b->base_height))
6164 if ((flags_a & GDK_HINT_ASPECT) &&
6165 (geometry_a->min_aspect != geometry_b->min_aspect ||
6166 geometry_a->max_aspect != geometry_b->max_aspect))
6169 if ((flags_a & GDK_HINT_RESIZE_INC) &&
6170 (geometry_a->width_inc != geometry_b->width_inc ||
6171 geometry_a->height_inc != geometry_b->height_inc))
6174 if ((flags_a & GDK_HINT_WIN_GRAVITY) &&
6175 geometry_a->win_gravity != geometry_b->win_gravity)
6182 _gtk_window_constrain_size (GtkWindow *window,
6188 GtkWindowGeometryInfo *info;
6190 g_return_if_fail (GTK_IS_WINDOW (window));
6192 info = window->geometry_info;
6195 GdkWindowHints flags = info->last.flags;
6196 GdkGeometry *geometry = &info->last.geometry;
6198 gtk_window_constrain_size (window,
6209 gtk_window_constrain_size (GtkWindow *window,
6210 GdkGeometry *geometry,
6217 gdk_window_constrain_size (geometry, flags, width, height,
6218 new_width, new_height);
6221 /* Compute the set of geometry hints and flags for a window
6222 * based on the application set geometry, and requisiition
6223 * of the window. gtk_widget_size_request() must have been
6227 gtk_window_compute_hints (GtkWindow *window,
6228 GdkGeometry *new_geometry,
6232 gint extra_width = 0;
6233 gint extra_height = 0;
6234 GtkWindowGeometryInfo *geometry_info;
6235 GtkRequisition requisition;
6237 widget = GTK_WIDGET (window);
6239 gtk_widget_get_child_requisition (widget, &requisition);
6240 geometry_info = gtk_window_get_geometry_info (GTK_WINDOW (widget), FALSE);
6244 *new_flags = geometry_info->mask;
6245 *new_geometry = geometry_info->geometry;
6252 if (geometry_info && geometry_info->widget)
6254 GtkRequisition child_requisition;
6256 /* FIXME: This really isn't right. It gets the min size wrong and forces
6257 * callers to do horrible hacks like set a huge usize on the child requisition
6258 * to get the base size right. We really want to find the answers to:
6260 * - If the geometry widget was infinitely big, how much extra space
6261 * would be needed for the stuff around it.
6263 * - If the geometry widget was infinitely small, how big would the
6264 * window still have to be.
6266 * Finding these answers would be a bit of a mess here. (Bug #68668)
6268 gtk_widget_get_child_requisition (geometry_info->widget, &child_requisition);
6270 extra_width = widget->requisition.width - child_requisition.width;
6271 extra_height = widget->requisition.height - child_requisition.height;
6274 /* We don't want to set GDK_HINT_POS in here, we just set it
6275 * in gtk_window_move_resize() when we want the position
6279 if (*new_flags & GDK_HINT_BASE_SIZE)
6281 new_geometry->base_width += extra_width;
6282 new_geometry->base_height += extra_height;
6284 else if (!(*new_flags & GDK_HINT_MIN_SIZE) &&
6285 (*new_flags & GDK_HINT_RESIZE_INC) &&
6286 ((extra_width != 0) || (extra_height != 0)))
6288 *new_flags |= GDK_HINT_BASE_SIZE;
6290 new_geometry->base_width = extra_width;
6291 new_geometry->base_height = extra_height;
6294 if (*new_flags & GDK_HINT_MIN_SIZE)
6296 if (new_geometry->min_width < 0)
6297 new_geometry->min_width = requisition.width;
6299 new_geometry->min_width += extra_width;
6301 if (new_geometry->min_height < 0)
6302 new_geometry->min_height = requisition.height;
6304 new_geometry->min_height += extra_height;
6306 else if (!window->allow_shrink)
6308 *new_flags |= GDK_HINT_MIN_SIZE;
6310 new_geometry->min_width = requisition.width;
6311 new_geometry->min_height = requisition.height;
6314 if (*new_flags & GDK_HINT_MAX_SIZE)
6316 if (new_geometry->max_width < 0)
6317 new_geometry->max_width = requisition.width;
6319 new_geometry->max_width += extra_width;
6321 if (new_geometry->max_height < 0)
6322 new_geometry->max_height = requisition.height;
6324 new_geometry->max_height += extra_height;
6326 else if (!window->allow_grow)
6328 *new_flags |= GDK_HINT_MAX_SIZE;
6330 new_geometry->max_width = requisition.width;
6331 new_geometry->max_height = requisition.height;
6334 *new_flags |= GDK_HINT_WIN_GRAVITY;
6335 new_geometry->win_gravity = window->gravity;
6338 /***********************
6339 * Redrawing functions *
6340 ***********************/
6343 gtk_window_paint (GtkWidget *widget,
6346 gtk_paint_flat_box (widget->style, widget->window, GTK_STATE_NORMAL,
6347 GTK_SHADOW_NONE, area, widget, "base", 0, 0, -1, -1);
6351 gtk_window_expose (GtkWidget *widget,
6352 GdkEventExpose *event)
6354 if (!GTK_WIDGET_APP_PAINTABLE (widget))
6355 gtk_window_paint (widget, &event->area);
6357 if (GTK_WIDGET_CLASS (gtk_window_parent_class)->expose_event)
6358 return GTK_WIDGET_CLASS (gtk_window_parent_class)->expose_event (widget, event);
6364 * gtk_window_set_has_frame:
6365 * @window: a #GtkWindow
6366 * @setting: a boolean
6368 * (Note: this is a special-purpose function for the framebuffer port,
6369 * that causes GTK+ to draw its own window border. For most applications,
6370 * you want gtk_window_set_decorated() instead, which tells the window
6371 * manager whether to draw the window border.)
6373 * If this function is called on a window with setting of %TRUE, before
6374 * it is realized or showed, it will have a "frame" window around
6375 * @window->window, accessible in @window->frame. Using the signal
6376 * frame_event you can receive all events targeted at the frame.
6378 * This function is used by the linux-fb port to implement managed
6379 * windows, but it could conceivably be used by X-programs that
6380 * want to do their own window decorations.
6384 gtk_window_set_has_frame (GtkWindow *window,
6387 g_return_if_fail (GTK_IS_WINDOW (window));
6388 g_return_if_fail (!GTK_WIDGET_REALIZED (window));
6390 window->has_frame = setting != FALSE;
6394 * gtk_window_get_has_frame:
6395 * @window: a #GtkWindow
6397 * Accessor for whether the window has a frame window exterior to
6398 * @window->window. Gets the value set by gtk_window_set_has_frame ().
6400 * Return value: %TRUE if a frame has been added to the window
6401 * via gtk_window_set_has_frame().
6404 gtk_window_get_has_frame (GtkWindow *window)
6406 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
6408 return window->has_frame;
6412 * gtk_window_set_frame_dimensions:
6413 * @window: a #GtkWindow that has a frame
6414 * @left: The width of the left border
6415 * @top: The height of the top border
6416 * @right: The width of the right border
6417 * @bottom: The height of the bottom border
6419 * (Note: this is a special-purpose function intended for the framebuffer
6420 * port; see gtk_window_set_has_frame(). It will have no effect on the
6421 * window border drawn by the window manager, which is the normal
6422 * case when using the X Window system.)
6424 * For windows with frames (see gtk_window_set_has_frame()) this function
6425 * can be used to change the size of the frame border.
6428 gtk_window_set_frame_dimensions (GtkWindow *window,
6436 g_return_if_fail (GTK_IS_WINDOW (window));
6438 widget = GTK_WIDGET (window);
6440 if (window->frame_left == left &&
6441 window->frame_top == top &&
6442 window->frame_right == right &&
6443 window->frame_bottom == bottom)
6446 window->frame_left = left;
6447 window->frame_top = top;
6448 window->frame_right = right;
6449 window->frame_bottom = bottom;
6451 if (GTK_WIDGET_REALIZED (widget) && window->frame)
6453 gint width = widget->allocation.width + left + right;
6454 gint height = widget->allocation.height + top + bottom;
6455 gdk_window_resize (window->frame, width, height);
6456 gtk_decorated_window_move_resize_window (window,
6458 widget->allocation.width,
6459 widget->allocation.height);
6464 * gtk_window_present:
6465 * @window: a #GtkWindow
6467 * Presents a window to the user. This may mean raising the window
6468 * in the stacking order, deiconifying it, moving it to the current
6469 * desktop, and/or giving it the keyboard focus, possibly dependent
6470 * on the user's platform, window manager, and preferences.
6472 * If @window is hidden, this function calls gtk_widget_show()
6475 * This function should be used when the user tries to open a window
6476 * that's already open. Say for example the preferences dialog is
6477 * currently open, and the user chooses Preferences from the menu
6478 * a second time; use gtk_window_present() to move the already-open dialog
6479 * where the user can see it.
6481 * If you are calling this function in response to a user interaction,
6482 * it is preferable to use gtk_window_present_with_time().
6486 gtk_window_present (GtkWindow *window)
6488 gtk_window_present_with_time (window, GDK_CURRENT_TIME);
6492 * gtk_window_present_with_time:
6493 * @window: a #GtkWindow
6494 * @timestamp: the timestamp of the user interaction (typically a
6495 * button or key press event) which triggered this call
6497 * Presents a window to the user in response to a user interaction.
6498 * If you need to present a window without a timestamp, use
6499 * gtk_window_present(). See gtk_window_present() for details.
6504 gtk_window_present_with_time (GtkWindow *window,
6509 g_return_if_fail (GTK_IS_WINDOW (window));
6511 widget = GTK_WIDGET (window);
6513 if (GTK_WIDGET_VISIBLE (window))
6515 g_assert (widget->window != NULL);
6517 gdk_window_show (widget->window);
6519 /* Translate a timestamp of GDK_CURRENT_TIME appropriately */
6520 if (timestamp == GDK_CURRENT_TIME)
6522 #ifdef GDK_WINDOWING_X11
6523 GdkDisplay *display;
6525 display = gtk_widget_get_display (GTK_WIDGET (window));
6526 timestamp = gdk_x11_display_get_user_time (display);
6528 timestamp = gtk_get_current_event_time ();
6532 gdk_window_focus (widget->window, timestamp);
6536 gtk_widget_show (widget);
6541 * gtk_window_iconify:
6542 * @window: a #GtkWindow
6544 * Asks to iconify (i.e. minimize) the specified @window. Note that
6545 * you shouldn't assume the window is definitely iconified afterward,
6546 * because other entities (e.g. the user or <link
6547 * linkend="gtk-X11-arch">window manager</link>) could deiconify it
6548 * again, or there may not be a window manager in which case
6549 * iconification isn't possible, etc. But normally the window will end
6550 * up iconified. Just don't write code that crashes if not.
6552 * It's permitted to call this function before showing a window,
6553 * in which case the window will be iconified before it ever appears
6556 * You can track iconification via the "window_state_event" signal
6561 gtk_window_iconify (GtkWindow *window)
6564 GdkWindow *toplevel;
6566 g_return_if_fail (GTK_IS_WINDOW (window));
6568 widget = GTK_WIDGET (window);
6570 window->iconify_initially = TRUE;
6573 toplevel = window->frame;
6575 toplevel = widget->window;
6577 if (toplevel != NULL)
6578 gdk_window_iconify (toplevel);
6582 * gtk_window_deiconify:
6583 * @window: a #GtkWindow
6585 * Asks to deiconify (i.e. unminimize) the specified @window. Note
6586 * that you shouldn't assume the window is definitely deiconified
6587 * afterward, because other entities (e.g. the user or <link
6588 * linkend="gtk-X11-arch">window manager</link>) could iconify it
6589 * again before your code which assumes deiconification gets to run.
6591 * You can track iconification via the "window_state_event" signal
6595 gtk_window_deiconify (GtkWindow *window)
6598 GdkWindow *toplevel;
6600 g_return_if_fail (GTK_IS_WINDOW (window));
6602 widget = GTK_WIDGET (window);
6604 window->iconify_initially = FALSE;
6607 toplevel = window->frame;
6609 toplevel = widget->window;
6611 if (toplevel != NULL)
6612 gdk_window_deiconify (toplevel);
6617 * @window: a #GtkWindow
6619 * Asks to stick @window, which means that it will appear on all user
6620 * desktops. Note that you shouldn't assume the window is definitely
6621 * stuck afterward, because other entities (e.g. the user or <link
6622 * linkend="gtk-X11-arch">window manager</link>) could unstick it
6623 * again, and some window managers do not support sticking
6624 * windows. But normally the window will end up stuck. Just don't
6625 * write code that crashes if not.
6627 * It's permitted to call this function before showing a window.
6629 * You can track stickiness via the "window_state_event" signal
6634 gtk_window_stick (GtkWindow *window)
6637 GdkWindow *toplevel;
6639 g_return_if_fail (GTK_IS_WINDOW (window));
6641 widget = GTK_WIDGET (window);
6643 window->stick_initially = TRUE;
6646 toplevel = window->frame;
6648 toplevel = widget->window;
6650 if (toplevel != NULL)
6651 gdk_window_stick (toplevel);
6655 * gtk_window_unstick:
6656 * @window: a #GtkWindow
6658 * Asks to unstick @window, which means that it will appear on only
6659 * one of the user's desktops. Note that you shouldn't assume the
6660 * window is definitely unstuck afterward, because other entities
6661 * (e.g. the user or <link linkend="gtk-X11-arch">window
6662 * manager</link>) could stick it again. But normally the window will
6663 * end up stuck. Just don't write code that crashes if not.
6665 * You can track stickiness via the "window_state_event" signal
6670 gtk_window_unstick (GtkWindow *window)
6673 GdkWindow *toplevel;
6675 g_return_if_fail (GTK_IS_WINDOW (window));
6677 widget = GTK_WIDGET (window);
6679 window->stick_initially = FALSE;
6682 toplevel = window->frame;
6684 toplevel = widget->window;
6686 if (toplevel != NULL)
6687 gdk_window_unstick (toplevel);
6691 * gtk_window_maximize:
6692 * @window: a #GtkWindow
6694 * Asks to maximize @window, so that it becomes full-screen. Note that
6695 * you shouldn't assume the window is definitely maximized afterward,
6696 * because other entities (e.g. the user or <link
6697 * linkend="gtk-X11-arch">window manager</link>) could unmaximize it
6698 * again, and not all window managers support maximization. But
6699 * normally the window will end up maximized. Just don't write code
6700 * that crashes if not.
6702 * It's permitted to call this function before showing a window,
6703 * in which case the window will be maximized when it appears onscreen
6706 * You can track maximization via the "window_state_event" signal
6711 gtk_window_maximize (GtkWindow *window)
6714 GdkWindow *toplevel;
6716 g_return_if_fail (GTK_IS_WINDOW (window));
6718 widget = GTK_WIDGET (window);
6720 window->maximize_initially = TRUE;
6723 toplevel = window->frame;
6725 toplevel = widget->window;
6727 if (toplevel != NULL)
6728 gdk_window_maximize (toplevel);
6732 * gtk_window_unmaximize:
6733 * @window: a #GtkWindow
6735 * Asks to unmaximize @window. Note that you shouldn't assume the
6736 * window is definitely unmaximized afterward, because other entities
6737 * (e.g. the user or <link linkend="gtk-X11-arch">window
6738 * manager</link>) could maximize it again, and not all window
6739 * managers honor requests to unmaximize. But normally the window will
6740 * end up unmaximized. Just don't write code that crashes if not.
6742 * You can track maximization via the "window_state_event" signal
6747 gtk_window_unmaximize (GtkWindow *window)
6750 GdkWindow *toplevel;
6752 g_return_if_fail (GTK_IS_WINDOW (window));
6754 widget = GTK_WIDGET (window);
6756 window->maximize_initially = FALSE;
6759 toplevel = window->frame;
6761 toplevel = widget->window;
6763 if (toplevel != NULL)
6764 gdk_window_unmaximize (toplevel);
6768 * gtk_window_fullscreen:
6769 * @window: a #GtkWindow
6771 * Asks to place @window in the fullscreen state. Note that you
6772 * shouldn't assume the window is definitely full screen afterward,
6773 * because other entities (e.g. the user or <link
6774 * linkend="gtk-X11-arch">window manager</link>) could unfullscreen it
6775 * again, and not all window managers honor requests to fullscreen
6776 * windows. But normally the window will end up fullscreen. Just
6777 * don't write code that crashes if not.
6779 * You can track the fullscreen state via the "window_state_event" signal
6785 gtk_window_fullscreen (GtkWindow *window)
6788 GdkWindow *toplevel;
6789 GtkWindowPrivate *priv;
6791 g_return_if_fail (GTK_IS_WINDOW (window));
6793 widget = GTK_WIDGET (window);
6794 priv = GTK_WINDOW_GET_PRIVATE (window);
6796 priv->fullscreen_initially = TRUE;
6799 toplevel = window->frame;
6801 toplevel = widget->window;
6803 if (toplevel != NULL)
6804 gdk_window_fullscreen (toplevel);
6808 * gtk_window_unfullscreen:
6809 * @window: a #GtkWindow
6811 * Asks to toggle off the fullscreen state for @window. Note that you
6812 * shouldn't assume the window is definitely not full screen
6813 * afterward, because other entities (e.g. the user or <link
6814 * linkend="gtk-X11-arch">window manager</link>) could fullscreen it
6815 * again, and not all window managers honor requests to unfullscreen
6816 * windows. But normally the window will end up restored to its normal
6817 * state. Just don't write code that crashes if not.
6819 * You can track the fullscreen state via the "window_state_event" signal
6825 gtk_window_unfullscreen (GtkWindow *window)
6828 GdkWindow *toplevel;
6829 GtkWindowPrivate *priv;
6831 g_return_if_fail (GTK_IS_WINDOW (window));
6833 widget = GTK_WIDGET (window);
6834 priv = GTK_WINDOW_GET_PRIVATE (window);
6836 priv->fullscreen_initially = FALSE;
6839 toplevel = window->frame;
6841 toplevel = widget->window;
6843 if (toplevel != NULL)
6844 gdk_window_unfullscreen (toplevel);
6848 * gtk_window_set_keep_above:
6849 * @window: a #GtkWindow
6850 * @setting: whether to keep @window above other windows
6852 * Asks to keep @window above, so that it stays on top. Note that
6853 * you shouldn't assume the window is definitely above afterward,
6854 * because other entities (e.g. the user or <link
6855 * linkend="gtk-X11-arch">window manager</link>) could not keep it above,
6856 * and not all window managers support keeping windows above. But
6857 * normally the window will end kept above. Just don't write code
6858 * that crashes if not.
6860 * It's permitted to call this function before showing a window,
6861 * in which case the window will be kept above when it appears onscreen
6864 * You can track the above state via the "window_state_event" signal
6867 * Note that, according to the <ulink
6868 * url="http://www.freedesktop.org/Standards/wm-spec">Extended Window
6869 * Manager Hints</ulink> specification, the above state is mainly meant
6870 * for user preferences and should not be used by applications e.g. for
6871 * drawing attention to their dialogs.
6876 gtk_window_set_keep_above (GtkWindow *window,
6880 GtkWindowPrivate *priv;
6881 GdkWindow *toplevel;
6883 g_return_if_fail (GTK_IS_WINDOW (window));
6885 widget = GTK_WIDGET (window);
6886 priv = GTK_WINDOW_GET_PRIVATE (window);
6888 priv->above_initially = setting != FALSE;
6890 priv->below_initially = FALSE;
6893 toplevel = window->frame;
6895 toplevel = widget->window;
6897 if (toplevel != NULL)
6898 gdk_window_set_keep_above (toplevel, setting);
6902 * gtk_window_set_keep_below:
6903 * @window: a #GtkWindow
6904 * @setting: whether to keep @window below other windows
6906 * Asks to keep @window below, so that it stays in bottom. Note that
6907 * you shouldn't assume the window is definitely below afterward,
6908 * because other entities (e.g. the user or <link
6909 * linkend="gtk-X11-arch">window manager</link>) could not keep it below,
6910 * and not all window managers support putting windows below. But
6911 * normally the window will be kept below. Just don't write code
6912 * that crashes if not.
6914 * It's permitted to call this function before showing a window,
6915 * in which case the window will be kept below when it appears onscreen
6918 * You can track the below state via the "window_state_event" signal
6921 * Note that, according to the <ulink
6922 * url="http://www.freedesktop.org/Standards/wm-spec">Extended Window
6923 * Manager Hints</ulink> specification, the above state is mainly meant
6924 * for user preferences and should not be used by applications e.g. for
6925 * drawing attention to their dialogs.
6930 gtk_window_set_keep_below (GtkWindow *window,
6934 GtkWindowPrivate *priv;
6935 GdkWindow *toplevel;
6937 g_return_if_fail (GTK_IS_WINDOW (window));
6939 widget = GTK_WIDGET (window);
6940 priv = GTK_WINDOW_GET_PRIVATE (window);
6942 priv->below_initially = setting != FALSE;
6944 priv->above_initially = FALSE;
6947 toplevel = window->frame;
6949 toplevel = widget->window;
6951 if (toplevel != NULL)
6952 gdk_window_set_keep_below (toplevel, setting);
6956 * gtk_window_set_resizable:
6957 * @window: a #GtkWindow
6958 * @resizable: %TRUE if the user can resize this window
6960 * Sets whether the user can resize a window. Windows are user resizable
6964 gtk_window_set_resizable (GtkWindow *window,
6967 g_return_if_fail (GTK_IS_WINDOW (window));
6969 gtk_window_set_policy (window, FALSE, resizable, FALSE);
6973 * gtk_window_get_resizable:
6974 * @window: a #GtkWindow
6976 * Gets the value set by gtk_window_set_resizable().
6978 * Return value: %TRUE if the user can resize the window
6981 gtk_window_get_resizable (GtkWindow *window)
6983 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
6985 /* allow_grow is most likely to indicate the semantic concept we
6986 * mean by "resizable" (and will be a reliable indicator if
6987 * set_policy() hasn't been called)
6989 return window->allow_grow;
6993 * gtk_window_set_gravity:
6994 * @window: a #GtkWindow
6995 * @gravity: window gravity
6997 * Window gravity defines the meaning of coordinates passed to
6998 * gtk_window_move(). See gtk_window_move() and #GdkGravity for
7001 * The default window gravity is #GDK_GRAVITY_NORTH_WEST which will
7002 * typically "do what you mean."
7006 gtk_window_set_gravity (GtkWindow *window,
7009 g_return_if_fail (GTK_IS_WINDOW (window));
7011 if (gravity != window->gravity)
7013 window->gravity = gravity;
7015 /* gtk_window_move_resize() will adapt gravity
7017 gtk_widget_queue_resize (GTK_WIDGET (window));
7019 g_object_notify (G_OBJECT (window), "gravity");
7024 * gtk_window_get_gravity:
7025 * @window: a #GtkWindow
7027 * Gets the value set by gtk_window_set_gravity().
7029 * Return value: window gravity
7032 gtk_window_get_gravity (GtkWindow *window)
7034 g_return_val_if_fail (GTK_IS_WINDOW (window), 0);
7036 return window->gravity;
7040 * gtk_window_begin_resize_drag:
7041 * @window: a #GtkWindow
7042 * @button: mouse button that initiated the drag
7043 * @edge: position of the resize control
7044 * @root_x: X position where the user clicked to initiate the drag, in root window coordinates
7045 * @root_y: Y position where the user clicked to initiate the drag
7046 * @timestamp: timestamp from the click event that initiated the drag
7048 * Starts resizing a window. This function is used if an application
7049 * has window resizing controls. When GDK can support it, the resize
7050 * will be done using the standard mechanism for the <link
7051 * linkend="gtk-X11-arch">window manager</link> or windowing
7052 * system. Otherwise, GDK will try to emulate window resizing,
7053 * potentially not all that well, depending on the windowing system.
7057 gtk_window_begin_resize_drag (GtkWindow *window,
7065 GdkWindow *toplevel;
7067 g_return_if_fail (GTK_IS_WINDOW (window));
7068 g_return_if_fail (GTK_WIDGET_VISIBLE (window));
7070 widget = GTK_WIDGET (window);
7073 toplevel = window->frame;
7075 toplevel = widget->window;
7077 gdk_window_begin_resize_drag (toplevel,
7084 * gtk_window_get_frame_dimensions:
7085 * @window: a #GtkWindow
7086 * @left: location to store the width of the frame at the left, or %NULL
7087 * @top: location to store the height of the frame at the top, or %NULL
7088 * @right: location to store the width of the frame at the returns, or %NULL
7089 * @bottom: location to store the height of the frame at the bottom, or %NULL
7091 * (Note: this is a special-purpose function intended for the
7092 * framebuffer port; see gtk_window_set_has_frame(). It will not
7093 * return the size of the window border drawn by the <link
7094 * linkend="gtk-X11-arch">window manager</link>, which is the normal
7095 * case when using a windowing system. See
7096 * gdk_window_get_frame_extents() to get the standard window border
7099 * Retrieves the dimensions of the frame window for this toplevel.
7100 * See gtk_window_set_has_frame(), gtk_window_set_frame_dimensions().
7103 gtk_window_get_frame_dimensions (GtkWindow *window,
7109 g_return_if_fail (GTK_IS_WINDOW (window));
7112 *left = window->frame_left;
7114 *top = window->frame_top;
7116 *right = window->frame_right;
7118 *bottom = window->frame_bottom;
7122 * gtk_window_begin_move_drag:
7123 * @window: a #GtkWindow
7124 * @button: mouse button that initiated the drag
7125 * @root_x: X position where the user clicked to initiate the drag, in root window coordinates
7126 * @root_y: Y position where the user clicked to initiate the drag
7127 * @timestamp: timestamp from the click event that initiated the drag
7129 * Starts moving a window. This function is used if an application has
7130 * window movement grips. When GDK can support it, the window movement
7131 * will be done using the standard mechanism for the <link
7132 * linkend="gtk-X11-arch">window manager</link> or windowing
7133 * system. Otherwise, GDK will try to emulate window movement,
7134 * potentially not all that well, depending on the windowing system.
7138 gtk_window_begin_move_drag (GtkWindow *window,
7145 GdkWindow *toplevel;
7147 g_return_if_fail (GTK_IS_WINDOW (window));
7148 g_return_if_fail (GTK_WIDGET_VISIBLE (window));
7150 widget = GTK_WIDGET (window);
7153 toplevel = window->frame;
7155 toplevel = widget->window;
7157 gdk_window_begin_move_drag (toplevel,
7164 * gtk_window_set_screen:
7165 * @window: a #GtkWindow.
7166 * @screen: a #GdkScreen.
7168 * Sets the #GdkScreen where the @window is displayed; if
7169 * the window is already mapped, it will be unmapped, and
7170 * then remapped on the new screen.
7175 gtk_window_set_screen (GtkWindow *window,
7179 GdkScreen *previous_screen;
7180 gboolean was_mapped;
7182 g_return_if_fail (GTK_IS_WINDOW (window));
7183 g_return_if_fail (GDK_IS_SCREEN (screen));
7185 if (screen == window->screen)
7188 widget = GTK_WIDGET (window);
7190 previous_screen = window->screen;
7191 was_mapped = GTK_WIDGET_MAPPED (widget);
7194 gtk_widget_unmap (widget);
7195 if (GTK_WIDGET_REALIZED (widget))
7196 gtk_widget_unrealize (widget);
7198 gtk_window_free_key_hash (window);
7199 window->screen = screen;
7200 gtk_widget_reset_rc_styles (widget);
7201 if (screen != previous_screen)
7203 g_signal_handlers_disconnect_by_func (previous_screen,
7204 gtk_window_on_composited_changed, window);
7205 g_signal_connect (screen, "composited_changed",
7206 G_CALLBACK (gtk_window_on_composited_changed), window);
7208 _gtk_widget_propagate_screen_changed (widget, previous_screen);
7209 _gtk_widget_propagate_composited_changed (widget);
7211 g_object_notify (G_OBJECT (window), "screen");
7214 gtk_widget_map (widget);
7218 gtk_window_on_composited_changed (GdkScreen *screen,
7221 gtk_widget_queue_draw (GTK_WIDGET (window));
7223 _gtk_widget_propagate_composited_changed (GTK_WIDGET (window));
7227 gtk_window_check_screen (GtkWindow *window)
7230 return window->screen;
7233 g_warning ("Screen for GtkWindow not set; you must always set\n"
7234 "a screen for a GtkWindow before using the window");
7240 * gtk_window_get_screen:
7241 * @window: a #GtkWindow.
7243 * Returns the #GdkScreen associated with @window.
7245 * Return value: a #GdkScreen.
7250 gtk_window_get_screen (GtkWindow *window)
7252 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
7254 return window->screen;
7258 * gtk_window_is_active:
7259 * @window: a #GtkWindow
7261 * Returns whether the window is part of the current active toplevel.
7262 * (That is, the toplevel window receiving keystrokes.)
7263 * The return value is %TRUE if the window is active toplevel
7264 * itself, but also if it is, say, a #GtkPlug embedded in the active toplevel.
7265 * You might use this function if you wanted to draw a widget
7266 * differently in an active window from a widget in an inactive window.
7267 * See gtk_window_has_toplevel_focus()
7269 * Return value: %TRUE if the window part of the current active window.
7274 gtk_window_is_active (GtkWindow *window)
7276 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
7278 return window->is_active;
7282 * gtk_window_has_toplevel_focus:
7283 * @window: a #GtkWindow
7285 * Returns whether the input focus is within this GtkWindow.
7286 * For real toplevel windows, this is identical to gtk_window_is_active(),
7287 * but for embedded windows, like #GtkPlug, the results will differ.
7289 * Return value: %TRUE if the input focus is within this GtkWindow
7294 gtk_window_has_toplevel_focus (GtkWindow *window)
7296 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
7298 return window->has_toplevel_focus;
7302 gtk_window_group_class_init (GtkWindowGroupClass *klass)
7307 gtk_window_group_get_type (void)
7309 static GType window_group_type = 0;
7311 if (!window_group_type)
7313 const GTypeInfo window_group_info =
7315 sizeof (GtkWindowGroupClass),
7316 NULL, /* base_init */
7317 NULL, /* base_finalize */
7318 (GClassInitFunc) gtk_window_group_class_init,
7319 NULL, /* class_finalize */
7320 NULL, /* class_data */
7321 sizeof (GtkWindowGroup),
7322 0, /* n_preallocs */
7323 (GInstanceInitFunc) NULL,
7326 window_group_type = g_type_register_static (G_TYPE_OBJECT, I_("GtkWindowGroup"),
7327 &window_group_info, 0);
7330 return window_group_type;
7334 * gtk_window_group_new:
7336 * Creates a new #GtkWindowGroup object. Grabs added with
7337 * gtk_grab_add() only affect windows within the same #GtkWindowGroup.
7339 * Return value: a new #GtkWindowGroup.
7342 gtk_window_group_new (void)
7344 return g_object_new (GTK_TYPE_WINDOW_GROUP, NULL);
7348 window_group_cleanup_grabs (GtkWindowGroup *group,
7352 GSList *to_remove = NULL;
7354 tmp_list = group->grabs;
7357 if (gtk_widget_get_toplevel (tmp_list->data) == (GtkWidget*) window)
7358 to_remove = g_slist_prepend (to_remove, g_object_ref (tmp_list->data));
7359 tmp_list = tmp_list->next;
7364 gtk_grab_remove (to_remove->data);
7365 g_object_unref (to_remove->data);
7366 to_remove = g_slist_delete_link (to_remove, to_remove);
7371 * gtk_window_group_add_window:
7372 * @window_group: a #GtkWindowGroup
7373 * @window: the #GtkWindow to add
7375 * Adds a window to a #GtkWindowGroup.
7378 gtk_window_group_add_window (GtkWindowGroup *window_group,
7381 g_return_if_fail (GTK_IS_WINDOW_GROUP (window_group));
7382 g_return_if_fail (GTK_IS_WINDOW (window));
7384 if (window->group != window_group)
7386 g_object_ref (window);
7387 g_object_ref (window_group);
7390 gtk_window_group_remove_window (window->group, window);
7392 window_group_cleanup_grabs (gtk_window_get_group (NULL), window);
7394 window->group = window_group;
7396 g_object_unref (window);
7401 * gtk_window_group_remove_window:
7402 * @window_group: a #GtkWindowGroup
7403 * @window: the #GtkWindow to remove
7405 * Removes a window from a #GtkWindowGroup.
7408 gtk_window_group_remove_window (GtkWindowGroup *window_group,
7411 g_return_if_fail (GTK_IS_WINDOW_GROUP (window_group));
7412 g_return_if_fail (GTK_IS_WINDOW (window));
7413 g_return_if_fail (window->group == window_group);
7415 g_object_ref (window);
7417 window_group_cleanup_grabs (window_group, window);
7418 window->group = NULL;
7420 g_object_unref (window_group);
7421 g_object_unref (window);
7425 * gtk_window_get_group:
7426 * @window: a #GtkWindow, or %NULL
7428 * Returns the group for @window or the default group, if
7429 * @window is %NULL or if @window does not have an explicit
7432 * Returns: the #GtkWindowGroup for a window or the default group
7437 gtk_window_get_group (GtkWindow *window)
7439 if (window && window->group)
7440 return window->group;
7443 static GtkWindowGroup *default_group = NULL;
7446 default_group = gtk_window_group_new ();
7448 return default_group;
7452 /* Return the current grab widget of the given group
7455 _gtk_window_group_get_current_grab (GtkWindowGroup *window_group)
7457 if (window_group->grabs)
7458 return GTK_WIDGET (window_group->grabs->data);
7463 Derived from XParseGeometry() in XFree86
7465 Copyright 1985, 1986, 1987,1998 The Open Group
7467 All Rights Reserved.
7469 The above copyright notice and this permission notice shall be included
7470 in all copies or substantial portions of the Software.
7472 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
7473 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
7474 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
7475 IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
7476 OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
7477 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
7478 OTHER DEALINGS IN THE SOFTWARE.
7480 Except as contained in this notice, the name of The Open Group shall
7481 not be used in advertising or otherwise to promote the sale, use or
7482 other dealings in this Software without prior written authorization
7483 from The Open Group.
7488 * XParseGeometry parses strings of the form
7489 * "=<width>x<height>{+-}<xoffset>{+-}<yoffset>", where
7490 * width, height, xoffset, and yoffset are unsigned integers.
7491 * Example: "=80x24+300-49"
7492 * The equal sign is optional.
7493 * It returns a bitmask that indicates which of the four values
7494 * were actually found in the string. For each value found,
7495 * the corresponding argument is updated; for each value
7496 * not found, the corresponding argument is left unchanged.
7499 /* The following code is from Xlib, and is minimally modified, so we
7500 * can track any upstream changes if required. Don't change this
7501 * code. Or if you do, put in a huge comment marking which thing
7506 read_int (gchar *string,
7514 else if (*string == '-')
7520 for (; (*string >= '0') && (*string <= '9'); string++)
7522 result = (result * 10) + (*string - '0');
7534 * Bitmask returned by XParseGeometry(). Each bit tells if the corresponding
7535 * value (x, y, width, height) was found in the parsed string.
7537 #define NoValue 0x0000
7538 #define XValue 0x0001
7539 #define YValue 0x0002
7540 #define WidthValue 0x0004
7541 #define HeightValue 0x0008
7542 #define AllValues 0x000F
7543 #define XNegative 0x0010
7544 #define YNegative 0x0020
7546 /* Try not to reformat/modify, so we can compare/sync with X sources */
7548 gtk_XParseGeometry (const char *string,
7551 unsigned int *width,
7552 unsigned int *height)
7556 unsigned int tempWidth, tempHeight;
7558 char *nextCharacter;
7560 /* These initializations are just to silence gcc */
7566 if ( (string == NULL) || (*string == '\0')) return(mask);
7568 string++; /* ignore possible '=' at beg of geometry spec */
7570 strind = (char *)string;
7571 if (*strind != '+' && *strind != '-' && *strind != 'x') {
7572 tempWidth = read_int(strind, &nextCharacter);
7573 if (strind == nextCharacter)
7575 strind = nextCharacter;
7579 if (*strind == 'x' || *strind == 'X') {
7581 tempHeight = read_int(strind, &nextCharacter);
7582 if (strind == nextCharacter)
7584 strind = nextCharacter;
7585 mask |= HeightValue;
7588 if ((*strind == '+') || (*strind == '-')) {
7589 if (*strind == '-') {
7591 tempX = -read_int(strind, &nextCharacter);
7592 if (strind == nextCharacter)
7594 strind = nextCharacter;
7600 tempX = read_int(strind, &nextCharacter);
7601 if (strind == nextCharacter)
7603 strind = nextCharacter;
7606 if ((*strind == '+') || (*strind == '-')) {
7607 if (*strind == '-') {
7609 tempY = -read_int(strind, &nextCharacter);
7610 if (strind == nextCharacter)
7612 strind = nextCharacter;
7619 tempY = read_int(strind, &nextCharacter);
7620 if (strind == nextCharacter)
7622 strind = nextCharacter;
7628 /* If strind isn't at the end of the string the it's an invalid
7629 geometry specification. */
7631 if (*strind != '\0') return (0);
7637 if (mask & WidthValue)
7639 if (mask & HeightValue)
7640 *height = tempHeight;
7645 * gtk_window_parse_geometry:
7646 * @window: a #GtkWindow
7647 * @geometry: geometry string
7649 * Parses a standard X Window System geometry string - see the
7650 * manual page for X (type 'man X') for details on this.
7651 * gtk_window_parse_geometry() does work on all GTK+ ports
7652 * including Win32 but is primarily intended for an X environment.
7654 * If either a size or a position can be extracted from the
7655 * geometry string, gtk_window_parse_geometry() returns %TRUE
7656 * and calls gtk_window_set_default_size() and/or gtk_window_move()
7657 * to resize/move the window.
7659 * If gtk_window_parse_geometry() returns %TRUE, it will also
7660 * set the #GDK_HINT_USER_POS and/or #GDK_HINT_USER_SIZE hints
7661 * indicating to the window manager that the size/position of
7662 * the window was user-specified. This causes most window
7663 * managers to honor the geometry.
7665 * Note that for gtk_window_parse_geometry() to work as expected, it has
7666 * to be called when the window has its "final" size, i.e. after calling
7667 * gtk_widget_show_all() on the contents and gtk_window_set_geometry_hints()
7670 * #include <gtk/gtk.h>
7673 * fill_with_content (GtkWidget *vbox)
7675 * /* fill with content... */
7679 * main (int argc, char *argv[])
7681 * GtkWidget *window, *vbox;
7682 * GdkGeometry size_hints = {
7683 * 100, 50, 0, 0, 100, 50, 10, 10, 0.0, 0.0, GDK_GRAVITY_NORTH_WEST
7686 * gtk_init (&argc, &argv);
7688 * window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
7689 * vbox = gtk_vbox_new (FALSE, 0);
7691 * gtk_container_add (GTK_CONTAINER (window), vbox);
7692 * fill_with_content (vbox);
7693 * gtk_widget_show_all (vbox);
7695 * gtk_window_set_geometry_hints (GTK_WINDOW (window),
7698 * GDK_HINT_MIN_SIZE |
7699 * GDK_HINT_BASE_SIZE |
7700 * GDK_HINT_RESIZE_INC);
7704 * if (!gtk_window_parse_geometry (GTK_WINDOW (window), argv[1]))
7705 * fprintf (stderr, "Failed to parse '%s'\n", argv[1]);
7708 * gtk_widget_show_all (window);
7715 * Return value: %TRUE if string was parsed successfully
7718 gtk_window_parse_geometry (GtkWindow *window,
7719 const gchar *geometry)
7721 gint result, x = 0, y = 0;
7724 gboolean size_set, pos_set;
7727 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
7728 g_return_val_if_fail (geometry != NULL, FALSE);
7730 screen = gtk_window_check_screen (window);
7732 result = gtk_XParseGeometry (geometry, &x, &y, &w, &h);
7735 if ((result & WidthValue) || (result & HeightValue))
7737 gtk_window_set_default_size_internal (window,
7738 TRUE, result & WidthValue ? w : -1,
7739 TRUE, result & HeightValue ? h : -1,
7744 gtk_window_get_size (window, (gint *)&w, (gint *)&h);
7746 grav = GDK_GRAVITY_NORTH_WEST;
7748 if ((result & XNegative) && (result & YNegative))
7749 grav = GDK_GRAVITY_SOUTH_EAST;
7750 else if (result & XNegative)
7751 grav = GDK_GRAVITY_NORTH_EAST;
7752 else if (result & YNegative)
7753 grav = GDK_GRAVITY_SOUTH_WEST;
7755 if ((result & XValue) == 0)
7758 if ((result & YValue) == 0)
7761 if (grav == GDK_GRAVITY_SOUTH_WEST ||
7762 grav == GDK_GRAVITY_SOUTH_EAST)
7763 y = gdk_screen_get_height (screen) - h + y;
7765 if (grav == GDK_GRAVITY_SOUTH_EAST ||
7766 grav == GDK_GRAVITY_NORTH_EAST)
7767 x = gdk_screen_get_width (screen) - w + x;
7769 /* we don't let you put a window offscreen; maybe some people would
7770 * prefer to be able to, but it's kind of a bogus thing to do.
7779 if ((result & XValue) || (result & YValue))
7781 gtk_window_set_gravity (window, grav);
7782 gtk_window_move (window, x, y);
7786 if (size_set || pos_set)
7788 /* Set USSize, USPosition hints */
7789 GtkWindowGeometryInfo *info;
7791 info = gtk_window_get_geometry_info (window, TRUE);
7794 info->mask |= GDK_HINT_USER_POS;
7796 info->mask |= GDK_HINT_USER_SIZE;
7803 gtk_window_mnemonic_hash_foreach (guint keyval,
7809 GtkWindowKeysForeachFunc func;
7813 (*info->func) (info->window, keyval, info->window->mnemonic_modifier, TRUE, info->func_data);
7817 _gtk_window_keys_foreach (GtkWindow *window,
7818 GtkWindowKeysForeachFunc func,
7822 GtkMnemonicHash *mnemonic_hash;
7826 GtkWindowKeysForeachFunc func;
7830 info.window = window;
7832 info.func_data = func_data;
7834 mnemonic_hash = gtk_window_get_mnemonic_hash (window, FALSE);
7836 _gtk_mnemonic_hash_foreach (mnemonic_hash,
7837 gtk_window_mnemonic_hash_foreach, &info);
7839 groups = gtk_accel_groups_from_object (G_OBJECT (window));
7842 GtkAccelGroup *group = groups->data;
7845 for (i = 0; i < group->n_accels; i++)
7847 GtkAccelKey *key = &group->priv_accels[i].key;
7850 (*func) (window, key->accel_key, key->accel_mods, FALSE, func_data);
7853 groups = groups->next;
7858 gtk_window_keys_changed (GtkWindow *window)
7860 gtk_window_free_key_hash (window);
7861 gtk_window_get_key_hash (window);
7864 typedef struct _GtkWindowKeyEntry GtkWindowKeyEntry;
7866 struct _GtkWindowKeyEntry
7870 guint is_mnemonic : 1;
7874 window_key_entry_destroy (gpointer data)
7876 g_slice_free (GtkWindowKeyEntry, data);
7880 add_to_key_hash (GtkWindow *window,
7882 GdkModifierType modifiers,
7883 gboolean is_mnemonic,
7886 GtkKeyHash *key_hash = data;
7888 GtkWindowKeyEntry *entry = g_slice_new (GtkWindowKeyEntry);
7890 entry->keyval = keyval;
7891 entry->modifiers = modifiers;
7892 entry->is_mnemonic = is_mnemonic;
7894 /* GtkAccelGroup stores lowercased accelerators. To deal
7895 * with this, if <Shift> was specified, uppercase.
7897 if (modifiers & GDK_SHIFT_MASK)
7899 if (keyval == GDK_Tab)
7900 keyval = GDK_ISO_Left_Tab;
7902 keyval = gdk_keyval_to_upper (keyval);
7905 _gtk_key_hash_add_entry (key_hash, keyval, entry->modifiers, entry);
7909 gtk_window_get_key_hash (GtkWindow *window)
7911 GdkScreen *screen = gtk_window_check_screen (window);
7912 GtkKeyHash *key_hash = g_object_get_qdata (G_OBJECT (window), quark_gtk_window_key_hash);
7917 key_hash = _gtk_key_hash_new (gdk_keymap_get_for_display (gdk_screen_get_display (screen)),
7918 (GDestroyNotify)window_key_entry_destroy);
7919 _gtk_window_keys_foreach (window, add_to_key_hash, key_hash);
7920 g_object_set_qdata (G_OBJECT (window), quark_gtk_window_key_hash, key_hash);
7926 gtk_window_free_key_hash (GtkWindow *window)
7928 GtkKeyHash *key_hash = g_object_get_qdata (G_OBJECT (window), quark_gtk_window_key_hash);
7931 _gtk_key_hash_free (key_hash);
7932 g_object_set_qdata (G_OBJECT (window), quark_gtk_window_key_hash, NULL);
7937 * gtk_window_activate_key:
7938 * @window: a #GtkWindow
7939 * @event: a #GdkEventKey
7941 * Activates mnemonics and accelerators for this #GtkWindow. This is normally
7942 * called by the default ::key_press_event handler for toplevel windows,
7943 * however in some cases it may be useful to call this directly when
7944 * overriding the standard key handling for a toplevel window.
7946 * Return value: %TRUE if a mnemonic or accelerator was found and activated.
7949 gtk_window_activate_key (GtkWindow *window,
7952 GtkKeyHash *key_hash;
7953 GtkWindowKeyEntry *found_entry = NULL;
7955 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
7956 g_return_val_if_fail (event != NULL, FALSE);
7958 key_hash = gtk_window_get_key_hash (window);
7962 GSList *entries = _gtk_key_hash_lookup (key_hash,
7963 event->hardware_keycode,
7965 gtk_accelerator_get_default_mod_mask (),
7969 for (tmp_list = entries; tmp_list; tmp_list = tmp_list->next)
7971 GtkWindowKeyEntry *entry = tmp_list->data;
7972 if (entry->is_mnemonic)
7974 found_entry = entry;
7979 if (!found_entry && entries)
7980 found_entry = entries->data;
7982 g_slist_free (entries);
7987 gboolean enable_mnemonics;
7988 gboolean enable_accels;
7990 g_object_get (gtk_widget_get_settings (GTK_WIDGET (window)),
7991 "gtk-enable-mnemonics", &enable_mnemonics,
7992 "gtk-enable-accels", &enable_accels,
7995 if (found_entry->is_mnemonic)
7997 if (enable_mnemonics)
7998 return gtk_window_mnemonic_activate (window, found_entry->keyval,
7999 found_entry->modifiers);
8004 return gtk_accel_groups_activate (G_OBJECT (window), found_entry->keyval,
8005 found_entry->modifiers);
8013 window_update_has_focus (GtkWindow *window)
8015 GtkWidget *widget = GTK_WIDGET (window);
8016 gboolean has_focus = window->has_toplevel_focus && window->is_active;
8018 if (has_focus != window->has_focus)
8020 window->has_focus = has_focus;
8024 if (window->focus_widget &&
8025 window->focus_widget != widget &&
8026 !GTK_WIDGET_HAS_FOCUS (window->focus_widget))
8027 do_focus_change (window->focus_widget, TRUE);
8031 if (window->focus_widget &&
8032 window->focus_widget != widget &&
8033 GTK_WIDGET_HAS_FOCUS (window->focus_widget))
8034 do_focus_change (window->focus_widget, FALSE);
8040 * _gtk_window_set_is_active:
8041 * @window: a #GtkWindow
8042 * @is_active: %TRUE if the window is in the currently active toplevel
8044 * Internal function that sets whether the #GtkWindow is part
8045 * of the currently active toplevel window (taking into account inter-process
8049 _gtk_window_set_is_active (GtkWindow *window,
8052 g_return_if_fail (GTK_IS_WINDOW (window));
8054 is_active = is_active != FALSE;
8056 if (is_active != window->is_active)
8058 window->is_active = is_active;
8059 window_update_has_focus (window);
8061 g_object_notify (G_OBJECT (window), "is-active");
8066 * _gtk_window_set_has_toplevel_focus:
8067 * @window: a #GtkWindow
8068 * @has_toplevel_focus: %TRUE if the in
8070 * Internal function that sets whether the keyboard focus for the
8071 * toplevel window (taking into account inter-process embedding.)
8074 _gtk_window_set_has_toplevel_focus (GtkWindow *window,
8075 gboolean has_toplevel_focus)
8077 g_return_if_fail (GTK_IS_WINDOW (window));
8079 has_toplevel_focus = has_toplevel_focus != FALSE;
8081 if (has_toplevel_focus != window->has_toplevel_focus)
8083 window->has_toplevel_focus = has_toplevel_focus;
8084 window_update_has_focus (window);
8086 g_object_notify (G_OBJECT (window), "has-toplevel-focus");
8091 * gtk_window_set_auto_startup_notification:
8092 * @setting: %TRUE to automatically do startup notification
8094 * By default, after showing the first #GtkWindow, GTK+ calls
8095 * gdk_notify_startup_complete(). Call this function to disable
8096 * the automatic startup notification. You might do this if your
8097 * first window is a splash screen, and you want to delay notification
8098 * until after your real main window has been shown, for example.
8100 * In that example, you would disable startup notification
8101 * temporarily, show your splash screen, then re-enable it so that
8102 * showing the main window would automatically result in notification.
8107 gtk_window_set_auto_startup_notification (gboolean setting)
8109 disable_startup_notification = !setting;
8114 #undef gtk_window_set_icon_from_file
8117 gtk_window_set_icon_from_file (GtkWindow *window,
8118 const gchar *filename,
8121 gchar *utf8_filename = g_locale_to_utf8 (filename, -1, NULL, NULL, err);
8124 if (utf8_filename == NULL)
8127 retval = gtk_window_set_icon_from_file_utf8 (window, utf8_filename, err);
8129 g_free (utf8_filename);
8134 #undef gtk_window_set_default_icon_from_file
8137 gtk_window_set_default_icon_from_file (const gchar *filename,
8140 gchar *utf8_filename = g_locale_to_utf8 (filename, -1, NULL, NULL, err);
8143 if (utf8_filename == NULL)
8146 retval = gtk_window_set_default_icon_from_file_utf8 (utf8_filename, err);
8148 g_free (utf8_filename);
8155 #define __GTK_WINDOW_C__
8156 #include "gtkaliasdef.c"