diff options
-rw-r--r-- | src/plugins/platforms/wasm/qwasmclipboard.cpp | 204 | ||||
-rw-r--r-- | src/plugins/platforms/wasm/qwasmclipboard.h | 59 | ||||
-rw-r--r-- | src/plugins/platforms/wasm/qwasmeventtranslator.cpp | 23 | ||||
-rw-r--r-- | src/plugins/platforms/wasm/qwasmintegration.cpp | 18 | ||||
-rw-r--r-- | src/plugins/platforms/wasm/qwasmintegration.h | 8 | ||||
-rw-r--r-- | src/plugins/platforms/wasm/wasm.pro | 6 |
6 files changed, 307 insertions, 11 deletions
diff --git a/src/plugins/platforms/wasm/qwasmclipboard.cpp b/src/plugins/platforms/wasm/qwasmclipboard.cpp new file mode 100644 index 0000000000..ec058f05dd --- /dev/null +++ b/src/plugins/platforms/wasm/qwasmclipboard.cpp @@ -0,0 +1,204 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qwasmclipboard.h" +#include "qwasmwindow.h" + +#include <emscripten.h> +#include <emscripten/html5.h> +#include <emscripten/bind.h> + +#include <QCoreApplication> +#include <qpa/qwindowsysteminterface.h> + +using namespace emscripten; + +// there has got to be a better way... +static QByteArray g_clipboardArray; +static QByteArray g_clipboardFormat; + +static val getClipboardData() +{ + return val(g_clipboardArray.constData()); +} + +static val getClipboardFormat() +{ + return val(g_clipboardFormat.constData()); +} + +static void pasteClipboardData(emscripten::val format, emscripten::val dataPtr) +{ + QString formatString = QString::fromStdString(format.as<std::string>()); + QByteArray dataArray = QByteArray::fromStdString(dataPtr.as<std::string>()); + QMimeData *mMimeData = new QMimeData; + mMimeData->setData(formatString, dataArray); + QWasmClipboard::qWasmClipboardPaste(mMimeData); +} + +static void qClipboardPromiseResolve(emscripten::val something) +{ + pasteClipboardData(emscripten::val("text/plain"), something); +} + +static void qClipboardCopyTo(val event) +{ + val target = event["target"]; + val clipboard = event["clipboardData"]; + + val module = val::global("Module"); + val clipdata = module.call<val>("getClipboardData"); + val clipFormat = module.call<val>("getClipboardFormat"); + clipboard.call<void>("setData", clipFormat, clipdata); + target.call<void>("preventDefault"); +} + +static void qClipboardPasteTo(val event) +{ + val target = event["clipboardData"]; + val module = val::global("Module"); + val clipdata = module.call<val>("getClipboardData"); + + const std::string data = clipdata.as<std::string>(); + if (data.length() > 0) { + QString qstr = QString::fromStdString(data); + QMimeData *mMimeData = new QMimeData; + mMimeData->setText(qstr); + QWasmClipboard::qWasmClipboardPaste(mMimeData); + } +} + +EMSCRIPTEN_BINDINGS(clipboard_module) { + function("getClipboardData", &getClipboardData); + function("getClipboardFormat", &getClipboardFormat); + function("pasteClipboardData", &pasteClipboardData); + function("qClipboardPromiseResolve", &qClipboardPromiseResolve); + function("qClipboardCopyTo", &qClipboardCopyTo); + function("qClipboardPasteTo", &qClipboardPasteTo); +} + +QWasmClipboard::QWasmClipboard() : + hasClipboardApi(false) +{ + initClipboardEvents(); +} + +QWasmClipboard::~QWasmClipboard() +{ + g_clipboardArray.clear(); + g_clipboardFormat.clear(); +} + +QMimeData* QWasmClipboard::mimeData(QClipboard::Mode mode) +{ + if (mode != QClipboard::Clipboard) + return nullptr; + + return QPlatformClipboard::mimeData(mode); +} + +void QWasmClipboard::setMimeData(QMimeData* mimeData, QClipboard::Mode mode) +{ + if (mimeData->hasText()) { + g_clipboardFormat = mimeData->formats().at(0).toUtf8(); + g_clipboardArray = mimeData->text().toUtf8(); + } else if (mimeData->hasHtml()) { + g_clipboardFormat =mimeData->formats().at(0).toUtf8(); + g_clipboardArray = mimeData->html().toUtf8(); + } + + QPlatformClipboard::setMimeData(mimeData, mode); +} + +bool QWasmClipboard::supportsMode(QClipboard::Mode mode) const +{ + return mode == QClipboard::Clipboard; +} + +bool QWasmClipboard::ownsMode(QClipboard::Mode mode) const +{ + Q_UNUSED(mode); + return false; +} + +void QWasmClipboard::qWasmClipboardPaste(QMimeData *mData) +{ + QWasmIntegration::get()->clipboard()->setMimeData(mData, QClipboard::Clipboard); + + QWindowSystemInterface::handleKeyEvent<QWindowSystemInterface::SynchronousDelivery>( + 0, QEvent::KeyPress, Qt::Key_V, Qt::ControlModifier, "V"); +} + +void QWasmClipboard::initClipboardEvents() +{ + val navigator = val::global("navigator"); + val permissions = navigator["permissions"]; + val clipboard = navigator["clipboard"]; + + hasClipboardApi = (!clipboard.isUndefined()); + if (hasClipboardApi) { + val readPermissionsMap = val::object(); + readPermissionsMap.set("name", val("clipboard-read")); + permissions.call<val>("query", readPermissionsMap); + + val writePermissionsMap = val::object(); + writePermissionsMap.set("name", val("clipboard-write")); + permissions.call<val>("query", writePermissionsMap); + + } else { + + val window = val::global("window"); + window.call<void>("addEventListener", std::string("paste"), + val::module_property("qClipboardPasteTo")); + + window.call<void>("addEventListener", std::string("copy"), + val::module_property("qClipboardCopyTo")); + } +} + +void QWasmClipboard::readTextFromClipboard() +{ + if (QWasmIntegration::get()->getWasmClipboard()->hasClipboardApi) { + val navigator = val::global("navigator"); + val textPromise = navigator["clipboard"].call<val>("readText"); + val readTextResolve = val::global("Module")["qClipboardPromiseResolve"]; + textPromise.call<val>("then", readTextResolve); + } +} + +void QWasmClipboard::writeTextToClipboard() +{ + if (QWasmIntegration::get()->getWasmClipboard()->hasClipboardApi) { + val module = val::global("Module"); + val txt = module.call<val>("getClipboardData"); + val format = module.call<val>("getClipboardFormat"); + val navigator = val::global("navigator"); + navigator["clipboard"].call<void>("writeText", txt.as<std::string>()); + } +} diff --git a/src/plugins/platforms/wasm/qwasmclipboard.h b/src/plugins/platforms/wasm/qwasmclipboard.h new file mode 100644 index 0000000000..e64b2e5007 --- /dev/null +++ b/src/plugins/platforms/wasm/qwasmclipboard.h @@ -0,0 +1,59 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the plugins of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QWasmClipboard_H +#define QWasmClipboard_H + +#include <QObject> + +#include <qpa/qplatformclipboard.h> +#include <QMimeData> + +#include <emscripten/bind.h> + +class QWasmClipboard : public QObject, public QPlatformClipboard +{ +public: + QWasmClipboard(); + virtual ~QWasmClipboard(); + + // QPlatformClipboard methods. + QMimeData* mimeData(QClipboard::Mode mode = QClipboard::Clipboard) override; + void setMimeData(QMimeData* data, QClipboard::Mode mode = QClipboard::Clipboard) override; + bool supportsMode(QClipboard::Mode mode) const override; + bool ownsMode(QClipboard::Mode mode) const override; + + static void qWasmClipboardPaste(QMimeData *mData); + void initClipboardEvents(); + bool hasClipboardApi; + void readTextFromClipboard(); + void writeTextToClipboard(); +}; + +#endif // QWASMCLIPBOARD_H diff --git a/src/plugins/platforms/wasm/qwasmeventtranslator.cpp b/src/plugins/platforms/wasm/qwasmeventtranslator.cpp index ea88ef59a0..df81413d5c 100644 --- a/src/plugins/platforms/wasm/qwasmeventtranslator.cpp +++ b/src/plugins/platforms/wasm/qwasmeventtranslator.cpp @@ -31,6 +31,7 @@ #include "qwasmeventdispatcher.h" #include "qwasmcompositor.h" #include "qwasmintegration.h" +#include "qwasmclipboard.h" #include <QtGui/qevent.h> #include <qpa/qwindowsysteminterface.h> @@ -175,10 +176,26 @@ int QWasmEventTranslator::keyboard_cb(int eventType, const EmscriptenKeyboardEve if (keyType == QEvent::None) return 0; - QString keyText = alphanumeric ? QString(keyEvent->key) : QString(); - bool accepted = QWindowSystemInterface::handleKeyEvent<QWindowSystemInterface::SynchronousDelivery>( - 0, keyType, qtKey, translateKeyboardEventModifier(keyEvent), keyText); + QFlags<Qt::KeyboardModifier> mods = translateKeyboardEventModifier(keyEvent); + bool accepted = false; + + if (keyType == QEvent::KeyPress && + mods.testFlag(Qt::ControlModifier) + && qtKey == Qt::Key_V) { + QWasmIntegration::get()->getWasmClipboard()->readTextFromClipboard(); + } else { + QString keyText = alphanumeric ? QString(keyEvent->key) : QString(); + accepted = QWindowSystemInterface::handleKeyEvent<QWindowSystemInterface::SynchronousDelivery>( + 0, keyType, qtKey, translateKeyboardEventModifier(keyEvent), keyText); + } + + if (keyType == QEvent::KeyPress && + mods.testFlag(Qt::ControlModifier) + && qtKey == Qt::Key_C) { + QWasmIntegration::get()->getWasmClipboard()->writeTextToClipboard(); + } QWasmEventDispatcher::maintainTimers(); + return accepted ? 1 : 0; } diff --git a/src/plugins/platforms/wasm/qwasmintegration.cpp b/src/plugins/platforms/wasm/qwasmintegration.cpp index 7a44c47893..6f96ec69da 100644 --- a/src/plugins/platforms/wasm/qwasmintegration.cpp +++ b/src/plugins/platforms/wasm/qwasmintegration.cpp @@ -33,6 +33,7 @@ #include "qwasmcompositor.h" #include "qwasmopenglcontext.h" #include "qwasmtheme.h" +#include "qwasmclipboard.h" #include "qwasmwindow.h" #ifndef QT_NO_OPENGL @@ -65,17 +66,16 @@ EMSCRIPTEN_BINDINGS(my_module) function("browserBeforeUnload", &browserBeforeUnload); } -static QWasmIntegration *globalHtml5Integration; -QWasmIntegration *QWasmIntegration::get() { return globalHtml5Integration; } +QWasmIntegration *QWasmIntegration::s_instance; QWasmIntegration::QWasmIntegration() : m_fontDb(nullptr), m_compositor(new QWasmCompositor), m_screen(new QWasmScreen(m_compositor)), - m_eventDispatcher(nullptr) + m_eventDispatcher(nullptr), + m_clipboard(new QWasmClipboard) { - - globalHtml5Integration = this; + s_instance = this; updateQScreenAndCanvasRenderSize(); screenAdded(m_screen); @@ -93,6 +93,7 @@ QWasmIntegration::~QWasmIntegration() destroyScreen(m_screen); delete m_fontDb; delete m_eventTranslator; + s_instance = nullptr; } void QWasmIntegration::QWasmBrowserExit() @@ -211,4 +212,11 @@ void QWasmIntegration::updateQScreenAndCanvasRenderSize() QWasmIntegration::get()->m_compositor->redrawWindowContent(); } +QPlatformClipboard* QWasmIntegration::clipboard() const +{ + if (!m_clipboard) + m_clipboard = new QWasmClipboard; + return m_clipboard; +} + QT_END_NAMESPACE diff --git a/src/plugins/platforms/wasm/qwasmintegration.h b/src/plugins/platforms/wasm/qwasmintegration.h index ebc3d9d431..4c5aeb4ebc 100644 --- a/src/plugins/platforms/wasm/qwasmintegration.h +++ b/src/plugins/platforms/wasm/qwasmintegration.h @@ -49,6 +49,7 @@ class QWasmEventDispatcher; class QWasmScreen; class QWasmCompositor; class QWasmBackingStore; +class QWasmClipboard; class QWasmIntegration : public QObject, public QPlatformIntegration { @@ -68,12 +69,14 @@ public: QVariant styleHint(QPlatformIntegration::StyleHint hint) const override; QStringList themeNames() const override; QPlatformTheme *createPlatformTheme(const QString &name) const override; + QPlatformClipboard *clipboard() const override; - static QWasmIntegration *get(); QWasmScreen *screen() { return m_screen; } QWasmCompositor *compositor() { return m_compositor; } QWasmEventTranslator *eventTranslator() { return m_eventTranslator; } + QWasmClipboard *getWasmClipboard() { return m_clipboard; } + static QWasmIntegration *get() { return s_instance; } static void QWasmBrowserExit(); static void updateQScreenAndCanvasRenderSize(); @@ -85,6 +88,9 @@ private: mutable QWasmEventDispatcher *m_eventDispatcher; static int uiEvent_cb(int eventType, const EmscriptenUiEvent *e, void *userData); mutable QHash<QWindow *, QWasmBackingStore *> m_backingStores; + + mutable QWasmClipboard *m_clipboard; + static QWasmIntegration *s_instance; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/wasm/wasm.pro b/src/plugins/platforms/wasm/wasm.pro index eaaba53aa2..5aa6dfccf3 100644 --- a/src/plugins/platforms/wasm/wasm.pro +++ b/src/plugins/platforms/wasm/wasm.pro @@ -18,7 +18,8 @@ SOURCES = \ qwasmcompositor.cpp \ qwasmcursor.cpp \ qwasmopenglcontext.cpp \ - qwasmtheme.cpp + qwasmtheme.cpp \ + qwasmclipboard.cpp HEADERS = \ qwasmintegration.h \ @@ -31,7 +32,8 @@ HEADERS = \ qwasmstylepixmaps_p.h \ qwasmcursor.h \ qwasmopenglcontext.h \ - qwasmtheme.h + qwasmtheme.h \ + qwasmclipboard.h wasmfonts.files = \ ../../../3rdparty/wasm/Vera.ttf \ |