diff options
Diffstat (limited to 'config/kwin/sz-window-layout')
| -rw-r--r-- | config/kwin/sz-window-layout/contents/code/main.js | 57 | ||||
| -rw-r--r-- | config/kwin/sz-window-layout/metadata.json | 13 |
2 files changed, 70 insertions, 0 deletions
diff --git a/config/kwin/sz-window-layout/contents/code/main.js b/config/kwin/sz-window-layout/contents/code/main.js new file mode 100644 index 0000000..2b498a2 --- /dev/null +++ b/config/kwin/sz-window-layout/contents/code/main.js @@ -0,0 +1,57 @@ +// The window shortcuts from config/hammerspoon/init.lua, for KWin on Plasma 6. +// Linked into ~/.local/share/kwin/scripts/ and enabled by link.sh. +// +// Every action is registered twice, because Toshy sits between the keyboard +// and KWin. On a Mac keyboard it turns physical Ctrl into Meta in GUI apps but +// leaves it as Ctrl in terminals, so the same physical Ctrl+Opt+2 reaches KWin +// as Meta+Alt+2 in a browser and as Ctrl+Alt+2 in Ghostty. The Ctrl variant +// also covers Toshy being paused or absent. +// +// KWin compiles this at load: after an edit, toggle the script off and on in +// System Settings -> Window Management -> KWin Scripts. A changed default key +// may not replace one already saved in kglobalshortcutsrc. + +// [key, name, left edge, width], as fractions of the usable screen area. +const layouts = [ + ["1", "Maximize", 0, 1], + ["2", "Left 50%", 0, 0.5], + ["3", "Right 50%", 0.5, 0.5], + ["4", "Left 30%", 0, 0.3], + ["5", "Right 70%", 0.3, 0.7], + ["6", "Left 25%", 0, 0.25], + ["7", "Right 75%", 0.25, 0.75], + ["8", "Left 20%", 0, 0.2], + ["9", "Right 80%", 0.2, 0.8], +]; + +function place(x, w) { + const win = workspace.activeWindow; + if (!win) return; + const area = workspace.clientArea(KWin.MaximizeArea, win); + // Rounding both edges rather than the width keeps a left/right pair flush. + const left = Math.round(area.x + area.width * x); + const right = Math.round(area.x + area.width * (x + w)); + // A window left in a quick tile (Meta+Left/Right) or maximized would + // otherwise be pulled back to that geometry. + win.tile = null; + win.setMaximize(false, false); + win.frameGeometry = { x: left, y: area.y, width: right - left, height: area.height }; +} + +function nextScreen() { + const win = workspace.activeWindow; + if (!win) return; + const screens = workspace.screens; + // By name: the wrappers of one output are not guaranteed to be ===. + let i = 0; + while (i < screens.length && screens[i].name !== win.output.name) i++; + workspace.sendClientToScreen(win, screens[(i + 1) % screens.length]); +} + +for (const [key, name, x, w] of layouts) { + const fn = () => place(x, w); + registerShortcut(`sz ${name}`, `sz: ${name}`, `Meta+Alt+${key}`, fn); + registerShortcut(`sz ${name} (Ctrl)`, `sz: ${name} (Ctrl)`, `Ctrl+Alt+${key}`, fn); +} +registerShortcut("sz Next Screen", "sz: Next Screen", "Meta+Shift+Space", nextScreen); +registerShortcut("sz Next Screen (Ctrl)", "sz: Next Screen (Ctrl)", "Ctrl+Shift+Space", nextScreen); diff --git a/config/kwin/sz-window-layout/metadata.json b/config/kwin/sz-window-layout/metadata.json new file mode 100644 index 0000000..8df8b23 --- /dev/null +++ b/config/kwin/sz-window-layout/metadata.json @@ -0,0 +1,13 @@ +{ + "KPackageStructure": "KWin/Script", + "KPlugin": { + "Name": "sz window layout", + "Description": "Hammerspoon-style shortcuts to place the active window at fixed screen fractions", + "Icon": "preferences-system-windows", + "Id": "sz-window-layout", + "Version": "1.0", + "License": "MIT" + }, + "X-Plasma-API": "javascript", + "X-Plasma-MainScript": "code/main.js" +} |
