diff --git a/keybindings.js b/keybindings.js
index efe18151..5c127117 100644
--- a/keybindings.js
+++ b/keybindings.js
@@ -227,6 +227,23 @@ export function setupActions(settings) {
registerMinimapAction("switch-global-up", (mw, space) => space.switchGlobalUp());
registerMinimapAction("switch-global-down", (mw, space) => space.switchGlobalDown());
+ registerAction("move-global-right",
+ (mw, space) => space.moveGlobal(mw, Meta.MotionDirection.RIGHT),
+ { settings, mutterFlags: Meta.KeyBindingFlags.PER_WINDOW }
+ );
+ registerAction("move-global-left",
+ (mw, space) => space.moveGlobal(mw, Meta.MotionDirection.LEFT),
+ { settings, mutterFlags: Meta.KeyBindingFlags.PER_WINDOW }
+ );
+ registerAction("move-global-up",
+ (mw, space) => space.moveGlobal(mw, Meta.MotionDirection.UP),
+ { settings, mutterFlags: Meta.KeyBindingFlags.PER_WINDOW }
+ );
+ registerAction("move-global-down",
+ (mw, space) => space.moveGlobal(mw, Meta.MotionDirection.DO),
+ { settings, mutterFlags: Meta.KeyBindingFlags.PER_WINDOW }
+ );
+
registerMinimapAction("move-left",
(_mw, space) => space.swap(Meta.MotionDirection.LEFT));
registerMinimapAction("move-right",
diff --git a/prefsKeybinding.js b/prefsKeybinding.js
index c74d5362..63e2aeb4 100644
--- a/prefsKeybinding.js
+++ b/prefsKeybinding.js
@@ -39,6 +39,10 @@ const actions = {
'switch-global-right',
'switch-global-up',
'switch-global-down',
+ 'move-global-left',
+ 'move-global-right',
+ 'move-global-up',
+ 'move-global-down',
'switch-up-or-else-workspace',
'switch-down-or-else-workspace',
'switch-first',
diff --git a/schemas/gschemas.compiled b/schemas/gschemas.compiled
index 484bc328..89758b2f 100644
Binary files a/schemas/gschemas.compiled and b/schemas/gschemas.compiled differ
diff --git a/schemas/org.gnome.shell.extensions.paperwm.gschema.xml b/schemas/org.gnome.shell.extensions.paperwm.gschema.xml
index 1819e96b..b4c8f55f 100644
--- a/schemas/org.gnome.shell.extensions.paperwm.gschema.xml
+++ b/schemas/org.gnome.shell.extensions.paperwm.gschema.xml
@@ -285,6 +285,22 @@
Switch to window or monitor below
+
+
+ Move active window to the next spot or monitor to the right
+
+
+
+ Move active window to the next spot or monitor to the left
+
+
+
+ Move active window to the next spot or monitor above
+
+
+
+ Move active window to the next spot or monitor below
+
Switch to window or workspace above
diff --git a/tiling.js b/tiling.js
index ce182fee..8b2ae8bb 100644
--- a/tiling.js
+++ b/tiling.js
@@ -1094,6 +1094,33 @@ export class Space extends Array {
ensureViewport(this.selectedWindow, this, { force: true });
}
+ moveToStart(metaWindow) {
+ metaWindow = metaWindow || this.selectedWindow;
+
+ let [index, row] = this.positionOf(metaWindow);
+ if (index == 0) return;
+
+ let [it] = this.splice(index, 1);
+ this.unshift(it);
+ this.layout();
+ this.emit("swapped", index, 0, row, row);
+ ensureViewport(this.selectedWindow, this, { force: true });
+ }
+
+ moveToEnd(metaWindow) {
+ metaWindow = metaWindow || this.selectedWindow;
+
+ let [index, row] = this.positionOf(metaWindow);
+ let targetIndex = this.length-1;
+ if (index == targetIndex) return;
+
+ let [it] = this.splice(index, 1);
+ this.push(it);
+ this.layout();
+ this.emit("swapped", index, 0, row, row);
+ ensureViewport(this.selectedWindow, this, { force: true });
+ }
+
switchLinear(dir, loop) {
let index = this.selectedIndex();
let column = this[index];
@@ -1262,6 +1289,65 @@ export class Space extends Array {
ensureViewport(metaWindow, space);
}
+ moveGlobal(metaWindow, direction) {
+ let space = this;
+ let index = space.selectedIndex();
+ if (index === -1) {
+ return;
+ }
+
+ let column = space[index];
+ let row = column.indexOf(metaWindow);
+ if (row === -1) {
+ let selected = sortWindows(this, column)[column.length - 1];
+ row = column.indexOf(selected);
+ }
+
+ switch (direction) {
+ case Meta.MotionDirection.LEFT:
+ if (index > 0) {
+ space.swap(direction, metaWindow);
+ return;
+ } else {
+ let new_space = spaces.switchMonitor(Meta.DisplayDirection.LEFT, true);
+ if (new_space != null) {
+ new_space.moveToEnd(metaWindow);
+ }
+ return;
+ }
+
+ case Meta.MotionDirection.RIGHT:
+ if (index < space.length-1) {
+ space.swap(direction);
+ return;
+ } else {
+ let new_space = spaces.switchMonitor(Meta.DisplayDirection.RIGHT, true);
+ if (new_space != null) {
+ new_space.moveToStart(metaWindow);
+ }
+ return;
+ }
+
+ case Meta.MotionDirection.UP:
+ if (row > 0) {
+ space.swap(direction);
+ return;
+ } else {
+ spaces.switchMonitor(Meta.DisplayDirection.UP, true);
+ return;
+ }
+
+ case Meta.MotionDirection.DOWN:
+ if (row < column.length-1) {
+ space.swap(direction);
+ return;
+ } else {
+ spaces.switchMonitor(Meta.DisplayDirection.DOWN, true);
+ return;
+ }
+ }
+ }
+
_drift(dx) {
if (dx === 0) {
return;
@@ -2542,7 +2628,7 @@ export const Spaces = class Spaces extends Map {
let currentSpace = this.monitors.get(monitor);
let i = display.get_monitor_neighbor_index(monitor.index, direction);
if (i === -1)
- return;
+ return null;
let newMonitor = Main.layoutManager.monitors[i];
if (warp) {
Utils.warpPointerToMonitor(newMonitor);
@@ -2575,6 +2661,7 @@ export const Spaces = class Spaces extends Map {
} else {
space.activate(false, false);
}
+ return space;
}
moveToMonitor(direction, backDirection) {