feat: add mouse buttons 6–9 as pickable actions - #335
Conversation
Greptile SummaryThis PR adds pickable actions for mouse buttons 6 through 9. The main changes are:
Confidence Score: 4/5This is close, but the Linux Button 9 mapping should be fixed before merging.
Files Needing Attention: crates/openlogi-inject/src/inject/linux.rs
|
| 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. |
Reviews (3): Last reviewed commit: "feat(gui): add Button 6-9 translation ke..." | Re-trigger Greptile
| 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), |
There was a problem hiding this comment.
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.
|
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.
c018d69 to
03fa79f
Compare
| Action::MouseButton6 => click(KeyCode::BTN_FORWARD), | ||
| Action::MouseButton7 => click(KeyCode::BTN_BACK), | ||
| Action::MouseButton8 => click(KeyCode::BTN_TASK), | ||
| Action::MouseButton9 => click(KeyCode::BTN_0), |
There was a problem hiding this comment.
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.
Summary
Adds four pickable actions —
MouseButton6–MouseButton9— that synthesizemouse buttons 6–9, for apps/games/CAD that bind buttons beyond the standard
five. Mirrors the existing
MouseBack/MouseForwardpattern.Why: the
Actionvocabulary capped output at "button 5". Users wanting aphysical 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
openlogi-core/src/binding.rsActionvariants; wired intolabel()("Button 6"…),category()(Category::Mouse), andcatalog()openlogi-inject/src/inject.rspost_other_button(5..=8); Linux → evdevBTN_FORWARD/BACK/TASK/0; Windows → log-and-skipopenlogi-gui/src/mouse_model/picker.rsmatch, no wildcard)openlogi-gui/locales/*.yml(×20)"Button 6"–"Button 9"translation keys, each locale's own "button" wordPurely additive — no
schema_versionbump, no migration. New unit variantsserialize as bare TOML strings (
"MouseButton6"), consistent with existingextra-button actions.
Platform coverage
post_other_buttonalready takes any number)BTN_*family)SendInput's mouse path carries flags forbuttons 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 newextra_mouse_button_labelsand extendedcategory_mouse_variants;all_catalog_variants_roundtrip_tomlnow exercises the 4 new variantscargo test -p openlogi-inject— 1 passcargo test -p openlogi-agent-core— 33 pass (consumes theActionenum; confirms no downstream missing-match arms)
cargo build -p openlogi-gui(macOS) — succeeds after installing theMetal Toolchain; the picker's exhaustive
matchcompiles, proving allfour variants are covered
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) — succeedscargo check --target— no cross-targets installedlocally; 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_NUMBERfield, so the risk is low — butflagging it rather than claiming full end-to-end verification.
Notes
MouseButton6–MouseButton9, labels"Button 6"–"Button 9". Unlike Back/Forward these have no universal semantic meaning.docs/superpowers/specs/2026-06-29-mouse-buttons-6-9-design.mdand
docs/superpowers/plans/2026-06-29-mouse-buttons-6-9.md(in the last twocommits on this branch). Happy to rebase them out if you'd prefer code-only.