Skip to content

macOS emulation inverts scroll direction (missing sign flip into CGEvent) #481

Description

@marknutter

Summary

Scrolling arrives inverted on a macOS client. The macOS emulation backend passes the Wayland axis value straight into CGEvent::new_scroll_event without accounting for the opposite sign convention between the two platforms.

  • Wayland (wl_pointer::Event::Axis): positive = scroll down
  • macOS CGEvent scroll wheel: positive = scroll up

Environment

lan-mouse 0.11.0
server (capture) Linux, Hyprland, layer-shell capture backend
client (emulation) macOS, macos emulation backend

Where

input-emulation/src/macos.rs, both scroll arms:

PointerEvent::Axis { time: _, axis, value } => {
    let value = value as i32;
    let (count, wheel1, wheel2, wheel3) = match axis {
        0 => (1, value, 0, 0), // vertical
        1 => (2, 0, value, 0), // horizontal
        ...
    };
    let event = match CGEvent::new_scroll_event(
        self.event_source.clone(),
        ScrollEventUnit::PIXEL,
        count, wheel1, wheel2, wheel3,
    ) { ... }
}

and the same pattern immediately below in PointerEvent::AxisDiscrete120. Neither negates value, so both paths are affected, not just one.

Reproduction

  1. Linux server (Hyprland/layer-shell) with a macOS client
  2. Cross to the macOS client and scroll the wheel
  3. Content scrolls in the opposite direction to the same gesture on the server

Notes that may save someone else time

  • macOS "Natural scrolling" has no effect on this. That preference is applied to real HID devices; synthetic CGEvents bypass it. So it cannot be worked around from macOS System Settings, in either position.
  • The mouse in question emits both REL_WHEEL and REL_WHEEL_HI_RES, and the inversion is present regardless of which path is taken.

Suggested fix

Negate the value in input-emulation/src/macos.rs for both arms, so the sign conversion lives with the platform whose convention differs.

I'm currently working around it downstream by negating on the capture side instead, which is obviously wrong in general (it would break non-macOS clients, and it will silently double-negate once this is fixed upstream). Happy to open a PR against macos.rs if the approach above looks right to you.

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions