refactor: make MainWindow to register sni host instead of tray plugin

Change-Id: I8f6b05ed69ced2d937aac8828a1adb3e77e79b07
This commit is contained in:
listenerri 2019-01-15 19:54:13 +08:00
parent e96971aecd
commit 2bc2f2e831
Notes: gerrit 2019-01-15 20:02:39 +08:00
Verified+1: <jenkins@deepin.com>
Code-Review+2: listenerri <listenerri@gmail.com>
Submitted-by: listenerri <listenerri@gmail.com>
Submitted-at: Tue, 15 Jan 2019 20:02:38 +0800
Reviewed-on: https://cr.deepin.io/41345
Project: dde/dde-dock
Branch: refs/heads/master
15 changed files with 47 additions and 378 deletions

View File

@ -35,6 +35,11 @@
#include <X11/X.h>
#include <X11/Xutil.h>
#define SNI_WATCHER_SERVICE "org.kde.StatusNotifierWatcher"
#define SNI_WATCHER_PATH "/StatusNotifierWatcher"
using org::kde::StatusNotifierWatcher;
const QPoint rawXPosition(const QPoint &scaledPos)
{
QRect g = qApp->primaryScreen()->geometry();
@ -87,8 +92,9 @@ MainWindow::MainWindow(QWidget *parent)
m_posChangeAni(new QVariantAnimation(this)),
m_panelShowAni(new QPropertyAnimation(m_mainPanel, "pos")),
m_panelHideAni(new QPropertyAnimation(m_mainPanel, "pos")),
m_xcbMisc(XcbMisc::instance())
m_xcbMisc(XcbMisc::instance()),
m_dbusDaemonInterface(QDBusConnection::sessionBus().interface()),
m_sniWatcher(new StatusNotifierWatcher(SNI_WATCHER_SERVICE, SNI_WATCHER_PATH, QDBusConnection::sessionBus(), this))
{
setAccessibleName("dock-mainwindow");
setWindowFlags(Qt::FramelessWindowHint | Qt::WindowDoesNotAcceptFocus);
@ -107,6 +113,7 @@ MainWindow::MainWindow(QWidget *parent)
m_settings = &DockSettings::Instance();
m_xcbMisc->set_window_type(winId(), XcbMisc::Dock);
initSNIHost();
initComponents();
initConnections();
@ -248,6 +255,21 @@ void MainWindow::internalAnimationMove(int x, int y)
m_posChangeAni->start();
}
void MainWindow::initSNIHost()
{
// registor dock as SNI Host on dbus
QDBusConnection dbusConn = QDBusConnection::sessionBus();
m_sniHostService = QString("org.kde.StatusNotifierHost-") + QString::number(qApp->applicationPid());
dbusConn.registerService(m_sniHostService);
dbusConn.registerObject("/StatusNotifierHost", this);
if (m_sniWatcher->isValid()) {
m_sniWatcher->RegisterStatusNotifierHost(m_sniHostService);
} else {
qDebug() << SNI_WATCHER_SERVICE << "SNI watcher daemon is not exist for now!";
}
}
void MainWindow::initComponents()
{
m_positionUpdateTimer->setSingleShot(true);
@ -364,6 +386,8 @@ void MainWindow::initConnections()
connect(m_wmHelper, &DWindowManagerHelper::hasCompositeChanged, this, &MainWindow::compositeChanged, Qt::QueuedConnection);
connect(&m_platformWindowHandle, &DPlatformWindowHandle::frameMarginsChanged, m_shadowMaskOptimizeTimer, static_cast<void (QTimer::*)()>(&QTimer::start));
connect(m_dbusDaemonInterface, &QDBusConnectionInterface::serviceOwnerChanged, this, &MainWindow::onDbusNameOwnerChanged);
}
const QPoint MainWindow::x11GetWindowPos()
@ -726,3 +750,13 @@ void MainWindow::positionCheck()
// this may cause some position error and animation caton
//internalMove();
}
void MainWindow::onDbusNameOwnerChanged(const QString &name, const QString &oldOwner, const QString &newOwner)
{
Q_UNUSED(oldOwner);
if (name == SNI_WATCHER_SERVICE && !newOwner.isEmpty()) {
qDebug() << SNI_WATCHER_SERVICE << "SNI watcher daemon started, register dock to watcher as SNI Host";
m_sniWatcher->RegisterStatusNotifierHost(m_sniHostService);
}
}

View File

@ -1,4 +1,4 @@
/*
/*
* Copyright (C) 2011 ~ 2018 Deepin Technology Co., Ltd.
*
* Author: sbw <sbw@sbw.so>
@ -25,6 +25,7 @@
#include "xcb/xcb_misc.h"
#include "dbus/dbusdisplay.h"
#include "dbus/dbusdockadaptors.h"
#include "dbus/sni/statusnotifierwatcher_interface.h"
#include "util/docksettings.h"
#include <QWidget>
@ -61,6 +62,7 @@ private:
void setFixedSize(const QSize &size);
void internalAnimationMove(int x, int y);
void initSNIHost();
void initComponents();
void initConnections();
@ -89,6 +91,8 @@ private slots:
void adjustShadowMask();
void positionCheck();
void onDbusNameOwnerChanged(const QString &name, const QString &oldOwner, const QString &newOwner);
private:
bool m_launched;
bool m_updatePanelVisible;
@ -108,6 +112,10 @@ private:
XcbMisc *m_xcbMisc;
DockSettings *m_settings;
QDBusConnectionInterface *m_dbusDaemonInterface;
org::kde::StatusNotifierWatcher *m_sniWatcher;
QString m_sniHostService;
};
#endif // MAINWINDOW_H

View File

@ -7,6 +7,7 @@ project(${PLUGIN_NAME})
file(GLOB_RECURSE SRCS "*.h" "*.cpp" "../../widgets/*.h" "../../widgets/*.cpp"
"../../frame/util/themeappicon.h" "../../frame/util/themeappicon.cpp"
"../../frame/util/dockpopupwindow.h" "../../frame/util/dockpopupwindow.cpp"
"../../frame/dbus/sni/*.h" "../../frame/dbus/sni/*.cpp"
"../../frame/dbus/dbusmenu.h" "../../frame/dbus/dbusmenu.cpp"
"../../frame/dbus/dbusmenumanager.h" "../../frame/dbus/dbusmenumanager.cpp")

View File

@ -1,65 +0,0 @@
/*
* This file was generated by qdbusxml2cpp version 0.8
* Command line was: qdbusxml2cpp watcher-inter.xml -a statusnotifierwatcheradapter -p statusnotifierwatcherproxy
*
* qdbusxml2cpp is Copyright (C) 2017 The Qt Company Ltd.
*
* This is an auto-generated file.
* Do not edit! All changes made to it will be lost.
*/
#include "statusnotifierwatcheradapter.h"
#include <QtCore/QMetaObject>
#include <QtCore/QByteArray>
#include <QtCore/QList>
#include <QtCore/QMap>
#include <QtCore/QString>
#include <QtCore/QStringList>
#include <QtCore/QVariant>
/*
* Implementation of adaptor class StatusNotifierWatcherAdaptor
*/
StatusNotifierWatcherAdaptor::StatusNotifierWatcherAdaptor(QObject *parent)
: QDBusAbstractAdaptor(parent)
{
// constructor
setAutoRelaySignals(true);
}
StatusNotifierWatcherAdaptor::~StatusNotifierWatcherAdaptor()
{
// destructor
}
bool StatusNotifierWatcherAdaptor::isStatusNotifierHostRegistered() const
{
// get the value of property IsStatusNotifierHostRegistered
return qvariant_cast< bool >(parent()->property("IsStatusNotifierHostRegistered"));
}
int StatusNotifierWatcherAdaptor::protocolVersion() const
{
// get the value of property ProtocolVersion
return qvariant_cast< int >(parent()->property("ProtocolVersion"));
}
QStringList StatusNotifierWatcherAdaptor::registeredStatusNotifierItems() const
{
// get the value of property RegisteredStatusNotifierItems
return qvariant_cast< QStringList >(parent()->property("RegisteredStatusNotifierItems"));
}
void StatusNotifierWatcherAdaptor::RegisterStatusNotifierHost(const QString &service)
{
// handle method call org.kde.StatusNotifierWatcher.RegisterStatusNotifierHost
QMetaObject::invokeMethod(parent(), "RegisterStatusNotifierHost", Q_ARG(QString, service));
}
void StatusNotifierWatcherAdaptor::RegisterStatusNotifierItem(const QString &service)
{
// handle method call org.kde.StatusNotifierWatcher.RegisterStatusNotifierItem
QMetaObject::invokeMethod(parent(), "RegisterStatusNotifierItem", Q_ARG(QString, service));
}

View File

@ -1,80 +0,0 @@
/*
* This file was generated by qdbusxml2cpp version 0.8
* Command line was: qdbusxml2cpp watcher-inter.xml -a statusnotifierwatcheradapter -p statusnotifierwatcherproxy
*
* qdbusxml2cpp is Copyright (C) 2017 The Qt Company Ltd.
*
* This is an auto-generated file.
* This file may have been hand-edited. Look for HAND-EDIT comments
* before re-generating it.
*/
#ifndef STATUSNOTIFIERWATCHERADAPTER_H
#define STATUSNOTIFIERWATCHERADAPTER_H
#include <QtCore/QObject>
#include <QtDBus/QtDBus>
QT_BEGIN_NAMESPACE
class QByteArray;
template<class T> class QList;
template<class Key, class Value> class QMap;
class QString;
class QStringList;
class QVariant;
QT_END_NAMESPACE
/*
* Adaptor class for interface org.kde.StatusNotifierWatcher
*/
class StatusNotifierWatcherAdaptor: public QDBusAbstractAdaptor
{
Q_OBJECT
Q_CLASSINFO("D-Bus Interface", "org.kde.StatusNotifierWatcher")
Q_CLASSINFO("D-Bus Introspection", ""
" <interface name=\"org.kde.StatusNotifierWatcher\">\n"
" <method name=\"RegisterStatusNotifierItem\">\n"
" <arg direction=\"in\" type=\"s\" name=\"service\"/>\n"
" </method>\n"
" <method name=\"RegisterStatusNotifierHost\">\n"
" <arg direction=\"in\" type=\"s\" name=\"service\"/>\n"
" </method>\n"
" <property access=\"read\" type=\"as\" name=\"RegisteredStatusNotifierItems\">\n"
" <annotation value=\"QStringList\" name=\"org.qtproject.QtDBus.QtTypeName.Out0\"/>\n"
" </property>\n"
" <property access=\"read\" type=\"b\" name=\"IsStatusNotifierHostRegistered\"/>\n"
" <property access=\"read\" type=\"i\" name=\"ProtocolVersion\"/>\n"
" <signal name=\"StatusNotifierItemRegistered\">\n"
" <arg type=\"s\"/>\n"
" </signal>\n"
" <signal name=\"StatusNotifierItemUnregistered\">\n"
" <arg type=\"s\"/>\n"
" </signal>\n"
" <signal name=\"StatusNotifierHostRegistered\"/>\n"
" <signal name=\"StatusNotifierHostUnregistered\"/>\n"
" </interface>\n"
"")
public:
StatusNotifierWatcherAdaptor(QObject *parent);
virtual ~StatusNotifierWatcherAdaptor();
public: // PROPERTIES
Q_PROPERTY(bool IsStatusNotifierHostRegistered READ isStatusNotifierHostRegistered)
bool isStatusNotifierHostRegistered() const;
Q_PROPERTY(int ProtocolVersion READ protocolVersion)
int protocolVersion() const;
Q_PROPERTY(QStringList RegisteredStatusNotifierItems READ registeredStatusNotifierItems)
QStringList registeredStatusNotifierItems() const;
public Q_SLOTS: // METHODS
void RegisterStatusNotifierHost(const QString &service);
void RegisterStatusNotifierItem(const QString &service);
Q_SIGNALS: // SIGNALS
void StatusNotifierHostRegistered();
void StatusNotifierHostUnregistered();
void StatusNotifierItemRegistered(const QString &in0);
void StatusNotifierItemUnregistered(const QString &in0);
};
#endif

View File

@ -1,131 +0,0 @@
/*
* Copyright (C) 2011 ~ 2018 Deepin Technology Co., Ltd.
*
* Author: listenerri <listenerri@gmail.com>
*
* Maintainer: listenerri <listenerri@gmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "statusnotifierwatcher.h"
#include <QDBusConnection>
#include <QDBusConnectionInterface>
#include <QDBusServiceWatcher>
#include <QDBusMessage>
#include <QDebug>
#include "dbus/sni/statusnotifierwatcheradapter.h"
#include "dbus/sni/statusnotifieritem_interface.h"
StatusNotifierWatcher::StatusNotifierWatcher(QObject *parent)
{
new StatusNotifierWatcherAdaptor(this);
QDBusConnection dbus = QDBusConnection::sessionBus();
dbus.registerObject(QStringLiteral("/StatusNotifierWatcher"), this);
dbus.registerService(QStringLiteral("org.kde.StatusNotifierWatcher"));
m_serviceWatcher = new QDBusServiceWatcher(this);
m_serviceWatcher->setConnection(dbus);
m_serviceWatcher->setWatchMode(QDBusServiceWatcher::WatchForUnregistration);
connect(m_serviceWatcher, &QDBusServiceWatcher::serviceUnregistered, this, &StatusNotifierWatcher::serviceUnregistered);
}
StatusNotifierWatcher::~StatusNotifierWatcher()
{
QDBusConnection dbus = QDBusConnection::sessionBus();
dbus.unregisterService(QStringLiteral("org.kde.StatusNotifierWatcher"));
}
void StatusNotifierWatcher::RegisterStatusNotifierItem(const QString &serviceOrPath)
{
QString service;
QString path;
if (serviceOrPath.startsWith(QLatin1Char('/'))) {
service = message().service();
path = serviceOrPath;
} else {
service = serviceOrPath;
path = QStringLiteral("/StatusNotifierItem");
}
QString notifierItemId = service + path;
if (QDBusConnection::sessionBus().interface()->isServiceRegistered(service).value() &&
!m_registeredServices.contains(notifierItemId)) {
qDebug()<<"Registering" << notifierItemId << "to tray";
//check if the service has registered a Tray object
com::deepin::dde::StatusNotifierItem trayclient(service, path,
QDBusConnection::sessionBus());
if (trayclient.isValid()) {
m_registeredServices.append(notifierItemId);
m_serviceWatcher->addWatchedService(service);
emit StatusNotifierItemRegistered(notifierItemId);
}
}
}
QStringList StatusNotifierWatcher::RegisteredStatusNotifierItems() const
{
return m_registeredServices;
}
void StatusNotifierWatcher::serviceUnregistered(const QString& name)
{
qDebug()<<"Service "<< name << "unregistered";
m_serviceWatcher->removeWatchedService(name);
QString match = name + QLatin1Char('/');
QStringList::Iterator it = m_registeredServices.begin();
while (it != m_registeredServices.end()) {
if (it->startsWith(match)) {
QString name = *it;
it = m_registeredServices.erase(it);
emit StatusNotifierItemUnregistered(name);
} else {
++it;
}
}
if (m_statusNotifierHostServices.contains(name)) {
m_statusNotifierHostServices.remove(name);
emit StatusNotifierHostUnregistered();
}
}
void StatusNotifierWatcher::RegisterStatusNotifierHost(const QString &service)
{
if (service.contains(QStringLiteral("org.kde.StatusNotifierHost-")) &&
QDBusConnection::sessionBus().interface()->isServiceRegistered(service).value() &&
!m_statusNotifierHostServices.contains(service)) {
qDebug()<<"Registering"<<service<<"as tray";
m_statusNotifierHostServices.insert(service);
m_serviceWatcher->addWatchedService(service);
emit StatusNotifierHostRegistered();
}
}
bool StatusNotifierWatcher::IsStatusNotifierHostRegistered() const
{
return !m_statusNotifierHostServices.isEmpty();
}
int StatusNotifierWatcher::ProtocolVersion() const
{
return 0;
}

View File

@ -1,70 +0,0 @@
/*
* Copyright (C) 2011 ~ 2018 Deepin Technology Co., Ltd.
*
* Author: listenerri <listenerri@gmail.com>
*
* Maintainer: listenerri <listenerri@gmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef STATUSNOTIFIERWATCHER_H
#define STATUSNOTIFIERWATCHER_H
#include <QDBusContext>
#include <QObject>
#include <QStringList>
#include <QSet>
class QDBusServiceWatcher;
class StatusNotifierWatcher : public QObject, protected QDBusContext
{
Q_OBJECT
Q_PROPERTY(QStringList RegisteredStatusNotifierItems READ RegisteredStatusNotifierItems)
Q_PROPERTY(bool IsStatusNotifierHostRegistered READ IsStatusNotifierHostRegistered)
Q_PROPERTY(int ProtocolVersion READ ProtocolVersion)
public:
StatusNotifierWatcher(QObject *parent);
~StatusNotifierWatcher();
QStringList RegisteredStatusNotifierItems() const;
bool IsStatusNotifierHostRegistered() const;
int ProtocolVersion() const;
public Q_SLOTS:
void RegisterStatusNotifierItem(const QString &service);
void RegisterStatusNotifierHost(const QString &service);
protected Q_SLOTS:
void serviceUnregistered(const QString& name);
Q_SIGNALS:
void StatusNotifierItemRegistered(const QString &service);
//TODO: decide if this makes sense, the systray itself could notice the vanishing of items, but looks complete putting it here
void StatusNotifierItemUnregistered(const QString &service);
void StatusNotifierHostRegistered();
void StatusNotifierHostUnregistered();
private:
QDBusServiceWatcher *m_serviceWatcher = nullptr;
QStringList m_registeredServices;
QSet<QString> m_statusNotifierHostServices;
};
#endif

View File

@ -42,9 +42,9 @@ using org::kde::StatusNotifierWatcher;
TrayPlugin::TrayPlugin(QObject *parent)
: QObject(parent),
m_trayInter(new DBusTrayManager(this)),
m_sniWatcher(new StatusNotifierWatcher(SNI_WATCHER_SERVICE, SNI_WATCHER_PATH, QDBusConnection::sessionBus(), this)),
m_fashionItem (new FashionTrayItem(this)),
m_systemTraysController(new SystemTraysController(this)),
m_dbusDaemonInterface(QDBusConnection::sessionBus().interface()),
m_refreshXEmbedItemsTimer(new QTimer(this)),
m_refreshSNIItemsTimer(new QTimer(this)),
m_tipsLabel(new TipsWidget)
@ -82,21 +82,6 @@ void TrayPlugin::init(PluginProxyInterface *proxyInter)
return;
}
// registor dock as SNI Host on dbus
QDBusConnection dbusConn = QDBusConnection::sessionBus();
m_sniHostService = QString("org.kde.StatusNotifierHost-") + QString::number(qApp->applicationPid());
dbusConn.registerService(m_sniHostService);
dbusConn.registerObject("/StatusNotifierHost", this);
m_sniWatcher = new StatusNotifierWatcher(SNI_WATCHER_SERVICE, SNI_WATCHER_PATH, QDBusConnection::sessionBus(), this);
if (m_sniWatcher->isValid()) {
m_sniWatcher->RegisterStatusNotifierHost(m_sniHostService);
} else {
qDebug() << "Tray:" << SNI_WATCHER_SERVICE << "SNI watcher daemon is not exist for now!";
}
connect(m_dbusDaemonInterface, &QDBusConnectionInterface::serviceOwnerChanged, this, &TrayPlugin::onDbusNameOwnerChanged);
connect(m_systemTraysController, &SystemTraysController::systemTrayAdded, this, &TrayPlugin::addTrayWidget);
connect(m_systemTraysController, &SystemTraysController::systemTrayRemoved, this, [=](const QString &itemKey) {trayRemoved(itemKey);});
@ -469,16 +454,6 @@ void TrayPlugin::switchToMode(const Dock::DisplayMode mode)
}
}
void TrayPlugin::onDbusNameOwnerChanged(const QString &name, const QString &oldOwner, const QString &newOwner)
{
Q_UNUSED(oldOwner);
if (name == SNI_WATCHER_SERVICE && !newOwner.isEmpty()) {
qDebug() << "Tray:" << SNI_WATCHER_SERVICE << "SNI watcher daemon started, register dock to watcher as SNI Host";
m_sniWatcher->RegisterStatusNotifierHost(m_sniHostService);
}
}
void TrayPlugin::onRequestWindowAutoHide(const bool autoHide)
{
const QString &itemKey = itemKeyOfTrayWidget(static_cast<AbstractTrayWidget *>(sender()));

View File

@ -82,7 +82,6 @@ private slots:
void trayRemoved(const QString &itemKey, const bool deleteObject = true);
void xembedItemChanged(quint32 winId);
void switchToMode(const Dock::DisplayMode mode);
void onDbusNameOwnerChanged(const QString &name, const QString &oldOwner, const QString &newOwner);
void onRequestWindowAutoHide(const bool autoHide);
void onRequestRefershWindowVisible();
void onSNIItemStatusChanged(SNITrayWidget::ItemStatus status);
@ -92,14 +91,12 @@ private:
org::kde::StatusNotifierWatcher *m_sniWatcher;
FashionTrayItem *m_fashionItem;
SystemTraysController *m_systemTraysController;
QDBusConnectionInterface *m_dbusDaemonInterface;
QTimer *m_refreshXEmbedItemsTimer;
QTimer *m_refreshSNIItemsTimer;
QMap<QString, AbstractTrayWidget *> m_trayMap;
QMap<QString, SNITrayWidget *> m_passiveSNITrayMap;
QMap<QString, IndicatorTray*> m_indicatorMap;
QString m_sniHostService;
TipsWidget *m_tipsLabel;
};