diff --git a/CMakeLists.txt b/CMakeLists.txt --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -233,7 +233,6 @@ SHM GLX CURSOR - OPTIONAL_COMPONENTS ICCCM ) set_package_properties(XCB PROPERTIES TYPE REQUIRED) @@ -569,6 +568,7 @@ XCB::KEYSYMS XCB::SHM XCB::GLX + XCB::ICCCM ) set(kwin_WAYLAND_LIBS diff --git a/autotests/integration/x11_client_test.cpp b/autotests/integration/x11_client_test.cpp --- a/autotests/integration/x11_client_test.cpp +++ b/autotests/integration/x11_client_test.cpp @@ -51,6 +51,7 @@ void testFullscreenLayerWithActiveWaylandWindow(); void testFocusInWithWaylandLastActiveWindow(); void testX11WindowId(); + void testCaptionWmName(); }; void X11ClientTest::initTestCase() @@ -376,5 +377,27 @@ xcb_flush(c.data()); } +void X11ClientTest::testCaptionWmName() +{ + // this test verifies that a caption set through WM_NAME is read correctly + + // open glxgears as that one only uses WM_NAME + QSignalSpy clientAddedSpy(workspace(), &Workspace::clientAdded); + QVERIFY(clientAddedSpy.isValid()); + + QProcess glxgears; + glxgears.start(QStringLiteral("glxgears")); + QVERIFY(glxgears.waitForStarted()); + + QVERIFY(clientAddedSpy.wait()); + QCOMPARE(clientAddedSpy.count(), 1); + QCOMPARE(workspace()->clientList().count(), 1); + Client *glxgearsClient = workspace()->clientList().first(); + QCOMPARE(glxgearsClient->caption(), QStringLiteral("glxgears")); + + glxgears.terminate(); + QVERIFY(glxgears.waitForFinished()); +} + WAYLANDTEST_MAIN(X11ClientTest) #include "x11_client_test.moc" diff --git a/client.cpp b/client.cpp --- a/client.cpp +++ b/client.cpp @@ -55,6 +55,7 @@ // XLib #include #include +#include // system #include #include @@ -1414,12 +1415,30 @@ setCaption(readName()); } +static inline QString readNameProperty(xcb_window_t w, xcb_atom_t atom) +{ + const auto cookie = xcb_icccm_get_text_property_unchecked(connection(), w, atom); + xcb_icccm_get_text_property_reply_t reply; + if (xcb_icccm_get_wm_name_reply(connection(), cookie, &reply, nullptr)) { + QString retVal; + if (reply.encoding == atoms->utf8_string) { + retVal = QString::fromUtf8(QByteArray(reply.name, reply.name_len)); + } else if (reply.encoding == XCB_ATOM_STRING) { + retVal = QString::fromLocal8Bit(QByteArray(reply.name, reply.name_len)); + } + xcb_icccm_get_text_property_reply_wipe(&reply); + return retVal.simplified(); + } + return QString(); +} + QString Client::readName() const { if (info->name() && info->name()[0] != '\0') return QString::fromUtf8(info->name()).simplified(); - else - return KWindowSystem::readNameProperty(window(), XCB_ATOM_WM_NAME).simplified(); + else { + return readNameProperty(window(), XCB_ATOM_WM_NAME); + } } // The list is taken from http://www.unicode.org/reports/tr9/ (#154840) @@ -1511,7 +1530,7 @@ if (info->iconName() && info->iconName()[0] != '\0') s = QString::fromUtf8(info->iconName()); else - s = KWindowSystem::readNameProperty(window(), XCB_ATOM_WM_ICON_NAME); + s = readNameProperty(window(), XCB_ATOM_WM_ICON_NAME); if (s != cap_iconic) { bool was_set = !cap_iconic.isEmpty(); cap_iconic = s;