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));
1166 parent_buildable_iface->parser_finished (buildable, builder);
1171 * @type: type of window
1173 * Creates a new #GtkWindow, which is a toplevel window that can
1174 * contain other widgets. Nearly always, the type of the window should
1175 * be #GTK_WINDOW_TOPLEVEL. If you're implementing something like a
1176 * popup menu from scratch (which is a bad idea, just use #GtkMenu),
1177 * you might use #GTK_WINDOW_POPUP. #GTK_WINDOW_POPUP is not for
1178 * dialogs, though in some other toolkits dialogs are called "popups".
1179 * In GTK+, #GTK_WINDOW_POPUP means a pop-up menu or pop-up tooltip.
1180 * On X11, popup windows are not controlled by the <link
1181 * linkend="gtk-X11-arch">window manager</link>.
1183 * If you simply want an undecorated window (no window borders), use
1184 * gtk_window_set_decorated(), don't use #GTK_WINDOW_POPUP.
1186 * Return value: a new #GtkWindow.
1189 gtk_window_new (GtkWindowType type)
1193 g_return_val_if_fail (type >= GTK_WINDOW_TOPLEVEL && type <= GTK_WINDOW_POPUP, NULL);
1195 window = g_object_new (GTK_TYPE_WINDOW, NULL);
1197 window->type = type;
1199 return GTK_WIDGET (window);
1203 * gtk_window_set_title:
1204 * @window: a #GtkWindow
1205 * @title: title of the window
1207 * Sets the title of the #GtkWindow. The title of a window will be
1208 * displayed in its title bar; on the X Window System, the title bar
1209 * is rendered by the <link linkend="gtk-X11-arch">window
1210 * manager</link>, so exactly how the title appears to users may vary
1211 * according to a user's exact configuration. The title should help a
1212 * user distinguish this window from other windows they may have
1213 * open. A good title might include the application name and current
1214 * document filename, for example.
1218 gtk_window_set_title (GtkWindow *window,
1223 g_return_if_fail (GTK_IS_WINDOW (window));
1225 new_title = g_strdup (title);
1226 g_free (window->title);
1227 window->title = new_title;
1229 if (GTK_WIDGET_REALIZED (window))
1231 gdk_window_set_title (GTK_WIDGET (window)->window, window->title);
1233 gtk_decorated_window_set_title (window, title);
1236 g_object_notify (G_OBJECT (window), "title");
1240 * gtk_window_get_title:
1241 * @window: a #GtkWindow
1243 * Retrieves the title of the window. See gtk_window_set_title().
1245 * Return value: the title of the window, or %NULL if none has
1246 * been set explicitely. The returned string is owned by the widget
1247 * and must not be modified or freed.
1249 G_CONST_RETURN gchar *
1250 gtk_window_get_title (GtkWindow *window)
1252 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
1254 return window->title;
1258 * gtk_window_set_wmclass:
1259 * @window: a #GtkWindow
1260 * @wmclass_name: window name hint
1261 * @wmclass_class: window class hint
1263 * Don't use this function. It sets the X Window System "class" and
1264 * "name" hints for a window. According to the ICCCM, you should
1265 * always set these to the same value for all windows in an
1266 * application, and GTK+ sets them to that value by default, so calling
1267 * this function is sort of pointless. However, you may want to call
1268 * gtk_window_set_role() on each window in your application, for the
1269 * benefit of the session manager. Setting the role allows the window
1270 * manager to restore window positions when loading a saved session.
1274 gtk_window_set_wmclass (GtkWindow *window,
1275 const gchar *wmclass_name,
1276 const gchar *wmclass_class)
1278 g_return_if_fail (GTK_IS_WINDOW (window));
1280 g_free (window->wmclass_name);
1281 window->wmclass_name = g_strdup (wmclass_name);
1283 g_free (window->wmclass_class);
1284 window->wmclass_class = g_strdup (wmclass_class);
1286 if (GTK_WIDGET_REALIZED (window))
1287 g_warning ("gtk_window_set_wmclass: shouldn't set wmclass after window is realized!\n");
1291 * gtk_window_set_role:
1292 * @window: a #GtkWindow
1293 * @role: unique identifier for the window to be used when restoring a session
1295 * This function is only useful on X11, not with other GTK+ targets.
1297 * In combination with the window title, the window role allows a
1298 * <link linkend="gtk-X11-arch">window manager</link> to identify "the
1299 * same" window when an application is restarted. So for example you
1300 * might set the "toolbox" role on your app's toolbox window, so that
1301 * when the user restarts their session, the window manager can put
1302 * the toolbox back in the same place.
1304 * If a window already has a unique title, you don't need to set the
1305 * role, since the WM can use the title to identify the window when
1306 * restoring the session.
1310 gtk_window_set_role (GtkWindow *window,
1315 g_return_if_fail (GTK_IS_WINDOW (window));
1317 new_role = g_strdup (role);
1318 g_free (window->wm_role);
1319 window->wm_role = new_role;
1321 if (GTK_WIDGET_REALIZED (window))
1322 gdk_window_set_role (GTK_WIDGET (window)->window, window->wm_role);
1324 g_object_notify (G_OBJECT (window), "role");
1328 * gtk_window_set_startup_id:
1329 * @window: a #GtkWindow
1330 * @startup_id: a string with startup-notification identifier
1332 * Startup notification identifiers are used by desktop environment to
1333 * track application startup, to provide user feedback and other
1334 * features. This function changes the corresponding property on the
1335 * underlying GdkWindow. Normally, startup identifier is managed
1336 * automatically and you should only use this function in special cases
1337 * like transferring focus from other processes. You should use this
1338 * function before calling gtk_window_present() or any equivalent
1339 * function generating a window map event.
1341 * This function is only useful on X11, not with other GTK+ targets.
1346 gtk_window_set_startup_id (GtkWindow *window,
1347 const gchar *startup_id)
1349 GtkWindowPrivate *priv = GTK_WINDOW_GET_PRIVATE (window);
1351 g_return_if_fail (GTK_IS_WINDOW (window));
1353 g_free (priv->startup_id);
1354 priv->startup_id = g_strdup (startup_id);
1356 if (GTK_WIDGET_REALIZED (window))
1358 /* Here we differentiate real and "fake" startup notification IDs,
1359 * constructed on purpose just to pass interaction timestamp
1361 if (startup_id_is_fake (priv->startup_id))
1363 guint32 timestamp = extract_time_from_startup_id (priv->startup_id);
1365 gtk_window_present_with_time (window, timestamp);
1369 gdk_window_set_startup_id (GTK_WIDGET (window)->window,
1372 /* If window is mapped, terminate the startup-notification too */
1373 if (GTK_WIDGET_MAPPED (window) && !disable_startup_notification)
1374 gdk_notify_startup_complete_with_id (priv->startup_id);
1378 g_object_notify (G_OBJECT (window), "startup-id");
1382 * gtk_window_get_role:
1383 * @window: a #GtkWindow
1385 * Returns the role of the window. See gtk_window_set_role() for
1386 * further explanation.
1388 * Return value: the role of the window if set, or %NULL. The
1389 * returned is owned by the widget and must not be modified
1392 G_CONST_RETURN gchar *
1393 gtk_window_get_role (GtkWindow *window)
1395 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
1397 return window->wm_role;
1401 * gtk_window_set_focus:
1402 * @window: a #GtkWindow
1403 * @focus: widget to be the new focus widget, or %NULL to unset
1404 * any focus widget for the toplevel window.
1406 * If @focus is not the current focus widget, and is focusable, sets
1407 * it as the focus widget for the window. If @focus is %NULL, unsets
1408 * the focus widget for this window. To set the focus to a particular
1409 * widget in the toplevel, it is usually more convenient to use
1410 * gtk_widget_grab_focus() instead of this function.
1413 gtk_window_set_focus (GtkWindow *window,
1416 g_return_if_fail (GTK_IS_WINDOW (window));
1419 g_return_if_fail (GTK_IS_WIDGET (focus));
1420 g_return_if_fail (GTK_WIDGET_CAN_FOCUS (focus));
1424 gtk_widget_grab_focus (focus);
1427 /* Clear the existing focus chain, so that when we focus into
1428 * the window again, we start at the beginnning.
1430 GtkWidget *widget = window->focus_widget;
1433 while (widget->parent)
1435 widget = widget->parent;
1436 gtk_container_set_focus_child (GTK_CONTAINER (widget), NULL);
1440 _gtk_window_internal_set_focus (window, NULL);
1445 _gtk_window_internal_set_focus (GtkWindow *window,
1448 g_return_if_fail (GTK_IS_WINDOW (window));
1450 if ((window->focus_widget != focus) ||
1451 (focus && !GTK_WIDGET_HAS_FOCUS (focus)))
1452 g_signal_emit (window, window_signals[SET_FOCUS], 0, focus);
1456 * gtk_window_set_default:
1457 * @window: a #GtkWindow
1458 * @default_widget: widget to be the default, or %NULL to unset the
1459 * default widget for the toplevel.
1461 * The default widget is the widget that's activated when the user
1462 * presses Enter in a dialog (for example). This function sets or
1463 * unsets the default widget for a #GtkWindow about. When setting
1464 * (rather than unsetting) the default widget it's generally easier to
1465 * call gtk_widget_grab_focus() on the widget. Before making a widget
1466 * the default widget, you must set the #GTK_CAN_DEFAULT flag on the
1467 * widget you'd like to make the default using GTK_WIDGET_SET_FLAGS().
1470 gtk_window_set_default (GtkWindow *window,
1471 GtkWidget *default_widget)
1473 g_return_if_fail (GTK_IS_WINDOW (window));
1476 g_return_if_fail (GTK_WIDGET_CAN_DEFAULT (default_widget));
1478 if (window->default_widget != default_widget)
1480 GtkWidget *old_default_widget = NULL;
1483 g_object_ref (default_widget);
1485 if (window->default_widget)
1487 old_default_widget = window->default_widget;
1489 if (window->focus_widget != window->default_widget ||
1490 !GTK_WIDGET_RECEIVES_DEFAULT (window->default_widget))
1491 GTK_WIDGET_UNSET_FLAGS (window->default_widget, GTK_HAS_DEFAULT);
1492 gtk_widget_queue_draw (window->default_widget);
1495 window->default_widget = default_widget;
1497 if (window->default_widget)
1499 if (window->focus_widget == NULL ||
1500 !GTK_WIDGET_RECEIVES_DEFAULT (window->focus_widget))
1501 GTK_WIDGET_SET_FLAGS (window->default_widget, GTK_HAS_DEFAULT);
1502 gtk_widget_queue_draw (window->default_widget);
1505 if (old_default_widget)
1506 g_object_notify (G_OBJECT (old_default_widget), "has-default");
1510 g_object_notify (G_OBJECT (default_widget), "has-default");
1511 g_object_unref (default_widget);
1517 * gtk_window_get_default:
1518 * @window: a #GtkWindow
1520 * Returns the default widget for @window. See gtk_window_set_default()
1523 * Returns: the default widget, or %NULL if there is none.
1528 gtk_window_get_default (GtkWindow *window)
1530 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
1532 return window->default_widget;
1536 gtk_window_set_policy (GtkWindow *window,
1537 gboolean allow_shrink,
1538 gboolean allow_grow,
1539 gboolean auto_shrink)
1541 g_return_if_fail (GTK_IS_WINDOW (window));
1543 window->allow_shrink = (allow_shrink != FALSE);
1544 window->allow_grow = (allow_grow != FALSE);
1546 g_object_freeze_notify (G_OBJECT (window));
1547 g_object_notify (G_OBJECT (window), "allow-shrink");
1548 g_object_notify (G_OBJECT (window), "allow-grow");
1549 g_object_notify (G_OBJECT (window), "resizable");
1550 g_object_thaw_notify (G_OBJECT (window));
1552 gtk_widget_queue_resize (GTK_WIDGET (window));
1556 handle_keys_changed (gpointer data)
1560 window = GTK_WINDOW (data);
1562 if (window->keys_changed_handler)
1564 g_source_remove (window->keys_changed_handler);
1565 window->keys_changed_handler = 0;
1568 g_signal_emit (window, window_signals[KEYS_CHANGED], 0);
1574 gtk_window_notify_keys_changed (GtkWindow *window)
1576 if (!window->keys_changed_handler)
1577 window->keys_changed_handler = gdk_threads_add_idle (handle_keys_changed, window);
1581 * gtk_window_add_accel_group:
1582 * @window: window to attach accelerator group to
1583 * @accel_group: a #GtkAccelGroup
1585 * Associate @accel_group with @window, such that calling
1586 * gtk_accel_groups_activate() on @window will activate accelerators
1590 gtk_window_add_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 _gtk_accel_group_attach (accel_group, G_OBJECT (window));
1597 g_signal_connect_object (accel_group, "accel_changed",
1598 G_CALLBACK (gtk_window_notify_keys_changed),
1599 window, G_CONNECT_SWAPPED);
1600 gtk_window_notify_keys_changed (window);
1604 * gtk_window_remove_accel_group:
1605 * @window: a #GtkWindow
1606 * @accel_group: a #GtkAccelGroup
1608 * Reverses the effects of gtk_window_add_accel_group().
1611 gtk_window_remove_accel_group (GtkWindow *window,
1612 GtkAccelGroup *accel_group)
1614 g_return_if_fail (GTK_IS_WINDOW (window));
1615 g_return_if_fail (GTK_IS_ACCEL_GROUP (accel_group));
1617 g_signal_handlers_disconnect_by_func (accel_group,
1618 gtk_window_notify_keys_changed,
1620 _gtk_accel_group_detach (accel_group, G_OBJECT (window));
1621 gtk_window_notify_keys_changed (window);
1624 static GtkMnemonicHash *
1625 gtk_window_get_mnemonic_hash (GtkWindow *window,
1628 GtkWindowPrivate *private = GTK_WINDOW_GET_PRIVATE (window);
1629 if (!private->mnemonic_hash && create)
1630 private->mnemonic_hash = _gtk_mnemonic_hash_new ();
1632 return private->mnemonic_hash;
1636 * gtk_window_add_mnemonic:
1637 * @window: a #GtkWindow
1638 * @keyval: the mnemonic
1639 * @target: the widget that gets activated by the mnemonic
1641 * Adds a mnemonic to this window.
1644 gtk_window_add_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_add (gtk_window_get_mnemonic_hash (window, TRUE),
1653 gtk_window_notify_keys_changed (window);
1657 * gtk_window_remove_mnemonic:
1658 * @window: a #GtkWindow
1659 * @keyval: the mnemonic
1660 * @target: the widget that gets activated by the mnemonic
1662 * Removes a mnemonic from this window.
1665 gtk_window_remove_mnemonic (GtkWindow *window,
1669 g_return_if_fail (GTK_IS_WINDOW (window));
1670 g_return_if_fail (GTK_IS_WIDGET (target));
1672 _gtk_mnemonic_hash_remove (gtk_window_get_mnemonic_hash (window, TRUE),
1674 gtk_window_notify_keys_changed (window);
1678 * gtk_window_mnemonic_activate:
1679 * @window: a #GtkWindow
1680 * @keyval: the mnemonic
1681 * @modifier: the modifiers
1682 * @returns: %TRUE if the activation is done.
1684 * Activates the targets associated with the mnemonic.
1687 gtk_window_mnemonic_activate (GtkWindow *window,
1689 GdkModifierType modifier)
1691 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
1693 if (window->mnemonic_modifier == (modifier & gtk_accelerator_get_default_mod_mask ()))
1695 GtkMnemonicHash *mnemonic_hash = gtk_window_get_mnemonic_hash (window, FALSE);
1697 return _gtk_mnemonic_hash_activate (mnemonic_hash, keyval);
1704 * gtk_window_set_mnemonic_modifier:
1705 * @window: a #GtkWindow
1706 * @modifier: the modifier mask used to activate
1707 * mnemonics on this window.
1709 * Sets the mnemonic modifier for this window.
1712 gtk_window_set_mnemonic_modifier (GtkWindow *window,
1713 GdkModifierType modifier)
1715 g_return_if_fail (GTK_IS_WINDOW (window));
1716 g_return_if_fail ((modifier & ~GDK_MODIFIER_MASK) == 0);
1718 window->mnemonic_modifier = modifier;
1719 gtk_window_notify_keys_changed (window);
1723 * gtk_window_get_mnemonic_modifier:
1724 * @window: a #GtkWindow
1726 * Returns the mnemonic modifier for this window. See
1727 * gtk_window_set_mnemonic_modifier().
1729 * Return value: the modifier mask used to activate
1730 * mnemonics on this window.
1733 gtk_window_get_mnemonic_modifier (GtkWindow *window)
1735 g_return_val_if_fail (GTK_IS_WINDOW (window), 0);
1737 return window->mnemonic_modifier;
1741 * gtk_window_set_position:
1742 * @window: a #GtkWindow.
1743 * @position: a position constraint.
1745 * Sets a position constraint for this window. If the old or new
1746 * constraint is %GTK_WIN_POS_CENTER_ALWAYS, this will also cause
1747 * the window to be repositioned to satisfy the new constraint.
1750 gtk_window_set_position (GtkWindow *window,
1751 GtkWindowPosition position)
1753 g_return_if_fail (GTK_IS_WINDOW (window));
1755 if (position == GTK_WIN_POS_CENTER_ALWAYS ||
1756 window->position == GTK_WIN_POS_CENTER_ALWAYS)
1758 GtkWindowGeometryInfo *info;
1760 info = gtk_window_get_geometry_info (window, TRUE);
1762 /* this flag causes us to re-request the CENTER_ALWAYS
1763 * constraint in gtk_window_move_resize(), see
1764 * comment in that function.
1766 info->position_constraints_changed = TRUE;
1768 gtk_widget_queue_resize (GTK_WIDGET (window));
1771 window->position = position;
1773 g_object_notify (G_OBJECT (window), "window-position");
1777 * gtk_window_activate_focus:
1778 * @window: a #GtkWindow
1780 * Activates the current focused widget within the window.
1782 * Return value: %TRUE if a widget got activated.
1785 gtk_window_activate_focus (GtkWindow *window)
1787 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
1789 if (window->focus_widget && GTK_WIDGET_IS_SENSITIVE (window->focus_widget))
1790 return gtk_widget_activate (window->focus_widget);
1796 * gtk_window_get_focus:
1797 * @window: a #GtkWindow
1799 * Retrieves the current focused widget within the window.
1800 * Note that this is the widget that would have the focus
1801 * if the toplevel window focused; if the toplevel window
1802 * is not focused then <literal>GTK_WIDGET_HAS_FOCUS (widget)</literal> will
1803 * not be %TRUE for the widget.
1805 * Return value: the currently focused widget, or %NULL if there is none.
1808 gtk_window_get_focus (GtkWindow *window)
1810 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
1812 return window->focus_widget;
1816 * gtk_window_activate_default:
1817 * @window: a #GtkWindow
1819 * Activates the default widget for the window, unless the current
1820 * focused widget has been configured to receive the default action
1821 * (see #GTK_RECEIVES_DEFAULT in #GtkWidgetFlags), in which case the
1822 * focused widget is activated.
1824 * Return value: %TRUE if a widget got activated.
1827 gtk_window_activate_default (GtkWindow *window)
1829 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
1831 if (window->default_widget && GTK_WIDGET_IS_SENSITIVE (window->default_widget) &&
1832 (!window->focus_widget || !GTK_WIDGET_RECEIVES_DEFAULT (window->focus_widget)))
1833 return gtk_widget_activate (window->default_widget);
1834 else if (window->focus_widget && GTK_WIDGET_IS_SENSITIVE (window->focus_widget))
1835 return gtk_widget_activate (window->focus_widget);
1841 * gtk_window_set_modal:
1842 * @window: a #GtkWindow
1843 * @modal: whether the window is modal
1845 * Sets a window modal or non-modal. Modal windows prevent interaction
1846 * with other windows in the same application. To keep modal dialogs
1847 * on top of main application windows, use
1848 * gtk_window_set_transient_for() to make the dialog transient for the
1849 * parent; most <link linkend="gtk-X11-arch">window managers</link>
1850 * will then disallow lowering the dialog below the parent.
1855 gtk_window_set_modal (GtkWindow *window,
1858 g_return_if_fail (GTK_IS_WINDOW (window));
1860 modal = modal != FALSE;
1861 if (window->modal == modal)
1864 window->modal = modal;
1866 /* adjust desired modality state */
1867 if (GTK_WIDGET_REALIZED (window))
1869 GtkWidget *widget = GTK_WIDGET (window);
1872 gdk_window_set_modal_hint (widget->window, TRUE);
1874 gdk_window_set_modal_hint (widget->window, FALSE);
1877 if (GTK_WIDGET_VISIBLE (window))
1880 gtk_grab_add (GTK_WIDGET (window));
1882 gtk_grab_remove (GTK_WIDGET (window));
1885 g_object_notify (G_OBJECT (window), "modal");
1889 * gtk_window_get_modal:
1890 * @window: a #GtkWindow
1892 * Returns whether the window is modal. See gtk_window_set_modal().
1894 * Return value: %TRUE if the window is set to be modal and
1895 * establishes a grab when shown
1898 gtk_window_get_modal (GtkWindow *window)
1900 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
1902 return window->modal;
1906 * gtk_window_list_toplevels:
1908 * Returns a list of all existing toplevel windows. The widgets
1909 * in the list are not individually referenced. If you want
1910 * to iterate through the list and perform actions involving
1911 * callbacks that might destroy the widgets, you <emphasis>must</emphasis> call
1912 * <literal>g_list_foreach (result, (GFunc)g_object_ref, NULL)</literal> first, and
1913 * then unref all the widgets afterwards.
1915 * Return value: list of toplevel widgets
1918 gtk_window_list_toplevels (void)
1923 for (slist = toplevel_list; slist; slist = slist->next)
1924 list = g_list_prepend (list, slist->data);
1930 gtk_window_add_embedded_xid (GtkWindow *window, guint xid)
1932 GList *embedded_windows;
1934 g_return_if_fail (GTK_IS_WINDOW (window));
1936 embedded_windows = g_object_get_qdata (G_OBJECT (window), quark_gtk_embedded);
1937 if (embedded_windows)
1938 g_object_steal_qdata (G_OBJECT (window), quark_gtk_embedded);
1939 embedded_windows = g_list_prepend (embedded_windows,
1940 GUINT_TO_POINTER (xid));
1942 g_object_set_qdata_full (G_OBJECT (window), quark_gtk_embedded,
1945 (GDestroyNotify) g_list_free : NULL);
1949 gtk_window_remove_embedded_xid (GtkWindow *window, guint xid)
1951 GList *embedded_windows;
1954 g_return_if_fail (GTK_IS_WINDOW (window));
1956 embedded_windows = g_object_get_qdata (G_OBJECT (window), quark_gtk_embedded);
1957 if (embedded_windows)
1958 g_object_steal_qdata (G_OBJECT (window), quark_gtk_embedded);
1960 node = g_list_find (embedded_windows, GUINT_TO_POINTER (xid));
1963 embedded_windows = g_list_remove_link (embedded_windows, node);
1964 g_list_free_1 (node);
1967 g_object_set_qdata_full (G_OBJECT (window), quark_gtk_embedded,
1970 (GDestroyNotify) g_list_free : NULL);
1974 _gtk_window_reposition (GtkWindow *window,
1978 g_return_if_fail (GTK_IS_WINDOW (window));
1980 gtk_window_move (window, x, y);
1984 gtk_window_dispose (GObject *object)
1986 GtkWindow *window = GTK_WINDOW (object);
1988 gtk_window_set_focus (window, NULL);
1989 gtk_window_set_default (window, NULL);
1991 G_OBJECT_CLASS (gtk_window_parent_class)->dispose (object);
1995 parent_destroyed_callback (GtkWindow *parent, GtkWindow *child)
1997 gtk_widget_destroy (GTK_WIDGET (child));
2001 connect_parent_destroyed (GtkWindow *window)
2003 if (window->transient_parent)
2005 g_signal_connect (window->transient_parent,
2007 G_CALLBACK (parent_destroyed_callback),
2013 disconnect_parent_destroyed (GtkWindow *window)
2015 if (window->transient_parent)
2017 g_signal_handlers_disconnect_by_func (window->transient_parent,
2018 parent_destroyed_callback,
2024 gtk_window_transient_parent_realized (GtkWidget *parent,
2027 if (GTK_WIDGET_REALIZED (window))
2028 gdk_window_set_transient_for (window->window, parent->window);
2032 gtk_window_transient_parent_unrealized (GtkWidget *parent,
2035 if (GTK_WIDGET_REALIZED (window))
2036 gdk_property_delete (window->window,
2037 gdk_atom_intern_static_string ("WM_TRANSIENT_FOR"));
2041 gtk_window_transient_parent_screen_changed (GtkWindow *parent,
2045 gtk_window_set_screen (window, parent->screen);
2049 gtk_window_unset_transient_for (GtkWindow *window)
2051 GtkWindowPrivate *priv = GTK_WINDOW_GET_PRIVATE (window);
2053 if (window->transient_parent)
2055 if (priv->transient_parent_group)
2056 gtk_window_group_remove_window (window->group,
2059 g_signal_handlers_disconnect_by_func (window->transient_parent,
2060 gtk_window_transient_parent_realized,
2062 g_signal_handlers_disconnect_by_func (window->transient_parent,
2063 gtk_window_transient_parent_unrealized,
2065 g_signal_handlers_disconnect_by_func (window->transient_parent,
2066 gtk_window_transient_parent_screen_changed,
2068 g_signal_handlers_disconnect_by_func (window->transient_parent,
2069 gtk_widget_destroyed,
2070 &window->transient_parent);
2072 if (window->destroy_with_parent)
2073 disconnect_parent_destroyed (window);
2075 window->transient_parent = NULL;
2076 priv->transient_parent_group = FALSE;
2081 * gtk_window_set_transient_for:
2082 * @window: a #GtkWindow
2083 * @parent: parent window
2085 * Dialog windows should be set transient for the main application
2086 * window they were spawned from. This allows <link
2087 * linkend="gtk-X11-arch">window managers</link> to e.g. keep the
2088 * dialog on top of the main window, or center the dialog over the
2089 * main window. gtk_dialog_new_with_buttons() and other convenience
2090 * functions in GTK+ will sometimes call
2091 * gtk_window_set_transient_for() on your behalf.
2093 * On Windows, this function puts the child window on top of the parent,
2094 * much as the window manager would have done on X.
2098 gtk_window_set_transient_for (GtkWindow *window,
2101 GtkWindowPrivate *priv = GTK_WINDOW_GET_PRIVATE (window);
2103 g_return_if_fail (GTK_IS_WINDOW (window));
2104 g_return_if_fail (parent == NULL || GTK_IS_WINDOW (parent));
2105 g_return_if_fail (window != parent);
2107 if (window->transient_parent)
2109 if (GTK_WIDGET_REALIZED (window) &&
2110 GTK_WIDGET_REALIZED (window->transient_parent) &&
2111 (!parent || !GTK_WIDGET_REALIZED (parent)))
2112 gtk_window_transient_parent_unrealized (GTK_WIDGET (window->transient_parent),
2113 GTK_WIDGET (window));
2115 gtk_window_unset_transient_for (window);
2118 window->transient_parent = parent;
2122 g_signal_connect (parent, "destroy",
2123 G_CALLBACK (gtk_widget_destroyed),
2124 &window->transient_parent);
2125 g_signal_connect (parent, "realize",
2126 G_CALLBACK (gtk_window_transient_parent_realized),
2128 g_signal_connect (parent, "unrealize",
2129 G_CALLBACK (gtk_window_transient_parent_unrealized),
2131 g_signal_connect (parent, "notify::screen",
2132 G_CALLBACK (gtk_window_transient_parent_screen_changed),
2135 gtk_window_set_screen (window, parent->screen);
2137 if (window->destroy_with_parent)
2138 connect_parent_destroyed (window);
2140 if (GTK_WIDGET_REALIZED (window) &&
2141 GTK_WIDGET_REALIZED (parent))
2142 gtk_window_transient_parent_realized (GTK_WIDGET (parent),
2143 GTK_WIDGET (window));
2147 gtk_window_group_add_window (parent->group, window);
2148 priv->transient_parent_group = TRUE;
2154 * gtk_window_get_transient_for:
2155 * @window: a #GtkWindow
2157 * Fetches the transient parent for this window. See
2158 * gtk_window_set_transient_for().
2160 * Return value: the transient parent for this window, or %NULL
2161 * if no transient parent has been set.
2164 gtk_window_get_transient_for (GtkWindow *window)
2166 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
2168 return window->transient_parent;
2172 * gtk_window_set_opacity:
2173 * @window: a #GtkWindow
2174 * @opacity: desired opacity, between 0 and 1
2176 * Request the windowing system to make @window partially transparent,
2177 * with opacity 0 being fully transparent and 1 fully opaque. (Values
2178 * of the opacity parameter are clamped to the [0,1] range.) On X11
2179 * this has any effect only on X screens with a compositing manager
2180 * running. See gtk_widget_is_composited(). On Windows it should work
2183 * Note that setting a window's opacity after the window has been
2184 * shown causes it to flicker once on Windows.
2189 gtk_window_set_opacity (GtkWindow *window,
2192 GtkWindowPrivate *priv;
2194 g_return_if_fail (GTK_IS_WINDOW (window));
2196 priv = GTK_WINDOW_GET_PRIVATE (window);
2200 else if (opacity > 1.0)
2203 priv->opacity_set = TRUE;
2204 priv->opacity = opacity;
2206 if (GTK_WIDGET_REALIZED (window))
2207 gdk_window_set_opacity (GTK_WIDGET (window)->window, priv->opacity);
2211 * gtk_window_get_opacity:
2212 * @window: a #GtkWindow
2214 * Fetches the requested opacity for this window. See
2215 * gtk_window_set_opacity().
2217 * Return value: the requested opacity for this window.
2222 gtk_window_get_opacity (GtkWindow *window)
2224 GtkWindowPrivate *priv;
2226 g_return_val_if_fail (GTK_IS_WINDOW (window), 0.0);
2228 priv = GTK_WINDOW_GET_PRIVATE (window);
2230 return priv->opacity;
2234 * gtk_window_set_type_hint:
2235 * @window: a #GtkWindow
2236 * @hint: the window type
2238 * By setting the type hint for the window, you allow the window
2239 * manager to decorate and handle the window in a way which is
2240 * suitable to the function of the window in your application.
2242 * This function should be called before the window becomes visible.
2244 * gtk_dialog_new_with_buttons() and other convenience functions in GTK+
2245 * will sometimes call gtk_window_set_type_hint() on your behalf.
2249 gtk_window_set_type_hint (GtkWindow *window,
2250 GdkWindowTypeHint hint)
2252 GtkWindowPrivate *priv;
2254 g_return_if_fail (GTK_IS_WINDOW (window));
2255 g_return_if_fail (!GTK_WIDGET_VISIBLE (window));
2257 priv = GTK_WINDOW_GET_PRIVATE (window);
2259 if (hint < GDK_WINDOW_TYPE_HINT_DROPDOWN_MENU)
2260 window->type_hint = hint;
2262 window->type_hint = GDK_WINDOW_TYPE_HINT_NORMAL;
2264 priv->reset_type_hint = TRUE;
2265 priv->type_hint = hint;
2269 * gtk_window_get_type_hint:
2270 * @window: a #GtkWindow
2272 * Gets the type hint for this window. See gtk_window_set_type_hint().
2274 * Return value: the type hint for @window.
2277 gtk_window_get_type_hint (GtkWindow *window)
2279 GtkWindowPrivate *priv;
2281 g_return_val_if_fail (GTK_IS_WINDOW (window), GDK_WINDOW_TYPE_HINT_NORMAL);
2283 priv = GTK_WINDOW_GET_PRIVATE (window);
2285 return priv->type_hint;
2289 * gtk_window_set_skip_taskbar_hint:
2290 * @window: a #GtkWindow
2291 * @setting: %TRUE to keep this window from appearing in the task bar
2293 * Windows may set a hint asking the desktop environment not to display
2294 * the window in the task bar. This function sets this hint.
2299 gtk_window_set_skip_taskbar_hint (GtkWindow *window,
2302 GtkWindowPrivate *priv;
2304 g_return_if_fail (GTK_IS_WINDOW (window));
2306 priv = GTK_WINDOW_GET_PRIVATE (window);
2308 setting = setting != FALSE;
2310 if (priv->skips_taskbar != setting)
2312 priv->skips_taskbar = setting;
2313 if (GTK_WIDGET_REALIZED (window))
2314 gdk_window_set_skip_taskbar_hint (GTK_WIDGET (window)->window,
2315 priv->skips_taskbar);
2316 g_object_notify (G_OBJECT (window), "skip-taskbar-hint");
2321 * gtk_window_get_skip_taskbar_hint:
2322 * @window: a #GtkWindow
2324 * Gets the value set by gtk_window_set_skip_taskbar_hint()
2326 * Return value: %TRUE if window shouldn't be in taskbar
2331 gtk_window_get_skip_taskbar_hint (GtkWindow *window)
2333 GtkWindowPrivate *priv;
2335 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
2337 priv = GTK_WINDOW_GET_PRIVATE (window);
2339 return priv->skips_taskbar;
2343 * gtk_window_set_skip_pager_hint:
2344 * @window: a #GtkWindow
2345 * @setting: %TRUE to keep this window from appearing in the pager
2347 * Windows may set a hint asking the desktop environment not to display
2348 * the window in the pager. This function sets this hint.
2349 * (A "pager" is any desktop navigation tool such as a workspace
2350 * switcher that displays a thumbnail representation of the windows
2356 gtk_window_set_skip_pager_hint (GtkWindow *window,
2359 GtkWindowPrivate *priv;
2361 g_return_if_fail (GTK_IS_WINDOW (window));
2363 priv = GTK_WINDOW_GET_PRIVATE (window);
2365 setting = setting != FALSE;
2367 if (priv->skips_pager != setting)
2369 priv->skips_pager = setting;
2370 if (GTK_WIDGET_REALIZED (window))
2371 gdk_window_set_skip_pager_hint (GTK_WIDGET (window)->window,
2373 g_object_notify (G_OBJECT (window), "skip-pager-hint");
2378 * gtk_window_get_skip_pager_hint:
2379 * @window: a #GtkWindow
2381 * Gets the value set by gtk_window_set_skip_pager_hint().
2383 * Return value: %TRUE if window shouldn't be in pager
2388 gtk_window_get_skip_pager_hint (GtkWindow *window)
2390 GtkWindowPrivate *priv;
2392 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
2394 priv = GTK_WINDOW_GET_PRIVATE (window);
2396 return priv->skips_pager;
2400 * gtk_window_set_urgency_hint:
2401 * @window: a #GtkWindow
2402 * @setting: %TRUE to mark this window as urgent
2404 * Windows may set a hint asking the desktop environment to draw
2405 * the users attention to the window. This function sets this hint.
2410 gtk_window_set_urgency_hint (GtkWindow *window,
2413 GtkWindowPrivate *priv;
2415 g_return_if_fail (GTK_IS_WINDOW (window));
2417 priv = GTK_WINDOW_GET_PRIVATE (window);
2419 setting = setting != FALSE;
2421 if (priv->urgent != setting)
2423 priv->urgent = setting;
2424 if (GTK_WIDGET_REALIZED (window))
2425 gdk_window_set_urgency_hint (GTK_WIDGET (window)->window,
2427 g_object_notify (G_OBJECT (window), "urgency-hint");
2432 * gtk_window_get_urgency_hint:
2433 * @window: a #GtkWindow
2435 * Gets the value set by gtk_window_set_urgency_hint()
2437 * Return value: %TRUE if window is urgent
2442 gtk_window_get_urgency_hint (GtkWindow *window)
2444 GtkWindowPrivate *priv;
2446 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
2448 priv = GTK_WINDOW_GET_PRIVATE (window);
2450 return priv->urgent;
2454 * gtk_window_set_accept_focus:
2455 * @window: a #GtkWindow
2456 * @setting: %TRUE to let this window receive input focus
2458 * Windows may set a hint asking the desktop environment not to receive
2459 * the input focus. This function sets this hint.
2464 gtk_window_set_accept_focus (GtkWindow *window,
2467 GtkWindowPrivate *priv;
2469 g_return_if_fail (GTK_IS_WINDOW (window));
2471 priv = GTK_WINDOW_GET_PRIVATE (window);
2473 setting = setting != FALSE;
2475 if (priv->accept_focus != setting)
2477 priv->accept_focus = setting;
2478 if (GTK_WIDGET_REALIZED (window))
2479 gdk_window_set_accept_focus (GTK_WIDGET (window)->window,
2480 priv->accept_focus);
2481 g_object_notify (G_OBJECT (window), "accept-focus");
2486 * gtk_window_get_accept_focus:
2487 * @window: a #GtkWindow
2489 * Gets the value set by gtk_window_set_accept_focus().
2491 * Return value: %TRUE if window should receive the input focus
2496 gtk_window_get_accept_focus (GtkWindow *window)
2498 GtkWindowPrivate *priv;
2500 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
2502 priv = GTK_WINDOW_GET_PRIVATE (window);
2504 return priv->accept_focus;
2508 * gtk_window_set_focus_on_map:
2509 * @window: a #GtkWindow
2510 * @setting: %TRUE to let this window receive input focus on map
2512 * Windows may set a hint asking the desktop environment not to receive
2513 * the input focus when the window is mapped. This function sets this
2519 gtk_window_set_focus_on_map (GtkWindow *window,
2522 GtkWindowPrivate *priv;
2524 g_return_if_fail (GTK_IS_WINDOW (window));
2526 priv = GTK_WINDOW_GET_PRIVATE (window);
2528 setting = setting != FALSE;
2530 if (priv->focus_on_map != setting)
2532 priv->focus_on_map = setting;
2533 if (GTK_WIDGET_REALIZED (window))
2534 gdk_window_set_focus_on_map (GTK_WIDGET (window)->window,
2535 priv->focus_on_map);
2536 g_object_notify (G_OBJECT (window), "focus-on-map");
2541 * gtk_window_get_focus_on_map:
2542 * @window: a #GtkWindow
2544 * Gets the value set by gtk_window_set_focus_on_map().
2546 * Return value: %TRUE if window should receive the input focus when
2552 gtk_window_get_focus_on_map (GtkWindow *window)
2554 GtkWindowPrivate *priv;
2556 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
2558 priv = GTK_WINDOW_GET_PRIVATE (window);
2560 return priv->focus_on_map;
2564 * gtk_window_set_destroy_with_parent:
2565 * @window: a #GtkWindow
2566 * @setting: whether to destroy @window with its transient parent
2568 * If @setting is %TRUE, then destroying the transient parent of @window
2569 * will also destroy @window itself. This is useful for dialogs that
2570 * shouldn't persist beyond the lifetime of the main window they're
2571 * associated with, for example.
2574 gtk_window_set_destroy_with_parent (GtkWindow *window,
2577 g_return_if_fail (GTK_IS_WINDOW (window));
2579 if (window->destroy_with_parent == (setting != FALSE))
2582 if (window->destroy_with_parent)
2584 disconnect_parent_destroyed (window);
2588 connect_parent_destroyed (window);
2591 window->destroy_with_parent = setting;
2593 g_object_notify (G_OBJECT (window), "destroy-with-parent");
2597 * gtk_window_get_destroy_with_parent:
2598 * @window: a #GtkWindow
2600 * Returns whether the window will be destroyed with its transient parent. See
2601 * gtk_window_set_destroy_with_parent ().
2603 * Return value: %TRUE if the window will be destroyed with its transient parent.
2606 gtk_window_get_destroy_with_parent (GtkWindow *window)
2608 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
2610 return window->destroy_with_parent;
2613 static GtkWindowGeometryInfo*
2614 gtk_window_get_geometry_info (GtkWindow *window,
2617 GtkWindowGeometryInfo *info;
2619 info = window->geometry_info;
2620 if (!info && create)
2622 info = g_new0 (GtkWindowGeometryInfo, 1);
2624 info->default_width = -1;
2625 info->default_height = -1;
2626 info->resize_width = -1;
2627 info->resize_height = -1;
2628 info->initial_x = 0;
2629 info->initial_y = 0;
2630 info->initial_pos_set = FALSE;
2631 info->default_is_geometry = FALSE;
2632 info->position_constraints_changed = FALSE;
2633 info->last.configure_request.x = 0;
2634 info->last.configure_request.y = 0;
2635 info->last.configure_request.width = -1;
2636 info->last.configure_request.height = -1;
2637 info->widget = NULL;
2639 window->geometry_info = info;
2646 * gtk_window_set_geometry_hints:
2647 * @window: a #GtkWindow
2648 * @geometry_widget: widget the geometry hints will be applied to
2649 * @geometry: struct containing geometry information
2650 * @geom_mask: mask indicating which struct fields should be paid attention to
2652 * This function sets up hints about how a window can be resized by
2653 * the user. You can set a minimum and maximum size; allowed resize
2654 * increments (e.g. for xterm, you can only resize by the size of a
2655 * character); aspect ratios; and more. See the #GdkGeometry struct.
2659 gtk_window_set_geometry_hints (GtkWindow *window,
2660 GtkWidget *geometry_widget,
2661 GdkGeometry *geometry,
2662 GdkWindowHints geom_mask)
2664 GtkWindowGeometryInfo *info;
2666 g_return_if_fail (GTK_IS_WINDOW (window));
2667 g_return_if_fail (geometry_widget == NULL || GTK_IS_WIDGET (geometry_widget));
2669 info = gtk_window_get_geometry_info (window, TRUE);
2672 g_signal_handlers_disconnect_by_func (info->widget,
2673 gtk_widget_destroyed,
2676 info->widget = geometry_widget;
2678 g_signal_connect (geometry_widget, "destroy",
2679 G_CALLBACK (gtk_widget_destroyed),
2683 info->geometry = *geometry;
2685 /* We store gravity in window->gravity not in the hints. */
2686 info->mask = geom_mask & ~(GDK_HINT_WIN_GRAVITY);
2688 if (geom_mask & GDK_HINT_WIN_GRAVITY)
2690 gtk_window_set_gravity (window, geometry->win_gravity);
2693 gtk_widget_queue_resize (GTK_WIDGET (window));
2697 * gtk_window_set_decorated:
2698 * @window: a #GtkWindow
2699 * @setting: %TRUE to decorate the window
2701 * By default, windows are decorated with a title bar, resize
2702 * controls, etc. Some <link linkend="gtk-X11-arch">window
2703 * managers</link> allow GTK+ to disable these decorations, creating a
2704 * borderless window. If you set the decorated property to %FALSE
2705 * using this function, GTK+ will do its best to convince the window
2706 * manager not to decorate the window. Depending on the system, this
2707 * function may not have any effect when called on a window that is
2708 * already visible, so you should call it before calling gtk_window_show().
2710 * On Windows, this function always works, since there's no window manager
2715 gtk_window_set_decorated (GtkWindow *window,
2718 g_return_if_fail (GTK_IS_WINDOW (window));
2720 setting = setting != FALSE;
2722 if (setting == window->decorated)
2725 window->decorated = setting;
2727 if (GTK_WIDGET (window)->window)
2729 if (window->decorated)
2730 gdk_window_set_decorations (GTK_WIDGET (window)->window,
2733 gdk_window_set_decorations (GTK_WIDGET (window)->window,
2737 g_object_notify (G_OBJECT (window), "decorated");
2741 * gtk_window_get_decorated:
2742 * @window: a #GtkWindow
2744 * Returns whether the window has been set to have decorations
2745 * such as a title bar via gtk_window_set_decorated().
2747 * Return value: %TRUE if the window has been set to have decorations
2750 gtk_window_get_decorated (GtkWindow *window)
2752 g_return_val_if_fail (GTK_IS_WINDOW (window), TRUE);
2754 return window->decorated;
2758 * gtk_window_set_deletable:
2759 * @window: a #GtkWindow
2760 * @setting: %TRUE to decorate the window as deletable
2762 * By default, windows have a close button in the window frame. Some
2763 * <link linkend="gtk-X11-arch">window managers</link> allow GTK+ to
2764 * disable this button. If you set the deletable property to %FALSE
2765 * using this function, GTK+ will do its best to convince the window
2766 * manager not to show a close button. Depending on the system, this
2767 * function may not have any effect when called on a window that is
2768 * already visible, so you should call it before calling gtk_window_show().
2770 * On Windows, this function always works, since there's no window manager
2776 gtk_window_set_deletable (GtkWindow *window,
2779 GtkWindowPrivate *priv;
2781 g_return_if_fail (GTK_IS_WINDOW (window));
2783 priv = GTK_WINDOW_GET_PRIVATE (window);
2785 setting = setting != FALSE;
2787 if (setting == priv->deletable)
2790 priv->deletable = setting;
2792 if (GTK_WIDGET (window)->window)
2794 if (priv->deletable)
2795 gdk_window_set_functions (GTK_WIDGET (window)->window,
2798 gdk_window_set_functions (GTK_WIDGET (window)->window,
2799 GDK_FUNC_ALL | GDK_FUNC_CLOSE);
2802 g_object_notify (G_OBJECT (window), "deletable");
2806 * gtk_window_get_deletable:
2807 * @window: a #GtkWindow
2809 * Returns whether the window has been set to have a close button
2810 * via gtk_window_set_deletable().
2812 * Return value: %TRUE if the window has been set to have a close button
2817 gtk_window_get_deletable (GtkWindow *window)
2819 GtkWindowPrivate *priv;
2821 g_return_val_if_fail (GTK_IS_WINDOW (window), TRUE);
2823 priv = GTK_WINDOW_GET_PRIVATE (window);
2825 return priv->deletable;
2828 static GtkWindowIconInfo*
2829 get_icon_info (GtkWindow *window)
2831 return g_object_get_qdata (G_OBJECT (window), quark_gtk_window_icon_info);
2835 free_icon_info (GtkWindowIconInfo *info)
2837 g_free (info->icon_name);
2838 g_slice_free (GtkWindowIconInfo, info);
2842 static GtkWindowIconInfo*
2843 ensure_icon_info (GtkWindow *window)
2845 GtkWindowIconInfo *info;
2847 info = get_icon_info (window);
2851 info = g_slice_new0 (GtkWindowIconInfo);
2852 g_object_set_qdata_full (G_OBJECT (window),
2853 quark_gtk_window_icon_info,
2855 (GDestroyNotify)free_icon_info);
2867 static ScreenIconInfo *
2868 get_screen_icon_info (GdkScreen *screen)
2870 ScreenIconInfo *info = g_object_get_qdata (G_OBJECT (screen),
2871 quark_gtk_window_default_icon_pixmap);
2874 info = g_slice_new0 (ScreenIconInfo);
2875 g_object_set_qdata (G_OBJECT (screen),
2876 quark_gtk_window_default_icon_pixmap, info);
2879 if (info->serial != default_icon_serial)
2883 g_object_remove_weak_pointer (G_OBJECT (info->pixmap), (gpointer*)&info->pixmap);
2884 info->pixmap = NULL;
2889 g_object_remove_weak_pointer (G_OBJECT (info->mask), (gpointer*)&info->mask);
2893 info->serial = default_icon_serial;
2900 get_pixmap_and_mask (GdkWindow *window,
2901 GtkWindowIconInfo *parent_info,
2902 gboolean is_default_list,
2904 GdkPixmap **pmap_return,
2905 GdkBitmap **mask_return)
2907 GdkScreen *screen = gdk_drawable_get_screen (window);
2908 ScreenIconInfo *default_icon_info = get_screen_icon_info (screen);
2909 GdkPixbuf *best_icon;
2913 *pmap_return = NULL;
2914 *mask_return = NULL;
2916 if (is_default_list &&
2917 default_icon_info->pixmap != NULL)
2919 /* Use shared icon pixmap for all windows on this screen.
2921 if (default_icon_info->pixmap)
2922 g_object_ref (default_icon_info->pixmap);
2923 if (default_icon_info->mask)
2924 g_object_ref (default_icon_info->mask);
2926 *pmap_return = default_icon_info->pixmap;
2927 *mask_return = default_icon_info->mask;
2929 else if (parent_info && parent_info->icon_pixmap)
2931 if (parent_info->icon_pixmap)
2932 g_object_ref (parent_info->icon_pixmap);
2933 if (parent_info->icon_mask)
2934 g_object_ref (parent_info->icon_mask);
2936 *pmap_return = parent_info->icon_pixmap;
2937 *mask_return = parent_info->icon_mask;
2941 #define IDEAL_SIZE 48
2943 best_size = G_MAXINT;
2945 tmp_list = icon_list;
2946 while (tmp_list != NULL)
2948 GdkPixbuf *pixbuf = tmp_list->data;
2951 /* average width and height - if someone passes in a rectangular
2952 * icon they deserve what they get.
2954 this = gdk_pixbuf_get_width (pixbuf) + gdk_pixbuf_get_height (pixbuf);
2957 if (best_icon == NULL)
2964 /* icon is better if it's 32 pixels or larger, and closer to
2965 * the ideal size than the current best.
2968 (ABS (best_size - IDEAL_SIZE) <
2969 ABS (this - IDEAL_SIZE)))
2976 tmp_list = tmp_list->next;
2980 gdk_pixbuf_render_pixmap_and_mask_for_colormap (best_icon,
2981 gdk_screen_get_system_colormap (screen),
2986 /* Save pmap/mask for others to use if appropriate */
2989 parent_info->icon_pixmap = *pmap_return;
2990 parent_info->icon_mask = *mask_return;
2992 if (parent_info->icon_pixmap)
2993 g_object_ref (parent_info->icon_pixmap);
2994 if (parent_info->icon_mask)
2995 g_object_ref (parent_info->icon_mask);
2997 else if (is_default_list)
2999 default_icon_info->pixmap = *pmap_return;
3000 default_icon_info->mask = *mask_return;
3002 if (default_icon_info->pixmap)
3003 g_object_add_weak_pointer (G_OBJECT (default_icon_info->pixmap),
3004 (gpointer*)&default_icon_info->pixmap);
3005 if (default_icon_info->mask)
3006 g_object_add_weak_pointer (G_OBJECT (default_icon_info->mask),
3007 (gpointer*)&default_icon_info->mask);
3013 icon_list_from_theme (GtkWidget *widget,
3018 GtkIconTheme *icon_theme;
3023 icon_theme = gtk_icon_theme_get_for_screen (gtk_widget_get_screen (widget));
3025 sizes = gtk_icon_theme_get_icon_sizes (icon_theme, name);
3028 for (i = 0; sizes[i]; i++)
3031 * We need an EWMH extension to handle scalable icons
3032 * by passing their name to the WM. For now just use a
3036 icon = gtk_icon_theme_load_icon (icon_theme, name,
3039 icon = gtk_icon_theme_load_icon (icon_theme, name,
3042 list = g_list_append (list, icon);
3052 gtk_window_realize_icon (GtkWindow *window)
3055 GtkWindowIconInfo *info;
3058 widget = GTK_WIDGET (window);
3060 g_return_if_fail (widget->window != NULL);
3062 /* no point setting an icon on override-redirect */
3063 if (window->type == GTK_WINDOW_POPUP)
3068 info = ensure_icon_info (window);
3073 g_return_if_fail (info->icon_pixmap == NULL);
3074 g_return_if_fail (info->icon_mask == NULL);
3076 info->using_default_icon = FALSE;
3077 info->using_parent_icon = FALSE;
3078 info->using_themed_icon = FALSE;
3080 icon_list = info->icon_list;
3082 /* Look up themed icon */
3083 if (icon_list == NULL && info->icon_name)
3085 icon_list = icon_list_from_theme (widget, info->icon_name);
3087 info->using_themed_icon = TRUE;
3090 /* Inherit from transient parent */
3091 if (icon_list == NULL && window->transient_parent)
3093 icon_list = ensure_icon_info (window->transient_parent)->icon_list;
3095 info->using_parent_icon = TRUE;
3098 /* Inherit from default */
3099 if (icon_list == NULL)
3101 icon_list = default_icon_list;
3103 info->using_default_icon = TRUE;
3106 /* Look up themed icon */
3107 if (icon_list == NULL && default_icon_name)
3109 icon_list = icon_list_from_theme (widget, default_icon_name);
3110 info->using_default_icon = TRUE;
3111 info->using_themed_icon = TRUE;
3114 gdk_window_set_icon_list (widget->window, icon_list);
3116 get_pixmap_and_mask (widget->window,
3117 info->using_parent_icon ? ensure_icon_info (window->transient_parent) : NULL,
3118 info->using_default_icon,
3123 /* This is a slight ICCCM violation since it's a color pixmap not
3124 * a bitmap, but everyone does it.
3126 gdk_window_set_icon (widget->window,
3131 info->realized = TRUE;
3133 if (info->using_themed_icon)
3135 GtkIconTheme *icon_theme;
3137 g_list_foreach (icon_list, (GFunc) g_object_unref, NULL);
3138 g_list_free (icon_list);
3140 icon_theme = gtk_icon_theme_get_for_screen (gtk_widget_get_screen (GTK_WIDGET (window)));
3141 g_signal_connect (icon_theme, "changed",
3142 G_CALLBACK (update_themed_icon), window);
3147 gtk_window_unrealize_icon (GtkWindow *window)
3149 GtkWindowIconInfo *info;
3151 info = get_icon_info (window);
3156 if (info->icon_pixmap)
3157 g_object_unref (info->icon_pixmap);
3159 if (info->icon_mask)
3160 g_object_unref (info->icon_mask);
3162 info->icon_pixmap = NULL;
3163 info->icon_mask = NULL;
3165 if (info->using_themed_icon)
3167 GtkIconTheme *icon_theme;
3169 icon_theme = gtk_icon_theme_get_for_screen (gtk_widget_get_screen (GTK_WIDGET (window)));
3171 g_signal_handlers_disconnect_by_func (icon_theme, update_themed_icon, window);
3174 /* We don't clear the properties on the window, just figure the
3175 * window is going away.
3178 info->realized = FALSE;
3183 * gtk_window_set_icon_list:
3184 * @window: a #GtkWindow
3185 * @list: list of #GdkPixbuf
3187 * Sets up the icon representing a #GtkWindow. The icon is used when
3188 * the window is minimized (also known as iconified). Some window
3189 * managers or desktop environments may also place it in the window
3190 * frame, or display it in other contexts.
3192 * gtk_window_set_icon_list() allows you to pass in the same icon in
3193 * several hand-drawn sizes. The list should contain the natural sizes
3194 * your icon is available in; that is, don't scale the image before
3195 * passing it to GTK+. Scaling is postponed until the last minute,
3196 * when the desired final size is known, to allow best quality.
3198 * By passing several sizes, you may improve the final image quality
3199 * of the icon, by reducing or eliminating automatic image scaling.
3201 * Recommended sizes to provide: 16x16, 32x32, 48x48 at minimum, and
3202 * larger images (64x64, 128x128) if you have them.
3204 * See also gtk_window_set_default_icon_list() to set the icon
3205 * for all windows in your application in one go.
3207 * Note that transient windows (those who have been set transient for another
3208 * window using gtk_window_set_transient_for()) will inherit their
3209 * icon from their transient parent. So there's no need to explicitly
3210 * set the icon on transient windows.
3213 gtk_window_set_icon_list (GtkWindow *window,
3216 GtkWindowIconInfo *info;
3218 g_return_if_fail (GTK_IS_WINDOW (window));
3220 info = ensure_icon_info (window);
3222 if (info->icon_list == list) /* check for NULL mostly */
3225 g_list_foreach (list,
3226 (GFunc) g_object_ref, NULL);
3228 g_list_foreach (info->icon_list,
3229 (GFunc) g_object_unref, NULL);
3231 g_list_free (info->icon_list);
3233 info->icon_list = g_list_copy (list);
3235 g_object_notify (G_OBJECT (window), "icon");
3237 gtk_window_unrealize_icon (window);
3239 if (GTK_WIDGET_REALIZED (window))
3240 gtk_window_realize_icon (window);
3242 /* We could try to update our transient children, but I don't think
3243 * it's really worth it. If we did it, the best way would probably
3244 * be to have children connect to notify::icon-list
3249 * gtk_window_get_icon_list:
3250 * @window: a #GtkWindow
3252 * Retrieves the list of icons set by gtk_window_set_icon_list().
3253 * The list is copied, but the reference count on each
3254 * member won't be incremented.
3256 * Return value: copy of window's icon list
3259 gtk_window_get_icon_list (GtkWindow *window)
3261 GtkWindowIconInfo *info;
3263 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
3265 info = get_icon_info (window);
3268 return g_list_copy (info->icon_list);
3274 * gtk_window_set_icon:
3275 * @window: a #GtkWindow
3276 * @icon: icon image, or %NULL
3278 * Sets up the icon representing a #GtkWindow. This icon is used when
3279 * the window is minimized (also known as iconified). Some window
3280 * managers or desktop environments may also place it in the window
3281 * frame, or display it in other contexts.
3283 * The icon should be provided in whatever size it was naturally
3284 * drawn; that is, don't scale the image before passing it to
3285 * GTK+. Scaling is postponed until the last minute, when the desired
3286 * final size is known, to allow best quality.
3288 * If you have your icon hand-drawn in multiple sizes, use
3289 * gtk_window_set_icon_list(). Then the best size will be used.
3291 * This function is equivalent to calling gtk_window_set_icon_list()
3292 * with a 1-element list.
3294 * See also gtk_window_set_default_icon_list() to set the icon
3295 * for all windows in your application in one go.
3298 gtk_window_set_icon (GtkWindow *window,
3303 g_return_if_fail (GTK_IS_WINDOW (window));
3304 g_return_if_fail (icon == NULL || GDK_IS_PIXBUF (icon));
3309 list = g_list_append (list, icon);
3311 gtk_window_set_icon_list (window, list);
3317 update_themed_icon (GtkIconTheme *icon_theme,
3320 g_object_notify (G_OBJECT (window), "icon");
3322 gtk_window_unrealize_icon (window);
3324 if (GTK_WIDGET_REALIZED (window))
3325 gtk_window_realize_icon (window);
3329 * gtk_window_set_icon_name:
3330 * @window: a #GtkWindow
3331 * @name: the name of the themed icon
3333 * Sets the icon for the window from a named themed icon. See
3334 * the docs for #GtkIconTheme for more details.
3336 * Note that this has nothing to do with the WM_ICON_NAME
3337 * property which is mentioned in the ICCCM.
3342 gtk_window_set_icon_name (GtkWindow *window,
3345 GtkWindowIconInfo *info;
3348 g_return_if_fail (GTK_IS_WINDOW (window));
3350 info = ensure_icon_info (window);
3352 tmp = info->icon_name;
3353 info->icon_name = g_strdup (name);
3356 g_list_foreach (info->icon_list, (GFunc) g_object_unref, NULL);
3357 g_list_free (info->icon_list);
3358 info->icon_list = NULL;
3360 update_themed_icon (NULL, window);
3362 g_object_notify (G_OBJECT (window), "icon-name");
3366 * gtk_window_get_icon_name:
3367 * @window: a #GtkWindow
3369 * Returns the name of the themed icon for the window,
3370 * see gtk_window_set_icon_name().
3372 * Returns: the icon name or %NULL if the window has
3377 G_CONST_RETURN gchar *
3378 gtk_window_get_icon_name (GtkWindow *window)
3380 GtkWindowIconInfo *info;
3382 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
3384 info = ensure_icon_info (window);
3386 return info->icon_name;
3390 * gtk_window_get_icon:
3391 * @window: a #GtkWindow
3393 * Gets the value set by gtk_window_set_icon() (or if you've
3394 * called gtk_window_set_icon_list(), gets the first icon in
3397 * Return value: icon for window
3400 gtk_window_get_icon (GtkWindow *window)
3402 GtkWindowIconInfo *info;
3404 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
3406 info = get_icon_info (window);
3407 if (info && info->icon_list)
3408 return GDK_PIXBUF (info->icon_list->data);
3413 /* Load pixbuf, printing warning on failure if error == NULL
3416 load_pixbuf_verbosely (const char *filename,
3419 GError *local_err = NULL;
3422 pixbuf = gdk_pixbuf_new_from_file (filename, &local_err);
3430 g_warning ("Error loading icon from file '%s':\n\t%s",
3431 filename, local_err->message);
3432 g_error_free (local_err);
3440 * gtk_window_set_icon_from_file:
3441 * @window: a #GtkWindow
3442 * @filename: location of icon file
3443 * @err: location to store error, or %NULL.
3445 * Sets the icon for @window.
3446 * Warns on failure if @err is %NULL.
3448 * This function is equivalent to calling gtk_window_set_icon()
3449 * with a pixbuf created by loading the image from @filename.
3451 * Returns: %TRUE if setting the icon succeeded.
3456 gtk_window_set_icon_from_file (GtkWindow *window,
3457 const gchar *filename,
3460 GdkPixbuf *pixbuf = load_pixbuf_verbosely (filename, err);
3464 gtk_window_set_icon (window, pixbuf);
3465 g_object_unref (pixbuf);
3474 * gtk_window_set_default_icon_list:
3475 * @list: a list of #GdkPixbuf
3477 * Sets an icon list to be used as fallback for windows that haven't
3478 * had gtk_window_set_icon_list() called on them to set up a
3479 * window-specific icon list. This function allows you to set up the
3480 * icon for all windows in your app at once.
3482 * See gtk_window_set_icon_list() for more details.
3486 gtk_window_set_default_icon_list (GList *list)
3490 if (list == default_icon_list)
3493 /* Update serial so we don't used cached pixmaps/masks
3495 default_icon_serial++;
3497 g_list_foreach (list,
3498 (GFunc) g_object_ref, NULL);
3500 g_list_foreach (default_icon_list,
3501 (GFunc) g_object_unref, NULL);
3503 g_list_free (default_icon_list);
3505 default_icon_list = g_list_copy (list);
3507 /* Update all toplevels */
3508 toplevels = gtk_window_list_toplevels ();
3509 tmp_list = toplevels;
3510 while (tmp_list != NULL)
3512 GtkWindowIconInfo *info;
3513 GtkWindow *w = tmp_list->data;
3515 info = get_icon_info (w);
3516 if (info && info->using_default_icon)
3518 gtk_window_unrealize_icon (w);
3519 if (GTK_WIDGET_REALIZED (w))
3520 gtk_window_realize_icon (w);
3523 tmp_list = tmp_list->next;
3525 g_list_free (toplevels);
3529 * gtk_window_set_default_icon:
3532 * Sets an icon to be used as fallback for windows that haven't
3533 * had gtk_window_set_icon() called on them from a pixbuf.
3538 gtk_window_set_default_icon (GdkPixbuf *icon)
3542 g_return_if_fail (GDK_IS_PIXBUF (icon));
3544 list = g_list_prepend (NULL, icon);
3545 gtk_window_set_default_icon_list (list);
3550 * gtk_window_set_default_icon_name:
3551 * @name: the name of the themed icon
3553 * Sets an icon to be used as fallback for windows that haven't
3554 * had gtk_window_set_icon_list() called on them from a named
3555 * themed icon, see gtk_window_set_icon_name().
3560 gtk_window_set_default_icon_name (const gchar *name)
3565 /* Update serial so we don't used cached pixmaps/masks
3567 default_icon_serial++;
3569 g_free (default_icon_name);
3570 default_icon_name = g_strdup (name);
3572 g_list_foreach (default_icon_list,
3573 (GFunc) g_object_unref, NULL);
3575 g_list_free (default_icon_list);
3576 default_icon_list = NULL;
3578 /* Update all toplevels */
3579 toplevels = gtk_window_list_toplevels ();
3580 tmp_list = toplevels;
3581 while (tmp_list != NULL)
3583 GtkWindowIconInfo *info;
3584 GtkWindow *w = tmp_list->data;
3586 info = get_icon_info (w);
3587 if (info && info->using_default_icon && info->using_themed_icon)
3589 gtk_window_unrealize_icon (w);
3590 if (GTK_WIDGET_REALIZED (w))
3591 gtk_window_realize_icon (w);
3594 tmp_list = tmp_list->next;
3596 g_list_free (toplevels);
3600 * gtk_window_set_default_icon_from_file:
3601 * @filename: location of icon file
3602 * @err: location to store error, or %NULL.
3604 * Sets an icon to be used as fallback for windows that haven't
3605 * had gtk_window_set_icon_list() called on them from a file
3606 * on disk. Warns on failure if @err is %NULL.
3608 * Returns: %TRUE if setting the icon succeeded.
3613 gtk_window_set_default_icon_from_file (const gchar *filename,
3616 GdkPixbuf *pixbuf = load_pixbuf_verbosely (filename, err);
3620 gtk_window_set_default_icon (pixbuf);
3621 g_object_unref (pixbuf);
3630 * gtk_window_get_default_icon_list:
3632 * Gets the value set by gtk_window_set_default_icon_list().
3633 * The list is a copy and should be freed with g_list_free(),
3634 * but the pixbufs in the list have not had their reference count
3637 * Return value: copy of default icon list
3640 gtk_window_get_default_icon_list (void)
3642 return g_list_copy (default_icon_list);
3646 gtk_window_set_default_size_internal (GtkWindow *window,
3647 gboolean change_width,
3649 gboolean change_height,
3651 gboolean is_geometry)
3653 GtkWindowGeometryInfo *info;
3655 g_return_if_fail (change_width == FALSE || width >= -1);
3656 g_return_if_fail (change_height == FALSE || height >= -1);
3658 info = gtk_window_get_geometry_info (window, TRUE);
3660 g_object_freeze_notify (G_OBJECT (window));
3662 info->default_is_geometry = is_geometry != FALSE;
3672 info->default_width = width;
3674 g_object_notify (G_OBJECT (window), "default-width");
3685 info->default_height = height;
3687 g_object_notify (G_OBJECT (window), "default-height");
3690 g_object_thaw_notify (G_OBJECT (window));
3692 gtk_widget_queue_resize (GTK_WIDGET (window));
3696 * gtk_window_set_default_size:
3697 * @window: a #GtkWindow
3698 * @width: width in pixels, or -1 to unset the default width
3699 * @height: height in pixels, or -1 to unset the default height
3701 * Sets the default size of a window. If the window's "natural" size
3702 * (its size request) is larger than the default, the default will be
3703 * ignored. More generally, if the default size does not obey the
3704 * geometry hints for the window (gtk_window_set_geometry_hints() can
3705 * be used to set these explicitly), the default size will be clamped
3706 * to the nearest permitted size.
3708 * Unlike gtk_widget_set_size_request(), which sets a size request for
3709 * a widget and thus would keep users from shrinking the window, this
3710 * function only sets the initial size, just as if the user had
3711 * resized the window themselves. Users can still shrink the window
3712 * again as they normally would. Setting a default size of -1 means to
3713 * use the "natural" default size (the size request of the window).
3715 * For more control over a window's initial size and how resizing works,
3716 * investigate gtk_window_set_geometry_hints().
3718 * For some uses, gtk_window_resize() is a more appropriate function.
3719 * gtk_window_resize() changes the current size of the window, rather
3720 * than the size to be used on initial display. gtk_window_resize() always
3721 * affects the window itself, not the geometry widget.
3723 * The default size of a window only affects the first time a window is
3724 * shown; if a window is hidden and re-shown, it will remember the size
3725 * it had prior to hiding, rather than using the default size.
3727 * Windows can't actually be 0x0 in size, they must be at least 1x1, but
3728 * passing 0 for @width and @height is OK, resulting in a 1x1 default size.
3731 gtk_window_set_default_size (GtkWindow *window,
3735 g_return_if_fail (GTK_IS_WINDOW (window));
3736 g_return_if_fail (width >= -1);
3737 g_return_if_fail (height >= -1);
3739 gtk_window_set_default_size_internal (window, TRUE, width, TRUE, height, FALSE);
3743 * gtk_window_get_default_size:
3744 * @window: a #GtkWindow
3745 * @width: location to store the default width, or %NULL
3746 * @height: location to store the default height, or %NULL
3748 * Gets the default size of the window. A value of -1 for the width or
3749 * height indicates that a default size has not been explicitly set
3750 * for that dimension, so the "natural" size of the window will be
3755 gtk_window_get_default_size (GtkWindow *window,
3759 GtkWindowGeometryInfo *info;
3761 g_return_if_fail (GTK_IS_WINDOW (window));
3763 info = gtk_window_get_geometry_info (window, FALSE);
3766 *width = info ? info->default_width : -1;
3769 *height = info ? info->default_height : -1;
3773 * gtk_window_resize:
3774 * @window: a #GtkWindow
3775 * @width: width in pixels to resize the window to
3776 * @height: height in pixels to resize the window to
3778 * Resizes the window as if the user had done so, obeying geometry
3779 * constraints. The default geometry constraint is that windows may
3780 * not be smaller than their size request; to override this
3781 * constraint, call gtk_widget_set_size_request() to set the window's
3782 * request to a smaller value.
3784 * If gtk_window_resize() is called before showing a window for the
3785 * first time, it overrides any default size set with
3786 * gtk_window_set_default_size().
3788 * Windows may not be resized smaller than 1 by 1 pixels.
3792 gtk_window_resize (GtkWindow *window,
3796 GtkWindowGeometryInfo *info;
3798 g_return_if_fail (GTK_IS_WINDOW (window));
3799 g_return_if_fail (width > 0);
3800 g_return_if_fail (height > 0);
3802 info = gtk_window_get_geometry_info (window, TRUE);
3804 info->resize_width = width;
3805 info->resize_height = height;
3807 gtk_widget_queue_resize (GTK_WIDGET (window));
3811 * gtk_window_get_size:
3812 * @window: a #GtkWindow
3813 * @width: return location for width, or %NULL
3814 * @height: return location for height, or %NULL
3816 * Obtains the current size of @window. If @window is not onscreen,
3817 * it returns the size GTK+ will suggest to the <link
3818 * linkend="gtk-X11-arch">window manager</link> for the initial window
3819 * size (but this is not reliably the same as the size the window
3820 * manager will actually select). The size obtained by
3821 * gtk_window_get_size() is the last size received in a
3822 * #GdkEventConfigure, that is, GTK+ uses its locally-stored size,
3823 * rather than querying the X server for the size. As a result, if you
3824 * call gtk_window_resize() then immediately call
3825 * gtk_window_get_size(), the size won't have taken effect yet. After
3826 * the window manager processes the resize request, GTK+ receives
3827 * notification that the size has changed via a configure event, and
3828 * the size of the window gets updated.
3830 * Note 1: Nearly any use of this function creates a race condition,
3831 * because the size of the window may change between the time that you
3832 * get the size and the time that you perform some action assuming
3833 * that size is the current size. To avoid race conditions, connect to
3834 * "configure_event" on the window and adjust your size-dependent
3835 * state to match the size delivered in the #GdkEventConfigure.
3837 * Note 2: The returned size does <emphasis>not</emphasis> include the
3838 * size of the window manager decorations (aka the window frame or
3839 * border). Those are not drawn by GTK+ and GTK+ has no reliable
3840 * method of determining their size.
3842 * Note 3: If you are getting a window size in order to position
3843 * the window onscreen, there may be a better way. The preferred
3844 * way is to simply set the window's semantic type with
3845 * gtk_window_set_type_hint(), which allows the window manager to
3846 * e.g. center dialogs. Also, if you set the transient parent of
3847 * dialogs with gtk_window_set_transient_for() window managers
3848 * will often center the dialog over its parent window. It's
3849 * much preferred to let the window manager handle these
3850 * things rather than doing it yourself, because all apps will
3851 * behave consistently and according to user prefs if the window
3852 * manager handles it. Also, the window manager can take the size
3853 * of the window decorations/border into account, while your
3854 * application cannot.
3856 * In any case, if you insist on application-specified window
3857 * positioning, there's <emphasis>still</emphasis> a better way than
3858 * doing it yourself - gtk_window_set_position() will frequently
3859 * handle the details for you.
3863 gtk_window_get_size (GtkWindow *window,
3869 g_return_if_fail (GTK_IS_WINDOW (window));
3871 if (width == NULL && height == NULL)
3874 if (GTK_WIDGET_MAPPED (window))
3876 gdk_drawable_get_size (GTK_WIDGET (window)->window,
3881 GdkRectangle configure_request;
3883 gtk_window_compute_configure_request (window,
3887 w = configure_request.width;
3888 h = configure_request.height;
3899 * @window: a #GtkWindow
3900 * @x: X coordinate to move window to
3901 * @y: Y coordinate to move window to
3903 * Asks the <link linkend="gtk-X11-arch">window manager</link> to move
3904 * @window to the given position. Window managers are free to ignore
3905 * this; most window managers ignore requests for initial window
3906 * positions (instead using a user-defined placement algorithm) and
3907 * honor requests after the window has already been shown.
3909 * Note: the position is the position of the gravity-determined
3910 * reference point for the window. The gravity determines two things:
3911 * first, the location of the reference point in root window
3912 * coordinates; and second, which point on the window is positioned at
3913 * the reference point.
3915 * By default the gravity is #GDK_GRAVITY_NORTH_WEST, so the reference
3916 * point is simply the @x, @y supplied to gtk_window_move(). The
3917 * top-left corner of the window decorations (aka window frame or
3918 * border) will be placed at @x, @y. Therefore, to position a window
3919 * at the top left of the screen, you want to use the default gravity
3920 * (which is #GDK_GRAVITY_NORTH_WEST) and move the window to 0,0.
3922 * To position a window at the bottom right corner of the screen, you
3923 * would set #GDK_GRAVITY_SOUTH_EAST, which means that the reference
3924 * point is at @x + the window width and @y + the window height, and
3925 * the bottom-right corner of the window border will be placed at that
3926 * reference point. So, to place a window in the bottom right corner
3927 * you would first set gravity to south east, then write:
3928 * <literal>gtk_window_move (window, gdk_screen_width () - window_width,
3929 * gdk_screen_height () - window_height)</literal> (note that this
3930 * example does not take multi-head scenarios into account).
3932 * The Extended Window Manager Hints specification at <ulink
3933 * url="http://www.freedesktop.org/Standards/wm-spec">
3934 * http://www.freedesktop.org/Standards/wm-spec</ulink> has a
3935 * nice table of gravities in the "implementation notes" section.
3937 * The gtk_window_get_position() documentation may also be relevant.
3940 gtk_window_move (GtkWindow *window,
3944 GtkWindowGeometryInfo *info;
3947 g_return_if_fail (GTK_IS_WINDOW (window));
3949 widget = GTK_WIDGET (window);
3951 info = gtk_window_get_geometry_info (window, TRUE);
3953 if (GTK_WIDGET_MAPPED (window))
3955 /* we have now sent a request with this position
3956 * with currently-active constraints, so toggle flag.
3958 info->position_constraints_changed = FALSE;
3960 /* we only constrain if mapped - if not mapped,
3961 * then gtk_window_compute_configure_request()
3962 * will apply the constraints later, and we
3963 * don't want to lose information about
3964 * what position the user set before then.
3965 * i.e. if you do a move() then turn off POS_CENTER
3966 * then show the window, your move() will work.
3968 gtk_window_constrain_position (window,
3969 widget->allocation.width,
3970 widget->allocation.height,
3973 /* Note that this request doesn't go through our standard request
3974 * framework, e.g. doesn't increment configure_request_count,
3975 * doesn't set info->last, etc.; that's because
3976 * we don't save the info needed to arrive at this same request
3979 * To gtk_window_move_resize(), this will end up looking exactly
3980 * the same as the position being changed by the window
3984 /* FIXME are we handling gravity properly for framed windows? */
3986 gdk_window_move (window->frame,
3987 x - window->frame_left,
3988 y - window->frame_top);
3990 gdk_window_move (GTK_WIDGET (window)->window,
3995 /* Save this position to apply on mapping */
3996 info->initial_x = x;
3997 info->initial_y = y;
3998 info->initial_pos_set = TRUE;
4003 * gtk_window_get_position:
4004 * @window: a #GtkWindow
4005 * @root_x: return location for X coordinate of gravity-determined reference point
4006 * @root_y: return location for Y coordinate of gravity-determined reference point
4008 * This function returns the position you need to pass to
4009 * gtk_window_move() to keep @window in its current position. This
4010 * means that the meaning of the returned value varies with window
4011 * gravity. See gtk_window_move() for more details.
4013 * If you haven't changed the window gravity, its gravity will be
4014 * #GDK_GRAVITY_NORTH_WEST. This means that gtk_window_get_position()
4015 * gets the position of the top-left corner of the window manager
4016 * frame for the window. gtk_window_move() sets the position of this
4017 * same top-left corner.
4019 * gtk_window_get_position() is not 100% reliable because the X Window System
4020 * does not specify a way to obtain the geometry of the
4021 * decorations placed on a window by the window manager.
4022 * Thus GTK+ is using a "best guess" that works with most
4025 * Moreover, nearly all window managers are historically broken with
4026 * respect to their handling of window gravity. So moving a window to
4027 * its current position as returned by gtk_window_get_position() tends
4028 * to result in moving the window slightly. Window managers are
4029 * slowly getting better over time.
4031 * If a window has gravity #GDK_GRAVITY_STATIC the window manager
4032 * frame is not relevant, and thus gtk_window_get_position() will
4033 * always produce accurate results. However you can't use static
4034 * gravity to do things like place a window in a corner of the screen,
4035 * because static gravity ignores the window manager decorations.
4037 * If you are saving and restoring your application's window
4038 * positions, you should know that it's impossible for applications to
4039 * do this without getting it somewhat wrong because applications do
4040 * not have sufficient knowledge of window manager state. The Correct
4041 * Mechanism is to support the session management protocol (see the
4042 * "GnomeClient" object in the GNOME libraries for example) and allow
4043 * the window manager to save your window sizes and positions.
4048 gtk_window_get_position (GtkWindow *window,
4054 g_return_if_fail (GTK_IS_WINDOW (window));
4056 widget = GTK_WIDGET (window);
4058 if (window->gravity == GDK_GRAVITY_STATIC)
4060 if (GTK_WIDGET_MAPPED (widget))
4062 /* This does a server round-trip, which is sort of wrong;
4063 * but a server round-trip is inevitable for
4064 * gdk_window_get_frame_extents() in the usual
4065 * NorthWestGravity case below, so not sure what else to
4066 * do. We should likely be consistent about whether we get
4067 * the client-side info or the server-side info.
4069 gdk_window_get_origin (widget->window, root_x, root_y);
4073 GdkRectangle configure_request;
4075 gtk_window_compute_configure_request (window,
4079 *root_x = configure_request.x;
4080 *root_y = configure_request.y;
4085 GdkRectangle frame_extents;
4090 if (GTK_WIDGET_MAPPED (widget))
4093 gdk_window_get_frame_extents (window->frame, &frame_extents);
4095 gdk_window_get_frame_extents (widget->window, &frame_extents);
4096 x = frame_extents.x;
4097 y = frame_extents.y;
4098 gtk_window_get_size (window, &w, &h);
4102 /* We just say the frame has 0 size on all sides.
4103 * Not sure what else to do.
4105 gtk_window_compute_configure_request (window,
4108 x = frame_extents.x;
4109 y = frame_extents.y;
4110 w = frame_extents.width;
4111 h = frame_extents.height;
4114 switch (window->gravity)
4116 case GDK_GRAVITY_NORTH:
4117 case GDK_GRAVITY_CENTER:
4118 case GDK_GRAVITY_SOUTH:
4119 /* Find center of frame. */
4120 x += frame_extents.width / 2;
4121 /* Center client window on that point. */
4125 case GDK_GRAVITY_SOUTH_EAST:
4126 case GDK_GRAVITY_EAST:
4127 case GDK_GRAVITY_NORTH_EAST:
4128 /* Find right edge of frame */
4129 x += frame_extents.width;
4130 /* Align left edge of client at that point. */
4137 switch (window->gravity)
4139 case GDK_GRAVITY_WEST:
4140 case GDK_GRAVITY_CENTER:
4141 case GDK_GRAVITY_EAST:
4142 /* Find center of frame. */
4143 y += frame_extents.height / 2;
4144 /* Center client window there. */
4147 case GDK_GRAVITY_SOUTH_WEST:
4148 case GDK_GRAVITY_SOUTH:
4149 case GDK_GRAVITY_SOUTH_EAST:
4150 /* Find south edge of frame */
4151 y += frame_extents.height;
4152 /* Place bottom edge of client there */
4167 * gtk_window_reshow_with_initial_size:
4168 * @window: a #GtkWindow
4170 * Hides @window, then reshows it, resetting the
4171 * default size and position of the window. Used
4172 * by GUI builders only.
4175 gtk_window_reshow_with_initial_size (GtkWindow *window)
4179 g_return_if_fail (GTK_IS_WINDOW (window));
4181 widget = GTK_WIDGET (window);
4183 gtk_widget_hide (widget);
4184 gtk_widget_unrealize (widget);
4185 gtk_widget_show (widget);
4189 gtk_window_destroy (GtkObject *object)
4191 GtkWindow *window = GTK_WINDOW (object);
4193 toplevel_list = g_slist_remove (toplevel_list, window);
4195 if (window->transient_parent)
4196 gtk_window_set_transient_for (window, NULL);
4198 /* frees the icons */
4199 gtk_window_set_icon_list (window, NULL);
4201 if (window->has_user_ref_count)
4203 window->has_user_ref_count = FALSE;
4204 g_object_unref (window);
4208 gtk_window_group_remove_window (window->group, window);
4210 gtk_window_free_key_hash (window);
4212 GTK_OBJECT_CLASS (gtk_window_parent_class)->destroy (object);
4216 gtk_window_finalize (GObject *object)
4218 GtkWindow *window = GTK_WINDOW (object);
4219 GtkMnemonicHash *mnemonic_hash;
4221 g_free (window->title);
4222 g_free (window->wmclass_name);
4223 g_free (window->wmclass_class);
4224 g_free (window->wm_role);
4226 mnemonic_hash = gtk_window_get_mnemonic_hash (window, FALSE);
4228 _gtk_mnemonic_hash_free (mnemonic_hash);
4230 if (window->geometry_info)
4232 if (window->geometry_info->widget)
4233 g_signal_handlers_disconnect_by_func (window->geometry_info->widget,
4234 gtk_widget_destroyed,
4235 &window->geometry_info->widget);
4236 g_free (window->geometry_info);
4239 if (window->keys_changed_handler)
4241 g_source_remove (window->keys_changed_handler);
4242 window->keys_changed_handler = 0;
4247 g_signal_handlers_disconnect_by_func (window->screen,
4248 gtk_window_on_composited_changed, window);
4251 G_OBJECT_CLASS (gtk_window_parent_class)->finalize (object);
4255 gtk_window_show (GtkWidget *widget)
4257 GtkWindow *window = GTK_WINDOW (widget);
4258 GtkContainer *container = GTK_CONTAINER (window);
4259 gboolean need_resize;
4261 GTK_WIDGET_SET_FLAGS (widget, GTK_VISIBLE);
4263 need_resize = container->need_resize || !GTK_WIDGET_REALIZED (widget);
4264 container->need_resize = FALSE;
4268 GtkWindowGeometryInfo *info = gtk_window_get_geometry_info (window, TRUE);
4269 GtkAllocation allocation = { 0, 0 };
4270 GdkRectangle configure_request;
4271 GdkGeometry new_geometry;
4273 gboolean was_realized;
4275 /* We are going to go ahead and perform this configure request
4276 * and then emulate a configure notify by going ahead and
4277 * doing a size allocate. Sort of a synchronous
4278 * mini-copy of gtk_window_move_resize() here.
4280 gtk_window_compute_configure_request (window,
4285 /* We update this because we are going to go ahead
4286 * and gdk_window_resize() below, rather than
4289 info->last.configure_request.width = configure_request.width;
4290 info->last.configure_request.height = configure_request.height;
4292 /* and allocate the window - this is normally done
4293 * in move_resize in response to configure notify
4295 allocation.width = configure_request.width;
4296 allocation.height = configure_request.height;
4297 gtk_widget_size_allocate (widget, &allocation);
4299 /* Then we guarantee we have a realize */
4300 was_realized = FALSE;
4301 if (!GTK_WIDGET_REALIZED (widget))
4303 gtk_widget_realize (widget);
4304 was_realized = TRUE;
4307 /* Must be done after the windows are realized,
4308 * so that the decorations can be read
4310 gtk_decorated_window_calculate_frame_size (window);
4312 /* We only send configure request if we didn't just finish
4313 * creating the window; if we just created the window
4314 * then we created it with widget->allocation anyhow.
4317 gdk_window_move_resize (widget->window,
4318 configure_request.x,
4319 configure_request.y,
4320 configure_request.width,
4321 configure_request.height);
4324 gtk_container_check_resize (container);
4326 gtk_widget_map (widget);
4328 /* Try to make sure that we have some focused widget
4330 if (!window->focus_widget && !GTK_IS_PLUG (window))
4331 gtk_window_move_focus (window, GTK_DIR_TAB_FORWARD);
4334 gtk_grab_add (widget);
4338 gtk_window_hide (GtkWidget *widget)
4340 GtkWindow *window = GTK_WINDOW (widget);
4342 GTK_WIDGET_UNSET_FLAGS (widget, GTK_VISIBLE);
4343 gtk_widget_unmap (widget);
4346 gtk_grab_remove (widget);
4350 gtk_window_map (GtkWidget *widget)
4352 GtkWindow *window = GTK_WINDOW (widget);
4353 GtkWindowPrivate *priv = GTK_WINDOW_GET_PRIVATE (window);
4354 GdkWindow *toplevel;
4356 GTK_WIDGET_SET_FLAGS (widget, GTK_MAPPED);
4358 if (window->bin.child &&
4359 GTK_WIDGET_VISIBLE (window->bin.child) &&
4360 !GTK_WIDGET_MAPPED (window->bin.child))
4361 gtk_widget_map (window->bin.child);
4364 toplevel = window->frame;
4366 toplevel = widget->window;
4368 if (window->maximize_initially)
4369 gdk_window_maximize (toplevel);
4371 gdk_window_unmaximize (toplevel);
4373 if (window->stick_initially)
4374 gdk_window_stick (toplevel);
4376 gdk_window_unstick (toplevel);
4378 if (window->iconify_initially)
4379 gdk_window_iconify (toplevel);
4381 gdk_window_deiconify (toplevel);
4383 if (priv->fullscreen_initially)
4384 gdk_window_fullscreen (toplevel);
4386 gdk_window_unfullscreen (toplevel);
4388 gdk_window_set_keep_above (toplevel, priv->above_initially);
4390 gdk_window_set_keep_below (toplevel, priv->below_initially);
4392 /* No longer use the default settings */
4393 window->need_default_size = FALSE;
4394 window->need_default_position = FALSE;
4396 if (priv->reset_type_hint)
4398 /* We should only reset the type hint when the application
4399 * used gtk_window_set_type_hint() to change the hint.
4400 * Some applications use X directly to change the properties;
4401 * in that case, we shouldn't overwrite what they did.
4403 gdk_window_set_type_hint (widget->window, priv->type_hint);
4404 priv->reset_type_hint = FALSE;
4407 gdk_window_show (widget->window);
4410 gdk_window_show (window->frame);
4412 if (!disable_startup_notification)
4414 /* Do we have a custom startup-notification id? */
4415 if (priv->startup_id != NULL)
4417 /* Make sure we have a "real" id */
4418 if (!startup_id_is_fake (priv->startup_id))
4419 gdk_notify_startup_complete_with_id (priv->startup_id);
4421 priv->startup_id = NULL;
4423 else if (!sent_startup_notification)
4425 sent_startup_notification = TRUE;
4426 gdk_notify_startup_complete ();
4432 gtk_window_map_event (GtkWidget *widget,
4435 if (!GTK_WIDGET_MAPPED (widget))
4437 /* we should be be unmapped, but are getting a MapEvent, this may happen
4438 * to toplevel XWindows if mapping was intercepted by a window manager
4439 * and an unmap request occoured while the MapRequestEvent was still
4440 * being handled. we work around this situaiton here by re-requesting
4441 * the window being unmapped. more details can be found in:
4442 * http://bugzilla.gnome.org/show_bug.cgi?id=316180
4444 gdk_window_hide (widget->window);
4450 gtk_window_unmap (GtkWidget *widget)
4452 GtkWindow *window = GTK_WINDOW (widget);
4453 GtkWindowPrivate *priv = GTK_WINDOW_GET_PRIVATE (widget);
4454 GtkWindowGeometryInfo *info;
4455 GdkWindowState state;
4457 GTK_WIDGET_UNSET_FLAGS (widget, GTK_MAPPED);
4459 gdk_window_withdraw (window->frame);
4461 gdk_window_withdraw (widget->window);
4463 window->configure_request_count = 0;
4464 window->configure_notify_received = FALSE;
4466 /* on unmap, we reset the default positioning of the window,
4467 * so it's placed again, but we don't reset the default
4468 * size of the window, so it's remembered.
4470 window->need_default_position = TRUE;
4472 info = gtk_window_get_geometry_info (window, FALSE);
4475 info->initial_pos_set = FALSE;
4476 info->position_constraints_changed = FALSE;
4479 state = gdk_window_get_state (widget->window);
4480 window->iconify_initially = (state & GDK_WINDOW_STATE_ICONIFIED) != 0;
4481 window->maximize_initially = (state & GDK_WINDOW_STATE_MAXIMIZED) != 0;
4482 window->stick_initially = (state & GDK_WINDOW_STATE_STICKY) != 0;
4483 priv->above_initially = (state & GDK_WINDOW_STATE_ABOVE) != 0;
4484 priv->below_initially = (state & GDK_WINDOW_STATE_BELOW) != 0;
4488 gtk_window_realize (GtkWidget *widget)
4491 GdkWindow *parent_window;
4492 GdkWindowAttr attributes;
4493 gint attributes_mask;
4494 GtkWindowPrivate *priv;
4496 window = GTK_WINDOW (widget);
4497 priv = GTK_WINDOW_GET_PRIVATE (window);
4499 /* ensure widget tree is properly size allocated */
4500 if (widget->allocation.x == -1 &&
4501 widget->allocation.y == -1 &&
4502 widget->allocation.width == 1 &&
4503 widget->allocation.height == 1)
4505 GtkRequisition requisition;
4506 GtkAllocation allocation = { 0, 0, 200, 200 };
4508 gtk_widget_size_request (widget, &requisition);
4509 if (requisition.width || requisition.height)
4511 /* non-empty window */
4512 allocation.width = requisition.width;
4513 allocation.height = requisition.height;
4515 gtk_widget_size_allocate (widget, &allocation);
4517 _gtk_container_queue_resize (GTK_CONTAINER (widget));
4519 g_return_if_fail (!GTK_WIDGET_REALIZED (widget));
4522 GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED);
4524 switch (window->type)
4526 case GTK_WINDOW_TOPLEVEL:
4527 attributes.window_type = GDK_WINDOW_TOPLEVEL;
4529 case GTK_WINDOW_POPUP:
4530 attributes.window_type = GDK_WINDOW_TEMP;
4533 g_warning (G_STRLOC": Unknown window type %d!", window->type);
4537 attributes.title = window->title;
4538 attributes.wmclass_name = window->wmclass_name;
4539 attributes.wmclass_class = window->wmclass_class;
4540 attributes.wclass = GDK_INPUT_OUTPUT;
4541 attributes.visual = gtk_widget_get_visual (widget);
4542 attributes.colormap = gtk_widget_get_colormap (widget);
4544 if (window->has_frame)
4546 attributes.width = widget->allocation.width + window->frame_left + window->frame_right;
4547 attributes.height = widget->allocation.height + window->frame_top + window->frame_bottom;
4548 attributes.event_mask = (GDK_EXPOSURE_MASK |
4549 GDK_KEY_PRESS_MASK |
4550 GDK_ENTER_NOTIFY_MASK |
4551 GDK_LEAVE_NOTIFY_MASK |
4552 GDK_FOCUS_CHANGE_MASK |
4553 GDK_STRUCTURE_MASK |
4554 GDK_BUTTON_MOTION_MASK |
4555 GDK_POINTER_MOTION_HINT_MASK |
4556 GDK_BUTTON_PRESS_MASK |
4557 GDK_BUTTON_RELEASE_MASK);
4559 attributes_mask = GDK_WA_VISUAL | GDK_WA_COLORMAP;
4561 window->frame = gdk_window_new (gtk_widget_get_root_window (widget),
4562 &attributes, attributes_mask);
4564 if (priv->opacity_set)
4565 gdk_window_set_opacity (window->frame, priv->opacity);
4567 gdk_window_set_user_data (window->frame, widget);
4569 attributes.window_type = GDK_WINDOW_CHILD;
4570 attributes.x = window->frame_left;
4571 attributes.y = window->frame_top;
4573 attributes_mask = GDK_WA_X | GDK_WA_Y;
4575 parent_window = window->frame;
4577 g_signal_connect (window,
4579 G_CALLBACK (gtk_window_event),
4584 attributes_mask = 0;
4585 parent_window = gtk_widget_get_root_window (widget);
4588 attributes.width = widget->allocation.width;
4589 attributes.height = widget->allocation.height;
4590 attributes.event_mask = gtk_widget_get_events (widget);
4591 attributes.event_mask |= (GDK_EXPOSURE_MASK |
4592 GDK_KEY_PRESS_MASK |
4593 GDK_KEY_RELEASE_MASK |
4594 GDK_ENTER_NOTIFY_MASK |
4595 GDK_LEAVE_NOTIFY_MASK |
4596 GDK_FOCUS_CHANGE_MASK |
4597 GDK_STRUCTURE_MASK);
4598 attributes.type_hint = priv->type_hint;
4600 attributes_mask |= GDK_WA_VISUAL | GDK_WA_COLORMAP | GDK_WA_TYPE_HINT;
4601 attributes_mask |= (window->title ? GDK_WA_TITLE : 0);
4602 attributes_mask |= (window->wmclass_name ? GDK_WA_WMCLASS : 0);
4604 widget->window = gdk_window_new (parent_window, &attributes, attributes_mask);
4606 if (!window->has_frame && priv->opacity_set)
4607 gdk_window_set_opacity (widget->window, priv->opacity);
4609 gdk_window_enable_synchronized_configure (widget->window);
4611 gdk_window_set_user_data (widget->window, window);
4613 widget->style = gtk_style_attach (widget->style, widget->window);
4614 gtk_style_set_background (widget->style, widget->window, GTK_STATE_NORMAL);
4616 gtk_style_set_background (widget->style, window->frame, GTK_STATE_NORMAL);
4618 /* This is a bad hack to set the window background. */
4619 gtk_window_paint (widget, NULL);
4621 if (window->transient_parent &&
4622 GTK_WIDGET_REALIZED (window->transient_parent))
4623 gdk_window_set_transient_for (widget->window,
4624 GTK_WIDGET (window->transient_parent)->window);
4626 if (window->wm_role)
4627 gdk_window_set_role (widget->window, window->wm_role);
4629 if (!window->decorated)
4630 gdk_window_set_decorations (widget->window, 0);
4632 if (!priv->deletable)
4633 gdk_window_set_functions (widget->window, GDK_FUNC_ALL | GDK_FUNC_CLOSE);
4635 if (gtk_window_get_skip_pager_hint (window))
4636 gdk_window_set_skip_pager_hint (widget->window, TRUE);
4638 if (gtk_window_get_skip_taskbar_hint (window))
4639 gdk_window_set_skip_taskbar_hint (widget->window, TRUE);
4641 if (gtk_window_get_accept_focus (window))
4642 gdk_window_set_accept_focus (widget->window, TRUE);
4644 gdk_window_set_accept_focus (widget->window, FALSE);
4646 if (gtk_window_get_focus_on_map (window))
4647 gdk_window_set_focus_on_map (widget->window, TRUE);
4649 gdk_window_set_focus_on_map (widget->window, FALSE);
4652 gdk_window_set_modal_hint (widget->window, TRUE);
4654 gdk_window_set_modal_hint (widget->window, FALSE);
4656 if (priv->startup_id)
4658 #ifdef GDK_WINDOWING_X11
4659 guint32 timestamp = extract_time_from_startup_id (priv->startup_id);
4660 if (timestamp != GDK_CURRENT_TIME)
4661 gdk_x11_window_set_user_time (widget->window, timestamp);
4663 if (!startup_id_is_fake (priv->startup_id))
4664 gdk_window_set_startup_id (widget->window, priv->startup_id);
4668 gtk_window_realize_icon (window);
4672 gtk_window_unrealize (GtkWidget *widget)
4675 GtkWindowGeometryInfo *info;
4677 window = GTK_WINDOW (widget);
4679 /* On unrealize, we reset the size of the window such
4680 * that we will re-apply the default sizing stuff
4681 * next time we show the window.
4683 * Default positioning is reset on unmap, instead of unrealize.
4685 window->need_default_size = TRUE;
4686 info = gtk_window_get_geometry_info (window, FALSE);
4689 info->resize_width = -1;
4690 info->resize_height = -1;
4691 info->last.configure_request.x = 0;
4692 info->last.configure_request.y = 0;
4693 info->last.configure_request.width = -1;
4694 info->last.configure_request.height = -1;
4695 /* be sure we reset geom hints on re-realize */
4696 info->last.flags = 0;
4701 gdk_window_set_user_data (window->frame, NULL);
4702 gdk_window_destroy (window->frame);
4703 window->frame = NULL;
4707 gtk_window_unrealize_icon (window);
4709 (* GTK_WIDGET_CLASS (gtk_window_parent_class)->unrealize) (widget);
4713 gtk_window_size_request (GtkWidget *widget,
4714 GtkRequisition *requisition)
4719 window = GTK_WINDOW (widget);
4720 bin = GTK_BIN (window);
4722 requisition->width = GTK_CONTAINER (window)->border_width * 2;
4723 requisition->height = GTK_CONTAINER (window)->border_width * 2;
4725 if (bin->child && GTK_WIDGET_VISIBLE (bin->child))
4727 GtkRequisition child_requisition;
4729 gtk_widget_size_request (bin->child, &child_requisition);
4731 requisition->width += child_requisition.width;
4732 requisition->height += child_requisition.height;
4737 gtk_window_size_allocate (GtkWidget *widget,
4738 GtkAllocation *allocation)
4741 GtkAllocation child_allocation;
4743 window = GTK_WINDOW (widget);
4744 widget->allocation = *allocation;
4746 if (window->bin.child && GTK_WIDGET_VISIBLE (window->bin.child))
4748 child_allocation.x = GTK_CONTAINER (window)->border_width;
4749 child_allocation.y = GTK_CONTAINER (window)->border_width;
4750 child_allocation.width =
4751 MAX (1, (gint)allocation->width - child_allocation.x * 2);
4752 child_allocation.height =
4753 MAX (1, (gint)allocation->height - child_allocation.y * 2);
4755 gtk_widget_size_allocate (window->bin.child, &child_allocation);
4758 if (GTK_WIDGET_REALIZED (widget) && window->frame)
4760 gdk_window_resize (window->frame,
4761 allocation->width + window->frame_left + window->frame_right,
4762 allocation->height + window->frame_top + window->frame_bottom);
4767 gtk_window_event (GtkWidget *widget, GdkEvent *event)
4770 gboolean return_val;
4772 window = GTK_WINDOW (widget);
4774 if (window->frame && (event->any.window == window->frame))
4776 if ((event->type != GDK_KEY_PRESS) &&
4777 (event->type != GDK_KEY_RELEASE) &&
4778 (event->type != GDK_FOCUS_CHANGE))
4780 g_signal_stop_emission_by_name (widget, "event");
4782 g_signal_emit (widget, window_signals[FRAME_EVENT], 0, event, &return_val);
4787 g_object_unref (event->any.window);
4788 event->any.window = g_object_ref (widget->window);
4796 gtk_window_frame_event (GtkWindow *window, GdkEvent *event)
4798 GdkEventConfigure *configure_event;
4801 switch (event->type)
4804 configure_event = (GdkEventConfigure *)event;
4806 /* Invalidate the decorations */
4809 rect.width = configure_event->width;
4810 rect.height = configure_event->height;
4812 gdk_window_invalidate_rect (window->frame, &rect, FALSE);
4814 /* Pass on the (modified) configure event */
4815 configure_event->width -= window->frame_left + window->frame_right;
4816 configure_event->height -= window->frame_top + window->frame_bottom;
4817 return gtk_window_configure_event (GTK_WIDGET (window), configure_event);
4826 gtk_window_configure_event (GtkWidget *widget,
4827 GdkEventConfigure *event)
4829 GtkWindow *window = GTK_WINDOW (widget);
4830 gboolean expected_reply = window->configure_request_count > 0;
4832 /* window->configure_request_count incremented for each
4833 * configure request, and decremented to a min of 0 for
4834 * each configure notify.
4836 * All it means is that we know we will get at least
4837 * window->configure_request_count more configure notifies.
4838 * We could get more configure notifies than that; some
4839 * of the configure notifies we get may be unrelated to
4840 * the configure requests. But we will get at least
4841 * window->configure_request_count notifies.
4844 if (window->configure_request_count > 0)
4846 window->configure_request_count -= 1;
4847 gdk_window_thaw_toplevel_updates_libgtk_only (widget->window);
4850 /* As an optimization, we avoid a resize when possible.
4852 * The only times we can avoid a resize are:
4853 * - we know only the position changed, not the size
4854 * - we know we have made more requests and so will get more
4855 * notifies and can wait to resize when we get them
4858 if (!expected_reply &&
4859 (widget->allocation.width == event->width &&
4860 widget->allocation.height == event->height))
4862 gdk_window_configure_finished (widget->window);
4867 * If we do need to resize, we do that by:
4868 * - filling in widget->allocation with the new size
4869 * - setting configure_notify_received to TRUE
4870 * for use in gtk_window_move_resize()
4871 * - queueing a resize, leading to invocation of
4872 * gtk_window_move_resize() in an idle handler
4876 window->configure_notify_received = TRUE;
4878 widget->allocation.width = event->width;
4879 widget->allocation.height = event->height;
4881 _gtk_container_queue_resize (GTK_CONTAINER (widget));
4886 /* the accel_key and accel_mods fields of the key have to be setup
4887 * upon calling this function. it'll then return whether that key
4888 * is at all used as accelerator, and if so will OR in the
4889 * accel_flags member of the key.
4892 _gtk_window_query_nonaccels (GtkWindow *window,
4894 GdkModifierType accel_mods)
4896 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
4898 /* movement keys are considered locked accels */
4901 static const guint bindings[] = {
4902 GDK_space, GDK_KP_Space, GDK_Return, GDK_ISO_Enter, GDK_KP_Enter, GDK_Up, GDK_KP_Up, GDK_Down, GDK_KP_Down,
4903 GDK_Left, GDK_KP_Left, GDK_Right, GDK_KP_Right, GDK_Tab, GDK_KP_Tab, GDK_ISO_Left_Tab,
4907 for (i = 0; i < G_N_ELEMENTS (bindings); i++)
4908 if (bindings[i] == accel_key)
4912 /* mnemonics are considered locked accels */
4913 if (accel_mods == window->mnemonic_modifier)
4915 GtkMnemonicHash *mnemonic_hash = gtk_window_get_mnemonic_hash (window, FALSE);
4916 if (mnemonic_hash && _gtk_mnemonic_hash_lookup (mnemonic_hash, accel_key))
4924 * gtk_window_propagate_key_event:
4925 * @window: a #GtkWindow
4926 * @event: a #GdkEventKey
4928 * Propagate a key press or release event to the focus widget and
4929 * up the focus container chain until a widget handles @event.
4930 * This is normally called by the default ::key_press_event and
4931 * ::key_release_event handlers for toplevel windows,
4932 * however in some cases it may be useful to call this directly when
4933 * overriding the standard key handling for a toplevel window.
4935 * Return value: %TRUE if a widget in the focus chain handled the event.
4938 gtk_window_propagate_key_event (GtkWindow *window,
4941 gboolean handled = FALSE;
4942 GtkWidget *widget, *focus;
4944 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
4946 widget = GTK_WIDGET (window);
4947 focus = window->focus_widget;
4949 g_object_ref (focus);
4952 focus && focus != widget &&
4953 gtk_widget_get_toplevel (focus) == widget)
4957 if (GTK_WIDGET_IS_SENSITIVE (focus))
4958 handled = gtk_widget_event (focus, (GdkEvent*) event);
4960 parent = focus->parent;
4962 g_object_ref (parent);
4964 g_object_unref (focus);
4970 g_object_unref (focus);
4976 gtk_window_key_press_event (GtkWidget *widget,
4979 GtkWindow *window = GTK_WINDOW (widget);
4980 gboolean handled = FALSE;
4982 /* handle mnemonics and accelerators */
4984 handled = gtk_window_activate_key (window, event);
4986 /* handle focus widget key events */
4988 handled = gtk_window_propagate_key_event (window, event);
4990 /* Chain up, invokes binding set */
4992 handled = GTK_WIDGET_CLASS (gtk_window_parent_class)->key_press_event (widget, event);
4998 gtk_window_key_release_event (GtkWidget *widget,
5001 GtkWindow *window = GTK_WINDOW (widget);
5002 gboolean handled = FALSE;
5004 /* handle focus widget key events */
5006 handled = gtk_window_propagate_key_event (window, event);
5008 /* Chain up, invokes binding set */
5010 handled = GTK_WIDGET_CLASS (gtk_window_parent_class)->key_release_event (widget, event);
5016 gtk_window_real_activate_default (GtkWindow *window)
5018 gtk_window_activate_default (window);
5022 gtk_window_real_activate_focus (GtkWindow *window)
5024 gtk_window_activate_focus (window);
5028 gtk_window_move_focus (GtkWindow *window,
5029 GtkDirectionType dir)
5031 gtk_widget_child_focus (GTK_WIDGET (window), dir);
5033 if (!GTK_CONTAINER (window)->focus_child)
5034 gtk_window_set_focus (window, NULL);
5038 gtk_window_enter_notify_event (GtkWidget *widget,
5039 GdkEventCrossing *event)
5045 gtk_window_leave_notify_event (GtkWidget *widget,
5046 GdkEventCrossing *event)
5052 do_focus_change (GtkWidget *widget,
5055 GdkEvent *fevent = gdk_event_new (GDK_FOCUS_CHANGE);
5057 g_object_ref (widget);
5060 GTK_WIDGET_SET_FLAGS (widget, GTK_HAS_FOCUS);
5062 GTK_WIDGET_UNSET_FLAGS (widget, GTK_HAS_FOCUS);
5064 fevent->focus_change.type = GDK_FOCUS_CHANGE;
5065 fevent->focus_change.window = widget->window;
5067 g_object_ref (widget->window);
5068 fevent->focus_change.in = in;
5070 gtk_widget_event (widget, fevent);
5072 g_object_notify (G_OBJECT (widget), "has-focus");
5074 g_object_unref (widget);
5075 gdk_event_free (fevent);
5079 gtk_window_focus_in_event (GtkWidget *widget,
5080 GdkEventFocus *event)
5082 GtkWindow *window = GTK_WINDOW (widget);
5084 /* It appears spurious focus in events can occur when
5085 * the window is hidden. So we'll just check to see if
5086 * the window is visible before actually handling the
5089 if (GTK_WIDGET_VISIBLE (widget))
5091 _gtk_window_set_has_toplevel_focus (window, TRUE);
5092 _gtk_window_set_is_active (window, TRUE);
5099 gtk_window_focus_out_event (GtkWidget *widget,
5100 GdkEventFocus *event)
5102 GtkWindow *window = GTK_WINDOW (widget);
5104 _gtk_window_set_has_toplevel_focus (window, FALSE);
5105 _gtk_window_set_is_active (window, FALSE);
5110 static GdkAtom atom_rcfiles = GDK_NONE;
5111 static GdkAtom atom_iconthemes = GDK_NONE;
5114 send_client_message_to_embedded_windows (GtkWidget *widget,
5115 GdkAtom message_type)
5117 GList *embedded_windows;
5119 embedded_windows = g_object_get_qdata (G_OBJECT (widget), quark_gtk_embedded);
5120 if (embedded_windows)
5122 GdkEvent *send_event = gdk_event_new (GDK_CLIENT_EVENT);
5125 for (i = 0; i < 5; i++)
5126 send_event->client.data.l[i] = 0;
5127 send_event->client.data_format = 32;
5128 send_event->client.message_type = message_type;
5130 while (embedded_windows)
5132 guint xid = GPOINTER_TO_UINT (embedded_windows->data);
5133 gdk_event_send_client_message_for_display (gtk_widget_get_display (widget), send_event, xid);
5134 embedded_windows = embedded_windows->next;
5137 gdk_event_free (send_event);
5142 gtk_window_client_event (GtkWidget *widget,
5143 GdkEventClient *event)
5147 atom_rcfiles = gdk_atom_intern_static_string ("_GTK_READ_RCFILES");
5148 atom_iconthemes = gdk_atom_intern_static_string ("_GTK_LOAD_ICONTHEMES");
5151 if (event->message_type == atom_rcfiles)
5153 send_client_message_to_embedded_windows (widget, atom_rcfiles);
5154 gtk_rc_reparse_all_for_settings (gtk_widget_get_settings (widget), FALSE);
5157 if (event->message_type == atom_iconthemes)
5159 send_client_message_to_embedded_windows (widget, atom_iconthemes);
5160 _gtk_icon_theme_check_reload (gtk_widget_get_display (widget));
5167 gtk_window_check_resize (GtkContainer *container)
5169 GtkWindow *window = GTK_WINDOW (container);
5171 if (GTK_WIDGET_VISIBLE (container))
5172 gtk_window_move_resize (window);
5176 gtk_window_focus (GtkWidget *widget,
5177 GtkDirectionType direction)
5181 GtkContainer *container;
5182 GtkWidget *old_focus_child;
5185 container = GTK_CONTAINER (widget);
5186 window = GTK_WINDOW (widget);
5187 bin = GTK_BIN (widget);
5189 old_focus_child = container->focus_child;
5191 /* We need a special implementation here to deal properly with wrapping
5192 * around in the tab chain without the danger of going into an
5195 if (old_focus_child)
5197 if (gtk_widget_child_focus (old_focus_child, direction))
5201 if (window->focus_widget)
5203 if (direction == GTK_DIR_LEFT ||
5204 direction == GTK_DIR_RIGHT ||
5205 direction == GTK_DIR_UP ||
5206 direction == GTK_DIR_DOWN)
5211 /* Wrapped off the end, clear the focus setting for the toplpevel */
5212 parent = window->focus_widget->parent;
5215 gtk_container_set_focus_child (GTK_CONTAINER (parent), NULL);
5216 parent = GTK_WIDGET (parent)->parent;
5219 gtk_window_set_focus (GTK_WINDOW (container), NULL);
5222 /* Now try to focus the first widget in the window */
5225 if (gtk_widget_child_focus (bin->child, direction))
5233 gtk_window_real_set_focus (GtkWindow *window,
5236 GtkWidget *old_focus = window->focus_widget;
5237 gboolean had_default = FALSE;
5238 gboolean focus_had_default = FALSE;
5239 gboolean old_focus_had_default = FALSE;
5243 g_object_ref (old_focus);
5244 g_object_freeze_notify (G_OBJECT (old_focus));
5245 old_focus_had_default = GTK_WIDGET_HAS_DEFAULT (old_focus);
5249 g_object_ref (focus);
5250 g_object_freeze_notify (G_OBJECT (focus));
5251 focus_had_default = GTK_WIDGET_HAS_DEFAULT (focus);
5254 if (window->default_widget)
5255 had_default = GTK_WIDGET_HAS_DEFAULT (window->default_widget);
5257 if (window->focus_widget)
5259 if (GTK_WIDGET_RECEIVES_DEFAULT (window->focus_widget) &&
5260 (window->focus_widget != window->default_widget))
5262 GTK_WIDGET_UNSET_FLAGS (window->focus_widget, GTK_HAS_DEFAULT);
5263 gtk_widget_queue_draw (window->focus_widget);
5265 if (window->default_widget)
5266 GTK_WIDGET_SET_FLAGS (window->default_widget, GTK_HAS_DEFAULT);
5269 window->focus_widget = NULL;
5271 if (window->has_focus)
5272 do_focus_change (old_focus, FALSE);
5274 g_object_notify (G_OBJECT (old_focus), "is-focus");
5277 /* The above notifications may have set a new focus widget,
5278 * if so, we don't want to override it.
5280 if (focus && !window->focus_widget)
5282 window->focus_widget = focus;
5284 if (GTK_WIDGET_RECEIVES_DEFAULT (window->focus_widget) &&
5285 (window->focus_widget != window->default_widget))
5287 if (GTK_WIDGET_CAN_DEFAULT (window->focus_widget))
5288 GTK_WIDGET_SET_FLAGS (window->focus_widget, GTK_HAS_DEFAULT);
5290 if (window->default_widget)
5291 GTK_WIDGET_UNSET_FLAGS (window->default_widget, GTK_HAS_DEFAULT);
5294 if (window->has_focus)
5295 do_focus_change (window->focus_widget, TRUE);
5297 g_object_notify (G_OBJECT (window->focus_widget), "is-focus");
5300 /* If the default widget changed, a redraw will have been queued
5301 * on the old and new default widgets by gtk_window_set_default(), so
5302 * we only have to worry about the case where it didn't change.
5303 * We'll sometimes queue a draw twice on the new widget but that
5306 if (window->default_widget &&
5307 (had_default != GTK_WIDGET_HAS_DEFAULT (window->default_widget)))
5308 gtk_widget_queue_draw (window->default_widget);
5312 if (old_focus_had_default != GTK_WIDGET_HAS_DEFAULT (old_focus))
5313 gtk_widget_queue_draw (old_focus);
5315 g_object_thaw_notify (G_OBJECT (old_focus));
5316 g_object_unref (old_focus);
5320 if (focus_had_default != GTK_WIDGET_HAS_DEFAULT (focus))
5321 gtk_widget_queue_draw (focus);
5323 g_object_thaw_notify (G_OBJECT (focus));
5324 g_object_unref (focus);
5329 * _gtk_window_unset_focus_and_default:
5330 * @window: a #GtkWindow
5331 * @widget: a widget inside of @window
5333 * Checks whether the focus and default widgets of @window are
5334 * @widget or a descendent of @widget, and if so, unset them.
5337 _gtk_window_unset_focus_and_default (GtkWindow *window,
5343 g_object_ref (window);
5344 g_object_ref (widget);
5346 if (GTK_CONTAINER (widget->parent)->focus_child == widget)
5348 child = window->focus_widget;
5350 while (child && child != widget)
5351 child = child->parent;
5353 if (child == widget)
5354 gtk_window_set_focus (GTK_WINDOW (window), NULL);
5357 child = window->default_widget;
5359 while (child && child != widget)
5360 child = child->parent;
5362 if (child == widget)
5363 gtk_window_set_default (window, NULL);
5365 g_object_unref (widget);
5366 g_object_unref (window);
5369 /*********************************
5370 * Functions related to resizing *
5371 *********************************/
5373 /* This function doesn't constrain to geometry hints */
5375 gtk_window_compute_configure_request_size (GtkWindow *window,
5379 GtkRequisition requisition;
5380 GtkWindowGeometryInfo *info;
5384 * - we've done a size request
5387 widget = GTK_WIDGET (window);
5389 info = gtk_window_get_geometry_info (window, FALSE);
5391 if (window->need_default_size)
5393 gtk_widget_get_child_requisition (widget, &requisition);
5395 /* Default to requisition */
5396 *width = requisition.width;
5397 *height = requisition.height;
5399 /* If window is empty so requests 0, default to random nonzero size */
5400 if (*width == 0 && *height == 0)
5406 /* Override requisition with default size */
5410 gint base_width = 0;
5411 gint base_height = 0;
5413 gint min_height = 0;
5415 gint height_inc = 1;
5417 if (info->default_is_geometry &&
5418 (info->default_width > 0 || info->default_height > 0))
5420 GdkGeometry geometry;
5423 gtk_window_compute_hints (window, &geometry, &flags);
5425 if (flags & GDK_HINT_BASE_SIZE)
5427 base_width = geometry.base_width;
5428 base_height = geometry.base_height;
5430 if (flags & GDK_HINT_MIN_SIZE)
5432 min_width = geometry.min_width;
5433 min_height = geometry.min_height;
5435 if (flags & GDK_HINT_RESIZE_INC)
5437 width_inc = geometry.width_inc;
5438 height_inc = geometry.height_inc;
5442 if (info->default_width > 0)
5443 *width = MAX (info->default_width * width_inc + base_width, min_width);
5445 if (info->default_height > 0)
5446 *height = MAX (info->default_height * height_inc + base_height, min_height);
5451 /* Default to keeping current size */
5452 *width = widget->allocation.width;
5453 *height = widget->allocation.height;
5456 /* Override any size with gtk_window_resize() values */
5459 if (info->resize_width > 0)
5460 *width = info->resize_width;
5462 if (info->resize_height > 0)
5463 *height = info->resize_height;
5467 static GtkWindowPosition
5468 get_effective_position (GtkWindow *window)
5470 GtkWindowPosition pos = window->position;
5471 if (pos == GTK_WIN_POS_CENTER_ON_PARENT &&
5472 (window->transient_parent == NULL ||
5473 !GTK_WIDGET_MAPPED (window->transient_parent)))
5474 pos = GTK_WIN_POS_NONE;
5480 get_center_monitor_of_window (GtkWindow *window)
5482 /* We could try to sort out the relative positions of the monitors and
5483 * stuff, or we could just be losers and assume you have a row
5484 * or column of monitors.
5486 return gdk_screen_get_n_monitors (gtk_window_check_screen (window)) / 2;
5490 get_monitor_containing_pointer (GtkWindow *window)
5494 GdkScreen *window_screen;
5495 GdkScreen *pointer_screen;
5497 window_screen = gtk_window_check_screen (window);
5498 gdk_display_get_pointer (gdk_screen_get_display (window_screen),
5502 if (pointer_screen == window_screen)
5503 monitor_num = gdk_screen_get_monitor_at_point (pointer_screen, px, py);
5511 center_window_on_monitor (GtkWindow *window,
5517 GdkRectangle monitor;
5520 monitor_num = get_monitor_containing_pointer (window);
5522 if (monitor_num == -1)
5523 monitor_num = get_center_monitor_of_window (window);
5525 gdk_screen_get_monitor_geometry (gtk_window_check_screen (window),
5526 monitor_num, &monitor);
5528 *x = (monitor.width - w) / 2 + monitor.x;
5529 *y = (monitor.height - h) / 2 + monitor.y;
5531 /* Be sure we aren't off the monitor, ignoring _NET_WM_STRUT
5532 * and WM decorations.
5546 if (extent > clamp_extent)
5548 *base = clamp_base + clamp_extent/2 - extent/2;
5549 else if (*base < clamp_base)
5551 else if (*base + extent > clamp_base + clamp_extent)
5552 *base = clamp_base + clamp_extent - extent;
5556 clamp_window_to_rectangle (gint *x,
5560 const GdkRectangle *rect)
5562 #ifdef DEBUGGING_OUTPUT
5563 g_print ("%s: %+d%+d %dx%d: %+d%+d: %dx%d", __FUNCTION__, rect->x, rect->y, rect->width, rect->height, *x, *y, w, h);
5566 /* If it is too large, center it. If it fits on the monitor but is
5567 * partially outside, move it to the closest edge. Do this
5568 * separately in x and y directions.
5570 clamp (x, w, rect->x, rect->width);
5571 clamp (y, h, rect->y, rect->height);
5572 #ifdef DEBUGGING_OUTPUT
5573 g_print (" ==> %+d%+d: %dx%d\n", *x, *y, w, h);
5579 gtk_window_compute_configure_request (GtkWindow *window,
5580 GdkRectangle *request,
5581 GdkGeometry *geometry,
5584 GdkGeometry new_geometry;
5588 GtkWindowPosition pos;
5589 GtkWidget *parent_widget;
5590 GtkWindowGeometryInfo *info;
5594 widget = GTK_WIDGET (window);
5596 screen = gtk_window_check_screen (window);
5598 gtk_widget_size_request (widget, NULL);
5599 gtk_window_compute_configure_request_size (window, (guint *)&w, (guint *)&h);
5601 gtk_window_compute_hints (window, &new_geometry, &new_flags);
5602 gtk_window_constrain_size (window,
5603 &new_geometry, new_flags,
5607 parent_widget = (GtkWidget*) window->transient_parent;
5609 pos = get_effective_position (window);
5610 info = gtk_window_get_geometry_info (window, FALSE);
5612 /* by default, don't change position requested */
5615 x = info->last.configure_request.x;
5616 y = info->last.configure_request.y;
5625 if (window->need_default_position)
5628 /* FIXME this all interrelates with window gravity.
5629 * For most of them I think we want to set GRAVITY_CENTER.
5631 * Not sure how to go about that.
5636 /* here we are only handling CENTER_ALWAYS
5637 * as it relates to default positioning,
5638 * where it's equivalent to simply CENTER
5640 case GTK_WIN_POS_CENTER_ALWAYS:
5641 case GTK_WIN_POS_CENTER:
5642 center_window_on_monitor (window, w, h, &x, &y);
5645 case GTK_WIN_POS_CENTER_ON_PARENT:
5648 GdkRectangle monitor;
5651 g_assert (GTK_WIDGET_MAPPED (parent_widget)); /* established earlier */
5653 if (parent_widget->window != NULL)
5654 monitor_num = gdk_screen_get_monitor_at_window (screen,
5655 parent_widget->window);
5659 gdk_window_get_origin (parent_widget->window,
5662 x = ox + (parent_widget->allocation.width - w) / 2;
5663 y = oy + (parent_widget->allocation.height - h) / 2;
5665 /* Clamp onto current monitor, ignoring _NET_WM_STRUT and
5666 * WM decorations. If parent wasn't on a monitor, just
5669 if (monitor_num >= 0)
5671 gdk_screen_get_monitor_geometry (screen, monitor_num, &monitor);
5672 clamp_window_to_rectangle (&x, &y, w, h, &monitor);
5677 case GTK_WIN_POS_MOUSE:
5679 gint screen_width = gdk_screen_get_width (screen);
5680 gint screen_height = gdk_screen_get_height (screen);
5682 GdkRectangle monitor;
5683 GdkScreen *pointer_screen;
5686 gdk_display_get_pointer (gdk_screen_get_display (screen),
5690 if (pointer_screen == screen)
5691 monitor_num = gdk_screen_get_monitor_at_point (screen, px, py);
5697 x = CLAMP (x, 0, screen_width - w);
5698 y = CLAMP (y, 0, screen_height - h);
5700 /* Clamp onto current monitor, ignoring _NET_WM_STRUT and
5701 * WM decorations. Don't try to figure out what's going
5702 * on if the mouse wasn't inside a monitor.
5704 if (monitor_num >= 0)
5706 gdk_screen_get_monitor_geometry (screen, monitor_num, &monitor);
5707 clamp_window_to_rectangle (&x, &y, w, h, &monitor);
5715 } /* if (window->need_default_position) */
5717 if (window->need_default_position && info &&
5718 info->initial_pos_set)
5720 x = info->initial_x;
5721 y = info->initial_y;
5722 gtk_window_constrain_position (window, w, h, &x, &y);
5728 request->height = h;
5731 *geometry = new_geometry;
5737 gtk_window_constrain_position (GtkWindow *window,
5743 /* See long comments in gtk_window_move_resize()
5744 * on when it's safe to call this function.
5746 if (window->position == GTK_WIN_POS_CENTER_ALWAYS)
5748 gint center_x, center_y;
5750 center_window_on_monitor (window, new_width, new_height, ¢er_x, ¢er_y);
5758 gtk_window_move_resize (GtkWindow *window)
5762 * First we determine whether any information has changed that would
5763 * cause us to revise our last configure request. If we would send
5764 * a different configure request from last time, then
5765 * configure_request_size_changed = TRUE or
5766 * configure_request_pos_changed = TRUE. configure_request_size_changed
5767 * may be true due to new hints, a gtk_window_resize(), or whatever.
5768 * configure_request_pos_changed may be true due to gtk_window_set_position()
5769 * or gtk_window_move().
5771 * If the configure request has changed, we send off a new one. To
5772 * ensure GTK+ invariants are maintained (resize queue does what it
5773 * should), we go ahead and size_allocate the requested size in this
5776 * If the configure request has not changed, we don't ever resend
5777 * it, because it could mean fighting the user or window manager.
5780 * To prepare the configure request, we come up with a base size/pos:
5781 * - the one from gtk_window_move()/gtk_window_resize()
5782 * - else default_width, default_height if we haven't ever
5784 * - else the size request if we haven't ever been mapped,
5785 * as a substitute default size
5786 * - else the current size of the window, as received from
5787 * configure notifies (i.e. the current allocation)
5789 * If GTK_WIN_POS_CENTER_ALWAYS is active, we constrain
5790 * the position request to be centered.
5793 GtkContainer *container;
5794 GtkWindowGeometryInfo *info;
5795 GdkGeometry new_geometry;
5797 GdkRectangle new_request;
5798 gboolean configure_request_size_changed;
5799 gboolean configure_request_pos_changed;
5800 gboolean hints_changed; /* do we need to send these again */
5801 GtkWindowLastGeometryInfo saved_last_info;
5803 widget = GTK_WIDGET (window);
5804 container = GTK_CONTAINER (widget);
5805 info = gtk_window_get_geometry_info (window, TRUE);
5807 configure_request_size_changed = FALSE;
5808 configure_request_pos_changed = FALSE;
5810 gtk_window_compute_configure_request (window, &new_request,
5811 &new_geometry, &new_flags);
5813 /* This check implies the invariant that we never set info->last
5814 * without setting the hints and sending off a configure request.
5816 * If we change info->last without sending the request, we may
5819 if (info->last.configure_request.x != new_request.x ||
5820 info->last.configure_request.y != new_request.y)
5821 configure_request_pos_changed = TRUE;
5823 if ((info->last.configure_request.width != new_request.width ||
5824 info->last.configure_request.height != new_request.height))
5825 configure_request_size_changed = TRUE;
5827 hints_changed = FALSE;
5829 if (!gtk_window_compare_hints (&info->last.geometry, info->last.flags,
5830 &new_geometry, new_flags))
5832 hints_changed = TRUE;
5835 /* Position Constraints
5836 * ====================
5838 * POS_CENTER_ALWAYS is conceptually a constraint rather than
5839 * a default. The other POS_ values are used only when the
5840 * window is shown, not after that.
5842 * However, we can't implement a position constraint as
5843 * "anytime the window size changes, center the window"
5844 * because this may well end up fighting the WM or user. In
5845 * fact it gets in an infinite loop with at least one WM.
5847 * Basically, applications are in no way in a position to
5848 * constrain the position of a window, with one exception:
5849 * override redirect windows. (Really the intended purpose
5850 * of CENTER_ALWAYS anyhow, I would think.)
5852 * So the way we implement this "constraint" is to say that when WE
5853 * cause a move or resize, i.e. we make a configure request changing
5854 * window size, we recompute the CENTER_ALWAYS position to reflect
5855 * the new window size, and include it in our request. Also, if we
5856 * just turned on CENTER_ALWAYS we snap to center with a new
5857 * request. Otherwise, if we are just NOTIFIED of a move or resize
5858 * done by someone else e.g. the window manager, we do NOT send a
5859 * new configure request.
5861 * For override redirect windows, this works fine; all window
5862 * sizes are from our configure requests. For managed windows,
5863 * it is at least semi-sane, though who knows what the
5864 * app author is thinking.
5867 /* This condition should be kept in sync with the condition later on
5868 * that determines whether we send a configure request. i.e. we
5869 * should do this position constraining anytime we were going to
5870 * send a configure request anyhow, plus when constraints have
5873 if (configure_request_pos_changed ||
5874 configure_request_size_changed ||
5876 info->position_constraints_changed)
5878 /* We request the constrained position if:
5879 * - we were changing position, and need to clamp
5880 * the change to the constraint
5881 * - we're changing the size anyway
5882 * - set_position() was called to toggle CENTER_ALWAYS on
5885 gtk_window_constrain_position (window,
5891 /* Update whether we need to request a move */
5892 if (info->last.configure_request.x != new_request.x ||
5893 info->last.configure_request.y != new_request.y)
5894 configure_request_pos_changed = TRUE;
5896 configure_request_pos_changed = FALSE;
5900 if (window->type == GTK_WINDOW_TOPLEVEL)
5902 int notify_x, notify_y;
5904 /* this is the position from the last configure notify */
5905 gdk_window_get_position (widget->window, ¬ify_x, ¬ify_y);
5907 g_message ("--- %s ---\n"
5908 "last : %d,%d\t%d x %d\n"
5909 "this : %d,%d\t%d x %d\n"
5910 "alloc : %d,%d\t%d x %d\n"
5912 "resize: \t%d x %d\n"
5913 "size_changed: %d pos_changed: %d hints_changed: %d\n"
5914 "configure_notify_received: %d\n"
5915 "configure_request_count: %d\n"
5916 "position_constraints_changed: %d\n",
5917 window->title ? window->title : "(no title)",
5918 info->last.configure_request.x,
5919 info->last.configure_request.y,
5920 info->last.configure_request.width,
5921 info->last.configure_request.height,
5927 widget->allocation.width,
5928 widget->allocation.height,
5929 widget->requisition.width,
5930 widget->requisition.height,
5932 info->resize_height,
5933 configure_request_pos_changed,
5934 configure_request_size_changed,
5936 window->configure_notify_received,
5937 window->configure_request_count,
5938 info->position_constraints_changed);
5942 saved_last_info = info->last;
5943 info->last.geometry = new_geometry;
5944 info->last.flags = new_flags;
5945 info->last.configure_request = new_request;
5947 /* need to set PPosition so the WM will look at our position,
5948 * but we don't want to count PPosition coming and going as a hints
5949 * change for future iterations. So we saved info->last prior to
5953 /* Also, if the initial position was explicitly set, then we always
5954 * toggle on PPosition. This makes gtk_window_move(window, 0, 0)
5958 /* Also, we toggle on PPosition if GTK_WIN_POS_ is in use and
5959 * this is an initial map
5962 if ((configure_request_pos_changed ||
5963 info->initial_pos_set ||
5964 (window->need_default_position &&
5965 get_effective_position (window) != GTK_WIN_POS_NONE)) &&
5966 (new_flags & GDK_HINT_POS) == 0)
5968 new_flags |= GDK_HINT_POS;
5969 hints_changed = TRUE;
5972 /* Set hints if necessary
5975 gdk_window_set_geometry_hints (widget->window,
5979 /* handle resizing/moving and widget tree allocation
5981 if (window->configure_notify_received)
5983 GtkAllocation allocation;
5985 /* If we have received a configure event since
5986 * the last time in this function, we need to
5987 * accept our new size and size_allocate child widgets.
5988 * (see gtk_window_configure_event() for more details).
5990 * 1 or more configure notifies may have been received.
5991 * Also, configure_notify_received will only be TRUE
5992 * if all expected configure notifies have been received
5993 * (one per configure request), as an optimization.
5996 window->configure_notify_received = FALSE;
5998 /* gtk_window_configure_event() filled in widget->allocation */
5999 allocation = widget->allocation;
6000 gtk_widget_size_allocate (widget, &allocation);
6002 gdk_window_process_updates (widget->window, TRUE);
6004 gdk_window_configure_finished (widget->window);
6006 /* If the configure request changed, it means that
6008 * 1) coincidentally changed hints or widget properties
6009 * impacting the configure request before getting
6010 * a configure notify, or
6011 * 2) some broken widget is changing its size request
6012 * during size allocation, resulting in
6013 * a false appearance of changed configure request.
6015 * For 1), we could just go ahead and ask for the
6016 * new size right now, but doing that for 2)
6017 * might well be fighting the user (and can even
6018 * trigger a loop). Since we really don't want to
6019 * do that, we requeue a resize in hopes that
6020 * by the time it gets handled, the child has seen
6021 * the light and is willing to go along with the
6022 * new size. (this happens for the zvt widget, since
6023 * the size_allocate() above will have stored the
6024 * requisition corresponding to the new size in the
6027 * This doesn't buy us anything for 1), but it shouldn't
6028 * hurt us too badly, since it is what would have
6029 * happened if we had gotten the configure event before
6030 * the new size had been set.
6033 if (configure_request_size_changed ||
6034 configure_request_pos_changed)
6036 /* Don't change the recorded last info after all, because we
6037 * haven't actually updated to the new info yet - we decided
6038 * to postpone our configure request until later.
6040 info->last = saved_last_info;
6042 gtk_widget_queue_resize (widget); /* migth recurse for GTK_RESIZE_IMMEDIATE */
6045 return; /* Bail out, we didn't really process the move/resize */
6047 else if ((configure_request_size_changed || hints_changed) &&
6048 (widget->allocation.width != new_request.width ||
6049 widget->allocation.height != new_request.height))
6052 /* We are in one of the following situations:
6053 * A. configure_request_size_changed
6054 * our requisition has changed and we need a different window size,
6055 * so we request it from the window manager.
6056 * B. !configure_request_size_changed && hints_changed
6057 * the window manager rejects our size, but we have just changed the
6058 * window manager hints, so there's a chance our request will
6059 * be honoured this time, so we try again.
6061 * However, if the new requisition is the same as the current allocation,
6062 * we don't request it again, since we won't get a ConfigureNotify back from
6063 * the window manager unless it decides to change our requisition. If
6064 * we don't get the ConfigureNotify back, the resize queue will never be run.
6067 /* Now send the configure request */
6068 if (configure_request_pos_changed)
6072 gdk_window_move_resize (window->frame,
6073 new_request.x - window->frame_left,
6074 new_request.y - window->frame_top,
6075 new_request.width + window->frame_left + window->frame_right,
6076 new_request.height + window->frame_top + window->frame_bottom);
6077 gdk_window_resize (widget->window,
6078 new_request.width, new_request.height);
6081 gdk_window_move_resize (widget->window,
6082 new_request.x, new_request.y,
6083 new_request.width, new_request.height);
6085 else /* only size changed */
6088 gdk_window_resize (window->frame,
6089 new_request.width + window->frame_left + window->frame_right,
6090 new_request.height + window->frame_top + window->frame_bottom);
6091 gdk_window_resize (widget->window,
6092 new_request.width, new_request.height);
6095 if (window->type == GTK_WINDOW_POPUP)
6097 GtkAllocation allocation;
6099 /* Directly size allocate for override redirect (popup) windows. */
6102 allocation.width = new_request.width;
6103 allocation.height = new_request.height;
6105 gtk_widget_size_allocate (widget, &allocation);
6107 gdk_window_process_updates (widget->window, TRUE);
6109 if (container->resize_mode == GTK_RESIZE_QUEUE)
6110 gtk_widget_queue_draw (widget);
6114 /* Increment the number of have-not-yet-received-notify requests */
6115 window->configure_request_count += 1;
6116 gdk_window_freeze_toplevel_updates_libgtk_only (widget->window);
6118 /* for GTK_RESIZE_QUEUE toplevels, we are now awaiting a new
6119 * configure event in response to our resizing request.
6120 * the configure event will cause a new resize with
6121 * ->configure_notify_received=TRUE.
6122 * until then, we want to
6123 * - discard expose events
6124 * - coalesce resizes for our children
6125 * - defer any window resizes until the configure event arrived
6126 * to achieve this, we queue a resize for the window, but remove its
6127 * resizing handler, so resizing will not be handled from the next
6128 * idle handler but when the configure event arrives.
6130 * FIXME: we should also dequeue the pending redraws here, since
6131 * we handle those ourselves upon ->configure_notify_received==TRUE.
6133 if (container->resize_mode == GTK_RESIZE_QUEUE)
6135 gtk_widget_queue_resize (widget);
6136 _gtk_container_dequeue_resize_handler (container);
6142 /* Handle any position changes.
6144 if (configure_request_pos_changed)
6148 gdk_window_move (window->frame,
6149 new_request.x - window->frame_left,
6150 new_request.y - window->frame_top);
6153 gdk_window_move (widget->window,
6154 new_request.x, new_request.y);
6157 /* And run the resize queue.
6159 gtk_container_resize_children (container);
6162 /* We have now processed a move/resize since the last position
6163 * constraint change, setting of the initial position, or resize.
6164 * (Not resetting these flags here can lead to infinite loops for
6165 * GTK_RESIZE_IMMEDIATE containers)
6167 info->position_constraints_changed = FALSE;
6168 info->initial_pos_set = FALSE;
6169 info->resize_width = -1;
6170 info->resize_height = -1;
6173 /* Compare two sets of Geometry hints for equality.
6176 gtk_window_compare_hints (GdkGeometry *geometry_a,
6178 GdkGeometry *geometry_b,
6181 if (flags_a != flags_b)
6184 if ((flags_a & GDK_HINT_MIN_SIZE) &&
6185 (geometry_a->min_width != geometry_b->min_width ||
6186 geometry_a->min_height != geometry_b->min_height))
6189 if ((flags_a & GDK_HINT_MAX_SIZE) &&
6190 (geometry_a->max_width != geometry_b->max_width ||
6191 geometry_a->max_height != geometry_b->max_height))
6194 if ((flags_a & GDK_HINT_BASE_SIZE) &&
6195 (geometry_a->base_width != geometry_b->base_width ||
6196 geometry_a->base_height != geometry_b->base_height))
6199 if ((flags_a & GDK_HINT_ASPECT) &&
6200 (geometry_a->min_aspect != geometry_b->min_aspect ||
6201 geometry_a->max_aspect != geometry_b->max_aspect))
6204 if ((flags_a & GDK_HINT_RESIZE_INC) &&
6205 (geometry_a->width_inc != geometry_b->width_inc ||
6206 geometry_a->height_inc != geometry_b->height_inc))
6209 if ((flags_a & GDK_HINT_WIN_GRAVITY) &&
6210 geometry_a->win_gravity != geometry_b->win_gravity)
6217 _gtk_window_constrain_size (GtkWindow *window,
6223 GtkWindowGeometryInfo *info;
6225 g_return_if_fail (GTK_IS_WINDOW (window));
6227 info = window->geometry_info;
6230 GdkWindowHints flags = info->last.flags;
6231 GdkGeometry *geometry = &info->last.geometry;
6233 gtk_window_constrain_size (window,
6244 gtk_window_constrain_size (GtkWindow *window,
6245 GdkGeometry *geometry,
6252 gdk_window_constrain_size (geometry, flags, width, height,
6253 new_width, new_height);
6256 /* Compute the set of geometry hints and flags for a window
6257 * based on the application set geometry, and requisiition
6258 * of the window. gtk_widget_size_request() must have been
6262 gtk_window_compute_hints (GtkWindow *window,
6263 GdkGeometry *new_geometry,
6267 gint extra_width = 0;
6268 gint extra_height = 0;
6269 GtkWindowGeometryInfo *geometry_info;
6270 GtkRequisition requisition;
6272 widget = GTK_WIDGET (window);
6274 gtk_widget_get_child_requisition (widget, &requisition);
6275 geometry_info = gtk_window_get_geometry_info (GTK_WINDOW (widget), FALSE);
6279 *new_flags = geometry_info->mask;
6280 *new_geometry = geometry_info->geometry;
6287 if (geometry_info && geometry_info->widget)
6289 GtkRequisition child_requisition;
6291 /* FIXME: This really isn't right. It gets the min size wrong and forces
6292 * callers to do horrible hacks like set a huge usize on the child requisition
6293 * to get the base size right. We really want to find the answers to:
6295 * - If the geometry widget was infinitely big, how much extra space
6296 * would be needed for the stuff around it.
6298 * - If the geometry widget was infinitely small, how big would the
6299 * window still have to be.
6301 * Finding these answers would be a bit of a mess here. (Bug #68668)
6303 gtk_widget_get_child_requisition (geometry_info->widget, &child_requisition);
6305 extra_width = widget->requisition.width - child_requisition.width;
6306 extra_height = widget->requisition.height - child_requisition.height;
6309 /* We don't want to set GDK_HINT_POS in here, we just set it
6310 * in gtk_window_move_resize() when we want the position
6314 if (*new_flags & GDK_HINT_BASE_SIZE)
6316 new_geometry->base_width += extra_width;
6317 new_geometry->base_height += extra_height;
6319 else if (!(*new_flags & GDK_HINT_MIN_SIZE) &&
6320 (*new_flags & GDK_HINT_RESIZE_INC) &&
6321 ((extra_width != 0) || (extra_height != 0)))
6323 *new_flags |= GDK_HINT_BASE_SIZE;
6325 new_geometry->base_width = extra_width;
6326 new_geometry->base_height = extra_height;
6329 if (*new_flags & GDK_HINT_MIN_SIZE)
6331 if (new_geometry->min_width < 0)
6332 new_geometry->min_width = requisition.width;
6334 new_geometry->min_width += extra_width;
6336 if (new_geometry->min_height < 0)
6337 new_geometry->min_height = requisition.height;
6339 new_geometry->min_height += extra_height;
6341 else if (!window->allow_shrink)
6343 *new_flags |= GDK_HINT_MIN_SIZE;
6345 new_geometry->min_width = requisition.width;
6346 new_geometry->min_height = requisition.height;
6349 if (*new_flags & GDK_HINT_MAX_SIZE)
6351 if (new_geometry->max_width < 0)
6352 new_geometry->max_width = requisition.width;
6354 new_geometry->max_width += extra_width;
6356 if (new_geometry->max_height < 0)
6357 new_geometry->max_height = requisition.height;
6359 new_geometry->max_height += extra_height;
6361 else if (!window->allow_grow)
6363 *new_flags |= GDK_HINT_MAX_SIZE;
6365 new_geometry->max_width = requisition.width;
6366 new_geometry->max_height = requisition.height;
6369 *new_flags |= GDK_HINT_WIN_GRAVITY;
6370 new_geometry->win_gravity = window->gravity;
6373 /***********************
6374 * Redrawing functions *
6375 ***********************/
6378 gtk_window_paint (GtkWidget *widget,
6381 gtk_paint_flat_box (widget->style, widget->window, GTK_STATE_NORMAL,
6382 GTK_SHADOW_NONE, area, widget, "base", 0, 0, -1, -1);
6386 gtk_window_expose (GtkWidget *widget,
6387 GdkEventExpose *event)
6389 if (!GTK_WIDGET_APP_PAINTABLE (widget))
6390 gtk_window_paint (widget, &event->area);
6392 if (GTK_WIDGET_CLASS (gtk_window_parent_class)->expose_event)
6393 return GTK_WIDGET_CLASS (gtk_window_parent_class)->expose_event (widget, event);
6399 * gtk_window_set_has_frame:
6400 * @window: a #GtkWindow
6401 * @setting: a boolean
6403 * (Note: this is a special-purpose function for the framebuffer port,
6404 * that causes GTK+ to draw its own window border. For most applications,
6405 * you want gtk_window_set_decorated() instead, which tells the window
6406 * manager whether to draw the window border.)
6408 * If this function is called on a window with setting of %TRUE, before
6409 * it is realized or showed, it will have a "frame" window around
6410 * @window->window, accessible in @window->frame. Using the signal
6411 * frame_event you can receive all events targeted at the frame.
6413 * This function is used by the linux-fb port to implement managed
6414 * windows, but it could conceivably be used by X-programs that
6415 * want to do their own window decorations.
6419 gtk_window_set_has_frame (GtkWindow *window,
6422 g_return_if_fail (GTK_IS_WINDOW (window));
6423 g_return_if_fail (!GTK_WIDGET_REALIZED (window));
6425 window->has_frame = setting != FALSE;
6429 * gtk_window_get_has_frame:
6430 * @window: a #GtkWindow
6432 * Accessor for whether the window has a frame window exterior to
6433 * @window->window. Gets the value set by gtk_window_set_has_frame ().
6435 * Return value: %TRUE if a frame has been added to the window
6436 * via gtk_window_set_has_frame().
6439 gtk_window_get_has_frame (GtkWindow *window)
6441 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
6443 return window->has_frame;
6447 * gtk_window_set_frame_dimensions:
6448 * @window: a #GtkWindow that has a frame
6449 * @left: The width of the left border
6450 * @top: The height of the top border
6451 * @right: The width of the right border
6452 * @bottom: The height of the bottom border
6454 * (Note: this is a special-purpose function intended for the framebuffer
6455 * port; see gtk_window_set_has_frame(). It will have no effect on the
6456 * window border drawn by the window manager, which is the normal
6457 * case when using the X Window system.)
6459 * For windows with frames (see gtk_window_set_has_frame()) this function
6460 * can be used to change the size of the frame border.
6463 gtk_window_set_frame_dimensions (GtkWindow *window,
6471 g_return_if_fail (GTK_IS_WINDOW (window));
6473 widget = GTK_WIDGET (window);
6475 if (window->frame_left == left &&
6476 window->frame_top == top &&
6477 window->frame_right == right &&
6478 window->frame_bottom == bottom)
6481 window->frame_left = left;
6482 window->frame_top = top;
6483 window->frame_right = right;
6484 window->frame_bottom = bottom;
6486 if (GTK_WIDGET_REALIZED (widget) && window->frame)
6488 gint width = widget->allocation.width + left + right;
6489 gint height = widget->allocation.height + top + bottom;
6490 gdk_window_resize (window->frame, width, height);
6491 gtk_decorated_window_move_resize_window (window,
6493 widget->allocation.width,
6494 widget->allocation.height);
6499 * gtk_window_present:
6500 * @window: a #GtkWindow
6502 * Presents a window to the user. This may mean raising the window
6503 * in the stacking order, deiconifying it, moving it to the current
6504 * desktop, and/or giving it the keyboard focus, possibly dependent
6505 * on the user's platform, window manager, and preferences.
6507 * If @window is hidden, this function calls gtk_widget_show()
6510 * This function should be used when the user tries to open a window
6511 * that's already open. Say for example the preferences dialog is
6512 * currently open, and the user chooses Preferences from the menu
6513 * a second time; use gtk_window_present() to move the already-open dialog
6514 * where the user can see it.
6516 * If you are calling this function in response to a user interaction,
6517 * it is preferable to use gtk_window_present_with_time().
6521 gtk_window_present (GtkWindow *window)
6523 gtk_window_present_with_time (window, GDK_CURRENT_TIME);
6527 * gtk_window_present_with_time:
6528 * @window: a #GtkWindow
6529 * @timestamp: the timestamp of the user interaction (typically a
6530 * button or key press event) which triggered this call
6532 * Presents a window to the user in response to a user interaction.
6533 * If you need to present a window without a timestamp, use
6534 * gtk_window_present(). See gtk_window_present() for details.
6539 gtk_window_present_with_time (GtkWindow *window,
6544 g_return_if_fail (GTK_IS_WINDOW (window));
6546 widget = GTK_WIDGET (window);
6548 if (GTK_WIDGET_VISIBLE (window))
6550 g_assert (widget->window != NULL);
6552 gdk_window_show (widget->window);
6554 /* Translate a timestamp of GDK_CURRENT_TIME appropriately */
6555 if (timestamp == GDK_CURRENT_TIME)
6557 #ifdef GDK_WINDOWING_X11
6558 GdkDisplay *display;
6560 display = gtk_widget_get_display (GTK_WIDGET (window));
6561 timestamp = gdk_x11_display_get_user_time (display);
6563 timestamp = gtk_get_current_event_time ();
6567 gdk_window_focus (widget->window, timestamp);
6571 gtk_widget_show (widget);
6576 * gtk_window_iconify:
6577 * @window: a #GtkWindow
6579 * Asks to iconify (i.e. minimize) the specified @window. Note that
6580 * you shouldn't assume the window is definitely iconified afterward,
6581 * because other entities (e.g. the user or <link
6582 * linkend="gtk-X11-arch">window manager</link>) could deiconify it
6583 * again, or there may not be a window manager in which case
6584 * iconification isn't possible, etc. But normally the window will end
6585 * up iconified. Just don't write code that crashes if not.
6587 * It's permitted to call this function before showing a window,
6588 * in which case the window will be iconified before it ever appears
6591 * You can track iconification via the "window_state_event" signal
6596 gtk_window_iconify (GtkWindow *window)
6599 GdkWindow *toplevel;
6601 g_return_if_fail (GTK_IS_WINDOW (window));
6603 widget = GTK_WIDGET (window);
6605 window->iconify_initially = TRUE;
6608 toplevel = window->frame;
6610 toplevel = widget->window;
6612 if (toplevel != NULL)
6613 gdk_window_iconify (toplevel);
6617 * gtk_window_deiconify:
6618 * @window: a #GtkWindow
6620 * Asks to deiconify (i.e. unminimize) the specified @window. Note
6621 * that you shouldn't assume the window is definitely deiconified
6622 * afterward, because other entities (e.g. the user or <link
6623 * linkend="gtk-X11-arch">window manager</link>) could iconify it
6624 * again before your code which assumes deiconification gets to run.
6626 * You can track iconification via the "window_state_event" signal
6630 gtk_window_deiconify (GtkWindow *window)
6633 GdkWindow *toplevel;
6635 g_return_if_fail (GTK_IS_WINDOW (window));
6637 widget = GTK_WIDGET (window);
6639 window->iconify_initially = FALSE;
6642 toplevel = window->frame;
6644 toplevel = widget->window;
6646 if (toplevel != NULL)
6647 gdk_window_deiconify (toplevel);
6652 * @window: a #GtkWindow
6654 * Asks to stick @window, which means that it will appear on all user
6655 * desktops. Note that you shouldn't assume the window is definitely
6656 * stuck afterward, because other entities (e.g. the user or <link
6657 * linkend="gtk-X11-arch">window manager</link>) could unstick it
6658 * again, and some window managers do not support sticking
6659 * windows. But normally the window will end up stuck. Just don't
6660 * write code that crashes if not.
6662 * It's permitted to call this function before showing a window.
6664 * You can track stickiness via the "window_state_event" signal
6669 gtk_window_stick (GtkWindow *window)
6672 GdkWindow *toplevel;
6674 g_return_if_fail (GTK_IS_WINDOW (window));
6676 widget = GTK_WIDGET (window);
6678 window->stick_initially = TRUE;
6681 toplevel = window->frame;
6683 toplevel = widget->window;
6685 if (toplevel != NULL)
6686 gdk_window_stick (toplevel);
6690 * gtk_window_unstick:
6691 * @window: a #GtkWindow
6693 * Asks to unstick @window, which means that it will appear on only
6694 * one of the user's desktops. Note that you shouldn't assume the
6695 * window is definitely unstuck afterward, because other entities
6696 * (e.g. the user or <link linkend="gtk-X11-arch">window
6697 * manager</link>) could stick it again. But normally the window will
6698 * end up stuck. Just don't write code that crashes if not.
6700 * You can track stickiness via the "window_state_event" signal
6705 gtk_window_unstick (GtkWindow *window)
6708 GdkWindow *toplevel;
6710 g_return_if_fail (GTK_IS_WINDOW (window));
6712 widget = GTK_WIDGET (window);
6714 window->stick_initially = FALSE;
6717 toplevel = window->frame;
6719 toplevel = widget->window;
6721 if (toplevel != NULL)
6722 gdk_window_unstick (toplevel);
6726 * gtk_window_maximize:
6727 * @window: a #GtkWindow
6729 * Asks to maximize @window, so that it becomes full-screen. Note that
6730 * you shouldn't assume the window is definitely maximized afterward,
6731 * because other entities (e.g. the user or <link
6732 * linkend="gtk-X11-arch">window manager</link>) could unmaximize it
6733 * again, and not all window managers support maximization. But
6734 * normally the window will end up maximized. Just don't write code
6735 * that crashes if not.
6737 * It's permitted to call this function before showing a window,
6738 * in which case the window will be maximized when it appears onscreen
6741 * You can track maximization via the "window_state_event" signal
6746 gtk_window_maximize (GtkWindow *window)
6749 GdkWindow *toplevel;
6751 g_return_if_fail (GTK_IS_WINDOW (window));
6753 widget = GTK_WIDGET (window);
6755 window->maximize_initially = TRUE;
6758 toplevel = window->frame;
6760 toplevel = widget->window;
6762 if (toplevel != NULL)
6763 gdk_window_maximize (toplevel);
6767 * gtk_window_unmaximize:
6768 * @window: a #GtkWindow
6770 * Asks to unmaximize @window. Note that you shouldn't assume the
6771 * window is definitely unmaximized afterward, because other entities
6772 * (e.g. the user or <link linkend="gtk-X11-arch">window
6773 * manager</link>) could maximize it again, and not all window
6774 * managers honor requests to unmaximize. But normally the window will
6775 * end up unmaximized. Just don't write code that crashes if not.
6777 * You can track maximization via the "window_state_event" signal
6782 gtk_window_unmaximize (GtkWindow *window)
6785 GdkWindow *toplevel;
6787 g_return_if_fail (GTK_IS_WINDOW (window));
6789 widget = GTK_WIDGET (window);
6791 window->maximize_initially = FALSE;
6794 toplevel = window->frame;
6796 toplevel = widget->window;
6798 if (toplevel != NULL)
6799 gdk_window_unmaximize (toplevel);
6803 * gtk_window_fullscreen:
6804 * @window: a #GtkWindow
6806 * Asks to place @window in the fullscreen state. Note that you
6807 * shouldn't assume the window is definitely full screen afterward,
6808 * because other entities (e.g. the user or <link
6809 * linkend="gtk-X11-arch">window manager</link>) could unfullscreen it
6810 * again, and not all window managers honor requests to fullscreen
6811 * windows. But normally the window will end up fullscreen. Just
6812 * don't write code that crashes if not.
6814 * You can track the fullscreen state via the "window_state_event" signal
6820 gtk_window_fullscreen (GtkWindow *window)
6823 GdkWindow *toplevel;
6824 GtkWindowPrivate *priv;
6826 g_return_if_fail (GTK_IS_WINDOW (window));
6828 widget = GTK_WIDGET (window);
6829 priv = GTK_WINDOW_GET_PRIVATE (window);
6831 priv->fullscreen_initially = TRUE;
6834 toplevel = window->frame;
6836 toplevel = widget->window;
6838 if (toplevel != NULL)
6839 gdk_window_fullscreen (toplevel);
6843 * gtk_window_unfullscreen:
6844 * @window: a #GtkWindow
6846 * Asks to toggle off the fullscreen state for @window. Note that you
6847 * shouldn't assume the window is definitely not full screen
6848 * afterward, because other entities (e.g. the user or <link
6849 * linkend="gtk-X11-arch">window manager</link>) could fullscreen it
6850 * again, and not all window managers honor requests to unfullscreen
6851 * windows. But normally the window will end up restored to its normal
6852 * state. Just don't write code that crashes if not.
6854 * You can track the fullscreen state via the "window_state_event" signal
6860 gtk_window_unfullscreen (GtkWindow *window)
6863 GdkWindow *toplevel;
6864 GtkWindowPrivate *priv;
6866 g_return_if_fail (GTK_IS_WINDOW (window));
6868 widget = GTK_WIDGET (window);
6869 priv = GTK_WINDOW_GET_PRIVATE (window);
6871 priv->fullscreen_initially = FALSE;
6874 toplevel = window->frame;
6876 toplevel = widget->window;
6878 if (toplevel != NULL)
6879 gdk_window_unfullscreen (toplevel);
6883 * gtk_window_set_keep_above:
6884 * @window: a #GtkWindow
6885 * @setting: whether to keep @window above other windows
6887 * Asks to keep @window above, so that it stays on top. Note that
6888 * you shouldn't assume the window is definitely above afterward,
6889 * because other entities (e.g. the user or <link
6890 * linkend="gtk-X11-arch">window manager</link>) could not keep it above,
6891 * and not all window managers support keeping windows above. But
6892 * normally the window will end kept above. Just don't write code
6893 * that crashes if not.
6895 * It's permitted to call this function before showing a window,
6896 * in which case the window will be kept above when it appears onscreen
6899 * You can track the above state via the "window_state_event" signal
6902 * Note that, according to the <ulink
6903 * url="http://www.freedesktop.org/Standards/wm-spec">Extended Window
6904 * Manager Hints</ulink> specification, the above state is mainly meant
6905 * for user preferences and should not be used by applications e.g. for
6906 * drawing attention to their dialogs.
6911 gtk_window_set_keep_above (GtkWindow *window,
6915 GtkWindowPrivate *priv;
6916 GdkWindow *toplevel;
6918 g_return_if_fail (GTK_IS_WINDOW (window));
6920 widget = GTK_WIDGET (window);
6921 priv = GTK_WINDOW_GET_PRIVATE (window);
6923 priv->above_initially = setting != FALSE;
6925 priv->below_initially = FALSE;
6928 toplevel = window->frame;
6930 toplevel = widget->window;
6932 if (toplevel != NULL)
6933 gdk_window_set_keep_above (toplevel, setting);
6937 * gtk_window_set_keep_below:
6938 * @window: a #GtkWindow
6939 * @setting: whether to keep @window below other windows
6941 * Asks to keep @window below, so that it stays in bottom. Note that
6942 * you shouldn't assume the window is definitely below afterward,
6943 * because other entities (e.g. the user or <link
6944 * linkend="gtk-X11-arch">window manager</link>) could not keep it below,
6945 * and not all window managers support putting windows below. But
6946 * normally the window will be kept below. Just don't write code
6947 * that crashes if not.
6949 * It's permitted to call this function before showing a window,
6950 * in which case the window will be kept below when it appears onscreen
6953 * You can track the below state via the "window_state_event" signal
6956 * Note that, according to the <ulink
6957 * url="http://www.freedesktop.org/Standards/wm-spec">Extended Window
6958 * Manager Hints</ulink> specification, the above state is mainly meant
6959 * for user preferences and should not be used by applications e.g. for
6960 * drawing attention to their dialogs.
6965 gtk_window_set_keep_below (GtkWindow *window,
6969 GtkWindowPrivate *priv;
6970 GdkWindow *toplevel;
6972 g_return_if_fail (GTK_IS_WINDOW (window));
6974 widget = GTK_WIDGET (window);
6975 priv = GTK_WINDOW_GET_PRIVATE (window);
6977 priv->below_initially = setting != FALSE;
6979 priv->above_initially = FALSE;
6982 toplevel = window->frame;
6984 toplevel = widget->window;
6986 if (toplevel != NULL)
6987 gdk_window_set_keep_below (toplevel, setting);
6991 * gtk_window_set_resizable:
6992 * @window: a #GtkWindow
6993 * @resizable: %TRUE if the user can resize this window
6995 * Sets whether the user can resize a window. Windows are user resizable
6999 gtk_window_set_resizable (GtkWindow *window,
7002 g_return_if_fail (GTK_IS_WINDOW (window));
7004 gtk_window_set_policy (window, FALSE, resizable, FALSE);
7008 * gtk_window_get_resizable:
7009 * @window: a #GtkWindow
7011 * Gets the value set by gtk_window_set_resizable().
7013 * Return value: %TRUE if the user can resize the window
7016 gtk_window_get_resizable (GtkWindow *window)
7018 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
7020 /* allow_grow is most likely to indicate the semantic concept we
7021 * mean by "resizable" (and will be a reliable indicator if
7022 * set_policy() hasn't been called)
7024 return window->allow_grow;
7028 * gtk_window_set_gravity:
7029 * @window: a #GtkWindow
7030 * @gravity: window gravity
7032 * Window gravity defines the meaning of coordinates passed to
7033 * gtk_window_move(). See gtk_window_move() and #GdkGravity for
7036 * The default window gravity is #GDK_GRAVITY_NORTH_WEST which will
7037 * typically "do what you mean."
7041 gtk_window_set_gravity (GtkWindow *window,
7044 g_return_if_fail (GTK_IS_WINDOW (window));
7046 if (gravity != window->gravity)
7048 window->gravity = gravity;
7050 /* gtk_window_move_resize() will adapt gravity
7052 gtk_widget_queue_resize (GTK_WIDGET (window));
7054 g_object_notify (G_OBJECT (window), "gravity");
7059 * gtk_window_get_gravity:
7060 * @window: a #GtkWindow
7062 * Gets the value set by gtk_window_set_gravity().
7064 * Return value: window gravity
7067 gtk_window_get_gravity (GtkWindow *window)
7069 g_return_val_if_fail (GTK_IS_WINDOW (window), 0);
7071 return window->gravity;
7075 * gtk_window_begin_resize_drag:
7076 * @window: a #GtkWindow
7077 * @button: mouse button that initiated the drag
7078 * @edge: position of the resize control
7079 * @root_x: X position where the user clicked to initiate the drag, in root window coordinates
7080 * @root_y: Y position where the user clicked to initiate the drag
7081 * @timestamp: timestamp from the click event that initiated the drag
7083 * Starts resizing a window. This function is used if an application
7084 * has window resizing controls. When GDK can support it, the resize
7085 * will be done using the standard mechanism for the <link
7086 * linkend="gtk-X11-arch">window manager</link> or windowing
7087 * system. Otherwise, GDK will try to emulate window resizing,
7088 * potentially not all that well, depending on the windowing system.
7092 gtk_window_begin_resize_drag (GtkWindow *window,
7100 GdkWindow *toplevel;
7102 g_return_if_fail (GTK_IS_WINDOW (window));
7103 g_return_if_fail (GTK_WIDGET_VISIBLE (window));
7105 widget = GTK_WIDGET (window);
7108 toplevel = window->frame;
7110 toplevel = widget->window;
7112 gdk_window_begin_resize_drag (toplevel,
7119 * gtk_window_get_frame_dimensions:
7120 * @window: a #GtkWindow
7121 * @left: location to store the width of the frame at the left, or %NULL
7122 * @top: location to store the height of the frame at the top, or %NULL
7123 * @right: location to store the width of the frame at the returns, or %NULL
7124 * @bottom: location to store the height of the frame at the bottom, or %NULL
7126 * (Note: this is a special-purpose function intended for the
7127 * framebuffer port; see gtk_window_set_has_frame(). It will not
7128 * return the size of the window border drawn by the <link
7129 * linkend="gtk-X11-arch">window manager</link>, which is the normal
7130 * case when using a windowing system. See
7131 * gdk_window_get_frame_extents() to get the standard window border
7134 * Retrieves the dimensions of the frame window for this toplevel.
7135 * See gtk_window_set_has_frame(), gtk_window_set_frame_dimensions().
7138 gtk_window_get_frame_dimensions (GtkWindow *window,
7144 g_return_if_fail (GTK_IS_WINDOW (window));
7147 *left = window->frame_left;
7149 *top = window->frame_top;
7151 *right = window->frame_right;
7153 *bottom = window->frame_bottom;
7157 * gtk_window_begin_move_drag:
7158 * @window: a #GtkWindow
7159 * @button: mouse button that initiated the drag
7160 * @root_x: X position where the user clicked to initiate the drag, in root window coordinates
7161 * @root_y: Y position where the user clicked to initiate the drag
7162 * @timestamp: timestamp from the click event that initiated the drag
7164 * Starts moving a window. This function is used if an application has
7165 * window movement grips. When GDK can support it, the window movement
7166 * will be done using the standard mechanism for the <link
7167 * linkend="gtk-X11-arch">window manager</link> or windowing
7168 * system. Otherwise, GDK will try to emulate window movement,
7169 * potentially not all that well, depending on the windowing system.
7173 gtk_window_begin_move_drag (GtkWindow *window,
7180 GdkWindow *toplevel;
7182 g_return_if_fail (GTK_IS_WINDOW (window));
7183 g_return_if_fail (GTK_WIDGET_VISIBLE (window));
7185 widget = GTK_WIDGET (window);
7188 toplevel = window->frame;
7190 toplevel = widget->window;
7192 gdk_window_begin_move_drag (toplevel,
7199 * gtk_window_set_screen:
7200 * @window: a #GtkWindow.
7201 * @screen: a #GdkScreen.
7203 * Sets the #GdkScreen where the @window is displayed; if
7204 * the window is already mapped, it will be unmapped, and
7205 * then remapped on the new screen.
7210 gtk_window_set_screen (GtkWindow *window,
7214 GdkScreen *previous_screen;
7215 gboolean was_mapped;
7217 g_return_if_fail (GTK_IS_WINDOW (window));
7218 g_return_if_fail (GDK_IS_SCREEN (screen));
7220 if (screen == window->screen)
7223 widget = GTK_WIDGET (window);
7225 previous_screen = window->screen;
7226 was_mapped = GTK_WIDGET_MAPPED (widget);
7229 gtk_widget_unmap (widget);
7230 if (GTK_WIDGET_REALIZED (widget))
7231 gtk_widget_unrealize (widget);
7233 gtk_window_free_key_hash (window);
7234 window->screen = screen;
7235 gtk_widget_reset_rc_styles (widget);
7236 if (screen != previous_screen)
7238 g_signal_handlers_disconnect_by_func (previous_screen,
7239 gtk_window_on_composited_changed, window);
7240 g_signal_connect (screen, "composited_changed",
7241 G_CALLBACK (gtk_window_on_composited_changed), window);
7243 _gtk_widget_propagate_screen_changed (widget, previous_screen);
7244 _gtk_widget_propagate_composited_changed (widget);
7246 g_object_notify (G_OBJECT (window), "screen");
7249 gtk_widget_map (widget);
7253 gtk_window_on_composited_changed (GdkScreen *screen,
7256 gtk_widget_queue_draw (GTK_WIDGET (window));
7258 _gtk_widget_propagate_composited_changed (GTK_WIDGET (window));
7262 gtk_window_check_screen (GtkWindow *window)
7265 return window->screen;
7268 g_warning ("Screen for GtkWindow not set; you must always set\n"
7269 "a screen for a GtkWindow before using the window");
7275 * gtk_window_get_screen:
7276 * @window: a #GtkWindow.
7278 * Returns the #GdkScreen associated with @window.
7280 * Return value: a #GdkScreen.
7285 gtk_window_get_screen (GtkWindow *window)
7287 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
7289 return window->screen;
7293 * gtk_window_is_active:
7294 * @window: a #GtkWindow
7296 * Returns whether the window is part of the current active toplevel.
7297 * (That is, the toplevel window receiving keystrokes.)
7298 * The return value is %TRUE if the window is active toplevel
7299 * itself, but also if it is, say, a #GtkPlug embedded in the active toplevel.
7300 * You might use this function if you wanted to draw a widget
7301 * differently in an active window from a widget in an inactive window.
7302 * See gtk_window_has_toplevel_focus()
7304 * Return value: %TRUE if the window part of the current active window.
7309 gtk_window_is_active (GtkWindow *window)
7311 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
7313 return window->is_active;
7317 * gtk_window_has_toplevel_focus:
7318 * @window: a #GtkWindow
7320 * Returns whether the input focus is within this GtkWindow.
7321 * For real toplevel windows, this is identical to gtk_window_is_active(),
7322 * but for embedded windows, like #GtkPlug, the results will differ.
7324 * Return value: %TRUE if the input focus is within this GtkWindow
7329 gtk_window_has_toplevel_focus (GtkWindow *window)
7331 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
7333 return window->has_toplevel_focus;
7337 gtk_window_group_class_init (GtkWindowGroupClass *klass)
7342 gtk_window_group_get_type (void)
7344 static GType window_group_type = 0;
7346 if (!window_group_type)
7348 const GTypeInfo window_group_info =
7350 sizeof (GtkWindowGroupClass),
7351 NULL, /* base_init */
7352 NULL, /* base_finalize */
7353 (GClassInitFunc) gtk_window_group_class_init,
7354 NULL, /* class_finalize */
7355 NULL, /* class_data */
7356 sizeof (GtkWindowGroup),
7357 0, /* n_preallocs */
7358 (GInstanceInitFunc) NULL,
7361 window_group_type = g_type_register_static (G_TYPE_OBJECT, I_("GtkWindowGroup"),
7362 &window_group_info, 0);
7365 return window_group_type;
7369 * gtk_window_group_new:
7371 * Creates a new #GtkWindowGroup object. Grabs added with
7372 * gtk_grab_add() only affect windows within the same #GtkWindowGroup.
7374 * Return value: a new #GtkWindowGroup.
7377 gtk_window_group_new (void)
7379 return g_object_new (GTK_TYPE_WINDOW_GROUP, NULL);
7383 window_group_cleanup_grabs (GtkWindowGroup *group,
7387 GSList *to_remove = NULL;
7389 tmp_list = group->grabs;
7392 if (gtk_widget_get_toplevel (tmp_list->data) == (GtkWidget*) window)
7393 to_remove = g_slist_prepend (to_remove, g_object_ref (tmp_list->data));
7394 tmp_list = tmp_list->next;
7399 gtk_grab_remove (to_remove->data);
7400 g_object_unref (to_remove->data);
7401 to_remove = g_slist_delete_link (to_remove, to_remove);
7406 * gtk_window_group_add_window:
7407 * @window_group: a #GtkWindowGroup
7408 * @window: the #GtkWindow to add
7410 * Adds a window to a #GtkWindowGroup.
7413 gtk_window_group_add_window (GtkWindowGroup *window_group,
7416 g_return_if_fail (GTK_IS_WINDOW_GROUP (window_group));
7417 g_return_if_fail (GTK_IS_WINDOW (window));
7419 if (window->group != window_group)
7421 g_object_ref (window);
7422 g_object_ref (window_group);
7425 gtk_window_group_remove_window (window->group, window);
7427 window_group_cleanup_grabs (gtk_window_get_group (NULL), window);
7429 window->group = window_group;
7431 g_object_unref (window);
7436 * gtk_window_group_remove_window:
7437 * @window_group: a #GtkWindowGroup
7438 * @window: the #GtkWindow to remove
7440 * Removes a window from a #GtkWindowGroup.
7443 gtk_window_group_remove_window (GtkWindowGroup *window_group,
7446 g_return_if_fail (GTK_IS_WINDOW_GROUP (window_group));
7447 g_return_if_fail (GTK_IS_WINDOW (window));
7448 g_return_if_fail (window->group == window_group);
7450 g_object_ref (window);
7452 window_group_cleanup_grabs (window_group, window);
7453 window->group = NULL;
7455 g_object_unref (window_group);
7456 g_object_unref (window);
7460 * gtk_window_group_list_windows:
7461 * @window_group: a #GtkWindowGroup
7463 * Returns a list of the #GtkWindows that belong to @window_group.
7465 * Returns: A newly-allocated list of windows inside the group.
7470 gtk_window_group_list_windows (GtkWindowGroup *window_group)
7472 GList *toplevels, *toplevel, *group_windows;
7474 g_return_val_if_fail (GTK_IS_WINDOW_GROUP (window_group), NULL);
7476 group_windows = NULL;
7477 toplevels = gtk_window_list_toplevels ();
7479 for (toplevel = toplevels; toplevel; toplevel = toplevel->next)
7481 GtkWindow *window = toplevel->data;
7483 if (window_group == window->group)
7484 group_windows = g_list_prepend (group_windows, window);
7487 return g_list_reverse (group_windows);
7491 * gtk_window_get_group:
7492 * @window: a #GtkWindow, or %NULL
7494 * Returns the group for @window or the default group, if
7495 * @window is %NULL or if @window does not have an explicit
7498 * Returns: the #GtkWindowGroup for a window or the default group
7503 gtk_window_get_group (GtkWindow *window)
7505 if (window && window->group)
7506 return window->group;
7509 static GtkWindowGroup *default_group = NULL;
7512 default_group = gtk_window_group_new ();
7514 return default_group;
7518 /* Return the current grab widget of the given group
7521 _gtk_window_group_get_current_grab (GtkWindowGroup *window_group)
7523 if (window_group->grabs)
7524 return GTK_WIDGET (window_group->grabs->data);
7529 Derived from XParseGeometry() in XFree86
7531 Copyright 1985, 1986, 1987,1998 The Open Group
7533 All Rights Reserved.
7535 The above copyright notice and this permission notice shall be included
7536 in all copies or substantial portions of the Software.
7538 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
7539 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
7540 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
7541 IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
7542 OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
7543 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
7544 OTHER DEALINGS IN THE SOFTWARE.
7546 Except as contained in this notice, the name of The Open Group shall
7547 not be used in advertising or otherwise to promote the sale, use or
7548 other dealings in this Software without prior written authorization
7549 from The Open Group.
7554 * XParseGeometry parses strings of the form
7555 * "=<width>x<height>{+-}<xoffset>{+-}<yoffset>", where
7556 * width, height, xoffset, and yoffset are unsigned integers.
7557 * Example: "=80x24+300-49"
7558 * The equal sign is optional.
7559 * It returns a bitmask that indicates which of the four values
7560 * were actually found in the string. For each value found,
7561 * the corresponding argument is updated; for each value
7562 * not found, the corresponding argument is left unchanged.
7565 /* The following code is from Xlib, and is minimally modified, so we
7566 * can track any upstream changes if required. Don't change this
7567 * code. Or if you do, put in a huge comment marking which thing
7572 read_int (gchar *string,
7580 else if (*string == '-')
7586 for (; (*string >= '0') && (*string <= '9'); string++)
7588 result = (result * 10) + (*string - '0');
7600 * Bitmask returned by XParseGeometry(). Each bit tells if the corresponding
7601 * value (x, y, width, height) was found in the parsed string.
7603 #define NoValue 0x0000
7604 #define XValue 0x0001
7605 #define YValue 0x0002
7606 #define WidthValue 0x0004
7607 #define HeightValue 0x0008
7608 #define AllValues 0x000F
7609 #define XNegative 0x0010
7610 #define YNegative 0x0020
7612 /* Try not to reformat/modify, so we can compare/sync with X sources */
7614 gtk_XParseGeometry (const char *string,
7617 unsigned int *width,
7618 unsigned int *height)
7622 unsigned int tempWidth, tempHeight;
7624 char *nextCharacter;
7626 /* These initializations are just to silence gcc */
7632 if ( (string == NULL) || (*string == '\0')) return(mask);
7634 string++; /* ignore possible '=' at beg of geometry spec */
7636 strind = (char *)string;
7637 if (*strind != '+' && *strind != '-' && *strind != 'x') {
7638 tempWidth = read_int(strind, &nextCharacter);
7639 if (strind == nextCharacter)
7641 strind = nextCharacter;
7645 if (*strind == 'x' || *strind == 'X') {
7647 tempHeight = read_int(strind, &nextCharacter);
7648 if (strind == nextCharacter)
7650 strind = nextCharacter;
7651 mask |= HeightValue;
7654 if ((*strind == '+') || (*strind == '-')) {
7655 if (*strind == '-') {
7657 tempX = -read_int(strind, &nextCharacter);
7658 if (strind == nextCharacter)
7660 strind = nextCharacter;
7666 tempX = read_int(strind, &nextCharacter);
7667 if (strind == nextCharacter)
7669 strind = nextCharacter;
7672 if ((*strind == '+') || (*strind == '-')) {
7673 if (*strind == '-') {
7675 tempY = -read_int(strind, &nextCharacter);
7676 if (strind == nextCharacter)
7678 strind = nextCharacter;
7685 tempY = read_int(strind, &nextCharacter);
7686 if (strind == nextCharacter)
7688 strind = nextCharacter;
7694 /* If strind isn't at the end of the string the it's an invalid
7695 geometry specification. */
7697 if (*strind != '\0') return (0);
7703 if (mask & WidthValue)
7705 if (mask & HeightValue)
7706 *height = tempHeight;
7711 * gtk_window_parse_geometry:
7712 * @window: a #GtkWindow
7713 * @geometry: geometry string
7715 * Parses a standard X Window System geometry string - see the
7716 * manual page for X (type 'man X') for details on this.
7717 * gtk_window_parse_geometry() does work on all GTK+ ports
7718 * including Win32 but is primarily intended for an X environment.
7720 * If either a size or a position can be extracted from the
7721 * geometry string, gtk_window_parse_geometry() returns %TRUE
7722 * and calls gtk_window_set_default_size() and/or gtk_window_move()
7723 * to resize/move the window.
7725 * If gtk_window_parse_geometry() returns %TRUE, it will also
7726 * set the #GDK_HINT_USER_POS and/or #GDK_HINT_USER_SIZE hints
7727 * indicating to the window manager that the size/position of
7728 * the window was user-specified. This causes most window
7729 * managers to honor the geometry.
7731 * Note that for gtk_window_parse_geometry() to work as expected, it has
7732 * to be called when the window has its "final" size, i.e. after calling
7733 * gtk_widget_show_all() on the contents and gtk_window_set_geometry_hints()
7736 * #include <gtk/gtk.h>
7739 * fill_with_content (GtkWidget *vbox)
7741 * /* fill with content... */
7745 * main (int argc, char *argv[])
7747 * GtkWidget *window, *vbox;
7748 * GdkGeometry size_hints = {
7749 * 100, 50, 0, 0, 100, 50, 10, 10, 0.0, 0.0, GDK_GRAVITY_NORTH_WEST
7752 * gtk_init (&argc, &argv);
7754 * window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
7755 * vbox = gtk_vbox_new (FALSE, 0);
7757 * gtk_container_add (GTK_CONTAINER (window), vbox);
7758 * fill_with_content (vbox);
7759 * gtk_widget_show_all (vbox);
7761 * gtk_window_set_geometry_hints (GTK_WINDOW (window),
7764 * GDK_HINT_MIN_SIZE |
7765 * GDK_HINT_BASE_SIZE |
7766 * GDK_HINT_RESIZE_INC);
7770 * if (!gtk_window_parse_geometry (GTK_WINDOW (window), argv[1]))
7771 * fprintf (stderr, "Failed to parse '%s'\n", argv[1]);
7774 * gtk_widget_show_all (window);
7781 * Return value: %TRUE if string was parsed successfully
7784 gtk_window_parse_geometry (GtkWindow *window,
7785 const gchar *geometry)
7787 gint result, x = 0, y = 0;
7790 gboolean size_set, pos_set;
7793 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
7794 g_return_val_if_fail (geometry != NULL, FALSE);
7796 screen = gtk_window_check_screen (window);
7798 result = gtk_XParseGeometry (geometry, &x, &y, &w, &h);
7801 if ((result & WidthValue) || (result & HeightValue))
7803 gtk_window_set_default_size_internal (window,
7804 TRUE, result & WidthValue ? w : -1,
7805 TRUE, result & HeightValue ? h : -1,
7810 gtk_window_get_size (window, (gint *)&w, (gint *)&h);
7812 grav = GDK_GRAVITY_NORTH_WEST;
7814 if ((result & XNegative) && (result & YNegative))
7815 grav = GDK_GRAVITY_SOUTH_EAST;
7816 else if (result & XNegative)
7817 grav = GDK_GRAVITY_NORTH_EAST;
7818 else if (result & YNegative)
7819 grav = GDK_GRAVITY_SOUTH_WEST;
7821 if ((result & XValue) == 0)
7824 if ((result & YValue) == 0)
7827 if (grav == GDK_GRAVITY_SOUTH_WEST ||
7828 grav == GDK_GRAVITY_SOUTH_EAST)
7829 y = gdk_screen_get_height (screen) - h + y;
7831 if (grav == GDK_GRAVITY_SOUTH_EAST ||
7832 grav == GDK_GRAVITY_NORTH_EAST)
7833 x = gdk_screen_get_width (screen) - w + x;
7835 /* we don't let you put a window offscreen; maybe some people would
7836 * prefer to be able to, but it's kind of a bogus thing to do.
7845 if ((result & XValue) || (result & YValue))
7847 gtk_window_set_gravity (window, grav);
7848 gtk_window_move (window, x, y);
7852 if (size_set || pos_set)
7854 /* Set USSize, USPosition hints */
7855 GtkWindowGeometryInfo *info;
7857 info = gtk_window_get_geometry_info (window, TRUE);
7860 info->mask |= GDK_HINT_USER_POS;
7862 info->mask |= GDK_HINT_USER_SIZE;
7869 gtk_window_mnemonic_hash_foreach (guint keyval,
7875 GtkWindowKeysForeachFunc func;
7879 (*info->func) (info->window, keyval, info->window->mnemonic_modifier, TRUE, info->func_data);
7883 _gtk_window_keys_foreach (GtkWindow *window,
7884 GtkWindowKeysForeachFunc func,
7888 GtkMnemonicHash *mnemonic_hash;
7892 GtkWindowKeysForeachFunc func;
7896 info.window = window;
7898 info.func_data = func_data;
7900 mnemonic_hash = gtk_window_get_mnemonic_hash (window, FALSE);
7902 _gtk_mnemonic_hash_foreach (mnemonic_hash,
7903 gtk_window_mnemonic_hash_foreach, &info);
7905 groups = gtk_accel_groups_from_object (G_OBJECT (window));
7908 GtkAccelGroup *group = groups->data;
7911 for (i = 0; i < group->n_accels; i++)
7913 GtkAccelKey *key = &group->priv_accels[i].key;
7916 (*func) (window, key->accel_key, key->accel_mods, FALSE, func_data);
7919 groups = groups->next;
7924 gtk_window_keys_changed (GtkWindow *window)
7926 gtk_window_free_key_hash (window);
7927 gtk_window_get_key_hash (window);
7930 typedef struct _GtkWindowKeyEntry GtkWindowKeyEntry;
7932 struct _GtkWindowKeyEntry
7936 guint is_mnemonic : 1;
7940 window_key_entry_destroy (gpointer data)
7942 g_slice_free (GtkWindowKeyEntry, data);
7946 add_to_key_hash (GtkWindow *window,
7948 GdkModifierType modifiers,
7949 gboolean is_mnemonic,
7952 GtkKeyHash *key_hash = data;
7954 GtkWindowKeyEntry *entry = g_slice_new (GtkWindowKeyEntry);
7956 entry->keyval = keyval;
7957 entry->modifiers = modifiers;
7958 entry->is_mnemonic = is_mnemonic;
7960 /* GtkAccelGroup stores lowercased accelerators. To deal
7961 * with this, if <Shift> was specified, uppercase.
7963 if (modifiers & GDK_SHIFT_MASK)
7965 if (keyval == GDK_Tab)
7966 keyval = GDK_ISO_Left_Tab;
7968 keyval = gdk_keyval_to_upper (keyval);
7971 _gtk_key_hash_add_entry (key_hash, keyval, entry->modifiers, entry);
7975 gtk_window_get_key_hash (GtkWindow *window)
7977 GdkScreen *screen = gtk_window_check_screen (window);
7978 GtkKeyHash *key_hash = g_object_get_qdata (G_OBJECT (window), quark_gtk_window_key_hash);
7983 key_hash = _gtk_key_hash_new (gdk_keymap_get_for_display (gdk_screen_get_display (screen)),
7984 (GDestroyNotify)window_key_entry_destroy);
7985 _gtk_window_keys_foreach (window, add_to_key_hash, key_hash);
7986 g_object_set_qdata (G_OBJECT (window), quark_gtk_window_key_hash, key_hash);
7992 gtk_window_free_key_hash (GtkWindow *window)
7994 GtkKeyHash *key_hash = g_object_get_qdata (G_OBJECT (window), quark_gtk_window_key_hash);
7997 _gtk_key_hash_free (key_hash);
7998 g_object_set_qdata (G_OBJECT (window), quark_gtk_window_key_hash, NULL);
8003 * gtk_window_activate_key:
8004 * @window: a #GtkWindow
8005 * @event: a #GdkEventKey
8007 * Activates mnemonics and accelerators for this #GtkWindow. This is normally
8008 * called by the default ::key_press_event handler for toplevel windows,
8009 * however in some cases it may be useful to call this directly when
8010 * overriding the standard key handling for a toplevel window.
8012 * Return value: %TRUE if a mnemonic or accelerator was found and activated.
8015 gtk_window_activate_key (GtkWindow *window,
8018 GtkKeyHash *key_hash;
8019 GtkWindowKeyEntry *found_entry = NULL;
8021 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
8022 g_return_val_if_fail (event != NULL, FALSE);
8024 key_hash = gtk_window_get_key_hash (window);
8028 GSList *entries = _gtk_key_hash_lookup (key_hash,
8029 event->hardware_keycode,
8031 gtk_accelerator_get_default_mod_mask (),
8035 for (tmp_list = entries; tmp_list; tmp_list = tmp_list->next)
8037 GtkWindowKeyEntry *entry = tmp_list->data;
8038 if (entry->is_mnemonic)
8040 found_entry = entry;
8045 if (!found_entry && entries)
8046 found_entry = entries->data;
8048 g_slist_free (entries);
8053 gboolean enable_mnemonics;
8054 gboolean enable_accels;
8056 g_object_get (gtk_widget_get_settings (GTK_WIDGET (window)),
8057 "gtk-enable-mnemonics", &enable_mnemonics,
8058 "gtk-enable-accels", &enable_accels,
8061 if (found_entry->is_mnemonic)
8063 if (enable_mnemonics)
8064 return gtk_window_mnemonic_activate (window, found_entry->keyval,
8065 found_entry->modifiers);
8070 return gtk_accel_groups_activate (G_OBJECT (window), found_entry->keyval,
8071 found_entry->modifiers);
8079 window_update_has_focus (GtkWindow *window)
8081 GtkWidget *widget = GTK_WIDGET (window);
8082 gboolean has_focus = window->has_toplevel_focus && window->is_active;
8084 if (has_focus != window->has_focus)
8086 window->has_focus = has_focus;
8090 if (window->focus_widget &&
8091 window->focus_widget != widget &&
8092 !GTK_WIDGET_HAS_FOCUS (window->focus_widget))
8093 do_focus_change (window->focus_widget, TRUE);
8097 if (window->focus_widget &&
8098 window->focus_widget != widget &&
8099 GTK_WIDGET_HAS_FOCUS (window->focus_widget))
8100 do_focus_change (window->focus_widget, FALSE);
8106 * _gtk_window_set_is_active:
8107 * @window: a #GtkWindow
8108 * @is_active: %TRUE if the window is in the currently active toplevel
8110 * Internal function that sets whether the #GtkWindow is part
8111 * of the currently active toplevel window (taking into account inter-process
8115 _gtk_window_set_is_active (GtkWindow *window,
8118 g_return_if_fail (GTK_IS_WINDOW (window));
8120 is_active = is_active != FALSE;
8122 if (is_active != window->is_active)
8124 window->is_active = is_active;
8125 window_update_has_focus (window);
8127 g_object_notify (G_OBJECT (window), "is-active");
8132 * _gtk_window_set_has_toplevel_focus:
8133 * @window: a #GtkWindow
8134 * @has_toplevel_focus: %TRUE if the in
8136 * Internal function that sets whether the keyboard focus for the
8137 * toplevel window (taking into account inter-process embedding.)
8140 _gtk_window_set_has_toplevel_focus (GtkWindow *window,
8141 gboolean has_toplevel_focus)
8143 g_return_if_fail (GTK_IS_WINDOW (window));
8145 has_toplevel_focus = has_toplevel_focus != FALSE;
8147 if (has_toplevel_focus != window->has_toplevel_focus)
8149 window->has_toplevel_focus = has_toplevel_focus;
8150 window_update_has_focus (window);
8152 g_object_notify (G_OBJECT (window), "has-toplevel-focus");
8157 * gtk_window_set_auto_startup_notification:
8158 * @setting: %TRUE to automatically do startup notification
8160 * By default, after showing the first #GtkWindow, GTK+ calls
8161 * gdk_notify_startup_complete(). Call this function to disable
8162 * the automatic startup notification. You might do this if your
8163 * first window is a splash screen, and you want to delay notification
8164 * until after your real main window has been shown, for example.
8166 * In that example, you would disable startup notification
8167 * temporarily, show your splash screen, then re-enable it so that
8168 * showing the main window would automatically result in notification.
8173 gtk_window_set_auto_startup_notification (gboolean setting)
8175 disable_startup_notification = !setting;
8180 #undef gtk_window_set_icon_from_file
8183 gtk_window_set_icon_from_file (GtkWindow *window,
8184 const gchar *filename,
8187 gchar *utf8_filename = g_locale_to_utf8 (filename, -1, NULL, NULL, err);
8190 if (utf8_filename == NULL)
8193 retval = gtk_window_set_icon_from_file_utf8 (window, utf8_filename, err);
8195 g_free (utf8_filename);
8200 #undef gtk_window_set_default_icon_from_file
8203 gtk_window_set_default_icon_from_file (const gchar *filename,
8206 gchar *utf8_filename = g_locale_to_utf8 (filename, -1, NULL, NULL, err);
8209 if (utf8_filename == NULL)
8212 retval = gtk_window_set_default_icon_from_file_utf8 (utf8_filename, err);
8214 g_free (utf8_filename);
8221 #define __GTK_WINDOW_C__
8222 #include "gtkaliasdef.c"