From: Stephan Beyer Date: Wed, 24 Jun 2020 11:50:17 +0000 (+0200) Subject: Fix SEGV (by circular ownership) at exit X-Git-Tag: archive/raspbian/3.16.7-1_deb13u1+rpi1~1^2~222^2^2~137^2~1 X-Git-Url: https://dgit.raspbian.org/?a=commitdiff_plain;h=08cb289b8c49687f4fb917ac81f630246b3bf551;p=nextcloud-desktop.git Fix SEGV (by circular ownership) at exit Commit a12205f322d43476230881192616e47c9cf786ef (PR #1891) introduced a circular ownership: qmlRegisterSingletonType(...) makes the QQmlEngine own the resulting singleton Systray instance, however, the QQmlEngine _trayEngine itself is owned by the Systray instance. This circular ownership results in a crash when the destructor of Systray calls the destructor of _trayEngine which attempts to call the destructor of Systray. This commit solves this problem by making ownCloudGui, which is the parent of Systray, the parent of the _trayEngine. Signed-off-by: Stephan Beyer --- diff --git a/src/gui/owncloudgui.cpp b/src/gui/owncloudgui.cpp index ef335ffed..5dc280bdc 100644 --- a/src/gui/owncloudgui.cpp +++ b/src/gui/owncloudgui.cpp @@ -32,6 +32,7 @@ #include "cloudproviders/cloudprovidermanager.h" #endif +#include #include #include #include @@ -66,7 +67,7 @@ ownCloudGui::ownCloudGui(Application *parent) , _app(parent) { _tray = Systray::instance(); - _tray->setParent(this); + _tray->setTrayEngine(new QQmlApplicationEngine(this)); // for the beginning, set the offline icon until the account was verified _tray->setIcon(Theme::instance()->folderOfflineIcon(/*systray?*/ true)); diff --git a/src/gui/systray.cpp b/src/gui/systray.cpp index a2b570970..0cb3c86a6 100644 --- a/src/gui/systray.cpp +++ b/src/gui/systray.cpp @@ -49,13 +49,17 @@ Systray *Systray::instance() return _instance; } -Systray::Systray() - : QSystemTrayIcon(nullptr) - , _trayEngine(new QQmlApplicationEngine(this)) +void Systray::setTrayEngine(QQmlApplicationEngine *trayEngine) { + _trayEngine = trayEngine; + _trayEngine->addImportPath("qrc:/qml/theme"); _trayEngine->addImageProvider("avatars", new ImageProvider); +} +Systray::Systray() + : QSystemTrayIcon(nullptr) +{ qmlRegisterSingletonType("com.nextcloud.desktopclient", 1, 0, "UserModel", [](QQmlEngine *, QJSEngine *) -> QObject * { return UserModel::instance(); @@ -83,18 +87,22 @@ Systray::Systray() void Systray::create() { - if (!AccountManager::instance()->accounts().isEmpty()) { - _trayEngine->rootContext()->setContextProperty("activityModel", UserModel::instance()->currentActivityModel()); + if (_trayEngine) { + if (!AccountManager::instance()->accounts().isEmpty()) { + _trayEngine->rootContext()->setContextProperty("activityModel", UserModel::instance()->currentActivityModel()); + } + _trayEngine->load(QStringLiteral("qrc:/qml/src/gui/tray/Window.qml")); } - _trayEngine->load(QStringLiteral("qrc:/qml/src/gui/tray/Window.qml")); hideWindow(); emit activated(QSystemTrayIcon::ActivationReason::Unknown); } void Systray::slotNewUserSelected() { - // Change ActivityModel - _trayEngine->rootContext()->setContextProperty("activityModel", UserModel::instance()->currentActivityModel()); + if (_trayEngine) { + // Change ActivityModel + _trayEngine->rootContext()->setContextProperty("activityModel", UserModel::instance()->currentActivityModel()); + } // Rebuild App list UserAppsModel::instance()->buildAppList(); diff --git a/src/gui/systray.h b/src/gui/systray.h index 0cb9249f6..cffa4f843 100644 --- a/src/gui/systray.h +++ b/src/gui/systray.h @@ -49,6 +49,7 @@ public: enum class TaskBarPosition { Bottom, Left, Top, Right }; Q_ENUM(TaskBarPosition); + void setTrayEngine(QQmlApplicationEngine *trayEngine); void create(); void showMessage(const QString &title, const QString &message, MessageIcon icon = Information); void setToolTip(const QString &tip); @@ -89,7 +90,7 @@ private: bool _isOpen = false; bool _syncIsPaused = false; - QQmlApplicationEngine *_trayEngine; + QQmlApplicationEngine *_trayEngine = nullptr; }; } // namespace OCC