2023-02-16 13:51:55 +08:00
|
|
|
|
// Copyright (C) 2011 ~ 2018 Deepin Technology Co., Ltd.
|
|
|
|
|
// SPDX-FileCopyrightText: 2018 - 2023 UnionTech Software Technology Co., Ltd.
|
2022-09-06 11:36:55 +08:00
|
|
|
|
//
|
|
|
|
|
// SPDX-License-Identifier: LGPL-3.0-or-later
|
2017-09-18 14:33:44 +08:00
|
|
|
|
|
2018-11-13 20:07:52 +08:00
|
|
|
|
#include "trayplugin.h"
|
2018-12-27 16:54:49 +08:00
|
|
|
|
#include "fashiontray/fashiontrayitem.h"
|
2018-08-16 10:05:16 +08:00
|
|
|
|
#include "snitraywidget.h"
|
2021-03-20 12:10:45 +08:00
|
|
|
|
#include "utils.h"
|
2021-11-05 21:25:06 +08:00
|
|
|
|
#include "../widgets/tipswidget.h"
|
2016-06-28 14:23:30 +08:00
|
|
|
|
|
2017-12-28 19:23:50 +08:00
|
|
|
|
#include <QDir>
|
2016-06-28 17:11:29 +08:00
|
|
|
|
#include <QWindow>
|
|
|
|
|
#include <QWidget>
|
2016-08-15 14:11:19 +08:00
|
|
|
|
#include <QX11Info>
|
2020-09-09 13:07:05 +08:00
|
|
|
|
#include <QtConcurrent>
|
|
|
|
|
#include <QFuture>
|
|
|
|
|
#include <QFutureWatcher>
|
2016-08-15 14:11:19 +08:00
|
|
|
|
|
2021-11-05 21:25:06 +08:00
|
|
|
|
#include <xcb/xcb_icccm.h>
|
|
|
|
|
#include <X11/Xlib.h>
|
2016-06-28 17:11:29 +08:00
|
|
|
|
|
2019-01-30 18:00:46 +08:00
|
|
|
|
#define PLUGIN_ENABLED_KEY "enable"
|
2018-11-27 11:37:39 +08:00
|
|
|
|
#define FASHION_MODE_TRAYS_SORTED "fashion-mode-trays-sorted"
|
2016-06-28 17:11:29 +08:00
|
|
|
|
|
2018-11-29 10:24:58 +08:00
|
|
|
|
#define SNI_WATCHER_SERVICE "org.kde.StatusNotifierWatcher"
|
|
|
|
|
#define SNI_WATCHER_PATH "/StatusNotifierWatcher"
|
|
|
|
|
|
2021-12-01 12:22:31 +08:00
|
|
|
|
#define REGISTERTED_WAY_IS_SNI 1
|
|
|
|
|
#define REGISTERTED_WAY_IS_XEMBED 2
|
|
|
|
|
|
2018-11-29 10:24:58 +08:00
|
|
|
|
using org::kde::StatusNotifierWatcher;
|
2020-06-29 15:35:51 +08:00
|
|
|
|
using namespace Dock;
|
2021-11-05 21:25:06 +08:00
|
|
|
|
|
2018-11-13 20:07:52 +08:00
|
|
|
|
TrayPlugin::TrayPlugin(QObject *parent)
|
2019-06-28 16:58:31 +08:00
|
|
|
|
: QObject(parent)
|
2019-11-22 13:09:58 +08:00
|
|
|
|
, m_pluginLoaded(false)
|
2021-11-05 21:25:06 +08:00
|
|
|
|
, xcb_connection(nullptr)
|
|
|
|
|
, m_display(nullptr)
|
2016-06-28 14:23:30 +08:00
|
|
|
|
{
|
2021-11-05 21:25:06 +08:00
|
|
|
|
if (Utils::IS_WAYLAND_DISPLAY) {
|
|
|
|
|
int screenp = 0;
|
|
|
|
|
xcb_connection = xcb_connect(qgetenv("DISPLAY"), &screenp);
|
|
|
|
|
m_display = XOpenDisplay(nullptr);
|
|
|
|
|
}
|
2016-06-28 14:23:30 +08:00
|
|
|
|
}
|
|
|
|
|
|
2018-11-13 20:07:52 +08:00
|
|
|
|
const QString TrayPlugin::pluginName() const
|
2016-06-28 14:23:30 +08:00
|
|
|
|
{
|
2018-11-20 14:04:16 +08:00
|
|
|
|
return "tray";
|
2016-06-28 14:23:30 +08:00
|
|
|
|
}
|
|
|
|
|
|
2018-11-13 20:07:52 +08:00
|
|
|
|
void TrayPlugin::init(PluginProxyInterface *proxyInter)
|
2016-06-28 14:23:30 +08:00
|
|
|
|
{
|
2018-11-08 11:39:26 +08:00
|
|
|
|
// transfex config
|
|
|
|
|
QSettings settings("deepin", "dde-dock-shutdown");
|
|
|
|
|
if (QFile::exists(settings.fileName())) {
|
|
|
|
|
proxyInter->saveValue(this, "enable", settings.value("enable", true));
|
|
|
|
|
|
|
|
|
|
QFile::remove(settings.fileName());
|
|
|
|
|
}
|
|
|
|
|
|
2018-12-07 10:40:03 +08:00
|
|
|
|
m_proxyInter = proxyInter;
|
|
|
|
|
|
2019-01-30 18:00:46 +08:00
|
|
|
|
if (pluginIsDisable()) {
|
2018-06-06 17:29:22 +08:00
|
|
|
|
qDebug() << "hide tray from config disable!!";
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2019-11-22 13:09:58 +08:00
|
|
|
|
if (m_pluginLoaded) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
m_pluginLoaded = true;
|
|
|
|
|
|
2019-06-28 16:58:31 +08:00
|
|
|
|
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_refreshXEmbedItemsTimer = new QTimer(this);
|
|
|
|
|
m_refreshSNIItemsTimer = new QTimer(this);
|
|
|
|
|
|
|
|
|
|
m_refreshXEmbedItemsTimer->setInterval(0);
|
|
|
|
|
m_refreshXEmbedItemsTimer->setSingleShot(true);
|
|
|
|
|
|
|
|
|
|
m_refreshSNIItemsTimer->setInterval(0);
|
|
|
|
|
m_refreshSNIItemsTimer->setSingleShot(true);
|
|
|
|
|
|
2019-01-30 15:55:25 +08:00
|
|
|
|
connect(m_systemTraysController, &SystemTraysController::pluginItemAdded, this, &TrayPlugin::addTrayWidget);
|
2019-12-02 15:01:38 +08:00
|
|
|
|
connect(m_systemTraysController, &SystemTraysController::pluginItemRemoved, this, [ = ](const QString & itemKey) { trayRemoved(itemKey); });
|
2018-10-23 20:06:46 +08:00
|
|
|
|
|
2017-07-06 14:51:30 +08:00
|
|
|
|
m_trayInter->Manage();
|
2016-06-28 19:35:19 +08:00
|
|
|
|
|
|
|
|
|
switchToMode(displayMode());
|
2017-07-06 14:51:30 +08:00
|
|
|
|
|
2021-10-21 20:52:43 +08:00
|
|
|
|
// 加载sni,xem,自定义indicator协议以及其他托盘插件
|
2018-11-13 20:07:52 +08:00
|
|
|
|
QTimer::singleShot(0, this, &TrayPlugin::loadIndicator);
|
2019-06-25 18:41:46 +08:00
|
|
|
|
QTimer::singleShot(0, this, &TrayPlugin::initSNI);
|
|
|
|
|
QTimer::singleShot(0, this, &TrayPlugin::initXEmbed);
|
2016-06-28 19:35:19 +08:00
|
|
|
|
}
|
|
|
|
|
|
2019-01-30 18:00:46 +08:00
|
|
|
|
bool TrayPlugin::pluginIsDisable()
|
|
|
|
|
{
|
2019-07-02 14:42:10 +08:00
|
|
|
|
// NOTE(justforlxz): local config
|
|
|
|
|
QSettings enableSetting("deepin", "dde-dock");
|
|
|
|
|
enableSetting.beginGroup("tray");
|
|
|
|
|
if (!enableSetting.value("enable", true).toBool()) {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2019-12-02 15:01:38 +08:00
|
|
|
|
if (!m_proxyInter)
|
|
|
|
|
return true;
|
|
|
|
|
|
2019-01-30 18:00:46 +08:00
|
|
|
|
return !m_proxyInter->getValue(this, PLUGIN_ENABLED_KEY, true).toBool();
|
|
|
|
|
}
|
|
|
|
|
|
2018-11-13 20:07:52 +08:00
|
|
|
|
void TrayPlugin::displayModeChanged(const Dock::DisplayMode mode)
|
2016-06-28 19:35:19 +08:00
|
|
|
|
{
|
2021-12-31 15:09:12 +08:00
|
|
|
|
Q_UNUSED(mode);
|
|
|
|
|
|
2019-01-30 18:00:46 +08:00
|
|
|
|
if (pluginIsDisable()) {
|
2018-06-11 11:51:43 +08:00
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2019-08-27 19:31:49 +08:00
|
|
|
|
switchToMode(displayMode());
|
2016-06-28 17:11:29 +08:00
|
|
|
|
}
|
|
|
|
|
|
2018-11-13 20:07:52 +08:00
|
|
|
|
void TrayPlugin::positionChanged(const Dock::Position position)
|
2018-10-16 14:33:06 +08:00
|
|
|
|
{
|
2019-01-30 18:00:46 +08:00
|
|
|
|
if (pluginIsDisable()) {
|
2018-12-07 10:40:03 +08:00
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2018-12-27 16:54:49 +08:00
|
|
|
|
m_fashionItem->setDockPosition(position);
|
2018-10-16 14:33:06 +08:00
|
|
|
|
}
|
|
|
|
|
|
2018-11-13 20:07:52 +08:00
|
|
|
|
QWidget *TrayPlugin::itemWidget(const QString &itemKey)
|
2016-06-28 17:11:29 +08:00
|
|
|
|
{
|
2018-12-28 17:00:29 +08:00
|
|
|
|
if (itemKey == FASHION_MODE_ITEM_KEY) {
|
2016-06-28 19:35:19 +08:00
|
|
|
|
return m_fashionItem;
|
2017-12-28 19:23:50 +08:00
|
|
|
|
}
|
2016-06-28 17:11:29 +08:00
|
|
|
|
|
2018-10-23 20:06:46 +08:00
|
|
|
|
return m_trayMap.value(itemKey);
|
2016-06-28 17:11:29 +08:00
|
|
|
|
}
|
|
|
|
|
|
2018-11-13 20:07:52 +08:00
|
|
|
|
QWidget *TrayPlugin::itemTipsWidget(const QString &itemKey)
|
2016-09-20 14:34:38 +08:00
|
|
|
|
{
|
|
|
|
|
Q_UNUSED(itemKey);
|
|
|
|
|
|
2017-12-22 17:36:56 +08:00
|
|
|
|
return nullptr;
|
2016-09-20 14:34:38 +08:00
|
|
|
|
}
|
|
|
|
|
|
2018-11-13 20:07:52 +08:00
|
|
|
|
QWidget *TrayPlugin::itemPopupApplet(const QString &itemKey)
|
2016-07-11 10:19:21 +08:00
|
|
|
|
{
|
2018-11-13 20:07:52 +08:00
|
|
|
|
Q_UNUSED(itemKey);
|
2016-07-11 10:19:21 +08:00
|
|
|
|
|
2018-11-13 20:07:52 +08:00
|
|
|
|
return nullptr;
|
2016-07-11 10:19:21 +08:00
|
|
|
|
}
|
|
|
|
|
|
2018-11-13 20:07:52 +08:00
|
|
|
|
int TrayPlugin::itemSortKey(const QString &itemKey)
|
2016-08-15 14:11:19 +08:00
|
|
|
|
{
|
2018-11-21 17:14:07 +08:00
|
|
|
|
// 如果是系统托盘图标则调用内部插件的相应接口
|
|
|
|
|
if (isSystemTrayItem(itemKey)) {
|
|
|
|
|
return m_systemTraysController->systemTrayItemSortKey(itemKey);
|
|
|
|
|
}
|
|
|
|
|
|
2020-06-13 19:19:30 +08:00
|
|
|
|
const int defaultSort = 0;
|
2019-03-18 20:15:32 +08:00
|
|
|
|
|
2019-12-02 15:01:38 +08:00
|
|
|
|
AbstractTrayWidget *const trayWidget = m_trayMap.value(itemKey, nullptr);
|
2019-03-18 20:15:32 +08:00
|
|
|
|
if (trayWidget == nullptr) {
|
|
|
|
|
return defaultSort;
|
|
|
|
|
}
|
|
|
|
|
|
2020-01-11 10:35:29 +08:00
|
|
|
|
const QString key = QString("pos_%1_%2").arg(trayWidget->itemKeyForConfig()).arg(Dock::Efficient);
|
2018-09-06 10:42:27 +08:00
|
|
|
|
|
2019-03-18 20:15:32 +08:00
|
|
|
|
return m_proxyInter->getValue(this, key, defaultSort).toInt();
|
2018-03-06 15:18:53 +08:00
|
|
|
|
}
|
2016-09-06 14:51:11 +08:00
|
|
|
|
|
2018-11-13 20:07:52 +08:00
|
|
|
|
void TrayPlugin::setSortKey(const QString &itemKey, const int order)
|
2018-03-06 15:18:53 +08:00
|
|
|
|
{
|
2018-11-27 11:37:39 +08:00
|
|
|
|
if (displayMode() == Dock::DisplayMode::Fashion && !traysSortedInFashionMode()) {
|
|
|
|
|
m_proxyInter->saveValue(this, FASHION_MODE_TRAYS_SORTED, true);
|
|
|
|
|
}
|
|
|
|
|
|
2018-11-21 17:14:07 +08:00
|
|
|
|
// 如果是系统托盘图标则调用内部插件的相应接口
|
|
|
|
|
if (isSystemTrayItem(itemKey)) {
|
|
|
|
|
return m_systemTraysController->setSystemTrayItemSortKey(itemKey, order);
|
|
|
|
|
}
|
|
|
|
|
|
2019-12-02 15:01:38 +08:00
|
|
|
|
AbstractTrayWidget *const trayWidget = m_trayMap.value(itemKey, nullptr);
|
2019-03-18 20:15:32 +08:00
|
|
|
|
if (trayWidget == nullptr) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2020-01-11 10:35:29 +08:00
|
|
|
|
const QString key = QString("pos_%1_%2").arg(trayWidget->itemKeyForConfig()).arg(Dock::Efficient);
|
2018-11-08 11:39:26 +08:00
|
|
|
|
m_proxyInter->saveValue(this, key, order);
|
2016-09-06 14:51:11 +08:00
|
|
|
|
}
|
2016-08-15 14:11:19 +08:00
|
|
|
|
|
2018-12-06 18:05:30 +08:00
|
|
|
|
void TrayPlugin::refreshIcon(const QString &itemKey)
|
|
|
|
|
{
|
2018-12-28 17:00:29 +08:00
|
|
|
|
if (itemKey == FASHION_MODE_ITEM_KEY) {
|
2018-12-06 18:05:30 +08:00
|
|
|
|
for (auto trayWidget : m_trayMap.values()) {
|
|
|
|
|
if (trayWidget) {
|
|
|
|
|
trayWidget->updateIcon();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2019-12-02 15:01:38 +08:00
|
|
|
|
AbstractTrayWidget *const trayWidget = m_trayMap.value(itemKey);
|
2018-12-06 18:05:30 +08:00
|
|
|
|
if (trayWidget) {
|
|
|
|
|
trayWidget->updateIcon();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-01-30 18:00:46 +08:00
|
|
|
|
void TrayPlugin::pluginSettingsChanged()
|
|
|
|
|
{
|
|
|
|
|
if (pluginIsDisable()) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (displayMode() == Dock::DisplayMode::Fashion) {
|
|
|
|
|
m_fashionItem->onPluginSettingsChanged();
|
|
|
|
|
m_fashionItem->clearTrayWidgets();
|
|
|
|
|
m_fashionItem->setTrayWidgets(m_trayMap);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2018-11-21 15:11:01 +08:00
|
|
|
|
Dock::Position TrayPlugin::dockPosition() const
|
|
|
|
|
{
|
|
|
|
|
return position();
|
|
|
|
|
}
|
|
|
|
|
|
2018-11-27 11:37:39 +08:00
|
|
|
|
bool TrayPlugin::traysSortedInFashionMode()
|
|
|
|
|
{
|
|
|
|
|
return m_proxyInter->getValue(this, FASHION_MODE_TRAYS_SORTED, false).toBool();
|
|
|
|
|
}
|
|
|
|
|
|
2018-12-28 17:00:29 +08:00
|
|
|
|
void TrayPlugin::saveValue(const QString &itemKey, const QString &key, const QVariant &value)
|
2018-11-30 18:38:09 +08:00
|
|
|
|
{
|
2018-12-28 17:00:29 +08:00
|
|
|
|
// 如果是系统托盘图标则调用内部插件的相应接口
|
|
|
|
|
if (isSystemTrayItem(itemKey)) {
|
|
|
|
|
return m_systemTraysController->saveValueSystemTrayItem(itemKey, key, value);
|
|
|
|
|
}
|
|
|
|
|
|
2018-11-30 18:38:09 +08:00
|
|
|
|
m_proxyInter->saveValue(this, key, value);
|
|
|
|
|
}
|
|
|
|
|
|
2018-12-28 17:00:29 +08:00
|
|
|
|
const QVariant TrayPlugin::getValue(const QString &itemKey, const QString &key, const QVariant &fallback)
|
2018-11-30 18:38:09 +08:00
|
|
|
|
{
|
2018-12-28 17:00:29 +08:00
|
|
|
|
// 如果是系统托盘图标则调用内部插件的相应接口
|
|
|
|
|
if (isSystemTrayItem(itemKey)) {
|
|
|
|
|
return m_systemTraysController->getValueSystemTrayItem(itemKey, key, fallback);
|
|
|
|
|
}
|
|
|
|
|
|
2018-12-20 09:56:36 +08:00
|
|
|
|
return m_proxyInter->getValue(this, key, fallback);
|
2018-11-30 18:38:09 +08:00
|
|
|
|
}
|
|
|
|
|
|
2018-11-21 17:14:07 +08:00
|
|
|
|
bool TrayPlugin::isSystemTrayItem(const QString &itemKey)
|
|
|
|
|
{
|
2019-12-02 15:01:38 +08:00
|
|
|
|
AbstractTrayWidget *const trayWidget = m_trayMap.value(itemKey, nullptr);
|
2018-11-21 17:14:07 +08:00
|
|
|
|
|
|
|
|
|
if (trayWidget && trayWidget->trayTyep() == AbstractTrayWidget::TrayType::SystemTray) {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2018-12-03 18:16:39 +08:00
|
|
|
|
QString TrayPlugin::itemKeyOfTrayWidget(AbstractTrayWidget *trayWidget)
|
|
|
|
|
{
|
|
|
|
|
QString itemKey;
|
|
|
|
|
|
|
|
|
|
if (displayMode() == Dock::DisplayMode::Fashion) {
|
2018-12-28 17:00:29 +08:00
|
|
|
|
itemKey = FASHION_MODE_ITEM_KEY;
|
2018-12-03 18:16:39 +08:00
|
|
|
|
} else {
|
|
|
|
|
itemKey = m_trayMap.key(trayWidget);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return itemKey;
|
|
|
|
|
}
|
|
|
|
|
|
2019-08-27 19:31:49 +08:00
|
|
|
|
Dock::DisplayMode TrayPlugin::displayMode()
|
|
|
|
|
{
|
|
|
|
|
return Dock::DisplayMode::Fashion;
|
|
|
|
|
}
|
|
|
|
|
|
2019-01-15 18:03:43 +08:00
|
|
|
|
void TrayPlugin::initXEmbed()
|
|
|
|
|
{
|
|
|
|
|
connect(m_refreshXEmbedItemsTimer, &QTimer::timeout, this, &TrayPlugin::xembedItemsChanged);
|
2019-12-02 15:01:38 +08:00
|
|
|
|
connect(m_trayInter, &DBusTrayManager::TrayIconsChanged, this, [ = ] {m_refreshXEmbedItemsTimer->start();});
|
2019-01-15 18:03:43 +08:00
|
|
|
|
connect(m_trayInter, &DBusTrayManager::Changed, this, &TrayPlugin::xembedItemChanged);
|
|
|
|
|
|
|
|
|
|
m_refreshXEmbedItemsTimer->start();
|
|
|
|
|
}
|
|
|
|
|
|
2021-05-13 11:39:46 +08:00
|
|
|
|
/**
|
|
|
|
|
* @brief TrayPlugin::initSNI
|
|
|
|
|
* @note 初始化监听信号绑定
|
|
|
|
|
*/
|
2019-01-15 18:03:43 +08:00
|
|
|
|
void TrayPlugin::initSNI()
|
|
|
|
|
{
|
|
|
|
|
connect(m_refreshSNIItemsTimer, &QTimer::timeout, this, &TrayPlugin::sniItemsChanged);
|
2019-12-02 15:01:38 +08:00
|
|
|
|
connect(m_sniWatcher, &StatusNotifierWatcher::StatusNotifierItemRegistered, this, [ = ] {m_refreshSNIItemsTimer->start();});
|
|
|
|
|
connect(m_sniWatcher, &StatusNotifierWatcher::StatusNotifierItemUnregistered, this, [ = ] {m_refreshSNIItemsTimer->start();});
|
2019-01-15 18:03:43 +08:00
|
|
|
|
|
|
|
|
|
m_refreshSNIItemsTimer->start();
|
|
|
|
|
}
|
|
|
|
|
|
2021-05-13 11:39:46 +08:00
|
|
|
|
/**
|
|
|
|
|
* @brief TrayPlugin::sniItemsChanged
|
|
|
|
|
* @note 移除关闭的item,插入新增item
|
|
|
|
|
*/
|
2018-11-13 20:07:52 +08:00
|
|
|
|
void TrayPlugin::sniItemsChanged()
|
2018-08-16 10:05:16 +08:00
|
|
|
|
{
|
2018-11-29 10:24:58 +08:00
|
|
|
|
const QStringList &itemServicePaths = m_sniWatcher->registeredStatusNotifierItems();
|
2018-08-16 10:05:16 +08:00
|
|
|
|
QStringList sinTrayKeyList;
|
|
|
|
|
|
|
|
|
|
for (auto item : itemServicePaths) {
|
|
|
|
|
sinTrayKeyList << SNITrayWidget::toSNIKey(item);
|
|
|
|
|
}
|
2019-01-03 14:46:19 +08:00
|
|
|
|
for (auto itemKey : m_trayMap.keys()) {
|
2018-08-16 10:05:16 +08:00
|
|
|
|
if (!sinTrayKeyList.contains(itemKey) && SNITrayWidget::isSNIKey(itemKey)) {
|
2021-12-01 12:22:31 +08:00
|
|
|
|
m_registertedPID.take(m_trayMap[itemKey]->getOwnerPID());
|
2018-08-16 10:05:16 +08:00
|
|
|
|
trayRemoved(itemKey);
|
|
|
|
|
}
|
2019-01-03 14:46:19 +08:00
|
|
|
|
}
|
2019-01-08 14:21:18 +08:00
|
|
|
|
const QList<QString> &passiveSNIKeyList = m_passiveSNITrayMap.keys();
|
|
|
|
|
for (auto itemKey : passiveSNIKeyList) {
|
|
|
|
|
if (!sinTrayKeyList.contains(itemKey) && SNITrayWidget::isSNIKey(itemKey)) {
|
|
|
|
|
m_passiveSNITrayMap.take(itemKey)->deleteLater();
|
|
|
|
|
}
|
|
|
|
|
}
|
2019-01-03 14:46:19 +08:00
|
|
|
|
for (int i = 0; i < sinTrayKeyList.size(); ++i) {
|
2021-11-29 15:46:12 +08:00
|
|
|
|
uint pid = SNITrayWidget::servicePID(itemServicePaths.at(i));
|
2021-12-01 12:22:31 +08:00
|
|
|
|
if (m_registertedPID.value(pid, REGISTERTED_WAY_IS_SNI) == REGISTERTED_WAY_IS_SNI) {
|
2021-11-29 15:46:12 +08:00
|
|
|
|
traySNIAdded(sinTrayKeyList.at(i), itemServicePaths.at(i));
|
2021-12-01 12:22:31 +08:00
|
|
|
|
m_registertedPID.insert(pid, REGISTERTED_WAY_IS_SNI);
|
2021-11-29 15:46:12 +08:00
|
|
|
|
}
|
2018-08-16 10:05:16 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-01-15 18:03:43 +08:00
|
|
|
|
void TrayPlugin::xembedItemsChanged()
|
2016-08-09 10:33:42 +08:00
|
|
|
|
{
|
2017-12-28 19:23:50 +08:00
|
|
|
|
QList<quint32> winidList = m_trayInter->trayIcons();
|
2021-11-29 15:46:12 +08:00
|
|
|
|
QStringList newlyAddedTrayKeyList;
|
|
|
|
|
QStringList allKeytary;
|
|
|
|
|
QList<quint32> newlyAddedWindowID;
|
2017-12-28 19:23:50 +08:00
|
|
|
|
|
|
|
|
|
for (auto winid : winidList) {
|
2021-11-29 15:46:12 +08:00
|
|
|
|
uint pid = XEmbedTrayWidget::getWindowPID(winid);
|
|
|
|
|
allKeytary << XEmbedTrayWidget::toXEmbedKey(winid);
|
|
|
|
|
|
2021-12-01 12:22:31 +08:00
|
|
|
|
if (m_registertedPID.value(pid, REGISTERTED_WAY_IS_XEMBED) == REGISTERTED_WAY_IS_XEMBED) {
|
|
|
|
|
m_registertedPID.insert(pid, REGISTERTED_WAY_IS_XEMBED);
|
2021-11-29 15:46:12 +08:00
|
|
|
|
newlyAddedWindowID << winid;
|
|
|
|
|
newlyAddedTrayKeyList << XEmbedTrayWidget::toXEmbedKey(winid);
|
|
|
|
|
}
|
2017-12-28 19:23:50 +08:00
|
|
|
|
}
|
2016-08-09 10:33:42 +08:00
|
|
|
|
|
2019-01-03 14:46:19 +08:00
|
|
|
|
for (auto tray : m_trayMap.keys()) {
|
2021-11-29 15:46:12 +08:00
|
|
|
|
if (!allKeytary.contains(tray) && XEmbedTrayWidget::isXEmbedKey(tray)) {
|
2021-12-01 12:22:31 +08:00
|
|
|
|
m_registertedPID.take(m_trayMap[tray]->getOwnerPID());
|
2016-08-09 10:33:42 +08:00
|
|
|
|
trayRemoved(tray);
|
2017-12-28 19:23:50 +08:00
|
|
|
|
}
|
2019-01-03 14:46:19 +08:00
|
|
|
|
}
|
2016-08-09 10:33:42 +08:00
|
|
|
|
|
2021-11-29 15:46:12 +08:00
|
|
|
|
for (int i = 0; i < newlyAddedTrayKeyList.size(); ++i) {
|
|
|
|
|
trayXEmbedAdded(newlyAddedTrayKeyList.at(i), newlyAddedWindowID.at(i));
|
2017-12-28 19:23:50 +08:00
|
|
|
|
}
|
2016-08-09 10:33:42 +08:00
|
|
|
|
}
|
|
|
|
|
|
2018-11-13 20:07:52 +08:00
|
|
|
|
void TrayPlugin::addTrayWidget(const QString &itemKey, AbstractTrayWidget *trayWidget)
|
2018-08-16 10:05:16 +08:00
|
|
|
|
{
|
|
|
|
|
if (!trayWidget) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2019-03-12 14:24:24 +08:00
|
|
|
|
if (m_trayMap.contains(itemKey) || m_trayMap.values().contains(trayWidget)) {
|
|
|
|
|
return;
|
2018-08-16 10:05:16 +08:00
|
|
|
|
}
|
|
|
|
|
|
2019-03-12 14:24:24 +08:00
|
|
|
|
m_trayMap.insert(itemKey, trayWidget);
|
|
|
|
|
|
2018-08-16 10:05:16 +08:00
|
|
|
|
if (displayMode() == Dock::Efficient) {
|
|
|
|
|
m_proxyInter->itemAdded(this, itemKey);
|
|
|
|
|
} else {
|
2018-12-28 17:00:29 +08:00
|
|
|
|
m_proxyInter->itemAdded(this, FASHION_MODE_ITEM_KEY);
|
2018-11-21 13:17:32 +08:00
|
|
|
|
m_fashionItem->trayWidgetAdded(itemKey, trayWidget);
|
2018-08-16 10:05:16 +08:00
|
|
|
|
}
|
2018-12-04 09:50:56 +08:00
|
|
|
|
|
|
|
|
|
connect(trayWidget, &AbstractTrayWidget::requestWindowAutoHide, this, &TrayPlugin::onRequestWindowAutoHide, Qt::UniqueConnection);
|
|
|
|
|
connect(trayWidget, &AbstractTrayWidget::requestRefershWindowVisible, this, &TrayPlugin::onRequestRefershWindowVisible, Qt::UniqueConnection);
|
2018-08-16 10:05:16 +08:00
|
|
|
|
}
|
|
|
|
|
|
2019-01-15 18:03:43 +08:00
|
|
|
|
void TrayPlugin::trayXEmbedAdded(const QString &itemKey, quint32 winId)
|
2016-06-28 17:11:29 +08:00
|
|
|
|
{
|
2019-01-15 18:03:43 +08:00
|
|
|
|
if (m_trayMap.contains(itemKey) || !XEmbedTrayWidget::isXEmbedKey(itemKey)) {
|
2016-06-28 17:11:29 +08:00
|
|
|
|
return;
|
2017-12-28 19:23:50 +08:00
|
|
|
|
}
|
2016-06-28 17:11:29 +08:00
|
|
|
|
|
2021-03-20 12:10:45 +08:00
|
|
|
|
if (!Utils::SettingValue("com.deepin.dde.dock.module.systemtray", QByteArray(), "enable", false).toBool())
|
2019-08-01 15:59:25 +08:00
|
|
|
|
return;
|
|
|
|
|
|
2021-11-05 21:25:06 +08:00
|
|
|
|
AbstractTrayWidget *trayWidget = Utils::IS_WAYLAND_DISPLAY ? new XEmbedTrayWidget(winId, xcb_connection, m_display) : new XEmbedTrayWidget(winId);
|
2019-11-27 15:37:57 +08:00
|
|
|
|
if (trayWidget->isValid())
|
|
|
|
|
addTrayWidget(itemKey, trayWidget);
|
|
|
|
|
else {
|
|
|
|
|
qDebug() << "-- invalid tray windowid" << winId;
|
|
|
|
|
}
|
2019-01-03 14:46:19 +08:00
|
|
|
|
}
|
2018-07-24 19:55:39 +08:00
|
|
|
|
|
2019-01-03 14:46:19 +08:00
|
|
|
|
void TrayPlugin::traySNIAdded(const QString &itemKey, const QString &sniServicePath)
|
|
|
|
|
{
|
2020-09-09 13:07:05 +08:00
|
|
|
|
QFutureWatcher<bool> *watcher = new QFutureWatcher<bool>();
|
2021-05-13 11:39:46 +08:00
|
|
|
|
// 开线程去处理添加任务
|
2020-09-09 13:07:05 +08:00
|
|
|
|
connect(watcher, &QFutureWatcher<int>::finished, this, [=] {
|
|
|
|
|
watcher->deleteLater();
|
|
|
|
|
if (!watcher->result()) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
2018-07-10 17:23:05 +08:00
|
|
|
|
|
2020-09-09 13:07:05 +08:00
|
|
|
|
SNITrayWidget *trayWidget = new SNITrayWidget(sniServicePath);
|
2019-08-01 15:59:25 +08:00
|
|
|
|
|
2020-09-09 13:07:05 +08:00
|
|
|
|
// TODO(lxz): 在future里已经对dbus进行过检查了,这里应该不需要再次检查。
|
|
|
|
|
if (!trayWidget->isValid())
|
|
|
|
|
return;
|
2020-01-11 20:03:21 +08:00
|
|
|
|
|
2020-09-09 13:07:05 +08:00
|
|
|
|
std::lock_guard<std::mutex> lock(m_sniMutex);
|
|
|
|
|
if (trayWidget->status() == SNITrayWidget::ItemStatus::Passive) {
|
|
|
|
|
m_passiveSNITrayMap.insert(itemKey, trayWidget);
|
|
|
|
|
} else {
|
|
|
|
|
addTrayWidget(itemKey, trayWidget);
|
|
|
|
|
}
|
2020-01-11 20:03:21 +08:00
|
|
|
|
|
2020-09-09 13:07:05 +08:00
|
|
|
|
connect(trayWidget, &SNITrayWidget::statusChanged, this, &TrayPlugin::onSNIItemStatusChanged);
|
|
|
|
|
});
|
2020-01-11 20:03:21 +08:00
|
|
|
|
|
2020-09-09 13:07:05 +08:00
|
|
|
|
// Start the computation.
|
|
|
|
|
QFuture<bool> future = QtConcurrent::run([=]() -> bool {
|
|
|
|
|
{
|
|
|
|
|
std::lock_guard<std::mutex> lock(m_sniMutex);
|
|
|
|
|
if (m_trayMap.contains(itemKey) || !SNITrayWidget::isSNIKey(itemKey) || m_passiveSNITrayMap.contains(itemKey)) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
2019-12-14 13:54:17 +08:00
|
|
|
|
|
2021-03-20 12:10:45 +08:00
|
|
|
|
if (!Utils::SettingValue("com.deepin.dde.dock.module.systemtray", QByteArray(), "enable", false).toBool())
|
2020-09-09 13:07:05 +08:00
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
if (sniServicePath.startsWith("/") || !sniServicePath.contains("/")) {
|
|
|
|
|
qDebug() << "SNI service path invalid";
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// NOTE(lxz): The data from the sni daemon is interface/methd
|
|
|
|
|
// e.g. org.kde.StatusNotifierItem-1741-1/StatusNotifierItem
|
|
|
|
|
const QStringList list = sniServicePath.split("/");
|
|
|
|
|
const QString sniServerName = list.first();
|
|
|
|
|
|
|
|
|
|
if (sniServerName.isEmpty()) {
|
2020-09-09 17:06:59 +08:00
|
|
|
|
qWarning() << "SNI service error: " << sniServerName;
|
2020-09-09 13:07:05 +08:00
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2022-04-26 14:45:47 +08:00
|
|
|
|
// 1、确保服务有效
|
2020-09-09 17:06:59 +08:00
|
|
|
|
QDBusInterface sniItemDBus(sniServerName, "/" + list.last());
|
2020-09-09 13:07:05 +08:00
|
|
|
|
if (!sniItemDBus.isValid()) {
|
|
|
|
|
qDebug() << "sni dbus service error : " << sniServerName;
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2022-04-26 14:45:47 +08:00
|
|
|
|
// 部分服务虽然有效,但是在dbus总线上只能看到服务,其他信息都无法获取,这里通过Ping进行二次确认
|
|
|
|
|
// 参考: https://dbus.freedesktop.org/doc/dbus-specification.html#standard-interfaces
|
|
|
|
|
|
|
|
|
|
// 2、通过Ping接口确认服务是否正常
|
|
|
|
|
QDBusInterface peerInter(sniServerName, "/" + list.last(), "org.freedesktop.DBus.Peer");
|
|
|
|
|
QDBusReply<void> reply = peerInter.call("Ping");
|
|
|
|
|
if (!reply.isValid())
|
|
|
|
|
return false;
|
|
|
|
|
|
2020-09-09 13:07:05 +08:00
|
|
|
|
return true;
|
|
|
|
|
});
|
2020-02-28 19:11:00 +08:00
|
|
|
|
|
2020-09-09 13:07:05 +08:00
|
|
|
|
watcher->setFuture(future);
|
2019-01-03 14:46:19 +08:00
|
|
|
|
}
|
|
|
|
|
|
2019-03-18 16:11:02 +08:00
|
|
|
|
void TrayPlugin::trayIndicatorAdded(const QString &itemKey, const QString &indicatorName)
|
2019-01-03 14:46:19 +08:00
|
|
|
|
{
|
|
|
|
|
if (m_trayMap.contains(itemKey) || !IndicatorTrayWidget::isIndicatorKey(itemKey)) {
|
|
|
|
|
return;
|
2017-12-28 19:23:50 +08:00
|
|
|
|
}
|
2019-01-03 14:46:19 +08:00
|
|
|
|
|
2021-03-20 12:10:45 +08:00
|
|
|
|
if (!Utils::SettingValue("com.deepin.dde.dock.module.systemtray", QByteArray(), "enable", false).toBool())
|
2019-08-01 15:59:25 +08:00
|
|
|
|
return;
|
|
|
|
|
|
2019-03-18 16:11:02 +08:00
|
|
|
|
IndicatorTray *indicatorTray = nullptr;
|
|
|
|
|
if (!m_indicatorMap.keys().contains(indicatorName)) {
|
2021-05-25 13:05:45 +08:00
|
|
|
|
indicatorTray = new IndicatorTray(indicatorName, this);
|
2019-03-18 16:11:02 +08:00
|
|
|
|
m_indicatorMap[indicatorName] = indicatorTray;
|
2019-12-02 15:01:38 +08:00
|
|
|
|
} else {
|
2019-03-18 16:11:02 +08:00
|
|
|
|
indicatorTray = m_indicatorMap[itemKey];
|
2019-01-03 14:46:19 +08:00
|
|
|
|
}
|
|
|
|
|
|
2019-03-18 16:11:02 +08:00
|
|
|
|
connect(indicatorTray, &IndicatorTray::delayLoaded,
|
2020-02-28 19:11:00 +08:00
|
|
|
|
indicatorTray, [ = ]() {
|
2019-03-18 16:11:02 +08:00
|
|
|
|
addTrayWidget(itemKey, indicatorTray->widget());
|
|
|
|
|
}, Qt::UniqueConnection);
|
2019-01-03 14:46:19 +08:00
|
|
|
|
|
2019-12-02 15:01:38 +08:00
|
|
|
|
connect(indicatorTray, &IndicatorTray::removed, this, [ = ] {
|
2019-01-03 14:46:19 +08:00
|
|
|
|
trayRemoved(itemKey);
|
2019-03-18 16:11:02 +08:00
|
|
|
|
indicatorTray->removeWidget();
|
|
|
|
|
}, Qt::UniqueConnection);
|
2016-06-28 17:11:29 +08:00
|
|
|
|
}
|
|
|
|
|
|
2019-01-03 20:29:09 +08:00
|
|
|
|
void TrayPlugin::trayRemoved(const QString &itemKey, const bool deleteObject)
|
2016-06-28 17:11:29 +08:00
|
|
|
|
{
|
2018-10-23 20:06:46 +08:00
|
|
|
|
if (!m_trayMap.contains(itemKey)) {
|
2016-06-28 17:48:02 +08:00
|
|
|
|
return;
|
2017-12-28 19:23:50 +08:00
|
|
|
|
}
|
2016-06-28 17:48:02 +08:00
|
|
|
|
|
2019-01-08 14:21:18 +08:00
|
|
|
|
AbstractTrayWidget *widget = m_trayMap.take(itemKey);
|
2018-10-31 15:46:22 +08:00
|
|
|
|
|
|
|
|
|
if (displayMode() == Dock::Efficient) {
|
|
|
|
|
m_proxyInter->itemRemoved(this, itemKey);
|
|
|
|
|
} else {
|
|
|
|
|
m_fashionItem->trayWidgetRemoved(widget);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// only delete tray object when it is a tray of applications
|
2018-11-20 14:04:16 +08:00
|
|
|
|
// set the parent of the tray object to avoid be deconstructed by parent(DockItem/PluginsItem/TrayPluginsItem)
|
2018-10-31 15:46:22 +08:00
|
|
|
|
if (widget->trayTyep() == AbstractTrayWidget::TrayType::SystemTray) {
|
|
|
|
|
widget->setParent(nullptr);
|
2019-01-03 20:29:09 +08:00
|
|
|
|
} else if (deleteObject) {
|
2018-10-31 15:46:22 +08:00
|
|
|
|
widget->deleteLater();
|
|
|
|
|
}
|
2016-06-29 11:02:08 +08:00
|
|
|
|
}
|
|
|
|
|
|
2019-01-15 18:03:43 +08:00
|
|
|
|
void TrayPlugin::xembedItemChanged(quint32 winId)
|
2016-06-29 11:02:08 +08:00
|
|
|
|
{
|
2019-01-15 18:03:43 +08:00
|
|
|
|
QString itemKey = XEmbedTrayWidget::toXEmbedKey(winId);
|
2018-10-23 20:06:46 +08:00
|
|
|
|
if (!m_trayMap.contains(itemKey)) {
|
2016-06-29 11:02:08 +08:00
|
|
|
|
return;
|
2017-12-28 19:23:50 +08:00
|
|
|
|
}
|
2016-06-29 11:02:08 +08:00
|
|
|
|
|
2018-10-23 20:06:46 +08:00
|
|
|
|
m_trayMap.value(itemKey)->updateIcon();
|
2016-06-28 14:23:30 +08:00
|
|
|
|
}
|
2016-06-28 19:35:19 +08:00
|
|
|
|
|
2018-11-13 20:07:52 +08:00
|
|
|
|
void TrayPlugin::switchToMode(const Dock::DisplayMode mode)
|
2016-06-28 19:35:19 +08:00
|
|
|
|
{
|
2019-12-02 15:01:38 +08:00
|
|
|
|
if (!m_proxyInter)
|
|
|
|
|
return;
|
|
|
|
|
|
2017-12-28 19:23:50 +08:00
|
|
|
|
if (mode == Dock::Fashion) {
|
2018-10-23 20:06:46 +08:00
|
|
|
|
for (auto itemKey : m_trayMap.keys()) {
|
2017-12-28 19:23:50 +08:00
|
|
|
|
m_proxyInter->itemRemoved(this, itemKey);
|
|
|
|
|
}
|
2018-10-23 20:06:46 +08:00
|
|
|
|
if (m_trayMap.isEmpty()) {
|
2018-12-28 17:00:29 +08:00
|
|
|
|
m_proxyInter->itemRemoved(this, FASHION_MODE_ITEM_KEY);
|
2017-12-28 19:23:50 +08:00
|
|
|
|
} else {
|
2018-11-21 13:17:32 +08:00
|
|
|
|
m_fashionItem->setTrayWidgets(m_trayMap);
|
2018-12-28 17:00:29 +08:00
|
|
|
|
m_proxyInter->itemAdded(this, FASHION_MODE_ITEM_KEY);
|
2017-12-28 19:23:50 +08:00
|
|
|
|
}
|
|
|
|
|
} else {
|
2018-10-16 14:33:06 +08:00
|
|
|
|
m_fashionItem->clearTrayWidgets();
|
2018-12-28 17:00:29 +08:00
|
|
|
|
m_proxyInter->itemRemoved(this, FASHION_MODE_ITEM_KEY);
|
2018-10-23 20:06:46 +08:00
|
|
|
|
for (auto itemKey : m_trayMap.keys()) {
|
2017-12-28 19:23:50 +08:00
|
|
|
|
m_proxyInter->itemAdded(this, itemKey);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2018-12-03 18:16:39 +08:00
|
|
|
|
void TrayPlugin::onRequestWindowAutoHide(const bool autoHide)
|
|
|
|
|
{
|
|
|
|
|
const QString &itemKey = itemKeyOfTrayWidget(static_cast<AbstractTrayWidget *>(sender()));
|
|
|
|
|
|
|
|
|
|
if (itemKey.isEmpty()) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
m_proxyInter->requestWindowAutoHide(this, itemKey, autoHide);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void TrayPlugin::onRequestRefershWindowVisible()
|
|
|
|
|
{
|
|
|
|
|
const QString &itemKey = itemKeyOfTrayWidget(static_cast<AbstractTrayWidget *>(sender()));
|
|
|
|
|
|
|
|
|
|
if (itemKey.isEmpty()) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2018-12-04 09:50:56 +08:00
|
|
|
|
m_proxyInter->requestRefreshWindowVisible(this, itemKey);
|
2018-12-03 18:16:39 +08:00
|
|
|
|
}
|
|
|
|
|
|
2019-01-03 20:29:09 +08:00
|
|
|
|
void TrayPlugin::onSNIItemStatusChanged(SNITrayWidget::ItemStatus status)
|
|
|
|
|
{
|
|
|
|
|
SNITrayWidget *trayWidget = static_cast<SNITrayWidget *>(sender());
|
2019-01-08 14:21:18 +08:00
|
|
|
|
if (!trayWidget) {
|
2019-01-03 20:29:09 +08:00
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2019-01-08 14:21:18 +08:00
|
|
|
|
QString itemKey;
|
|
|
|
|
do {
|
|
|
|
|
itemKey = m_trayMap.key(trayWidget);
|
|
|
|
|
if (!itemKey.isEmpty()) {
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
itemKey = m_passiveSNITrayMap.key(trayWidget);
|
|
|
|
|
if (itemKey.isEmpty()) {
|
|
|
|
|
qDebug() << "Error! not found the status changed SNI tray!";
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
} while (false);
|
|
|
|
|
|
2019-01-03 20:29:09 +08:00
|
|
|
|
switch (status) {
|
|
|
|
|
case SNITrayWidget::Passive: {
|
2019-01-08 14:21:18 +08:00
|
|
|
|
m_passiveSNITrayMap.insert(itemKey, trayWidget);
|
2019-01-03 20:29:09 +08:00
|
|
|
|
trayRemoved(itemKey, false);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case SNITrayWidget::Active:
|
|
|
|
|
case SNITrayWidget::NeedsAttention: {
|
2019-01-08 14:21:18 +08:00
|
|
|
|
m_passiveSNITrayMap.remove(itemKey);
|
2019-01-03 20:29:09 +08:00
|
|
|
|
addTrayWidget(itemKey, trayWidget);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2018-11-13 20:07:52 +08:00
|
|
|
|
void TrayPlugin::loadIndicator()
|
2017-12-28 19:23:50 +08:00
|
|
|
|
{
|
|
|
|
|
QDir indicatorConfDir("/etc/dde-dock/indicator");
|
|
|
|
|
|
2019-03-18 16:11:02 +08:00
|
|
|
|
for (const QFileInfo &fileInfo : indicatorConfDir.entryInfoList({"*.json"}, QDir::Files | QDir::NoDotAndDotDot)) {
|
|
|
|
|
const QString &indicatorName = fileInfo.baseName();
|
|
|
|
|
trayIndicatorAdded(IndicatorTrayWidget::toIndicatorKey(indicatorName), indicatorName);
|
2016-06-28 19:35:19 +08:00
|
|
|
|
}
|
|
|
|
|
}
|