https://bugs.kde.org/show_bug.cgi?id=528162

            Bug ID: 528162
           Summary: Pointer lock: cursor position hint applied one
                    lock/unlock cycle late (6.8.x regression from 6.7.x)
    Classification: Plasma
           Product: kwin
      Version First 6.8.2
       Reported In:
          Platform: CachyOS
                OS: Linux
            Status: REPORTED
          Severity: major
          Priority: NOR
         Component: input
          Assignee: [email protected]
          Reporter: [email protected]
                CC: [email protected]
  Target Milestone: ---

Created attachment 197920
  --> https://bugs.kde.org/attachment.cgi?id=197920&action=edit
The reproduction of the issue

DESCRIPTION
On Plasma 6.8.x, a client's zwp_locked_pointer_v1 cursor position hint
(set_cursor_position_hint) is applied one lock/unlock cycle late: when a
pointer
lock ends, kwin materializes the cursor at the position requested during the
PREVIOUS lock/unlock cycle, not the current one. Additionally, while a lock is
active the hidden pointer position is not held inert: it integrates the
relative
motion and reappears at window-bounds-jammed positions instead of where the
lock
was engaged. Both affect any SDL 3.2+ game that enters per-window relative
mouse
mode and repositions the cursor at unlock (SDL_WarpMouseInWindow; on
compositors
without wp_pointer_warp_v1 SDL issues the position hint). Games that don't
reposition silently show it as "cursor reappears at a screen edge after closing
a
menu / after camera panning".

STEPS TO REPRODUCE
1. Attach kwin_hint_lag_repro.c (self-contained SDL3 program, ~70 lines; builds
   clean against SDL 3.4.0). Hold Right Mouse: the app enters per-window
relative
   mode (locked pointer) and hides the cursor.
2. Move the mouse around, then release RMB. The app requests the cursor at the
   next window corner (the request and every compositor-reported motion
position
   are printed), exits relative mode, and shows the cursor.
3. Repeat several times so the requested corner cycles. Console shows each
   requested target vs. where kwin actually reported the cursor afterwards.

OBSERVED RESULT
The cursor appears at the corner requested on the PREVIOUS release, every
cycle.
Recorded sequence from a game session on my machine (window-local coordinates,
1920x1009 window; "requested" = warp request recorded at that unlock,
"reported" =
first compositor-delivered absolute motion after that unlock):

  release 2: requested (871,442)   -> reported (1226,448)   = release 1's
request
  release 3: requested (1670,374)  -> reported (871,442)    = release 2's
request
  release 4: requested (1065,410)  -> reported (1670,374)   = release 3's
request
  release 5: requested (1425,526)  -> reported (1065,410)   = release 4's
request

Five for five in that session; 65 of 74 recorded releases across sessions show
the
same one-cycle lag (the fresh ones are rapid re-locks at the same spot). Rapid
manual lock/unlock repetition converges the cursor onto the requests - each
forced
locked->unlocked transition seems to consume exactly one outstanding hint.

The drift observation: with no hint at all, after long relative-mode pans the
cursor reappears at bounds-jammed positions (logged first post-unlock absolutes
of
x=0 on a 1920-wide window), at a distance correlating with the pan deltas
rather
than with any hand movement after the unlock.

EXPECTED RESULT
Per pointer-constraints-unstable-v1, a locked pointer's position is inert for
the
lock's duration, and a position hint set on a locked pointer determines where
the
pointer reappears when the lock deactivates - the request from the SAME unlock
should land at that unlock. On kwin 6.7.4 the same game binary showed no unlock
displacement over days of play immediately before the upgrade; the symptom
appeared right after the update (pacman log: kwin 6.7.4-7.1 -> 6.8.0-1.1,
2026-10-17), with no change to the client.

SOFTWARE/OS VERSIONS
Operating System: CachyOS Linux
KDE Plasma Version: 6.8.2
KDE Frameworks Version: 6.31.0
Qt Version: 6.12.0
Kernel Version: 7.3.1-1-cachyos (64-bit)
Graphics Platform: Wayland
Graphics Processor: NVIDIA GeForce RTX 4070 (driver 615.78.08)
kwin: 6.8.2-1.1

ADDITIONAL INFORMATION
Possible mechanism, from reading the 6.8.2 source (offering as pointers, not a
diagnosis):

1. src/wayland/surface.cpp, SurfaceState::mergeInto(): the hint copy
      target->pointerLockHint = pointerLockHint;
   runs WITHOUT the `committed & SurfaceState::Field::PointerLockHint` guard
that
   protects the pointerLockRegion copy directly above it, so every state
   amendment re-assigns the hint field.
2. src/wayland/pointerconstraints_v1.cpp, ~LockedPointerV1Interface(): the
unlock
   amendment notes "the position hint is intentionally not reset, since it will
be
   used when the next commit is applied". Combined with the unguarded merge,
the
   unlock amendment appears to overwrite a freshly committed hint (sent in the
   same cycle) with the older value it carries.
3. Application happens in the locked->unlocked transition in
   PointerInputRedirection::updatePointerConstraints (src/pointer_input.cpp),
   which reads SurfaceInterface::lockedPointerHint() - the current, stale
value.

The one-exchange-late signature and the convergence-by-repetition fall out of
that model naturally: each transition consumes the outstanding (older) hint,
and
forcing repeated transitions flushes them - which is the workaround my game
client currently ships (we drive a few rapid lock->hint->unlock exchanges at
unlock while the cursor is still hidden until the position converges; reliable,
but it generates compositor churn, and rapid user re-locks then run into lock
re-entry throttling).

SDL context: SDL 3.x implements WarpMouseInWindow on hintless compositors via a
short-lived locked pointer carrying set_cursor_position_hint before the unlock;
SDL 2.x never sends the hint (pure internal bookkeeping), so older games only
show the drift symptom, which is likely why this reads as underreported.

-- 
You are receiving this mail because:
You are watching all bug changes.

Reply via email to