Key Timing Control

@rebind / key-timing-controlv0.1.2Public

Ignore accidental double presses and make a held key type once. For tremor and lingering presses.

Files

main.luau1.4 KB

-- Key Timing Control: ignore a second press of the same key that comes too
-- soon, and make a held key type once instead of repeating.

local cfg = UI.Schema({
  debounce = UI.Toggle(true, { label = "Ignore double presses" }),
  debounce_ms = UI.Slider(200, {
    min = 50,
    max = 1000,
    suffix = " ms",
    label = "Within",
  }),
  no_repeat = UI.Toggle(true, { label = "One character per press" }),
})

-- modifiers and lock keys pass through untouched so chords keep working
local PASS = {
  LCtrl = true,
  RCtrl = true,
  LShift = true,
  RShift = true,
  LAlt = true,
  RAlt = true,
  LWin = true,
  RWin = true,
  CapsLock = true,
  NumLock = true,
  ScrollLock = true,
}

local last = {}
-- keys whose press was taken over, so their release is taken over too
local taken = {}

function OnDown(key)
  if PASS[key] or key == "Unknown" or key:sub(1, 5) == "Mouse" then
    return true
  end
  if cfg.debounce then
    local now = os.clock() * 1000
    local previous = last[key]
    last[key] = now
    if previous and now - previous < cfg.debounce_ms then
      taken[key] = true
      return false
    end
  end
  if cfg.no_repeat then
    -- a press that never reaches the app cannot auto-repeat: send one tap
    taken[key] = true
    HID.Combo(key)
    return false
  end
  return true
end

function OnUp(key)
  if taken[key] then
    taken[key] = nil
    return false
  end
  return true
end

3 files, 3.0 KB.