From 8a683d58afec7a81057eee022d227eb556536c06 Mon Sep 17 00:00:00 2001 From: Palo Kisa Date: Wed, 23 Feb 2022 10:06:13 +0100 Subject: [PATCH] statusnotifier: Avoid circular *Proxy <-> *Widget dependency --- plugin-statusnotifier/statusnotifierproxy.cpp | 73 ++++++------------- plugin-statusnotifier/statusnotifierproxy.h | 27 +++---- .../statusnotifierwidget.cpp | 13 ++-- plugin-statusnotifier/statusnotifierwidget.h | 9 +-- 4 files changed, 42 insertions(+), 80 deletions(-) diff --git a/plugin-statusnotifier/statusnotifierproxy.cpp b/plugin-statusnotifier/statusnotifierproxy.cpp index c8aefc221..968234f7d 100644 --- a/plugin-statusnotifier/statusnotifierproxy.cpp +++ b/plugin-statusnotifier/statusnotifierproxy.cpp @@ -25,7 +25,6 @@ #include "statusnotifierproxy.h" #include "statusnotifierwatcher.h" -#include "statusnotifierwidget.h" #include #include @@ -36,28 +35,24 @@ Q_GLOBAL_STATIC(StatusNotifierProxy, statusNotifierProxy) StatusNotifierProxy::StatusNotifierProxy() - : mWatcher(nullptr), - mWidgetCount(0), - mCreatingWatcher(false) + : mWatcher{nullptr}, + mUsersCount{0} { - createWatcher(); } void StatusNotifierProxy::createWatcher() { - mCreatingWatcher = true; QFutureWatcher * future_watcher = new QFutureWatcher; connect(future_watcher, &QFutureWatcher::finished, this, [this, future_watcher] { - mWatcher = future_watcher->future().result(); - watcherCreated(); + mWatcher.reset(future_watcher->future().result()); - connect(mWatcher, &StatusNotifierWatcher::StatusNotifierItemRegistered, - this, &StatusNotifierProxy::onStatusNotifierItemRegistered); - connect(mWatcher, &StatusNotifierWatcher::StatusNotifierItemUnregistered, - this, &StatusNotifierProxy::onStatusNotifierItemUnregistered); + connect(mWatcher.get(), &StatusNotifierWatcher::StatusNotifierItemRegistered, + this, &StatusNotifierProxy::StatusNotifierItemRegistered); + connect(mWatcher.get(), &StatusNotifierWatcher::StatusNotifierItemUnregistered, + this, &StatusNotifierProxy::StatusNotifierItemUnregistered); - qDebug() << mWatcher->RegisteredStatusNotifierItems(); + qDebug() << "StatusNotifierProxy, services:" << mWatcher->RegisteredStatusNotifierItems(); future_watcher->deleteLater(); }); @@ -77,53 +72,31 @@ void StatusNotifierProxy::createWatcher() future_watcher->setFuture(future); } -void StatusNotifierProxy::watcherCreated() +QStringList StatusNotifierProxy::RegisteredStatusNotifierItems() const { - mCreatingWatcher = false; + Q_ASSERT(mUsersCount > 0); + return mWatcher ? mWatcher->RegisteredStatusNotifierItems() : QStringList{}; } -StatusNotifierProxy::~StatusNotifierProxy() +StatusNotifierProxy & StatusNotifierProxy::registerLifetimeUsage(QObject * obj) { - qDebug() << "deleting Proxy"; + StatusNotifierProxy & p = *statusNotifierProxy(); + p.registerUsage(obj); + return p; } -StatusNotifierProxy *StatusNotifierProxy::instance() +void StatusNotifierProxy::registerUsage(QObject * obj) { - return statusNotifierProxy(); -} - -void StatusNotifierProxy::registerWidget(StatusNotifierWidget *widget) -{ - ++mWidgetCount; - if (nullptr == mWatcher && mCreatingWatcher == false) + connect(obj, &QObject::destroyed, this, &StatusNotifierProxy::unregisterUsage); + if (mUsersCount <= 0) createWatcher(); - for (auto i = mServices.cbegin(); i != mServices.cend(); ++i) - widget->itemAdded(*i); - - connect(this, &StatusNotifierProxy::StatusNotifierItemRegistered, - widget, &StatusNotifierWidget::itemAdded); - connect(this, &StatusNotifierProxy::StatusNotifierItemUnregistered, - widget, &StatusNotifierWidget::itemRemoved); + ++mUsersCount; } -void StatusNotifierProxy::unregisterWidget(StatusNotifierWidget */*widget*/) +void StatusNotifierProxy::unregisterUsage() { - --mWidgetCount; - if (mWidgetCount == 0) { - mWatcher->deleteLater(); - mWatcher = nullptr; - mServices.clear(); + --mUsersCount; + if (mUsersCount <= 0) { + mWatcher.reset(); } } - -void StatusNotifierProxy::onStatusNotifierItemRegistered(const QString &service) -{ - mServices.append(service); - emit StatusNotifierItemRegistered(service); -} - -void StatusNotifierProxy::onStatusNotifierItemUnregistered(const QString &service) -{ - mServices.removeAll(service); - emit StatusNotifierItemUnregistered(service); -} diff --git a/plugin-statusnotifier/statusnotifierproxy.h b/plugin-statusnotifier/statusnotifierproxy.h index 1448584ab..693c3f2a5 100644 --- a/plugin-statusnotifier/statusnotifierproxy.h +++ b/plugin-statusnotifier/statusnotifierproxy.h @@ -23,12 +23,11 @@ * * END_COMMON_COPYRIGHT_HEADER */ -#ifndef STATUSNOTIFIERPROXY_H -#define STATUSNOTIFIERPROXY_H - +#pragma once #include #include +#include class StatusNotifierWidget; class StatusNotifierWatcher; @@ -39,25 +38,19 @@ class StatusNotifierProxy : public QObject public: StatusNotifierProxy(); - ~StatusNotifierProxy(); - static StatusNotifierProxy *instance(); - - void onStatusNotifierItemRegistered(const QString &service); - void onStatusNotifierItemUnregistered(const QString &service); - void registerWidget(StatusNotifierWidget *widget); - void unregisterWidget(StatusNotifierWidget *widget); + ~StatusNotifierProxy() = default; + QStringList RegisteredStatusNotifierItems() const; + static StatusNotifierProxy & registerLifetimeUsage(QObject * obj); private: - QStringList mServices; - StatusNotifierWatcher *mWatcher; - int mWidgetCount; - bool mCreatingWatcher; + std::unique_ptr mWatcher; + int mUsersCount; + void createWatcher(); - void watcherCreated(); + void registerUsage(QObject * obj); + void unregisterUsage(); signals: void StatusNotifierItemRegistered(const QString &service); void StatusNotifierItemUnregistered(const QString &service); }; - -#endif //STATUSNOTIFIERPROXY_H diff --git a/plugin-statusnotifier/statusnotifierwidget.cpp b/plugin-statusnotifier/statusnotifierwidget.cpp index c5a080b0f..d71cca731 100644 --- a/plugin-statusnotifier/statusnotifierwidget.cpp +++ b/plugin-statusnotifier/statusnotifierwidget.cpp @@ -34,7 +34,6 @@ StatusNotifierWidget::StatusNotifierWidget(ILXQtPanelPlugin *plugin, QWidget *parent) : QWidget(parent), mPlugin(plugin), - mProxy(StatusNotifierProxy::instance()), mAttentionPeriod(5), mForceVisible(false) { @@ -80,13 +79,15 @@ StatusNotifierWidget::StatusNotifierWidget(ILXQtPanelPlugin *plugin, QWidget *pa } }); - mProxy->registerWidget(this); realign(); -} -StatusNotifierWidget::~StatusNotifierWidget() -{ - mProxy->unregisterWidget(this); + StatusNotifierProxy & proxy = StatusNotifierProxy::registerLifetimeUsage(this); + connect(&proxy, &StatusNotifierProxy::StatusNotifierItemRegistered, + this, &StatusNotifierWidget::itemAdded); + connect(&proxy, &StatusNotifierProxy::StatusNotifierItemUnregistered, + this, &StatusNotifierWidget::itemRemoved); + for (const auto & service: proxy.RegisteredStatusNotifierItems()) + itemAdded(service); } void StatusNotifierWidget::leaveEvent(QEvent * /*event*/) diff --git a/plugin-statusnotifier/statusnotifierwidget.h b/plugin-statusnotifier/statusnotifierwidget.h index 83bcdf260..1711eb6f4 100644 --- a/plugin-statusnotifier/statusnotifierwidget.h +++ b/plugin-statusnotifier/statusnotifierwidget.h @@ -26,10 +26,8 @@ * * END_COMMON_COPYRIGHT_HEADER */ -#ifndef STATUSNOTIFIERWIDGET_H -#define STATUSNOTIFIERWIDGET_H +#pragma once -#include #include #include @@ -44,7 +42,7 @@ class StatusNotifierWidget : public QWidget public: StatusNotifierWidget(ILXQtPanelPlugin *plugin, QWidget *parent = nullptr); - ~StatusNotifierWidget(); + ~StatusNotifierWidget() = default; void settingsChanged(); QStringList itemTitles() const; @@ -63,7 +61,6 @@ public slots: private: ILXQtPanelPlugin *mPlugin; - StatusNotifierProxy *mProxy; QTimer mHideTimer; @@ -76,5 +73,3 @@ public slots: int mAttentionPeriod; bool mForceVisible; }; - -#endif // STATUSNOTIFIERWIDGET_H