wayland/shell: Apply geometry after subsurface state application

The subsurface state may affect the geometry end result, e.g. when
window decoration enlarging the toplevel window are applied. If we don't
wait with calculating the window geometry, intersecting the set region
with the subsurface tree extents will not include the subsurfaces.

Closes: https://gitlab.gnome.org/GNOME/mutter/-/issues/928

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1295
This commit is contained in:
Jonas Ådahl 2020-06-08 09:13:44 +02:00 committed by Robert Mader
parent be59b514ca
commit d6af59612c
4 changed files with 140 additions and 32 deletions

View File

@ -664,8 +664,6 @@ meta_wayland_zxdg_toplevel_v6_apply_state (MetaWaylandSurfaceRole *surface_role
MetaWaylandSurface *surface = MetaWaylandSurface *surface =
meta_wayland_surface_role_get_surface (surface_role); meta_wayland_surface_role_get_surface (surface_role);
MetaWindow *window; MetaWindow *window;
MetaRectangle old_geometry;
gboolean geometry_changed;
window = meta_wayland_surface_get_window (surface); window = meta_wayland_surface_get_window (surface);
if (!window) if (!window)
@ -674,8 +672,6 @@ meta_wayland_zxdg_toplevel_v6_apply_state (MetaWaylandSurfaceRole *surface_role
return; return;
} }
old_geometry = xdg_surface_priv->geometry;
surface_role_class = surface_role_class =
META_WAYLAND_SURFACE_ROLE_CLASS (meta_wayland_zxdg_toplevel_v6_parent_class); META_WAYLAND_SURFACE_ROLE_CLASS (meta_wayland_zxdg_toplevel_v6_parent_class);
surface_role_class->apply_state (surface_role, pending); surface_role_class->apply_state (surface_role, pending);
@ -690,13 +686,37 @@ meta_wayland_zxdg_toplevel_v6_apply_state (MetaWaylandSurfaceRole *surface_role
meta_wayland_window_configuration_free (configuration); meta_wayland_window_configuration_free (configuration);
return; return;
} }
}
static void
meta_wayland_zxdg_toplevel_v6_post_apply_state (MetaWaylandSurfaceRole *surface_role,
MetaWaylandSurfaceState *pending)
{
MetaWaylandZxdgToplevelV6 *xdg_toplevel =
META_WAYLAND_ZXDG_TOPLEVEL_V6 (surface_role);
MetaWaylandZxdgSurfaceV6 *xdg_surface =
META_WAYLAND_ZXDG_SURFACE_V6 (xdg_toplevel);
MetaWaylandZxdgSurfaceV6Private *xdg_surface_priv =
meta_wayland_zxdg_surface_v6_get_instance_private (xdg_surface);
MetaWaylandSurfaceRoleClass *surface_role_class;
MetaWaylandSurface *surface =
meta_wayland_surface_role_get_surface (surface_role);
MetaWindow *window;
MetaRectangle old_geometry;
gboolean geometry_changed;
window = meta_wayland_surface_get_window (surface);
if (!window)
return;
if (!pending->newly_attached) if (!pending->newly_attached)
return; return;
/* If the window disappeared the surface is not coming back. */ old_geometry = xdg_surface_priv->geometry;
if (!window)
return; surface_role_class =
META_WAYLAND_SURFACE_ROLE_CLASS (meta_wayland_zxdg_toplevel_v6_parent_class);
surface_role_class->post_apply_state (surface_role, pending);
geometry_changed = !meta_rectangle_equal (&old_geometry, &xdg_surface_priv->geometry); geometry_changed = !meta_rectangle_equal (&old_geometry, &xdg_surface_priv->geometry);
@ -833,6 +853,8 @@ meta_wayland_zxdg_toplevel_v6_class_init (MetaWaylandZxdgToplevelV6Class *klass)
surface_role_class = META_WAYLAND_SURFACE_ROLE_CLASS (klass); surface_role_class = META_WAYLAND_SURFACE_ROLE_CLASS (klass);
surface_role_class->apply_state = meta_wayland_zxdg_toplevel_v6_apply_state; surface_role_class->apply_state = meta_wayland_zxdg_toplevel_v6_apply_state;
surface_role_class->post_apply_state =
meta_wayland_zxdg_toplevel_v6_post_apply_state;
surface_role_class->get_toplevel = meta_wayland_zxdg_toplevel_v6_get_toplevel; surface_role_class->get_toplevel = meta_wayland_zxdg_toplevel_v6_get_toplevel;
shell_surface_class = META_WAYLAND_SHELL_SURFACE_CLASS (klass); shell_surface_class = META_WAYLAND_SHELL_SURFACE_CLASS (klass);
@ -965,12 +987,7 @@ meta_wayland_zxdg_popup_v6_apply_state (MetaWaylandSurfaceRole *surface_role,
MetaWaylandSurfaceState *pending) MetaWaylandSurfaceState *pending)
{ {
MetaWaylandZxdgPopupV6 *xdg_popup = META_WAYLAND_ZXDG_POPUP_V6 (surface_role); MetaWaylandZxdgPopupV6 *xdg_popup = META_WAYLAND_ZXDG_POPUP_V6 (surface_role);
MetaWaylandZxdgSurfaceV6 *xdg_surface =
META_WAYLAND_ZXDG_SURFACE_V6 (surface_role);
MetaWaylandSurfaceRoleClass *surface_role_class; MetaWaylandSurfaceRoleClass *surface_role_class;
MetaWaylandSurface *surface =
meta_wayland_surface_role_get_surface (surface_role);
MetaWindow *window;
if (xdg_popup->setup.parent_surface) if (xdg_popup->setup.parent_surface)
finish_popup_setup (xdg_popup); finish_popup_setup (xdg_popup);
@ -978,12 +995,27 @@ meta_wayland_zxdg_popup_v6_apply_state (MetaWaylandSurfaceRole *surface_role,
surface_role_class = surface_role_class =
META_WAYLAND_SURFACE_ROLE_CLASS (meta_wayland_zxdg_popup_v6_parent_class); META_WAYLAND_SURFACE_ROLE_CLASS (meta_wayland_zxdg_popup_v6_parent_class);
surface_role_class->apply_state (surface_role, pending); surface_role_class->apply_state (surface_role, pending);
}
static void
meta_wayland_zxdg_popup_v6_post_apply_state (MetaWaylandSurfaceRole *surface_role,
MetaWaylandSurfaceState *pending)
{
MetaWaylandZxdgSurfaceV6 *xdg_surface =
META_WAYLAND_ZXDG_SURFACE_V6 (surface_role);
MetaWaylandSurfaceRoleClass *surface_role_class;
MetaWaylandSurface *surface =
meta_wayland_surface_role_get_surface (surface_role);
MetaWindow *window;
/* If the window disappeared the surface is not coming back. */
window = meta_wayland_surface_get_window (surface); window = meta_wayland_surface_get_window (surface);
if (!window) if (!window)
return; return;
surface_role_class =
META_WAYLAND_SURFACE_ROLE_CLASS (meta_wayland_zxdg_popup_v6_parent_class);
surface_role_class->post_apply_state (surface_role, pending);
if (!pending->newly_attached) if (!pending->newly_attached)
return; return;
@ -1166,6 +1198,8 @@ meta_wayland_zxdg_popup_v6_class_init (MetaWaylandZxdgPopupV6Class *klass)
surface_role_class = META_WAYLAND_SURFACE_ROLE_CLASS (klass); surface_role_class = META_WAYLAND_SURFACE_ROLE_CLASS (klass);
surface_role_class->apply_state = meta_wayland_zxdg_popup_v6_apply_state; surface_role_class->apply_state = meta_wayland_zxdg_popup_v6_apply_state;
surface_role_class->post_apply_state =
meta_wayland_zxdg_popup_v6_post_apply_state;
surface_role_class->get_toplevel = meta_wayland_zxdg_popup_v6_get_toplevel; surface_role_class->get_toplevel = meta_wayland_zxdg_popup_v6_get_toplevel;
shell_surface_class = META_WAYLAND_SHELL_SURFACE_CLASS (klass); shell_surface_class = META_WAYLAND_SHELL_SURFACE_CLASS (klass);
@ -1328,8 +1362,6 @@ meta_wayland_zxdg_surface_v6_apply_state (MetaWaylandSurfaceRole *surface_role,
{ {
MetaWaylandZxdgSurfaceV6 *xdg_surface = MetaWaylandZxdgSurfaceV6 *xdg_surface =
META_WAYLAND_ZXDG_SURFACE_V6 (surface_role); META_WAYLAND_ZXDG_SURFACE_V6 (surface_role);
MetaWaylandShellSurface *shell_surface =
META_WAYLAND_SHELL_SURFACE (xdg_surface);
MetaWaylandZxdgSurfaceV6Private *priv = MetaWaylandZxdgSurfaceV6Private *priv =
meta_wayland_zxdg_surface_v6_get_instance_private (xdg_surface); meta_wayland_zxdg_surface_v6_get_instance_private (xdg_surface);
MetaWaylandSurface *surface = MetaWaylandSurface *surface =
@ -1367,8 +1399,18 @@ meta_wayland_zxdg_surface_v6_apply_state (MetaWaylandSurfaceRole *surface_role,
if (surface->buffer_ref->buffer) if (surface->buffer_ref->buffer)
priv->first_buffer_attached = TRUE; priv->first_buffer_attached = TRUE;
else }
return;
static void
meta_wayland_zxdg_surface_v6_post_apply_state (MetaWaylandSurfaceRole *surface_role,
MetaWaylandSurfaceState *pending)
{
MetaWaylandZxdgSurfaceV6 *xdg_surface =
META_WAYLAND_ZXDG_SURFACE_V6 (surface_role);
MetaWaylandZxdgSurfaceV6Private *priv =
meta_wayland_zxdg_surface_v6_get_instance_private (xdg_surface);
MetaWaylandShellSurface *shell_surface =
META_WAYLAND_SHELL_SURFACE (xdg_surface);
if (pending->has_new_geometry) if (pending->has_new_geometry)
{ {
@ -1523,6 +1565,8 @@ meta_wayland_zxdg_surface_v6_class_init (MetaWaylandZxdgSurfaceV6Class *klass)
surface_role_class = META_WAYLAND_SURFACE_ROLE_CLASS (klass); surface_role_class = META_WAYLAND_SURFACE_ROLE_CLASS (klass);
surface_role_class->apply_state = meta_wayland_zxdg_surface_v6_apply_state; surface_role_class->apply_state = meta_wayland_zxdg_surface_v6_apply_state;
surface_role_class->post_apply_state =
meta_wayland_zxdg_surface_v6_post_apply_state;
surface_role_class->assigned = meta_wayland_zxdg_surface_v6_assigned; surface_role_class->assigned = meta_wayland_zxdg_surface_v6_assigned;
shell_surface_class = META_WAYLAND_SHELL_SURFACE_CLASS (klass); shell_surface_class = META_WAYLAND_SHELL_SURFACE_CLASS (klass);

View File

@ -113,6 +113,10 @@ static void
meta_wayland_surface_role_apply_state (MetaWaylandSurfaceRole *surface_role, meta_wayland_surface_role_apply_state (MetaWaylandSurfaceRole *surface_role,
MetaWaylandSurfaceState *pending); MetaWaylandSurfaceState *pending);
static void
meta_wayland_surface_role_post_apply_state (MetaWaylandSurfaceRole *surface_role,
MetaWaylandSurfaceState *pending);
static gboolean static gboolean
meta_wayland_surface_role_is_on_logical_monitor (MetaWaylandSurfaceRole *surface_role, meta_wayland_surface_role_is_on_logical_monitor (MetaWaylandSurfaceRole *surface_role,
MetaLogicalMonitor *logical_monitor); MetaLogicalMonitor *logical_monitor);
@ -787,8 +791,6 @@ cleanup:
surface_state_signals[SURFACE_STATE_SIGNAL_APPLIED], surface_state_signals[SURFACE_STATE_SIGNAL_APPLIED],
0); 0);
meta_wayland_surface_state_reset (state);
META_WAYLAND_SURFACE_FOREACH_SUBSURFACE (surface, subsurface_surface) META_WAYLAND_SURFACE_FOREACH_SUBSURFACE (surface, subsurface_surface)
{ {
MetaWaylandSubsurface *subsurface; MetaWaylandSubsurface *subsurface;
@ -812,6 +814,11 @@ cleanup:
meta_window_actor_notify_damaged (toplevel_window_actor); meta_window_actor_notify_damaged (toplevel_window_actor);
} }
} }
if (surface->role)
meta_wayland_surface_role_post_apply_state (surface->role, state);
meta_wayland_surface_state_reset (state);
} }
void void
@ -1755,6 +1762,17 @@ meta_wayland_surface_role_pre_apply_state (MetaWaylandSurfaceRole *surface_role
klass->pre_apply_state (surface_role, pending); klass->pre_apply_state (surface_role, pending);
} }
static void
meta_wayland_surface_role_post_apply_state (MetaWaylandSurfaceRole *surface_role,
MetaWaylandSurfaceState *pending)
{
MetaWaylandSurfaceRoleClass *klass;
klass = META_WAYLAND_SURFACE_ROLE_GET_CLASS (surface_role);
if (klass->post_apply_state)
klass->post_apply_state (surface_role, pending);
}
static void static void
meta_wayland_surface_role_apply_state (MetaWaylandSurfaceRole *surface_role, meta_wayland_surface_role_apply_state (MetaWaylandSurfaceRole *surface_role,
MetaWaylandSurfaceState *pending) MetaWaylandSurfaceState *pending)

View File

@ -58,6 +58,8 @@ struct _MetaWaylandSurfaceRoleClass
MetaWaylandSurfaceState *pending); MetaWaylandSurfaceState *pending);
void (*apply_state) (MetaWaylandSurfaceRole *surface_role, void (*apply_state) (MetaWaylandSurfaceRole *surface_role,
MetaWaylandSurfaceState *pending); MetaWaylandSurfaceState *pending);
void (*post_apply_state) (MetaWaylandSurfaceRole *surface_role,
MetaWaylandSurfaceState *pending);
gboolean (*is_on_logical_monitor) (MetaWaylandSurfaceRole *surface_role, gboolean (*is_on_logical_monitor) (MetaWaylandSurfaceRole *surface_role,
MetaLogicalMonitor *logical_monitor); MetaLogicalMonitor *logical_monitor);
MetaWaylandSurface * (*get_toplevel) (MetaWaylandSurfaceRole *surface_role); MetaWaylandSurface * (*get_toplevel) (MetaWaylandSurfaceRole *surface_role);

View File

@ -746,8 +746,6 @@ meta_wayland_xdg_toplevel_apply_state (MetaWaylandSurfaceRole *surface_role,
MetaWaylandSurface *surface = MetaWaylandSurface *surface =
meta_wayland_surface_role_get_surface (surface_role); meta_wayland_surface_role_get_surface (surface_role);
MetaWindow *window; MetaWindow *window;
MetaRectangle old_geometry;
gboolean geometry_changed;
window = meta_wayland_surface_get_window (surface); window = meta_wayland_surface_get_window (surface);
if (!window) if (!window)
@ -764,8 +762,6 @@ meta_wayland_xdg_toplevel_apply_state (MetaWaylandSurfaceRole *surface_role,
return; return;
} }
old_geometry = xdg_surface_priv->geometry;
surface_role_class = surface_role_class =
META_WAYLAND_SURFACE_ROLE_CLASS (meta_wayland_xdg_toplevel_parent_class); META_WAYLAND_SURFACE_ROLE_CLASS (meta_wayland_xdg_toplevel_parent_class);
surface_role_class->apply_state (surface_role, pending); surface_role_class->apply_state (surface_role, pending);
@ -779,6 +775,31 @@ meta_wayland_xdg_toplevel_apply_state (MetaWaylandSurfaceRole *surface_role,
meta_wayland_window_configuration_free (configuration); meta_wayland_window_configuration_free (configuration);
return; return;
} }
}
static void
meta_wayland_xdg_toplevel_post_apply_state (MetaWaylandSurfaceRole *surface_role,
MetaWaylandSurfaceState *pending)
{
MetaWaylandXdgSurface *xdg_surface = META_WAYLAND_XDG_SURFACE (surface_role);
MetaWaylandXdgSurfacePrivate *xdg_surface_priv =
meta_wayland_xdg_surface_get_instance_private (xdg_surface);
MetaWaylandSurface *surface =
meta_wayland_surface_role_get_surface (surface_role);
MetaWaylandSurfaceRoleClass *surface_role_class;
MetaWindow *window;
MetaRectangle old_geometry;
gboolean geometry_changed;
window = meta_wayland_surface_get_window (surface);
if (!window)
return;
old_geometry = xdg_surface_priv->geometry;
surface_role_class =
META_WAYLAND_SURFACE_ROLE_CLASS (meta_wayland_xdg_toplevel_parent_class);
surface_role_class->post_apply_state (surface_role, pending);
if (!pending->newly_attached) if (!pending->newly_attached)
return; return;
@ -938,6 +959,7 @@ meta_wayland_xdg_toplevel_class_init (MetaWaylandXdgToplevelClass *klass)
surface_role_class = META_WAYLAND_SURFACE_ROLE_CLASS (klass); surface_role_class = META_WAYLAND_SURFACE_ROLE_CLASS (klass);
surface_role_class->apply_state = meta_wayland_xdg_toplevel_apply_state; surface_role_class->apply_state = meta_wayland_xdg_toplevel_apply_state;
surface_role_class->post_apply_state = meta_wayland_xdg_toplevel_post_apply_state;
surface_role_class->get_toplevel = meta_wayland_xdg_toplevel_get_toplevel; surface_role_class->get_toplevel = meta_wayland_xdg_toplevel_get_toplevel;
shell_surface_class = META_WAYLAND_SHELL_SURFACE_CLASS (klass); shell_surface_class = META_WAYLAND_SHELL_SURFACE_CLASS (klass);
@ -1092,10 +1114,6 @@ meta_wayland_xdg_popup_apply_state (MetaWaylandSurfaceRole *surface_role,
MetaWaylandSurfaceRoleClass *surface_role_class; MetaWaylandSurfaceRoleClass *surface_role_class;
MetaWaylandSurface *surface = MetaWaylandSurface *surface =
meta_wayland_surface_role_get_surface (surface_role); meta_wayland_surface_role_get_surface (surface_role);
MetaWindow *window;
MetaRectangle buffer_rect;
MetaWindow *parent_window;
MetaRectangle parent_buffer_rect;
if (xdg_popup->setup.parent_surface) if (xdg_popup->setup.parent_surface)
finish_popup_setup (xdg_popup); finish_popup_setup (xdg_popup);
@ -1118,8 +1136,23 @@ meta_wayland_xdg_popup_apply_state (MetaWaylandSurfaceRole *surface_role,
"Can't commit buffer to dismissed popup"); "Can't commit buffer to dismissed popup");
return; return;
} }
}
static void
meta_wayland_xdg_popup_post_apply_state (MetaWaylandSurfaceRole *surface_role,
MetaWaylandSurfaceState *pending)
{
MetaWaylandXdgPopup *xdg_popup = META_WAYLAND_XDG_POPUP (surface_role);
MetaWaylandXdgSurface *xdg_surface = META_WAYLAND_XDG_SURFACE (surface_role);
MetaWaylandSurface *surface =
meta_wayland_surface_role_get_surface (surface_role);
MetaWaylandSurfaceRoleClass *surface_role_class =
META_WAYLAND_SURFACE_ROLE_CLASS (meta_wayland_xdg_popup_parent_class);
MetaWindow *window;
MetaWindow *parent_window;
MetaRectangle buffer_rect;
MetaRectangle parent_buffer_rect;
/* If the window disappeared the surface is not coming back. */
window = meta_wayland_surface_get_window (surface); window = meta_wayland_surface_get_window (surface);
if (!window) if (!window)
return; return;
@ -1130,6 +1163,8 @@ meta_wayland_xdg_popup_apply_state (MetaWaylandSurfaceRole *surface_role,
if (!surface->buffer_ref->buffer) if (!surface->buffer_ref->buffer)
return; return;
surface_role_class->post_apply_state (surface_role, pending);
if (pending->has_acked_configure_serial) if (pending->has_acked_configure_serial)
{ {
MetaRectangle window_geometry; MetaRectangle window_geometry;
@ -1326,6 +1361,7 @@ meta_wayland_xdg_popup_class_init (MetaWaylandXdgPopupClass *klass)
surface_role_class = META_WAYLAND_SURFACE_ROLE_CLASS (klass); surface_role_class = META_WAYLAND_SURFACE_ROLE_CLASS (klass);
surface_role_class->apply_state = meta_wayland_xdg_popup_apply_state; surface_role_class->apply_state = meta_wayland_xdg_popup_apply_state;
surface_role_class->post_apply_state = meta_wayland_xdg_popup_post_apply_state;
surface_role_class->get_toplevel = meta_wayland_xdg_popup_get_toplevel; surface_role_class->get_toplevel = meta_wayland_xdg_popup_get_toplevel;
shell_surface_class = META_WAYLAND_SHELL_SURFACE_CLASS (klass); shell_surface_class = META_WAYLAND_SHELL_SURFACE_CLASS (klass);
@ -1500,8 +1536,6 @@ meta_wayland_xdg_surface_apply_state (MetaWaylandSurfaceRole *surface_role,
MetaWaylandSurfaceState *pending) MetaWaylandSurfaceState *pending)
{ {
MetaWaylandXdgSurface *xdg_surface = META_WAYLAND_XDG_SURFACE (surface_role); MetaWaylandXdgSurface *xdg_surface = META_WAYLAND_XDG_SURFACE (surface_role);
MetaWaylandShellSurface *shell_surface =
META_WAYLAND_SHELL_SURFACE (xdg_surface);
MetaWaylandXdgSurfacePrivate *priv = MetaWaylandXdgSurfacePrivate *priv =
meta_wayland_xdg_surface_get_instance_private (xdg_surface); meta_wayland_xdg_surface_get_instance_private (xdg_surface);
MetaWaylandSurface *surface = MetaWaylandSurface *surface =
@ -1522,8 +1556,17 @@ meta_wayland_xdg_surface_apply_state (MetaWaylandSurfaceRole *surface_role,
if (surface->buffer_ref->buffer) if (surface->buffer_ref->buffer)
priv->first_buffer_attached = TRUE; priv->first_buffer_attached = TRUE;
else }
return;
static void
meta_wayland_xdg_surface_post_apply_state (MetaWaylandSurfaceRole *surface_role,
MetaWaylandSurfaceState *pending)
{
MetaWaylandXdgSurface *xdg_surface = META_WAYLAND_XDG_SURFACE (surface_role);
MetaWaylandXdgSurfacePrivate *priv =
meta_wayland_xdg_surface_get_instance_private (xdg_surface);
MetaWaylandShellSurface *shell_surface =
META_WAYLAND_SHELL_SURFACE (surface_role);
if (pending->has_new_geometry) if (pending->has_new_geometry)
{ {
@ -1676,6 +1719,7 @@ meta_wayland_xdg_surface_class_init (MetaWaylandXdgSurfaceClass *klass)
surface_role_class = META_WAYLAND_SURFACE_ROLE_CLASS (klass); surface_role_class = META_WAYLAND_SURFACE_ROLE_CLASS (klass);
surface_role_class->apply_state = meta_wayland_xdg_surface_apply_state; surface_role_class->apply_state = meta_wayland_xdg_surface_apply_state;
surface_role_class->post_apply_state = meta_wayland_xdg_surface_post_apply_state;
surface_role_class->assigned = meta_wayland_xdg_surface_assigned; surface_role_class->assigned = meta_wayland_xdg_surface_assigned;
shell_surface_class = META_WAYLAND_SHELL_SURFACE_CLASS (klass); shell_surface_class = META_WAYLAND_SHELL_SURFACE_CLASS (klass);