clipboard

This commit is contained in:
Jorijn van der Graaf 2026-05-19 00:45:22 +02:00
commit 850ef7bfb3
4 changed files with 325 additions and 10 deletions

View file

@ -441,6 +441,33 @@ function domStopFrameLoop() {
}
// ─── Clipboard ────────────────────────────────────────────────────────
//
// Read path is necessarily a latched buffer: navigator.clipboard.readText
// is async (Promise) but the C++ Clipboard::GetText signature is
// synchronous to match the Wayland / Win32 backends. Two feeders keep
// the cache fresh:
//
// 1. A capture-phase `paste` listener on `window` reads
// event.clipboardData.getData('text/plain') synchronously — this
// covers the standard Ctrl+V flow, where the paste event fires
// in the same task as the C++ key handler that will call GetText.
// 2. Each GetText call also kicks off a navigator.clipboard.readText
// in the background. The promise resolves in a later task; the
// first call usually still returns the latched paste value (or
// nullopt), subsequent calls see the readText result.
let __clipboardCache = null;
window.addEventListener("paste", (event) => {
try {
const t = event.clipboardData &&
event.clipboardData.getData("text/plain");
if (typeof t === "string") __clipboardCache = t;
} catch (err) {
// Some browsers reject clipboardData access inside non-input
// targets; the async readText fallback still has a chance.
}
}, true);
function clipboardSetText(strPtr, strLen) {
try {
@ -452,6 +479,19 @@ function clipboardSetText(strPtr, strLen) {
}
}
function clipboardGetText() {
// Best-effort async refresh. Permission/focus rejections are
// expected in non-activated contexts — swallow them so we don't
// spam the console on every paste check.
if (navigator.clipboard && navigator.clipboard.readText) {
navigator.clipboard.readText()
.then((t) => { if (typeof t === "string") __clipboardCache = t; })
.catch(() => {});
}
if (__clipboardCache === null) return 0;
return __writeUtf8(__clipboardCache);
}
// ─── History / routing ────────────────────────────────────────────────
function pushState(dataPtr, dataLen, titlePtr, titleLen, urlPtr, urlLen) {
@ -547,7 +587,7 @@ Object.assign(window.crafter_webbuild_env, {
domStartFrameLoop, domStopFrameLoop,
// Clipboard
clipboardSetText,
clipboardSetText, clipboardGetText,
// History
pushState, addPopStateListener, removePopStateListener, getPathName,