summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms/wasm/qwasmwindow.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/platforms/wasm/qwasmwindow.cpp')
-rw-r--r--src/plugins/platforms/wasm/qwasmwindow.cpp104
1 files changed, 92 insertions, 12 deletions
diff --git a/src/plugins/platforms/wasm/qwasmwindow.cpp b/src/plugins/platforms/wasm/qwasmwindow.cpp
index 174fff174e7..eb6b1cd2e3c 100644
--- a/src/plugins/platforms/wasm/qwasmwindow.cpp
+++ b/src/plugins/platforms/wasm/qwasmwindow.cpp
@@ -30,6 +30,7 @@
#include <emscripten/val.h>
#include <QtCore/private/qstdweb_p.h>
+#include <QKeySequence>
QT_BEGIN_NAMESPACE
@@ -106,6 +107,15 @@ QWasmWindow::QWasmWindow(QWindow *w, QWasmDeadKeySupport *deadKeySupport,
m_flags = window()->flags();
const auto pointerCallback = std::function([this](emscripten::val event) {
+ const auto eventTypeString = event["type"].as<std::string>();
+
+ // Ideally it should not be happened but
+ // it takes place sometime with some reason
+ // without compositionend.
+ QWasmInputContext *wasmInput = QWasmIntegration::get()->wasmInputContext();
+ if (wasmInput && !wasmInput->preeditString().isEmpty())
+ wasmInput->commitPreeditAndClear();
+
if (processPointer(*PointerEvent::fromWeb(event)))
event.call<void>("preventDefault");
});
@@ -121,25 +131,74 @@ QWasmWindow::QWasmWindow(QWindow *w, QWasmDeadKeySupport *deadKeySupport,
event.call<void>("preventDefault");
});
+ const auto keyCallbackForInputContext = std::function([this](emscripten::val event) {
+ QWasmInputContext *wasmInput = QWasmIntegration::get()->wasmInputContext();
+ if (wasmInput) {
+ const auto keyString = QString::fromStdString(event["key"].as<std::string>());
+ qCDebug(qLcQpaWasmInputContext) << "Key callback" << keyString << keyString.size();
+
+ if (keyString == "Unidentified") {
+ // Android makes a bunch of KeyEvents as "Unidentified"
+ // They will be processed just in InputContext.
+ return;
+ } else if (event["ctrlKey"].as<bool>()
+ || event["altKey"].as<bool>()
+ || event["metaKey"].as<bool>()) {
+ if (processKeyForInputContext(*KeyEvent::fromWebWithDeadKeyTranslation(event, m_deadKeySupport)))
+ event.call<void>("preventDefault");
+ event.call<void>("stopImmediatePropagation");
+ return;
+ } else if (keyString.size() != 1) {
+ if (!wasmInput->preeditString().isEmpty()) {
+ if (keyString == "Process" || keyString == "Backspace") {
+ // processed by InputContext
+ // "Process" should be handled by InputContext but
+ // QWasmInputContext's function is incomplete now
+ // so, there will be some exceptions here.
+ return;
+ } else if (keyString != "Shift"
+ && keyString != "Meta"
+ && keyString != "Alt"
+ && keyString != "Control"
+ && !keyString.startsWith("Arrow")) {
+ wasmInput->commitPreeditAndClear();
+ }
+ }
+ } else if (wasmInput->inputMethodAccepted()) {
+ // processed in inputContext with skipping processKey
+ return;
+ }
+ }
+
+ qCDebug(qLcQpaWasmInputContext) << "processKey as KeyEvent";
+ if (processKeyForInputContext(*KeyEvent::fromWebWithDeadKeyTranslation(event, m_deadKeySupport)))
+ event.call<void>("preventDefault");
+ event.call<void>("stopImmediatePropagation");
+ });
+
const auto keyCallback = std::function([this](emscripten::val event) {
+ qCDebug(qLcQpaWasmInputContext) << "processKey as KeyEvent";
if (processKey(*KeyEvent::fromWebWithDeadKeyTranslation(event, m_deadKeySupport)))
event.call<void>("preventDefault");
event.call<void>("stopPropagation");
});
- emscripten::val keyFocusWindow;
- if (QWasmInputContext *wasmContext =
- qobject_cast<QWasmInputContext *>(QWasmIntegration::get()->inputContext())) {
- // if there is an touchscreen input context,
- // use that window for key input
- keyFocusWindow = wasmContext->m_inputElement;
- } else {
- keyFocusWindow = m_qtWindow;
+ QWasmInputContext *wasmInput = QWasmIntegration::get()->wasmInputContext();
+ if (wasmInput) {
+ m_keyDownCallbackForInputContext =
+ std::make_unique<qstdweb::EventCallback>(wasmInput->m_inputElement,
+ "keydown",
+ keyCallbackForInputContext);
+ m_keyUpCallbackForInputContext =
+ std::make_unique<qstdweb::EventCallback>(wasmInput->m_inputElement,
+ "keyup",
+ keyCallbackForInputContext);
}
m_keyDownCallback =
- std::make_unique<qstdweb::EventCallback>(keyFocusWindow, "keydown", keyCallback);
- m_keyUpCallback = std::make_unique<qstdweb::EventCallback>(keyFocusWindow, "keyup", keyCallback);
+ std::make_unique<qstdweb::EventCallback>(m_qtWindow, "keydown", keyCallback);
+ m_keyUpCallback =std::make_unique<qstdweb::EventCallback>(m_qtWindow, "keyup", keyCallback);
+
setParent(parent());
}
@@ -356,8 +415,6 @@ void QWasmWindow::raise()
{
bringToTop();
invalidate();
- if (QWasmIntegration::get()->inputContext())
- m_canvas.call<void>("focus");
}
void QWasmWindow::lower()
@@ -526,6 +583,29 @@ bool QWasmWindow::processKey(const KeyEvent &event)
: result;
}
+bool QWasmWindow::processKeyForInputContext(const KeyEvent &event)
+{
+ qCDebug(qLcQpaWasmInputContext) << Q_FUNC_INFO;
+ Q_ASSERT(event.type == EventType::KeyDown || event.type == EventType::KeyUp);
+
+ QKeySequence keySeq(event.modifiers | event.key);
+
+ if (keySeq == QKeySequence::Paste) {
+ // Process it in pasteCallback and inputCallback
+ return false;
+ }
+
+ const auto result = QWindowSystemInterface::handleKeyEvent(
+ 0, event.type == EventType::KeyDown ? QEvent::KeyPress : QEvent::KeyRelease, event.key,
+ event.modifiers, event.text);
+
+ // Copy/Cut callback required to copy qtClipboard to system clipboard
+ if (keySeq == QKeySequence::Copy || keySeq == QKeySequence::Cut)
+ return false;
+
+ return result;
+}
+
bool QWasmWindow::processPointer(const PointerEvent &event)
{
if (event.pointerType != PointerType::Mouse && event.pointerType != PointerType::Pen)