From f23adb82e5fd1465994f7db77465c00d0a811803 Mon Sep 17 00:00:00 2001 From: Jay Ta'ala Date: Mon, 12 Aug 2024 21:07:32 +1000 Subject: [PATCH 1/5] Implemented ability to drop windows up/down. Updated descriptions for create/drop windows. --- ...gnome.shell.extensions.paperwm.gschema.xml | 14 ++-- tiling.js | 65 +++++++++++-------- 2 files changed, 45 insertions(+), 34 deletions(-) diff --git a/schemas/org.gnome.shell.extensions.paperwm.gschema.xml b/schemas/org.gnome.shell.extensions.paperwm.gschema.xml index d4d5cf3f..531272b2 100644 --- a/schemas/org.gnome.shell.extensions.paperwm.gschema.xml +++ b/schemas/org.gnome.shell.extensions.paperwm.gschema.xml @@ -182,31 +182,31 @@ w']]]> - Switch between positions for creating windows (e.g. right, left) + Switch between positions for creating/dropping windows - Create new windows to the right + Create/drop windows to the right - Create new windows to the left + Create/drop windows to the left - Create new windows in vertical stack (down) + Create/drop windows in vertical stack (down) - Create new windows in vertical stack (up) + Create/drop windows in vertical stack (up) - Create new windows at start position + Create/drop windows at start position - Create new windows at end position + Create/drop windows at end position diff --git a/tiling.js b/tiling.js index 0ca4ac66..0ada5016 100644 --- a/tiling.js +++ b/tiling.js @@ -3964,7 +3964,10 @@ export function add_handler(_ws, metaWindow) { and `Display::window-created` through `WindowActor::show` if window is newly created to ensure that the WindowActor exists. */ -export function insertWindow(metaWindow, { existing }) { +export function insertWindow(metaWindow, options = {}) { + const existing = options?.existing ?? false; + const dropping = options?.dropping ?? false; + // Add newly created windows to the space being previewed if (!existing && !metaWindow.is_on_all_workspaces() && @@ -4096,6 +4099,29 @@ export function insertWindow(metaWindow, { existing }) { // run a simple layout in pre-prepare layout space.layout(false); + const slurpCheck = () => { + let slurpPosition; + switch (Settings.prefs.open_window_position) { + case Settings.OpenWindowPositions.DOWN: + slurpPosition = SlurpInsertPosition.BELOW; + break; + case Settings.OpenWindowPositions.UP: + slurpPosition = SlurpInsertPosition.ABOVE; + break; + } + + // if need to slurp (i.e. vertical stack) + if (slurpPosition) { + stackSlurpTimeout = GLib.timeout_add( + GLib.PRIORITY_DEFAULT, + 100, + () => { + slurp(active, slurpPosition); + return false; // on return false destroys timeout + }); + } + }; + /** * If window is new, then setup and ensure is in view * after actor is shown on stage. @@ -4118,26 +4144,7 @@ export function insertWindow(metaWindow, { existing }) { ensureViewport(space.selectedWindow, space); space.setSpaceTopbarElementsVisible(true); - let slurpPosition; - switch (Settings.prefs.open_window_position) { - case Settings.OpenWindowPositions.DOWN: - slurpPosition = SlurpInsertPosition.BELOW; - break; - case Settings.OpenWindowPositions.UP: - slurpPosition = SlurpInsertPosition.ABOVE; - break; - } - - // if need to slurp (i.e. vertical stack) - if (slurpPosition) { - stackSlurpTimeout = GLib.timeout_add( - GLib.PRIORITY_DEFAULT, - 100, - () => { - slurp(active, slurpPosition); - return false; // on return false destroys timeout - }); - } + slurpCheck(); }); return; @@ -4152,6 +4159,10 @@ export function insertWindow(metaWindow, { existing }) { } else { ensureViewport(space.selectedWindow, space); } + + if (dropping) { + slurpCheck(); + } } /** @@ -5299,11 +5310,11 @@ export function moveUpSpace(_mw, _space) { Detach the @metaWindow, storing it at the bottom right corner while navigating. When done, insert all the detached windows again. */ -export function takeWindow(metaWindow, space, params) { +export function takeWindow(metaWindow, space, options = {}) { space = space ?? spaces.selectedSpace; metaWindow = metaWindow ?? space.selectedWindow; - const navigator = params?.navigator ?? Navigator.getNavigator(); - const existing = params?.existing ?? false; + const navigator = options?.navigator ?? Navigator.getNavigator(); + const existing = options?.existing ?? false; if (!existing && !space.removeWindow(metaWindow)) return; @@ -5375,7 +5386,7 @@ export function takeWindow(metaWindow, space, params) { const pop = navigator._moving.pop(); if (pop) { changeSpace(pop); - insertWindow(pop, { existing: true }); + insertWindow(pop, { existing: true, dropping: true }); // make space selectedWindow (keeps index for next insert) selectedSpace().selectedWindow = pop; ensureViewport(pop); @@ -5400,7 +5411,7 @@ export function takeWindow(metaWindow, space, params) { case Clutter.KEY_q: { navigator._moving.forEach(w => { changeSpace(w); - insertWindow(w, { existing: true }); + insertWindow(w, { existing: true, dropping: true }); w.delete(global.get_current_time()); }); @@ -5421,7 +5432,7 @@ export function takeWindow(metaWindow, space, params) { let selectedSpace = spaces.selectedSpace; navigator._moving.forEach(w => { changeSpace(w); - insertWindow(w, { existing: true }); + insertWindow(w, { existing: true, dropping: true }); // make space selectedWindow (keeps index for next insert) selectedSpace.selectedWindow = w; From 1345775cbb8336c639efd4b4d2479188b0ef7e63 Mon Sep 17 00:00:00 2001 From: Jay Ta'ala Date: Mon, 12 Aug 2024 21:19:44 +1000 Subject: [PATCH 2/5] Updated README.md. --- README.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 19b289af..17d25e97 100644 --- a/README.md +++ b/README.md @@ -95,13 +95,13 @@ Swiping the trackpad horizontally with three fingers (only available in Wayland) | CtrlAltTab | Cycle through previously active scratch windows | | ShiftCtrlAltTab | Cycle through previously active scratch windows (backward order) | | ShiftSuperC | Switch between window focus modes | -| ShiftSuperW | Switch between positions for creating new windows | -| _Not set by default (set in extension settings)_ | Create new windows to the right of current window | -| _Not set by default (set in extension settings)_ | Create new windows to the left of current window | -| _Not set by default (set in extension settings)_ | Create new windows in vertical stack (down) | -| _Not set by default (set in extension settings)_ | Create new windows in vertical stack (up) | -| _Not set by default (set in extension settings)_ | Create new windows at start position | -| _Not set by default (set in extension settings)_ | Create new windows at end position | +| ShiftSuperW | Switch between positions for creating/dropping new windows | +| _Not set by default (set in extension settings)_ | Create/drop windows to the right of current window | +| _Not set by default (set in extension settings)_ | Create/drop windows to the left of current window | +| _Not set by default (set in extension settings)_ | Create/drop windows in vertical stack (down) | +| _Not set by default (set in extension settings)_ | Create/drop windows in vertical stack (up) | +| _Not set by default (set in extension settings)_ | Create/drop windows at start position | +| _Not set by default (set in extension settings)_ | Create/drop windows at end position | | SuperCtrl, or SuperCtrl. | Move the current window to the left or right | | ShiftSuper, or ShiftSuper. | Move the current window to the left or right | | SuperCtrlLeft or SuperCtrlRight | Move the current window to the left or right | @@ -280,9 +280,9 @@ You do this by using the special "match all" operator `*` as an input for `wm_cl This special operator is at a lower precedence, so more specific properties that match a window will always take precedence and be applied. -## Window insertion position for new windows +## Window insertion position for new windows (and dropped windows in `take` mode) -By default PaperWM inserts new windows to the right of the currently active window. This behaviour can be changed via PaperWM settings, or with the `Open Window Position` button/icon (which is to the right of the focus mode icon): +By default PaperWM inserts new windows (and drops windows in `take` mode, see [Managing multiple windows at once](#managing-multiple-windows-at-once)) to the right of the currently active window. This behaviour can be changed via PaperWM settings, or with the `Open Window Position` button/icon (which is to the right of the focus mode icon): ![Open positions button](media/open-position-button.png) From 0a6be863f054e5de0b394162aabf3026a20c353e Mon Sep 17 00:00:00 2001 From: Jay Ta'ala Date: Mon, 12 Aug 2024 21:51:10 +1000 Subject: [PATCH 3/5] FIX: for delete windows, in slurpCheck, if no space, return gracefully. --- tiling.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tiling.js b/tiling.js index 0ada5016..c4c8f907 100644 --- a/tiling.js +++ b/tiling.js @@ -5141,6 +5141,10 @@ export function slurp(metaWindow, insertAt = SlurpInsertPosition.BOTTOM) { } const space = spaces.spaceOfWindow(metaWindow); + if (!space) { + return; + } + const index = space.indexOf(metaWindow); let to, from, metaWindowToSlurp; From 57a8c12c62242a3d8830f2d6452454d56cddc9f5 Mon Sep 17 00:00:00 2001 From: Jay Ta'ala Date: Mon, 12 Aug 2024 22:20:54 +1000 Subject: [PATCH 4/5] FIX: delete window after allowing slurp to settle (for `q` in take mode). --- tiling.js | 35 ++++++++++++++++++++++++----------- 1 file changed, 24 insertions(+), 11 deletions(-) diff --git a/tiling.js b/tiling.js index c4c8f907..86b5c9f1 100644 --- a/tiling.js +++ b/tiling.js @@ -3967,6 +3967,7 @@ export function add_handler(_ws, metaWindow) { export function insertWindow(metaWindow, options = {}) { const existing = options?.existing ?? false; const dropping = options?.dropping ?? false; + const dropCallback = options?.dropCallback ?? function() {}; // Add newly created windows to the space being previewed if (!existing && @@ -4110,16 +4111,20 @@ export function insertWindow(metaWindow, options = {}) { break; } - // if need to slurp (i.e. vertical stack) - if (slurpPosition) { - stackSlurpTimeout = GLib.timeout_add( - GLib.PRIORITY_DEFAULT, - 100, - () => { - slurp(active, slurpPosition); - return false; // on return false destroys timeout - }); + if (!slurpPosition) { + dropCallback(metaWindow); + return; } + + // if need to slurp (i.e. vertical stack) + stackSlurpTimeout = GLib.timeout_add( + GLib.PRIORITY_DEFAULT, + 100, + () => { + slurp(active, slurpPosition); + dropCallback(metaWindow); + return false; // on return false destroys timeout + }); }; /** @@ -5415,8 +5420,16 @@ export function takeWindow(metaWindow, space, options = {}) { case Clutter.KEY_q: { navigator._moving.forEach(w => { changeSpace(w); - insertWindow(w, { existing: true, dropping: true }); - w.delete(global.get_current_time()); + insertWindow( + w, + { + existing: true, + dropping: true, + dropCallback: mw => { + console.log(`deleting window ${mw.title}`); + mw.delete(global.get_current_time()); + }, + }); }); navigator._moving = []; From cf41092561a8b4be5375ff2413404b086a628963 Mon Sep 17 00:00:00 2001 From: Jay Ta'ala Date: Mon, 12 Aug 2024 23:36:44 +1000 Subject: [PATCH 5/5] FIX: for dropping, don't use callbackOnActor delay. --- tiling.js | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/tiling.js b/tiling.js index 86b5c9f1..27856500 100644 --- a/tiling.js +++ b/tiling.js @@ -4100,7 +4100,7 @@ export function insertWindow(metaWindow, options = {}) { // run a simple layout in pre-prepare layout space.layout(false); - const slurpCheck = () => { + const slurpCheck = timeout => { let slurpPosition; switch (Settings.prefs.open_window_position) { case Settings.OpenWindowPositions.DOWN: @@ -4116,6 +4116,13 @@ export function insertWindow(metaWindow, options = {}) { return; } + // has slurpPosition but no timeout + if (!timeout) { + slurp(active, slurpPosition); + dropCallback(metaWindow); + return; + } + // if need to slurp (i.e. vertical stack) stackSlurpTimeout = GLib.timeout_add( GLib.PRIORITY_DEFAULT, @@ -4149,7 +4156,7 @@ export function insertWindow(metaWindow, options = {}) { ensureViewport(space.selectedWindow, space); space.setSpaceTopbarElementsVisible(true); - slurpCheck(); + slurpCheck(true); }); return; @@ -4166,7 +4173,7 @@ export function insertWindow(metaWindow, options = {}) { } if (dropping) { - slurpCheck(); + slurpCheck(false); } } @@ -5426,7 +5433,6 @@ export function takeWindow(metaWindow, space, options = {}) { existing: true, dropping: true, dropCallback: mw => { - console.log(`deleting window ${mw.title}`); mw.delete(global.get_current_time()); }, });