[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