[Feature]: An action that holds the modifiers and taps the main key once, for Cmd+Tab / Alt+Tab style switchers
- Dominant language
- Rust
- Stars
- 21k
- Forks
- 675
- Avg merge
- 2d 5h
- Merged PRs (30d)
- 172
Description
### Pre-flight checklist
- [x] I searched existing issues and the [Roadmap](https://github.com/AprilNEA/OpenLogi#roadmap), and this isn't already tracked.
### Problem / motivation
Binding a mouse button to the application switcher does not work today, and the two existing shortcut actions each fail it in a different way:
| action | modifiers | main key | result with `Cmd+Tab` |
|---|---|---|---|
| `CustomShortcut` | tapped | tapped | switcher flashes and closes; Cmd is not held |
| `HoldShortcut` (#960, v0.8.0) | held | **held** | switcher runs to the end of the list and parks there |
| `HoldModifier(u8)` proposed in #652 | held | none | nothing taps Tab |
| **missing** | **held** | **tapped once** | what the switcher actually needs |
The switcher UI needs the modifier to stay down (so the overlay stays open and releasing commits the choice) while the main key is tapped exactly once. `HoldShortcut` was built for push-to-talk (#399), where holding the whole chord is the correct behaviour; this is not a bug in it, just a shape it does not cover.
Measured on an MX Master 3 (macOS 15.7.3), listening on `kCGSessionEventTap`, holding the bound button for about three seconds:
| | Cmd held | Tab |
|---|---|---|
| `HoldShortcut` bound to `Cmd+Tab` | 2683 ms | **held the whole time** |
| the same chord typed on a keyboard | 3143 ms | tapped, 5 ms |
### Proposed solution
A new `Action` variant that holds the combo's modifiers for the lifetime of the button press and taps the combo's main key once at press time: the third leg of the family `CustomShortcut` and `HoldShortcut` already form.
Sketch, following the existing conventions:
- `Action::TapKeyHoldingModifiers(KeyCombo)`, appended at the end of the enum. The `config.toml` side is position-independent (variant names are the external tags), but the IPC side encodes bincode variant indices, so appending is the append-only recipe v28 already followed when `Action::HoldShortcut` was added, together with the `PROTOCOL_VERSION` bump and the `cargo test -p openlogi-ipc --test wire_format` update that implies.
- Reuses the press lifecycle `HoldShortcut` already has (`try_hidpp_button_down` / `try_hidpp_button_up`), so no new plumbing.
- `crates/openlogi-inject/src/inject.rs::held_keys()` currently pushes the main key into the held list unconditionally (`keys.push(HeldKey::Key(combo.key()))`); the new variant would hold only the modifiers and emit a balanced down/up for the key.
- Platform-neutral, like every other `Action`: `KeyCombo` already stores abstract modifier bits and the injection layer maps them per platform, so a Windows user picks `Alt+Tab` (the Option bit) and a macOS user picks `Cmd+Tab`. No `cfg(target_os)` in the enum.
- The GUI label can be generated from the combo the way `HoldShortcut`'s `Hold {combo}` label already is, for example `Hold ⌘, tap Tab`.
**Scope, honestly.** This covers one family of interactions: UIs that stay open while a modifier is held and commit on release. On macOS that is Cmd+Tab and Cmd+\`; on Windows and Linux, Alt+Tab; in some editors, Ctrl+Tab for the recent-files switcher. Outside that family I cannot name a use for it. It is a narrower action than `HoldShortcut`, not a more general one.
### Alternatives considered
- **Fixing `HoldShortcut` to tap the key:** no. Push-to-talk (#399, the feature it was built for) needs the key held; changing it would break that.
- **`HoldModifier(u8)` from #652:** solves half of it; nothing taps the key.
- **Sending the chord repeatedly:** advances the switcher on its own and does not keep the overlay open.
### Related area(s)
- [x] GUI
- [ ] CLI
- [x] Button actions / remapping
- [ ] DPI
- [ ] SmartShift
- [ ] Per-application profiles
- [x] Configuration (TOML)
- [ ] Auto-update
- [ ] Other
### Additional context
The `Action` hold axis is already being extended one special case at a time: `HoldShortcut` (#960, merged), `HoldModifier` (#652, proposed), `HoldMouseButton6` (PR #1055, open), hold-to-repeat over HID++ (PR #467, open), plus #1046 and #1054 asking for held mouse buttons for CAD orbit. This is the keyboard-chord leg of the same axis.
It would also close a request that is currently filed away. #792 asked:
> add the ability to setup a custom shortcut for example cmd+ tab o something else
and was closed as a duplicate of #573. #573 is about shortcuts not being assignable to mouse buttons at all, and #1018 is about assigned shortcuts not firing; but even with both of those fixed, `Cmd+Tab` still will not work, because no existing action can express the hold-and-tap shape. As far as I can tell nobody has pointed that out yet.
Contributor guide
No contributing guide indexed for this repository
Research direction
Start with the Action enum and the existing HoldShortcut press lifecycle, then inspect crates/openlogi-inject/src/inject.rs::held_keys() for how held modifiers and the main key are emitted. Update the IPC protocol and GUI label following the existing conventions, and run cargo test -p openlogi-ipc --test wire_format; done means the new action holds modifiers while tapping the main key once and releases both cleanly.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- desktop
- Issue type
- Feature
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 72/100