From 003d33762b316775acb1a9ccc8364e608f1d60c9 Mon Sep 17 00:00:00 2001 From: slidinghotdog <33790211+slidinghotdog@users.noreply.github.com> Date: Fri, 7 May 2021 20:43:54 -0300 Subject: [PATCH] Add proxy singleton for StatusNotifier --- plugin-statusnotifier/CMakeLists.txt | 2 + plugin-statusnotifier/statusnotifier.h | 2 +- plugin-statusnotifier/statusnotifierproxy.cpp | 131 ++++++++++++++++++ plugin-statusnotifier/statusnotifierproxy.h | 63 +++++++++ .../statusnotifierwidget.cpp | 39 +----- plugin-statusnotifier/statusnotifierwidget.h | 5 +- 6 files changed, 204 insertions(+), 38 deletions(-) create mode 100644 plugin-statusnotifier/statusnotifierproxy.cpp create mode 100644 plugin-statusnotifier/statusnotifierproxy.h diff --git a/plugin-statusnotifier/CMakeLists.txt b/plugin-statusnotifier/CMakeLists.txt index 87369cd2a..d12a0f051 100644 --- a/plugin-statusnotifier/CMakeLists.txt +++ b/plugin-statusnotifier/CMakeLists.txt @@ -13,6 +13,7 @@ set(HEADERS statusnotifierwatcher.h statusnotifierwidget.h sniasync.h + statusnotifierproxy.h ) set(SOURCES @@ -24,6 +25,7 @@ set(SOURCES statusnotifierwatcher.cpp statusnotifierwidget.cpp sniasync.cpp + statusnotifierproxy.cpp ) set(UIS diff --git a/plugin-statusnotifier/statusnotifier.h b/plugin-statusnotifier/statusnotifier.h index d53b174fd..6e2498426 100644 --- a/plugin-statusnotifier/statusnotifier.h +++ b/plugin-statusnotifier/statusnotifier.h @@ -42,7 +42,7 @@ class StatusNotifier : public QObject, public ILXQtPanelPlugin bool isSeparate() const override { return true; } void realign() override; QString themeId() const override { return QStringLiteral("StatusNotifier"); } - Flags flags() const override { return SingleInstance | HaveConfigDialog | NeedsHandle; } + Flags flags() const override { return HaveConfigDialog | NeedsHandle; } QWidget *widget() override { return m_widget; } QDialog *configureDialog() override; diff --git a/plugin-statusnotifier/statusnotifierproxy.cpp b/plugin-statusnotifier/statusnotifierproxy.cpp new file mode 100644 index 000000000..f58d0bfe1 --- /dev/null +++ b/plugin-statusnotifier/statusnotifierproxy.cpp @@ -0,0 +1,131 @@ +/* BEGIN_COMMON_COPYRIGHT_HEADER + * (c)LGPL2+ + * + * LXQt - a lightweight, Qt based, desktop toolset + * https://lxqt.org + * + * Copyright: 2021 LXQt team + * + * This program or library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + * + * END_COMMON_COPYRIGHT_HEADER */ + +#include "statusnotifierproxy.h" +#include "statusnotifierwatcher.h" +#include "statusnotifierwidget.h" + +#include +#include +#include +#include +#include + +Q_GLOBAL_STATIC(StatusNotifierProxy, statusNotifierProxy) + +StatusNotifierProxy::StatusNotifierProxy() + : mWatcher(nullptr), + mWidgetCount(0), + mCreatingWatcher(false) +{ + 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(); + + connect(mWatcher, &StatusNotifierWatcher::StatusNotifierItemRegistered, + this, &StatusNotifierProxy::onStatusNotifierItemRegistered); + connect(mWatcher, &StatusNotifierWatcher::StatusNotifierItemUnregistered, + this, &StatusNotifierProxy::onStatusNotifierItemUnregistered); + + qDebug() << mWatcher->RegisteredStatusNotifierItems(); + + future_watcher->deleteLater(); + }); + + QFuture future = QtConcurrent::run([] + { + QString dbusName = QStringLiteral("org.kde.StatusNotifierHost-%1-%2").arg(QApplication::applicationPid()).arg(1); + if (QDBusConnectionInterface::ServiceNotRegistered == QDBusConnection::sessionBus().interface()->registerService(dbusName, QDBusConnectionInterface::DontQueueService)) + qDebug() << "unable to register service for " << dbusName; + + StatusNotifierWatcher * watcher = new StatusNotifierWatcher; + watcher->RegisterStatusNotifierHost(dbusName); + watcher->moveToThread(QApplication::instance()->thread()); + return watcher; + }); + + future_watcher->setFuture(future); +} + +void StatusNotifierProxy::watcherCreated() +{ + mCreatingWatcher = false; +} + +StatusNotifierProxy::~StatusNotifierProxy() +{ + qDebug() << "deleting Proxy"; +} + +StatusNotifierProxy *StatusNotifierProxy::instance() +{ + return statusNotifierProxy(); +} + +void StatusNotifierProxy::registerWidget(StatusNotifierWidget *widget) +{ + ++mWidgetCount; + if (nullptr == mWatcher && mCreatingWatcher == false) + 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); +} + +void StatusNotifierProxy::unregisterWidget(StatusNotifierWidget */*widget*/) +{ + --mWidgetCount; + if (mWidgetCount == 0) { + mWatcher->deleteLater(); + mWatcher = nullptr; + mServices.clear(); + } +} + +void StatusNotifierProxy::onStatusNotifierItemRegistered(const QString &service) +{ + QString temp(service); + mServices.append(temp); + emit StatusNotifierItemRegistered(temp); +} + +void StatusNotifierProxy::onStatusNotifierItemUnregistered(const QString &service) +{ + QString temp(service); + mServices.removeAll(temp); + emit StatusNotifierItemUnregistered(temp); +} diff --git a/plugin-statusnotifier/statusnotifierproxy.h b/plugin-statusnotifier/statusnotifierproxy.h new file mode 100644 index 000000000..1448584ab --- /dev/null +++ b/plugin-statusnotifier/statusnotifierproxy.h @@ -0,0 +1,63 @@ +/* BEGIN_COMMON_COPYRIGHT_HEADER + * (c)LGPL2+ + * + * LXQt - a lightweight, Qt based, desktop toolset + * https://lxqt.org + * + * Copyright: 2021 LXQt team + * + * This program or library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + * + * END_COMMON_COPYRIGHT_HEADER */ + +#ifndef STATUSNOTIFIERPROXY_H +#define STATUSNOTIFIERPROXY_H + + +#include +#include + +class StatusNotifierWidget; +class StatusNotifierWatcher; + +class StatusNotifierProxy : public QObject +{ + Q_OBJECT + +public: + StatusNotifierProxy(); + ~StatusNotifierProxy(); + static StatusNotifierProxy *instance(); + + void onStatusNotifierItemRegistered(const QString &service); + void onStatusNotifierItemUnregistered(const QString &service); + void registerWidget(StatusNotifierWidget *widget); + void unregisterWidget(StatusNotifierWidget *widget); + +private: + QStringList mServices; + StatusNotifierWatcher *mWatcher; + int mWidgetCount; + bool mCreatingWatcher; + void createWatcher(); + void watcherCreated(); + +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 f4097b374..c5a080b0f 100644 --- a/plugin-statusnotifier/statusnotifierwidget.cpp +++ b/plugin-statusnotifier/statusnotifierwidget.cpp @@ -27,17 +27,14 @@ * END_COMMON_COPYRIGHT_HEADER */ #include "statusnotifierwidget.h" -#include -#include -#include -#include -#include +#include "statusnotifierproxy.h" #include "../panel/pluginsettings.h" #include "../panel/ilxqtpanelplugin.h" StatusNotifierWidget::StatusNotifierWidget(ILXQtPanelPlugin *plugin, QWidget *parent) : QWidget(parent), mPlugin(plugin), + mProxy(StatusNotifierProxy::instance()), mAttentionPeriod(5), mForceVisible(false) { @@ -83,41 +80,13 @@ StatusNotifierWidget::StatusNotifierWidget(ILXQtPanelPlugin *plugin, QWidget *pa } }); - QFutureWatcher * future_watcher = new QFutureWatcher; - connect(future_watcher, &QFutureWatcher::finished, this, [this, future_watcher] - { - mWatcher = future_watcher->future().result(); - - connect(mWatcher, &StatusNotifierWatcher::StatusNotifierItemRegistered, - this, &StatusNotifierWidget::itemAdded); - connect(mWatcher, &StatusNotifierWatcher::StatusNotifierItemUnregistered, - this, &StatusNotifierWidget::itemRemoved); - - qDebug() << mWatcher->RegisteredStatusNotifierItems(); - - future_watcher->deleteLater(); - }); - - QFuture future = QtConcurrent::run([] - { - QString dbusName = QStringLiteral("org.kde.StatusNotifierHost-%1-%2").arg(QApplication::applicationPid()).arg(1); - if (QDBusConnectionInterface::ServiceNotRegistered == QDBusConnection::sessionBus().interface()->registerService(dbusName, QDBusConnectionInterface::DontQueueService)) - qDebug() << "unable to register service for " << dbusName; - - StatusNotifierWatcher * watcher = new StatusNotifierWatcher; - watcher->RegisterStatusNotifierHost(dbusName); - watcher->moveToThread(QApplication::instance()->thread()); - return watcher; - }); - - future_watcher->setFuture(future); - + mProxy->registerWidget(this); realign(); } StatusNotifierWidget::~StatusNotifierWidget() { - delete mWatcher; + mProxy->unregisterWidget(this); } void StatusNotifierWidget::leaveEvent(QEvent * /*event*/) diff --git a/plugin-statusnotifier/statusnotifierwidget.h b/plugin-statusnotifier/statusnotifierwidget.h index 28d2dcd70..83bcdf260 100644 --- a/plugin-statusnotifier/statusnotifierwidget.h +++ b/plugin-statusnotifier/statusnotifierwidget.h @@ -35,7 +35,8 @@ #include #include "statusnotifierbutton.h" -#include "statusnotifierwatcher.h" + +class StatusNotifierProxy; class StatusNotifierWidget : public QWidget { @@ -62,7 +63,7 @@ public slots: private: ILXQtPanelPlugin *mPlugin; - StatusNotifierWatcher *mWatcher; + StatusNotifierProxy *mProxy; QTimer mHideTimer;