util/qsystemtrayicon_x11.cpp

Source codeSwitch to Preprocessed file
LineSource CodeCoverage
1/**************************************************************************** -
2** -
3** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -
4** Contact: http://www.qt-project.org/legal -
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 Digia. For licensing terms and -
14** conditions see http://qt.digia.com/licensing. For further information -
15** use the contact form at http://qt.digia.com/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 as published by the Free Software -
20** Foundation and appearing in the file LICENSE.LGPL included in the -
21** packaging of this file. Please review the following information to -
22** ensure the GNU Lesser General Public License version 2.1 requirements -
23** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -
24** -
25** In addition, as a special exception, Digia gives you certain additional -
26** rights. These rights are described in the Digia Qt LGPL Exception -
27** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -
28** -
29** GNU General Public License Usage -
30** Alternatively, this file may be used under the terms of the GNU -
31** General Public License version 3.0 as published by the Free Software -
32** Foundation and appearing in the file LICENSE.GPL included in the -
33** packaging of this file. Please review the following information to -
34** ensure the GNU General Public License version 3.0 requirements will be -
35** met: http://www.gnu.org/copyleft/gpl.html. -
36** -
37** -
38** $QT_END_LICENSE$ -
39** -
40****************************************************************************/ -
41 -
42#include "qlabel.h" -
43#include "qpainter.h" -
44#include "qpixmap.h" -
45#include "qbitmap.h" -
46#include "qevent.h" -
47#include "qapplication.h" -
48#include "qlist.h" -
49#include "qmenu.h" -
50#include "qtimer.h" -
51#include "qsystemtrayicon_p.h" -
52#include "qpaintengine.h" -
53#include <qwindow.h> -
54#include <qguiapplication.h> -
55#include <qscreen.h> -
56#include <qbackingstore.h> -
57#include <qpa/qplatformnativeinterface.h> -
58#include <qdebug.h> -
59 -
60#include <X11/Xlib.h> -
61#include <X11/Xutil.h> -
62#include <X11/Xos.h> -
63#include <X11/Xatom.h> -
64 -
65#ifndef QT_NO_SYSTEMTRAYICON -
66QT_BEGIN_NAMESPACE -
67 -
68enum { -
69 SYSTEM_TRAY_REQUEST_DOCK = 0, -
70 SYSTEM_TRAY_BEGIN_MESSAGE = 1, -
71 SYSTEM_TRAY_CANCEL_MESSAGE =2 -
72}; -
73 -
74// ### fixme (15.3.2012): The following issues need to be resolved: -
75// - Tracking of the actual tray window for DestroyNotify and re-creation -
76// of the icons on the new window should it change (see Qt 4.X). -
77 -
78// Global context for the X11 system tray containing a display for the primary -
79// screen and a selection atom from which the tray window can be determined. -
80class QX11SystemTrayContext -
81{ -
82public: -
83 QX11SystemTrayContext(); -
84 ~QX11SystemTrayContext(); -
85 -
86 bool isValid() const { return m_systemTraySelection != 0; }
executed: return m_systemTraySelection != 0;
Execution Count:6
6
87 -
88 inline Display *display() const { return m_display; }
executed: return m_display;
Execution Count:15
15
89 inline int screenNumber() const { return m_screenNumber; }
executed: return m_screenNumber;
Execution Count:4
4
90 Window locateSystemTray() const; -
91 -
92private: -
93 Display *m_display; -
94 int m_screenNumber; -
95 Atom m_systemTraySelection; -
96}; -
97 -
98QX11SystemTrayContext::QX11SystemTrayContext() : m_display(0), m_screenNumber(0), m_systemTraySelection(0) -
99{ -
100 QScreen *screen = QGuiApplication::primaryScreen();
executed (the execution status of this line is deduced): QScreen *screen = QGuiApplication::primaryScreen();
-
101 if (!screen) {
partially evaluated: !screen
TRUEFALSE
no
Evaluation Count:0
yes
Evaluation Count:1
0-1
102 qWarning("%s: No screen.", Q_FUNC_INFO);
never executed (the execution status of this line is deduced): QMessageLogger("util/qsystemtrayicon_x11.cpp", 102, __PRETTY_FUNCTION__).warning("%s: No screen.", __PRETTY_FUNCTION__);
-
103 return;
never executed: return;
0
104 } -
105 void *displayV = QGuiApplication::platformNativeInterface()->nativeResourceForScreen(QByteArrayLiteral("display"), screen);
executed (the execution status of this line is deduced): void *displayV = QGuiApplication::platformNativeInterface()->nativeResourceForScreen(QByteArray("display", sizeof("display") - 1), screen);
-
106 if (!displayV) {
partially evaluated: !displayV
TRUEFALSE
no
Evaluation Count:0
yes
Evaluation Count:1
0-1
107 qWarning("%s: Unable to obtain X11 display of primary screen.", Q_FUNC_INFO);
never executed (the execution status of this line is deduced): QMessageLogger("util/qsystemtrayicon_x11.cpp", 107, __PRETTY_FUNCTION__).warning("%s: Unable to obtain X11 display of primary screen.", __PRETTY_FUNCTION__);
-
108 return;
never executed: return;
0
109 } -
110 -
111 m_display = static_cast<Display *>(displayV);
executed (the execution status of this line is deduced): m_display = static_cast<Display *>(displayV);
-
112 -
113 const QByteArray netSysTray = "_NET_SYSTEM_TRAY_S" + QByteArray::number(m_screenNumber);
executed (the execution status of this line is deduced): const QByteArray netSysTray = "_NET_SYSTEM_TRAY_S" + QByteArray::number(m_screenNumber);
-
114 m_systemTraySelection = XInternAtom(m_display, netSysTray.constData(), False);
executed (the execution status of this line is deduced): m_systemTraySelection = XInternAtom(m_display, netSysTray.constData(), 0);
-
115 if (!m_systemTraySelection) {
partially evaluated: !m_systemTraySelection
TRUEFALSE
no
Evaluation Count:0
yes
Evaluation Count:1
0-1
116 qWarning("%s: Unable to retrieve atom '%s'.", Q_FUNC_INFO, netSysTray.constData());
never executed (the execution status of this line is deduced): QMessageLogger("util/qsystemtrayicon_x11.cpp", 116, __PRETTY_FUNCTION__).warning("%s: Unable to retrieve atom '%s'.", __PRETTY_FUNCTION__, netSysTray.constData());
-
117 return;
never executed: return;
0
118 } -
119}
executed: }
Execution Count:1
1
120 -
121Window QX11SystemTrayContext::locateSystemTray() const -
122{ -
123 if (isValid())
partially evaluated: isValid()
TRUEFALSE
yes
Evaluation Count:3
no
Evaluation Count:0
0-3
124 return XGetSelectionOwner(m_display, m_systemTraySelection);
executed: return XGetSelectionOwner(m_display, m_systemTraySelection);
Execution Count:3
3
125 return 0;
never executed: return 0;
0
126} -
127 -
128QX11SystemTrayContext::~QX11SystemTrayContext() -
129{ -
130} -
131 -
132Q_GLOBAL_STATIC(QX11SystemTrayContext, qX11SystemTrayContext)
never executed: delete x;
executed: return thisGlobalStatic.pointer.load();
Execution Count:10
partially evaluated: !thisGlobalStatic.pointer.testAndSetOrdered(0, x)
TRUEFALSE
no
Evaluation Count:0
yes
Evaluation Count:1
evaluated: !thisGlobalStatic.pointer.load()
TRUEFALSE
yes
Evaluation Count:1
yes
Evaluation Count:9
partially evaluated: !thisGlobalStatic.destroyed
TRUEFALSE
yes
Evaluation Count:1
no
Evaluation Count:0
0-10
133 -
134// System tray widget. Could be replaced by a QWindow with -
135// a backing store if it did not need tooltip handling. -
136class QSystemTrayIconSys : public QWidget -
137{ -
138public: -
139 explicit QSystemTrayIconSys(QSystemTrayIcon *q); -
140 -
141 inline void updateIcon() { update(); }
executed: }
Execution Count:1
1
142 inline QSystemTrayIcon *systemTrayIcon() const { return q; }
executed: return q;
Execution Count:4
4
143 -
144 QRect globalGeometry() const; -
145 -
146protected: -
147 virtual void mousePressEvent(QMouseEvent *ev); -
148 virtual void mouseDoubleClickEvent(QMouseEvent *ev); -
149 virtual bool event(QEvent *); -
150 virtual void paintEvent(QPaintEvent *); -
151 -
152private: -
153 QSystemTrayIcon *q; -
154}; -
155 -
156QSystemTrayIconSys::QSystemTrayIconSys(QSystemTrayIcon *qIn) : -
157 q(qIn) -
158{ -
159 setToolTip(q->toolTip());
executed (the execution status of this line is deduced): setToolTip(q->toolTip());
-
160 QX11SystemTrayContext *context = qX11SystemTrayContext();
executed (the execution status of this line is deduced): QX11SystemTrayContext *context = qX11SystemTrayContext();
-
161 Q_ASSERT(context->isValid());
executed (the execution status of this line is deduced): qt_noop();
-
162 setAttribute(Qt::WA_AlwaysShowToolTips, true);
executed (the execution status of this line is deduced): setAttribute(Qt::WA_AlwaysShowToolTips, true);
-
163 setAttribute(Qt::WA_TranslucentBackground, true);
executed (the execution status of this line is deduced): setAttribute(Qt::WA_TranslucentBackground, true);
-
164 setAttribute(Qt::WA_QuitOnClose, false);
executed (the execution status of this line is deduced): setAttribute(Qt::WA_QuitOnClose, false);
-
165 setWindowFlags(Qt::Window | Qt::FramelessWindowHint);
executed (the execution status of this line is deduced): setWindowFlags(Qt::Window | Qt::FramelessWindowHint);
-
166 const QSize size(22, 22); // Gnome, standard size
executed (the execution status of this line is deduced): const QSize size(22, 22);
-
167 setGeometry(QRect(QPoint(0, 0), size));
executed (the execution status of this line is deduced): setGeometry(QRect(QPoint(0, 0), size));
-
168 setMinimumSize(size);
executed (the execution status of this line is deduced): setMinimumSize(size);
-
169 createWinId();
executed (the execution status of this line is deduced): createWinId();
-
170 setMouseTracking(true);
executed (the execution status of this line is deduced): setMouseTracking(true);
-
171 -
172 Display *display = context->display();
executed (the execution status of this line is deduced): Display *display = context->display();
-
173 -
174 // Request to be a tray window according to GNOME, NET WM Specification -
175 static Atom netwm_tray_atom = XInternAtom(display, "_NET_SYSTEM_TRAY_OPCODE", False); -
176 long l[5] = { CurrentTime, SYSTEM_TRAY_REQUEST_DOCK, static_cast<long>(winId()), 0, 0 };
executed (the execution status of this line is deduced): long l[5] = { 0L, SYSTEM_TRAY_REQUEST_DOCK, static_cast<long>(winId()), 0, 0 };
-
177 XEvent ev;
executed (the execution status of this line is deduced): XEvent ev;
-
178 memset(&ev, 0, sizeof(ev));
executed (the execution status of this line is deduced): memset(&ev, 0, sizeof(ev));
-
179 ev.xclient.type = ClientMessage;
executed (the execution status of this line is deduced): ev.xclient.type = 33;
-
180 ev.xclient.window = context->locateSystemTray();
executed (the execution status of this line is deduced): ev.xclient.window = context->locateSystemTray();
-
181 ev.xclient.message_type = netwm_tray_atom;
executed (the execution status of this line is deduced): ev.xclient.message_type = netwm_tray_atom;
-
182 ev.xclient.format = 32;
executed (the execution status of this line is deduced): ev.xclient.format = 32;
-
183 memcpy((char *)&ev.xclient.data, (const char *) l, sizeof(l));
executed (the execution status of this line is deduced): memcpy((char *)&ev.xclient.data, (const char *) l, sizeof(l));
-
184 XSendEvent(display, ev.xclient.window, False, 0, &ev);
executed (the execution status of this line is deduced): XSendEvent(display, ev.xclient.window, 0, 0, &ev);
-
185 XSync(display, False);
executed (the execution status of this line is deduced): XSync(display, 0);
-
186 show();
executed (the execution status of this line is deduced): show();
-
187}
executed: }
Execution Count:3
3
188 -
189QRect QSystemTrayIconSys::globalGeometry() const -
190{ -
191 QX11SystemTrayContext *context = qX11SystemTrayContext();
executed (the execution status of this line is deduced): QX11SystemTrayContext *context = qX11SystemTrayContext();
-
192 ::Window dummy;
executed (the execution status of this line is deduced): ::Window dummy;
-
193 int x, y, rootX, rootY;
executed (the execution status of this line is deduced): int x, y, rootX, rootY;
-
194 unsigned int width, height, border, depth;
executed (the execution status of this line is deduced): unsigned int width, height, border, depth;
-
195 // Use X11 API since we are parented on the tray, about which the QWindow does not know. -
196 XGetGeometry(context->display(), winId(), &dummy, &x, &y, &width, &height, &border, &depth);
executed (the execution status of this line is deduced): XGetGeometry(context->display(), winId(), &dummy, &x, &y, &width, &height, &border, &depth);
-
197 XTranslateCoordinates(context->display(), winId(),
executed (the execution status of this line is deduced): XTranslateCoordinates(context->display(), winId(),
-
198 XRootWindow(context->display(), context->screenNumber()),
executed (the execution status of this line is deduced): XRootWindow(context->display(), context->screenNumber()),
-
199 x, y, &rootX, &rootY, &dummy);
executed (the execution status of this line is deduced): x, y, &rootX, &rootY, &dummy);
-
200 return QRect(QPoint(rootX, rootY), QSize(width, height));
executed: return QRect(QPoint(rootX, rootY), QSize(width, height));
Execution Count:4
4
201} -
202 -
203 -
204void QSystemTrayIconSys::mousePressEvent(QMouseEvent *ev) -
205{ -
206 QPoint globalPos = ev->globalPos();
never executed (the execution status of this line is deduced): QPoint globalPos = ev->globalPos();
-
207#ifndef QT_NO_CONTEXTMENU -
208 if (ev->button() == Qt::RightButton && q->contextMenu())
never evaluated: ev->button() == Qt::RightButton
never evaluated: q->contextMenu()
0
209 q->contextMenu()->popup(globalPos);
never executed: q->contextMenu()->popup(globalPos);
0
210#endif -
211 -
212 if (QBalloonTip::isBalloonVisible()) {
never evaluated: QBalloonTip::isBalloonVisible()
0
213 emit q->messageClicked();
never executed (the execution status of this line is deduced): q->messageClicked();
-
214 QBalloonTip::hideBalloon();
never executed (the execution status of this line is deduced): QBalloonTip::hideBalloon();
-
215 }
never executed: }
0
216 -
217 if (ev->button() == Qt::LeftButton)
never evaluated: ev->button() == Qt::LeftButton
0
218 emit q->activated(QSystemTrayIcon::Trigger);
never executed: q->activated(QSystemTrayIcon::Trigger);
0
219 else if (ev->button() == Qt::RightButton)
never evaluated: ev->button() == Qt::RightButton
0
220 emit q->activated(QSystemTrayIcon::Context);
never executed: q->activated(QSystemTrayIcon::Context);
0
221 else if (ev->button() == Qt::MidButton)
never evaluated: ev->button() == Qt::MidButton
0
222 emit q->activated(QSystemTrayIcon::MiddleClick);
never executed: q->activated(QSystemTrayIcon::MiddleClick);
0
223} -
224 -
225void QSystemTrayIconSys::mouseDoubleClickEvent(QMouseEvent *ev) -
226{ -
227 if (ev->button() == Qt::LeftButton)
never evaluated: ev->button() == Qt::LeftButton
0
228 emit q->activated(QSystemTrayIcon::DoubleClick);
never executed: q->activated(QSystemTrayIcon::DoubleClick);
0
229}
never executed: }
0
230 -
231bool QSystemTrayIconSys::event(QEvent *e) -
232{ -
233 switch (e->type()) { -
234#ifndef QT_NO_WHEELEVENT -
235 case QEvent::Wheel: -
236 return QApplication::sendEvent(q, e);
never executed: return QApplication::sendEvent(q, e);
0
237#endif -
238 default: -
239 break;
executed: break;
Execution Count:52
52
240 } -
241 return QWidget::event(e);
executed: return QWidget::event(e);
Execution Count:52
52
242} -
243 -
244void QSystemTrayIconSys::paintEvent(QPaintEvent *) -
245{ -
246 // Note: Transparent pixels require a particular Visual which XCB -
247 // currently does not support yet. -
248 const QRect rect(QPoint(0, 0), geometry().size());
executed (the execution status of this line is deduced): const QRect rect(QPoint(0, 0), geometry().size());
-
249 QPainter painter(this);
executed (the execution status of this line is deduced): QPainter painter(this);
-
250 painter.setCompositionMode(QPainter::CompositionMode_Source);
executed (the execution status of this line is deduced): painter.setCompositionMode(QPainter::CompositionMode_Source);
-
251 painter.fillRect(rect, Qt::transparent);
executed (the execution status of this line is deduced): painter.fillRect(rect, Qt::transparent);
-
252 painter.setCompositionMode(QPainter::CompositionMode_SourceOver);
executed (the execution status of this line is deduced): painter.setCompositionMode(QPainter::CompositionMode_SourceOver);
-
253 q->icon().paint(&painter, rect);
executed (the execution status of this line is deduced): q->icon().paint(&painter, rect);
-
254}
executed: }
Execution Count:1
1
255 -
256//////////////////////////////////////////////////////////////////////////// -
257 -
258QSystemTrayIconPrivate::QSystemTrayIconPrivate() -
259 : sys(0), -
260 visible(false) -
261{ -
262}
executed: }
Execution Count:4
4
263 -
264QSystemTrayIconPrivate::~QSystemTrayIconPrivate() -
265{ -
266} -
267 -
268void QSystemTrayIconPrivate::install_sys() -
269{ -
270 Q_Q(QSystemTrayIcon);
executed (the execution status of this line is deduced): QSystemTrayIcon * const q = q_func();
-
271 if (!sys && qX11SystemTrayContext()->isValid())
partially evaluated: !sys
TRUEFALSE
yes
Evaluation Count:3
no
Evaluation Count:0
partially evaluated: qX11SystemTrayContext()->isValid()
TRUEFALSE
yes
Evaluation Count:3
no
Evaluation Count:0
0-3
272 sys = new QSystemTrayIconSys(q);
executed: sys = new QSystemTrayIconSys(q);
Execution Count:3
3
273}
executed: }
Execution Count:3
3
274 -
275QRect QSystemTrayIconPrivate::geometry_sys() const -
276{ -
277 if (!sys)
never evaluated: !sys
0
278 return QRect();
never executed: return QRect();
0
279 return sys->globalGeometry();
never executed: return sys->globalGeometry();
0
280} -
281 -
282void QSystemTrayIconPrivate::remove_sys() -
283{ -
284 if (!sys)
evaluated: !sys
TRUEFALSE
yes
Evaluation Count:2
yes
Evaluation Count:3
2-3
285 return;
executed: return;
Execution Count:2
2
286 QBalloonTip::hideBalloon();
executed (the execution status of this line is deduced): QBalloonTip::hideBalloon();
-
287 sys->hide(); // this should do the trick, but...
executed (the execution status of this line is deduced): sys->hide();
-
288 delete sys; // wm may resize system tray only for DestroyEvents
executed (the execution status of this line is deduced): delete sys;
-
289 sys = 0;
executed (the execution status of this line is deduced): sys = 0;
-
290}
executed: }
Execution Count:3
3
291 -
292void QSystemTrayIconPrivate::updateIcon_sys() -
293{ -
294 if (sys)
evaluated: sys
TRUEFALSE
yes
Evaluation Count:1
yes
Evaluation Count:4
1-4
295 sys->updateIcon();
executed: sys->updateIcon();
Execution Count:1
1
296}
executed: }
Execution Count:5
5
297 -
298void QSystemTrayIconPrivate::updateMenu_sys() -
299{ -
300 -
301} -
302 -
303void QSystemTrayIconPrivate::updateToolTip_sys() -
304{ -
305 if (!sys)
partially evaluated: !sys
TRUEFALSE
yes
Evaluation Count:1
no
Evaluation Count:0
0-1
306 return;
executed: return;
Execution Count:1
1
307#ifndef QT_NO_TOOLTIP -
308 sys->setToolTip(toolTip);
never executed (the execution status of this line is deduced): sys->setToolTip(toolTip);
-
309#endif -
310}
never executed: }
0
311 -
312bool QSystemTrayIconPrivate::isSystemTrayAvailable_sys() -
313{ -
314 const QString platform = QGuiApplication::platformName();
never executed (the execution status of this line is deduced): const QString platform = QGuiApplication::platformName();
-
315 if (platform.compare(QStringLiteral("xcb"), Qt::CaseInsensitive) == 0)
never evaluated: platform.compare(QString::fromUtf8("" "xcb" "", sizeof("xcb") - 1), Qt::CaseInsensitive) == 0
0
316 return qX11SystemTrayContext()->locateSystemTray() != None;
never executed: return qX11SystemTrayContext()->locateSystemTray() != 0L;
0
317 return false;
never executed: return false;
0
318} -
319 -
320bool QSystemTrayIconPrivate::supportsMessages_sys() -
321{ -
322 return true;
executed: return true;
Execution Count:1
1
323} -
324 -
325void QSystemTrayIconPrivate::showMessage_sys(const QString &message, const QString &title, -
326 QSystemTrayIcon::MessageIcon icon, int msecs) -
327{ -
328 if (!sys)
partially evaluated: !sys
TRUEFALSE
no
Evaluation Count:0
yes
Evaluation Count:4
0-4
329 return;
never executed: return;
0
330 const QPoint g = sys->globalGeometry().topLeft();
executed (the execution status of this line is deduced): const QPoint g = sys->globalGeometry().topLeft();
-
331 QBalloonTip::showBalloon(icon, message, title, sys->systemTrayIcon(),
executed (the execution status of this line is deduced): QBalloonTip::showBalloon(icon, message, title, sys->systemTrayIcon(),
-
332 QPoint(g.x() + sys->width()/2, g.y() + sys->height()/2),
executed (the execution status of this line is deduced): QPoint(g.x() + sys->width()/2, g.y() + sys->height()/2),
-
333 msecs);
executed (the execution status of this line is deduced): msecs);
-
334}
executed: }
Execution Count:4
4
335 -
336QT_END_NAMESPACE -
337#endif //QT_NO_SYSTEMTRAYICON -
338 -
Source codeSwitch to Preprocessed file

Generated by Squish Coco Non-Commercial