dbalatero/SkyRocket.spoon

Window movement sometimes lags behind the mouse cursor

dbalatero opened this issue · 4 comments

From Reddit:

It seems like the window movement is lagging behind the mouse cursor - if you drag it around very quickly, it will replay the cursor's path in slow motion.

This is a problem as we're moving the window in real-time as the mouse moves. It might just be that the APIs Hammerspoon expose for this can't handle how often it gets called.

Currently we are listening for the leftMouseDragged event from Hammerspoon, and then moving the window in real time every time the event handler fires:

SkyRocket.spoon/init.lua

Lines 124 to 129 in b32f81b

local dx = event:getProperty(hs.eventtap.event.properties.mouseEventDeltaX)
local dy = event:getProperty(hs.eventtap.event.properties.mouseEventDeltaY)
if self:isMoving() then
self.targetWindow:move({dx, dy}, nil, false, 0)
return true

Whatever the delta (x, y) of the drag was, we just nudge along the window and call window:move(...).

This is probably happening at too fast of a rate for Hammerspoon to handle it, depending how high your mouse sensitivity is. The thing to do would be to call move() less… but we still want the illusion of smooth movement. Maybe this event is just firing way too many times when you flick it quickly, and we just need to buffer movements accordingly.

Started to measure things, and I'm finding that window:move() has some variable latency to it:

2021-07-27 11:10:25: 11:10:25                 Handled 13 drag events
2021-07-27 11:10:25:                            Event 1: time = 328.71407ms, move = 53.9934ms, dx = 0px, dy = 0px
2021-07-27 11:10:25:                            Event 2: time = 400.17699ms, move = 23.50854ms, dx = -4px, dy = 0px
2021-07-27 11:10:25:                            Event 3: time = 425.15426ms, move = 16.09029ms, dx = -15px, dy = 0px
2021-07-27 11:10:25:                            Event 4: time = 487.36714ms, move = 16.00868ms, dx = -17px, dy = 0px
2021-07-27 11:10:25:                            Event 5: time = 570.61709ms, move = 14.17941ms, dx = -24px, dy = 0px
2021-07-27 11:10:25:                            Event 6: time = 650.29178ms, move = 17.97919ms, dx = -9px, dy = 0px
2021-07-27 11:10:25:                            Event 7: time = 728.43207ms, move = 826.48959ms, dx = -20px, dy = 0px
2021-07-27 11:10:25:                            Event 8: time = 1556.74348ms, move = 827.72796ms, dx = -20px, dy = -1px
2021-07-27 11:10:25:                            Event 9: time = 2386.59503ms, move = 819.58293ms, dx = -20px, dy = -5px
2021-07-27 11:10:25:                            Event 10: time = 3206.7307ms, move = 832.84942ms, dx = -14px, dy = -3px
2021-07-27 11:10:25:                            Event 11: time = 4040.11141ms, move = 833.63704ms, dx = -5px, dy = -1px
2021-07-27 11:10:25:                            Event 12: time = 4874.24237ms, move = 506.99123ms, dx = -11px, dy = -2px
2021-07-27 11:10:25:                            Event 13: time = 5381.76185ms, move = 14.93555ms, dx = -14px, dy = -1px

Events 7-12 have a huge spike in latency when calling move().

I've fixed this by moving a canvas instead, and calling move() once at the end.