From d6bcdcde3f2b6fdeced7994911debc81edd7b390 Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Fri, 25 May 2018 12:02:36 -0700 Subject: [PATCH] Fix DISABLE_QML behavior --- interface/src/Application.cpp | 13 +++--- libraries/qml/src/qml/OffscreenSurface.cpp | 2 +- .../qml/src/qml/impl/RenderEventHandler.cpp | 3 ++ .../qml/src/qml/impl/RenderEventHandler.h | 4 ++ libraries/qml/src/qml/impl/SharedObject.cpp | 42 ++++++++++++++++++- libraries/qml/src/qml/impl/SharedObject.h | 16 ++++--- libraries/ui/src/OffscreenUi.cpp | 11 +++-- 7 files changed, 73 insertions(+), 18 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index ba7c15ad33..b859dc4b66 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -4574,11 +4574,14 @@ void Application::idle() { _lastTimeUpdated.start(); // If the offscreen Ui has something active that is NOT the root, then assume it has keyboard focus. - if (_keyboardDeviceHasFocus && offscreenUi && offscreenUi->getWindow()->activeFocusItem() != offscreenUi->getRootItem()) { - _keyboardMouseDevice->pluginFocusOutEvent(); - _keyboardDeviceHasFocus = false; - } else if (offscreenUi && offscreenUi->getWindow()->activeFocusItem() == offscreenUi->getRootItem()) { - _keyboardDeviceHasFocus = true; + if (offscreenUi && offscreenUi->getWindow()) { + auto activeFocusItem = offscreenUi->getWindow()->activeFocusItem(); + if (_keyboardDeviceHasFocus && activeFocusItem != offscreenUi->getRootItem()) { + _keyboardMouseDevice->pluginFocusOutEvent(); + _keyboardDeviceHasFocus = false; + } else if (activeFocusItem == offscreenUi->getRootItem()) { + _keyboardDeviceHasFocus = true; + } } checkChangeCursor(); diff --git a/libraries/qml/src/qml/OffscreenSurface.cpp b/libraries/qml/src/qml/OffscreenSurface.cpp index ea6f1ce324..3c39d72a28 100644 --- a/libraries/qml/src/qml/OffscreenSurface.cpp +++ b/libraries/qml/src/qml/OffscreenSurface.cpp @@ -99,7 +99,7 @@ QPointF OffscreenSurface::mapToVirtualScreen(const QPointF& originalPoint) { // bool OffscreenSurface::filterEnabled(QObject* originalDestination, QEvent* event) const { - if (!_sharedObject || _sharedObject->getWindow() == originalDestination) { + if (!_sharedObject || !_sharedObject->getWindow() || _sharedObject->getWindow() == originalDestination) { return false; } // Only intercept events while we're in an active state diff --git a/libraries/qml/src/qml/impl/RenderEventHandler.cpp b/libraries/qml/src/qml/impl/RenderEventHandler.cpp index 945a469611..39f3123d40 100644 --- a/libraries/qml/src/qml/impl/RenderEventHandler.cpp +++ b/libraries/qml/src/qml/impl/RenderEventHandler.cpp @@ -8,6 +8,8 @@ #include "RenderEventHandler.h" +#ifndef DISABLE_QML + #include #include @@ -165,3 +167,4 @@ void RenderEventHandler::onQuit() { moveToThread(qApp->thread()); QThread::currentThread()->quit(); } +#endif \ No newline at end of file diff --git a/libraries/qml/src/qml/impl/RenderEventHandler.h b/libraries/qml/src/qml/impl/RenderEventHandler.h index d1e079cc85..1e2f9945f3 100644 --- a/libraries/qml/src/qml/impl/RenderEventHandler.h +++ b/libraries/qml/src/qml/impl/RenderEventHandler.h @@ -7,6 +7,8 @@ // #pragma once +#ifndef DISABLE_QML + #include #include #include @@ -54,3 +56,5 @@ private: }; }}} // namespace hifi::qml::impl + +#endif \ No newline at end of file diff --git a/libraries/qml/src/qml/impl/SharedObject.cpp b/libraries/qml/src/qml/impl/SharedObject.cpp index 2fde057ca8..3b8d0bb743 100644 --- a/libraries/qml/src/qml/impl/SharedObject.cpp +++ b/libraries/qml/src/qml/impl/SharedObject.cpp @@ -55,6 +55,8 @@ QOpenGLContext* SharedObject::getSharedContext() { } SharedObject::SharedObject() { +#ifndef DISABLE_QML + // Create render control _renderControl = new RenderControl(); @@ -68,6 +70,7 @@ SharedObject::SharedObject() { _quickWindow->setColor(QColor(255, 255, 255, 0)); _quickWindow->setClearBeforeRendering(true); +#endif QObject::connect(qApp, &QCoreApplication::aboutToQuit, this, &SharedObject::onAboutToQuit); } @@ -78,7 +81,7 @@ SharedObject::~SharedObject() { destroy(); // _renderTimer is created with `this` as the parent, so need no explicit destruction - +#ifndef DISABLE_QML // Destroy the event hand if (_renderObject) { delete _renderObject; @@ -89,18 +92,20 @@ SharedObject::~SharedObject() { delete _renderControl; _renderControl = nullptr; } +#endif if (_rootItem) { delete _rootItem; _rootItem = nullptr; } +#ifndef DISABLE_QML if (_quickWindow) { _quickWindow->destroy(); delete _quickWindow; _quickWindow = nullptr; } - +#endif if (_qmlContext) { auto engine = _qmlContext->engine(); delete _qmlContext; @@ -114,7 +119,9 @@ void SharedObject::create(OffscreenSurface* surface) { qFatal("QML surface root item already set"); } +#ifndef DISABLE_QML QObject::connect(_quickWindow, &QQuickWindow::focusObjectChanged, surface, &OffscreenSurface::onFocusObjectChanged); +#endif // Create a QML engine. auto qmlEngine = acquireEngine(surface); @@ -125,10 +132,12 @@ void SharedObject::create(OffscreenSurface* surface) { surface->onRootContextCreated(_qmlContext); emit surface->rootContextCreated(_qmlContext); +#ifndef DISABLE_QML if (!qmlEngine->incubationController()) { qmlEngine->setIncubationController(_quickWindow->incubationController()); } _qmlContext->setContextProperty("offscreenWindow", QVariant::fromValue(_quickWindow)); +#endif } void SharedObject::setRootItem(QQuickItem* rootItem) { @@ -137,6 +146,7 @@ void SharedObject::setRootItem(QQuickItem* rootItem) { } _rootItem = rootItem; +#ifndef DISABLE_QML _rootItem->setSize(_quickWindow->size()); // Create the render thread @@ -150,6 +160,8 @@ void SharedObject::setRootItem(QQuickItem* rootItem) { QObject::connect(_renderControl, &QQuickRenderControl::renderRequested, this, &SharedObject::requestRender); QObject::connect(_renderControl, &QQuickRenderControl::sceneChanged, this, &SharedObject::requestRenderSync); +#endif + } void SharedObject::destroy() { @@ -163,6 +175,7 @@ void SharedObject::destroy() { } _paused = true; +#ifndef DISABLE_QML if (_renderTimer) { _renderTimer->stop(); QObject::disconnect(_renderTimer); @@ -171,9 +184,11 @@ void SharedObject::destroy() { if (_renderControl) { QObject::disconnect(_renderControl); } +#endif QObject::disconnect(qApp); +#ifndef DISABLE_QML { QMutexLocker lock(&_mutex); _quit = true; @@ -190,6 +205,7 @@ void SharedObject::destroy() { delete _renderThread; _renderThread = nullptr; } +#endif } @@ -240,6 +256,7 @@ void SharedObject::releaseEngine(QQmlEngine* engine) { } bool SharedObject::event(QEvent* e) { +#ifndef DISABLE_QML switch (static_cast(e->type())) { case OffscreenEvent::Initialize: onInitialize(); @@ -252,6 +269,7 @@ bool SharedObject::event(QEvent* e) { default: break; } +#endif return QObject::event(e); } @@ -261,22 +279,28 @@ void SharedObject::initializeRenderControl(QOpenGLContext* context) { qFatal("QML rendering context has no share context"); } +#ifndef DISABLE_QML if (!nsightActive()) { _renderControl->initialize(context); } +#endif } void SharedObject::releaseTextureAndFence() { +#ifndef DISABLE_QML QMutexLocker lock(&_mutex); // If the most recent texture was unused, we can directly recycle it if (_latestTextureAndFence.first) { getTextureCache().releaseTexture(_latestTextureAndFence); _latestTextureAndFence = TextureAndFence{ 0, 0 }; } +#endif } void SharedObject::setRenderTarget(uint32_t fbo, const QSize& size) { +#ifndef DISABLE_QML _quickWindow->setRenderTarget(fbo, size); +#endif } QSize SharedObject::getSize() const { @@ -295,6 +319,7 @@ void SharedObject::setSize(const QSize& size) { } qCDebug(qmlLogging) << "Offscreen UI resizing to " << size.width() << "x" << size.height(); +#ifndef DISABLE_QML _quickWindow->setGeometry(QRect(QPoint(), size)); _quickWindow->contentItem()->setSize(size); @@ -304,9 +329,11 @@ void SharedObject::setSize(const QSize& size) { } requestRenderSync(); +#endif } bool SharedObject::preRender() { +#ifndef DISABLE_QML QMutexLocker lock(&_mutex); if (_paused) { if (_syncRequested) { @@ -327,6 +354,7 @@ bool SharedObject::preRender() { } _syncRequested = false; } +#endif return true; } @@ -339,8 +367,10 @@ void SharedObject::shutdownRendering(OffscreenGLCanvas& canvas, const QSize& siz getTextureCache().releaseTexture(_latestTextureAndFence); } } +#ifndef DISABLE_QML _renderControl->invalidate(); canvas.doneCurrent(); +#endif wake(); } @@ -381,8 +411,10 @@ bool SharedObject::fetchTexture(TextureAndFence& textureAndFence) { } void SharedObject::setProxyWindow(QWindow* window) { +#ifndef DISABLE_QML _proxyWindow = window; _renderControl->setRenderWindow(window); +#endif } void SharedObject::wait() { @@ -394,6 +426,7 @@ void SharedObject::wake() { } void SharedObject::onInitialize() { +#ifndef DISABLE_QML // Associate root item with the window. _rootItem->setParentItem(_quickWindow->contentItem()); _renderControl->prepareThread(_renderThread); @@ -410,9 +443,11 @@ void SharedObject::onInitialize() { _renderTimer->setTimerType(Qt::PreciseTimer); _renderTimer->setInterval(MIN_TIMER_MS); // 5ms, Qt::PreciseTimer required _renderTimer->start(); +#endif } void SharedObject::onRender() { +#ifndef DISABLE_QML PROFILE_RANGE(render_qml, __FUNCTION__); if (_quit) { return; @@ -430,6 +465,7 @@ void SharedObject::onRender() { QCoreApplication::postEvent(_renderObject, new OffscreenEvent(OffscreenEvent::Render)); } _renderRequested = false; +#endif } void SharedObject::onTimer() { @@ -455,7 +491,9 @@ void SharedObject::onTimer() { } } +#ifndef DISABLE_QML QCoreApplication::postEvent(this, new OffscreenEvent(OffscreenEvent::Render)); +#endif } void SharedObject::onAboutToQuit() { diff --git a/libraries/qml/src/qml/impl/SharedObject.h b/libraries/qml/src/qml/impl/SharedObject.h index 76dde611fc..002679c44d 100644 --- a/libraries/qml/src/qml/impl/SharedObject.h +++ b/libraries/qml/src/qml/impl/SharedObject.h @@ -93,17 +93,21 @@ private: // Texture management TextureAndFence _latestTextureAndFence{ 0, 0 }; - RenderControl* _renderControl{ nullptr }; - RenderEventHandler* _renderObject{ nullptr }; - QQuickWindow* _quickWindow{ nullptr }; - QWindow* _proxyWindow{ nullptr }; QQuickItem* _item{ nullptr }; QQuickItem* _rootItem{ nullptr }; + QQuickWindow* _quickWindow{ nullptr }; QQmlContext* _qmlContext{ nullptr }; + mutable QMutex _mutex; + QWaitCondition _cond; + +#ifndef DISABLE_QML + QWindow* _proxyWindow{ nullptr }; + RenderControl* _renderControl{ nullptr }; + RenderEventHandler* _renderObject{ nullptr }; + QTimer* _renderTimer{ nullptr }; QThread* _renderThread{ nullptr }; - QWaitCondition _cond; - mutable QMutex _mutex; +#endif uint64_t _lastRenderTime{ 0 }; QSize _size{ 100, 100 }; diff --git a/libraries/ui/src/OffscreenUi.cpp b/libraries/ui/src/OffscreenUi.cpp index 25f0652496..a5ef1457db 100644 --- a/libraries/ui/src/OffscreenUi.cpp +++ b/libraries/ui/src/OffscreenUi.cpp @@ -96,10 +96,13 @@ static OffscreenFlags* offscreenFlags { nullptr }; // so I think it's OK for the time being. bool OffscreenUi::shouldSwallowShortcut(QEvent* event) { Q_ASSERT(event->type() == QEvent::ShortcutOverride); - QObject* focusObject = getWindow()->focusObject(); - if (focusObject != getWindow() && focusObject != getRootItem()) { - event->accept(); - return true; + auto window = getWindow(); + if (window) { + QObject* focusObject = getWindow()->focusObject(); + if (focusObject != getWindow() && focusObject != getRootItem()) { + event->accept(); + return true; + } } return false; }