-
-
Save kizzx2/e542fa74b80b7563045a to your computer and use it in GitHub Desktop.
-- Inspired by Linux alt-drag or Better Touch Tools move/resize functionality | |
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 | |
drag_event = hs.eventtap.new({ hs.eventtap.event.types.mouseMoved }, function(e) | |
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() | |
-- Ctrl + Shift to move the window under cursor | |
if dragging_mode == 1 and mods.ctrl and mods.shift then | |
dragging_win:move({dx, dy}, nil, false, 0) | |
-- Alt + Shift to resize the window under cursor | |
elseif mods.alt and mods.shift then | |
local sz = dragging_win:size() | |
local w1 = sz.w + dx | |
local h1 = sz.h + dy | |
dragging_win:setSize(w1, h1) | |
end | |
end | |
return nil | |
end) | |
flags_event = hs.eventtap.new({ hs.eventtap.event.types.flagsChanged }, function(e) | |
local flags = e:getFlags() | |
if flags.ctrl and flags.shift and dragging_win == nil then | |
dragging_win = get_window_under_mouse() | |
dragging_mode = 1 | |
drag_event:start() | |
elseif flags.alt and flags.shift and dragging_win == nil then | |
dragging_win = get_window_under_mouse() | |
dragging_mode = 2 | |
drag_event:start() | |
else | |
drag_event:stop() | |
dragging_win = nil | |
end | |
return nil | |
end) | |
flags_event:start() |
I've been happily using this for years, but now that I've upgraded to OSX Catalina it's extremely laggy. The window moves with delay relative to cursor movement, and the modifier keys seem to stay activated for a few seconds after unpressing them. Has anyone else encountered this or found a fix?
Hi guys, I just found out about hammerspoon. After spending a weekend on linux I found myself trying to alt+leftClick to drag and alt+rightClick to resize, so I went looked for a solution and here I am :)
Here's what I did based on the script I found here. This implements cmd + leftClick
for moving and cmd + rightClick
for resizing.
function get_window_under_mouse()
local pos = hs.geometry.new(hs.mouse.getAbsolutePosition())
local screen = hs.mouse.getCurrentScreen()
return hs.fnutils.find(hs.window.orderedWindows(), function(w)
return screen == w:screen() and pos:inside(w:frame())
end)
end
dragging_window = nil
drag_event = hs.eventtap.new(
{
hs.eventtap.event.types.leftMouseDragged,
hs.eventtap.event.types.rightMouseDragged,
}, function(e)
if not dragging_win then return nil end
local dx = e:getProperty(hs.eventtap.event.properties.mouseEventDeltaX)
local dy = e:getProperty(hs.eventtap.event.properties.mouseEventDeltaY)
local mouse = hs.mouse:getButtons()
if mouse.left then
dragging_win:move({dx, dy}, nil, false, 0)
elseif mouse.right then
local sz = dragging_win:size()
local w1 = sz.w + dx
local h1 = sz.h + dy
dragging_win:setSize(w1, h1)
end
end)
flag_event = hs.eventtap.new({ hs.eventtap.event.types.flagsChanged }, function(e)
local flags = e:getFlags()
if flags.cmd then
dragging_win = get_window_under_mouse()
drag_event:start()
else
draggin_win = nil
drag_event:stop()
end
end)
flag_event:start()
As @harob has said, hammerspoon is getting a little still, I don't know why. If one of you finds a solution, share it with us! :)
Regarding slow FPS when resizing, check out this (closed) issue. Sounds like it needs to be fixed internally somehow: Hammerspoon/hammerspoon#923
Hey all,
I created a spoon that combines some of the techniques here and fixes the slow framerate while resizing:
https://github.com/dbalatero/SkyRocket.spoon
Instead of resizing the window in realtime, I draw an transparent preview box on the screen with hs.canvas
, resize that as you drag, then commit the actual resize to the window when you let go of the mouse. It's a compromise for sure, but it's way better than dealing with the laggy framerate when naively trying to resize the window in realtime.
@dbalatero Thanks for the workaround - works like a charm!
Thank you all — this is exactly what I've been looking for!