Created
April 16, 2025 13:53
-
-
Save amirrajan/5995b9dd87f98ae34a27e427709a27f7 to your computer and use it in GitHub Desktop.
Hammer Spoon windows management
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
require("hs.ipc") | |
--- ========================================== | |
--- Window Management | |
--- ========================================== | |
-- ctrl+option+left resizes window to left half of screen | |
hs.hotkey.bind({'ctrl', 'option'}, "Left", function() | |
local win = hs.window.focusedWindow() | |
local f = win:frame() | |
local screen = win:screen() | |
local max = screen:frame() | |
local target_w_half = math.floor(max.w / 2) | |
local target_w_third = math.floor(max.w / 3) | |
local target_w_two_thirds = math.floor(max.w * 2 / 3) | |
f.x = max.x | |
f.y = max.y | |
if f.w == target_w_half then | |
f.w = target_w_third | |
elseif f.w == target_w_third then | |
f.w = target_w_two_thirds | |
else | |
f.w = target_w_half | |
end | |
f.h = max.h | |
win:setFrame(f, 0) | |
end) | |
-- ctrl+option+right resizes window to right half of screen | |
hs.hotkey.bind({'ctrl', 'option'}, "Right", function() | |
local win = hs.window.focusedWindow() | |
local f = win:frame() | |
local screen = win:screen() | |
local max = screen:frame() | |
local target_w_half = math.floor(max.w / 2) | |
local target_w_third = math.floor(max.w / 3) | |
local target_w_two_thirds = math.floor(max.w * 2 / 3) | |
f.y = max.y | |
if f.w == target_w_half and f.x == max.x + (max.w / 2) then | |
f.x = max.x + (max.w - target_w_third) | |
f.w = target_w_third | |
elseif f.w == target_w_third then | |
f.x = max.x + (max.w - target_w_two_thirds) | |
f.w = target_w_two_thirds | |
else | |
f.x = max.x + target_w_half | |
f.w = target_w_half | |
end | |
f.h = max.h | |
win:setFrame(f, 0) | |
end) | |
-- ctrl+option+j resizes window to fill screen | |
hs.hotkey.bind({'ctrl', 'option'}, "j", function() | |
local win = hs.window.focusedWindow() | |
local f = win:frame() | |
local screen = win:screen() | |
local max = screen:frame() | |
f.x = max.x | |
f.y = max.y | |
f.w = max.w | |
f.h = max.h | |
win:setFrame(f, 0) | |
end) | |
-- ctrl+option+, centers window and toggles between 1280x720 and full vertical height | |
hs.hotkey.bind({'ctrl', 'option'}, ",", function() | |
local win = hs.window.focusedWindow() | |
local f = win:frame() | |
local screen = win:screen() | |
local max = screen:frame() | |
local h = 748 | |
if f.w == 1280 and f.h == h then | |
f.x = max.x + (max.w / 4) | |
f.w = max.w / 2 | |
f.y = max.y | |
f.h = max.h | |
elseif f.w == max.w / 2 and f.x == max.x + (max.w / 4)then | |
f.w = 1280 | |
f.h = h | |
f.x = max.x + ((max.w - f.w) / 2) | |
f.y = max.y + ((max.h - f.h) / 2) | |
else | |
f.x = max.x + (max.w / 4) | |
f.w = max.w / 2 | |
f.y = max.y | |
f.h = max.h | |
end | |
win:setFrame(f, 0) | |
end) | |
-- ctrl+option+up sends window to next screen | |
hs.hotkey.bind({'ctrl', 'option'}, "Up", function() | |
local win = hs.window.focusedWindow() | |
win:moveToScreen(win:screen():previous(), 0) | |
end) | |
-- ctrl+option+down sends window to prev screen | |
hs.hotkey.bind({'ctrl', 'option'}, "Down", function() | |
local win = hs.window.focusedWindow() | |
win:moveToScreen(win:screen():next(), 0) | |
end) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment