[gnome-shell] overview: Make 3fg vertical swipes bring overview and app grid



commit cd506d45ef448d318c042b6901c4da57634c2b28
Author: Carlos Garnacho <carlosg gnome org>
Date:   Mon Jan 4 16:23:45 2021 +0100

    overview: Make 3fg vertical swipes bring overview and app grid
    
    The gesture internally manipulates the main adjustment so one swipe
    up brings up the overview, and a second swipe up brings the app
    grid. The gesture also works in the other direction to get out of
    the overview.
    
    Internally, this is delegated on the OverviewControls, so the
    adjustment is not leaked out of there. This however meant open
    coding the gesture interaction so it can be directed from
    overview.js code.
    
    Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1643>

 js/ui/overview.js         | 52 +++++++++++++++++++++++++++++++++++++++++++++++
 js/ui/overviewControls.js | 41 +++++++++++++++++++++++++++++++++++++
 2 files changed, 93 insertions(+)
---
diff --git a/js/ui/overview.js b/js/ui/overview.js
index 136b69c1d7..af3e5be2b9 100644
--- a/js/ui/overview.js
+++ b/js/ui/overview.js
@@ -14,6 +14,7 @@ const Main = imports.ui.main;
 const MessageTray = imports.ui.messageTray;
 const OverviewControls = imports.ui.overviewControls;
 const Params = imports.misc.params;
+const SwipeTracker = imports.ui.swipeTracker;
 const WindowManager = imports.ui.windowManager;
 const WorkspaceThumbnail = imports.ui.workspaceThumbnail;
 
@@ -117,6 +118,10 @@ class OverviewActor extends St.BoxLayout {
     get viewSelector() {
         return this._controls.viewSelector;
     }
+
+    get controls() {
+        return this._controls;
+    }
 });
 
 var Overview = class {
@@ -233,6 +238,15 @@ var Overview = class {
             Meta.KeyBindingFlags.IGNORE_AUTOREPEAT,
             Shell.ActionMode.NORMAL | Shell.ActionMode.OVERVIEW,
             this.toggle.bind(this));
+
+        const swipeTracker = new SwipeTracker.SwipeTracker(global.stage,
+            Shell.ActionMode.NORMAL | Shell.ActionMode.OVERVIEW,
+            { allowDrag: false, allowScroll: false });
+        swipeTracker.orientation = Clutter.Orientation.VERTICAL;
+        swipeTracker.connect('begin', this._gestureBegin.bind(this));
+        swipeTracker.connect('update', this._gestureUpdate.bind(this));
+        swipeTracker.connect('end', this._gestureEnd.bind(this));
+        this._swipeTracker = swipeTracker;
     }
 
     addSearchProvider(provider) {
@@ -365,6 +379,44 @@ var Overview = class {
         this.emit('windows-restacked', stackIndices);
     }
 
+    _gestureBegin(tracker) {
+        this._overview.controls.gestureBegin(tracker);
+    }
+
+    _gestureUpdate(tracker, progress) {
+        if (!this._shown) {
+            Meta.disable_unredirect_for_display(global.display);
+
+            this._shown = true;
+            this._visible = true;
+            this._visibleTarget = true;
+            this._animationInProgress = true;
+
+            Main.layoutManager.overviewGroup.set_child_above_sibling(
+                this._coverPane, null);
+            this._coverPane.show();
+            this.emit('showing');
+
+            Main.layoutManager.showOverview();
+            this._syncGrab();
+        }
+
+        this._overview.controls.gestureProgress(progress);
+    }
+
+    _gestureEnd(tracker, duration, endProgress) {
+        let onComplete;
+        if (endProgress === 0) {
+            this._shown = false;
+            this.emit('hiding');
+            onComplete = () => this._hideDone();
+        } else {
+            onComplete = () => this._showDone();
+        }
+
+        this._overview.controls.gestureEnd(endProgress, duration, onComplete);
+    }
+
     beginItemDrag(source) {
         this.emit('item-drag-begin', source);
         this._inItemDrag = true;
diff --git a/js/ui/overviewControls.js b/js/ui/overviewControls.js
index f43d8e236e..14f247b091 100644
--- a/js/ui/overviewControls.js
+++ b/js/ui/overviewControls.js
@@ -583,6 +583,47 @@ class ControlsManager extends St.Widget {
         return this.layoutManager.getWorkspacesBoxForState(state);
     }
 
+    gestureBegin(tracker) {
+        const baseDistance = global.screen_height;
+        const progress = this._stateAdjustment.value;
+        const points = [
+            ControlsState.HIDDEN,
+            ControlsState.WINDOW_PICKER,
+            ControlsState.APP_GRID,
+        ];
+
+        const transition = this._stateAdjustment.get_transition('value');
+        const cancelProgress = transition
+            ? transition.get_interval().peek_final_value()
+            : Math.round(progress);
+
+        tracker.confirmSwipe(baseDistance, points, progress, cancelProgress);
+        this._workspacesDisplay.prepareToEnterOverview();
+        this._searchController.prepareToEnterOverview();
+        this._stateAdjustment.gestureInProgress = true;
+    }
+
+    gestureProgress(progress) {
+        this._stateAdjustment.value = progress;
+    }
+
+    gestureEnd(target, duration, onComplete) {
+        if (target === ControlsState.HIDDEN)
+            this._workspacesDisplay.prepareToLeaveOverview();
+
+        this.dash.showAppsButton.checked =
+            target === ControlsState.APP_GRID;
+
+        this._stateAdjustment.remove_transition('value');
+        this._stateAdjustment.ease(target, {
+            duration,
+            mode: Clutter.AnimationMode.EASE_OUT_QUAD,
+            onComplete,
+        });
+
+        this._stateAdjustment.gestureInProgress = false;
+    }
+
     get searchEntry() {
         return this._searchEntry;
     }


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