[SCM] xembed-sni-proxy packaging branch, master, updated. debian/0_git20151104-ded1538-1-4-g7e89d01

Boris Pek tehnick at moszumanska.debian.org
Thu Feb 4 18:20:00 UTC 2016


Gitweb-URL: http://git.debian.org/?p=pkg-kde/kde-extras/xembed-sni-proxy.git;a=commitdiff;h=90cbeca

The following commit has been merged in the master branch:
commit 90cbeca202ef22cf00de8963ed114da623f3523a
Author: Boris Pek <tehnick-8 at yandex.ru>
Date:   Thu Feb 4 21:07:11 2016 +0300

    Add mitigate-failed-icon-grabbing.patch.
---
 debian/patches/mitigate-failed-icon-grabbing.patch | 209 +++++++++++++++++++++
 debian/patches/series                              |   1 +
 2 files changed, 210 insertions(+)

diff --git a/debian/patches/mitigate-failed-icon-grabbing.patch b/debian/patches/mitigate-failed-icon-grabbing.patch
new file mode 100644
index 0000000..184c9f2
--- /dev/null
+++ b/debian/patches/mitigate-failed-icon-grabbing.patch
@@ -0,0 +1,209 @@
+Description: Mitigate failed icon grabbing in xembed-sni-proxy
+ If grabbed icons are blank, try to salvage the copied data as well as
+ possible while leaving setups where image grabbing works fine alone.
+Origin: https://quickgit.kde.org/?p=plasma-workspace.git&a=commitdiff&h=41df1bd
+Bug: https://bugs.kde.org/355684
+Applied-Upstream: 5.5.4-1
+Last-Update: 2016-02-04
+
+--- a/sniproxy.cpp
++++ b/sniproxy.cpp
+@@ -33,7 +33,7 @@
+ #include <QGuiApplication>
+ #include <QTimer>
+ 
+-#include <QPainter>
++#include <QBitmap>
+ 
+ #include <KWindowSystem>
+ #include <netwm.h>
+@@ -191,48 +191,51 @@
+ void SNIProxy::update()
+ {
+     const QImage image = getImageNonComposite();
++    if (image.isNull()) {
++        qCDebug(SNIPROXY) << "No xembed icon for" << m_windowId << Title();
++        return;
++    }
+ 
+     int w = image.width();
+     int h = image.height();
+ 
++    m_pixmap = QPixmap::fromImage(image);
++    if (w != s_embedSize || h != s_embedSize) {
++        qCDebug(SNIPROXY) << "Scaling pixmap of window" << m_windowId << Title() << "from w*h" << w << h;
++        m_pixmap = m_pixmap.scaled(s_embedSize, s_embedSize, Qt::KeepAspectRatio, Qt::SmoothTransformation);
++    }
++    emit NewIcon();
++    emit NewToolTip();
++}
++
++void sni_cleanup_xcb_image(void *data) {
++    xcb_image_destroy(static_cast<xcb_image_t*>(data));
++}
++
++bool SNIProxy::isTransparentImage(const QImage& image) const
++{
++    int w = image.width();
++    int h = image.height();
++
+     // check for the center and sub-center pixels first and avoid full image scan
+-    bool isTransparentImage = qAlpha(image.pixel(w >> 1, h >> 1)) + qAlpha(image.pixel(w >> 2, h >> 2)) == 0;
++    if (! (qAlpha(image.pixel(w >> 1, h >> 1)) + qAlpha(image.pixel(w >> 2, h >> 2)) == 0))
++        return false;
+ 
+     // skip scan altogether if sub-center pixel found to be opaque
+     // and break out from the outer loop too on full scan
+-    for (int x = 0; x < w && isTransparentImage; ++x) {
+-	for (int y = 0; y < h; ++y) {
+-	    if (qAlpha(image.pixel(x, y))) {
+-		// Found an opaque pixel.
+-		isTransparentImage = false;
+-		break;
+-	    }
+-	}
++    for (int x = 0; x < w; ++x) {
++        for (int y = 0; y < h; ++y) {
++            if (qAlpha(image.pixel(x, y))) {
++                // Found an opaque pixel.
++                return false;
++            }
++        }
+     }
+ 
+-    // Update icon only if it is at least partially opaque.
+-    // This is just a workaround for X11 bug: xembed icon may suddenly
+-    // become transparent for a one or few frames. Reproducible at least
+-    // with WINE applications.
+-    if (!isTransparentImage) {
+-        m_pixmap = QPixmap::fromImage(image);
+-	if (w != s_embedSize || h != s_embedSize) {
+-	    qCDebug(SNIPROXY) << "Scaling pixmap of window" << m_windowId << Title() << "from w*h" << w << h;
+-	    m_pixmap = m_pixmap.scaled(s_embedSize, s_embedSize, Qt::KeepAspectRatio, Qt::SmoothTransformation);
+-	}
+-        emit NewIcon();
+-        emit NewToolTip();
+-    }
+-    else {
+-        qCDebug(SNIPROXY) << "Skip transparent xembed icon for" << m_windowId << Title();
+-    }
++    return true;
+ }
+ 
+-void sni_cleanup_xcb_image(void *data) {
+-    xcb_image_destroy(static_cast<xcb_image_t*>(data));
+-}
+-
+-QImage SNIProxy::getImageNonComposite()
++QImage SNIProxy::getImageNonComposite() const
+ {
+     auto c = QX11Info::connection();
+     auto cookie = xcb_get_geometry(c, m_windowId);
+@@ -240,9 +243,83 @@
+ 
+     xcb_image_t *image = xcb_image_get(c, m_windowId, 0, 0, geom->width, geom->height, 0xFFFFFF, XCB_IMAGE_FORMAT_Z_PIXMAP);
+ 
+-    QImage qimage(image->data, image->width, image->height, image->stride, QImage::Format_ARGB32, sni_cleanup_xcb_image, image);
++    // Don't hook up cleanup yet, we may use a different QImage after all
++    QImage naiveConversion = QImage(image->data, image->width, image->height, QImage::Format_ARGB32);
++
++    if (isTransparentImage(naiveConversion)) {
++        QImage elaborateConversion = QImage(convertFromNative(image));
++
++        // Update icon only if it is at least partially opaque.
++        // This is just a workaround for X11 bug: xembed icon may suddenly
++        // become transparent for a one or few frames. Reproducible at least
++        // with WINE applications.
++        if (isTransparentImage(elaborateConversion)) {
++            qCDebug(SNIPROXY) << "Skip transparent xembed icon for" << m_windowId << Title();
++            return QImage();
++        } else
++            return elaborateConversion;
++    } else {
++        // Now we are sure we can eventually delete the xcb_image_t with this version
++        return QImage(image->data, image->width, image->height, image->stride, QImage::Format_ARGB32, sni_cleanup_xcb_image, image);
++    }
++}
++
++QImage SNIProxy::convertFromNative(xcb_image_t *xcbImage) const
++{
++    QImage::Format format = QImage::Format_Invalid;
++
++    switch (xcbImage->depth) {
++    case 1:
++        format = QImage::Format_MonoLSB;
++        break;
++    case 16:
++        format = QImage::Format_RGB16;
++        break;
++    case 24:
++        format = QImage::Format_RGB32;
++        break;
++    case 30: {
++        // Qt doesn't have a matching image format. We need to convert manually
++        quint32 *pixels = reinterpret_cast<quint32 *>(xcbImage->data);
++        for (uint i = 0; i < (xcbImage->size / 4); i++) {
++            int r = (pixels[i] >> 22) & 0xff;
++            int g = (pixels[i] >> 12) & 0xff;
++            int b = (pixels[i] >>  2) & 0xff;
++
++            pixels[i] = qRgba(r, g, b, 0xff);
++        }
++        // fall through, Qt format is still Format_ARGB32_Premultiplied
++    }
++    case 32:
++        format = QImage::Format_ARGB32_Premultiplied;
++        break;
++    default:
++        return QImage(); // we don't know
++    }
++
++    QImage image(xcbImage->data, xcbImage->width, xcbImage->height, xcbImage->stride, format, sni_cleanup_xcb_image, xcbImage);
++
++    if (image.isNull()) {
++        return QImage();
++    }
++
++    if (format == QImage::Format_RGB32 && xcbImage->bpp == 32)
++    {
++        QImage m = image.createHeuristicMask();
++        QBitmap mask(QPixmap::fromImage(m));
++        QPixmap p = QPixmap::fromImage(image);
++        p.setMask(mask);
++        image = p.toImage();
++    }
++
++    // work around an abort in QImage::color
++    if (image.format() == QImage::Format_MonoLSB) {
++        image.setColorCount(2);
++        image.setColor(0, QColor(Qt::white).rgb());
++        image.setColor(1, QColor(Qt::black).rgb());
++    }
+ 
+-    return qimage;
++    return image;
+ }
+ 
+ //____________properties__________
+--- a/sniproxy.h
++++ b/sniproxy.h
+@@ -28,6 +28,7 @@
+ #include <QPixmap>
+ 
+ #include <xcb/xcb.h>
++#include <xcb/xcb_image.h>
+ 
+ #include "snidbus.h"
+ 
+@@ -140,7 +141,9 @@
+ 
+ private:
+     void sendClick(uint8_t mouseButton, int x, int y);
+-    QImage getImageNonComposite();
++    QImage getImageNonComposite() const;
++    bool isTransparentImage(const QImage &image) const;
++    QImage convertFromNative(xcb_image_t *xcbImage) const;
+ 
+     QDBusConnection m_dbus;
+     xcb_window_t m_windowId;
+
diff --git a/debian/patches/series b/debian/patches/series
new file mode 100644
index 0000000..241a196
--- /dev/null
+++ b/debian/patches/series
@@ -0,0 +1 @@
+mitigate-failed-icon-grabbing.patch

-- 
xembed-sni-proxy packaging



More information about the pkg-kde-commits mailing list