[client] input: stop absolute cursor feedback
Some checks are pending
build / client (Debug, map[cc:clang cxx:clang++], libdecor) (push) Waiting to run
build / client (Debug, map[cc:clang cxx:clang++], xdg-shell) (push) Waiting to run
build / client (Debug, map[cc:gcc cxx:g++], libdecor) (push) Waiting to run
build / client (Debug, map[cc:gcc cxx:g++], xdg-shell) (push) Waiting to run
build / client (Release, map[cc:clang cxx:clang++], libdecor) (push) Waiting to run
build / client (Release, map[cc:clang cxx:clang++], xdg-shell) (push) Waiting to run
build / client (Release, map[cc:gcc cxx:g++], libdecor) (push) Waiting to run
build / client (Release, map[cc:gcc cxx:g++], xdg-shell) (push) Waiting to run
build / module (push) Waiting to run
build / host-linux (push) Waiting to run
build / host-windows-cross (push) Waiting to run
build / host-windows-native (push) Waiting to run
build / idd (push) Waiting to run
build / obs (clang) (push) Waiting to run
build / obs (gcc) (push) Waiting to run
build / docs (push) Waiting to run

X11's legacy guest-position synchronization warps the host cursor to
delayed guest updates. With absolute input this feeds old positions back
through cooked motion and pulls the cursor away from window edges.

Skip display-server guest synchronization when the active input is
absolute. Relative input and explicit uncapture alignment are unchanged.
This commit is contained in:
Geoffrey McRae
2026-08-10 19:29:22 +10:00
parent 89dcf56073
commit d20904e3af
3 changed files with 46 additions and 10 deletions

View File

@@ -120,6 +120,7 @@ set(MOUSE_CASES
surface-exit
exit-immediate
exit-guest
absolute-sync
exit-reentry
view-immediate
capture-pending

View File

@@ -262,9 +262,8 @@ void app_mouseTrace(const char * file, unsigned int line,
static bool inputSupports(void * opaque, LG_InputSupport support)
{
(void)opaque;
(void)support;
return false;
return support == LG_INPUT_SUPPORT_MOUSE_ABSOLUTE &&
opaque && *(const bool *)opaque;
}
static bool inputKey(void * opaque, int key)
@@ -281,6 +280,17 @@ static bool inputMouseMotion(void * opaque, int32_t x, int32_t y)
return true;
}
static bool inputMousePosition(void * opaque, uint32_t x, uint32_t y,
uint32_t width, uint32_t height)
{
(void)opaque;
(void)x;
(void)y;
(void)width;
(void)height;
return true;
}
static bool inputMouseButton(void * opaque, unsigned int button)
{
(void)opaque;
@@ -289,13 +299,14 @@ static bool inputMouseButton(void * opaque, unsigned int button)
}
static const LG_InputOps inputOps = {
.name = "test",
.supports = inputSupports,
.keyDown = inputKey,
.keyUp = inputKey,
.mouseMotion = inputMouseMotion,
.mousePress = inputMouseButton,
.mouseRelease = inputMouseButton,
.name = "test",
.supports = inputSupports,
.keyDown = inputKey,
.keyUp = inputKey,
.mouseMotion = inputMouseMotion,
.mousePosition = inputMousePosition,
.mousePress = inputMouseButton,
.mouseRelease = inputMouseButton,
};
static void reset(void)
@@ -482,6 +493,24 @@ static void testExitGuest(void)
CHECK(count(EV_GUEST) == 0);
}
static void testAbsoluteSync(void)
{
reset();
setLocal(50, 50);
core_handleGuestMouseUpdate();
CHECK(count(EV_GUEST) == 1);
bool absolute = true;
lgInput_setFallback(&inputOps, &absolute);
m.count = 0;
core_handleGuestMouseUpdate();
CHECK(count(EV_GUEST) == 0);
lgInput_setFallback(&inputOps, NULL);
}
static void testExitReentry(void)
{
startExit();
@@ -895,6 +924,7 @@ static const struct Test tests[] = {
{ "surface-exit" , testSurfaceExit },
{ "exit-immediate" , testExitImmediate},
{ "exit-guest" , testExitGuest },
{ "absolute-sync" , testAbsoluteSync },
{ "exit-reentry" , testExitReentry },
{ "view-immediate" , testViewImmediate},
{ "capture-pending" , testCapWait },