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