1 System tray icon plugin system for SNI
2 diff --git a/examples/desktop/systray/window.cpp b/examples/desktop/systray/window.cpp
3 index 4091358..50c4ca6 100644
4 --- a/examples/desktop/systray/window.cpp
5 +++ b/examples/desktop/systray/window.cpp
6 @@ -158,15 +158,23 @@ void Window::createIconGroupBox()
7 iconComboBox->addItem(QIcon(":/images/bad.svg"), tr("Bad"));
8 iconComboBox->addItem(QIcon(":/images/heart.svg"), tr("Heart"));
9 iconComboBox->addItem(QIcon(":/images/trash.svg"), tr("Trash"));
10 + iconComboBox->addItem(QIcon::fromTheme("system-file-manager"), tr("File Manager"));
12 showIconCheckBox = new QCheckBox(tr("Show icon"));
13 showIconCheckBox->setChecked(true);
15 +#if defined(Q_WS_X11)
16 + jitToolTipCheckBox = new QCheckBox(tr("Just In Time Tooltip"));
19 QHBoxLayout *iconLayout = new QHBoxLayout;
20 iconLayout->addWidget(iconLabel);
21 iconLayout->addWidget(iconComboBox);
22 iconLayout->addStretch();
23 iconLayout->addWidget(showIconCheckBox);
24 +#if defined(Q_WS_X11)
25 + iconLayout->addWidget(jitToolTipCheckBox);
27 iconGroupBox->setLayout(iconLayout);
30 @@ -254,5 +262,37 @@ void Window::createTrayIcon()
31 trayIconMenu->addAction(quitAction);
33 trayIcon = new QSystemTrayIcon(this);
34 + QByteArray category = qgetenv("SNI_CATEGORY");
35 + if (!category.isEmpty()) {
36 + trayIcon->setProperty("_qt_sni_category", QString::fromLocal8Bit(category));
38 trayIcon->setContextMenu(trayIconMenu);
40 +#if defined(Q_WS_X11)
41 + trayIcon->installEventFilter(this);
45 +#if defined(Q_WS_X11)
46 +bool Window::eventFilter(QObject *, QEvent *event)
48 + switch(event->type()) {
49 + case QEvent::ToolTip:
50 + if (jitToolTipCheckBox->isChecked()) {
51 + QString timeString = QTime::currentTime().toString();
52 + trayIcon->setToolTip(tr("Current Time: %1").arg(timeString));
55 + case QEvent::Wheel: {
56 + QWheelEvent *wheelEvent = static_cast<QWheelEvent*>(event);
57 + int delta = wheelEvent->delta() > 0 ? 1 : -1;
58 + int index = (iconComboBox->currentIndex() + delta) % iconComboBox->count();
59 + iconComboBox->setCurrentIndex(index);
68 diff --git a/examples/desktop/systray/window.h b/examples/desktop/systray/window.h
69 index 537a8a2..374a623 100644
70 --- a/examples/desktop/systray/window.h
71 +++ b/examples/desktop/systray/window.h
72 @@ -69,6 +69,9 @@ public:
75 void closeEvent(QCloseEvent *event);
76 +#if defined(Q_WS_X11)
77 + bool eventFilter(QObject *object, QEvent *event);
81 void setIcon(int index);
82 @@ -86,6 +89,9 @@ private:
84 QComboBox *iconComboBox;
85 QCheckBox *showIconCheckBox;
86 +#if defined(Q_WS_X11)
87 + QCheckBox *jitToolTipCheckBox;
90 QGroupBox *messageGroupBox;
92 diff --git a/src/gui/util/qabstractsystemtrayiconsys.cpp b/src/gui/util/qabstractsystemtrayiconsys.cpp
94 index 0000000..0c4f7ae
96 +++ b/src/gui/util/qabstractsystemtrayiconsys.cpp
98 +/****************************************************************************
100 +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
101 +** All rights reserved.
102 +** Contact: Nokia Corporation (qt-info@nokia.com)
104 +** This file is part of the QtGui module of the Qt Toolkit.
106 +** $QT_BEGIN_LICENSE:LGPL$
107 +** GNU Lesser General Public License Usage
108 +** This file may be used under the terms of the GNU Lesser General Public
109 +** License version 2.1 as published by the Free Software Foundation and
110 +** appearing in the file LICENSE.LGPL included in the packaging of this
111 +** file. Please review the following information to ensure the GNU Lesser
112 +** General Public License version 2.1 requirements will be met:
113 +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
115 +** In addition, as a special exception, Nokia gives you certain additional
116 +** rights. These rights are described in the Nokia Qt LGPL Exception
117 +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
119 +** GNU General Public License Usage
120 +** Alternatively, this file may be used under the terms of the GNU General
121 +** Public License version 3.0 as published by the Free Software Foundation
122 +** and appearing in the file LICENSE.GPL included in the packaging of this
123 +** file. Please review the following information to ensure the GNU General
124 +** Public License version 3.0 requirements will be met:
125 +** http://www.gnu.org/copyleft/gpl.html.
128 +** Alternatively, this file may be used in accordance with the terms and
129 +** conditions contained in a signed written agreement between you and Nokia.
137 +****************************************************************************/
138 +#ifndef QT_NO_SYSTEMTRAYICON
140 +#include "qabstractsystemtrayiconsys_p.h"
143 +QSystemTrayIconSysFactoryInterface::QSystemTrayIconSysFactoryInterface()
147 +/////////////////////////////////////////////////
148 +QAbstractSystemTrayIconSys::QAbstractSystemTrayIconSys(QSystemTrayIcon *icon)
153 +QAbstractSystemTrayIconSys::~QAbstractSystemTrayIconSys()
157 +void QAbstractSystemTrayIconSys::sendActivated(QSystemTrayIcon::ActivationReason reason)
159 + qtsystray_sendActivated(trayIcon, reason);
163 diff --git a/src/gui/util/qabstractsystemtrayiconsys_p.h b/src/gui/util/qabstractsystemtrayiconsys_p.h
165 index 0000000..65ca2f6
167 +++ b/src/gui/util/qabstractsystemtrayiconsys_p.h
169 +/****************************************************************************
171 +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
172 +** All rights reserved.
173 +** Contact: Nokia Corporation (qt-info@nokia.com)
175 +** This file is part of the QtGui module of the Qt Toolkit.
177 +** $QT_BEGIN_LICENSE:LGPL$
178 +** GNU Lesser General Public License Usage
179 +** This file may be used under the terms of the GNU Lesser General Public
180 +** License version 2.1 as published by the Free Software Foundation and
181 +** appearing in the file LICENSE.LGPL included in the packaging of this
182 +** file. Please review the following information to ensure the GNU Lesser
183 +** General Public License version 2.1 requirements will be met:
184 +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
186 +** In addition, as a special exception, Nokia gives you certain additional
187 +** rights. These rights are described in the Nokia Qt LGPL Exception
188 +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
190 +** GNU General Public License Usage
191 +** Alternatively, this file may be used under the terms of the GNU General
192 +** Public License version 3.0 as published by the Free Software Foundation
193 +** and appearing in the file LICENSE.GPL included in the packaging of this
194 +** file. Please review the following information to ensure the GNU General
195 +** Public License version 3.0 requirements will be met:
196 +** http://www.gnu.org/copyleft/gpl.html.
199 +** Alternatively, this file may be used in accordance with the terms and
200 +** conditions contained in a signed written agreement between you and Nokia.
208 +****************************************************************************/
210 +#ifndef QABSTRACTSYSTEMTRAYICONSYS_P_H
211 +#define QABSTRACTSYSTEMTRAYICONSYS_P_H
217 +// This file is not part of the Qt API. It exists for the convenience
218 +// of a number of Qt sources files. This header file may change from
219 +// version to version without notice, or even be removed.
224 +#ifndef QT_NO_SYSTEMTRAYICON
226 +#include <qfactoryinterface.h>
227 +#include <qsystemtrayicon.h>
229 +class QAbstractSystemTrayIconSys;
231 +class Q_GUI_EXPORT QSystemTrayIconSysFactoryInterface : public QObject, public QFactoryInterface
235 + QSystemTrayIconSysFactoryInterface();
236 + virtual QAbstractSystemTrayIconSys * create(QSystemTrayIcon *) = 0;
237 + virtual bool isAvailable() const = 0;
240 + virtual QStringList keys() const { return QStringList() << QLatin1String("default"); }
243 + void availableChanged(bool);
246 +#define QSystemTrayIconSysFactoryInterface_iid "com.nokia.qt.QSystemTrayIconSysFactoryInterface"
247 +Q_DECLARE_INTERFACE(QSystemTrayIconSysFactoryInterface, QSystemTrayIconSysFactoryInterface_iid)
251 +class Q_GUI_EXPORT QAbstractSystemTrayIconSys
254 + QAbstractSystemTrayIconSys(QSystemTrayIcon *icon);
255 + virtual ~QAbstractSystemTrayIconSys();
257 + virtual QRect geometry() const = 0;
258 + virtual void updateVisibility() = 0;
259 + virtual void updateIcon() = 0;
260 + virtual void updateToolTip() = 0;
261 + virtual void updateMenu() = 0;
262 + virtual void showMessage(const QString &message, const QString &title,
263 + QSystemTrayIcon::MessageIcon icon, int msecs) = 0;
265 + void sendActivated(QSystemTrayIcon::ActivationReason);
268 + QSystemTrayIcon *trayIcon;
271 +#endif // QT_NO_SYSTEMTRAYICON
273 +#endif // QABSTRACTSYSTEMTRAYICONSYS_P_H
275 diff --git a/src/gui/util/qsystemtrayicon.cpp b/src/gui/util/qsystemtrayicon.cpp
276 index 28d4932..96d68fc 100644
277 --- a/src/gui/util/qsystemtrayicon.cpp
278 +++ b/src/gui/util/qsystemtrayicon.cpp
279 @@ -287,12 +287,6 @@ bool QSystemTrayIcon::isVisible() const
281 bool QSystemTrayIcon::event(QEvent *e)
283 -#if defined(Q_WS_X11)
284 - if (e->type() == QEvent::ToolTip) {
285 - Q_D(QSystemTrayIcon);
286 - return d->sys->deliverToolTipEvent(e);
289 return QObject::event(e);
292 diff --git a/src/gui/util/qsystemtrayicon_p.h b/src/gui/util/qsystemtrayicon_p.h
293 index 14495ee..2596658 100644
294 --- a/src/gui/util/qsystemtrayicon_p.h
295 +++ b/src/gui/util/qsystemtrayicon_p.h
297 #include "QtGui/qpixmap.h"
298 #include "QtCore/qstring.h"
299 #include "QtCore/qpointer.h"
300 +#if defined(Q_WS_X11)
301 +#include "QtCore/qset.h"
306 +#if defined(Q_WS_X11)
307 +class QAbstractSystemTrayIconSys;
309 class QSystemTrayIconSys;
314 @@ -75,6 +82,9 @@ class QSystemTrayIconPrivate : public QObjectPrivate
317 QSystemTrayIconPrivate() : sys(0), visible(false) { }
318 + #if defined(Q_WS_X11)
319 + ~QSystemTrayIconPrivate();
324 @@ -90,7 +100,11 @@ public:
325 QPointer<QMenu> menu;
328 + #if defined(Q_WS_X11)
329 + QAbstractSystemTrayIconSys *sys;
331 QSystemTrayIconSys *sys;
336 @@ -123,60 +137,37 @@ private:
339 #if defined(Q_WS_X11)
340 -QT_BEGIN_INCLUDE_NAMESPACE
341 -#include <QtCore/qcoreapplication.h>
342 -#include <X11/Xlib.h>
343 -#include <X11/Xatom.h>
344 -#include <X11/Xutil.h>
345 -QT_END_INCLUDE_NAMESPACE
347 -class QSystemTrayIconSys : public QWidget
348 +class QSystemTrayIconSysFactoryInterface;
351 + * This class acts as a composite QSystemTrayIconSysFactory: It can create
352 + * instances of QAbstractSystemTrayIconSys* using either a plugin or the
353 + * builtin factory and will cause QSystemTrayIconPrivate to recreate their
354 + * 'sys' instances if the plugin availability changes.
356 +class QSystemTrayIconSysFactory : public QObject
358 - friend class QSystemTrayIconPrivate;
362 - QSystemTrayIconSys(QSystemTrayIcon *q);
363 - ~QSystemTrayIconSys();
365 - SYSTEM_TRAY_REQUEST_DOCK = 0,
366 - SYSTEM_TRAY_BEGIN_MESSAGE = 1,
367 - SYSTEM_TRAY_CANCEL_MESSAGE =2
372 - XVisualInfo* getSysTrayVisualInfo();
374 - // QObject::event is public but QWidget's ::event() re-implementation
376 - inline bool deliverToolTipEvent(QEvent *e)
377 - { return QWidget::event(e); }
379 - static Window sysTrayWindow;
380 - static QList<QSystemTrayIconSys *> trayIcons;
381 - static QCoreApplication::EventFilter oldEventFilter;
382 - static bool sysTrayTracker(void *message, long *result);
383 - static Window locateSystemTray();
384 - static Atom sysTraySelection;
385 - static XVisualInfo sysTrayVisual;
386 + QSystemTrayIconSysFactory();
387 + void registerSystemTrayIconPrivate(QSystemTrayIconPrivate *iconPrivate);
388 + void unregisterSystemTrayIconPrivate(QSystemTrayIconPrivate *iconPrivate);
391 - void paintEvent(QPaintEvent *pe);
392 - void resizeEvent(QResizeEvent *re);
393 - bool x11Event(XEvent *event);
394 - void mousePressEvent(QMouseEvent *event);
395 - void mouseDoubleClickEvent(QMouseEvent *event);
396 -#ifndef QT_NO_WHEELEVENT
397 - void wheelEvent(QWheelEvent *event);
399 - bool event(QEvent *e);
400 + QAbstractSystemTrayIconSys *create(QSystemTrayIcon *) const;
402 + bool isAvailable() const;
405 + void refreshTrayIconPrivates();
408 - QPixmap background;
409 - QSystemTrayIcon *q;
411 + QSystemTrayIconSysFactoryInterface *factory() const;
412 + void loadPluginFactory();
414 + QSystemTrayIconSysFactoryInterface *pluginFactory;
415 + QSet<QSystemTrayIconPrivate *> trayIconPrivates;
422 diff --git a/src/gui/util/qsystemtrayicon_x11.cpp b/src/gui/util/qsystemtrayicon_x11.cpp
423 index 86c2749..33f672b 100644
424 --- a/src/gui/util/qsystemtrayicon_x11.cpp
425 +++ b/src/gui/util/qsystemtrayicon_x11.cpp
426 @@ -38,311 +38,114 @@
429 ****************************************************************************/
430 +#ifndef QT_NO_SYSTEMTRAYICON
432 +#include <private/qfactoryloader_p.h>
434 -#include "private/qt_x11_p.h"
436 -#include "qx11info_x11.h"
437 -#include "qpainter.h"
438 -#include "qpixmap.h"
439 -#include "qbitmap.h"
441 -#include "qapplication.h"
445 #include "qsystemtrayicon_p.h"
446 -#include "qpaintengine.h"
447 +#include "qabstractsystemtrayiconsys_p.h"
448 +#include "qcoreapplication.h"
449 +#include "qxembedsystemtrayicon_x11_p.h"
451 -#ifndef QT_NO_SYSTEMTRAYICON
454 -Window QSystemTrayIconSys::sysTrayWindow = XNone;
455 -QList<QSystemTrayIconSys *> QSystemTrayIconSys::trayIcons;
456 -QCoreApplication::EventFilter QSystemTrayIconSys::oldEventFilter = 0;
457 -Atom QSystemTrayIconSys::sysTraySelection = XNone;
458 -XVisualInfo QSystemTrayIconSys::sysTrayVisual = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
459 +Q_GLOBAL_STATIC(QSystemTrayIconSysFactory, qt_guiSystemTrayIconSysFactory)
461 -// Locate the system tray
462 -Window QSystemTrayIconSys::locateSystemTray()
463 +QSystemTrayIconSysFactory::QSystemTrayIconSysFactory()
466 - Display *display = QX11Info::display();
467 - if (sysTraySelection == XNone) {
468 - int screen = QX11Info::appScreen();
469 - QString net_sys_tray = QString::fromLatin1("_NET_SYSTEM_TRAY_S%1").arg(screen);
470 - sysTraySelection = XInternAtom(display, net_sys_tray.toLatin1(), False);
473 - return XGetSelectionOwner(QX11Info::display(), sysTraySelection);
476 -XVisualInfo* QSystemTrayIconSys::getSysTrayVisualInfo()
477 +void QSystemTrayIconSysFactory::loadPluginFactory()
479 - Display *display = QX11Info::display();
481 - if (!sysTrayVisual.visual) {
482 - Window win = locateSystemTray();
483 - if (win != XNone) {
486 - ulong nitems, bytes_remaining;
488 - int result = XGetWindowProperty(display, win, ATOM(_NET_SYSTEM_TRAY_VISUAL), 0, 1,
489 - False, XA_VISUALID, &actual_type,
490 - &actual_format, &nitems, &bytes_remaining, &data);
492 - if (result == Success && data && actual_type == XA_VISUALID && actual_format == 32 &&
493 - nitems == 1 && bytes_remaining == 0)
494 - vid = *(VisualID*)data;
500 - uint mask = VisualIDMask;
501 - XVisualInfo *vi, rvi;
503 - rvi.visualid = vid;
504 - vi = XGetVisualInfo(display, mask, &rvi, &count);
506 - sysTrayVisual = vi[0];
509 - if (sysTrayVisual.depth != 32)
510 - memset(&sysTrayVisual, 0, sizeof(sysTrayVisual));
512 + if (pluginFactory) {
516 - return sysTrayVisual.visual ? &sysTrayVisual : 0;
519 -bool QSystemTrayIconSys::sysTrayTracker(void *message, long *result)
521 - bool retval = false;
522 - if (QSystemTrayIconSys::oldEventFilter)
523 - retval = QSystemTrayIconSys::oldEventFilter(message, result);
525 - if (trayIcons.isEmpty())
528 - Display *display = QX11Info::display();
529 - XEvent *ev = (XEvent *)message;
530 - if (ev->type == DestroyNotify && ev->xany.window == sysTrayWindow) {
531 - sysTrayWindow = locateSystemTray();
532 - memset(&sysTrayVisual, 0, sizeof(sysTrayVisual));
533 - for (int i = 0; i < trayIcons.count(); i++) {
534 - if (sysTrayWindow == XNone) {
535 - QBalloonTip::hideBalloon();
536 - trayIcons[i]->hide(); // still no luck
537 - trayIcons[i]->destroy();
538 - trayIcons[i]->create();
540 - trayIcons[i]->addToTray(); // add it to the new tray
543 - } else if (ev->type == ClientMessage && sysTrayWindow == XNone) {
544 - static Atom manager_atom = XInternAtom(display, "MANAGER", False);
545 - XClientMessageEvent *cm = (XClientMessageEvent *)message;
546 - if ((cm->message_type == manager_atom) && ((Atom)cm->data.l[1] == sysTraySelection)) {
547 - sysTrayWindow = cm->data.l[2];
548 - memset(&sysTrayVisual, 0, sizeof(sysTrayVisual));
549 - XSelectInput(display, sysTrayWindow, StructureNotifyMask);
550 - for (int i = 0; i < trayIcons.count(); i++) {
551 - trayIcons[i]->addToTray();
555 - } else if (ev->type == PropertyNotify && ev->xproperty.atom == ATOM(_NET_SYSTEM_TRAY_VISUAL) &&
556 - ev->xproperty.window == sysTrayWindow) {
557 - memset(&sysTrayVisual, 0, sizeof(sysTrayVisual));
558 - for (int i = 0; i < trayIcons.count(); i++) {
559 - trayIcons[i]->addToTray();
561 +#ifndef QT_NO_LIBRARY
562 + QFactoryLoader loader(QSystemTrayIconSysFactoryInterface_iid, QLatin1String("/systemtrayicon"));
563 + pluginFactory = qobject_cast<QSystemTrayIconSysFactoryInterface *>(loader.instance(QLatin1String("default")));
564 + if (pluginFactory) {
565 + // Set parent to ensure factory destructor is called when application
567 + pluginFactory->setParent(QCoreApplication::instance());
568 + connect(pluginFactory, SIGNAL(availableChanged(bool)), SLOT(refreshTrayIconPrivates()));
572 +#endif // QT_NO_LIBRARY
575 -QSystemTrayIconSys::QSystemTrayIconSys(QSystemTrayIcon *q)
576 - : QWidget(0, Qt::FramelessWindowHint | Qt::X11BypassWindowManagerHint),
578 +QSystemTrayIconSysFactoryInterface *QSystemTrayIconSysFactory::factory() const
580 - setAttribute(Qt::WA_AlwaysShowToolTips);
581 - setAttribute(Qt::WA_QuitOnClose, false);
582 - setAttribute(Qt::WA_NoSystemBackground, true);
583 - setAttribute(Qt::WA_PaintOnScreen);
585 - static bool eventFilterAdded = false;
586 - Display *display = QX11Info::display();
587 - if (!eventFilterAdded) {
588 - oldEventFilter = qApp->setEventFilter(sysTrayTracker);
589 - eventFilterAdded = true;
590 - Window root = QX11Info::appRootWindow();
591 - XWindowAttributes attr;
592 - XGetWindowAttributes(display, root, &attr);
593 - if ((attr.your_event_mask & StructureNotifyMask) != StructureNotifyMask) {
594 - (void) QApplication::desktop(); // lame trick to ensure our event mask is not overridden
595 - XSelectInput(display, root, attr.your_event_mask | StructureNotifyMask); // for MANAGER selection
597 + if (!pluginFactory) {
598 + const_cast<QSystemTrayIconSysFactory*>(this)->loadPluginFactory();
600 - if (trayIcons.isEmpty()) {
601 - sysTrayWindow = locateSystemTray();
602 - if (sysTrayWindow != XNone)
603 - XSelectInput(display, sysTrayWindow, StructureNotifyMask); // track tray events
605 - trayIcons.append(this);
606 - setMouseTracking(true);
607 -#ifndef QT_NO_TOOLTIP
608 - setToolTip(q->toolTip());
610 - if (sysTrayWindow != XNone)
614 -QSystemTrayIconSys::~QSystemTrayIconSys()
616 - trayIcons.removeAt(trayIcons.indexOf(this));
617 - Display *display = QX11Info::display();
618 - if (trayIcons.isEmpty()) {
619 - if (sysTrayWindow == XNone)
622 - XSelectInput(display, sysTrayWindow, 0); // stop tracking the tray
623 - sysTrayWindow = XNone;
624 + if (pluginFactory && pluginFactory->isAvailable()) {
625 + return pluginFactory;
628 - XFreeColormap(display, colormap);
629 + static QXEmbedSystemTrayIconSysFactory def;
630 + return def.isAvailable() ? &def : 0;
633 -void QSystemTrayIconSys::addToTray()
634 +void QSystemTrayIconSysFactory::refreshTrayIconPrivates()
636 - Q_ASSERT(sysTrayWindow != XNone);
637 - Display *display = QX11Info::display();
639 - XVisualInfo *vi = getSysTrayVisualInfo();
640 - if (vi && vi->visual) {
641 - Window root = RootWindow(display, vi->screen);
643 - if (QWidget *pw = parentWidget())
644 - p = pw->effectiveWinId();
645 - colormap = XCreateColormap(display, root, vi->visual, AllocNone);
646 - XSetWindowAttributes wsa;
647 - wsa.background_pixmap = 0;
648 - wsa.colormap = colormap;
649 - wsa.background_pixel = 0;
650 - wsa.border_pixel = 0;
651 - Window wid = XCreateWindow(display, p, -1, -1, 1, 1,
652 - 0, vi->depth, InputOutput, vi->visual,
653 - CWBackPixmap|CWBackPixel|CWBorderPixel|CWColormap, &wsa);
656 - XSetWindowBackgroundPixmap(display, winId(), ParentRelative);
657 + Q_FOREACH(QSystemTrayIconPrivate *trayIconPrivate, trayIconPrivates) {
658 + if (trayIconPrivate->sys) {
659 + delete trayIconPrivate->sys;
660 + trayIconPrivate->sys = 0;
661 + trayIconPrivate->install_sys();
665 - // GNOME, NET WM Specification
666 - static Atom netwm_tray_atom = XInternAtom(display, "_NET_SYSTEM_TRAY_OPCODE", False);
667 - long l[5] = { CurrentTime, SYSTEM_TRAY_REQUEST_DOCK, winId(), 0, 0 };
669 - memset(&ev, 0, sizeof(ev));
670 - ev.xclient.type = ClientMessage;
671 - ev.xclient.window = sysTrayWindow;
672 - ev.xclient.message_type = netwm_tray_atom;
673 - ev.xclient.format = 32;
674 - memcpy((char *)&ev.xclient.data, (const char *) l, sizeof(l));
675 - XSendEvent(display, sysTrayWindow, False, 0, &ev);
676 - setMinimumSize(22, 22); // required at least on GNOME
679 -void QSystemTrayIconSys::updateIcon()
680 +void QSystemTrayIconSysFactory::registerSystemTrayIconPrivate(QSystemTrayIconPrivate* trayIconPrivate)
683 + trayIconPrivates.insert(trayIconPrivate);
686 -void QSystemTrayIconSys::resizeEvent(QResizeEvent *re)
687 +void QSystemTrayIconSysFactory::unregisterSystemTrayIconPrivate(QSystemTrayIconPrivate* trayIconPrivate)
689 - QWidget::resizeEvent(re);
693 -void QSystemTrayIconSys::paintEvent(QPaintEvent*)
696 - if (!getSysTrayVisualInfo()) {
697 - const QRegion oldSystemClip = p.paintEngine()->systemClip();
698 - const QRect clearedRect = oldSystemClip.boundingRect();
699 - XClearArea(QX11Info::display(), winId(), clearedRect.x(), clearedRect.y(),
700 - clearedRect.width(), clearedRect.height(), False);
701 - QPaintEngine *pe = p.paintEngine();
702 - pe->setSystemClip(clearedRect);
703 - q->icon().paint(&p, rect());
704 - pe->setSystemClip(oldSystemClip);
706 - p.setCompositionMode(QPainter::CompositionMode_Source);
707 - p.fillRect(rect(), Qt::transparent);
708 - p.setCompositionMode(QPainter::CompositionMode_SourceOver);
709 - q->icon().paint(&p, rect());
711 + trayIconPrivates.remove(trayIconPrivate);
714 -void QSystemTrayIconSys::mousePressEvent(QMouseEvent *ev)
715 +QAbstractSystemTrayIconSys *QSystemTrayIconSysFactory::create(QSystemTrayIcon *trayIcon) const
717 - QPoint globalPos = ev->globalPos();
718 - if (ev->button() == Qt::RightButton && q->contextMenu())
719 - q->contextMenu()->popup(globalPos);
721 - if (QBalloonTip::isBalloonVisible()) {
722 - emit q->messageClicked();
723 - QBalloonTip::hideBalloon();
724 + QSystemTrayIconSysFactoryInterface *f = factory();
726 + qWarning("No systemtrayicon available");
730 - if (ev->button() == Qt::LeftButton)
731 - emit q->activated(QSystemTrayIcon::Trigger);
732 - else if (ev->button() == Qt::RightButton)
733 - emit q->activated(QSystemTrayIcon::Context);
734 - else if (ev->button() == Qt::MidButton)
735 - emit q->activated(QSystemTrayIcon::MiddleClick);
736 + return f->create(trayIcon);
739 -void QSystemTrayIconSys::mouseDoubleClickEvent(QMouseEvent *ev)
740 +bool QSystemTrayIconSysFactory::isAvailable() const
742 - if (ev->button() == Qt::LeftButton)
743 - emit q->activated(QSystemTrayIcon::DoubleClick);
747 -#ifndef QT_NO_WHEELEVENT
748 -void QSystemTrayIconSys::wheelEvent(QWheelEvent *e)
749 +////////////////////////////////////////////////
750 +QSystemTrayIconPrivate::~QSystemTrayIconPrivate()
752 - QApplication::sendEvent(q, e);
756 -bool QSystemTrayIconSys::event(QEvent *e)
758 - if (e->type() == QEvent::ToolTip) {
759 - return QApplication::sendEvent(q, e);
761 - return QWidget::event(e);
762 + qt_guiSystemTrayIconSysFactory()->unregisterSystemTrayIconPrivate(this);
766 -bool QSystemTrayIconSys::x11Event(XEvent *event)
768 - if (event->type == ReparentNotify)
770 - return QWidget::x11Event(event);
773 -////////////////////////////////////////////////////////////////////////////
774 void QSystemTrayIconPrivate::install_sys()
776 Q_Q(QSystemTrayIcon);
778 - sys = new QSystemTrayIconSys(q);
780 + sys = qt_guiSystemTrayIconSysFactory()->create(q);
784 + qt_guiSystemTrayIconSysFactory()->registerSystemTrayIconPrivate(this);
786 + sys->updateVisibility();
789 QRect QSystemTrayIconPrivate::geometry_sys() const
793 - return QRect(sys->mapToGlobal(QPoint(0, 0)), sys->size());
794 + if (!sys || !visible)
796 + return sys->geometry();
799 void QSystemTrayIconPrivate::remove_sys()
800 @@ -350,35 +153,35 @@ void QSystemTrayIconPrivate::remove_sys()
803 QBalloonTip::hideBalloon();
804 - sys->hide(); // this should do the trick, but...
805 - delete sys; // wm may resize system tray only for DestroyEvents
807 + sys->updateVisibility();
810 void QSystemTrayIconPrivate::updateIcon_sys()
813 + if (!sys || !visible)
818 void QSystemTrayIconPrivate::updateMenu_sys()
821 + if (!sys || !visible)
826 void QSystemTrayIconPrivate::updateToolTip_sys()
829 + if (!sys || !visible)
831 #ifndef QT_NO_TOOLTIP
832 - sys->setToolTip(toolTip);
833 + sys->updateToolTip();
837 bool QSystemTrayIconPrivate::isSystemTrayAvailable_sys()
839 - return QSystemTrayIconSys::locateSystemTray() != XNone;
840 + return qt_guiSystemTrayIconSysFactory()->isAvailable();
843 bool QSystemTrayIconPrivate::supportsMessages_sys()
844 @@ -389,12 +192,9 @@ bool QSystemTrayIconPrivate::supportsMessages_sys()
845 void QSystemTrayIconPrivate::showMessage_sys(const QString &message, const QString &title,
846 QSystemTrayIcon::MessageIcon icon, int msecs)
849 + if (!sys || !visible)
851 - QPoint g = sys->mapToGlobal(QPoint(0, 0));
852 - QBalloonTip::showBalloon(icon, message, title, sys->q,
853 - QPoint(g.x() + sys->width()/2, g.y() + sys->height()/2),
855 + sys->showMessage(message, title, icon, msecs);
859 diff --git a/src/gui/util/qxembedsystemtrayicon_x11.cpp b/src/gui/util/qxembedsystemtrayicon_x11.cpp
861 index 0000000..d39bc68
863 +++ b/src/gui/util/qxembedsystemtrayicon_x11.cpp
865 +/****************************************************************************
867 +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
868 +** All rights reserved.
869 +** Contact: Nokia Corporation (qt-info@nokia.com)
871 +** This file is part of the QtGui module of the Qt Toolkit.
873 +** $QT_BEGIN_LICENSE:LGPL$
874 +** GNU Lesser General Public License Usage
875 +** This file may be used under the terms of the GNU Lesser General Public
876 +** License version 2.1 as published by the Free Software Foundation and
877 +** appearing in the file LICENSE.LGPL included in the packaging of this
878 +** file. Please review the following information to ensure the GNU Lesser
879 +** General Public License version 2.1 requirements will be met:
880 +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
882 +** In addition, as a special exception, Nokia gives you certain additional
883 +** rights. These rights are described in the Nokia Qt LGPL Exception
884 +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
886 +** GNU General Public License Usage
887 +** Alternatively, this file may be used under the terms of the GNU General
888 +** Public License version 3.0 as published by the Free Software Foundation
889 +** and appearing in the file LICENSE.GPL included in the packaging of this
890 +** file. Please review the following information to ensure the GNU General
891 +** Public License version 3.0 requirements will be met:
892 +** http://www.gnu.org/copyleft/gpl.html.
895 +** Alternatively, this file may be used in accordance with the terms and
896 +** conditions contained in a signed written agreement between you and Nokia.
904 +****************************************************************************/
905 +#include "qxembedsystemtrayicon_x11_p.h"
907 +#ifndef QT_NO_SYSTEMTRAYICON
909 +#include "private/qt_x11_p.h"
910 +#include "qapplication.h"
914 +#include "qpainter.h"
915 +#include "qpaintengine.h"
916 +#include "qsystemtrayicon_p.h"
917 +#include "qx11info_x11.h"
919 +QT_BEGIN_INCLUDE_NAMESPACE
920 +#include <QtCore/qcoreapplication.h>
921 +#include <X11/Xlib.h>
922 +#include <X11/Xatom.h>
923 +#include <X11/Xutil.h>
924 +QT_END_INCLUDE_NAMESPACE
928 +class QSystemTrayIconWidget : public QWidget
931 + QSystemTrayIconWidget(QSystemTrayIcon *q, QXEmbedSystemTrayIconSys *s);
932 + ~QSystemTrayIconWidget();
934 + static Window locateSystemTray();
937 + void paintEvent(QPaintEvent *pe);
938 + void resizeEvent(QResizeEvent *re);
939 + bool x11Event(XEvent *event);
940 + void mousePressEvent(QMouseEvent *event);
941 + void mouseDoubleClickEvent(QMouseEvent *event);
942 +#ifndef QT_NO_WHEELEVENT
943 + void wheelEvent(QWheelEvent *event);
945 + bool event(QEvent *e);
949 + SYSTEM_TRAY_REQUEST_DOCK = 0,
950 + SYSTEM_TRAY_BEGIN_MESSAGE = 1,
951 + SYSTEM_TRAY_CANCEL_MESSAGE =2
955 + static XVisualInfo* getSysTrayVisualInfo();
957 + static Window sysTrayWindow;
958 + static QList<QSystemTrayIconWidget *> trayIcons;
959 + static QCoreApplication::EventFilter oldEventFilter;
960 + static bool sysTrayTracker(void *message, long *result);
961 + static Atom sysTraySelection;
962 + static XVisualInfo sysTrayVisual;
964 + QSystemTrayIcon *q;
965 + QXEmbedSystemTrayIconSys *sys;
969 +Window QSystemTrayIconWidget::sysTrayWindow = XNone;
970 +QList<QSystemTrayIconWidget *> QSystemTrayIconWidget::trayIcons;
971 +QCoreApplication::EventFilter QSystemTrayIconWidget::oldEventFilter = 0;
972 +Atom QSystemTrayIconWidget::sysTraySelection = XNone;
973 +XVisualInfo QSystemTrayIconWidget::sysTrayVisual = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
975 +QSystemTrayIconWidget::QSystemTrayIconWidget(QSystemTrayIcon* q, QXEmbedSystemTrayIconSys* sys)
976 +: QWidget(0, Qt::FramelessWindowHint | Qt::X11BypassWindowManagerHint)
981 + setAttribute(Qt::WA_AlwaysShowToolTips);
982 + setAttribute(Qt::WA_QuitOnClose, false);
983 + setAttribute(Qt::WA_NoSystemBackground, true);
984 + setAttribute(Qt::WA_PaintOnScreen);
985 + setMouseTracking(true);
986 +#ifndef QT_NO_TOOLTIP
987 + setToolTip(q->toolTip());
990 + static bool eventFilterAdded = false;
991 + Display *display = QX11Info::display();
992 + if (!eventFilterAdded) {
993 + oldEventFilter = qApp->setEventFilter(sysTrayTracker);
994 + eventFilterAdded = true;
995 + Window root = QX11Info::appRootWindow();
996 + XWindowAttributes attr;
997 + XGetWindowAttributes(display, root, &attr);
998 + if ((attr.your_event_mask & StructureNotifyMask) != StructureNotifyMask) {
999 + (void) QApplication::desktop(); // lame trick to ensure our event mask is not overridden
1000 + XSelectInput(display, root, attr.your_event_mask | StructureNotifyMask); // for MANAGER selection
1003 + if (trayIcons.isEmpty()) {
1004 + sysTrayWindow = locateSystemTray();
1005 + if (sysTrayWindow != XNone)
1006 + XSelectInput(display, sysTrayWindow, StructureNotifyMask); // track tray events
1008 + trayIcons.append(this);
1009 + if (sysTrayWindow != XNone)
1013 +QSystemTrayIconWidget::~QSystemTrayIconWidget()
1015 + trayIcons.removeAt(trayIcons.indexOf(this));
1016 + Display *display = QX11Info::display();
1017 + if (trayIcons.isEmpty()) {
1018 + if (sysTrayWindow == XNone)
1021 + XSelectInput(display, sysTrayWindow, 0); // stop tracking the tray
1022 + sysTrayWindow = XNone;
1025 + XFreeColormap(display, colormap);
1028 +void QSystemTrayIconWidget::resizeEvent(QResizeEvent *re)
1030 + QWidget::resizeEvent(re);
1034 +void QSystemTrayIconWidget::paintEvent(QPaintEvent*)
1037 + if (!getSysTrayVisualInfo()) {
1038 + const QRegion oldSystemClip = p.paintEngine()->systemClip();
1039 + const QRect clearedRect = oldSystemClip.boundingRect();
1040 + XClearArea(QX11Info::display(), winId(), clearedRect.x(), clearedRect.y(),
1041 + clearedRect.width(), clearedRect.height(), False);
1042 + QPaintEngine *pe = p.paintEngine();
1043 + pe->setSystemClip(clearedRect);
1044 + q->icon().paint(&p, rect());
1045 + pe->setSystemClip(oldSystemClip);
1047 + p.setCompositionMode(QPainter::CompositionMode_Source);
1048 + p.fillRect(rect(), Qt::transparent);
1049 + p.setCompositionMode(QPainter::CompositionMode_SourceOver);
1050 + q->icon().paint(&p, rect());
1054 +void QSystemTrayIconWidget::mousePressEvent(QMouseEvent *ev)
1056 + QPoint globalPos = ev->globalPos();
1057 + if (ev->button() == Qt::RightButton && q->contextMenu())
1058 + q->contextMenu()->popup(globalPos);
1060 + if (QBalloonTip::isBalloonVisible()) {
1061 + QMetaObject::invokeMethod(q, "messageClicked");
1062 + QBalloonTip::hideBalloon();
1065 + if (ev->button() == Qt::LeftButton)
1066 + qtsystray_sendActivated(q, QSystemTrayIcon::Trigger);
1067 + else if (ev->button() == Qt::RightButton)
1068 + qtsystray_sendActivated(q, QSystemTrayIcon::Context);
1069 + else if (ev->button() == Qt::MidButton)
1070 + qtsystray_sendActivated(q, QSystemTrayIcon::MiddleClick);
1073 +void QSystemTrayIconWidget::mouseDoubleClickEvent(QMouseEvent *ev)
1075 + if (ev->button() == Qt::LeftButton)
1076 + qtsystray_sendActivated(q, QSystemTrayIcon::DoubleClick);
1079 +#ifndef QT_NO_WHEELEVENT
1080 +void QSystemTrayIconWidget::wheelEvent(QWheelEvent *e)
1082 + sys->sendWheelEventToTrayIcon(e->delta(), e->orientation());
1086 +bool QSystemTrayIconWidget::event(QEvent *e)
1088 + if (e->type() == QEvent::ToolTip) {
1089 + sys->sendToolTipEventToTrayIcon();
1091 + return QWidget::event(e);
1094 +bool QSystemTrayIconWidget::x11Event(XEvent *event)
1096 + if (event->type == ReparentNotify)
1098 + return QWidget::x11Event(event);
1101 +// Locate the system tray
1102 +Window QSystemTrayIconWidget::locateSystemTray()
1104 + Display *display = QX11Info::display();
1105 + if (sysTraySelection == XNone) {
1106 + int screen = QX11Info::appScreen();
1107 + QString net_sys_tray = QString::fromLatin1("_NET_SYSTEM_TRAY_S%1").arg(screen);
1108 + sysTraySelection = XInternAtom(display, net_sys_tray.toLatin1(), False);
1111 + return XGetSelectionOwner(QX11Info::display(), sysTraySelection);
1114 +XVisualInfo* QSystemTrayIconWidget::getSysTrayVisualInfo()
1116 + Display *display = QX11Info::display();
1118 + if (!sysTrayVisual.visual) {
1119 + Window win = locateSystemTray();
1120 + if (win != XNone) {
1122 + int actual_format;
1123 + ulong nitems, bytes_remaining;
1125 + int result = XGetWindowProperty(display, win, ATOM(_NET_SYSTEM_TRAY_VISUAL), 0, 1,
1126 + False, XA_VISUALID, &actual_type,
1127 + &actual_format, &nitems, &bytes_remaining, &data);
1129 + if (result == Success && data && actual_type == XA_VISUALID && actual_format == 32 &&
1130 + nitems == 1 && bytes_remaining == 0)
1131 + vid = *(VisualID*)data;
1137 + uint mask = VisualIDMask;
1138 + XVisualInfo *vi, rvi;
1140 + rvi.visualid = vid;
1141 + vi = XGetVisualInfo(display, mask, &rvi, &count);
1143 + sysTrayVisual = vi[0];
1146 + if (sysTrayVisual.depth != 32)
1147 + memset(&sysTrayVisual, 0, sizeof(sysTrayVisual));
1151 + return sysTrayVisual.visual ? &sysTrayVisual : 0;
1154 +bool QSystemTrayIconWidget::sysTrayTracker(void *message, long *result)
1156 + bool retval = false;
1157 + if (QSystemTrayIconWidget::oldEventFilter)
1158 + retval = QSystemTrayIconWidget::oldEventFilter(message, result);
1160 + if (trayIcons.isEmpty())
1163 + Display *display = QX11Info::display();
1164 + XEvent *ev = (XEvent *)message;
1165 + if (ev->type == DestroyNotify && ev->xany.window == sysTrayWindow) {
1166 + sysTrayWindow = locateSystemTray();
1167 + memset(&sysTrayVisual, 0, sizeof(sysTrayVisual));
1168 + for (int i = 0; i < trayIcons.count(); i++) {
1169 + if (sysTrayWindow == XNone) {
1170 + QBalloonTip::hideBalloon();
1171 + trayIcons[i]->hide(); // still no luck
1172 + trayIcons[i]->destroy();
1173 + trayIcons[i]->create();
1175 + trayIcons[i]->addToTray(); // add it to the new tray
1178 + } else if (ev->type == ClientMessage && sysTrayWindow == XNone) {
1179 + static Atom manager_atom = XInternAtom(display, "MANAGER", False);
1180 + XClientMessageEvent *cm = (XClientMessageEvent *)message;
1181 + if ((cm->message_type == manager_atom) && ((Atom)cm->data.l[1] == sysTraySelection)) {
1182 + sysTrayWindow = cm->data.l[2];
1183 + memset(&sysTrayVisual, 0, sizeof(sysTrayVisual));
1184 + XSelectInput(display, sysTrayWindow, StructureNotifyMask);
1185 + for (int i = 0; i < trayIcons.count(); i++) {
1186 + trayIcons[i]->addToTray();
1190 + } else if (ev->type == PropertyNotify && ev->xproperty.atom == ATOM(_NET_SYSTEM_TRAY_VISUAL) &&
1191 + ev->xproperty.window == sysTrayWindow) {
1192 + memset(&sysTrayVisual, 0, sizeof(sysTrayVisual));
1193 + for (int i = 0; i < trayIcons.count(); i++) {
1194 + trayIcons[i]->addToTray();
1201 +void QSystemTrayIconWidget::addToTray()
1203 + Q_ASSERT(sysTrayWindow != XNone);
1204 + Display *display = QX11Info::display();
1206 + XVisualInfo *vi = getSysTrayVisualInfo();
1207 + if (vi && vi->visual) {
1208 + Window root = RootWindow(display, vi->screen);
1210 + if (QWidget *pw = parentWidget())
1211 + p = pw->effectiveWinId();
1212 + colormap = XCreateColormap(display, root, vi->visual, AllocNone);
1213 + XSetWindowAttributes wsa;
1214 + wsa.background_pixmap = 0;
1215 + wsa.colormap = colormap;
1216 + wsa.background_pixel = 0;
1217 + wsa.border_pixel = 0;
1218 + Window wid = XCreateWindow(display, p, -1, -1, 1, 1,
1219 + 0, vi->depth, InputOutput, vi->visual,
1220 + CWBackPixmap|CWBackPixel|CWBorderPixel|CWColormap, &wsa);
1223 + XSetWindowBackgroundPixmap(display, winId(), ParentRelative);
1226 + // GNOME, NET WM Specification
1227 + static Atom netwm_tray_atom = XInternAtom(display, "_NET_SYSTEM_TRAY_OPCODE", False);
1228 + long l[5] = { CurrentTime, SYSTEM_TRAY_REQUEST_DOCK, winId(), 0, 0 };
1230 + memset(&ev, 0, sizeof(ev));
1231 + ev.xclient.type = ClientMessage;
1232 + ev.xclient.window = sysTrayWindow;
1233 + ev.xclient.message_type = netwm_tray_atom;
1234 + ev.xclient.format = 32;
1235 + memcpy((char *)&ev.xclient.data, (const char *) l, sizeof(l));
1236 + XSendEvent(display, sysTrayWindow, False, 0, &ev);
1237 + setMinimumSize(22, 22); // required at least on GNOME
1240 +////////////////////////////////////////////////////////////////////////////
1241 +QXEmbedSystemTrayIconSys::QXEmbedSystemTrayIconSys(QSystemTrayIcon *q)
1242 +: QAbstractSystemTrayIconSys(q)
1247 +QXEmbedSystemTrayIconSys::~QXEmbedSystemTrayIconSys()
1252 +QRect QXEmbedSystemTrayIconSys::geometry() const
1256 + return QRect(widget->mapToGlobal(QPoint(0, 0)), widget->size());
1259 +void QXEmbedSystemTrayIconSys::updateIcon()
1266 +void QXEmbedSystemTrayIconSys::updateToolTip()
1270 + widget->setToolTip(trayIcon->toolTip());
1273 +void QXEmbedSystemTrayIconSys::showMessage(const QString &message, const QString &title,
1274 + QSystemTrayIcon::MessageIcon icon, int msecs)
1278 + QPoint point = geometry().center();
1279 + QBalloonTip::showBalloon(icon, message, title, trayIcon, point, msecs);
1282 +void QXEmbedSystemTrayIconSys::updateVisibility()
1284 + bool visible = trayIcon->isVisible();
1285 + if (visible && !widget)
1286 + widget = new QSystemTrayIconWidget(trayIcon, this);
1287 + else if (!visible && widget) {
1293 +void QXEmbedSystemTrayIconSys::sendToolTipEventToTrayIcon()
1295 +#ifndef QT_NO_TOOLTIP
1296 + // Pass the event through QSystemTrayIcon so that it gets a chance to
1297 + // update the tooltip, then asks widget to show the tooltip
1299 + QPoint globalPos = QCursor::pos();
1300 + QPoint pos = widget->mapFromGlobal(globalPos);
1301 + QHelpEvent event(QEvent::ToolTip, pos, globalPos);
1302 + QApplication::sendEvent(trayIcon, &event);
1306 +void QXEmbedSystemTrayIconSys::sendWheelEventToTrayIcon(int delta, Qt::Orientation orientation)
1308 +#ifndef QT_NO_WHEELEVENT
1310 + QPoint globalPos = QCursor::pos();
1311 + QPoint pos = widget->mapFromGlobal(globalPos);
1312 + QWheelEvent event(pos, globalPos, delta, Qt::NoButton, Qt::NoModifier, orientation);
1313 + QApplication::sendEvent(trayIcon, &event);
1317 +void QXEmbedSystemTrayIconSys::updateMenu()
1321 +/////////////////////////////////////////////////////////////
1322 +QAbstractSystemTrayIconSys * QXEmbedSystemTrayIconSysFactory::create(QSystemTrayIcon *icon)
1324 + return new QXEmbedSystemTrayIconSys(icon);
1327 +bool QXEmbedSystemTrayIconSysFactory::isAvailable() const
1329 + return QSystemTrayIconWidget::locateSystemTray() != XNone;
1333 +#endif //QT_NO_SYSTEMTRAYICON
1334 diff --git a/src/gui/util/qxembedsystemtrayicon_x11_p.h b/src/gui/util/qxembedsystemtrayicon_x11_p.h
1335 new file mode 100644
1336 index 0000000..9fcc908
1338 +++ b/src/gui/util/qxembedsystemtrayicon_x11_p.h
1340 +/****************************************************************************
1342 +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
1343 +** All rights reserved.
1344 +** Contact: Nokia Corporation (qt-info@nokia.com)
1346 +** This file is part of the QtGui module of the Qt Toolkit.
1348 +** $QT_BEGIN_LICENSE:LGPL$
1349 +** GNU Lesser General Public License Usage
1350 +** This file may be used under the terms of the GNU Lesser General Public
1351 +** License version 2.1 as published by the Free Software Foundation and
1352 +** appearing in the file LICENSE.LGPL included in the packaging of this
1353 +** file. Please review the following information to ensure the GNU Lesser
1354 +** General Public License version 2.1 requirements will be met:
1355 +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
1357 +** In addition, as a special exception, Nokia gives you certain additional
1358 +** rights. These rights are described in the Nokia Qt LGPL Exception
1359 +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
1361 +** GNU General Public License Usage
1362 +** Alternatively, this file may be used under the terms of the GNU General
1363 +** Public License version 3.0 as published by the Free Software Foundation
1364 +** and appearing in the file LICENSE.GPL included in the packaging of this
1365 +** file. Please review the following information to ensure the GNU General
1366 +** Public License version 3.0 requirements will be met:
1367 +** http://www.gnu.org/copyleft/gpl.html.
1370 +** Alternatively, this file may be used in accordance with the terms and
1371 +** conditions contained in a signed written agreement between you and Nokia.
1377 +** $QT_END_LICENSE$
1379 +****************************************************************************/
1381 +#ifndef QXEMBEDSYSTEMTRAYICON_X11_P_H
1382 +#define QXEMBEDSYSTEMTRAYICON_X11_P_H
1388 +// This file is not part of the Qt API. It exists for the convenience
1389 +// of a number of Qt sources files. This header file may change from
1390 +// version to version without notice, or even be removed.
1395 +#ifndef QT_NO_SYSTEMTRAYICON
1397 +#include "qabstractsystemtrayiconsys_p.h"
1401 +class QSystemTrayIconWidget;
1403 +class QXEmbedSystemTrayIconSys : public QAbstractSystemTrayIconSys
1406 + QXEmbedSystemTrayIconSys(QSystemTrayIcon *);
1407 + ~QXEmbedSystemTrayIconSys();
1409 + QRect geometry() const;
1411 + void updateVisibility();
1413 + void updateIcon();
1415 + void updateToolTip();
1417 + void updateMenu();
1419 + void showMessage(const QString &message, const QString &title,
1420 + QSystemTrayIcon::MessageIcon icon, int msecs);
1423 + friend class QSystemTrayIconWidget;
1424 + QSystemTrayIconWidget *widget;
1426 + void sendToolTipEventToTrayIcon();
1428 + void sendWheelEventToTrayIcon(int delta, Qt::Orientation orientation);
1431 +struct QXEmbedSystemTrayIconSysFactory : public QSystemTrayIconSysFactoryInterface
1433 + QAbstractSystemTrayIconSys * create(QSystemTrayIcon *trayIcon);
1434 + bool isAvailable() const;
1440 +#endif // QT_NO_SYSTEMTRAYICON
1442 +#endif // QXEMBEDSYSTEMTRAYICON_X11_P_H
1444 diff --git a/src/gui/util/util.pri b/src/gui/util/util.pri
1445 index d1c4ff8..c225183 100644
1446 --- a/src/gui/util/util.pri
1447 +++ b/src/gui/util/util.pri
1448 @@ -29,8 +29,13 @@ wince* {
1453 + util/qabstractsystemtrayiconsys_p.h \
1454 + util/qxembedsystemtrayicon_x11_p.h
1456 - util/qsystemtrayicon_x11.cpp
1457 + util/qabstractsystemtrayiconsys.cpp \
1458 + util/qsystemtrayicon_x11.cpp \
1459 + util/qxembedsystemtrayicon_x11.cpp
1463 @@ -56,4 +61,4 @@ symbian {
1465 DEFINES += USE_SCHEMEHANDLER
1468 \ No newline at end of file