Hold mouse key to scroll in hammerspoon

869 Views Asked by At

I currently trying to setup a lua script in hammerspoon on mac so that when I hold down the back/forward side buttons on my mouse, I can scroll up and down continuously as long as the button is held down. Indeed, the following code is what I have so far

back    = 3
forward = 4
pixels  = 50
fast_scroll = hs.eventtap.new({ hs.eventtap.event.types.otherMouseDown }, function(e)
   local pressed = e:getProperty(hs.eventtap.event.properties['mouseEventButtonNumber'])
   print(pressed)
   if     pressed == back    then sign=-1
   elseif pressed == forward then sign= 1
   else return false, {}
   end
   local scroll = hs.eventtap.event.newScrollEvent({0, sign*pixels},{},'pixel')
   return true, {scroll}
end)
fast_scroll:start()

The code here allows me to scroll every time I press the side buttons, but only scrolls once. To continue scrolling, I would need to release the side button, click again and repeat. It seems that I would need a while loop of some sort, but I'm not quite sure how to do that with hammerspoon. Any tips would be appreciated.

1

There are 1 best solutions below

0
Christophe Geers On

One way to solve this is to start a timer when the mouse button is pressed and stop it when the mouse button is released.

Here's an example I quickly put together which scrolls down as long as I keep my right mouse button pressed. You'll have to play a bit with the amount of pixels and interval passed to the timer to get a scroll that feels natural. Scrolling 50 pixels every 20ms felt OK for me.

local pixels = 50

-- 1s / 50 = 20ms
local scrollDownTimer = hs.timer.new(1 / 50, function()
  hs.eventtap.event.newScrollEvent({0, -1*pixels},{},'pixel'):post()
end)

local events = hs.eventtap.event.types
mouseTracker = hs.eventtap.new({ events.rightMouseDown, events.rightMouseUp }, function (e)
  local sign = -1

  if e:getType() == events.rightMouseUp then
    scrollDownTimer:stop()
  elseif e:getType() == events.rightMouseDown then
    scrollDownTimer:start()
    -- for the first scroll, don't wait until the timer expires
    local scroll = hs.eventtap.event.newScrollEvent({0, -1*pixels},{},'pixel')
  end

  return true, { scroll }
end)
mouseTracker:start()