Skip to content

Instantly share code, notes, and snippets.

@micimize
Created July 7, 2021 02:49
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save micimize/bdcbc92b31ec7158c3b2c0186f0c53b6 to your computer and use it in GitHub Desktop.
Save micimize/bdcbc92b31ec7158c3b2c0186f0c53b6 to your computer and use it in GitHub Desktop.
hammerspoon script for stacking and rotating through windows
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