diff options
Diffstat (limited to 'src/widgets/util/qsystemtrayicon_x11.cpp')
-rw-r--r-- | src/widgets/util/qsystemtrayicon_x11.cpp | 72 |
1 files changed, 66 insertions, 6 deletions
diff --git a/src/widgets/util/qsystemtrayicon_x11.cpp b/src/widgets/util/qsystemtrayicon_x11.cpp index 21ce23437f..e7007e4091 100644 --- a/src/widgets/util/qsystemtrayicon_x11.cpp +++ b/src/widgets/util/qsystemtrayicon_x11.cpp @@ -55,6 +55,9 @@ #include <qscreen.h> #include <qbackingstore.h> #include <qpa/qplatformnativeinterface.h> +#include <qpa/qplatformsystemtrayicon.h> +#include <qpa/qplatformtheme.h> +#include <private/qguiapplication_p.h> #include <qdebug.h> #ifndef QT_NO_SYSTEMTRAYICON @@ -101,11 +104,24 @@ QSystemTrayIconSys::QSystemTrayIconSys(QSystemTrayIcon *qIn) setObjectName(QStringLiteral("QSystemTrayIconSys")); setToolTip(q->toolTip()); setAttribute(Qt::WA_AlwaysShowToolTips, true); - setAttribute(Qt::WA_TranslucentBackground, true); setAttribute(Qt::WA_QuitOnClose, false); const QSize size(22, 22); // Gnome, standard size setGeometry(QRect(QPoint(0, 0), size)); setMinimumSize(size); + + // We need two different behaviors depending on whether the X11 visual for the system tray + // (a) exists and (b) supports an alpha channel, i.e. is 32 bits. + // If we have a visual that has an alpha channel, we can paint this widget with a transparent + // background and it will work. + // However, if there's no alpha channel visual, in order for transparent tray icons to work, + // we do not have a transparent background on the widget, but call xcb_clear_region before + // painting the icon + bool hasAlphaChannel = false; + QMetaObject::invokeMethod(QGuiApplication::platformNativeInterface(), + "systrayVisualHasAlphaChannel", Qt::DirectConnection, + Q_RETURN_ARG(bool, hasAlphaChannel)); + setAttribute(Qt::WA_TranslucentBackground, hasAlphaChannel); + addToTray(); } @@ -196,12 +212,21 @@ bool QSystemTrayIconSys::event(QEvent *e) void QSystemTrayIconSys::paintEvent(QPaintEvent *) { - // Note: Transparent pixels require a particular Visual which XCB - // currently does not support yet. const QRect rect(QPoint(0, 0), geometry().size()); QPainter painter(this); - painter.setCompositionMode(QPainter::CompositionMode_Source); - painter.fillRect(rect, Qt::transparent); + + // If we have Qt::WA_TranslucentBackground set, during widget creation + // we detected the systray visual supported an alpha channel + if (testAttribute(Qt::WA_TranslucentBackground)) { + painter.setCompositionMode(QPainter::CompositionMode_Source); + painter.fillRect(rect, Qt::transparent); + } else { + QMetaObject::invokeMethod(QGuiApplication::platformNativeInterface(), + "clearRegion", Qt::DirectConnection, + Q_ARG(const QWindow *, windowHandle()), + Q_ARG(const QRect&, rect) + ); + } painter.setCompositionMode(QPainter::CompositionMode_SourceOver); q->icon().paint(&painter, rect); } @@ -215,16 +240,22 @@ void QSystemTrayIconSys::resizeEvent(QResizeEvent *) QSystemTrayIconPrivate::QSystemTrayIconPrivate() : sys(0), + qpa_sys(QGuiApplicationPrivate::platformTheme()->createPlatformSystemTrayIcon()), visible(false) { } QSystemTrayIconPrivate::~QSystemTrayIconPrivate() { + delete qpa_sys; } void QSystemTrayIconPrivate::install_sys() { + if (qpa_sys) { + install_sys_qpa(); + return; + } Q_Q(QSystemTrayIcon); if (!sys && locateSystemTray()) { sys = new QSystemTrayIconSys(q); @@ -235,6 +266,8 @@ void QSystemTrayIconPrivate::install_sys() QRect QSystemTrayIconPrivate::geometry_sys() const { + if (qpa_sys) + return geometry_sys_qpa(); if (!sys) return QRect(); return sys->globalGeometry(); @@ -242,6 +275,10 @@ QRect QSystemTrayIconPrivate::geometry_sys() const void QSystemTrayIconPrivate::remove_sys() { + if (qpa_sys) { + remove_sys_qpa(); + return; + } if (!sys) return; QBalloonTip::hideBalloon(); @@ -252,17 +289,26 @@ void QSystemTrayIconPrivate::remove_sys() void QSystemTrayIconPrivate::updateIcon_sys() { + if (qpa_sys) { + updateIcon_sys_qpa(); + return; + } if (sys) sys->updateIcon(); } void QSystemTrayIconPrivate::updateMenu_sys() { - + if (qpa_sys) + updateMenu_sys_qpa(); } void QSystemTrayIconPrivate::updateToolTip_sys() { + if (qpa_sys) { + updateToolTip_sys_qpa(); + return; + } if (!sys) return; #ifndef QT_NO_TOOLTIP @@ -272,6 +318,11 @@ void QSystemTrayIconPrivate::updateToolTip_sys() bool QSystemTrayIconPrivate::isSystemTrayAvailable_sys() { + QScopedPointer<QPlatformSystemTrayIcon> sys(QGuiApplicationPrivate::platformTheme()->createPlatformSystemTrayIcon()); + if (sys) + return sys->isSystemTrayAvailable(); + + // no QPlatformSystemTrayIcon so fall back to default xcb platform behavior const QString platform = QGuiApplication::platformName(); if (platform.compare(QStringLiteral("xcb"), Qt::CaseInsensitive) == 0) return locateSystemTray(); @@ -280,12 +331,21 @@ bool QSystemTrayIconPrivate::isSystemTrayAvailable_sys() bool QSystemTrayIconPrivate::supportsMessages_sys() { + QScopedPointer<QPlatformSystemTrayIcon> sys(QGuiApplicationPrivate::platformTheme()->createPlatformSystemTrayIcon()); + if (sys) + return sys->supportsMessages(); + + // no QPlatformSystemTrayIcon so fall back to default xcb platform behavior return true; } void QSystemTrayIconPrivate::showMessage_sys(const QString &message, const QString &title, QSystemTrayIcon::MessageIcon icon, int msecs) { + if (qpa_sys) { + showMessage_sys_qpa(message, title, icon, msecs); + return; + } if (!sys) return; const QPoint g = sys->globalGeometry().topLeft(); |