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 @@ -49,7 +49,8 @@ void init(); void cleanup(); - void testCaptionSimplified(); + void testTrimCaption_data(); + void testTrimCaption(); void testFullscreenLayerWithActiveWaylandWindow(); void testFocusInWithWaylandLastActiveWindow(); void testX11WindowId(); @@ -94,13 +95,23 @@ } }; +void X11ClientTest::testTrimCaption_data() +{ + QTest::addColumn("originalTitle"); + QTest::addColumn("expectedTitle"); + + QTest::newRow("simplified") + << QByteArrayLiteral("Was tun, wenn Schüler Autismus haben?\342\200\250\342\200\250\342\200\250 – Marlies Hübner - Mozilla Firefox") + << QByteArrayLiteral("Was tun, wenn Schüler Autismus haben? – Marlies Hübner - Mozilla Firefox"); + + QTest::newRow("with emojis") + << QByteArrayLiteral("\bTesting non\302\255printable:\177, emoij:\360\237\230\203, non-characters:\357\277\276") + << QByteArrayLiteral("Testing nonprintable:, emoij:\360\237\230\203, non-characters:"); +} -void X11ClientTest::testCaptionSimplified() +void X11ClientTest::testTrimCaption() { // this test verifies that caption is properly trimmed - // see BUG 323798 comment #12 - QSignalSpy windowAddedSpy(effects, &EffectsHandler::windowAdded); - QVERIFY(windowAddedSpy.isValid()); // create an xcb window QScopedPointer c(xcb_connect(nullptr, nullptr)); @@ -119,8 +130,8 @@ xcb_icccm_size_hints_set_size(&hints, 1, windowGeometry.width(), windowGeometry.height()); xcb_icccm_set_wm_normal_hints(c.data(), w, &hints); NETWinInfo winInfo(c.data(), w, rootWindow(), NET::Properties(), NET::Properties2()); - const QByteArray origTitle = QByteArrayLiteral("Was tun, wenn Schüler Autismus haben?\342\200\250\342\200\250\342\200\250 – Marlies Hübner - Mozilla Firefox"); - winInfo.setName(origTitle.constData()); + QFETCH(QByteArray, originalTitle); + winInfo.setName(originalTitle); xcb_map_window(c.data(), w); xcb_flush(c.data()); @@ -131,8 +142,8 @@ Client *client = windowCreatedSpy.first().first().value(); QVERIFY(client); QCOMPARE(client->window(), w); - QVERIFY(client->caption() != QString::fromUtf8(origTitle)); - QCOMPARE(client->caption(), QString::fromUtf8(origTitle).simplified()); + QFETCH(QByteArray, expectedTitle); + QCOMPARE(client->caption(), QString::fromUtf8(expectedTitle)); // and destroy the window again xcb_unmap_window(c.data(), w); diff --git a/client.cpp b/client.cpp --- a/client.cpp +++ b/client.cpp @@ -1463,13 +1463,27 @@ void Client::setCaption(const QString& _s, bool force) { - if (!force && _s == cap_normal) - return; QString s(_s); - for (int i = 0; i < s.length(); ++i) - if (!s[i].isPrint()) - s[i] = QChar(u' '); + for (int i = 0; i < s.length(); ) { + if (!s[i].isPrint()) { + if (QChar(s[i]).isHighSurrogate() && i + 1 < s.length() && QChar(s[i + 1]).isLowSurrogate()) { + const uint uc = QChar::surrogateToUcs4(s[i], s[i + 1]); + if (!QChar::isPrint(uc)) { + s.remove(i, 2); + } else { + i += 2; + } + continue; + } + s.remove(i, 1); + continue; + } + ++i; + } const bool changed = (s != cap_normal); + if (!force && !changed) { + return; + } cap_normal = s; if (!force && !changed) { emit captionChanged();