qdbustrayicon.cpp

Absolute File Name:/home/qt/qt5_coco/qt5/qtbase/src/platformsupport/dbustray/qdbustrayicon.cpp
Source codeSwitch to Preprocessed file
LineSourceCount
1/****************************************************************************-
2**-
3** Copyright (C) 2016 The Qt Company Ltd.-
4** Contact: https://www.qt.io/licensing/-
5**-
6** This file is part of the QtGui module of the Qt Toolkit.-
7**-
8** $QT_BEGIN_LICENSE:LGPL$-
9** Commercial License Usage-
10** Licensees holding valid commercial Qt licenses may use this file in-
11** accordance with the commercial license agreement provided with the-
12** Software or, alternatively, in accordance with the terms contained in-
13** a written agreement between you and The Qt Company. For licensing terms-
14** and conditions see https://www.qt.io/terms-conditions. For further-
15** information use the contact form at https://www.qt.io/contact-us.-
16**-
17** GNU Lesser General Public License Usage-
18** Alternatively, this file may be used under the terms of the GNU Lesser-
19** General Public License version 3 as published by the Free Software-
20** Foundation and appearing in the file LICENSE.LGPL3 included in the-
21** packaging of this file. Please review the following information to-
22** ensure the GNU Lesser General Public License version 3 requirements-
23** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.-
24**-
25** GNU General Public License Usage-
26** Alternatively, this file may be used under the terms of the GNU-
27** General Public License version 2.0 or (at your option) the GNU General-
28** Public license version 3 or any later version approved by the KDE Free-
29** Qt Foundation. The licenses are as published by the Free Software-
30** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3-
31** included in the packaging of this file. Please review the following-
32** information to ensure the GNU General Public License requirements will-
33** be met: https://www.gnu.org/licenses/gpl-2.0.html and-
34** https://www.gnu.org/licenses/gpl-3.0.html.-
35**-
36** $QT_END_LICENSE$-
37**-
38****************************************************************************/-
39-
40#ifndef QT_NO_SYSTEMTRAYICON-
41-
42#include "qdbustrayicon_p.h"-
43#include "qdbusmenuconnection_p.h"-
44#include "qstatusnotifieritemadaptor_p.h"-
45#include "qdbusmenuadaptor_p.h"-
46#include "dbusmenu/qdbusplatformmenu_p.h"-
47#include "qxdgnotificationproxy_p.h"-
48-
49#include <qplatformmenu.h>-
50#include <qstring.h>-
51#include <qdebug.h>-
52#include <qrect.h>-
53#include <qloggingcategory.h>-
54#include <qplatformintegration.h>-
55#include <qplatformservices.h>-
56#include <qdbusconnectioninterface.h>-
57#include <private/qlockfile_p.h>-
58#include <private/qguiapplication_p.h>-
59-
60// Defined in Windows headers which get included by qlockfile_p.h-
61#undef interface-
62-
63QT_BEGIN_NAMESPACE-
64-
65Q_LOGGING_CATEGORY(qLcTray, "qt.qpa.tray")
executed 1 time by 1 test: return category;
Executed by:
  • tst_QSystemTrayIcon
1
66-
67static const QString KDEItemFormat = QStringLiteral("org.kde.StatusNotifierItem-%1-%2");-
68static const QString KDEWatcherService = QStringLiteral("org.kde.StatusNotifierWatcher");-
69static const QString TempFileTemplate = QDir::tempPath() + QLatin1String("/qt-trayicon-XXXXXX.png");-
70static const QString XdgNotificationService = QStringLiteral("org.freedesktop.Notifications");-
71static const QString XdgNotificationPath = QStringLiteral("/org/freedesktop/Notifications");-
72static const QString DefaultAction = QStringLiteral("default");-
73static int instanceCount = 0;-
74-
75/*!-
76 \class QDBusTrayIcon-
77 \internal-
78*/-
79-
80QDBusTrayIcon::QDBusTrayIcon()-
81 : m_dbusConnection(Q_NULLPTR)-
82 , m_adaptor(new QStatusNotifierItemAdaptor(this))-
83 , m_menuAdaptor(Q_NULLPTR)-
84 , m_menu(Q_NULLPTR)-
85 , m_notifier(Q_NULLPTR)-
86 , m_instanceId(KDEItemFormat.arg(QCoreApplication::applicationPid()).arg(++instanceCount))-
87 , m_category(QStringLiteral("ApplicationStatus"))-
88 , m_defaultStatus(QStringLiteral("Active")) // be visible all the time. QSystemTrayIcon has no API to control this.-
89 , m_status(m_defaultStatus)-
90 , m_tempIcon(Q_NULLPTR)-
91 , m_tempAttentionIcon(Q_NULLPTR)-
92 , m_registered(false)-
93{-
94 qCDebug(qLcTray);
never executed: QMessageLogger(__FILE__, 94, __PRETTY_FUNCTION__, qLcTray().categoryName()).debug();
qt_category_enabledDescription
TRUEnever evaluated
FALSEnever evaluated
0
95 if (instanceCount == 1) {
instanceCount == 1Description
TRUEnever evaluated
FALSEnever evaluated
0
96 QDBusMenuItem::registerDBusTypes();-
97 qDBusRegisterMetaType<QXdgDBusImageStruct>();-
98 qDBusRegisterMetaType<QXdgDBusImageVector>();-
99 qDBusRegisterMetaType<QXdgDBusToolTipStruct>();-
100 }
never executed: end of block
0
101 connect(this, SIGNAL(statusChanged(QString)), m_adaptor, SIGNAL(NewStatus(QString)));-
102 connect(this, SIGNAL(tooltipChanged()), m_adaptor, SIGNAL(NewToolTip()));-
103 connect(this, SIGNAL(iconChanged()), m_adaptor, SIGNAL(NewIcon()));-
104 connect(this, SIGNAL(attention()), m_adaptor, SIGNAL(NewAttentionIcon()));-
105 connect(this, SIGNAL(attention()), m_adaptor, SIGNAL(NewTitle()));-
106 connect(&m_attentionTimer, SIGNAL(timeout()), this, SLOT(attentionTimerExpired()));-
107 m_attentionTimer.setSingleShot(true);-
108}
never executed: end of block
0
109-
110QDBusTrayIcon::~QDBusTrayIcon()-
111{-
112}-
113-
114void QDBusTrayIcon::init()-
115{-
116 qCDebug(qLcTray) << "registering" << m_instanceId;
never executed: QMessageLogger(__FILE__, 116, __PRETTY_FUNCTION__, qLcTray().categoryName()).debug() << "registering" << m_instanceId;
qt_category_enabledDescription
TRUEnever evaluated
FALSEnever evaluated
0
117 m_registered = dBusConnection()->registerTrayIcon(this);-
118}
never executed: end of block
0
119-
120void QDBusTrayIcon::cleanup()-
121{-
122 qCDebug(qLcTray) << "unregistering" << m_instanceId;
never executed: QMessageLogger(__FILE__, 122, __PRETTY_FUNCTION__, qLcTray().categoryName()).debug() << "unregistering" << m_instanceId;
qt_category_enabledDescription
TRUEnever evaluated
FALSEnever evaluated
0
123 if (m_registered)
m_registeredDescription
TRUEnever evaluated
FALSEnever evaluated
0
124 dBusConnection()->unregisterTrayIcon(this);
never executed: dBusConnection()->unregisterTrayIcon(this);
0
125 delete m_dbusConnection;-
126 m_dbusConnection = Q_NULLPTR;-
127 delete m_notifier;-
128 m_notifier = Q_NULLPTR;-
129 m_registered = false;-
130}
never executed: end of block
0
131-
132void QDBusTrayIcon::attentionTimerExpired()-
133{-
134 m_messageTitle = QString();-
135 m_message = QString();-
136 m_attentionIcon = QIcon();-
137 emit attention();-
138 emit tooltipChanged();-
139 setStatus(m_defaultStatus);-
140}
never executed: end of block
0
141-
142void QDBusTrayIcon::setStatus(const QString &status)-
143{-
144 qCDebug(qLcTray) << status;
never executed: QMessageLogger(__FILE__, 144, __PRETTY_FUNCTION__, qLcTray().categoryName()).debug() << status;
qt_category_enabledDescription
TRUEnever evaluated
FALSEnever evaluated
0
145 if (m_status == status)
m_status == statusDescription
TRUEnever evaluated
FALSEnever evaluated
0
146 return;
never executed: return;
0
147 m_status = status;-
148 emit statusChanged(m_status);-
149}
never executed: end of block
0
150-
151QTemporaryFile *QDBusTrayIcon::tempIcon(const QIcon &icon)-
152{-
153 // Hack for indicator-application, which doesn't handle icons sent across D-Bus:-
154 // save the icon to a temp file and set the icon name to that filename.-
155 static bool necessity_checked = false;-
156 static bool necessary = false;-
157 if (!necessity_checked) {
!necessity_checkedDescription
TRUEnever evaluated
FALSEnever evaluated
0
158 QDBusConnection session = QDBusConnection::sessionBus();-
159 uint pid = session.interface()->servicePid(KDEWatcherService).value();-
160 QString processName = QLockFilePrivate::processNameByPid(pid);-
161 necessary = processName.endsWith(QLatin1String("indicator-application-service"));-
162 necessity_checked = true;-
163 }
never executed: end of block
0
164 if (!necessary)
!necessaryDescription
TRUEnever evaluated
FALSEnever evaluated
0
165 return Q_NULLPTR;
never executed: return nullptr;
0
166 qreal dpr = qGuiApp->devicePixelRatio();-
167 QTemporaryFile *ret = new QTemporaryFile(TempFileTemplate, this);-
168 ret->open();-
169 icon.pixmap(QSize(22 * dpr, 22 * dpr)).save(ret);-
170 ret->close();-
171 return ret;
never executed: return ret;
0
172}-
173-
174QDBusMenuConnection * QDBusTrayIcon::dBusConnection()-
175{-
176 if (!m_dbusConnection) {
!m_dbusConnectionDescription
TRUEnever evaluated
FALSEnever evaluated
0
177 m_dbusConnection = new QDBusMenuConnection(this, m_instanceId);-
178 m_notifier = new QXdgNotificationInterface(XdgNotificationService,-
179 XdgNotificationPath, m_dbusConnection->connection(), this);-
180 connect(m_notifier, SIGNAL(NotificationClosed(uint,uint)), this, SLOT(notificationClosed(uint,uint)));-
181 connect(m_notifier, SIGNAL(ActionInvoked(uint,QString)), this, SLOT(actionInvoked(uint,QString)));-
182 }
never executed: end of block
0
183 return m_dbusConnection;
never executed: return m_dbusConnection;
0
184}-
185-
186void QDBusTrayIcon::updateIcon(const QIcon &icon)-
187{-
188 m_iconName = icon.name();-
189 m_icon = icon;-
190 if (m_iconName.isEmpty()) {
m_iconName.isEmpty()Description
TRUEnever evaluated
FALSEnever evaluated
0
191 if (m_tempIcon)
m_tempIconDescription
TRUEnever evaluated
FALSEnever evaluated
0
192 delete m_tempIcon;
never executed: delete m_tempIcon;
0
193 m_tempIcon = tempIcon(icon);-
194 if (m_tempIcon)
m_tempIconDescription
TRUEnever evaluated
FALSEnever evaluated
0
195 m_iconName = m_tempIcon->fileName();
never executed: m_iconName = m_tempIcon->fileName();
0
196 }
never executed: end of block
0
197 qCDebug(qLcTray) << m_iconName << icon.availableSizes();
never executed: QMessageLogger(__FILE__, 197, __PRETTY_FUNCTION__, qLcTray().categoryName()).debug() << m_iconName << icon.availableSizes();
qt_category_enabledDescription
TRUEnever evaluated
FALSEnever evaluated
0
198 emit iconChanged();-
199}
never executed: end of block
0
200-
201void QDBusTrayIcon::updateToolTip(const QString &tooltip)-
202{-
203 qCDebug(qLcTray) << tooltip;
never executed: QMessageLogger(__FILE__, 203, __PRETTY_FUNCTION__, qLcTray().categoryName()).debug() << tooltip;
qt_category_enabledDescription
TRUEnever evaluated
FALSEnever evaluated
0
204 m_tooltip = tooltip;-
205 emit tooltipChanged();-
206}
never executed: end of block
0
207-
208QPlatformMenu *QDBusTrayIcon::createMenu() const-
209{-
210 return new QDBusPlatformMenu();
never executed: return new QDBusPlatformMenu();
0
211}-
212-
213void QDBusTrayIcon::updateMenu(QPlatformMenu * menu)-
214{-
215 qCDebug(qLcTray) << menu;
never executed: QMessageLogger(__FILE__, 215, __PRETTY_FUNCTION__, qLcTray().categoryName()).debug() << menu;
qt_category_enabledDescription
TRUEnever evaluated
FALSEnever evaluated
0
216 QDBusPlatformMenu *newMenu = qobject_cast<QDBusPlatformMenu *>(menu);-
217 if (m_menu != newMenu) {
m_menu != newMenuDescription
TRUEnever evaluated
FALSEnever evaluated
0
218 if (m_menu) {
m_menuDescription
TRUEnever evaluated
FALSEnever evaluated
0
219 dBusConnection()->unregisterTrayIconMenu(this);-
220 delete m_menuAdaptor;-
221 }
never executed: end of block
0
222 m_menu = newMenu;-
223 m_menuAdaptor = new QDBusMenuAdaptor(m_menu);-
224 // TODO connect(m_menu, , m_menuAdaptor, SIGNAL(ItemActivationRequested(int,uint)));-
225 connect(m_menu, SIGNAL(propertiesUpdated(QDBusMenuItemList,QDBusMenuItemKeysList)),-
226 m_menuAdaptor, SIGNAL(ItemsPropertiesUpdated(QDBusMenuItemList,QDBusMenuItemKeysList)));-
227 connect(m_menu, SIGNAL(updated(uint,int)),-
228 m_menuAdaptor, SIGNAL(LayoutUpdated(uint,int)));-
229 dBusConnection()->registerTrayIconMenu(this);-
230 }
never executed: end of block
0
231}
never executed: end of block
0
232-
233void QDBusTrayIcon::showMessage(const QString &title, const QString &msg, const QIcon &icon,-
234 QPlatformSystemTrayIcon::MessageIcon iconType, int msecs)-
235{-
236 m_messageTitle = title;-
237 m_message = msg;-
238 m_attentionIcon = icon;-
239 QStringList notificationActions;-
240 switch (iconType) {-
241 case Information:
never executed: case Information:
0
242 m_attentionIconName = QStringLiteral("dialog-information");
never executed: return qstring_literal_temp;
0
243 break;
never executed: break;
0
244 case Warning:
never executed: case Warning:
0
245 m_attentionIconName = QStringLiteral("dialog-warning");
never executed: return qstring_literal_temp;
0
246 break;
never executed: break;
0
247 case Critical:
never executed: case Critical:
0
248 m_attentionIconName = QStringLiteral("dialog-error");
never executed: return qstring_literal_temp;
0
249 // If there are actions, the desktop notification may appear as a message dialog-
250 // with button(s), which will interrupt the user and require a response.-
251 // That is an optional feature in implementations of org.freedesktop.Notifications-
252 notificationActions << DefaultAction << tr("OK");-
253 break;
never executed: break;
0
254 default:
never executed: default:
0
255 m_attentionIconName.clear();-
256 break;
never executed: break;
0
257 }-
258 if (m_attentionIconName.isEmpty()) {
m_attentionIconName.isEmpty()Description
TRUEnever evaluated
FALSEnever evaluated
0
259 if (m_tempAttentionIcon)
m_tempAttentionIconDescription
TRUEnever evaluated
FALSEnever evaluated
0
260 delete m_tempAttentionIcon;
never executed: delete m_tempAttentionIcon;
0
261 m_tempAttentionIcon = tempIcon(icon);-
262 if (m_tempAttentionIcon)
m_tempAttentionIconDescription
TRUEnever evaluated
FALSEnever evaluated
0
263 m_attentionIconName = m_tempAttentionIcon->fileName();
never executed: m_attentionIconName = m_tempAttentionIcon->fileName();
0
264 }
never executed: end of block
0
265 qCDebug(qLcTray) << title << msg <<
never executed: QMessageLogger(__FILE__, 265, __PRETTY_FUNCTION__, qLcTray().categoryName()).debug() << title << msg << QPlatformSystemTrayIcon::metaObject()->enumerator( QPlatformSystemTrayIcon::staticMetaObject.indexOfEnumerator("MessageIcon")).valueToKey(iconType) << m_attentionIconName << msecs;
qt_category_enabledDescription
TRUEnever evaluated
FALSEnever evaluated
0
266 QPlatformSystemTrayIcon::metaObject()->enumerator(
never executed: QMessageLogger(__FILE__, 265, __PRETTY_FUNCTION__, qLcTray().categoryName()).debug() << title << msg << QPlatformSystemTrayIcon::metaObject()->enumerator( QPlatformSystemTrayIcon::staticMetaObject.indexOfEnumerator("MessageIcon")).valueToKey(iconType) << m_attentionIconName << msecs;
0
267 QPlatformSystemTrayIcon::staticMetaObject.indexOfEnumerator("MessageIcon")).valueToKey(iconType)
never executed: QMessageLogger(__FILE__, 265, __PRETTY_FUNCTION__, qLcTray().categoryName()).debug() << title << msg << QPlatformSystemTrayIcon::metaObject()->enumerator( QPlatformSystemTrayIcon::staticMetaObject.indexOfEnumerator("MessageIcon")).valueToKey(iconType) << m_attentionIconName << msecs;
0
268 << m_attentionIconName << msecs;
never executed: QMessageLogger(__FILE__, 265, __PRETTY_FUNCTION__, qLcTray().categoryName()).debug() << title << msg << QPlatformSystemTrayIcon::metaObject()->enumerator( QPlatformSystemTrayIcon::staticMetaObject.indexOfEnumerator("MessageIcon")).valueToKey(iconType) << m_attentionIconName << msecs;
0
269 setStatus(QStringLiteral("NeedsAttention"));
never executed: return qstring_literal_temp;
0
270 m_attentionTimer.start(msecs);-
271 emit tooltipChanged();-
272 emit attention();-
273-
274 // Desktop notification-
275 QVariantMap hints;-
276 // urgency levels according to https://developer.gnome.org/notification-spec/#urgency-levels-
277 // 0 low, 1 normal, 2 critical-
278 int urgency = static_cast<int>(iconType) - 1;-
279 if (urgency < 0) // no icon
urgency < 0Description
TRUEnever evaluated
FALSEnever evaluated
0
280 urgency = 0;
never executed: urgency = 0;
0
281 hints.insert(QLatin1String("urgency"), QVariant(urgency));-
282 m_notifier->notify(QCoreApplication::applicationName(), 0,-
283 m_attentionIconName, title, msg, notificationActions, hints, msecs);-
284}
never executed: end of block
0
285-
286void QDBusTrayIcon::actionInvoked(uint id, const QString &action)-
287{-
288 qCDebug(qLcTray) << id << action;
never executed: QMessageLogger(__FILE__, 288, __PRETTY_FUNCTION__, qLcTray().categoryName()).debug() << id << action;
qt_category_enabledDescription
TRUEnever evaluated
FALSEnever evaluated
0
289 emit messageClicked();-
290}
never executed: end of block
0
291-
292void QDBusTrayIcon::notificationClosed(uint id, uint reason)-
293{-
294 qCDebug(qLcTray) << id << reason;
never executed: QMessageLogger(__FILE__, 294, __PRETTY_FUNCTION__, qLcTray().categoryName()).debug() << id << reason;
qt_category_enabledDescription
TRUEnever evaluated
FALSEnever evaluated
0
295}
never executed: end of block
0
296-
297bool QDBusTrayIcon::isSystemTrayAvailable() const-
298{-
299 QDBusMenuConnection * conn = const_cast<QDBusTrayIcon *>(this)->dBusConnection();-
300 qCDebug(qLcTray) << conn->isStatusNotifierHostRegistered();
never executed: QMessageLogger(__FILE__, 300, __PRETTY_FUNCTION__, qLcTray().categoryName()).debug() << conn->isStatusNotifierHostRegistered();
qt_category_enabledDescription
TRUEnever evaluated
FALSEnever evaluated
0
301 return conn->isStatusNotifierHostRegistered();
never executed: return conn->isStatusNotifierHostRegistered();
0
302}-
303-
304QT_END_NAMESPACE-
305#endif //QT_NO_SYSTEMTRAYICON-
306-
Source codeSwitch to Preprocessed file

Generated by Squish Coco Non-Commercial 4.3.0-BETA-master-30-08-2018-4cb69e9