[mutter] wayland/window: Correct detection whether to send `configure`



commit 236e9ec68fc56fad5af35e6f663a40ada1b6d0af
Author: Aleksandr Mezin <mezin alexander gmail com>
Date:   Fri Mar 5 14:38:57 2021 +0600

    wayland/window: Correct detection whether to send `configure`
    
    When deciding if `configure` event should be sent,
    `meta_window_wayland_move_resize_internal` compares requested window size
    with `window->rect` size. However, `window->rect` is only updated when `commit`
    is received. So the following sequence produces incorrect result:
    
    1. a window initially has size `size1`
    2. `move_resize_internal` is called with `size2`. `configure` is sent
    3. `move_resize_internal` is called with `size1` to restore original size,
    but `commit` for `size2` haven't arrived yet. So `window->rect` still has size
    `size1`, and thus new `configure` is not sent
    4. `commit` for `size2` arrives, window changes size to `size2`
    
    Expected window size in the end: `size1`
    Actual: `size2`
    
    To fix the issue, take size from pending `configure` events into account.
    
    Fixes https://gitlab.gnome.org/GNOME/mutter/-/issues/1627
    
    Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1755>

 src/wayland/meta-wayland-window-configuration.c | 13 +++++++--
 src/wayland/meta-window-wayland.c               | 38 ++++++++++++++++++++++---
 src/wayland/meta-window-wayland.h               |  4 +++
 3 files changed, 49 insertions(+), 6 deletions(-)
---
diff --git a/src/wayland/meta-wayland-window-configuration.c b/src/wayland/meta-wayland-window-configuration.c
index 6a91a7141e..c3de8a777b 100644
--- a/src/wayland/meta-wayland-window-configuration.c
+++ b/src/wayland/meta-wayland-window-configuration.c
@@ -22,6 +22,8 @@
 
 #include "wayland/meta-wayland-window-configuration.h"
 
+#include "wayland/meta-window-wayland.h"
+
 static uint32_t global_serial_counter = 0;
 
 static gboolean
@@ -51,6 +53,13 @@ meta_wayland_window_configuration_new (MetaWindow          *window,
                                        MetaGravity          gravity)
 {
   MetaWaylandWindowConfiguration *configuration;
+  MetaWindowWayland *wl_window = META_WINDOW_WAYLAND (window);
+  int pending_width;
+  int pending_height;
+
+  meta_window_wayland_get_pending_size (wl_window,
+                                        &pending_width,
+                                        &pending_height);
 
   configuration = g_new0 (MetaWaylandWindowConfiguration, 1);
   *configuration = (MetaWaylandWindowConfiguration) {
@@ -72,8 +81,8 @@ meta_wayland_window_configuration_new (MetaWindow          *window,
 
   if (flags & META_MOVE_RESIZE_RESIZE_ACTION ||
       is_window_size_fixed (window) ||
-      window->rect.width != width ||
-      window->rect.height != height)
+      pending_width != width ||
+      pending_height != height)
     {
       configuration->has_size = TRUE;
       configuration->width = width;
diff --git a/src/wayland/meta-window-wayland.c b/src/wayland/meta-window-wayland.c
index 31e0ef1032..b37b13efbc 100644
--- a/src/wayland/meta-window-wayland.c
+++ b/src/wayland/meta-window-wayland.c
@@ -301,6 +301,12 @@ meta_window_wayland_move_resize_internal (MetaWindow                *window,
     }
   else
     {
+      int pending_width;
+      int pending_height;
+      meta_window_wayland_get_pending_size (wl_window,
+                                            &pending_width,
+                                            &pending_height);
+
       if (window->placement.rule)
         {
           switch (window->placement.state)
@@ -315,8 +321,8 @@ meta_window_wayland_move_resize_internal (MetaWindow                *window,
                 if (flags & META_MOVE_RESIZE_PLACEMENT_CHANGED ||
                     rel_x != wl_window->last_sent_rel_x ||
                     rel_y != wl_window->last_sent_rel_y ||
-                    constrained_rect.width != window->rect.width ||
-                    constrained_rect.height != window->rect.height)
+                    constrained_rect.width != pending_width ||
+                    constrained_rect.height != pending_height)
                   {
                     MetaWaylandWindowConfiguration *configuration;
 
@@ -349,8 +355,8 @@ meta_window_wayland_move_resize_internal (MetaWindow                *window,
               break;
             }
         }
-      else if (constrained_rect.width != window->rect.width ||
-               constrained_rect.height != window->rect.height ||
+      else if (constrained_rect.width != pending_width ||
+               constrained_rect.height != pending_height ||
                flags & META_MOVE_RESIZE_STATE_CHANGED)
         {
           MetaWaylandWindowConfiguration *configuration;
@@ -1204,3 +1210,27 @@ meta_window_wayland_get_max_size (MetaWindow *window,
   scale = 1.0 / (float) meta_window_wayland_get_geometry_scale (window);
   scale_size (width, height, scale);
 }
+
+void
+meta_window_wayland_get_pending_size (MetaWindowWayland *wl_window,
+                                      int               *width,
+                                      int               *height)
+{
+  MetaWindow *window = META_WINDOW (wl_window);
+  GList *l;
+
+  for (l = wl_window->pending_configurations; l; l = l->next)
+    {
+      MetaWaylandWindowConfiguration *configuration = l->data;
+
+      if (configuration->has_size)
+        {
+          *width = configuration->width;
+          *height = configuration->height;
+          return;
+        }
+    }
+
+  *width = window->rect.width;
+  *height = window->rect.height;
+}
diff --git a/src/wayland/meta-window-wayland.h b/src/wayland/meta-window-wayland.h
index db152daaa7..c242757dfb 100644
--- a/src/wayland/meta-window-wayland.h
+++ b/src/wayland/meta-window-wayland.h
@@ -77,4 +77,8 @@ void meta_window_wayland_get_max_size (MetaWindow *window,
                                        int        *width,
                                        int        *height);
 
+void meta_window_wayland_get_pending_size (MetaWindowWayland *wl_window,
+                                           int               *width,
+                                           int               *height);
+
 #endif


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