WINGs: implement Wayland selection fetch (middle-click paste)

Add selection_fetch vtable slot for synchronous selection retrieval.
On Wayland, WMRequestSelection uses this to fetch clipboard/primary
selection data directly (via W_ClipboardFetchFn -> seat pipe read)
and calls the callback immediately. On X11, the async path
(selection_request -> SelectionNotify event) is unchanged.

This makes middle-click paste work in WINGs text widgets on Wayland.
This commit is contained in:
Ollie 2026-05-23 16:37:58 +02:00
parent 130fd760b5
commit 3acf2f6b2b
4 changed files with 28 additions and 0 deletions

View File

@ -621,6 +621,7 @@ typedef struct W_ViewBackend {
Bool (*selection_acquire)(void *vctx, struct W_View *view, Atom selection, Time timestamp);
void (*selection_release)(void *vctx, struct W_View *view, Atom selection);
Bool (*selection_request)(void *vctx, struct W_View *view, Atom selection, Atom target, Time timestamp);
char *(*selection_fetch)(void *vctx, Atom selection, int *len_out);
/* Platform-specific post-init (e.g. X11 atoms, IM setup) */
void (*platform_init)(struct W_Screen *scr);

View File

@ -362,6 +362,20 @@ WMRequestSelection(WMView * view, Atom selection, Atom target, Time timestamp,
SelectionCallback *handler;
const W_ViewBackend *vb = view->screen->viewBackend;
/* Synchronous path (Wayland): fetch data directly and call callback */
if (vb->selection_fetch) {
int len = 0;
char *text = vb->selection_fetch(view->screen->viewBackendCtx, selection, &len);
if (!text)
return False;
WMData *data = WMCreateDataWithBytesNoCopy(text, len, wfree);
(*callback)(view, selection, target, timestamp, cdata, data);
WMReleaseData(data);
return True;
}
/* Async path (X11): initiate conversion, callback fires on SelectionNotify */
if (!vb->selection_request ||
!vb->selection_request(view->screen->viewBackendCtx, view, selection, target, timestamp))
return False;

View File

@ -483,6 +483,17 @@ static void wl_selection_release(void *vctx, W_View *view, Atom selection)
(void)vctx; (void)view; (void)selection;
}
static char *wl_selection_fetch(void *vctx, Atom selection, int *len_out)
{
(void)vctx; (void)selection;
/* Use the clipboard fetch path (reads from seat selection via pipe) */
if (W_ClipboardFetchFn)
return W_ClipboardFetchFn(len_out);
if (len_out)
*len_out = 0;
return NULL;
}
static char *wl_clipboard_buf = NULL;
static int wl_clipboard_len = 0;
@ -605,6 +616,7 @@ const W_ViewBackend W_ViewBackendWL = {
.selection_acquire = wl_selection_acquire,
.selection_release = wl_selection_release,
.selection_request = NULL,
.selection_fetch = wl_selection_fetch,
.platform_init = NULL,
.flush = wl_flush,
.clipboard_store = wl_clipboard_store,

View File

@ -564,6 +564,7 @@ const W_ViewBackend W_ViewBackendX11 = {
.selection_acquire = x11_selection_acquire,
.selection_release = x11_selection_release,
.selection_request = x11_selection_request,
.selection_fetch = NULL,
.platform_init = W_X11PlatformInit,
.flush = x11_flush,
.clipboard_store = x11_clipboard_store,