From 9ccfd33971d2dd65b1255015e203057e6afb34f1 Mon Sep 17 00:00:00 2001 From: Ollie Date: Sat, 23 May 2026 16:02:11 +0200 Subject: [PATCH] WINGs: route selection acquire/release/request through vtable - WMDeleteSelectionHandler: X11 grab/release replaced with selection_release vtable - WMRequestSelection: XGetSelectionOwner+XConvertSelection replaced with selection_request vtable - x11_selection_release: now properly releases ownership (was no-op) - x11_selection_request: new vtable impl for X11 selection conversion - Wayland selection_request: NULL (no-op, returns False) --- WINGs/WINGs/WINGsP.h.in | 1 + WINGs/selection.c | 18 +++++------------- WINGs/wview_wl.c | 1 + WINGs/wview_x11.c | 19 ++++++++++++++++++- 4 files changed, 25 insertions(+), 14 deletions(-) diff --git a/WINGs/WINGs/WINGsP.h.in b/WINGs/WINGs/WINGsP.h.in index cf14786..6cfc14f 100644 --- a/WINGs/WINGs/WINGsP.h.in +++ b/WINGs/WINGs/WINGsP.h.in @@ -620,6 +620,7 @@ typedef struct W_ViewBackend { /* Selection ownership */ 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); /* Platform-specific post-init (e.g. X11 atoms, IM setup) */ void (*platform_init)(struct W_Screen *scr); diff --git a/WINGs/selection.c b/WINGs/selection.c index 0f8bccb..c8f3fbc 100644 --- a/WINGs/selection.c +++ b/WINGs/selection.c @@ -45,8 +45,6 @@ static Bool gotXError = False; void WMDeleteSelectionHandler(WMView * view, Atom selection, Time timestamp) { SelectionHandler *handler; - Display *dpy = W_VIEW_SCREEN(view)->display; - Window win = W_VIEW_DRAWABLE(view); WMArrayIterator iter; if (!selHandlers) @@ -71,11 +69,8 @@ void WMDeleteSelectionHandler(WMView * view, Atom selection, Time timestamp) /*//printf("\n"); */ - XGrabServer(dpy); - if (XGetSelectionOwner(dpy, selection) == win) { - XSetSelectionOwner(dpy, selection, None, timestamp); - } - XUngrabServer(dpy); + const W_ViewBackend *vb = view->screen->viewBackend; + vb->selection_release(view->screen->viewBackendCtx, view, selection); } static void WMDeleteSelectionCallback(WMView * view, Atom selection, Time timestamp) @@ -366,14 +361,11 @@ WMRequestSelection(WMView * view, Atom selection, Atom target, Time timestamp, { SelectionCallback *handler; - if (XGetSelectionOwner(W_VIEW_SCREEN(view)->display, selection) == None) + const W_ViewBackend *vb = view->screen->viewBackend; + if (!vb->selection_request || + !vb->selection_request(view->screen->viewBackendCtx, view, selection, target, timestamp)) return False; - if (!XConvertSelection(W_VIEW_SCREEN(view)->display, selection, target, - W_VIEW_SCREEN(view)->clipboardAtom, W_VIEW_DRAWABLE(view), timestamp)) { - return False; - } - handler = wmalloc(sizeof(SelectionCallback)); handler->view = view; handler->selection = selection; diff --git a/WINGs/wview_wl.c b/WINGs/wview_wl.c index 29f013d..b54a0b3 100644 --- a/WINGs/wview_wl.c +++ b/WINGs/wview_wl.c @@ -604,6 +604,7 @@ const W_ViewBackend W_ViewBackendWL = { .get_screen_position = wl_get_screen_position, .selection_acquire = wl_selection_acquire, .selection_release = wl_selection_release, + .selection_request = NULL, .platform_init = NULL, .flush = wl_flush, .clipboard_store = wl_clipboard_store, diff --git a/WINGs/wview_x11.c b/WINGs/wview_x11.c index 2a8fbb6..6f4fcf9 100644 --- a/WINGs/wview_x11.c +++ b/WINGs/wview_x11.c @@ -206,7 +206,23 @@ static Bool x11_selection_acquire(void *vctx, W_View *view, Atom selection, Time static void x11_selection_release(void *vctx, W_View *view, Atom selection) { - (void)vctx; (void)view; (void)selection; + W_Screen *scr = (W_Screen *)vctx; + Display *dpy = scr->display; + Window win = W_VIEW_DRAWABLE(view); + XGrabServer(dpy); + if (XGetSelectionOwner(dpy, selection) == win) + XSetSelectionOwner(dpy, selection, None, CurrentTime); + XUngrabServer(dpy); +} + +static Bool x11_selection_request(void *vctx, W_View *view, Atom selection, Atom target, Time timestamp) +{ + W_Screen *scr = (W_Screen *)vctx; + Display *dpy = scr->display; + if (XGetSelectionOwner(dpy, selection) == None) + return False; + return XConvertSelection(dpy, selection, target, + scr->clipboardAtom, W_VIEW_DRAWABLE(view), timestamp) != 0; } static void x11_clipboard_store(void *vctx, const char *text, int len) @@ -547,6 +563,7 @@ const W_ViewBackend W_ViewBackendX11 = { .get_screen_position = x11_get_screen_position, .selection_acquire = x11_selection_acquire, .selection_release = x11_selection_release, + .selection_request = x11_selection_request, .platform_init = W_X11PlatformInit, .flush = x11_flush, .clipboard_store = x11_clipboard_store,