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/.
30 #include "gdk/gdkkeysyms.h"
32 #if defined (GDK_WINDOWING_X11)
34 #elif defined (GDK_WINDOWING_WIN32)
35 #include "win32/gdkwin32.h"
36 #elif defined (GDK_WINDOWING_NANOX)
37 #include "nanox/gdkprivate-nanox.h"
38 #elif defined (GDK_WINDOWING_FB)
39 #include "linux-fb/gdkfb.h"
42 #include "gtkprivate.h"
44 #include "gtksignal.h"
45 #include "gtkwindow.h"
46 #include "gtkwindow-decorate.h"
47 #include "gtkbindings.h"
49 #include "gtkiconfactory.h"
77 PROP_DESTROY_WITH_PARENT,
83 GdkGeometry geometry; /* Last set of geometry hints we set */
87 } GtkWindowLastGeometryInfo;
89 struct _GtkWindowGeometryInfo
91 /* Properties that the app has set on the window
93 GdkGeometry geometry; /* Geometry hints */
95 GtkWidget *widget; /* subwidget to which hints apply */
96 gint width; /* Default size */
98 guint may_shrink : 1; /* one-shot auto_shrink behaviour after set_default_size */
100 GtkWindowLastGeometryInfo last;
111 static void gtk_window_class_init (GtkWindowClass *klass);
112 static void gtk_window_init (GtkWindow *window);
113 static void gtk_window_shutdown (GObject *object);
114 static void gtk_window_destroy (GtkObject *object);
115 static void gtk_window_finalize (GObject *object);
116 static void gtk_window_show (GtkWidget *widget);
117 static void gtk_window_hide (GtkWidget *widget);
118 static void gtk_window_map (GtkWidget *widget);
119 static void gtk_window_unmap (GtkWidget *widget);
120 static void gtk_window_realize (GtkWidget *widget);
121 static void gtk_window_unrealize (GtkWidget *widget);
122 static void gtk_window_size_request (GtkWidget *widget,
123 GtkRequisition *requisition);
124 static void gtk_window_size_allocate (GtkWidget *widget,
125 GtkAllocation *allocation);
126 static gint gtk_window_event (GtkWidget *widget,
128 static gboolean gtk_window_frame_event (GtkWidget *widget,
130 static gint gtk_window_configure_event (GtkWidget *widget,
131 GdkEventConfigure *event);
132 static gint gtk_window_key_press_event (GtkWidget *widget,
134 static gint gtk_window_key_release_event (GtkWidget *widget,
136 static gint gtk_window_enter_notify_event (GtkWidget *widget,
137 GdkEventCrossing *event);
138 static gint gtk_window_leave_notify_event (GtkWidget *widget,
139 GdkEventCrossing *event);
140 static gint gtk_window_focus_in_event (GtkWidget *widget,
141 GdkEventFocus *event);
142 static gint gtk_window_focus_out_event (GtkWidget *widget,
143 GdkEventFocus *event);
144 static gint gtk_window_client_event (GtkWidget *widget,
145 GdkEventClient *event);
146 static void gtk_window_check_resize (GtkContainer *container);
147 static gint gtk_window_focus (GtkWidget *widget,
148 GtkDirectionType direction);
149 static void gtk_window_real_set_focus (GtkWindow *window,
152 static void gtk_window_real_activate_default (GtkWindow *window);
153 static void gtk_window_real_activate_focus (GtkWindow *window);
154 static void gtk_window_move_focus (GtkWindow *window,
155 GtkDirectionType dir);
157 static void gtk_window_move_resize (GtkWindow *window);
158 static gboolean gtk_window_compare_hints (GdkGeometry *geometry_a,
160 GdkGeometry *geometry_b,
162 static void gtk_window_compute_default_size (GtkWindow *window,
165 static void gtk_window_constrain_size (GtkWindow *window,
166 GdkGeometry *geometry,
172 static void gtk_window_compute_hints (GtkWindow *window,
173 GdkGeometry *new_geometry,
175 static gint gtk_window_compute_reposition (GtkWindow *window,
181 static void gtk_window_read_rcfiles (GtkWidget *widget,
182 GdkEventClient *event);
183 static void gtk_window_paint (GtkWidget *widget,
185 static gint gtk_window_expose (GtkWidget *widget,
186 GdkEventExpose *event);
187 static void gtk_window_unset_transient_for (GtkWindow *window);
188 static void gtk_window_transient_parent_realized (GtkWidget *parent,
190 static void gtk_window_transient_parent_unrealized (GtkWidget *parent,
193 static GtkWindowGeometryInfo* gtk_window_get_geometry_info (GtkWindow *window,
197 static GSList *toplevel_list = NULL;
198 static GHashTable *mnemonic_hash_table = NULL;
199 static GtkBinClass *parent_class = NULL;
200 static guint window_signals[LAST_SIGNAL] = { 0 };
202 static void gtk_window_set_property (GObject *object,
206 static void gtk_window_get_property (GObject *object,
213 mnemonic_hash (gconstpointer key)
215 const GtkWindowMnemonic *k;
218 k = (GtkWindowMnemonic *)key;
220 h = (gulong) k->window;
221 h ^= k->keyval << 16;
222 h ^= k->keyval >> 16;
228 mnemonic_equal (gconstpointer a, gconstpointer b)
230 const GtkWindowMnemonic *ka;
231 const GtkWindowMnemonic *kb;
233 ka = (GtkWindowMnemonic *)a;
234 kb = (GtkWindowMnemonic *)b;
237 (ka->window == kb->window) &&
238 (ka->keyval == kb->keyval);
242 gtk_window_get_type (void)
244 static GtkType window_type = 0;
248 static const GtkTypeInfo window_info =
252 sizeof (GtkWindowClass),
253 (GtkClassInitFunc) gtk_window_class_init,
254 (GtkObjectInitFunc) gtk_window_init,
255 /* reserved_1 */ NULL,
256 /* reserved_2 */ NULL,
257 (GtkClassInitFunc) NULL,
260 window_type = gtk_type_unique (gtk_bin_get_type (), &window_info);
267 gtk_window_class_init (GtkWindowClass *klass)
269 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
270 GtkObjectClass *object_class;
271 GtkWidgetClass *widget_class;
272 GtkContainerClass *container_class;
273 GtkBindingSet *binding_set;
275 object_class = (GtkObjectClass*) klass;
276 widget_class = (GtkWidgetClass*) klass;
277 container_class = (GtkContainerClass*) klass;
279 parent_class = gtk_type_class (gtk_bin_get_type ());
281 gobject_class->shutdown = gtk_window_shutdown;
282 gobject_class->finalize = gtk_window_finalize;
284 gobject_class->set_property = gtk_window_set_property;
285 gobject_class->get_property = gtk_window_get_property;
287 object_class->destroy = gtk_window_destroy;
289 widget_class->show = gtk_window_show;
290 widget_class->hide = gtk_window_hide;
291 widget_class->map = gtk_window_map;
292 widget_class->unmap = gtk_window_unmap;
293 widget_class->realize = gtk_window_realize;
294 widget_class->unrealize = gtk_window_unrealize;
295 widget_class->size_request = gtk_window_size_request;
296 widget_class->size_allocate = gtk_window_size_allocate;
297 widget_class->configure_event = gtk_window_configure_event;
298 widget_class->key_press_event = gtk_window_key_press_event;
299 widget_class->key_release_event = gtk_window_key_release_event;
300 widget_class->enter_notify_event = gtk_window_enter_notify_event;
301 widget_class->leave_notify_event = gtk_window_leave_notify_event;
302 widget_class->focus_in_event = gtk_window_focus_in_event;
303 widget_class->focus_out_event = gtk_window_focus_out_event;
304 widget_class->client_event = gtk_window_client_event;
305 widget_class->focus = gtk_window_focus;
307 widget_class->expose_event = gtk_window_expose;
309 container_class->check_resize = gtk_window_check_resize;
311 klass->set_focus = gtk_window_real_set_focus;
312 klass->frame_event = gtk_window_frame_event;
314 klass->activate_default = gtk_window_real_activate_default;
315 klass->activate_focus = gtk_window_real_activate_focus;
316 klass->move_focus = gtk_window_move_focus;
319 g_object_class_install_property (gobject_class,
321 g_param_spec_enum ("type",
323 _("The type of the window"),
324 GTK_TYPE_WINDOW_TYPE,
326 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
329 g_object_class_install_property (gobject_class,
331 g_param_spec_string ("title",
333 _("The title of the window"),
337 g_object_class_install_property (gobject_class,
339 g_param_spec_boolean ("auto_shrink",
341 _("If TRUE, the window automatically shrinks to its size request anytime a resize occurs. Don't use this feature, it makes no sense."),
345 g_object_class_install_property (gobject_class,
347 g_param_spec_boolean ("allow_shrink",
349 _("If TRUE, the window has no mimimum size. Don't use this feature, it makes no sense."),
353 g_object_class_install_property (gobject_class,
355 g_param_spec_boolean ("allow_grow",
357 _("If TRUE, users can expand the window beyond its minimum size."),
361 g_object_class_install_property (gobject_class,
363 g_param_spec_boolean ("resizable",
365 _("If TRUE, users can resize the window."),
369 g_object_class_install_property (gobject_class,
371 g_param_spec_boolean ("modal",
373 _("If TRUE, the window is modal (other windows are not usable while this one is up)."),
377 g_object_class_install_property (gobject_class,
379 g_param_spec_enum ("window_position",
380 _("Window Position"),
381 _("The initial position of the window."),
382 GTK_TYPE_WINDOW_POSITION,
386 g_object_class_install_property (gobject_class,
388 g_param_spec_int ("default_width",
390 _("The default width of the window, or 0 to use the size request."),
396 g_object_class_install_property (gobject_class,
398 g_param_spec_int ("default_height",
400 _("The default height of the windo, or 0 to use the size request."),
406 g_object_class_install_property (gobject_class,
407 PROP_DESTROY_WITH_PARENT,
408 g_param_spec_boolean ("destroy_with_parent",
409 _("Destroy with Parent"),
410 _("If this window should be destroyed when the parent is destroyed,"),
414 /* Style props are set or not */
416 window_signals[SET_FOCUS] =
417 g_signal_newc ("set_focus",
418 G_TYPE_FROM_CLASS (object_class),
420 G_STRUCT_OFFSET (GtkWindowClass, set_focus),
422 gtk_marshal_VOID__OBJECT,
426 window_signals[FRAME_EVENT] =
427 g_signal_newc ("frame_event",
428 G_TYPE_FROM_CLASS(object_class),
430 G_STRUCT_OFFSET(GtkWindowClass, frame_event),
431 _gtk_boolean_handled_accumulator, NULL,
432 gtk_marshal_BOOLEAN__BOXED,
436 window_signals[ACTIVATE_FOCUS] =
437 g_signal_newc ("activate_focus",
438 G_OBJECT_CLASS_TYPE (object_class),
439 G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
440 GTK_SIGNAL_OFFSET (GtkWindowClass, activate_focus),
442 gtk_marshal_VOID__VOID,
446 window_signals[ACTIVATE_DEFAULT] =
447 g_signal_newc ("activate_default",
448 G_OBJECT_CLASS_TYPE (object_class),
449 G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
450 GTK_SIGNAL_OFFSET (GtkWindowClass, activate_default),
452 gtk_marshal_VOID__VOID,
456 window_signals[MOVE_FOCUS] =
457 g_signal_newc ("move_focus",
458 G_OBJECT_CLASS_TYPE (object_class),
459 G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
460 GTK_SIGNAL_OFFSET (GtkWindowClass, move_focus),
462 gtk_marshal_VOID__ENUM,
465 GTK_TYPE_DIRECTION_TYPE);
467 if (!mnemonic_hash_table)
468 mnemonic_hash_table = g_hash_table_new (mnemonic_hash,
475 binding_set = gtk_binding_set_by_class (klass);
477 gtk_binding_entry_add_signal (binding_set, GDK_space, 0,
478 "activate_focus", 0);
480 gtk_binding_entry_add_signal (binding_set, GDK_Return, 0,
481 "activate_default", 0);
483 gtk_binding_entry_add_signal (binding_set, GDK_KP_Enter, 0,
484 "activate_default", 0);
486 gtk_binding_entry_add_signal (binding_set, GDK_Up, 0,
488 GTK_TYPE_DIRECTION_TYPE, GTK_DIR_UP);
489 gtk_binding_entry_add_signal (binding_set, GDK_KP_Up, 0,
491 GTK_TYPE_DIRECTION_TYPE, GTK_DIR_UP);
493 gtk_binding_entry_add_signal (binding_set, GDK_Down, 0,
495 GTK_TYPE_DIRECTION_TYPE, GTK_DIR_DOWN);
496 gtk_binding_entry_add_signal (binding_set, GDK_KP_Down, 0,
498 GTK_TYPE_DIRECTION_TYPE, GTK_DIR_DOWN);
500 gtk_binding_entry_add_signal (binding_set, GDK_Left, 0,
502 GTK_TYPE_DIRECTION_TYPE, GTK_DIR_LEFT);
503 gtk_binding_entry_add_signal (binding_set, GDK_KP_Left, 0,
505 GTK_TYPE_DIRECTION_TYPE, GTK_DIR_LEFT);
507 gtk_binding_entry_add_signal (binding_set, GDK_Right, 0,
509 GTK_TYPE_DIRECTION_TYPE, GTK_DIR_RIGHT);
510 gtk_binding_entry_add_signal (binding_set, GDK_KP_Right, 0,
512 GTK_TYPE_DIRECTION_TYPE, GTK_DIR_RIGHT);
514 gtk_binding_entry_add_signal (binding_set, GDK_Tab, 0,
516 GTK_TYPE_DIRECTION_TYPE, GTK_DIR_TAB_FORWARD);
517 gtk_binding_entry_add_signal (binding_set, GDK_ISO_Left_Tab, 0,
519 GTK_TYPE_DIRECTION_TYPE, GTK_DIR_TAB_FORWARD);
521 gtk_binding_entry_add_signal (binding_set, GDK_Tab, GDK_SHIFT_MASK,
523 GTK_TYPE_DIRECTION_TYPE, GTK_DIR_TAB_BACKWARD);
524 gtk_binding_entry_add_signal (binding_set, GDK_ISO_Left_Tab, GDK_SHIFT_MASK,
526 GTK_TYPE_DIRECTION_TYPE, GTK_DIR_TAB_BACKWARD);
530 gtk_window_init (GtkWindow *window)
532 GTK_WIDGET_UNSET_FLAGS (window, GTK_NO_WINDOW);
533 GTK_WIDGET_SET_FLAGS (window, GTK_TOPLEVEL);
535 GTK_PRIVATE_SET_FLAG (window, GTK_ANCHORED);
537 gtk_container_set_resize_mode (GTK_CONTAINER (window), GTK_RESIZE_QUEUE);
539 window->title = NULL;
540 window->wmclass_name = g_strdup (g_get_prgname ());
541 window->wmclass_class = g_strdup (gdk_progclass);
542 window->wm_role = NULL;
543 window->geometry_info = NULL;
544 window->type = GTK_WINDOW_TOPLEVEL;
545 window->focus_widget = NULL;
546 window->default_widget = NULL;
547 window->resize_count = 0;
548 window->allow_shrink = FALSE;
549 window->allow_grow = TRUE;
550 window->auto_shrink = FALSE;
551 window->handling_resize = FALSE;
552 window->position = GTK_WIN_POS_NONE;
553 window->use_uposition = TRUE;
554 window->modal = FALSE;
555 window->frame = NULL;
556 window->has_frame = FALSE;
557 window->frame_left = 0;
558 window->frame_right = 0;
559 window->frame_top = 0;
560 window->frame_bottom = 0;
561 window->type_hint = GDK_WINDOW_TYPE_HINT_NORMAL;
562 window->gravity = GDK_GRAVITY_NORTH_WEST;
563 window->decorated = TRUE;
564 window->mnemonic_modifier = GDK_MOD1_MASK;
566 gtk_widget_ref (GTK_WIDGET (window));
567 gtk_object_sink (GTK_OBJECT (window));
568 window->has_user_ref_count = TRUE;
569 toplevel_list = g_slist_prepend (toplevel_list, window);
571 gtk_decorated_window_init (window);
573 gtk_signal_connect (GTK_OBJECT (window),
575 GTK_SIGNAL_FUNC (gtk_window_event),
580 gtk_window_set_property (GObject *object,
587 window = GTK_WINDOW (object);
592 window->type = g_value_get_enum (value);
595 gtk_window_set_title (window, g_value_get_string (value));
597 case PROP_AUTO_SHRINK:
598 window->auto_shrink = g_value_get_boolean (value);
599 gtk_widget_queue_resize (GTK_WIDGET (window));
601 case PROP_ALLOW_SHRINK:
602 window->allow_shrink = g_value_get_boolean (value);
603 gtk_widget_queue_resize (GTK_WIDGET (window));
605 case PROP_ALLOW_GROW:
606 window->allow_grow = g_value_get_boolean (value);
607 gtk_widget_queue_resize (GTK_WIDGET (window));
608 g_object_notify (G_OBJECT (window), "resizable");
611 window->allow_grow = g_value_get_boolean (value);
612 gtk_widget_queue_resize (GTK_WIDGET (window));
613 g_object_notify (G_OBJECT (window), "allow_grow");
616 gtk_window_set_modal (window, g_value_get_boolean (value));
619 gtk_window_set_position (window, g_value_get_enum (value));
621 case PROP_DEFAULT_WIDTH:
622 gtk_window_set_default_size (window, g_value_get_int (value), -1);
624 case PROP_DEFAULT_HEIGHT:
625 gtk_window_set_default_size (window, -1, g_value_get_int (value));
627 case PROP_DESTROY_WITH_PARENT:
628 gtk_window_set_destroy_with_parent (window, g_value_get_boolean (value));
636 gtk_window_get_property (GObject *object,
643 window = GTK_WINDOW (object);
647 GtkWindowGeometryInfo *info;
649 g_value_set_enum (value, window->type);
652 g_value_set_string (value, window->title);
654 case PROP_AUTO_SHRINK:
655 g_value_set_boolean (value, window->auto_shrink);
657 case PROP_ALLOW_SHRINK:
658 g_value_set_boolean (value, window->allow_shrink);
660 case PROP_ALLOW_GROW:
661 g_value_set_boolean (value, window->allow_grow);
664 g_value_set_boolean (value, window->allow_grow);
667 g_value_set_boolean (value, window->modal);
670 g_value_set_enum (value, window->position);
672 case PROP_DEFAULT_WIDTH:
673 info = gtk_window_get_geometry_info (window, FALSE);
675 g_value_set_int (value, 0);
677 g_value_set_int (value, info->width);
679 case PROP_DEFAULT_HEIGHT:
680 info = gtk_window_get_geometry_info (window, FALSE);
682 g_value_set_int (value, 0);
684 g_value_set_int (value, info->height);
686 case PROP_DESTROY_WITH_PARENT:
687 g_value_set_boolean (value, window->destroy_with_parent);
690 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
697 * @type: type of window
699 * Creates a new #GtkWindow, which is a toplevel window that can
700 * contain other widgets. Nearly always, the type of the window should
701 * be #GTK_WINDOW_TOPLEVEL. If you're implementing something like a
702 * popup menu from scratch (which is a bad idea, just use #GtkMenu),
703 * you might use #GTK_WINDOW_POPUP. #GTK_WINDOW_POPUP is not for
704 * dialogs, though in some other toolkits dialogs are called "popups."
705 * In GTK+, #GTK_WINDOW_POPUP means a pop-up menu or pop-up tooltip.
706 * Popup windows are not controlled by the window manager.
708 * If you simply want an undecorated window (no window borders), use
709 * gtk_window_set_decorated(), don't use #GTK_WINDOW_POPUP.
711 * Return value: a new #GtkWindow.
714 gtk_window_new (GtkWindowType type)
718 g_return_val_if_fail (type >= GTK_WINDOW_TOPLEVEL && type <= GTK_WINDOW_POPUP, NULL);
720 window = gtk_type_new (GTK_TYPE_WINDOW);
724 return GTK_WIDGET (window);
728 * gtk_window_set_title:
729 * @window: a #GtkWindow
730 * @title: title of the window
732 * Sets the title of the #GtkWindow. The title of a window will be displayed in
733 * its title bar; on the X Window System, the title bar is rendered by the
734 * window manager, so exactly how the title appears to users may vary according
735 * to a user's exact configuration. The title should help a user distinguish
736 * this window from other windows they may have open. A good title might
737 * include the application name and current document filename, for example.
741 gtk_window_set_title (GtkWindow *window,
744 g_return_if_fail (window != NULL);
745 g_return_if_fail (GTK_IS_WINDOW (window));
748 g_free (window->title);
749 window->title = g_strdup (title);
751 if (GTK_WIDGET_REALIZED (window))
753 gdk_window_set_title (GTK_WIDGET (window)->window, window->title);
755 gtk_decorated_window_set_title (window, title);
758 g_object_notify (G_OBJECT (window), "title");
762 * gtk_window_get_title:
763 * @window: a #GtkWindow
765 * Retrieves the title of the window. See gtk_window_set_title().
767 * Return value: the title of the window, or %NULL if none has
768 * been set explicitely. The returned string is owned by the widget
769 * and must not be modified or freed.
771 G_CONST_RETURN gchar *
772 gtk_window_get_title (GtkWindow *window)
774 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
776 return window->title;
780 * gtk_window_set_wmclass:
781 * @window: a #GtkWindow
782 * @wmclass_name: window name hint
783 * @wmclass_class: window class hint
785 * Don't use this function. It sets the X Window System "class" and
786 * "name" hints for a window. According to the ICCCM, you should
787 * always set these to the same value for all windows in an
788 * application, and GTK sets them to that value by default, so calling
789 * this function is sort of pointless. However, you may want to call
790 * gtk_window_set_role() on each window in your application, for the
791 * benefit of the session manager. Setting the role allows the window
792 * manager to restore window positions when loading a saved session.
796 gtk_window_set_wmclass (GtkWindow *window,
797 const gchar *wmclass_name,
798 const gchar *wmclass_class)
800 g_return_if_fail (window != NULL);
801 g_return_if_fail (GTK_IS_WINDOW (window));
803 g_free (window->wmclass_name);
804 window->wmclass_name = g_strdup (wmclass_name);
806 g_free (window->wmclass_class);
807 window->wmclass_class = g_strdup (wmclass_class);
809 if (GTK_WIDGET_REALIZED (window))
810 g_warning ("gtk_window_set_wmclass: shouldn't set wmclass after window is realized!\n");
814 * gtk_window_set_role:
815 * @window: a #GtkWindow
816 * @role: unique identifier for the window to be used when restoring a session
818 * In combination with the window title, the window role allows a
819 * window manager to identify "the same" window when an application is
820 * restarted. So for example you might set the "toolbox" role on your
821 * app's toolbox window, so that when the user restarts their session,
822 * the window manager can put the toolbox back in the same place.
824 * If a window already has a unique title, you don't need to set the
825 * role, since the WM can use the title to identify the window when
826 * restoring the session.
830 gtk_window_set_role (GtkWindow *window,
833 g_return_if_fail (GTK_IS_WINDOW (window));
835 if (role == window->wm_role)
838 g_free (window->wm_role);
839 window->wm_role = g_strdup (role);
841 if (GTK_WIDGET_REALIZED (window))
842 g_warning ("gtk_window_set_role(): shouldn't set role after window is realized!\n");
846 * gtk_window_get_role:
847 * @window: a #GtkWindow
849 * Returns the role of the window. See gtk_window_set_role() for
850 * further explanation.
852 * Return value: the role of the window if set, or %NULL. The
853 * returned is owned by the widget and must not be modified
856 G_CONST_RETURN gchar *
857 gtk_window_get_role (GtkWindow *window)
859 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
861 return window->wm_role;
865 * gtk_window_set_focus:
866 * @window: a #GtkWindow
867 * @focus: widget to be the new focus widget
869 * If @focus is not the current focus widget, and is focusable, emits
870 * the "set_focus" signal to set @focus as the focus widget for the
871 * window. This function is more or less GTK-internal; to focus an
872 * entry widget or the like, you should use gtk_widget_grab_focus()
873 * instead of this function.
877 gtk_window_set_focus (GtkWindow *window,
880 g_return_if_fail (window != NULL);
881 g_return_if_fail (GTK_IS_WINDOW (window));
884 g_return_if_fail (GTK_IS_WIDGET (focus));
885 g_return_if_fail (GTK_WIDGET_CAN_FOCUS (focus));
888 if ((window->focus_widget != focus) ||
889 (focus && !GTK_WIDGET_HAS_FOCUS (focus)))
890 gtk_signal_emit (GTK_OBJECT (window), window_signals[SET_FOCUS], focus);
894 * gtk_window_set_default:
895 * @window: a #GtkWindow
896 * @default_widget: widget to be the default
898 * The default widget is the widget that's activated when the user
899 * presses Enter in a dialog (for example). This function tells a
900 * #GtkWindow about the current default widget; it's really a GTK
901 * internal function and you shouldn't need it. Instead, to change the
902 * default widget, first set the #GTK_CAN_DEFAULT flag on the widget
903 * you'd like to make the default using GTK_WIDGET_SET_FLAGS(), then
904 * call gtk_widget_grab_default() to move the default.
908 gtk_window_set_default (GtkWindow *window,
909 GtkWidget *default_widget)
911 g_return_if_fail (window != NULL);
912 g_return_if_fail (GTK_IS_WINDOW (window));
915 g_return_if_fail (GTK_WIDGET_CAN_DEFAULT (default_widget));
917 if (window->default_widget != default_widget)
919 if (window->default_widget)
921 if (window->focus_widget != window->default_widget ||
922 !GTK_WIDGET_RECEIVES_DEFAULT (window->default_widget))
923 GTK_WIDGET_UNSET_FLAGS (window->default_widget, GTK_HAS_DEFAULT);
924 gtk_widget_queue_draw (window->default_widget);
927 window->default_widget = default_widget;
929 if (window->default_widget)
931 if (window->focus_widget == NULL ||
932 !GTK_WIDGET_RECEIVES_DEFAULT (window->focus_widget))
933 GTK_WIDGET_SET_FLAGS (window->default_widget, GTK_HAS_DEFAULT);
934 gtk_widget_queue_draw (window->default_widget);
940 gtk_window_set_policy (GtkWindow *window,
941 gboolean allow_shrink,
943 gboolean auto_shrink)
945 g_return_if_fail (window != NULL);
946 g_return_if_fail (GTK_IS_WINDOW (window));
948 window->allow_shrink = (allow_shrink != FALSE);
949 window->allow_grow = (allow_grow != FALSE);
950 window->auto_shrink = (auto_shrink != FALSE);
952 g_object_notify (G_OBJECT (window), "allow_shrink");
953 g_object_notify (G_OBJECT (window), "allow_grow");
954 g_object_notify (G_OBJECT (window), "auto_shrink");
956 gtk_widget_queue_resize (GTK_WIDGET (window));
960 gtk_window_add_accel_group (GtkWindow *window,
961 GtkAccelGroup *accel_group)
963 g_return_if_fail (window != NULL);
964 g_return_if_fail (GTK_IS_WINDOW (window));
965 g_return_if_fail (accel_group != NULL);
967 gtk_accel_group_attach (accel_group, GTK_OBJECT (window));
971 gtk_window_remove_accel_group (GtkWindow *window,
972 GtkAccelGroup *accel_group)
974 g_return_if_fail (window != NULL);
975 g_return_if_fail (GTK_IS_WINDOW (window));
976 g_return_if_fail (accel_group != NULL);
978 gtk_accel_group_detach (accel_group, GTK_OBJECT (window));
982 gtk_window_add_mnemonic (GtkWindow *window,
986 GtkWindowMnemonic key;
987 GtkWindowMnemonic *mnemonic;
989 g_return_if_fail (GTK_IS_WINDOW (window));
990 g_return_if_fail (GTK_IS_WIDGET (target));
994 mnemonic = g_hash_table_lookup (mnemonic_hash_table, &key);
998 g_return_if_fail (g_slist_find (mnemonic->targets, target) == NULL);
999 mnemonic->targets = g_slist_prepend (mnemonic->targets, target);
1003 mnemonic = g_new (GtkWindowMnemonic, 1);
1005 mnemonic->targets = g_slist_prepend (NULL, target);
1006 g_hash_table_insert (mnemonic_hash_table, mnemonic, mnemonic);
1011 gtk_window_remove_mnemonic (GtkWindow *window,
1015 GtkWindowMnemonic key;
1016 GtkWindowMnemonic *mnemonic;
1018 g_return_if_fail (GTK_IS_WINDOW (window));
1019 g_return_if_fail (GTK_IS_WIDGET (target));
1021 key.window = window;
1022 key.keyval = keyval;
1023 mnemonic = g_hash_table_lookup (mnemonic_hash_table, &key);
1025 g_return_if_fail (mnemonic && g_slist_find (mnemonic->targets, target) != NULL);
1027 mnemonic->targets = g_slist_remove (mnemonic->targets, target);
1028 if (mnemonic->targets == NULL)
1030 g_hash_table_remove (mnemonic_hash_table, mnemonic);
1036 gtk_window_mnemonic_activate (GtkWindow *window,
1038 GdkModifierType modifier)
1040 GtkWindowMnemonic key;
1041 GtkWindowMnemonic *mnemonic;
1043 GtkWidget *widget, *chosen_widget;
1044 gboolean overloaded;
1046 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
1048 if (window->mnemonic_modifier != (modifier & gtk_accelerator_get_default_mod_mask ()))
1051 key.window = window;
1052 key.keyval = keyval;
1053 mnemonic = g_hash_table_lookup (mnemonic_hash_table, &key);
1059 chosen_widget = NULL;
1060 list = mnemonic->targets;
1063 widget = GTK_WIDGET (list->data);
1065 if (GTK_WIDGET_IS_SENSITIVE (widget) &&
1066 GTK_WIDGET_MAPPED (widget))
1074 chosen_widget = widget;
1076 list = g_slist_next (list);
1081 /* For round robin we put the activated entry on
1082 * the end of the list after activation
1084 mnemonic->targets = g_slist_remove (mnemonic->targets, chosen_widget);
1085 mnemonic->targets = g_slist_append (mnemonic->targets, chosen_widget);
1087 return gtk_widget_mnemonic_activate (chosen_widget, overloaded);
1093 gtk_window_set_mnemonic_modifier (GtkWindow *window,
1094 GdkModifierType modifier)
1096 g_return_if_fail (GTK_IS_WINDOW (window));
1097 g_return_if_fail ((modifier & ~GDK_MODIFIER_MASK) == 0);
1099 window->mnemonic_modifier = modifier;
1103 * gtk_window_get_mnemonic_modifier:
1104 * @window: a #GtkWindow
1106 * Returns the mnemonic modifier for this window. See
1107 * gtk_window_set_mnemonic_modifier().
1109 * Return value: the modifier mask used to activate
1110 * mnemonics on this window.
1113 gtk_window_get_mnemonic_modifier (GtkWindow *window)
1115 g_return_val_if_fail (GTK_IS_WINDOW (window), 0);
1117 return window->mnemonic_modifier;
1121 gtk_window_set_position (GtkWindow *window,
1122 GtkWindowPosition position)
1124 g_return_if_fail (GTK_IS_WINDOW (window));
1126 window->position = position;
1128 g_object_notify (G_OBJECT (window), "window_position");
1132 gtk_window_activate_focus (GtkWindow *window)
1134 g_return_val_if_fail (window != NULL, FALSE);
1135 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
1137 if (window->focus_widget)
1139 if (GTK_WIDGET_IS_SENSITIVE (window->focus_widget))
1140 gtk_widget_activate (window->focus_widget);
1148 gtk_window_activate_default (GtkWindow *window)
1150 g_return_val_if_fail (window != NULL, FALSE);
1151 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
1153 if (window->default_widget && GTK_WIDGET_IS_SENSITIVE (window->default_widget) &&
1154 (!window->focus_widget || !GTK_WIDGET_RECEIVES_DEFAULT (window->focus_widget)))
1156 gtk_widget_activate (window->default_widget);
1159 else if (window->focus_widget)
1161 if (GTK_WIDGET_IS_SENSITIVE (window->focus_widget))
1162 gtk_widget_activate (window->focus_widget);
1170 * gtk_window_set_modal:
1171 * @window: a #GtkWindow
1172 * @modal: whether the window is modal
1174 * Sets a window modal or non-modal. Modal windows prevent interaction
1175 * with other windows in the same application. To keep modal dialogs
1176 * on top of main application windows, use
1177 * gtk_window_set_transient_for() to make the dialog transient for the
1178 * parent; most window managers will then disallow lowering the dialog
1184 gtk_window_set_modal (GtkWindow *window,
1187 g_return_if_fail (window != NULL);
1188 g_return_if_fail (GTK_IS_WINDOW (window));
1190 window->modal = modal != FALSE;
1192 /* adjust desired modality state */
1193 if (GTK_WIDGET_VISIBLE (window) && window->modal)
1194 gtk_grab_add (GTK_WIDGET (window));
1196 gtk_grab_remove (GTK_WIDGET (window));
1198 g_object_notify (G_OBJECT (window), "modal");
1202 * gtk_window_get_modal:
1203 * @window: a #GtkWindow
1205 * Returns whether the window is modal. See gtk_window_set_modal().
1207 * Return value: %TRUE if the window is set to be modal and
1208 * establishes a grab when shown
1211 gtk_window_get_modal (GtkWindow *window)
1213 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
1215 return window->modal;
1219 * gtk_window_list_toplevels:
1221 * Returns a list of all existing toplevel windows. The widgets
1222 * in the list are not individually referenced. If you want
1223 * to iterate through the list and perform actions involving
1224 * callbacks that might destroy the widgets, you MUST call
1225 * g_list_foreach (result, (GFunc)g_object_ref, NULL) first, and
1226 * then unref all the widgets afterwards.
1228 * Return value: list of toplevel widgets
1231 gtk_window_list_toplevels (void)
1236 for (slist = toplevel_list; slist; slist = slist->next)
1237 list = g_list_prepend (list, slist->data);
1243 gtk_window_add_embedded_xid (GtkWindow *window, guint xid)
1245 GList *embedded_windows;
1247 g_return_if_fail (window != NULL);
1248 g_return_if_fail (GTK_IS_WINDOW (window));
1250 embedded_windows = gtk_object_get_data (GTK_OBJECT (window), "gtk-embedded");
1251 if (embedded_windows)
1252 gtk_object_remove_no_notify_by_id (GTK_OBJECT (window),
1253 g_quark_from_static_string ("gtk-embedded"));
1254 embedded_windows = g_list_prepend (embedded_windows,
1255 GUINT_TO_POINTER (xid));
1257 gtk_object_set_data_full (GTK_OBJECT (window), "gtk-embedded",
1260 (GtkDestroyNotify) g_list_free : NULL);
1264 gtk_window_remove_embedded_xid (GtkWindow *window, guint xid)
1266 GList *embedded_windows;
1269 g_return_if_fail (window != NULL);
1270 g_return_if_fail (GTK_IS_WINDOW (window));
1272 embedded_windows = gtk_object_get_data (GTK_OBJECT (window), "gtk-embedded");
1273 if (embedded_windows)
1274 gtk_object_remove_no_notify_by_id (GTK_OBJECT (window),
1275 g_quark_from_static_string ("gtk-embedded"));
1277 node = g_list_find (embedded_windows, GUINT_TO_POINTER (xid));
1280 embedded_windows = g_list_remove_link (embedded_windows, node);
1281 g_list_free_1 (node);
1284 gtk_object_set_data_full (GTK_OBJECT (window),
1285 "gtk-embedded", embedded_windows,
1287 (GtkDestroyNotify) g_list_free : NULL);
1291 _gtk_window_reposition (GtkWindow *window,
1295 GtkWindowGeometryInfo *info;
1297 g_return_if_fail (window != NULL);
1298 g_return_if_fail (GTK_IS_WINDOW (window));
1300 /* keep this in sync with gtk_window_compute_reposition()
1302 if (GTK_WIDGET_REALIZED (window))
1304 info = gtk_window_get_geometry_info (window, TRUE);
1306 if (!(info->last.flags & GDK_HINT_POS))
1308 info->last.flags |= GDK_HINT_POS;
1309 gdk_window_set_geometry_hints (GTK_WIDGET (window)->window,
1310 &info->last.geometry,
1315 gdk_window_move (window->frame, x - window->frame_left, y - window->frame_top);
1317 gdk_window_move (GTK_WIDGET (window)->window, x, y);
1322 gtk_window_shutdown (GObject *object)
1326 g_return_if_fail (GTK_IS_WINDOW (object));
1328 window = GTK_WINDOW (object);
1330 gtk_window_set_focus (window, NULL);
1331 gtk_window_set_default (window, NULL);
1333 G_OBJECT_CLASS (parent_class)->shutdown (object);
1337 parent_destroyed_callback (GtkWindow *parent, GtkWindow *child)
1339 gtk_widget_destroy (GTK_WIDGET (child));
1343 connect_parent_destroyed (GtkWindow *window)
1345 if (window->transient_parent)
1347 gtk_signal_connect (GTK_OBJECT (window->transient_parent),
1349 GTK_SIGNAL_FUNC (parent_destroyed_callback),
1355 disconnect_parent_destroyed (GtkWindow *window)
1357 if (window->transient_parent)
1359 gtk_signal_disconnect_by_func (GTK_OBJECT (window->transient_parent),
1360 GTK_SIGNAL_FUNC (parent_destroyed_callback),
1366 gtk_window_transient_parent_realized (GtkWidget *parent,
1369 if (GTK_WIDGET_REALIZED (window))
1370 gdk_window_set_transient_for (window->window, parent->window);
1374 gtk_window_transient_parent_unrealized (GtkWidget *parent,
1377 if (GTK_WIDGET_REALIZED (window))
1378 gdk_property_delete (window->window,
1379 gdk_atom_intern ("WM_TRANSIENT_FOR", FALSE));
1383 gtk_window_unset_transient_for (GtkWindow *window)
1385 if (window->transient_parent)
1387 gtk_signal_disconnect_by_func (GTK_OBJECT (window->transient_parent),
1388 GTK_SIGNAL_FUNC (gtk_window_transient_parent_realized),
1390 gtk_signal_disconnect_by_func (GTK_OBJECT (window->transient_parent),
1391 GTK_SIGNAL_FUNC (gtk_window_transient_parent_unrealized),
1393 gtk_signal_disconnect_by_func (GTK_OBJECT (window->transient_parent),
1394 GTK_SIGNAL_FUNC (gtk_widget_destroyed),
1395 &window->transient_parent);
1397 if (window->destroy_with_parent)
1398 disconnect_parent_destroyed (window);
1400 window->transient_parent = NULL;
1405 * gtk_window_set_transient_for:
1406 * @window: a #GtkWindow
1407 * @parent: parent window
1409 * Dialog windows should be set transient for the main application
1410 * window they were spawned from. This allows window managers to
1411 * e.g. keep the dialog on top of the main window, or center the
1412 * dialog over the main window. gtk_dialog_new_with_buttons() and
1413 * other convenience functions in GTK+ will sometimes call
1414 * gtk_window_set_transient_for() on your behalf.
1418 gtk_window_set_transient_for (GtkWindow *window,
1421 g_return_if_fail (GTK_IS_WINDOW (window));
1422 g_return_if_fail (parent == NULL || GTK_IS_WINDOW (parent));
1423 g_return_if_fail (window != parent);
1426 if (window->transient_parent)
1428 if (GTK_WIDGET_REALIZED (window) &&
1429 GTK_WIDGET_REALIZED (window->transient_parent) &&
1430 (!parent || !GTK_WIDGET_REALIZED (parent)))
1431 gtk_window_transient_parent_unrealized (GTK_WIDGET (window->transient_parent),
1432 GTK_WIDGET (window));
1434 gtk_window_unset_transient_for (window);
1437 window->transient_parent = parent;
1441 gtk_signal_connect (GTK_OBJECT (parent), "destroy",
1442 GTK_SIGNAL_FUNC (gtk_widget_destroyed),
1443 &window->transient_parent);
1444 gtk_signal_connect (GTK_OBJECT (parent), "realize",
1445 GTK_SIGNAL_FUNC (gtk_window_transient_parent_realized),
1447 gtk_signal_connect (GTK_OBJECT (parent), "unrealize",
1448 GTK_SIGNAL_FUNC (gtk_window_transient_parent_unrealized),
1451 if (window->destroy_with_parent)
1452 connect_parent_destroyed (window);
1454 if (GTK_WIDGET_REALIZED (window) &&
1455 GTK_WIDGET_REALIZED (parent))
1456 gtk_window_transient_parent_realized (GTK_WIDGET (parent),
1457 GTK_WIDGET (window));
1462 * gtk_window_get_transient_for:
1463 * @window: a #GtkWindow
1465 * Fetches the transient parent for this window. See
1466 * gtk_window_set_transient_for().
1468 * Return value: the transient parent for this window, or %NULL
1469 * if no transient parent has been set.
1472 gtk_window_get_transient_for (GtkWindow *window)
1474 g_return_val_if_fail (GTK_IS_WINDOW (window), NULL);
1476 return window->transient_parent;
1480 * gtk_window_set_type_hint:
1481 * @window: a #GtkWindow
1482 * @hint: the window type
1484 * By setting the type hint for the window, you allow the window
1485 * manager to decorate and handle the window in a way which is
1486 * suitable to the function of the window in your application.
1488 * This function should be called before the window becomes visible.
1490 * gtk_dialog_new_with_buttons() and other convenience functions in GTK+
1491 * will sometimes call gtk_window_set_type_hint() on your behalf.
1495 gtk_window_set_type_hint (GtkWindow *window,
1496 GdkWindowTypeHint hint)
1498 g_return_if_fail (GTK_IS_WINDOW (window));
1499 g_return_if_fail (!GTK_WIDGET_VISIBLE (window));
1500 window->type_hint = hint;
1504 * gtk_window_get_type_hint:
1505 * @window: a #GtkWindow
1507 * Gets the type hint for this window. See gtk_window_set_type_hint().
1509 * Return value: the type hint for @window.
1512 gtk_window_get_type_hint (GtkWindow *window)
1514 g_return_val_if_fail (GTK_IS_WINDOW (window), GDK_WINDOW_TYPE_HINT_NORMAL);
1516 return window->type_hint;
1520 * gtk_window_set_destroy_with_parent:
1521 * @window: a #GtkWindow
1522 * @setting: whether to destroy @window with its transient parent
1524 * If @setting is TRUE, then destroying the transient parent of @window
1525 * will also destroy @window itself. This is useful for dialogs that
1526 * shouldn't persist beyond the lifetime of the main window they're
1527 * associated with, for example.
1530 gtk_window_set_destroy_with_parent (GtkWindow *window,
1533 g_return_if_fail (GTK_IS_WINDOW (window));
1535 if (window->destroy_with_parent == (setting != FALSE))
1538 if (window->destroy_with_parent)
1540 disconnect_parent_destroyed (window);
1544 connect_parent_destroyed (window);
1547 window->destroy_with_parent = setting;
1549 g_object_notify (G_OBJECT (window), "destroy_with_parent");
1553 * gtk_window_get_destroy_with_parent:
1554 * @window: a #GtkWindow
1556 * Returns whether the window will be destroyed with its transient parent. See
1557 * gtk_window_set_destroy_with_parent ().
1559 * Return value: %TRUE if the window will be destroyed with its transient parent.
1562 gtk_window_get_destroy_with_parent (GtkWindow *window)
1564 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
1566 return window->destroy_with_parent;
1569 static GtkWindowGeometryInfo*
1570 gtk_window_get_geometry_info (GtkWindow *window,
1573 GtkWindowGeometryInfo *info;
1575 info = window->geometry_info;
1576 if (!info && create)
1578 info = g_new0 (GtkWindowGeometryInfo, 1);
1582 info->last.width = -1;
1583 info->last.height = -1;
1584 info->widget = NULL;
1586 info->may_shrink = FALSE;
1587 window->geometry_info = info;
1594 * gtk_window_set_geometry_hints:
1595 * @window: a #GtkWindow
1596 * @geometry_widget: widget the geometry hints will be applied to
1597 * @geometry: struct containing geometry information
1598 * @geom_mask: mask indicating which struct fields should be paid attention to
1600 * This function sets up hints about how a window can be resized by
1601 * the user. You can set a minimum and maximum size; allowed resize
1602 * increments (e.g. for xterm, you can only resize by the size of a
1603 * character); aspect ratios; and more. See the #GdkGeometry struct.
1607 gtk_window_set_geometry_hints (GtkWindow *window,
1608 GtkWidget *geometry_widget,
1609 GdkGeometry *geometry,
1610 GdkWindowHints geom_mask)
1612 GtkWindowGeometryInfo *info;
1614 g_return_if_fail (window != NULL);
1616 info = gtk_window_get_geometry_info (window, TRUE);
1619 gtk_signal_disconnect_by_func (GTK_OBJECT (info->widget),
1620 GTK_SIGNAL_FUNC (gtk_widget_destroyed),
1623 info->widget = geometry_widget;
1625 gtk_signal_connect (GTK_OBJECT (geometry_widget), "destroy",
1626 GTK_SIGNAL_FUNC (gtk_widget_destroyed),
1630 info->geometry = *geometry;
1632 info->mask = geom_mask;
1634 gtk_widget_queue_resize (GTK_WIDGET (window));
1638 * gtk_window_set_decorated:
1639 * @window: a #GtkWindow
1640 * @setting: %TRUE to decorate the window
1642 * By default, windows are decorated with a title bar, resize
1643 * controls, etc. Some window managers allow GTK+ to disable these
1644 * decorations, creating a borderless window. If you set the decorated
1645 * property to %FALSE using this function, GTK+ will do its best to
1646 * convince the window manager not to decorate the window.
1650 gtk_window_set_decorated (GtkWindow *window,
1653 g_return_if_fail (GTK_IS_WINDOW (window));
1655 setting = setting != FALSE;
1657 if (setting == window->decorated)
1660 if (GTK_WIDGET (window)->window)
1662 if (window->decorated)
1663 gdk_window_set_decorations (GTK_WIDGET (window)->window,
1666 gdk_window_set_decorations (GTK_WIDGET (window)->window,
1672 * gtk_window_get_decorated:
1673 * @window: a #GtkWindow
1675 * Returns whether the window has been set to have decorations
1676 * such as a title bar via gtk_window_set_decorated().
1678 * Return value: %TRUE if the window has been set to have decorations
1681 gtk_window_get_decorated (GtkWindow *window)
1683 g_return_val_if_fail (GTK_IS_WINDOW (window), TRUE);
1685 return window->decorated;
1689 * gtk_window_set_default_size:
1690 * @window: a #GtkWindow
1691 * @width: width in pixels, 0 to unset, or -1 to leave the width unchanged
1692 * @height: height in pixels, 0 to unset, or -1 to leave the height unchanged
1694 * Sets the default size of a window. If the window's "natural" size
1695 * (its size request) is larger than the default, the default will be
1696 * ignored. So the default size is a minimum initial size. Unlike
1697 * gtk_widget_set_usize(), which sets a size request for a widget and
1698 * thus would keep users from shrinking the window, this function only
1699 * sets the initial size, just as if the user had resized the window
1700 * themselves. Users can still shrink the window again as they
1701 * normally would. Setting a default size of 0 means to use the
1702 * "natural" default size (the size request of the window).
1704 * For more control over a window's initial size and how resizing works,
1705 * investigate gtk_window_set_geometry_hints().
1707 * A useful feature: if you set the "geometry widget" via
1708 * gtk_window_set_geometry_hints(), the default size specified by
1709 * gtk_window_set_default_size() will be the default size of that
1710 * widget, not of the entire window.
1714 gtk_window_set_default_size (GtkWindow *window,
1718 GtkWindowGeometryInfo *info;
1720 g_return_if_fail (GTK_IS_WINDOW (window));
1722 info = gtk_window_get_geometry_info (window, TRUE);
1724 g_object_freeze_notify (G_OBJECT (window));
1727 info->width = width;
1728 g_object_notify (G_OBJECT (window), "default_width");
1729 info->may_shrink = TRUE;
1733 info->height = height;
1734 g_object_notify (G_OBJECT (window), "default_height");
1735 info->may_shrink = TRUE;
1737 g_object_thaw_notify (G_OBJECT (window));
1739 gtk_widget_queue_resize (GTK_WIDGET (window));
1743 * gtk_window_get_default_size:
1744 * @window: a #GtkWindow
1745 * @width: location to store the default width, or %NULL
1746 * @height: location to store the default height, or %NULL
1748 * Gets the default size of the window. A value of 0 for the
1749 * width or height indicates that a default size has not
1750 * been explicitely set for that dimension, so the value
1751 * will be computed from the requisition of the window.
1754 gtk_window_get_default_size (GtkWindow *window,
1758 GtkWindowGeometryInfo *info;
1760 g_return_if_fail (GTK_IS_WINDOW (window));
1762 info = gtk_window_get_geometry_info (window, FALSE);
1765 *width = info ? info->width : 0;
1768 *height = info ? info->height : 0;
1772 gtk_window_destroy (GtkObject *object)
1776 g_return_if_fail (GTK_IS_WINDOW (object));
1778 window = GTK_WINDOW (object);
1780 if (window->transient_parent)
1781 gtk_window_set_transient_for (window, NULL);
1783 if (window->has_user_ref_count)
1785 window->has_user_ref_count = FALSE;
1786 gtk_widget_unref (GTK_WIDGET (window));
1790 gtk_window_group_remove_window (window->group, window);
1792 GTK_OBJECT_CLASS (parent_class)->destroy (object);
1796 gtk_window_mnemonic_hash_remove (gpointer key,
1800 GtkWindowMnemonic *mnemonic = key;
1801 GtkWindow *window = user;
1803 if (mnemonic->window == window)
1805 if (mnemonic->targets)
1807 gchar *name = gtk_accelerator_name (mnemonic->keyval, 0);
1809 g_warning ("mnemonic \"%s\" wasn't removed for widget (%p)",
1810 name, mnemonic->targets->data);
1813 g_slist_free (mnemonic->targets);
1822 gtk_window_finalize (GObject *object)
1826 g_return_if_fail (GTK_IS_WINDOW (object));
1828 window = GTK_WINDOW (object);
1830 toplevel_list = g_slist_remove (toplevel_list, window);
1832 g_free (window->title);
1833 g_free (window->wmclass_name);
1834 g_free (window->wmclass_class);
1835 g_free (window->wm_role);
1837 g_hash_table_foreach_remove (mnemonic_hash_table,
1838 gtk_window_mnemonic_hash_remove,
1840 if (window->geometry_info)
1842 if (window->geometry_info->widget)
1843 gtk_signal_disconnect_by_func (GTK_OBJECT (window->geometry_info->widget),
1844 GTK_SIGNAL_FUNC (gtk_widget_destroyed),
1845 &window->geometry_info->widget);
1846 g_free (window->geometry_info);
1849 G_OBJECT_CLASS (parent_class)->finalize (object);
1853 gtk_window_show (GtkWidget *widget)
1855 GtkWindow *window = GTK_WINDOW (widget);
1856 GtkContainer *container = GTK_CONTAINER (window);
1857 gboolean need_resize;
1859 GTK_WIDGET_SET_FLAGS (widget, GTK_VISIBLE);
1861 need_resize = container->need_resize || !GTK_WIDGET_REALIZED (widget);
1862 container->need_resize = FALSE;
1866 GtkWindowGeometryInfo *info = gtk_window_get_geometry_info (window, TRUE);
1867 GtkAllocation allocation = { 0, 0 };
1868 GdkGeometry new_geometry;
1869 guint width, height, new_flags;
1870 gboolean was_realized;
1872 /* determine default size to initially show the window with */
1873 gtk_widget_size_request (widget, NULL);
1874 gtk_window_compute_default_size (window, &width, &height);
1876 /* save away the last default size for later comparisions */
1877 info->last.width = width;
1878 info->last.height = height;
1880 /* constrain size to geometry */
1881 gtk_window_compute_hints (window, &new_geometry, &new_flags);
1882 gtk_window_constrain_size (window,
1883 &new_geometry, new_flags,
1887 /* and allocate the window */
1888 allocation.width = width;
1889 allocation.height = height;
1890 gtk_widget_size_allocate (widget, &allocation);
1892 was_realized = FALSE;
1893 if (!GTK_WIDGET_REALIZED (widget))
1895 gtk_widget_realize (widget);
1896 was_realized = TRUE;;
1899 /* Must be done after the windows are realized,
1900 * so that the decorations can be read
1902 gtk_decorated_window_calculate_frame_size (window);
1905 gdk_window_resize (widget->window, width, height);
1908 gtk_container_check_resize (container);
1910 gtk_widget_map (widget);
1913 gtk_grab_add (widget);
1917 gtk_window_hide (GtkWidget *widget)
1921 g_return_if_fail (widget != NULL);
1922 g_return_if_fail (GTK_IS_WINDOW (widget));
1924 window = GTK_WINDOW (widget);
1926 GTK_WIDGET_UNSET_FLAGS (widget, GTK_VISIBLE);
1927 gtk_widget_unmap (widget);
1930 gtk_grab_remove (widget);
1934 gtk_window_map (GtkWidget *widget)
1937 GdkWindow *toplevel;
1939 g_return_if_fail (widget != NULL);
1940 g_return_if_fail (GTK_IS_WINDOW (widget));
1942 GTK_WIDGET_SET_FLAGS (widget, GTK_MAPPED);
1944 window = GTK_WINDOW (widget);
1946 if (window->bin.child &&
1947 GTK_WIDGET_VISIBLE (window->bin.child) &&
1948 !GTK_WIDGET_MAPPED (window->bin.child))
1949 gtk_widget_map (window->bin.child);
1952 toplevel = window->frame;
1954 toplevel = widget->window;
1956 if (window->maximize_initially)
1957 gdk_window_maximize (toplevel);
1959 gdk_window_unmaximize (toplevel);
1961 if (window->stick_initially)
1962 gdk_window_stick (toplevel);
1964 gdk_window_unstick (toplevel);
1966 if (window->iconify_initially)
1967 gdk_window_iconify (toplevel);
1969 gdk_window_deiconify (toplevel);
1971 gdk_window_show (widget->window);
1974 gdk_window_show (window->frame);
1978 gtk_window_unmap (GtkWidget *widget)
1982 g_return_if_fail (widget != NULL);
1983 g_return_if_fail (GTK_IS_WINDOW (widget));
1985 window = GTK_WINDOW (widget);
1987 GTK_WIDGET_UNSET_FLAGS (widget, GTK_MAPPED);
1989 gdk_window_withdraw (window->frame);
1991 gdk_window_withdraw (widget->window);
1993 window->use_uposition = TRUE;
1994 window->resize_count = 0;
1995 window->handling_resize = FALSE;
2000 gtk_window_realize (GtkWidget *widget)
2003 GdkWindow *parent_window;
2004 GdkWindowAttr attributes;
2005 gint attributes_mask;
2007 g_return_if_fail (GTK_IS_WINDOW (widget));
2009 window = GTK_WINDOW (widget);
2011 /* ensure widget tree is properly size allocated */
2012 if (widget->allocation.x == -1 &&
2013 widget->allocation.y == -1 &&
2014 widget->allocation.width == 1 &&
2015 widget->allocation.height == 1)
2017 GtkRequisition requisition;
2018 GtkAllocation allocation = { 0, 0, 200, 200 };
2020 gtk_widget_size_request (widget, &requisition);
2021 if (requisition.width || requisition.height)
2023 /* non-empty window */
2024 allocation.width = requisition.width;
2025 allocation.height = requisition.height;
2027 gtk_widget_size_allocate (widget, &allocation);
2029 gtk_container_queue_resize (GTK_CONTAINER (widget));
2031 g_return_if_fail (!GTK_WIDGET_REALIZED (widget));
2034 GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED);
2036 switch (window->type)
2038 case GTK_WINDOW_TOPLEVEL:
2039 attributes.window_type = GDK_WINDOW_TOPLEVEL;
2041 case GTK_WINDOW_POPUP:
2042 attributes.window_type = GDK_WINDOW_TEMP;
2045 g_warning (G_STRLOC": Unknown window type %d!", window->type);
2049 attributes.title = window->title;
2050 attributes.wmclass_name = window->wmclass_name;
2051 attributes.wmclass_class = window->wmclass_class;
2052 attributes.wclass = GDK_INPUT_OUTPUT;
2053 attributes.visual = gtk_widget_get_visual (widget);
2054 attributes.colormap = gtk_widget_get_colormap (widget);
2056 if (window->has_frame)
2058 attributes.width = widget->allocation.width + window->frame_left + window->frame_right;
2059 attributes.height = widget->allocation.height + window->frame_top + window->frame_bottom;
2060 attributes.event_mask = (GDK_EXPOSURE_MASK |
2061 GDK_KEY_PRESS_MASK |
2062 GDK_ENTER_NOTIFY_MASK |
2063 GDK_LEAVE_NOTIFY_MASK |
2064 GDK_FOCUS_CHANGE_MASK |
2065 GDK_STRUCTURE_MASK |
2066 GDK_BUTTON_MOTION_MASK |
2067 GDK_POINTER_MOTION_HINT_MASK |
2068 GDK_BUTTON_PRESS_MASK |
2069 GDK_BUTTON_RELEASE_MASK);
2071 attributes_mask = GDK_WA_VISUAL | GDK_WA_COLORMAP;
2073 window->frame = gdk_window_new (NULL, &attributes, attributes_mask);
2074 gdk_window_set_user_data (window->frame, widget);
2076 attributes.window_type = GDK_WINDOW_CHILD;
2077 attributes.x = window->frame_left;
2078 attributes.y = window->frame_right;
2080 attributes_mask = GDK_WA_X | GDK_WA_Y;
2082 parent_window = window->frame;
2086 attributes_mask = 0;
2087 parent_window = NULL;
2090 attributes.width = widget->allocation.width;
2091 attributes.height = widget->allocation.height;
2092 attributes.event_mask = gtk_widget_get_events (widget);
2093 attributes.event_mask |= (GDK_EXPOSURE_MASK |
2094 GDK_KEY_PRESS_MASK |
2095 GDK_ENTER_NOTIFY_MASK |
2096 GDK_LEAVE_NOTIFY_MASK |
2097 GDK_FOCUS_CHANGE_MASK |
2098 GDK_STRUCTURE_MASK);
2100 attributes_mask |= GDK_WA_VISUAL | GDK_WA_COLORMAP;
2101 attributes_mask |= (window->title ? GDK_WA_TITLE : 0);
2102 attributes_mask |= (window->wmclass_name ? GDK_WA_WMCLASS : 0);
2103 widget->window = gdk_window_new (parent_window, &attributes, attributes_mask);
2104 gdk_window_set_user_data (widget->window, window);
2106 widget->style = gtk_style_attach (widget->style, widget->window);
2107 gtk_style_set_background (widget->style, widget->window, GTK_STATE_NORMAL);
2109 gtk_style_set_background (widget->style, window->frame, GTK_STATE_NORMAL);
2111 /* This is a bad hack to set the window background. */
2112 gtk_window_paint (widget, NULL);
2114 if (window->transient_parent &&
2115 GTK_WIDGET_REALIZED (window->transient_parent))
2116 gdk_window_set_transient_for (widget->window,
2117 GTK_WIDGET (window->transient_parent)->window);
2119 if (window->wm_role)
2120 gdk_window_set_role (widget->window, window->wm_role);
2122 if (!window->decorated)
2123 gdk_window_set_decorations (widget->window, 0);
2125 gdk_window_set_type_hint (widget->window, window->type_hint);
2127 /* transient_for must be set to allow the modal hint */
2128 if (window->transient_parent && window->modal)
2129 gdk_window_set_modal_hint (widget->window, TRUE);
2131 gdk_window_set_modal_hint (widget->window, FALSE);
2135 gtk_window_unrealize (GtkWidget *widget)
2139 g_return_if_fail (widget != NULL);
2140 g_return_if_fail (GTK_IS_WINDOW (widget));
2142 window = GTK_WINDOW (widget);
2146 gdk_window_set_user_data (window->frame, NULL);
2147 gdk_window_destroy (window->frame);
2148 window->frame = NULL;
2151 (* GTK_WIDGET_CLASS (parent_class)->unrealize) (widget);
2155 gtk_window_size_request (GtkWidget *widget,
2156 GtkRequisition *requisition)
2161 g_return_if_fail (widget != NULL);
2162 g_return_if_fail (GTK_IS_WINDOW (widget));
2163 g_return_if_fail (requisition != NULL);
2165 window = GTK_WINDOW (widget);
2166 bin = GTK_BIN (window);
2168 requisition->width = GTK_CONTAINER (window)->border_width * 2;
2169 requisition->height = GTK_CONTAINER (window)->border_width * 2;
2171 if (bin->child && GTK_WIDGET_VISIBLE (bin->child))
2173 GtkRequisition child_requisition;
2175 gtk_widget_size_request (bin->child, &child_requisition);
2177 requisition->width += child_requisition.width;
2178 requisition->height += child_requisition.height;
2183 gtk_window_size_allocate (GtkWidget *widget,
2184 GtkAllocation *allocation)
2187 GtkAllocation child_allocation;
2189 g_return_if_fail (widget != NULL);
2190 g_return_if_fail (GTK_IS_WINDOW (widget));
2191 g_return_if_fail (allocation != NULL);
2193 window = GTK_WINDOW (widget);
2194 widget->allocation = *allocation;
2196 if (window->bin.child && GTK_WIDGET_VISIBLE (window->bin.child))
2198 child_allocation.x = GTK_CONTAINER (window)->border_width;
2199 child_allocation.y = GTK_CONTAINER (window)->border_width;
2200 child_allocation.width =
2201 MAX (1, (gint)allocation->width - child_allocation.x * 2);
2202 child_allocation.height =
2203 MAX (1, (gint)allocation->height - child_allocation.y * 2);
2205 gtk_widget_size_allocate (window->bin.child, &child_allocation);
2208 if (GTK_WIDGET_REALIZED (widget) && window->frame)
2210 gdk_window_resize (window->frame,
2211 allocation->width + window->frame_left + window->frame_right,
2212 allocation->height + window->frame_top + window->frame_bottom);
2217 gtk_window_event (GtkWidget *widget, GdkEvent *event)
2220 gboolean return_val;
2223 g_return_val_if_fail (widget != NULL, FALSE);
2224 g_return_val_if_fail (GTK_IS_WINDOW (widget), FALSE);
2225 g_return_val_if_fail (event != NULL, FALSE);
2227 window = GTK_WINDOW (widget);
2229 if (window->frame && (event->any.window == window->frame))
2231 if ((event->type != GDK_KEY_PRESS) &&
2232 (event->type != GDK_KEY_RELEASE) &&
2233 (event->type != GDK_FOCUS_CHANGE))
2235 gtk_signal_emit_stop_by_name (GTK_OBJECT (widget), "event");
2237 gtk_signal_emit (GTK_OBJECT (widget), window_signals[FRAME_EVENT], event, &return_val);
2242 g_object_unref (event->any.window);
2243 event->any.window = g_object_ref (widget->window);
2251 gtk_window_frame_event (GtkWidget *widget, GdkEvent *event)
2253 GdkEventConfigure *configure_event;
2254 GtkWindow *window = GTK_WINDOW (widget);
2257 switch (event->type)
2260 configure_event = (GdkEventConfigure *)event;
2262 /* Invalidate the decorations */
2265 rect.width = configure_event->width;
2266 rect.height = configure_event->height;
2268 gdk_window_invalidate_rect (window->frame, &rect, FALSE);
2270 /* Pass on the (modified) configure event */
2271 configure_event->width -= window->frame_left + window->frame_right;
2272 configure_event->height -= window->frame_top + window->frame_bottom;
2273 return gtk_window_configure_event (widget, configure_event);
2282 gtk_window_configure_event (GtkWidget *widget,
2283 GdkEventConfigure *event)
2287 g_return_val_if_fail (widget != NULL, FALSE);
2288 g_return_val_if_fail (GTK_IS_WINDOW (widget), FALSE);
2289 g_return_val_if_fail (event != NULL, FALSE);
2291 window = GTK_WINDOW (widget);
2293 /* we got a configure event specifying the new window size and position,
2294 * in principle we have to distinguish 4 cases here:
2295 * 1) the size didn't change and resize_count == 0
2296 * -> the window was merely moved (sometimes not even that)
2297 * 2) the size didn't change and resize_count > 0
2298 * -> we requested a new size, but didn't get it
2299 * 3) the size changed and resize_count > 0
2300 * -> we asked for a new size and we got one
2301 * 4) the size changed and resize_count == 0
2302 * -> we got resized from outside the toolkit, and have to
2303 * accept that size since we don't want to fight neither the
2304 * window manager nor the user
2305 * in the three latter cases we have to reallocate the widget tree,
2306 * which happens in gtk_window_move_resize(), so we set a flag for
2307 * that function and assign the new size. if resize_count > 1,
2308 * we simply do nothing and wait for more configure events.
2311 if (window->resize_count > 0 ||
2312 widget->allocation.width != event->width ||
2313 widget->allocation.height != event->height)
2315 if (window->resize_count > 0)
2316 window->resize_count -= 1;
2318 if (window->resize_count == 0)
2320 window->handling_resize = TRUE;
2322 widget->allocation.width = event->width;
2323 widget->allocation.height = event->height;
2325 gtk_widget_queue_resize (widget);
2333 gtk_window_key_press_event (GtkWidget *widget,
2339 g_return_val_if_fail (widget != NULL, FALSE);
2340 g_return_val_if_fail (GTK_IS_WINDOW (widget), FALSE);
2341 g_return_val_if_fail (event != NULL, FALSE);
2343 window = GTK_WINDOW (widget);
2347 if (window->focus_widget && window->focus_widget != widget &&
2348 GTK_WIDGET_IS_SENSITIVE (window->focus_widget))
2349 handled = gtk_widget_event (window->focus_widget, (GdkEvent*) event);
2352 handled = gtk_window_mnemonic_activate (window,
2357 handled = gtk_accel_groups_activate (GTK_OBJECT (window), event->keyval, event->state);
2359 /* Chain up, invokes binding set */
2360 if (!handled && GTK_WIDGET_CLASS (parent_class)->key_press_event)
2361 handled = GTK_WIDGET_CLASS (parent_class)->key_press_event (widget, event);
2368 gtk_window_real_activate_default (GtkWindow *window)
2370 gtk_window_activate_default (window);
2374 gtk_window_real_activate_focus (GtkWindow *window)
2376 gtk_window_activate_focus (window);
2380 gtk_window_move_focus (GtkWindow *window,
2381 GtkDirectionType dir)
2383 gtk_widget_child_focus (GTK_WIDGET (window), dir);
2385 if (!GTK_CONTAINER (window)->focus_child)
2386 gtk_window_set_focus (window, NULL);
2390 gtk_window_key_release_event (GtkWidget *widget,
2396 g_return_val_if_fail (widget != NULL, FALSE);
2397 g_return_val_if_fail (GTK_IS_WINDOW (widget), FALSE);
2398 g_return_val_if_fail (event != NULL, FALSE);
2400 window = GTK_WINDOW (widget);
2402 if (window->focus_widget &&
2403 window->focus_widget != widget &&
2404 GTK_WIDGET_SENSITIVE (window->focus_widget))
2406 handled = gtk_widget_event (window->focus_widget, (GdkEvent*) event);
2409 if (!handled && GTK_WIDGET_CLASS (parent_class)->key_release_event)
2410 handled = GTK_WIDGET_CLASS (parent_class)->key_release_event (widget, event);
2416 gtk_window_enter_notify_event (GtkWidget *widget,
2417 GdkEventCrossing *event)
2419 g_return_val_if_fail (widget != NULL, FALSE);
2420 g_return_val_if_fail (GTK_IS_WINDOW (widget), FALSE);
2421 g_return_val_if_fail (event != NULL, FALSE);
2427 gtk_window_leave_notify_event (GtkWidget *widget,
2428 GdkEventCrossing *event)
2430 g_return_val_if_fail (widget != NULL, FALSE);
2431 g_return_val_if_fail (GTK_IS_WINDOW (widget), FALSE);
2432 g_return_val_if_fail (event != NULL, FALSE);
2438 gtk_window_focus_in_event (GtkWidget *widget,
2439 GdkEventFocus *event)
2441 GtkWindow *window = GTK_WINDOW (widget);
2442 GdkEventFocus fevent;
2444 /* It appears spurious focus in events can occur when
2445 * the window is hidden. So we'll just check to see if
2446 * the window is visible before actually handling the
2449 if (GTK_WIDGET_VISIBLE (widget))
2451 window->has_focus = TRUE;
2453 if (window->focus_widget &&
2454 window->focus_widget != widget &&
2455 !GTK_WIDGET_HAS_FOCUS (window->focus_widget))
2457 fevent.type = GDK_FOCUS_CHANGE;
2458 fevent.window = window->focus_widget->window;
2461 gtk_widget_event (window->focus_widget, (GdkEvent*) &fevent);
2469 gtk_window_focus_out_event (GtkWidget *widget,
2470 GdkEventFocus *event)
2472 GtkWindow *window = GTK_WINDOW (widget);
2473 GdkEventFocus fevent;
2475 window->has_focus = FALSE;
2477 if (window->focus_widget &&
2478 window->focus_widget != widget &&
2479 GTK_WIDGET_HAS_FOCUS (window->focus_widget))
2481 fevent.type = GDK_FOCUS_CHANGE;
2482 fevent.window = window->focus_widget->window;
2485 gtk_widget_event (window->focus_widget, (GdkEvent*) &fevent);
2491 static GdkAtom atom_rcfiles = GDK_NONE;
2494 gtk_window_read_rcfiles (GtkWidget *widget,
2495 GdkEventClient *event)
2497 GList *embedded_windows;
2499 embedded_windows = gtk_object_get_data (GTK_OBJECT (widget), "gtk-embedded");
2500 if (embedded_windows)
2505 for(i = 0; i < 5; i++)
2507 sev.data_format = 32;
2508 sev.message_type = atom_rcfiles;
2510 while (embedded_windows)
2512 guint xid = GPOINTER_TO_UINT (embedded_windows->data);
2513 gdk_event_send_client_message ((GdkEvent *) &sev, xid);
2514 embedded_windows = embedded_windows->next;
2518 if (gtk_rc_reparse_all ())
2520 /* If the above returned true, some of our RC files are out
2521 * of date, so we need to reset all our widgets. Our other
2522 * toplevel windows will also get the message, but by
2523 * then, the RC file will up to date, so we have to tell
2524 * them now. Also, we have to invalidate cached icons in
2525 * icon sets so they get re-rendered.
2527 GList *list, *toplevels;
2529 _gtk_icon_set_invalidate_caches ();
2531 toplevels = gtk_window_list_toplevels ();
2532 g_list_foreach (toplevels, (GFunc)g_object_ref, NULL);
2534 for (list = toplevels; list; list = list->next)
2536 gtk_widget_reset_rc_styles (list->data);
2537 gtk_widget_unref (list->data);
2539 g_list_free (toplevels);
2544 gtk_window_client_event (GtkWidget *widget,
2545 GdkEventClient *event)
2547 g_return_val_if_fail (widget != NULL, FALSE);
2548 g_return_val_if_fail (GTK_IS_WINDOW (widget), FALSE);
2549 g_return_val_if_fail (event != NULL, FALSE);
2552 atom_rcfiles = gdk_atom_intern("_GTK_READ_RCFILES", FALSE);
2554 if(event->message_type == atom_rcfiles)
2555 gtk_window_read_rcfiles (widget, event);
2561 gtk_window_check_resize (GtkContainer *container)
2565 g_return_if_fail (container != NULL);
2566 g_return_if_fail (GTK_IS_WINDOW (container));
2568 window = GTK_WINDOW (container);
2570 if (GTK_WIDGET_VISIBLE (container))
2571 gtk_window_move_resize (window);
2575 gtk_window_focus (GtkWidget *widget,
2576 GtkDirectionType direction)
2580 GtkContainer *container;
2581 GtkWidget *old_focus_child;
2584 container = GTK_CONTAINER (widget);
2585 window = GTK_WINDOW (widget);
2586 bin = GTK_BIN (widget);
2588 old_focus_child = container->focus_child;
2590 /* We need a special implementation here to deal properly with wrapping
2591 * around in the tab chain without the danger of going into an
2594 if (old_focus_child)
2596 if (gtk_widget_child_focus (old_focus_child, direction))
2600 if (window->focus_widget)
2602 /* Wrapped off the end, clear the focus setting for the toplpevel */
2603 parent = window->focus_widget->parent;
2606 gtk_container_set_focus_child (GTK_CONTAINER (parent), NULL);
2607 parent = GTK_WIDGET (parent)->parent;
2610 gtk_window_set_focus (GTK_WINDOW (container), NULL);
2613 /* Now try to focus the first widget in the window */
2616 if (gtk_widget_child_focus (bin->child, direction))
2624 gtk_window_real_set_focus (GtkWindow *window,
2627 GdkEventFocus event;
2628 gboolean def_flags = 0;
2630 g_return_if_fail (window != NULL);
2631 g_return_if_fail (GTK_IS_WINDOW (window));
2633 if (window->default_widget)
2634 def_flags = GTK_WIDGET_HAS_DEFAULT (window->default_widget);
2636 if (window->focus_widget)
2638 if (GTK_WIDGET_RECEIVES_DEFAULT (window->focus_widget) &&
2639 (window->focus_widget != window->default_widget))
2641 GTK_WIDGET_UNSET_FLAGS (window->focus_widget, GTK_HAS_DEFAULT);
2643 if (window->default_widget)
2644 GTK_WIDGET_SET_FLAGS (window->default_widget, GTK_HAS_DEFAULT);
2647 if (window->has_focus)
2649 event.type = GDK_FOCUS_CHANGE;
2650 event.window = window->focus_widget->window;
2653 gtk_widget_event (window->focus_widget, (GdkEvent*) &event);
2657 window->focus_widget = focus;
2659 if (window->focus_widget)
2661 if (GTK_WIDGET_RECEIVES_DEFAULT (window->focus_widget) &&
2662 (window->focus_widget != window->default_widget))
2664 if (GTK_WIDGET_CAN_DEFAULT (window->focus_widget))
2665 GTK_WIDGET_SET_FLAGS (window->focus_widget, GTK_HAS_DEFAULT);
2667 if (window->default_widget)
2668 GTK_WIDGET_UNSET_FLAGS (window->default_widget, GTK_HAS_DEFAULT);
2671 if (window->has_focus)
2673 event.type = GDK_FOCUS_CHANGE;
2674 event.window = window->focus_widget->window;
2677 gtk_widget_event (window->focus_widget, (GdkEvent*) &event);
2681 if (window->default_widget &&
2682 (def_flags != GTK_WIDGET_FLAGS (window->default_widget)))
2683 gtk_widget_queue_draw (window->default_widget);
2688 /*********************************
2689 * Functions related to resizing *
2690 *********************************/
2693 gtk_window_move_resize (GtkWindow *window)
2696 GtkContainer *container;
2697 GtkWindowGeometryInfo *info;
2698 GtkWindowLastGeometryInfo saved_last_info;
2699 GdkGeometry new_geometry;
2703 gint new_width, new_height;
2704 gboolean need_reposition;
2705 gboolean default_size_changed = FALSE;
2706 gboolean hints_changed = FALSE;
2707 gboolean may_shrink = window->auto_shrink;
2709 g_return_if_fail (GTK_WIDGET_REALIZED (window));
2711 widget = GTK_WIDGET (window);
2712 container = GTK_CONTAINER (widget);
2713 info = gtk_window_get_geometry_info (window, TRUE);
2714 saved_last_info = info->last;
2716 gtk_widget_size_request (widget, NULL);
2717 gtk_window_compute_default_size (window, &new_width, &new_height);
2719 if (info->last.width < 0 ||
2720 info->last.width != new_width ||
2721 info->last.height != new_height)
2723 default_size_changed = TRUE;
2724 may_shrink |= info->may_shrink;
2725 info->last.width = new_width;
2726 info->last.height = new_height;
2728 /* We need to force a reposition in this case
2730 if (window->position == GTK_WIN_POS_CENTER_ALWAYS)
2731 window->use_uposition = TRUE;
2733 info->may_shrink = FALSE;
2735 /* Compute new set of hints for the window
2737 gtk_window_compute_hints (window, &new_geometry, &new_flags);
2738 if (!gtk_window_compare_hints (&info->last.geometry, info->last.flags,
2739 &new_geometry, new_flags))
2741 hints_changed = TRUE;
2742 info->last.geometry = new_geometry;
2743 info->last.flags = new_flags;
2746 /* From the default size and the allocation, figure out the size
2747 * the window should be.
2749 if (!default_size_changed ||
2751 new_width <= widget->allocation.width &&
2752 new_height <= widget->allocation.height))
2754 new_width = widget->allocation.width;
2755 new_height = widget->allocation.height;
2758 /* constrain the window size to the specified geometry */
2759 gtk_window_constrain_size (window,
2760 &new_geometry, new_flags,
2761 new_width, new_height,
2762 &new_width, &new_height);
2764 /* compute new window position if a move is required
2766 need_reposition = gtk_window_compute_reposition (window, new_width, new_height, &x, &y);
2767 if (need_reposition && !(new_flags & GDK_HINT_POS))
2769 new_flags |= GDK_HINT_POS;
2770 hints_changed = TRUE;
2774 /* handle actual resizing:
2775 * - handle reallocations due to configure events
2776 * - figure whether we need to request a new window size
2777 * - handle simple resizes within our widget tree
2778 * - reposition window if neccessary
2780 width = widget->allocation.width;
2781 height = widget->allocation.height;
2783 if (window->handling_resize)
2785 GtkAllocation allocation;
2787 /* if we are just responding to a configure event, which
2788 * might be due to a resize by the window manager, the
2789 * user, or a response to a resizing request we made
2790 * earlier, we go ahead, allocate the new size and we're done
2791 * (see gtk_window_configure_event() for more details).
2794 window->handling_resize = FALSE;
2796 allocation = widget->allocation;
2798 gtk_widget_size_allocate (widget, &allocation);
2799 gtk_widget_queue_draw (widget);
2801 if ((default_size_changed || hints_changed) && (width != new_width || height != new_height))
2803 /* We could be here for two reasons
2804 * 1) We coincidentally got a resize while handling
2806 * 2) Our computation of default_size_changed was completely
2807 * screwed up, probably because one of our children
2808 * is changed requisition during size allocation).
2810 * For 1), we could just go ahead and ask for the
2811 * new size right now, but doing that for 2)
2812 * might well be fighting the user (and can even
2813 * trigger a loop). Since we really don't want to
2814 * do that, we requeue a resize in hopes that
2815 * by the time it gets handled, the child has seen
2816 * the light and is willing to go along with the
2817 * new size. (this happens for the zvt widget, since
2818 * the size_allocate() above will have stored the
2819 * requisition corresponding to the new size in the
2822 * This doesn't buy us anything for 1), but it shouldn't
2823 * hurt us too badly, since it is what would have
2824 * happened if we had gotten the configure event before
2825 * the new size had been set.
2828 if (need_reposition)
2831 gdk_window_move (window->frame, x - window->frame_left, y - window->frame_top);
2833 gdk_window_move (GTK_WIDGET (window)->window, x, y);
2836 /* we have to preserve the values and flags that are used
2837 * for computation of default_size_changed and hints_changed
2839 info->last = saved_last_info;
2841 gtk_widget_queue_resize (widget);
2847 /* Now set hints if necessary
2850 gdk_window_set_geometry_hints (widget->window,
2854 if ((default_size_changed || hints_changed) &&
2855 (width != new_width || height != new_height))
2857 /* given that (width != new_width || height != new_height), we are in one
2858 * of the following situations:
2860 * default_size_changed
2861 * our requisition has changed and we need a different window size,
2862 * so we request it from the window manager.
2864 * !default_size_changed
2865 * the window manager wouldn't assign us the size we requested, in this
2866 * case we don't try to request a new size with every resize.
2868 * !default_size_changed && hints_changed
2869 * the window manager rejects our size, but we have just changed the
2870 * window manager hints, so there's a certain chance our request will
2871 * be honoured this time, so we try again.
2874 /* request a new window size */
2875 if (need_reposition)
2879 gdk_window_move_resize (window->frame,
2880 x - window->frame_left, y - window->frame_top,
2881 new_width + window->frame_left + window->frame_right,
2882 new_height + window->frame_top + window->frame_bottom);
2883 gdk_window_resize (GTK_WIDGET (window)->window, new_width, new_height);
2886 gdk_window_move_resize (GTK_WIDGET (window)->window, x, y, new_width, new_height);
2891 gdk_window_resize (window->frame,
2892 new_width + window->frame_left + window->frame_right,
2893 new_height + window->frame_top + window->frame_bottom);
2894 gdk_window_resize (GTK_WIDGET (window)->window, new_width, new_height);
2896 window->resize_count += 1;
2898 /* we are now awaiting the new configure event in response to our
2899 * resizing request. the configure event will cause a new resize
2900 * with ->handling_resize=TRUE.
2901 * until then, we want to
2902 * - discard expose events
2903 * - coalesce resizes for our children
2904 * - defer any window resizes until the configure event arrived
2905 * to achive this, we queue a resize for the window, but remove its
2906 * resizing handler, so resizing will not be handled from the next
2907 * idle handler but when the configure event arrives.
2909 * FIXME: we should also dequeue the pending redraws here, since
2910 * we handle those ourselves in ->handling_resize==TRUE.
2912 gtk_widget_queue_resize (GTK_WIDGET (container));
2913 if (container->resize_mode == GTK_RESIZE_QUEUE)
2914 gtk_container_dequeue_resize_handler (container);
2918 if (need_reposition)
2921 gdk_window_move (window->frame, x - window->frame_left, y - window->frame_top);
2923 gdk_window_move (widget->window, x, y);
2926 if (container->resize_widgets)
2927 gtk_container_resize_children (GTK_CONTAINER (window));
2931 /* Compare two sets of Geometry hints for equality.
2934 gtk_window_compare_hints (GdkGeometry *geometry_a,
2936 GdkGeometry *geometry_b,
2939 if (flags_a != flags_b)
2942 if ((flags_a & GDK_HINT_MIN_SIZE) &&
2943 (geometry_a->min_width != geometry_b->min_width ||
2944 geometry_a->min_height != geometry_b->min_height))
2947 if ((flags_a & GDK_HINT_MAX_SIZE) &&
2948 (geometry_a->max_width != geometry_b->max_width ||
2949 geometry_a->max_height != geometry_b->max_height))
2952 if ((flags_a & GDK_HINT_BASE_SIZE) &&
2953 (geometry_a->base_width != geometry_b->base_width ||
2954 geometry_a->base_height != geometry_b->base_height))
2957 if ((flags_a & GDK_HINT_ASPECT) &&
2958 (geometry_a->min_aspect != geometry_b->min_aspect ||
2959 geometry_a->max_aspect != geometry_b->max_aspect))
2962 if ((flags_a & GDK_HINT_RESIZE_INC) &&
2963 (geometry_a->width_inc != geometry_b->width_inc ||
2964 geometry_a->height_inc != geometry_b->height_inc))
2967 if ((flags_a & GDK_HINT_WIN_GRAVITY) &&
2968 geometry_a->win_gravity != geometry_b->win_gravity)
2974 /* Compute the default_size for a window. The result will
2975 * be stored in *width and *height. The default size is
2976 * the size the window should have when initially mapped.
2977 * This routine does not attempt to constrain the size
2978 * to obey the geometry hints - that must be done elsewhere.
2981 gtk_window_compute_default_size (GtkWindow *window,
2985 GtkRequisition requisition;
2986 GtkWindowGeometryInfo *info;
2988 gtk_widget_get_child_requisition (GTK_WIDGET (window), &requisition);
2989 *width = requisition.width;
2990 *height = requisition.height;
2992 info = gtk_window_get_geometry_info (window, FALSE);
2994 if (*width == 0 && *height == 0)
3003 *width = info->width > 0 ? info->width : *width;
3004 *height = info->height > 0 ? info->height : *height;
3009 _gtk_window_constrain_size (GtkWindow *window,
3015 GtkWindowGeometryInfo *info;
3017 g_return_if_fail (GTK_IS_WINDOW (window));
3019 info = window->geometry_info;
3022 GdkWindowHints flags = info->last.flags;
3023 GdkGeometry *geometry = &info->last.geometry;
3025 gtk_window_constrain_size (window,
3036 gtk_window_constrain_size (GtkWindow *window,
3037 GdkGeometry *geometry,
3044 gdk_window_constrain_size (geometry, flags, width, height,
3045 new_width, new_height);
3048 /* Compute the set of geometry hints and flags for a window
3049 * based on the application set geometry, and requisiition
3050 * of the window. gtk_widget_size_request() must have been
3054 gtk_window_compute_hints (GtkWindow *window,
3055 GdkGeometry *new_geometry,
3059 GtkWidgetAuxInfo *aux_info;
3061 gint extra_width = 0;
3062 gint extra_height = 0;
3063 GtkWindowGeometryInfo *geometry_info;
3064 GtkRequisition requisition;
3066 g_return_if_fail (GTK_IS_WINDOW (window));
3068 widget = GTK_WIDGET (window);
3070 gtk_widget_get_child_requisition (widget, &requisition);
3071 geometry_info = gtk_window_get_geometry_info (GTK_WINDOW (widget), FALSE);
3073 g_return_if_fail (geometry_info != NULL);
3075 *new_flags = geometry_info->mask;
3076 *new_geometry = geometry_info->geometry;
3078 if (geometry_info->widget)
3080 extra_width = widget->requisition.width - geometry_info->widget->requisition.width;
3081 extra_height = widget->requisition.height - geometry_info->widget->requisition.height;
3087 aux_info = _gtk_widget_get_aux_info (widget, FALSE);
3088 if (aux_info && aux_info->x_set && aux_info->y_set)
3092 *new_flags |= GDK_HINT_POS;
3095 if (*new_flags & GDK_HINT_BASE_SIZE)
3097 new_geometry->base_width += extra_width;
3098 new_geometry->base_height += extra_height;
3100 else if (!(*new_flags & GDK_HINT_MIN_SIZE) &&
3101 (*new_flags & GDK_HINT_RESIZE_INC) &&
3102 ((extra_width != 0) || (extra_height != 0)))
3104 *new_flags |= GDK_HINT_BASE_SIZE;
3106 new_geometry->base_width = extra_width;
3107 new_geometry->base_height = extra_height;
3110 if (*new_flags & GDK_HINT_MIN_SIZE)
3112 if (new_geometry->min_width < 0)
3113 new_geometry->min_width = requisition.width;
3115 new_geometry->min_width += extra_width;
3117 if (new_geometry->min_height < 0)
3118 new_geometry->min_width = requisition.height;
3120 new_geometry->min_height += extra_height;
3122 else if (!window->allow_shrink)
3124 *new_flags |= GDK_HINT_MIN_SIZE;
3126 new_geometry->min_width = requisition.width;
3127 new_geometry->min_height = requisition.height;
3130 if (*new_flags & GDK_HINT_MAX_SIZE)
3132 if (new_geometry->max_width < 0)
3133 new_geometry->max_width = requisition.width;
3135 new_geometry->max_width += extra_width;
3137 if (new_geometry->max_height < 0)
3138 new_geometry->max_width = requisition.height;
3140 new_geometry->max_height += extra_height;
3142 else if (!window->allow_grow)
3144 *new_flags |= GDK_HINT_MAX_SIZE;
3146 new_geometry->max_width = requisition.width;
3147 new_geometry->max_height = requisition.height;
3150 *new_flags |= GDK_HINT_WIN_GRAVITY;
3151 new_geometry->win_gravity = window->gravity;
3154 /* Compute a new position for the window based on a new
3155 * size. *x and *y will be set to the new coordinates. Returns
3156 * TRUE if the window needs to be moved (and thus x and y got
3160 gtk_window_compute_reposition (GtkWindow *window,
3166 GtkWidget *widget = GTK_WIDGET (window);
3167 GtkWindowPosition pos;
3168 GtkWidget *parent_widget;
3169 gboolean needs_move = FALSE;
3171 parent_widget = (GtkWidget*) window->transient_parent;
3173 pos = window->position;
3174 if (pos == GTK_WIN_POS_CENTER_ON_PARENT &&
3175 (parent_widget == NULL ||
3176 !GTK_WIDGET_MAPPED (parent_widget)))
3177 pos = GTK_WIN_POS_NONE;
3181 case GTK_WIN_POS_CENTER:
3182 case GTK_WIN_POS_CENTER_ALWAYS:
3183 if (window->use_uposition)
3185 gint screen_width = gdk_screen_width ();
3186 gint screen_height = gdk_screen_height ();
3188 *x = (screen_width - new_width) / 2;
3189 *y = (screen_height - new_height) / 2;
3194 case GTK_WIN_POS_CENTER_ON_PARENT:
3195 if (window->use_uposition)
3198 gdk_window_get_origin (parent_widget->window,
3201 *x = ox + (parent_widget->allocation.width - new_width) / 2;
3202 *y = oy + (parent_widget->allocation.height - new_height) / 2;
3207 case GTK_WIN_POS_MOUSE:
3208 if (window->use_uposition)
3210 gint screen_width = gdk_screen_width ();
3211 gint screen_height = gdk_screen_height ();
3213 gdk_window_get_pointer (NULL, x, y, NULL);
3214 *x -= new_width / 2;
3215 *y -= new_height / 2;
3216 *x = CLAMP (*x, 0, screen_width - new_width);
3217 *y = CLAMP (*y, 0, screen_height - new_height);
3222 if (window->use_uposition)
3224 GtkWidgetAuxInfo *aux_info = _gtk_widget_get_aux_info (widget, FALSE);
3226 if (aux_info && aux_info->x_set && aux_info->y_set)
3238 GtkWidgetAuxInfo *aux_info = _gtk_widget_get_aux_info (widget, TRUE);
3240 /* we handle necessary window positioning by hand here,
3241 * so we can coalesce the window movement with possible
3242 * resizes to get only one configure event.
3244 aux_info->x_set = TRUE;
3245 aux_info->y_set = TRUE;
3248 window->use_uposition = FALSE;
3254 /***********************
3255 * Redrawing functions *
3256 ***********************/
3259 gtk_window_paint (GtkWidget *widget,
3262 gtk_paint_flat_box (widget->style, widget->window, GTK_STATE_NORMAL,
3263 GTK_SHADOW_NONE, area, widget, "base", 0, 0, -1, -1);
3267 gtk_window_expose (GtkWidget *widget,
3268 GdkEventExpose *event)
3270 g_return_val_if_fail (widget != NULL, FALSE);
3271 g_return_val_if_fail (GTK_IS_WINDOW (widget), FALSE);
3272 g_return_val_if_fail (event != NULL, FALSE);
3274 if (!GTK_WIDGET_APP_PAINTABLE (widget))
3275 gtk_window_paint (widget, &event->area);
3277 if (GTK_WIDGET_CLASS (parent_class)->expose_event)
3278 return GTK_WIDGET_CLASS (parent_class)->expose_event (widget, event);
3284 * gtk_window_set_has_frame:
3285 * @window: a #GtkWindow
3286 * @setting: a boolean
3288 * If this function is called on a window with setting of TRUE, before
3289 * it is realized or showed, it will have a "frame" window around
3290 * widget->window, accessible in window->frame. Using the signal
3291 * frame_event you can recieve all events targeted at the frame.
3293 * This function is used by the linux-fb port to implement managed
3294 * windows, but it could concievably be used by X-programs that
3295 * want to do their own window decorations.
3298 gtk_window_set_has_frame (GtkWindow *window,
3301 g_return_if_fail (window != NULL);
3302 g_return_if_fail (GTK_IS_WINDOW (window));
3303 g_return_if_fail (!GTK_WIDGET_REALIZED (window));
3305 window->has_frame = setting != FALSE;
3309 * gtk_window_get_has_frame:
3310 * @window: a #GtkWindow
3312 * Returns whether the window has a frame window exterior to
3313 * widget->window. See gtk_window_set_has_frame ().
3315 * Return value: %TRUE if a frame has been added to the window
3316 * via gtk_widow_has_frame
3319 gtk_window_get_has_frame (GtkWindow *window)
3321 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
3323 return window->has_frame;
3327 * gtk_window_set_frame_dimensions:
3328 * @window: a #GtkWindow that has a frame
3329 * @left: The width of the left border
3330 * @top: The height of the top border
3331 * @right: The width of the right border
3332 * @bottom: The height of the bottom border
3334 * For windows with frames (see #gtk_window_set_has_frame) this function
3335 * can be used to change the size of the frame border.
3338 gtk_window_set_frame_dimensions (GtkWindow *window,
3344 GtkWidget *widget = GTK_WIDGET (window);
3346 g_return_if_fail (window != NULL);
3347 g_return_if_fail (GTK_IS_WINDOW (window));
3349 if (window->frame_left == left &&
3350 window->frame_top == top &&
3351 window->frame_right == right &&
3352 window->frame_bottom == bottom)
3355 window->frame_left = left;
3356 window->frame_top = top;
3357 window->frame_right = right;
3358 window->frame_bottom = bottom;
3360 if (GTK_WIDGET_REALIZED (widget) && window->frame)
3362 gint width = widget->allocation.width + left + right;
3363 gint height = widget->allocation.height + top + bottom;
3364 gdk_window_resize (window->frame, width, height);
3365 gtk_decorated_window_move_resize_window (window,
3367 widget->allocation.width,
3368 widget->allocation.height);
3373 * gtk_window_present:
3374 * @window: a #GtkWindow
3376 * Presents a window to the user. This may mean raising the window
3377 * in the stacking order, deiconifying it, moving it to the current
3378 * desktop, and/or giving it the keyboard focus, possibly dependent
3379 * on the user's platform, window manager, and preferences.
3381 * If @window is hidden, this function calls gtk_widget_show()
3384 * This function should be used when the user tries to open a window
3385 * that's already open. Say for example the preferences dialog is
3386 * currently open, and the user chooses Preferences from the menu
3387 * a second time; use gtk_window_present() to move the already-open dialog
3388 * where the user can see it.
3392 gtk_window_present (GtkWindow *window)
3396 g_return_if_fail (GTK_IS_WINDOW (window));
3398 widget = GTK_WIDGET (window);
3400 if (GTK_WIDGET_VISIBLE (window))
3402 g_assert (widget->window != NULL);
3404 gdk_window_show (widget->window);
3406 /* note that gdk_window_focus() will also move the window to
3407 * the current desktop, for WM spec compliant window managers.
3409 gdk_window_focus (widget->window,
3410 gtk_get_current_event_time ());
3414 gtk_widget_show (widget);
3419 * gtk_window_iconify:
3420 * @window: a #GtkWindow
3422 * Asks to iconify @window. Note that you shouldn't assume the window
3423 * is definitely iconified afterward, because other entities (e.g. the
3424 * user or window manager) could deiconify it again, or there may not
3425 * be a window manager in which case iconification isn't possible,
3426 * etc. But normally the window will end up iconified. Just don't write
3427 * code that crashes if not.
3429 * It's permitted to call this function before showing a window,
3430 * in which case the window will be iconified before it ever appears
3433 * You can track iconification via the "window_state_event" signal
3438 gtk_window_iconify (GtkWindow *window)
3441 GdkWindow *toplevel;
3443 g_return_if_fail (GTK_IS_WINDOW (window));
3445 widget = GTK_WIDGET (window);
3447 window->iconify_initially = TRUE;
3450 toplevel = window->frame;
3452 toplevel = widget->window;
3454 if (toplevel != NULL)
3455 gdk_window_iconify (toplevel);
3459 * gtk_window_deiconify:
3460 * @window: a #GtkWindow
3462 * Asks to deiconify @window. Note that you shouldn't assume the
3463 * window is definitely deiconified afterward, because other entities
3464 * (e.g. the user or window manager) could iconify it again before
3465 * your code which assumes deiconification gets to run.
3467 * You can track iconification via the "window_state_event" signal
3471 gtk_window_deiconify (GtkWindow *window)
3474 GdkWindow *toplevel;
3476 g_return_if_fail (GTK_IS_WINDOW (window));
3478 widget = GTK_WIDGET (window);
3480 window->iconify_initially = FALSE;
3483 toplevel = window->frame;
3485 toplevel = widget->window;
3487 if (toplevel != NULL)
3488 gdk_window_deiconify (toplevel);
3493 * @window: a #GtkWindow
3495 * Asks to stick @window, which means that it will appear on all user
3496 * desktops. Note that you shouldn't assume the window is definitely
3497 * stuck afterward, because other entities (e.g. the user or window
3498 * manager) could unstick it again, and some window managers do not
3499 * support sticking windows. But normally the window will end up
3500 * stuck. Just don't write code that crashes if not.
3502 * It's permitted to call this function before showing a window.
3504 * You can track stickiness via the "window_state_event" signal
3509 gtk_window_stick (GtkWindow *window)
3512 GdkWindow *toplevel;
3514 g_return_if_fail (GTK_IS_WINDOW (window));
3516 widget = GTK_WIDGET (window);
3518 window->stick_initially = TRUE;
3521 toplevel = window->frame;
3523 toplevel = widget->window;
3525 if (toplevel != NULL)
3526 gdk_window_stick (toplevel);
3530 * gtk_window_unstick:
3531 * @window: a #GtkWindow
3533 * Asks to unstick @window, which means that it will appear on only
3534 * one of the user's desktops. Note that you shouldn't assume the
3535 * window is definitely unstuck afterward, because other entities
3536 * (e.g. the user or window manager) could stick it again. But
3537 * normally the window will end up stuck. Just don't write code that
3540 * You can track stickiness via the "window_state_event" signal
3545 gtk_window_unstick (GtkWindow *window)
3548 GdkWindow *toplevel;
3550 g_return_if_fail (GTK_IS_WINDOW (window));
3552 widget = GTK_WIDGET (window);
3554 window->stick_initially = FALSE;
3557 toplevel = window->frame;
3559 toplevel = widget->window;
3561 if (toplevel != NULL)
3562 gdk_window_unstick (toplevel);
3566 * gtk_window_maximize:
3567 * @window: a #GtkWindow
3569 * Asks to maximize @window, so that it becomes full-screen. Note that
3570 * you shouldn't assume the window is definitely maximized afterward,
3571 * because other entities (e.g. the user or window manager) could
3572 * unmaximize it again, and not all window managers support
3573 * maximization. But normally the window will end up maximized. Just
3574 * don't write code that crashes if not.
3576 * It's permitted to call this function before showing a window,
3577 * in which case the window will be maximized when it appears onscreen
3580 * You can track maximization via the "window_state_event" signal
3585 gtk_window_maximize (GtkWindow *window)
3588 GdkWindow *toplevel;
3590 g_return_if_fail (GTK_IS_WINDOW (window));
3592 widget = GTK_WIDGET (window);
3594 window->maximize_initially = TRUE;
3597 toplevel = window->frame;
3599 toplevel = widget->window;
3601 if (toplevel != NULL)
3602 gdk_window_maximize (toplevel);
3606 * gtk_window_unmaximize:
3607 * @window: a #GtkWindow
3609 * Asks to unmaximize @window. Note that you shouldn't assume the
3610 * window is definitely unmaximized afterward, because other entities
3611 * (e.g. the user or window manager) could maximize it again, and not
3612 * all window managers honor requests to unmaximize. But normally the
3613 * window will end up unmaximized. Just don't write code that crashes
3616 * You can track maximization via the "window_state_event" signal
3621 gtk_window_unmaximize (GtkWindow *window)
3624 GdkWindow *toplevel;
3626 g_return_if_fail (GTK_IS_WINDOW (window));
3628 widget = GTK_WIDGET (window);
3630 window->maximize_initially = FALSE;
3633 toplevel = window->frame;
3635 toplevel = widget->window;
3637 if (toplevel != NULL)
3638 gdk_window_unmaximize (toplevel);
3642 * gtk_window_set_resizable:
3643 * @window: a #GtkWindow
3644 * @resizable: %TRUE if the user can resize this window
3646 * Sets whether the user can resize a window. Windows are user resizable
3650 gtk_window_set_resizable (GtkWindow *window,
3653 g_return_if_fail (GTK_IS_WINDOW (window));
3655 gtk_window_set_policy (window, FALSE, resizable, FALSE);
3659 * gtk_window_get_resizable:
3660 * @window: a #GtkWindow
3662 * Gets the value set by gtk_window_set_resizable().
3664 * Return value: %TRUE if the user can resize the window
3667 gtk_window_get_resizable (GtkWindow *window)
3669 g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE);
3671 /* allow_grow is most likely to indicate the semantic concept we
3672 * mean by "resizable" (and will be a reliable indicator if
3673 * set_policy() hasn't been called)
3675 return window->allow_grow;
3679 * gtk_window_set_gravity:
3680 * @window: a #GtkWindow
3681 * @gravity: window gravity
3683 * Window gravity defines the "reference point" to be used when
3684 * positioning or resizing a window. Calls to
3685 * gtk_widget_set_uposition() will position a different point on the
3686 * window depending on the window gravity. When the window changes size
3687 * the reference point determined by the window's gravity will stay in
3690 * See #GdkGravity for full details. To briefly summarize,
3691 * #GDK_GRAVITY_NORTH_WEST means that the reference point is the
3692 * northwest (top left) corner of the window
3693 * frame. #GDK_GRAVITY_SOUTH_EAST would be the bottom right corner of
3694 * the frame, and so on. If you want to position the window contents,
3695 * rather than the window manager's frame, #GDK_GRAVITY_STATIC moves
3696 * the reference point to the northwest corner of the #GtkWindow
3699 * The default window gravity is #GDK_GRAVITY_NORTH_WEST.
3703 gtk_window_set_gravity (GtkWindow *window,
3706 g_return_if_fail (GTK_IS_WINDOW (window));
3708 if (gravity != window->gravity)
3710 window->gravity = gravity;
3712 /* gtk_window_move_resize() will adapt gravity
3714 gtk_widget_queue_resize (GTK_WIDGET (window));
3719 * gtk_window_get_gravity:
3720 * @window: a #GtkWindow
3722 * Gets the value set by gtk_window_set_gravity().
3724 * Return value: window gravity
3727 gtk_window_get_gravity (GtkWindow *window)
3729 g_return_val_if_fail (GTK_IS_WINDOW (window), 0);
3731 return window->gravity;
3735 * gtk_window_begin_resize_drag:
3736 * @window: a #GtkWindow
3737 * @button: mouse button that initiated the drag
3738 * @edge: position of the resize control
3739 * @root_x: X position where the user clicked to initiate the drag, in root window coordinates
3740 * @root_y: Y position where the user clicked to initiate the drag
3741 * @timestamp: timestamp from the click event that initiated the drag
3743 * Starts resizing a window. This function is used if an application
3744 * has window resizing controls. When GDK can support it, the resize
3745 * will be done using the standard mechanism for the window manager or
3746 * windowing system. Otherwise, GDK will try to emulate window
3747 * resizing, potentially not all that well, depending on the windowing system.
3751 gtk_window_begin_resize_drag (GtkWindow *window,
3759 GdkWindow *toplevel;
3761 g_return_if_fail (GTK_IS_WINDOW (window));
3762 g_return_if_fail (GTK_WIDGET_VISIBLE (window));
3764 widget = GTK_WIDGET (window);
3767 toplevel = window->frame;
3769 toplevel = widget->window;
3771 gdk_window_begin_resize_drag (toplevel,
3778 * gtk_window_get_frame_dimensions:
3779 * @window: a #GtkWindow
3780 * @left: location to store the width of the frame at the left, or %NULL
3781 * @top: location to store the height of the frame at the top, or %NULL
3782 * @right: location to store the width of the frame at the returns, or %NULL
3783 * @bottom: location to store the height of the frame at the bottom, or %NULL
3785 * Retrieves the dimensions of the frame window for this toplevel.
3786 * See gtk_window_set_has_frame(), gtk_window_set_frame_dimensions().
3789 gtk_window_get_frame_dimensions (GtkWindow *window,
3795 g_return_if_fail (GTK_IS_WINDOW (window));
3798 *left = window->frame_left;
3800 *top = window->frame_top;
3802 *top = window->frame_right;
3804 *top = window->frame_bottom;
3808 * gtk_window_begin_move_drag:
3809 * @window: a #GtkWindow
3810 * @button: mouse button that initiated the drag
3811 * @root_x: X position where the user clicked to initiate the drag, in root window coordinates
3812 * @root_y: Y position where the user clicked to initiate the drag
3813 * @timestamp: timestamp from the click event that initiated the drag
3815 * Starts moving a window. This function is used if an application
3816 * has window movement grips. When GDK can support it, the window movement
3817 * will be done using the standard mechanism for the window manager or
3818 * windowing system. Otherwise, GDK will try to emulate window
3819 * movement, potentially not all that well, depending on the windowing system.
3823 gtk_window_begin_move_drag (GtkWindow *window,
3830 GdkWindow *toplevel;
3832 g_return_if_fail (GTK_IS_WINDOW (window));
3833 g_return_if_fail (GTK_WIDGET_VISIBLE (window));
3835 widget = GTK_WIDGET (window);
3838 toplevel = window->frame;
3840 toplevel = widget->window;
3842 gdk_window_begin_move_drag (toplevel,
3850 gtk_window_group_class_init (GtkWindowGroupClass *klass)
3855 gtk_window_group_get_type (void)
3857 static GtkType window_group_type = 0;
3859 if (!window_group_type)
3861 static const GTypeInfo window_group_info =
3863 sizeof (GtkWindowGroupClass),
3864 NULL, /* base_init */
3865 NULL, /* base_finalize */
3866 (GClassInitFunc) gtk_window_group_class_init,
3867 NULL, /* class_finalize */
3868 NULL, /* class_data */
3869 sizeof (GtkWindowGroup),
3870 16, /* n_preallocs */
3871 (GInstanceInitFunc) NULL,
3874 window_group_type = g_type_register_static (G_TYPE_OBJECT, "GtkWindowGroup", &window_group_info, 0);
3877 return window_group_type;
3881 * gtk_window_group_new:
3883 * Create a new #GtkWindowGroup object. Grabs added with
3884 * gtk_window_grab_add() only affect windows within the
3885 * same #GtkWindowGroup
3890 gtk_window_group_new (void)
3892 return g_object_new (GTK_TYPE_WINDOW_GROUP, NULL);
3896 window_group_cleanup_grabs (GtkWindowGroup *group,
3900 GSList *to_remove = NULL;
3902 tmp_list = group->grabs;
3905 if (gtk_widget_get_toplevel (tmp_list->data) == (GtkWidget*) window)
3906 to_remove = g_slist_prepend (to_remove, g_object_ref (tmp_list->data));
3907 tmp_list = tmp_list->next;
3912 gtk_grab_remove (to_remove->data);
3913 g_object_unref (to_remove->data);
3914 to_remove = g_slist_delete_link (to_remove, to_remove);
3919 * gtk_window_group_add_widget:
3920 * @window_group: a #GtkWindowGroup
3921 * @window: the #GtkWindow to add
3923 * Add a window to a #GtkWindowGroup.
3926 gtk_window_group_add_window (GtkWindowGroup *window_group,
3929 g_return_if_fail (GTK_IS_WINDOW_GROUP (window_group));
3930 g_return_if_fail (GTK_IS_WINDOW (window));
3932 if (window->group != window_group)
3934 g_object_ref (window);
3935 g_object_ref (window_group);
3938 gtk_window_group_remove_window (window->group, window);
3940 window_group_cleanup_grabs (_gtk_window_get_group (NULL), window);
3942 window->group = window_group;
3944 g_object_unref (window);
3949 * gtk_window_group_remove_window:
3950 * @window_group: a #GtkWindowGroup
3951 * @window: the #GtkWindow to remove
3953 * Removes a window from a #GtkWindowGroup.
3956 gtk_window_group_remove_window (GtkWindowGroup *window_group,
3959 g_return_if_fail (GTK_IS_WINDOW_GROUP (window_group));
3960 g_return_if_fail (GTK_IS_WIDGET (window));
3961 g_return_if_fail (window->group == window_group);
3963 g_object_ref (window);
3965 window_group_cleanup_grabs (window_group, window);
3966 window->group = NULL;
3968 g_object_unref (G_OBJECT (window_group));
3969 g_object_unref (window);
3972 /* Return the group for the window or the default group
3975 _gtk_window_get_group (GtkWindow *window)
3977 if (window && window->group)
3978 return window->group;
3981 static GtkWindowGroup *default_group = NULL;
3984 default_group = gtk_window_group_new ();
3986 return default_group;