Skip to content

wlserver: keep cursor position in sync when constraint rejects motion#2100

Open
Krakty wants to merge 1 commit intoValveSoftware:masterfrom
Krakty:fix/force-grab-cursor-constraint
Open

wlserver: keep cursor position in sync when constraint rejects motion#2100
Krakty wants to merge 1 commit intoValveSoftware:masterfrom
Krakty:fix/force-grab-cursor-constraint

Conversation

@Krakty
Copy link

@Krakty Krakty commented Mar 3, 2026

When --force-grab-cursor is active and the inner XWayland client sets a locked pointer constraint, wlserver_apply_constraint() rejects the motion and returns early. The problem is that the early return skips updating mouse_surface_cursorx/cursory, even though relative motion was already forwarded by wlserver_perform_rel_pointer_motion() just above.

This means the absolute cursor position gets stuck at wherever it was when the constraint kicked in. Games that use both relative motion (camera/mouselook) and absolute position (UI clicks) via XWayland see the camera snap to a fixed angle because the stale absolute coords get used on the next accepted motion or button event.

I hit this running EverQuest under Wine in multiple concurrent gamescope instances (6 clients, each in its own gamescope with --force-grab-cursor). A single instance worked fine — the issue only appeared with multiple instances. EQ uses DirectInput for mouselook (relative) and XWayland absolute positioning for UI interaction, so the stale coordinates caused the camera to fight the player on every mouselook release.

The fix keeps the cursor position tracking in sync even when the constraint blocks. Only runs under g_bForceRelativeMouse so normal constraint behavior is untouched.

Related issues: #1748 #1428 #1470

When --force-grab-cursor is active and the inner client has a locked
pointer constraint, wlserver_apply_constraint() rejects the motion but
the cursor position isn't updated. This causes the absolute position to
go stale at the lock point. When the constraint is later released (or
on the next accepted motion), the cursor jumps from its stale position,
which shows up as the camera snapping to a fixed angle in games that
use both relative motion and absolute position via XWayland.

Fix this by updating cursor position, notifying the seat, and clamping
even when the constraint blocks the motion. This keeps absolute
coordinates consistent with the relative deltas that were already
forwarded by wlserver_perform_rel_pointer_motion().
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