AprilNEA / AprilNEA/OpenLogi

[Bug]: macOS: Back/Forward never navigate in Finder on a Bluetooth-direct MX Master 3S — `MouseBack` posts a button 4/5 Finder ignores, and the default ⌘[ binding is never HID++-diverted so it dies in the fail-closed hook

Open
#1,263 3 comments 1 reaction 0 assignees View on GitHub
platform: macos type: bug
Dominant language
Rust
Stars
21k
Forks
675
Avg merge
2d 5h
Merged PRs (30d)
172

Description

### Pre-flight checklist

- [x] I searched existing issues. Related: #354 (MX Master 3S over Bolt, Back/Forward dead in Safari *and* Finder), #582 (Finder Back/Forward dead since 0.6.25), #23, #736, #1118 (Safari), PR #363. This report adds the two concrete reasons Finder cannot work today, with evidence for each and a proposal; happy to have it folded into #354 if you prefer one thread.
- [x] I am on the latest release: 0.8.3 (first hit on 0.8.1, re-tested on 0.8.3 today — identical).
- [x] Logi Options+ is not installed (no Options+ app, no `com.logitech.manager` process running).

### Which part of OpenLogi?

Both

### OpenLogi version

0.8.3 (Homebrew cask)

### Operating system

macOS

### OS version & architecture

macOS 26.5.2 (25F84), Apple Silicon (arm64)

### Device model

MX Master 3S for Business (`046d:b035`), no receiver

### How is the device connected?

Bluetooth (direct, no receiver)

### Affected area(s)

- [x] Button remapping

### What happened?

Two bindings tried on the side buttons, same result in Finder:

**a) "Back (Button 4)" / "Forward (Button 5)"** (`MouseBack` / `MouseForward`):

```toml
[devices."serial:REDACTED".bindings]
Back = "MouseBack"
Forward = "MouseForward"
```

- Chrome: both buttons navigate back/forward. ✅
- Finder: pressing either button does nothing — no folder navigation. ❌

**b) The default "Browser Back" / "Browser Forward"** (`BrowserBack` / `BrowserForward`, ⌘[ / ⌘]):

```toml
[devices."serial:REDACTED".bindings]
Back = "BrowserBack"
Forward = "BrowserForward"
```

- Finder: still nothing. ❌ (re-checked on 0.8.3 today)

Expected: Back/Forward navigate in Finder as well, as they do with Logi Options+ on the same mouse — and as the default binding (⌘[ / ⌘], which Finder's *Go → Back/Forward* menu honours) is supposed to.

### Steps to reproduce

1. MX Master 3S paired directly over Bluetooth, no receiver.
2. Buttons tab → bind Back → *Back (Button 4)*, Forward → *Forward (Button 5)*.
3. Chrome: open a link, press the Back button → navigates.
4. Finder: open a subfolder, press the Back button → nothing.
5. Reset both to the default *Browser Back* / *Browser Forward*.
6. Finder: open a subfolder, press the Back button → still nothing.

### Why (code reading against v0.8.3)

Two independent things stop Finder from ever seeing a "back":

**1. `MouseBack`/`MouseForward` cannot work in Finder or Safari by construction.**
[`post_other_button(3|4)`](https://github.com/AprilNEA/OpenLogi/blob/v0.8.3/crates/openlogi-inject/src/inject/macos.rs#L213) posts a synthetic `OtherMouseDown/Up` with button number 3/4. On macOS only Chromium- and Firefox-family apps implement navigation on those buttons; Finder, Safari, Preview etc. never did (that gap is the whole reason tools like SensibleSideButtons exist). Yet the [action docs](https://github.com/AprilNEA/OpenLogi/blob/v0.8.3/crates/openlogi-core/src/binding/action.rs#L36-L43) and the picker text sell it the other way round — "browsers and most apps interpret natively — unlike `BrowserBack`, which sends ⌘[ and is ignored by many apps". On macOS it is the reverse: ⌘[ / ⌘] is honoured by Finder, Safari, Chrome and Firefox alike, while button 4/5 is the one most apps ignore. That text is what steered me to the wrong action in the first place.

**2. The default `BrowserBack` (⌘[) is never HID++-diverted, so on this unit it depends on a hook that fails closed.**
[`default_binding`](https://github.com/AprilNEA/OpenLogi/blob/v0.8.3/crates/openlogi-core/src/binding/defaults.rs#L51-L52) makes `Back = BrowserBack`, and [`plan_for_device`](https://github.com/AprilNEA/OpenLogi/blob/v0.8.3/crates/openlogi-agent-core/src/capture_plan.rs#L156) only diverts a control when its action differs from that default. The agent log confirms it: with the default binding the capture summary reports `buttons=1` (only the GestureButton's single binding), so `0x0053`/`0x0056` stay native and ⌘[ can only come from the global CGEventTap. That tap [refuses events it cannot attribute](https://github.com/AprilNEA/OpenLogi/blob/v0.8.3/crates/openlogi-agent-core/src/runtime/hook.rs#L202-L209), and #722 established that on this mouse family the side-button CGEvents arrive with `device=None` — it fixed *gesture-mode* Back/Forward by moving them to the HID++ raw-XY channel, but a *single-action* Back/Forward equal to the default still takes the hook path. Net effect: ⌘[ is never sent, the native button 4/5 leaks through (so Chrome keeps working and hides the failure), and Finder/Safari get nothing. I have not instrumented the hook to print `device=None` for this unit myself; tell me if you want that trace.

### Proposed fix

1. Divert Back/Forward over HID++ whenever the OS hook cannot be relied on for them (Bluetooth-direct on macOS at least), even when the binding equals the default — the "default means native" shortcut in `plan_for_device` is only valid when the hook can actually see and attribute the button. The divert plumbing from #722 already exists for CIDs `0x0053`/`0x0056`; the device reports both as `divertable, raw-xy`.
2. Make the macOS semantics honest, one of:
- relabel/document `MouseBack`/`MouseForward` as "Chromium/Firefox only" on macOS and point Finder/Safari users to ⌘[ / ⌘], or
- give macOS an Options+-style navigation action: post button 4/5 *and* fall back to ⌘[ / ⌘] for apps known not to consume it (Finder, Safari, Preview, System Settings), or synthesise the two-finger navigation swipe that all of them honour.

Workaround worth trying (not verified yet): a **Custom Shortcut** ⌘[ / ⌘] on the side buttons — being non-default it should be HID++-diverted and injected by the agent, bypassing the hook.

### Diagnostics report

Collected from the CLI and the agent log (I can paste the About → Copy Diagnostics block on request):

- OpenLogi (GUI/agent): 0.8.3, Homebrew cask
- OS: macOS 26.5.2 (arm64)
- Accessibility: granted (`accessibility granted — installing OS mouse hook` / `OS input hook installed` in the log) · Input Monitoring: granted
- Config: schema 6 · `capture_mouse_events = true`

### `openlogi list` output

```text
(inventory read from the running agent)
MX Master 3S B (—, vid=046d pid=b035)
└─ slot 255 ● MX Master 3S For Business (mouse, wpid=?, battery=85% full (discharging))
model_ids=[b035,0000,0000] ext=00 serial=REDACTED unit_id=REDACTED transports=btle
```

```text
$ openlogi diag controls
device: MX Master 3S For Business (direct 046d:b035)
0x0053 0x003c 0x0531 divertable, raw-xy, analytics-events ← Back
0x0056 0x003e 0x0531 divertable, raw-xy, analytics-events ← Forward
```

### Logs

Capture summary with `MouseBack`/`MouseForward` (both diverted, counted in `buttons=4`; the synthetic button 4/5 reaches Chrome, so nothing is logged as failing — the Finder miss is silent):

```shell
2026-08-31T08:42:15.118267Z INFO openlogi_device::session::gesture: control capture active index=255 gesture_sources=0 dpi_buttons=1 buttons=4 thumbwheel=true
```

Capture summary with the default `BrowserBack`/`BrowserForward` on 0.8.3 (Back/Forward not diverted — only the GestureButton is):

```shell
2026-09-04T05:34:46.474875Z INFO openlogi_agent::lifecycle: accessibility granted — installing OS mouse hook
2026-09-04T05:34:46.476540Z INFO openlogi_agent_core::runtime::hook: OS input hook installed
2026-09-04T05:35:41.173344Z INFO openlogi_device::session::gesture: control capture active index=255 gesture_sources=0 gesture_buttons=0 dpi_buttons=1 buttons=1 thumbwheel=true wake_rearm=true
```

### macOS permissions (if applicable)

- [x] OpenLogi has **Accessibility** permission
- [x] OpenLogi has **Input Monitoring** permission

Refs #354, #582, #23, #736, #1118, #722, #363

Contributor guide

No contributing guide indexed for this repository

Research direction

Start with crates/openlogi-agent-core/src/capture_plan.rs and runtime/hook.rs, then inspect crates/openlogi-inject/src/inject/macos.rs and the defaults in crates/openlogi-core/src/binding/defaults.rs. Trace default and custom Back/Forward capture for direct Bluetooth devices, reproduce it in Finder and Chrome, and verify that the chosen behavior is injected reliably without breaking native navigation.

Written by the indexing model from the issue text.

Assessment

Tech stack
macos, rust
Domain
desktop
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
52/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.