From 6adb7987284176407a186778670e1a4b0f41aa57 Mon Sep 17 00:00:00 2001 From: Stephan Beyer Date: Wed, 17 Jun 2020 22:46:25 +0200 Subject: [PATCH 1/3] Let Systray constructor call its base class constructor Although I see no behavioral difference, this is probably a good idea. Signed-off-by: Stephan Beyer --- src/gui/systray.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/gui/systray.cpp b/src/gui/systray.cpp index 6b15ddaba..a2b570970 100644 --- a/src/gui/systray.cpp +++ b/src/gui/systray.cpp @@ -50,7 +50,8 @@ Systray *Systray::instance() } Systray::Systray() - : _trayEngine(new QQmlApplicationEngine(this)) + : QSystemTrayIcon(nullptr) + , _trayEngine(new QQmlApplicationEngine(this)) { _trayEngine->addImportPath("qrc:/qml/theme"); _trayEngine->addImageProvider("avatars", new ImageProvider); From 08cb289b8c49687f4fb917ac81f630246b3bf551 Mon Sep 17 00:00:00 2001 From: Stephan Beyer Date: Wed, 24 Jun 2020 13:50:17 +0200 Subject: [PATCH 2/3] 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 --- src/gui/owncloudgui.cpp | 3 ++- src/gui/systray.cpp | 24 ++++++++++++++++-------- src/gui/systray.h | 3 ++- 3 files changed, 20 insertions(+), 10 deletions(-) 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 From f90e0e519f532f3202bd58ab6a4bf966230c45ed Mon Sep 17 00:00:00 2001 From: Stephan Beyer Date: Wed, 24 Jun 2020 17:24:52 +0200 Subject: [PATCH 3/3] Make Systray's _trayEngine a QPointer This is just safer. Signed-off-by: Stephan Beyer --- src/gui/systray.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/systray.h b/src/gui/systray.h index cffa4f843..02a0034cf 100644 --- a/src/gui/systray.h +++ b/src/gui/systray.h @@ -90,7 +90,7 @@ private: bool _isOpen = false; bool _syncIsPaused = false; - QQmlApplicationEngine *_trayEngine = nullptr; + QPointer _trayEngine; }; } // namespace OCC