summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms/wasm/qwasmclipboard.cpp
diff options
context:
space:
mode:
authorMorten Sørvig <morten.sorvig@qt.io>2025-07-02 11:05:27 +0200
committerMorten Sørvig <morten.sorvig@qt.io>2025-07-16 15:54:22 +0200
commit1b24cfdac501bae99cc1e34a995ab78d18badd92 (patch)
tree86d5f9b8b963ead9904c47f3d962e79f8b49e09a /src/plugins/platforms/wasm/qwasmclipboard.cpp
parentad8d335c035150f5d6cddb957efa3c4be2540cbd (diff)
wasm: Handle multiple mime types in the clipboard
Create a single ClipboardItem with several mime types instead of multiple ClipboardItems (multiple clipboard items are allowed by the API, but generally not supported by the browsers) Support the web standard mime types for now: text/plain, text/html, and image/png. Adding extra mime types (e.g. text/markdown) may cause the browser to reject the ClipboardItem. Later, we can add support for testing if additional mime types are supported. Done-with: Even Oscar Andersen <even.oscar.andersen@qt.io> Done-with: Volker Hemsen Fixes: QTBUG-138044 Fixes: QTBUG-125366 Pick-to: 6.10 Change-Id: I6adbf239597576e393da824232c5933e76ad851f Reviewed-by: Even Oscar Andersen <even.oscar.andersen@qt.io> Reviewed-by: Morten Johan Sørvig <morten.sorvig@qt.io> Reviewed-by: Lorn Potter <lorn.potter@qt.io>
Diffstat (limited to 'src/plugins/platforms/wasm/qwasmclipboard.cpp')
-rw-r--r--src/plugins/platforms/wasm/qwasmclipboard.cpp98
1 files changed, 27 insertions, 71 deletions
diff --git a/src/plugins/platforms/wasm/qwasmclipboard.cpp b/src/plugins/platforms/wasm/qwasmclipboard.cpp
index 3b5a00ff464..44db371ca4d 100644
--- a/src/plugins/platforms/wasm/qwasmclipboard.cpp
+++ b/src/plugins/platforms/wasm/qwasmclipboard.cpp
@@ -171,86 +171,42 @@ void QWasmClipboard::writeToClipboardApi()
{
Q_ASSERT(m_hasClipboardApi);
- // copy event
- // browser event handler detected ctrl c if clipboard API
- // or Qt call from keyboard event handler
-
- QMimeData *_mimes = mimeData(QClipboard::Clipboard);
- if (!_mimes)
+ QMimeData *mimeData = this->mimeData(QClipboard::Clipboard);
+ if (!mimeData)
return;
- emscripten::val clipboardWriteArray = emscripten::val::array();
- QByteArray ba;
-
- for (auto mimetype : _mimes->formats()) {
- // we need to treat binary and text differently, as the blob method below
- // fails for text mimetypes
- // ignore text types
-
- if (mimetype.contains("STRING", Qt::CaseSensitive) || mimetype.contains("TEXT", Qt::CaseSensitive))
- continue;
-
- if (_mimes->hasHtml()) { // prefer html over text
- ba = _mimes->html().toLocal8Bit();
- // force this mime
- mimetype = "text/html";
- } else if (mimetype.contains("text/plain")) {
- ba = _mimes->text().toLocal8Bit();
- } else if (mimetype.contains("image")) {
- QImage img = qvariant_cast<QImage>( _mimes->imageData());
+ // Support for plain text, html and images (png) are standardized,
+ // copy those to the clipboard data object.
+ emscripten::val clipboardData = emscripten::val::object();
+ for (const QString &mimetype: mimeData->formats()) {
+ if (mimetype == QLatin1String("text/plain")) {
+ emscripten::val text = mimeData->text().toEcmaString();
+ clipboardData.set(mimetype.toEcmaString(), text);
+ } else if (mimetype == QLatin1String("text/html")) {
+ emscripten::val html = mimeData->html().toEcmaString();
+ clipboardData.set(mimetype.toEcmaString(), html);
+ } else if (mimetype.contains(QLatin1String("image"))) {
+ // Serialize the Qt image data to browser supported png
+ QImage img = qvariant_cast<QImage>(mimeData->imageData());
+ QByteArray ba;
QBuffer buffer(&ba);
buffer.open(QIODevice::WriteOnly);
img.save(&buffer, "PNG");
- mimetype = "image/png"; // chrome only allows png
- // clipboard error "NotAllowedError" "Type application/x-qt-image not supported on write."
- // safari silently fails
- // so we use png internally for now
- } else {
- // DATA
- ba = _mimes->data(mimetype);
- }
- // Create file data Blob
- const char *content = ba.data();
- int dataLength = ba.length();
- if (dataLength < 1) {
- qDebug() << "no content found";
- return;
+ qstdweb::Blob blob = qstdweb::Blob::fromArrayBuffer(qstdweb::Uint8Array::copyFrom(ba).buffer());
+ clipboardData.set(std::string("image/png"), blob.val());
}
-
- emscripten::val document = emscripten::val::global("document");
- emscripten::val window = emscripten::val::global("window");
-
- emscripten::val fileContentView =
- emscripten::val(emscripten::typed_memory_view(dataLength, content));
- emscripten::val fileContentCopy = emscripten::val::global("ArrayBuffer").new_(dataLength);
- emscripten::val fileContentCopyView =
- emscripten::val::global("Uint8Array").new_(fileContentCopy);
- fileContentCopyView.call<void>("set", fileContentView);
-
- emscripten::val contentArray = emscripten::val::array();
- contentArray.call<void>("push", fileContentCopyView);
-
- // we have a blob, now create a ClipboardItem
- emscripten::val type = emscripten::val::array();
- type.set("type", mimetype.toEcmaString());
-
- emscripten::val contentBlob = emscripten::val::global("Blob").new_(contentArray, type);
-
- emscripten::val clipboardItemObject = emscripten::val::object();
- clipboardItemObject.set(mimetype.toEcmaString(), contentBlob);
-
- val clipboardItemData = val::global("ClipboardItem").new_(clipboardItemObject);
-
- clipboardWriteArray.call<void>("push", clipboardItemData);
-
- // Clipboard write is only supported with one ClipboardItem at the moment
- // but somehow this still works?
- // break;
}
- val navigator = val::global("navigator");
+ // Return if there is no data (creating an empty ClipboardItem is an error)
+ if (val::global("Object").call<val>("keys", clipboardData)["length"].as<int>() == 0)
+ return;
+ // Write a single clipboard item containing the data formats to the clipboard
+ emscripten::val clipboardItem = val::global("ClipboardItem").new_(clipboardData);
+ emscripten::val clipboardItemArray = emscripten::val::array();
+ clipboardItemArray.call<void>("push", clipboardItem);
+ val navigator = val::global("navigator");
qstdweb::Promise::make(
navigator["clipboard"], "write",
{
@@ -260,7 +216,7 @@ void QWasmClipboard::writeToClipboardApi()
<< QString::fromStdString(error["message"].as<std::string>());
}
},
- clipboardWriteArray);
+ clipboardItemArray);
}
void QWasmClipboard::writeToClipboard()