diff options
author | Alexander Volkov <a.volkov@rusbitech.ru> | 2015-10-27 15:08:41 +0300 |
---|---|---|
committer | Gatis Paeglis <gatis.paeglis@qt.io> | 2018-07-10 20:03:53 +0000 |
commit | 5cf6f51b4c73cb1309279aa42d828097b24aa119 (patch) | |
tree | c5ecc96c74ba59d62c623fc096abacaa11113aad /src/widgets/util | |
parent | d743df975db3403ec83d67bd376d8a6bfea3dfb0 (diff) |
xcb: Fix artifacts on the tray background with lock screens
With the current method of painting the tray icon with 24 bpp
visuals we grab the window's background once on the first show
and then use it in all paint operations. This leads to a wrong
background if an application shows the system tray icon when
the lock screen is active.
We can avoid this by painting with XRender when it's available.
This change introduces QXcbSystemTrayBackingStore and moves the
selection of a suitable painting method from QSystemTrayIconSys
into it. In addition the visual for the window is selected
according to the system tray specification and the platform window
for the tray icon is created without needless OpenGL and Vulkan
support.
Task-number: QTBUG-55540
Change-Id: Ib3ca42bc02dcbdd4ccfe5d6e23f870ef22f0d25a
Reviewed-by: Gatis Paeglis <gatis.paeglis@qt.io>
Diffstat (limited to 'src/widgets/util')
-rw-r--r-- | src/widgets/util/qsystemtrayicon_x11.cpp | 43 |
1 files changed, 1 insertions, 42 deletions
diff --git a/src/widgets/util/qsystemtrayicon_x11.cpp b/src/widgets/util/qsystemtrayicon_x11.cpp index df93e15f80..3f6166ae78 100644 --- a/src/widgets/util/qsystemtrayicon_x11.cpp +++ b/src/widgets/util/qsystemtrayicon_x11.cpp @@ -101,7 +101,6 @@ private: bool addToTray(); QSystemTrayIcon *q; - QPixmap background; }; QSystemTrayIconSys::QSystemTrayIconSys(QSystemTrayIcon *qIn) @@ -117,29 +116,7 @@ QSystemTrayIconSys::QSystemTrayIconSys(QSystemTrayIcon *qIn) 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 set the BackPixmap property of our - // window to ParentRelative (so that it inherits the background of its X11 parent window), call - // xcb_clear_region before painting (so that the inherited background is visible) and then grab - // the just-drawn background from the X11 server. - bool hasAlphaChannel = QXcbIntegrationFunctions::xEmbedSystemTrayVisualHasAlphaChannel(); - setAttribute(Qt::WA_TranslucentBackground, hasAlphaChannel); - if (!hasAlphaChannel) { - createWinId(); - QXcbWindowFunctions::setParentRelativeBackPixmap(windowHandle()); - - // XXX: This is actually required, but breaks things ("QWidget::paintEngine: Should no - // longer be called"). Why is this needed? When the widget is drawn, we use tricks to grab - // the tray icon's background from the server. If the tray icon isn't visible (because - // another window is on top of it), the trick fails and instead uses the content of that - // other window as the background. - // setAttribute(Qt::WA_PaintOnScreen); - } + setAttribute(Qt::WA_TranslucentBackground); addToTray(); } @@ -155,8 +132,6 @@ bool QSystemTrayIconSys::addToTray() if (!QXcbWindowFunctions::requestSystemTrayWindowDock(windowHandle())) return false; - if (!background.isNull()) - background = QPixmap(); show(); return true; } @@ -227,22 +202,6 @@ void QSystemTrayIconSys::paintEvent(QPaintEvent *) const QRect rect(QPoint(0, 0), geometry().size()); QPainter painter(this); - // 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 { - // 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); } |