feat(core): add the Calculator hotkey as a divertable keyboard key - #1247
feat(core): add the Calculator hotkey as a divertable keyboard key#1247thorstent wants to merge 1 commit into
Conversation
Adds `ButtonId::KeyCalculator` and `(0x000a, ButtonId::KeyCalculator)` to `KEYBOARD_KEY_CIDS`, so the Calculator hotkey can be bound like the existing keyboard keys. Closes AprilNEA#1147. Unlike the F-row keys the table was built for, this control sits in the hotkey cluster beside the numpad (ERGO K860, MX Keys S) and is absent from the Signature series. Diversion is the only way to reach it on macOS: with the keyboard in its macOS mode the firmware emits no HID usage at all for this key, so nothing above the HID layer has an event to intercept. In Windows mode the same key natively sends consumer usage 0x0192 (`AL Calculator`). CID and firmware task (`CALCULATOR`) cross-checked against Solaar's `special_keys.py`, the same catalog the existing nine entries cite, and against the Logi asset metadata slot `SLOT_NAME_CALCULATOR`. As for every entry in the table, an unbound key is never diverted, so stock firmware behavior is unchanged unless the user binds it.
Greptile SummaryAdds Calculator as a configurable, divertable keyboard control and advances the IPC protocol version.
Confidence Score: 4/5The configuration schema compatibility issue should be fixed before merging because a saved Calculator binding makes the configuration unreadable after downgrading. KeyCalculator becomes a serialized ButtonId map key while the configuration schema remains unchanged, allowing older readers to accept the schema and then fail parsing the entire file. Files Needing Attention: crates/openlogi-core/src/binding/button.rs and the configuration schema declaration in crates/openlogi-core/src/config.rs
|
| Filename | Overview |
|---|---|
| crates/openlogi-core/src/binding/button.rs | Adds the Calculator identifier and metadata, but expands the persisted ButtonId key space without advancing the configuration schema. |
| crates/openlogi-device/src/session/keyboard.rs | Adds CID 0x000a to capability-filtered keyboard diversion while preserving per-key graceful degradation. |
| crates/openlogi-ipc/src/ipc.rs | Advances the strict IPC compatibility version to 30. |
| crates/openlogi-ipc/tests/wire_format.rs | Updates the protocol-version pin consistently. |
| crates/openlogi-core/src/binding/defaults.rs | Gives the new keyboard key the expected unbound default action. |
| crates/openlogi-ui/locales/en.toml | Adds the canonical Calculator key label mirrored across all locale catalogs. |
Flowchart
%%{init: {'theme': 'neutral'}}%%
flowchart LR
K[Calculator control CID 0x000a] --> E[Enumerate divertable controls]
E --> B{KeyCalculator binding exists?}
B -->|No| N[Leave firmware behavior native]
B -->|Yes| D[Divert control]
D --> A[Dispatch configured action]
Reviews (1): Last reviewed commit: "feat(core): add the Calculator hotkey as..." | Re-trigger Greptile
| /// key: it sits in the hotkey cluster above/right of the numpad on boards | ||
| /// like the ERGO K860 and MX Keys S, and is absent from the Signature | ||
| /// series. | ||
| /// |
There was a problem hiding this comment.
Configuration schema stays stale
When a KeyCalculator binding is saved and the user subsequently runs an older release, the schema-version-7 file passes the version gate but its new ButtonId key fails deserialization, causing the agent to run with defaults and the desktop to treat the saved configuration as read-only.
Adds
ButtonId::KeyCalculatorand(0x000a, ButtonId::KeyCalculator)toKEYBOARD_KEY_CIDS, making the Calculator hotkey bindable like the existing nine keyboard keys.Closes #1147.
Why diversion is the only option here
Unlike the F-row keys the table was built for, this control sits in the hotkey cluster beside the numpad (ERGO K860, MX Keys S) and is absent from the Signature series.
The part that makes this more than a missing table entry: with the keyboard in its macOS mode the firmware emits no HID usage at all for this key, so nothing above the HID layer has an event to intercept. I verified the absence at three levels on an ERGO K860 for Business:
consumer_key_code volume_incrementand the Search keyconsumer_key_code ac_search(0x0221), so the observer was working and that receiver's consumer usages were visible.libinput debug-events --show-keycodes, at raw evdev (evtest, including the receiver's Consumer Control node), and at the raw HID report level — no report arrives, so it is not a missing keycode mapping.0x0192(AL Calculator).Logitech documents this constraint from the other side: their SIGNATURE K650 page lists the "Close browser tab key, Settings key and Calculator key" as requiring Options+ "to work on Mac" while working "out of the box on Windows and Chrome OS", and the K250 page names Calculator as an exception to "Most keys work on Windows, macOS and ChromeOS". Diversion is presumably how Options+ delivers it, and it is the only mechanism available to OpenLogi.
CID and firmware task (
CALCULATOR) cross-checked against Solaar'sspecial_keys.py— the same catalog the existing nine entries cite — and against the Logi asset metadata slotSLOT_NAME_CALCULATOR(slotIdergo-k860-2b364_c10).openlogi diag controlson the K860 reports the control as divertable:As for every entry in the table, an unbound key is never diverted, so stock firmware behavior is unchanged unless the user binds it. In Windows mode, binding it suppresses the native
AL Calculatorusage, which matches how the other keys here behave.KeyCalculatoris appended last in bothButtonIdandKEYBOARD_KEYS, matchingKEYBOARD_KEY_CIDSorder, per the append-only note inbutton.rs. No newActionis needed —RunShellCommand/OpenApplicationalready cover the obvious bindings.Testing
Verified on hardware — ERGO K860 for Business (
ERGO 860B, model id2b364) on a Bolt receiver, macOS on Apple Silicon, keyboard in macOS mode, with:A release build of the patched agent arms the diversion and dispatches the press:
Calculator launches. Before the patch the same keypress produced nothing anywhere in the stack.
Local checks, with
RUSTFLAGS="-D warnings":cargo fmt --all -- --check— cleancargo clippy --all-targets -- -D warningsforopenlogi-core,openlogi-device,openlogi-ipc,openlogi-agent-core,openlogi-hid,openlogi-hidpp,openlogi-inject,openlogi-hook,openlogi-cli,openlogi-ui— cleancargo testfor the same ten packages — 1004 passed, 0 failed, includingwire_format'sprotocol_version_is_pinnedcargo test -p openlogi-ui locale— catalog parity passes;calculator_keyadded at the same position in all 23 catalogscargo build --release -p openlogi-agent— successNot run locally, per the "do not claim a skipped job passed" rule:
cargo test -p openlogi-desktop i18n, and clippy/tests foropenlogi-desktop,openlogi-overlayandopenlogi-camera.gpui_macos's build script needs the Metal shader compiler, which ships only with full Xcode — unavailable on the machine I built on (xcrun: error: unable to find utility "metal"). Those are left to CI. The desktop-side change is limited to the locale catalogs plus the newButtonIdarm, both covered by the portable parity test above.Note for review
PROTOCOL_VERSIONis bumped 29 → 30 for the appendedButtonIdvariant. #1116 also claims 30; whichever lands first, I'll happily rebase this onto 31. Order inKEYBOARD_KEY_CIDSis kept aligned withButtonId::KEYBOARD_KEYS, so the cross-crate ordering test #1116 introduces will hold if that merges first.Happy to add a GUI affordance if wanted — these keyboard slots appear to be config-only today, so this follows the existing pattern.