diff --git a/js/ui/workspaceAnimation.js b/js/ui/workspaceAnimation.js index 1dbd873b7..664e98a65 100644 --- a/js/ui/workspaceAnimation.js +++ b/js/ui/workspaceAnimation.js @@ -4,17 +4,19 @@ const { Clutter, GObject, Meta, Shell } = imports.gi; const Main = imports.ui.main; +const Layout = imports.ui.layout; const SwipeTracker = imports.ui.swipeTracker; const WINDOW_ANIMATION_TIME = 250; const WorkspaceGroup = GObject.registerClass( class WorkspaceGroup extends Clutter.Actor { - _init(controller, workspace) { + _init(controller, workspace, monitor) { super._init(); this._controller = controller; this._workspace = workspace; + this._monitor = monitor; this._windows = []; this._refreshWindows(); @@ -28,6 +30,11 @@ class WorkspaceGroup extends Clutter.Actor { if (window.get_workspace() !== this._workspace) return false; + let geometry = global.display.get_monitor_geometry(this._monitor.index); + let [intersects, intersection_] = window.get_frame_rect().intersect(geometry); + if (!intersects) + return false; + if (!window.showing_on_its_workspace()) return false; @@ -51,8 +58,8 @@ class WorkspaceGroup extends Clutter.Actor { for (let window of windows) { let clone = new Clutter.Clone({ source: window, - x: window.x, - y: window.y, + x: window.x - this._monitor.x, + y: window.y - this._monitor.y, }); this.add_actor(clone); @@ -105,45 +112,65 @@ const WorkspaceAnimation = GObject.registerClass({ this._controller = controller; this._movingWindow = null; - this._surroundings = {}; + this._monitors = []; this._progress = 0; - this._container = new Clutter.Actor(); - - this.add_actor(this._container); global.window_group.add_actor(this); let workspaceManager = global.workspace_manager; let curWs = workspaceManager.get_workspace_by_index(from); - this._curGroup = new WorkspaceGroup(controller, curWs); - this._container.add_actor(this._curGroup); + for (let monitor of Main.layoutManager.monitors) { + let record = { + index: monitor.index, + clipBin: new Clutter.Actor({ + x_expand: true, + y_expand: true, + clip_to_allocation: true, + }), + container: new Clutter.Actor(), + surroundings: {}, + }; - for (let dir of Object.values(Meta.MotionDirection)) { - let ws = null; + let constraint = new Layout.MonitorConstraint({ index: monitor.index }); + record.clipBin.add_constraint(constraint); - if (to < 0) - ws = curWs.get_neighbor(dir); - else if (dir === direction) - ws = workspaceManager.get_workspace_by_index(to); + record.clipBin.add_actor(record.container); - if (ws === null || ws === curWs) { - this._surroundings[dir] = null; - continue; + this.add_actor(record.clipBin); + + record.curGroup = new WorkspaceGroup(controller, curWs, monitor); + record.container.add_actor(record.curGroup); + + for (let dir of Object.values(Meta.MotionDirection)) { + let ws = null; + + if (to < 0) + ws = curWs.get_neighbor(dir); + else if (dir === direction) + ws = workspaceManager.get_workspace_by_index(to); + + if (ws === null || ws === curWs) { + record.surroundings[dir] = null; + continue; + } + + let [x, y] = this._getPositionForDirection(dir, curWs, ws, + monitor.index); + let info = { + index: ws.index(), + actor: new WorkspaceGroup(controller, ws, monitor), + xDest: x, + yDest: y, + }; + record.surroundings[dir] = info; + record.container.add_actor(info.actor); + record.container.set_child_above_sibling(info.actor, null); + + info.actor.set_position(x, y); } - let [x, y] = this._getPositionForDirection(dir, curWs, ws); - let info = { - index: ws.index(), - actor: new WorkspaceGroup(controller, ws), - xDest: x, - yDest: y, - }; - this._surroundings[dir] = info; - this._container.add_actor(info.actor); - this._container.set_child_above_sibling(info.actor, null); - - info.actor.set_position(x, y); + this._monitors.push(record); } if (this._controller.movingWindow) { @@ -168,6 +195,8 @@ const WorkspaceAnimation = GObject.registerClass({ } _onDestroy() { + this._monitors = []; + if (this._movingWindow) { let record = this._movingWindow; record.window.disconnect(record.windowDestroyId); @@ -179,34 +208,39 @@ const WorkspaceAnimation = GObject.registerClass({ } } - _getPositionForDirection(direction, fromWs, toWs) { + _getPositionForDirection(direction, fromWs, toWs, monitor) { let xDest = 0, yDest = 0; - let oldWsIsFullscreen = fromWs.list_windows().some(w => w.is_fullscreen()); - let newWsIsFullscreen = toWs.list_windows().some(w => w.is_fullscreen()); + let condition = w => w.get_monitor() === monitor && w.is_fullscreen(); + + let oldWsIsFullscreen = fromWs.list_windows().some(condition); + let newWsIsFullscreen = toWs.list_windows().some(condition); + + let geometry = Main.layoutManager.monitors[monitor]; // We have to shift windows up or down by the height of the panel to prevent having a // visible gap between the windows while switching workspaces. Since fullscreen windows // hide the panel, they don't need to be shifted up or down. - let shiftHeight = Main.panel.height; + let shiftHeight = monitor === Main.layoutManager.primaryIndex + ? Main.panel.height : 0; if (direction === Meta.MotionDirection.UP || direction === Meta.MotionDirection.UP_LEFT || direction === Meta.MotionDirection.UP_RIGHT) - yDest = -global.screen_height + (oldWsIsFullscreen ? 0 : shiftHeight); + yDest = -geometry.height + (oldWsIsFullscreen ? 0 : shiftHeight); else if (direction === Meta.MotionDirection.DOWN || direction === Meta.MotionDirection.DOWN_LEFT || direction === Meta.MotionDirection.DOWN_RIGHT) - yDest = global.screen_height - (newWsIsFullscreen ? 0 : shiftHeight); + yDest = geometry.height - (newWsIsFullscreen ? 0 : shiftHeight); if (direction === Meta.MotionDirection.LEFT || direction === Meta.MotionDirection.UP_LEFT || direction === Meta.MotionDirection.DOWN_LEFT) - xDest = -global.screen_width; + xDest = -geometry.width; else if (direction === Meta.MotionDirection.RIGHT || direction === Meta.MotionDirection.UP_RIGHT || direction === Meta.MotionDirection.DOWN_RIGHT) - xDest = global.screen_width; + xDest = geometry.width; return [xDest, yDest]; } @@ -244,21 +278,24 @@ const WorkspaceAnimation = GObject.registerClass({ this._progress = progress; let direction = this.directionForProgress(progress); - let xPos = 0; - let yPos = 0; - if (global.workspace_manager.layout_rows === -1) - yPos = -Math.round(progress * this._getDistance(direction)); - else if (Clutter.get_default_text_direction() === Clutter.TextDirection.RTL) - xPos = Math.round(progress * this._getDistance(direction)); - else - xPos = -Math.round(progress * this._getDistance(direction)); + for (let monitorData of this._monitors) { + let xPos = 0; + let yPos = 0; - this._container.set_position(xPos, yPos); + if (global.workspace_manager.layout_rows === -1) + yPos = -Math.round(progress * this._getDistance(monitorData, direction)); + else if (Clutter.get_default_text_direction() === Clutter.TextDirection.RTL) + xPos = Math.round(progress * this._getDistance(monitorData, direction)); + else + xPos = -Math.round(progress * this._getDistance(monitorData, direction)); + + monitorData.container.set_position(xPos, yPos); + } } - _getDistance(direction) { - let info = this._surroundings[direction]; + _getDistance(monitorData, direction) { + let info = monitorData.surroundings[direction]; if (!info) return 0; @@ -276,19 +313,30 @@ const WorkspaceAnimation = GObject.registerClass({ return 0; } - getProgressRange() { + getProgressRange(monitor) { + let monitorData = null; + for (let data of this._monitors) { + if (data.index === monitor) { + monitorData = data; + break; + } + } + + if (!monitorData) + return 0; + let baseDistance; if (global.workspace_manager.layout_rows !== -1) - baseDistance = global.screen_width; + baseDistance = Main.layoutManager.monitors[monitor].width; else - baseDistance = global.screen_height; + baseDistance = Main.layoutManager.monitors[monitor].height; let direction = this.directionForProgress(-1); - let distance = this._getDistance(direction); + let distance = this._getDistance(monitorData, direction); let lower = -distance / baseDistance; direction = this.directionForProgress(1); - distance = this._getDistance(direction); + distance = this._getDistance(monitorData, direction); let upper = distance / baseDistance; return [lower, upper]; @@ -335,6 +383,7 @@ var WorkspaceAnimationController = class { this._inProgress = false; this._gestureActivated = false; this.movingWindow = null; + this._monitor = null; } animateSwitchWorkspace(from, to, direction, onComplete) { @@ -368,9 +417,9 @@ var WorkspaceAnimationController = class { let baseDistance; if (horiz) - baseDistance = global.screen_width; + baseDistance = Main.layoutManager.monitors[monitor].width; else - baseDistance = global.screen_height; + baseDistance = Main.layoutManager.monitors[monitor].height; let progress; if (this._gestureActivated) { @@ -381,7 +430,8 @@ var WorkspaceAnimationController = class { progress = 0; } - let [lower, upper] = this._animation.getProgressRange(); + this._monitor = monitor; + let [lower, upper] = this._animation.getProgressRange(monitor); if (progress < 0) progress *= -lower; else if (progress > 0) @@ -401,7 +451,7 @@ var WorkspaceAnimationController = class { _switchWorkspaceUpdate(tracker, progress) { // Translate the progress into [-1;1] range - let [lower, upper] = this._animation.getProgressRange(); + let [lower, upper] = this._animation.getProgressRange(this._monitor); if (progress < 0) progress /= -lower; else if (progress > 0)