diff --git a/README.md b/README.md index 4f82f1b..2604384 100644 --- a/README.md +++ b/README.md @@ -59,6 +59,7 @@ PaperWM doesn't handle attached modal dialogs very well, so it's best to turn it | 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) | | SuperF | Maximize the width of a window | | SuperShiftF | Toggle fullscreen | | SuperReturn or SuperN | Create a new window from the active application | diff --git a/examples/keybindings.js b/examples/keybindings.js index 678d759..0b11c71 100644 --- a/examples/keybindings.js +++ b/examples/keybindings.js @@ -90,56 +90,6 @@ function showNavigator() { } -function cycleWindowHeight() { - Keybindings.bindkey("q", "cycle-height", cycleHeight, { activeInNavigator: true }); - - var Tiling = Extension.imports.tiling; - - function cycleHeight(metaWindow) { - const ratios = [1/3, 1/2, 2/3]; - - function findNext(tr) { - // Find the first ratio that is significantly bigger than 'tr' - for (let i = 0; i < ratios.length; i++) { - let r = ratios[i] - if (tr <= r) { - if (tr/r > 0.9) { - return (i+1) % ratios.length; - } else { - return i; - } - } - } - return 0; // cycle - } - - let space = Tiling.spaces.spaceOfWindow(metaWindow); - if (!space) - return; - - let i = space.indexOf(metaWindow); - - function allocate(column, available) { - available -= (column.length - 1) * Tiling.prefs.window_gap; - let frame = metaWindow.get_frame_rect(); - let r = frame.height / available; - let nextR = ratios[findNext(r)]; - return column.map(mw => { - if (mw === metaWindow) { - return Math.floor(available * nextR); - } else { - return Math.floor(available * (1-nextR)/(column.length-1)); - } - }); - } - - if (space[i].length > 1) { - space.layout(false, {customAllocators: {[i]: allocate}}); - } - } -} - - // listFreeBindings("").join("\n") function listFreeBindings(modifierString) { let free = []; diff --git a/keybindings.js b/keybindings.js index a1f5809..d80d3f8 100644 --- a/keybindings.js +++ b/keybindings.js @@ -118,6 +118,11 @@ function init() { Tiling), Meta.KeyBindingFlags.PER_WINDOW); + registerPaperAction("cycle-height", + dynamic_function_ref("cycleWindowHeight", + Tiling), + Meta.KeyBindingFlags.PER_WINDOW); + registerPaperAction("center-horizontally", dynamic_function_ref("centerWindowHorizontally", Tiling), diff --git a/prefs.js b/prefs.js index ac96c77..7fffc6d 100644 --- a/prefs.js +++ b/prefs.js @@ -164,7 +164,8 @@ class SettingsWidget { 'switch-first', 'switch-last', 'live-alt-tab', 'live-alt-tab-backward', 'move-left', 'move-right', 'move-up', 'move-down', 'slurp-in', 'barf-out', 'center-horizontally', - 'paper-toggle-fullscreen', 'toggle-maximize-width', 'cycle-width'] + 'paper-toggle-fullscreen', 'toggle-maximize-width', 'cycle-width', + 'cycle-height'] .forEach(k => { addKeybinding(windows.model.child_model, settings, k); }); diff --git a/schemas/gschemas.compiled b/schemas/gschemas.compiled index dbf5152..2fb3064 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 bde02a2..2be67e1 100644 --- a/schemas/org.gnome.shell.extensions.org-scrollwm.gschema.xml +++ b/schemas/org.gnome.shell.extensions.org-scrollwm.gschema.xml @@ -113,6 +113,11 @@ Cycle through useful window widths + + r']]]> + Cycle through useful window heights + + c']]]> Center window horizontally diff --git a/tiling.js b/tiling.js index 9123434..134b79b 100644 --- a/tiling.js +++ b/tiling.js @@ -2345,6 +2345,54 @@ function cycleWindowWidth(metaWindow) { metaWindow.move_resize_frame(true, nextX, frame.y, nextW, frame.height); } +function cycleWindowHeight(metaWindow) { + log("OMG") + const ratios = [1/3, 1/2, 2/3]; + + function findNext(tr) { + // Find the first ratio that is significantly bigger than 'tr' + for (let i = 0; i < ratios.length; i++) { + let r = ratios[i] + if (tr <= r) { + if (tr/r > 0.9) { + return (i+1) % ratios.length; + } else { + return i; + } + } + } + return 0; // cycle + } + + let space = spaces.spaceOfWindow(metaWindow); + if (!space) + return; + + let i = space.indexOf(metaWindow); + + // Fix `frame` outside `allocate` so the allocation wont change during + // fixpoint calculation. (could move more out, but then we'd have to + // calculate available manually) + let frame = metaWindow.get_frame_rect(); + + function allocate(column, available) { + available -= (column.length - 1) * prefs.window_gap; + let r = frame.height / available; + let nextR = ratios[findNext(r)]; + return column.map(mw => { + if (mw === metaWindow) { + return Math.floor(available * nextR); + } else { + return Math.floor(available * (1-nextR)/(column.length-1)); + } + }); + } + + if (space[i].length > 1) { + space.layout(false, {customAllocators: {[i]: allocate}}); + } +} + function activateNthWindow(n, space) { space = space || spaces.spaceOf(workspaceManager.get_active_workspace()); let nth = space[n][0];