window: Make Window.set_transient_for a vfunc

So we can move the xgroup_leader to WindowX11. See next commit

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3211>
This commit is contained in:
Bilal Elmoussaoui 2023-08-24 12:14:14 +02:00 committed by Robert Mader
parent c0685fe29b
commit 7d6e7773bf
4 changed files with 62 additions and 43 deletions

View File

@ -601,6 +601,9 @@ struct _MetaWindowClass
MetaWaylandSurface * (*get_wayland_surface) (MetaWindow *window); MetaWaylandSurface * (*get_wayland_surface) (MetaWindow *window);
#endif #endif
gboolean (*set_transient_for) (MetaWindow *window,
MetaWindow *parent);
void (* map) (MetaWindow *window); void (* map) (MetaWindow *window);
void (* unmap) (MetaWindow *window); void (* unmap) (MetaWindow *window);
}; };
@ -877,3 +880,6 @@ gboolean meta_window_is_suspended (MetaWindow *window);
META_EXPORT_TEST META_EXPORT_TEST
int meta_get_window_suspend_timeout_s (void); int meta_get_window_suspend_timeout_s (void);
gboolean
meta_window_should_attach_to_parent (MetaWindow *window);

View File

@ -165,8 +165,6 @@ static MetaWindow * meta_window_find_tile_match (MetaWindow *window,
MetaTileMode mode); MetaTileMode mode);
static void update_edge_constraints (MetaWindow *window); 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); static void initable_iface_init (GInitableIface *initable_iface);
typedef struct _MetaWindowPrivate typedef struct _MetaWindowPrivate
@ -7240,7 +7238,7 @@ check_transient_for_loop (MetaWindow *window,
while (parent) while (parent)
{ {
if (parent == window) if (parent == window)
return TRUE; return TRUE;
parent = parent->transient_for; parent = parent->transient_for;
} }
@ -7261,6 +7259,8 @@ void
meta_window_set_transient_for (MetaWindow *window, meta_window_set_transient_for (MetaWindow *window,
MetaWindow *parent) MetaWindow *parent)
{ {
MetaWindowClass *klass = META_WINDOW_GET_CLASS (window);
if (check_transient_for_loop (window, parent)) if (check_transient_for_loop (window, parent))
{ {
meta_warning ("Setting %s transient for %s would create a loop.", 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) if (window->appears_focused && window->transient_for != NULL)
meta_window_propagate_focus_appearance (window, FALSE); meta_window_propagate_focus_appearance (window, FALSE);
/* may now be a dialog */ if (!klass->set_transient_for (window, parent))
if (window->client_type == META_WINDOW_CLIENT_TYPE_X11) return;
{
meta_window_x11_recalc_window_type (window);
if (!window->constructing) if (window->attached && parent == NULL)
{
/* 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)
{ {
guint32 timestamp; guint32 timestamp;
@ -7307,26 +7286,10 @@ meta_window_set_transient_for (MetaWindow *window,
g_set_object (&window->transient_for, parent); 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 */ /* update stacking constraints */
if (!window->override_redirect) if (!window->override_redirect)
meta_stack_update_transient (window->display->stack, window); 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) if (!window->constructing && !window->override_redirect)
meta_window_queue (window, META_QUEUE_MOVE_RESIZE | META_QUEUE_CALC_SHOWING); meta_window_queue (window, META_QUEUE_MOVE_RESIZE | META_QUEUE_CALC_SHOWING);

View File

@ -801,6 +801,18 @@ meta_window_wayland_get_wayland_surface (MetaWindow *window)
return wl_window->surface; 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 static MetaStackLayer
meta_window_wayland_calculate_layer (MetaWindow *window) 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->unmap = meta_window_wayland_unmap;
window_class->is_focus_async = meta_window_wayland_is_focus_async; window_class->is_focus_async = meta_window_wayland_is_focus_async;
window_class->get_wayland_surface = meta_window_wayland_get_wayland_surface; 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] = obj_props[PROP_SURFACE] =
g_param_spec_object ("surface", NULL, NULL, g_param_spec_object ("surface", NULL, NULL,

View File

@ -1998,6 +1998,42 @@ meta_window_x11_is_focus_async (MetaWindow *window)
return !window->input && priv->wm_take_focus; 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 static void
meta_window_x11_constructed (GObject *object) 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->map = meta_window_x11_map;
window_class->unmap = meta_window_x11_unmap; window_class->unmap = meta_window_x11_unmap;
window_class->is_focus_async = meta_window_x11_is_focus_async; 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->freeze_commits = meta_window_x11_impl_freeze_commits;
klass->thaw_commits = meta_window_x11_impl_thaw_commits; klass->thaw_commits = meta_window_x11_impl_thaw_commits;