diff --git a/crates/openlogi-hid/src/gesture.rs b/crates/openlogi-hid/src/gesture.rs index 1783494b..1f0da4e1 100644 --- a/crates/openlogi-hid/src/gesture.rs +++ b/crates/openlogi-hid/src/gesture.rs @@ -13,7 +13,8 @@ //! it, mirroring how the CGEventTap hook handles the side buttons. The thumb //! wheel is special: diverting it stops native horizontal scroll, so the GUI //! re-synthesises scroll from the [`CapturedInput::Scroll`] deltas — the wheel -//! is therefore only diverted when its click is actually bound. +//! is therefore only diverted when the user's thumbwheel config leaves its +//! defaults (click bound, rotation rebound, or sensitivity changed). use std::sync::{Arc, Mutex, PoisonError, RwLock}; @@ -44,8 +45,8 @@ pub enum CapturedInput { /// ([`ButtonId::Thumbwheel`]). ButtonPressed(ButtonId), /// Thumb-wheel rotation to re-synthesise as horizontal scroll, in the - /// wheel's `diverted_res` increments. Emitted only while the wheel is - /// diverted to capture its click. + /// wheel's `diverted_res` increments. Emitted while the wheel is diverted + /// (click bound, rotation rebound, or sensitivity changed). Scroll(i16), } @@ -206,8 +207,8 @@ impl ArmedControls { /// Resolve features off the device's root and divert the controls we capture: /// the gesture button (raw-XY) and DPI/ModeShift buttons over `0x1b04`, and — -/// when `capture_thumbwheel` and the wheel reports a single tap — the thumb -/// wheel over `0x2150`. The root-feature lookup mirrors `write::open_feature`, +/// when `capture_thumbwheel` — the thumb wheel over `0x2150`. The +/// root-feature lookup mirrors `write::open_feature`, /// since hidpp 0.2's registry doesn't carry the features OpenLogi reimplements. async fn arm_controls( chan: &Arc, @@ -273,14 +274,17 @@ async fn arm_controls( false } }; - if supports_single_tap { - tw.set_reporting(true, false) - .await - .map_err(|e| GestureError::Hidpp(format!("{e:?}")))?; - thumb = Some((tw, info.index)); - } else { + // Divert whenever capture was requested: rotation rebinds and the + // sensitivity multiplier need the diverted event stream even on wheels + // that report no single-tap capability (e.g. MX Master 4) — lacking the + // tap only means a bound click can never fire. + if !supports_single_tap { debug!("thumb wheel reports no single tap — click not capturable"); } + tw.set_reporting(true, false) + .await + .map_err(|e| GestureError::Hidpp(format!("{e:?}")))?; + thumb = Some((tw, info.index)); } if !gesture_diverted && dpi_cids.is_empty() && thumb.is_none() { diff --git a/crates/openlogi-hid/src/thumbwheel.rs b/crates/openlogi-hid/src/thumbwheel.rs index e0be78f3..d26485ea 100644 --- a/crates/openlogi-hid/src/thumbwheel.rs +++ b/crates/openlogi-hid/src/thumbwheel.rs @@ -4,7 +4,8 @@ //! //! The wheel only has two reporting modes — Native (HID scroll) or Diverted //! (HID++ events) — there is no "report taps but keep scrolling" mode. So the -//! capture session diverts the wheel only when the user has bound its click, +//! capture session diverts the wheel whenever the user's thumbwheel config +//! leaves its defaults (click bound, rotation rebound, or sensitivity changed), //! and re-synthesises horizontal scroll from the rotation deltas to keep //! scrolling working. //!