From dd4275430b830309ae4a341605c1599e81dcf055 Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Thu, 2 Nov 2017 17:48:37 -0700 Subject: [PATCH] fix hover events, working on HUD events --- interface/src/Application.cpp | 36 ++++++++++ interface/src/Application.h | 2 + .../src/raypick/PointerScriptingInterface.h | 2 +- interface/src/ui/overlays/Web3DOverlay.cpp | 27 +++---- .../src/RenderableWebEntityItem.cpp | 10 +-- .../src/pointers/PickCacheOptimizer.h | 9 +-- libraries/pointers/src/pointers/Pointer.cpp | 70 +++++++++++++------ libraries/pointers/src/pointers/Pointer.h | 2 + libraries/shared/src/PointerEvent.h | 9 ++- libraries/ui/CMakeLists.txt | 3 +- libraries/ui/src/ui/OffscreenQmlSurface.cpp | 59 +++------------- libraries/ui/src/ui/OffscreenQmlSurface.h | 5 -- 12 files changed, 129 insertions(+), 105 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 3a1f970438..d81332e7d5 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1504,6 +1504,14 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo setKeyboardFocusEntity(UNKNOWN_ENTITY_ID); }); + auto pointerManager = DependencyManager::get(); + connect(pointerManager.data(), &PointerManager::hoverBeginHUD, this, &Application::handleHUDPointerEvent); + connect(pointerManager.data(), &PointerManager::hoverContinueHUD, this, &Application::handleHUDPointerEvent); + connect(pointerManager.data(), &PointerManager::hoverEndHUD, this, &Application::handleHUDPointerEvent); + connect(pointerManager.data(), &PointerManager::triggerBeginHUD, this, &Application::handleHUDPointerEvent); + connect(pointerManager.data(), &PointerManager::triggerContinueHUD, this, &Application::handleHUDPointerEvent); + connect(pointerManager.data(), &PointerManager::triggerEndHUD, this, &Application::handleHUDPointerEvent); + // Add periodic checks to send user activity data static int CHECK_NEARBY_AVATARS_INTERVAL_MS = 10000; static int NEARBY_AVATAR_RADIUS_METERS = 10; @@ -7479,4 +7487,32 @@ void Application::setAvatarOverrideUrl(const QUrl& url, bool save) { _avatarOverrideUrl = url; _saveAvatarOverrideUrl = save; } + +void Application::handleHUDPointerEvent(const QUuid& id, const PointerEvent& event) { + QEvent::Type type = QEvent::Type::MouseMove; + switch (event.getType()) { + case PointerEvent::Press: + type = QEvent::Type::MouseButtonPress; + break; + case PointerEvent::DoublePress: + type = QEvent::Type::MouseButtonDblClick; + break; + case PointerEvent::Release: + type = QEvent::Type::MouseButtonRelease; + break; + case PointerEvent::Move: + type = QEvent::Type::MouseMove; + break; + default: + break; + } + + QPointF screenPos(event.getPos2D().x, event.getPos2D().y); + //QMouseEvent mouseEvent(type, screenPos, Qt::MouseButton(event.getButton()), Qt::MouseButtons(event.getButtons()), event.getKeyboardModifiers()); + QMouseEvent moveEvent(QEvent::Type::MouseMove, screenPos, Qt::LeftButton, Qt::LeftButton, Qt::NoModifier); + sendEvent(_glWidget, &moveEvent); + QMouseEvent mouseEvent(type, screenPos, Qt::LeftButton, Qt::LeftButton, Qt::NoModifier); + sendEvent(_glWidget, &mouseEvent); +} + #include "Application.moc" diff --git a/interface/src/Application.h b/interface/src/Application.h index d2a55db216..a229c4b91a 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -434,6 +434,8 @@ private slots: void handleSandboxStatus(QNetworkReply* reply); void switchDisplayMode(); + + void handleHUDPointerEvent(const QUuid& id, const PointerEvent& event); private: static void initDisplay(); void init(); diff --git a/interface/src/raypick/PointerScriptingInterface.h b/interface/src/raypick/PointerScriptingInterface.h index 722ba8cec5..8ea9594fda 100644 --- a/interface/src/raypick/PointerScriptingInterface.h +++ b/interface/src/raypick/PointerScriptingInterface.h @@ -35,7 +35,7 @@ public slots: Q_INVOKABLE void setIgnoreItems(unsigned int uid, const QScriptValue& ignoreEntities) const; Q_INVOKABLE void setIncludeItems(unsigned int uid, const QScriptValue& includeEntities) const; - Q_INVOKABLE void setLockEndUid(unsigned int uid, const QUuid& objectID, bool isOverlay) const { DependencyManager::get()->setLockEndUUID(uid, objectID, isOverlay); } + Q_INVOKABLE void setLockEndUUID(unsigned int uid, const QUuid& objectID, bool isOverlay) const { DependencyManager::get()->setLockEndUUID(uid, objectID, isOverlay); } signals: void triggerBegin(const QUuid& id, const PointerEvent& pointerEvent); diff --git a/interface/src/ui/overlays/Web3DOverlay.cpp b/interface/src/ui/overlays/Web3DOverlay.cpp index 5339deba2b..b8683b43e3 100644 --- a/interface/src/ui/overlays/Web3DOverlay.cpp +++ b/interface/src/ui/overlays/Web3DOverlay.cpp @@ -160,14 +160,6 @@ void Web3DOverlay::buildWebSurface() { QObject::connect(_webSurface.data(), &OffscreenQmlSurface::webEventReceived, this, &Web3DOverlay::webEventReceived); } -void Web3DOverlay::hoverLeaveOverlay(const PointerEvent& event) { - if ((_pressed || (!_activeTouchPoints.empty() && _touchBeginAccepted))) { - PointerEvent endEvent(PointerEvent::Release, event.getID(), event.getPos2D(), event.getPos3D(), event.getNormal(), event.getDirection(), - event.getButton(), event.getButtons(), event.getKeyboardModifiers()); - handlePointerEvent(endEvent); - } -} - void Web3DOverlay::update(float deltatime) { if (_webSurface) { // update globalPosition @@ -348,6 +340,17 @@ void Web3DOverlay::setProxyWindow(QWindow* proxyWindow) { _webSurface->setProxyWindow(proxyWindow); } +void Web3DOverlay::hoverLeaveOverlay(const PointerEvent& event) { + if ((_pressed || (!_activeTouchPoints.empty() && _touchBeginAccepted)) && event.sendReleaseOnHoverLeave()) { + PointerEvent endEvent(PointerEvent::Release, event.getID(), event.getPos2D(), event.getPos3D(), event.getNormal(), event.getDirection(), + event.getButton(), event.getButtons(), event.getKeyboardModifiers()); + handlePointerEvent(endEvent); + // QML onReleased is only triggered if a click has happened first. We need to send this "fake" mouse move event to properly trigger an onExited. + PointerEvent endMoveEvent(PointerEvent::Move, event.getID()); + handlePointerEvent(endMoveEvent); + } +} + void Web3DOverlay::handlePointerEvent(const PointerEvent& event) { if (event.getType() == PointerEvent::Press) { _pressed = true; @@ -386,7 +389,7 @@ void Web3DOverlay::handlePointerEventAsTouch(const PointerEvent& event) { } if (state == Qt::TouchPointReleased && _activeTouchPoints.size() == 1 && _activeTouchPoints.count(event.getID())) { // If the last active touch point is being released, send an end touchType = QEvent::TouchEnd; - } + } { QTouchEvent::TouchPoint point; @@ -428,7 +431,7 @@ void Web3DOverlay::handlePointerEventAsTouch(const PointerEvent& event) { #if QT_VERSION >= QT_VERSION_CHECK(5, 9, 0) if (event.getType() == PointerEvent::Move) { - QMouseEvent mouseEvent(QEvent::MouseMove, windowPoint, windowPoint, windowPoint, button, buttons, Qt::NoModifier); + QMouseEvent mouseEvent(QEvent::MouseMove, windowPoint, windowPoint, windowPoint, button, buttons, event.getKeyboardModifiers()); QCoreApplication::sendEvent(_webSurface->getWindow(), &mouseEvent); } #endif @@ -446,7 +449,7 @@ void Web3DOverlay::handlePointerEventAsTouch(const PointerEvent& event) { #if QT_VERSION < QT_VERSION_CHECK(5, 9, 0) if (event.getType() == PointerEvent::Move) { - QMouseEvent mouseEvent(QEvent::MouseMove, windowPoint, windowPoint, windowPoint, button, buttons, Qt::NoModifier); + QMouseEvent mouseEvent(QEvent::MouseMove, windowPoint, windowPoint, windowPoint, button, buttons, event.getKeyboardModifiers()); QCoreApplication::sendEvent(_webSurface->getWindow(), &mouseEvent); } #endif @@ -485,7 +488,7 @@ void Web3DOverlay::handlePointerEventAsMouse(const PointerEvent& event) { return; } - QMouseEvent mouseEvent(type, windowPoint, windowPoint, windowPoint, button, buttons, Qt::NoModifier); + QMouseEvent mouseEvent(type, windowPoint, windowPoint, windowPoint, button, buttons, event.getKeyboardModifiers()); QCoreApplication::sendEvent(_webSurface->getWindow(), &mouseEvent); } diff --git a/libraries/entities-renderer/src/RenderableWebEntityItem.cpp b/libraries/entities-renderer/src/RenderableWebEntityItem.cpp index ad4230c55b..cdeba865ba 100644 --- a/libraries/entities-renderer/src/RenderableWebEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableWebEntityItem.cpp @@ -315,11 +315,13 @@ void WebEntityRenderer::loadSourceURL() { } void WebEntityRenderer::hoverLeaveEntity(const PointerEvent& event) { - if (!_lastLocked && _webSurface && _pressed) { - // If the user mouses off the entity while the button is down, simulate a touch end. + if (!_lastLocked && _webSurface && _pressed && event.sendReleaseOnHoverLeave()) { PointerEvent endEvent(PointerEvent::Release, event.getID(), event.getPos2D(), event.getPos3D(), event.getNormal(), event.getDirection(), event.getButton(), event.getButtons(), event.getKeyboardModifiers()); handlePointerEvent(endEvent); + // QML onReleased is only triggered if a click has happened first. We need to send this "fake" mouse move event to properly trigger an onExited. + PointerEvent endMoveEvent(PointerEvent::Move, event.getID()); + handlePointerEvent(endMoveEvent); } } @@ -396,7 +398,7 @@ void WebEntityRenderer::handlePointerEvent(const PointerEvent& event) { #if QT_VERSION >= QT_VERSION_CHECK(5, 9, 0) if (event.getType() == PointerEvent::Move) { - QMouseEvent mouseEvent(QEvent::MouseMove, windowPoint, windowPoint, windowPoint, button, buttons, Qt::NoModifier); + QMouseEvent mouseEvent(QEvent::MouseMove, windowPoint, windowPoint, windowPoint, button, buttons, event.getKeyboardModifiers()); QCoreApplication::sendEvent(_webSurface->getWindow(), &mouseEvent); } #endif @@ -414,7 +416,7 @@ void WebEntityRenderer::handlePointerEvent(const PointerEvent& event) { #if QT_VERSION < QT_VERSION_CHECK(5, 9, 0) if (event.getType() == PointerEvent::Move) { - QMouseEvent mouseEvent(QEvent::MouseMove, windowPoint, windowPoint, windowPoint, button, buttons, Qt::NoModifier); + QMouseEvent mouseEvent(QEvent::MouseMove, windowPoint, windowPoint, windowPoint, button, buttons, event.getKeyboardModifiers()); QCoreApplication::sendEvent(_webSurface->getWindow(), &mouseEvent); } #endif diff --git a/libraries/pointers/src/pointers/PickCacheOptimizer.h b/libraries/pointers/src/pointers/PickCacheOptimizer.h index f3bdbb87b0..18285f3a6f 100644 --- a/libraries/pointers/src/pointers/PickCacheOptimizer.h +++ b/libraries/pointers/src/pointers/PickCacheOptimizer.h @@ -71,18 +71,15 @@ void PickCacheOptimizer::update(QHash> pick = std::static_pointer_cast>(picks[uid]); - if (!pick->isEnabled() || pick->getFilter().doesPickNothing() || pick->getMaxDistance() < 0.0f) { - continue; - } T mathematicalPick = pick->getMathematicalPick(); + PickResultPointer res = pick->getDefaultResult(mathematicalPick.toVariantMap()); - if (!mathematicalPick) { + if (!pick->isEnabled() || pick->getFilter().doesPickNothing() || pick->getMaxDistance() < 0.0f || !mathematicalPick) { + pick->setPickResult(res); continue; } - PickResultPointer res = pick->getDefaultResult(mathematicalPick.toVariantMap()); - if (pick->getFilter().doesPickEntities()) { PickCacheKey entityKey = { pick->getFilter().getEntityFlags(), pick->getIncludeItems(), pick->getIgnoreItems() }; if (!checkAndCompareCachedResults(mathematicalPick, results, res, entityKey)) { diff --git a/libraries/pointers/src/pointers/Pointer.cpp b/libraries/pointers/src/pointers/Pointer.cpp index f57bded5ad..354669a55e 100644 --- a/libraries/pointers/src/pointers/Pointer.cpp +++ b/libraries/pointers/src/pointers/Pointer.cpp @@ -59,14 +59,45 @@ void Pointer::generatePointerEvents(unsigned int pointerID, const QVariantMap& p // TODO: avatars? auto pointerManager = DependencyManager::get(); + // NOTE: After this loop: _prevButtons = buttons that were removed + // If switching to disabled or should stop triggering, release all buttons + Buttons buttons; + Buttons newButtons; + Buttons sameButtons; + const std::string PRIMARY_BUTTON = "Primary"; + bool primaryPressed = false; + if (_enabled && shouldTrigger()) { + buttons = getPressedButtons(); + primaryPressed = buttons.find(PRIMARY_BUTTON) != buttons.end(); + for (const std::string& button : buttons) { + if (_prevButtons.find(button) == _prevButtons.end()) { + newButtons.insert(button); + } else { + sameButtons.insert(button); + _prevButtons.erase(button); + } + } + } + // Hover events + bool doHover = shouldHover(); Pointer::PickedObject hoveredObject = getHoveredObject(pickResult); PointerEvent hoveredEvent = buildPointerEvent(hoveredObject, pickResult); hoveredEvent.setType(PointerEvent::Move); hoveredEvent.setID(pointerID); - // TODO: set buttons on hover events - hoveredEvent.setButton(PointerEvent::NoButtons); - if (_enabled && _hover && shouldHover()) { + bool releaseOnHoverLeave = !primaryPressed || (!_enabled && _prevEnabled) || (!doHover && _prevDoHover); + hoveredEvent.setReleaseOnHoverLeave(releaseOnHoverLeave); + + // if shouldHover && !_prevDoHover, only send hoverBegin + if (_enabled && _hover && doHover && !_prevDoHover) { + if (hoveredObject.type == ENTITY) { + emit pointerManager->hoverBeginEntity(hoveredObject.objectID, hoveredEvent); + } else if (hoveredObject.type == OVERLAY) { + emit pointerManager->hoverBeginOverlay(hoveredObject.objectID, hoveredEvent); + } else if (hoveredObject.type == HUD) { + emit pointerManager->hoverBeginHUD(hoveredObject.objectID, hoveredEvent); + } + } else if (_enabled && _hover && doHover) { if (hoveredObject.type == OVERLAY) { if (_prevHoveredObject.type == OVERLAY) { if (hoveredObject.objectID == _prevHoveredObject.objectID) { @@ -74,6 +105,7 @@ void Pointer::generatePointerEvents(unsigned int pointerID, const QVariantMap& p } else { PointerEvent prevHoveredEvent = buildPointerEvent(_prevHoveredObject, pickResult); prevHoveredEvent.setID(pointerID); + prevHoveredEvent.setReleaseOnHoverLeave(releaseOnHoverLeave); emit pointerManager->hoverEndOverlay(_prevHoveredObject.objectID, prevHoveredEvent); emit pointerManager->hoverBeginOverlay(hoveredObject.objectID, hoveredEvent); } @@ -95,6 +127,7 @@ void Pointer::generatePointerEvents(unsigned int pointerID, const QVariantMap& p } else { PointerEvent prevHoveredEvent = buildPointerEvent(_prevHoveredObject, pickResult); prevHoveredEvent.setID(pointerID); + prevHoveredEvent.setReleaseOnHoverLeave(releaseOnHoverLeave); emit pointerManager->hoverEndEntity(_prevHoveredObject.objectID, prevHoveredEvent); emit pointerManager->hoverBeginEntity(hoveredObject.objectID, hoveredEvent); } @@ -123,20 +156,15 @@ void Pointer::generatePointerEvents(unsigned int pointerID, const QVariantMap& p } } - // Trigger events - Buttons buttons; - Buttons newButtons; - Buttons sameButtons; - // NOTE: After this loop: _prevButtons = buttons that were removed - // If switching to disabled or should stop triggering, release all buttons - if (_enabled && shouldTrigger()) { - buttons = getPressedButtons(); - for (const std::string& button : buttons) { - if (_prevButtons.find(button) == _prevButtons.end()) { - newButtons.insert(button); - } else { - sameButtons.insert(button); - _prevButtons.erase(button); + if (_hover) { + // send hoverEnd events if we disable the pointer, disable hovering, or actually stop hovering over an object + if ((!_enabled && _prevEnabled) || (!doHover && _prevDoHover) || (hoveredObject.type == NONE && _prevHoveredObject.type != NONE)) { + if (_prevHoveredObject.type == ENTITY) { + emit pointerManager->hoverEndEntity(_prevHoveredObject.objectID, hoveredEvent); + } else if (_prevHoveredObject.type == OVERLAY) { + emit pointerManager->hoverEndOverlay(_prevHoveredObject.objectID, hoveredEvent); + } else if (_prevHoveredObject.type == HUD) { + emit pointerManager->hoverEndHUD(_prevHoveredObject.objectID, hoveredEvent); } } } @@ -156,15 +184,13 @@ void Pointer::generatePointerEvents(unsigned int pointerID, const QVariantMap& p } _triggeredObjects[button] = hoveredObject; } - // We still want other trigger events for Focus buttons, but they only set focus on triggerBegin - hoveredEvent.setShouldFocus(false); // Trigger continue for (const std::string& button : sameButtons) { PointerEvent triggeredEvent = buildPointerEvent(_triggeredObjects[button], pickResult); triggeredEvent.setID(pointerID); triggeredEvent.setType(PointerEvent::Move); - hoveredEvent.setButton(chooseButton(button)); + triggeredEvent.setButton(chooseButton(button)); if (_triggeredObjects[button].type == ENTITY) { emit pointerManager->triggerContinueEntity(_triggeredObjects[button].objectID, triggeredEvent); } else if (_triggeredObjects[button].type == OVERLAY) { @@ -179,7 +205,7 @@ void Pointer::generatePointerEvents(unsigned int pointerID, const QVariantMap& p PointerEvent triggeredEvent = buildPointerEvent(_triggeredObjects[button], pickResult); triggeredEvent.setID(pointerID); triggeredEvent.setType(PointerEvent::Release); - hoveredEvent.setButton(chooseButton(button)); + triggeredEvent.setButton(chooseButton(button)); if (_triggeredObjects[button].type == ENTITY) { emit pointerManager->triggerEndEntity(_triggeredObjects[button].objectID, triggeredEvent); } else if (_triggeredObjects[button].type == OVERLAY) { @@ -192,6 +218,8 @@ void Pointer::generatePointerEvents(unsigned int pointerID, const QVariantMap& p _prevHoveredObject = hoveredObject; _prevButtons = buttons; + _prevEnabled = _enabled; + _prevDoHover = doHover; } PointerEvent::Button Pointer::chooseButton(const std::string& button) { diff --git a/libraries/pointers/src/pointers/Pointer.h b/libraries/pointers/src/pointers/Pointer.h index fc43e121f0..d8661436b9 100644 --- a/libraries/pointers/src/pointers/Pointer.h +++ b/libraries/pointers/src/pointers/Pointer.h @@ -89,6 +89,8 @@ protected: private: PickedObject _prevHoveredObject; Buttons _prevButtons; + bool _prevEnabled { false }; + bool _prevDoHover { false }; std::unordered_map _triggeredObjects; PointerEvent::Button chooseButton(const std::string& button); diff --git a/libraries/shared/src/PointerEvent.h b/libraries/shared/src/PointerEvent.h index 239e7c6e4e..f6b1a81602 100644 --- a/libraries/shared/src/PointerEvent.h +++ b/libraries/shared/src/PointerEvent.h @@ -37,9 +37,9 @@ public: PointerEvent(); PointerEvent(EventType type, uint32_t id, - const glm::vec2& pos2D, const glm::vec3& pos3D, - const glm::vec3& normal, const glm::vec3& direction, - Button button, uint32_t buttons = NoButtons, Qt::KeyboardModifiers keyboardModifiers = Qt::KeyboardModifier::NoModifier); + const glm::vec2& pos2D = glm::vec2(NAN), const glm::vec3& pos3D = glm::vec3(NAN), + const glm::vec3& normal = glm::vec3(NAN), const glm::vec3& direction = glm::vec3(NAN), + Button button = NoButtons, uint32_t buttons = NoButtons, Qt::KeyboardModifiers keyboardModifiers = Qt::KeyboardModifier::NoModifier); static QScriptValue toScriptValue(QScriptEngine* engine, const PointerEvent& event); static void fromScriptValue(const QScriptValue& object, PointerEvent& event); @@ -56,11 +56,13 @@ public: uint32_t getButtons() const { return _buttons; } Qt::KeyboardModifiers getKeyboardModifiers() const { return _keyboardModifiers; } bool shouldFocus() const { return _shouldFocus; } + bool sendReleaseOnHoverLeave() const { return _releaseOnHoverLeave; } void setID(uint32_t id) { _id = id; } void setType(EventType type) { _type = type; } void setButton(Button button); void setShouldFocus(bool focus) { _shouldFocus = focus; } + void setReleaseOnHoverLeave(bool releaseOnHoverLeave) { _releaseOnHoverLeave = releaseOnHoverLeave; } private: EventType _type; @@ -75,6 +77,7 @@ private: Qt::KeyboardModifiers _keyboardModifiers; // set of keys held when event was generated bool _shouldFocus { true }; + bool _releaseOnHoverLeave { true }; }; QDebug& operator<<(QDebug& dbg, const PointerEvent& p); diff --git a/libraries/ui/CMakeLists.txt b/libraries/ui/CMakeLists.txt index 334cce97e5..f28157ff97 100644 --- a/libraries/ui/CMakeLists.txt +++ b/libraries/ui/CMakeLists.txt @@ -1,7 +1,6 @@ set(TARGET_NAME ui) setup_hifi_library(OpenGL Network Qml Quick Script WebChannel WebEngine WebSockets XmlPatterns) -link_hifi_libraries(shared networking gl audio pointers) -include_hifi_library_headers(controllers) +link_hifi_libraries(shared networking gl audio) # Required for some low level GL interaction in the OffscreenQMLSurface target_opengl() diff --git a/libraries/ui/src/ui/OffscreenQmlSurface.cpp b/libraries/ui/src/ui/OffscreenQmlSurface.cpp index 204986090c..08662031da 100644 --- a/libraries/ui/src/ui/OffscreenQmlSurface.cpp +++ b/libraries/ui/src/ui/OffscreenQmlSurface.cpp @@ -49,8 +49,6 @@ #include "Logging.h" -#include - Q_LOGGING_CATEGORY(trace_render_qml, "trace.render.qml") Q_LOGGING_CATEGORY(trace_render_qml_gl, "trace.render.qml.gl") Q_LOGGING_CATEGORY(offscreenFocus, "hifi.offscreen.focus") @@ -531,13 +529,6 @@ bool OffscreenQmlSurface::allowNewFrame(uint8_t fps) { } OffscreenQmlSurface::OffscreenQmlSurface() { - auto pointerManager = DependencyManager::get(); - connect(pointerManager.data(), &PointerManager::hoverBeginHUD, this, &OffscreenQmlSurface::handlePointerEvent); - connect(pointerManager.data(), &PointerManager::hoverContinueHUD, this, &OffscreenQmlSurface::handlePointerEvent); - connect(pointerManager.data(), &PointerManager::hoverEndHUD, this, &OffscreenQmlSurface::handlePointerEvent); - connect(pointerManager.data(), &PointerManager::triggerBeginHUD, this, &OffscreenQmlSurface::handlePointerEvent); - connect(pointerManager.data(), &PointerManager::triggerContinueHUD, this, &OffscreenQmlSurface::handlePointerEvent); - connect(pointerManager.data(), &PointerManager::triggerEndHUD, this, &OffscreenQmlSurface::handlePointerEvent); } OffscreenQmlSurface::~OffscreenQmlSurface() { @@ -941,8 +932,14 @@ bool OffscreenQmlSurface::eventFilter(QObject* originalDestination, QEvent* even transformedPos, mouseEvent->screenPos(), mouseEvent->button(), mouseEvent->buttons(), mouseEvent->modifiers()); - if (sendMouseEvent(mappedEvent)) { - return true; + if (event->type() == QEvent::MouseMove) { + // TODO - this line necessary for the QML Tooltop to work (which is not currently being used), but it causes interface to crash on launch on a fresh install + // need to investigate into why this crash is happening. + //_qmlContext->setContextProperty("lastMousePosition", mouseEvent.localPos()); + } + mappedEvent.ignore(); + if (QCoreApplication::sendEvent(_quickWindow, &mappedEvent)) { + return mappedEvent.isAccepted(); } break; } @@ -954,46 +951,6 @@ bool OffscreenQmlSurface::eventFilter(QObject* originalDestination, QEvent* even return false; } -void OffscreenQmlSurface::handlePointerEvent(const QUuid& id, const PointerEvent& event) { - if (_paused) { - return; - } - - QEvent::Type type = QEvent::Type::MouseMove; - switch (event.getType()) { - case PointerEvent::Press: - type = QEvent::Type::MouseButtonPress; - break; - case PointerEvent::DoublePress: - type = QEvent::Type::MouseButtonDblClick; - break; - case PointerEvent::Release: - type = QEvent::Type::MouseButtonRelease; - break; - case PointerEvent::Move: - type = QEvent::Type::MouseMove; - break; - default: - break; - } - QPointF screenPos(event.getPos2D().x, event.getPos2D().y); - QMouseEvent mouseEvent(type, screenPos, Qt::MouseButton(event.getButton()), Qt::MouseButtons(event.getButtons()), event.getKeyboardModifiers()); - sendMouseEvent(mouseEvent); -} - -bool OffscreenQmlSurface::sendMouseEvent(QMouseEvent& mouseEvent) { - if (mouseEvent.type() == QEvent::MouseMove) { - // TODO - this line necessary for the QML Tooltop to work (which is not currently being used), but it causes interface to crash on launch on a fresh install - // need to investigate into why this crash is happening. - //_qmlContext->setContextProperty("lastMousePosition", mouseEvent.localPos()); - } - mouseEvent.ignore(); - if (QCoreApplication::sendEvent(_quickWindow, &mouseEvent)) { - return mouseEvent.isAccepted(); - } - return false; -} - void OffscreenQmlSurface::pause() { _paused = true; } diff --git a/libraries/ui/src/ui/OffscreenQmlSurface.h b/libraries/ui/src/ui/OffscreenQmlSurface.h index 3deab07411..12ee9e59a1 100644 --- a/libraries/ui/src/ui/OffscreenQmlSurface.h +++ b/libraries/ui/src/ui/OffscreenQmlSurface.h @@ -30,8 +30,6 @@ class QQmlContext; class QQmlComponent; class QQuickWindow; class QQuickItem; -class QMouseEvent; -class PointerEvent; // GPU resources are typically buffered for one copy being used by the renderer, // one copy in flight, and one copy being used by the receiver @@ -137,7 +135,6 @@ private: private slots: void updateQuick(); void onFocusObjectChanged(QObject* newFocus); - void handlePointerEvent(const QUuid& id, const PointerEvent& event); private: QQuickWindow* _quickWindow { nullptr }; @@ -164,8 +161,6 @@ private: QWindow* _proxyWindow { nullptr }; QQuickItem* _currentFocusItem { nullptr }; - - bool sendMouseEvent(QMouseEvent& mouseEvent); }; #endif