diff --git a/CMakeLists.txt b/CMakeLists.txt
index 2f8e31a2ea..4860c20c56 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -233,7 +233,6 @@ find_package(XCB 1.10
SHM
GLX
CURSOR
- OPTIONAL_COMPONENTS
ICCCM
)
set_package_properties(XCB PROPERTIES TYPE REQUIRED)
@@ -570,6 +569,7 @@ set(kwin_XCB_LIBS
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
index bb5af38c12..c5040c00f1 100644
--- a/autotests/integration/x11_client_test.cpp
+++ b/autotests/integration/x11_client_test.cpp
@@ -52,6 +52,7 @@ private Q_SLOTS:
void testFocusInWithWaylandLastActiveWindow();
void testX11WindowId();
void testCaptionChanges();
+ void testCaptionWmName();
};
void X11ClientTest::initTestCase()
@@ -427,5 +428,27 @@ void X11ClientTest::testCaptionChanges()
c.reset();
}
+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
index 3dd7fd87f9..8b8f32e18e 100644
--- a/client.cpp
+++ b/client.cpp
@@ -52,6 +52,7 @@ along with this program. If not, see .
// XLib
#include
#include
+#include
// system
#include
#include
@@ -1411,12 +1412,30 @@ void Client::fetchName()
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)
@@ -1487,7 +1506,7 @@ void Client::fetchIconicName()
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;