marketplace/accessibility

Keyboard Mouse

v0.1.0

@rebindfree

Move the pointer with the numpad, with acceleration you set, plus click, right click and a drag lock.

Gallery

Keyboard Mouse preview

Readme

The numpad moves the pointer in eight directions, starting slow for precision and speeding up the longer you hold. 5 clicks, + right clicks, Enter middle clicks, and 0 holds the left button down for dragging until you tap it again.

Needs Rebind 3.5.0 or newer on Windows, macOS, or Linux. No extra permissions.

Numpad keyAction
8 / 2 / 4 / 6Up / down / left / right
7 / 9 / 1 / 3Diagonals
5Click
+Right click
EnterMiddle click
0Drag lock on or off

Settings

  • Keys tab: every key above can be changed. Restart the package after changing keys.
  • Start speed and Top speed: pixels per step at the start of a hold and at full speed.
  • Time to top speed: how long a hold takes to reach top speed. 0 starts at top speed.

Limits

  • On Windows, turn Num Lock on. With Num Lock off, Windows reports the numpad as arrow and navigation keys, which this package does not catch.
  • The numpad keys do not type numbers while the package runs.
  • Live use remains unverified on Windows, macOS, and Linux.

Stop

Stopping the package releases any held button. Stop it from the editor toolbar, or press Left Ctrl + Left Alt + K to stop all scripts.

Reviews

No reviews yet. Be the first, from the app.

Source

Version 0.1.0 (current)

main.luau

-- Keyboard Mouse: numpad keys move the pointer in eight directions, slow at
-- first and faster the longer you hold, with click, right click, middle
-- click and a drag lock.

local cfg = UI.Schema({
  up = UI.Keybind("Kp8", { label = "Up", tab = "Keys" }),
  down = UI.Keybind("Kp2", { label = "Down", tab = "Keys" }),
  left = UI.Keybind("Kp4", { label = "Left", tab = "Keys" }),
  right = UI.Keybind("Kp6", { label = "Right", tab = "Keys" }),
  upLeft = UI.Keybind("Kp7", { label = "Up and left", tab = "Keys" }),
  upRight = UI.Keybind("Kp9", { label = "Up and right", tab = "Keys" }),
  downLeft = UI.Keybind("Kp1", { label = "Down and left", tab = "Keys" }),
  downRight = UI.Keybind("Kp3", { label = "Down and right", tab = "Keys" }),
  click = UI.Keybind("Kp5", { label = "Click", tab = "Keys" }),
  rightClick = UI.Keybind("KpPlus", { label = "Right click", tab = "Keys" }),
  middleClick = UI.Keybind("KpEnter", { label = "Middle click", tab = "Keys" }),
  drag = UI.Keybind("Kp0", { label = "Drag lock on or off", tab = "Keys" }),
  slow = UI.Slider(2, { min = 1, max = 10, suffix = " px", label = "Start speed" }),
  fast = UI.Slider(18, { min = 4, max = 60, suffix = " px", label = "Top speed" }),
  ramp = UI.Slider(700, {
    min = 0,
    max = 2000,
    suffix = " ms",
    label = "Time to top speed",
  }),
})

local DIRS = {
  [cfg.up] = { 0, -1 },
  [cfg.down] = { 0, 1 },
  [cfg.left] = { -1, 0 },
  [cfg.right] = { 1, 0 },
  [cfg.upLeft] = { -1, -1 },
  [cfg.upRight] = { 1, -1 },
  [cfg.downLeft] = { -1, 1 },
  [cfg.downRight] = { 1, 1 },
}

-- direction keys only steer; OnTick reads which are held
for key in DIRS do
  Bind(key, function() end)
end

local held = {}
for key, button in { [cfg.click] = "Mouse1", [cfg.rightClick] = "Mouse2", [cfg.middleClick] = "Mouse3" } do
  Bind(key, {
    action = function()
      held[button] = true
      HID.Down(button)
    end,
    release = function()
      held[button] = nil
      HID.Up(button)
    end,
  })
end

-- the drag key holds the left button until it is tapped again
local dragging = false
Bind(cfg.drag, function()
  dragging = not dragging
  if dragging then
    HID.Down("Mouse1")
  else
    HID.Up("Mouse1")
  end
end)

function OnTick()
  local dx, dy, longest = 0, 0, 0
  for key, d in DIRS do
    if Input.IsDown(key) then
      dx, dy = dx + d[1], dy + d[2]
      longest = math.max(longest, Input.GetDuration(key))
    end
  end
  if dx == 0 and dy == 0 then
    return
  end
  local t = if cfg.ramp > 0 then math.min(longest / cfg.ramp, 1) else 1
  local speed = cfg.slow + (cfg.fast - cfg.slow) * t * t
  HID.Move(math.round(dx * speed), math.round(dy * speed))
end

function OnStop()
  if dragging then
    HID.Up("Mouse1")
  end
  for button in held do
    HID.Up(button)
  end
end