From f10a8dbf6cbb729d7fba80ac5e5a01d873b3a96b Mon Sep 17 00:00:00 2001 From: Even Oscar Andersen Date: Mon, 12 May 2025 11:59:20 +0200 Subject: [PATCH] wasm: set focus to m_canvas instead of m_window MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Setting focus and contentEditable on m_window causes innerHTML to build up with characters. This does not happen when using the m_canvas The downside is that m_canvas is aria-hidden, but this should, in principle, not be a problem since m_canvas should not be focused when a11y is in effect. Later aria-hidden might be set only if a11y is in effect. It turns out this also fixes tabbing between textfields and buttons bug. This is a candidate for manual cherry-picking to 6.9 6.9.1 Task-number: QTBUG-136687 Task-number: QTBUG-136562 Change-Id: I08a9db2c39f9b0b0038c75fd06d3504b736ea031 Reviewed-by: Morten Johan Sørvig --- src/plugins/platforms/wasm/qwasmclipboard.cpp | 16 -------------- src/plugins/platforms/wasm/qwasmclipboard.h | 2 -- src/plugins/platforms/wasm/qwasmwindow.cpp | 22 +++++++++++++------ src/plugins/platforms/wasm/qwasmwindow.h | 1 - 4 files changed, 15 insertions(+), 26 deletions(-) diff --git a/src/plugins/platforms/wasm/qwasmclipboard.cpp b/src/plugins/platforms/wasm/qwasmclipboard.cpp index 5112c3ae462..98e36813e15 100644 --- a/src/plugins/platforms/wasm/qwasmclipboard.cpp +++ b/src/plugins/platforms/wasm/qwasmclipboard.cpp @@ -86,26 +86,10 @@ void QWasmClipboard::paste(val event) QWasmIntegration::get()->getWasmClipboard()->sendClipboardData(event); } -void QWasmClipboard::beforeInput(emscripten::val event) -{ - event.call("preventDefault"); - event.call("stopPropagation"); -} - -void QWasmClipboard::input(emscripten::val event) -{ - event.call("preventDefault"); - event.call("stopPropagation"); - event["target"].set("innerHTML", std::string()); - event["target"].set("value", std::string()); -} - EMSCRIPTEN_BINDINGS(qtClipboardModule) { function("qtClipboardCutTo", &QWasmClipboard::cut); function("qtClipboardCopyTo", &QWasmClipboard::copy); function("qtClipboardPasteTo", &QWasmClipboard::paste); - function("qtClipboardBeforeInput", &QWasmClipboard::beforeInput); - function("qtClipboardInput", &QWasmClipboard::input); } QWasmClipboard::QWasmClipboard() diff --git a/src/plugins/platforms/wasm/qwasmclipboard.h b/src/plugins/platforms/wasm/qwasmclipboard.h index 67c65613c90..c22a31001b0 100644 --- a/src/plugins/platforms/wasm/qwasmclipboard.h +++ b/src/plugins/platforms/wasm/qwasmclipboard.h @@ -43,8 +43,6 @@ public: static void cut(emscripten::val event); static void copy(emscripten::val event); static void paste(emscripten::val event); - static void beforeInput(emscripten::val event); - static void input(emscripten::val event); private: void initClipboardPermissions(); diff --git a/src/plugins/platforms/wasm/qwasmwindow.cpp b/src/plugins/platforms/wasm/qwasmwindow.cpp index 8bd77ad55b5..69f3cb0fa63 100644 --- a/src/plugins/platforms/wasm/qwasmwindow.cpp +++ b/src/plugins/platforms/wasm/qwasmwindow.cpp @@ -56,7 +56,6 @@ QWasmWindow::QWasmWindow(QWindow *w, QWasmDeadKeySupport *deadKeySupport, m_document(dom::document()), m_decoratedWindow(m_document.call("createElement", emscripten::val("div"))), m_window(m_document.call("createElement", emscripten::val("div"))), - m_windowInput(m_document.call("createElement", emscripten::val("div"))), m_a11yContainer(m_document.call("createElement", emscripten::val("div"))), m_canvas(m_document.call("createElement", emscripten::val("canvas"))) { @@ -71,17 +70,26 @@ QWasmWindow::QWasmWindow(QWindow *w, QWasmDeadKeySupport *deadKeySupport, m_window.set("className", "qt-window"); m_decoratedWindow.call("appendChild", m_window); - m_window.call("appendChild", m_windowInput); m_canvas["classList"].call("add", emscripten::val("qt-window-canvas")); + // Set contentEditable for two reasons; + // 1) so that the window gets clipboard events, + // 2) For applications who will handle keyboard events, but without having inputMethodAccepted() + // + // Set inputMode to none to avoid keyboard popping up on push buttons + // This is a tradeoff, we are not able to separate between a push button and + // a widget that reads keyboard events. + m_canvas.call("setAttribute", std::string("inputmode"), std::string("none")); + m_canvas.call("setAttribute", std::string("contenteditable"), std::string("true")); + m_canvas["style"].set("outline", std::string("none")); + #if QT_CONFIG(clipboard) - QWasmClipboard::installEventHandlers(m_windowInput); + QWasmClipboard::installEventHandlers(m_canvas); #endif // Set inputMode to none to stop the mobile keyboard from opening // when the user clicks on the window. m_window.set("inputMode", std::string("none")); - m_windowInput.set("inputMode", std::string("none")); // Hide the canvas from screen readers. m_canvas.call("setAttribute", std::string("aria-hidden"), std::string("true")); @@ -119,9 +127,9 @@ QWasmWindow::QWasmWindow(QWindow *w, QWasmDeadKeySupport *deadKeySupport, [this](emscripten::val event) { this->handleKeyForInputContextEvent(event); }); } - m_keyDownCallback = std::make_unique(m_window, "keydown", + m_keyDownCallback = std::make_unique(m_canvas, "keydown", [this](emscripten::val event) { this->handleKeyEvent(event); }); - m_keyUpCallback =std::make_unique(m_window, "keyup", + m_keyUpCallback =std::make_unique(m_canvas, "keyup", [this](emscripten::val event) { this->handleKeyEvent(event); }); setParent(parent()); @@ -718,7 +726,7 @@ void QWasmWindow::requestActivateWindow() void QWasmWindow::focus() { - m_windowInput.call("focus"); + m_canvas.call("focus"); } bool QWasmWindow::setMouseGrabEnabled(bool grab) diff --git a/src/plugins/platforms/wasm/qwasmwindow.h b/src/plugins/platforms/wasm/qwasmwindow.h index 9f3b484aeeb..7a24b41cb08 100644 --- a/src/plugins/platforms/wasm/qwasmwindow.h +++ b/src/plugins/platforms/wasm/qwasmwindow.h @@ -140,7 +140,6 @@ private: emscripten::val m_document; emscripten::val m_decoratedWindow; emscripten::val m_window; - emscripten::val m_windowInput; emscripten::val m_a11yContainer; emscripten::val m_canvas; emscripten::val m_context2d = emscripten::val::undefined();