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
|
||||
"WM_STATE\0"
|
||||
"WM_CHANGE_STATE\0"
|
||||
"WM_CLASS\0"
|
||||
|
||||
// Session management
|
||||
"WM_CLIENT_LEADER\0"
|
||||
|
@ -102,6 +102,7 @@ namespace QXcbAtom {
|
||||
// ICCCM window state
|
||||
WM_STATE,
|
||||
WM_CHANGE_STATE,
|
||||
WM_CLASS,
|
||||
|
||||
// Session management
|
||||
WM_CLIENT_LEADER,
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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));
|
||||
|
Loading…
Reference in New Issue
Block a user