diff --git a/src/plugins/platforms/xcb/qxcbconnection.cpp b/src/plugins/platforms/xcb/qxcbconnection.cpp index d9c3352747..40a54ffc35 100644 --- a/src/plugins/platforms/xcb/qxcbconnection.cpp +++ b/src/plugins/platforms/xcb/qxcbconnection.cpp @@ -906,6 +906,7 @@ static const char * xcb_atomnames = { // Property formats "TEXT\0" "UTF8_STRING\0" + "CARDINAL\0" // xdnd "XdndEnter\0" diff --git a/src/plugins/platforms/xcb/qxcbconnection.h b/src/plugins/platforms/xcb/qxcbconnection.h index 9fbeb9f5f6..3b17f93917 100644 --- a/src/plugins/platforms/xcb/qxcbconnection.h +++ b/src/plugins/platforms/xcb/qxcbconnection.h @@ -183,6 +183,7 @@ namespace QXcbAtom { // Property formats TEXT, UTF8_STRING, + CARDINAL, // Xdnd XdndEnter, diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp index 168a4419c5..390628d291 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.cpp +++ b/src/plugins/platforms/xcb/qxcbwindow.cpp @@ -43,12 +43,14 @@ #include #include +#include #include "qxcbconnection.h" #include "qxcbscreen.h" #include "qxcbdrag.h" #include "qxcbkeyboard.h" #include "qxcbwmsupport.h" +#include "qxcbimage.h" #include @@ -1122,6 +1124,49 @@ void QXcbWindow::setWindowTitle(const QString &title) ba.constData())); } +void QXcbWindow::setWindowIcon(const QIcon &icon) +{ + QVector icon_data; + + if (!icon.isNull()) { + QList 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; diff --git a/src/plugins/platforms/xcb/qxcbwindow.h b/src/plugins/platforms/xcb/qxcbwindow.h index 43eb9e8639..c3ea4af83c 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.h +++ b/src/plugins/platforms/xcb/qxcbwindow.h @@ -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();