Skip to content

fix(hook): grab only relative pointer devices, never touchpads or pointing sticks - #401

Open
kesleyfort wants to merge 4 commits into
AprilNEA:masterfrom
kesleyfort:fix/hook-touchpad-grab
Open

fix(hook): grab only relative pointer devices, never touchpads or pointing sticks#401
kesleyfort wants to merge 4 commits into
AprilNEA:masterfrom
kesleyfort:fix/hook-touchpad-grab

Conversation

@kesleyfort

Copy link
Copy Markdown
Contributor

Summary

The Linux hook selected every evdev device advertising BTN_LEFT, which
includes touchpads: they got an exclusive grab whose multitouch EV_ABS
stream the relative-only virtual mouse cannot re-inject, so the built-in
touchpad went dead the moment the agent started. This tightens device
selection and adds an opt-out for users who only want HID++ configuration.

Changes

  • openlogi-hook (src/linux.rs): device selection now requires a real
    relative pointer (BTN_LEFT + REL_X/REL_Y) and refuses anything
    touch-driven (BTN_TOUCH/BTN_TOOL_FINGER, ABS_MT_POSITION_X, or the
    BUTTONPAD/SEMI_MT/DIRECT input properties) as well as pointing sticks
    (POINTING_STICK, whose libinput behaviors a re-injected stream would lose).
    Our own uinput devices are excluded by the shared OpenLogi name prefix,
    covering the action injector too.
  • openlogi-core (src/config.rs) + openlogi-agent (src/main.rs): add
    app_settings.capture_mouse_events (default true). When false, the agent
    never installs the OS-level mouse hook, so no input device is grabbed or
    intercepted on any platform; DPI, SmartShift, gesture-button, and thumb-wheel
    features are unaffected. Read once at agent startup (like show_in_menu_bar);
    flipping it requires an agent restart.
  • docs/CONFIGURATION.md: document the new setting.

Testing

  • cargo build / cargo clippy on the hook, agent, and core crates.
  • Not yet runtime-tested on Linux hardware with a built-in touchpad — needs
    maintainer verification that the touchpad stays live while a relative mouse is
    still hooked, and that capture_mouse_events = false leaves no device grabbed.

Fixes #355

Related: #356 (contributor draft targeting the same issue via device selection)
— overlapping; left open for the maintainer to compare/adopt.

@greptile-apps

greptile-apps Bot commented Jul 17, 2026

Copy link
Copy Markdown

Greptile Summary

This PR fixes the Linux evdev hook incorrectly grabbing touchpads and pointing sticks by tightening device selection to require real relative-pointer capabilities (BTN_LEFT + REL_X/REL_Y) while explicitly excluding touch-driven and pointing-stick devices. It also adds a capture_mouse_events kill-switch that lets users opt out of the OS-level hook entirely without losing HID++-side features.

  • openlogi-hook/src/linux.rs: Introduces is_hookable_mouse() with a layered exclusion strategy (name prefix, relative-axis requirement, touch-key/ABS_MT/property guards) and a comprehensive test suite covering all exclusion paths.
  • openlogi-core/src/config/settings.rs: Adds capture_mouse_events: bool (default true) to AppSettings; the auto_download_assets field ends up with a duplicated doc comment that should be cleaned up.
  • openlogi-agent/src/main.rs: Gates the Accessibility prompt and hook installation behind capture_mouse_events, read once at startup like show_in_menu_bar.

Confidence Score: 4/5

Safe to merge after removing the doubled doc comment on auto_download_assets; the hook-selection logic and kill-switch are correct.

The auto_download_assets field in settings.rs now carries two consecutive, slightly inconsistent doc paragraphs because the old comment was not removed when the new one was inserted. Rustdoc will render both, producing confusing public documentation for the field. Everything else — the exclusion logic, the tests, the agent-side kill-switch — looks correct.

Files Needing Attention: crates/openlogi-core/src/config/settings.rs — the doubled doc comment on auto_download_assets needs the old paragraph removed.

Important Files Changed

Filename Overview
crates/openlogi-hook/src/linux.rs Adds is_hookable_mouse with multi-layer touch/pointing-stick exclusion guards and exhaustive unit tests; fixes the touchpad-kill bug correctly.
crates/openlogi-core/src/config/settings.rs Adds capture_mouse_events field correctly, but the old doc comment for auto_download_assets was not removed, leaving a doubled and inconsistent description in rustdoc output.
crates/openlogi-agent/src/main.rs Gates the accessibility prompt and hook installation behind capture_mouse_events; the accessibility watcher only emits on state transitions so no log spam occurs.
docs/CONFIGURATION.md Documents the new capture_mouse_events setting accurately alongside the existing options.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[evdev::enumerate all /dev/input/ devices] --> B[is_hookable_mouse?]
    B --> C{Name starts with 'OpenLogi '?}
    C -- yes --> SKIP[Skip device]
    C -- no --> D{Has BTN_LEFT + REL_X + REL_Y?}
    D -- no --> SKIP
    D -- yes --> E{Touch keys / ABS_MT / BUTTONPAD / SEMI_MT / DIRECT?}
    E -- yes --> SKIP
    E -- no --> F{POINTING_STICK prop?}
    F -- yes --> SKIP
    F -- no --> HOOK[Grab & hook device]
    HOOK --> G[Create paired uinput virtual mouse]
    G --> H[Re-inject PassThrough events / Swallow Suppress events]
Loading

Reviews (4): Last reviewed commit: "Merge branch 'master' into fix/hook-touc..." | Re-trigger Greptile

Comment thread crates/openlogi-hook/src/linux.rs
Comment on lines +161 to +170
if !hookable
&& d.supported_keys()
.is_some_and(|keys| keys.contains(KeyCode::BTN_LEFT))
{
debug!(
"not hooking {} ({}): has mouse buttons but is not a plain relative-pointer mouse",
path.display(),
d.name().unwrap_or("unnamed"),
);
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Redundant supported_keys() call in debug guard

d.supported_keys() is already called (and its result consumed) inside is_hookable_mouse, but the debug logging condition calls it again on the same Device. Because Device does not cache individual capability tables, this triggers a second parse of the same bitfield. For the fast path (devices that are hookable) no second call happens, but for every non-mouse device that advertises BTN_LEFT the key set is parsed twice. Capturing the keys reference once (or simply accepting the minor duplication) keeps intent clear.

Fix in Codex Fix in Claude Code

kesleyfort and others added 3 commits July 19, 2026 14:43
…nting sticks

The Linux hook selected every evdev device advertising BTN_LEFT, which
includes touchpads: they got an exclusive grab whose multitouch EV_ABS
stream the relative-only virtual mouse cannot re-inject, so the built-in
touchpad went dead the moment the agent started.

Device selection now requires a real relative pointer (BTN_LEFT plus
REL_X/REL_Y) and refuses anything touch-driven (BTN_TOUCH/BTN_TOOL_FINGER,
ABS_MT_POSITION_X, or the BUTTONPAD/SEMI_MT/DIRECT input properties) as
well as pointing sticks, whose POINTING_STICK-derived libinput behaviors
a re-injected stream would lose. Our own uinput devices are excluded by
the shared "OpenLogi " name prefix, covering the action injector too.
… hook

app_settings.capture_mouse_events (default true) is an escape hatch for
users who want OpenLogi purely for HID++ device configuration: set to
false, the agent never installs the OS-level mouse hook, so no input
device is grabbed or intercepted on any platform. DPI, SmartShift,
gesture-button, and thumb-wheel features are unaffected. Read once at
agent startup, like show_in_menu_bar; flipping it requires an agent
restart, as documented.
…bled

With capture_mouse_events = false the agent never installs the CGEventTap,
so it has no use for the Accessibility permission — firing the TCC prompt
at startup contradicts the setting's hands-off intent. Read the toggle
first and prompt only when the hook is actually wanted.
@AprilNEA
AprilNEA force-pushed the fix/hook-touchpad-grab branch from 460b0fa to f9bc554 Compare July 19, 2026 06:53
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.

[Bug]: Linux/KDE Wayland: agent virtual mice disable built-in touchpad

2 participants