X-Git-Url: http://pileus.org/git/?a=blobdiff_plain;f=gtk%2Fgtkwindow.c;h=98b5c86dd0c381245350f9ec6adcd31dc166330e;hb=f91c04e2846de010871ee21389eb926dd18e065e;hp=2723c426144fac509ac2ca5b8be3eda49a5d05dd;hpb=8f1f7439033e85ebf480c1c62e8e4647cba80b97;p=~andy%2Fgtk diff --git a/gtk/gtkwindow.c b/gtk/gtkwindow.c index 2723c4261..98b5c86dd 100644 --- a/gtk/gtkwindow.c +++ b/gtk/gtkwindow.c @@ -26,19 +26,17 @@ #include "config.h" -#include "gtkintl.h" +#include "gtkwindow.h" #include #include #include #include -#include "gdk/gdk.h" -#include "gdk/gdkkeysyms.h" #include "gtkprivate.h" #include "gtkrc.h" -#include "gtkwindow.h" #include "gtkwindowprivate.h" +#include "gtkaccelgroupprivate.h" #include "gtkbindings.h" #include "gtkkeyhash.h" #include "gtkmain.h" @@ -50,6 +48,8 @@ #include "gtkplug.h" #include "gtkbuildable.h" #include "gtkwidgetprivate.h" +#include "gtkintl.h" +#include "gtktypebuiltins.h" #ifdef GDK_WINDOWING_X11 #include "x11/gdkx.h" @@ -110,7 +110,6 @@ struct _GtkWindowPrivate GdkModifierType mnemonic_modifier; GdkScreen *screen; - GdkWindow *frame; GdkWindowTypeHint gdk_type_hint; GtkApplication *application; @@ -125,10 +124,6 @@ struct _GtkWindowPrivate gchar *wmclass_name; gchar *wm_role; - guint frame_bottom; - guint frame_left; - guint frame_right; - guint frame_top; guint keys_changed_handler; guint16 configure_request_count; @@ -155,7 +150,6 @@ struct _GtkWindowPrivate guint gravity : 5; /* GdkGravity */ guint has_focus : 1; guint has_user_ref_count : 1; - guint has_frame : 1; guint has_toplevel_focus : 1; guint iconify_initially : 1; /* gtk_window_iconify() called before realization */ guint is_active : 1; @@ -323,12 +317,8 @@ static void gtk_window_realize (GtkWidget *widget); static void gtk_window_unrealize (GtkWidget *widget); static void gtk_window_size_allocate (GtkWidget *widget, GtkAllocation *allocation); -static gint gtk_window_event (GtkWidget *widget, - GdkEvent *event); static gboolean gtk_window_map_event (GtkWidget *widget, GdkEventAny *event); -static gboolean gtk_window_frame_event (GtkWindow *window, - GdkEvent *event); static gint gtk_window_configure_event (GtkWidget *widget, GdkEventConfigure *event); static gint gtk_window_key_press_event (GtkWidget *widget, @@ -346,8 +336,6 @@ static gint gtk_window_focus_in_event (GtkWidget *widget, static gint gtk_window_focus_out_event (GtkWidget *widget, GdkEventFocus *event); static void gtk_window_style_updated (GtkWidget *widget); -static gint gtk_window_client_event (GtkWidget *widget, - GdkEventClient *event); static gboolean gtk_window_state_event (GtkWidget *widget, GdkEventWindowState *event); static void gtk_window_check_resize (GtkContainer *container); @@ -585,7 +573,6 @@ gtk_window_class_init (GtkWindowClass *klass) widget_class->focus_in_event = gtk_window_focus_in_event; widget_class->button_press_event = gtk_window_button_press_event; widget_class->focus_out_event = gtk_window_focus_out_event; - widget_class->client_event = gtk_window_client_event; widget_class->focus = gtk_window_focus; widget_class->move_focus = gtk_window_move_focus; widget_class->draw = gtk_window_draw; @@ -599,7 +586,6 @@ gtk_window_class_init (GtkWindowClass *klass) container_class->check_resize = gtk_window_check_resize; klass->set_focus = gtk_window_real_set_focus; - klass->frame_event = gtk_window_frame_event; klass->activate_default = gtk_window_real_activate_default; klass->activate_focus = gtk_window_real_activate_focus; @@ -872,7 +858,7 @@ gtk_window_class_init (GtkWindowClass *klass) GTK_PARAM_READWRITE)); /** - * GtkWindow: resize-grip-visible: + * GtkWindow:resize-grip-visible: * * Whether a corner resize grip is currently shown. * @@ -954,15 +940,18 @@ gtk_window_class_init (GtkWindowClass *klass) 0, G_MAXINT, 16, GTK_PARAM_READWRITE)); - /* Signals - */ /** * GtkWindow:application: * * The #GtkApplication associated with the window. * - * The application will be kept alive for at least as long as the - * window is open. + * The application will be kept alive for at least as long as it + * has any windows associated with it (see g_application_hold() + * for a way to keep it alive without windows). + * + * Normally, the connection between the application and the window + * will remain until the window is destroyed, but you can explicitly + * remove it by setting the ::application property to %NULL. * * Since: 3.0 */ @@ -983,16 +972,6 @@ gtk_window_class_init (GtkWindowClass *klass) _gtk_marshal_VOID__OBJECT, G_TYPE_NONE, 1, GTK_TYPE_WIDGET); - - window_signals[FRAME_EVENT] = - g_signal_new (I_("frame-event"), - G_TYPE_FROM_CLASS (gobject_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET(GtkWindowClass, frame_event), - _gtk_boolean_handled_accumulator, NULL, - _gtk_marshal_BOOLEAN__BOXED, - G_TYPE_BOOLEAN, 1, - GDK_TYPE_EVENT); /** * GtkWindow::activate-focus: @@ -1110,12 +1089,6 @@ gtk_window_init (GtkWindow *window) priv->need_default_size = TRUE; priv->need_default_position = TRUE; priv->modal = FALSE; - priv->frame = NULL; - priv->has_frame = FALSE; - priv->frame_left = 0; - priv->frame_right = 0; - priv->frame_top = 0; - priv->frame_bottom = 0; priv->gdk_type_hint = GDK_WINDOW_TYPE_HINT_NORMAL; priv->gravity = GDK_GRAVITY_NORTH_WEST; priv->decorated = TRUE; @@ -1135,8 +1108,9 @@ gtk_window_init (GtkWindow *window) priv->has_user_ref_count = TRUE; toplevel_list = g_slist_prepend (toplevel_list, window); - g_signal_connect (priv->screen, "composited-changed", - G_CALLBACK (gtk_window_on_composited_changed), window); + if (priv->screen) + g_signal_connect (priv->screen, "composited-changed", + G_CALLBACK (gtk_window_on_composited_changed), window); } static void @@ -2318,50 +2292,6 @@ gtk_window_list_toplevels (void) return list; } -void -gtk_window_add_embedded_xid (GtkWindow *window, GdkNativeWindow xid) -{ - GList *embedded_windows; - - g_return_if_fail (GTK_IS_WINDOW (window)); - - embedded_windows = g_object_get_qdata (G_OBJECT (window), quark_gtk_embedded); - if (embedded_windows) - g_object_steal_qdata (G_OBJECT (window), quark_gtk_embedded); - embedded_windows = g_list_prepend (embedded_windows, - GUINT_TO_POINTER (xid)); - - g_object_set_qdata_full (G_OBJECT (window), quark_gtk_embedded, - embedded_windows, - embedded_windows ? - (GDestroyNotify) g_list_free : NULL); -} - -void -gtk_window_remove_embedded_xid (GtkWindow *window, GdkNativeWindow xid) -{ - GList *embedded_windows; - GList *node; - - g_return_if_fail (GTK_IS_WINDOW (window)); - - embedded_windows = g_object_get_qdata (G_OBJECT (window), quark_gtk_embedded); - if (embedded_windows) - g_object_steal_qdata (G_OBJECT (window), quark_gtk_embedded); - - node = g_list_find (embedded_windows, GUINT_TO_POINTER (xid)); - if (node) - { - embedded_windows = g_list_remove_link (embedded_windows, node); - g_list_free_1 (node); - } - - g_object_set_qdata_full (G_OBJECT (window), quark_gtk_embedded, - embedded_windows, - embedded_windows ? - (GDestroyNotify) g_list_free : NULL); -} - static void gtk_window_dispose (GObject *object) { @@ -2625,7 +2555,7 @@ gtk_window_get_opacity (GtkWindow *window) * * Gets the #GtkApplication associated with the window (if any). * - * Return value: a #GtkApplication, or %NULL + * Return value: (transfer none): a #GtkApplication, or %NULL * * Since: 3.0 **/ @@ -2656,7 +2586,7 @@ gtk_window_release_application (GtkWindow *window) /** * gtk_window_set_application: * @window: a #GtkWindow - * @application: a #GtkApplication, or %NULL + * @application: (allow-none): a #GtkApplication, or %NULL * * Sets or unsets the #GtkApplication associated with the window. * @@ -3147,7 +3077,7 @@ gtk_window_set_geometry_hints (GtkWindow *window, * using this function, GTK+ will do its best to convince the window * manager not to decorate the window. Depending on the system, this * function may not have any effect when called on a window that is - * already visible, so you should call it before calling gtk_window_show(). + * already visible, so you should call it before calling gtk_widget_show(). * * On Windows, this function always works, since there's no window manager * policy involved. @@ -3453,7 +3383,7 @@ gtk_window_unrealize_icon (GtkWindow *window) /** * gtk_window_set_icon_list: * @window: a #GtkWindow - * @list: (element-type GdkPixbuf) (transfer container): list of #GdkPixbuf + * @list: (element-type GdkPixbuf): list of #GdkPixbuf * * Sets up the icon representing a #GtkWindow. The icon is used when * the window is minimized (also known as iconified). Some window @@ -3713,7 +3643,7 @@ load_pixbuf_verbosely (const char *filename, /** * gtk_window_set_icon_from_file: * @window: a #GtkWindow - * @filename: location of icon file + * @filename: (type filename): location of icon file * @err: (allow-none): location to store error, or %NULL. * * Sets the icon for @window. @@ -3891,7 +3821,7 @@ gtk_window_get_default_icon_name (void) /** * gtk_window_set_default_icon_from_file: - * @filename: location of icon file + * @filename: (type filename): location of icon file * @err: (allow-none): location to store error, or %NULL. * * Sets an icon to be used as fallback for windows that haven't @@ -4279,9 +4209,9 @@ gtk_window_get_size (GtkWindow *window, * gdk_screen_height () - window_height) (note that this * example does not take multi-head scenarios into account). * - * The Extended Window Manager Hints specification at - * http://www.freedesktop.org/Standards/wm-spec has a + * http://www.freedesktop.org/Standards/wm-spec has a * nice table of gravities in the "implementation notes" section. * * The gtk_window_get_position() documentation may also be relevant. @@ -4291,17 +4221,15 @@ gtk_window_move (GtkWindow *window, gint x, gint y) { - GtkWindowPrivate *priv; GtkWindowGeometryInfo *info; GtkWidget *widget; - + g_return_if_fail (GTK_IS_WINDOW (window)); - priv = window->priv; widget = GTK_WIDGET (window); info = gtk_window_get_geometry_info (window, TRUE); - + if (gtk_widget_get_mapped (widget)) { GtkAllocation allocation; @@ -4324,7 +4252,7 @@ gtk_window_move (GtkWindow *window, gtk_window_constrain_position (window, allocation.width, allocation.height, &x, &y); - + /* Note that this request doesn't go through our standard request * framework, e.g. doesn't increment configure_request_count, * doesn't set info->last, etc.; that's because @@ -4335,15 +4263,7 @@ gtk_window_move (GtkWindow *window, * the same as the position being changed by the window * manager. */ - - /* FIXME are we handling gravity properly for framed windows? */ - if (priv->frame) - gdk_window_move (priv->frame, - x - priv->frame_left, - y - priv->frame_top); - else - gdk_window_move (gtk_widget_get_window (GTK_WIDGET (window)), - x, y); + gdk_window_move (gtk_widget_get_window (GTK_WIDGET (window)), x, y); } else { @@ -4448,10 +4368,7 @@ gtk_window_get_position (GtkWindow *window, if (gtk_widget_get_mapped (widget)) { - if (priv->frame) - gdk_window_get_frame_extents (priv->frame, &frame_extents); - else - gdk_window_get_frame_extents (gdk_window, &frame_extents); + gdk_window_get_frame_extents (gdk_window, &frame_extents); x = frame_extents.x; y = frame_extents.y; gtk_window_get_size (window, &w, &h); @@ -4460,7 +4377,7 @@ gtk_window_get_position (GtkWindow *window, { /* We just say the frame has 0 size on all sides. * Not sure what else to do. - */ + */ gtk_window_compute_configure_request (window, &frame_extents, NULL, NULL); @@ -4550,6 +4467,8 @@ gtk_window_destroy (GtkWidget *widget) GtkWindow *window = GTK_WINDOW (widget); GtkWindowPrivate *priv = window->priv; + gtk_window_release_application (window); + toplevel_list = g_slist_remove (toplevel_list, window); if (priv->transient_parent) @@ -4557,7 +4476,7 @@ gtk_window_destroy (GtkWidget *widget) /* frees the icons */ gtk_window_set_icon_list (window, NULL); - + if (priv->has_user_ref_count) { priv->has_user_ref_count = FALSE; @@ -4620,6 +4539,13 @@ gtk_window_show (GtkWidget *widget) GtkWindowPrivate *priv = window->priv; GtkContainer *container = GTK_CONTAINER (window); gboolean need_resize; + gboolean is_plug; + + if (!gtk_widget_is_toplevel (GTK_WIDGET (widget))) + { + GTK_WIDGET_CLASS (gtk_window_parent_class)->show (widget); + return; + } _gtk_widget_set_visible_flag (widget, TRUE); @@ -4685,7 +4611,12 @@ gtk_window_show (GtkWidget *widget) /* Try to make sure that we have some focused widget */ - if (!priv->focus_widget && !GTK_IS_PLUG (window)) +#ifdef GDK_WINDOWING_X11 + is_plug = GTK_IS_PLUG (window); +#else + is_plug = FALSE; +#endif + if (!priv->focus_widget && !is_plug) gtk_window_move_focus (widget, GTK_DIR_TAB_FORWARD); if (priv->modal) @@ -4698,6 +4629,12 @@ gtk_window_hide (GtkWidget *widget) GtkWindow *window = GTK_WINDOW (widget); GtkWindowPrivate *priv = window->priv; + if (!gtk_widget_is_toplevel (GTK_WIDGET (widget))) + { + GTK_WIDGET_CLASS (gtk_window_parent_class)->hide (widget); + return; + } + _gtk_widget_set_visible_flag (widget, FALSE); gtk_widget_unmap (widget); @@ -4717,6 +4654,12 @@ gtk_window_map (GtkWidget *widget) gdk_window = gtk_widget_get_window (widget); + if (!gtk_widget_is_toplevel (GTK_WIDGET (widget))) + { + GTK_WIDGET_CLASS (gtk_window_parent_class)->map (widget); + return; + } + gtk_widget_set_mapped (widget, TRUE); child = gtk_bin_get_child (&(window->bin)); @@ -4725,10 +4668,7 @@ gtk_window_map (GtkWidget *widget) !gtk_widget_get_mapped (child)) gtk_widget_map (child); - if (priv->frame) - toplevel = priv->frame; - else - toplevel = gdk_window; + toplevel = gdk_window; if (priv->maximize_initially) gdk_window_maximize (toplevel); @@ -4771,9 +4711,6 @@ gtk_window_map (GtkWidget *widget) gdk_window_show (gdk_window); - if (priv->frame) - gdk_window_show (priv->frame); - if (priv->grip_window) gdk_window_show (priv->grip_window); @@ -4833,13 +4770,16 @@ gtk_window_unmap (GtkWidget *widget) GdkWindow *gdk_window; GdkWindowState state; + if (!gtk_widget_is_toplevel (GTK_WIDGET (widget))) + { + GTK_WIDGET_CLASS (gtk_window_parent_class)->unmap (widget); + return; + } + gdk_window = gtk_widget_get_window (widget); gtk_widget_set_mapped (widget, FALSE); - if (priv->frame) - gdk_window_withdraw (priv->frame); - else - gdk_window_withdraw (gdk_window); + gdk_window_withdraw (gdk_window); priv->configure_request_count = 0; priv->configure_notify_received = FALSE; @@ -4886,6 +4826,38 @@ gtk_window_realize (GtkWidget *widget) gtk_widget_get_allocation (widget, &allocation); + if (gtk_widget_get_parent_window (widget)) + { + gtk_container_set_resize_mode (GTK_CONTAINER (widget), GTK_RESIZE_PARENT); + + gtk_widget_set_realized (widget, TRUE); + + attributes.x = allocation.x; + attributes.y = allocation.y; + attributes.width = allocation.width; + attributes.height = allocation.height; + attributes.window_type = GDK_WINDOW_CHILD; + + attributes.event_mask = gtk_widget_get_events (widget) | GDK_EXPOSURE_MASK | GDK_STRUCTURE_MASK; + + attributes.visual = gtk_widget_get_visual (widget); + attributes.wclass = GDK_INPUT_OUTPUT; + + attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL; + + gdk_window = gdk_window_new (gtk_widget_get_parent_window (widget), + &attributes, attributes_mask); + gtk_widget_set_window (widget, gdk_window); + gdk_window_set_user_data (gdk_window, widget); + + gtk_style_context_set_background (gtk_widget_get_style_context (widget), gdk_window); + + gdk_window_enable_synchronized_configure (gdk_window); + return; + } + + gtk_container_set_resize_mode (GTK_CONTAINER (window), GTK_RESIZE_QUEUE); + /* ensure widget tree is properly size allocated */ if (allocation.x == -1 && allocation.y == -1 && @@ -4927,57 +4899,15 @@ gtk_window_realize (GtkWidget *widget) g_warning (G_STRLOC": Unknown window type %d!", priv->type); break; } - + attributes.title = priv->title; attributes.wmclass_name = priv->wmclass_name; attributes.wmclass_class = priv->wmclass_class; attributes.wclass = GDK_INPUT_OUTPUT; attributes.visual = gtk_widget_get_visual (widget); - if (priv->has_frame) - { - gtk_widget_get_allocation (widget, &allocation); - attributes.width = allocation.width + priv->frame_left + priv->frame_right; - attributes.height = allocation.height + priv->frame_top + priv->frame_bottom; - attributes.event_mask = (GDK_EXPOSURE_MASK | - GDK_KEY_PRESS_MASK | - GDK_ENTER_NOTIFY_MASK | - GDK_LEAVE_NOTIFY_MASK | - GDK_FOCUS_CHANGE_MASK | - GDK_STRUCTURE_MASK | - GDK_BUTTON_MOTION_MASK | - GDK_POINTER_MOTION_HINT_MASK | - GDK_BUTTON_PRESS_MASK | - GDK_BUTTON_RELEASE_MASK); - - attributes_mask = GDK_WA_VISUAL; - - priv->frame = gdk_window_new (gtk_widget_get_root_window (widget), - &attributes, attributes_mask); - - if (priv->opacity_set) - gdk_window_set_opacity (priv->frame, priv->opacity); - - gdk_window_set_user_data (priv->frame, widget); - - attributes.window_type = GDK_WINDOW_CHILD; - attributes.x = priv->frame_left; - attributes.y = priv->frame_top; - - attributes_mask = GDK_WA_X | GDK_WA_Y; - - parent_window = priv->frame; - - g_signal_connect (window, - "event", - G_CALLBACK (gtk_window_event), - NULL); - } - else - { - attributes_mask = 0; - parent_window = gtk_widget_get_root_window (widget); - } + attributes_mask = 0; + parent_window = gtk_widget_get_root_window (widget); gtk_widget_get_allocation (widget, &allocation); attributes.width = allocation.width; @@ -4999,19 +4929,16 @@ gtk_window_realize (GtkWidget *widget) gdk_window = gdk_window_new (parent_window, &attributes, attributes_mask); gtk_widget_set_window (widget, gdk_window); - if (!priv->has_frame && priv->opacity_set) + if (priv->opacity_set) gdk_window_set_opacity (gdk_window, priv->opacity); gdk_window_enable_synchronized_configure (gdk_window); gdk_window_set_user_data (gdk_window, window); - gtk_widget_style_attach (widget); context = gtk_widget_get_style_context (widget); - gtk_style_context_set_background (context, gdk_window); - if (priv->frame) - gtk_style_context_set_background (context, priv->frame); + if (priv->transient_parent && gtk_widget_get_realized (GTK_WIDGET (priv->transient_parent))) @@ -5020,48 +4947,48 @@ gtk_window_realize (GtkWidget *widget) if (priv->wm_role) gdk_window_set_role (gdk_window, priv->wm_role); - + if (!priv->decorated) gdk_window_set_decorations (gdk_window, 0); - + if (!priv->deletable) gdk_window_set_functions (gdk_window, GDK_FUNC_ALL | GDK_FUNC_CLOSE); - + if (gtk_window_get_skip_pager_hint (window)) gdk_window_set_skip_pager_hint (gdk_window, TRUE); - + if (gtk_window_get_skip_taskbar_hint (window)) gdk_window_set_skip_taskbar_hint (gdk_window, TRUE); - + if (gtk_window_get_accept_focus (window)) gdk_window_set_accept_focus (gdk_window, TRUE); else gdk_window_set_accept_focus (gdk_window, FALSE); - + if (gtk_window_get_focus_on_map (window)) gdk_window_set_focus_on_map (gdk_window, TRUE); else gdk_window_set_focus_on_map (gdk_window, FALSE); - + if (priv->modal) gdk_window_set_modal_hint (gdk_window, TRUE); else gdk_window_set_modal_hint (gdk_window, FALSE); - + if (priv->startup_id) { #ifdef GDK_WINDOWING_X11 guint32 timestamp = extract_time_from_startup_id (priv->startup_id); if (timestamp != GDK_CURRENT_TIME) - gdk_x11_window_set_user_time (gdk_window, timestamp); + gdk_x11_window_set_user_time (gdk_window, timestamp); #endif if (!startup_id_is_fake (priv->startup_id)) - gdk_window_set_startup_id (gdk_window, priv->startup_id); + gdk_window_set_startup_id (gdk_window, priv->startup_id); } - + /* Icons */ gtk_window_realize_icon (window); - + if (priv->has_resize_grip) resize_grip_create_window (window); } @@ -5093,13 +5020,6 @@ gtk_window_unrealize (GtkWidget *widget) info->last.flags = 0; } - if (priv->frame) - { - gdk_window_set_user_data (priv->frame, NULL); - gdk_window_destroy (priv->frame); - priv->frame = NULL; - } - /* Icons */ gtk_window_unrealize_icon (window); @@ -5271,13 +5191,30 @@ gtk_window_size_allocate (GtkWidget *widget, GtkAllocation *allocation) { GtkWindow *window = GTK_WINDOW (widget); - GtkWindowPrivate *priv = window->priv; GtkAllocation child_allocation; GtkWidget *child; guint border_width; gtk_widget_set_allocation (widget, allocation); + if (gtk_widget_get_realized (widget)) + { + /* If it's not a toplevel we're embedded, we need to resize the window's + * window and skip the grip. + */ + if (!gtk_widget_is_toplevel (widget)) + { + gdk_window_move_resize (gtk_widget_get_window (widget), + allocation->x, allocation->y, + allocation->width, allocation->height); + } + else + { + update_grip_visibility (window); + set_grip_position (window); + } + } + child = gtk_bin_get_child (&(window->bin)); if (child && gtk_widget_get_visible (child)) { @@ -5291,75 +5228,6 @@ gtk_window_size_allocate (GtkWidget *widget, gtk_widget_size_allocate (child, &child_allocation); } - - if (gtk_widget_get_realized (widget)) - { - if (priv->frame) - gdk_window_resize (priv->frame, - allocation->width + priv->frame_left + priv->frame_right, - allocation->height + priv->frame_top + priv->frame_bottom); - update_grip_visibility (window); - set_grip_position (window); - } -} - -static gint -gtk_window_event (GtkWidget *widget, GdkEvent *event) -{ - GtkWindow *window = GTK_WINDOW (widget); - GtkWindowPrivate *priv = window->priv; - gboolean return_val; - - if (priv->frame && (event->any.window == priv->frame)) - { - if ((event->type != GDK_KEY_PRESS) && - (event->type != GDK_KEY_RELEASE) && - (event->type != GDK_FOCUS_CHANGE)) - { - g_signal_stop_emission_by_name (widget, "event"); - return_val = FALSE; - g_signal_emit (widget, window_signals[FRAME_EVENT], 0, event, &return_val); - return TRUE; - } - else - { - g_object_unref (event->any.window); - event->any.window = g_object_ref (gtk_widget_get_window (widget)); - } - } - - return FALSE; -} - -static gboolean -gtk_window_frame_event (GtkWindow *window, GdkEvent *event) -{ - GtkWindowPrivate *priv = window->priv; - GdkEventConfigure *configure_event; - GdkRectangle rect; - - switch (event->type) - { - case GDK_CONFIGURE: - configure_event = (GdkEventConfigure *)event; - - /* Invalidate the decorations */ - rect.x = 0; - rect.y = 0; - rect.width = configure_event->width; - rect.height = configure_event->height; - - gdk_window_invalidate_rect (priv->frame, &rect, FALSE); - - /* Pass on the (modified) configure event */ - configure_event->width -= priv->frame_left + priv->frame_right; - configure_event->height -= priv->frame_top + priv->frame_bottom; - return gtk_window_configure_event (GTK_WIDGET (window), configure_event); - break; - default: - break; - } - return FALSE; } static gint @@ -5371,6 +5239,15 @@ gtk_window_configure_event (GtkWidget *widget, GtkWindowPrivate *priv = window->priv; gboolean expected_reply = priv->configure_request_count > 0; + if (!gtk_widget_is_toplevel (GTK_WIDGET (widget))) + { + if (GTK_WIDGET_CLASS (gtk_window_parent_class)->configure_event) + return GTK_WIDGET_CLASS (gtk_window_parent_class)->configure_event (widget, event); + + gdk_window_configure_finished (gtk_widget_get_window (widget)); + return FALSE; + } + /* priv->configure_request_count incremented for each * configure request, and decremented to a min of 0 for * each configure notify. @@ -5464,6 +5341,8 @@ gtk_window_style_updated (GtkWidget *widget) GtkWindowPrivate *priv = window->priv; GdkRectangle rect; + GTK_WIDGET_CLASS (gtk_window_parent_class)->style_updated (widget); + if (priv->grip_window != NULL && gtk_window_get_resize_grip_area (window, &rect)) { gdk_window_move_resize (priv->grip_window, @@ -5555,7 +5434,8 @@ gtk_window_set_has_resize_grip (GtkWindow *window, priv->has_resize_grip = value; gtk_widget_queue_draw (widget); - if (gtk_widget_get_realized (widget)) + if (gtk_widget_get_realized (widget) && + gtk_widget_is_toplevel (GTK_WIDGET (widget))) { if (priv->has_resize_grip && priv->grip_window == NULL) resize_grip_create_window (window); @@ -5602,7 +5482,7 @@ update_grip_visibility (GtkWindow *window) * * Determines whether a resize grip is visible for the specified window. * - * Returns %TRUE if a resize grip exists and is visible. + * Returns: %TRUE if a resize grip exists and is visible * * Since: 3.0 */ @@ -5624,6 +5504,9 @@ gtk_window_resize_grip_is_visible (GtkWindow *window) if (!priv->resizable) return FALSE; + if (!gtk_widget_is_toplevel (GTK_WIDGET (widget))) + return FALSE; + if (gtk_widget_get_realized (widget)) { GdkWindowState state; @@ -5646,7 +5529,7 @@ gtk_window_resize_grip_is_visible (GtkWindow *window) * * Determines whether the window may have a resize grip. * - * Returns: %TRUE if the window has a resize grip. + * Returns: %TRUE if the window has a resize grip * * Since: 3.0 */ @@ -5661,13 +5544,13 @@ gtk_window_get_has_resize_grip (GtkWindow *window) /** * gtk_window_get_resize_grip_area: * @window: a #GtkWindow - * @rect: a pointer to a #GdkRectangle which we should store the - * resize grip area. + * @rect: (out): a pointer to a #GdkRectangle which we should store + * the resize grip area * * If a window has a resize grip, this will retrieve the grip * position, width and height into the specified #GdkRectangle. * - * Returns: %TRUE if the resize grip's area was retrieved. + * Returns: %TRUE if the resize grip's area was retrieved * * Since: 3.0 */ @@ -5985,66 +5868,14 @@ gtk_window_focus_out_event (GtkWidget *widget, return FALSE; } -static GdkAtom atom_rcfiles = GDK_NONE; -static GdkAtom atom_iconthemes = GDK_NONE; - -static void -send_client_message_to_embedded_windows (GtkWidget *widget, - GdkAtom message_type) -{ - GList *embedded_windows; - - embedded_windows = g_object_get_qdata (G_OBJECT (widget), quark_gtk_embedded); - if (embedded_windows) - { - GdkEvent *send_event = gdk_event_new (GDK_CLIENT_EVENT); - int i; - - for (i = 0; i < 5; i++) - send_event->client.data.l[i] = 0; - send_event->client.data_format = 32; - send_event->client.message_type = message_type; - - while (embedded_windows) - { - GdkNativeWindow xid = GDK_GPOINTER_TO_NATIVE_WINDOW(embedded_windows->data); - gdk_event_send_client_message_for_display (gtk_widget_get_display (widget), send_event, xid); - embedded_windows = embedded_windows->next; - } - - gdk_event_free (send_event); - } -} - -static gint -gtk_window_client_event (GtkWidget *widget, - GdkEventClient *event) -{ - if (!atom_rcfiles) - { - atom_rcfiles = gdk_atom_intern_static_string ("_GTK_READ_RCFILES"); - atom_iconthemes = gdk_atom_intern_static_string ("_GTK_LOAD_ICONTHEMES"); - } - - if (event->message_type == atom_rcfiles) - { - send_client_message_to_embedded_windows (widget, atom_rcfiles); - gtk_style_context_reset_widgets (gtk_widget_get_screen (widget)); - } - - if (event->message_type == atom_iconthemes) - { - send_client_message_to_embedded_windows (widget, atom_iconthemes); - _gtk_icon_theme_check_reload (gtk_widget_get_display (widget)); - } - - return FALSE; -} - static void gtk_window_check_resize (GtkContainer *container) { - if (gtk_widget_get_visible (GTK_WIDGET (container))) + /* If the window is not toplevel anymore than it's embedded somewhere, + * so handle it like a normal window */ + if (!gtk_widget_is_toplevel (GTK_WIDGET (container))) + GTK_CONTAINER_CLASS (gtk_window_parent_class)->check_resize (container); + else if (gtk_widget_get_visible (GTK_WIDGET (container))) gtk_window_move_resize (GTK_WINDOW (container)); } @@ -6060,6 +5891,9 @@ gtk_window_focus (GtkWidget *widget, GtkWidget *old_focus_child; GtkWidget *parent; + if (!gtk_widget_is_toplevel (GTK_WIDGET (widget))) + return GTK_WIDGET_CLASS (gtk_window_parent_class)->focus (widget, direction); + container = GTK_CONTAINER (widget); window = GTK_WINDOW (widget); priv = window->priv; @@ -6113,6 +5947,12 @@ static void gtk_window_move_focus (GtkWidget *widget, GtkDirectionType dir) { + if (!gtk_widget_is_toplevel (GTK_WIDGET (widget))) + { + GTK_WIDGET_CLASS (gtk_window_parent_class)->move_focus (widget, dir); + return; + } + gtk_widget_child_focus (widget, dir); if (! gtk_container_get_focus_child (GTK_CONTAINER (widget))) @@ -6477,9 +6317,9 @@ get_monitor_containing_pointer (GtkWindow *window) device_manager = gdk_display_get_device_manager (display); pointer = gdk_device_manager_get_client_pointer (device_manager); - gdk_display_get_device_state (display, pointer, - &pointer_screen, - &px, &py, NULL); + gdk_device_get_position (pointer, + &pointer_screen, + &px, &py); if (pointer_screen == window_screen) monitor_num = gdk_screen_get_monitor_at_point (pointer_screen, px, py); @@ -6567,21 +6407,18 @@ gtk_window_compute_configure_request (GtkWindow *window, GdkGeometry new_geometry; guint new_flags; int w, h; - GtkWidget *widget; GtkWindowPosition pos; GtkWidget *parent_widget; GtkWindowGeometryInfo *info; GdkScreen *screen; int x, y; - - widget = GTK_WIDGET (window); screen = gtk_window_check_screen (window); gtk_window_compute_hints (window, &new_geometry, &new_flags); gtk_window_compute_configure_request_size (window, - &new_geometry, new_flags, - (guint *)&w, (guint *)&h); + &new_geometry, new_flags, + (guint *)&w, (guint *)&h); gtk_window_constrain_size (window, &new_geometry, new_flags, @@ -6589,10 +6426,10 @@ gtk_window_compute_configure_request (GtkWindow *window, &w, &h); parent_widget = (GtkWidget*) priv->transient_parent; - + pos = get_effective_position (window); info = gtk_window_get_geometry_info (window, FALSE); - + /* by default, don't change position requested */ if (info) { @@ -6614,7 +6451,6 @@ gtk_window_compute_configure_request (GtkWindow *window, * * Not sure how to go about that. */ - switch (pos) { /* here we are only handling CENTER_ALWAYS @@ -6625,7 +6461,7 @@ gtk_window_compute_configure_request (GtkWindow *window, case GTK_WIN_POS_CENTER: center_window_on_monitor (window, w, h, &x, &y); break; - + case GTK_WIN_POS_CENTER_ON_PARENT: { GtkAllocation allocation; @@ -6633,7 +6469,7 @@ gtk_window_compute_configure_request (GtkWindow *window, gint monitor_num; GdkRectangle monitor; gint ox, oy; - + g_assert (gtk_widget_get_mapped (parent_widget)); /* established earlier */ gdk_window = gtk_widget_get_window (parent_widget); @@ -6667,8 +6503,8 @@ gtk_window_compute_configure_request (GtkWindow *window, { gint screen_width = gdk_screen_get_width (screen); gint screen_height = gdk_screen_get_height (screen); - gint monitor_num; - GdkRectangle monitor; + gint monitor_num; + GdkRectangle monitor; GdkDisplay *display; GdkDeviceManager *device_manager; GdkDevice *pointer; @@ -6679,15 +6515,15 @@ gtk_window_compute_configure_request (GtkWindow *window, device_manager = gdk_display_get_device_manager (display); pointer = gdk_device_manager_get_client_pointer (device_manager); - gdk_display_get_device_state (display, pointer, - &pointer_screen, - &px, &py, NULL); + gdk_device_get_position (pointer, + &pointer_screen, + &px, &py); if (pointer_screen == screen) monitor_num = gdk_screen_get_monitor_at_point (screen, px, py); else monitor_num = -1; - + x = px - w / 2; y = py - h / 2; x = CLAMP (x, 0, screen_width - w); @@ -6717,7 +6553,7 @@ gtk_window_compute_configure_request (GtkWindow *window, y = info->initial_y; gtk_window_constrain_position (window, w, h, &x, &y); } - + request->x = x; request->y = y; request->width = w; @@ -6802,6 +6638,7 @@ gtk_window_move_resize (GtkWindow *window) GtkWindowLastGeometryInfo saved_last_info; widget = GTK_WIDGET (window); + gdk_window = gtk_widget_get_window (widget); container = GTK_CONTAINER (widget); info = gtk_window_get_geometry_info (window, TRUE); @@ -7069,31 +6906,16 @@ gtk_window_move_resize (GtkWindow *window) /* Now send the configure request */ if (configure_request_pos_changed) - { - if (priv->frame) - { - gdk_window_move_resize (priv->frame, - new_request.x - priv->frame_left, - new_request.y - priv->frame_top, - new_request.width + priv->frame_left + priv->frame_right, - new_request.height + priv->frame_top + priv->frame_bottom); - gdk_window_resize (gdk_window, - new_request.width, new_request.height); - } - else - gdk_window_move_resize (gdk_window, - new_request.x, new_request.y, - new_request.width, new_request.height); - } + { + gdk_window_move_resize (gdk_window, + new_request.x, new_request.y, + new_request.width, new_request.height); + } else /* only size changed */ - { - if (priv->frame) - gdk_window_resize (priv->frame, - new_request.width + priv->frame_left + priv->frame_right, - new_request.height + priv->frame_top + priv->frame_bottom); - gdk_window_resize (gdk_window, - new_request.width, new_request.height); - } + { + gdk_window_resize (gdk_window, + new_request.width, new_request.height); + } if (priv->type == GTK_WINDOW_POPUP) { @@ -7145,17 +6967,10 @@ gtk_window_move_resize (GtkWindow *window) /* Handle any position changes. */ if (configure_request_pos_changed) - { - if (priv->frame) - { - gdk_window_move (priv->frame, - new_request.x - priv->frame_left, - new_request.y - priv->frame_top); - } - else - gdk_window_move (gdk_window, - new_request.x, new_request.y); - } + { + gdk_window_move (gdk_window, + new_request.x, new_request.y); + } /* And run the resize queue. */ @@ -7476,116 +7291,6 @@ gtk_window_draw (GtkWidget *widget, return ret; } -/** - * gtk_window_set_has_frame: - * @window: a #GtkWindow - * @setting: a boolean - * - * (Note: this is a special-purpose function for the framebuffer port, - * that causes GTK+ to draw its own window border. For most applications, - * you want gtk_window_set_decorated() instead, which tells the window - * manager whether to draw the window border.) - * - * If this function is called on a window with setting of %TRUE, before - * it is realized or showed, it will have a "frame" window around - * @window->window, accessible in @window->frame. Using the signal - * frame_event you can receive all events targeted at the frame. - * - * This function is used by the linux-fb port to implement managed - * windows, but it could conceivably be used by X-programs that - * want to do their own window decorations. - * - **/ -void -gtk_window_set_has_frame (GtkWindow *window, - gboolean setting) -{ - GtkWindowPrivate *priv; - - g_return_if_fail (GTK_IS_WINDOW (window)); - g_return_if_fail (!gtk_widget_get_realized (GTK_WIDGET (window))); - - priv = window->priv; - - priv->has_frame = setting != FALSE; -} - -/** - * gtk_window_get_has_frame: - * @window: a #GtkWindow - * - * Accessor for whether the window has a frame window exterior to - * @window->window. Gets the value set by gtk_window_set_has_frame (). - * - * Return value: %TRUE if a frame has been added to the window - * via gtk_window_set_has_frame(). - **/ -gboolean -gtk_window_get_has_frame (GtkWindow *window) -{ - g_return_val_if_fail (GTK_IS_WINDOW (window), FALSE); - - return window->priv->has_frame; -} - -/** - * gtk_window_set_frame_dimensions: - * @window: a #GtkWindow that has a frame - * @left: The width of the left border - * @top: The height of the top border - * @right: The width of the right border - * @bottom: The height of the bottom border - * - * (Note: this is a special-purpose function intended for the framebuffer - * port; see gtk_window_set_has_frame(). It will have no effect on the - * window border drawn by the window manager, which is the normal - * case when using the X Window system.) - * - * For windows with frames (see gtk_window_set_has_frame()) this function - * can be used to change the size of the frame border. - **/ -void -gtk_window_set_frame_dimensions (GtkWindow *window, - gint left, - gint top, - gint right, - gint bottom) -{ - GtkWindowPrivate *priv; - GtkAllocation allocation; - GtkWidget *widget; - - g_return_if_fail (GTK_IS_WINDOW (window)); - - priv = window->priv; - widget = GTK_WIDGET (window); - - if (priv->frame_left == left && - priv->frame_top == top && - priv->frame_right == right && - priv->frame_bottom == bottom) - return; - - priv->frame_left = left; - priv->frame_top = top; - priv->frame_right = right; - priv->frame_bottom = bottom; - - if (gtk_widget_get_realized (widget) && priv->frame) - { - gint width, height; - gtk_widget_get_allocation (widget, &allocation); - - width = allocation.width + left + right; - height = allocation.height + top + bottom; - gdk_window_resize (priv->frame, width, height); - gdk_window_move_resize (gtk_widget_get_window (GTK_WIDGET (window)), - left, top, - allocation.width, - allocation.height); - } -} - /** * gtk_window_present: * @window: a #GtkWindow @@ -7700,10 +7405,7 @@ gtk_window_iconify (GtkWindow *window) priv->iconify_initially = TRUE; - if (priv->frame) - toplevel = priv->frame; - else - toplevel = gtk_widget_get_window (widget); + toplevel = gtk_widget_get_window (widget); if (toplevel != NULL) gdk_window_iconify (toplevel); @@ -7736,10 +7438,7 @@ gtk_window_deiconify (GtkWindow *window) priv->iconify_initially = FALSE; - if (priv->frame) - toplevel = priv->frame; - else - toplevel = gtk_widget_get_window (widget); + toplevel = gtk_widget_get_window (widget); if (toplevel != NULL) gdk_window_deiconify (toplevel); @@ -7777,10 +7476,7 @@ gtk_window_stick (GtkWindow *window) priv->stick_initially = TRUE; - if (priv->frame) - toplevel = priv->frame; - else - toplevel = gtk_widget_get_window (widget); + toplevel = gtk_widget_get_window (widget); if (toplevel != NULL) gdk_window_stick (toplevel); @@ -7815,10 +7511,7 @@ gtk_window_unstick (GtkWindow *window) priv->stick_initially = FALSE; - if (priv->frame) - toplevel = priv->frame; - else - toplevel = gtk_widget_get_window (widget); + toplevel = gtk_widget_get_window (widget); if (toplevel != NULL) gdk_window_unstick (toplevel); @@ -7858,10 +7551,7 @@ gtk_window_maximize (GtkWindow *window) priv->maximize_initially = TRUE; - if (priv->frame) - toplevel = priv->frame; - else - toplevel = gtk_widget_get_window (widget); + toplevel = gtk_widget_get_window (widget); if (toplevel != NULL) gdk_window_maximize (toplevel); @@ -7896,10 +7586,7 @@ gtk_window_unmaximize (GtkWindow *window) priv->maximize_initially = FALSE; - if (priv->frame) - toplevel = priv->frame; - else - toplevel = gtk_widget_get_window (widget); + toplevel = gtk_widget_get_window (widget); if (toplevel != NULL) gdk_window_unmaximize (toplevel); @@ -7936,10 +7623,7 @@ gtk_window_fullscreen (GtkWindow *window) priv->fullscreen_initially = TRUE; - if (priv->frame) - toplevel = priv->frame; - else - toplevel = gtk_widget_get_window (widget); + toplevel = gtk_widget_get_window (widget); if (toplevel != NULL) gdk_window_fullscreen (toplevel); @@ -7976,10 +7660,7 @@ gtk_window_unfullscreen (GtkWindow *window) priv->fullscreen_initially = FALSE; - if (priv->frame) - toplevel = priv->frame; - else - toplevel = gtk_widget_get_window (widget); + toplevel = gtk_widget_get_window (widget); if (toplevel != NULL) gdk_window_unfullscreen (toplevel); @@ -8030,10 +7711,7 @@ gtk_window_set_keep_above (GtkWindow *window, if (setting) priv->below_initially = FALSE; - if (priv->frame) - toplevel = priv->frame; - else - toplevel = gtk_widget_get_window (widget); + toplevel = gtk_widget_get_window (widget); if (toplevel != NULL) gdk_window_set_keep_above (toplevel, setting); @@ -8084,10 +7762,7 @@ gtk_window_set_keep_below (GtkWindow *window, if (setting) priv->above_initially = FALSE; - if (priv->frame) - toplevel = priv->frame; - else - toplevel = gtk_widget_get_window (widget); + toplevel = gtk_widget_get_window (widget); if (toplevel != NULL) gdk_window_set_keep_below (toplevel, setting); @@ -8217,20 +7892,14 @@ gtk_window_begin_resize_drag (GtkWindow *window, gint root_y, guint32 timestamp) { - GtkWindowPrivate *priv; GtkWidget *widget; GdkWindow *toplevel; - + g_return_if_fail (GTK_IS_WINDOW (window)); widget = GTK_WIDGET (window); g_return_if_fail (gtk_widget_get_visible (widget)); - priv = window->priv; - - if (priv->frame) - toplevel = priv->frame; - else - toplevel = gtk_widget_get_window (widget); + toplevel = gtk_widget_get_window (widget); gdk_window_begin_resize_drag (toplevel, edge, button, @@ -8238,48 +7907,6 @@ gtk_window_begin_resize_drag (GtkWindow *window, timestamp); } -/** - * gtk_window_get_frame_dimensions: - * @window: a #GtkWindow - * @left: (out) (allow-none): location to store the width of the frame at the left, or %NULL - * @top: (out) (allow-none): location to store the height of the frame at the top, or %NULL - * @right: (out) (allow-none): location to store the width of the frame at the returns, or %NULL - * @bottom: (out) (allow-none): location to store the height of the frame at the bottom, or %NULL - * - * (Note: this is a special-purpose function intended for the - * framebuffer port; see gtk_window_set_has_frame(). It will not - * return the size of the window border drawn by the window manager, which is the normal - * case when using a windowing system. See - * gdk_window_get_frame_extents() to get the standard window border - * extents.) - * - * Retrieves the dimensions of the frame window for this toplevel. - * See gtk_window_set_has_frame(), gtk_window_set_frame_dimensions(). - **/ -void -gtk_window_get_frame_dimensions (GtkWindow *window, - gint *left, - gint *top, - gint *right, - gint *bottom) -{ - GtkWindowPrivate *priv; - - g_return_if_fail (GTK_IS_WINDOW (window)); - - priv = window->priv; - - if (left) - *left = priv->frame_left; - if (top) - *top = priv->frame_top; - if (right) - *right = priv->frame_right; - if (bottom) - *bottom = priv->frame_bottom; -} - /** * gtk_window_begin_move_drag: * @window: a #GtkWindow @@ -8303,20 +7930,14 @@ gtk_window_begin_move_drag (GtkWindow *window, gint root_y, guint32 timestamp) { - GtkWindowPrivate *priv; GtkWidget *widget; GdkWindow *toplevel; - + g_return_if_fail (GTK_IS_WINDOW (window)); widget = GTK_WIDGET (window); g_return_if_fail (gtk_widget_get_visible (widget)); - priv = window->priv; - - if (priv->frame) - toplevel = priv->frame; - else - toplevel = gtk_widget_get_window (widget); + toplevel = gtk_widget_get_window (widget); gdk_window_begin_move_drag (toplevel, button, @@ -8324,7 +7945,7 @@ gtk_window_begin_move_drag (GtkWindow *window, timestamp); } -/** +/** * gtk_window_set_screen: * @window: a #GtkWindow. * @screen: a #GdkScreen. @@ -8343,7 +7964,7 @@ gtk_window_set_screen (GtkWindow *window, GtkWidget *widget; GdkScreen *previous_screen; gboolean was_mapped; - + g_return_if_fail (GTK_IS_WINDOW (window)); g_return_if_fail (GDK_IS_SCREEN (screen)); @@ -8361,17 +7982,18 @@ gtk_window_set_screen (GtkWindow *window, gtk_widget_unmap (widget); if (gtk_widget_get_realized (widget)) gtk_widget_unrealize (widget); - + gtk_window_free_key_hash (window); priv->screen = screen; gtk_widget_reset_rc_styles (widget); if (screen != previous_screen) { - g_signal_handlers_disconnect_by_func (previous_screen, - gtk_window_on_composited_changed, window); - g_signal_connect (screen, "composited-changed", - G_CALLBACK (gtk_window_on_composited_changed), window); - + if (previous_screen) + g_signal_handlers_disconnect_by_func (previous_screen, + gtk_window_on_composited_changed, window); + g_signal_connect (screen, "composited-changed", + G_CALLBACK (gtk_window_on_composited_changed), window); + _gtk_widget_propagate_screen_changed (widget, previous_screen); _gtk_widget_propagate_composited_changed (widget); } @@ -8611,8 +8233,8 @@ gtk_window_group_remove_window (GtkWindowGroup *window_group, * * Returns a list of the #GtkWindows that belong to @window_group. * - * Returns: (element-type GtkWidget) (transfer container): A newly-allocated list of - * windows inside the group. + * Returns: (element-type GtkWindow) (transfer container): A + * newly-allocated list of windows inside the group. * * Since: 2.14 **/ @@ -8634,6 +8256,8 @@ gtk_window_group_list_windows (GtkWindowGroup *window_group) group_windows = g_list_prepend (group_windows, window); } + g_list_free (toplevels); + return g_list_reverse (group_windows); } @@ -8690,7 +8314,7 @@ gtk_window_has_group (GtkWindow *window) * Gets the current grab widget of the given group, * see gtk_grab_add(). * - * Returns: the current grab widget of the group + * Returns: (transfer none): the current grab widget of the group * * Since: 2.22 */ @@ -8789,7 +8413,7 @@ _gtk_window_group_remove_device_grab (GtkWindowGroup *window_group, * * Returns the current grab widget for @device, or %NULL if none. * - * Returns: The grab widget, or %NULL + * Returns: (transfer none): The grab widget, or %NULL * * Since: 3.0 */ @@ -9482,7 +9106,7 @@ _gtk_window_set_is_active (GtkWindow *window, * _gtk_window_set_is_toplevel: * @window: a #GtkWindow * @is_toplevel: %TRUE if the window is still a real toplevel (nominally a - * parent of the root window); %FALSE if it is not (for example, for an + * child of the root window); %FALSE if it is not (for example, for an * in-process, parented GtkPlug) * * Internal function used by #GtkPlug when it gets parented/unparented by a @@ -9491,9 +9115,10 @@ _gtk_window_set_is_active (GtkWindow *window, */ void _gtk_window_set_is_toplevel (GtkWindow *window, - gboolean is_toplevel) + gboolean is_toplevel) { GtkWidget *widget; + GtkWidget *toplevel; widget = GTK_WIDGET (window); @@ -9507,13 +9132,45 @@ _gtk_window_set_is_toplevel (GtkWindow *window, if (is_toplevel) { + /* Pass through regular pathways of an embedded toplevel + * to go through unmapping and hiding the widget before + * becomming a toplevel again. + * + * We remain hidden after becomming toplevel in order to + * avoid problems during an embedded toplevel's dispose cycle + * (When a toplevel window is shown it tries to grab focus again, + * this causes problems while disposing). + */ + gtk_widget_hide (widget); + + /* Save the toplevel this widget was previously anchored into before + * propagating a hierarchy-changed. + * + * Usually this happens by way of gtk_widget_unparent() and we are + * already unanchored at this point, just adding this clause incase + * things happen differently. + */ + toplevel = gtk_widget_get_toplevel (widget); + if (!gtk_widget_is_toplevel (toplevel)) + toplevel = NULL; + _gtk_widget_set_is_toplevel (widget, TRUE); + + /* When a window becomes toplevel after being embedded and anchored + * into another window we need to unset its anchored flag so that + * the hierarchy changed signal kicks in properly. + */ + _gtk_widget_set_anchored (widget, FALSE); + _gtk_widget_propagate_hierarchy_changed (widget, toplevel); + toplevel_list = g_slist_prepend (toplevel_list, window); } else { _gtk_widget_set_is_toplevel (widget, FALSE); toplevel_list = g_slist_remove (toplevel_list, window); + + _gtk_widget_propagate_hierarchy_changed (widget, widget); } } @@ -9645,3 +9302,27 @@ _gtk_window_get_wmclass (GtkWindow *window, *wmclass_name = priv->wmclass_name; *wmclass_class = priv->wmclass_class; } + +/** + * gtk_window_set_has_user_ref_count: + * @window: a #GtkWindow + * @setting: the new value + * + * Tells GTK+ whether to drop its extra reference to the window + * when gtk_window_destroy() is called. + * + * This function is only exported for the benefit of language + * bindings which may need to keep the window alive until their + * wrapper object is garbage collected. There is no justification + * for ever calling this function in an application. + * + * Since: 3.0 + */ +void +gtk_window_set_has_user_ref_count (GtkWindow *window, + gboolean setting) +{ + g_return_if_fail (GTK_IS_WINDOW (window)); + + window->priv->has_user_ref_count = setting; +}