Last active
September 8, 2025 08:15
-
-
Save kenlim/04a9ce425c7218929ccbea3b004161e5 to your computer and use it in GitHub Desktop.
My Hammerspoon init file that provides window resizing to thirds of the screen
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.hotkey.bind({"cmd", "alt", "ctrl"}, "Left", function() | |
| local win = hs.window.focusedWindow() | |
| local currentWindow = win:frame() | |
| local screen = win:screen() | |
| local screenFrame = screen:frame() | |
| local half = screenFrame.w / 2 | |
| local third = screenFrame.w / 3 | |
| local twothirds = screenFrame.w - third | |
| if currentWindow.x == screenFrame.x and currentWindow.w == half then | |
| currentWindow.w = third | |
| elseif currentWindow.x == screenFrame.x and currentWindow.w <= third then | |
| currentWindow.w = twothirds | |
| else | |
| -- default action is to go half left | |
| currentWindow.w = half | |
| end | |
| -- move window anchor to the origin of the screen | |
| currentWindow.x = screenFrame.x | |
| currentWindow.y = screenFrame.y | |
| -- match height of the screen | |
| currentWindow.h = screenFrame.h | |
| win:setFrame(currentWindow) | |
| end) | |
| hs.hotkey.bind({"cmd", "alt", "ctrl"}, "Right", function() | |
| local win = hs.window.focusedWindow() | |
| local currentWindow = win:frame() | |
| local screen = win:screen() | |
| local screenFrame = screen:frame() | |
| local half = screenFrame.w / 2 | |
| local third = screenFrame.w / 3 | |
| local twothirds = screenFrame.w - third | |
| if currentWindow.w == half and currentWindow.x == screenFrame.x + half then | |
| currentWindow.w = third | |
| currentWindow.x = screenFrame.x + twothirds | |
| elseif currentWindow.w <= third and currentWindow.x >= | |
| (screenFrame.x + twothirds - 5) then | |
| -- have to give a small margin of error due to rounding | |
| currentWindow.w = twothirds | |
| currentWindow.x = screenFrame.x + third | |
| else | |
| currentWindow.x = screenFrame.x + half | |
| currentWindow.w = half | |
| end | |
| currentWindow.y = screenFrame.y | |
| -- match height of the screen | |
| currentWindow.h = screenFrame.h | |
| win:setFrame(currentWindow) | |
| end) | |
| hs.hotkey.bind({'alt', 'ctrl', 'cmd'}, 'Up', function() | |
| local win = hs.window.focusedWindow() | |
| local currentWindow = win:frame() | |
| local screen = win:screen() | |
| local screenFrame = screen:frame() | |
| local half = screenFrame.h / 2 | |
| local third = screenFrame.h / 3 | |
| local twothirds = screenFrame.h - third | |
| if currentWindow.h > half then | |
| currentWindow.h = half | |
| elseif currentWindow.h > third then | |
| currentWindow.h = third | |
| else | |
| currentWindow.h = twothirds | |
| end | |
| currentWindow.y = screenFrame.y | |
| win:setFrame(currentWindow) | |
| end) | |
| hs.hotkey.bind({'alt', 'ctrl', 'cmd'}, 'Down', function() | |
| local win = hs.window.focusedWindow() | |
| local currentWindow = win:frame() | |
| local screen = win:screen() | |
| local screenFrame = screen:frame() | |
| local half = screenFrame.h / 2 | |
| local third = screenFrame.h / 3 | |
| local twothirds = screenFrame.h - third | |
| if currentWindow.h > half then | |
| currentWindow.y = screenFrame.y + half | |
| currentWindow.h = half | |
| elseif currentWindow.h > third then | |
| currentWindow.y = screenFrame.y + twothirds | |
| currentWindow.h = third | |
| else | |
| currentWindow.y = screenFrame.y + third | |
| currentWindow.h = twothirds | |
| end | |
| win:setFrame(currentWindow) | |
| end) | |
| hs.hotkey.bind({'alt', 'ctrl', 'cmd'}, 'n', function() | |
| -- get the focused window | |
| local win = hs.window.focusedWindow() | |
| -- get the screen where the focused window is displayed, a.k.a. current screen | |
| local screen = win:screen() | |
| -- compute the unitRect of the focused window relative to the current screen | |
| -- and move the window to the next screen setting the same unitRect | |
| win:move(win:frame():toUnitRect(screen:frame()), screen:next(), true, 0) | |
| end) | |
| hs.hotkey.bind({'alt', 'ctrl', 'cmd'}, 'm', function() | |
| -- maximise to screen | |
| 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) | |
| end) | |
| hs.hotkey.bind({'alt', 'ctrl', 'cmd'}, 'c', function() | |
| -- resize to 60% of screen, and position it in the center | |
| 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 * 0.6 | |
| f.h = max.h * 0.9 | |
| win:setFrame(f) | |
| win:centerOnScreen() | |
| end) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment