Skip to content

fix(agent): reload control capture across app switches - #671

Open
Phecda wants to merge 2 commits into
AprilNEA:masterfrom
Phecda:fix/stabilize-control-capture
Open

fix(agent): reload control capture across app switches#671
Phecda wants to merge 2 commits into
AprilNEA:masterfrom
Phecda:fix/stabilize-control-capture

Conversation

@Phecda

@Phecda Phecda commented Aug 19, 2026

Copy link
Copy Markdown
Contributor

Summary

Foreground-app changes previously stopped and rebuilt the HID++ control-capture session so the new app-specific configuration could take effect. On the tested MX Master 3, rebuilding left a gap of more than one second between control capture stopped and control capture active.

During that gap, diverted controls temporarily returned to their firmware-native behavior. In practice, using the auxiliary button could open the macOS application switcher instead of executing the active OpenLogi binding.

This change keeps the existing capture channel, listener, and session alive across normal app switches and reloads the complete app-specific CaptureSpec in place.

Changes

  • Agent core: publish each complete app-specific CaptureSpec to the active capture session instead of restarting it.
  • HID: incrementally transition controls between native, plain-diverted, raw-XY, and thumb-wheel modes.
  • HID: avoid hardware writes when only the action assigned to an already-captured control changes.
  • HID: keep the listener active and retry the latest specification after a failed HID++ reload.
  • Agent core: continue restarting capture when the route or re-arm generation changes, pairing takes ownership, the device is removed, or the capture channel dies.
  • Tests: cover per-app capture-plan differences, session continuity across specification changes, requested control modes, and gesture-state cleanup when a source is removed.

Behavior

Before this change:

  • Switching the frontmost app stopped the current capture session.
  • Diverted buttons were restored to native behavior while a replacement session was created.
  • The observed stop/start gap could exceed one second.
  • Input during that gap could trigger the device or macOS default action instead of the configured OpenLogi action.

After this change:

  • Normal app switches produce control capture reloaded without control capture stopped.
  • The capture channel, event listener, and session remain active.
  • The new app-specific rules take effect without the previous stop/start gap.
  • Only hardware capture modes that actually changed require HID++ writes; action-only changes require none.

Testing

  • cargo fmt --all -- --check
  • cargo clippy --workspace --all-targets -- -D warnings
  • cargo test --workspace
  • RUSTDOCFLAGS="-D warnings" cargo doc -p openlogi-hid -p openlogi-hidpp -p openlogi-hidpp-derive --no-deps --document-private-items
  • Runtime-tested with an MX Master 3: repeated foreground-app switches logged control capture reloaded without control capture stopped, and the configured auxiliary-button behavior remained active across app switches.
  • The final tree includes a control-flow-only simplification made after the hardware test and has passed the full automated gate.

@Phecda
Phecda force-pushed the fix/stabilize-control-capture branch from c8e15fe to 4dc4375 Compare August 20, 2026 02:07
@Phecda Phecda changed the title fix(agent): keep button diversion stable across apps fix(agent): reload control capture across app switches Aug 20, 2026
@Phecda
Phecda marked this pull request as ready for review August 20, 2026 03:51
@Phecda
Phecda requested a review from AprilNEA as a code owner August 20, 2026 03:51
@greptile-apps

greptile-apps Bot commented Aug 20, 2026

Copy link
Copy Markdown

Greptile Summary

The PR keeps each device’s HID++ capture session alive while app-specific capture specifications change, applying incremental control-mode updates and retrying failed reloads.

  • Publishes complete capture specifications through a watch channel instead of restarting sessions.
  • Transitions reprogrammable controls and thumb-wheel diversion in place while retaining the existing listener and channel.
  • Synchronizes listener-visible control mappings and clears stale gesture state after source changes.
  • Adds coverage for app-specific plans, session reconciliation, requested control modes, and gesture cleanup.

Confidence Score: 5/5

The PR appears safe to merge, with no concrete blocking or independently actionable non-blocking defect identified.

The session reconciliation, incremental hardware transitions, runtime mapping updates, retry behavior, and lifecycle restart conditions form a consistent capture flow across application switches.

Important Files Changed

Filename Overview
crates/openlogi-agent-core/src/watchers/gesture.rs Reconciles compatible plan changes through a watch channel while preserving restart behavior for route, generation, ownership, removal, and session failures.
crates/openlogi-hid/src/gesture.rs Adds incremental capture-mode reconfiguration, listener-visible runtime state, retry handling, and in-place thumb-wheel transitions without an actionable correctness defect identified.
crates/openlogi-hid/src/gesture/tests.rs Adds focused tests for control-mode selection and cleanup of in-progress gesture state when a source is removed.
crates/openlogi-agent-core/src/capture_plan.rs Adds regression coverage confirming that a per-app button override changes only that app’s diversion set.
crates/openlogi-hid/src/lib.rs Re-exports the new capture-session entry point that accepts live specification updates.

Sequence Diagram

sequenceDiagram
    participant App as Foreground-app watcher
    participant Manager as Capture manager
    participant Session as Live capture session
    participant Device as HID++ device
    App->>Manager: Publish updated DeviceCapturePlan
    Manager->>Session: Send complete CaptureSpec
    Session->>Device: Apply changed control modes
    alt Reload succeeds
        Session->>Session: Publish updated runtime mappings
        Session-->>Manager: Keep channel and listener alive
    else HID++ write fails
        Session->>Session: Retain latest requested spec
        Session->>Device: Retry after delay
    end
Loading

Reviews (1): Last reviewed commit: "fix(agent): reload control capture specs..." | Re-trigger Greptile

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant