From 0dc7e33e4bde4453ec3d268e07f859ce7a516f3c Mon Sep 17 00:00:00 2001 From: Window Maker Date: Sat, 23 May 2026 14:55:23 +0200 Subject: [PATCH] WINGs: route clipboard through view backend vtable Adds clipboard_store/clipboard_fetch to W_ViewBackend. Replaces direct XFetchBuffer/XStoreBuffer calls in wtextfield.c and wtext.c with vtable dispatch. X11 backend wraps Xlib, Wayland backend uses an internal buffer. --- WINGs/WINGs/WINGsP.h.in | 4 ++++ WINGs/wtext.c | 6 ++++-- WINGs/wtextfield.c | 10 +++++++--- WINGs/wview_wl.c | 37 +++++++++++++++++++++++++++++++++++++ WINGs/wview_x11.c | 18 ++++++++++++++++++ 5 files changed, 70 insertions(+), 5 deletions(-) diff --git a/WINGs/WINGs/WINGsP.h.in b/WINGs/WINGs/WINGsP.h.in index 9d26bf2..810eeef 100644 --- a/WINGs/WINGs/WINGsP.h.in +++ b/WINGs/WINGs/WINGsP.h.in @@ -629,6 +629,10 @@ typedef struct W_ViewBackend { /* Flush pending display output */ void (*flush)(void *vctx); + + /* Clipboard (cut buffer) */ + void (*clipboard_store)(void *vctx, const char *text, int len); + char *(*clipboard_fetch)(void *vctx, int *len_out); } W_ViewBackend; extern const W_ViewBackend W_ViewBackendX11; diff --git a/WINGs/wtext.c b/WINGs/wtext.c index f0dc530..c97436f 100644 --- a/WINGs/wtext.c +++ b/WINGs/wtext.c @@ -2369,7 +2369,8 @@ static void pasteText(WMView * view, Atom selection, Atom target, Time timestamp } else { int n; - text = XFetchBuffer(tPtr->view->screen->display, &n, 0); + text = tPtr->view->screen->viewBackend->clipboard_fetch( + tPtr->view->screen->viewBackendCtx, &n); if (text) { text[n] = 0; @@ -2532,7 +2533,8 @@ static void handleActionEvents(WMEvent * event, void *data) if (!WMRequestSelection(tPtr->view, XA_PRIMARY, XA_STRING, event->u.button.time, pasteText, NULL)) { - text = XFetchBuffer(tPtr->view->screen->display, &n, 0); + text = tPtr->view->screen->viewBackend->clipboard_fetch( + tPtr->view->screen->viewBackendCtx, &n); tPtr->flags.waitingForSelection = 0; if (text) { diff --git a/WINGs/wtextfield.c b/WINGs/wtextfield.c index 23b9b70..557ce3a 100644 --- a/WINGs/wtextfield.c +++ b/WINGs/wtextfield.c @@ -1348,7 +1348,8 @@ static void pasteText(WMView * view, Atom selection, Atom target, Time timestamp } else { int n; - str = XFetchBuffer(tPtr->view->screen->display, &n, 0); + str = tPtr->view->screen->viewBackend->clipboard_fetch( + tPtr->view->screen->viewBackendCtx, &n); if (str != NULL) { str[n] = 0; @@ -1470,7 +1471,8 @@ static void handleTextFieldActionEvents(WMEvent * event, void *data) if (!WMRequestSelection(tPtr->view, XA_PRIMARY, XA_STRING, event->u.button.time, pasteText, NULL)) { - text = XFetchBuffer(tPtr->view->screen->display, &n, 0); + text = tPtr->view->screen->viewBackend->clipboard_fetch( + tPtr->view->screen->viewBackendCtx, &n); if (text) { text[n] = 0; @@ -1508,7 +1510,9 @@ static void handleTextFieldActionEvents(WMEvent * event, void *data) else start = tPtr->selection.position; - XStoreBuffer(dpy, &tPtr->text[start], count, 0); + tPtr->view->screen->viewBackend->clipboard_store( + tPtr->view->screen->viewBackendCtx, + &tPtr->text[start], count); } if (!tPtr->flags.secure && diff --git a/WINGs/wview_wl.c b/WINGs/wview_wl.c index c3ccbd8..ceb8121 100644 --- a/WINGs/wview_wl.c +++ b/WINGs/wview_wl.c @@ -479,6 +479,41 @@ static void wl_selection_release(void *vctx, W_View *view, Atom selection) (void)vctx; (void)view; (void)selection; } +static char *wl_clipboard_buf = NULL; +static int wl_clipboard_len = 0; + +static void wl_clipboard_store(void *vctx, const char *text, int len) +{ + (void)vctx; + if (wl_clipboard_buf) + wfree(wl_clipboard_buf); + if (text && len > 0) { + wl_clipboard_buf = wmalloc(len + 1); + memcpy(wl_clipboard_buf, text, len); + wl_clipboard_buf[len] = '\0'; + wl_clipboard_len = len; + } else { + wl_clipboard_buf = NULL; + wl_clipboard_len = 0; + } +} + +static char *wl_clipboard_fetch(void *vctx, int *len_out) +{ + (void)vctx; + if (wl_clipboard_buf && wl_clipboard_len > 0) { + char *copy = wmalloc(wl_clipboard_len + 1); + memcpy(copy, wl_clipboard_buf, wl_clipboard_len); + copy[wl_clipboard_len] = '\0'; + if (len_out) + *len_out = wl_clipboard_len; + return copy; + } + if (len_out) + *len_out = 0; + return NULL; +} + static void wl_flush(void *vctx) { (void)vctx; @@ -507,4 +542,6 @@ const W_ViewBackend W_ViewBackendWL = { .selection_release = wl_selection_release, .platform_init = NULL, .flush = wl_flush, + .clipboard_store = wl_clipboard_store, + .clipboard_fetch = wl_clipboard_fetch, }; diff --git a/WINGs/wview_x11.c b/WINGs/wview_x11.c index bfecbde..a85efce 100644 --- a/WINGs/wview_x11.c +++ b/WINGs/wview_x11.c @@ -206,6 +206,22 @@ static void x11_selection_release(void *vctx, W_View *view, Atom selection) (void)vctx; (void)view; (void)selection; } +static void x11_clipboard_store(void *vctx, const char *text, int len) +{ + W_Screen *scr = (W_Screen *)vctx; + XStoreBuffer(scr->display, text, len, 0); +} + +static char *x11_clipboard_fetch(void *vctx, int *len_out) +{ + W_Screen *scr = (W_Screen *)vctx; + int n = 0; + char *text = XFetchBuffer(scr->display, &n, 0); + if (len_out) + *len_out = n; + return text; +} + static void x11_flush(void *vctx) { W_Screen *scr = (W_Screen *)vctx; @@ -235,4 +251,6 @@ const W_ViewBackend W_ViewBackendX11 = { .selection_release = x11_selection_release, .platform_init = W_X11PlatformInit, .flush = x11_flush, + .clipboard_store = x11_clipboard_store, + .clipboard_fetch = x11_clipboard_fetch, };