[gnome-shell/wip/exalm/gestures] proper distance and extents



commit 983d3402f903eddec7308c0ccbdcdc088065e364
Author: Alexander Mikhaylenko <exalm7659 gmail com>
Date:   Sat Jun 29 16:18:52 2019 +0500

    proper distance and extents

 js/ui/swipeTracker.js   | 91 +++++++++++++++++++++++++++++--------------------
 js/ui/windowManager.js  | 34 ++++++++++++------
 js/ui/workspacesView.js |  5 +--
 3 files changed, 81 insertions(+), 49 deletions(-)
---
diff --git a/js/ui/swipeTracker.js b/js/ui/swipeTracker.js
index 64ca02307..6e9ff7137 100644
--- a/js/ui/swipeTracker.js
+++ b/js/ui/swipeTracker.js
@@ -25,7 +25,6 @@ function clamp(value, min, max) {
     return Math.max(min, Math.min(max, value));
 }
 
-// TODO: support scrolling
 // TODO: support horizontal
 
 var TouchpadSwipeGesture = class TouchpadSwipeGesture {
@@ -75,6 +74,7 @@ var TouchSwipeGesture = GObject.registerClass({
         this.set_trigger_edge(trigger_edge);
 
         this._shouldSkip = shouldSkip;
+        this._distance = global.screen_height;
     }
 
     vfunc_gesture_begin(actor, point) {
@@ -92,7 +92,7 @@ var TouchSwipeGesture = GObject.registerClass({
         let [distance, dx, dy] = this.get_motion_delta(0);
         let time = this.get_last_event(point).get_time();
 
-        this.emit('update', time, -dy / (global.screen_height - Main.panel.height)); // TODO: the height 
isn't always equal to the actor height
+        this.emit('update', time, -dy / this._distance);
     }
 
     vfunc_gesture_end(actor, point) {
@@ -106,6 +106,10 @@ var TouchSwipeGesture = GObject.registerClass({
 
         this.emit('cancel', time);
     }
+
+    setDistance(distance) {
+        this._distance = distance;
+    }
 });
 
 var ScrollGesture = class ScrollGesture {
@@ -148,7 +152,17 @@ Signals.addSignalMethods(ScrollGesture.prototype);
 // begin(tracker)
 //   The handler should check whether a deceleration animation is currently
 //   running. If it is, it should stop the animation (without resetting progress)
-//   and call tracker.continueFrom(progress). Otherwise it should initialize the gesture.
+//   and call tracker.continueFrom(progress). Otherwise it should initialize the gesture
+//   and call tracker.startSwipe(canSwipeBack, canSwipeForward, distance, backExtent, forwardExtent).
+//   The parameters are:
+//    * canSwipeBack: whether the tracker should allow to swipe back;
+//    * canSwipeForward: whether the tracker should allow to swipe forward;
+//    * distance: the page size
+//    * backExtent: can be used to make "back" page longer. Normally this is 0.
+//    * forwardExtent: can be used to make "forward" page longer. Normally this is 0
+//   Extents should be used for extending one or both page in some cases (such as switching to a
+//   workspace with a fullscreen window). Speed of touchpad swipe and scrolling only depend on
+//   distance, so the speed is consistent with or without extents.
 //
 // update(tracker, progress)
 //   The handler should set the progress to the given value.
@@ -164,9 +178,6 @@ Signals.addSignalMethods(ScrollGesture.prototype);
 //
 // ======================================================================================
 //
-// 'can_swipe_back' and 'can_swipe_forward'
-//   These properties can be used to disable swiping back from the first page or forward from the last page.
-//
 // 'enabled'
 //   This property can be used to enable or disable the swipe tracker temporarily.
 
@@ -177,8 +188,11 @@ var SwipeTracker = class {
 
         this._reset();
 
-        this._can_swipe_back = true;
-        this._can_swipe_forward = true;
+        this._canSwipeBack = true;
+        this._canSwipeForward = true;
+        this._distance = 0;
+        this._backExtent = 0;
+        this._forwardExtent = 0;
 
         let shouldSkip = () =>
             ((this._allowedModes & Main.actionMode) == 0 || !this._enabled);
@@ -193,6 +207,7 @@ var SwipeTracker = class {
         touchGesture.connect('end', this._endGesture.bind(this));
         touchGesture.connect('cancel', this._cancelGesture.bind(this));
         global.stage.add_action(touchGesture);
+        this._touchGesture = touchGesture;
 
         if (allowDrag) {
             let dragGesture = new TouchSwipeGesture(shouldSkip, 1, Clutter.TriggerEdge.AFTER);
@@ -204,7 +219,9 @@ var SwipeTracker = class {
             } catch (e) {
                 actor.addAction(dragGesture); // FIXME: wtf is this
             }
-        }
+            this._dragGesture = dragGesture;
+        } else
+            this._dragGesture = null;
 
         if (allowScroll) {
             let scrollGesture = new ScrollGesture(actor, shouldSkip);
@@ -226,26 +243,6 @@ var SwipeTracker = class {
             this._cancel();
     }
 
-    get can_swipe_back() {
-        return this._can_swipe_back;
-    }
-
-    set can_swipe_back(can_swipe_back) {
-        this._can_swipe_back = can_swipe_back;
-        if (!can_swipe_back && this._progress > 0)
-            this._cancel();
-    }
-
-    get can_swipe_forward() {
-        return this._can_swipe_forward;
-    }
-
-    set can_swipe_forward(can_swipe_forward) {
-        this._can_swipe_forward = can_swipe_forward;
-        if (!can_swipe_forward && this._progress < 0)
-            this._cancel();
-    }
-
     _reset() {
         this._state = State.NONE;
 
@@ -273,6 +270,10 @@ var SwipeTracker = class {
         this._state = State.SCROLLING;
     }
 
+//    _updateGestureWithClamp(gesture, time, delta) {
+//        this._updateGesture(gesture, time, delta / this._distance);
+//    }
+
     _updateGesture(gesture, time, delta) {
         if ((this._allowedModes & Main.actionMode) == 0 || !this._enabled)
             return;
@@ -285,16 +286,18 @@ var SwipeTracker = class {
         if (time != this._prevTime)
             this._velocity = delta / (time - this._prevTime);
 
-        if (this._progress > 0 && !this.can_swipe_back)
+        if (this._progress > 0 && !this._canSwipeBack)
             this._progress = 0;
-        if (this._progress < 0 && !this.can_swipe_forward)
+        if (this._progress < 0 && !this._canSwipeForward)
             this._progress = 0;
 
-        let maxProgress = (this._progress > 0) ? 1 : 0;
-        let minProgress = (this._progress < 0) ? -1 : 0;
+        let maxProgress = (this._progress > 0) ? (1 + this._backExtent / this._distance) : 0;
+        let minProgress = (this._progress < 0) ? -(1 + this._forwardExtent / this._distance) : 0;
         this._progress = clamp(this._progress, minProgress, maxProgress);
 
-        this.emit('update', this._progress);
+        // Clamp progress to [0,1]
+        let progress = this._progress / (1 + (this._progress > 0 ? this._backExtent : this._forwardExtent) / 
this._distance);
+        this.emit('update', progress);
 
         this._prevTime = time;
     }
@@ -306,10 +309,10 @@ var SwipeTracker = class {
         if (this._progress == 0)
             return true;
 
-        if (this._progress > 0 && !this.can_swipe_back)
+        if (this._progress > 0 && !this._canSwipeBack)
             return true;
 
-        if (this._progress < 0 && !this.can_swipe_forward)
+        if (this._progress < 0 && !this._canSwipeForward)
             return true;
 
         if (Math.abs(this._velocity) < VELOCITY_THRESHOLD)
@@ -331,7 +334,7 @@ var SwipeTracker = class {
 
         let endProgress = 0;
         if (!cancelled)
-            endProgress = (this._progress > 0) ? 1 : -1;
+            endProgress = (this._progress > 0) ? (1 + this._backExtent / this._distance) : -(1 + 
this._forwardExtent / this._distance);
 
         let velocity = ANIMATION_BASE_VELOCITY;
         if ((endProgress - this._progress) * this._velocity > 0)
@@ -355,6 +358,20 @@ var SwipeTracker = class {
         this._endGesture(gesture, time);
     }
 
+    startSwipe(canSwipeBack, canSwipeForward, distance, backExtent, forwardExtent) {
+        this._canSwipeBack = canSwipeBack;
+        this._canSwipeForward = canSwipeForward;
+        this._distance = distance;
+        this._backExtent = backExtent;
+        this._forwardExtent = forwardExtent;
+
+        this._touchGesture.setDistance(distance);
+        if (this._dragGesture)
+            this._dragGesture.setDistance(distance);
+
+        log("start", canSwipeBack, canSwipeForward, distance, backExtent, forwardExtent);
+    }
+
     continueFrom(progress) {
         this._progress = progress;
         this._velocity = 0;
diff --git a/js/ui/windowManager.js b/js/ui/windowManager.js
index be6090fcd..e3e4fcc47 100644
--- a/js/ui/windowManager.js
+++ b/js/ui/windowManager.js
@@ -986,8 +986,18 @@ var WindowManager = class {
         this._prepareWorkspaceSwitch(activeWorkspace.index(), -1);
 
         // TODO: horizontal
-        tracker.can_swipe_forward = this._switchData.surroundings[Meta.MotionDirection.UP];
-        tracker.can_swipe_back = this._switchData.surroundings[Meta.MotionDirection.DOWN];
+
+        let baseDistance = global.screen_height - Main.panel.height;
+
+        let direction = Meta.MotionDirection.DOWN;
+        let backInfo = this._switchData.surroundings[direction];
+        let backExtent = backInfo ? (backInfo.yDest - baseDistance) : 0;
+
+        direction = Meta.MotionDirection.UP;
+        let forwardInfo = this._switchData.surroundings[direction];
+        let forwardExtent = forwardInfo ? (-forwardInfo.yDest - baseDistance) : 0;
+
+        tracker.startSwipe((backInfo != null), (forwardInfo != null), baseDistance, backExtent, 
forwardExtent);
     }
 
     _switchWorkspaceUpdate(tracker, progress) {
@@ -995,7 +1005,12 @@ var WindowManager = class {
             return;
 
         this._switchData.progress = progress;
-        this._switchData.container.set_position(0, Math.round(-progress * (global.screen_height - 
Main.panel.height)));
+
+        let direction = (progress > 0) ? Meta.MotionDirection.DOWN : Meta.MotionDirection.UP;
+        let info = this._switchData.surroundings[direction];
+        let distance = info ? Math.abs(info.yDest) : 0;
+
+        this._switchData.container.set_position(0, Math.round(-progress * distance));
     }
 
     _switchWorkspaceEnd(tracker, duration, isBack) {
@@ -1049,11 +1064,8 @@ var WindowManager = class {
     _switchWorkspaceAnimate(direction, duration, newWs) {
         let switchData = this._switchData;
 
-        let oldWs = global.workspace_manager.get_active_workspace();
-        let [xDest, yDest] = this._getPositionForDirection(direction, oldWs, newWs);
-
-        xDest = -xDest;
-        yDest = -yDest;
+        let xDest = -this._switchData.surroundings[direction].xDest;
+        let yDest = -this._switchData.surroundings[direction].yDest;
 
         Tweener.addTween(switchData,
                          { progress: direction == Meta.MotionDirection.DOWN ? 1 : -1,
@@ -1824,13 +1836,15 @@ var WindowManager = class {
                 continue;
             }
 
+            let [x, y] = this._getPositionForDirection(dir, curWs, ws);
             let info = { index: ws.index(),
-                         actor: new Clutter.Actor() };
+                         actor: new Clutter.Actor(),
+                         xDest: x,
+                         yDest: y };
             switchData.surroundings[dir] = info;
             switchData.container.add_actor(info.actor);
             info.actor.raise_top();
 
-            let [x, y] = this._getPositionForDirection(dir, curWs, ws);
             info.actor.set_position(x, y);
         }
 
diff --git a/js/ui/workspacesView.js b/js/ui/workspacesView.js
index 530581e3e..49a4b1624 100644
--- a/js/ui/workspacesView.js
+++ b/js/ui/workspacesView.js
@@ -472,8 +472,9 @@ var WorkspacesDisplay = class {
         let workspaceManager = global.workspace_manager;
         let activeWs = workspaceManager.get_active_workspace();
 
-        tracker.can_swipe_forward = (activeWs.get_neighbor(Meta.MotionDirection.UP) != activeWs);
-        tracker.can_swipe_back = (activeWs.get_neighbor(Meta.MotionDirection.DOWN) != activeWs);
+        let canSwipeBack = (activeWs.get_neighbor(Meta.MotionDirection.DOWN) != activeWs);
+        let canSwipeForward = (activeWs.get_neighbor(Meta.MotionDirection.UP) != activeWs);
+        tracker.startSwipe(canSwipeBack, canSwipeForward, this.actor.height, 0, 0);
 
         this._gestureActive = true;
     }


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