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)
This commit is contained in:
Ollie 2026-05-23 16:02:11 +02:00
parent 2dce45432d
commit 9ccfd33971
4 changed files with 25 additions and 14 deletions

View File

@ -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);

View File

@ -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;

View File

@ -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,

View File

@ -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,