From a74b2b5f152ae81da6c0906afc63b8647c3a048a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Wed, 27 Feb 2019 11:30:31 +0100 Subject: macOS: Initialize QNSView mouse related members with other mouse logic MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I4ff67028823d62ed67bf4303a58bee127bd76501 Reviewed-by: Timur Pocheptsov Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/cocoa/qnsview.mm | 9 --------- src/plugins/platforms/cocoa/qnsview_mouse.mm | 13 +++++++++++++ 2 files changed, 13 insertions(+), 9 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/cocoa/qnsview.mm b/src/plugins/platforms/cocoa/qnsview.mm index 17063f6e92..5309449dce 100644 --- a/src/plugins/platforms/cocoa/qnsview.mm +++ b/src/plugins/platforms/cocoa/qnsview.mm @@ -137,22 +137,13 @@ { if ((self = [super initWithFrame:NSZeroRect])) { m_platformWindow = platformWindow; - m_buttons = Qt::NoButton; - m_acceptedMouseDowns = Qt::NoButton; - m_frameStrutButtons = Qt::NoButton; m_sendKeyEvent = false; - m_sendUpAsRightButton = false; m_inputSource = nil; - m_mouseMoveHelper = [[QT_MANGLE_NAMESPACE(QNSViewMouseMoveHelper) alloc] initWithView:self]; m_resendKeyEvent = false; - m_scrolling = false; m_updatingDrag = false; m_currentlyInterpretedKeyEvent = nil; - m_dontOverrideCtrlLMB = qt_mac_resolveOption(false, platformWindow->window(), - "_q_platform_MacDontOverrideCtrlLMB", "QT_MAC_DONT_OVERRIDE_CTRL_LMB"); self.focusRingType = NSFocusRingTypeNone; - self.cursor = nil; self.previousSuperview = nil; self.previousWindow = nil; diff --git a/src/plugins/platforms/cocoa/qnsview_mouse.mm b/src/plugins/platforms/cocoa/qnsview_mouse.mm index 49c94f18db..c9c87d9323 100644 --- a/src/plugins/platforms/cocoa/qnsview_mouse.mm +++ b/src/plugins/platforms/cocoa/qnsview_mouse.mm @@ -153,6 +153,19 @@ - (void)initMouse { + m_buttons = Qt::NoButton; + m_acceptedMouseDowns = Qt::NoButton; + m_frameStrutButtons = Qt::NoButton; + + m_scrolling = false; + self.cursor = nil; + + m_sendUpAsRightButton = false; + m_dontOverrideCtrlLMB = qt_mac_resolveOption(false, m_platformWindow->window(), + "_q_platform_MacDontOverrideCtrlLMB", "QT_MAC_DONT_OVERRIDE_CTRL_LMB"); + + m_mouseMoveHelper = [[QT_MANGLE_NAMESPACE(QNSViewMouseMoveHelper) alloc] initWithView:self]; + NSUInteger trackingOptions = NSTrackingActiveInActiveApp | NSTrackingMouseEnteredAndExited | NSTrackingCursorUpdate; -- cgit v1.2.3 From 070f75d3b0f5313a0f486fe5c811a8e40dd97967 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Sat, 23 Feb 2019 09:40:30 +0100 Subject: wasm: improve clipboard fallback path MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This improves handling of cut/copy/paste clipboard events, ands allows clipboard access via the common keyboard shortcuts. Make the canvas be eligible for clipboard events by setting the contenteditable attribute. Install clipboard event handlers directly on the canvas. Suppress Ctrl+X/C/V key event handling in the keyboard event handler in order to make the browser generate clipboard events. Send synthetic key events from the clipboard event handlers to make the app copy/paste to Qt’s clipboard at the correct time. Access the system clipboard data using event.clipboardData. Task-number: QTBUG-64638 Change-Id: I584b78ffa2b755b1b76e477b970255c6e5522f6a Reviewed-by: Lorn Potter --- src/plugins/platforms/wasm/qtloader.js | 9 +++- src/plugins/platforms/wasm/qwasmclipboard.cpp | 48 +++++++++++++++------- .../platforms/wasm/qwasmeventtranslator.cpp | 8 ++++ src/plugins/platforms/wasm/wasm_shell.html | 8 +++- 4 files changed, 56 insertions(+), 17 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/wasm/qtloader.js b/src/plugins/platforms/wasm/qtloader.js index 84694c7b9f..203213db56 100644 --- a/src/plugins/platforms/wasm/qtloader.js +++ b/src/plugins/platforms/wasm/qtloader.js @@ -168,7 +168,14 @@ function QtLoader(config) removeChildren(container); var canvas = document.createElement("canvas"); canvas.className = "QtCanvas" - canvas.style = "height: 100%; width: 100%;" + canvas.style.height = "100%" + canvas.style.width = "100%" + + // Set contentEditable in order to enable clipboard events; hide the resulting focus frame. + canvas.contentEditable = true; + canvas.style.outline = "0px solid transparent"; + canvas.style.cursor = "default"; + return canvas; } diff --git a/src/plugins/platforms/wasm/qwasmclipboard.cpp b/src/plugins/platforms/wasm/qwasmclipboard.cpp index ec058f05dd..63fea7738d 100644 --- a/src/plugins/platforms/wasm/qwasmclipboard.cpp +++ b/src/plugins/platforms/wasm/qwasmclipboard.cpp @@ -67,23 +67,42 @@ static void qClipboardPromiseResolve(emscripten::val something) pasteClipboardData(emscripten::val("text/plain"), something); } -static void qClipboardCopyTo(val event) +static void qClipboardCutTo(val event) { - val target = event["target"]; - val clipboard = event["clipboardData"]; + if (!QWasmIntegration::get()->getWasmClipboard()->hasClipboardApi) { + // Send synthetic Ctrl+X to make the app cut data to Qt's clipboard + QWindowSystemInterface::handleKeyEvent( + 0, QEvent::KeyPress, Qt::Key_X, Qt::ControlModifier, "X"); + } val module = val::global("Module"); val clipdata = module.call("getClipboardData"); val clipFormat = module.call("getClipboardFormat"); - clipboard.call("setData", clipFormat, clipdata); - target.call("preventDefault"); + event["clipboardData"].call("setData", clipFormat, clipdata); + event.call("preventDefault"); } -static void qClipboardPasteTo(val event) +static void qClipboardCopyTo(val event) { - val target = event["clipboardData"]; + if (!QWasmIntegration::get()->getWasmClipboard()->hasClipboardApi) { + // Send synthetic Ctrl+C to make the app copy data to Qt's clipboard + QWindowSystemInterface::handleKeyEvent( + 0, QEvent::KeyPress, Qt::Key_C, Qt::ControlModifier, "C"); + } + val module = val::global("Module"); val clipdata = module.call("getClipboardData"); + val clipFormat = module.call("getClipboardFormat"); + event["clipboardData"].call("setData", clipFormat, clipdata); + event.call("preventDefault"); +} + +static void qClipboardPasteTo(val event) +{ + bool hasClipboardApi = QWasmIntegration::get()->getWasmClipboard()->hasClipboardApi; + val clipdata = hasClipboardApi ? + val::global("Module").call("getClipboardData") : + event["clipboardData"].call("getData", std::string("text")); const std::string data = clipdata.as(); if (data.length() > 0) { @@ -99,6 +118,7 @@ EMSCRIPTEN_BINDINGS(clipboard_module) { function("getClipboardFormat", &getClipboardFormat); function("pasteClipboardData", &pasteClipboardData); function("qClipboardPromiseResolve", &qClipboardPromiseResolve); + function("qClipboardCutTo", &qClipboardCutTo); function("qClipboardCopyTo", &qClipboardCopyTo); function("qClipboardPasteTo", &qClipboardPasteTo); } @@ -161,7 +181,7 @@ void QWasmClipboard::initClipboardEvents() val permissions = navigator["permissions"]; val clipboard = navigator["clipboard"]; - hasClipboardApi = (!clipboard.isUndefined()); + hasClipboardApi = (!clipboard.isUndefined() && !clipboard["readText"].isUndefined()); if (hasClipboardApi) { val readPermissionsMap = val::object(); readPermissionsMap.set("name", val("clipboard-read")); @@ -172,13 +192,13 @@ void QWasmClipboard::initClipboardEvents() permissions.call("query", writePermissionsMap); } else { - - val window = val::global("window"); - window.call("addEventListener", std::string("paste"), - val::module_property("qClipboardPasteTo")); - - window.call("addEventListener", std::string("copy"), + val canvas = val::module_property("canvas"); + canvas.call("addEventListener", std::string("cut"), + val::module_property("qClipboardCutTo")); + canvas.call("addEventListener", std::string("copy"), val::module_property("qClipboardCopyTo")); + canvas.call("addEventListener", std::string("paste"), + val::module_property("qClipboardPasteTo")); } } diff --git a/src/plugins/platforms/wasm/qwasmeventtranslator.cpp b/src/plugins/platforms/wasm/qwasmeventtranslator.cpp index 3fc8f600a1..05c09ec9a0 100644 --- a/src/plugins/platforms/wasm/qwasmeventtranslator.cpp +++ b/src/plugins/platforms/wasm/qwasmeventtranslator.cpp @@ -832,6 +832,14 @@ bool QWasmEventTranslator::processKeyboard(int eventType, const EmscriptenKeyboa return 0; QFlags mods = translateKeyboardEventModifier(keyEvent); + + // Clipboard fallback path: cut/copy/paste are handled by clipboard event + // handlers if direct clipboard access is not available. + if (!QWasmIntegration::get()->getWasmClipboard()->hasClipboardApi && modifiers & Qt::ControlModifier && + (qtKey == Qt::Key_X || qtKey == Qt::Key_C || qtKey == Qt::Key_V)) { + return 0; + } + bool accepted = false; if (keyType == QEvent::KeyPress && diff --git a/src/plugins/platforms/wasm/wasm_shell.html b/src/plugins/platforms/wasm/wasm_shell.html index 67bfcdfbdc..110d45e036 100644 --- a/src/plugins/platforms/wasm/wasm_shell.html +++ b/src/plugins/platforms/wasm/wasm_shell.html @@ -7,7 +7,11 @@ @@ -19,7 +23,7 @@ - +