From fe43c733f8dbe193298915729f58abe848ab92d9 Mon Sep 17 00:00:00 2001 From: Alexander Ivash Date: Sat, 17 Nov 2018 22:56:59 +0530 Subject: [PATCH 1/2] FB19400 during shutdown -- TypeError: Cannot read property 'buttons' --- interface/resources/qml/hifi/Desktop.qml | 4 ++-- interface/resources/qml/hifi/tablet/TabletHome.qml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/interface/resources/qml/hifi/Desktop.qml b/interface/resources/qml/hifi/Desktop.qml index f57c612b98..354c8095a0 100644 --- a/interface/resources/qml/hifi/Desktop.qml +++ b/interface/resources/qml/hifi/Desktop.qml @@ -70,8 +70,8 @@ OriginalDesktop.Desktop { anchors.horizontalCenter: settings.constrainToolbarToCenterX ? desktop.horizontalCenter : undefined; // Literal 50 is overwritten by settings from previous session, and sysToolbar.x comes from settings when not constrained. x: sysToolbar.x - buttonModel: tablet.buttons; - shown: tablet.toolbarMode; + buttonModel: tablet ? tablet.buttons : null; + shown: tablet ? tablet.toolbarMode : false; } Settings { diff --git a/interface/resources/qml/hifi/tablet/TabletHome.qml b/interface/resources/qml/hifi/tablet/TabletHome.qml index f1f54e8419..cbfb3c1337 100644 --- a/interface/resources/qml/hifi/tablet/TabletHome.qml +++ b/interface/resources/qml/hifi/tablet/TabletHome.qml @@ -115,9 +115,9 @@ Item { property int previousIndex: -1 Repeater { id: pageRepeater - model: Math.ceil(tabletProxy.buttons.rowCount() / TabletEnums.ButtonsOnPage) + model: tabletProxy != null ? Math.ceil(tabletProxy.buttons.rowCount() / TabletEnums.ButtonsOnPage) : 0 onItemAdded: { - item.proxyModel.sourceModel = tabletProxy.buttons; + item.proxyModel.sourceModel = tabletProxy != null ? tabletProxy.buttons : null; item.proxyModel.pageIndex = index; } From 64d05e33c11b8b957630b26ebd7ddfdbe8451d04 Mon Sep 17 00:00:00 2001 From: Alexander Ivash Date: Sun, 18 Nov 2018 00:24:45 +0530 Subject: [PATCH 2/2] second attempt to fix all other shutdown QML warnings at once --- libraries/qml/src/qml/OffscreenSurface.cpp | 4 ++++ libraries/qml/src/qml/impl/SharedObject.cpp | 15 +++++++++++++++ libraries/qml/src/qml/impl/SharedObject.h | 4 +++- 3 files changed, 22 insertions(+), 1 deletion(-) diff --git a/libraries/qml/src/qml/OffscreenSurface.cpp b/libraries/qml/src/qml/OffscreenSurface.cpp index 91532534e3..abab5391e2 100644 --- a/libraries/qml/src/qml/OffscreenSurface.cpp +++ b/libraries/qml/src/qml/OffscreenSurface.cpp @@ -389,6 +389,10 @@ void OffscreenSurface::finishQmlLoad(QQmlComponent* qmlComponent, } // Allow child windows to be destroyed from JS QQmlEngine::setObjectOwnership(newObject, QQmlEngine::JavaScriptOwnership); + + // add object to the manual deletion list + _sharedObject->addToDeletionList(newObject); + newObject->setParent(parent); newItem->setParentItem(parent); } else { diff --git a/libraries/qml/src/qml/impl/SharedObject.cpp b/libraries/qml/src/qml/impl/SharedObject.cpp index 259defdb48..5bcca0821f 100644 --- a/libraries/qml/src/qml/impl/SharedObject.cpp +++ b/libraries/qml/src/qml/impl/SharedObject.cpp @@ -15,6 +15,7 @@ #include #include +#include #include #include @@ -96,6 +97,15 @@ SharedObject::~SharedObject() { } #endif + // already deleted objects will be reset to null by QPointer so it should be safe just iterate here + for (auto qmlObject : _deletionList) { + if (qmlObject) { + // manually delete not-deleted-yet qml items + QQmlEngine::setObjectOwnership(qmlObject, QQmlEngine::CppOwnership); + delete qmlObject; + } + } + if (_rootItem) { delete _rootItem; _rootItem = nullptr; @@ -412,6 +422,11 @@ bool SharedObject::fetchTexture(TextureAndFence& textureAndFence) { return true; } +void hifi::qml::impl::SharedObject::addToDeletionList(QObject * object) +{ + _deletionList.append(QPointer(object)); +} + void SharedObject::setProxyWindow(QWindow* window) { #ifndef DISABLE_QML _proxyWindow = window; diff --git a/libraries/qml/src/qml/impl/SharedObject.h b/libraries/qml/src/qml/impl/SharedObject.h index 002679c44d..ce9fcd46d2 100644 --- a/libraries/qml/src/qml/impl/SharedObject.h +++ b/libraries/qml/src/qml/impl/SharedObject.h @@ -66,7 +66,7 @@ public: void resume(); bool isPaused() const; bool fetchTexture(TextureAndFence& textureAndFence); - + void addToDeletionList(QObject* object); private: bool event(QEvent* e) override; @@ -91,6 +91,8 @@ private: void onAboutToQuit(); void updateTextureAndFence(const TextureAndFence& newTextureAndFence); + QList> _deletionList; + // Texture management TextureAndFence _latestTextureAndFence{ 0, 0 }; QQuickItem* _item{ nullptr };