[client] x11: serialize pointer grab state

This commit is contained in:
Geoffrey McRae
2026-08-06 14:54:05 +10:00
parent 023430da31
commit 997c690e04
2 changed files with 33 additions and 11 deletions

View File

@@ -341,6 +341,7 @@ static bool x11Init(const LG_DSInitParams params)
XSetIOErrorHandler(x11IOErrorHandler); XSetIOErrorHandler(x11IOErrorHandler);
memset(&x11, 0, sizeof(x11)); memset(&x11, 0, sizeof(x11));
LG_LOCK_INIT(x11.pointerLock);
atomic_init(&x11.captureActive, false); atomic_init(&x11.captureActive, false);
atomic_init(&x11.pointerGrabbed, false); atomic_init(&x11.pointerGrabbed, false);
x11.xValuator = -1; x11.xValuator = -1;
@@ -869,6 +870,7 @@ static void x11Free(void)
if (x11.cursors[i]) if (x11.cursors[i])
XFreeCursor(x11.display, x11.cursors[i]); XFreeCursor(x11.display, x11.cursors[i]);
LG_LOCK_FREE(x11.pointerLock);
x11.wm->deinit(); x11.wm->deinit();
XCloseDisplay(x11.display); XCloseDisplay(x11.display);
} }
@@ -1886,10 +1888,10 @@ static void x11PrintGrabError(const char * type, int dev, Status ret)
} }
static void x11GrabPointer(void) static bool x11GrabPointerLocked(void)
{ {
if (atomic_load_explicit(&x11.pointerGrabbed, memory_order_acquire)) if (atomic_load_explicit(&x11.pointerGrabbed, memory_order_acquire))
return; return true;
unsigned char mask_bits[XIMaskLen(XI_LASTEVENT)] = { 0 }; unsigned char mask_bits[XIMaskLen(XI_LASTEVENT)] = { 0 };
XIEventMask mask = { XIEventMask mask = {
@@ -1934,16 +1936,22 @@ static void x11GrabPointer(void)
if (ret != Success) if (ret != Success)
{ {
x11PrintGrabError("pointer", x11.pointerDev, ret); x11PrintGrabError("pointer", x11.pointerDev, ret);
return; return false;
} }
atomic_store_explicit(&x11.pointerGrabbed, true, memory_order_release); atomic_store_explicit(&x11.pointerGrabbed, true, memory_order_release);
return true;
} }
static void x11UngrabPointer(void) static void x11GrabPointer(void)
{ {
atomic_store_explicit(&x11.captureActive, false, memory_order_release); LG_LOCK(x11.pointerLock);
x11GrabPointerLocked();
LG_UNLOCK(x11.pointerLock);
}
static void x11UngrabPointerLocked(void)
{
if (!atomic_load_explicit(&x11.pointerGrabbed, memory_order_acquire)) if (!atomic_load_explicit(&x11.pointerGrabbed, memory_order_acquire))
{ {
app_handleGrabEvent(false); app_handleGrabEvent(false);
@@ -1957,6 +1965,14 @@ static void x11UngrabPointer(void)
app_handleGrabEvent(false); app_handleGrabEvent(false);
} }
static void x11UngrabPointer(void)
{
LG_LOCK(x11.pointerLock);
atomic_store_explicit(&x11.captureActive, false, memory_order_release);
x11UngrabPointerLocked();
LG_UNLOCK(x11.pointerLock);
}
static bool x11IsPointerGrabbed(void) static bool x11IsPointerGrabbed(void)
{ {
return atomic_load_explicit(&x11.pointerGrabbed, memory_order_acquire); return atomic_load_explicit(&x11.pointerGrabbed, memory_order_acquire);
@@ -1964,14 +1980,17 @@ static bool x11IsPointerGrabbed(void)
static void x11CapturePointer(void) static void x11CapturePointer(void)
{ {
x11GrabPointer(); LG_LOCK(x11.pointerLock);
atomic_store_explicit(&x11.captureActive, const bool active = x11GrabPointerLocked();
atomic_load_explicit(&x11.pointerGrabbed, memory_order_acquire), atomic_store_explicit(&x11.captureActive, active, memory_order_release);
memory_order_release); LG_UNLOCK(x11.pointerLock);
} }
static void x11UncapturePointer(void) static void x11UncapturePointer(void)
{ {
const bool ungrab = !app_isFormatValid() || app_isCaptureOnlyMode();
LG_LOCK(x11.pointerLock);
atomic_store_explicit(&x11.captureActive, false, memory_order_release); atomic_store_explicit(&x11.captureActive, false, memory_order_release);
/* 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:
@@ -1980,8 +1999,9 @@ static void x11UncapturePointer(void)
* window when we release it. * window when we release it.
* - if the user has opted to use captureInputOnly mode. * - if the user has opted to use captureInputOnly mode.
*/ */
if (!app_isFormatValid() || app_isCaptureOnlyMode()) if (ungrab)
x11UngrabPointer(); x11UngrabPointerLocked();
LG_UNLOCK(x11.pointerLock);
} }
static bool x11IsPointerCaptured(void) static bool x11IsPointerCaptured(void)

View File

@@ -31,6 +31,7 @@
#include <GL/glx.h> #include <GL/glx.h>
#include "interface/displayserver.h" #include "interface/displayserver.h"
#include "common/locking.h"
#include "common/thread.h" #include "common/thread.h"
#include "common/types.h" #include "common/types.h"
#include "wm.h" #include "wm.h"
@@ -93,6 +94,7 @@ struct X11DSState
int xValuator; int xValuator;
int yValuator; int yValuator;
LG_Lock pointerLock;
_Atomic(bool) captureActive; _Atomic(bool) captureActive;
_Atomic(bool) pointerGrabbed; _Atomic(bool) pointerGrabbed;
bool keyboardGrabbed; bool keyboardGrabbed;