Skip to content

feat: map the pen buttons and the tablet keys - #175

Merged
iSweat-exe merged 3 commits into
mainfrom
feat/button-mapping
Oct 20, 2026
Merged

iSweat-exe merged 3 commits into
mainfrom
feat/button-mapping

Conversation

@iSweat-exe

Copy link
Copy Markdown
Collaborator

What and why

The pen button bindings were saved but never used: the engine ignored them. This change makes the buttons work, and adds bindings for the keys on the tablet itself (ExpressKeys).

  • A pen button or a tablet key can press a mouse button (Left Click, Right Click, Middle Click, Back, Forward), a key, or a shortcut such as Ctrl+Shift+Z.
  • Engine. New core::input (the binding format) and tablet_manager::buttons (follows button changes, counts shared keys, releases everything when the pen leaves, the tablet goes away or the engine stops). The binding is read when the button is pressed and kept until it is released, so editing a binding while a button is held cannot leave a key stuck.
  • Windows. SendInput, keys sent as scan codes by position on a US keyboard, so the key recorded in the interface is the key that is pressed on any keyboard layout.
  • Linux. Mouse buttons on the existing virtual mouse, and a new NextTabletDriver Virtual Keyboard.
  • Tablet keys. New aux_button_bindings setting (old profiles load without it). The number of pen buttons and tablet keys comes from the tablet definition (Pen.ButtonCount, AuxiliaryButtons.ButtonCount), so each tablet shows the right rows.
  • Interface. Each row has a text field checked by the driver's own parser (a new normalize_binding command), a presets list, and a recorder for keys and shortcuts.
  • Docs. New Button mapping guide, and the pages that said these buttons were "not used yet" are updated.

Also changes process_packet to take one PacketLoopState instead of two loop variables.

How it was tested

  • cargo clippy --all-targets --all-features -- -D warnings clean on the root crate, sdk and src-tauri.
  • cargo nextest run --all-features --profile ci: 602 passed. New tests cover the parser (aliases, errors, round trip), the router (order, shared modifiers, release on leave, release on stop, a binding edited while held), the Windows tables, and the tablet key counts.
  • Frontend: vitest 263 passed, svelte-check and eslint clean, Playwright 65 passed (new tests for tablet keys, recording and the error message). I looked at the screen in a browser with the dev mock.
  • Not tested: real key and mouse events on Windows (the tests never inject input, on purpose) and any real tablet. Linux was not compiled or run on my machine (no Linux toolchain here), so the Linux CI job is the first check of injector/linux.rs. I checked the evdev signatures and key codes against the crate source.

Known limits

  • A pen button bound to Left Click shares the left button with the tip; releasing one while the other is held also releases the click.
  • The tip and eraser bindings on the same tab are still not used.
  • The number pad and media keys cannot be bound yet.
  • The security advisories check is red on main for dependencies that are not part of this change.

Checklist

  • The title follows Conventional Commits.
  • I added or updated tests for the behavior that changed.
  • I added no unwrap(), expect(), panic! or indexing on a runtime path, and I handled locks safely.
  • I updated the docs (README, docs/, or the interface) if a user or a developer can see the change.
  • If this touches how installed copies update (tag format, release files, installer, update address or key), I read docs/releasing.md. (Does not apply.)

The pen button bindings were saved but never used. The engine now turns the
buttons reported by the parsers into mouse buttons and keys, on Windows
(SendInput, by scan code) and Linux (a virtual mouse and a new virtual keyboard).

- core::input: the binding format (None, a mouse button, or a chord such as
  Ctrl+Shift+Z), with the OpenTabletDriver spellings still accepted.
- tablet_manager::buttons: follows button changes only, counts shared keys,
  remembers the binding applied at press time and releases everything when the pen
  leaves, the tablet goes away or the engine stops.
- aux_button_bindings: bindings for the keys on the tablet (ExpressKeys).
- The tablet definition gives the pen button and tablet key counts, which
  reach the interface through get_tablet_status.
- normalize_binding: lets the interface check a binding with the same parser.
Each pen button and tablet key gets a field with a list of presets, a recorder
that captures a key or a shortcut, and the driver's own check of the text. A
Tablet Keys section appears for tablets that have keys, and the rows follow the
button counts of the tablet definition.
Pen buttons and tablet keys are no longer listed as not used. The guide covers
the binding format, the recorder, how the buttons behave and the known limits.
@github-actions github-actions Bot added feature New functional requirement or request area: frontend Svelte UI area: backend Rust driver and Tauri backend area: plugins Plugin system, SDK and bundled plugins area: docs Documentation labels Oct 19, 2026
@github-actions

Copy link
Copy Markdown

Coverage

Lines Floor
Rust, production code (5693/6602 lines) 86.2 % 85 % pass
Frontend (969/2143 lines) 45.2 % 40 % pass
All code (6662/8745 lines) 76.2 % 70 % pass

Coverage is well above its floor: raise frontend to 45, total to 76 in coverage-thresholds.json.

The 10 least covered Rust files
File Lines Missed
drivers/detection.rs 9.2 % 217
engine/injector/mod.rs 33.3 % 18
drivers/hid_caps.rs 34.5 % 19
application/telemetry/mod.rs 35.9 % 25
logger.rs 51.0 % 51
application/services/supervisor.rs 53.1 % 15
engine/plugins/manager.rs 54.7 % 81
settings/session.rs 55.6 % 12
engine/tablet_manager/owner.rs 59.0 % 80
settings/logging.rs 60.0 % 6

@iSweat-exe
iSweat-exe merged commit 15a2ea3 into main Oct 20, 2026
17 checks passed
@iSweat-exe
iSweat-exe deleted the feat/button-mapping branch October 20, 2026 15:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: backend Rust driver and Tauri backend area: docs Documentation area: frontend Svelte UI area: plugins Plugin system, SDK and bundled plugins feature New functional requirement or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant