Implement QXcbWindow::setWindowIcon
authorCorentin Jabot <corentinjabot@gmail.com>
Fri, 25 May 2012 10:11:58 +0000 (12:11 +0200)
committerQt by Nokia <qt-info@nokia.com>
Fri, 1 Jun 2012 23:14:22 +0000 (01:14 +0200)
Change-Id: I1908cbef0c20d3725423b559f234bd6d3ddd4167
Reviewed-by: Girish Ramakrishnan <girish.1.ramakrishnan@nokia.com>
Reviewed-by: Uli Schlachter <psychon@znc.in>
Reviewed-by: Samuel Rødal <samuel.rodal@nokia.com>
src/plugins/platforms/xcb/qxcbconnection.cpp
src/plugins/platforms/xcb/qxcbconnection.h
src/plugins/platforms/xcb/qxcbwindow.cpp
src/plugins/platforms/xcb/qxcbwindow.h

index d9c3352..40a54ff 100644 (file)
@@ -906,6 +906,7 @@ static const char * xcb_atomnames = {
     // Property formats
     "TEXT\0"
     "UTF8_STRING\0"
+    "CARDINAL\0"
 
     // xdnd
     "XdndEnter\0"
index 9fbeb9f..3b17f93 100644 (file)
@@ -183,6 +183,7 @@ namespace QXcbAtom {
         // Property formats
         TEXT,
         UTF8_STRING,
+        CARDINAL,
 
         // Xdnd
         XdndEnter,
index 168a441..390628d 100644 (file)
 
 #include <QtDebug>
 #include <QScreen>
+#include <QtGui/QIcon>
 
 #include "qxcbconnection.h"
 #include "qxcbscreen.h"
 #include "qxcbdrag.h"
 #include "qxcbkeyboard.h"
 #include "qxcbwmsupport.h"
+#include "qxcbimage.h"
 
 #include <qpa/qplatformintegration.h>
 
@@ -1122,6 +1124,49 @@ void QXcbWindow::setWindowTitle(const QString &title)
                                    ba.constData()));
 }
 
+void QXcbWindow::setWindowIcon(const QIcon &icon)
+{
+    QVector<quint32> icon_data;
+
+    if (!icon.isNull()) {
+        QList<QSize> availableSizes = icon.availableSizes();
+        if (availableSizes.isEmpty()) {
+            // try to use default sizes since the icon can be a scalable image like svg.
+            availableSizes.push_back(QSize(16,16));
+            availableSizes.push_back(QSize(32,32));
+            availableSizes.push_back(QSize(64,64));
+            availableSizes.push_back(QSize(128,128));
+        }
+        for (int i = 0; i < availableSizes.size(); ++i) {
+            QSize size = availableSizes.at(i);
+            QPixmap pixmap = icon.pixmap(size);
+            if (!pixmap.isNull()) {
+                QImage image = pixmap.toImage().convertToFormat(QImage::Format_ARGB32);
+                int pos = icon_data.size();
+                icon_data.resize(pos + 2 + image.width()*image.height());
+                icon_data[pos++] = image.width();
+                icon_data[pos++] = image.height();
+                memcpy(icon_data.data() + pos, image.bits(), image.width()*image.height()*4);
+            }
+        }
+    }
+
+    if (!icon_data.isEmpty()) {
+        Q_XCB_CALL(xcb_change_property(xcb_connection(),
+                                       XCB_PROP_MODE_REPLACE,
+                                       m_window,
+                                       atom(QXcbAtom::_NET_WM_ICON),
+                                       atom(QXcbAtom::CARDINAL),
+                                       32,
+                                       icon_data.size(),
+                                       (unsigned char *) icon_data.data()));
+    } else {
+        Q_XCB_CALL(xcb_delete_property(xcb_connection(),
+                                       m_window,
+                                       atom(QXcbAtom::_NET_WM_ICON)));
+    }
+}
+
 void QXcbWindow::raise()
 {
     const quint32 mask = XCB_CONFIG_WINDOW_STACK_MODE;
index 43eb9e8..c3ea4af 100644 (file)
@@ -55,6 +55,7 @@ QT_BEGIN_NAMESPACE
 
 class QXcbScreen;
 class QXcbEGLSurface;
+class QIcon;
 
 class QXcbWindow : public QXcbObject, public QPlatformWindow
 {
@@ -88,6 +89,7 @@ public:
     bool isExposed() const;
 
     void setWindowTitle(const QString &title);
+    void setWindowIcon(const QIcon &icon);
     void raise();
     void lower();
     void propagateSizeHints();