Skip to content

feat: thread device identity for per-device switch conditions#1973

Closed
malpern wants to merge 5 commits intojtroo:mainfrom
malpern:feat/device-identity-pipeline
Closed

feat: thread device identity for per-device switch conditions#1973
malpern wants to merge 5 commits intojtroo:mainfrom
malpern:feat/device-identity-pipeline

Conversation

@malpern
Copy link
Copy Markdown
Contributor

@malpern malpern commented Mar 13, 2026

Summary

  • Adds device_index: u8 field to KeyEvent, threaded from Linux KbdIn through to keyberon switch evaluation
  • On Linux, each registered input device gets a monotonically increasing index assigned at registration time
  • New (device N) switch condition in the parser that matches events from a specific physical device
  • Stores current_device: Option<u8> on Layout (not in keyberon Event row) to preserve the row 0/1 real/virtual key invariant
  • macOS/Windows compile cleanly with device_index: 0 default (no multi-device support yet)

Data Flow

Linux KbdIn::read()             -- Token → device_indices[token] → u8
  → Vec<(InputEvent, u8)>
  → event_loop: KeyEvent.with_device(idx)
  → tx.try_send(KeyEvent{code, value, device_index})
  → handle_input_event:
      layout.current_device = Some(event.device_index)
      layout.event(Event::Press(0, evc))   ← row still 0
  → Layout::do_action → Switch(sw)
      sw.actions(..., self.current_device)
  → evaluate_boolean:
      Device(idx) => current_device == Some(idx as u8)

Usage Example

(switch
  ((device 0) X break)
  ((device 1) Y break))

Not in scope (follow-up PRs)

  • Name-based matching (device "Kinesis") / (defdevice ...) config
  • Per-device layer stacks
  • Windows/macOS multi-device support
  • Device hot-plug stable indexing

Test plan

  • cargo build succeeds
  • All existing keyberon tests pass (79 tests)
  • All existing parser tests pass (100 tests)
  • All existing kanata lib tests pass (28 tests)
  • New unit tests: device_opcode_encoding_roundtrip, device_evaluate_boolean_matches, device_evaluate_boolean_with_and
  • Manual test on Linux with 2 keyboards using (device N) switch conditions

🤖 Generated with Claude Code

malpern and others added 2 commits March 13, 2026 05:21
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…itch conditions

Add device_index to KeyEvent and thread it from Linux KbdIn through to
keyberon's switch evaluation. On Linux, each registered input device gets
a monotonically increasing u8 index. This enables a new `(device N)`
switch condition that matches events from a specific device.

Data flow: KbdIn assigns device indices at registration time, pairs each
InputEvent with its device index in read(), the event loop enriches
KeyEvent via with_device(), handle_input_event sets Layout.current_device,
and switch evaluation checks OpCodeType::Device against current_device.

macOS/Windows default to device_index=0 (no multi-device support yet).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@malpern malpern force-pushed the feat/device-identity-pipeline branch from b21123c to 0c46590 Compare March 13, 2026 10:22
malpern and others added 3 commits March 13, 2026 05:23
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Fixes build failures on Windows, Linux (no-features), Android, and
simulated/test targets where KeyEvent struct literals were missing
the new device_index field.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
… too_many_arguments

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@malpern
Copy link
Copy Markdown
Contributor Author

malpern commented Mar 13, 2026

Closing — opened prematurely against upstream. Will validate locally in KeyPath integration before upstreaming.

@malpern malpern closed this Mar 13, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant