diff --git a/autotests/integration/shell_client_test.cpp b/autotests/integration/shell_client_test.cpp --- a/autotests/integration/shell_client_test.cpp +++ b/autotests/integration/shell_client_test.cpp @@ -778,6 +778,8 @@ auto c = Test::renderAndWaitForShown(surface.data(), QSize(100, 50), Qt::blue); QVERIFY(c); QCOMPARE(c->desktopFileName(), QByteArrayLiteral("org.kde.foo")); + QCOMPARE(c->resourceClass(), QByteArrayLiteral("org.kde.foo")); + QVERIFY(c->resourceName().startsWith("testShellClient")); // the desktop file does not exist, so icon should be generic Wayland QCOMPARE(c->icon().name(), QStringLiteral("wayland")); @@ -788,6 +790,8 @@ shellSurface->setAppId(QByteArrayLiteral("org.kde.bar")); QVERIFY(desktopFileNameChangedSpy.wait()); QCOMPARE(c->desktopFileName(), QByteArrayLiteral("org.kde.bar")); + QCOMPARE(c->resourceClass(), QByteArrayLiteral("org.kde.bar")); + QVERIFY(c->resourceName().startsWith("testShellClient")); // icon should still be wayland QCOMPARE(c->icon().name(), QStringLiteral("wayland")); QVERIFY(iconChangedSpy.isEmpty()); diff --git a/shell_client.cpp b/shell_client.cpp --- a/shell_client.cpp +++ b/shell_client.cpp @@ -51,6 +51,7 @@ #include +#include #include #include @@ -126,11 +127,18 @@ } ); - setResourceClass(shellSurface->windowClass()); + // determine the resource name, this is inspired from ICCCM 4.1.2.5 + // the binary name of the invoked client + QFileInfo info{shellSurface->client()->executablePath()}; + QByteArray resourceName; + if (info.exists()) { + resourceName = info.fileName().toUtf8(); + } + setResourceClass(resourceName, shellSurface->windowClass()); setDesktopFileName(shellSurface->windowClass()); connect(shellSurface, &T::windowClassChanged, this, - [this] (const QByteArray &windowClass) { - setResourceClass(windowClass); + [this, resourceName] (const QByteArray &windowClass) { + setResourceClass(resourceName, windowClass); setDesktopFileName(windowClass); } );