Skip to content

Add wp_pointer_warp_v1 protocol support#4001

Open
zakissimo wants to merge 1 commit into
niri-wm:mainfrom
zakissimo:pointer-warp-v1
Open

Add wp_pointer_warp_v1 protocol support#4001
zakissimo wants to merge 1 commit into
niri-wm:mainfrom
zakissimo:pointer-warp-v1

Conversation

@zakissimo
Copy link
Copy Markdown

Closes #3988.

Adds support for the wp_pointer_warp_v1 staging protocol (wayland-protocols 1.45).
Niri's pinned Smithay already includes the server-side handler from
Smithay#1757; this PR is the compositor
wiring + validation policy + the niri-side helpers.

Validation policy

Implements the protocol's three "should" rules with lenient (KWin-style) semantics:
focus + bounds, no button_count > 0 requirement. The protocol says "honor it if the
surface has pointer focus, including when it has an implicit pointer grab" — "including"
reads as "focus is sufficient; implicit grab is one valid case", not as a requirement.
Most legitimate SetCursorPos-class callers (Wine apps, mouselook recentering,
drag-completion, menu navigation) happen outside a button-down, so the strict reading
rejects most of them.

Reference implementations

(Per @YaLTeR's request in #3988.)

Implementation overview

  • Two free helpers in src/utils/mod.rs:
    • get_surface_toplevel_coords — walks the subsurface chain accumulating offsets via
      SubsurfaceCachedState.location. Parallel to Smithay's existing get_popup_toplevel_coords
      (which handles xdg_popup chains).
    • get_surface_size — reads RendererSurfaceState::surface_size().
  • impl PointerWarpHandler for State in src/handlers/mod.rs: serial check via
    pointer.last_enter(), surface-local bounds check, find_window_and_output
    window-rect → output-global four-term composition, self.move_cursor(target).
  • New per-window window_visual_rectangle(id) -> Option<Rectangle<f64, Logical>> at all
    four layout layers (floating/scrolling/workspace/monitor), parallel to the existing
    active_window_visual_rectangle. Dispatches monitor → workspace → (floating | scrolling).
  • Field + init + delegate macro for PointerWarpManager in src/niri.rs and
    src/handlers/mod.rs.

Testing

Verified end-to-end with Wine MR !10830
— the matching client-side winewayland.drv patch.

  • SetCursorPos called 12 times by a test program (3 laps × 4 corners of a square).
  • Niri side: registry binds the global; every warp validated and honored; cursor lands on
    each target.
  • Wine side: every GetCursorPos returns the requested position — full roundtrip works.

Tested both nested (winit backend) and as a real session.

Implements the staging protocol (wayland-protocols 1.45) with a
lenient policy: focus + bounds, no implicit-grab requirement.
The protocol's "should" rules say "honor it if the surface has
pointer focus, *including* when it has an implicit pointer grab"
— focus alone is sufficient.

Adds two free helpers in src/utils/mod.rs (get_surface_toplevel_coords
walks subsurface chains, get_surface_size reads the surface's logical
size), an impl PointerWarpHandler for State in src/handlers/mod.rs,
and per-window window_visual_rectangle at the four layout layers
parallel to the existing active_window_visual_rectangle.

Closes niri-wm#3988.
@Sempyos Sempyos added area:wayland Wayland protocols, problems with Wayland handling pr kind:feature New features and functionality area:input Keyboard, mouse, touchpad, tablet, gestures, pointer labels May 6, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:input Keyboard, mouse, touchpad, tablet, gestures, pointer area:wayland Wayland protocols, problems with Wayland handling pr kind:feature New features and functionality

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add wp_pointer_warp_v1 protocol support

2 participants