From d65c618915bfc7b08089c376d879e94cd567978f Mon Sep 17 00:00:00 2001 From: Mikolaj Boc Date: Thu, 14 Jul 2022 15:56:38 +0200 Subject: [PATCH] Refactor code focused around QWasmCompositor::processMouse Refactoring of the logic around QWasmCompositor::processMouse has been performed for readability and easier modification, in preparation for further fixes for event delivery and handling in windows. There should be no logic changes, just cleaner code. Change groups: Members of QWasmCompositor have been prefixed by m_ for easier discerning of stateful and stateless variables in functions. Variables renamed to more descriptive, e.g. window2->targetWindow, globalPoint->targetPointInScreenCoords. Magic numbers eliminated, e.g. mouseEvent->button == 0 is now button == Qt::MouseButton::LeftButton. Some common condition checks have been wrapped into single constants, e.g. !(htmlWindow->m_windowState & Qt::WindowFullScreen) && !(htmlWindow->m_windowState & Qt::WindowMaximized) == isTargetWindowResizable Some nested if-conditions were collapsed. Some unnecessary checks have been moved to outer if conditions (e.g. for draggedWindow in EMSCRIPTEN_EVENT_MOUSEMOVE, since the code would crash anyway because only some parts are guarded against it being nullptr). Consts introduced so that variables are only used for one purpose. Made QWasmEventTranslator::translateMouseButton constexpr Made QWasmWindow::isPointOnTitle behave correctly when the window has no title bar so that no flag probing is needed prior to calling it. Made QWasmCursor::setOverrideWasmCursor accept a const ref - having it accept pointer suggested it might dangle. Change-Id: I8910622fddad764ee86eb0260b5ad23c7ee7f97a Reviewed-by: David Skoland (cherry picked from commit ec58600cc923d6b7de5266e20e27d377fcc1540a) --- .../platforms/wasm/qwasmcompositor.cpp | 336 +++++++++--------- src/plugins/platforms/wasm/qwasmcompositor.h | 70 ++-- src/plugins/platforms/wasm/qwasmcursor.cpp | 4 +- src/plugins/platforms/wasm/qwasmcursor.h | 2 +- .../platforms/wasm/qwasmeventtranslator.cpp | 12 - .../platforms/wasm/qwasmeventtranslator.h | 13 +- src/plugins/platforms/wasm/qwasmwindow.cpp | 3 +- 7 files changed, 209 insertions(+), 231 deletions(-) diff --git a/src/plugins/platforms/wasm/qwasmcompositor.cpp b/src/plugins/platforms/wasm/qwasmcompositor.cpp index 7787367e010..920a8bf016c 100644 --- a/src/plugins/platforms/wasm/qwasmcompositor.cpp +++ b/src/plugins/platforms/wasm/qwasmcompositor.cpp @@ -25,6 +25,12 @@ #include +namespace { +QWasmWindow *AsWasmWindow(QWindow *window) { + return static_cast(window->handle()); +} +} // namespace + using namespace emscripten; Q_GUI_EXPORT int qt_defaultDpiX(); @@ -51,32 +57,22 @@ EMSCRIPTEN_BINDINGS(qtMouseModule) { } QWasmCompositor::QWasmCompositor(QWasmScreen *screen) - :QObject(screen) + : QObject(screen) , m_blitter(new QOpenGLTextureBlitter) - , m_needComposit(false) - , m_inFlush(false) - , m_inResize(false) - , m_isEnabled(true) - , m_targetDevicePixelRatio(1) - , draggedWindow(nullptr) - , lastWindow(nullptr) - , pressedButtons(Qt::NoButton) - , resizeMode(QWasmCompositor::ResizeNone) - , eventTranslator(new QWasmEventTranslator()) - , mouseInCanvas(false) + , m_eventTranslator(std::make_unique()) { - touchDevice = new QPointingDevice( + m_touchDevice = std::make_unique( "touchscreen", 1, QInputDevice::DeviceType::TouchScreen, QPointingDevice::PointerType::Finger, QPointingDevice::Capability::Position | QPointingDevice::Capability::Area | QPointingDevice::Capability::NormalizedPosition, 10, 0); - QWindowSystemInterface::registerInputDevice(touchDevice); + QWindowSystemInterface::registerInputDevice(m_touchDevice.get()); } QWasmCompositor::~QWasmCompositor() { - windowUnderMouse.clear(); + m_windowUnderMouse.clear(); if (m_requestAnimationFrameId != -1) emscripten_cancel_animation_frame(m_requestAnimationFrameId); @@ -137,7 +133,7 @@ void QWasmCompositor::initEventHandlers() { QByteArray canvasSelector = screen()->canvasTargetId().toUtf8(); - eventTranslator->g_usePlatformMacSpecifics + m_eventTranslator->g_usePlatformMacSpecifics = (QWasmIntegration::get()->platform == QWasmIntegration::MacOSPlatform); if (QWasmIntegration::get()->platform == QWasmIntegration::MacOSPlatform) { if (!emscripten::val::global("window")["safari"].isUndefined()) { @@ -148,23 +144,25 @@ void QWasmCompositor::initEventHandlers() } } - emscripten_set_keydown_callback(canvasSelector.constData(), (void *)this, 1, &keyboard_cb); - emscripten_set_keyup_callback(canvasSelector.constData(), (void *)this, 1, &keyboard_cb); + constexpr EM_BOOL UseCapture = 1; - emscripten_set_mousedown_callback(canvasSelector.constData(), (void *)this, 1, &mouse_cb); - emscripten_set_mouseup_callback(canvasSelector.constData(), (void *)this, 1, &mouse_cb); - emscripten_set_mousemove_callback(canvasSelector.constData(), (void *)this, 1, &mouse_cb); - emscripten_set_mouseenter_callback(canvasSelector.constData(), (void *)this, 1, &mouse_cb); - emscripten_set_mouseleave_callback(canvasSelector.constData(), (void *)this, 1, &mouse_cb); + emscripten_set_keydown_callback(canvasSelector.constData(), (void *)this, UseCapture, &keyboard_cb); + emscripten_set_keyup_callback(canvasSelector.constData(), (void *)this, UseCapture, &keyboard_cb); - emscripten_set_focus_callback(canvasSelector.constData(), (void *)this, 1, &focus_cb); + emscripten_set_mousedown_callback(canvasSelector.constData(), (void *)this, UseCapture, &mouse_cb); + emscripten_set_mouseup_callback(canvasSelector.constData(), (void *)this, UseCapture, &mouse_cb); + emscripten_set_mousemove_callback(canvasSelector.constData(), (void *)this, UseCapture, &mouse_cb); + emscripten_set_mouseenter_callback(canvasSelector.constData(), (void *)this, UseCapture, &mouse_cb); + emscripten_set_mouseleave_callback(canvasSelector.constData(), (void *)this, UseCapture, &mouse_cb); - emscripten_set_wheel_callback(canvasSelector.constData(), (void *)this, 1, &wheel_cb); + emscripten_set_focus_callback(canvasSelector.constData(), (void *)this, UseCapture, &focus_cb); - emscripten_set_touchstart_callback(canvasSelector.constData(), (void *)this, 1, &touchCallback); - emscripten_set_touchend_callback(canvasSelector.constData(), (void *)this, 1, &touchCallback); - emscripten_set_touchmove_callback(canvasSelector.constData(), (void *)this, 1, &touchCallback); - emscripten_set_touchcancel_callback(canvasSelector.constData(), (void *)this, 1, &touchCallback); + emscripten_set_wheel_callback(canvasSelector.constData(), (void *)this, UseCapture, &wheel_cb); + + emscripten_set_touchstart_callback(canvasSelector.constData(), (void *)this, UseCapture, &touchCallback); + emscripten_set_touchend_callback(canvasSelector.constData(), (void *)this, UseCapture, &touchCallback); + emscripten_set_touchmove_callback(canvasSelector.constData(), (void *)this, UseCapture, &touchCallback); + emscripten_set_touchcancel_callback(canvasSelector.constData(), (void *)this, UseCapture, &touchCallback); val canvas = screen()->canvas(); canvas.call("addEventListener", @@ -208,9 +206,9 @@ void QWasmCompositor::removeWindow(QWasmWindow *window) m_requestUpdateWindows.remove(window); if (!m_windowStack.isEmpty() && !QGuiApplication::focusWindow()) { - auto lastWindow = m_windowStack.last(); - lastWindow->requestActivateWindow(); - notifyTopWindowChanged(lastWindow); + auto m_lastMouseTargetWindow = m_windowStack.last(); + m_lastMouseTargetWindow->requestActivateWindow(); + notifyTopWindowChanged(m_lastMouseTargetWindow); } } @@ -268,7 +266,7 @@ int QWasmCompositor::windowCount() const return m_windowStack.count(); } -QWindow *QWasmCompositor::windowAt(QPoint globalPoint, int padding) const +QWindow *QWasmCompositor::windowAt(QPoint targetPointInScreenCoords, int padding) const { int index = m_windowStack.count() - 1; // qDebug() << "window at" << "point" << p << "window count" << index; @@ -280,7 +278,7 @@ QWindow *QWasmCompositor::windowAt(QPoint globalPoint, int padding) const QRect geometry = compositedWindow.window->windowFrameGeometry() .adjusted(-padding, -padding, padding, padding); - if (compositedWindow.visible && geometry.contains(globalPoint)) + if (compositedWindow.visible && geometry.contains(targetPointInScreenCoords)) return m_windowStack.at(index)->window(); --index; } @@ -920,11 +918,11 @@ void QWasmCompositor::resizeWindow(QWindow *window, QWasmCompositor::ResizeMode void QWasmCompositor::notifyTopWindowChanged(QWasmWindow *window) { QWindow *modalWindow; - bool blocked = QGuiApplicationPrivate::instance()->isWindowBlocked(window->window(), &modalWindow); + bool isTargetWindowBlocked = QGuiApplicationPrivate::instance()->isWindowBlocked(window->window(), &modalWindow); - if (blocked) { + if (isTargetWindowBlocked) { modalWindow->requestActivate(); - raise(static_cast(modalWindow->handle())); + raise(AsWasmWindow(modalWindow)); return; } @@ -976,162 +974,146 @@ int QWasmCompositor::touchCallback(int eventType, const EmscriptenTouchEvent *to bool QWasmCompositor::processMouse(int eventType, const EmscriptenMouseEvent *mouseEvent) { - QPoint targetPoint(mouseEvent->targetX, mouseEvent->targetY); - QPoint globalPoint = screen()->geometry().topLeft() + targetPoint; + const Qt::MouseButton button = QWasmEventTranslator::translateMouseButton(mouseEvent->button); + + const QPoint targetPointInCanvasCoords(mouseEvent->targetX, mouseEvent->targetY); + const QPoint targetPointInScreenCoords = screen()->geometry().topLeft() + targetPointInCanvasCoords; QEvent::Type buttonEventType = QEvent::None; - Qt::MouseButton button = Qt::NoButton; - Qt::KeyboardModifiers modifiers = eventTranslator->translateMouseEventModifier(mouseEvent); + Qt::KeyboardModifiers modifiers = m_eventTranslator->translateMouseEventModifier(mouseEvent); - QWindow *window2 = nullptr; - if (resizeMode == QWasmCompositor::ResizeNone) - window2 = screen()->compositor()->windowAt(globalPoint, 5); + QWindow *const targetWindow = ([this, &targetPointInScreenCoords]() -> QWindow * { + auto *targetWindow = + m_resizeMode == QWasmCompositor::ResizeNone ? + screen()->compositor()->windowAt(targetPointInScreenCoords, 5) : nullptr; - if (window2 == nullptr) { - window2 = lastWindow; - } else { - lastWindow = window2; - } + return targetWindow ? targetWindow : m_lastMouseTargetWindow.get(); + })(); + if (targetWindow) + m_lastMouseTargetWindow = targetWindow; - QPoint localPoint = window2->mapFromGlobal(globalPoint); - bool interior = window2->geometry().contains(globalPoint); - bool blocked = QGuiApplicationPrivate::instance()->isWindowBlocked(window2); + const QPoint pointInTargetWindowCoords = targetWindow->mapFromGlobal(targetPointInScreenCoords); + const bool pointerIsWithinTargetWindowBounds = targetWindow->geometry().contains(targetPointInScreenCoords); + const bool isTargetWindowBlocked = QGuiApplicationPrivate::instance()->isWindowBlocked(targetWindow); - if (mouseInCanvas) { - if (windowUnderMouse != window2 && interior) { + if (m_mouseInCanvas && m_windowUnderMouse != targetWindow && pointerIsWithinTargetWindowBounds) { // delayed mouse enter - enterWindow(window2, localPoint, globalPoint); - windowUnderMouse = window2; - } + enterWindow(targetWindow, pointInTargetWindowCoords, targetPointInScreenCoords); + m_windowUnderMouse = targetWindow; } - QWasmWindow *htmlWindow = static_cast(window2->handle()); - Qt::WindowStates windowState = htmlWindow->window()->windowState(); - bool isResizable = !(windowState.testFlag(Qt::WindowMaximized) || - windowState.testFlag(Qt::WindowFullScreen)); + QWasmWindow *wasmTargetWindow = AsWasmWindow(targetWindow); + Qt::WindowStates windowState = targetWindow->windowState(); + const bool isTargetWindowResizable = !windowState.testFlag(Qt::WindowMaximized) && !windowState.testFlag(Qt::WindowFullScreen); switch (eventType) { case EMSCRIPTEN_EVENT_MOUSEDOWN: { - button = QWasmEventTranslator::translateMouseButton(mouseEvent->button); - - if (window2) - window2->requestActivate(); - - pressedButtons.setFlag(button); - - pressedWindow = window2; buttonEventType = QEvent::MouseButtonPress; + m_pressedButtons.setFlag(button); - // button overview: - // 0 = primary mouse button, usually left click - // 1 = middle mouse button, usually mouse wheel - // 2 = right mouse button, usually right click - // from: https://w3c.github.io/uievents/#dom-mouseevent-button - if (mouseEvent->button == 0) { - if (!blocked && !(htmlWindow->m_windowState & Qt::WindowFullScreen) - && !(htmlWindow->m_windowState & Qt::WindowMaximized)) { - if (htmlWindow && window2->flags().testFlag(Qt::WindowTitleHint) - && htmlWindow->isPointOnTitle(globalPoint)) - draggedWindow = window2; - else if (htmlWindow && htmlWindow->isPointOnResizeRegion(globalPoint)) { - draggedWindow = window2; - resizeMode = htmlWindow->resizeModeAtPoint(globalPoint); - resizePoint = globalPoint; - resizeStartRect = window2->geometry(); - } + if (targetWindow) + targetWindow->requestActivate(); + + m_pressedWindow = targetWindow; + + if (isTargetWindowResizable && button == Qt::MouseButton::LeftButton && !isTargetWindowBlocked) { + if (wasmTargetWindow->isPointOnTitle(targetPointInScreenCoords)) { + m_windowBeingManipulated = targetWindow; + } else if (wasmTargetWindow->isPointOnResizeRegion(targetPointInScreenCoords)) { + m_windowBeingManipulated = targetWindow; + m_resizeMode = wasmTargetWindow->resizeModeAtPoint(targetPointInScreenCoords); + m_resizePoint = targetPointInScreenCoords; + m_resizeStartRect = targetWindow->geometry(); } } - htmlWindow->injectMousePressed(localPoint, globalPoint, button, modifiers); + wasmTargetWindow->injectMousePressed(pointInTargetWindowCoords, targetPointInScreenCoords, button, modifiers); break; } case EMSCRIPTEN_EVENT_MOUSEUP: { - button = QWasmEventTranslator::translateMouseButton(mouseEvent->button); - pressedButtons.setFlag(button, false); buttonEventType = QEvent::MouseButtonRelease; - QWasmWindow *oldWindow = nullptr; - if (mouseEvent->button == 0 && pressedWindow) { - oldWindow = static_cast(pressedWindow->handle()); - pressedWindow = nullptr; + m_pressedButtons.setFlag(button, false); + + if (m_windowBeingManipulated && m_pressedButtons.testFlag(Qt::NoButton)) { + m_windowBeingManipulated = nullptr; + m_resizeMode = QWasmCompositor::ResizeNone; } - if (draggedWindow && pressedButtons.testFlag(Qt::NoButton)) { - draggedWindow = nullptr; - resizeMode = QWasmCompositor::ResizeNone; + if (m_pressedWindow) { + // Always deliver the released event to the same window that was pressed + AsWasmWindow(m_pressedWindow)->injectMouseReleased(pointInTargetWindowCoords, targetPointInScreenCoords, button, modifiers); + if (button == Qt::MouseButton::LeftButton) + m_pressedWindow = nullptr; + } else { + wasmTargetWindow->injectMouseReleased(pointInTargetWindowCoords, targetPointInScreenCoords, button, modifiers); } - - if (oldWindow) - oldWindow->injectMouseReleased(localPoint, globalPoint, button, modifiers); - else - htmlWindow->injectMouseReleased(localPoint, globalPoint, button, modifiers); break; } - case EMSCRIPTEN_EVENT_MOUSEMOVE: // drag event + case EMSCRIPTEN_EVENT_MOUSEMOVE: { buttonEventType = QEvent::MouseMove; - if (htmlWindow && pressedButtons.testFlag(Qt::NoButton)) { + if (wasmTargetWindow && m_pressedButtons.testFlag(Qt::NoButton)) { + const bool isOnResizeRegion = wasmTargetWindow->isPointOnResizeRegion(targetPointInScreenCoords); - bool isOnResizeRegion = htmlWindow->isPointOnResizeRegion(globalPoint); + if (isTargetWindowResizable && isOnResizeRegion && !isTargetWindowBlocked) { + const QCursor resizingCursor = QWasmEventTranslator::cursorForMode( + wasmTargetWindow->resizeModeAtPoint(targetPointInScreenCoords)); - if (isResizable && isOnResizeRegion && !blocked) { - QCursor resizingCursor = eventTranslator->cursorForMode(htmlWindow->resizeModeAtPoint(globalPoint)); - - if (resizingCursor != window2->cursor()) { - isCursorOverridden = true; - QWasmCursor::setOverrideWasmCursor(&resizingCursor, window2->screen()); - } - } else { // off resizing area - if (isCursorOverridden) { - isCursorOverridden = false; - QWasmCursor::clearOverrideWasmCursor(window2->screen()); + if (resizingCursor != targetWindow->cursor()) { + m_isResizeCursorDisplayed = true; + QWasmCursor::setOverrideWasmCursor(resizingCursor, targetWindow->screen()); } + } else if (m_isResizeCursorDisplayed) { // off resizing area + m_isResizeCursorDisplayed = false; + QWasmCursor::clearOverrideWasmCursor(targetWindow->screen()); } } - if (!(htmlWindow->m_windowState & Qt::WindowFullScreen) && !(htmlWindow->m_windowState & Qt::WindowMaximized)) { - if (resizeMode == QWasmCompositor::ResizeNone && draggedWindow) { - draggedWindow->setX(draggedWindow->x() + mouseEvent->movementX); - draggedWindow->setY(draggedWindow->y() + mouseEvent->movementY); - } - - if (resizeMode != QWasmCompositor::ResizeNone && !(htmlWindow->m_windowState & Qt::WindowFullScreen)) { - QPoint delta = QPoint(mouseEvent->targetX, mouseEvent->targetY) - resizePoint; - resizeWindow(draggedWindow, resizeMode, resizeStartRect, delta); + if (m_windowBeingManipulated && isTargetWindowResizable) { + if (m_resizeMode == QWasmCompositor::ResizeNone) { + m_windowBeingManipulated->setPosition( + m_windowBeingManipulated->position() + QPoint(mouseEvent->movementX, mouseEvent->movementY)); + } else { + const QPoint delta = targetPointInCanvasCoords - m_resizePoint; + resizeWindow(m_windowBeingManipulated, m_resizeMode, m_resizeStartRect, delta); } } break; } - case EMSCRIPTEN_EVENT_MOUSEENTER: - processMouseEnter(mouseEvent); + case EMSCRIPTEN_EVENT_MOUSEENTER: + processMouseEnter(mouseEvent); break; - case EMSCRIPTEN_EVENT_MOUSELEAVE: - processMouseLeave(); + case EMSCRIPTEN_EVENT_MOUSELEAVE: + processMouseLeave(); + break; + default: break; - default: break; }; - if (!interior && pressedButtons.testFlag(Qt::NoButton)) { - leaveWindow(lastWindow); + if (!pointerIsWithinTargetWindowBounds && m_pressedButtons.testFlag(Qt::NoButton)) { + leaveWindow(m_lastMouseTargetWindow); } - if (!window2 && buttonEventType == QEvent::MouseButtonRelease) { - window2 = lastWindow; - lastWindow = nullptr; - interior = true; - } - bool accepted = false; - if (window2 && interior) { - accepted = QWindowSystemInterface::handleMouseEvent( - window2, QWasmIntegration::getTimestamp(), localPoint, globalPoint, pressedButtons, button, buttonEventType, modifiers); + bool shouldDeliverEvent = pointerIsWithinTargetWindowBounds; + QWindow *eventTarget = targetWindow; + if (!eventTarget && buttonEventType == QEvent::MouseButtonRelease) { + eventTarget = m_lastMouseTargetWindow; + m_lastMouseTargetWindow = nullptr; + shouldDeliverEvent = true; } + const bool eventAccepted = + eventTarget != nullptr && shouldDeliverEvent && + QWindowSystemInterface::handleMouseEvent( + eventTarget, QWasmIntegration::getTimestamp(), pointInTargetWindowCoords, targetPointInScreenCoords, + m_pressedButtons, button, buttonEventType, modifiers); - if (eventType == EMSCRIPTEN_EVENT_MOUSEDOWN && !accepted) + if (!eventAccepted && buttonEventType == QEvent::MouseButtonPress) QGuiApplicationPrivate::instance()->closeAllPopups(); - return accepted; + return eventAccepted; } bool QWasmCompositor::processKeyboard(int eventType, const EmscriptenKeyboardEvent *keyEvent) @@ -1143,12 +1125,12 @@ bool QWasmCompositor::processKeyboard(int eventType, const EmscriptenKeyboardEve case EMSCRIPTEN_EVENT_KEYPRESS: case EMSCRIPTEN_EVENT_KEYDOWN: // down keyType = QEvent::KeyPress; - qtKey = this->eventTranslator->getKey(keyEvent); - keyText = this->eventTranslator->getKeyText(keyEvent, qtKey); + qtKey = m_eventTranslator->getKey(keyEvent); + keyText = m_eventTranslator->getKeyText(keyEvent, qtKey); break; case EMSCRIPTEN_EVENT_KEYUP: // up keyType = QEvent::KeyRelease; - this->eventTranslator->setStickyDeadKey(keyEvent); + m_eventTranslator->setStickyDeadKey(keyEvent); break; default: break; @@ -1157,7 +1139,7 @@ bool QWasmCompositor::processKeyboard(int eventType, const EmscriptenKeyboardEve if (keyType == QEvent::None) return 0; - QFlags modifiers = eventTranslator->translateKeyboardEventModifier(keyEvent); + QFlags modifiers = m_eventTranslator->translateKeyboardEventModifier(keyEvent); // Clipboard fallback path: cut/copy/paste are handled by clipboard event // handlers if direct clipboard access is not available. @@ -1215,14 +1197,14 @@ bool QWasmCompositor::processWheel(int eventType, const EmscriptenWheelEvent *wh scrollFactor = -scrollFactor; // Web scroll deltas are inverted from Qt deltas. - Qt::KeyboardModifiers modifiers = eventTranslator->translateMouseEventModifier(&mouseEvent); - QPoint targetPoint(mouseEvent.targetX, mouseEvent.targetY); - QPoint globalPoint = screen()->geometry().topLeft() + targetPoint; + Qt::KeyboardModifiers modifiers = m_eventTranslator->translateMouseEventModifier(&mouseEvent); + QPoint targetPointInCanvasCoords(mouseEvent.targetX, mouseEvent.targetY); + QPoint targetPointInScreenCoords = screen()->geometry().topLeft() + targetPointInCanvasCoords; - QWindow *window2 = screen()->compositor()->windowAt(globalPoint, 5); - if (!window2) + QWindow *targetWindow = screen()->compositor()->windowAt(targetPointInScreenCoords, 5); + if (!targetWindow) return 0; - QPoint localPoint = window2->mapFromGlobal(globalPoint); + QPoint pointInTargetWindowCoords = targetWindow->mapFromGlobal(targetPointInScreenCoords); QPoint pixelDelta; @@ -1232,8 +1214,8 @@ bool QWasmCompositor::processWheel(int eventType, const EmscriptenWheelEvent *wh QPoint angleDelta = pixelDelta; // FIXME: convert from pixels? bool accepted = QWindowSystemInterface::handleWheelEvent( - window2, QWasmIntegration::getTimestamp(), localPoint, - globalPoint, pixelDelta, angleDelta, modifiers, + targetWindow, QWasmIntegration::getTimestamp(), pointInTargetWindowCoords, + targetPointInScreenCoords, pixelDelta, angleDelta, modifiers, Qt::NoScrollPhase, Qt::MouseEventNotSynthesized, g_scrollingInvertedFromDevice); return accepted; @@ -1243,17 +1225,17 @@ int QWasmCompositor::handleTouch(int eventType, const EmscriptenTouchEvent *touc { QList touchPointList; touchPointList.reserve(touchEvent->numTouches); - QWindow *window2; + QWindow *targetWindow; for (int i = 0; i < touchEvent->numTouches; i++) { const EmscriptenTouchPoint *touches = &touchEvent->touches[i]; - QPoint targetPoint(touches->targetX, touches->targetY); - QPoint globalPoint = screen()->geometry().topLeft() + targetPoint; + QPoint targetPointInCanvasCoords(touches->targetX, touches->targetY); + QPoint targetPointInScreenCoords = screen()->geometry().topLeft() + targetPointInCanvasCoords; - window2 = this->screen()->compositor()->windowAt(globalPoint, 5); - if (window2 == nullptr) + targetWindow = screen()->compositor()->windowAt(targetPointInScreenCoords, 5); + if (targetWindow == nullptr) continue; QWindowSystemInterface::TouchPoint touchPoint; @@ -1262,41 +1244,41 @@ int QWasmCompositor::handleTouch(int eventType, const EmscriptenTouchEvent *touc touchPoint.id = touches->identifier; touchPoint.pressure = 1.0; - touchPoint.area.moveCenter(globalPoint); + touchPoint.area.moveCenter(targetPointInScreenCoords); - const auto tp = pressedTouchIds.constFind(touchPoint.id); - if (tp != pressedTouchIds.constEnd()) + const auto tp = m_pressedTouchIds.constFind(touchPoint.id); + if (tp != m_pressedTouchIds.constEnd()) touchPoint.normalPosition = tp.value(); - QPointF localPoint = QPointF(window2->mapFromGlobal(globalPoint)); - QPointF normalPosition(localPoint.x() / window2->width(), - localPoint.y() / window2->height()); + QPointF pointInTargetWindowCoords = QPointF(targetWindow->mapFromGlobal(targetPointInScreenCoords)); + QPointF normalPosition(pointInTargetWindowCoords.x() / targetWindow->width(), + pointInTargetWindowCoords.y() / targetWindow->height()); const bool stationaryTouchPoint = (normalPosition == touchPoint.normalPosition); touchPoint.normalPosition = normalPosition; switch (eventType) { case EMSCRIPTEN_EVENT_TOUCHSTART: - if (tp != pressedTouchIds.constEnd()) { + if (tp != m_pressedTouchIds.constEnd()) { touchPoint.state = (stationaryTouchPoint ? QEventPoint::State::Stationary : QEventPoint::State::Updated); } else { touchPoint.state = QEventPoint::State::Pressed; } - pressedTouchIds.insert(touchPoint.id, touchPoint.normalPosition); + m_pressedTouchIds.insert(touchPoint.id, touchPoint.normalPosition); break; case EMSCRIPTEN_EVENT_TOUCHEND: touchPoint.state = QEventPoint::State::Released; - pressedTouchIds.remove(touchPoint.id); + m_pressedTouchIds.remove(touchPoint.id); break; case EMSCRIPTEN_EVENT_TOUCHMOVE: touchPoint.state = (stationaryTouchPoint ? QEventPoint::State::Stationary : QEventPoint::State::Updated); - pressedTouchIds.insert(touchPoint.id, touchPoint.normalPosition); + m_pressedTouchIds.insert(touchPoint.id, touchPoint.normalPosition); break; default: break; @@ -1305,40 +1287,40 @@ int QWasmCompositor::handleTouch(int eventType, const EmscriptenTouchEvent *touc touchPointList.append(touchPoint); } - QFlags keyModifier = eventTranslator->translateTouchEventModifier(touchEvent); + QFlags keyModifier = m_eventTranslator->translateTouchEventModifier(touchEvent); bool accepted = false; if (eventType == EMSCRIPTEN_EVENT_TOUCHCANCEL) - accepted = QWindowSystemInterface::handleTouchCancelEvent(window2, QWasmIntegration::getTimestamp(), touchDevice, keyModifier); + accepted = QWindowSystemInterface::handleTouchCancelEvent(targetWindow, QWasmIntegration::getTimestamp(), m_touchDevice.get(), keyModifier); else accepted = QWindowSystemInterface::handleTouchEvent( - window2, QWasmIntegration::getTimestamp(), touchDevice, touchPointList, keyModifier); + targetWindow, QWasmIntegration::getTimestamp(), m_touchDevice.get(), touchPointList, keyModifier); return static_cast(accepted); } void QWasmCompositor::leaveWindow(QWindow *window) { - windowUnderMouse = nullptr; + m_windowUnderMouse = nullptr; QWindowSystemInterface::handleLeaveEvent(window); } -void QWasmCompositor::enterWindow(QWindow *window, const QPoint &localPoint, const QPoint &globalPoint) +void QWasmCompositor::enterWindow(QWindow *window, const QPoint &pointInTargetWindowCoords, const QPoint &targetPointInScreenCoords) { - QWindowSystemInterface::handleEnterEvent(window, localPoint, globalPoint); + QWindowSystemInterface::handleEnterEvent(window, pointInTargetWindowCoords, targetPointInScreenCoords); } bool QWasmCompositor::processMouseEnter(const EmscriptenMouseEvent *mouseEvent) { Q_UNUSED(mouseEvent) // mouse has entered the canvas area - mouseInCanvas = true; + m_mouseInCanvas = true; return true; } bool QWasmCompositor::processMouseLeave() { - mouseInCanvas = false; + m_mouseInCanvas = false; return true; } diff --git a/src/plugins/platforms/wasm/qwasmcompositor.h b/src/plugins/platforms/wasm/qwasmcompositor.h index 29a0f022678..8524747a9d7 100644 --- a/src/plugins/platforms/wasm/qwasmcompositor.h +++ b/src/plugins/platforms/wasm/qwasmcompositor.h @@ -146,39 +146,6 @@ private: void blit(QOpenGLTextureBlitter *blitter, QWasmScreen *screen, const QOpenGLTexture *texture, QRect targetGeometry); void drawWindowDecorations(QOpenGLTextureBlitter *blitter, QWasmScreen *screen, QWasmWindow *window); - void drwPanelButton(); - - QScopedPointer m_context; - QScopedPointer m_blitter; - - QHash m_compositedWindows; - QList m_windowStack; - QRegion m_globalDamage; // damage caused by expose, window close, etc. - bool m_needComposit; - bool m_inFlush; - bool m_inResize; - bool m_isEnabled; - QSize m_targetSize; - qreal m_targetDevicePixelRatio; - QMap m_requestUpdateWindows; - bool m_requestUpdateAllWindows = false; - int m_requestAnimationFrameId = -1; - bool m_inDeliverUpdateRequest = false; - - QPointer draggedWindow; - QPointer pressedWindow; - QPointer lastWindow; - Qt::MouseButtons pressedButtons; - - QWasmCompositor::ResizeMode resizeMode; - QPoint resizePoint; - QRect resizeStartRect; - QPointingDevice *touchDevice; - - QMap pressedTouchIds; - - QCursor overriddenCursor; - bool isCursorOverridden = false; static QPalette makeWindowPalette(); @@ -195,10 +162,41 @@ private: static int touchCallback(int eventType, const EmscriptenTouchEvent *ev, void *userData); - QWasmEventTranslator *eventTranslator; + QScopedPointer m_context; + QScopedPointer m_blitter; - bool mouseInCanvas; - QPointer windowUnderMouse; + QHash m_compositedWindows; + QList m_windowStack; + QRegion m_globalDamage; // damage caused by expose, window close, etc. + bool m_needComposit = false; + bool m_inFlush = false; + bool m_inResize = false; + bool m_isEnabled = true; + QSize m_targetSize; + qreal m_targetDevicePixelRatio = 1; + QMap m_requestUpdateWindows; + bool m_requestUpdateAllWindows = false; + int m_requestAnimationFrameId = -1; + bool m_inDeliverUpdateRequest = false; + + QPointer m_windowBeingManipulated; + QPointer m_pressedWindow; + QPointer m_lastMouseTargetWindow; + Qt::MouseButtons m_pressedButtons = Qt::NoButton; + + ResizeMode m_resizeMode = ResizeNone; + QPoint m_resizePoint; + QRect m_resizeStartRect; + std::unique_ptr m_touchDevice; + + QMap m_pressedTouchIds; + + bool m_isResizeCursorDisplayed = false; + + std::unique_ptr m_eventTranslator; + + bool m_mouseInCanvas = false; + QPointer m_windowUnderMouse; }; Q_DECLARE_OPERATORS_FOR_FLAGS(QWasmCompositor::SubControls) diff --git a/src/plugins/platforms/wasm/qwasmcursor.cpp b/src/plugins/platforms/wasm/qwasmcursor.cpp index f1f5e77bcb0..f954e005ce1 100644 --- a/src/plugins/platforms/wasm/qwasmcursor.cpp +++ b/src/plugins/platforms/wasm/qwasmcursor.cpp @@ -123,10 +123,10 @@ void QWasmCursor::setWasmCursor(QScreen *screen, const QByteArray &name) canvasStyle.set("cursor", val(name.constData())); } -void QWasmCursor::setOverrideWasmCursor(QCursor *windowCursor, QScreen *screen) +void QWasmCursor::setOverrideWasmCursor(const QCursor &windowCursor, QScreen *screen) { QWasmCursor *wCursor = static_cast(QWasmScreen::get(screen)->cursor()); - wCursor->setWasmCursor(screen, wCursor->cursorShapeToHtml(windowCursor->shape())); + wCursor->setWasmCursor(screen, wCursor->cursorShapeToHtml(windowCursor.shape())); } void QWasmCursor::clearOverrideWasmCursor(QScreen *screen) diff --git a/src/plugins/platforms/wasm/qwasmcursor.h b/src/plugins/platforms/wasm/qwasmcursor.h index 17ddd344b1b..4a5cb23bf4d 100644 --- a/src/plugins/platforms/wasm/qwasmcursor.h +++ b/src/plugins/platforms/wasm/qwasmcursor.h @@ -13,7 +13,7 @@ public: void changeCursor(QCursor *windowCursor, QWindow *window) override; QByteArray cursorShapeToHtml(Qt::CursorShape shape); - static void setOverrideWasmCursor(QCursor *windowCursor, QScreen *screen); + static void setOverrideWasmCursor(const QCursor &windowCursor, QScreen *screen); static void clearOverrideWasmCursor(QScreen *screen); private: QByteArray htmlCursorName = "default"; diff --git a/src/plugins/platforms/wasm/qwasmeventtranslator.cpp b/src/plugins/platforms/wasm/qwasmeventtranslator.cpp index 8f9050ba5da..6f13009aef0 100644 --- a/src/plugins/platforms/wasm/qwasmeventtranslator.cpp +++ b/src/plugins/platforms/wasm/qwasmeventtranslator.cpp @@ -238,18 +238,6 @@ Qt::Key QWasmEventTranslator::translateEmscriptKey(const EmscriptenKeyboardEvent return qtKey; } -Qt::MouseButton QWasmEventTranslator::translateMouseButton(unsigned short button) -{ - if (button == 0) - return Qt::LeftButton; - else if (button == 1) - return Qt::MiddleButton; - else if (button == 2) - return Qt::RightButton; - - return Qt::NoButton; -} - struct KeyMapping { Qt::Key from, to; }; constexpr KeyMapping tildeKeyTable[] = { // ~ diff --git a/src/plugins/platforms/wasm/qwasmeventtranslator.h b/src/plugins/platforms/wasm/qwasmeventtranslator.h index d098c10b77b..d86ddf76253 100644 --- a/src/plugins/platforms/wasm/qwasmeventtranslator.h +++ b/src/plugins/platforms/wasm/qwasmeventtranslator.h @@ -33,7 +33,18 @@ public: QFlags translateKeyboardEventModifier(const EmscriptenKeyboardEvent *keyEvent); QFlags translateMouseEventModifier(const EmscriptenMouseEvent *mouseEvent); QFlags translateTouchEventModifier(const EmscriptenTouchEvent *touchEvent); - static Qt::MouseButton translateMouseButton(unsigned short button); + static constexpr Qt::MouseButton translateMouseButton(unsigned short button) { + switch (button) { + case 0: + return Qt::LeftButton; + case 1: + return Qt::MiddleButton; + case 2: + return Qt::RightButton; + default: + return Qt::NoButton; + } + } static QCursor cursorForMode(QWasmCompositor::ResizeMode mode); QString getKeyText(const EmscriptenKeyboardEvent *keyEvent, Qt::Key key); diff --git a/src/plugins/platforms/wasm/qwasmwindow.cpp b/src/plugins/platforms/wasm/qwasmwindow.cpp index 4206ede1bbd..9f63f4bccf6 100644 --- a/src/plugins/platforms/wasm/qwasmwindow.cpp +++ b/src/plugins/platforms/wasm/qwasmwindow.cpp @@ -229,8 +229,7 @@ QRegion QWasmWindow::resizeRegion() const bool QWasmWindow::isPointOnTitle(QPoint point) const { - bool ok = titleGeometry().contains(point); - return ok; + return hasTitleBar() ? titleGeometry().contains(point) : false; } bool QWasmWindow::isPointOnResizeRegion(QPoint point) const