295d286161
The new plans for a row of workspace thumbnails on the right side of the overview means that the mental model we present to the user will be vertical, so switch the Metacity workspace layout to be vertical and adjust the keybinding handling, animations, and workspace layout in the overview to match. (This commit does not change the workspace switching indicator pending finalization of what we want to do with that - it still shows workspaces arranged vertically.) https://bugzilla.gnome.org/show_bug.cgi?id=640996
604 lines
22 KiB
JavaScript
604 lines
22 KiB
JavaScript
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
|
|
|
|
const Clutter = imports.gi.Clutter;
|
|
const GLib = imports.gi.GLib;
|
|
const Gio = imports.gi.Gio;
|
|
const Lang = imports.lang;
|
|
const Meta = imports.gi.Meta;
|
|
const St = imports.gi.St;
|
|
|
|
const AltTab = imports.ui.altTab;
|
|
const WorkspaceSwitcherPopup = imports.ui.workspaceSwitcherPopup;
|
|
const Main = imports.ui.main;
|
|
const Tweener = imports.ui.tweener;
|
|
|
|
const WINDOW_ANIMATION_TIME = 0.25;
|
|
const DIM_TIME = 0.500;
|
|
const UNDIM_TIME = 0.250;
|
|
|
|
var dimShader = undefined;
|
|
|
|
function getDimShader() {
|
|
if (dimShader === null)
|
|
return null;
|
|
if (!dimShader) {
|
|
let [success, source, length] = GLib.file_get_contents(global.datadir +
|
|
'/shaders/dim-window.glsl');
|
|
try {
|
|
let shader = new Clutter.Shader();
|
|
shader.set_fragment_source(source, -1);
|
|
shader.compile();
|
|
|
|
dimShader = shader;
|
|
} catch (e) {
|
|
log(e.message);
|
|
dimShader = null;
|
|
}
|
|
}
|
|
return dimShader;
|
|
}
|
|
|
|
function WindowDimmer(actor) {
|
|
this._init(actor);
|
|
}
|
|
|
|
WindowDimmer.prototype = {
|
|
_init: function(actor) {
|
|
this.actor = actor;
|
|
},
|
|
|
|
set dimFraction(fraction) {
|
|
this._dimFraction = fraction;
|
|
let shader = getDimShader();
|
|
if (!Meta.prefs_get_attach_modal_dialogs() || !shader) {
|
|
this.actor.set_shader(null);
|
|
return;
|
|
}
|
|
if (fraction > 0.01) {
|
|
this.actor.set_shader(shader);
|
|
this.actor.set_shader_param_float('height', this.actor.get_height());
|
|
this.actor.set_shader_param_float('fraction', fraction);
|
|
} else
|
|
this.actor.set_shader(null);
|
|
},
|
|
|
|
get dimFraction() {
|
|
return this._dimFraction;
|
|
},
|
|
|
|
_dimFraction: 0.0
|
|
};
|
|
|
|
function getWindowDimmer(texture) {
|
|
if (!texture._windowDimmer)
|
|
texture._windowDimmer = new WindowDimmer(texture);
|
|
|
|
return texture._windowDimmer;
|
|
}
|
|
|
|
function WindowManager() {
|
|
this._init();
|
|
}
|
|
|
|
WindowManager.prototype = {
|
|
_init : function() {
|
|
this._shellwm = global.window_manager;
|
|
|
|
this._keyBindingHandlers = [];
|
|
this._minimizing = [];
|
|
this._maximizing = [];
|
|
this._unmaximizing = [];
|
|
this._mapping = [];
|
|
this._destroying = [];
|
|
|
|
this._dimmedWindows = [];
|
|
|
|
this._switchData = null;
|
|
this._shellwm.connect('kill-switch-workspace', Lang.bind(this, this._switchWorkspaceDone));
|
|
this._shellwm.connect('kill-window-effects', Lang.bind(this, function (shellwm, actor) {
|
|
this._minimizeWindowDone(shellwm, actor);
|
|
this._maximizeWindowDone(shellwm, actor);
|
|
this._unmaximizeWindowDone(shellwm, actor);
|
|
this._mapWindowDone(shellwm, actor);
|
|
this._destroyWindowDone(shellwm, actor);
|
|
}));
|
|
|
|
this._shellwm.connect('switch-workspace', Lang.bind(this, this._switchWorkspace));
|
|
this._shellwm.connect('minimize', Lang.bind(this, this._minimizeWindow));
|
|
this._shellwm.connect('maximize', Lang.bind(this, this._maximizeWindow));
|
|
this._shellwm.connect('unmaximize', Lang.bind(this, this._unmaximizeWindow));
|
|
this._shellwm.connect('map', Lang.bind(this, this._mapWindow));
|
|
this._shellwm.connect('destroy', Lang.bind(this, this._destroyWindow));
|
|
|
|
this._workspaceSwitcherPopup = null;
|
|
this.setKeybindingHandler('switch_to_workspace_left', Lang.bind(this, this._showWorkspaceSwitcher));
|
|
this.setKeybindingHandler('switch_to_workspace_right', Lang.bind(this, this._showWorkspaceSwitcher));
|
|
this.setKeybindingHandler('switch_to_workspace_up', Lang.bind(this, this._showWorkspaceSwitcher));
|
|
this.setKeybindingHandler('switch_to_workspace_down', Lang.bind(this, this._showWorkspaceSwitcher));
|
|
this.setKeybindingHandler('switch_windows', Lang.bind(this, this._startAppSwitcher));
|
|
|
|
Main.overview.connect('showing', Lang.bind(this, function() {
|
|
for (let i = 0; i < this._dimmedWindows.length; i++)
|
|
this._undimParentWindow(this._dimmedWindows[i], true);
|
|
}));
|
|
Main.overview.connect('hiding', Lang.bind(this, function() {
|
|
for (let i = 0; i < this._dimmedWindows.length; i++)
|
|
this._dimParentWindow(this._dimmedWindows[i], true);
|
|
}));
|
|
},
|
|
|
|
setKeybindingHandler: function(keybinding, handler){
|
|
if (this._keyBindingHandlers[keybinding])
|
|
this._shellwm.disconnect(this._keyBindingHandlers[keybinding]);
|
|
else
|
|
this._shellwm.takeover_keybinding(keybinding);
|
|
|
|
this._keyBindingHandlers[keybinding] =
|
|
this._shellwm.connect('keybinding::' + keybinding, handler);
|
|
},
|
|
|
|
_shouldAnimate : function(actor) {
|
|
if (Main.overview.visible)
|
|
return false;
|
|
if (actor && (actor.meta_window.get_window_type() != Meta.WindowType.NORMAL))
|
|
return false;
|
|
return true;
|
|
},
|
|
|
|
_removeEffect : function(list, actor) {
|
|
let idx = list.indexOf(actor);
|
|
if (idx != -1) {
|
|
list.splice(idx, 1);
|
|
return true;
|
|
}
|
|
return false;
|
|
},
|
|
|
|
_minimizeWindow : function(shellwm, actor) {
|
|
if (!this._shouldAnimate(actor)) {
|
|
shellwm.completed_minimize(actor);
|
|
return;
|
|
}
|
|
|
|
actor.set_scale(1.0, 1.0);
|
|
actor.move_anchor_point_from_gravity(Clutter.Gravity.CENTER);
|
|
|
|
/* scale window down to 0x0.
|
|
* maybe TODO: get icon geometry passed through and move the window towards it?
|
|
*/
|
|
this._minimizing.push(actor);
|
|
|
|
let primary = global.get_primary_monitor();
|
|
let xDest = primary.x;
|
|
if (St.Widget.get_default_direction() == St.TextDirection.RTL)
|
|
xDest += primary.width;
|
|
|
|
Tweener.addTween(actor,
|
|
{ scale_x: 0.0,
|
|
scale_y: 0.0,
|
|
x: xDest,
|
|
y: 0,
|
|
time: WINDOW_ANIMATION_TIME,
|
|
transition: 'easeOutQuad',
|
|
onComplete: this._minimizeWindowDone,
|
|
onCompleteScope: this,
|
|
onCompleteParams: [shellwm, actor],
|
|
onOverwrite: this._minimizeWindowOverwritten,
|
|
onOverwriteScope: this,
|
|
onOverwriteParams: [shellwm, actor]
|
|
});
|
|
},
|
|
|
|
_minimizeWindowDone : function(shellwm, actor) {
|
|
if (this._removeEffect(this._minimizing, actor)) {
|
|
Tweener.removeTweens(actor);
|
|
actor.set_scale(1.0, 1.0);
|
|
actor.move_anchor_point_from_gravity(Clutter.Gravity.NORTH_WEST);
|
|
|
|
shellwm.completed_minimize(actor);
|
|
}
|
|
},
|
|
|
|
_minimizeWindowOverwritten : function(shellwm, actor) {
|
|
if (this._removeEffect(this._minimizing, actor)) {
|
|
shellwm.completed_minimize(actor);
|
|
}
|
|
},
|
|
|
|
_maximizeWindow : function(shellwm, actor, targetX, targetY, targetWidth, targetHeight) {
|
|
shellwm.completed_maximize(actor);
|
|
},
|
|
|
|
_maximizeWindowDone : function(shellwm, actor) {
|
|
},
|
|
|
|
_maximizeWindowOverwrite : function(shellwm, actor) {
|
|
},
|
|
|
|
_unmaximizeWindow : function(shellwm, actor, targetX, targetY, targetWidth, targetHeight) {
|
|
shellwm.completed_unmaximize(actor);
|
|
},
|
|
|
|
_unmaximizeWindowDone : function(shellwm, actor) {
|
|
},
|
|
|
|
_parentHasOtherAttachedDialog: function(parent, self) {
|
|
var count = 0;
|
|
parent.foreach_transient(function(win) {
|
|
if (win.get_window_type() == Meta.WindowType.MODAL_DIALOG && win != self)
|
|
count++;
|
|
return false;
|
|
});
|
|
return count != 0;
|
|
},
|
|
|
|
_markParentWindowAsDimmable: function(actor, animate) {
|
|
if (Meta.prefs_get_attach_modal_dialogs()) {
|
|
this._dimmedWindows.push(actor);
|
|
if (this._shouldAnimate())
|
|
this._dimParentWindow(actor, animate);
|
|
}
|
|
},
|
|
|
|
_unmarkParentWindowAsDimmable: function(actor, animate) {
|
|
if (!Main.overview.visible)
|
|
this._undimParentWindow(actor, true);
|
|
this._dimmedWindows = this._dimmedWindows.filter(function(win) {
|
|
return win != actor;
|
|
});
|
|
},
|
|
|
|
_dimParentWindow: function(actor, animate) {
|
|
let meta = actor.get_meta_window();
|
|
let parent = meta.get_transient_for();
|
|
if (!parent)
|
|
return;
|
|
let parentActor = parent.get_compositor_private();
|
|
if (!parentActor || this._parentHasOtherAttachedDialog(parent, meta))
|
|
return;
|
|
let texture = parentActor.get_texture();
|
|
if (animate)
|
|
Tweener.addTween(getWindowDimmer(texture),
|
|
{ dimFraction: 1.0,
|
|
time: DIM_TIME,
|
|
transition: 'linear'
|
|
});
|
|
else
|
|
getWindowDimmer(texture).dimFraction = 1.0;
|
|
},
|
|
|
|
_undimParentWindow: function(actor, animate) {
|
|
let meta = actor.get_meta_window();
|
|
let parent = meta.get_transient_for();
|
|
if (!parent)
|
|
return;
|
|
let parentActor = parent.get_compositor_private();
|
|
if (!parentActor || this._parentHasOtherAttachedDialog(parent, meta))
|
|
return;
|
|
let texture = parentActor.get_texture();
|
|
if (animate)
|
|
Tweener.addTween(getWindowDimmer(texture),
|
|
{ dimFraction: 0.0,
|
|
time: UNDIM_TIME,
|
|
transition: 'linear'
|
|
});
|
|
else
|
|
getWindowDimmer(texture).dimFraction = 0.0;
|
|
},
|
|
|
|
_mapWindow : function(shellwm, actor) {
|
|
actor._windowType = actor.meta_window.get_window_type();
|
|
actor._notifyWindowTypeSignalId = actor.meta_window.connect('notify::window-type', Lang.bind(this, function () {
|
|
let type = actor.meta_window.get_window_type();
|
|
if (type == actor._windowType)
|
|
return;
|
|
if (type == Meta.WindowType.MODAL_DIALOG)
|
|
this._markParentWindowAsDimmable(actor, true);
|
|
else if (actor._windowType == Meta.WindowType.MODAL_DIALOG)
|
|
this._unmarkParentWindowAsDimmable(actor, true);
|
|
|
|
actor._windowType = type;
|
|
}));
|
|
if (actor.meta_window.get_window_type() == Meta.WindowType.MODAL_DIALOG
|
|
&& Meta.prefs_get_attach_modal_dialogs()
|
|
&& actor.get_meta_window().get_transient_for()) {
|
|
this._markParentWindowAsDimmable(actor, true);
|
|
if (this._shouldAnimate()) {
|
|
actor.set_scale(1.0, 0.0);
|
|
actor.show();
|
|
this._mapping.push(actor);
|
|
|
|
Tweener.addTween(actor,
|
|
{ scale_y: 1,
|
|
time: WINDOW_ANIMATION_TIME,
|
|
transition: "easeOutQuad",
|
|
onComplete: this._mapWindowDone,
|
|
onCompleteScope: this,
|
|
onCompleteParams: [shellwm, actor],
|
|
onOverwrite: this._mapWindowOverwrite,
|
|
onOverwriteScope: this,
|
|
onOverwriteParams: [shellwm, actor]
|
|
});
|
|
return;
|
|
}
|
|
shellwm.completed_map(actor);
|
|
return;
|
|
}
|
|
if (!this._shouldAnimate(actor)) {
|
|
shellwm.completed_map(actor);
|
|
return;
|
|
}
|
|
|
|
actor.opacity = 0;
|
|
actor.show();
|
|
|
|
/* Fade window in */
|
|
this._mapping.push(actor);
|
|
Tweener.addTween(actor,
|
|
{ opacity: 255,
|
|
time: WINDOW_ANIMATION_TIME,
|
|
transition: 'easeOutQuad',
|
|
onComplete: this._mapWindowDone,
|
|
onCompleteScope: this,
|
|
onCompleteParams: [shellwm, actor],
|
|
onOverwrite: this._mapWindowOverwrite,
|
|
onOverwriteScope: this,
|
|
onOverwriteParams: [shellwm, actor]
|
|
});
|
|
},
|
|
|
|
_mapWindowDone : function(shellwm, actor) {
|
|
if (this._removeEffect(this._mapping, actor)) {
|
|
Tweener.removeTweens(actor);
|
|
actor.opacity = 255;
|
|
shellwm.completed_map(actor);
|
|
}
|
|
},
|
|
|
|
_mapWindowOverwrite : function(shellwm, actor) {
|
|
if (this._removeEffect(this._mapping, actor)) {
|
|
shellwm.completed_map(actor);
|
|
}
|
|
},
|
|
|
|
_destroyWindow : function(shellwm, actor) {
|
|
let parent = actor.meta_window.get_transient_for();
|
|
if (actor._notifyWindowTypeSignalId) {
|
|
actor.meta_window.disconnect(actor._notifyWindowTypeSignalId);
|
|
actor._notifyWindowTypeSignalId = 0;
|
|
}
|
|
while (actor.meta_window.get_window_type() == Meta.WindowType.MODAL_DIALOG
|
|
&& parent) {
|
|
this._unmarkParentWindowAsDimmable(actor, true);
|
|
if (!Meta.prefs_get_attach_modal_dialogs()
|
|
|| !this._shouldAnimate())
|
|
break;
|
|
actor.set_scale(1.0, 1.0);
|
|
actor.show();
|
|
this._destroying.push(actor);
|
|
|
|
actor._parentDestroyId = parent.connect('unmanaged', Lang.bind(this, function () {
|
|
Tweener.removeTweens(actor);
|
|
this._destroyWindowDone(shellwm, actor);
|
|
}));
|
|
|
|
Tweener.addTween(actor,
|
|
{ scale_y: 0,
|
|
time: WINDOW_ANIMATION_TIME,
|
|
transition: "easeOutQuad",
|
|
onComplete: this._destroyWindowDone,
|
|
onCompleteScope: this,
|
|
onCompleteParams: [shellwm, actor],
|
|
onOverwrite: this._destroyWindowDone,
|
|
onOverwriteScope: this,
|
|
onOverwriteParams: [shellwm, actor]
|
|
});
|
|
return;
|
|
}
|
|
shellwm.completed_destroy(actor);
|
|
},
|
|
|
|
_destroyWindowDone : function(shellwm, actor) {
|
|
if (this._removeEffect(this._destroying, actor)) {
|
|
let parent = actor.get_meta_window().get_transient_for();
|
|
if (parent && actor._parentDestroyId) {
|
|
parent.disconnect(actor._parentDestroyId);
|
|
actor._parentDestroyId = 0;
|
|
}
|
|
shellwm.completed_destroy(actor);
|
|
}
|
|
},
|
|
|
|
_switchWorkspace : function(shellwm, from, to, direction) {
|
|
if (!this._shouldAnimate()) {
|
|
shellwm.completed_switch_workspace();
|
|
return;
|
|
}
|
|
|
|
let windows = global.get_window_actors();
|
|
|
|
/* @direction is the direction that the "camera" moves, so the
|
|
* screen contents have to move one screen's worth in the
|
|
* opposite direction.
|
|
*/
|
|
let xDest = 0, yDest = 0;
|
|
|
|
if (direction == Meta.MotionDirection.UP ||
|
|
direction == Meta.MotionDirection.UP_LEFT ||
|
|
direction == Meta.MotionDirection.UP_RIGHT)
|
|
yDest = global.screen_height;
|
|
else if (direction == Meta.MotionDirection.DOWN ||
|
|
direction == Meta.MotionDirection.DOWN_LEFT ||
|
|
direction == Meta.MotionDirection.DOWN_RIGHT)
|
|
yDest = -global.screen_height;
|
|
|
|
if (direction == Meta.MotionDirection.LEFT ||
|
|
direction == Meta.MotionDirection.UP_LEFT ||
|
|
direction == Meta.MotionDirection.DOWN_LEFT)
|
|
xDest = global.screen_width;
|
|
else if (direction == Meta.MotionDirection.RIGHT ||
|
|
direction == Meta.MotionDirection.UP_RIGHT ||
|
|
direction == Meta.MotionDirection.DOWN_RIGHT)
|
|
xDest = -global.screen_width;
|
|
|
|
let switchData = {};
|
|
this._switchData = switchData;
|
|
switchData.inGroup = new Clutter.Group();
|
|
switchData.outGroup = new Clutter.Group();
|
|
switchData.windows = [];
|
|
|
|
let wgroup = global.window_group;
|
|
wgroup.add_actor(switchData.inGroup);
|
|
wgroup.add_actor(switchData.outGroup);
|
|
|
|
for (let i = 0; i < windows.length; i++) {
|
|
let window = windows[i];
|
|
|
|
if (!window.meta_window.showing_on_its_workspace())
|
|
continue;
|
|
|
|
if (window.get_workspace() == from) {
|
|
switchData.windows.push({ window: window,
|
|
parent: window.get_parent() });
|
|
window.reparent(switchData.outGroup);
|
|
} else if (window.get_workspace() == to) {
|
|
switchData.windows.push({ window: window,
|
|
parent: window.get_parent() });
|
|
window.reparent(switchData.inGroup);
|
|
window.show_all();
|
|
}
|
|
}
|
|
|
|
switchData.inGroup.set_position(-xDest, -yDest);
|
|
switchData.inGroup.raise_top();
|
|
|
|
Tweener.addTween(switchData.outGroup,
|
|
{ x: xDest,
|
|
y: yDest,
|
|
time: WINDOW_ANIMATION_TIME,
|
|
transition: 'easeOutQuad',
|
|
onComplete: this._switchWorkspaceDone,
|
|
onCompleteScope: this,
|
|
onCompleteParams: [shellwm]
|
|
});
|
|
Tweener.addTween(switchData.inGroup,
|
|
{ x: 0,
|
|
y: 0,
|
|
time: WINDOW_ANIMATION_TIME,
|
|
transition: 'easeOutQuad'
|
|
});
|
|
},
|
|
|
|
_switchWorkspaceDone : function(shellwm) {
|
|
let switchData = this._switchData;
|
|
if (!switchData)
|
|
return;
|
|
this._switchData = null;
|
|
|
|
for (let i = 0; i < switchData.windows.length; i++) {
|
|
let w = switchData.windows[i];
|
|
if (w.window.is_destroyed()) // Window gone
|
|
continue;
|
|
if (w.window.get_parent() == switchData.outGroup) {
|
|
w.window.reparent(w.parent);
|
|
w.window.hide();
|
|
} else
|
|
w.window.reparent(w.parent);
|
|
}
|
|
Tweener.removeTweens(switchData.inGroup);
|
|
Tweener.removeTweens(switchData.outGroup);
|
|
switchData.inGroup.destroy();
|
|
switchData.outGroup.destroy();
|
|
|
|
shellwm.completed_switch_workspace();
|
|
},
|
|
|
|
_startAppSwitcher : function(shellwm, binding, window, backwards) {
|
|
/* prevent a corner case where both popups show up at once */
|
|
if (this._workspaceSwitcherPopup != null)
|
|
this._workspaceSwitcherPopup.actor.hide();
|
|
|
|
let tabPopup = new AltTab.AltTabPopup();
|
|
|
|
if (!tabPopup.show(backwards))
|
|
tabPopup.destroy();
|
|
},
|
|
|
|
_showWorkspaceSwitcher : function(shellwm, binding, window, backwards) {
|
|
if (global.screen.n_workspaces == 1)
|
|
return;
|
|
|
|
if (this._workspaceSwitcherPopup == null)
|
|
this._workspaceSwitcherPopup = new WorkspaceSwitcherPopup.WorkspaceSwitcherPopup();
|
|
|
|
if (binding == 'switch_to_workspace_up')
|
|
this.actionMoveWorkspaceUp();
|
|
else if (binding == 'switch_to_workspace_down')
|
|
this.actionMoveWorkspaceDown();
|
|
// left/right would effectively act as synonyms for up/down if we enabled them;
|
|
// but that could be considered confusing.
|
|
// else if (binding == 'switch_to_workspace_left')
|
|
// this.actionMoveWorkspaceLeft();
|
|
// else if (binding == 'switch_to_workspace_right')
|
|
// this.actionMoveWorkspaceRight();
|
|
},
|
|
|
|
actionMoveWorkspaceLeft: function() {
|
|
let rtl = (St.Widget.get_default_direction() == St.TextDirection.RTL);
|
|
let activeWorkspaceIndex = global.screen.get_active_workspace_index();
|
|
let indexToActivate = activeWorkspaceIndex;
|
|
if (rtl && activeWorkspaceIndex < global.screen.n_workspaces - 1)
|
|
indexToActivate++;
|
|
else if (!rtl && activeWorkspaceIndex > 0)
|
|
indexToActivate--;
|
|
|
|
if (indexToActivate != activeWorkspaceIndex)
|
|
global.screen.get_workspace_by_index(indexToActivate).activate(global.get_current_time());
|
|
|
|
if (!Main.overview.visible)
|
|
this._workspaceSwitcherPopup.display(WorkspaceSwitcherPopup.LEFT, indexToActivate);
|
|
},
|
|
|
|
actionMoveWorkspaceRight: function() {
|
|
let rtl = (St.Widget.get_default_direction() == St.TextDirection.RTL);
|
|
let activeWorkspaceIndex = global.screen.get_active_workspace_index();
|
|
let indexToActivate = activeWorkspaceIndex;
|
|
if (rtl && activeWorkspaceIndex > 0)
|
|
indexToActivate--;
|
|
else if (!rtl && activeWorkspaceIndex < global.screen.n_workspaces - 1)
|
|
indexToActivate++;
|
|
|
|
if (indexToActivate != activeWorkspaceIndex)
|
|
global.screen.get_workspace_by_index(indexToActivate).activate(global.get_current_time());
|
|
|
|
if (!Main.overview.visible)
|
|
this._workspaceSwitcherPopup.display(WorkspaceSwitcherPopup.RIGHT, indexToActivate);
|
|
},
|
|
|
|
actionMoveWorkspaceUp: function() {
|
|
let activeWorkspaceIndex = global.screen.get_active_workspace_index();
|
|
let indexToActivate = activeWorkspaceIndex;
|
|
if (activeWorkspaceIndex > 0)
|
|
indexToActivate--;
|
|
|
|
if (indexToActivate != activeWorkspaceIndex)
|
|
global.screen.get_workspace_by_index(indexToActivate).activate(global.get_current_time());
|
|
|
|
if (!Main.overview.visible)
|
|
this._workspaceSwitcherPopup.display(WorkspaceSwitcherPopup.LEFT, indexToActivate);
|
|
},
|
|
|
|
actionMoveWorkspaceDown: function() {
|
|
let activeWorkspaceIndex = global.screen.get_active_workspace_index();
|
|
let indexToActivate = activeWorkspaceIndex;
|
|
if (activeWorkspaceIndex < global.screen.n_workspaces - 1)
|
|
indexToActivate++;
|
|
|
|
if (indexToActivate != activeWorkspaceIndex)
|
|
global.screen.get_workspace_by_index(indexToActivate).activate(global.get_current_time());
|
|
|
|
if (!Main.overview.visible)
|
|
this._workspaceSwitcherPopup.display(WorkspaceSwitcherPopup.RIGHT, indexToActivate);
|
|
}
|
|
};
|