Skip to content

fix(hook): read Windows pointer motion from raw input - #472

Draft
Stanley5249 wants to merge 1 commit into
AprilNEA:masterfrom
Stanley5249:fix/windows-gesture-motion-rawinput
Draft

fix(hook): read Windows pointer motion from raw input#472
Stanley5249 wants to merge 1 commit into
AprilNEA:masterfrom
Stanley5249:fix/windows-gesture-motion-rawinput

Conversation

@Stanley5249

Copy link
Copy Markdown

Summary

Alternative fix for #471, without the edge-clamp limitation of the simpler
approach. Raw input (WM_INPUT) reports the device's own relative counts, so a
swipe keeps producing deltas after the cursor hits a screen edge.

Opening as a draft: this is ~350 lines of Win32 FFI against RAWINPUT layout,
buffer alignment, and record striding, and I'm not convinced the edge case earns
that maintenance cost. The ordering hazard below is the tell — it exists only
because motion and buttons stopped arriving on one channel, and the remedy is a
heuristic rather than a guarantee. Filed so the alternative is concrete and
reviewable, not because I think it should land as-is.

Changes

openlogi-hook

  • New windows/raw_input.rs: message-only sink window + RIDEV_INPUTSINK
    registration, GetRawInputBuffer batch drain, RIDEV_REMOVE teardown.
  • windows.rs: WM_INPUT handled in the message loop, DefWindowProcW called
    directly to release each record; dispatch() extracted so both input paths
    reach the callback.
  • Buttons and motion arrive on two independent paths, so a button press discards
    the queued motion backlog — otherwise a flick made just before a gesture press
    is summed into the fresh hold and commits a swipe the user never made.
  • Cargo.toml: Win32_UI_Input + Win32_Devices_HumanInterfaceDevice;
    Win32_UI_Input_KeyboardAndMouse was unused.

Testing

  • cargo clippy -p openlogi-hook --all-targets — clean
  • cargo test -p openlogi-hook — passing
  • Not runtime-tested on hardware.

Note: the Windows CI job fails until #458 lands — openlogi-hid does not build
without the Win32_System_IO feature.

Refs #471

WH_MOUSE_LL carries the absolute cursor point, which the OS clamps at the
desktop edge, so no motion reached the gesture accumulator on Windows at
all. Raw input reports the device's own relative counts, matching macOS
MOUSE_EVENT_DELTA_X and Linux REL_X.

A message-only sink window registers for WM_INPUT with RIDEV_INPUTSINK
(the agent never holds focus). The hook thread drains the whole queued
backlog per wakeup via GetRawInputBuffer rather than one record per
message: it also services the low-level hook, and reading singly put a
1 kHz mouse's report stream in front of every click. Records are released
by calling DefWindowProcW directly, so cleanup does not depend on the
Static control's window procedure.

Buttons and motion arrive on two independent paths, and a WH_MOUSE_LL
callback runs ahead of WM_INPUT records already queued, so a press
discards the pending backlog — otherwise a flick made just before a
gesture-button press would be summed into the fresh hold.
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