From 2667af3682981f21fe3728adb38446f5a3312b49 Mon Sep 17 00:00:00 2001 From: HifiExperiments Date: Wed, 20 Jan 2021 21:25:30 -0800 Subject: [PATCH] more safeguards --- interface/src/AboutUtil.cpp | 10 ++--- interface/src/Bookmarks.cpp | 1 - interface/src/avatar/AvatarPackager.cpp | 4 +- .../AssetMappingsScriptingInterface.cpp | 5 +++ .../scripting/DesktopScriptingInterface.cpp | 7 +++- .../src/scripting/HMDScriptingInterface.cpp | 10 +++-- interface/src/ui/ApplicationOverlay.cpp | 4 +- interface/src/ui/InteractiveWindow.cpp | 7 ++-- interface/src/ui/overlays/Overlays.cpp | 8 ++-- interface/src/ui/overlays/QmlOverlay.cpp | 8 +++- libraries/ui/src/DockWidget.cpp | 17 ++++---- libraries/ui/src/InfoView.cpp | 23 ++++++----- libraries/ui/src/OffscreenQmlElement.h | 41 +++++++++++-------- libraries/ui/src/QmlFragmentClass.cpp | 4 -- libraries/ui/src/QmlWebWindowClass.cpp | 2 - libraries/ui/src/QmlWindowClass.cpp | 2 - plugins/openvr/src/OpenVrHelpers.cpp | 14 +++---- 17 files changed, 94 insertions(+), 73 deletions(-) diff --git a/interface/src/AboutUtil.cpp b/interface/src/AboutUtil.cpp index b9bea2d85c..5340fcd248 100644 --- a/interface/src/AboutUtil.cpp +++ b/interface/src/AboutUtil.cpp @@ -57,15 +57,15 @@ void AboutUtil::openUrl(const QString& url) const { auto tablet = DependencyManager::get()->getTablet("com.highfidelity.interface.tablet.system"); auto hmd = DependencyManager::get(); - auto offscreenUi = DependencyManager::get(); + auto offscreenUI = DependencyManager::get(); - if (tablet->getToolbarMode()) { - offscreenUi->load("Browser.qml", [=](QQmlContext* context, QObject* newObject) { + if (tablet->getToolbarMode() && offscreenUI) { + offscreenUI->load("Browser.qml", [=](QQmlContext* context, QObject* newObject) { newObject->setProperty("url", url); }); } else { - if (!hmd->getShouldShowTablet() && !qApp->isHMDMode()) { - offscreenUi->load("Browser.qml", [=](QQmlContext* context, QObject* newObject) { + if (!hmd->getShouldShowTablet() && !qApp->isHMDMode() && offscreenUI) { + offscreenUI->load("Browser.qml", [=](QQmlContext* context, QObject* newObject) { newObject->setProperty("url", url); }); } else { diff --git a/interface/src/Bookmarks.cpp b/interface/src/Bookmarks.cpp index 9a8d8eb279..263723ebe0 100644 --- a/interface/src/Bookmarks.cpp +++ b/interface/src/Bookmarks.cpp @@ -61,7 +61,6 @@ void Bookmarks::deleteBookmark(const QString& bookmarkName) { void Bookmarks::addBookmarkToFile(const QString& bookmarkName, const QVariant& bookmark) { Menu* menubar = Menu::getInstance(); if (contains(bookmarkName)) { - auto offscreenUi = DependencyManager::get(); ModalDialogListener* dlg = OffscreenUi::asyncWarning("Duplicate Bookmark", "The bookmark name you entered already exists in your list.", QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes); diff --git a/interface/src/avatar/AvatarPackager.cpp b/interface/src/avatar/AvatarPackager.cpp index 90def7ad43..d43b7d9575 100644 --- a/interface/src/avatar/AvatarPackager.cpp +++ b/interface/src/avatar/AvatarPackager.cpp @@ -58,7 +58,9 @@ bool AvatarPackager::open() { if (tablet->getToolbarMode()) { static const QUrl url{ "hifi/AvatarPackagerWindow.qml" }; - DependencyManager::get()->show(url, "AvatarPackager", packageModelDialogCreated); + if (auto offscreenUI = DependencyManager::get()) { + offscreenUI->show(url, "AvatarPackager", packageModelDialogCreated); + } return true; } diff --git a/interface/src/scripting/AssetMappingsScriptingInterface.cpp b/interface/src/scripting/AssetMappingsScriptingInterface.cpp index c5769ef4bb..a6fbd8b3fd 100644 --- a/interface/src/scripting/AssetMappingsScriptingInterface.cpp +++ b/interface/src/scripting/AssetMappingsScriptingInterface.cpp @@ -77,6 +77,11 @@ void AssetMappingsScriptingInterface::uploadFile(QString path, QString mapping, "Specifying a new folder name will automatically create that folder for you."; auto offscreenUi = DependencyManager::get(); + if (!offscreenUi) { + completedCallback.call({ -1 }); + return; + } + auto result = offscreenUi->inputDialog(OffscreenUi::ICON_INFORMATION, "Specify Asset Path", dropEvent ? dropHelpText : helpText, mapping); diff --git a/interface/src/scripting/DesktopScriptingInterface.cpp b/interface/src/scripting/DesktopScriptingInterface.cpp index f78f7853ca..e527561b05 100644 --- a/interface/src/scripting/DesktopScriptingInterface.cpp +++ b/interface/src/scripting/DesktopScriptingInterface.cpp @@ -99,11 +99,16 @@ void DesktopScriptingInterface::setHUDAlpha(float alpha) { } void DesktopScriptingInterface::show(const QString& path, const QString& title) { + auto offscreenUI = DependencyManager::get(); + if (!offscreenUI) { + return; + } + if (QThread::currentThread() != thread()) { QMetaObject::invokeMethod(this, "show", Qt::QueuedConnection, Q_ARG(QString, path), Q_ARG(QString, title)); return; } - DependencyManager::get()->show(path, title); + offscreenUI->show(path, title); } InteractiveWindowPointer DesktopScriptingInterface::createWindow(const QString& sourceUrl, const QVariantMap& properties) { diff --git a/interface/src/scripting/HMDScriptingInterface.cpp b/interface/src/scripting/HMDScriptingInterface.cpp index 8f7ae7c4dc..79c0452a45 100644 --- a/interface/src/scripting/HMDScriptingInterface.cpp +++ b/interface/src/scripting/HMDScriptingInterface.cpp @@ -96,8 +96,9 @@ bool HMDScriptingInterface::shouldShowHandControllers() const { void HMDScriptingInterface::activateHMDHandMouse() { QWriteLocker lock(&_hmdHandMouseLock); - auto offscreenUi = DependencyManager::get(); - offscreenUi->getDesktop()->setProperty("hmdHandMouseActive", true); + if (auto offscreenUI = DependencyManager::get()) { + offscreenUI->getDesktop()->setProperty("hmdHandMouseActive", true); + } _hmdHandMouseCount++; } @@ -105,8 +106,9 @@ void HMDScriptingInterface::deactivateHMDHandMouse() { QWriteLocker lock(&_hmdHandMouseLock); _hmdHandMouseCount = std::max(_hmdHandMouseCount - 1, 0); if (_hmdHandMouseCount == 0) { - auto offscreenUi = DependencyManager::get(); - offscreenUi->getDesktop()->setProperty("hmdHandMouseActive", false); + if (auto offscreenUI = DependencyManager::get()) { + offscreenUI->getDesktop()->setProperty("hmdHandMouseActive", false); + } } } diff --git a/interface/src/ui/ApplicationOverlay.cpp b/interface/src/ui/ApplicationOverlay.cpp index e91b1d725c..144f64c385 100644 --- a/interface/src/ui/ApplicationOverlay.cpp +++ b/interface/src/ui/ApplicationOverlay.cpp @@ -100,10 +100,10 @@ void ApplicationOverlay::renderQmlUi(RenderArgs* renderArgs) { // threads, we need to use a sync object to deteremine when // the current UI texture is no longer being read from, and only // then release it back to the UI for re-use - auto offscreenUi = DependencyManager::get(); + auto offscreenUI = DependencyManager::get(); OffscreenQmlSurface::TextureAndFence newTextureAndFence; - bool newTextureAvailable = offscreenUi->fetchTexture(newTextureAndFence); + bool newTextureAvailable = offscreenUI ? offscreenUI->fetchTexture(newTextureAndFence) : false; if (newTextureAvailable) { _uiTexture->setExternalTexture(newTextureAndFence.first, newTextureAndFence.second); } diff --git a/interface/src/ui/InteractiveWindow.cpp b/interface/src/ui/InteractiveWindow.cpp index 0ac1f05737..420efbf448 100644 --- a/interface/src/ui/InteractiveWindow.cpp +++ b/interface/src/ui/InteractiveWindow.cpp @@ -362,10 +362,11 @@ InteractiveWindow::InteractiveWindow(const QString& sourceUrl, const QVariantMap object->setObjectName("InteractiveWindow"); object->setProperty(SOURCE_PROPERTY, sourceURL); }; - auto offscreenUi = DependencyManager::get(); - // Build the event bridge and wrapper on the main thread - offscreenUi->loadInNewContext(CONTENT_WINDOW_QML, objectInitLambda, contextInitLambda); + if (auto offscreenUi = DependencyManager::get()) { + // Build the event bridge and wrapper on the main thread + offscreenUi->loadInNewContext(CONTENT_WINDOW_QML, objectInitLambda, contextInitLambda); + } } } diff --git a/interface/src/ui/overlays/Overlays.cpp b/interface/src/ui/overlays/Overlays.cpp index 5e43c5df8d..e9e310e68b 100644 --- a/interface/src/ui/overlays/Overlays.cpp +++ b/interface/src/ui/overlays/Overlays.cpp @@ -1212,8 +1212,8 @@ float Overlays::width() { return result; } - auto offscreenUi = DependencyManager::get(); - return offscreenUi->getWindow()->size().width(); + auto offscreenUI = DependencyManager::get(); + return offscreenUI ? offscreenUI->getWindow()->size().width() : -1.0f; } float Overlays::height() { @@ -1224,8 +1224,8 @@ float Overlays::height() { return result; } - auto offscreenUi = DependencyManager::get(); - return offscreenUi->getWindow()->size().height(); + auto offscreenUI = DependencyManager::get(); + return offscreenUI ? offscreenUI->getWindow()->size().height() : -1.0f; } void Overlays::mousePressOnPointerEvent(const QUuid& id, const PointerEvent& event) { diff --git a/interface/src/ui/overlays/QmlOverlay.cpp b/interface/src/ui/overlays/QmlOverlay.cpp index 2afb29bb91..c097e7dd97 100644 --- a/interface/src/ui/overlays/QmlOverlay.cpp +++ b/interface/src/ui/overlays/QmlOverlay.cpp @@ -24,13 +24,17 @@ QmlOverlay::QmlOverlay(const QUrl& url, const QmlOverlay* overlay) } void QmlOverlay::buildQmlElement(const QUrl& url) { + auto offscreenUI = DependencyManager::get(); + if (!offscreenUI) { + return; + } + if (QThread::currentThread() != thread()) { QMetaObject::invokeMethod(this, "buildQmlElement", Q_ARG(QUrl, url)); return; } - auto offscreenUi = DependencyManager::get(); - offscreenUi->load(url, [=](QQmlContext* context, QObject* object) { + offscreenUI->load(url, [=](QQmlContext* context, QObject* object) { _qmlElement = dynamic_cast(object); connect(_qmlElement, &QObject::destroyed, this, &QmlOverlay::qmlElementDestroyed); }); diff --git a/libraries/ui/src/DockWidget.cpp b/libraries/ui/src/DockWidget.cpp index 13c4d9a548..f899def2c6 100644 --- a/libraries/ui/src/DockWidget.cpp +++ b/libraries/ui/src/DockWidget.cpp @@ -26,14 +26,15 @@ static void quickViewDeleter(QQuickView* quickView) { } DockWidget::DockWidget(const QString& title, QWidget* parent) : QDockWidget(title, parent) { - auto offscreenUi = DependencyManager::get(); - auto qmlEngine = offscreenUi->getSurfaceContext()->engine(); - _quickView = std::shared_ptr(new QQuickView(qmlEngine, nullptr), quickViewDeleter); - _quickView->setFormat(getDefaultOpenGLSurfaceFormat()); - QWidget* widget = QWidget::createWindowContainer(_quickView.get()); - setWidget(widget); - QWidget* headerWidget = new QWidget(); - setTitleBarWidget(headerWidget); + if (auto offscreenUI = DependencyManager::get()) { + auto qmlEngine = offscreenUI->getSurfaceContext()->engine(); + _quickView = std::shared_ptr(new QQuickView(qmlEngine, nullptr), quickViewDeleter); + _quickView->setFormat(getDefaultOpenGLSurfaceFormat()); + QWidget* widget = QWidget::createWindowContainer(_quickView.get()); + setWidget(widget); + QWidget* headerWidget = new QWidget(); + setTitleBarWidget(headerWidget); + } } void DockWidget::setSource(const QUrl& url) { diff --git a/libraries/ui/src/InfoView.cpp b/libraries/ui/src/InfoView.cpp index 478401c6f8..f98d514f5d 100644 --- a/libraries/ui/src/InfoView.cpp +++ b/libraries/ui/src/InfoView.cpp @@ -65,17 +65,18 @@ void InfoView::show(const QString& path, bool firstOrChangedOnly, QString urlQue } infoVersion.set(version); } - auto offscreenUi = DependencyManager::get(); - QString infoViewName(NAME + "_" + path); - offscreenUi->show(QML, NAME + "_" + path, [=](QQmlContext* context, QObject* newObject){ - QQuickItem* item = dynamic_cast(newObject); - item->setWidth(1024); - item->setHeight(720); - InfoView* newInfoView = newObject->findChild(); - Q_ASSERT(newInfoView); - newInfoView->parent()->setObjectName(infoViewName); - newInfoView->setUrl(url); - }); + if (auto offscreenUI = DependencyManager::get()) { + QString infoViewName(NAME + "_" + path); + offscreenUI->show(QML, NAME + "_" + path, [=](QQmlContext* context, QObject* newObject){ + QQuickItem* item = dynamic_cast(newObject); + item->setWidth(1024); + item->setHeight(720); + InfoView* newInfoView = newObject->findChild(); + Q_ASSERT(newInfoView); + newInfoView->parent()->setObjectName(infoViewName); + newInfoView->setUrl(url); + }); + } } QUrl InfoView::url() { diff --git a/libraries/ui/src/OffscreenQmlElement.h b/libraries/ui/src/OffscreenQmlElement.h index 69009533c6..ac1bcb0866 100644 --- a/libraries/ui/src/OffscreenQmlElement.h +++ b/libraries/ui/src/OffscreenQmlElement.h @@ -53,25 +53,30 @@ private: } \ \ void x::show(std::function f) { \ - auto offscreenUi = DependencyManager::get(); \ + auto offscreenUI = DependencyManager::get(); \ if (!registered) { \ x::registerType(); \ } \ - offscreenUi->show(QML, NAME, f); \ + if (offscreenUI) { \ + offscreenUI->show(QML, NAME, f); \ + } \ } \ \ void x::hide() { \ - auto offscreenUi = DependencyManager::get(); \ - offscreenUi->hide(NAME); \ + if (auto offscreenUI = DependencyManager::get()) { \ + offscreenUI->hide(NAME); \ + } \ } \ \ void x::toggle(std::function f) { \ - auto offscreenUi = DependencyManager::get(); \ - offscreenUi->toggle(QML, NAME, f); \ + if (auto offscreenUI = DependencyManager::get()) { \ + offscreenUI->toggle(QML, NAME, f); \ + } \ } \ void x::load(std::function f) { \ - auto offscreenUi = DependencyManager::get(); \ - offscreenUi->load(QML, f); \ + if (auto offscreenUI = DependencyManager::get()) { \ + offscreenUI->load(QML, f); \ + } \ } #define HIFI_QML_DEF_LAMBDA(x, f) \ @@ -82,21 +87,25 @@ private: qmlRegisterType("Hifi", 1, 0, NAME.toLocal8Bit().constData()); \ } \ void x::show() { \ - auto offscreenUi = DependencyManager::get(); \ - offscreenUi->show(QML, NAME, f); \ + if (auto offscreenUI = DependencyManager::get()) { \ + offscreenUI->show(QML, NAME, f); \ + } \ } \ void x::hide() { \ - auto offscreenUi = DependencyManager::get(); \ - offscreenUi->hide(NAME); \ + if (auto offscreenUI = DependencyManager::get()) { \ + offscreenUI->hide(NAME); \ + } \ } \ \ void x::toggle() { \ - auto offscreenUi = DependencyManager::get(); \ - offscreenUi->toggle(QML, NAME, f); \ + if (auto offscreenUI = DependencyManager::get()) { \ + offscreenUI->toggle(QML, NAME, f); \ + } \ } \ void x::load() { \ - auto offscreenUi = DependencyManager::get(); \ - offscreenUi->load(QML, f); \ + if (auto offscreenUI = DependencyManager::get()) { \ + offscreenUI->load(QML, f); \ + } \ } #endif diff --git a/libraries/ui/src/QmlFragmentClass.cpp b/libraries/ui/src/QmlFragmentClass.cpp index fbd045fdb1..1219094afc 100644 --- a/libraries/ui/src/QmlFragmentClass.cpp +++ b/libraries/ui/src/QmlFragmentClass.cpp @@ -14,9 +14,6 @@ #include -#include "OffscreenUi.h" - - std::mutex QmlFragmentClass::_mutex; std::map QmlFragmentClass::_fragments; @@ -40,7 +37,6 @@ QScriptValue QmlFragmentClass::internal_constructor(QScriptContext* context, QSc } auto properties = parseArguments(context); - auto offscreenUi = DependencyManager::get(); QmlFragmentClass* retVal = new QmlFragmentClass(restricted, qml.toString()); Q_ASSERT(retVal); if (QThread::currentThread() != qApp->thread()) { diff --git a/libraries/ui/src/QmlWebWindowClass.cpp b/libraries/ui/src/QmlWebWindowClass.cpp index 282161497a..c7851d416f 100644 --- a/libraries/ui/src/QmlWebWindowClass.cpp +++ b/libraries/ui/src/QmlWebWindowClass.cpp @@ -14,7 +14,6 @@ #include #include -#include "OffscreenUi.h" static const char* const URL_PROPERTY = "source"; static const char* const SCRIPT_PROPERTY = "scriptUrl"; @@ -22,7 +21,6 @@ static const char* const SCRIPT_PROPERTY = "scriptUrl"; // Method called by Qt scripts to create a new web window in the overlay QScriptValue QmlWebWindowClass::internal_constructor(QScriptContext* context, QScriptEngine* engine, bool restricted) { auto properties = parseArguments(context); - auto offscreenUi = DependencyManager::get(); QmlWebWindowClass* retVal = new QmlWebWindowClass(restricted); Q_ASSERT(retVal); if (QThread::currentThread() != qApp->thread()) { diff --git a/libraries/ui/src/QmlWindowClass.cpp b/libraries/ui/src/QmlWindowClass.cpp index 13a289a5fd..ae2292dc09 100644 --- a/libraries/ui/src/QmlWindowClass.cpp +++ b/libraries/ui/src/QmlWindowClass.cpp @@ -72,7 +72,6 @@ QVariantMap QmlWindowClass::parseArguments(QScriptContext* context) { // Method called by Qt scripts to create a new web window in the overlay QScriptValue QmlWindowClass::internal_constructor(QScriptContext* context, QScriptEngine* engine, bool restricted) { auto properties = parseArguments(context); - auto offscreenUi = DependencyManager::get(); QmlWindowClass* retVal = new QmlWindowClass(restricted); Q_ASSERT(retVal); if (QThread::currentThread() != qApp->thread()) { @@ -349,7 +348,6 @@ void QmlWindowClass::raise() { return; } - auto offscreenUi = DependencyManager::get(); if (_qmlWindow) { QMetaObject::invokeMethod(asQuickItem(), "raise", Qt::DirectConnection); } diff --git a/plugins/openvr/src/OpenVrHelpers.cpp b/plugins/openvr/src/OpenVrHelpers.cpp index ce7625eedb..eed2242602 100644 --- a/plugins/openvr/src/OpenVrHelpers.cpp +++ b/plugins/openvr/src/OpenVrHelpers.cpp @@ -203,14 +203,14 @@ void updateFromOpenVrKeyboardInput() { } void finishOpenVrKeyboardInput() { - auto offscreenUi = DependencyManager::get(); + auto offscreenUI = DependencyManager::get(); updateFromOpenVrKeyboardInput(); // Simulate an enter press on the top level window to trigger the action - if (0 == (_currentHints & Qt::ImhMultiLine)) { + if (0 == (_currentHints & Qt::ImhMultiLine) && offscreenUI) { auto keyPress = QKeyEvent(QEvent::KeyPress, Qt::Key_Return, Qt::KeyboardModifiers(), QString("\n")); auto keyRelease = QKeyEvent(QEvent::KeyRelease, Qt::Key_Return, Qt::KeyboardModifiers()); - qApp->sendEvent(offscreenUi->getWindow(), &keyPress); - qApp->sendEvent(offscreenUi->getWindow(), &keyRelease); + qApp->sendEvent(offscreenUI->getWindow(), &keyPress); + qApp->sendEvent(offscreenUI->getWindow(), &keyRelease); } } @@ -221,10 +221,8 @@ void enableOpenVrKeyboard(PluginContainer* container) { if (disableSteamVrKeyboard) { return; } - auto offscreenUi = DependencyManager::get(); _overlay = vr::VROverlay(); - auto menu = container->getPrimaryMenu(); auto action = menu->getActionForOption(MenuOption::Overlays); @@ -282,7 +280,9 @@ void handleOpenVrEvents() { case vr::VREvent_KeyboardClosed: _keyboardFocusObject = nullptr; _keyboardShown = false; - DependencyManager::get()->unfocusWindows(); + if (auto offscreenUI = DependencyManager::get()) { + offscreenUI->unfocusWindows(); + } break; default: