Skip to content

feat: add mouse buttons 6–9 as pickable actions - #335

Open
MichaelDanCurtis wants to merge 6 commits into
AprilNEA:masterfrom
MichaelDanCurtis:feat/mouse-buttons-6-9
Open

feat: add mouse buttons 6–9 as pickable actions#335
MichaelDanCurtis wants to merge 6 commits into
AprilNEA:masterfrom
MichaelDanCurtis:feat/mouse-buttons-6-9

Conversation

@MichaelDanCurtis

@MichaelDanCurtis MichaelDanCurtis commented Jun 30, 2026

Copy link
Copy Markdown
Contributor

Summary

Adds four pickable actions — MouseButton6MouseButton9 — that synthesize
mouse buttons 6–9, for apps/games/CAD that bind buttons beyond the standard
five. Mirrors the existing MouseBack/MouseForward pattern.

Why: the Action vocabulary capped output at "button 5". Users wanting a
physical button to emit button 6+ (Blender, MMO-mouse emulators, etc.) had no
path, even though the underlying injection layer already supported arbitrary
button numbers on macOS/Linux.

What changes

Layer Change
openlogi-core/src/binding.rs +4 Action variants; wired into label() ("Button 6"…), category() (Category::Mouse), and catalog()
openlogi-inject/src/inject.rs macOS → post_other_button(5..=8); Linux → evdev BTN_FORWARD/BACK/TASK/0; Windows → log-and-skip
openlogi-gui/src/mouse_model/picker.rs icon arms (compiler-forced — exhaustive match, no wildcard)
openlogi-gui/locales/*.yml (×20) "Button 6""Button 9" translation keys, each locale's own "button" word

Purely additive — no schema_version bump, no migration. New unit variants
serialize as bare TOML strings ("MouseButton6"), consistent with existing
extra-button actions.

Platform coverage

  • macOS — full (existing post_other_button already takes any number)
  • Linux — full (evdev BTN_* family)
  • Windows — log-and-skip. SendInput's mouse path carries flags for
    buttons 1–5 only; there's no flag for 6+. Documented gap, matches the
    existing "no platform equivalent → debug log + skip" pattern. Left out of
    scope to fix here since Windows is a preview target.

Test plan — what was verified locally

  • cargo test -p openlogi-core — 84 pass, including new
    extra_mouse_button_labels and extended category_mouse_variants;
    all_catalog_variants_roundtrip_toml now exercises the 4 new variants
  • cargo test -p openlogi-inject — 1 pass
  • cargo test -p openlogi-agent-core — 33 pass (consumes the Action
    enum; confirms no downstream missing-match arms)
  • cargo build -p openlogi-gui (macOS) — succeeds after installing the
    Metal Toolchain; the picker's exhaustive match compiles, proving all
    four variants are covered
  • Ran the dev-built GUI on real hardware against an MX Master 3S over
    Bluetooth-direct — confirmed Button 6/7/8/9 appear in the MOUSE section
    of the action picker, with icons, after Forward (Button 5)
  • cargo build -p openlogi-inject (macOS) — succeeds
  • Linux/Windows cargo check --target — no cross-targets installed
    locally; relies on CI. evdev 0.13.2 confirmed to expose
    BTN_FORWARD/BTN_BACK/BTN_TASK/BTN_0.

Honest note on emission coverage

Button reception by a downstream app (e.g. Blender registering MB6) was not
end-to-end tested. The emission path reuses the already-shipping
post_other_button (proven for buttons 3/4) with a different integer argument
(5–8) on the same MOUSE_EVENT_BUTTON_NUMBER field, so the risk is low — but
flagging it rather than claiming full end-to-end verification.

Notes

  • Naming: variants MouseButton6MouseButton9, labels "Button 6"
    "Button 9". Unlike Back/Forward these have no universal semantic meaning.
  • Spec & plan live in docs/superpowers/specs/2026-06-29-mouse-buttons-6-9-design.md
    and docs/superpowers/plans/2026-06-29-mouse-buttons-6-9.md (in the last two
    commits on this branch). Happy to rebase them out if you'd prefer code-only.

@greptile-apps

greptile-apps Bot commented Jun 30, 2026

Copy link
Copy Markdown

Greptile Summary

This PR adds pickable actions for mouse buttons 6 through 9. The main changes are:

  • New Action variants, labels, categories, catalog entries, and core tests.
  • GUI picker icon handling and locale keys for the new actions.
  • macOS and Linux injection paths for the new buttons.
  • Windows debug-and-skip handling for unsupported buttons.

Confidence Score: 4/5

This is close, but the Linux Button 9 mapping should be fixed before merging.

  • Linux now advertises the new emitted button codes.
  • MouseButton9 still emits BTN_0, so apps can receive the wrong numbered button event.
  • The core, GUI, macOS, and Windows changes look consistent with the intended additive behavior.

Files Needing Attention: crates/openlogi-inject/src/inject/linux.rs

Important Files Changed

Filename Overview
crates/openlogi-core/src/binding.rs Adds the new action variants with labels, mouse categorization, catalog entries, and focused tests.
crates/openlogi-inject/src/inject/linux.rs Adds Linux emission and uinput capabilities for the new actions, but Button 9 still maps to the wrong evdev code.
crates/openlogi-inject/src/inject/macos.rs Maps the new actions to the existing macOS other-button event path.
crates/openlogi-inject/src/inject/windows.rs Adds explicit debug-and-skip handling for unsupported Windows output.
crates/openlogi-gui/src/mouse_model/picker.rs Adds picker icon coverage for the new mouse-button actions.

Fix All in Codex Fix All in Claude Code

Reviews (3): Last reviewed commit: "feat(gui): add Button 6-9 translation ke..." | Re-trigger Greptile

Comment thread crates/openlogi-inject/src/inject.rs Outdated
Comment thread crates/openlogi-inject/src/inject.rs Outdated
Comment on lines +80 to +83
Action::MouseButton6 => linux::click(KeyCode::BTN_FORWARD),
Action::MouseButton7 => linux::click(KeyCode::BTN_BACK),
Action::MouseButton8 => linux::click(KeyCode::BTN_TASK),
Action::MouseButton9 => linux::click(KeyCode::BTN_0),

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Linux Button Numbers Are Reordered

The new Linux mapping mixes semantic side-button codes with the positional BTN_0 range, so the emitted events do not line up with the user-facing button numbers. A Linux app that binds the numbered extra buttons can receive BTN_FORWARD, BTN_BACK, BTN_TASK, and then BTN_0 for Button 9, which makes Button 9 look like the first generic button instead of the ninth numbered button.

Fix in Codex Fix in Claude Code

@MichaelDanCurtis

Copy link
Copy Markdown
Contributor Author

Closing for now — withdrawing until the feature is fully built and tested locally. Sorry for the noise.

Add an approved design for emitting mouse buttons 6–9 as pickable
actions. Approach A — four unit variants mirroring MouseBack/
MouseForward — surfaced through the existing data-driven action
stack (catalog/category/picker/inject). macOS and Linux get full
support; Windows is a documented log-and-skip gap (SendInput caps
at button 5).
…g-and-skip)

macOS: post_other_button(5..=8) via MOUSE_EVENT_BUTTON_NUMBER.
Linux: evdev BTN_FORWARD/BACK/TASK/0.
Windows: SendInput caps at button 5, so log-and-skip (documented gap,
same pattern as macOS-only navigation actions).
Reuses the generic mouse.svg icon (same as MiddleClick). The picker's
icon match is exhaustive with no wildcard, so this is compiler-forced:
the build cannot succeed without it once the variants exist.
Each locale uses its own word for 'button' (derived from its existing
'Back (Button 4)' entry). For locales whose existing word includes a
'side' modifier (ja サイドボタン, ru боковая кнопка, zh-* 侧键/側鍵) the
plain button/key word is used, since buttons 6-9 are not side buttons.
@davidbudnick
davidbudnick force-pushed the feat/mouse-buttons-6-9 branch from c018d69 to 03fa79f Compare August 2, 2026 00:51
Action::MouseButton6 => click(KeyCode::BTN_FORWARD),
Action::MouseButton7 => click(KeyCode::BTN_BACK),
Action::MouseButton8 => click(KeyCode::BTN_TASK),
Action::MouseButton9 => click(KeyCode::BTN_0),

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Button 9 misfires

MouseButton9 still emits BTN_0 on Linux. That code is the first entry in the generic BTN_0..BTN_9 range, not a ninth positional mouse button, so an app that binds numbered extra buttons can receive this as the first generic button instead of the selected Button 9 action. The new capability list now advertises this event, which means the wrong event is delivered instead of being dropped.

Fix in Codex Fix in Claude Code

@davidbudnick davidbudnick added platform: all Cross-platform issue type: feature New feature request labels Aug 2, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

platform: all Cross-platform issue type: feature New feature request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants