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 */ /* Selection ownership */
Bool (*selection_acquire)(void *vctx, struct W_View *view, Atom selection, Time timestamp); Bool (*selection_acquire)(void *vctx, struct W_View *view, Atom selection, Time timestamp);
void (*selection_release)(void *vctx, struct W_View *view, Atom selection); 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) */ /* Platform-specific post-init (e.g. X11 atoms, IM setup) */
void (*platform_init)(struct W_Screen *scr); 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) void WMDeleteSelectionHandler(WMView * view, Atom selection, Time timestamp)
{ {
SelectionHandler *handler; SelectionHandler *handler;
Display *dpy = W_VIEW_SCREEN(view)->display;
Window win = W_VIEW_DRAWABLE(view);
WMArrayIterator iter; WMArrayIterator iter;
if (!selHandlers) if (!selHandlers)
@ -71,11 +69,8 @@ void WMDeleteSelectionHandler(WMView * view, Atom selection, Time timestamp)
/*//printf("\n"); */ /*//printf("\n"); */
XGrabServer(dpy); const W_ViewBackend *vb = view->screen->viewBackend;
if (XGetSelectionOwner(dpy, selection) == win) { vb->selection_release(view->screen->viewBackendCtx, view, selection);
XSetSelectionOwner(dpy, selection, None, timestamp);
}
XUngrabServer(dpy);
} }
static void WMDeleteSelectionCallback(WMView * view, Atom selection, Time timestamp) static void WMDeleteSelectionCallback(WMView * view, Atom selection, Time timestamp)
@ -366,14 +361,11 @@ WMRequestSelection(WMView * view, Atom selection, Atom target, Time timestamp,
{ {
SelectionCallback *handler; 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; 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 = wmalloc(sizeof(SelectionCallback));
handler->view = view; handler->view = view;
handler->selection = selection; handler->selection = selection;

View File

@ -604,6 +604,7 @@ const W_ViewBackend W_ViewBackendWL = {
.get_screen_position = wl_get_screen_position, .get_screen_position = wl_get_screen_position,
.selection_acquire = wl_selection_acquire, .selection_acquire = wl_selection_acquire,
.selection_release = wl_selection_release, .selection_release = wl_selection_release,
.selection_request = NULL,
.platform_init = NULL, .platform_init = NULL,
.flush = wl_flush, .flush = wl_flush,
.clipboard_store = wl_clipboard_store, .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) 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) 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, .get_screen_position = x11_get_screen_position,
.selection_acquire = x11_selection_acquire, .selection_acquire = x11_selection_acquire,
.selection_release = x11_selection_release, .selection_release = x11_selection_release,
.selection_request = x11_selection_request,
.platform_init = W_X11PlatformInit, .platform_init = W_X11PlatformInit,
.flush = x11_flush, .flush = x11_flush,
.clipboard_store = x11_clipboard_store, .clipboard_store = x11_clipboard_store,