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

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