Skip to content
Draft
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions keybindings.js
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,15 @@ export function setupActions(settings) {
registerMinimapAction("move-down",
(_mw, space) => space.swap(Meta.MotionDirection.DOWN));

registerMinimapAction("move-global-left",
(_mw, space) => space.swapGlobal(Meta.MotionDirection.LEFT));
registerMinimapAction("move-global-right",
(_mw, space) => space.swapGlobal(Meta.MotionDirection.RIGHT));
registerMinimapAction("move-global-up",
(_mw, space) => space.swapGlobal(Meta.MotionDirection.UP));
registerMinimapAction("move-global-down",
(_mw, space) => space.swapGlobal(Meta.MotionDirection.DOWN));

registerPaperAction("toggle-scratch-window",
Scratch.toggleScratchWindow);

Expand Down
4 changes: 4 additions & 0 deletions prefsKeybinding.js
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,10 @@ const actions = {
'move-right',
'move-up',
'move-down',
'move-global-left',
'move-global-right',
'move-global-up',
'move-global-down',
'slurp-in',
'barf-out',
'barf-out-active',
Expand Down
Binary file modified schemas/gschemas.compiled
Binary file not shown.
21 changes: 19 additions & 2 deletions schemas/org.gnome.shell.extensions.paperwm.gschema.xml
Original file line number Diff line number Diff line change
Expand Up @@ -347,11 +347,11 @@

<key type="as" name="move-right">
<default><![CDATA[['<Super><Ctrl>period', '<Super><Shift>period', '<Super><Ctrl>Right']]]></default>
<summary>Move the active window to the right</summary>
<summary>Move the active window to the right, staying on the same monitor</summary>
</key>
<key type="as" name="move-left">
<default><![CDATA[['<Super><Ctrl>comma', '<Super><Shift>comma', '<Super><Ctrl>Left']]]></default>
<summary>Move the active window to the left</summary>
<summary>Move the active window to the left, staying on the same monitor</summary>
</key>
<key type="as" name="move-up">
<default><![CDATA[['<Super><Ctrl>Up']]]></default>
Expand All @@ -362,6 +362,23 @@
<summary>Move the active window down</summary>
</key>

<key type="as" name="move-global-right">
<default><![CDATA[[]]]></default>
<summary>Move the active window to the right</summary>
</key>
<key type="as" name="move-global-left">
<default><![CDATA[[]]]></default>
<summary>Move the active window to the left</summary>
</key>
<key type="as" name="move-global-up">
<default><![CDATA[[]]]></default>
<summary>Move the active window up or to the workspace above</summary>
</key>
<key type="as" name="move-global-down">
<default><![CDATA[[]]]></default>
<summary>Move the active window down or to the workspace below</summary>
</key>

<key type="as" name="slurp-in">
<default><![CDATA[['<Super>i']]]></default>
<summary>Consume window into the active column</summary>
Expand Down
105 changes: 95 additions & 10 deletions tiling.js
Original file line number Diff line number Diff line change
Expand Up @@ -1095,6 +1095,45 @@ export class Space extends Array {
ensureViewport(this.selectedWindow, this, { force: true });
}

swapGlobal(direction, metaWindow) {
metaWindow = metaWindow || this.selectedWindow;

let [index, row] = this.positionOf(metaWindow);
let targetIndex = index;
let targetRow = row;
const dir = Utils.motionToDisplayDirection[direction];
switch (direction) {
case Meta.MotionDirection.LEFT:
targetIndex--;
break;
case Meta.MotionDirection.RIGHT:
targetIndex++;
break;
case Meta.MotionDirection.DOWN:
targetRow++;
break;
case Meta.MotionDirection.UP:
targetRow--;
break;
}
if (targetIndex < 0 || targetIndex >= this.length) {
spaces.switchMonitor(dir, true, true, metaWindow);
return;
}
let column = this[index];
if (targetRow < 0 || targetRow >= column.length) {
// TODO: Move to workspace above/below
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I need to give more thought to how switching up/down should work when there is a monitor above.

return;
}

Lib.swap(this[index], row, targetRow);
Lib.swap(this, index, targetIndex);

this.layout();
this.emit('swapped', index, targetIndex, row, targetRow);
ensureViewport(this.selectedWindow, this, { force: true });
}

switchLinear(dir, loop) {
let index = this.selectedIndex();
let column = this[index];
Expand Down Expand Up @@ -1190,13 +1229,8 @@ export class Space extends Array {
switchGlobalUp() { this.switchGlobal(Meta.MotionDirection.UP); }
switchGlobalDown() { this.switchGlobal(Meta.MotionDirection.DOWN); }
switchGlobal(direction) {
const motionToDisplayDirection = {
[Meta.MotionDirection.LEFT]: Meta.DisplayDirection.LEFT,
[Meta.MotionDirection.RIGHT]: Meta.DisplayDirection.RIGHT,
[Meta.MotionDirection.UP]: Meta.DisplayDirection.UP,
[Meta.MotionDirection.DOWN]: Meta.DisplayDirection.DOWN,
};
const dir = motionToDisplayDirection[direction]
const dir = Utils.motionToDisplayDirection[direction];

let space = this;

const switchMonitor = () => {
Expand Down Expand Up @@ -2566,8 +2600,10 @@ export const Spaces = class Spaces extends Map {
return nSpaces <= nMonitors;
}

switchMonitor(direction, move, warp = true) {
let focus = display.focus_window;
switchMonitor(direction, move, warp = true, focus = null) {
// For unkown reasons, display.focus_window is null if you are in the
// middle of moving a winodw, aka if navigation is open.
focus = focus ?? display.focus_window;
let monitor = focusMonitor();
let currentSpace = this.monitors.get(monitor);
let i = display.get_monitor_neighbor_index(monitor.index, direction);
Expand All @@ -2580,6 +2616,12 @@ export const Spaces = class Spaces extends Map {
let space = this.monitors.get(newMonitor);

if (move && focus) {
const customIndex = getMoveWindowPositionIndex(space, direction);
if (customIndex !== null) {
// namespaced prop to avoid possible future collisions
focus.paperwm_openAtIndex = customIndex;
}

let metaWindow = focus.get_transient_for() || focus;

if (currentSpace && currentSpace.indexOf(metaWindow) !== -1) {
Expand Down Expand Up @@ -4164,7 +4206,13 @@ Opening "${metaWindow?.title}" on current space.`);
}
ok && clone.set_position(x, y);

if (!space.addWindow(metaWindow, getOpenWindowPositionIndex(space)))
// When moving a window from another monitor, we may request a certain index
const openAtIndex = metaWindow.paperwm_openAtIndex ?? getOpenWindowPositionIndex(space);
if (metaWindow.paperwm_openAtIndex) {
delete metaWindow.paperwm_openAtIndex;
}

if (!space.addWindow(metaWindow, openAtIndex))
return;

metaWindow.unmake_above();
Expand Down Expand Up @@ -4267,6 +4315,43 @@ Opening "${metaWindow?.title}" on current space.`);
}
}

/**
* When we're moving a window from an existing monitor, we want to insert with
* minimal disruption. E.g. if we're moving window E to the left,
*
* ([a b] c d) ([E f])
* (a [b E] c d) ([f])
*
* so that visually it looks like this:
*
* [a b] [E f]
* [b E] [f g]
*
* regardless of the setting for inserting new windows.
*/
function getMoveWindowPositionIndex(space, direction) {
const visibleColumns = space.filter(([mw]) => space.isVisible(mw));

if (visibleColumns.length === 0) {
return null;
}

switch (direction) {
case Meta.DisplayDirection.LEFT: {
const windowAtTarget = visibleColumns[visibleColumns.length - 1][0];
return space.indexOf(windowAtTarget) + 1;
break;
}
case Meta.DisplayDirection.RIGHT: {
const windowAtTarget = visibleColumns[0][0];
return space.indexOf(windowAtTarget);
}
default:
// No special handling yet for moving up/down
return null;
}
}

/**
* Gets the window index to add a new window in the space:
* { RIGHT: 0, LEFT: 1, START: 2, END: 3 };
Expand Down
7 changes: 7 additions & 0 deletions utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,13 @@ export function setBackgroundImage(actor, resource_path) {
actor.content_repeat = Clutter.ContentRepeat.BOTH;
}

export const motionToDisplayDirection = {
[Meta.MotionDirection.LEFT]: Meta.DisplayDirection.LEFT,
[Meta.MotionDirection.RIGHT]: Meta.DisplayDirection.RIGHT,
[Meta.MotionDirection.UP]: Meta.DisplayDirection.UP,
[Meta.MotionDirection.DOWN]: Meta.DisplayDirection.DOWN,
};

/**
* Backwards compatible function. Attempts to use Cogl.Color with a fallback
* to Clutter.Color.
Expand Down