[client] wayland: use locked pointer to implement capture mode

This prevents the host cursor from moving into another window in capture
mode, solving the problem of input going to an overlapping window in
capture mode, and also preventing loss of focus with focus_follows_mouse.
This commit is contained in:
Quantum 2021-05-03 20:37:01 -04:00 committed by Geoffrey McRae
parent 00c2773e6b
commit 71c9680245
2 changed files with 30 additions and 2 deletions

View File

@ -359,11 +359,31 @@ void waylandUngrabPointer(void)
void waylandCapturePointer(void) void waylandCapturePointer(void)
{ {
waylandGrabPointer(); if (!wlWm.warpSupport)
{
waylandGrabPointer();
return;
}
if (wlWm.confinedPointer)
{
zwp_confined_pointer_v1_destroy(wlWm.confinedPointer);
wlWm.confinedPointer = NULL;
}
wlWm.lockedPointer = zwp_pointer_constraints_v1_lock_pointer(
wlWm.pointerConstraints, wlWm.surface, wlWm.pointer, NULL,
ZWP_POINTER_CONSTRAINTS_V1_LIFETIME_PERSISTENT);
} }
void waylandUncapturePointer(void) void waylandUncapturePointer(void)
{ {
if (wlWm.lockedPointer)
{
zwp_locked_pointer_v1_destroy(wlWm.lockedPointer);
wlWm.lockedPointer = NULL;
}
/* we need to ungrab the pointer on the following conditions when exiting capture mode: /* we need to ungrab the pointer on the following conditions when exiting capture mode:
* - if warp is not supported, exit via window edge detection will never work * - if warp is not supported, exit via window edge detection will never work
* as the cursor can not be warped out of the window when we release it. * as the cursor can not be warped out of the window when we release it.
@ -372,7 +392,14 @@ void waylandUncapturePointer(void)
* - if the user has opted to use captureInputOnly mode. * - if the user has opted to use captureInputOnly mode.
*/ */
if (!wlWm.warpSupport || !app_isFormatValid() || app_isCaptureOnlyMode()) if (!wlWm.warpSupport || !app_isFormatValid() || app_isCaptureOnlyMode())
{
waylandUngrabPointer(); waylandUngrabPointer();
return;
}
wlWm.confinedPointer = zwp_pointer_constraints_v1_confine_pointer(
wlWm.pointerConstraints, wlWm.surface, wlWm.pointer, NULL,
ZWP_POINTER_CONSTRAINTS_V1_LIFETIME_PERSISTENT);
} }
void waylandGrabKeyboard(void) void waylandGrabKeyboard(void)
@ -434,7 +461,7 @@ void waylandRealignPointer(void)
void waylandGuestPointerUpdated(double x, double y, int localX, int localY) void waylandGuestPointerUpdated(double x, double y, int localX, int localY)
{ {
if (!wlWm.warpSupport || !wlWm.pointerInSurface) if (!wlWm.warpSupport || !wlWm.pointerInSurface || wlWm.lockedPointer)
return; return;
waylandWarpPointer(localX, localY, false); waylandWarpPointer(localX, localY, false);

View File

@ -126,6 +126,7 @@ struct WaylandDSState
struct zwp_pointer_constraints_v1 * pointerConstraints; struct zwp_pointer_constraints_v1 * pointerConstraints;
struct zwp_relative_pointer_v1 * relativePointer; struct zwp_relative_pointer_v1 * relativePointer;
struct zwp_confined_pointer_v1 * confinedPointer; struct zwp_confined_pointer_v1 * confinedPointer;
struct zwp_locked_pointer_v1 * lockedPointer;
bool showPointer; bool showPointer;
uint32_t pointerEnterSerial; uint32_t pointerEnterSerial;