diff options
author | Shawn Rutledge <shawn.rutledge@digia.com> | 2015-02-11 12:14:13 +0100 |
---|---|---|
committer | Shawn Rutledge <shawn.rutledge@digia.com> | 2015-02-12 13:24:33 +0000 |
commit | 98aae7428d86155a596c4318643752477d7726ad (patch) | |
tree | d14361b023bf75bfb601b50e7f95fe3ad0a2a50b /src/widgets/util | |
parent | 69d46a3e205e3533c8bdcf1a1f4e5ce92604759d (diff) |
xcb: QSystemTrayIcon: grab background pixmap for compositing only once
Followup to 2203d9d93e24e00d6e9bc9bda0e65a0c7f9923cc: clearRegion takes
a little time, so doing grabWindow() too soon afterwards can result in
grabbing a pixmap with undesired leftovers. And doing it every time
we render the icon causes flicker. So, do clearRegion() ASAP when showing
the icon, wait for it to happen, then grabWindow() only the first time we
render, and reuse the resulting pixmap for all future calls to paintEvent().
(The downside is, if there is any corruption during the first grabWindow(),
it's going to stay there as long as the app is running.)
Task-number: QTBUG-35658
Change-Id: If881ab192dba43758dcbb0d080663ff42057fa4f
Reviewed-by: Jørgen Lind <jorgen.lind@theqtcompany.com>
Diffstat (limited to 'src/widgets/util')
-rw-r--r-- | src/widgets/util/qsystemtrayicon_x11.cpp | 23 |
1 files changed, 11 insertions, 12 deletions
diff --git a/src/widgets/util/qsystemtrayicon_x11.cpp b/src/widgets/util/qsystemtrayicon_x11.cpp index 070ab367f7..2b153d53d9 100644 --- a/src/widgets/util/qsystemtrayicon_x11.cpp +++ b/src/widgets/util/qsystemtrayicon_x11.cpp @@ -88,6 +88,7 @@ private: bool addToTray(); QSystemTrayIcon *q; + QPixmap background; }; QSystemTrayIconSys::QSystemTrayIconSys(QSystemTrayIcon *qIn) @@ -151,6 +152,8 @@ bool QSystemTrayIconSys::addToTray() qWarning("requestSystemTrayWindowDock failed."); return false; } + if (!background.isNull()) + background = QPixmap(); show(); return true; } @@ -230,18 +233,14 @@ void QSystemTrayIconSys::paintEvent(QPaintEvent *) painter.setCompositionMode(QPainter::CompositionMode_Source); painter.fillRect(rect, Qt::transparent); } else { - // Without Qt::WA_TranslucentBackground, we use a ParentRelative BackPixmap and jump through - // some hops to draw this background below our icon. This clears the whole tray icon to its - // background color and thus causes flickering (you can see that the icon is being - // repainted). However, we can't really do much about this. - QMetaObject::invokeMethod(QGuiApplication::platformNativeInterface(), - "clearRegion", Qt::DirectConnection, - Q_ARG(const QWindow *, windowHandle()), - Q_ARG(const QRect&, rect) - ); - painter.drawPixmap(QPoint(0, 0), - QGuiApplication::primaryScreen()->grabWindow(winId(), - 0, 0, rect.size().width(), rect.size().height())); + // clearRegion() was called on XEMBED_EMBEDDED_NOTIFY, so we hope that got done by now. + // Grab the tray background pixmap, before rendering the icon for the first time. + if (background.isNull()) { + background = QGuiApplication::primaryScreen()->grabWindow(winId(), + 0, 0, rect.size().width(), rect.size().height()); + } + // Then paint over the icon area with the background before compositing the icon on top. + painter.drawPixmap(QPoint(0, 0), background); } painter.setCompositionMode(QPainter::CompositionMode_SourceOver); q->icon().paint(&painter, rect); |