[mutter] wayland/shell: Apply geometry after subsurface state application



commit d6af59612cee2050798ea9af092afc1269f0eea5
Author: Jonas Ã…dahl <jadahl gmail com>
Date:   Mon Jun 8 09:13:44 2020 +0200

    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

 src/wayland/meta-wayland-legacy-xdg-shell.c | 78 ++++++++++++++++++++++-------
 src/wayland/meta-wayland-surface.c          | 22 +++++++-
 src/wayland/meta-wayland-surface.h          |  2 +
 src/wayland/meta-wayland-xdg-shell.c        | 70 +++++++++++++++++++++-----
 4 files changed, 140 insertions(+), 32 deletions(-)
---
diff --git a/src/wayland/meta-wayland-legacy-xdg-shell.c b/src/wayland/meta-wayland-legacy-xdg-shell.c
index 5bd6fbae2f..c9c0df6e6e 100644
--- a/src/wayland/meta-wayland-legacy-xdg-shell.c
+++ b/src/wayland/meta-wayland-legacy-xdg-shell.c
@@ -664,8 +664,6 @@ meta_wayland_zxdg_toplevel_v6_apply_state (MetaWaylandSurfaceRole  *surface_role
   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)
@@ -674,8 +672,6 @@ meta_wayland_zxdg_toplevel_v6_apply_state (MetaWaylandSurfaceRole  *surface_role
       return;
     }
 
-  old_geometry = xdg_surface_priv->geometry;
-
   surface_role_class =
     META_WAYLAND_SURFACE_ROLE_CLASS (meta_wayland_zxdg_toplevel_v6_parent_class);
   surface_role_class->apply_state (surface_role, pending);
@@ -690,14 +686,38 @@ meta_wayland_zxdg_toplevel_v6_apply_state (MetaWaylandSurfaceRole  *surface_role
       meta_wayland_window_configuration_free (configuration);
       return;
     }
+}
 
-  if (!pending->newly_attached)
-    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;
 
-  /* If the window disappeared the surface is not coming back. */
+  window = meta_wayland_surface_get_window (surface);
   if (!window)
     return;
 
+  if (!pending->newly_attached)
+    return;
+
+  old_geometry = xdg_surface_priv->geometry;
+
+  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);
 
   if (geometry_changed || pending->has_acked_configure_serial)
@@ -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->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;
 
   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)
 {
   MetaWaylandZxdgPopupV6 *xdg_popup = META_WAYLAND_ZXDG_POPUP_V6 (surface_role);
-  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 (xdg_popup->setup.parent_surface)
     finish_popup_setup (xdg_popup);
@@ -978,12 +995,27 @@ meta_wayland_zxdg_popup_v6_apply_state (MetaWaylandSurfaceRole  *surface_role,
   surface_role_class =
     META_WAYLAND_SURFACE_ROLE_CLASS (meta_wayland_zxdg_popup_v6_parent_class);
   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);
   if (!window)
     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)
     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->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;
 
   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 =
     META_WAYLAND_ZXDG_SURFACE_V6 (surface_role);
-  MetaWaylandShellSurface *shell_surface =
-    META_WAYLAND_SHELL_SURFACE (xdg_surface);
   MetaWaylandZxdgSurfaceV6Private *priv =
     meta_wayland_zxdg_surface_v6_get_instance_private (xdg_surface);
   MetaWaylandSurface *surface =
@@ -1367,8 +1399,18 @@ meta_wayland_zxdg_surface_v6_apply_state (MetaWaylandSurfaceRole  *surface_role,
 
   if (surface->buffer_ref->buffer)
     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)
     {
@@ -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->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;
 
   shell_surface_class = META_WAYLAND_SHELL_SURFACE_CLASS (klass);
diff --git a/src/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c
index 515c679575..edc2eb772b 100644
--- a/src/wayland/meta-wayland-surface.c
+++ b/src/wayland/meta-wayland-surface.c
@@ -113,6 +113,10 @@ static void
 meta_wayland_surface_role_apply_state (MetaWaylandSurfaceRole  *surface_role,
                                        MetaWaylandSurfaceState *pending);
 
+static void
+meta_wayland_surface_role_post_apply_state (MetaWaylandSurfaceRole  *surface_role,
+                                            MetaWaylandSurfaceState *pending);
+
 static gboolean
 meta_wayland_surface_role_is_on_logical_monitor (MetaWaylandSurfaceRole *surface_role,
                                                  MetaLogicalMonitor     *logical_monitor);
@@ -787,8 +791,6 @@ cleanup:
                  surface_state_signals[SURFACE_STATE_SIGNAL_APPLIED],
                  0);
 
-  meta_wayland_surface_state_reset (state);
-
   META_WAYLAND_SURFACE_FOREACH_SUBSURFACE (surface, subsurface_surface)
     {
       MetaWaylandSubsurface *subsurface;
@@ -812,6 +814,11 @@ cleanup:
             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
@@ -1755,6 +1762,17 @@ meta_wayland_surface_role_pre_apply_state (MetaWaylandSurfaceRole  *surface_role
     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
 meta_wayland_surface_role_apply_state (MetaWaylandSurfaceRole  *surface_role,
                                        MetaWaylandSurfaceState *pending)
diff --git a/src/wayland/meta-wayland-surface.h b/src/wayland/meta-wayland-surface.h
index 0e66f4b4eb..c9ed38e306 100644
--- a/src/wayland/meta-wayland-surface.h
+++ b/src/wayland/meta-wayland-surface.h
@@ -58,6 +58,8 @@ struct _MetaWaylandSurfaceRoleClass
                            MetaWaylandSurfaceState *pending);
   void (*apply_state) (MetaWaylandSurfaceRole  *surface_role,
                        MetaWaylandSurfaceState *pending);
+  void (*post_apply_state) (MetaWaylandSurfaceRole  *surface_role,
+                            MetaWaylandSurfaceState *pending);
   gboolean (*is_on_logical_monitor) (MetaWaylandSurfaceRole *surface_role,
                                      MetaLogicalMonitor     *logical_monitor);
   MetaWaylandSurface * (*get_toplevel) (MetaWaylandSurfaceRole *surface_role);
diff --git a/src/wayland/meta-wayland-xdg-shell.c b/src/wayland/meta-wayland-xdg-shell.c
index 97811971bf..93fa3c4e96 100644
--- a/src/wayland/meta-wayland-xdg-shell.c
+++ b/src/wayland/meta-wayland-xdg-shell.c
@@ -746,8 +746,6 @@ meta_wayland_xdg_toplevel_apply_state (MetaWaylandSurfaceRole  *surface_role,
   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)
@@ -764,8 +762,6 @@ meta_wayland_xdg_toplevel_apply_state (MetaWaylandSurfaceRole  *surface_role,
       return;
     }
 
-  old_geometry = xdg_surface_priv->geometry;
-
   surface_role_class =
     META_WAYLAND_SURFACE_ROLE_CLASS (meta_wayland_xdg_toplevel_parent_class);
   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);
       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)
     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->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;
 
   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;
   MetaWaylandSurface *surface =
     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)
     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");
       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);
   if (!window)
     return;
@@ -1130,6 +1163,8 @@ meta_wayland_xdg_popup_apply_state (MetaWaylandSurfaceRole  *surface_role,
   if (!surface->buffer_ref->buffer)
     return;
 
+  surface_role_class->post_apply_state (surface_role, pending);
+
   if (pending->has_acked_configure_serial)
     {
       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->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;
 
   shell_surface_class = META_WAYLAND_SHELL_SURFACE_CLASS (klass);
@@ -1500,8 +1536,6 @@ meta_wayland_xdg_surface_apply_state (MetaWaylandSurfaceRole  *surface_role,
                                       MetaWaylandSurfaceState *pending)
 {
   MetaWaylandXdgSurface *xdg_surface = META_WAYLAND_XDG_SURFACE (surface_role);
-  MetaWaylandShellSurface *shell_surface =
-    META_WAYLAND_SHELL_SURFACE (xdg_surface);
   MetaWaylandXdgSurfacePrivate *priv =
     meta_wayland_xdg_surface_get_instance_private (xdg_surface);
   MetaWaylandSurface *surface =
@@ -1522,8 +1556,17 @@ meta_wayland_xdg_surface_apply_state (MetaWaylandSurfaceRole  *surface_role,
 
   if (surface->buffer_ref->buffer)
     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)
     {
@@ -1676,6 +1719,7 @@ meta_wayland_xdg_surface_class_init (MetaWaylandXdgSurfaceClass *klass)
 
   surface_role_class = META_WAYLAND_SURFACE_ROLE_CLASS (klass);
   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;
 
   shell_surface_class = META_WAYLAND_SHELL_SURFACE_CLASS (klass);


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]