commit ec8e405ca447ba5bc5a9f6a2a12e2fa90412a0d4 Author: Andreas Hartmetz Date: Tue Jul 2 18:35:35 2013 +0200 Fix pixmap leak when the tray icon changes (e.g. when it's animated). This could easily leak 4KB/second of X pixmap memory. All the actual difference comes from the QPixmap::ExplicitlyShared argument, the rest is making some wonky-looking but working code look less wonky. BUG: 314919 diff --git a/plasma/generic/applets/systemtray/protocols/fdo/x11embedcontainer.cpp b/plasma/generic/applets/systemtray/protocols/fdo/x11embedcontainer.cpp index 1826512..a5bc826 100644 --- a/plasma/generic/applets/systemtray/protocols/fdo/x11embedcontainer.cpp +++ b/plasma/generic/applets/systemtray/protocols/fdo/x11embedcontainer.cpp @@ -194,8 +194,7 @@ void X11EmbedContainer::paintEvent(QPaintEvent *event) // Taking a detour via a QPixmap is unfortunately the only way we can get // the window contents into Qt's backing store. - QPixmap pixmap(size()); - pixmap = toX11Pixmap(pixmap); + QPixmap pixmap = toX11Pixmap(QPixmap(size())); pixmap.fill(Qt::transparent); XRenderComposite(x11Info().display(), PictOpSrc, d->picture, None, pixmap.x11PictureHandle(), 0, 0, 0, 0, 0, 0, width(), height()); @@ -232,16 +231,18 @@ void X11EmbedContainer::setBackgroundPixmap(QPixmap background) // NOTE: The alpha-channel is not preserved if it exists, but for X pixmaps it generally should not be needed anyway. QPixmap X11EmbedContainer::toX11Pixmap(const QPixmap& pix) { - if(pix.handle() != 0) // X11 pixmap + if (pix.handle() != 0) // X11 pixmap return pix; + QPixmap ret; Pixmap xpix = XCreatePixmap(pix.x11Info().display(), RootWindow(pix.x11Info().display(), pix.x11Info().screen()), pix.width(), pix.height(), QX11Info::appDepth()); - QPixmap wrk = QPixmap::fromX11Pixmap(xpix); - QPainter paint(&wrk); - paint.drawPixmap(0, 0, pix); - paint.end(); - QPixmap ret = wrk.copy(); - wrk = QPixmap(); // reset, so that xpix can be freed (QPixmap does not own it) + { + QPixmap wrk = QPixmap::fromX11Pixmap(xpix, QPixmap::ExplicitlyShared); + QPainter paint(&wrk); + paint.drawPixmap(0, 0, pix); + paint.end(); + ret = wrk.copy(); + } // free resources so that xpix can be freed (QPixmap does not own it) XFreePixmap(pix.x11Info().display(), xpix); return ret; }