[gnome-shell/wip/exalm/gestures: 15/17] workspacesView: Use SwipeTracker
- From: Alexander Mikhaylenko <alexm src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-shell/wip/exalm/gestures: 15/17] workspacesView: Use SwipeTracker
- Date: Sun, 30 Jun 2019 13:56:26 +0000 (UTC)
commit 5b37c4fbd63397b7c60483828586010f5d444ec2
Author: Alexander Mikhaylenko <exalm7659 gmail com>
Date: Sun Jun 30 17:15:18 2019 +0500
workspacesView: Use SwipeTracker
js/ui/overviewControls.js | 2 +-
js/ui/viewSelector.js | 4 +-
js/ui/workspaceThumbnail.js | 45 ++++++++--
js/ui/workspacesView.js | 207 +++++++++++++++++++++++---------------------
4 files changed, 151 insertions(+), 107 deletions(-)
---
diff --git a/js/ui/overviewControls.js b/js/ui/overviewControls.js
index f10ba7306..b93c34a7e 100644
--- a/js/ui/overviewControls.js
+++ b/js/ui/overviewControls.js
@@ -400,7 +400,7 @@ var ControlsManager = class {
this._thumbnailsBox = new WorkspaceThumbnail.ThumbnailsBox();
this._thumbnailsSlider = new ThumbnailsSlider(this._thumbnailsBox);
- this.viewSelector = new ViewSelector.ViewSelector(searchEntry,
+ this.viewSelector = new ViewSelector.ViewSelector(searchEntry, this._thumbnailsBox,
this.dash.showAppsButton);
this.viewSelector.connect('page-changed', this._setVisibility.bind(this));
this.viewSelector.connect('page-empty', this._onPageEmpty.bind(this));
diff --git a/js/ui/viewSelector.js b/js/ui/viewSelector.js
index ba32163f0..9119af793 100644
--- a/js/ui/viewSelector.js
+++ b/js/ui/viewSelector.js
@@ -120,7 +120,7 @@ var ShowOverviewAction = GObject.registerClass({
});
var ViewSelector = class {
- constructor(searchEntry, showAppsButton) {
+ constructor(searchEntry, thumbnailsBox, showAppsButton) {
this.actor = new Shell.Stack({ name: 'viewSelector' });
this._showAppsButton = showAppsButton;
@@ -160,7 +160,7 @@ var ViewSelector = class {
this._iconClickedId = 0;
this._capturedEventId = 0;
- this._workspacesDisplay = new WorkspacesView.WorkspacesDisplay();
+ this._workspacesDisplay = new WorkspacesView.WorkspacesDisplay(thumbnailsBox);
this._workspacesPage = this._addPage(this._workspacesDisplay.actor,
_("Windows"), 'focus-windows-symbolic');
diff --git a/js/ui/workspaceThumbnail.js b/js/ui/workspaceThumbnail.js
index 25629b814..b747da25d 100644
--- a/js/ui/workspaceThumbnail.js
+++ b/js/ui/workspaceThumbnail.js
@@ -626,7 +626,8 @@ class ThumbnailsBox extends St.Widget {
this._pendingScaleUpdate = false;
this._stateUpdateQueued = false;
this._animatingIndicator = false;
- this._indicatorY = 0; // only used when _animatingIndicator is true
+ this._gestureActive = false;
+ this._indicatorY = 0; // only used when _animatingIndicator or_gestureActive is true
this._stateCounts = {};
for (let key in ThumbnailState)
@@ -1009,6 +1010,37 @@ class ThumbnailsBox extends St.Widget {
return this._indicatorY;
}
+ overrideIndicatorProgress(progress) {
+ if (this._animatingIndicator) {
+ Tweener.removeTweens(this);
+ this._animatingIndicator = false;
+ }
+
+ let workspaceManager = global.workspace_manager;
+ let activeWorkspace = workspaceManager.get_active_workspace();
+
+ let active;
+ for (let i = 0; i < this._thumbnails.length; i++) {
+ if (this._thumbnails[i].metaWorkspace == activeWorkspace) {
+ active = i;
+ break;
+ }
+ }
+
+ this._gestureActive = true;
+
+// log("WTF", progress);
+ let indicatorY1 = this._thumbnails[active].actor.allocation.y1;
+ let indicatorY2 = this._thumbnails[active + Math.sign(progress)].actor.allocation.y1;
+ this.indicatorY = (indicatorY2 - indicatorY1) * Math.abs(progress);
+ }
+
+ resetIndicatorProgress() {
+ this.indicatorY = 0;
+ this._gestureActive = false;
+ this._queueUpdateStates();
+ }
+
_setThumbnailState(thumbnail, state) {
this._stateCounts[thumbnail.state]--;
thumbnail.state = state;
@@ -1038,7 +1070,7 @@ class ThumbnailsBox extends St.Widget {
this._stateUpdateQueued = false;
// If we are animating the indicator, wait
- if (this._animatingIndicator)
+ if (this._animatingIndicator || this._gestureActive)
return;
// Then slide out any thumbnails that have been destroyed
@@ -1301,6 +1333,11 @@ class ThumbnailsBox extends St.Widget {
}
_activeWorkspaceChanged(wm, from, to, direction) {
+ this.queue_relayout();
+
+ if (this._gestureActive)
+ return;
+
let thumbnail;
let workspaceManager = global.workspace_manager;
let activeWorkspace = workspaceManager.get_active_workspace();
@@ -1311,15 +1348,13 @@ class ThumbnailsBox extends St.Widget {
}
}
- this.queue_relayout();
-
this._animatingIndicator = true;
this.indicatorY = this._indicator.allocation.y1 - thumbnail.actor.allocation.y1;
Tweener.addTween(this,
{ indicatorY: 0,
time: WorkspacesView.WORKSPACE_SWITCH_TIME,
- transition: 'easeOutQuad',
+ transition: 'easeOutCubic',
onComplete() {
this._animatingIndicator = false;
this._queueUpdateStates();
diff --git a/js/ui/workspacesView.js b/js/ui/workspacesView.js
index 53dd1dce1..bd45e6d7d 100644
--- a/js/ui/workspacesView.js
+++ b/js/ui/workspacesView.js
@@ -4,8 +4,8 @@ const { Clutter, Gio, GObject, Meta, Shell, St } = imports.gi;
const Signals = imports.signals;
const Main = imports.ui.main;
+const SwipeTracker = imports.ui.swipeTracker;
const Tweener = imports.ui.tweener;
-const WindowManager = imports.ui.windowManager;
const Workspace = imports.ui.workspace;
var WORKSPACE_SWITCH_TIME = 0.25;
@@ -82,7 +82,6 @@ var WorkspacesView = class extends WorkspacesViewBase {
super(monitorIndex);
this._animating = false; // tweening
- this._scrolling = false; // swipe-scrolling
this._gestureActive = false; // touch(pad) gestures
this._animatingScroll = false; // programmatically updating the adjustment
@@ -164,7 +163,7 @@ var WorkspacesView = class extends WorkspacesViewBase {
let workspaceManager = global.workspace_manager;
let active = workspaceManager.get_active_workspace_index();
- this._updateWorkspaceActors(true);
+ this._updateWorkspaceActors(!this._gestureActive);
this._updateScrollAdjustment(active);
}
@@ -186,7 +185,7 @@ var WorkspacesView = class extends WorkspacesViewBase {
if (showAnimation) {
let params = { y: y,
time: WORKSPACE_SWITCH_TIME,
- transition: 'easeOutQuad'
+ transition: 'easeOutCubic'
};
// we have to call _updateVisibility() once before the
// animation and once afterwards - it does not really
@@ -213,7 +212,7 @@ var WorkspacesView = class extends WorkspacesViewBase {
for (let w = 0; w < this._workspaces.length; w++) {
let workspace = this._workspaces[w];
- if (this._animating || this._scrolling || this._gestureActive) {
+ if (this._animating || this._gestureActive) {
workspace.actor.show();
} else {
if (this._inDrag)
@@ -225,7 +224,7 @@ var WorkspacesView = class extends WorkspacesViewBase {
}
_updateScrollAdjustment(index) {
- if (this._scrolling || this._gestureActive)
+ if (this._gestureActive)
return;
this._animatingScroll = true;
@@ -233,7 +232,7 @@ var WorkspacesView = class extends WorkspacesViewBase {
Tweener.addTween(this.scrollAdjustment, {
value: index,
time: WORKSPACE_SWITCH_TIME,
- transition: 'easeOutQuad',
+ transition: 'easeOutCubic',
onComplete: () => {
this._animatingScroll = false;
}
@@ -274,7 +273,7 @@ var WorkspacesView = class extends WorkspacesViewBase {
}
_activeWorkspaceChanged(wm, from, to, direction) {
- if (this._scrolling)
+ if (this._gestureActive)
return;
this._scrollToActive();
@@ -290,28 +289,15 @@ var WorkspacesView = class extends WorkspacesViewBase {
workspaceManager.disconnect(this._updateWorkspacesId);
}
- startSwipeScroll() {
- this._scrolling = true;
- }
-
- endSwipeScroll() {
- this._scrolling = false;
-
- // Make sure title captions etc are shown as necessary
- this._scrollToActive();
- this._updateVisibility();
- }
-
startTouchGesture() {
this._gestureActive = true;
}
endTouchGesture() {
- this._gestureActive = false;
-
- // Make sure title captions etc are shown as necessary
this._scrollToActive();
this._updateVisibility();
+
+ this._gestureActive = false;
}
// sync the workspaces' positions to the value of the scroll adjustment
@@ -400,12 +386,6 @@ var ExtraWorkspaceView = class extends WorkspacesViewBase {
this._workspace.syncStacking(stackIndices);
}
- startSwipeScroll() {
- }
-
- endSwipeScroll() {
- }
-
startTouchGesture() {
}
@@ -421,14 +401,16 @@ class DelegateFocusNavigator extends St.Widget {
});
var WorkspacesDisplay = class {
- constructor() {
+ constructor(thumbnailsBox) {
+ this._thumbnailsBox = thumbnailsBox;
+
this.actor = new DelegateFocusNavigator({ clip_to_allocation: true });
this.actor._delegate = this;
this.actor.connect('notify::allocation', this._updateWorkspacesActualGeometry.bind(this));
this.actor.connect('parent-set', this._parentSet.bind(this));
- let clickAction = new Clutter.ClickAction();
- clickAction.connect('clicked', action => {
+ this._clickAction = new Clutter.ClickAction();
+ this._clickAction.connect('clicked', action => {
// Only switch to the workspace when there's no application
// windows open. The problem is that it's too easy to miss
// an app window and get the wrong one focused.
@@ -438,52 +420,23 @@ var WorkspacesDisplay = class {
this._workspacesViews[index].getActiveWorkspace().isEmpty())
Main.overview.hide();
});
- Main.overview.addAction(clickAction);
- this.actor.bind_property('mapped', clickAction, 'enabled', GObject.BindingFlags.SYNC_CREATE);
-
- let panAction = new Clutter.PanAction({ trigger_edge: Clutter.TriggerEdge.AFTER });
- panAction.connect('pan', this._onPan.bind(this));
- panAction.connect('gesture-begin', () => {
- if (this._workspacesOnlyOnPrimary) {
- let event = Clutter.get_current_event();
- if (this._getMonitorIndexForEvent(event) != this._primaryIndex)
- return false;
- }
-
- this._startSwipeScroll();
- return true;
- });
- panAction.connect('gesture-cancel', () => {
- clickAction.release();
- this._endSwipeScroll();
- });
- panAction.connect('gesture-end', () => {
- clickAction.release();
- this._endSwipeScroll();
- });
- Main.overview.addAction(panAction);
- this.actor.bind_property('mapped', panAction, 'enabled', GObject.BindingFlags.SYNC_CREATE);
+ Main.overview.addAction(this._clickAction);
+ this.actor.bind_property('mapped', this._clickAction, 'enabled', GObject.BindingFlags.SYNC_CREATE);
let allowedModes = Shell.ActionMode.OVERVIEW;
- let switchGesture = new WindowManager.WorkspaceSwitchAction(allowedModes);
- switchGesture.connect('motion', this._onSwitchWorkspaceMotion.bind(this));
- switchGesture.connect('activated', this._onSwitchWorkspaceActivated.bind(this));
- switchGesture.connect('cancel', this._endTouchGesture.bind(this));
- Main.overview.addAction(switchGesture);
- this.actor.bind_property('mapped', switchGesture, 'enabled', GObject.BindingFlags.SYNC_CREATE);
-
- switchGesture = new WindowManager.TouchpadWorkspaceSwitchAction(global.stage, allowedModes);
- switchGesture.connect('motion', this._onSwitchWorkspaceMotion.bind(this));
- switchGesture.connect('activated', this._onSwitchWorkspaceActivated.bind(this));
- switchGesture.connect('cancel', this._endTouchGesture.bind(this));
+ let swipeTracker = new SwipeTracker.SwipeTracker(Main.overview, allowedModes);
+ swipeTracker.connect('begin', this._switchWorkspaceBegin.bind(this));
+ swipeTracker.connect('update', this._switchWorkspaceUpdate.bind(this));
+ swipeTracker.connect('end', this._switchWorkspaceEnd.bind(this));
+ swipeTracker.connect('cancel', this._switchWorkspaceCancel.bind(this));
this.actor.connect('notify::mapped', () => {
- switchGesture.enabled = this.actor.mapped;
+ swipeTracker.enabled = this.actor.mapped;
});
this._primaryIndex = Main.layoutManager.primaryIndex;
this._workspacesViews = [];
- switchGesture.enabled = this.actor.mapped;
+ swipeTracker.enabled = this.actor.mapped;
this._settings = new Gio.Settings({ schema_id: MUTTER_SCHEMA });
this._settings.connect('changed::workspaces-only-on-primary',
@@ -496,56 +449,103 @@ var WorkspacesDisplay = class {
this._keyPressEventId = 0;
this._fullGeometry = null;
- }
- _onPan(action) {
- let [dist, dx, dy] = action.get_motion_delta(0);
- let adjustment = this._scrollAdjustment;
- adjustment.value -= (dy / this.actor.height) * adjustment.page_size;
- return false;
+ this._gestureActive = false;
}
- _startSwipeScroll() {
- for (let i = 0; i < this._workspacesViews.length; i++)
- this._workspacesViews[i].startSwipeScroll();
- }
+ _switchWorkspaceBegin(tracker, monitor) {
+ if (this._workspacesOnlyOnPrimary && monitor != this._primaryIndex)
+ return;
- _endSwipeScroll() {
- for (let i = 0; i < this._workspacesViews.length; i++)
- this._workspacesViews[i].endSwipeScroll();
- }
+ if (this._gestureActive) {
+ let workspaceManager = global.workspace_manager;
+ let active = workspaceManager.get_active_workspace_index();
+ let adjustment = this._scrollAdjustment;
+
+ Tweener.removeTweens(adjustment);
+
+ let progress = adjustment.value / adjustment.page_size - active;
+ tracker.continueSwipe(progress);
+ return;
+ }
- _startTouchGesture() {
for (let i = 0; i < this._workspacesViews.length; i++)
this._workspacesViews[i].startTouchGesture();
- }
- _endTouchGesture() {
- for (let i = 0; i < this._workspacesViews.length; i++)
- this._workspacesViews[i].endTouchGesture();
- }
+ let workspaceManager = global.workspace_manager;
+ let activeWs = workspaceManager.get_active_workspace();
+
+ let canSwipeBack = (activeWs.get_neighbor(Meta.MotionDirection.DOWN) != activeWs);
+ let canSwipeForward = (activeWs.get_neighbor(Meta.MotionDirection.UP) != activeWs);
+ tracker.confirmSwipe(canSwipeBack, canSwipeForward, this.actor.height, 0, 0);
- _onSwitchWorkspaceMotion(action, xRel, yRel) {
- // We don't have a way to hook into start of touchpad actions,
- // luckily this is safe to call repeatedly.
- this._startTouchGesture();
+ this._gestureActive = true;
+ }
+ _switchWorkspaceUpdate(tracker, progress) {
let workspaceManager = global.workspace_manager;
let active = workspaceManager.get_active_workspace_index();
let adjustment = this._scrollAdjustment;
- adjustment.value = (active - yRel / this.actor.height) * adjustment.page_size;
+ adjustment.value = (active + progress) * adjustment.page_size;
}
- _onSwitchWorkspaceActivated(action, direction) {
+ _switchWorkspaceEnd(tracker, duration, isBack) {
+ this._clickAction.release();
+
+ let direction = isBack ? Meta.MotionDirection.DOWN : Meta.MotionDirection.UP;
+
let workspaceManager = global.workspace_manager;
let activeWorkspace = workspaceManager.get_active_workspace();
let newWs = activeWorkspace.get_neighbor(direction);
- if (newWs != activeWorkspace)
- newWs.activate(global.get_current_time());
+
+ if (newWs == activeWorkspace) {
+ // FIXME: throw an error
+ log('this should never happen')
+ } else {
+ let active = workspaceManager.get_active_workspace_index();
+ Tweener.addTween(this._scrollAdjustment,
+ { value: active + (isBack ? 1 : -1),
+ time: duration,
+ transition: 'easeOutCubic',
+ onComplete: this._switchWorkspaceActivate,
+ onCompleteScope: this,
+ onCompleteParams: [newWs]
+ });
+ }
+ }
+
+ _switchWorkspaceCancel(tracker, duration) {
+ this._clickAction.release();
+
+ if (duration == 0) {
+ this._endTouchGesture();
+ return;
+ }
+
+ let workspaceManager = global.workspace_manager;
+ let active = workspaceManager.get_active_workspace_index();
+ Tweener.addTween(this._scrollAdjustment,
+ { value: active,
+ time: duration,
+ transition: 'easeOutCubic',
+ onComplete: this._endTouchGesture,
+ onCompleteScope: this
+ });
+ }
+
+ _switchWorkspaceActivate(newWs) {
+ newWs.activate(global.get_current_time());
this._endTouchGesture();
}
+ _endTouchGesture() {
+ for (let i = 0; i < this._workspacesViews.length; i++)
+ this._workspacesViews[i].endTouchGesture();
+ this._gestureActive = false;
+ this._thumbnailsBox.resetIndicatorProgress();
+ }
+
navigateFocus(from, direction) {
return this._getPrimaryView().actor.navigate_focus(from, direction, false);
}
@@ -623,7 +623,6 @@ var WorkspacesDisplay = class {
else
view = new WorkspacesView(i);
- view.actor.connect('scroll-event', this._onScrollEvent.bind(this));
if (i == this._primaryIndex) {
this._scrollAdjustment = view.scrollAdjustment;
this._scrollAdjustment.connect('notify::value',
@@ -651,6 +650,13 @@ var WorkspacesDisplay = class {
// values map directly
adjustment.value = this._scrollAdjustment.value;
}
+
+ if (this._gestureActive) {
+ let workspaceManager = global.workspace_manager;
+ let active = workspaceManager.get_active_workspace_index();
+ let progress = this._scrollAdjustment.value / this._scrollAdjustment.page_size - active;
+ this._thumbnailsBox.overrideIndicatorProgress(progress);
+ }
}
_getMonitorIndexForEvent(event) {
@@ -735,6 +741,9 @@ var WorkspacesDisplay = class {
}
_onScrollEvent(actor, event) {
+ if (event.get_scroll_source() == Clutter.ScrollSource.FINGER ||
event.get_source_device().get_device_type() == Clutter.InputDeviceType.TOUCHPAD_DEVICE) // TODO: remove this
and handle it in SwipeTracker too
+ return Clutter.EVENT_PROPAGATE;
+
if (!this.actor.mapped)
return Clutter.EVENT_PROPAGATE;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]