workspaceAnimation: Extract WorkspaceGroup
Simplify the code a bit. The workspace group is relatively self-contained, so split it from the general animation. Reimplement _syncStacking(). This will help a lot later, with workspace strip and multi-monitor support. Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1326>
This commit is contained in:
parent
269c5ca957
commit
e32ec73315
@ -1,20 +1,95 @@
|
|||||||
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
||||||
/* exported WorkspaceAnimationController */
|
/* exported WorkspaceAnimationController */
|
||||||
|
|
||||||
const { Clutter, Meta, Shell } = imports.gi;
|
const { Clutter, GObject, Meta, Shell } = imports.gi;
|
||||||
|
|
||||||
const Main = imports.ui.main;
|
const Main = imports.ui.main;
|
||||||
const SwipeTracker = imports.ui.swipeTracker;
|
const SwipeTracker = imports.ui.swipeTracker;
|
||||||
|
|
||||||
const WINDOW_ANIMATION_TIME = 250;
|
const WINDOW_ANIMATION_TIME = 250;
|
||||||
|
|
||||||
|
const WorkspaceGroup = GObject.registerClass(
|
||||||
|
class WorkspaceGroup extends Clutter.Actor {
|
||||||
|
_init(workspace, movingWindow) {
|
||||||
|
super._init();
|
||||||
|
|
||||||
|
this._workspace = workspace;
|
||||||
|
this._movingWindow = movingWindow;
|
||||||
|
this._windowRecords = [];
|
||||||
|
|
||||||
|
this._createWindows();
|
||||||
|
|
||||||
|
this.connect('destroy', this._onDestroy.bind(this));
|
||||||
|
this._restackedId = global.display.connect('restacked',
|
||||||
|
this._syncStacking.bind(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
_shouldShowWindow(window) {
|
||||||
|
if (!window.showing_on_its_workspace())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
const isSticky =
|
||||||
|
window.is_on_all_workspaces() || window === this._movingWindow;
|
||||||
|
|
||||||
|
return !isSticky && window.located_on_workspace(this._workspace);
|
||||||
|
}
|
||||||
|
|
||||||
|
_syncStacking() {
|
||||||
|
const windowActors = global.get_window_actors();
|
||||||
|
let lastSibling = null;
|
||||||
|
|
||||||
|
for (const windowActor of windowActors) {
|
||||||
|
this.set_child_above_sibling(windowActor, lastSibling);
|
||||||
|
lastSibling = windowActor;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_createWindows() {
|
||||||
|
const windowActors = global.get_window_actors().filter(w =>
|
||||||
|
this._shouldShowWindow(w.meta_window));
|
||||||
|
|
||||||
|
for (const windowActor of windowActors) {
|
||||||
|
const record = {
|
||||||
|
windowActor,
|
||||||
|
parent: windowActor.get_parent(),
|
||||||
|
};
|
||||||
|
|
||||||
|
record.parent.remove_child(windowActor);
|
||||||
|
this.add_child(windowActor);
|
||||||
|
windowActor.show();
|
||||||
|
|
||||||
|
record.windowDestroyId = windowActor.connect('destroy', () => {
|
||||||
|
this._windowRecords.splice(this._windowRecords.indexOf(record), 1);
|
||||||
|
});
|
||||||
|
|
||||||
|
this._windowRecords.push(record);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_removeWindows() {
|
||||||
|
for (const record of this._windowRecords) {
|
||||||
|
record.windowActor.disconnect(record.windowDestroyId);
|
||||||
|
this.remove_child(record.windowActor);
|
||||||
|
record.parent.add_child(record.windowActor);
|
||||||
|
|
||||||
|
if (!this._workspace.active)
|
||||||
|
record.windowActor.hide();
|
||||||
|
}
|
||||||
|
|
||||||
|
this._windowRecords = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
_onDestroy() {
|
||||||
|
global.display.disconnect(this._restackedId);
|
||||||
|
this._removeWindows();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
var WorkspaceAnimationController = class {
|
var WorkspaceAnimationController = class {
|
||||||
constructor() {
|
constructor() {
|
||||||
this._movingWindow = null;
|
this._movingWindow = null;
|
||||||
this._switchData = null;
|
this._switchData = null;
|
||||||
|
|
||||||
global.display.connect('restacked', this._syncStacking.bind(this));
|
|
||||||
|
|
||||||
Main.overview.connect('showing', () => {
|
Main.overview.connect('showing', () => {
|
||||||
if (this._switchData) {
|
if (this._switchData) {
|
||||||
if (this._switchData.gestureActivated)
|
if (this._switchData.gestureActivated)
|
||||||
@ -34,35 +109,6 @@ var WorkspaceAnimationController = class {
|
|||||||
this._swipeTracker = swipeTracker;
|
this._swipeTracker = swipeTracker;
|
||||||
}
|
}
|
||||||
|
|
||||||
_syncStacking() {
|
|
||||||
if (this._switchData === null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
const windows = global.get_window_actors();
|
|
||||||
let lastCurSibling = null;
|
|
||||||
const lastDirSibling = [];
|
|
||||||
for (let i = 0; i < windows.length; i++) {
|
|
||||||
if (windows[i].get_parent() === this._switchData.curGroup) {
|
|
||||||
this._switchData.curGroup.set_child_above_sibling(windows[i], lastCurSibling);
|
|
||||||
lastCurSibling = windows[i];
|
|
||||||
} else {
|
|
||||||
for (const dir of Object.values(Meta.MotionDirection)) {
|
|
||||||
const info = this._switchData.surroundings[dir];
|
|
||||||
if (!info || windows[i].get_parent() !== info.actor)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
let sibling = lastDirSibling[dir];
|
|
||||||
if (sibling === undefined)
|
|
||||||
sibling = null;
|
|
||||||
|
|
||||||
info.actor.set_child_above_sibling(windows[i], sibling);
|
|
||||||
lastDirSibling[dir] = windows[i];
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_getPositionForDirection(direction, fromWs, toWs) {
|
_getPositionForDirection(direction, fromWs, toWs) {
|
||||||
let xDest = 0, yDest = 0;
|
let xDest = 0, yDest = 0;
|
||||||
|
|
||||||
@ -100,13 +146,15 @@ var WorkspaceAnimationController = class {
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
const wgroup = global.window_group;
|
const wgroup = global.window_group;
|
||||||
const windows = global.get_window_actors();
|
const workspaceManager = global.workspace_manager;
|
||||||
|
const curWs = workspaceManager.get_workspace_by_index(from);
|
||||||
|
|
||||||
const switchData = {};
|
const switchData = {};
|
||||||
|
|
||||||
this._switchData = switchData;
|
this._switchData = switchData;
|
||||||
switchData.curGroup = new Clutter.Actor();
|
switchData.curGroup = new WorkspaceGroup(curWs, this.movingWindow);
|
||||||
switchData.movingWindowBin = new Clutter.Actor();
|
switchData.movingWindowBin = new Clutter.Actor();
|
||||||
switchData.windows = [];
|
switchData.movingWindow = null;
|
||||||
switchData.surroundings = {};
|
switchData.surroundings = {};
|
||||||
switchData.gestureActivated = false;
|
switchData.gestureActivated = false;
|
||||||
switchData.inProgress = false;
|
switchData.inProgress = false;
|
||||||
@ -117,9 +165,6 @@ var WorkspaceAnimationController = class {
|
|||||||
wgroup.add_child(switchData.movingWindowBin);
|
wgroup.add_child(switchData.movingWindowBin);
|
||||||
wgroup.add_child(switchData.container);
|
wgroup.add_child(switchData.container);
|
||||||
|
|
||||||
const workspaceManager = global.workspace_manager;
|
|
||||||
const curWs = workspaceManager.get_workspace_by_index(from);
|
|
||||||
|
|
||||||
for (const dir of Object.values(Meta.MotionDirection)) {
|
for (const dir of Object.values(Meta.MotionDirection)) {
|
||||||
let ws = null;
|
let ws = null;
|
||||||
|
|
||||||
@ -134,66 +179,28 @@ var WorkspaceAnimationController = class {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const [x, y] = this._getPositionForDirection(dir, curWs, ws);
|
const [x, y] = this._getPositionForDirection(dir, curWs, ws);
|
||||||
const info = {
|
const group = new WorkspaceGroup(ws, this.movingWindow);
|
||||||
index: ws.index(),
|
switchData.surroundings[dir] = group;
|
||||||
actor: new Clutter.Actor(),
|
switchData.container.add_child(group);
|
||||||
xDest: x,
|
switchData.container.set_child_above_sibling(group, null);
|
||||||
yDest: y,
|
|
||||||
};
|
|
||||||
switchData.surroundings[dir] = info;
|
|
||||||
switchData.container.add_child(info.actor);
|
|
||||||
switchData.container.set_child_above_sibling(info.actor, null);
|
|
||||||
|
|
||||||
info.actor.set_position(x, y);
|
group.set_position(x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
wgroup.set_child_above_sibling(switchData.movingWindowBin, null);
|
wgroup.set_child_above_sibling(switchData.movingWindowBin, null);
|
||||||
|
|
||||||
for (const windowActor of windows) {
|
if (this.movingWindow) {
|
||||||
const window = windowActor.get_meta_window();
|
const windowActor = this.movingWindow.get_compositor_private();
|
||||||
|
|
||||||
if (!window.showing_on_its_workspace())
|
switchData.movingWindow = {
|
||||||
continue;
|
|
||||||
|
|
||||||
if (window.is_on_all_workspaces())
|
|
||||||
continue;
|
|
||||||
|
|
||||||
const record = {
|
|
||||||
windowActor,
|
windowActor,
|
||||||
parent: windowActor.get_parent(),
|
parent: windowActor.get_parent(),
|
||||||
};
|
};
|
||||||
|
|
||||||
if (this.movingWindow && window === this.movingWindow) {
|
switchData.movingWindow.parent.remove_child(windowActor);
|
||||||
record.parent.remove_child(windowActor);
|
switchData.movingWindowBin.add_child(windowActor);
|
||||||
switchData.movingWindow = record;
|
switchData.movingWindow.windowDestroyId = windowActor.connect('destroy', () => {
|
||||||
switchData.windows.push(switchData.movingWindow);
|
switchData.movingWindow = null;
|
||||||
switchData.movingWindowBin.add_child(windowActor);
|
|
||||||
} else if (window.get_workspace().index() === from) {
|
|
||||||
record.parent.remove_child(windowActor);
|
|
||||||
switchData.windows.push(record);
|
|
||||||
switchData.curGroup.add_child(windowActor);
|
|
||||||
} else {
|
|
||||||
let visible = false;
|
|
||||||
for (const dir of Object.values(Meta.MotionDirection)) {
|
|
||||||
const info = switchData.surroundings[dir];
|
|
||||||
|
|
||||||
if (!info || info.index !== window.get_workspace().index())
|
|
||||||
continue;
|
|
||||||
|
|
||||||
record.parent.remove_child(windowActor);
|
|
||||||
switchData.windows.push(record);
|
|
||||||
info.actor.add_child(windowActor);
|
|
||||||
visible = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
windowActor.visible = visible;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const record of switchData.windows) {
|
|
||||||
record.windowDestroyId = record.windowActor.connect('destroy', () => {
|
|
||||||
switchData.windows.splice(switchData.windows.indexOf(record), 1);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -201,14 +208,15 @@ var WorkspaceAnimationController = class {
|
|||||||
_finishWorkspaceSwitch(switchData) {
|
_finishWorkspaceSwitch(switchData) {
|
||||||
this._switchData = null;
|
this._switchData = null;
|
||||||
|
|
||||||
for (const record of switchData.windows) {
|
if (switchData.movingWindow) {
|
||||||
|
const record = switchData.movingWindow;
|
||||||
record.windowActor.disconnect(record.windowDestroyId);
|
record.windowActor.disconnect(record.windowDestroyId);
|
||||||
switchData.movingWindowBin.remove_child(record.windowActor);
|
switchData.movingWindowBin.remove_child(record.windowActor);
|
||||||
record.parent.add_child(record.windowActor);
|
record.parent.add_child(record.windowActor);
|
||||||
|
|
||||||
if (!record.windowActor.get_meta_window().get_workspace().active)
|
switchData.movingWindow = null;
|
||||||
record.windowActor.hide();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
switchData.container.destroy();
|
switchData.container.destroy();
|
||||||
switchData.movingWindowBin.destroy();
|
switchData.movingWindowBin.destroy();
|
||||||
|
|
||||||
@ -275,16 +283,16 @@ var WorkspaceAnimationController = class {
|
|||||||
baseDistance = global.screen_height;
|
baseDistance = global.screen_height;
|
||||||
|
|
||||||
let direction = this._directionForProgress(-1);
|
let direction = this._directionForProgress(-1);
|
||||||
let info = this._switchData.surroundings[direction];
|
let group = this._switchData.surroundings[direction];
|
||||||
if (info !== null) {
|
if (group !== null) {
|
||||||
const distance = horiz ? info.xDest : info.yDest;
|
const distance = horiz ? group.x : group.y;
|
||||||
lower = -Math.abs(distance) / baseDistance;
|
lower = -Math.abs(distance) / baseDistance;
|
||||||
}
|
}
|
||||||
|
|
||||||
direction = this._directionForProgress(1);
|
direction = this._directionForProgress(1);
|
||||||
info = this._switchData.surroundings[direction];
|
group = this._switchData.surroundings[direction];
|
||||||
if (info !== null) {
|
if (group !== null) {
|
||||||
const distance = horiz ? info.xDest : info.yDest;
|
const distance = horiz ? group.x : group.y;
|
||||||
upper = Math.abs(distance) / baseDistance;
|
upper = Math.abs(distance) / baseDistance;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -343,10 +351,10 @@ var WorkspaceAnimationController = class {
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
const direction = this._directionForProgress(progress);
|
const direction = this._directionForProgress(progress);
|
||||||
const info = this._switchData.surroundings[direction];
|
const group = this._switchData.surroundings[direction];
|
||||||
let xPos = 0;
|
let xPos = 0;
|
||||||
let yPos = 0;
|
let yPos = 0;
|
||||||
if (info) {
|
if (group) {
|
||||||
if (global.workspace_manager.layout_rows === -1)
|
if (global.workspace_manager.layout_rows === -1)
|
||||||
yPos = -Math.round(progress * global.screen_height);
|
yPos = -Math.round(progress * global.screen_height);
|
||||||
else if (Clutter.get_default_text_direction() === Clutter.TextDirection.RTL)
|
else if (Clutter.get_default_text_direction() === Clutter.TextDirection.RTL)
|
||||||
@ -370,8 +378,8 @@ var WorkspaceAnimationController = class {
|
|||||||
if (endProgress !== 0) {
|
if (endProgress !== 0) {
|
||||||
const direction = this._directionForProgress(endProgress);
|
const direction = this._directionForProgress(endProgress);
|
||||||
newWs = activeWorkspace.get_neighbor(direction);
|
newWs = activeWorkspace.get_neighbor(direction);
|
||||||
xDest = -this._switchData.surroundings[direction].xDest;
|
xDest = -this._switchData.surroundings[direction].x;
|
||||||
yDest = -this._switchData.surroundings[direction].yDest;
|
yDest = -this._switchData.surroundings[direction].y;
|
||||||
}
|
}
|
||||||
|
|
||||||
const switchData = this._switchData;
|
const switchData = this._switchData;
|
||||||
|
Loading…
Reference in New Issue
Block a user