[client] clipboard: keep controls responsive during stalls
Some checks failed
build / client (Debug, map[cc:clang cxx:clang++], libdecor) (push) Has been cancelled
build / client (Debug, map[cc:clang cxx:clang++], xdg-shell) (push) Has been cancelled
build / client (Debug, map[cc:gcc cxx:g++], libdecor) (push) Has been cancelled
build / client (Debug, map[cc:gcc cxx:g++], xdg-shell) (push) Has been cancelled
build / client (Release, map[cc:clang cxx:clang++], libdecor) (push) Has been cancelled
build / client (Release, map[cc:clang cxx:clang++], xdg-shell) (push) Has been cancelled
build / client (Release, map[cc:gcc cxx:g++], libdecor) (push) Has been cancelled
build / client (Release, map[cc:gcc cxx:g++], xdg-shell) (push) Has been cancelled
build / module (push) Has been cancelled
build / host-linux (push) Has been cancelled
build / host-windows-cross (push) Has been cancelled
build / host-windows-native (push) Has been cancelled
build / idd (push) Has been cancelled
build / obs (clang) (push) Has been cancelled
build / obs (gcc) (push) Has been cancelled
build / docs (push) Has been cancelled

Release LGMP stream slots before dispatching clipboard data so an X11
INCR consumer cannot prevent control queue acknowledgements.

Retain one bounded record in client memory while the sink is blocked.
Cancel abandoned X11 transfers after requestor destruction or a finite
progress timeout.
This commit is contained in:
Geoffrey McRae
2026-10-08 09:58:04 +11:00
parent 6214dccf12
commit cdba29f2f6
9 changed files with 336 additions and 113 deletions

View File

@@ -2116,6 +2116,35 @@ bool clipboard_requestReady(LG_ClipboardRequest id)
return result;
}
bool clipboard_requestCancel(LG_ClipboardRequest id,
LG_ClipboardCancelReason reason)
{
if (id == LG_CLIPBOARD_REQUEST_INVALID ||
(unsigned int)reason > LG_CLIPBOARD_CANCEL_INVALID ||
!clipboard.requests)
return false;
LG_LOCK(clipboard.callbackLock);
LG_LOCK(clipboard.requestLock);
ClipboardRequest * request = takeRequest(id);
LG_UNLOCK(clipboard.requestLock);
if (!request)
{
LG_UNLOCK(clipboard.callbackLock);
return false;
}
const ClipboardBinding binding = request->binding;
freeRequest(request);
LG_LOCK_SHARED(clipboard.activeLock);
if (bindingActiveNL(&binding) && binding.ops->requestCancel)
binding.ops->requestCancel(binding.opaque, id, reason);
LG_UNLOCK_SHARED(clipboard.activeLock);
LG_UNLOCK(clipboard.callbackLock);
return true;
}
bool clipboard_request(LG_ClipboardData type,
LG_ClipboardReplyFn replyFn, void * opaque)
{