[gnome-shell/wip/exalm/gestures] overview part 1
- From: Alexander Mikhaylenko <alexm src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-shell/wip/exalm/gestures] overview part 1
- Date: Fri, 28 Jun 2019 07:28:37 +0000 (UTC)
commit 4c19bafeea35852f51795521d33234671c306f4c
Author: Alexander Mikhaylenko <exalm7659 gmail com>
Date: Thu Jun 27 18:15:36 2019 +0500
overview part 1
js/ui/overviewControls.js | 2 +-
js/ui/swipeTracker.js | 19 ++++---
js/ui/viewSelector.js | 4 +-
js/ui/windowManager.js | 2 +-
js/ui/workspaceThumbnail.js | 46 +++++++++++++--
js/ui/workspacesView.js | 134 ++++++++++++++++++++++++++++++++------------
6 files changed, 155 insertions(+), 52 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/swipeTracker.js b/js/ui/swipeTracker.js
index 7ef1e8ef3..45cffeb42 100644
--- a/js/ui/swipeTracker.js
+++ b/js/ui/swipeTracker.js
@@ -30,10 +30,11 @@ function clamp(value, min, max) {
// TODO: support horizontal
var TouchpadSwipeGesture = class TouchpadSwipeGesture {
- constructor(actor) {
+ constructor(actor, shouldSkip) {
this._touchpadSettings = new Gio.Settings({schema_id: 'org.gnome.desktop.peripherals.touchpad'});
actor.connect('captured-event', this._handleEvent.bind(this));
+ this._shouldSkip = shouldSkip;
}
_handleEvent(actor, event) {
@@ -43,8 +44,8 @@ var TouchpadSwipeGesture = class TouchpadSwipeGesture {
if (event.get_touchpad_gesture_finger_count() != 4)
return Clutter.EVENT_PROPAGATE;
-// if ((this._allowedModes & Main.actionMode) == 0 || !this._enabled)
-// return Clutter.EVENT_PROPAGATE;
+ if (this._shouldSkip())
+ return Clutter.EVENT_PROPAGATE;
let time = event.get_time();
let [dx, dy] = event.get_gesture_motion_delta();
@@ -69,18 +70,19 @@ var TouchSwipeGesture = GObject.registerClass({
'end': { param_types: [GObject.TYPE_UINT] },
'cancel': { param_types: [GObject.TYPE_UINT] }},
}, class TouchSwipeGesture extends Clutter.GestureAction {
- _init(actor) {
+ _init(actor, shouldSkip) {
super._init();
this.set_n_touch_points(4);
this._actor = actor;
+ this._shouldSkip = shouldSkip;
}
vfunc_gesture_begin(actor, point) {
if (!super.vfunc_gesture_begin(actor, point))
return false;
- return true; //(this._allowedModes & Main.actionMode) != 0 && this._enabled;
+ return !this._shouldSkip();
}
// TODO: track center of the fingers instead of the first one
@@ -148,12 +150,15 @@ var SwipeTracker = class {
this._can_swipe_back = true;
this._can_swipe_forward = true;
- let gesture = new TouchpadSwipeGesture(actor);
+ let shouldSkip = () =>
+ ((this._allowedModes & Main.actionMode) == 0 || !this._enabled);
+
+ let gesture = new TouchpadSwipeGesture(actor, shouldSkip);
gesture.connect('update', this._updateGesture.bind(this));
gesture.connect('end', this._endGesture.bind(this));
// gesture.connect('cancel', this._cancelGesture.bind(this)); // End the gesture normally for
touchpads
- gesture = new TouchSwipeGesture(actor);
+ gesture = new TouchSwipeGesture(actor, shouldSkip);
gesture.connect('update', this._updateGesture.bind(this));
gesture.connect('end', this._endGesture.bind(this));
gesture.connect('cancel', this._cancelGesture.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/windowManager.js b/js/ui/windowManager.js
index b6c168d56..6c5b39323 100644
--- a/js/ui/windowManager.js
+++ b/js/ui/windowManager.js
@@ -16,8 +16,8 @@ const WindowMenu = imports.ui.windowMenu;
const PadOsd = imports.ui.padOsd;
const EdgeDragAction = imports.ui.edgeDragAction;
const CloseDialog = imports.ui.closeDialog;
-const SwitchMonitor = imports.ui.switchMonitor;
const SwipeTracker = imports.ui.swipeTracker;
+const SwitchMonitor = imports.ui.switchMonitor;
const { loadInterfaceXML } = imports.misc.fileUtils;
diff --git a/js/ui/workspaceThumbnail.js b/js/ui/workspaceThumbnail.js
index 25629b814..ceb61fcbf 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,17 +1348,16 @@ 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._queue_relayout();
this._queueUpdateStates();
},
onCompleteScope: this
diff --git a/js/ui/workspacesView.js b/js/ui/workspacesView.js
index f5bd44699..9f249a62c 100644
--- a/js/ui/workspacesView.js
+++ b/js/ui/workspacesView.js
@@ -4,6 +4,7 @@ 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 Workspace = imports.ui.workspace;
@@ -163,7 +164,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);
}
@@ -185,7 +186,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
@@ -232,7 +233,7 @@ var WorkspacesView = class extends WorkspacesViewBase {
Tweener.addTween(this.scrollAdjustment, {
value: index,
time: WORKSPACE_SWITCH_TIME,
- transition: 'easeOutQuad',
+ transition: 'easeOutCubic',
onComplete: () => {
this._animatingScroll = false;
}
@@ -306,11 +307,10 @@ var WorkspacesView = class extends WorkspacesViewBase {
}
endTouchGesture() {
- this._gestureActive = false;
-
- // Make sure title captions etc are shown as necessary
- this._scrollToActive();
+ this._scrollToActive(false);
this._updateVisibility();
+
+ this._gestureActive = false;
}
// sync the workspaces' positions to the value of the scroll adjustment
@@ -420,7 +420,9 @@ 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));
@@ -464,25 +466,19 @@ var WorkspacesDisplay = class {
this.actor.bind_property('mapped', panAction, '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(global.stage, allowedModes); // TODO: somehow teach
it to work with addAction() too
+ 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',
@@ -495,6 +491,8 @@ var WorkspacesDisplay = class {
this._keyPressEventId = 0;
this._fullGeometry = null;
+
+ this._gestureActive = false;
}
_onPan(action) {
@@ -507,44 +505,101 @@ var WorkspacesDisplay = class {
_startSwipeScroll() {
for (let i = 0; i < this._workspacesViews.length; i++)
this._workspacesViews[i].startSwipeScroll();
+ this._gestureActive = true;
}
_endSwipeScroll() {
for (let i = 0; i < this._workspacesViews.length; i++)
this._workspacesViews[i].endSwipeScroll();
+ this._gestureActive = false;
+ this._thumbnailsBox.resetIndicatorProgress();
}
- _startTouchGesture() {
+ _switchWorkspaceBegin(tracker) {
+ 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.continueFrom(progress);
+ return;
+ }
+
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();
- _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();
+ tracker.can_swipe_forward = (activeWs.get_neighbor(Meta.MotionDirection.UP) != activeWs);
+ tracker.can_swipe_back = (activeWs.get_neighbor(Meta.MotionDirection.DOWN) != activeWs);
+ 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) {
+ 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) {
+ 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);
}
@@ -650,6 +705,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) {
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]