[gnome-shell/wip/carlosg/interactive-workspace-switching: 3/4] windowManager: Refactor workspace switching animations



commit e5c95b910d24b7a149c0a62ddbe8db7aa7643196
Author: Carlos Garnacho <carlosg gnome org>
Date:   Fri Jul 13 15:04:02 2018 +0200

    windowManager: Refactor workspace switching animations
    
    Besides the separation into distinct functions, the stored data has
    been made able to generically store windows from all surrounding
    workspaces. All while keeping a special mode to animate between two
    workspaces (The usual till now), this is the only mode exercised so
    far.
    
    In order to ease animations, all window groups are now children of
    a common container, which is then animated.

 js/ui/windowManager.js | 193 +++++++++++++++++++++++++++++++------------------
 1 file changed, 121 insertions(+), 72 deletions(-)
---
diff --git a/js/ui/windowManager.js b/js/ui/windowManager.js
index 02d5f9029..18f393dda 100644
--- a/js/ui/windowManager.js
+++ b/js/ui/windowManager.js
@@ -1017,10 +1017,10 @@ var WindowManager = new Lang.Class({
     },
 
     _actionSwitchWorkspace(action, direction) {
-            let workspaceManager = global.workspace_manager;
-            let activeWorkspace = workspaceManager.get_active_workspace();
-            let newWs = activeWorkspace.get_neighbor(direction);
-            this.actionMoveWorkspace(newWs);
+        let workspaceManager = global.workspace_manager;
+        let activeWorkspace = workspaceManager.get_active_workspace();
+        let newWs = activeWorkspace.get_neighbor(direction);
+        this.actionMoveWorkspace(newWs);
     },
 
     _lookupIndex(windows, metaWindow) {
@@ -1700,63 +1700,96 @@ var WindowManager = new Lang.Class({
         if (this._switchData == null)
             return;
 
-        // Update stacking of windows in inGroup (aka the workspace we are
-        // switching to). Windows in outGroup are about to be hidden anyway,
-        // so we just ignore them here.
         let windows = global.get_window_actors();
-        let sibling = null;
+        let lastCurSibling = null;
+        let lastDirSibling = [];
         for (let i = 0; i < windows.length; i++) {
-            if (windows[i].get_parent() != this._switchData.inGroup)
-                continue;
+            if (windows[i].get_parent() == this._switchData.curGroup) {
+                this._switchData.curGroup.set_child_above_sibling(windows[i], lastCurSibling);
+                lastCurSibling = windows[i];
+            } else {
+                for (let dir of Object.values(Meta.MotionDirection)) {
+                    let info = this._switchData.surroundings[dir];
+                    if (!info || windows[i].get_parent() != info.actor)
+                        continue;
 
-            this._switchData.inGroup.set_child_above_sibling(windows[i], sibling);
-            sibling = windows[i];
-        }
-    },
+                    let sibling = lastDirSibling[dir];
+                    if (sibling == undefined)
+                        sibling = null;
 
-    _switchWorkspace(shellwm, from, to, direction) {
-        if (!Main.sessionMode.hasWorkspaces || !this._shouldAnimate()) {
-            shellwm.completed_switch_workspace();
-            return;
+                    info.actor.set_child_above_sibling(windows[i], sibling);
+                    lastDirSibling[dir] = windows[i];
+                    break;
+                }
+            }
         }
+    },
 
-        let windows = global.get_window_actors();
-
-        /* @direction is the direction that the "camera" moves, so the
-         * screen contents have to move one screen's worth in the
-         * opposite direction.
-         */
+    _getPositionForDirection(direction) {
         let xDest = 0, yDest = 0;
 
         if (direction == Meta.MotionDirection.UP ||
             direction == Meta.MotionDirection.UP_LEFT ||
             direction == Meta.MotionDirection.UP_RIGHT)
-                yDest = global.screen_height - Main.panel.actor.height;
+            yDest = -global.screen_height + Main.panel.actor.height;
         else if (direction == Meta.MotionDirection.DOWN ||
             direction == Meta.MotionDirection.DOWN_LEFT ||
             direction == Meta.MotionDirection.DOWN_RIGHT)
-                yDest = -global.screen_height + Main.panel.actor.height;
+            yDest = global.screen_height - Main.panel.actor.height;
 
         if (direction == Meta.MotionDirection.LEFT ||
             direction == Meta.MotionDirection.UP_LEFT ||
             direction == Meta.MotionDirection.DOWN_LEFT)
-                xDest = global.screen_width;
+            xDest = -global.screen_width;
         else if (direction == Meta.MotionDirection.RIGHT ||
                  direction == Meta.MotionDirection.UP_RIGHT ||
                  direction == Meta.MotionDirection.DOWN_RIGHT)
-                xDest = -global.screen_width;
+            xDest = global.screen_width;
+
+        return [xDest, yDest];
+    },
 
+    _prepareWorkspaceSwitch(from, to, direction) {
+        if (this._switchData)
+            return;
+
+        let wgroup = global.window_group;
+        let windows = global.get_window_actors();
         let switchData = {};
+
         this._switchData = switchData;
-        switchData.inGroup = new Clutter.Actor();
-        switchData.outGroup = new Clutter.Actor();
+        switchData.curGroup = new Clutter.Actor();
         switchData.movingWindowBin = new Clutter.Actor();
         switchData.windows = [];
+        switchData.surroundings = {};
+
+        switchData.container = new Clutter.Actor();
+        switchData.container.add_actor(switchData.curGroup);
 
-        let wgroup = global.window_group;
-        wgroup.add_actor(switchData.inGroup);
-        wgroup.add_actor(switchData.outGroup);
         wgroup.add_actor(switchData.movingWindowBin);
+        wgroup.add_actor(switchData.container);
+
+        let workspaceManager = global.workspace_manager;
+        let curWs = workspaceManager.get_workspace_by_index (from);
+
+        for (let dir of Object.values(Meta.MotionDirection)) {
+            let ws = curWs.get_neighbor(dir);
+            if (ws == curWs || (to >= 0 && ws.index() != to)) {
+                switchData.surroundings[dir] = null;
+                continue;
+            }
+
+            let info = { index: ws.index(),
+                         actor: new Clutter.Actor() };
+            switchData.surroundings[dir] = info;
+            switchData.container.add_actor(info.actor);
+            info.actor.raise_top();
+
+            let [x, y] = this._getPositionForDirection(dir);
+            info.actor.set_position(x, y);
+        }
+
+        switchData.movingWindowBin.raise_top();
 
         for (let i = 0; i < windows.length; i++) {
             let actor = windows[i];
@@ -1777,20 +1810,65 @@ var WindowManager = new Lang.Class({
                 actor.reparent(switchData.movingWindowBin);
             } else if (window.get_workspace().index() == from) {
                 switchData.windows.push(record);
-                actor.reparent(switchData.outGroup);
-            } else if (window.get_workspace().index() == to) {
-                switchData.windows.push(record);
-                actor.reparent(switchData.inGroup);
-                actor.show();
+                actor.reparent(switchData.curGroup);
+            } else {
+                let visible = false;
+                for (let dir of Object.values(Meta.MotionDirection)) {
+                    let info = switchData.surroundings[dir];
+
+                    if (!info || info.index != window.get_workspace().index())
+                        continue;
+
+                    switchData.windows.push(record);
+                    actor.reparent(info.actor);
+                    visible = true;
+                    break;
+                }
+
+                actor.visible = visible;
             }
         }
+    },
 
-        switchData.inGroup.set_position(-xDest, -yDest);
-        switchData.inGroup.raise_top();
+    _finishWorkspaceSwitch(switchData) {
+        this._switchData = null;
 
-        switchData.movingWindowBin.raise_top();
+        for (let i = 0; i < switchData.windows.length; i++) {
+            let w = switchData.windows[i];
+            if (w.window.is_destroyed()) // Window gone
+                continue;
+
+            w.window.reparent(w.parent);
+
+            if (w.window.get_meta_window().get_workspace() !=
+                global.workspace_manager.get_active_workspace())
+                w.window.hide();
+        }
+        Tweener.removeTweens(switchData.container);
+        switchData.container.destroy();
+        switchData.movingWindowBin.destroy();
+
+        this._movingWindow = null;
+    },
+
+    _switchWorkspace(shellwm, from, to, direction) {
+        if (!Main.sessionMode.hasWorkspaces || !this._shouldAnimate()) {
+            shellwm.completed_switch_workspace();
+            return;
+        }
 
-        Tweener.addTween(switchData.outGroup,
+        let [xDest, yDest] = this._getPositionForDirection(direction);
+
+        /* @direction is the direction that the "camera" moves, so the
+         * screen contents have to move one screen's worth in the
+         * opposite direction.
+         */
+        xDest = -xDest;
+        yDest = -yDest;
+
+        this._prepareWorkspaceSwitch(from, to, direction);
+
+        Tweener.addTween(this._switchData.container,
                          { x: xDest,
                            y: yDest,
                            time: WINDOW_ANIMATION_TIME,
@@ -1799,39 +1877,10 @@ var WindowManager = new Lang.Class({
                            onCompleteScope: this,
                            onCompleteParams: [shellwm]
                          });
-        Tweener.addTween(switchData.inGroup,
-                         { x: 0,
-                           y: 0,
-                           time: WINDOW_ANIMATION_TIME,
-                           transition: 'easeOutQuad'
-                         });
     },
 
     _switchWorkspaceDone(shellwm) {
-        let switchData = this._switchData;
-        if (!switchData)
-            return;
-        this._switchData = null;
-
-        for (let i = 0; i < switchData.windows.length; i++) {
-                let w = switchData.windows[i];
-                if (w.window.is_destroyed()) // Window gone
-                    continue;
-                if (w.window.get_parent() == switchData.outGroup) {
-                    w.window.reparent(w.parent);
-                    w.window.hide();
-                } else
-                    w.window.reparent(w.parent);
-        }
-        Tweener.removeTweens(switchData.inGroup);
-        Tweener.removeTweens(switchData.outGroup);
-        switchData.inGroup.destroy();
-        switchData.outGroup.destroy();
-        switchData.movingWindowBin.destroy();
-
-        if (this._movingWindow)
-            this._movingWindow = null;
-
+        this._finishWorkspaceSwitch(this._switchData);
         shellwm.completed_switch_workspace();
     },
 


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