Last active
February 21, 2025 11:19
-
-
Save nicwolff/b95cda99e672eeb28911adadbc9b0054 to your computer and use it in GitHub Desktop.
Hammerspoon script to move/resize window under mouse cursor with modifier keys
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
function get_window_under_mouse() | |
-- Invoke `hs.application` because `hs.window.orderedWindows()` doesn't do it | |
-- and breaks itself | |
local _ = hs.application | |
local my_pos = hs.geometry.new(hs.mouse.getAbsolutePosition()) | |
local my_screen = hs.mouse.getCurrentScreen() | |
return hs.fnutils.find(hs.window.orderedWindows(), function(w) | |
return my_screen == w:screen() and my_pos:inside(w:frame()) | |
end) | |
end | |
dragging_win = nil | |
dragging_mode = 1 | |
count = 0 | |
drag_event = hs.eventtap.new({ hs.eventtap.event.types.mouseMoved }, function(e) | |
count = count + 1 | |
if dragging_win then | |
local dx = e:getProperty(hs.eventtap.event.properties.mouseEventDeltaX) | |
local dy = e:getProperty(hs.eventtap.event.properties.mouseEventDeltaY) | |
local mods = hs.eventtap.checkKeyboardModifiers() | |
if dragging_mode == 2 and mods.fn and mods.ctrl and (count % 3) == 0 then | |
-- Fn + Ctrl to resize the window under cursor | |
local sz = dragging_win:size() | |
local w1 = sz.w + dx * 2 | |
local h1 = sz.h + dy * 2 | |
dragging_win:setSize(w1, h1) | |
elseif dragging_mode == 1 and mods.fn then | |
-- Fn to move the window under cursor | |
dragging_win:move({dx, dy}, nil, false, 0) | |
end | |
end | |
return nil | |
end) | |
flags_event = hs.eventtap.new({ hs.eventtap.event.types.flagsChanged }, function(e) | |
local flags = e:getFlags() | |
drag_event:stop() | |
dragging_win = nil | |
if flags.fn and flags.ctrl and dragging_win == nil then | |
dragging_win = get_window_under_mouse() | |
dragging_mode = 2 | |
count = 0 | |
drag_event:start() | |
elseif flags.fn and not flags.ctrl and dragging_win == nil then | |
dragging_win = get_window_under_mouse() | |
dragging_mode = 1 | |
drag_event:start() | |
end | |
return nil | |
end) | |
flags_event:start() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment