qsystemtrayicon_x11.cpp

Absolute File Name:/home/qt/qt5_coco/qt5/qtbase/src/widgets/util/qsystemtrayicon_x11.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 QtWidgets 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#include "qlabel.h"-
35#include "qpainter.h"-
36#include "qpixmap.h"-
37#include "qbitmap.h"-
38#include "qevent.h"-
39#include "qapplication.h"-
40#include "qlist.h"-
41#include "qmenu.h"-
42#include "qtimer.h"-
43#include "qsystemtrayicon_p.h"-
44#include "qpaintengine.h"-
45#include <qwindow.h>-
46#include <qguiapplication.h>-
47#include <qscreen.h>-
48#include <qbackingstore.h>-
49#include <qpa/qplatformnativeinterface.h>-
50#include <qpa/qplatformsystemtrayicon.h>-
51#include <qpa/qplatformtheme.h>-
52#include <private/qguiapplication_p.h>-
53#include <qdebug.h>-
54-
55#include <QtPlatformHeaders/qxcbwindowfunctions.h>-
56#include <QtPlatformHeaders/qxcbintegrationfunctions.h>-
57#ifndef QT_NO_SYSTEMTRAYICON-
58QT_BEGIN_NAMESPACE-
59-
60static inline unsigned long locateSystemTray()-
61{-
62 return (unsigned long)QGuiApplication::platformNativeInterface()->nativeResourceForScreen(QByteArrayLiteral("traywindow"), QGuiApplication::primaryScreen());
never executed: return (unsigned long)QGuiApplication::platformNativeInterface()->nativeResourceForScreen(([]() -> QByteArray { enum { Size = sizeof("traywindow") - 1 }; static const QStaticByteArrayData<Size> qbytearray_literal = { { { { -1 } }, Size, 0, 0, sizeof(QByteArrayData) }, "traywindow" }; QByteArrayDataPtr holder = { qbytearray_literal.data_ptr() }; const QByteArray ba(holder); return ba; }()), QGuiApplication::primaryScreen());
never executed: return ba;
0
63}-
64-
65// System tray widget. Could be replaced by a QWindow with-
66// a backing store if it did not need tooltip handling.-
67class QSystemTrayIconSys : public QWidget-
68{-
69 Q_OBJECT-
70public:-
71 explicit QSystemTrayIconSys(QSystemTrayIcon *q);-
72-
73 inline void updateIcon() { update(); }
never executed: end of block
0
74 inline QSystemTrayIcon *systemTrayIcon() const { return q; }
never executed: return q;
0
75-
76 QRect globalGeometry() const;-
77-
78protected:-
79 virtual void mousePressEvent(QMouseEvent *ev) Q_DECL_OVERRIDE;-
80 virtual void mouseDoubleClickEvent(QMouseEvent *ev) Q_DECL_OVERRIDE;-
81 virtual bool event(QEvent *) Q_DECL_OVERRIDE;-
82 virtual void paintEvent(QPaintEvent *) Q_DECL_OVERRIDE;-
83 virtual void resizeEvent(QResizeEvent *) Q_DECL_OVERRIDE;-
84 virtual void moveEvent(QMoveEvent *) Q_DECL_OVERRIDE;-
85-
86private slots:-
87 void systemTrayWindowChanged(QScreen *screen);-
88-
89private:-
90 bool addToTray();-
91-
92 QSystemTrayIcon *q;-
93 QPixmap background;-
94};-
95-
96QSystemTrayIconSys::QSystemTrayIconSys(QSystemTrayIcon *qIn)-
97 : QWidget(0, Qt::Window | Qt::FramelessWindowHint | Qt::BypassWindowManagerHint)-
98 , q(qIn)-
99{-
100 setObjectName(QStringLiteral("QSystemTrayIconSys"));
never executed: return qstring_literal_temp;
0
101 setToolTip(q->toolTip());-
102 setAttribute(Qt::WA_AlwaysShowToolTips, true);-
103 setAttribute(Qt::WA_QuitOnClose, false);-
104 const QSize size(22, 22); // Gnome, standard size-
105 setGeometry(QRect(QPoint(0, 0), size));-
106 setMinimumSize(size);-
107-
108 // We need two different behaviors depending on whether the X11 visual for the system tray-
109 // (a) exists and (b) supports an alpha channel, i.e. is 32 bits.-
110 // If we have a visual that has an alpha channel, we can paint this widget with a transparent-
111 // background and it will work.-
112 // However, if there's no alpha channel visual, in order for transparent tray icons to work,-
113 // we do not have a transparent background on the widget, but set the BackPixmap property of our-
114 // window to ParentRelative (so that it inherits the background of its X11 parent window), call-
115 // xcb_clear_region before painting (so that the inherited background is visible) and then grab-
116 // the just-drawn background from the X11 server.-
117 bool hasAlphaChannel = QXcbIntegrationFunctions::xEmbedSystemTrayVisualHasAlphaChannel();-
118 setAttribute(Qt::WA_TranslucentBackground, hasAlphaChannel);-
119 if (!hasAlphaChannel) {
!hasAlphaChannelDescription
TRUEnever evaluated
FALSEnever evaluated
0
120 createWinId();-
121 QXcbWindowFunctions::setParentRelativeBackPixmap(windowHandle());-
122-
123 // XXX: This is actually required, but breaks things ("QWidget::paintEngine: Should no-
124 // longer be called"). Why is this needed? When the widget is drawn, we use tricks to grab-
125 // the tray icon's background from the server. If the tray icon isn't visible (because-
126 // another window is on top of it), the trick fails and instead uses the content of that-
127 // other window as the background.-
128 // setAttribute(Qt::WA_PaintOnScreen);-
129 }
never executed: end of block
0
130-
131 addToTray();-
132}
never executed: end of block
0
133-
134bool QSystemTrayIconSys::addToTray()-
135{-
136 if (!locateSystemTray())
!locateSystemTray()Description
TRUEnever evaluated
FALSEnever evaluated
0
137 return false;
never executed: return false;
0
138-
139 createWinId();-
140 setMouseTracking(true);-
141-
142 if (!QXcbWindowFunctions::requestSystemTrayWindowDock(windowHandle()))
!QXcbWindowFun...indowHandle())Description
TRUEnever evaluated
FALSEnever evaluated
0
143 return false;
never executed: return false;
0
144-
145 if (!background.isNull())
!background.isNull()Description
TRUEnever evaluated
FALSEnever evaluated
0
146 background = QPixmap();
never executed: background = QPixmap();
0
147 show();-
148 return true;
never executed: return true;
0
149}-
150-
151void QSystemTrayIconSys::systemTrayWindowChanged(QScreen *)-
152{-
153 if (locateSystemTray()) {
locateSystemTray()Description
TRUEnever evaluated
FALSEnever evaluated
0
154 addToTray();-
155 } else {
never executed: end of block
0
156 QBalloonTip::hideBalloon();-
157 hide(); // still no luck-
158 destroy();-
159 }
never executed: end of block
0
160}-
161-
162QRect QSystemTrayIconSys::globalGeometry() const-
163{-
164 return QXcbWindowFunctions::systemTrayWindowGlobalGeometry(windowHandle());
never executed: return QXcbWindowFunctions::systemTrayWindowGlobalGeometry(windowHandle());
0
165}-
166-
167void QSystemTrayIconSys::mousePressEvent(QMouseEvent *ev)-
168{-
169 QPoint globalPos = ev->globalPos();-
170#ifndef QT_NO_CONTEXTMENU-
171 if (ev->button() == Qt::RightButton && q->contextMenu())
ev->button() =...t::RightButtonDescription
TRUEnever evaluated
FALSEnever evaluated
q->contextMenu()Description
TRUEnever evaluated
FALSEnever evaluated
0
172 q->contextMenu()->popup(globalPos);
never executed: q->contextMenu()->popup(globalPos);
0
173#endif-
174-
175 if (QBalloonTip::isBalloonVisible()) {
QBalloonTip::i...lloonVisible()Description
TRUEnever evaluated
FALSEnever evaluated
0
176 emit q->messageClicked();-
177 QBalloonTip::hideBalloon();-
178 }
never executed: end of block
0
179-
180 if (ev->button() == Qt::LeftButton)
ev->button() == Qt::LeftButtonDescription
TRUEnever evaluated
FALSEnever evaluated
0
181 emit q->activated(QSystemTrayIcon::Trigger);
never executed: q->activated(QSystemTrayIcon::Trigger);
0
182 else if (ev->button() == Qt::RightButton)
ev->button() =...t::RightButtonDescription
TRUEnever evaluated
FALSEnever evaluated
0
183 emit q->activated(QSystemTrayIcon::Context);
never executed: q->activated(QSystemTrayIcon::Context);
0
184 else if (ev->button() == Qt::MidButton)
ev->button() == Qt::MidButtonDescription
TRUEnever evaluated
FALSEnever evaluated
0
185 emit q->activated(QSystemTrayIcon::MiddleClick);
never executed: q->activated(QSystemTrayIcon::MiddleClick);
0
186}
never executed: end of block
0
187-
188void QSystemTrayIconSys::mouseDoubleClickEvent(QMouseEvent *ev)-
189{-
190 if (ev->button() == Qt::LeftButton)
ev->button() == Qt::LeftButtonDescription
TRUEnever evaluated
FALSEnever evaluated
0
191 emit q->activated(QSystemTrayIcon::DoubleClick);
never executed: q->activated(QSystemTrayIcon::DoubleClick);
0
192}
never executed: end of block
0
193-
194bool QSystemTrayIconSys::event(QEvent *e)-
195{-
196 switch (e->type()) {-
197 case QEvent::ToolTip:
never executed: case QEvent::ToolTip:
0
198 QApplication::sendEvent(q, e);-
199 break;
never executed: break;
0
200#ifndef QT_NO_WHEELEVENT-
201 case QEvent::Wheel:
never executed: case QEvent::Wheel:
0
202 return QApplication::sendEvent(q, e);
never executed: return QApplication::sendEvent(q, e);
0
203#endif-
204 default:
never executed: default:
0
205 break;
never executed: break;
0
206 }-
207 return QWidget::event(e);
never executed: return QWidget::event(e);
0
208}-
209-
210void QSystemTrayIconSys::paintEvent(QPaintEvent *)-
211{-
212 const QRect rect(QPoint(0, 0), geometry().size());-
213 QPainter painter(this);-
214-
215 // If we have Qt::WA_TranslucentBackground set, during widget creation-
216 // we detected the systray visual supported an alpha channel-
217 if (testAttribute(Qt::WA_TranslucentBackground)) {
testAttribute(...entBackground)Description
TRUEnever evaluated
FALSEnever evaluated
0
218 painter.setCompositionMode(QPainter::CompositionMode_Source);-
219 painter.fillRect(rect, Qt::transparent);-
220 } else {
never executed: end of block
0
221 // clearRegion() was called on XEMBED_EMBEDDED_NOTIFY, so we hope that got done by now.-
222 // Grab the tray background pixmap, before rendering the icon for the first time.-
223 if (background.isNull()) {
background.isNull()Description
TRUEnever evaluated
FALSEnever evaluated
0
224 background = QGuiApplication::primaryScreen()->grabWindow(winId(),-
225 0, 0, rect.size().width(), rect.size().height());-
226 }
never executed: end of block
0
227 // Then paint over the icon area with the background before compositing the icon on top.-
228 painter.drawPixmap(QPoint(0, 0), background);-
229 }
never executed: end of block
0
230 painter.setCompositionMode(QPainter::CompositionMode_SourceOver);-
231 q->icon().paint(&painter, rect);-
232}
never executed: end of block
0
233-
234void QSystemTrayIconSys::moveEvent(QMoveEvent *event)-
235{-
236 QWidget::moveEvent(event);-
237 if (QBalloonTip::isBalloonVisible())
QBalloonTip::i...lloonVisible()Description
TRUEnever evaluated
FALSEnever evaluated
0
238 QBalloonTip::updateBalloonPosition(globalGeometry().center());
never executed: QBalloonTip::updateBalloonPosition(globalGeometry().center());
0
239}
never executed: end of block
0
240-
241void QSystemTrayIconSys::resizeEvent(QResizeEvent *event)-
242{-
243 update();-
244 QWidget::resizeEvent(event);-
245 if (QBalloonTip::isBalloonVisible())
QBalloonTip::i...lloonVisible()Description
TRUEnever evaluated
FALSEnever evaluated
0
246 QBalloonTip::updateBalloonPosition(globalGeometry().center());
never executed: QBalloonTip::updateBalloonPosition(globalGeometry().center());
0
247}
never executed: end of block
0
248////////////////////////////////////////////////////////////////////////////-
249-
250QSystemTrayIconPrivate::QSystemTrayIconPrivate()-
251 : sys(0),-
252 qpa_sys(QGuiApplicationPrivate::platformTheme()->createPlatformSystemTrayIcon()),-
253 visible(false)-
254{-
255}
never executed: end of block
0
256-
257QSystemTrayIconPrivate::~QSystemTrayIconPrivate()-
258{-
259 delete qpa_sys;-
260}
never executed: end of block
0
261-
262void QSystemTrayIconPrivate::install_sys()-
263{-
264 if (qpa_sys) {
qpa_sysDescription
TRUEnever evaluated
FALSEnever evaluated
0
265 install_sys_qpa();-
266 return;
never executed: return;
0
267 }-
268 Q_Q(QSystemTrayIcon);-
269 if (!sys && locateSystemTray()) {
!sysDescription
TRUEnever evaluated
FALSEnever evaluated
locateSystemTray()Description
TRUEnever evaluated
FALSEnever evaluated
0
270 sys = new QSystemTrayIconSys(q);-
271 QObject::connect(QGuiApplication::platformNativeInterface(), SIGNAL(systemTrayWindowChanged(QScreen*)),-
272 sys, SLOT(systemTrayWindowChanged(QScreen*)));-
273 }
never executed: end of block
0
274}
never executed: end of block
0
275-
276QRect QSystemTrayIconPrivate::geometry_sys() const-
277{-
278 if (qpa_sys)
qpa_sysDescription
TRUEnever evaluated
FALSEnever evaluated
0
279 return geometry_sys_qpa();
never executed: return geometry_sys_qpa();
0
280 if (!sys)
!sysDescription
TRUEnever evaluated
FALSEnever evaluated
0
281 return QRect();
never executed: return QRect();
0
282 return sys->globalGeometry();
never executed: return sys->globalGeometry();
0
283}-
284-
285void QSystemTrayIconPrivate::remove_sys()-
286{-
287 if (qpa_sys) {
qpa_sysDescription
TRUEnever evaluated
FALSEnever evaluated
0
288 remove_sys_qpa();-
289 return;
never executed: return;
0
290 }-
291 if (!sys)
!sysDescription
TRUEnever evaluated
FALSEnever evaluated
0
292 return;
never executed: return;
0
293 QBalloonTip::hideBalloon();-
294 sys->hide(); // this should do the trick, but...-
295 delete sys; // wm may resize system tray only for DestroyEvents-
296 sys = 0;-
297}
never executed: end of block
0
298-
299void QSystemTrayIconPrivate::updateIcon_sys()-
300{-
301 if (qpa_sys) {
qpa_sysDescription
TRUEnever evaluated
FALSEnever evaluated
0
302 updateIcon_sys_qpa();-
303 return;
never executed: return;
0
304 }-
305 if (sys)
sysDescription
TRUEnever evaluated
FALSEnever evaluated
0
306 sys->updateIcon();
never executed: sys->updateIcon();
0
307}
never executed: end of block
0
308-
309void QSystemTrayIconPrivate::updateMenu_sys()-
310{-
311 if (qpa_sys)
qpa_sysDescription
TRUEnever evaluated
FALSEnever evaluated
0
312 updateMenu_sys_qpa();
never executed: updateMenu_sys_qpa();
0
313}
never executed: end of block
0
314-
315void QSystemTrayIconPrivate::updateToolTip_sys()-
316{-
317 if (qpa_sys) {
qpa_sysDescription
TRUEnever evaluated
FALSEnever evaluated
0
318 updateToolTip_sys_qpa();-
319 return;
never executed: return;
0
320 }-
321 if (!sys)
!sysDescription
TRUEnever evaluated
FALSEnever evaluated
0
322 return;
never executed: return;
0
323#ifndef QT_NO_TOOLTIP-
324 sys->setToolTip(toolTip);-
325#endif-
326}
never executed: end of block
0
327-
328bool QSystemTrayIconPrivate::isSystemTrayAvailable_sys()-
329{-
330 QScopedPointer<QPlatformSystemTrayIcon> sys(QGuiApplicationPrivate::platformTheme()->createPlatformSystemTrayIcon());-
331 if (sys && sys->isSystemTrayAvailable())
sysDescription
TRUEnever evaluated
FALSEnever evaluated
sys->isSystemTrayAvailable()Description
TRUEnever evaluated
FALSEnever evaluated
0
332 return true;
never executed: return true;
0
333-
334 // no QPlatformSystemTrayIcon so fall back to default xcb platform behavior-
335 const QString platform = QGuiApplication::platformName();-
336 if (platform.compare(QLatin1String("xcb"), Qt::CaseInsensitive) == 0)
platform.compa...ensitive) == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
337 return locateSystemTray();
never executed: return locateSystemTray();
0
338 return false;
never executed: return false;
0
339}-
340-
341bool QSystemTrayIconPrivate::supportsMessages_sys()-
342{-
343 QScopedPointer<QPlatformSystemTrayIcon> sys(QGuiApplicationPrivate::platformTheme()->createPlatformSystemTrayIcon());-
344 if (sys)
sysDescription
TRUEnever evaluated
FALSEnever evaluated
0
345 return sys->supportsMessages();
never executed: return sys->supportsMessages();
0
346-
347 // no QPlatformSystemTrayIcon so fall back to default xcb platform behavior-
348 return true;
never executed: return true;
0
349}-
350-
351void QSystemTrayIconPrivate::showMessage_sys(const QString &title, const QString &message,-
352 QSystemTrayIcon::MessageIcon icon, int msecs)-
353{-
354 if (qpa_sys) {
qpa_sysDescription
TRUEnever evaluated
FALSEnever evaluated
0
355 showMessage_sys_qpa(title, message, icon, msecs);-
356 return;
never executed: return;
0
357 }-
358 if (!sys)
!sysDescription
TRUEnever evaluated
FALSEnever evaluated
0
359 return;
never executed: return;
0
360 QBalloonTip::showBalloon(icon, title, message, sys->systemTrayIcon(),-
361 sys->globalGeometry().center(),-
362 msecs);-
363}
never executed: end of block
0
364-
365QT_END_NAMESPACE-
366-
367#include "qsystemtrayicon_x11.moc"-
368-
369#endif //QT_NO_SYSTEMTRAYICON-
Source codeSwitch to Preprocessed file

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