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/.
31 #include "gdk/gdkkeysyms.h"
35 #include "gtkprivate.h"
37 #include "gtkwindow.h"
38 #include "gtkwindow-decorate.h"
39 #include "gtkbindings.h"
40 #include "gtkkeyhash.h"
42 #include "gtkmnemonichash.h"
43 #include "gtkiconfactory.h"
44 #include "gtkicontheme.h"
45 #include "gtkmarshalers.h"
49 #ifdef GDK_WINDOWING_X11
79 PROP_DESTROY_WITH_PARENT,
84 PROP_SKIP_TASKBAR_HINT,
92 /* Readonly properties */
94 PROP_HAS_TOPLEVEL_FOCUS,
102 GdkPixmap *icon_pixmap;
103 GdkPixmap *icon_mask;
106 guint using_default_icon : 1;
107 guint using_parent_icon : 1;
108 guint using_themed_icon : 1;
112 GdkGeometry geometry; /* Last set of geometry hints we set */
113 GdkWindowHints flags;
114 GdkRectangle configure_request;
115 } GtkWindowLastGeometryInfo;
117 struct _GtkWindowGeometryInfo
119 /* Properties that the app has set on the window
121 GdkGeometry geometry; /* Geometry hints */
123 GtkWidget *widget; /* subwidget to which hints apply */
124 /* from last gtk_window_resize () - if > 0, indicates that
125 * we should resize to this size.
130 /* From last gtk_window_move () prior to mapping -
131 * only used if initial_pos_set
136 /* Default size - used only the FIRST time we map a window,
141 /* whether to use initial_x, initial_y */
142 guint initial_pos_set : 1;
143 /* CENTER_ALWAYS or other position constraint changed since
144 * we sent the last configure request.
146 guint position_constraints_changed : 1;
148 /* if true, default_width, height come from gtk_window_parse_geometry,
149 * and thus should be multiplied by the increments and affect the
150 * geometry widget only
152 guint default_is_geometry : 1;
154 GtkWindowLastGeometryInfo last;
157 #define GTK_WINDOW_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GTK_TYPE_WINDOW, GtkWindowPrivate))
159 typedef struct _GtkWindowPrivate GtkWindowPrivate;
161 struct _GtkWindowPrivate
163 GtkMnemonicHash *mnemonic_hash;
165 guint above_initially : 1;
166 guint below_initially : 1;
167 guint fullscreen_initially : 1;
168 guint skips_taskbar : 1;
169 guint skips_pager : 1;
171 guint accept_focus : 1;
172 guint focus_on_map : 1;
175 static void gtk_window_class_init (GtkWindowClass *klass);
176 static void gtk_window_init (GtkWindow *window);
177 static void gtk_window_dispose (GObject *object);
178 static void gtk_window_destroy (GtkObject *object);
179 static void gtk_window_finalize (GObject *object);
180 static void gtk_window_show (GtkWidget *widget);
181 static void gtk_window_hide (GtkWidget *widget);
182 static void gtk_window_map (GtkWidget *widget);
183 static void gtk_window_unmap (GtkWidget *widget);
184 static void gtk_window_realize (GtkWidget *widget);
185 static void gtk_window_unrealize (GtkWidget *widget);
186 static void gtk_window_size_request (GtkWidget *widget,
187 GtkRequisition *requisition);
188 static void gtk_window_size_allocate (GtkWidget *widget,
189 GtkAllocation *allocation);
190 static gint gtk_window_event (GtkWidget *widget,
192 static gboolean gtk_window_frame_event (GtkWindow *window,
194 static gint gtk_window_configure_event (GtkWidget *widget,
195 GdkEventConfigure *event);
196 static gint gtk_window_key_press_event (GtkWidget *widget,
198 static gint gtk_window_key_release_event (GtkWidget *widget,
200 static gint gtk_window_enter_notify_event (GtkWidget *widget,
201 GdkEventCrossing *event);
202 static gint gtk_window_leave_notify_event (GtkWidget *widget,
203 GdkEventCrossing *event);
204 static gint gtk_window_focus_in_event (GtkWidget *widget,
205 GdkEventFocus *event);
206 static gint gtk_window_focus_out_event (GtkWidget *widget,
207 GdkEventFocus *event);
208 static gint gtk_window_client_event (GtkWidget *widget,
209 GdkEventClient *event);
210 static void gtk_window_check_resize (GtkContainer *container);
211 static gint gtk_window_focus (GtkWidget *widget,
212 GtkDirectionType direction);
213 static void gtk_window_real_set_focus (GtkWindow *window,
216 static void gtk_window_real_activate_default (GtkWindow *window);
217 static void gtk_window_real_activate_focus (GtkWindow *window);
218 static void gtk_window_move_focus (GtkWindow *window,
219 GtkDirectionType dir);
220 static void gtk_window_keys_changed (GtkWindow *window);
221 static void gtk_window_read_rcfiles (GtkWidget *widget,
222 GdkEventClient *event);
223 static void gtk_window_paint (GtkWidget *widget,
225 static gint gtk_window_expose (GtkWidget *widget,
226 GdkEventExpose *event);
227 static void gtk_window_unset_transient_for (GtkWindow *window);
228 static void gtk_window_transient_parent_realized (GtkWidget *parent,
230 static void gtk_window_transient_parent_unrealized (GtkWidget *parent,
233 static GdkScreen *gtk_window_check_screen (GtkWindow *window);
235 static GtkWindowGeometryInfo* gtk_window_get_geometry_info (GtkWindow *window,
238 static void gtk_window_move_resize (GtkWindow *window);
239 static gboolean gtk_window_compare_hints (GdkGeometry *geometry_a,
241 GdkGeometry *geometry_b,
243 static void gtk_window_constrain_size (GtkWindow *window,
244 GdkGeometry *geometry,
250 static void gtk_window_constrain_position (GtkWindow *window,
255 static void gtk_window_compute_hints (GtkWindow *window,
256 GdkGeometry *new_geometry,
258 static void gtk_window_compute_configure_request (GtkWindow *window,
259 GdkRectangle *request,
260 GdkGeometry *geometry,
263 static void gtk_window_set_default_size_internal (GtkWindow *window,
264 gboolean change_width,
266 gboolean change_height,
268 gboolean is_geometry);
270 static void update_themed_icon (GtkIconTheme *theme,
272 static GList *icon_list_from_theme (GtkWidget *widget,
274 static void gtk_window_realize_icon (GtkWindow *window);
275 static void gtk_window_unrealize_icon (GtkWindow *window);
277 static void gtk_window_notify_keys_changed (GtkWindow *window);
278 static GtkKeyHash *gtk_window_get_key_hash (GtkWindow *window);
279 static void gtk_window_free_key_hash (GtkWindow *window);
281 static GSList *toplevel_list = NULL;
282 static GtkBinClass *parent_class = NULL;
283 static guint window_signals[LAST_SIGNAL] = { 0 };
284 static GList *default_icon_list = NULL;
285 static gchar *default_icon_name = NULL;
286 static guint default_icon_serial = 0;
287 static gboolean disable_startup_notification = FALSE;
288 static gboolean sent_startup_notification = FALSE;
290 static void gtk_window_set_property (GObject *object,
294 static void gtk_window_get_property (GObject *object,
301 gtk_window_get_type (void)
303 static GType window_type = 0;
307 static const GTypeInfo window_info =
309 sizeof (GtkWindowClass),
310 NULL, /* base_init */
311 NULL, /* base_finalize */
312 (GClassInitFunc) gtk_window_class_init,
313 NULL, /* class_finalize */
314 NULL, /* class_data */
317 (GInstanceInitFunc) gtk_window_init,
320 window_type = g_type_register_static (GTK_TYPE_BIN, "GtkWindow",
328 add_tab_bindings (GtkBindingSet *binding_set,
329 GdkModifierType modifiers,
330 GtkDirectionType direction)
332 gtk_binding_entry_add_signal (binding_set, GDK_Tab, modifiers,
334 GTK_TYPE_DIRECTION_TYPE, direction);
335 gtk_binding_entry_add_signal (binding_set, GDK_KP_Tab, modifiers,
337 GTK_TYPE_DIRECTION_TYPE, direction);
341 add_arrow_bindings (GtkBindingSet *binding_set,
343 GtkDirectionType direction)
345 guint keypad_keysym = keysym - GDK_Left + GDK_KP_Left;
347 gtk_binding_entry_add_signal (binding_set, keysym, 0,
349 GTK_TYPE_DIRECTION_TYPE, direction);
350 gtk_binding_entry_add_signal (binding_set, keysym, GDK_CONTROL_MASK,
352 GTK_TYPE_DIRECTION_TYPE, direction);
353 gtk_binding_entry_add_signal (binding_set, keypad_keysym, 0,
355 GTK_TYPE_DIRECTION_TYPE, direction);
356 gtk_binding_entry_add_signal (binding_set, keypad_keysym, GDK_CONTROL_MASK,
358 GTK_TYPE_DIRECTION_TYPE, direction);
363 gtk_window_class_init (GtkWindowClass *klass)
365 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
366 GtkObjectClass *object_class;
367 GtkWidgetClass *widget_class;
368 GtkContainerClass *container_class;
369 GtkBindingSet *binding_set;
371 object_class = (GtkObjectClass*) klass;
372 widget_class = (GtkWidgetClass*) klass;
373 container_class = (GtkContainerClass*) klass;
375 parent_class = g_type_class_peek_parent (klass);
377 gobject_class->dispose = gtk_window_dispose;
378 gobject_class->finalize = gtk_window_finalize;
380 gobject_class->set_property = gtk_window_set_property;
381 gobject_class->get_property = gtk_window_get_property;
383 object_class->destroy = gtk_window_destroy;
385 widget_class->show = gtk_window_show;
386 widget_class->hide = gtk_window_hide;
387 widget_class->map = gtk_window_map;
388 widget_class->unmap = gtk_window_unmap;
389 widget_class->realize = gtk_window_realize;
390 widget_class->unrealize = gtk_window_unrealize;
391 widget_class->size_request = gtk_window_size_request;
392 widget_class->size_allocate = gtk_window_size_allocate;
393 widget_class->configure_event = gtk_window_configure_event;
394 widget_class->key_press_event = gtk_window_key_press_event;
395 widget_class->key_release_event = gtk_window_key_release_event;
396 widget_class->enter_notify_event = gtk_window_enter_notify_event;
397 widget_class->leave_notify_event = gtk_window_leave_notify_event;
398 widget_class->focus_in_event = gtk_window_focus_in_event;
399 widget_class->focus_out_event = gtk_window_focus_out_event;
400 widget_class->client_event = gtk_window_client_event;
401 widget_class->focus = gtk_window_focus;
403 widget_class->expose_event = gtk_window_expose;
405 container_class->check_resize = gtk_window_check_resize;
407 klass->set_focus = gtk_window_real_set_focus;
408 klass->frame_event = gtk_window_frame_event;
410 klass->activate_default = gtk_window_real_activate_default;
411 klass->activate_focus = gtk_window_real_activate_focus;
412 klass->move_focus = gtk_window_move_focus;
413 klass->keys_changed = gtk_window_keys_changed;
415 g_type_class_add_private (gobject_class, sizeof (GtkWindowPrivate));
418 g_object_class_install_property (gobject_class,
420 g_param_spec_enum ("type",
422 P_("The type of the window"),
423 GTK_TYPE_WINDOW_TYPE,
425 GTK_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
427 g_object_class_install_property (gobject_class,
429 g_param_spec_string ("title",
431 P_("The title of the window"),
433 GTK_PARAM_READWRITE));
435 g_object_class_install_property (gobject_class,
437 g_param_spec_string ("role",
439 P_("Unique identifier for the window to be used when restoring a session"),
441 GTK_PARAM_READWRITE));
443 g_object_class_install_property (gobject_class,
445 g_param_spec_boolean ("allow-shrink",
447 /* xgettext:no-c-format */
448 P_("If TRUE, the window has no mimimum size. Setting this to TRUE is 99% of the time a bad idea"),
450 GTK_PARAM_READWRITE));
452 g_object_class_install_property (gobject_class,
454 g_param_spec_boolean ("allow-grow",
456 P_("If TRUE, users can expand the window beyond its minimum size"),
458 GTK_PARAM_READWRITE));
460 g_object_class_install_property (gobject_class,
462 g_param_spec_boolean ("resizable",
464 P_("If TRUE, users can resize the window"),
466 GTK_PARAM_READWRITE));
468 g_object_class_install_property (gobject_class,
470 g_param_spec_boolean ("modal",
472 P_("If TRUE, the window is modal (other windows are not usable while this one is up)"),
474 GTK_PARAM_READWRITE));
476 g_object_class_install_property (gobject_class,
478 g_param_spec_enum ("window-position",
479 P_("Window Position"),
480 P_("The initial position of the window"),
481 GTK_TYPE_WINDOW_POSITION,
483 GTK_PARAM_READWRITE));
485 g_object_class_install_property (gobject_class,
487 g_param_spec_int ("default-width",
489 P_("The default width of the window, used when initially showing the window"),
493 GTK_PARAM_READWRITE));
495 g_object_class_install_property (gobject_class,
497 g_param_spec_int ("default-height",
498 P_("Default Height"),
499 P_("The default height of the window, used when initially showing the window"),
503 GTK_PARAM_READWRITE));
505 g_object_class_install_property (gobject_class,
506 PROP_DESTROY_WITH_PARENT,
507 g_param_spec_boolean ("destroy-with-parent",
508 P_("Destroy with Parent"),
509 P_("If this window should be destroyed when the parent is destroyed"),
511 GTK_PARAM_READWRITE));
513 g_object_class_install_property (gobject_class,
515 g_param_spec_object ("icon",
517 P_("Icon for this window"),
519 GTK_PARAM_READWRITE));
522 * GtkWindow:icon-name:
524 * The :icon-name property specifies the name of the themed icon to
525 * use as the window icon. See #GtkIconTheme for more details.
529 g_object_class_install_property (gobject_class,
531 g_param_spec_string ("icon-name",
533 P_("Name of the themed icon for this window"),
535 GTK_PARAM_READWRITE));
537 g_object_class_install_property (gobject_class,
539 g_param_spec_object ("screen",
541 P_("The screen where this window will be displayed"),
543 GTK_PARAM_READWRITE));
545 g_object_class_install_property (gobject_class,
547 g_param_spec_boolean ("is-active",
549 P_("Whether the toplevel is the current active window"),
551 GTK_PARAM_READABLE));
553 g_object_class_install_property (gobject_class,
554 PROP_HAS_TOPLEVEL_FOCUS,
555 g_param_spec_boolean ("has-toplevel-focus",
556 P_("Focus in Toplevel"),
557 P_("Whether the input focus is within this GtkWindow"),
559 GTK_PARAM_READABLE));
561 g_object_class_install_property (gobject_class,
563 g_param_spec_enum ("type-hint",
565 P_("Hint to help the desktop environment understand what kind of window this is and how to treat it."),
566 GDK_TYPE_WINDOW_TYPE_HINT,
567 GDK_WINDOW_TYPE_HINT_NORMAL,
568 GTK_PARAM_READWRITE));
570 g_object_class_install_property (gobject_class,
571 PROP_SKIP_TASKBAR_HINT,
572 g_param_spec_boolean ("skip-taskbar-hint",
574 P_("TRUE if the window should not be in the task bar."),
576 GTK_PARAM_READWRITE));
578 g_object_class_install_property (gobject_class,
579 PROP_SKIP_PAGER_HINT,
580 g_param_spec_boolean ("skip-pager-hint",
582 P_("TRUE if the window should not be in the pager."),
584 GTK_PARAM_READWRITE));
586 g_object_class_install_property (gobject_class,
588 g_param_spec_boolean ("urgency-hint",
590 P_("TRUE if the window should be brought to the user's attention."),
592 GTK_PARAM_READWRITE));
595 * GtkWindow:accept-focus-hint:
597 * Whether the window should receive the input focus.
601 g_object_class_install_property (gobject_class,
603 g_param_spec_boolean ("accept-focus",
605 P_("TRUE if the window should receive the input focus."),
607 GTK_PARAM_READWRITE));
610 * GtkWindow:focus-on-map-hint:
612 * Whether the window should receive the input focus when mapped.
616 g_object_class_install_property (gobject_class,
618 g_param_spec_boolean ("focus-on-map",
620 P_("TRUE if the window should receive the input focus when mapped."),
622 GTK_PARAM_READWRITE));
625 * GtkWindow:decorated:
627 * Whether the window should be decorated by the window manager.
631 g_object_class_install_property (gobject_class,
633 g_param_spec_boolean ("decorated",
635 P_("Whether the window should be decorated by the window manager"),
637 GTK_PARAM_READWRITE));
642 * The window gravity of the window. See gtk_window_move() and #GdkGravity for
643 * more details about window gravity.
647 g_object_class_install_property (gobject_class,
649 g_param_spec_enum ("gravity",
651 P_("The window gravity of the window"),
653 GDK_GRAVITY_NORTH_WEST,
654 GTK_PARAM_READWRITE));
656 window_signals[SET_FOCUS] =
657 g_signal_new ("set_focus",
658 G_TYPE_FROM_CLASS (gobject_class),
660 G_STRUCT_OFFSET (GtkWindowClass, set_focus),
662 _gtk_marshal_VOID__OBJECT,
666 window_signals[FRAME_EVENT] =
667 g_signal_new ("frame_event",
668 G_TYPE_FROM_CLASS (gobject_class),
670 G_STRUCT_OFFSET(GtkWindowClass, frame_event),
671 _gtk_boolean_handled_accumulator, NULL,
672 _gtk_marshal_BOOLEAN__BOXED,
676 window_signals[ACTIVATE_FOCUS] =
677 g_signal_new ("activate_focus",
678 G_TYPE_FROM_CLASS (gobject_class),
679 G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
680 G_STRUCT_OFFSET (GtkWindowClass, activate_focus),
682 _gtk_marshal_VOID__VOID,
686 window_signals[ACTIVATE_DEFAULT] =
687 g_signal_new ("activate_default",
688 G_TYPE_FROM_CLASS (gobject_class),
689 G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
690 G_STRUCT_OFFSET (GtkWindowClass, activate_default),
692 _gtk_marshal_VOID__VOID,
696 window_signals[MOVE_FOCUS] =
697 g_signal_new ("move_focus",
698 G_TYPE_FROM_CLASS (gobject_class),
699 G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
700 G_STRUCT_OFFSET (GtkWindowClass, move_focus),
702 _gtk_marshal_VOID__ENUM,
705 GTK_TYPE_DIRECTION_TYPE);
707 window_signals[KEYS_CHANGED] =
708 g_signal_new ("keys_changed",
709 G_TYPE_FROM_CLASS (gobject_class),
711 G_STRUCT_OFFSET (GtkWindowClass, keys_changed),
713 _gtk_marshal_VOID__VOID,
721 binding_set = gtk_binding_set_by_class (klass);
723 gtk_binding_entry_add_signal (binding_set, GDK_space, 0,
724 "activate_focus", 0);
725 gtk_binding_entry_add_signal (binding_set, GDK_KP_Space, 0,
726 "activate_focus", 0);
728 gtk_binding_entry_add_signal (binding_set, GDK_Return, 0,
729 "activate_default", 0);
731 gtk_binding_entry_add_signal (binding_set, GDK_KP_Enter, 0,
732 "activate_default", 0);
734 add_arrow_bindings (binding_set, GDK_Up, GTK_DIR_UP);
735 add_arrow_bindings (binding_set, GDK_Down, GTK_DIR_DOWN);
736 add_arrow_bindings (binding_set, GDK_Left, GTK_DIR_LEFT);
737 add_arrow_bindings (binding_set, GDK_Right, GTK_DIR_RIGHT);
739 add_tab_bindings (binding_set, 0, GTK_DIR_TAB_FORWARD);
740 add_tab_bindings (binding_set, GDK_CONTROL_MASK, GTK_DIR_TAB_FORWARD);
741 add_tab_bindings (binding_set, GDK_SHIFT_MASK, GTK_DIR_TAB_BACKWARD);
742 add_tab_bindings (binding_set, GDK_CONTROL_MASK | GDK_SHIFT_MASK, GTK_DIR_TAB_BACKWARD);
746 gtk_window_init (GtkWindow *window)
748 GdkColormap *colormap;
749 GtkWindowPrivate *priv = GTK_WINDOW_GET_PRIVATE (window);
751 GTK_WIDGET_UNSET_FLAGS (window, GTK_NO_WINDOW);
752 GTK_WIDGET_SET_FLAGS (window, GTK_TOPLEVEL);
754 GTK_PRIVATE_SET_FLAG (window, GTK_ANCHORED);
756 gtk_container_set_resize_mode (GTK_CONTAINER (window), GTK_RESIZE_QUEUE);
758 window->title = NULL;
759 window->wmclass_name = g_strdup (g_get_prgname ());
760 window->wmclass_class = g_strdup (gdk_get_program_class ());
761 window->wm_role = NULL;
762 window->geometry_info = NULL;
763 window->type = GTK_WINDOW_TOPLEVEL;
764 window->focus_widget = NULL;
765 window->default_widget = NULL;
766 window->configure_request_count = 0;
767 window->allow_shrink = FALSE;
768 window->allow_grow = TRUE;
769 window->configure_notify_received = FALSE;
770 window->position = GTK_WIN_POS_NONE;
771 window->need_default_size = TRUE;
772 window->need_default_position = TRUE;
773 window->modal = FALSE;
774 window->frame = NULL;
775 window->has_frame = FALSE;
776 window->frame_left = 0;
777 window->frame_right = 0;
778 window->frame_top = 0;
779 window->frame_bottom = 0;
780 window->type_hint = GDK_WINDOW_TYPE_HINT_NORMAL;
781 window->gravity = GDK_GRAVITY_NORTH_WEST;
782 window->decorated = TRUE;
783 window->mnemonic_modifier = GDK_MOD1_MASK;
784 window->screen = gdk_screen_get_default ();
786 priv->accept_focus = TRUE;
787 priv->focus_on_map = TRUE;
789 colormap = _gtk_widget_peek_colormap ();
791 gtk_widget_set_colormap (GTK_WIDGET (window), colormap);
793 g_object_ref (window);
794 gtk_object_sink (GTK_OBJECT (window));
795 window->has_user_ref_count = TRUE;
796 toplevel_list = g_slist_prepend (toplevel_list, window);
798 gtk_decorated_window_init (window);
800 g_signal_connect (window,
802 G_CALLBACK (gtk_window_event),
807 gtk_window_set_property (GObject *object,
814 window = GTK_WINDOW (object);
819 window->type = g_value_get_enum (value);
822 gtk_window_set_title (window, g_value_get_string (value));
825 gtk_window_set_role (window, g_value_get_string (value));
827 case PROP_ALLOW_SHRINK:
828 window->allow_shrink = g_value_get_boolean (value);
829 gtk_widget_queue_resize (GTK_WIDGET (window));
831 case PROP_ALLOW_GROW:
832 window->allow_grow = g_value_get_boolean (value);
833 gtk_widget_queue_resize (GTK_WIDGET (window));
834 g_object_notify (G_OBJECT (window), "resizable");
837 window->allow_grow = g_value_get_boolean (value);
838 gtk_widget_queue_resize (GTK_WIDGET (window));
839 g_object_notify (G_OBJECT (window), "allow-grow");
842 gtk_window_set_modal (window, g_value_get_boolean (value));
845 gtk_window_set_position (window, g_value_get_enum (value));
847 case PROP_DEFAULT_WIDTH:
848 gtk_window_set_default_size_internal (window,
849 TRUE, g_value_get_int (value),
852 case PROP_DEFAULT_HEIGHT:
853 gtk_window_set_default_size_internal (window,
855 TRUE, g_value_get_int (value), FALSE);
857 case PROP_DESTROY_WITH_PARENT:
858 gtk_window_set_destroy_with_parent (window, g_value_get_boolean (value));
861 gtk_window_set_icon (window,
862 g_value_get_object (value));
865 gtk_window_set_icon_name (window, g_value_get_string (value));
868 gtk_window_set_screen (window, g_value_get_object (value));
871 gtk_window_set_type_hint (window,
872 g_value_get_enum (value));
874 case PROP_SKIP_TASKBAR_HINT:
875 gtk_window_set_skip_taskbar_hint (window,
876 g_value_get_boolean (value));
878 case PROP_SKIP_PAGER_HINT:
879 gtk_window_set_skip_pager_hint (window,
880 g_value_get_boolean (value));
882 case PROP_URGENCY_HINT:
883 gtk_window_set_urgency_hint (window,
884 g_value_get_boolean (value));
886 case PROP_ACCEPT_FOCUS:
887 gtk_window_set_accept_focus (window,
888 g_value_get_boolean (value));
890 case PROP_FOCUS_ON_MAP:
891 gtk_window_set_focus_on_map (window,
892 g_value_get_boolean (value));
895 gtk_window_set_decorated (window, g_value_get_boolean (value));
898 gtk_window_set_gravity (window, g_value_get_enum (value));
906 gtk_window_get_property (GObject *object,
913 window = GTK_WINDOW (object);
917 GtkWindowGeometryInfo *info;
919 g_value_set_enum (value, window->type);
922 g_value_set_string (value, window->wm_role);
925 g_value_set_string (value, window->title);
927 case PROP_ALLOW_SHRINK:
928 g_value_set_boolean (value, window->allow_shrink);
930 case PROP_ALLOW_GROW:
931 g_value_set_boolean (value, window->allow_grow);
934 g_value_set_boolean (value, window->allow_grow);
937 g_value_set_boolean (value, window->modal);
940 g_value_set_enum (value, window->position);
942 case PROP_DEFAULT_WIDTH:
943 info = gtk_window_get_geometry_info (window, FALSE);
945 g_value_set_int (value, -1);
947 g_value_set_int (value, info->default_width);
949 case PROP_DEFAULT_HEIGHT:
950 info = gtk_window_get_geometry_info (window, FALSE);
952 g_value_set_int (value, -1);
954 g_value_set_int (value, info->default_height);
956 case PROP_DESTROY_WITH_PARENT:
957 g_value_set_boolean (value, window->destroy_with_parent);
960 g_value_set_object (value, gtk_window_get_icon (window));
963 g_value_set_string (value, gtk_window_get_icon_name (window));
966 g_value_set_object (value, window->screen);
969 g_value_set_boolean (value, window->is_active);
971 case PROP_HAS_TOPLEVEL_FOCUS:
972 g_value_set_boolean (value, window->has_toplevel_focus);
975 g_value_set_enum (value,
978 case PROP_SKIP_TASKBAR_HINT:
979 g_value_set_boolean (value,
980 gtk_window_get_skip_taskbar_hint (window));
982 case PROP_SKIP_PAGER_HINT:
983 g_value_set_boolean (value,
984 gtk_window_get_skip_pager_hint (window));
986 case PROP_URGENCY_HINT:
987 g_value_set_boolean (value,
988 gtk_window_get_urgency_hint (window));
990 case PROP_ACCEPT_FOCUS:
991 g_value_set_boolean (value,
992 gtk_window_get_accept_focus (window));
994 case PROP_FOCUS_ON_MAP:
995 g_value_set_boolean (value,
996 gtk_window_get_focus_on_map (window));
999 g_value_set_boolean (value, gtk_window_get_decorated (window));
1002 g_value_set_enum (value, gtk_window_get_gravity (window));
1005 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1012 * @type: type of window
1014 * Creates a new #GtkWindow, which is a toplevel window that can
1015 * contain other widgets. Nearly always, the type of the window should
1016 * be #GTK_WINDOW_TOPLEVEL. If you're implementing something like a
1017 * popup menu from scratch (which is a bad idea, just use #GtkMenu),
1018 * you might use #GTK_WINDOW_POPUP. #GTK_WINDOW_POPUP is not for
1019 * dialogs, though in some other toolkits dialogs are called "popups".
1020 * In GTK+, #GTK_WINDOW_POPUP means a pop-up menu or pop-up tooltip.
1021 * On X11, popup windows are not controlled by the <link
1022 * linkend="gtk-X11-arch">window manager</link>.
1024 * If you simply want an undecorated window (no window borders), use
1025 * gtk_window_set_decorated(), don't use #GTK_WINDOW_POPUP.
1027 * Return value: a new #GtkWindow.
1030 gtk_window_new (GtkWindowType type)
1034 g_return_val_if_fail (type >= GTK_WINDOW_TOPLEVEL && type <= GTK_WINDOW_POPUP, NULL);
1036 window = g_object_new (GTK_TYPE_WINDOW, NULL);
1038 window->type = type;
1040 return GTK_WIDGET (window);
1044 * gtk_window_set_title:
1045 * @window: a #GtkWindow
1046 * @title: title of the window
1048 * Sets the title of the #GtkWindow. The title of a window will be
1049 * displayed in its title bar; on the X Window System, the title bar
1050 * is rendered by the <link linkend="gtk-X11-arch">window
1051 * manager</link>, so exactly how the title appears to users may vary
1052 * according to a user's exact configuration. The title should help a
1053 * user distinguish this window from other windows they may have
1054 * open. A good title might include the application name and current
1055 * document filename, for example.
1059 gtk_window_set_title (GtkWindow *window,
1064 g_return_if_fail (GTK_IS_WINDOW (window));
1066 new_title = g_strdup (title);
1067 g_free (window->title);
1068 window->title = new_title;
1070 if (GTK_WIDGET_REALIZED (window))
1072 gdk_window_set_title (GTK_WIDGET (window)->window, window->title);
1074 gtk_decorated_window_set_title (window, title);
1077 g_object_notify (G_OBJECT (window), "title");
1081 * gtk_window_get_title:
1082 * @window: a #GtkWindow
1084 * Retrieves the title of the window. See gtk_window_set_title().
1086 * Return value: the title of the window, or %NULL if none has
1087 * been set explicitely. The returned string is owned by the widget
1088 * and must not be modified or freed.
1090 G_CONST_RETURN gchar *
1091 gtk_window_get_title (GtkWindow *window)
1093 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
1095 return window->title;
1099 * gtk_window_set_wmclass:
1100 * @window: a #GtkWindow
1101 * @wmclass_name: window name hint
1102 * @wmclass_class: window class hint
1104 * Don't use this function. It sets the X Window System "class" and
1105 * "name" hints for a window. According to the ICCCM, you should
1106 * always set these to the same value for all windows in an
1107 * application, and GTK+ sets them to that value by default, so calling
1108 * this function is sort of pointless. However, you may want to call
1109 * gtk_window_set_role() on each window in your application, for the
1110 * benefit of the session manager. Setting the role allows the window
1111 * manager to restore window positions when loading a saved session.
1115 gtk_window_set_wmclass (GtkWindow *window,
1116 const gchar *wmclass_name,
1117 const gchar *wmclass_class)
1119 g_return_if_fail (GTK_IS_WINDOW (window));
1121 g_free (window->wmclass_name);
1122 window->wmclass_name = g_strdup (wmclass_name);
1124 g_free (window->wmclass_class);
1125 window->wmclass_class = g_strdup (wmclass_class);
1127 if (GTK_WIDGET_REALIZED (window))
1128 g_warning ("gtk_window_set_wmclass: shouldn't set wmclass after window is realized!\n");
1132 * gtk_window_set_role:
1133 * @window: a #GtkWindow
1134 * @role: unique identifier for the window to be used when restoring a session
1136 * This function is only useful on X11, not with other GTK+ targets.
1138 * In combination with the window title, the window role allows a
1139 * <link linkend="gtk-X11-arch">window manager</link> to identify "the
1140 * same" window when an application is restarted. So for example you
1141 * might set the "toolbox" role on your app's toolbox window, so that
1142 * when the user restarts their session, the window manager can put
1143 * the toolbox back in the same place.
1145 * If a window already has a unique title, you don't need to set the
1146 * role, since the WM can use the title to identify the window when
1147 * restoring the session.
1151 gtk_window_set_role (GtkWindow *window,
1156 g_return_if_fail (GTK_IS_WINDOW (window));
1158 new_role = g_strdup (role);
1159 g_free (window->wm_role);
1160 window->wm_role = new_role;
1162 if (GTK_WIDGET_REALIZED (window))
1163 gdk_window_set_role (GTK_WIDGET (window)->window, window->wm_role);
1165 g_object_notify (G_OBJECT (window), "role");
1169 * gtk_window_get_role:
1170 * @window: a #GtkWindow
1172 * Returns the role of the window. See gtk_window_set_role() for
1173 * further explanation.
1175 * Return value: the role of the window if set, or %NULL. The
1176 * returned is owned by the widget and must not be modified
1179 G_CONST_RETURN gchar *
1180 gtk_window_get_role (GtkWindow *window)
1182 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
1184 return window->wm_role;
1188 * gtk_window_set_focus:
1189 * @window: a #GtkWindow
1190 * @focus: widget to be the new focus widget, or %NULL to unset
1191 * any focus widget for the toplevel window.
1193 * If @focus is not the current focus widget, and is focusable, sets
1194 * it as the focus widget for the window. If @focus is %NULL, unsets
1195 * the focus widget for this window. To set the focus to a particular
1196 * widget in the toplevel, it is usually more convenient to use
1197 * gtk_widget_grab_focus() instead of this function.
1200 gtk_window_set_focus (GtkWindow *window,
1203 g_return_if_fail (GTK_IS_WINDOW (window));
1206 g_return_if_fail (GTK_IS_WIDGET (focus));
1207 g_return_if_fail (GTK_WIDGET_CAN_FOCUS (focus));
1211 gtk_widget_grab_focus (focus);
1214 /* Clear the existing focus chain, so that when we focus into
1215 * the window again, we start at the beginnning.
1217 GtkWidget *widget = window->focus_widget;
1220 while (widget->parent)
1222 widget = widget->parent;
1223 gtk_container_set_focus_child (GTK_CONTAINER (widget), NULL);
1227 _gtk_window_internal_set_focus (window, NULL);
1232 _gtk_window_internal_set_focus (GtkWindow *window,
1235 g_return_if_fail (GTK_IS_WINDOW (window));
1237 if ((window->focus_widget != focus) ||
1238 (focus && !GTK_WIDGET_HAS_FOCUS (focus)))
1239 g_signal_emit (window, window_signals[SET_FOCUS], 0, focus);
1243 * gtk_window_set_default:
1244 * @window: a #GtkWindow
1245 * @default_widget: widget to be the default, or %NULL to unset the
1246 * default widget for the toplevel.
1248 * The default widget is the widget that's activated when the user
1249 * presses Enter in a dialog (for example). This function sets or
1250 * unsets the default widget for a #GtkWindow about. When setting
1251 * (rather than unsetting) the default widget it's generally easier to
1252 * call gtk_widget_grab_focus() on the widget. Before making a widget
1253 * the default widget, you must set the #GTK_CAN_DEFAULT flag on the
1254 * widget you'd like to make the default using GTK_WIDGET_SET_FLAGS().
1257 gtk_window_set_default (GtkWindow *window,
1258 GtkWidget *default_widget)
1260 g_return_if_fail (GTK_IS_WINDOW (window));
1263 g_return_if_fail (GTK_WIDGET_CAN_DEFAULT (default_widget));
1265 if (window->default_widget != default_widget)
1267 GtkWidget *old_default_widget = NULL;
1270 g_object_ref (default_widget);
1272 if (window->default_widget)
1274 old_default_widget = window->default_widget;
1276 if (window->focus_widget != window->default_widget ||
1277 !GTK_WIDGET_RECEIVES_DEFAULT (window->default_widget))
1278 GTK_WIDGET_UNSET_FLAGS (window->default_widget, GTK_HAS_DEFAULT);
1279 gtk_widget_queue_draw (window->default_widget);
1282 window->default_widget = default_widget;
1284 if (window->default_widget)
1286 if (window->focus_widget == NULL ||
1287 !GTK_WIDGET_RECEIVES_DEFAULT (window->focus_widget))
1288 GTK_WIDGET_SET_FLAGS (window->default_widget, GTK_HAS_DEFAULT);
1289 gtk_widget_queue_draw (window->default_widget);
1292 if (old_default_widget)
1293 g_object_notify (G_OBJECT (old_default_widget), "has-default");
1297 g_object_notify (G_OBJECT (default_widget), "has-default");
1298 g_object_unref (default_widget);
1304 gtk_window_set_policy (GtkWindow *window,
1305 gboolean allow_shrink,
1306 gboolean allow_grow,
1307 gboolean auto_shrink)
1309 g_return_if_fail (GTK_IS_WINDOW (window));
1311 window->allow_shrink = (allow_shrink != FALSE);
1312 window->allow_grow = (allow_grow != FALSE);
1314 g_object_freeze_notify (G_OBJECT (window));
1315 g_object_notify (G_OBJECT (window), "allow-shrink");
1316 g_object_notify (G_OBJECT (window), "allow-grow");
1317 g_object_notify (G_OBJECT (window), "resizable");
1318 g_object_thaw_notify (G_OBJECT (window));
1320 gtk_widget_queue_resize (GTK_WIDGET (window));
1324 handle_keys_changed (gpointer data)
1328 GDK_THREADS_ENTER ();
1329 window = GTK_WINDOW (data);
1331 if (window->keys_changed_handler)
1333 g_source_remove (window->keys_changed_handler);
1334 window->keys_changed_handler = 0;
1337 g_signal_emit (window, window_signals[KEYS_CHANGED], 0);
1338 GDK_THREADS_LEAVE ();
1344 gtk_window_notify_keys_changed (GtkWindow *window)
1346 if (!window->keys_changed_handler)
1347 window->keys_changed_handler = g_idle_add (handle_keys_changed, window);
1351 * gtk_window_add_accel_group:
1352 * @window: window to attach accelerator group to
1353 * @accel_group: a #GtkAccelGroup
1355 * Associate @accel_group with @window, such that calling
1356 * gtk_accel_groups_activate() on @window will activate accelerators
1360 gtk_window_add_accel_group (GtkWindow *window,
1361 GtkAccelGroup *accel_group)
1363 g_return_if_fail (GTK_IS_WINDOW (window));
1364 g_return_if_fail (GTK_IS_ACCEL_GROUP (accel_group));
1366 _gtk_accel_group_attach (accel_group, G_OBJECT (window));
1367 g_signal_connect_object (accel_group, "accel_changed",
1368 G_CALLBACK (gtk_window_notify_keys_changed),
1369 window, G_CONNECT_SWAPPED);
1373 * gtk_window_remove_accel_group:
1374 * @window: a #GtkWindow
1375 * @accel_group: a #GtkAccelGroup
1377 * Reverses the effects of gtk_window_add_accel_group().
1380 gtk_window_remove_accel_group (GtkWindow *window,
1381 GtkAccelGroup *accel_group)
1383 g_return_if_fail (GTK_IS_WINDOW (window));
1384 g_return_if_fail (GTK_IS_ACCEL_GROUP (accel_group));
1386 g_signal_handlers_disconnect_by_func (accel_group,
1387 gtk_window_notify_keys_changed,
1389 _gtk_accel_group_detach (accel_group, G_OBJECT (window));
1392 static GtkMnemonicHash *
1393 gtk_window_get_mnemonic_hash (GtkWindow *window,
1396 GtkWindowPrivate *private = GTK_WINDOW_GET_PRIVATE (window);
1397 if (!private->mnemonic_hash && create)
1398 private->mnemonic_hash = _gtk_mnemonic_hash_new ();
1400 return private->mnemonic_hash;
1404 * gtk_window_add_mnemonic:
1405 * @window: a #GtkWindow
1406 * @keyval: the mnemonic
1407 * @target: the widget that gets activated by the mnemonic
1409 * Adds a mnemonic to this window.
1412 gtk_window_add_mnemonic (GtkWindow *window,
1416 g_return_if_fail (GTK_IS_WINDOW (window));
1417 g_return_if_fail (GTK_IS_WIDGET (target));
1419 _gtk_mnemonic_hash_add (gtk_window_get_mnemonic_hash (window, TRUE),
1421 gtk_window_notify_keys_changed (window);
1425 * gtk_window_remove_mnemonic:
1426 * @window: a #GtkWindow
1427 * @keyval: the mnemonic
1428 * @target: the widget that gets activated by the mnemonic
1430 * Removes a mnemonic from this window.
1433 gtk_window_remove_mnemonic (GtkWindow *window,
1437 g_return_if_fail (GTK_IS_WINDOW (window));
1438 g_return_if_fail (GTK_IS_WIDGET (target));
1440 _gtk_mnemonic_hash_remove (gtk_window_get_mnemonic_hash (window, TRUE),
1442 gtk_window_notify_keys_changed (window);
1446 * gtk_window_mnemonic_activate:
1447 * @window: a #GtkWindow
1448 * @keyval: the mnemonic
1449 * @modifier: the modifiers
1450 * @returns: %TRUE if the activation is done.
1452 * Activates the targets associated with the mnemonic.
1455 gtk_window_mnemonic_activate (GtkWindow *window,
1457 GdkModifierType modifier)
1459 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
1461 if (window->mnemonic_modifier == (modifier & gtk_accelerator_get_default_mod_mask ()))
1463 GtkMnemonicHash *mnemonic_hash = gtk_window_get_mnemonic_hash (window, FALSE);
1465 return _gtk_mnemonic_hash_activate (mnemonic_hash, keyval);
1472 * gtk_window_set_mnemonic_modifier:
1473 * @window: a #GtkWindow
1474 * @modifier: the modifier mask used to activate
1475 * mnemonics on this window.
1477 * Sets the mnemonic modifier for this window.
1480 gtk_window_set_mnemonic_modifier (GtkWindow *window,
1481 GdkModifierType modifier)
1483 g_return_if_fail (GTK_IS_WINDOW (window));
1484 g_return_if_fail ((modifier & ~GDK_MODIFIER_MASK) == 0);
1486 window->mnemonic_modifier = modifier;
1487 gtk_window_notify_keys_changed (window);
1491 * gtk_window_get_mnemonic_modifier:
1492 * @window: a #GtkWindow
1494 * Returns the mnemonic modifier for this window. See
1495 * gtk_window_set_mnemonic_modifier().
1497 * Return value: the modifier mask used to activate
1498 * mnemonics on this window.
1501 gtk_window_get_mnemonic_modifier (GtkWindow *window)
1503 g_return_val_if_fail (GTK_IS_WINDOW (window), 0);
1505 return window->mnemonic_modifier;
1509 * gtk_window_set_position:
1510 * @window: a #GtkWindow.
1511 * @position: a position constraint.
1513 * Sets a position constraint for this window. If the old or new
1514 * constraint is %GTK_WIN_POS_CENTER_ALWAYS, this will also cause
1515 * the window to be repositioned to satisfy the new constraint.
1518 gtk_window_set_position (GtkWindow *window,
1519 GtkWindowPosition position)
1521 g_return_if_fail (GTK_IS_WINDOW (window));
1523 if (position == GTK_WIN_POS_CENTER_ALWAYS ||
1524 window->position == GTK_WIN_POS_CENTER_ALWAYS)
1526 GtkWindowGeometryInfo *info;
1528 info = gtk_window_get_geometry_info (window, TRUE);
1530 /* this flag causes us to re-request the CENTER_ALWAYS
1531 * constraint in gtk_window_move_resize(), see
1532 * comment in that function.
1534 info->position_constraints_changed = TRUE;
1536 gtk_widget_queue_resize (GTK_WIDGET (window));
1539 window->position = position;
1541 g_object_notify (G_OBJECT (window), "window-position");
1545 * gtk_window_activate_focus:
1546 * @window: a #GtkWindow
1548 * Activates the current focused widget within the window.
1550 * Return value: %TRUE if a widget got activated.
1553 gtk_window_activate_focus (GtkWindow *window)
1555 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
1557 if (window->focus_widget && GTK_WIDGET_IS_SENSITIVE (window->focus_widget))
1558 return gtk_widget_activate (window->focus_widget);
1564 * gtk_window_get_focus:
1565 * @window: a #GtkWindow
1567 * Retrieves the current focused widget within the window.
1568 * Note that this is the widget that would have the focus
1569 * if the toplevel window focused; if the toplevel window
1570 * is not focused then <literal>GTK_WIDGET_HAS_FOCUS (widget)</literal> will
1571 * not be %TRUE for the widget.
1573 * Return value: the currently focused widget, or %NULL if there is none.
1576 gtk_window_get_focus (GtkWindow *window)
1578 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
1580 return window->focus_widget;
1584 * gtk_window_activate_default:
1585 * @window: a #GtkWindow
1587 * Activates the default widget for the window, unless the current
1588 * focused widget has been configured to receive the default action
1589 * (see #GTK_RECEIVES_DEFAULT in #GtkWidgetFlags), in which case the
1590 * focused widget is activated.
1592 * Return value: %TRUE if a widget got activated.
1595 gtk_window_activate_default (GtkWindow *window)
1597 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
1599 if (window->default_widget && GTK_WIDGET_IS_SENSITIVE (window->default_widget) &&
1600 (!window->focus_widget || !GTK_WIDGET_RECEIVES_DEFAULT (window->focus_widget)))
1601 return gtk_widget_activate (window->default_widget);
1602 else if (window->focus_widget && GTK_WIDGET_IS_SENSITIVE (window->focus_widget))
1603 return gtk_widget_activate (window->focus_widget);
1609 * gtk_window_set_modal:
1610 * @window: a #GtkWindow
1611 * @modal: whether the window is modal
1613 * Sets a window modal or non-modal. Modal windows prevent interaction
1614 * with other windows in the same application. To keep modal dialogs
1615 * on top of main application windows, use
1616 * gtk_window_set_transient_for() to make the dialog transient for the
1617 * parent; most <link linkend="gtk-X11-arch">window managers</link>
1618 * will then disallow lowering the dialog below the parent.
1623 gtk_window_set_modal (GtkWindow *window,
1626 g_return_if_fail (GTK_IS_WINDOW (window));
1628 modal = modal != FALSE;
1629 if (window->modal == modal)
1632 window->modal = modal;
1634 /* adjust desired modality state */
1635 if (GTK_WIDGET_REALIZED (window))
1637 GtkWidget *widget = GTK_WIDGET (window);
1640 gdk_window_set_modal_hint (widget->window, TRUE);
1642 gdk_window_set_modal_hint (widget->window, FALSE);
1645 if (GTK_WIDGET_VISIBLE (window))
1648 gtk_grab_add (GTK_WIDGET (window));
1650 gtk_grab_remove (GTK_WIDGET (window));
1653 g_object_notify (G_OBJECT (window), "modal");
1657 * gtk_window_get_modal:
1658 * @window: a #GtkWindow
1660 * Returns whether the window is modal. See gtk_window_set_modal().
1662 * Return value: %TRUE if the window is set to be modal and
1663 * establishes a grab when shown
1666 gtk_window_get_modal (GtkWindow *window)
1668 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
1670 return window->modal;
1674 * gtk_window_list_toplevels:
1676 * Returns a list of all existing toplevel windows. The widgets
1677 * in the list are not individually referenced. If you want
1678 * to iterate through the list and perform actions involving
1679 * callbacks that might destroy the widgets, you <emphasis>must</emphasis> call
1680 * <literal>g_list_foreach (result, (GFunc)g_object_ref, NULL)</literal> first, and
1681 * then unref all the widgets afterwards.
1683 * Return value: list of toplevel widgets
1686 gtk_window_list_toplevels (void)
1691 for (slist = toplevel_list; slist; slist = slist->next)
1692 list = g_list_prepend (list, slist->data);
1698 gtk_window_add_embedded_xid (GtkWindow *window, guint xid)
1700 GList *embedded_windows;
1702 g_return_if_fail (GTK_IS_WINDOW (window));
1704 embedded_windows = g_object_get_data (G_OBJECT (window), "gtk-embedded");
1705 if (embedded_windows)
1706 g_object_steal_qdata (G_OBJECT (window),
1707 g_quark_from_static_string ("gtk-embedded"));
1708 embedded_windows = g_list_prepend (embedded_windows,
1709 GUINT_TO_POINTER (xid));
1711 g_object_set_data_full (G_OBJECT (window), "gtk-embedded",
1714 (GDestroyNotify) g_list_free : NULL);
1718 gtk_window_remove_embedded_xid (GtkWindow *window, guint xid)
1720 GList *embedded_windows;
1723 g_return_if_fail (GTK_IS_WINDOW (window));
1725 embedded_windows = g_object_get_data (G_OBJECT (window), "gtk-embedded");
1726 if (embedded_windows)
1727 g_object_steal_qdata (G_OBJECT (window),
1728 g_quark_from_static_string ("gtk-embedded"));
1730 node = g_list_find (embedded_windows, GUINT_TO_POINTER (xid));
1733 embedded_windows = g_list_remove_link (embedded_windows, node);
1734 g_list_free_1 (node);
1737 g_object_set_data_full (G_OBJECT (window), "gtk-embedded",
1740 (GDestroyNotify) g_list_free : NULL);
1744 _gtk_window_reposition (GtkWindow *window,
1748 g_return_if_fail (GTK_IS_WINDOW (window));
1750 gtk_window_move (window, x, y);
1754 gtk_window_dispose (GObject *object)
1756 GtkWindow *window = GTK_WINDOW (object);
1758 gtk_window_set_focus (window, NULL);
1759 gtk_window_set_default (window, NULL);
1761 G_OBJECT_CLASS (parent_class)->dispose (object);
1765 parent_destroyed_callback (GtkWindow *parent, GtkWindow *child)
1767 gtk_widget_destroy (GTK_WIDGET (child));
1771 connect_parent_destroyed (GtkWindow *window)
1773 if (window->transient_parent)
1775 g_signal_connect (window->transient_parent,
1777 G_CALLBACK (parent_destroyed_callback),
1783 disconnect_parent_destroyed (GtkWindow *window)
1785 if (window->transient_parent)
1787 g_signal_handlers_disconnect_by_func (window->transient_parent,
1788 parent_destroyed_callback,
1794 gtk_window_transient_parent_realized (GtkWidget *parent,
1797 if (GTK_WIDGET_REALIZED (window))
1798 gdk_window_set_transient_for (window->window, parent->window);
1802 gtk_window_transient_parent_unrealized (GtkWidget *parent,
1805 if (GTK_WIDGET_REALIZED (window))
1806 gdk_property_delete (window->window,
1807 gdk_atom_intern ("WM_TRANSIENT_FOR", FALSE));
1811 gtk_window_transient_parent_screen_changed (GtkWindow *parent,
1815 gtk_window_set_screen (window, parent->screen);
1819 gtk_window_unset_transient_for (GtkWindow *window)
1821 if (window->transient_parent)
1823 g_signal_handlers_disconnect_by_func (window->transient_parent,
1824 gtk_window_transient_parent_realized,
1826 g_signal_handlers_disconnect_by_func (window->transient_parent,
1827 gtk_window_transient_parent_unrealized,
1829 g_signal_handlers_disconnect_by_func (window->transient_parent,
1830 gtk_window_transient_parent_screen_changed,
1832 g_signal_handlers_disconnect_by_func (window->transient_parent,
1833 gtk_widget_destroyed,
1834 &window->transient_parent);
1836 if (window->destroy_with_parent)
1837 disconnect_parent_destroyed (window);
1839 window->transient_parent = NULL;
1844 * gtk_window_set_transient_for:
1845 * @window: a #GtkWindow
1846 * @parent: parent window
1848 * Dialog windows should be set transient for the main application
1849 * window they were spawned from. This allows <link
1850 * linkend="gtk-X11-arch">window managers</link> to e.g. keep the
1851 * dialog on top of the main window, or center the dialog over the
1852 * main window. gtk_dialog_new_with_buttons() and other convenience
1853 * functions in GTK+ will sometimes call
1854 * gtk_window_set_transient_for() on your behalf.
1856 * On Windows, this function will and put the child window
1857 * on top of the parent, much as the window manager would have
1862 gtk_window_set_transient_for (GtkWindow *window,
1865 g_return_if_fail (GTK_IS_WINDOW (window));
1866 g_return_if_fail (parent == NULL || GTK_IS_WINDOW (parent));
1867 g_return_if_fail (window != parent);
1870 if (window->transient_parent)
1872 if (GTK_WIDGET_REALIZED (window) &&
1873 GTK_WIDGET_REALIZED (window->transient_parent) &&
1874 (!parent || !GTK_WIDGET_REALIZED (parent)))
1875 gtk_window_transient_parent_unrealized (GTK_WIDGET (window->transient_parent),
1876 GTK_WIDGET (window));
1878 gtk_window_unset_transient_for (window);
1881 window->transient_parent = parent;
1885 g_signal_connect (parent, "destroy",
1886 G_CALLBACK (gtk_widget_destroyed),
1887 &window->transient_parent);
1888 g_signal_connect (parent, "realize",
1889 G_CALLBACK (gtk_window_transient_parent_realized),
1891 g_signal_connect (parent, "unrealize",
1892 G_CALLBACK (gtk_window_transient_parent_unrealized),
1894 g_signal_connect (parent, "notify::screen",
1895 G_CALLBACK (gtk_window_transient_parent_screen_changed),
1898 gtk_window_set_screen (window, parent->screen);
1900 if (window->destroy_with_parent)
1901 connect_parent_destroyed (window);
1903 if (GTK_WIDGET_REALIZED (window) &&
1904 GTK_WIDGET_REALIZED (parent))
1905 gtk_window_transient_parent_realized (GTK_WIDGET (parent),
1906 GTK_WIDGET (window));
1911 * gtk_window_get_transient_for:
1912 * @window: a #GtkWindow
1914 * Fetches the transient parent for this window. See
1915 * gtk_window_set_transient_for().
1917 * Return value: the transient parent for this window, or %NULL
1918 * if no transient parent has been set.
1921 gtk_window_get_transient_for (GtkWindow *window)
1923 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
1925 return window->transient_parent;
1929 * gtk_window_set_type_hint:
1930 * @window: a #GtkWindow
1931 * @hint: the window type
1933 * By setting the type hint for the window, you allow the window
1934 * manager to decorate and handle the window in a way which is
1935 * suitable to the function of the window in your application.
1937 * This function should be called before the window becomes visible.
1939 * gtk_dialog_new_with_buttons() and other convenience functions in GTK+
1940 * will sometimes call gtk_window_set_type_hint() on your behalf.
1944 gtk_window_set_type_hint (GtkWindow *window,
1945 GdkWindowTypeHint hint)
1947 g_return_if_fail (GTK_IS_WINDOW (window));
1948 g_return_if_fail (!GTK_WIDGET_VISIBLE (window));
1949 window->type_hint = hint;
1953 * gtk_window_get_type_hint:
1954 * @window: a #GtkWindow
1956 * Gets the type hint for this window. See gtk_window_set_type_hint().
1958 * Return value: the type hint for @window.
1961 gtk_window_get_type_hint (GtkWindow *window)
1963 g_return_val_if_fail (GTK_IS_WINDOW (window), GDK_WINDOW_TYPE_HINT_NORMAL);
1965 return window->type_hint;
1969 * gtk_window_set_skip_taskbar_hint:
1970 * @window: a #GtkWindow
1971 * @setting: %TRUE to keep this window from appearing in the task bar
1973 * Windows may set a hint asking the desktop environment not to display
1974 * the window in the task bar. This function sets this hint.
1979 gtk_window_set_skip_taskbar_hint (GtkWindow *window,
1982 GtkWindowPrivate *priv;
1984 g_return_if_fail (GTK_IS_WINDOW (window));
1986 priv = GTK_WINDOW_GET_PRIVATE (window);
1988 setting = setting != FALSE;
1990 if (priv->skips_taskbar != setting)
1992 priv->skips_taskbar = setting;
1993 if (GTK_WIDGET_REALIZED (window))
1994 gdk_window_set_skip_taskbar_hint (GTK_WIDGET (window)->window,
1995 priv->skips_taskbar);
1996 g_object_notify (G_OBJECT (window), "skip-taskbar-hint");
2001 * gtk_window_get_skip_taskbar_hint:
2002 * @window: a #GtkWindow
2004 * Gets the value set by gtk_window_set_skip_taskbar_hint()
2006 * Return value: %TRUE if window shouldn't be in taskbar
2011 gtk_window_get_skip_taskbar_hint (GtkWindow *window)
2013 GtkWindowPrivate *priv;
2015 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
2017 priv = GTK_WINDOW_GET_PRIVATE (window);
2019 return priv->skips_taskbar;
2023 * gtk_window_set_skip_pager_hint:
2024 * @window: a #GtkWindow
2025 * @setting: %TRUE to keep this window from appearing in the pager
2027 * Windows may set a hint asking the desktop environment not to display
2028 * the window in the pager. This function sets this hint.
2029 * (A "pager" is any desktop navigation tool such as a workspace
2030 * switcher that displays a thumbnail representation of the windows
2036 gtk_window_set_skip_pager_hint (GtkWindow *window,
2039 GtkWindowPrivate *priv;
2041 g_return_if_fail (GTK_IS_WINDOW (window));
2043 priv = GTK_WINDOW_GET_PRIVATE (window);
2045 setting = setting != FALSE;
2047 if (priv->skips_pager != setting)
2049 priv->skips_pager = setting;
2050 if (GTK_WIDGET_REALIZED (window))
2051 gdk_window_set_skip_pager_hint (GTK_WIDGET (window)->window,
2053 g_object_notify (G_OBJECT (window), "skip-pager-hint");
2058 * gtk_window_get_skip_pager_hint:
2059 * @window: a #GtkWindow
2061 * Gets the value set by gtk_window_set_skip_pager_hint().
2063 * Return value: %TRUE if window shouldn't be in pager
2068 gtk_window_get_skip_pager_hint (GtkWindow *window)
2070 GtkWindowPrivate *priv;
2072 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
2074 priv = GTK_WINDOW_GET_PRIVATE (window);
2076 return priv->skips_pager;
2080 * gtk_window_set_urgency_hint:
2081 * @window: a #GtkWindow
2082 * @setting: %TRUE to mark this window as urgent
2084 * Windows may set a hint asking the desktop environment to draw
2085 * the users attention to the window. This function sets this hint.
2090 gtk_window_set_urgency_hint (GtkWindow *window,
2093 GtkWindowPrivate *priv;
2095 g_return_if_fail (GTK_IS_WINDOW (window));
2097 priv = GTK_WINDOW_GET_PRIVATE (window);
2099 setting = setting != FALSE;
2101 if (priv->urgent != setting)
2103 priv->urgent = setting;
2104 if (GTK_WIDGET_REALIZED (window))
2105 gdk_window_set_urgency_hint (GTK_WIDGET (window)->window,
2107 g_object_notify (G_OBJECT (window), "urgency-hint");
2112 * gtk_window_get_urgency_hint:
2113 * @window: a #GtkWindow
2115 * Gets the value set by gtk_window_set_urgency_hint()
2117 * Return value: %TRUE if window is urgent
2122 gtk_window_get_urgency_hint (GtkWindow *window)
2124 GtkWindowPrivate *priv;
2126 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
2128 priv = GTK_WINDOW_GET_PRIVATE (window);
2130 return priv->urgent;
2134 * gtk_window_set_accept_focus:
2135 * @window: a #GtkWindow
2136 * @setting: %TRUE to let this window receive input focus
2138 * Windows may set a hint asking the desktop environment not to receive
2139 * the input focus. This function sets this hint.
2144 gtk_window_set_accept_focus (GtkWindow *window,
2147 GtkWindowPrivate *priv;
2149 g_return_if_fail (GTK_IS_WINDOW (window));
2151 priv = GTK_WINDOW_GET_PRIVATE (window);
2153 setting = setting != FALSE;
2155 if (priv->accept_focus != setting)
2157 priv->accept_focus = setting;
2158 if (GTK_WIDGET_REALIZED (window))
2159 gdk_window_set_accept_focus (GTK_WIDGET (window)->window,
2160 priv->accept_focus);
2161 g_object_notify (G_OBJECT (window), "accept-focus");
2166 * gtk_window_get_accept_focus:
2167 * @window: a #GtkWindow
2169 * Gets the value set by gtk_window_set_accept_focus().
2171 * Return value: %TRUE if window should receive the input focus
2176 gtk_window_get_accept_focus (GtkWindow *window)
2178 GtkWindowPrivate *priv;
2180 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
2182 priv = GTK_WINDOW_GET_PRIVATE (window);
2184 return priv->accept_focus;
2188 * gtk_window_set_focus_on_map:
2189 * @window: a #GtkWindow
2190 * @setting: %TRUE to let this window receive input focus on map
2192 * Windows may set a hint asking the desktop environment not to receive
2193 * the input focus when the window is mapped. This function sets this
2199 gtk_window_set_focus_on_map (GtkWindow *window,
2202 GtkWindowPrivate *priv;
2204 g_return_if_fail (GTK_IS_WINDOW (window));
2206 priv = GTK_WINDOW_GET_PRIVATE (window);
2208 setting = setting != FALSE;
2210 if (priv->focus_on_map != setting)
2212 priv->focus_on_map = setting;
2213 if (GTK_WIDGET_REALIZED (window))
2214 gdk_window_set_focus_on_map (GTK_WIDGET (window)->window,
2215 priv->focus_on_map);
2216 g_object_notify (G_OBJECT (window), "focus-on-map");
2221 * gtk_window_get_focus_on_map:
2222 * @window: a #GtkWindow
2224 * Gets the value set by gtk_window_set_focus_on_map().
2226 * Return value: %TRUE if window should receive the input focus when
2232 gtk_window_get_focus_on_map (GtkWindow *window)
2234 GtkWindowPrivate *priv;
2236 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
2238 priv = GTK_WINDOW_GET_PRIVATE (window);
2240 return priv->focus_on_map;
2244 * gtk_window_set_destroy_with_parent:
2245 * @window: a #GtkWindow
2246 * @setting: whether to destroy @window with its transient parent
2248 * If @setting is %TRUE, then destroying the transient parent of @window
2249 * will also destroy @window itself. This is useful for dialogs that
2250 * shouldn't persist beyond the lifetime of the main window they're
2251 * associated with, for example.
2254 gtk_window_set_destroy_with_parent (GtkWindow *window,
2257 g_return_if_fail (GTK_IS_WINDOW (window));
2259 if (window->destroy_with_parent == (setting != FALSE))
2262 if (window->destroy_with_parent)
2264 disconnect_parent_destroyed (window);
2268 connect_parent_destroyed (window);
2271 window->destroy_with_parent = setting;
2273 g_object_notify (G_OBJECT (window), "destroy-with-parent");
2277 * gtk_window_get_destroy_with_parent:
2278 * @window: a #GtkWindow
2280 * Returns whether the window will be destroyed with its transient parent. See
2281 * gtk_window_set_destroy_with_parent ().
2283 * Return value: %TRUE if the window will be destroyed with its transient parent.
2286 gtk_window_get_destroy_with_parent (GtkWindow *window)
2288 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
2290 return window->destroy_with_parent;
2293 static GtkWindowGeometryInfo*
2294 gtk_window_get_geometry_info (GtkWindow *window,
2297 GtkWindowGeometryInfo *info;
2299 info = window->geometry_info;
2300 if (!info && create)
2302 info = g_new0 (GtkWindowGeometryInfo, 1);
2304 info->default_width = -1;
2305 info->default_height = -1;
2306 info->resize_width = -1;
2307 info->resize_height = -1;
2308 info->initial_x = 0;
2309 info->initial_y = 0;
2310 info->initial_pos_set = FALSE;
2311 info->default_is_geometry = FALSE;
2312 info->position_constraints_changed = FALSE;
2313 info->last.configure_request.x = 0;
2314 info->last.configure_request.y = 0;
2315 info->last.configure_request.width = -1;
2316 info->last.configure_request.height = -1;
2317 info->widget = NULL;
2319 window->geometry_info = info;
2326 * gtk_window_set_geometry_hints:
2327 * @window: a #GtkWindow
2328 * @geometry_widget: widget the geometry hints will be applied to
2329 * @geometry: struct containing geometry information
2330 * @geom_mask: mask indicating which struct fields should be paid attention to
2332 * This function sets up hints about how a window can be resized by
2333 * the user. You can set a minimum and maximum size; allowed resize
2334 * increments (e.g. for xterm, you can only resize by the size of a
2335 * character); aspect ratios; and more. See the #GdkGeometry struct.
2339 gtk_window_set_geometry_hints (GtkWindow *window,
2340 GtkWidget *geometry_widget,
2341 GdkGeometry *geometry,
2342 GdkWindowHints geom_mask)
2344 GtkWindowGeometryInfo *info;
2346 g_return_if_fail (GTK_IS_WINDOW (window));
2347 g_return_if_fail (geometry_widget == NULL || GTK_IS_WIDGET (geometry_widget));
2349 info = gtk_window_get_geometry_info (window, TRUE);
2352 g_signal_handlers_disconnect_by_func (info->widget,
2353 gtk_widget_destroyed,
2356 info->widget = geometry_widget;
2358 g_signal_connect (geometry_widget, "destroy",
2359 G_CALLBACK (gtk_widget_destroyed),
2363 info->geometry = *geometry;
2365 /* We store gravity in window->gravity not in the hints. */
2366 info->mask = geom_mask & ~(GDK_HINT_WIN_GRAVITY);
2368 if (geom_mask & GDK_HINT_WIN_GRAVITY)
2370 gtk_window_set_gravity (window, geometry->win_gravity);
2373 gtk_widget_queue_resize (GTK_WIDGET (window));
2377 * gtk_window_set_decorated:
2378 * @window: a #GtkWindow
2379 * @setting: %TRUE to decorate the window
2381 * By default, windows are decorated with a title bar, resize
2382 * controls, etc. Some <link linkend="gtk-X11-arch">window
2383 * managers</link> allow GTK+ to disable these decorations, creating a
2384 * borderless window. If you set the decorated property to %FALSE
2385 * using this function, GTK+ will do its best to convince the window
2386 * manager not to decorate the window. Depending on the system, this
2387 * function may not have any effect when called on a window that is
2388 * already visible, so you should call it before calling gtk_window_show().
2390 * On Windows, this function always works, since there's no window manager
2395 gtk_window_set_decorated (GtkWindow *window,
2398 g_return_if_fail (GTK_IS_WINDOW (window));
2400 setting = setting != FALSE;
2402 if (setting == window->decorated)
2405 window->decorated = setting;
2407 if (GTK_WIDGET (window)->window)
2409 if (window->decorated)
2410 gdk_window_set_decorations (GTK_WIDGET (window)->window,
2413 gdk_window_set_decorations (GTK_WIDGET (window)->window,
2417 g_object_notify (G_OBJECT (window), "decorated");
2421 * gtk_window_get_decorated:
2422 * @window: a #GtkWindow
2424 * Returns whether the window has been set to have decorations
2425 * such as a title bar via gtk_window_set_decorated().
2427 * Return value: %TRUE if the window has been set to have decorations
2430 gtk_window_get_decorated (GtkWindow *window)
2432 g_return_val_if_fail (GTK_IS_WINDOW (window), TRUE);
2434 return window->decorated;
2437 static GtkWindowIconInfo*
2438 get_icon_info (GtkWindow *window)
2440 return g_object_get_data (G_OBJECT (window),
2441 "gtk-window-icon-info");
2445 free_icon_info (GtkWindowIconInfo *info)
2447 g_free (info->icon_name);
2452 static GtkWindowIconInfo*
2453 ensure_icon_info (GtkWindow *window)
2455 GtkWindowIconInfo *info;
2457 info = get_icon_info (window);
2461 info = g_new0 (GtkWindowIconInfo, 1);
2462 g_object_set_data_full (G_OBJECT (window),
2463 "gtk-window-icon-info",
2465 (GDestroyNotify)free_icon_info);
2477 static ScreenIconInfo *
2478 get_screen_icon_info (GdkScreen *screen)
2480 ScreenIconInfo *info = g_object_get_data (G_OBJECT (screen),
2481 "gtk-window-default-icon-pixmap");
2484 info = g_new0 (ScreenIconInfo, 1);
2485 g_object_set_data (G_OBJECT (screen), "gtk-window-default-icon-pixmap", info);
2488 if (info->serial != default_icon_serial)
2492 g_object_remove_weak_pointer (G_OBJECT (info->pixmap), (gpointer*)&info->pixmap);
2493 info->pixmap = NULL;
2498 g_object_remove_weak_pointer (G_OBJECT (info->mask), (gpointer*)&info->mask);
2502 info->serial = default_icon_serial;
2509 get_pixmap_and_mask (GdkWindow *window,
2510 GtkWindowIconInfo *parent_info,
2511 gboolean is_default_list,
2513 GdkPixmap **pmap_return,
2514 GdkBitmap **mask_return)
2516 GdkScreen *screen = gdk_drawable_get_screen (window);
2517 ScreenIconInfo *default_icon_info = get_screen_icon_info (screen);
2518 GdkPixbuf *best_icon;
2522 *pmap_return = NULL;
2523 *mask_return = NULL;
2525 if (is_default_list &&
2526 default_icon_info->pixmap != NULL)
2528 /* Use shared icon pixmap for all windows on this screen.
2530 if (default_icon_info->pixmap)
2531 g_object_ref (default_icon_info->pixmap);
2532 if (default_icon_info->mask)
2533 g_object_ref (default_icon_info->mask);
2535 *pmap_return = default_icon_info->pixmap;
2536 *mask_return = default_icon_info->mask;
2538 else if (parent_info && parent_info->icon_pixmap)
2540 if (parent_info->icon_pixmap)
2541 g_object_ref (parent_info->icon_pixmap);
2542 if (parent_info->icon_mask)
2543 g_object_ref (parent_info->icon_mask);
2545 *pmap_return = parent_info->icon_pixmap;
2546 *mask_return = parent_info->icon_mask;
2550 #define IDEAL_SIZE 48
2552 best_size = G_MAXINT;
2554 tmp_list = icon_list;
2555 while (tmp_list != NULL)
2557 GdkPixbuf *pixbuf = tmp_list->data;
2560 /* average width and height - if someone passes in a rectangular
2561 * icon they deserve what they get.
2563 this = gdk_pixbuf_get_width (pixbuf) + gdk_pixbuf_get_height (pixbuf);
2566 if (best_icon == NULL)
2573 /* icon is better if it's 32 pixels or larger, and closer to
2574 * the ideal size than the current best.
2577 (ABS (best_size - IDEAL_SIZE) <
2578 ABS (this - IDEAL_SIZE)))
2585 tmp_list = tmp_list->next;
2589 gdk_pixbuf_render_pixmap_and_mask_for_colormap (best_icon,
2590 gdk_screen_get_system_colormap (screen),
2595 /* Save pmap/mask for others to use if appropriate */
2598 parent_info->icon_pixmap = *pmap_return;
2599 parent_info->icon_mask = *mask_return;
2601 if (parent_info->icon_pixmap)
2602 g_object_ref (parent_info->icon_pixmap);
2603 if (parent_info->icon_mask)
2604 g_object_ref (parent_info->icon_mask);
2606 else if (is_default_list)
2608 default_icon_info->pixmap = *pmap_return;
2609 default_icon_info->mask = *mask_return;
2611 if (default_icon_info->pixmap)
2612 g_object_add_weak_pointer (G_OBJECT (default_icon_info->pixmap),
2613 (gpointer*)&default_icon_info->pixmap);
2614 if (default_icon_info->mask)
2615 g_object_add_weak_pointer (G_OBJECT (default_icon_info->mask),
2616 (gpointer*)&default_icon_info->mask);
2622 icon_list_from_theme (GtkWidget *widget,
2627 GtkIconTheme *icon_theme;
2632 icon_theme = gtk_icon_theme_get_for_screen (gtk_widget_get_screen (widget));
2634 sizes = gtk_icon_theme_get_icon_sizes (icon_theme, name);
2637 for (i = 0; sizes[i]; i++)
2640 * We need an EWMH extension to handle scalable icons
2641 * by passing their name to the WM. For now just use a
2645 icon = gtk_icon_theme_load_icon (icon_theme, name,
2648 icon = gtk_icon_theme_load_icon (icon_theme, name,
2651 list = g_list_append (list, icon);
2661 gtk_window_realize_icon (GtkWindow *window)
2664 GtkWindowIconInfo *info;
2667 widget = GTK_WIDGET (window);
2669 g_return_if_fail (widget->window != NULL);
2671 /* no point setting an icon on override-redirect */
2672 if (window->type == GTK_WINDOW_POPUP)
2677 info = ensure_icon_info (window);
2682 g_return_if_fail (info->icon_pixmap == NULL);
2683 g_return_if_fail (info->icon_mask == NULL);
2685 info->using_default_icon = FALSE;
2686 info->using_parent_icon = FALSE;
2687 info->using_themed_icon = FALSE;
2689 icon_list = info->icon_list;
2691 /* Look up themed icon */
2692 if (icon_list == NULL && info->icon_name)
2694 icon_list = icon_list_from_theme (widget, info->icon_name);
2696 info->using_themed_icon = TRUE;
2699 /* Inherit from transient parent */
2700 if (icon_list == NULL && window->transient_parent)
2702 icon_list = ensure_icon_info (window->transient_parent)->icon_list;
2704 info->using_parent_icon = TRUE;
2707 /* Inherit from default */
2708 if (icon_list == NULL)
2710 icon_list = default_icon_list;
2712 info->using_default_icon = TRUE;
2715 /* Look up themed icon */
2716 if (icon_list == NULL && default_icon_name)
2718 icon_list = icon_list_from_theme (widget, default_icon_name);
2719 info->using_default_icon = TRUE;
2720 info->using_themed_icon = TRUE;
2723 gdk_window_set_icon_list (widget->window, icon_list);
2725 get_pixmap_and_mask (widget->window,
2726 info->using_parent_icon ? ensure_icon_info (window->transient_parent) : NULL,
2727 info->using_default_icon,
2732 /* This is a slight ICCCM violation since it's a color pixmap not
2733 * a bitmap, but everyone does it.
2735 gdk_window_set_icon (widget->window,
2740 info->realized = TRUE;
2742 if (info->using_themed_icon)
2744 GtkIconTheme *icon_theme;
2746 g_list_foreach (icon_list, (GFunc) g_object_unref, NULL);
2747 g_list_free (icon_list);
2749 icon_theme = gtk_icon_theme_get_for_screen (gtk_widget_get_screen (GTK_WIDGET (window)));
2750 g_signal_connect (icon_theme, "changed",
2751 G_CALLBACK (update_themed_icon), window);
2756 gtk_window_unrealize_icon (GtkWindow *window)
2758 GtkWindowIconInfo *info;
2761 widget = GTK_WIDGET (window);
2763 info = get_icon_info (window);
2768 if (info->icon_pixmap)
2769 g_object_unref (info->icon_pixmap);
2771 if (info->icon_mask)
2772 g_object_unref (info->icon_mask);
2774 info->icon_pixmap = NULL;
2775 info->icon_mask = NULL;
2777 if (info->using_themed_icon)
2779 GtkIconTheme *icon_theme;
2781 icon_theme = gtk_icon_theme_get_for_screen (gtk_widget_get_screen (GTK_WIDGET (window)));
2783 g_signal_handlers_disconnect_by_func (icon_theme, update_themed_icon, window);
2786 /* We don't clear the properties on the window, just figure the
2787 * window is going away.
2790 info->realized = FALSE;
2795 * gtk_window_set_icon_list:
2796 * @window: a #GtkWindow
2797 * @list: list of #GdkPixbuf
2799 * Sets up the icon representing a #GtkWindow. The icon is used when
2800 * the window is minimized (also known as iconified). Some window
2801 * managers or desktop environments may also place it in the window
2802 * frame, or display it in other contexts.
2804 * gtk_window_set_icon_list() allows you to pass in the same icon in
2805 * several hand-drawn sizes. The list should contain the natural sizes
2806 * your icon is available in; that is, don't scale the image before
2807 * passing it to GTK+. Scaling is postponed until the last minute,
2808 * when the desired final size is known, to allow best quality.
2810 * By passing several sizes, you may improve the final image quality
2811 * of the icon, by reducing or eliminating automatic image scaling.
2813 * Recommended sizes to provide: 16x16, 32x32, 48x48 at minimum, and
2814 * larger images (64x64, 128x128) if you have them.
2816 * See also gtk_window_set_default_icon_list() to set the icon
2817 * for all windows in your application in one go.
2819 * Note that transient windows (those who have been set transient for another
2820 * window using gtk_window_set_transient_for()) will inherit their
2821 * icon from their transient parent. So there's no need to explicitly
2822 * set the icon on transient windows.
2825 gtk_window_set_icon_list (GtkWindow *window,
2828 GtkWindowIconInfo *info;
2830 g_return_if_fail (GTK_IS_WINDOW (window));
2832 info = ensure_icon_info (window);
2834 if (info->icon_list == list) /* check for NULL mostly */
2837 g_list_foreach (list,
2838 (GFunc) g_object_ref, NULL);
2840 g_list_foreach (info->icon_list,
2841 (GFunc) g_object_unref, NULL);
2843 g_list_free (info->icon_list);
2845 info->icon_list = g_list_copy (list);
2847 g_object_notify (G_OBJECT (window), "icon");
2849 gtk_window_unrealize_icon (window);
2851 if (GTK_WIDGET_REALIZED (window))
2852 gtk_window_realize_icon (window);
2854 /* We could try to update our transient children, but I don't think
2855 * it's really worth it. If we did it, the best way would probably
2856 * be to have children connect to notify::icon-list
2861 * gtk_window_get_icon_list:
2862 * @window: a #GtkWindow
2864 * Retrieves the list of icons set by gtk_window_set_icon_list().
2865 * The list is copied, but the reference count on each
2866 * member won't be incremented.
2868 * Return value: copy of window's icon list
2871 gtk_window_get_icon_list (GtkWindow *window)
2873 GtkWindowIconInfo *info;
2875 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
2877 info = get_icon_info (window);
2880 return g_list_copy (info->icon_list);
2886 * gtk_window_set_icon:
2887 * @window: a #GtkWindow
2888 * @icon: icon image, or %NULL
2890 * Sets up the icon representing a #GtkWindow. This icon is used when
2891 * the window is minimized (also known as iconified). Some window
2892 * managers or desktop environments may also place it in the window
2893 * frame, or display it in other contexts.
2895 * The icon should be provided in whatever size it was naturally
2896 * drawn; that is, don't scale the image before passing it to
2897 * GTK+. Scaling is postponed until the last minute, when the desired
2898 * final size is known, to allow best quality.
2900 * If you have your icon hand-drawn in multiple sizes, use
2901 * gtk_window_set_icon_list(). Then the best size will be used.
2903 * This function is equivalent to calling gtk_window_set_icon_list()
2904 * with a 1-element list.
2906 * See also gtk_window_set_default_icon_list() to set the icon
2907 * for all windows in your application in one go.
2910 gtk_window_set_icon (GtkWindow *window,
2915 g_return_if_fail (GTK_IS_WINDOW (window));
2916 g_return_if_fail (icon == NULL || GDK_IS_PIXBUF (icon));
2921 list = g_list_append (list, icon);
2923 gtk_window_set_icon_list (window, list);
2929 update_themed_icon (GtkIconTheme *icon_theme,
2932 g_object_notify (G_OBJECT (window), "icon");
2934 gtk_window_unrealize_icon (window);
2936 if (GTK_WIDGET_REALIZED (window))
2937 gtk_window_realize_icon (window);
2941 * gtk_window_set_icon_name:
2942 * @window: a #GtkWindow
2943 * @name: the name of the themed icon
2945 * Sets the icon for the window from a named themed icon. See
2946 * the docs for #GtkIconTheme for more details.
2948 * Note that this has nothing to do with the WM_ICON_NAME
2949 * property which is mentioned in the ICCCM.
2954 gtk_window_set_icon_name (GtkWindow *window,
2957 GtkWindowIconInfo *info;
2960 g_return_if_fail (GTK_IS_WINDOW (window));
2962 info = ensure_icon_info (window);
2964 tmp = info->icon_name;
2965 info->icon_name = g_strdup (name);
2968 g_list_foreach (info->icon_list, (GFunc) g_object_unref, NULL);
2969 g_list_free (info->icon_list);
2970 info->icon_list = NULL;
2972 update_themed_icon (NULL, window);
2974 g_object_notify (G_OBJECT (window), "icon-name");
2978 * gtk_window_get_icon_name:
2979 * @window: a #GtkWindow
2981 * Returns the name of the themed icon for the window,
2982 * see gtk_window_set_icon_name().
2984 * Returns: the icon name or %NULL if the window has
2989 G_CONST_RETURN gchar *
2990 gtk_window_get_icon_name (GtkWindow *window)
2992 GtkWindowIconInfo *info;
2994 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
2996 info = ensure_icon_info (window);
2998 return info->icon_name;
3002 * gtk_window_get_icon:
3003 * @window: a #GtkWindow
3005 * Gets the value set by gtk_window_set_icon() (or if you've
3006 * called gtk_window_set_icon_list(), gets the first icon in
3009 * Return value: icon for window
3012 gtk_window_get_icon (GtkWindow *window)
3014 GtkWindowIconInfo *info;
3016 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
3018 info = get_icon_info (window);
3019 if (info && info->icon_list)
3020 return GDK_PIXBUF (info->icon_list->data);
3025 /* Load pixbuf, printing warning on failure if error == NULL
3028 load_pixbuf_verbosely (const char *filename,
3031 GError *local_err = NULL;
3034 pixbuf = gdk_pixbuf_new_from_file (filename, &local_err);
3042 g_warning ("Error loading icon from file '%s':\n\t%s",
3043 filename, local_err->message);
3044 g_error_free (local_err);
3052 * gtk_window_set_icon_from_file:
3053 * @window: a #GtkWindow
3054 * @filename: location of icon file
3055 * @err: location to store error, or %NULL.
3057 * Sets the icon for @window.
3058 * Warns on failure if @err is %NULL.
3060 * This function is equivalent to calling gtk_window_set_icon()
3061 * with a pixbuf created by loading the image from @filename.
3063 * Returns: %TRUE if setting the icon succeeded.
3068 gtk_window_set_icon_from_file (GtkWindow *window,
3069 const gchar *filename,
3072 GdkPixbuf *pixbuf = load_pixbuf_verbosely (filename, err);
3076 gtk_window_set_icon (window, pixbuf);
3077 g_object_unref (pixbuf);
3086 * gtk_window_set_default_icon_list:
3087 * @list: a list of #GdkPixbuf
3089 * Sets an icon list to be used as fallback for windows that haven't
3090 * had gtk_window_set_icon_list() called on them to set up a
3091 * window-specific icon list. This function allows you to set up the
3092 * icon for all windows in your app at once.
3094 * See gtk_window_set_icon_list() for more details.
3098 gtk_window_set_default_icon_list (GList *list)
3102 if (list == default_icon_list)
3105 /* Update serial so we don't used cached pixmaps/masks
3107 default_icon_serial++;
3109 g_list_foreach (list,
3110 (GFunc) g_object_ref, NULL);
3112 g_list_foreach (default_icon_list,
3113 (GFunc) g_object_unref, NULL);
3115 g_list_free (default_icon_list);
3117 default_icon_list = g_list_copy (list);
3119 /* Update all toplevels */
3120 toplevels = gtk_window_list_toplevels ();
3121 tmp_list = toplevels;
3122 while (tmp_list != NULL)
3124 GtkWindowIconInfo *info;
3125 GtkWindow *w = tmp_list->data;
3127 info = get_icon_info (w);
3128 if (info && info->using_default_icon)
3130 gtk_window_unrealize_icon (w);
3131 if (GTK_WIDGET_REALIZED (w))
3132 gtk_window_realize_icon (w);
3135 tmp_list = tmp_list->next;
3137 g_list_free (toplevels);
3141 * gtk_window_set_default_icon:
3144 * Sets an icon to be used as fallback for windows that haven't
3145 * had gtk_window_set_icon() called on them from a pixbuf.
3150 gtk_window_set_default_icon (GdkPixbuf *icon)
3154 g_return_if_fail (GDK_IS_PIXBUF (icon));
3156 list = g_list_prepend (NULL, icon);
3157 gtk_window_set_default_icon_list (list);
3162 * gtk_window_set_default_icon_name:
3163 * @name: the name of the themed icon
3165 * Sets an icon to be used as fallback for windows that haven't
3166 * had gtk_window_set_icon_list() called on them from a named
3167 * themed icon, see gtk_window_set_icon_name().
3172 gtk_window_set_default_icon_name (const gchar *name)
3177 /* Update serial so we don't used cached pixmaps/masks
3179 default_icon_serial++;
3181 g_free (default_icon_name);
3182 default_icon_name = g_strdup (name);
3184 g_list_foreach (default_icon_list,
3185 (GFunc) g_object_unref, NULL);
3187 g_list_free (default_icon_list);
3188 default_icon_list = NULL;
3190 /* Update all toplevels */
3191 toplevels = gtk_window_list_toplevels ();
3192 tmp_list = toplevels;
3193 while (tmp_list != NULL)
3195 GtkWindowIconInfo *info;
3196 GtkWindow *w = tmp_list->data;
3198 info = get_icon_info (w);
3199 if (info && info->using_default_icon && info->using_themed_icon)
3201 gtk_window_unrealize_icon (w);
3202 if (GTK_WIDGET_REALIZED (w))
3203 gtk_window_realize_icon (w);
3206 tmp_list = tmp_list->next;
3208 g_list_free (toplevels);
3212 * gtk_window_set_default_icon_from_file:
3213 * @filename: location of icon file
3214 * @err: location to store error, or %NULL.
3216 * Sets an icon to be used as fallback for windows that haven't
3217 * had gtk_window_set_icon_list() called on them from a file
3218 * on disk. Warns on failure if @err is %NULL.
3220 * Returns: %TRUE if setting the icon succeeded.
3225 gtk_window_set_default_icon_from_file (const gchar *filename,
3228 GdkPixbuf *pixbuf = load_pixbuf_verbosely (filename, err);
3232 gtk_window_set_default_icon (pixbuf);
3233 g_object_unref (pixbuf);
3242 * gtk_window_get_default_icon_list:
3244 * Gets the value set by gtk_window_set_default_icon_list().
3245 * The list is a copy and should be freed with g_list_free(),
3246 * but the pixbufs in the list have not had their reference count
3249 * Return value: copy of default icon list
3252 gtk_window_get_default_icon_list (void)
3254 return g_list_copy (default_icon_list);
3258 gtk_window_set_default_size_internal (GtkWindow *window,
3259 gboolean change_width,
3261 gboolean change_height,
3263 gboolean is_geometry)
3265 GtkWindowGeometryInfo *info;
3267 g_return_if_fail (change_width == FALSE || width >= -1);
3268 g_return_if_fail (change_height == FALSE || height >= -1);
3270 info = gtk_window_get_geometry_info (window, TRUE);
3272 g_object_freeze_notify (G_OBJECT (window));
3274 info->default_is_geometry = is_geometry != FALSE;
3284 info->default_width = width;
3286 g_object_notify (G_OBJECT (window), "default-width");
3297 info->default_height = height;
3299 g_object_notify (G_OBJECT (window), "default-height");
3302 g_object_thaw_notify (G_OBJECT (window));
3304 gtk_widget_queue_resize (GTK_WIDGET (window));
3308 * gtk_window_set_default_size:
3309 * @window: a #GtkWindow
3310 * @width: width in pixels, or -1 to unset the default width
3311 * @height: height in pixels, or -1 to unset the default height
3313 * Sets the default size of a window. If the window's "natural" size
3314 * (its size request) is larger than the default, the default will be
3315 * ignored. More generally, if the default size does not obey the
3316 * geometry hints for the window (gtk_window_set_geometry_hints() can
3317 * be used to set these explicitly), the default size will be clamped
3318 * to the nearest permitted size.
3320 * Unlike gtk_widget_set_size_request(), which sets a size request for
3321 * a widget and thus would keep users from shrinking the window, this
3322 * function only sets the initial size, just as if the user had
3323 * resized the window themselves. Users can still shrink the window
3324 * again as they normally would. Setting a default size of -1 means to
3325 * use the "natural" default size (the size request of the window).
3327 * For more control over a window's initial size and how resizing works,
3328 * investigate gtk_window_set_geometry_hints().
3330 * For some uses, gtk_window_resize() is a more appropriate function.
3331 * gtk_window_resize() changes the current size of the window, rather
3332 * than the size to be used on initial display. gtk_window_resize() always
3333 * affects the window itself, not the geometry widget.
3335 * The default size of a window only affects the first time a window is
3336 * shown; if a window is hidden and re-shown, it will remember the size
3337 * it had prior to hiding, rather than using the default size.
3339 * Windows can't actually be 0x0 in size, they must be at least 1x1, but
3340 * passing 0 for @width and @height is OK, resulting in a 1x1 default size.
3343 gtk_window_set_default_size (GtkWindow *window,
3347 g_return_if_fail (GTK_IS_WINDOW (window));
3348 g_return_if_fail (width >= -1);
3349 g_return_if_fail (height >= -1);
3351 gtk_window_set_default_size_internal (window, TRUE, width, TRUE, height, FALSE);
3355 * gtk_window_get_default_size:
3356 * @window: a #GtkWindow
3357 * @width: location to store the default width, or %NULL
3358 * @height: location to store the default height, or %NULL
3360 * Gets the default size of the window. A value of -1 for the width or
3361 * height indicates that a default size has not been explicitly set
3362 * for that dimension, so the "natural" size of the window will be
3367 gtk_window_get_default_size (GtkWindow *window,
3371 GtkWindowGeometryInfo *info;
3373 g_return_if_fail (GTK_IS_WINDOW (window));
3375 info = gtk_window_get_geometry_info (window, FALSE);
3378 *width = info ? info->default_width : -1;
3381 *height = info ? info->default_height : -1;
3385 * gtk_window_resize:
3386 * @window: a #GtkWindow
3387 * @width: width in pixels to resize the window to
3388 * @height: height in pixels to resize the window to
3390 * Resizes the window as if the user had done so, obeying geometry
3391 * constraints. The default geometry constraint is that windows may
3392 * not be smaller than their size request; to override this
3393 * constraint, call gtk_widget_set_size_request() to set the window's
3394 * request to a smaller value.
3396 * If gtk_window_resize() is called before showing a window for the
3397 * first time, it overrides any default size set with
3398 * gtk_window_set_default_size().
3400 * Windows may not be resized smaller than 1 by 1 pixels.
3404 gtk_window_resize (GtkWindow *window,
3408 GtkWindowGeometryInfo *info;
3410 g_return_if_fail (GTK_IS_WINDOW (window));
3411 g_return_if_fail (width > 0);
3412 g_return_if_fail (height > 0);
3414 info = gtk_window_get_geometry_info (window, TRUE);
3416 info->resize_width = width;
3417 info->resize_height = height;
3419 gtk_widget_queue_resize (GTK_WIDGET (window));
3423 * gtk_window_get_size:
3424 * @window: a #GtkWindow
3425 * @width: return location for width, or %NULL
3426 * @height: return location for height, or %NULL
3428 * Obtains the current size of @window. If @window is not onscreen,
3429 * it returns the size GTK+ will suggest to the <link
3430 * linkend="gtk-X11-arch">window manager</link> for the initial window
3431 * size (but this is not reliably the same as the size the window
3432 * manager will actually select). The size obtained by
3433 * gtk_window_get_size() is the last size received in a
3434 * #GdkEventConfigure, that is, GTK+ uses its locally-stored size,
3435 * rather than querying the X server for the size. As a result, if you
3436 * call gtk_window_resize() then immediately call
3437 * gtk_window_get_size(), the size won't have taken effect yet. After
3438 * the window manager processes the resize request, GTK+ receives
3439 * notification that the size has changed via a configure event, and
3440 * the size of the window gets updated.
3442 * Note 1: Nearly any use of this function creates a race condition,
3443 * because the size of the window may change between the time that you
3444 * get the size and the time that you perform some action assuming
3445 * that size is the current size. To avoid race conditions, connect to
3446 * "configure_event" on the window and adjust your size-dependent
3447 * state to match the size delivered in the #GdkEventConfigure.
3449 * Note 2: The returned size does <emphasis>not</emphasis> include the
3450 * size of the window manager decorations (aka the window frame or
3451 * border). Those are not drawn by GTK+ and GTK+ has no reliable
3452 * method of determining their size.
3454 * Note 3: If you are getting a window size in order to position
3455 * the window onscreen, there may be a better way. The preferred
3456 * way is to simply set the window's semantic type with
3457 * gtk_window_set_type_hint(), which allows the window manager to
3458 * e.g. center dialogs. Also, if you set the transient parent of
3459 * dialogs with gtk_window_set_transient_for() window managers
3460 * will often center the dialog over its parent window. It's
3461 * much preferred to let the window manager handle these
3462 * things rather than doing it yourself, because all apps will
3463 * behave consistently and according to user prefs if the window
3464 * manager handles it. Also, the window manager can take the size
3465 * of the window decorations/border into account, while your
3466 * application cannot.
3468 * In any case, if you insist on application-specified window
3469 * positioning, there's <emphasis>still</emphasis> a better way than
3470 * doing it yourself - gtk_window_set_position() will frequently
3471 * handle the details for you.
3475 gtk_window_get_size (GtkWindow *window,
3482 g_return_if_fail (GTK_IS_WINDOW (window));
3484 widget = GTK_WIDGET (window);
3486 if (width == NULL && height == NULL)
3489 if (GTK_WIDGET_MAPPED (window))
3491 gdk_drawable_get_size (GTK_WIDGET (window)->window,
3496 GdkRectangle configure_request;
3498 gtk_window_compute_configure_request (window,
3502 w = configure_request.width;
3503 h = configure_request.height;
3514 * @window: a #GtkWindow
3515 * @x: X coordinate to move window to
3516 * @y: Y coordinate to move window to
3518 * Asks the <link linkend="gtk-X11-arch">window manager</link> to move
3519 * @window to the given position. Window managers are free to ignore
3520 * this; most window managers ignore requests for initial window
3521 * positions (instead using a user-defined placement algorithm) and
3522 * honor requests after the window has already been shown.
3524 * Note: the position is the position of the gravity-determined
3525 * reference point for the window. The gravity determines two things:
3526 * first, the location of the reference point in root window
3527 * coordinates; and second, which point on the window is positioned at
3528 * the reference point.
3530 * By default the gravity is #GDK_GRAVITY_NORTH_WEST, so the reference
3531 * point is simply the @x, @y supplied to gtk_window_move(). The
3532 * top-left corner of the window decorations (aka window frame or
3533 * border) will be placed at @x, @y. Therefore, to position a window
3534 * at the top left of the screen, you want to use the default gravity
3535 * (which is #GDK_GRAVITY_NORTH_WEST) and move the window to 0,0.
3537 * To position a window at the bottom right corner of the screen, you
3538 * would set #GDK_GRAVITY_SOUTH_EAST, which means that the reference
3539 * point is at @x + the window width and @y + the window height, and
3540 * the bottom-right corner of the window border will be placed at that
3541 * reference point. So, to place a window in the bottom right corner
3542 * you would first set gravity to south east, then write:
3543 * <literal>gtk_window_move (window, gdk_screen_width () - window_width,
3544 * gdk_screen_height () - window_height)</literal>.
3546 * The Extended Window Manager Hints specification at <ulink
3547 * url="http://www.freedesktop.org/Standards/wm-spec">
3548 * http://www.freedesktop.org/Standards/wm-spec</ulink> has a
3549 * nice table of gravities in the "implementation notes" section.
3551 * The gtk_window_get_position() documentation may also be relevant.
3555 gtk_window_move (GtkWindow *window,
3559 GtkWindowGeometryInfo *info;
3562 g_return_if_fail (GTK_IS_WINDOW (window));
3564 widget = GTK_WIDGET (window);
3566 info = gtk_window_get_geometry_info (window, TRUE);
3568 if (GTK_WIDGET_MAPPED (window))
3570 /* we have now sent a request with this position
3571 * with currently-active constraints, so toggle flag.
3573 info->position_constraints_changed = FALSE;
3575 /* we only constrain if mapped - if not mapped,
3576 * then gtk_window_compute_configure_request()
3577 * will apply the constraints later, and we
3578 * don't want to lose information about
3579 * what position the user set before then.
3580 * i.e. if you do a move() then turn off POS_CENTER
3581 * then show the window, your move() will work.
3583 gtk_window_constrain_position (window,
3584 widget->allocation.width,
3585 widget->allocation.height,
3588 /* Note that this request doesn't go through our standard request
3589 * framework, e.g. doesn't increment configure_request_count,
3590 * doesn't set info->last, etc.; that's because
3591 * we don't save the info needed to arrive at this same request
3594 * To gtk_window_move_resize(), this will end up looking exactly
3595 * the same as the position being changed by the window
3599 /* FIXME are we handling gravity properly for framed windows? */
3601 gdk_window_move (window->frame,
3602 x - window->frame_left,
3603 y - window->frame_top);
3605 gdk_window_move (GTK_WIDGET (window)->window,
3610 /* Save this position to apply on mapping */
3611 info->initial_x = x;
3612 info->initial_y = y;
3613 info->initial_pos_set = TRUE;
3618 * gtk_window_get_position:
3619 * @window: a #GtkWindow
3620 * @root_x: return location for X coordinate of gravity-determined reference p\oint
3621 * @root_y: return location for Y coordinate of gravity-determined reference p\oint
3623 * This function returns the position you need to pass to
3624 * gtk_window_move() to keep @window in its current position. This
3625 * means that the meaning of the returned value varies with window
3626 * gravity. See gtk_window_move() for more details.
3628 * If you haven't changed the window gravity, its gravity will be
3629 * #GDK_GRAVITY_NORTH_WEST. This means that gtk_window_get_position()
3630 * gets the position of the top-left corner of the window manager
3631 * frame for the window. gtk_window_move() sets the position of this
3632 * same top-left corner.
3634 * gtk_window_get_position() is not 100% reliable because the X Window System
3635 * does not specify a way to obtain the geometry of the
3636 * decorations placed on a window by the window manager.
3637 * Thus GTK+ is using a "best guess" that works with most
3640 * Moreover, nearly all window managers are historically broken with
3641 * respect to their handling of window gravity. So moving a window to
3642 * its current position as returned by gtk_window_get_position() tends
3643 * to result in moving the window slightly. Window managers are
3644 * slowly getting better over time.
3646 * If a window has gravity #GDK_GRAVITY_STATIC the window manager
3647 * frame is not relevant, and thus gtk_window_get_position() will
3648 * always produce accurate results. However you can't use static
3649 * gravity to do things like place a window in a corner of the screen,
3650 * because static gravity ignores the window manager decorations.
3652 * If you are saving and restoring your application's window
3653 * positions, you should know that it's impossible for applications to
3654 * do this without getting it somewhat wrong because applications do
3655 * not have sufficient knowledge of window manager state. The Correct
3656 * Mechanism is to support the session management protocol (see the
3657 * "GnomeClient" object in the GNOME libraries for example) and allow
3658 * the window manager to save your window sizes and positions.
3663 gtk_window_get_position (GtkWindow *window,
3669 g_return_if_fail (GTK_IS_WINDOW (window));
3671 widget = GTK_WIDGET (window);
3673 if (window->gravity == GDK_GRAVITY_STATIC)
3675 if (GTK_WIDGET_MAPPED (widget))
3677 /* This does a server round-trip, which is sort of wrong;
3678 * but a server round-trip is inevitable for
3679 * gdk_window_get_frame_extents() in the usual
3680 * NorthWestGravity case below, so not sure what else to
3681 * do. We should likely be consistent about whether we get
3682 * the client-side info or the server-side info.
3684 gdk_window_get_origin (widget->window, root_x, root_y);
3688 GdkRectangle configure_request;
3690 gtk_window_compute_configure_request (window,
3694 *root_x = configure_request.x;
3695 *root_y = configure_request.y;
3700 GdkRectangle frame_extents;
3705 if (GTK_WIDGET_MAPPED (widget))
3708 gdk_window_get_frame_extents (window->frame, &frame_extents);
3710 gdk_window_get_frame_extents (widget->window, &frame_extents);
3711 x = frame_extents.x;
3712 y = frame_extents.y;
3713 gtk_window_get_size (window, &w, &h);
3717 /* We just say the frame has 0 size on all sides.
3718 * Not sure what else to do.
3720 gtk_window_compute_configure_request (window,
3723 x = frame_extents.x;
3724 y = frame_extents.y;
3725 w = frame_extents.width;
3726 h = frame_extents.height;
3729 switch (window->gravity)
3731 case GDK_GRAVITY_NORTH:
3732 case GDK_GRAVITY_CENTER:
3733 case GDK_GRAVITY_SOUTH:
3734 /* Find center of frame. */
3735 x += frame_extents.width / 2;
3736 /* Center client window on that point. */
3740 case GDK_GRAVITY_SOUTH_EAST:
3741 case GDK_GRAVITY_EAST:
3742 case GDK_GRAVITY_NORTH_EAST:
3743 /* Find right edge of frame */
3744 x += frame_extents.width;
3745 /* Align left edge of client at that point. */
3752 switch (window->gravity)
3754 case GDK_GRAVITY_WEST:
3755 case GDK_GRAVITY_CENTER:
3756 case GDK_GRAVITY_EAST:
3757 /* Find center of frame. */
3758 y += frame_extents.height / 2;
3759 /* Center client window there. */
3762 case GDK_GRAVITY_SOUTH_WEST:
3763 case GDK_GRAVITY_SOUTH:
3764 case GDK_GRAVITY_SOUTH_EAST:
3765 /* Find south edge of frame */
3766 y += frame_extents.height;
3767 /* Place bottom edge of client there */
3782 * gtk_window_reshow_with_initial_size:
3783 * @window: a #GtkWindow
3785 * Hides @window, then reshows it, resetting the
3786 * default size and position of the window. Used
3787 * by GUI builders only.
3790 gtk_window_reshow_with_initial_size (GtkWindow *window)
3794 g_return_if_fail (GTK_IS_WINDOW (window));
3796 widget = GTK_WIDGET (window);
3798 gtk_widget_hide (widget);
3799 gtk_widget_unrealize (widget);
3800 gtk_widget_show (widget);
3804 gtk_window_destroy (GtkObject *object)
3806 GtkWindow *window = GTK_WINDOW (object);
3808 toplevel_list = g_slist_remove (toplevel_list, window);
3810 if (window->transient_parent)
3811 gtk_window_set_transient_for (window, NULL);
3813 /* frees the icons */
3814 gtk_window_set_icon_list (window, NULL);
3816 if (window->has_user_ref_count)
3818 window->has_user_ref_count = FALSE;
3819 g_object_unref (window);
3823 gtk_window_group_remove_window (window->group, window);
3825 gtk_window_free_key_hash (window);
3827 GTK_OBJECT_CLASS (parent_class)->destroy (object);
3831 gtk_window_finalize (GObject *object)
3833 GtkWindow *window = GTK_WINDOW (object);
3834 GtkMnemonicHash *mnemonic_hash;
3836 g_free (window->title);
3837 g_free (window->wmclass_name);
3838 g_free (window->wmclass_class);
3839 g_free (window->wm_role);
3841 mnemonic_hash = gtk_window_get_mnemonic_hash (window, FALSE);
3843 _gtk_mnemonic_hash_free (mnemonic_hash);
3845 if (window->geometry_info)
3847 if (window->geometry_info->widget)
3848 g_signal_handlers_disconnect_by_func (window->geometry_info->widget,
3849 gtk_widget_destroyed,
3850 &window->geometry_info->widget);
3851 g_free (window->geometry_info);
3854 if (window->keys_changed_handler)
3856 g_source_remove (window->keys_changed_handler);
3857 window->keys_changed_handler = 0;
3860 G_OBJECT_CLASS (parent_class)->finalize (object);
3864 gtk_window_show (GtkWidget *widget)
3866 GtkWindow *window = GTK_WINDOW (widget);
3867 GtkContainer *container = GTK_CONTAINER (window);
3868 gboolean need_resize;
3870 GTK_WIDGET_SET_FLAGS (widget, GTK_VISIBLE);
3872 need_resize = container->need_resize || !GTK_WIDGET_REALIZED (widget);
3873 container->need_resize = FALSE;
3877 GtkWindowGeometryInfo *info = gtk_window_get_geometry_info (window, TRUE);
3878 GtkAllocation allocation = { 0, 0 };
3879 GdkRectangle configure_request;
3880 GdkGeometry new_geometry;
3882 gboolean was_realized;
3884 /* We are going to go ahead and perform this configure request
3885 * and then emulate a configure notify by going ahead and
3886 * doing a size allocate. Sort of a synchronous
3887 * mini-copy of gtk_window_move_resize() here.
3889 gtk_window_compute_configure_request (window,
3894 /* We update this because we are going to go ahead
3895 * and gdk_window_resize() below, rather than
3898 info->last.configure_request.width = configure_request.width;
3899 info->last.configure_request.height = configure_request.height;
3901 /* and allocate the window - this is normally done
3902 * in move_resize in response to configure notify
3904 allocation.width = configure_request.width;
3905 allocation.height = configure_request.height;
3906 gtk_widget_size_allocate (widget, &allocation);
3908 /* Then we guarantee we have a realize */
3909 was_realized = FALSE;
3910 if (!GTK_WIDGET_REALIZED (widget))
3912 gtk_widget_realize (widget);
3913 was_realized = TRUE;
3916 /* Must be done after the windows are realized,
3917 * so that the decorations can be read
3919 gtk_decorated_window_calculate_frame_size (window);
3921 /* We only send configure request if we didn't just finish
3922 * creating the window; if we just created the window
3923 * then we created it with widget->allocation anyhow.
3926 gdk_window_move_resize (widget->window,
3927 configure_request.x,
3928 configure_request.y,
3929 configure_request.width,
3930 configure_request.height);
3933 gtk_container_check_resize (container);
3935 gtk_widget_map (widget);
3937 /* Try to make sure that we have some focused widget
3939 if (!window->focus_widget && !GTK_IS_PLUG (window))
3940 gtk_window_move_focus (window, GTK_DIR_TAB_FORWARD);
3943 gtk_grab_add (widget);
3947 gtk_window_hide (GtkWidget *widget)
3949 GtkWindow *window = GTK_WINDOW (widget);
3951 GTK_WIDGET_UNSET_FLAGS (widget, GTK_VISIBLE);
3952 gtk_widget_unmap (widget);
3955 gtk_grab_remove (widget);
3959 gtk_window_map (GtkWidget *widget)
3961 GtkWindow *window = GTK_WINDOW (widget);
3962 GtkWindowPrivate *priv = GTK_WINDOW_GET_PRIVATE (window);
3963 GdkWindow *toplevel;
3965 GTK_WIDGET_SET_FLAGS (widget, GTK_MAPPED);
3967 if (window->bin.child &&
3968 GTK_WIDGET_VISIBLE (window->bin.child) &&
3969 !GTK_WIDGET_MAPPED (window->bin.child))
3970 gtk_widget_map (window->bin.child);
3973 toplevel = window->frame;
3975 toplevel = widget->window;
3977 if (window->maximize_initially)
3978 gdk_window_maximize (toplevel);
3980 gdk_window_unmaximize (toplevel);
3982 if (window->stick_initially)
3983 gdk_window_stick (toplevel);
3985 gdk_window_unstick (toplevel);
3987 if (window->iconify_initially)
3988 gdk_window_iconify (toplevel);
3990 gdk_window_deiconify (toplevel);
3992 if (priv->fullscreen_initially)
3993 gdk_window_fullscreen (toplevel);
3995 gdk_window_unfullscreen (toplevel);
3997 gdk_window_set_keep_above (toplevel, priv->above_initially);
3999 gdk_window_set_keep_below (toplevel, priv->below_initially);
4001 /* No longer use the default settings */
4002 window->need_default_size = FALSE;
4003 window->need_default_position = FALSE;
4005 gdk_window_show (widget->window);
4008 gdk_window_show (window->frame);
4010 if (!disable_startup_notification &&
4011 !sent_startup_notification)
4013 sent_startup_notification = TRUE;
4014 gdk_notify_startup_complete ();
4019 gtk_window_unmap (GtkWidget *widget)
4021 GtkWindow *window = GTK_WINDOW (widget);
4022 GtkWindowPrivate *priv = GTK_WINDOW_GET_PRIVATE (widget);
4023 GtkWindowGeometryInfo *info;
4024 GdkWindowState state;
4026 GTK_WIDGET_UNSET_FLAGS (widget, GTK_MAPPED);
4028 gdk_window_withdraw (window->frame);
4030 gdk_window_withdraw (widget->window);
4032 window->configure_request_count = 0;
4033 window->configure_notify_received = FALSE;
4035 /* on unmap, we reset the default positioning of the window,
4036 * so it's placed again, but we don't reset the default
4037 * size of the window, so it's remembered.
4039 window->need_default_position = TRUE;
4041 info = gtk_window_get_geometry_info (window, FALSE);
4044 info->initial_pos_set = FALSE;
4045 info->position_constraints_changed = FALSE;
4048 state = gdk_window_get_state (widget->window);
4049 window->iconify_initially = state & GDK_WINDOW_STATE_ICONIFIED;
4050 window->maximize_initially = state & GDK_WINDOW_STATE_MAXIMIZED;
4051 window->stick_initially = state & GDK_WINDOW_STATE_STICKY;
4052 priv->above_initially = state & GDK_WINDOW_STATE_ABOVE;
4053 priv->below_initially = state & GDK_WINDOW_STATE_BELOW;
4057 gtk_window_realize (GtkWidget *widget)
4060 GdkWindow *parent_window;
4061 GdkWindowAttr attributes;
4062 gint attributes_mask;
4064 window = GTK_WINDOW (widget);
4066 /* ensure widget tree is properly size allocated */
4067 if (widget->allocation.x == -1 &&
4068 widget->allocation.y == -1 &&
4069 widget->allocation.width == 1 &&
4070 widget->allocation.height == 1)
4072 GtkRequisition requisition;
4073 GtkAllocation allocation = { 0, 0, 200, 200 };
4075 gtk_widget_size_request (widget, &requisition);
4076 if (requisition.width || requisition.height)
4078 /* non-empty window */
4079 allocation.width = requisition.width;
4080 allocation.height = requisition.height;
4082 gtk_widget_size_allocate (widget, &allocation);
4084 _gtk_container_queue_resize (GTK_CONTAINER (widget));
4086 g_return_if_fail (!GTK_WIDGET_REALIZED (widget));
4089 GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED);
4091 switch (window->type)
4093 case GTK_WINDOW_TOPLEVEL:
4094 attributes.window_type = GDK_WINDOW_TOPLEVEL;
4096 case GTK_WINDOW_POPUP:
4097 attributes.window_type = GDK_WINDOW_TEMP;
4100 g_warning (G_STRLOC": Unknown window type %d!", window->type);
4104 attributes.title = window->title;
4105 attributes.wmclass_name = window->wmclass_name;
4106 attributes.wmclass_class = window->wmclass_class;
4107 attributes.wclass = GDK_INPUT_OUTPUT;
4108 attributes.visual = gtk_widget_get_visual (widget);
4109 attributes.colormap = gtk_widget_get_colormap (widget);
4111 if (window->has_frame)
4113 attributes.width = widget->allocation.width + window->frame_left + window->frame_right;
4114 attributes.height = widget->allocation.height + window->frame_top + window->frame_bottom;
4115 attributes.event_mask = (GDK_EXPOSURE_MASK |
4116 GDK_KEY_PRESS_MASK |
4117 GDK_ENTER_NOTIFY_MASK |
4118 GDK_LEAVE_NOTIFY_MASK |
4119 GDK_FOCUS_CHANGE_MASK |
4120 GDK_STRUCTURE_MASK |
4121 GDK_BUTTON_MOTION_MASK |
4122 GDK_POINTER_MOTION_HINT_MASK |
4123 GDK_BUTTON_PRESS_MASK |
4124 GDK_BUTTON_RELEASE_MASK);
4126 attributes_mask = GDK_WA_VISUAL | GDK_WA_COLORMAP;
4128 window->frame = gdk_window_new (gtk_widget_get_root_window (widget),
4129 &attributes, attributes_mask);
4131 gdk_window_set_user_data (window->frame, widget);
4133 attributes.window_type = GDK_WINDOW_CHILD;
4134 attributes.x = window->frame_left;
4135 attributes.y = window->frame_top;
4137 attributes_mask = GDK_WA_X | GDK_WA_Y;
4139 parent_window = window->frame;
4143 attributes_mask = 0;
4144 parent_window = gtk_widget_get_root_window (widget);
4147 attributes.width = widget->allocation.width;
4148 attributes.height = widget->allocation.height;
4149 attributes.event_mask = gtk_widget_get_events (widget);
4150 attributes.event_mask |= (GDK_EXPOSURE_MASK |
4151 GDK_KEY_PRESS_MASK |
4152 GDK_KEY_RELEASE_MASK |
4153 GDK_ENTER_NOTIFY_MASK |
4154 GDK_LEAVE_NOTIFY_MASK |
4155 GDK_FOCUS_CHANGE_MASK |
4156 GDK_STRUCTURE_MASK);
4158 attributes_mask |= GDK_WA_VISUAL | GDK_WA_COLORMAP;
4159 attributes_mask |= (window->title ? GDK_WA_TITLE : 0);
4160 attributes_mask |= (window->wmclass_name ? GDK_WA_WMCLASS : 0);
4162 widget->window = gdk_window_new (parent_window, &attributes, attributes_mask);
4164 gdk_window_enable_synchronized_configure (widget->window);
4166 gdk_window_set_user_data (widget->window, window);
4168 widget->style = gtk_style_attach (widget->style, widget->window);
4169 gtk_style_set_background (widget->style, widget->window, GTK_STATE_NORMAL);
4171 gtk_style_set_background (widget->style, window->frame, GTK_STATE_NORMAL);
4173 /* This is a bad hack to set the window background. */
4174 gtk_window_paint (widget, NULL);
4176 if (window->transient_parent &&
4177 GTK_WIDGET_REALIZED (window->transient_parent))
4178 gdk_window_set_transient_for (widget->window,
4179 GTK_WIDGET (window->transient_parent)->window);
4181 if (window->wm_role)
4182 gdk_window_set_role (widget->window, window->wm_role);
4184 if (!window->decorated)
4185 gdk_window_set_decorations (widget->window, 0);
4187 gdk_window_set_type_hint (widget->window, window->type_hint);
4189 if (gtk_window_get_skip_pager_hint (window))
4190 gdk_window_set_skip_pager_hint (widget->window, TRUE);
4192 if (gtk_window_get_skip_taskbar_hint (window))
4193 gdk_window_set_skip_taskbar_hint (widget->window, TRUE);
4195 if (gtk_window_get_accept_focus (window))
4196 gdk_window_set_accept_focus (widget->window, TRUE);
4198 gdk_window_set_accept_focus (widget->window, FALSE);
4200 if (gtk_window_get_focus_on_map (window))
4201 gdk_window_set_focus_on_map (widget->window, TRUE);
4203 gdk_window_set_focus_on_map (widget->window, FALSE);
4206 gdk_window_set_modal_hint (widget->window, TRUE);
4208 gdk_window_set_modal_hint (widget->window, FALSE);
4211 gtk_window_realize_icon (window);
4215 gtk_window_unrealize (GtkWidget *widget)
4218 GtkWindowGeometryInfo *info;
4220 window = GTK_WINDOW (widget);
4222 /* On unrealize, we reset the size of the window such
4223 * that we will re-apply the default sizing stuff
4224 * next time we show the window.
4226 * Default positioning is reset on unmap, instead of unrealize.
4228 window->need_default_size = TRUE;
4229 info = gtk_window_get_geometry_info (window, FALSE);
4232 info->resize_width = -1;
4233 info->resize_height = -1;
4234 info->last.configure_request.x = 0;
4235 info->last.configure_request.y = 0;
4236 info->last.configure_request.width = -1;
4237 info->last.configure_request.height = -1;
4238 /* be sure we reset geom hints on re-realize */
4239 info->last.flags = 0;
4244 gdk_window_set_user_data (window->frame, NULL);
4245 gdk_window_destroy (window->frame);
4246 window->frame = NULL;
4250 gtk_window_unrealize_icon (window);
4252 (* GTK_WIDGET_CLASS (parent_class)->unrealize) (widget);
4256 gtk_window_size_request (GtkWidget *widget,
4257 GtkRequisition *requisition)
4262 window = GTK_WINDOW (widget);
4263 bin = GTK_BIN (window);
4265 requisition->width = GTK_CONTAINER (window)->border_width * 2;
4266 requisition->height = GTK_CONTAINER (window)->border_width * 2;
4268 if (bin->child && GTK_WIDGET_VISIBLE (bin->child))
4270 GtkRequisition child_requisition;
4272 gtk_widget_size_request (bin->child, &child_requisition);
4274 requisition->width += child_requisition.width;
4275 requisition->height += child_requisition.height;
4280 gtk_window_size_allocate (GtkWidget *widget,
4281 GtkAllocation *allocation)
4284 GtkAllocation child_allocation;
4286 window = GTK_WINDOW (widget);
4287 widget->allocation = *allocation;
4289 if (window->bin.child && GTK_WIDGET_VISIBLE (window->bin.child))
4291 child_allocation.x = GTK_CONTAINER (window)->border_width;
4292 child_allocation.y = GTK_CONTAINER (window)->border_width;
4293 child_allocation.width =
4294 MAX (1, (gint)allocation->width - child_allocation.x * 2);
4295 child_allocation.height =
4296 MAX (1, (gint)allocation->height - child_allocation.y * 2);
4298 gtk_widget_size_allocate (window->bin.child, &child_allocation);
4301 if (GTK_WIDGET_REALIZED (widget) && window->frame)
4303 gdk_window_resize (window->frame,
4304 allocation->width + window->frame_left + window->frame_right,
4305 allocation->height + window->frame_top + window->frame_bottom);
4310 gtk_window_event (GtkWidget *widget, GdkEvent *event)
4313 gboolean return_val;
4315 window = GTK_WINDOW (widget);
4317 if (window->frame && (event->any.window == window->frame))
4319 if ((event->type != GDK_KEY_PRESS) &&
4320 (event->type != GDK_KEY_RELEASE) &&
4321 (event->type != GDK_FOCUS_CHANGE))
4323 g_signal_stop_emission_by_name (widget, "event");
4325 g_signal_emit (widget, window_signals[FRAME_EVENT], 0, event, &return_val);
4330 g_object_unref (event->any.window);
4331 event->any.window = g_object_ref (widget->window);
4339 gtk_window_frame_event (GtkWindow *window, GdkEvent *event)
4341 GdkEventConfigure *configure_event;
4344 switch (event->type)
4347 configure_event = (GdkEventConfigure *)event;
4349 /* Invalidate the decorations */
4352 rect.width = configure_event->width;
4353 rect.height = configure_event->height;
4355 gdk_window_invalidate_rect (window->frame, &rect, FALSE);
4357 /* Pass on the (modified) configure event */
4358 configure_event->width -= window->frame_left + window->frame_right;
4359 configure_event->height -= window->frame_top + window->frame_bottom;
4360 return gtk_window_configure_event (GTK_WIDGET (window), configure_event);
4369 gtk_window_configure_event (GtkWidget *widget,
4370 GdkEventConfigure *event)
4372 GtkWindow *window = GTK_WINDOW (widget);
4373 gboolean expected_reply = window->configure_request_count > 0;
4375 /* window->configure_request_count incremented for each
4376 * configure request, and decremented to a min of 0 for
4377 * each configure notify.
4379 * All it means is that we know we will get at least
4380 * window->configure_request_count more configure notifies.
4381 * We could get more configure notifies than that; some
4382 * of the configure notifies we get may be unrelated to
4383 * the configure requests. But we will get at least
4384 * window->configure_request_count notifies.
4387 if (window->configure_request_count > 0)
4388 window->configure_request_count -= 1;
4390 /* As an optimization, we avoid a resize when possible.
4392 * The only times we can avoid a resize are:
4393 * - we know only the position changed, not the size
4394 * - we know we have made more requests and so will get more
4395 * notifies and can wait to resize when we get them
4398 if (!expected_reply &&
4399 (widget->allocation.width == event->width &&
4400 widget->allocation.height == event->height))
4402 gdk_window_configure_finished (widget->window);
4407 * If we do need to resize, we do that by:
4408 * - filling in widget->allocation with the new size
4409 * - setting configure_notify_received to TRUE
4410 * for use in gtk_window_move_resize()
4411 * - queueing a resize, leading to invocation of
4412 * gtk_window_move_resize() in an idle handler
4416 window->configure_notify_received = TRUE;
4418 widget->allocation.width = event->width;
4419 widget->allocation.height = event->height;
4421 _gtk_container_queue_resize (GTK_CONTAINER (widget));
4426 /* the accel_key and accel_mods fields of the key have to be setup
4427 * upon calling this function. it'll then return whether that key
4428 * is at all used as accelerator, and if so will OR in the
4429 * accel_flags member of the key.
4432 _gtk_window_query_nonaccels (GtkWindow *window,
4434 GdkModifierType accel_mods)
4436 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
4438 /* movement keys are considered locked accels */
4441 static const guint bindings[] = {
4442 GDK_space, GDK_KP_Space, GDK_Return, GDK_KP_Enter, GDK_Up, GDK_KP_Up, GDK_Down, GDK_KP_Down,
4443 GDK_Left, GDK_KP_Left, GDK_Right, GDK_KP_Right, GDK_Tab, GDK_KP_Tab, GDK_ISO_Left_Tab,
4447 for (i = 0; i < G_N_ELEMENTS (bindings); i++)
4448 if (bindings[i] == accel_key)
4452 /* mnemonics are considered locked accels */
4453 if (accel_mods == window->mnemonic_modifier)
4455 GtkMnemonicHash *mnemonic_hash = gtk_window_get_mnemonic_hash (window, FALSE);
4456 if (mnemonic_hash && _gtk_mnemonic_hash_lookup (mnemonic_hash, accel_key))
4464 * gtk_window_propagate_key_event:
4465 * @window: a #GtkWindow
4466 * @event: a #GdkEventKey
4468 * Propagate a key press or release event to the focus widget and
4469 * up the focus container chain until a widget handles @event.
4470 * This is normally called by the default ::key_press_event and
4471 * ::key_release_event handlers for toplevel windows,
4472 * however in some cases it may be useful to call this directly when
4473 * overriding the standard key handling for a toplevel window.
4475 * Return value: %TRUE if a widget in the focus chain handled the event.
4478 gtk_window_propagate_key_event (GtkWindow *window,
4481 gboolean handled = FALSE;
4482 GtkWidget *widget, *focus;
4484 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
4486 widget = GTK_WIDGET (window);
4487 focus = window->focus_widget;
4489 g_object_ref (focus);
4492 focus && focus != widget &&
4493 gtk_widget_get_toplevel (focus) == widget)
4497 if (GTK_WIDGET_IS_SENSITIVE (focus))
4498 handled = gtk_widget_event (focus, (GdkEvent*) event);
4500 parent = focus->parent;
4502 g_object_ref (parent);
4504 g_object_unref (focus);
4510 g_object_unref (focus);
4516 gtk_window_key_press_event (GtkWidget *widget,
4519 GtkWindow *window = GTK_WINDOW (widget);
4520 gboolean handled = FALSE;
4522 /* handle mnemonics and accelerators */
4524 handled = gtk_window_activate_key (window, event);
4526 /* handle focus widget key events */
4528 handled = gtk_window_propagate_key_event (window, event);
4530 /* Chain up, invokes binding set */
4532 handled = GTK_WIDGET_CLASS (parent_class)->key_press_event (widget, event);
4538 gtk_window_key_release_event (GtkWidget *widget,
4541 GtkWindow *window = GTK_WINDOW (widget);
4542 gboolean handled = FALSE;
4544 /* handle focus widget key events */
4546 handled = gtk_window_propagate_key_event (window, event);
4548 /* Chain up, invokes binding set */
4550 handled = GTK_WIDGET_CLASS (parent_class)->key_press_event (widget, event);
4556 gtk_window_real_activate_default (GtkWindow *window)
4558 gtk_window_activate_default (window);
4562 gtk_window_real_activate_focus (GtkWindow *window)
4564 gtk_window_activate_focus (window);
4568 gtk_window_move_focus (GtkWindow *window,
4569 GtkDirectionType dir)
4571 gtk_widget_child_focus (GTK_WIDGET (window), dir);
4573 if (!GTK_CONTAINER (window)->focus_child)
4574 gtk_window_set_focus (window, NULL);
4578 gtk_window_enter_notify_event (GtkWidget *widget,
4579 GdkEventCrossing *event)
4585 gtk_window_leave_notify_event (GtkWidget *widget,
4586 GdkEventCrossing *event)
4592 do_focus_change (GtkWidget *widget,
4595 GdkEvent *fevent = gdk_event_new (GDK_FOCUS_CHANGE);
4597 g_object_ref (widget);
4600 GTK_WIDGET_SET_FLAGS (widget, GTK_HAS_FOCUS);
4602 GTK_WIDGET_UNSET_FLAGS (widget, GTK_HAS_FOCUS);
4604 fevent->focus_change.type = GDK_FOCUS_CHANGE;
4605 fevent->focus_change.window = widget->window;
4607 g_object_ref (widget->window);
4608 fevent->focus_change.in = in;
4610 gtk_widget_event (widget, fevent);
4612 g_object_notify (G_OBJECT (widget), "has-focus");
4614 g_object_unref (widget);
4615 gdk_event_free (fevent);
4619 gtk_window_focus_in_event (GtkWidget *widget,
4620 GdkEventFocus *event)
4622 GtkWindow *window = GTK_WINDOW (widget);
4624 /* It appears spurious focus in events can occur when
4625 * the window is hidden. So we'll just check to see if
4626 * the window is visible before actually handling the
4629 if (GTK_WIDGET_VISIBLE (widget))
4631 _gtk_window_set_has_toplevel_focus (window, TRUE);
4632 _gtk_window_set_is_active (window, TRUE);
4639 gtk_window_focus_out_event (GtkWidget *widget,
4640 GdkEventFocus *event)
4642 GtkWindow *window = GTK_WINDOW (widget);
4644 _gtk_window_set_has_toplevel_focus (window, FALSE);
4645 _gtk_window_set_is_active (window, FALSE);
4650 static GdkAtom atom_rcfiles = GDK_NONE;
4653 gtk_window_read_rcfiles (GtkWidget *widget,
4654 GdkEventClient *event)
4656 GList *embedded_windows;
4658 embedded_windows = g_object_get_data (G_OBJECT (widget), "gtk-embedded");
4659 if (embedded_windows)
4661 GdkEvent *send_event = gdk_event_new (GDK_CLIENT_EVENT);
4664 for (i = 0; i < 5; i++)
4665 send_event->client.data.l[i] = 0;
4666 send_event->client.data_format = 32;
4667 send_event->client.message_type = atom_rcfiles;
4669 while (embedded_windows)
4671 guint xid = GPOINTER_TO_UINT (embedded_windows->data);
4672 gdk_event_send_client_message_for_display (gtk_widget_get_display (widget), send_event, xid);
4673 embedded_windows = embedded_windows->next;
4676 gdk_event_free (send_event);
4679 gtk_rc_reparse_all_for_settings (gtk_widget_get_settings (widget), FALSE);
4683 gtk_window_client_event (GtkWidget *widget,
4684 GdkEventClient *event)
4687 atom_rcfiles = gdk_atom_intern ("_GTK_READ_RCFILES", FALSE);
4689 if (event->message_type == atom_rcfiles)
4690 gtk_window_read_rcfiles (widget, event);
4696 gtk_window_check_resize (GtkContainer *container)
4698 GtkWindow *window = GTK_WINDOW (container);
4700 if (GTK_WIDGET_VISIBLE (container))
4701 gtk_window_move_resize (window);
4705 gtk_window_focus (GtkWidget *widget,
4706 GtkDirectionType direction)
4710 GtkContainer *container;
4711 GtkWidget *old_focus_child;
4714 container = GTK_CONTAINER (widget);
4715 window = GTK_WINDOW (widget);
4716 bin = GTK_BIN (widget);
4718 old_focus_child = container->focus_child;
4720 /* We need a special implementation here to deal properly with wrapping
4721 * around in the tab chain without the danger of going into an
4724 if (old_focus_child)
4726 if (gtk_widget_child_focus (old_focus_child, direction))
4730 if (window->focus_widget)
4732 if (direction == GTK_DIR_LEFT ||
4733 direction == GTK_DIR_RIGHT ||
4734 direction == GTK_DIR_UP ||
4735 direction == GTK_DIR_DOWN)
4740 /* Wrapped off the end, clear the focus setting for the toplpevel */
4741 parent = window->focus_widget->parent;
4744 gtk_container_set_focus_child (GTK_CONTAINER (parent), NULL);
4745 parent = GTK_WIDGET (parent)->parent;
4748 gtk_window_set_focus (GTK_WINDOW (container), NULL);
4751 /* Now try to focus the first widget in the window */
4754 if (gtk_widget_child_focus (bin->child, direction))
4762 gtk_window_real_set_focus (GtkWindow *window,
4765 GtkWidget *old_focus = window->focus_widget;
4766 gboolean had_default = FALSE;
4767 gboolean focus_had_default = FALSE;
4768 gboolean old_focus_had_default = FALSE;
4772 g_object_ref (old_focus);
4773 g_object_freeze_notify (G_OBJECT (old_focus));
4774 old_focus_had_default = GTK_WIDGET_HAS_DEFAULT (old_focus);
4778 g_object_ref (focus);
4779 g_object_freeze_notify (G_OBJECT (focus));
4780 focus_had_default = GTK_WIDGET_HAS_DEFAULT (focus);
4783 if (window->default_widget)
4784 had_default = GTK_WIDGET_HAS_DEFAULT (window->default_widget);
4786 if (window->focus_widget)
4788 if (GTK_WIDGET_RECEIVES_DEFAULT (window->focus_widget) &&
4789 (window->focus_widget != window->default_widget))
4791 GTK_WIDGET_UNSET_FLAGS (window->focus_widget, GTK_HAS_DEFAULT);
4792 gtk_widget_queue_draw (window->focus_widget);
4794 if (window->default_widget)
4795 GTK_WIDGET_SET_FLAGS (window->default_widget, GTK_HAS_DEFAULT);
4798 window->focus_widget = NULL;
4800 if (window->has_focus)
4801 do_focus_change (old_focus, FALSE);
4803 g_object_notify (G_OBJECT (old_focus), "is-focus");
4806 /* The above notifications may have set a new focus widget,
4807 * if so, we don't want to override it.
4809 if (focus && !window->focus_widget)
4811 window->focus_widget = focus;
4813 if (GTK_WIDGET_RECEIVES_DEFAULT (window->focus_widget) &&
4814 (window->focus_widget != window->default_widget))
4816 if (GTK_WIDGET_CAN_DEFAULT (window->focus_widget))
4817 GTK_WIDGET_SET_FLAGS (window->focus_widget, GTK_HAS_DEFAULT);
4819 if (window->default_widget)
4820 GTK_WIDGET_UNSET_FLAGS (window->default_widget, GTK_HAS_DEFAULT);
4823 if (window->has_focus)
4824 do_focus_change (window->focus_widget, TRUE);
4826 g_object_notify (G_OBJECT (window->focus_widget), "is-focus");
4829 /* If the default widget changed, a redraw will have been queued
4830 * on the old and new default widgets by gtk_window_set_default(), so
4831 * we only have to worry about the case where it didn't change.
4832 * We'll sometimes queue a draw twice on the new widget but that
4835 if (window->default_widget &&
4836 (had_default != GTK_WIDGET_HAS_DEFAULT (window->default_widget)))
4837 gtk_widget_queue_draw (window->default_widget);
4841 if (old_focus_had_default != GTK_WIDGET_HAS_DEFAULT (old_focus))
4842 gtk_widget_queue_draw (old_focus);
4844 g_object_thaw_notify (G_OBJECT (old_focus));
4845 g_object_unref (old_focus);
4849 if (focus_had_default != GTK_WIDGET_HAS_DEFAULT (focus))
4850 gtk_widget_queue_draw (focus);
4852 g_object_thaw_notify (G_OBJECT (focus));
4853 g_object_unref (focus);
4858 * _gtk_window_unset_focus_and_default:
4859 * @window: a #GtkWindow
4860 * @widget: a widget inside of @window
4862 * Checks whether the focus and default widgets of @window are
4863 * @widget or a descendent of @widget, and if so, unset them.
4866 _gtk_window_unset_focus_and_default (GtkWindow *window,
4872 g_object_ref (window);
4873 g_object_ref (widget);
4875 if (GTK_CONTAINER (widget->parent)->focus_child == widget)
4877 child = window->focus_widget;
4879 while (child && child != widget)
4880 child = child->parent;
4882 if (child == widget)
4883 gtk_window_set_focus (GTK_WINDOW (window), NULL);
4886 child = window->default_widget;
4888 while (child && child != widget)
4889 child = child->parent;
4891 if (child == widget)
4892 gtk_window_set_default (window, NULL);
4894 g_object_unref (widget);
4895 g_object_unref (window);
4898 /*********************************
4899 * Functions related to resizing *
4900 *********************************/
4902 /* This function doesn't constrain to geometry hints */
4904 gtk_window_compute_configure_request_size (GtkWindow *window,
4908 GtkRequisition requisition;
4909 GtkWindowGeometryInfo *info;
4913 * - we've done a size request
4916 widget = GTK_WIDGET (window);
4918 info = gtk_window_get_geometry_info (window, FALSE);
4920 if (window->need_default_size)
4922 gtk_widget_get_child_requisition (widget, &requisition);
4924 /* Default to requisition */
4925 *width = requisition.width;
4926 *height = requisition.height;
4928 /* If window is empty so requests 0, default to random nonzero size */
4929 if (*width == 0 && *height == 0)
4935 /* Override requisition with default size */
4939 gint base_width = 0;
4940 gint base_height = 0;
4942 gint height_inc = 1;
4944 if (info->default_is_geometry &&
4945 (info->default_width > 0 || info->default_height > 0))
4947 GdkGeometry geometry;
4950 gtk_window_compute_hints (window, &geometry, &flags);
4952 if (flags & GDK_HINT_BASE_SIZE)
4954 base_width = geometry.base_width;
4955 base_height = geometry.base_height;
4957 else if (flags & GDK_HINT_MIN_SIZE)
4959 base_width = geometry.min_width;
4960 base_height = geometry.min_height;
4962 if (flags & GDK_HINT_RESIZE_INC)
4964 width_inc = geometry.width_inc;
4965 height_inc = geometry.height_inc;
4969 if (info->default_width > 0)
4970 *width = info->default_width * width_inc + base_width;
4972 if (info->default_height > 0)
4973 *height = info->default_height * height_inc + base_height;
4978 /* Default to keeping current size */
4979 *width = widget->allocation.width;
4980 *height = widget->allocation.height;
4983 /* Override any size with gtk_window_resize() values */
4986 if (info->resize_width > 0)
4987 *width = info->resize_width;
4989 if (info->resize_height > 0)
4990 *height = info->resize_height;
4994 static GtkWindowPosition
4995 get_effective_position (GtkWindow *window)
4997 GtkWindowPosition pos = window->position;
4998 if (pos == GTK_WIN_POS_CENTER_ON_PARENT &&
4999 (window->transient_parent == NULL ||
5000 !GTK_WIDGET_MAPPED (window->transient_parent)))
5001 pos = GTK_WIN_POS_NONE;
5007 get_center_monitor_of_window (GtkWindow *window)
5009 /* We could try to sort out the relative positions of the monitors and
5010 * stuff, or we could just be losers and assume you have a row
5011 * or column of monitors.
5013 return gdk_screen_get_n_monitors (gtk_window_check_screen (window)) / 2;
5017 get_monitor_containing_pointer (GtkWindow *window)
5021 GdkScreen *window_screen;
5022 GdkScreen *pointer_screen;
5024 window_screen = gtk_window_check_screen (window);
5025 gdk_display_get_pointer (gdk_screen_get_display (window_screen),
5029 if (pointer_screen == window_screen)
5030 monitor_num = gdk_screen_get_monitor_at_point (pointer_screen, px, py);
5038 center_window_on_monitor (GtkWindow *window,
5044 GdkRectangle monitor;
5047 monitor_num = get_monitor_containing_pointer (window);
5049 if (monitor_num == -1)
5050 monitor_num = get_center_monitor_of_window (window);
5052 gdk_screen_get_monitor_geometry (gtk_window_check_screen (window),
5053 monitor_num, &monitor);
5055 *x = (monitor.width - w) / 2 + monitor.x;
5056 *y = (monitor.height - h) / 2 + monitor.y;
5058 /* Be sure we aren't off the monitor, ignoring _NET_WM_STRUT
5059 * and WM decorations.
5068 clamp_window_to_rectangle (gint *x,
5072 const GdkRectangle *rect)
5074 gint outside_w, outside_h;
5076 outside_w = (*x + w) - (rect->x + rect->width);
5080 outside_h = (*y + h) - (rect->y + rect->height);
5084 /* if larger than the screen, center on the screen. */
5086 *x += (rect->x - *x) / 2;
5088 *y += (rect->y - *y) / 2;
5093 gtk_window_compute_configure_request (GtkWindow *window,
5094 GdkRectangle *request,
5095 GdkGeometry *geometry,
5098 GdkGeometry new_geometry;
5102 GtkWindowPosition pos;
5103 GtkWidget *parent_widget;
5104 GtkWindowGeometryInfo *info;
5108 widget = GTK_WIDGET (window);
5110 screen = gtk_window_check_screen (window);
5112 gtk_widget_size_request (widget, NULL);
5113 gtk_window_compute_configure_request_size (window, &w, &h);
5115 gtk_window_compute_hints (window, &new_geometry, &new_flags);
5116 gtk_window_constrain_size (window,
5117 &new_geometry, new_flags,
5121 parent_widget = (GtkWidget*) window->transient_parent;
5123 pos = get_effective_position (window);
5124 info = gtk_window_get_geometry_info (window, TRUE);
5126 /* by default, don't change position requested */
5127 x = info->last.configure_request.x;
5128 y = info->last.configure_request.y;
5130 if (window->need_default_position)
5133 /* FIXME this all interrelates with window gravity.
5134 * For most of them I think we want to set GRAVITY_CENTER.
5136 * Not sure how to go about that.
5141 /* here we are only handling CENTER_ALWAYS
5142 * as it relates to default positioning,
5143 * where it's equivalent to simply CENTER
5145 case GTK_WIN_POS_CENTER_ALWAYS:
5146 case GTK_WIN_POS_CENTER:
5147 center_window_on_monitor (window, w, h, &x, &y);
5150 case GTK_WIN_POS_CENTER_ON_PARENT:
5153 GdkRectangle monitor;
5156 g_assert (GTK_WIDGET_MAPPED (parent_widget)); /* established earlier */
5158 if (parent_widget->window != NULL)
5159 monitor_num = gdk_screen_get_monitor_at_window (screen,
5160 parent_widget->window);
5164 gdk_window_get_origin (parent_widget->window,
5167 x = ox + (parent_widget->allocation.width - w) / 2;
5168 y = oy + (parent_widget->allocation.height - h) / 2;
5170 /* Clamp onto current monitor, ignoring _NET_WM_STRUT and
5171 * WM decorations. If parent wasn't on a monitor, just
5174 if (monitor_num >= 0)
5176 gdk_screen_get_monitor_geometry (screen, monitor_num, &monitor);
5177 clamp_window_to_rectangle (&x, &y, w, h, &monitor);
5182 case GTK_WIN_POS_MOUSE:
5184 gint screen_width = gdk_screen_get_width (screen);
5185 gint screen_height = gdk_screen_get_height (screen);
5187 GdkRectangle monitor;
5188 GdkScreen *pointer_screen;
5191 gdk_display_get_pointer (gdk_screen_get_display (screen),
5195 if (pointer_screen == screen)
5196 monitor_num = gdk_screen_get_monitor_at_point (screen, px, py);
5202 x = CLAMP (x, 0, screen_width - w);
5203 y = CLAMP (y, 0, screen_height - h);
5205 /* Clamp onto current monitor, ignoring _NET_WM_STRUT and
5206 * WM decorations. Don't try to figure out what's going
5207 * on if the mouse wasn't inside a monitor.
5209 if (monitor_num >= 0)
5211 gdk_screen_get_monitor_geometry (screen, monitor_num, &monitor);
5212 clamp_window_to_rectangle (&x, &y, w, h, &monitor);
5220 } /* if (window->need_default_position) */
5222 if (window->need_default_position &&
5223 info->initial_pos_set)
5225 x = info->initial_x;
5226 y = info->initial_y;
5227 gtk_window_constrain_position (window, w, h, &x, &y);
5233 request->height = h;
5236 *geometry = new_geometry;
5242 gtk_window_constrain_position (GtkWindow *window,
5248 /* See long comments in gtk_window_move_resize()
5249 * on when it's safe to call this function.
5251 if (window->position == GTK_WIN_POS_CENTER_ALWAYS)
5253 gint center_x, center_y;
5255 center_window_on_monitor (window, new_width, new_height, ¢er_x, ¢er_y);
5263 gtk_window_move_resize (GtkWindow *window)
5267 * First we determine whether any information has changed that would
5268 * cause us to revise our last configure request. If we would send
5269 * a different configure request from last time, then
5270 * configure_request_size_changed = TRUE or
5271 * configure_request_pos_changed = TRUE. configure_request_size_changed
5272 * may be true due to new hints, a gtk_window_resize(), or whatever.
5273 * configure_request_pos_changed may be true due to gtk_window_set_position()
5274 * or gtk_window_move().
5276 * If the configure request has changed, we send off a new one. To
5277 * ensure GTK+ invariants are maintained (resize queue does what it
5278 * should), we go ahead and size_allocate the requested size in this
5281 * If the configure request has not changed, we don't ever resend
5282 * it, because it could mean fighting the user or window manager.
5285 * To prepare the configure request, we come up with a base size/pos:
5286 * - the one from gtk_window_move()/gtk_window_resize()
5287 * - else default_width, default_height if we haven't ever
5289 * - else the size request if we haven't ever been mapped,
5290 * as a substitute default size
5291 * - else the current size of the window, as received from
5292 * configure notifies (i.e. the current allocation)
5294 * If GTK_WIN_POS_CENTER_ALWAYS is active, we constrain
5295 * the position request to be centered.
5298 GtkContainer *container;
5299 GtkWindowGeometryInfo *info;
5300 GdkGeometry new_geometry;
5302 GdkRectangle new_request;
5303 gboolean configure_request_size_changed;
5304 gboolean configure_request_pos_changed;
5305 gboolean hints_changed; /* do we need to send these again */
5306 GtkWindowLastGeometryInfo saved_last_info;
5308 widget = GTK_WIDGET (window);
5309 container = GTK_CONTAINER (widget);
5310 info = gtk_window_get_geometry_info (window, TRUE);
5312 configure_request_size_changed = FALSE;
5313 configure_request_pos_changed = FALSE;
5315 gtk_window_compute_configure_request (window, &new_request,
5316 &new_geometry, &new_flags);
5318 /* This check implies the invariant that we never set info->last
5319 * without setting the hints and sending off a configure request.
5321 * If we change info->last without sending the request, we may
5324 if (info->last.configure_request.x != new_request.x ||
5325 info->last.configure_request.y != new_request.y)
5326 configure_request_pos_changed = TRUE;
5328 if ((info->last.configure_request.width != new_request.width ||
5329 info->last.configure_request.height != new_request.height))
5330 configure_request_size_changed = TRUE;
5332 hints_changed = FALSE;
5334 if (!gtk_window_compare_hints (&info->last.geometry, info->last.flags,
5335 &new_geometry, new_flags))
5337 hints_changed = TRUE;
5340 /* Position Constraints
5341 * ====================
5343 * POS_CENTER_ALWAYS is conceptually a constraint rather than
5344 * a default. The other POS_ values are used only when the
5345 * window is shown, not after that.
5347 * However, we can't implement a position constraint as
5348 * "anytime the window size changes, center the window"
5349 * because this may well end up fighting the WM or user. In
5350 * fact it gets in an infinite loop with at least one WM.
5352 * Basically, applications are in no way in a position to
5353 * constrain the position of a window, with one exception:
5354 * override redirect windows. (Really the intended purpose
5355 * of CENTER_ALWAYS anyhow, I would think.)
5357 * So the way we implement this "constraint" is to say that when WE
5358 * cause a move or resize, i.e. we make a configure request changing
5359 * window size, we recompute the CENTER_ALWAYS position to reflect
5360 * the new window size, and include it in our request. Also, if we
5361 * just turned on CENTER_ALWAYS we snap to center with a new
5362 * request. Otherwise, if we are just NOTIFIED of a move or resize
5363 * done by someone else e.g. the window manager, we do NOT send a
5364 * new configure request.
5366 * For override redirect windows, this works fine; all window
5367 * sizes are from our configure requests. For managed windows,
5368 * it is at least semi-sane, though who knows what the
5369 * app author is thinking.
5372 /* This condition should be kept in sync with the condition later on
5373 * that determines whether we send a configure request. i.e. we
5374 * should do this position constraining anytime we were going to
5375 * send a configure request anyhow, plus when constraints have
5378 if (configure_request_pos_changed ||
5379 configure_request_size_changed ||
5381 info->position_constraints_changed)
5383 /* We request the constrained position if:
5384 * - we were changing position, and need to clamp
5385 * the change to the constraint
5386 * - we're changing the size anyway
5387 * - set_position() was called to toggle CENTER_ALWAYS on
5390 gtk_window_constrain_position (window,
5396 /* Update whether we need to request a move */
5397 if (info->last.configure_request.x != new_request.x ||
5398 info->last.configure_request.y != new_request.y)
5399 configure_request_pos_changed = TRUE;
5401 configure_request_pos_changed = FALSE;
5405 if (window->type == GTK_WINDOW_TOPLEVEL)
5407 int notify_x, notify_y;
5409 /* this is the position from the last configure notify */
5410 gdk_window_get_position (widget->window, ¬ify_x, ¬ify_y);
5412 g_message ("--- %s ---\n"
5413 "last : %d,%d\t%d x %d\n"
5414 "this : %d,%d\t%d x %d\n"
5415 "alloc : %d,%d\t%d x %d\n"
5417 "resize: \t%d x %d\n"
5418 "size_changed: %d pos_changed: %d hints_changed: %d\n"
5419 "configure_notify_received: %d\n"
5420 "configure_request_count: %d\n"
5421 "position_constraints_changed: %d\n",
5422 window->title ? window->title : "(no title)",
5423 info->last.configure_request.x,
5424 info->last.configure_request.y,
5425 info->last.configure_request.width,
5426 info->last.configure_request.height,
5432 widget->allocation.width,
5433 widget->allocation.height,
5434 widget->requisition.width,
5435 widget->requisition.height,
5437 info->resize_height,
5438 configure_request_pos_changed,
5439 configure_request_size_changed,
5441 window->configure_notify_received,
5442 window->configure_request_count,
5443 info->position_constraints_changed);
5447 saved_last_info = info->last;
5448 info->last.geometry = new_geometry;
5449 info->last.flags = new_flags;
5450 info->last.configure_request = new_request;
5452 /* need to set PPosition so the WM will look at our position,
5453 * but we don't want to count PPosition coming and going as a hints
5454 * change for future iterations. So we saved info->last prior to
5458 /* Also, if the initial position was explicitly set, then we always
5459 * toggle on PPosition. This makes gtk_window_move(window, 0, 0)
5463 /* Also, we toggle on PPosition if GTK_WIN_POS_ is in use and
5464 * this is an initial map
5467 if ((configure_request_pos_changed ||
5468 info->initial_pos_set ||
5469 (window->need_default_position &&
5470 get_effective_position (window) != GTK_WIN_POS_NONE)) &&
5471 (new_flags & GDK_HINT_POS) == 0)
5473 new_flags |= GDK_HINT_POS;
5474 hints_changed = TRUE;
5477 /* Set hints if necessary
5480 gdk_window_set_geometry_hints (widget->window,
5484 /* handle resizing/moving and widget tree allocation
5486 if (window->configure_notify_received)
5488 GtkAllocation allocation;
5490 /* If we have received a configure event since
5491 * the last time in this function, we need to
5492 * accept our new size and size_allocate child widgets.
5493 * (see gtk_window_configure_event() for more details).
5495 * 1 or more configure notifies may have been received.
5496 * Also, configure_notify_received will only be TRUE
5497 * if all expected configure notifies have been received
5498 * (one per configure request), as an optimization.
5501 window->configure_notify_received = FALSE;
5503 /* gtk_window_configure_event() filled in widget->allocation */
5504 allocation = widget->allocation;
5505 gtk_widget_size_allocate (widget, &allocation);
5507 gdk_window_process_all_updates ();
5509 gdk_window_configure_finished (widget->window);
5511 /* If the configure request changed, it means that
5513 * 1) coincidentally changed hints or widget properties
5514 * impacting the configure request before getting
5515 * a configure notify, or
5516 * 2) some broken widget is changing its size request
5517 * during size allocation, resulting in
5518 * a false appearance of changed configure request.
5520 * For 1), we could just go ahead and ask for the
5521 * new size right now, but doing that for 2)
5522 * might well be fighting the user (and can even
5523 * trigger a loop). Since we really don't want to
5524 * do that, we requeue a resize in hopes that
5525 * by the time it gets handled, the child has seen
5526 * the light and is willing to go along with the
5527 * new size. (this happens for the zvt widget, since
5528 * the size_allocate() above will have stored the
5529 * requisition corresponding to the new size in the
5532 * This doesn't buy us anything for 1), but it shouldn't
5533 * hurt us too badly, since it is what would have
5534 * happened if we had gotten the configure event before
5535 * the new size had been set.
5538 if (configure_request_size_changed ||
5539 configure_request_pos_changed)
5541 /* Don't change the recorded last info after all, because we
5542 * haven't actually updated to the new info yet - we decided
5543 * to postpone our configure request until later.
5545 info->last = saved_last_info;
5547 gtk_widget_queue_resize (widget); /* migth recurse for GTK_RESIZE_IMMEDIATE */
5550 return; /* Bail out, we didn't really process the move/resize */
5552 else if ((configure_request_size_changed || hints_changed) &&
5553 (widget->allocation.width != new_request.width ||
5554 widget->allocation.height != new_request.height))
5557 /* We are in one of the following situations:
5558 * A. configure_request_size_changed
5559 * our requisition has changed and we need a different window size,
5560 * so we request it from the window manager.
5561 * B. !configure_request_size_changed && hints_changed
5562 * the window manager rejects our size, but we have just changed the
5563 * window manager hints, so there's a chance our request will
5564 * be honoured this time, so we try again.
5566 * However, if the new requisition is the same as the current allocation,
5567 * we don't request it again, since we won't get a ConfigureNotify back from
5568 * the window manager unless it decides to change our requisition. If
5569 * we don't get the ConfigureNotify back, the resize queue will never be run.
5572 /* Now send the configure request */
5573 if (configure_request_pos_changed)
5577 gdk_window_move_resize (window->frame,
5578 new_request.x - window->frame_left,
5579 new_request.y - window->frame_top,
5580 new_request.width + window->frame_left + window->frame_right,
5581 new_request.height + window->frame_top + window->frame_bottom);
5582 gdk_window_resize (widget->window,
5583 new_request.width, new_request.height);
5586 gdk_window_move_resize (widget->window,
5587 new_request.x, new_request.y,
5588 new_request.width, new_request.height);
5590 else /* only size changed */
5593 gdk_window_resize (window->frame,
5594 new_request.width + window->frame_left + window->frame_right,
5595 new_request.height + window->frame_top + window->frame_bottom);
5596 gdk_window_resize (widget->window,
5597 new_request.width, new_request.height);
5600 /* Increment the number of have-not-yet-received-notify requests */
5601 window->configure_request_count += 1;
5603 /* for GTK_RESIZE_QUEUE toplevels, we are now awaiting a new
5604 * configure event in response to our resizing request.
5605 * the configure event will cause a new resize with
5606 * ->configure_notify_received=TRUE.
5607 * until then, we want to
5608 * - discard expose events
5609 * - coalesce resizes for our children
5610 * - defer any window resizes until the configure event arrived
5611 * to achieve this, we queue a resize for the window, but remove its
5612 * resizing handler, so resizing will not be handled from the next
5613 * idle handler but when the configure event arrives.
5615 * FIXME: we should also dequeue the pending redraws here, since
5616 * we handle those ourselves upon ->configure_notify_received==TRUE.
5618 if (container->resize_mode == GTK_RESIZE_QUEUE)
5620 gtk_widget_queue_resize (widget);
5621 _gtk_container_dequeue_resize_handler (container);
5626 /* Handle any position changes.
5628 if (configure_request_pos_changed)
5632 gdk_window_move (window->frame,
5633 new_request.x - window->frame_left,
5634 new_request.y - window->frame_top);
5637 gdk_window_move (widget->window,
5638 new_request.x, new_request.y);
5641 /* And run the resize queue.
5643 gtk_container_resize_children (container);
5646 /* We have now processed a move/resize since the last position
5647 * constraint change, setting of the initial position, or resize.
5648 * (Not resetting these flags here can lead to infinite loops for
5649 * GTK_RESIZE_IMMEDIATE containers)
5651 info->position_constraints_changed = FALSE;
5652 info->initial_pos_set = FALSE;
5653 info->resize_width = -1;
5654 info->resize_height = -1;
5657 /* Compare two sets of Geometry hints for equality.
5660 gtk_window_compare_hints (GdkGeometry *geometry_a,
5662 GdkGeometry *geometry_b,
5665 if (flags_a != flags_b)
5668 if ((flags_a & GDK_HINT_MIN_SIZE) &&
5669 (geometry_a->min_width != geometry_b->min_width ||
5670 geometry_a->min_height != geometry_b->min_height))
5673 if ((flags_a & GDK_HINT_MAX_SIZE) &&
5674 (geometry_a->max_width != geometry_b->max_width ||
5675 geometry_a->max_height != geometry_b->max_height))
5678 if ((flags_a & GDK_HINT_BASE_SIZE) &&
5679 (geometry_a->base_width != geometry_b->base_width ||
5680 geometry_a->base_height != geometry_b->base_height))
5683 if ((flags_a & GDK_HINT_ASPECT) &&
5684 (geometry_a->min_aspect != geometry_b->min_aspect ||
5685 geometry_a->max_aspect != geometry_b->max_aspect))
5688 if ((flags_a & GDK_HINT_RESIZE_INC) &&
5689 (geometry_a->width_inc != geometry_b->width_inc ||
5690 geometry_a->height_inc != geometry_b->height_inc))
5693 if ((flags_a & GDK_HINT_WIN_GRAVITY) &&
5694 geometry_a->win_gravity != geometry_b->win_gravity)
5701 _gtk_window_constrain_size (GtkWindow *window,
5707 GtkWindowGeometryInfo *info;
5709 g_return_if_fail (GTK_IS_WINDOW (window));
5711 info = window->geometry_info;
5714 GdkWindowHints flags = info->last.flags;
5715 GdkGeometry *geometry = &info->last.geometry;
5717 gtk_window_constrain_size (window,
5728 gtk_window_constrain_size (GtkWindow *window,
5729 GdkGeometry *geometry,
5736 gdk_window_constrain_size (geometry, flags, width, height,
5737 new_width, new_height);
5740 /* Compute the set of geometry hints and flags for a window
5741 * based on the application set geometry, and requisiition
5742 * of the window. gtk_widget_size_request() must have been
5746 gtk_window_compute_hints (GtkWindow *window,
5747 GdkGeometry *new_geometry,
5751 gint extra_width = 0;
5752 gint extra_height = 0;
5753 GtkWindowGeometryInfo *geometry_info;
5754 GtkRequisition requisition;
5756 widget = GTK_WIDGET (window);
5758 gtk_widget_get_child_requisition (widget, &requisition);
5759 geometry_info = gtk_window_get_geometry_info (GTK_WINDOW (widget), FALSE);
5763 *new_flags = geometry_info->mask;
5764 *new_geometry = geometry_info->geometry;
5771 if (geometry_info && geometry_info->widget)
5773 GtkRequisition child_requisition;
5775 /* FIXME: This really isn't right. It gets the min size wrong and forces
5776 * callers to do horrible hacks like set a huge usize on the child requisition
5777 * to get the base size right. We really want to find the answers to:
5779 * - If the geometry widget was infinitely big, how much extra space
5780 * would be needed for the stuff around it.
5782 * - If the geometry widget was infinitely small, how big would the
5783 * window still have to be.
5785 * Finding these answers would be a bit of a mess here. (Bug #68668)
5787 gtk_widget_get_child_requisition (geometry_info->widget, &child_requisition);
5789 extra_width = widget->requisition.width - child_requisition.width;
5790 extra_height = widget->requisition.height - child_requisition.height;
5793 /* We don't want to set GDK_HINT_POS in here, we just set it
5794 * in gtk_window_move_resize() when we want the position
5798 if (*new_flags & GDK_HINT_BASE_SIZE)
5800 new_geometry->base_width += extra_width;
5801 new_geometry->base_height += extra_height;
5803 else if (!(*new_flags & GDK_HINT_MIN_SIZE) &&
5804 (*new_flags & GDK_HINT_RESIZE_INC) &&
5805 ((extra_width != 0) || (extra_height != 0)))
5807 *new_flags |= GDK_HINT_BASE_SIZE;
5809 new_geometry->base_width = extra_width;
5810 new_geometry->base_height = extra_height;
5813 if (*new_flags & GDK_HINT_MIN_SIZE)
5815 if (new_geometry->min_width < 0)
5816 new_geometry->min_width = requisition.width;
5818 new_geometry->min_width += extra_width;
5820 if (new_geometry->min_height < 0)
5821 new_geometry->min_height = requisition.height;
5823 new_geometry->min_height += extra_height;
5825 else if (!window->allow_shrink)
5827 *new_flags |= GDK_HINT_MIN_SIZE;
5829 new_geometry->min_width = requisition.width;
5830 new_geometry->min_height = requisition.height;
5833 if (*new_flags & GDK_HINT_MAX_SIZE)
5835 if (new_geometry->max_width < 0)
5836 new_geometry->max_width = requisition.width;
5838 new_geometry->max_width += extra_width;
5840 if (new_geometry->max_height < 0)
5841 new_geometry->max_height = requisition.height;
5843 new_geometry->max_height += extra_height;
5845 else if (!window->allow_grow)
5847 *new_flags |= GDK_HINT_MAX_SIZE;
5849 new_geometry->max_width = requisition.width;
5850 new_geometry->max_height = requisition.height;
5853 *new_flags |= GDK_HINT_WIN_GRAVITY;
5854 new_geometry->win_gravity = window->gravity;
5857 /***********************
5858 * Redrawing functions *
5859 ***********************/
5862 gtk_window_paint (GtkWidget *widget,
5865 gtk_paint_flat_box (widget->style, widget->window, GTK_STATE_NORMAL,
5866 GTK_SHADOW_NONE, area, widget, "base", 0, 0, -1, -1);
5870 gtk_window_expose (GtkWidget *widget,
5871 GdkEventExpose *event)
5873 if (!GTK_WIDGET_APP_PAINTABLE (widget))
5874 gtk_window_paint (widget, &event->area);
5876 if (GTK_WIDGET_CLASS (parent_class)->expose_event)
5877 return GTK_WIDGET_CLASS (parent_class)->expose_event (widget, event);
5883 * gtk_window_set_has_frame:
5884 * @window: a #GtkWindow
5885 * @setting: a boolean
5887 * (Note: this is a special-purpose function for the framebuffer port,
5888 * that causes GTK+ to draw its own window border. For most applications,
5889 * you want gtk_window_set_decorated() instead, which tells the window
5890 * manager whether to draw the window border.)
5892 * If this function is called on a window with setting of %TRUE, before
5893 * it is realized or showed, it will have a "frame" window around
5894 * @window->window, accessible in @window->frame. Using the signal
5895 * frame_event you can receive all events targeted at the frame.
5897 * This function is used by the linux-fb port to implement managed
5898 * windows, but it could concievably be used by X-programs that
5899 * want to do their own window decorations.
5903 gtk_window_set_has_frame (GtkWindow *window,
5906 g_return_if_fail (GTK_IS_WINDOW (window));
5907 g_return_if_fail (!GTK_WIDGET_REALIZED (window));
5909 window->has_frame = setting != FALSE;
5913 * gtk_window_get_has_frame:
5914 * @window: a #GtkWindow
5916 * Accessor for whether the window has a frame window exterior to
5917 * @window->window. Gets the value set by gtk_window_set_has_frame ().
5919 * Return value: %TRUE if a frame has been added to the window
5920 * via gtk_window_set_has_frame().
5923 gtk_window_get_has_frame (GtkWindow *window)
5925 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
5927 return window->has_frame;
5931 * gtk_window_set_frame_dimensions:
5932 * @window: a #GtkWindow that has a frame
5933 * @left: The width of the left border
5934 * @top: The height of the top border
5935 * @right: The width of the right border
5936 * @bottom: The height of the bottom border
5938 * (Note: this is a special-purpose function intended for the framebuffer
5939 * port; see gtk_window_set_has_frame(). It will have no effect on the
5940 * window border drawn by the window manager, which is the normal
5941 * case when using the X Window system.)
5943 * For windows with frames (see gtk_window_set_has_frame()) this function
5944 * can be used to change the size of the frame border.
5947 gtk_window_set_frame_dimensions (GtkWindow *window,
5955 g_return_if_fail (GTK_IS_WINDOW (window));
5957 widget = GTK_WIDGET (window);
5959 if (window->frame_left == left &&
5960 window->frame_top == top &&
5961 window->frame_right == right &&
5962 window->frame_bottom == bottom)
5965 window->frame_left = left;
5966 window->frame_top = top;
5967 window->frame_right = right;
5968 window->frame_bottom = bottom;
5970 if (GTK_WIDGET_REALIZED (widget) && window->frame)
5972 gint width = widget->allocation.width + left + right;
5973 gint height = widget->allocation.height + top + bottom;
5974 gdk_window_resize (window->frame, width, height);
5975 gtk_decorated_window_move_resize_window (window,
5977 widget->allocation.width,
5978 widget->allocation.height);
5983 * gtk_window_present:
5984 * @window: a #GtkWindow
5986 * Presents a window to the user. This may mean raising the window
5987 * in the stacking order, deiconifying it, moving it to the current
5988 * desktop, and/or giving it the keyboard focus, possibly dependent
5989 * on the user's platform, window manager, and preferences.
5991 * If @window is hidden, this function calls gtk_widget_show()
5994 * This function should be used when the user tries to open a window
5995 * that's already open. Say for example the preferences dialog is
5996 * currently open, and the user chooses Preferences from the menu
5997 * a second time; use gtk_window_present() to move the already-open dialog
5998 * where the user can see it.
6000 * If you are calling this function in response to a user interaction,
6001 * it is preferable to use gdk_window_present_with_time().
6005 gtk_window_present (GtkWindow *window)
6007 gtk_window_present_with_time (window, GDK_CURRENT_TIME);
6011 * gtk_window_present_with_time:
6012 * @window: a #GtkWindow
6013 * @timestamp: the timestamp of the user interaction (typically a
6014 * button or key press event) which triggered this call
6016 * Presents a window to the user in response to a user interaction.
6017 * If you need to present a window without a timestamp, use
6018 * gtk_window_present(). See gtk_window_present() for details.
6023 gtk_window_present_with_time (GtkWindow *window,
6028 g_return_if_fail (GTK_IS_WINDOW (window));
6030 widget = GTK_WIDGET (window);
6032 if (GTK_WIDGET_VISIBLE (window))
6034 g_assert (widget->window != NULL);
6036 gdk_window_show (widget->window);
6038 /* Translate a timestamp of GDK_CURRENT_TIME appropriately */
6039 if (timestamp == GDK_CURRENT_TIME)
6041 #ifdef GDK_WINDOWING_X11
6042 GdkDisplay *display;
6044 display = gtk_widget_get_display (GTK_WIDGET (window));
6045 timestamp = gdk_x11_display_get_user_time (display);
6047 timestamp = gtk_get_current_event_time ();
6051 gdk_window_focus (widget->window, timestamp);
6055 gtk_widget_show (widget);
6060 * gtk_window_iconify:
6061 * @window: a #GtkWindow
6063 * Asks to iconify (i.e. minimize) the specified @window. Note that
6064 * you shouldn't assume the window is definitely iconified afterward,
6065 * because other entities (e.g. the user or <link
6066 * linkend="gtk-X11-arch">window manager</link>) could deiconify it
6067 * again, or there may not be a window manager in which case
6068 * iconification isn't possible, etc. But normally the window will end
6069 * up iconified. Just don't write code that crashes if not.
6071 * It's permitted to call this function before showing a window,
6072 * in which case the window will be iconified before it ever appears
6075 * You can track iconification via the "window_state_event" signal
6080 gtk_window_iconify (GtkWindow *window)
6083 GdkWindow *toplevel;
6085 g_return_if_fail (GTK_IS_WINDOW (window));
6087 widget = GTK_WIDGET (window);
6089 window->iconify_initially = TRUE;
6092 toplevel = window->frame;
6094 toplevel = widget->window;
6096 if (toplevel != NULL)
6097 gdk_window_iconify (toplevel);
6101 * gtk_window_deiconify:
6102 * @window: a #GtkWindow
6104 * Asks to deiconify (i.e. unminimize) the specified @window. Note
6105 * that you shouldn't assume the window is definitely deiconified
6106 * afterward, because other entities (e.g. the user or <link
6107 * linkend="gtk-X11-arch">window manager</link>) could iconify it
6108 * again before your code which assumes deiconification gets to run.
6110 * You can track iconification via the "window_state_event" signal
6114 gtk_window_deiconify (GtkWindow *window)
6117 GdkWindow *toplevel;
6119 g_return_if_fail (GTK_IS_WINDOW (window));
6121 widget = GTK_WIDGET (window);
6123 window->iconify_initially = FALSE;
6126 toplevel = window->frame;
6128 toplevel = widget->window;
6130 if (toplevel != NULL)
6131 gdk_window_deiconify (toplevel);
6136 * @window: a #GtkWindow
6138 * Asks to stick @window, which means that it will appear on all user
6139 * desktops. Note that you shouldn't assume the window is definitely
6140 * stuck afterward, because other entities (e.g. the user or <link
6141 * linkend="gtk-X11-arch">window manager</link>) could unstick it
6142 * again, and some window managers do not support sticking
6143 * windows. But normally the window will end up stuck. Just don't
6144 * write code that crashes if not.
6146 * It's permitted to call this function before showing a window.
6148 * You can track stickiness via the "window_state_event" signal
6153 gtk_window_stick (GtkWindow *window)
6156 GdkWindow *toplevel;
6158 g_return_if_fail (GTK_IS_WINDOW (window));
6160 widget = GTK_WIDGET (window);
6162 window->stick_initially = TRUE;
6165 toplevel = window->frame;
6167 toplevel = widget->window;
6169 if (toplevel != NULL)
6170 gdk_window_stick (toplevel);
6174 * gtk_window_unstick:
6175 * @window: a #GtkWindow
6177 * Asks to unstick @window, which means that it will appear on only
6178 * one of the user's desktops. Note that you shouldn't assume the
6179 * window is definitely unstuck afterward, because other entities
6180 * (e.g. the user or <link linkend="gtk-X11-arch">window
6181 * manager</link>) could stick it again. But normally the window will
6182 * end up stuck. Just don't write code that crashes if not.
6184 * You can track stickiness via the "window_state_event" signal
6189 gtk_window_unstick (GtkWindow *window)
6192 GdkWindow *toplevel;
6194 g_return_if_fail (GTK_IS_WINDOW (window));
6196 widget = GTK_WIDGET (window);
6198 window->stick_initially = FALSE;
6201 toplevel = window->frame;
6203 toplevel = widget->window;
6205 if (toplevel != NULL)
6206 gdk_window_unstick (toplevel);
6210 * gtk_window_maximize:
6211 * @window: a #GtkWindow
6213 * Asks to maximize @window, so that it becomes full-screen. Note that
6214 * you shouldn't assume the window is definitely maximized afterward,
6215 * because other entities (e.g. the user or <link
6216 * linkend="gtk-X11-arch">window manager</link>) could unmaximize it
6217 * again, and not all window managers support maximization. But
6218 * normally the window will end up maximized. Just don't write code
6219 * that crashes if not.
6221 * It's permitted to call this function before showing a window,
6222 * in which case the window will be maximized when it appears onscreen
6225 * You can track maximization via the "window_state_event" signal
6230 gtk_window_maximize (GtkWindow *window)
6233 GdkWindow *toplevel;
6235 g_return_if_fail (GTK_IS_WINDOW (window));
6237 widget = GTK_WIDGET (window);
6239 window->maximize_initially = TRUE;
6242 toplevel = window->frame;
6244 toplevel = widget->window;
6246 if (toplevel != NULL)
6247 gdk_window_maximize (toplevel);
6251 * gtk_window_unmaximize:
6252 * @window: a #GtkWindow
6254 * Asks to unmaximize @window. Note that you shouldn't assume the
6255 * window is definitely unmaximized afterward, because other entities
6256 * (e.g. the user or <link linkend="gtk-X11-arch">window
6257 * manager</link>) could maximize it again, and not all window
6258 * managers honor requests to unmaximize. But normally the window will
6259 * end up unmaximized. Just don't write code that crashes if not.
6261 * You can track maximization via the "window_state_event" signal
6266 gtk_window_unmaximize (GtkWindow *window)
6269 GdkWindow *toplevel;
6271 g_return_if_fail (GTK_IS_WINDOW (window));
6273 widget = GTK_WIDGET (window);
6275 window->maximize_initially = FALSE;
6278 toplevel = window->frame;
6280 toplevel = widget->window;
6282 if (toplevel != NULL)
6283 gdk_window_unmaximize (toplevel);
6287 * gtk_window_fullscreen:
6288 * @window: a #GtkWindow
6290 * Asks to place @window in the fullscreen state. Note that you
6291 * shouldn't assume the window is definitely full screen afterward,
6292 * because other entities (e.g. the user or <link
6293 * linkend="gtk-X11-arch">window manager</link>) could unfullscreen it
6294 * again, and not all window managers honor requests to fullscreen
6295 * windows. But normally the window will end up fullscreen. Just
6296 * don't write code that crashes if not.
6298 * You can track the fullscreen state via the "window_state_event" signal
6304 gtk_window_fullscreen (GtkWindow *window)
6307 GdkWindow *toplevel;
6308 GtkWindowPrivate *priv;
6310 g_return_if_fail (GTK_IS_WINDOW (window));
6312 widget = GTK_WIDGET (window);
6313 priv = GTK_WINDOW_GET_PRIVATE (window);
6315 priv->fullscreen_initially = TRUE;
6318 toplevel = window->frame;
6320 toplevel = widget->window;
6322 if (toplevel != NULL)
6323 gdk_window_fullscreen (toplevel);
6327 * gtk_window_unfullscreen:
6328 * @window: a #GtkWindow
6330 * Asks to toggle off the fullscreen state for @window. Note that you
6331 * shouldn't assume the window is definitely not full screen
6332 * afterward, because other entities (e.g. the user or <link
6333 * linkend="gtk-X11-arch">window manager</link>) could fullscreen it
6334 * again, and not all window managers honor requests to unfullscreen
6335 * windows. But normally the window will end up restored to its normal
6336 * state. Just don't write code that crashes if not.
6338 * You can track the fullscreen state via the "window_state_event" signal
6344 gtk_window_unfullscreen (GtkWindow *window)
6347 GdkWindow *toplevel;
6348 GtkWindowPrivate *priv;
6350 g_return_if_fail (GTK_IS_WINDOW (window));
6352 widget = GTK_WIDGET (window);
6353 priv = GTK_WINDOW_GET_PRIVATE (window);
6355 priv->fullscreen_initially = FALSE;
6358 toplevel = window->frame;
6360 toplevel = widget->window;
6362 if (toplevel != NULL)
6363 gdk_window_unfullscreen (toplevel);
6367 * gtk_window_set_keep_above:
6368 * @window: a #GtkWindow
6369 * @setting: whether to keep @window above other windows
6371 * Asks to keep @window above, so that it stays on top. Note that
6372 * you shouldn't assume the window is definitely above afterward,
6373 * because other entities (e.g. the user or <link
6374 * linkend="gtk-X11-arch">window manager</link>) could not keep it above,
6375 * and not all window managers support keeping windows above. But
6376 * normally the window will end kept above. Just don't write code
6377 * that crashes if not.
6379 * It's permitted to call this function before showing a window,
6380 * in which case the window will be kept above when it appears onscreen
6383 * You can track the above state via the "window_state_event" signal
6386 * Note that, according to the <ulink
6387 * url="http://www.freedesktop.org/Standards/wm-spec">Extended Window
6388 * Manager Hints</ulink> specification, the above state is mainly meant
6389 * for user preferences and should not be used by applications e.g. for
6390 * drawing attention to their dialogs.
6395 gtk_window_set_keep_above (GtkWindow *window,
6399 GtkWindowPrivate *priv;
6400 GdkWindow *toplevel;
6402 g_return_if_fail (GTK_IS_WINDOW (window));
6404 widget = GTK_WIDGET (window);
6405 priv = GTK_WINDOW_GET_PRIVATE (window);
6407 priv->above_initially = setting;
6409 priv->below_initially = FALSE;
6412 toplevel = window->frame;
6414 toplevel = widget->window;
6416 if (toplevel != NULL)
6417 gdk_window_set_keep_above (toplevel, setting);
6421 * gtk_window_set_keep_below:
6422 * @window: a #GtkWindow
6423 * @setting: whether to keep @window below other windows
6425 * Asks to keep @window below, so that it stays in bottom. Note that
6426 * you shouldn't assume the window is definitely below afterward,
6427 * because other entities (e.g. the user or <link
6428 * linkend="gtk-X11-arch">window manager</link>) could not keep it below,
6429 * and not all window managers support putting windows below. But
6430 * normally the window will be kept below. Just don't write code
6431 * that crashes if not.
6433 * It's permitted to call this function before showing a window,
6434 * in which case the window will be kept below when it appears onscreen
6437 * You can track the below state via the "window_state_event" signal
6440 * Note that, according to the <ulink
6441 * url="http://www.freedesktop.org/Standards/wm-spec">Extended Window
6442 * Manager Hints</ulink> specification, the above state is mainly meant
6443 * for user preferences and should not be used by applications e.g. for
6444 * drawing attention to their dialogs.
6449 gtk_window_set_keep_below (GtkWindow *window,
6453 GtkWindowPrivate *priv;
6454 GdkWindow *toplevel;
6456 g_return_if_fail (GTK_IS_WINDOW (window));
6458 widget = GTK_WIDGET (window);
6459 priv = GTK_WINDOW_GET_PRIVATE (window);
6461 priv->below_initially = setting;
6463 priv->above_initially = FALSE;
6466 toplevel = window->frame;
6468 toplevel = widget->window;
6470 if (toplevel != NULL)
6471 gdk_window_set_keep_below (toplevel, setting);
6475 * gtk_window_set_resizable:
6476 * @window: a #GtkWindow
6477 * @resizable: %TRUE if the user can resize this window
6479 * Sets whether the user can resize a window. Windows are user resizable
6483 gtk_window_set_resizable (GtkWindow *window,
6486 g_return_if_fail (GTK_IS_WINDOW (window));
6488 gtk_window_set_policy (window, FALSE, resizable, FALSE);
6492 * gtk_window_get_resizable:
6493 * @window: a #GtkWindow
6495 * Gets the value set by gtk_window_set_resizable().
6497 * Return value: %TRUE if the user can resize the window
6500 gtk_window_get_resizable (GtkWindow *window)
6502 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
6504 /* allow_grow is most likely to indicate the semantic concept we
6505 * mean by "resizable" (and will be a reliable indicator if
6506 * set_policy() hasn't been called)
6508 return window->allow_grow;
6512 * gtk_window_set_gravity:
6513 * @window: a #GtkWindow
6514 * @gravity: window gravity
6516 * Window gravity defines the meaning of coordinates passed to
6517 * gtk_window_move(). See gtk_window_move() and #GdkGravity for
6520 * The default window gravity is #GDK_GRAVITY_NORTH_WEST which will
6521 * typically "do what you mean."
6525 gtk_window_set_gravity (GtkWindow *window,
6528 g_return_if_fail (GTK_IS_WINDOW (window));
6530 if (gravity != window->gravity)
6532 window->gravity = gravity;
6534 /* gtk_window_move_resize() will adapt gravity
6536 gtk_widget_queue_resize (GTK_WIDGET (window));
6538 g_object_notify (G_OBJECT (window), "gravity");
6543 * gtk_window_get_gravity:
6544 * @window: a #GtkWindow
6546 * Gets the value set by gtk_window_set_gravity().
6548 * Return value: window gravity
6551 gtk_window_get_gravity (GtkWindow *window)
6553 g_return_val_if_fail (GTK_IS_WINDOW (window), 0);
6555 return window->gravity;
6559 * gtk_window_begin_resize_drag:
6560 * @window: a #GtkWindow
6561 * @button: mouse button that initiated the drag
6562 * @edge: position of the resize control
6563 * @root_x: X position where the user clicked to initiate the drag, in root window coordinates
6564 * @root_y: Y position where the user clicked to initiate the drag
6565 * @timestamp: timestamp from the click event that initiated the drag
6567 * Starts resizing a window. This function is used if an application
6568 * has window resizing controls. When GDK can support it, the resize
6569 * will be done using the standard mechanism for the <link
6570 * linkend="gtk-X11-arch">window manager</link> or windowing
6571 * system. Otherwise, GDK will try to emulate window resizing,
6572 * potentially not all that well, depending on the windowing system.
6576 gtk_window_begin_resize_drag (GtkWindow *window,
6584 GdkWindow *toplevel;
6586 g_return_if_fail (GTK_IS_WINDOW (window));
6587 g_return_if_fail (GTK_WIDGET_VISIBLE (window));
6589 widget = GTK_WIDGET (window);
6592 toplevel = window->frame;
6594 toplevel = widget->window;
6596 gdk_window_begin_resize_drag (toplevel,
6603 * gtk_window_get_frame_dimensions:
6604 * @window: a #GtkWindow
6605 * @left: location to store the width of the frame at the left, or %NULL
6606 * @top: location to store the height of the frame at the top, or %NULL
6607 * @right: location to store the width of the frame at the returns, or %NULL
6608 * @bottom: location to store the height of the frame at the bottom, or %NULL
6610 * (Note: this is a special-purpose function intended for the
6611 * framebuffer port; see gtk_window_set_has_frame(). It will not
6612 * return the size of the window border drawn by the <link
6613 * linkend="gtk-X11-arch">window manager</link>, which is the normal
6614 * case when using a windowing system. See
6615 * gdk_window_get_frame_extents() to get the standard window border
6618 * Retrieves the dimensions of the frame window for this toplevel.
6619 * See gtk_window_set_has_frame(), gtk_window_set_frame_dimensions().
6622 gtk_window_get_frame_dimensions (GtkWindow *window,
6628 g_return_if_fail (GTK_IS_WINDOW (window));
6631 *left = window->frame_left;
6633 *top = window->frame_top;
6635 *right = window->frame_right;
6637 *bottom = window->frame_bottom;
6641 * gtk_window_begin_move_drag:
6642 * @window: a #GtkWindow
6643 * @button: mouse button that initiated the drag
6644 * @root_x: X position where the user clicked to initiate the drag, in root window coordinates
6645 * @root_y: Y position where the user clicked to initiate the drag
6646 * @timestamp: timestamp from the click event that initiated the drag
6648 * Starts moving a window. This function is used if an application has
6649 * window movement grips. When GDK can support it, the window movement
6650 * will be done using the standard mechanism for the <link
6651 * linkend="gtk-X11-arch">window manager</link> or windowing
6652 * system. Otherwise, GDK will try to emulate window movement,
6653 * potentially not all that well, depending on the windowing system.
6657 gtk_window_begin_move_drag (GtkWindow *window,
6664 GdkWindow *toplevel;
6666 g_return_if_fail (GTK_IS_WINDOW (window));
6667 g_return_if_fail (GTK_WIDGET_VISIBLE (window));
6669 widget = GTK_WIDGET (window);
6672 toplevel = window->frame;
6674 toplevel = widget->window;
6676 gdk_window_begin_move_drag (toplevel,
6683 * gtk_window_set_screen:
6684 * @window: a #GtkWindow.
6685 * @screen: a #GdkScreen.
6687 * Sets the #GdkScreen where the @window is displayed; if
6688 * the window is already mapped, it will be unmapped, and
6689 * then remapped on the new screen.
6694 gtk_window_set_screen (GtkWindow *window,
6698 GdkScreen *previous_screen;
6699 gboolean was_mapped;
6701 g_return_if_fail (GTK_IS_WINDOW (window));
6702 g_return_if_fail (GDK_IS_SCREEN (screen));
6704 if (screen == window->screen)
6707 widget = GTK_WIDGET (window);
6709 previous_screen = window->screen;
6710 was_mapped = GTK_WIDGET_MAPPED (widget);
6713 gtk_widget_unmap (widget);
6714 if (GTK_WIDGET_REALIZED (widget))
6715 gtk_widget_unrealize (widget);
6717 gtk_window_free_key_hash (window);
6718 window->screen = screen;
6719 gtk_widget_reset_rc_styles (widget);
6720 if (screen != previous_screen)
6721 _gtk_widget_propagate_screen_changed (widget, previous_screen);
6722 g_object_notify (G_OBJECT (window), "screen");
6725 gtk_widget_map (widget);
6729 gtk_window_check_screen (GtkWindow *window)
6732 return window->screen;
6735 g_warning ("Screen for GtkWindow not set; you must always set\n"
6736 "a screen for a GtkWindow before using the window");
6742 * gtk_window_get_screen:
6743 * @window: a #GtkWindow.
6745 * Returns the #GdkScreen associated with @window.
6747 * Return value: a #GdkScreen.
6752 gtk_window_get_screen (GtkWindow *window)
6754 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
6756 return window->screen;
6760 * gtk_window_is_active:
6761 * @window: a #GtkWindow
6763 * Returns whether the window is part of the current active toplevel.
6764 * (That is, the toplevel window receiving keystrokes.)
6765 * The return value is %TRUE if the window is active toplevel
6766 * itself, but also if it is, say, a #GtkPlug embedded in the active toplevel.
6767 * You might use this function if you wanted to draw a widget
6768 * differently in an active window from a widget in an inactive window.
6769 * See gtk_window_has_toplevel_focus()
6771 * Return value: %TRUE if the window part of the current active window.
6776 gtk_window_is_active (GtkWindow *window)
6778 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
6780 return window->is_active;
6784 * gtk_window_has_toplevel_focus:
6785 * @window: a #GtkWindow
6787 * Returns whether the input focus is within this GtkWindow.
6788 * For real toplevel windows, this is identical to gtk_window_is_active(),
6789 * but for embedded windows, like #GtkPlug, the results will differ.
6791 * Return value: %TRUE if the input focus is within this GtkWindow
6796 gtk_window_has_toplevel_focus (GtkWindow *window)
6798 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
6800 return window->has_toplevel_focus;
6804 gtk_window_group_class_init (GtkWindowGroupClass *klass)
6809 gtk_window_group_get_type (void)
6811 static GType window_group_type = 0;
6813 if (!window_group_type)
6815 static const GTypeInfo window_group_info =
6817 sizeof (GtkWindowGroupClass),
6818 NULL, /* base_init */
6819 NULL, /* base_finalize */
6820 (GClassInitFunc) gtk_window_group_class_init,
6821 NULL, /* class_finalize */
6822 NULL, /* class_data */
6823 sizeof (GtkWindowGroup),
6824 16, /* n_preallocs */
6825 (GInstanceInitFunc) NULL,
6828 window_group_type = g_type_register_static (G_TYPE_OBJECT, "GtkWindowGroup", &window_group_info, 0);
6831 return window_group_type;
6835 * gtk_window_group_new:
6837 * Creates a new #GtkWindowGroup object. Grabs added with
6838 * gtk_grab_add() only affect windows within the same #GtkWindowGroup.
6840 * Return value: a new #GtkWindowGroup.
6843 gtk_window_group_new (void)
6845 return g_object_new (GTK_TYPE_WINDOW_GROUP, NULL);
6849 window_group_cleanup_grabs (GtkWindowGroup *group,
6853 GSList *to_remove = NULL;
6855 tmp_list = group->grabs;
6858 if (gtk_widget_get_toplevel (tmp_list->data) == (GtkWidget*) window)
6859 to_remove = g_slist_prepend (to_remove, g_object_ref (tmp_list->data));
6860 tmp_list = tmp_list->next;
6865 gtk_grab_remove (to_remove->data);
6866 g_object_unref (to_remove->data);
6867 to_remove = g_slist_delete_link (to_remove, to_remove);
6872 * gtk_window_group_add_window:
6873 * @window_group: a #GtkWindowGroup
6874 * @window: the #GtkWindow to add
6876 * Adds a window to a #GtkWindowGroup.
6879 gtk_window_group_add_window (GtkWindowGroup *window_group,
6882 g_return_if_fail (GTK_IS_WINDOW_GROUP (window_group));
6883 g_return_if_fail (GTK_IS_WINDOW (window));
6885 if (window->group != window_group)
6887 g_object_ref (window);
6888 g_object_ref (window_group);
6891 gtk_window_group_remove_window (window->group, window);
6893 window_group_cleanup_grabs (_gtk_window_get_group (NULL), window);
6895 window->group = window_group;
6897 g_object_unref (window);
6902 * gtk_window_group_remove_window:
6903 * @window_group: a #GtkWindowGroup
6904 * @window: the #GtkWindow to remove
6906 * Removes a window from a #GtkWindowGroup.
6909 gtk_window_group_remove_window (GtkWindowGroup *window_group,
6912 g_return_if_fail (GTK_IS_WINDOW_GROUP (window_group));
6913 g_return_if_fail (GTK_IS_WIDGET (window));
6914 g_return_if_fail (window->group == window_group);
6916 g_object_ref (window);
6918 window_group_cleanup_grabs (window_group, window);
6919 window->group = NULL;
6921 g_object_unref (window_group);
6922 g_object_unref (window);
6925 /* Return the group for the window or the default group
6928 _gtk_window_get_group (GtkWindow *window)
6930 if (window && window->group)
6931 return window->group;
6934 static GtkWindowGroup *default_group = NULL;
6937 default_group = gtk_window_group_new ();
6939 return default_group;
6943 /* Return the current grab widget of the given group
6946 _gtk_window_group_get_current_grab (GtkWindowGroup *window_group)
6948 if (window_group->grabs)
6949 return GTK_WIDGET (window_group->grabs->data);
6954 Derived from XParseGeometry() in XFree86
6956 Copyright 1985, 1986, 1987,1998 The Open Group
6958 All Rights Reserved.
6960 The above copyright notice and this permission notice shall be included
6961 in all copies or substantial portions of the Software.
6963 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
6964 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
6965 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
6966 IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
6967 OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
6968 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
6969 OTHER DEALINGS IN THE SOFTWARE.
6971 Except as contained in this notice, the name of The Open Group shall
6972 not be used in advertising or otherwise to promote the sale, use or
6973 other dealings in this Software without prior written authorization
6974 from The Open Group.
6979 * XParseGeometry parses strings of the form
6980 * "=<width>x<height>{+-}<xoffset>{+-}<yoffset>", where
6981 * width, height, xoffset, and yoffset are unsigned integers.
6982 * Example: "=80x24+300-49"
6983 * The equal sign is optional.
6984 * It returns a bitmask that indicates which of the four values
6985 * were actually found in the string. For each value found,
6986 * the corresponding argument is updated; for each value
6987 * not found, the corresponding argument is left unchanged.
6990 /* The following code is from Xlib, and is minimally modified, so we
6991 * can track any upstream changes if required. Don't change this
6992 * code. Or if you do, put in a huge comment marking which thing
6997 read_int (gchar *string,
7005 else if (*string == '-')
7011 for (; (*string >= '0') && (*string <= '9'); string++)
7013 result = (result * 10) + (*string - '0');
7025 * Bitmask returned by XParseGeometry(). Each bit tells if the corresponding
7026 * value (x, y, width, height) was found in the parsed string.
7028 #define NoValue 0x0000
7029 #define XValue 0x0001
7030 #define YValue 0x0002
7031 #define WidthValue 0x0004
7032 #define HeightValue 0x0008
7033 #define AllValues 0x000F
7034 #define XNegative 0x0010
7035 #define YNegative 0x0020
7037 /* Try not to reformat/modify, so we can compare/sync with X sources */
7039 gtk_XParseGeometry (const char *string,
7042 unsigned int *width,
7043 unsigned int *height)
7047 unsigned int tempWidth, tempHeight;
7049 char *nextCharacter;
7051 /* These initializations are just to silence gcc */
7057 if ( (string == NULL) || (*string == '\0')) return(mask);
7059 string++; /* ignore possible '=' at beg of geometry spec */
7061 strind = (char *)string;
7062 if (*strind != '+' && *strind != '-' && *strind != 'x') {
7063 tempWidth = read_int(strind, &nextCharacter);
7064 if (strind == nextCharacter)
7066 strind = nextCharacter;
7070 if (*strind == 'x' || *strind == 'X') {
7072 tempHeight = read_int(strind, &nextCharacter);
7073 if (strind == nextCharacter)
7075 strind = nextCharacter;
7076 mask |= HeightValue;
7079 if ((*strind == '+') || (*strind == '-')) {
7080 if (*strind == '-') {
7082 tempX = -read_int(strind, &nextCharacter);
7083 if (strind == nextCharacter)
7085 strind = nextCharacter;
7091 tempX = read_int(strind, &nextCharacter);
7092 if (strind == nextCharacter)
7094 strind = nextCharacter;
7097 if ((*strind == '+') || (*strind == '-')) {
7098 if (*strind == '-') {
7100 tempY = -read_int(strind, &nextCharacter);
7101 if (strind == nextCharacter)
7103 strind = nextCharacter;
7110 tempY = read_int(strind, &nextCharacter);
7111 if (strind == nextCharacter)
7113 strind = nextCharacter;
7119 /* If strind isn't at the end of the string the it's an invalid
7120 geometry specification. */
7122 if (*strind != '\0') return (0);
7128 if (mask & WidthValue)
7130 if (mask & HeightValue)
7131 *height = tempHeight;
7136 * gtk_window_parse_geometry:
7137 * @window: a #GtkWindow
7138 * @geometry: geometry string
7140 * Parses a standard X Window System geometry string - see the
7141 * manual page for X (type 'man X') for details on this.
7142 * gtk_window_parse_geometry() does work on all GTK+ ports
7143 * including Win32 but is primarily intended for an X environment.
7145 * If either a size or a position can be extracted from the
7146 * geometry string, gtk_window_parse_geometry() returns %TRUE
7147 * and calls gtk_window_set_default_size() and/or gtk_window_move()
7148 * to resize/move the window.
7150 * If gtk_window_parse_geometry() returns %TRUE, it will also
7151 * set the #GDK_HINT_USER_POS and/or #GDK_HINT_USER_SIZE hints
7152 * indicating to the window manager that the size/position of
7153 * the window was user-specified. This causes most window
7154 * managers to honor the geometry.
7156 * Note that for gtk_window_parse_geometry() to work as expected, it has
7157 * to be called when the window has its "final" size, i.e. after calling
7158 * gtk_widget_show_all() on the contents and gtk_window_set_geometry_hints()
7161 * <informalexample><programlisting>
7162 * #include <gtk/gtk.h>
7165 * fill_with_content (GtkWidget *vbox)
7167 * /<!-- -->* fill with content... *<!-- -->/
7171 * main (int argc, char *argv[])
7173 * GtkWidget *window, *vbox;
7174 * GdkGeometry size_hints = {
7175 * 100, 50, 0, 0, 100, 50, 10, 10, 0.0, 0.0, GDK_GRAVITY_NORTH_WEST
7178 * gtk_init (&argc, &argv);
7180 * window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
7181 * vbox = gtk_vbox_new (FALSE, 0);
7183 * gtk_container_add (GTK_CONTAINER (window), vbox);
7184 * fill_with_content (vbox);
7185 * gtk_widget_show_all (vbox);
7187 * gtk_window_set_geometry_hints (GTK_WINDOW (window),
7190 * GDK_HINT_MIN_SIZE |
7191 * GDK_HINT_BASE_SIZE |
7192 * GDK_HINT_RESIZE_INC);
7196 * if (!gtk_window_parse_geometry (GTK_WINDOW (window), argv[1]))
7197 * fprintf (stderr, "Failed to parse '%s'\n", argv[1]);
7200 * gtk_widget_show_all (window);
7205 * </programlisting></informalexample>
7207 * Return value: %TRUE if string was parsed successfully
7210 gtk_window_parse_geometry (GtkWindow *window,
7211 const gchar *geometry)
7216 gboolean size_set, pos_set;
7219 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
7220 g_return_val_if_fail (geometry != NULL, FALSE);
7222 screen = gtk_window_check_screen (window);
7224 result = gtk_XParseGeometry (geometry, &x, &y, &w, &h);
7226 if ((result & WidthValue) == 0 ||
7229 if ((result & HeightValue) == 0 ||
7234 if ((result & WidthValue) || (result & HeightValue))
7236 gtk_window_set_default_size_internal (window, TRUE, w, TRUE, h, TRUE);
7240 gtk_window_get_size (window, &w, &h);
7242 grav = GDK_GRAVITY_NORTH_WEST;
7244 if ((result & XNegative) && (result & YNegative))
7245 grav = GDK_GRAVITY_SOUTH_EAST;
7246 else if (result & XNegative)
7247 grav = GDK_GRAVITY_NORTH_EAST;
7248 else if (result & YNegative)
7249 grav = GDK_GRAVITY_SOUTH_WEST;
7251 if ((result & XValue) == 0)
7254 if ((result & YValue) == 0)
7257 if (grav == GDK_GRAVITY_SOUTH_WEST ||
7258 grav == GDK_GRAVITY_SOUTH_EAST)
7259 y = gdk_screen_get_height (screen) - h + y;
7261 if (grav == GDK_GRAVITY_SOUTH_EAST ||
7262 grav == GDK_GRAVITY_NORTH_EAST)
7263 x = gdk_screen_get_width (screen) - w + x;
7265 /* we don't let you put a window offscreen; maybe some people would
7266 * prefer to be able to, but it's kind of a bogus thing to do.
7275 if ((result & XValue) || (result & YValue))
7277 gtk_window_set_gravity (window, grav);
7278 gtk_window_move (window, x, y);
7282 if (size_set || pos_set)
7284 /* Set USSize, USPosition hints */
7285 GtkWindowGeometryInfo *info;
7287 info = gtk_window_get_geometry_info (window, TRUE);
7290 info->mask |= GDK_HINT_USER_POS;
7292 info->mask |= GDK_HINT_USER_SIZE;
7299 gtk_window_mnemonic_hash_foreach (guint keyval,
7305 GtkWindowKeysForeachFunc func;
7309 (*info->func) (info->window, keyval, info->window->mnemonic_modifier, TRUE, info->func_data);
7313 _gtk_window_keys_foreach (GtkWindow *window,
7314 GtkWindowKeysForeachFunc func,
7318 GtkMnemonicHash *mnemonic_hash;
7322 GtkWindowKeysForeachFunc func;
7326 info.window = window;
7328 info.func_data = func_data;
7330 mnemonic_hash = gtk_window_get_mnemonic_hash (window, FALSE);
7332 _gtk_mnemonic_hash_foreach (mnemonic_hash,
7333 gtk_window_mnemonic_hash_foreach, &info);
7335 groups = gtk_accel_groups_from_object (G_OBJECT (window));
7338 GtkAccelGroup *group = groups->data;
7341 for (i = 0; i < group->n_accels; i++)
7343 GtkAccelKey *key = &group->priv_accels[i].key;
7346 (*func) (window, key->accel_key, key->accel_mods, FALSE, func_data);
7349 groups = groups->next;
7354 gtk_window_keys_changed (GtkWindow *window)
7356 gtk_window_free_key_hash (window);
7357 gtk_window_get_key_hash (window);
7360 typedef struct _GtkWindowKeyEntry GtkWindowKeyEntry;
7362 struct _GtkWindowKeyEntry
7366 gboolean is_mnemonic;
7370 add_to_key_hash (GtkWindow *window,
7372 GdkModifierType modifiers,
7373 gboolean is_mnemonic,
7376 GtkKeyHash *key_hash = data;
7378 GtkWindowKeyEntry *entry = g_new (GtkWindowKeyEntry, 1);
7380 entry->keyval = keyval;
7381 entry->modifiers = modifiers;
7382 entry->is_mnemonic = is_mnemonic;
7384 /* GtkAccelGroup stores lowercased accelerators. To deal
7385 * with this, if <Shift> was specified, uppercase.
7387 if (modifiers & GDK_SHIFT_MASK)
7389 if (keyval == GDK_Tab)
7390 keyval = GDK_ISO_Left_Tab;
7392 keyval = gdk_keyval_to_upper (keyval);
7395 _gtk_key_hash_add_entry (key_hash, keyval, entry->modifiers, entry);
7399 gtk_window_get_key_hash (GtkWindow *window)
7401 GdkScreen *screen = gtk_window_check_screen (window);
7402 GtkKeyHash *key_hash = g_object_get_data (G_OBJECT (window), "gtk-window-key-hash");
7407 key_hash = _gtk_key_hash_new (gdk_keymap_get_for_display (gdk_screen_get_display (screen)),
7408 (GDestroyNotify)g_free);
7409 _gtk_window_keys_foreach (window, add_to_key_hash, key_hash);
7410 g_object_set_data (G_OBJECT (window), "gtk-window-key-hash", key_hash);
7416 gtk_window_free_key_hash (GtkWindow *window)
7418 GtkKeyHash *key_hash = g_object_get_data (G_OBJECT (window), "gtk-window-key-hash");
7421 _gtk_key_hash_free (key_hash);
7422 g_object_set_data (G_OBJECT (window), "gtk-window-key-hash", NULL);
7427 * gtk_window_activate_key:
7428 * @window: a #GtkWindow
7429 * @event: a #GdkEventKey
7431 * Activates mnemonics and accelerators for this #GtkWindow. This is normally
7432 * called by the default ::key_press_event handler for toplevel windows,
7433 * however in some cases it may be useful to call this directly when
7434 * overriding the standard key handling for a toplevel window.
7436 * Return value: %TRUE if a mnemonic or accelerator was found and activated.
7439 gtk_window_activate_key (GtkWindow *window,
7442 GtkKeyHash *key_hash = g_object_get_data (G_OBJECT (window), "gtk-window-key-hash");
7443 GtkWindowKeyEntry *found_entry = NULL;
7447 gtk_window_keys_changed (window);
7448 key_hash = g_object_get_data (G_OBJECT (window), "gtk-window-key-hash");
7453 GSList *entries = _gtk_key_hash_lookup (key_hash,
7454 event->hardware_keycode,
7456 gtk_accelerator_get_default_mod_mask (),
7460 for (tmp_list = entries; tmp_list; tmp_list = tmp_list->next)
7462 GtkWindowKeyEntry *entry = tmp_list->data;
7463 if (entry->is_mnemonic)
7465 found_entry = entry;
7470 if (!found_entry && entries)
7471 found_entry = entries->data;
7473 g_slist_free (entries);
7478 if (found_entry->is_mnemonic)
7479 return gtk_window_mnemonic_activate (window, found_entry->keyval, found_entry->modifiers);
7481 return gtk_accel_groups_activate (G_OBJECT (window), found_entry->keyval, found_entry->modifiers);
7488 window_update_has_focus (GtkWindow *window)
7490 GtkWidget *widget = GTK_WIDGET (window);
7491 gboolean has_focus = window->has_toplevel_focus && window->is_active;
7493 if (has_focus != window->has_focus)
7495 window->has_focus = has_focus;
7499 if (window->focus_widget &&
7500 window->focus_widget != widget &&
7501 !GTK_WIDGET_HAS_FOCUS (window->focus_widget))
7502 do_focus_change (window->focus_widget, TRUE);
7506 if (window->focus_widget &&
7507 window->focus_widget != widget &&
7508 GTK_WIDGET_HAS_FOCUS (window->focus_widget))
7509 do_focus_change (window->focus_widget, FALSE);
7515 * _gtk_window_set_is_active:
7516 * @window: a #GtkWindow
7517 * @is_active: %TRUE if the window is in the currently active toplevel
7519 * Internal function that sets whether the #GtkWindow is part
7520 * of the currently active toplevel window (taking into account inter-process
7524 _gtk_window_set_is_active (GtkWindow *window,
7527 g_return_if_fail (GTK_IS_WINDOW (window));
7529 is_active = is_active != FALSE;
7531 if (is_active != window->is_active)
7533 window->is_active = is_active;
7534 window_update_has_focus (window);
7536 g_object_notify (G_OBJECT (window), "is-active");
7541 * _gtk_window_set_has_toplevel_focus:
7542 * @window: a #GtkWindow
7543 * @has_toplevel_focus: %TRUE if the in
7545 * Internal function that sets whether the keyboard focus for the
7546 * toplevel window (taking into account inter-process embedding.)
7549 _gtk_window_set_has_toplevel_focus (GtkWindow *window,
7550 gboolean has_toplevel_focus)
7552 g_return_if_fail (GTK_IS_WINDOW (window));
7554 has_toplevel_focus = has_toplevel_focus != FALSE;
7556 if (has_toplevel_focus != window->has_toplevel_focus)
7558 window->has_toplevel_focus = has_toplevel_focus;
7559 window_update_has_focus (window);
7561 g_object_notify (G_OBJECT (window), "has-toplevel-focus");
7566 * gtk_window_set_auto_startup_notification:
7567 * @setting: %TRUE to automatically do startup notification
7569 * By default, after showing the first #GtkWindow for each #GdkScreen,
7570 * GTK+ calls gdk_screen_notify_startup_complete(). Call this
7571 * function to disable the automatic startup notification. You might
7572 * do this if your first window is a splash screen, and you want to
7573 * delay notification until after your real main window has been
7574 * shown, for example.
7576 * In that example, you would disable startup notification
7577 * temporarily, show your splash screen, then re-enable it so that
7578 * showing the main window would automatically result in notification.
7583 gtk_window_set_auto_startup_notification (gboolean setting)
7585 disable_startup_notification = !setting;
7590 #undef gtk_window_set_icon_from_file
7593 gtk_window_set_icon_from_file (GtkWindow *window,
7594 const gchar *filename,
7597 gchar *utf8_filename = g_locale_to_utf8 (filename, -1, NULL, NULL, err);
7600 if (utf8_filename == NULL)
7603 retval = gtk_window_set_icon_from_file_utf8 (window, utf8_filename, err);
7605 g_free (utf8_filename);
7610 #undef gtk_window_set_default_icon_from_file
7613 gtk_window_set_default_icon_from_file (const gchar *filename,
7616 gchar *utf8_filename = g_locale_to_utf8 (filename, -1, NULL, NULL, err);
7619 if (utf8_filename == NULL)
7622 retval = gtk_window_set_default_icon_from_file_utf8 (utf8_filename, err);
7624 g_free (utf8_filename);
7631 #define __GTK_WINDOW_C__
7632 #include "gtkaliasdef.c"