From f6de3eca01e873a4216e172cacb6c7447bf9f020 Mon Sep 17 00:00:00 2001 From: Olivier Fourdan Date: Tue, 10 Mar 2026 13:42:18 +0100 Subject: [PATCH] dix: Add a selection bridge callback This is intended to be used to implement selection bridges in mixed windowing systems such as Xwayland. This adds a new SelectionBridgeCallback along with a new SelectionBridgeInfoRec to convey the information from a selection request so that a DDX such as Xwayland can bridge that to some other clipboard implementation from another windowing system directly from the DDX. Signed-off-by: Olivier Fourdan Assisted-by: Cursor AI Assisted-by: Claude Code Part-of: --- dix/selection.c | 28 ++++++++++++++++++++++++++++ include/selection.h | 17 +++++++++++++++++ 2 files changed, 45 insertions(+) diff --git a/dix/selection.c b/dix/selection.c index df5269f52..622e0646a 100644 --- a/dix/selection.c +++ b/dix/selection.c @@ -66,6 +66,7 @@ SOFTWARE. Selection *CurrentSelections; CallbackListPtr SelectionCallback; +CallbackListPtr SelectionBridgeCallback; int dixLookupSelection(Selection ** result, Atom selectionName, @@ -247,6 +248,25 @@ ProcGetSelectionOwner(ClientPtr client) return Success; } +static void +CallSelectionBridgeCallback(ClientPtr pClient, Selection *pSel, xEvent *event) +{ + SelectionBridgeInfoRec info; + + if (!pSel->pWin) + return; + + info.screen = pSel->pWin->drawable.pScreen; + info.client = pClient; + info.requestor = event->u.selectionRequest.requestor; + info.selection = event->u.selectionRequest.selection; + info.target = event->u.selectionRequest.target; + info.property = event->u.selectionRequest.property; + info.time = ClientTimeToServerTime(event->u.selectionRequest.time); + + CallCallbacks(&SelectionBridgeCallback, &info); +} + int ProcConvertSelection(ClientPtr client) { @@ -291,6 +311,14 @@ ProcConvertSelection(ClientPtr client) WriteEventsToClient(pSel->client, 1, &event); return Success; } + + /* If the selection is owned by the server client, and there are + * selection bridge callbacks registered, call them now. + */ + if (pSel->client == serverClient && SelectionBridgeCallback != NULL) { + CallSelectionBridgeCallback(client, pSel, &event); + return Success; + } } event.u.u.type = SelectionNotify; diff --git a/include/selection.h b/include/selection.h index 7a516f14a..500439e37 100644 --- a/include/selection.h +++ b/include/selection.h @@ -49,6 +49,7 @@ SOFTWARE. #include "dixstruct.h" #include "privates.h" +#include "screenint.h" /* * Selection data structures @@ -87,6 +88,22 @@ typedef struct { SelectionCallbackKind kind; } SelectionInfoRec; +/* + * Selection bridge callback: + * can be used to bridge a selection request to the target clients. + */ +extern _X_EXPORT CallbackListPtr SelectionBridgeCallback; + +typedef struct { + ScreenPtr screen; + ClientPtr client; + Window requestor; + Atom selection; + Atom target; + Atom property; + TimeStamp time; +} SelectionBridgeInfoRec; + /* * Selection server internals */