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>
This commit is contained in:
parent
07bc530250
commit
81addcc1ed
@ -1232,6 +1232,7 @@ static const char * xcb_atomnames = {
|
|||||||
// ICCCM window state
|
// ICCCM window state
|
||||||
"WM_STATE\0"
|
"WM_STATE\0"
|
||||||
"WM_CHANGE_STATE\0"
|
"WM_CHANGE_STATE\0"
|
||||||
|
"WM_CLASS\0"
|
||||||
|
|
||||||
// Session management
|
// Session management
|
||||||
"WM_CLIENT_LEADER\0"
|
"WM_CLIENT_LEADER\0"
|
||||||
|
@ -102,6 +102,7 @@ namespace QXcbAtom {
|
|||||||
// ICCCM window state
|
// ICCCM window state
|
||||||
WM_STATE,
|
WM_STATE,
|
||||||
WM_CHANGE_STATE,
|
WM_CHANGE_STATE,
|
||||||
|
WM_CLASS,
|
||||||
|
|
||||||
// Session management
|
// Session management
|
||||||
WM_CLIENT_LEADER,
|
WM_CLIENT_LEADER,
|
||||||
|
@ -369,4 +369,48 @@ QVariant QXcbIntegration::styleHint(QPlatformIntegration::StyleHint hint) const
|
|||||||
return QPlatformIntegration::styleHint(hint);
|
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
|
QT_END_NAMESPACE
|
||||||
|
@ -99,6 +99,8 @@ public:
|
|||||||
|
|
||||||
QXcbConnection *defaultConnection() const { return m_connections.first(); }
|
QXcbConnection *defaultConnection() const { return m_connections.first(); }
|
||||||
|
|
||||||
|
QByteArray wmClass() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QList<QXcbConnection *> m_connections;
|
QList<QXcbConnection *> m_connections;
|
||||||
|
|
||||||
@ -115,6 +117,8 @@ private:
|
|||||||
QScopedPointer<QPlatformServices> m_services;
|
QScopedPointer<QPlatformServices> m_services;
|
||||||
|
|
||||||
friend class QXcbConnection; // access QPlatformIntegration::screenAdded()
|
friend class QXcbConnection; // access QPlatformIntegration::screenAdded()
|
||||||
|
|
||||||
|
mutable QByteArray m_wmClass;
|
||||||
};
|
};
|
||||||
|
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
|
@ -379,6 +379,13 @@ void QXcbWindow::create()
|
|||||||
m_syncValue.hi = 0;
|
m_syncValue.hi = 0;
|
||||||
m_syncValue.lo = 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) {
|
if (m_usingSyncProtocol) {
|
||||||
m_syncCounter = xcb_generate_id(xcb_connection());
|
m_syncCounter = xcb_generate_id(xcb_connection());
|
||||||
Q_XCB_CALL(xcb_sync_create_counter(xcb_connection(), m_syncCounter, m_syncValue));
|
Q_XCB_CALL(xcb_sync_create_counter(xcb_connection(), m_syncCounter, m_syncValue));
|
||||||
|
Loading…
Reference in New Issue
Block a user