[mutter/wip/ssd-black-borders-fix: 17/22] window: track when resize is pending via new flag



commit db1adab828c8bac2909e1f4ca9a626b0baa6fc9b
Author: Ray Strode <rstrode redhat com>
Date:   Thu Mar 15 13:09:23 2018 -0400

    window: track when resize is pending via new flag
    
    For Xwayland clients, resizing is an asynchronous operation.  First, the
    window manager part of mutter resizes the frame and client window, then
    Xwayland waits for damage from the client, and commits a new surface to
    the display server part of mutter.
    
    In order to prevent flicker, we need to know when an initiated resize
    operation has fully come out the other end of that multi-step process as
    a new surface.
    
    This commit lays the plumbing work for preventing the aforementioned
    flicker problem, by adding a new resize_pending flag (and associated
    accessors), and setting the flag appropriately based on when a resize
    is started and subsequently when a new surface is attached.

 src/compositor/meta-surface-actor-wayland.c | 13 +++++++++++++
 src/compositor/meta-surface-actor.c         |  4 ++--
 src/compositor/meta-surface-actor.h         |  2 ++
 src/core/window-private.h                   |  6 ++++++
 src/core/window.c                           | 13 +++++++++++++
 src/wayland/meta-wayland-surface.c          |  1 +
 src/wayland/meta-window-xwayland.c          | 15 +++++++++++++++
 7 files changed, 52 insertions(+), 2 deletions(-)
---
diff --git a/src/compositor/meta-surface-actor-wayland.c b/src/compositor/meta-surface-actor-wayland.c
index c70e44461..887b848bb 100644
--- a/src/compositor/meta-surface-actor-wayland.c
+++ b/src/compositor/meta-surface-actor-wayland.c
@@ -125,6 +125,17 @@ meta_surface_actor_wayland_get_window (MetaSurfaceActor *actor)
   return surface->window;
 }
 
+static void
+meta_surface_actor_wayland_size_changed (MetaSurfaceActor *actor)
+{
+  MetaWindow *window;
+
+  window = meta_surface_actor_wayland_get_window (actor);
+
+  if (window)
+    meta_window_set_resize_pending (window, FALSE);
+}
+
 static void
 meta_surface_actor_wayland_get_preferred_width  (ClutterActor *actor,
                                                  gfloat        for_height,
@@ -237,6 +248,8 @@ meta_surface_actor_wayland_class_init (MetaSurfaceActorWaylandClass *klass)
   surface_actor_class->set_frozen = meta_surface_actor_wayland_set_frozen;
   surface_actor_class->get_window = meta_surface_actor_wayland_get_window;
 
+  surface_actor_class->size_changed = meta_surface_actor_wayland_size_changed;
+
   object_class->dispose = meta_surface_actor_wayland_dispose;
 }
 
diff --git a/src/compositor/meta-surface-actor.c b/src/compositor/meta-surface-actor.c
index 64491ac8c..156a9cf89 100644
--- a/src/compositor/meta-surface-actor.c
+++ b/src/compositor/meta-surface-actor.c
@@ -135,8 +135,8 @@ meta_surface_actor_class_init (MetaSurfaceActorClass *klass)
 
   signals[SIZE_CHANGED] = g_signal_new ("size-changed",
                                         G_TYPE_FROM_CLASS (object_class),
-                                        G_SIGNAL_RUN_LAST,
-                                        0,
+                                        G_SIGNAL_RUN_FIRST,
+                                        G_STRUCT_OFFSET (MetaSurfaceActorClass, size_changed),
                                         NULL, NULL, NULL,
                                         G_TYPE_NONE, 0);
 
diff --git a/src/compositor/meta-surface-actor.h b/src/compositor/meta-surface-actor.h
index f60cbb64f..ef307f0fc 100644
--- a/src/compositor/meta-surface-actor.h
+++ b/src/compositor/meta-surface-actor.h
@@ -40,6 +40,8 @@ struct _MetaSurfaceActorClass
                                   gboolean          is_frozen);
 
   MetaWindow *(* get_window)      (MetaSurfaceActor *actor);
+
+  void     (* size_changed)      (MetaSurfaceActor *actor);
 };
 
 struct _MetaSurfaceActor
diff --git a/src/core/window-private.h b/src/core/window-private.h
index 9545dfc3c..afaa499e5 100644
--- a/src/core/window-private.h
+++ b/src/core/window-private.h
@@ -407,6 +407,9 @@ struct _MetaWindow
   /* whether or not the window is from a program running on another machine */
   guint is_remote : 1;
 
+  /* if TRUE, the X server hasn't yet committed a new buffer following resize of the frame/client window */
+  guint resize_pending : 1;
+
   /* if non-NULL, the bounds of the window frame */
   cairo_region_t *frame_bounds;
 
@@ -781,6 +784,9 @@ void meta_window_move_resize_internal (MetaWindow          *window,
                                        MetaMoveResizeFlags  flags,
                                        int                  gravity,
                                        MetaRectangle        frame_rect);
+void meta_window_set_resize_pending (MetaWindow *window,
+                                     gboolean    is_resize_pending);
+gboolean meta_window_resize_is_pending (MetaWindow  *window);
 
 void meta_window_grab_op_began (MetaWindow *window, MetaGrabOp op);
 void meta_window_grab_op_ended (MetaWindow *window, MetaGrabOp op);
diff --git a/src/core/window.c b/src/core/window.c
index 86f9d69b1..34f48712f 100644
--- a/src/core/window.c
+++ b/src/core/window.c
@@ -6311,6 +6311,19 @@ meta_window_update_resize (MetaWindow *window,
   update_resize (window, snap, x, y, force);
 }
 
+void
+meta_window_set_resize_pending (MetaWindow *window,
+                                gboolean    is_resize_pending)
+{
+  window->resize_pending = is_resize_pending;
+}
+
+gboolean
+meta_window_resize_is_pending (MetaWindow  *window)
+{
+  return window->resize_pending;
+}
+
 static void
 end_grab_op (MetaWindow *window,
              const ClutterEvent *event)
diff --git a/src/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c
index 159e6f86e..3038beb86 100644
--- a/src/wayland/meta-wayland-surface.c
+++ b/src/wayland/meta-wayland-surface.c
@@ -1102,6 +1102,7 @@ meta_wayland_surface_set_window (MetaWaylandSurface *surface,
                                "position-changed",
                                G_CALLBACK (window_position_changed),
                                surface, 0);
+      meta_window_set_resize_pending (window, FALSE);
     }
 }
 
diff --git a/src/wayland/meta-window-xwayland.c b/src/wayland/meta-window-xwayland.c
index 6f073893a..08d0649da 100644
--- a/src/wayland/meta-window-xwayland.c
+++ b/src/wayland/meta-window-xwayland.c
@@ -71,6 +71,20 @@ meta_window_xwayland_shortcuts_inhibited (MetaWindow         *window,
   return meta_wayland_compositor_is_shortcuts_inhibited (compositor, source);
 }
 
+static void
+meta_window_xwayland_move_resize_internal (MetaWindow                *window,
+                                           int                        gravity,
+                                           MetaRectangle              unconstrained_rect,
+                                           MetaRectangle              constrained_rect,
+                                           MetaMoveResizeFlags        flags,
+                                           MetaMoveResizeResultFlags *result)
+{
+  META_WINDOW_CLASS (meta_window_xwayland_parent_class)->move_resize_internal (window, gravity, 
unconstrained_rect, constrained_rect, flags, result);
+
+  if (*result & META_MOVE_RESIZE_RESULT_RESIZED)
+    meta_window_set_resize_pending (window, TRUE);
+}
+
 static void
 meta_window_xwayland_get_property (GObject    *object,
                                    guint       prop_id,
@@ -117,6 +131,7 @@ meta_window_xwayland_class_init (MetaWindowXwaylandClass *klass)
 
   window_class->force_restore_shortcuts = meta_window_xwayland_force_restore_shortcuts;
   window_class->shortcuts_inhibited = meta_window_xwayland_shortcuts_inhibited;
+  window_class->move_resize_internal = meta_window_xwayland_move_resize_internal;
 
   gobject_class->get_property = meta_window_xwayland_get_property;
   gobject_class->set_property = meta_window_xwayland_set_property;


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