diff --git a/libraries/gl/src/gl/OffscreenQmlSurface.cpp b/libraries/gl/src/gl/OffscreenQmlSurface.cpp index 1d7824f789..5f86bc13ec 100644 --- a/libraries/gl/src/gl/OffscreenQmlSurface.cpp +++ b/libraries/gl/src/gl/OffscreenQmlSurface.cpp @@ -569,7 +569,7 @@ QPointF OffscreenQmlSurface::mapToVirtualScreen(const QPointF& originalPoint, QO // Event handling customization // -bool OffscreenQmlSurface::eventFilter(QObject* originalDestination, QEvent* event) { +bool OffscreenQmlSurface::filterEnabled(QObject* originalDestination, QEvent* event) const { if (_renderer->_quickWindow == originalDestination) { return false; } @@ -577,7 +577,13 @@ bool OffscreenQmlSurface::eventFilter(QObject* originalDestination, QEvent* even if (_paused) { return false; } + return true; +} +bool OffscreenQmlSurface::eventFilter(QObject* originalDestination, QEvent* event) { + if (!filterEnabled(originalDestination, event)) { + return false; + } #ifdef DEBUG // Don't intercept our own events, or we enter an infinite recursion QObject* recurseTest = originalDestination; diff --git a/libraries/gl/src/gl/OffscreenQmlSurface.h b/libraries/gl/src/gl/OffscreenQmlSurface.h index 3160df1c9d..22a1b99fe6 100644 --- a/libraries/gl/src/gl/OffscreenQmlSurface.h +++ b/libraries/gl/src/gl/OffscreenQmlSurface.h @@ -66,7 +66,7 @@ public: QQmlContext* getRootContext(); QPointF mapToVirtualScreen(const QPointF& originalPoint, QObject* originalWidget); - virtual bool eventFilter(QObject* originalDestination, QEvent* event); + bool eventFilter(QObject* originalDestination, QEvent* event) override; signals: void textureUpdated(unsigned int texture); @@ -76,6 +76,9 @@ public slots: void requestRender(); void onAboutToQuit(); +protected: + bool filterEnabled(QObject* originalDestination, QEvent* event) const; + private: QObject* finishQmlLoad(std::function f); QPointF mapWindowToUi(const QPointF& sourcePosition, QObject* sourceObject); diff --git a/libraries/ui/src/OffscreenUi.cpp b/libraries/ui/src/OffscreenUi.cpp index 269cf86e2d..8cc0522ce5 100644 --- a/libraries/ui/src/OffscreenUi.cpp +++ b/libraries/ui/src/OffscreenUi.cpp @@ -563,5 +563,38 @@ QString OffscreenUi::getSaveFileName(void* ignored, const QString &caption, cons return DependencyManager::get()->fileSaveDialog(caption, dir, filter, selectedFilter, options); } +bool OffscreenUi::eventFilter(QObject* originalDestination, QEvent* event) { + if (!filterEnabled(originalDestination, event)) { + return false; + } + + // let the parent class do it's work + bool result = OffscreenQmlSurface::eventFilter(originalDestination, event); + + // Check if this is a key press/release event that might need special attention + auto type = event->type(); + if (type != QEvent::KeyPress && type != QEvent::KeyRelease) { + return result; + } + + QKeyEvent* keyEvent = dynamic_cast(event); + bool& pressed = _pressedKeys[keyEvent->key()]; + + // Keep track of which key press events the QML has accepted + if (result && QEvent::KeyPress == type) { + pressed = true; + } + + // QML input elements absorb key press, but apparently not key release. + // therefore we want to ensure that key release events for key presses that were + // accepted by the QML layer are suppressed + if (!result && type == QEvent::KeyRelease && pressed) { + pressed = false; + return true; + } + + return result; +} #include "OffscreenUi.moc" + diff --git a/libraries/ui/src/OffscreenUi.h b/libraries/ui/src/OffscreenUi.h index 0188ac5365..f219d0fea8 100644 --- a/libraries/ui/src/OffscreenUi.h +++ b/libraries/ui/src/OffscreenUi.h @@ -12,6 +12,7 @@ #ifndef hifi_OffscreenUi_h #define hifi_OffscreenUi_h +#include #include #include #include @@ -37,6 +38,7 @@ public: void setNavigationFocused(bool focused); void unfocusWindows(); void toggleMenu(const QPoint& screenCoordinates); + bool eventFilter(QObject* originalDestination, QEvent* event) override; QQuickItem* getDesktop(); QQuickItem* getToolWindow(); @@ -131,6 +133,7 @@ private: QQuickItem* _desktop { nullptr }; QQuickItem* _toolWindow { nullptr }; + std::unordered_map _pressedKeys; }; #endif