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',
+ });
+}