diff --git a/README.md b/README.md index 2604384..a9087e7 100644 --- a/README.md +++ b/README.md @@ -55,11 +55,12 @@ PaperWM doesn't handle attached modal dialogs very well, so it's best to turn it | SuperCtrl, or SuperCtrl. | Move the current window to the left or right | | SuperCtrlLeft or SuperCtrlRight | Move the current window to the left or right | | SuperCtrlUp or SuperCtrlDown | Move the current window up or down | +| Supert | Take the window, placing it when finished navigating | | SuperTab or AltTab | Cycle through the most recently used windows | | SuperShiftTab or AltShiftTab | Cycle backwards through the most recently used windows | | SuperC | Center the active window horizontally | | SuperR | Resize the window (cycles through useful widths) | -| SuperShiftR | Resize the window (cycles through useful heights) | +| SuperShiftR | Resize the window (cycles through useful heights) | | SuperF | Maximize the width of a window | | SuperShiftF | Toggle fullscreen | | SuperReturn or SuperN | Create a new window from the active application | diff --git a/keybindings.js b/keybindings.js index d80d3f8..8ba4a40 100644 --- a/keybindings.js +++ b/keybindings.js @@ -80,6 +80,8 @@ function init() { registerNavigatorAction('move-previous-workspace-backward', Tiling.movePreviousSpaceBackwards); + registerNavigatorAction('take-window', Tiling.takeWindow); + registerMinimapAction("switch-next", (mw, space) => space.switchLinear(1)); registerMinimapAction("switch-previous", (mw, space) => space.switchLinear(-1)); diff --git a/prefs.js b/prefs.js index 7fffc6d..5acc0b1 100644 --- a/prefs.js +++ b/prefs.js @@ -165,7 +165,7 @@ class SettingsWidget { 'move-left', 'move-right', 'move-up', 'move-down', 'slurp-in', 'barf-out', 'center-horizontally', 'paper-toggle-fullscreen', 'toggle-maximize-width', 'cycle-width', - 'cycle-height'] + 'cycle-height', 'take-window'] .forEach(k => { addKeybinding(windows.model.child_model, settings, k); }); diff --git a/schemas/gschemas.compiled b/schemas/gschemas.compiled index 2fb3064..ffff2cb 100644 Binary files a/schemas/gschemas.compiled and b/schemas/gschemas.compiled differ diff --git a/schemas/org.gnome.shell.extensions.org-scrollwm.gschema.xml b/schemas/org.gnome.shell.extensions.org-scrollwm.gschema.xml index 2be67e1..bf75cf9 100644 --- a/schemas/org.gnome.shell.extensions.org-scrollwm.gschema.xml +++ b/schemas/org.gnome.shell.extensions.org-scrollwm.gschema.xml @@ -47,6 +47,11 @@ Attach/detach the active window into the scratch layer + + t']]]> + Take the window, dropping it when finished navigating + + period']]]> Switch to the next window diff --git a/tiling.js b/tiling.js index 7d8d28d..841f13a 100644 --- a/tiling.js +++ b/tiling.js @@ -1012,7 +1012,6 @@ class Spaces extends Map { this.clickOverlays = []; this.signals = new utils.Signals(); this.stack = []; - this._moving = []; let spaceContainer = new Clutter.Actor({name: 'spaceContainer'}); spaceContainer.hide(); this.spaceContainer = spaceContainer; @@ -1386,45 +1385,24 @@ class Spaces extends Map { let newSpace = this.selectedSpace; let to = from; if (move && this.selectedSpace.selectedWindow) { - let moving = this.selectedSpace.selectedWindow; - this._moving.push(moving); - - this.selectedSpace.removeWindow(moving); - let actor = moving.get_compositor_private(); - backgroundGroup.add_actor(moving.clone); - let lowest = this._moving[this._moving.length - 2]; - lowest && backgroundGroup.set_child_below_sibling(moving.clone, lowest.clone); - let point = this.selectedSpace.cloneContainer.apply_relative_transform_to_point( - backgroundGroup, new Clutter.Vertex({x: moving.clone.x, - y: moving.clone.y})); - moving.clone.set_position(point.x, point.y); - let x = Math.round(space.monitor.x + - space.monitor.width - - (0.1*space.monitor.width*(1 +this._moving.length))); - let y = Math.round(space.monitor.y + space.monitor.height*2/3) - + 20*this._moving.length; - moving.move_frame(true, x, y); - animateWindow(moving); - Tweener.addTween(moving.clone, - {x, y, - time: prefs.animation_time, - transition - }); - } else { - if (direction === Meta.MotionDirection.DOWN) - to = from + 1; - else - to = from - 1; - if (to < 0 || to >= mru.length) { - to = from; - } - if (to === from && Tweener.getTweenCount(newSpace.actor) > 0) - return; - - newSpace = mru[to]; - this.selectedSpace = newSpace; + takeWindow(this.selectedSpace.selectedWindow, + this.selectedSpace, + {navigator: Navigator.getNavigator()}); } + if (direction === Meta.MotionDirection.DOWN) + to = from + 1; + else + to = from - 1; + if (to < 0 || to >= mru.length) { + to = from; + } + if (to === from && Tweener.getTweenCount(newSpace.actor) > 0) + return; + + newSpace = mru[to]; + this.selectedSpace = newSpace; + TopBar.updateWorkspaceIndicator(newSpace.workspace.index()); mru.forEach((space, i) => { @@ -1462,14 +1440,6 @@ class Spaces extends Map { inPreview = false; TopBar.updateWorkspaceIndicator(to.workspace.index()); - this._moving.reverse().forEach(w => { - w.change_workspace(to.workspace); - if (w.get_workspace() === to.workspace) { - insertWindow(w, {existing: true}); - } - }); - this._moving = []; - this.selectedSpace = to; to.actor.show(); @@ -2571,3 +2541,52 @@ function movePreviousSpace(mw, space) { function movePreviousSpaceBackwards(mw, space) { spaces.selectSpace(Meta.MotionDirection.UP, true); } + +/** + Detach the @metaWindow, storing it at the bottom right corner while + navigating. When done, insert all the detached windows again. + */ +function takeWindow(metaWindow, space, {navigator}) { + space = space || spaces.selectedSpace; + metaWindow = metaWindow || space.selectedWindow; + navigator = navigator || Navigator.getNavigator(); + if (!space.removeWindow(metaWindow)) + return; + + if (!navigator._movingId) { + navigator._moving = []; + let id = navigator.connect('destroy', () => { + navigator.disconnect(id); + let space = spaces.selectedSpace; + navigator._moving.reverse().forEach(w => { + w.change_workspace(space.workspace); + if (w.get_workspace() === space.workspace) { + insertWindow(w, {existing: true}); + } + }); + }); + } + + navigator._moving.push(metaWindow); + let parent = backgroundGroup; + let actor = metaWindow.get_compositor_private(); + parent.add_actor(metaWindow.clone); + let lowest = navigator._moving[navigator._moving.length - 2]; + lowest && parent.set_child_below_sibling(metaWindow.clone, lowest.clone); + let point = space.cloneContainer.apply_relative_transform_to_point( + parent, new Clutter.Vertex({x: metaWindow.clone.x, + y: metaWindow.clone.y})); + metaWindow.clone.set_position(point.x, point.y); + let x = Math.round(space.monitor.x + + space.monitor.width - + (0.1*space.monitor.width*(1 +navigator._moving.length))); + let y = Math.round(space.monitor.y + space.monitor.height*2/3) + + 20*navigator._moving.length; + metaWindow.move_frame(true, x, y); + animateWindow(metaWindow); + Tweener.addTween(metaWindow.clone, + {x, y, + time: prefs.animation_time, + transition: 'easeInOutQuad', + }); +}