117 lines
3.3 KiB
Diff
117 lines
3.3 KiB
Diff
diff --git a/xembed-sni-proxy/sniproxy.cpp b/xembed-sni-proxy/sniproxy.cpp
|
|
index ca2667f..0b7c072 100644
|
|
--- a/xembed-sni-proxy/sniproxy.cpp
|
|
+++ b/xembed-sni-proxy/sniproxy.cpp
|
|
@@ -33,7 +33,7 @@
|
|
#include <QGuiApplication>
|
|
#include <QTimer>
|
|
|
|
-#include <QPainter>
|
|
+#include <QBitmap>
|
|
|
|
#include <KWindowSystem>
|
|
#include <netwm.h>
|
|
@@ -191,6 +191,10 @@
|
|
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();
|
|
@@ -240,11 +244,70 @@
|
|
|
|
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);
|
|
+ QImage qimage(convertFromNative(image));
|
|
|
|
return qimage;
|
|
}
|
|
|
|
+QImage SNIProxy::convertFromNative(xcb_image_t *xcbImage)
|
|
+{
|
|
+ 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, format);
|
|
+ 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 image;
|
|
+}
|
|
+
|
|
//____________properties__________
|
|
|
|
QString SNIProxy::Category() const
|
|
diff --git a/xembed-sni-proxy/sniproxy.h b/xembed-sni-proxy/sniproxy.h
|
|
index 29aa56e..89746a7 100644
|
|
--- a/xembed-sni-proxy/sniproxy.h
|
|
+++ b/xembed-sni-proxy/sniproxy.h
|
|
@@ -28,6 +28,7 @@
|
|
#include <QPixmap>
|
|
|
|
#include <xcb/xcb.h>
|
|
+#include <xcb/xcb_image.h>
|
|
|
|
#include "snidbus.h"
|
|
|
|
@@ -141,6 +142,7 @@
|
|
private:
|
|
void sendClick(uint8_t mouseButton, int x, int y);
|
|
QImage getImageNonComposite();
|
|
+ QImage convertFromNative(xcb_image_t *xcbImage);
|
|
|
|
QDBusConnection m_dbus;
|
|
xcb_window_t m_windowId;
|