[gnome-shell] windowManager: Use new mutter API to freeze window actors ourself



commit 4a6f550acb3f3c0672cd72f64e0639d9db2f3c94
Author: Jonas Dreßler <verdre v0yd nl>
Date:   Tue May 12 13:50:05 2020 +0200

    windowManager: Use new mutter API to freeze window actors ourself
    
    We're currently using the hack of telling mutter that our effect is
    completed (even though it isn't) in order to unfreeze updates of the
    window actor.
    
    This causes a bug with detecting the wl_outputs a window is
    visible on, because the MetaWindowActor emits its "effects-completed"
    signal too early, making Mutter update the wl_outputs while we're doing
    the animation.
    
    Now since meta_wayland_actor_surface_is_on_logical_monitor() uses the
    transformed position and size of the MetaSurfaceActor and is being
    called right after we setup the animation (but before it actually
    starts, that happens at the next paint cycle) it will use a "very wrong"
    rectangle: The transformation has been set to move the actor back to its
    old position, and while we did already unfreeze updates and called
    clutter_actor_set_position() in meta_window_actor_sync_actor_geometry(),
    the actual allocation is not updated yet; this makes
    clutter_actor_get_transformed_position() return a position including in
    the new transformation, but not including the new allocation, and the
    rectangle ends up being moved to the next monitor or completely out of
    the stage.
    
    To fix this issue properly, we need to decouple unfreezing actor updates
    from emitting the "effects-completed" signal, which is now possible with
    the new meta_window_actor_freeze() and meta_window_actor_thaw() APIs. So
    use those new methods to freeze and thaw actor updates ourselves and
    make sure to call shellwm.completed_size_change() only after the
    animation has finished.
    
    Mutter MR: https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1250
    
    Fixes https://gitlab.gnome.org/GNOME/mutter/-/issues/513
    
    https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1251

 js/ui/windowManager.js | 18 ++++++++++++++----
 1 file changed, 14 insertions(+), 4 deletions(-)
---
diff --git a/js/ui/windowManager.js b/js/ui/windowManager.js
index 61d4f96f14..97601eee47 100644
--- a/js/ui/windowManager.js
+++ b/js/ui/windowManager.js
@@ -1299,6 +1299,8 @@ var WindowManager = class {
         actorClone.set_position(oldFrameRect.x, oldFrameRect.y);
         actorClone.set_size(oldFrameRect.width, oldFrameRect.height);
 
+        actor.freeze();
+
         if (this._clearAnimationInfo(actor))
             this._shellwm.completed_size_change(actor);
 
@@ -1307,9 +1309,12 @@ var WindowManager = class {
         });
 
         this._resizePending.add(actor);
-        actor.__animationInfo = { clone: actorClone,
-                                  oldRect: oldFrameRect,
-                                  destroyId };
+        actor.__animationInfo = {
+            clone: actorClone,
+            oldRect: oldFrameRect,
+            frozen: true,
+            destroyId,
+        };
     }
 
     _sizeChangedWindow(shellwm, actor) {
@@ -1362,13 +1367,17 @@ var WindowManager = class {
         // Now unfreeze actor updates, to get it to the new size.
         // It's important that we don't wait until the animation is completed to
         // do this, otherwise our scale will be applied to the old texture size.
-        shellwm.completed_size_change(actor);
+        actor.thaw();
+        actor.__animationInfo.frozen = false;
     }
 
     _clearAnimationInfo(actor) {
         if (actor.__animationInfo) {
             actor.__animationInfo.clone.destroy();
             actor.disconnect(actor.__animationInfo.destroyId);
+            if (actor.__animationInfo.frozen)
+                actor.thaw();
+
             delete actor.__animationInfo;
             return true;
         }
@@ -1383,6 +1392,7 @@ var WindowManager = class {
             actor.translation_x = 0;
             actor.translation_y = 0;
             this._clearAnimationInfo(actor);
+            this._shellwm.completed_size_change(actor);
         }
 
         if (this._resizePending.delete(actor)) {


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