Created
July 7, 2021 02:49
-
-
Save micimize/bdcbc92b31ec7158c3b2c0186f0c53b6 to your computer and use it in GitHub Desktop.
hammerspoon script for stacking and rotating through windows
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
hs.window.animationDuration = 0 -- disable animations | |
local menuHeight = 40 | |
local W = hs.window | |
local WF = hs.window.filter | |
local G = hs.geometry | |
function getWindowsBehind(region) | |
local wf = WF.copy(WF.defaultCurrentSpace):setRegions({region}) | |
return wf:getWindows(WF.sortByFocusedLast) | |
end | |
function looseRegionOf(frame) | |
return G.copy(frame):scale(1.25) | |
end | |
function nicelyStackWindows(stack, lowerMostFrame) | |
local frame = G.copy(lowerMostFrame) | |
local upByMenuHeight = G.point{x=0, y=-menuHeight} | |
local fullHeight = menuHeight * (#stack + 1) | |
for _, w in ipairs(stack) do | |
w:setFrame(frame) | |
frame = G.copy(frame):move(upByMenuHeight) | |
end | |
end | |
hs.hotkey.bind({"cmd", "alt", "ctrl"}, "s", function() | |
local win = W.focusedWindow() | |
local frame = win:frame() | |
local stack = getWindowsBehind(looseRegionOf(frame)) | |
nicelyStackWindows(stack, frame) | |
end) | |
hs.hotkey.bind({"cmd", "alt", "ctrl"}, "n", function() | |
local oldFront = W.focusedWindow() | |
local frame = G.copy(oldFront:frame()) | |
rotateStackN(getWindowsBehind(looseRegionOf(frame))) | |
end) | |
hs.hotkey.bind({"cmd", "alt", "ctrl"}, "p", function() | |
local oldFront = W.focusedWindow() | |
local frame = G.copy(oldFront:frame()) | |
rotateStackP(getWindowsBehind(looseRegionOf(frame))) | |
end) | |
function rotateStackN(stack) | |
if #stack < 2 then return end | |
table.sort(stack, function(a,b) | |
return a:frame().y < b:frame().y | |
end) | |
local downByMenuHeight = G.point{x=0, y=menuHeight} | |
local highestFrame = G.copy(stack[1]:frame()) | |
stack[#stack]:setFrame(highestFrame) | |
for i, w in ipairs(stack) do | |
if i ~= #stack then | |
w:focus() | |
w:move(downByMenuHeight) | |
hs.timer.usleep(1000) | |
end | |
end | |
end | |
function rotateStackP(stack) | |
if #stack < 2 then return end | |
table.sort(stack, function(a,b) | |
return a:frame().y < b:frame().y | |
end) | |
local upByMenuHeight = G.point{x=0, y=-menuHeight} | |
local lowestFrame = G.copy(stack[#stack]:frame()) | |
stack[1]:setFrame(lowestFrame) | |
stack[1]:focus() | |
for i, w in ipairs(stack) do | |
if i ~= 1 then | |
w:move(upByMenuHeight) | |
end | |
end | |
end | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment