wasm: set contenteditable on canvas

We don't want to make the top-level screen contenteditable,
since that interferes with accessibility. Instead, make
the canvas contenteditable and install clipboard event
handlers there.

Also move follow-up settings which counters some of the
effects contenteditable (outline: none and inputmode: none),
and move aria-hidden.

Change-Id: Ibe73d8d097acd948ba8920c781a2003db0a14f3d
Reviewed-by: Morten Johan Sørvig <morten.sorvig@qt.io>
(cherry picked from commit 2443f2be07607e44ec483278873702eb0f57ab26)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
Morten Sørvig 2023-02-03 12:59:42 +01:00 committed by Qt Cherry-pick Bot
parent 192291bb08
commit 79ffb2eb33
6 changed files with 21 additions and 19 deletions

View File

@ -240,15 +240,15 @@ void QWasmClipboard::initClipboardPermissions()
})());
}
void QWasmClipboard::installEventHandlers(const emscripten::val &screenElement)
void QWasmClipboard::installEventHandlers(const emscripten::val &target)
{
emscripten::val cContext = val::undefined();
emscripten::val isChromium = val::global("window")["chrome"];
if (!isChromium.isUndefined()) {
if (!isChromium.isUndefined()) {
cContext = val::global("document");
} else {
cContext = screenElement;
}
} else {
cContext = target;
}
// Fallback path for browsers which do not support direct clipboard access
cContext.call<void>("addEventListener", val("cut"),
val::module_property("qtClipboardCutTo"), true);

View File

@ -36,7 +36,7 @@ public:
ProcessKeyboardResult processKeyboard(const QWasmEventTranslator::TranslatedEvent &event,
const QFlags<Qt::KeyboardModifier> &modifiers);
void installEventHandlers(const emscripten::val &canvas);
static void installEventHandlers(const emscripten::val &target);
bool hasClipboardApi();
private:

View File

@ -24,7 +24,6 @@ const char *Style = R"css(
width: 100%;
height: 100%;
overflow: hidden;
outline: none;
}
.qt-window {

View File

@ -278,7 +278,6 @@ void QWasmIntegration::addScreen(const emscripten::val &element)
{
QWasmScreen *screen = new QWasmScreen(element);
m_screens.append(qMakePair(element, screen));
m_clipboard->installEventHandlers(element);
QWindowSystemInterface::handleScreenAdded(screen);
}

View File

@ -57,22 +57,11 @@ QWasmScreen::QWasmScreen(const emscripten::val &containerOrCanvas)
m_shadowContainer["classList"].call<void>("add", std::string("qt-screen"));
// Set contenteditable so that the canvas gets clipboard events,
// then hide the resulting focus frame, and reset the cursor.
m_shadowContainer.set("contentEditable", std::string("true"));
// set inputmode to none to stop mobile keyboard opening
// when user clicks anywhere on the canvas.
m_shadowContainer.set("inputmode", std::string("none"));
// Hide the canvas from screen readers.
m_shadowContainer.call<void>("setAttribute", std::string("aria-hidden"), std::string("true"));
// Disable the default context menu; Qt applications typically
// provide custom right-click behavior.
m_onContextMenu = std::make_unique<qstdweb::EventCallback>(
m_shadowContainer, "contextmenu",
[](emscripten::val event) { event.call<void>("preventDefault"); });
// Create "specialHTMLTargets" mapping for the canvas - the element might be unreachable based
// on its id only under some conditions, like the target being embedded in a shadow DOM or a
// subframe.

View File

@ -20,6 +20,7 @@
#include "qwasmeventdispatcher.h"
#include "qwasmstring.h"
#include "qwasmaccessibility.h"
#include "qwasmclipboard.h"
#include <iostream>
#include <emscripten/val.h>
@ -56,6 +57,20 @@ QWasmWindow::QWasmWindow(QWindow *w, QWasmCompositor *compositor, QWasmBackingSt
m_canvas["classList"].call<void>("add", emscripten::val("qt-window-content"));
// Set contenteditable so that the canvas gets clipboard events,
// then hide the resulting focus frame.
m_canvas.set("contentEditable", std::string("true"));
m_canvas["style"].set("outline", std::string("none"));
QWasmClipboard::installEventHandlers(m_canvas);
// set inputmode to none to stop mobile keyboard opening
// when user clicks anywhere on the canvas.
m_canvas.set("inputmode", std::string("none"));
// Hide the canvas from screen readers.
m_canvas.call<void>("setAttribute", std::string("aria-hidden"), std::string("true"));
m_windowContents.call<void>("appendChild", m_canvasContainer);
m_canvasContainer["classList"].call<void>("add", emscripten::val("qt-window-canvas-container"));