Skip to content

Commit

Permalink
Add proxy singleton for StatusNotifier
Browse files Browse the repository at this point in the history
  • Loading branch information
elviosak authored and palinek committed Mar 9, 2022
1 parent e50d4b9 commit 003d337
Show file tree
Hide file tree
Showing 6 changed files with 204 additions and 38 deletions.
2 changes: 2 additions & 0 deletions plugin-statusnotifier/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ set(HEADERS
statusnotifierwatcher.h
statusnotifierwidget.h
sniasync.h
statusnotifierproxy.h
)

set(SOURCES
Expand All @@ -24,6 +25,7 @@ set(SOURCES
statusnotifierwatcher.cpp
statusnotifierwidget.cpp
sniasync.cpp
statusnotifierproxy.cpp
)

set(UIS
Expand Down
2 changes: 1 addition & 1 deletion plugin-statusnotifier/statusnotifier.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
131 changes: 131 additions & 0 deletions plugin-statusnotifier/statusnotifierproxy.cpp
Original file line number Diff line number Diff line change
@@ -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 <QApplication>
#include <QFutureWatcher>
#include <QtConcurrent>
#include <QDBusConnectionInterface>
#include <QDebug>

Q_GLOBAL_STATIC(StatusNotifierProxy, statusNotifierProxy)

StatusNotifierProxy::StatusNotifierProxy()
: mWatcher(nullptr),
mWidgetCount(0),
mCreatingWatcher(false)
{
createWatcher();
}

void StatusNotifierProxy::createWatcher()
{
mCreatingWatcher = true;
QFutureWatcher<StatusNotifierWatcher *> * future_watcher = new QFutureWatcher<StatusNotifierWatcher *>;
connect(future_watcher, &QFutureWatcher<StatusNotifierWatcher *>::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<StatusNotifierWatcher *> 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);
}
63 changes: 63 additions & 0 deletions plugin-statusnotifier/statusnotifierproxy.h
Original file line number Diff line number Diff line change
@@ -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 <QObject>
#include <QStringList>

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
39 changes: 4 additions & 35 deletions plugin-statusnotifier/statusnotifierwidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,17 +27,14 @@
* END_COMMON_COPYRIGHT_HEADER */

#include "statusnotifierwidget.h"
#include <QApplication>
#include <QDebug>
#include <QFutureWatcher>
#include <QtConcurrent>
#include <QDBusConnectionInterface>
#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)
{
Expand Down Expand Up @@ -83,41 +80,13 @@ StatusNotifierWidget::StatusNotifierWidget(ILXQtPanelPlugin *plugin, QWidget *pa
}
});

QFutureWatcher<StatusNotifierWatcher *> * future_watcher = new QFutureWatcher<StatusNotifierWatcher *>;
connect(future_watcher, &QFutureWatcher<StatusNotifierWatcher *>::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<StatusNotifierWatcher *> 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*/)
Expand Down
5 changes: 3 additions & 2 deletions plugin-statusnotifier/statusnotifierwidget.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@
#include <LXQt/GridLayout>

#include "statusnotifierbutton.h"
#include "statusnotifierwatcher.h"

class StatusNotifierProxy;

class StatusNotifierWidget : public QWidget
{
Expand All @@ -62,7 +63,7 @@ public slots:

private:
ILXQtPanelPlugin *mPlugin;
StatusNotifierWatcher *mWatcher;
StatusNotifierProxy *mProxy;

QTimer mHideTimer;

Expand Down

0 comments on commit 003d337

Please sign in to comment.