[gnome-shell/wip/exalm/gestures-part-3: 7/7] windowManager: Use SwipeTracker
- From: Alexander Mikhaylenko <alexm src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-shell/wip/exalm/gestures-part-3: 7/7] windowManager: Use SwipeTracker
- Date: Thu, 9 Jan 2020 19:02:57 +0000 (UTC)
commit d3edcfe2dcd5ab7f5b729eb74bf2550dc4b020cd
Author: Alexander Mikhaylenko <alexm gnome org>
Date: Sun Jun 30 17:15:44 2019 +0500
windowManager: Use SwipeTracker
Replace existing four-finger gestures with SwipeTracker.
Since TouchpadWorkspaceSwitchAction and WorkspaceSwitchAction are now
unused, remove them.
Change programmatic workspace transition to use easeOutCubic interpolator
to match the gesture.
Fixes https://gitlab.gnome.org/GNOME/gnome-shell/issues/756
https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/826
js/ui/windowManager.js | 392 +++++++++++++++++++++++--------------------------
1 file changed, 181 insertions(+), 211 deletions(-)
---
diff --git a/js/ui/windowManager.js b/js/ui/windowManager.js
index 7716bab741..c1b809f6d3 100644
--- a/js/ui/windowManager.js
+++ b/js/ui/windowManager.js
@@ -2,7 +2,6 @@
/* exported WindowManager */
const { Clutter, Gio, GLib, GObject, Meta, Shell, St } = imports.gi;
-const Signals = imports.signals;
const AltTab = imports.ui.altTab;
const AppFavorites = imports.ui.appFavorites;
@@ -15,6 +14,7 @@ const WindowMenu = imports.ui.windowMenu;
const PadOsd = imports.ui.padOsd;
const EdgeDragAction = imports.ui.edgeDragAction;
const CloseDialog = imports.ui.closeDialog;
+const SwipeTracker = imports.ui.swipeTracker;
const SwitchMonitor = imports.ui.switchMonitor;
const IBusManager = imports.misc.ibusManager;
@@ -30,7 +30,6 @@ var WINDOW_ANIMATION_TIME = 250;
var DIM_BRIGHTNESS = -0.3;
var DIM_TIME = 500;
var UNDIM_TIME = 250;
-var WS_MOTION_THRESHOLD = 100;
var APP_MOTION_THRESHOLD = 30;
var ONE_SECOND = 1000; // in ms
@@ -468,147 +467,6 @@ class TilePreview extends St.Widget {
}
});
-var TouchpadWorkspaceSwitchAction = class {
- constructor(actor, allowedModes) {
- this._allowedModes = allowedModes;
- this._dx = 0;
- this._dy = 0;
- this._enabled = true;
- actor.connect('captured-event', this._handleEvent.bind(this));
- this._touchpadSettings = new Gio.Settings({ schema_id: 'org.gnome.desktop.peripherals.touchpad' });
- }
-
- get enabled() {
- return this._enabled;
- }
-
- set enabled(enabled) {
- if (this._enabled == enabled)
- return;
-
- this._enabled = enabled;
- if (!enabled)
- this.emit('cancel');
- }
-
- _checkActivated() {
- let dir;
-
- if (this._dy < -WS_MOTION_THRESHOLD)
- dir = Meta.MotionDirection.DOWN;
- else if (this._dy > WS_MOTION_THRESHOLD)
- dir = Meta.MotionDirection.UP;
- else if (this._dx < -WS_MOTION_THRESHOLD)
- dir = Meta.MotionDirection.RIGHT;
- else if (this._dx > WS_MOTION_THRESHOLD)
- dir = Meta.MotionDirection.LEFT;
- else
- return false;
-
- this.emit('activated', dir);
- return true;
- }
-
- _handleEvent(actor, event) {
- if (event.type() != Clutter.EventType.TOUCHPAD_SWIPE)
- return Clutter.EVENT_PROPAGATE;
-
- if (event.get_touchpad_gesture_finger_count() != 4)
- return Clutter.EVENT_PROPAGATE;
-
- if ((this._allowedModes & Main.actionMode) == 0)
- return Clutter.EVENT_PROPAGATE;
-
- if (!this._enabled)
- return Clutter.EVENT_PROPAGATE;
-
- if (event.get_gesture_phase() == Clutter.TouchpadGesturePhase.UPDATE) {
- let [dx, dy] = event.get_gesture_motion_delta();
-
- // Scale deltas up a bit to make it feel snappier
- this._dx += dx * 2;
- if (!this._touchpadSettings.get_boolean('natural-scroll'))
- this._dy -= dy * 2;
- else
- this._dy += dy * 2;
-
- this.emit('motion', this._dx, this._dy);
- } else {
- if ((event.get_gesture_phase() == Clutter.TouchpadGesturePhase.END && !this._checkActivated()) ||
- event.get_gesture_phase() == Clutter.TouchpadGesturePhase.CANCEL)
- this.emit('cancel');
-
- this._dx = 0;
- this._dy = 0;
- }
-
- return Clutter.EVENT_STOP;
- }
-};
-Signals.addSignalMethods(TouchpadWorkspaceSwitchAction.prototype);
-
-var WorkspaceSwitchAction = GObject.registerClass({
- Signals: { 'activated': { param_types: [Meta.MotionDirection.$gtype] },
- 'motion': { param_types: [GObject.TYPE_DOUBLE, GObject.TYPE_DOUBLE] },
- 'cancel': { param_types: [] } },
-}, class WorkspaceSwitchAction extends Clutter.SwipeAction {
- _init(allowedModes) {
- super._init();
- this.set_n_touch_points(4);
- this._swept = false;
- this._allowedModes = allowedModes;
-
- global.display.connect('grab-op-begin', () => {
- this.cancel();
- });
- }
-
- vfunc_gesture_prepare(actor) {
- this._swept = false;
-
- if (!super.vfunc_gesture_prepare(actor))
- return false;
-
- return this._allowedModes & Main.actionMode;
- }
-
- vfunc_gesture_progress(_actor) {
- let [x, y] = this.get_motion_coords(0);
- let [xPress, yPress] = this.get_press_coords(0);
- this.emit('motion', x - xPress, y - yPress);
- return true;
- }
-
- vfunc_gesture_cancel(_actor) {
- if (!this._swept)
- this.emit('cancel');
- }
-
- vfunc_swipe(actor, direction) {
- let [x, y] = this.get_motion_coords(0);
- let [xPress, yPress] = this.get_press_coords(0);
- if (Math.abs(x - xPress) < WS_MOTION_THRESHOLD &&
- Math.abs(y - yPress) < WS_MOTION_THRESHOLD) {
- this.emit('cancel');
- return;
- }
-
- let dir;
-
- if (direction & Clutter.SwipeDirection.UP)
- dir = Meta.MotionDirection.DOWN;
- else if (direction & Clutter.SwipeDirection.DOWN)
- dir = Meta.MotionDirection.UP;
- else if (direction & Clutter.SwipeDirection.LEFT)
- dir = Meta.MotionDirection.RIGHT;
- else if (direction & Clutter.SwipeDirection.RIGHT)
- dir = Meta.MotionDirection.LEFT;
-
- this._swept = true;
- this.emit('activated', dir);
- }
-});
-
var AppSwitchAction = GObject.registerClass({
Signals: { 'activated': {} },
}, class AppSwitchAction extends Clutter.GestureAction {
@@ -1054,10 +912,17 @@ var WindowManager = class {
Main.overview.connect('showing', () => {
for (let i = 0; i < this._dimmedWindows.length; i++)
this._undimWindow(this._dimmedWindows[i]);
+
+ if (this._switchData) {
+ if (this._switchData.gestureActivated)
+ this._switchWorkspaceStop();
+ this._swipeTracker.enabled = false;
+ }
});
Main.overview.connect('hiding', () => {
for (let i = 0; i < this._dimmedWindows.length; i++)
this._dimWindow(this._dimmedWindows[i]);
+ this._swipeTracker.enabled = true;
});
this._windowMenuManager = new WindowMenu.WindowMenuManager();
@@ -1068,18 +933,12 @@ var WindowManager = class {
global.workspace_manager.override_workspace_layout(Meta.DisplayCorner.TOPLEFT,
false, -1, 1);
- let allowedModes = Shell.ActionMode.NORMAL;
- let workspaceSwitchAction = new WorkspaceSwitchAction(allowedModes);
- workspaceSwitchAction.connect('motion', this._switchWorkspaceMotion.bind(this));
- workspaceSwitchAction.connect('activated', this._actionSwitchWorkspace.bind(this));
- workspaceSwitchAction.connect('cancel', this._switchWorkspaceCancel.bind(this));
- global.stage.add_action(workspaceSwitchAction);
-
- // This is not a normal Clutter.GestureAction, doesn't need add_action()
- let touchpadSwitchAction = new TouchpadWorkspaceSwitchAction(global.stage, allowedModes);
- touchpadSwitchAction.connect('motion', this._switchWorkspaceMotion.bind(this));
- touchpadSwitchAction.connect('activated', this._actionSwitchWorkspace.bind(this));
- touchpadSwitchAction.connect('cancel', this._switchWorkspaceCancel.bind(this));
+ let swipeTracker = new SwipeTracker.SwipeTracker(global.stage,
+ Shell.ActionMode.NORMAL, false, false);
+ swipeTracker.connect('begin', this._switchWorkspaceBegin.bind(this));
+ swipeTracker.connect('update', this._switchWorkspaceUpdate.bind(this));
+ swipeTracker.connect('end', this._switchWorkspaceEnd.bind(this));
+ this._swipeTracker = swipeTracker;
let appSwitchAction = new AppSwitchAction();
appSwitchAction.connect('activated', this._switchApp.bind(this));
@@ -1121,52 +980,6 @@ var WindowManager = class {
return this._currentPadOsd;
}
- _switchWorkspaceMotion(action, xRel, yRel) {
- let workspaceManager = global.workspace_manager;
- let activeWorkspace = workspaceManager.get_active_workspace();
-
- if (!this._switchData)
- this._prepareWorkspaceSwitch(activeWorkspace.index(), -1);
-
- if (yRel < 0 && !this._switchData.surroundings[Meta.MotionDirection.DOWN])
- yRel = 0;
- if (yRel > 0 && !this._switchData.surroundings[Meta.MotionDirection.UP])
- yRel = 0;
- if (xRel < 0 && !this._switchData.surroundings[Meta.MotionDirection.RIGHT])
- xRel = 0;
- if (xRel > 0 && !this._switchData.surroundings[Meta.MotionDirection.LEFT])
- xRel = 0;
-
- this._switchData.container.set_position(xRel, yRel);
- }
-
- _switchWorkspaceCancel() {
- if (!this._switchData || this._switchData.inProgress)
- return;
- let switchData = this._switchData;
- this._switchData = null;
- switchData.container.ease({
- x: 0,
- y: 0,
- duration: WINDOW_ANIMATION_TIME,
- mode: Clutter.AnimationMode.EASE_OUT_QUAD,
- onComplete: () => this._finishWorkspaceSwitch(switchData),
- });
- }
-
- _actionSwitchWorkspace(action, direction) {
- let workspaceManager = global.workspace_manager;
- let activeWorkspace = workspaceManager.get_active_workspace();
- let newWs = activeWorkspace.get_neighbor(direction);
-
- if (newWs == activeWorkspace) {
- this._switchWorkspaceCancel();
- } else {
- this._switchData.gestureActivated = true;
- this.actionMoveWorkspace(newWs);
- }
- }
-
_lookupIndex(windows, metaWindow) {
for (let i = 0; i < windows.length; i++) {
if (windows[i].metaWindow == metaWindow)
@@ -1280,7 +1093,8 @@ var WindowManager = class {
}
_shouldAnimate() {
- return !Main.overview.visible;
+ return !(Main.overview.visible ||
+ (this._switchData && this._switchData.gestureActivated));
}
_shouldAnimateActor(actor, types) {
@@ -1860,13 +1674,17 @@ var WindowManager = class {
continue;
}
- let info = { index: ws.index(),
- actor: new Clutter.Actor() };
+ let [x, y] = this._getPositionForDirection(dir, curWs, ws);
+ let info = {
+ index: ws.index(),
+ actor: new Clutter.Actor(),
+ xDest: x,
+ yDest: y,
+ };
switchData.surroundings[dir] = info;
switchData.container.add_actor(info.actor);
switchData.container.set_child_above_sibling(info.actor, null);
- let [x, y] = this._getPositionForDirection(dir, curWs, ws);
info.actor.set_position(x, y);
}
@@ -1948,11 +1766,7 @@ var WindowManager = class {
return;
}
- // If we come from a gesture, switchData will already be set,
- // and we don't want to overwrite it.
- if (!this._switchData)
- this._prepareWorkspaceSwitch(from, to, direction);
-
+ this._prepareWorkspaceSwitch(from, to, direction);
this._switchData.inProgress = true;
let workspaceManager = global.workspace_manager;
@@ -1972,7 +1786,7 @@ var WindowManager = class {
x: xDest,
y: yDest,
duration: WINDOW_ANIMATION_TIME,
- mode: Clutter.AnimationMode.EASE_OUT_QUAD,
+ mode: Clutter.AnimationMode.EASE_OUT_CUBIC,
onComplete: () => this._switchWorkspaceDone(shellwm),
});
}
@@ -1982,6 +1796,162 @@ var WindowManager = class {
shellwm.completed_switch_workspace();
}
+ _directionForProgress(progress) {
+ if (global.workspace_manager.layout_rows === -1) {
+ return progress > 0
+ ? Meta.MotionDirection.DOWN
+ : Meta.MotionDirection.UP;
+ } else if (Clutter.get_default_text_direction() === Clutter.TextDirection.RTL) {
+ return progress > 0
+ ? Meta.MotionDirection.LEFT
+ : Meta.MotionDirection.RIGHT;
+ } else {
+ return progress > 0
+ ? Meta.MotionDirection.RIGHT
+ : Meta.MotionDirection.LEFT;
+ }
+ }
+
+ _getProgressRange() {
+ if (!this._switchData)
+ return [0, 0];
+
+ let lower = 0;
+ let upper = 0;
+
+ let horiz = global.workspace_manager.layout_rows !== -1;
+ let baseDistance;
+ if (horiz)
+ baseDistance = global.screen_width;
+ else
+ baseDistance = global.screen_height;
+
+ let direction = this._directionForProgress(-1);
+ let info = this._switchData.surroundings[direction];
+ if (info !== null) {
+ let distance = horiz ? info.xDest : info.yDest;
+ lower = -Math.abs(distance) / baseDistance;
+ }
+
+ direction = this._directionForProgress(1);
+ info = this._switchData.surroundings[direction];
+ if (info !== null) {
+ let distance = horiz ? info.xDest : info.yDest;
+ upper = Math.abs(distance) / baseDistance;
+ }
+
+ return [lower, upper];
+ }
+
+ _switchWorkspaceBegin(tracker, monitor) {
+ if (Meta.prefs_get_workspaces_only_on_primary() &&
+ monitor !== Main.layoutManager.primaryIndex)
+ return;
+
+ let horiz = global.workspace_manager.layout_rows !== -1;
+ tracker.orientation = horiz ? Clutter.Orientation.HORIZONTAL
+ : Clutter.Orientation.VERTICAL;
+
+ let workspaceManager = global.workspace_manager;
+ let activeWorkspace = workspaceManager.get_active_workspace();
+
+ let baseDistance;
+ if (horiz)
+ baseDistance = global.screen_width;
+ else
+ baseDistance = global.screen_height;
+
+ let progress;
+ if (this._switchData && this._switchData.gestureActivated) {
+ this._switchData.container.remove_all_transitions();
+ if (!horiz)
+ progress = -this._switchData.container.y / baseDistance;
+ else if (Clutter.get_default_text_direction() === Clutter.TextDirection.RTL)
+ progress = this._switchData.container.x / baseDistance;
+ else
+ progress = -this._switchData.container.x / baseDistance;
+ } else {
+ this._prepareWorkspaceSwitch(activeWorkspace.index(), -1);
+ progress = 0;
+ }
+
+ let points = [];
+ let [lower, upper] = this._getProgressRange();
+
+ if (lower !== 0)
+ points.push(lower);
+
+ points.push(0);
+
+ if (upper !== 0)
+ points.push(upper);
+
+ tracker.confirmSwipe(baseDistance, points, progress, 0);
+ }
+
+ _switchWorkspaceUpdate(tracker, progress) {
+ if (!this._switchData)
+ return;
+
+ let direction = this._directionForProgress(progress);
+ let info = this._switchData.surroundings[direction];
+ let xPos = 0;
+ let yPos = 0;
+ if (info) {
+ if (global.workspace_manager.layout_rows === -1)
+ yPos = Math.round(Math.abs(progress) * -info.yDest);
+ else
+ xPos = Math.round(Math.abs(progress) * -info.xDest);
+ }
+
+ this._switchData.container.set_position(xPos, yPos);
+ }
+
+ _switchWorkspaceEnd(tracker, duration, endProgress) {
+ if (!this._switchData)
+ return;
+
+ let workspaceManager = global.workspace_manager;
+ let activeWorkspace = workspaceManager.get_active_workspace();
+ let newWs = activeWorkspace;
+ let xDest = 0;
+ let yDest = 0;
+ if (endProgress !== 0) {
+ let direction = this._directionForProgress(endProgress);
+ newWs = activeWorkspace.get_neighbor(direction);
+ xDest = -this._switchData.surroundings[direction].xDest;
+ yDest = -this._switchData.surroundings[direction].yDest;
+ }
+
+ if (duration === 0) {
+ if (newWs !== activeWorkspace)
+ this.actionMoveWorkspace(newWs);
+ this._switchWorkspaceStop();
+ return;
+ }
+
+ let switchData = this._switchData;
+ switchData.gestureActivated = true;
+
+ this._switchData.container.ease({
+ x: xDest,
+ y: yDest,
+ duration,
+ mode: Clutter.AnimationMode.EASE_OUT_CUBIC,
+ onComplete: () => {
+ if (newWs !== activeWorkspace)
+ this.actionMoveWorkspace(newWs);
+ this._finishWorkspaceSwitch(switchData);
+ },
+ });
+ }
+
+ _switchWorkspaceStop() {
+ this._switchData.container.x = 0;
+ this._switchData.container.y = 0;
+ this._finishWorkspaceSwitch(this._switchData);
+ }
+
_showTilePreview(shellwm, window, tileRect, monitorIndex) {
if (!this._tilePreview)
this._tilePreview = new TilePreview();
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]