summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms/xcb
diff options
context:
space:
mode:
authorFriedemann Kleint <Friedemann.Kleint@digia.com>2013-07-17 14:39:42 +0200
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-07-18 15:12:37 +0200
commit81addcc1edddaefa19080ad90c27df49f92b53a6 (patch)
treedbfe7f0838c69b09c605784b532f3d749b071e8b /src/plugins/platforms/xcb
parent07bc5302503ef855541f5bc39296798127a06de1 (diff)
XCB: Set WM_CLASS.
Set the instance name and class name of the application windows. Task-number: QTBUG-29396 Change-Id: Ia1fb492ab169108c3779deb8964bb731b322dd89 Reviewed-by: Uli Schlachter <psychon@znc.in> Reviewed-by: Shawn Rutledge <shawn.rutledge@digia.com>
Diffstat (limited to 'src/plugins/platforms/xcb')
-rw-r--r--src/plugins/platforms/xcb/qxcbconnection.cpp1
-rw-r--r--src/plugins/platforms/xcb/qxcbconnection.h1
-rw-r--r--src/plugins/platforms/xcb/qxcbintegration.cpp44
-rw-r--r--src/plugins/platforms/xcb/qxcbintegration.h4
-rw-r--r--src/plugins/platforms/xcb/qxcbwindow.cpp7
5 files changed, 57 insertions, 0 deletions
diff --git a/src/plugins/platforms/xcb/qxcbconnection.cpp b/src/plugins/platforms/xcb/qxcbconnection.cpp
index f944b65a57..01af23377e 100644
--- a/src/plugins/platforms/xcb/qxcbconnection.cpp
+++ b/src/plugins/platforms/xcb/qxcbconnection.cpp
@@ -1232,6 +1232,7 @@ static const char * xcb_atomnames = {
// ICCCM window state
"WM_STATE\0"
"WM_CHANGE_STATE\0"
+ "WM_CLASS\0"
// Session management
"WM_CLIENT_LEADER\0"
diff --git a/src/plugins/platforms/xcb/qxcbconnection.h b/src/plugins/platforms/xcb/qxcbconnection.h
index 883ee95e22..2a5ff0b1cb 100644
--- a/src/plugins/platforms/xcb/qxcbconnection.h
+++ b/src/plugins/platforms/xcb/qxcbconnection.h
@@ -102,6 +102,7 @@ namespace QXcbAtom {
// ICCCM window state
WM_STATE,
WM_CHANGE_STATE,
+ WM_CLASS,
// Session management
WM_CLIENT_LEADER,
diff --git a/src/plugins/platforms/xcb/qxcbintegration.cpp b/src/plugins/platforms/xcb/qxcbintegration.cpp
index 77c265fd09..cf7e99023a 100644
--- a/src/plugins/platforms/xcb/qxcbintegration.cpp
+++ b/src/plugins/platforms/xcb/qxcbintegration.cpp
@@ -369,4 +369,48 @@ QVariant QXcbIntegration::styleHint(QPlatformIntegration::StyleHint hint) const
return QPlatformIntegration::styleHint(hint);
}
+static QString argv0BaseName()
+{
+ QString result;
+ const QStringList arguments = QCoreApplication::arguments();
+ if (!arguments.isEmpty() && !arguments.front().isEmpty()) {
+ result = arguments.front();
+ const int lastSlashPos = result.lastIndexOf(QLatin1Char('/'));
+ if (lastSlashPos != -1)
+ result.remove(0, lastSlashPos + 1);
+ }
+ return result;
+}
+
+static const char resourceNameVar[] = "RESOURCE_NAME";
+
+QByteArray QXcbIntegration::wmClass() const
+{
+ if (m_wmClass.isEmpty()) {
+ // Instance name according to ICCCM 4.1.2.5
+ QString name;
+ if (name.isEmpty() && qEnvironmentVariableIsSet(resourceNameVar))
+ name = QString::fromLocal8Bit(qgetenv(resourceNameVar));
+ if (name.isEmpty())
+ name = argv0BaseName();
+
+ // Note: QCoreApplication::applicationName() cannot be called from the QGuiApplication constructor,
+ // hence this delayed initialization.
+ QString className = QCoreApplication::applicationName();
+ if (className.isEmpty()) {
+ className = argv0BaseName();
+ if (!className.isEmpty() && className.at(0).isLower())
+ className[0] = className.at(0).toUpper();
+ }
+
+ if (!name.isEmpty() && !className.isEmpty()) {
+ m_wmClass = name.toLocal8Bit();
+ m_wmClass.append('\0');
+ m_wmClass.append(className.toLocal8Bit());
+ m_wmClass.append('\0');
+ }
+ }
+ return m_wmClass;
+}
+
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/xcb/qxcbintegration.h b/src/plugins/platforms/xcb/qxcbintegration.h
index 7042628203..07b6b8d678 100644
--- a/src/plugins/platforms/xcb/qxcbintegration.h
+++ b/src/plugins/platforms/xcb/qxcbintegration.h
@@ -99,6 +99,8 @@ public:
QXcbConnection *defaultConnection() const { return m_connections.first(); }
+ QByteArray wmClass() const;
+
private:
QList<QXcbConnection *> m_connections;
@@ -115,6 +117,8 @@ private:
QScopedPointer<QPlatformServices> m_services;
friend class QXcbConnection; // access QPlatformIntegration::screenAdded()
+
+ mutable QByteArray m_wmClass;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp
index 3a19788316..3b818d78d8 100644
--- a/src/plugins/platforms/xcb/qxcbwindow.cpp
+++ b/src/plugins/platforms/xcb/qxcbwindow.cpp
@@ -379,6 +379,13 @@ void QXcbWindow::create()
m_syncValue.hi = 0;
m_syncValue.lo = 0;
+ const QByteArray wmClass = static_cast<QXcbIntegration *>(QGuiApplicationPrivate::platformIntegration())->wmClass();
+ if (!wmClass.isEmpty()) {
+ Q_XCB_CALL(xcb_change_property(xcb_connection(), XCB_PROP_MODE_REPLACE,
+ m_window, atom(QXcbAtom::WM_CLASS),
+ XCB_ATOM_STRING, 8, wmClass.size(), wmClass.constData()));
+ }
+
if (m_usingSyncProtocol) {
m_syncCounter = xcb_generate_id(xcb_connection());
Q_XCB_CALL(xcb_sync_create_counter(xcb_connection(), m_syncCounter, m_syncValue));