Use xcb-icccm to read the name property

Summary:
The KWindowSystem call which we used doesn't work on Wayland as it's only
implemented in the xcb variant and cannot be made available for Wayland
in an easy way as it is still XLib based.

This change turns the optional XCB-ICCCM dependency in a required one
and thus can use the functionality provided by said library to implement
what KWindowSystem provided.

BUG: 382789

Test Plan: New test case which failed with old code

Reviewers: #kwin, #plasma

Subscribers: plasma-devel, kwin

Tags: #kwin

Differential Revision: https://phabricator.kde.org/D7046
icc-effect-5.14.5
Martin Flöser 2017-08-01 21:28:36 +02:00
parent 0455fa9ef9
commit c87230c3a5
3 changed files with 46 additions and 4 deletions

View File

@ -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

View File

@ -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"

View File

@ -52,6 +52,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
// XLib
#include <X11/Xutil.h>
#include <fixx11h.h>
#include <xcb/xcb_icccm.h>
// system
#include <unistd.h>
#include <signal.h>
@ -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;