// 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);