diff --git a/src/core/window-private.h b/src/core/window-private.h index 3315fa3a5..0d5d68c6f 100644 --- a/src/core/window-private.h +++ b/src/core/window-private.h @@ -601,6 +601,9 @@ struct _MetaWindowClass MetaWaylandSurface * (*get_wayland_surface) (MetaWindow *window); #endif + gboolean (*set_transient_for) (MetaWindow *window, + MetaWindow *parent); + void (* map) (MetaWindow *window); void (* unmap) (MetaWindow *window); }; @@ -877,3 +880,6 @@ gboolean meta_window_is_suspended (MetaWindow *window); META_EXPORT_TEST int meta_get_window_suspend_timeout_s (void); + +gboolean +meta_window_should_attach_to_parent (MetaWindow *window); diff --git a/src/core/window.c b/src/core/window.c index 60446f70d..6eed1acbb 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -165,8 +165,6 @@ static MetaWindow * meta_window_find_tile_match (MetaWindow *window, MetaTileMode mode); static void update_edge_constraints (MetaWindow *window); -static gboolean meta_window_should_attach_to_parent (MetaWindow *window); - static void initable_iface_init (GInitableIface *initable_iface); typedef struct _MetaWindowPrivate @@ -7240,7 +7238,7 @@ check_transient_for_loop (MetaWindow *window, while (parent) { if (parent == window) - return TRUE; + return TRUE; parent = parent->transient_for; } @@ -7261,6 +7259,8 @@ void meta_window_set_transient_for (MetaWindow *window, MetaWindow *parent) { + MetaWindowClass *klass = META_WINDOW_GET_CLASS (window); + if (check_transient_for_loop (window, parent)) { meta_warning ("Setting %s transient for %s would create a loop.", @@ -7271,31 +7271,10 @@ meta_window_set_transient_for (MetaWindow *window, if (window->appears_focused && window->transient_for != NULL) meta_window_propagate_focus_appearance (window, FALSE); - /* may now be a dialog */ - if (window->client_type == META_WINDOW_CLIENT_TYPE_X11) - { - meta_window_x11_recalc_window_type (window); + if (!klass->set_transient_for (window, parent)) + return; - if (!window->constructing) - { - /* If the window attaches, detaches, or changes attached - * parents, we need to destroy the MetaWindow and let a new one - * be created (which happens as a side effect of - * meta_window_unmanage()). The condition below is correct - * because we know window->transient_for has changed. - */ - if (window->attached || meta_window_should_attach_to_parent (window)) - { - guint32 timestamp; - - timestamp = - meta_display_get_current_time_roundtrip (window->display); - meta_window_unmanage (window, timestamp); - return; - } - } - } - else if (window->attached && parent == NULL) + if (window->attached && parent == NULL) { guint32 timestamp; @@ -7307,26 +7286,10 @@ meta_window_set_transient_for (MetaWindow *window, g_set_object (&window->transient_for, parent); - if (window->client_type == META_WINDOW_CLIENT_TYPE_WAYLAND && - window->attached != meta_window_should_attach_to_parent (window)) - { - window->attached = meta_window_should_attach_to_parent (window); - meta_window_recalc_features (window); - } - /* update stacking constraints */ if (!window->override_redirect) meta_stack_update_transient (window->display->stack, window); - /* possibly change its group. We treat being a window's transient as - * equivalent to making it your group leader, to work around shortcomings - * in programs such as xmms-- see #328211. - */ - if (window->xtransient_for != None && - window->xgroup_leader != None && - window->xtransient_for != window->xgroup_leader) - meta_window_group_leader_changed (window); - if (!window->constructing && !window->override_redirect) meta_window_queue (window, META_QUEUE_MOVE_RESIZE | META_QUEUE_CALC_SHOWING); diff --git a/src/wayland/meta-window-wayland.c b/src/wayland/meta-window-wayland.c index f2499b965..73a48b475 100644 --- a/src/wayland/meta-window-wayland.c +++ b/src/wayland/meta-window-wayland.c @@ -801,6 +801,18 @@ meta_window_wayland_get_wayland_surface (MetaWindow *window) return wl_window->surface; } +static gboolean +meta_window_wayland_set_transient_for (MetaWindow *window, + MetaWindow *parent) +{ + if (window->attached != meta_window_should_attach_to_parent (window)) + { + window->attached = meta_window_should_attach_to_parent (window); + meta_window_recalc_features (window); + } + return TRUE; +} + static MetaStackLayer meta_window_wayland_calculate_layer (MetaWindow *window) { @@ -930,6 +942,7 @@ meta_window_wayland_class_init (MetaWindowWaylandClass *klass) window_class->unmap = meta_window_wayland_unmap; window_class->is_focus_async = meta_window_wayland_is_focus_async; window_class->get_wayland_surface = meta_window_wayland_get_wayland_surface; + window_class->set_transient_for = meta_window_wayland_set_transient_for; obj_props[PROP_SURFACE] = g_param_spec_object ("surface", NULL, NULL, diff --git a/src/x11/window-x11.c b/src/x11/window-x11.c index 3dc06aa19..11e1f336c 100644 --- a/src/x11/window-x11.c +++ b/src/x11/window-x11.c @@ -1998,6 +1998,42 @@ meta_window_x11_is_focus_async (MetaWindow *window) return !window->input && priv->wm_take_focus; } +static gboolean +meta_window_x11_set_transient_for (MetaWindow *window, + MetaWindow *parent) +{ + meta_window_x11_recalc_window_type (window); + if (!window->constructing) + { + /* If the window attaches, detaches, or changes attached + * parents, we need to destroy the MetaWindow and let a new one + * be created (which happens as a side effect of + * meta_window_unmanage()). The condition below is correct + * because we know window->transient_for has changed. + */ + if (window->attached || meta_window_should_attach_to_parent (window)) + { + guint32 timestamp; + + timestamp = + meta_display_get_current_time_roundtrip (window->display); + meta_window_unmanage (window, timestamp); + return FALSE; + } + } + + /* possibly change its group. We treat being a window's transient as + * equivalent to making it your group leader, to work around shortcomings + * in programs such as xmms-- see #328211. + */ + if (window->xtransient_for != None && + window->xgroup_leader != None && + window->xtransient_for != window->xgroup_leader) + meta_window_group_leader_changed (window); + + return TRUE; +} + static void meta_window_x11_constructed (GObject *object) { @@ -2127,6 +2163,7 @@ meta_window_x11_class_init (MetaWindowX11Class *klass) window_class->map = meta_window_x11_map; window_class->unmap = meta_window_x11_unmap; window_class->is_focus_async = meta_window_x11_is_focus_async; + window_class->set_transient_for = meta_window_x11_set_transient_for; klass->freeze_commits = meta_window_x11_impl_freeze_commits; klass->thaw_commits = meta_window_x11_impl_thaw_commits;