marketplace/accessibility

One-Handed Layout

v0.1.0

@rebindfree

Hold Space and the left half of the keyboard types the right half. A tap still types a space.

Gallery

One-Handed Layout preview

Readme

The half-keyboard layout: hold Space and every left-hand key types its mirror on the right, so F becomes J, A becomes the semicolon, and 1 becomes 0. Tab becomes Backspace and Caps Lock becomes Enter. A quick tap of Space still types a space.

Each finger keeps its position on both halves, so the layout is quick to learn.

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

Held with SpaceTypes
1 2 3 4 50 9 8 7 6
Q W E R TP O I U Y
A S D F G; L K J H
Z X C V B/ . , M N
Tab / Caps LockBackspace / Enter

Settings

  • Hold to mirror: the layer key. Default Space. Restart the package after changing it.
  • A shorter press still types the key: a press of the layer key shorter than this, with no other key, types the layer key itself. 100 to 400 ms.

Limits

  • The layer key types on release, so a space appears when you let go, not when you press. Type the next word's first letter after letting go of Space: a key pressed while Space is still down is mirrored if it is on the left half, or typed before the space if it is on the right half.
  • Holding Space to auto-repeat spaces no longer works while the package runs.
  • On macOS, Caps Lock reaches Rebind as a switch, so Caps Lock with Space sends Enter on every other press and never holds it.
  • Live use remains unverified on Windows, macOS, and Linux.

Stop

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

Reviews

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

Source

Version 0.1.0 (current)

main.luau

-- One-Handed Layout: hold the layer key and every left-hand key types its
-- mirror on the right half. A quick tap of the layer key still types it.

local cfg = UI.Schema({
  layer_key = UI.Keybind("Space", { label = "Hold to mirror" }),
  tap_ms = UI.Slider(200, {
    min = 100,
    max = 400,
    suffix = " ms",
    label = "A shorter press still types the key",
  }),
})

local MIRROR = {
  ["1"] = "0",
  ["2"] = "9",
  ["3"] = "8",
  ["4"] = "7",
  ["5"] = "6",
  Q = "P",
  W = "O",
  E = "I",
  R = "U",
  T = "Y",
  A = "Semicolon",
  S = "L",
  D = "K",
  F = "J",
  G = "H",
  Z = "Slash",
  X = "Period",
  C = "Comma",
  V = "M",
  B = "N",
  Tab = "Backspace",
  CapsLock = "Enter",
}

-- macOS reports Caps Lock as a switch, so its mirror is a single tap there
local IS_MAC = _REBIND.platform == "macos"

local layer, used = false, false
local held = {}

function OnDown(key)
  if key == cfg.layer_key then
    if not layer then
      layer, used = true, false
    end
    return false
  end
  local out = layer and MIRROR[key]
  if not out then
    return true
  end
  used = true
  if IS_MAC and key == "CapsLock" then
    HID.Combo(out)
  else
    held[key] = out
    HID.Down(out)
  end
  return false
end

function OnUp(key, durationMs)
  if key == cfg.layer_key then
    if not layer then
      return true
    end
    if not used and (durationMs or 0) < cfg.tap_ms then
      HID.Combo(cfg.layer_key)
    end
    layer, used = false, false
    return false
  end
  local out = held[key]
  if out then
    HID.Up(out)
    held[key] = nil
    return false
  end
  return true
end

function OnStop()
  for _, out in held do
    HID.Up(out)
  end
end