refactor: delay load XEmbed and SNI trays

Change-Id: Ia9d5684410a57192b228de9478bb3b87025e5b27
This commit is contained in:
listenerri 2019-01-15 18:03:43 +08:00
parent 75cb24488e
commit e96971aecd
Notes: gerrit 2019-01-15 18:14:55 +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 18:14:53 +0800
Reviewed-on: https://cr.deepin.io/41342
Project: dde/dde-dock
Branch: refs/heads/master
4 changed files with 79 additions and 55 deletions

View File

@ -42,11 +42,18 @@ using org::kde::StatusNotifierWatcher;
TrayPlugin::TrayPlugin(QObject *parent)
: QObject(parent),
m_trayInter(new DBusTrayManager(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)
{
m_fashionItem = new FashionTrayItem(this);
m_refreshXEmbedItemsTimer->setInterval(500);
m_refreshXEmbedItemsTimer->setSingleShot(true);
m_refreshSNIItemsTimer->setInterval(500);
m_refreshSNIItemsTimer->setSingleShot(true);
m_tipsLabel->setObjectName("tray");
m_tipsLabel->setText(tr("System Tray"));
@ -90,12 +97,6 @@ void TrayPlugin::init(PluginProxyInterface *proxyInter)
connect(m_dbusDaemonInterface, &QDBusConnectionInterface::serviceOwnerChanged, this, &TrayPlugin::onDbusNameOwnerChanged);
connect(m_sniWatcher, &StatusNotifierWatcher::StatusNotifierItemRegistered, this, &TrayPlugin::sniItemsChanged);
connect(m_sniWatcher, &StatusNotifierWatcher::StatusNotifierItemUnregistered, this, &TrayPlugin::sniItemsChanged);
connect(m_trayInter, &DBusTrayManager::TrayIconsChanged, this, &TrayPlugin::trayListChanged, Qt::QueuedConnection);
connect(m_trayInter, &DBusTrayManager::Changed, this, &TrayPlugin::trayChanged);
connect(m_systemTraysController, &SystemTraysController::systemTrayAdded, this, &TrayPlugin::addTrayWidget);
connect(m_systemTraysController, &SystemTraysController::systemTrayRemoved, this, [=](const QString &itemKey) {trayRemoved(itemKey);});
@ -103,10 +104,11 @@ void TrayPlugin::init(PluginProxyInterface *proxyInter)
switchToMode(displayMode());
QTimer::singleShot(0, this, &TrayPlugin::trayListChanged);
QTimer::singleShot(0, this, &TrayPlugin::loadIndicator);
QTimer::singleShot(0, this, &TrayPlugin::sniItemsChanged);
QTimer::singleShot(0, m_systemTraysController, &SystemTraysController::startLoader);
QTimer::singleShot(3000, this, &TrayPlugin::initSNI);
QTimer::singleShot(4000, this, &TrayPlugin::initXEmbed);
}
void TrayPlugin::displayModeChanged(const Dock::DisplayMode mode)
@ -275,6 +277,24 @@ QString TrayPlugin::itemKeyOfTrayWidget(AbstractTrayWidget *trayWidget)
return itemKey;
}
void TrayPlugin::initXEmbed()
{
connect(m_refreshXEmbedItemsTimer, &QTimer::timeout, this, &TrayPlugin::xembedItemsChanged);
connect(m_trayInter, &DBusTrayManager::TrayIconsChanged, this, [=] {m_refreshXEmbedItemsTimer->start();});
connect(m_trayInter, &DBusTrayManager::Changed, this, &TrayPlugin::xembedItemChanged);
m_refreshXEmbedItemsTimer->start();
}
void TrayPlugin::initSNI()
{
connect(m_refreshSNIItemsTimer, &QTimer::timeout, this, &TrayPlugin::sniItemsChanged);
connect(m_sniWatcher, &StatusNotifierWatcher::StatusNotifierItemRegistered, this, [=] {m_refreshSNIItemsTimer->start();});
connect(m_sniWatcher, &StatusNotifierWatcher::StatusNotifierItemUnregistered, this, [=] {m_refreshSNIItemsTimer->start();});
m_refreshSNIItemsTimer->start();
}
void TrayPlugin::sniItemsChanged()
{
const QStringList &itemServicePaths = m_sniWatcher->registeredStatusNotifierItems();
@ -300,23 +320,23 @@ void TrayPlugin::sniItemsChanged()
}
}
void TrayPlugin::trayListChanged()
void TrayPlugin::xembedItemsChanged()
{
QList<quint32> winidList = m_trayInter->trayIcons();
QStringList trayKeyList;
for (auto winid : winidList) {
trayKeyList << XWindowTrayWidget::toTrayWidgetId(winid);
trayKeyList << XEmbedTrayWidget::toXEmbedKey(winid);
}
for (auto tray : m_trayMap.keys()) {
if (!trayKeyList.contains(tray) && XWindowTrayWidget::isXWindowKey(tray)) {
if (!trayKeyList.contains(tray) && XEmbedTrayWidget::isXEmbedKey(tray)) {
trayRemoved(tray);
}
}
for (int i = 0; i < trayKeyList.size(); ++i) {
trayXWindowAdded(trayKeyList.at(i), winidList.at(i));
trayXEmbedAdded(trayKeyList.at(i), winidList.at(i));
}
}
@ -341,13 +361,13 @@ void TrayPlugin::addTrayWidget(const QString &itemKey, AbstractTrayWidget *trayW
connect(trayWidget, &AbstractTrayWidget::requestRefershWindowVisible, this, &TrayPlugin::onRequestRefershWindowVisible, Qt::UniqueConnection);
}
void TrayPlugin::trayXWindowAdded(const QString &itemKey, quint32 winId)
void TrayPlugin::trayXEmbedAdded(const QString &itemKey, quint32 winId)
{
if (m_trayMap.contains(itemKey) || !XWindowTrayWidget::isXWindowKey(itemKey)) {
if (m_trayMap.contains(itemKey) || !XEmbedTrayWidget::isXEmbedKey(itemKey)) {
return;
}
AbstractTrayWidget *trayWidget = new XWindowTrayWidget(winId);
AbstractTrayWidget *trayWidget = new XEmbedTrayWidget(winId);
addTrayWidget(itemKey, trayWidget);
}
@ -418,9 +438,9 @@ void TrayPlugin::trayRemoved(const QString &itemKey, const bool deleteObject)
}
}
void TrayPlugin::trayChanged(quint32 winId)
void TrayPlugin::xembedItemChanged(quint32 winId)
{
QString itemKey = XWindowTrayWidget::toTrayWidgetId(winId);
QString itemKey = XEmbedTrayWidget::toXEmbedKey(winId);
if (!m_trayMap.contains(itemKey)) {
return;
}

View File

@ -25,7 +25,7 @@
#include "pluginsiteminterface.h"
#include "dbus/dbustraymanager.h"
#include "xwindowtraywidget.h"
#include "xembedtraywidget.h"
#include "indicatortray.h"
#include "indicatortraywidget.h"
#include "snitraywidget.h"
@ -71,14 +71,16 @@ private:
QString itemKeyOfTrayWidget(AbstractTrayWidget *trayWidget);
private slots:
void initXEmbed();
void initSNI();
void addTrayWidget(const QString &itemKey, AbstractTrayWidget *trayWidget);
void sniItemsChanged();
void trayListChanged();
void trayXWindowAdded(const QString &itemKey, quint32 winId);
void xembedItemsChanged();
void trayXEmbedAdded(const QString &itemKey, quint32 winId);
void traySNIAdded(const QString &itemKey, const QString &sniServicePath);
void trayIndicatorAdded(const QString &itemKey);
void trayRemoved(const QString &itemKey, const bool deleteObject = true);
void trayChanged(quint32 winId);
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);
@ -91,6 +93,8 @@ private:
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;

View File

@ -19,7 +19,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "xwindowtraywidget.h"
#include "xembedtraywidget.h"
#include <QWindow>
#include <QPainter>
@ -74,7 +74,7 @@ void sni_cleanup_xcb_image(void *data)
xcb_image_destroy(static_cast<xcb_image_t*>(data));
}
XWindowTrayWidget::XWindowTrayWidget(quint32 winId, QWidget *parent)
XEmbedTrayWidget::XEmbedTrayWidget(quint32 winId, QWidget *parent)
: AbstractTrayWidget(parent)
, m_windowId(winId)
, m_appName(getAppNameForWindow(winId))
@ -89,37 +89,37 @@ XWindowTrayWidget::XWindowTrayWidget(quint32 winId, QWidget *parent)
m_sendHoverEvent->setInterval(100);
m_sendHoverEvent->setSingleShot(true);
connect(m_updateTimer, &QTimer::timeout, this, &XWindowTrayWidget::refershIconImage);
connect(m_updateTimer, &QTimer::timeout, this, &XEmbedTrayWidget::refershIconImage);
setMouseTracking(true);
connect(m_sendHoverEvent, &QTimer::timeout, this, &XWindowTrayWidget::sendHoverEvent);
connect(m_sendHoverEvent, &QTimer::timeout, this, &XEmbedTrayWidget::sendHoverEvent);
m_updateTimer->start();
}
XWindowTrayWidget::~XWindowTrayWidget()
XEmbedTrayWidget::~XEmbedTrayWidget()
{
AppWinidSuffixMap[m_appName].remove(m_windowId);
}
const QImage XWindowTrayWidget::trayImage()
const QImage XEmbedTrayWidget::trayImage()
{
return m_image;
}
QSize XWindowTrayWidget::sizeHint() const
QSize XEmbedTrayWidget::sizeHint() const
{
return QSize(26, 26);
}
void XWindowTrayWidget::showEvent(QShowEvent *e)
void XEmbedTrayWidget::showEvent(QShowEvent *e)
{
QWidget::showEvent(e);
m_updateTimer->start();
}
void XWindowTrayWidget::paintEvent(QPaintEvent *e)
void XEmbedTrayWidget::paintEvent(QPaintEvent *e)
{
Q_UNUSED(e);
if (m_image.isNull())
@ -140,7 +140,7 @@ void XWindowTrayWidget::paintEvent(QPaintEvent *e)
painter.end();
}
void XWindowTrayWidget::mouseMoveEvent(QMouseEvent *e)
void XEmbedTrayWidget::mouseMoveEvent(QMouseEvent *e)
{
AbstractTrayWidget::mouseMoveEvent(e);
@ -152,7 +152,7 @@ void XWindowTrayWidget::mouseMoveEvent(QMouseEvent *e)
m_sendHoverEvent->start();
}
void XWindowTrayWidget::configContainerPosition()
void XEmbedTrayWidget::configContainerPosition()
{
auto c = QX11Info::connection();
@ -172,7 +172,7 @@ void XWindowTrayWidget::configContainerPosition()
xcb_flush(c);
}
void XWindowTrayWidget::wrapWindow()
void XEmbedTrayWidget::wrapWindow()
{
auto c = QX11Info::connection();
@ -271,7 +271,7 @@ void XWindowTrayWidget::wrapWindow()
setX11PassMouseEvent(true);
}
void XWindowTrayWidget::sendHoverEvent()
void XEmbedTrayWidget::sendHoverEvent()
{
if (!rect().contains(mapFromGlobal(QCursor::pos()))) {
return;
@ -287,7 +287,7 @@ void XWindowTrayWidget::sendHoverEvent()
QTimer::singleShot(100, this, [=] { setX11PassMouseEvent(true); });
}
void XWindowTrayWidget::updateIcon()
void XEmbedTrayWidget::updateIcon()
{
// if (!isVisible() && !m_active)
// return;
@ -310,7 +310,7 @@ void XWindowTrayWidget::updateIcon()
// hide();
//}
void XWindowTrayWidget::sendClick(uint8_t mouseButton, int x, int y)
void XEmbedTrayWidget::sendClick(uint8_t mouseButton, int x, int y)
{
if (isBadWindow())
return;
@ -331,7 +331,7 @@ void XWindowTrayWidget::sendClick(uint8_t mouseButton, int x, int y)
}
// NOTE: WM_NAME may can not obtain successfully
QString XWindowTrayWidget::getWindowProperty(quint32 winId, QString propName)
QString XEmbedTrayWidget::getWindowProperty(quint32 winId, QString propName)
{
const auto display = QX11Info::display();
@ -363,7 +363,7 @@ QString XWindowTrayWidget::getWindowProperty(quint32 winId, QString propName)
return QString::fromLocal8Bit((char*)prop_return);
}
QString XWindowTrayWidget::toTrayWidgetId(quint32 winId)
QString XEmbedTrayWidget::toXEmbedKey(quint32 winId)
{
const QString &appName = getAppNameForWindow(winId);
int suffix = getTrayWidgetKeySuffix(appName, winId);
@ -378,18 +378,18 @@ QString XWindowTrayWidget::toTrayWidgetId(quint32 winId)
return key;
}
bool XWindowTrayWidget::isXWindowKey(const QString &itemKey)
bool XEmbedTrayWidget::isXEmbedKey(const QString &itemKey)
{
return itemKey.startsWith("window:");
}
void XWindowTrayWidget::setActive(const bool active)
void XEmbedTrayWidget::setActive(const bool active)
{
m_active = active;
m_updateTimer->start();
}
void XWindowTrayWidget::refershIconImage()
void XEmbedTrayWidget::refershIconImage()
{
const auto ratio = devicePixelRatioF();
auto c = QX11Info::connection();
@ -427,7 +427,7 @@ void XWindowTrayWidget::refershIconImage()
}
}
QString XWindowTrayWidget::getAppNameForWindow(quint32 winId)
QString XEmbedTrayWidget::getAppNameForWindow(quint32 winId)
{
QString appName;
do {
@ -450,7 +450,7 @@ QString XWindowTrayWidget::getAppNameForWindow(quint32 winId)
return appName;
}
int XWindowTrayWidget::getTrayWidgetKeySuffix(const QString &appName, quint32 winId)
int XEmbedTrayWidget::getTrayWidgetKeySuffix(const QString &appName, quint32 winId)
{
int suffix = AppWinidSuffixMap.value(appName).value(winId, 0);
@ -489,7 +489,7 @@ int XWindowTrayWidget::getTrayWidgetKeySuffix(const QString &appName, quint32 wi
return suffix;
}
void XWindowTrayWidget::setX11PassMouseEvent(const bool pass)
void XEmbedTrayWidget::setX11PassMouseEvent(const bool pass)
{
if (pass)
{
@ -511,7 +511,7 @@ void XWindowTrayWidget::setX11PassMouseEvent(const bool pass)
XFlush(QX11Info::display());
}
void XWindowTrayWidget::setWindowOnTop(const bool top)
void XEmbedTrayWidget::setWindowOnTop(const bool top)
{
auto c = QX11Info::connection();
const uint32_t stackAboveData[] = {top ? XCB_STACK_MODE_ABOVE : XCB_STACK_MODE_BELOW};
@ -519,7 +519,7 @@ void XWindowTrayWidget::setWindowOnTop(const bool top)
xcb_flush(c);
}
bool XWindowTrayWidget::isBadWindow()
bool XEmbedTrayWidget::isBadWindow()
{
auto c = QX11Info::connection();

View File

@ -19,21 +19,21 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef TRAYWIDGET_H
#define TRAYWIDGET_H
#ifndef XEMBEDTRAYWIDGET_H
#define XEMBEDTRAYWIDGET_H
#include "abstracttraywidget.h"
#include <QWidget>
#include <QTimer>
class XWindowTrayWidget : public AbstractTrayWidget
class XEmbedTrayWidget : public AbstractTrayWidget
{
Q_OBJECT
public:
explicit XWindowTrayWidget(quint32 winId, QWidget *parent = 0);
~XWindowTrayWidget();
explicit XEmbedTrayWidget(quint32 winId, QWidget *parent = 0);
~XEmbedTrayWidget();
void updateIcon() Q_DECL_OVERRIDE;
void setActive(const bool active) Q_DECL_OVERRIDE;
@ -41,8 +41,8 @@ public:
void sendClick(uint8_t mouseButton, int x, int y) Q_DECL_OVERRIDE;
static QString getWindowProperty(quint32 winId, QString propName);
static QString toTrayWidgetId(quint32 winId);
static bool isXWindowKey(const QString &itemKey);
static QString toXEmbedKey(quint32 winId);
static bool isXEmbedKey(const QString &itemKey);
private:
QSize sizeHint() const Q_DECL_OVERRIDE;
@ -75,4 +75,4 @@ private:
QTimer *m_sendHoverEvent;
};
#endif // TRAYWIDGET_H
#endif // XEMBEDTRAYWIDGET_H