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) {