File indexing completed on 2024-06-16 05:05:05

0001 /*
0002     SPDX-FileCopyrightText: 2020 Bhushan Shah <bshah@kde.org>
0003 
0004     SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
0005 */
0006 
0007 #include <QSignalSpy>
0008 #include <QTest>
0009 #include <QThread>
0010 
0011 #include "wayland/compositor.h"
0012 #include "wayland/display.h"
0013 #include "wayland/seat.h"
0014 #include "wayland/surface.h"
0015 #include "wayland/textinput_v1.h"
0016 
0017 #include "KWayland/Client/compositor.h"
0018 #include "KWayland/Client/connection_thread.h"
0019 #include "KWayland/Client/event_queue.h"
0020 #include "KWayland/Client/registry.h"
0021 #include "KWayland/Client/seat.h"
0022 #include "KWayland/Client/surface.h"
0023 
0024 #include "qwayland-text-input-unstable-v1.h"
0025 
0026 using namespace KWin;
0027 
0028 Q_DECLARE_METATYPE(QtWayland::zwp_text_input_v1::content_purpose)
0029 Q_DECLARE_METATYPE(QtWayland::zwp_text_input_v1::content_hint)
0030 
0031 class TextInputV1 : public QObject, public QtWayland::zwp_text_input_v1
0032 {
0033     Q_OBJECT
0034 Q_SIGNALS:
0035     void surface_enter(wl_surface *surface);
0036     void surface_leave();
0037     void commit_string(const QString &text);
0038     void delete_surrounding_text(qint32 index, quint32 length);
0039     void preedit_string(const QString &text, const QString &commit);
0040 
0041 public:
0042     void zwp_text_input_v1_enter(struct ::wl_surface *surface) override
0043     {
0044         Q_EMIT surface_enter(surface);
0045     }
0046     void zwp_text_input_v1_leave() override
0047     {
0048         Q_EMIT surface_leave();
0049     }
0050     void zwp_text_input_v1_commit_string(uint32_t serial, const QString &text) override
0051     {
0052         Q_EMIT commit_string(text);
0053     }
0054     void zwp_text_input_v1_delete_surrounding_text(int32_t index, uint32_t length) override
0055     {
0056         Q_EMIT delete_surrounding_text(index, length);
0057     }
0058     void zwp_text_input_v1_preedit_string(uint32_t serial, const QString &text, const QString &commit) override
0059     {
0060         Q_EMIT preedit_string(text, commit);
0061     }
0062 };
0063 
0064 class TextInputManagerV1 : public QtWayland::zwp_text_input_manager_v1
0065 {
0066 public:
0067     ~TextInputManagerV1() override
0068     {
0069     }
0070 };
0071 
0072 class TestTextInputV1Interface : public QObject
0073 {
0074     Q_OBJECT
0075 
0076 public:
0077     ~TestTextInputV1Interface() override;
0078 
0079 private Q_SLOTS:
0080     void initTestCase();
0081     void testEnableDisable();
0082     void testEvents();
0083     void testContentPurpose_data();
0084     void testContentPurpose();
0085     void testContentHints_data();
0086     void testContentHints();
0087 
0088 private:
0089     KWayland::Client::ConnectionThread *m_connection = nullptr;
0090     KWayland::Client::EventQueue *m_queue = nullptr;
0091     KWayland::Client::Compositor *m_clientCompositor = nullptr;
0092     KWayland::Client::Seat *m_clientSeat = nullptr;
0093 
0094     SeatInterface *m_seat;
0095     QThread *m_thread;
0096     KWin::Display m_display;
0097     TextInputV1 *m_clientTextInputV1;
0098     CompositorInterface *m_serverCompositor;
0099     TextInputV1Interface *m_serverTextInputV1;
0100     TextInputManagerV1 *m_clientTextInputManagerV1;
0101 
0102     quint32 m_totalCommits = 0;
0103 };
0104 
0105 static const QString s_socketName = QStringLiteral("kwin-wayland-server-text-input-v1-test-0");
0106 
0107 void TestTextInputV1Interface::initTestCase()
0108 {
0109     m_display.addSocketName(s_socketName);
0110     m_display.start();
0111     QVERIFY(m_display.isRunning());
0112 
0113     m_seat = new SeatInterface(&m_display, this);
0114     m_seat->setHasKeyboard(true);
0115 
0116     m_serverCompositor = new CompositorInterface(&m_display, this);
0117     new TextInputManagerV1Interface(&m_display);
0118 
0119     m_connection = new KWayland::Client::ConnectionThread;
0120     QSignalSpy connectedSpy(m_connection, &KWayland::Client::ConnectionThread::connected);
0121     m_connection->setSocketName(s_socketName);
0122 
0123     m_thread = new QThread(this);
0124     m_connection->moveToThread(m_thread);
0125     m_thread->start();
0126 
0127     m_connection->initConnection();
0128     QVERIFY(connectedSpy.wait());
0129     QVERIFY(!m_connection->connections().isEmpty());
0130 
0131     m_queue = new KWayland::Client::EventQueue(this);
0132     QVERIFY(!m_queue->isValid());
0133     m_queue->setup(m_connection);
0134     QVERIFY(m_queue->isValid());
0135 
0136     auto registry = new KWayland::Client::Registry(this);
0137     connect(registry, &KWayland::Client::Registry::interfaceAnnounced, this, [this, registry](const QByteArray &interface, quint32 id, quint32 version) {
0138         if (interface == QByteArrayLiteral("zwp_text_input_manager_v1")) {
0139             m_clientTextInputManagerV1 = new TextInputManagerV1();
0140             m_clientTextInputManagerV1->init(*registry, id, version);
0141         }
0142     });
0143 
0144     connect(registry, &KWayland::Client::Registry::seatAnnounced, this, [this, registry](quint32 name, quint32 version) {
0145         m_clientSeat = registry->createSeat(name, version);
0146     });
0147 
0148     QSignalSpy allAnnouncedSpy(registry, &KWayland::Client::Registry::interfaceAnnounced);
0149     QSignalSpy compositorSpy(registry, &KWayland::Client::Registry::compositorAnnounced);
0150     QSignalSpy shmSpy(registry, &KWayland::Client::Registry::shmAnnounced);
0151     registry->setEventQueue(m_queue);
0152     registry->create(m_connection->display());
0153     QVERIFY(registry->isValid());
0154     registry->setup();
0155     QVERIFY(allAnnouncedSpy.wait());
0156 
0157     m_clientCompositor = registry->createCompositor(compositorSpy.first().first().value<quint32>(), compositorSpy.first().last().value<quint32>(), this);
0158     QVERIFY(m_clientCompositor->isValid());
0159     // create a text input v1
0160     m_clientTextInputV1 = new TextInputV1();
0161     m_clientTextInputV1->init(m_clientTextInputManagerV1->create_text_input());
0162     QVERIFY(m_clientTextInputV1);
0163 }
0164 
0165 TestTextInputV1Interface::~TestTextInputV1Interface()
0166 {
0167     if (m_clientTextInputV1) {
0168         delete m_clientTextInputV1;
0169         m_clientTextInputV1 = nullptr;
0170     }
0171     if (m_clientTextInputManagerV1) {
0172         delete m_clientTextInputManagerV1;
0173         m_clientTextInputManagerV1 = nullptr;
0174     }
0175     if (m_queue) {
0176         delete m_queue;
0177         m_queue = nullptr;
0178     }
0179     if (m_thread) {
0180         m_thread->quit();
0181         m_thread->wait();
0182         delete m_thread;
0183         m_thread = nullptr;
0184     }
0185     m_connection->deleteLater();
0186     m_connection = nullptr;
0187 }
0188 
0189 // Ensures that enable disable events don't fire without commit
0190 void TestTextInputV1Interface::testEnableDisable()
0191 {
0192     // create a surface
0193     QSignalSpy serverSurfaceCreatedSpy(m_serverCompositor, &CompositorInterface::surfaceCreated);
0194     std::unique_ptr<KWayland::Client::Surface> clientSurface(m_clientCompositor->createSurface(this));
0195     QVERIFY(serverSurfaceCreatedSpy.wait());
0196     SurfaceInterface *serverSurface = serverSurfaceCreatedSpy.first().first().value<SurfaceInterface *>();
0197     QVERIFY(serverSurface);
0198 
0199     m_serverTextInputV1 = m_seat->textInputV1();
0200     QVERIFY(m_serverTextInputV1);
0201 
0202     QSignalSpy focusedSurfaceChangedSpy(m_seat, &SeatInterface::focusedTextInputSurfaceChanged);
0203     QSignalSpy textInputEnabledSpy(m_serverTextInputV1, &TextInputV1Interface::enabledChanged);
0204     QSignalSpy cursorRectangleChangedSpy(m_serverTextInputV1, &TextInputV1Interface::cursorRectangleChanged);
0205 
0206     QSignalSpy surfaceEnterSpy(m_clientTextInputV1, &TextInputV1::surface_enter);
0207     QSignalSpy surfaceLeaveSpy(m_clientTextInputV1, &TextInputV1::surface_leave);
0208 
0209     // Enter the textinput
0210 
0211     QCOMPARE(focusedSurfaceChangedSpy.count(), 0);
0212 
0213     // Make sure that entering surface does not trigger the text input
0214     m_seat->setFocusedTextInputSurface(serverSurface);
0215     QCOMPARE(focusedSurfaceChangedSpy.count(), 1);
0216     QCOMPARE(surfaceEnterSpy.count(), 0);
0217     QCOMPARE(textInputEnabledSpy.count(), 0);
0218 
0219     // Now enable the textInput, we should not get event just yet
0220     m_clientTextInputV1->activate(*m_clientSeat, *clientSurface);
0221     m_clientTextInputV1->set_cursor_rectangle(0, 0, 20, 20);
0222     m_clientTextInputV1->set_surrounding_text("KDE Plasma Desktop", 0, 3);
0223     QVERIFY(surfaceEnterSpy.wait());
0224 
0225     QCOMPARE(textInputEnabledSpy.count(), 1);
0226     QCOMPARE(cursorRectangleChangedSpy.count(), 1);
0227     QCOMPARE(m_serverTextInputV1->cursorRectangle(), QRect(0, 0, 20, 20));
0228     QCOMPARE(m_serverTextInputV1->surroundingText(), QString("KDE Plasma Desktop"));
0229     QCOMPARE(m_serverTextInputV1->surroundingTextCursorPosition(), 0);
0230     QCOMPARE(m_serverTextInputV1->surroundingTextSelectionAnchor(), 3);
0231 
0232     // disabling we should get the event
0233     m_clientTextInputV1->deactivate(*m_clientSeat);
0234     QVERIFY(textInputEnabledSpy.wait());
0235     QCOMPARE(textInputEnabledSpy.count(), 2);
0236     QVERIFY(surfaceLeaveSpy.wait());
0237 
0238     // Lets try leaving the surface and make sure event propogage
0239     m_seat->setFocusedTextInputSurface(nullptr);
0240     QCOMPARE(surfaceLeaveSpy.count(), 1);
0241 }
0242 
0243 void TestTextInputV1Interface::testEvents()
0244 {
0245     // create a surface
0246     QSignalSpy serverSurfaceCreatedSpy(m_serverCompositor, &CompositorInterface::surfaceCreated);
0247     std::unique_ptr<KWayland::Client::Surface> clientSurface(m_clientCompositor->createSurface(this));
0248     QVERIFY(serverSurfaceCreatedSpy.wait());
0249     SurfaceInterface *serverSurface = serverSurfaceCreatedSpy.first().first().value<SurfaceInterface *>();
0250     QVERIFY(serverSurface);
0251 
0252     m_serverTextInputV1 = m_seat->textInputV1();
0253     QVERIFY(m_serverTextInputV1);
0254 
0255     QSignalSpy focusedSurfaceChangedSpy(m_seat, &SeatInterface::focusedTextInputSurfaceChanged);
0256     QSignalSpy textInputEnabledSpy(m_serverTextInputV1, &TextInputV1Interface::enabledChanged);
0257 
0258     // Enter the textinput
0259     QCOMPARE(focusedSurfaceChangedSpy.count(), 0);
0260 
0261     // Make sure that entering surface does not trigger the text input
0262     m_seat->setFocusedTextInputSurface(serverSurface);
0263     // FIXME: somehow this triggers BEFORE setFocusedTextInputSurface returns :(
0264     //  QVERIFY(focusedSurfaceChangedSpy.wait());
0265     QCOMPARE(focusedSurfaceChangedSpy.count(), 1);
0266 
0267     // Now enable the textInput
0268     m_clientTextInputV1->activate(*m_clientSeat, *clientSurface);
0269     QVERIFY(textInputEnabledSpy.wait());
0270 
0271     QSignalSpy preEditSpy(m_clientTextInputV1, &TextInputV1::preedit_string);
0272     QSignalSpy commitStringSpy(m_clientTextInputV1, &TextInputV1::commit_string);
0273     QSignalSpy deleteSurroundingSpy(m_clientTextInputV1, &TextInputV1::delete_surrounding_text);
0274 
0275     m_serverTextInputV1->preEdit("Hello KDE community!", "Hello");
0276     m_serverTextInputV1->deleteSurroundingText(6, 10);
0277     m_serverTextInputV1->commitString("Plasma");
0278 
0279     // Wait for the last update
0280     QVERIFY(commitStringSpy.wait());
0281 
0282     QCOMPARE(preEditSpy.last().at(0).value<QString>(), "Hello KDE community!");
0283     QCOMPARE(preEditSpy.last().at(1).value<QString>(), "Hello");
0284     QCOMPARE(commitStringSpy.last().at(0).value<QString>(), "Plasma");
0285     QCOMPARE(deleteSurroundingSpy.last().at(0).value<quint32>(), 6);
0286     QCOMPARE(deleteSurroundingSpy.last().at(1).value<quint32>(), 10);
0287 
0288     // Now disable the textInput
0289     m_clientTextInputV1->deactivate(*m_clientSeat);
0290     QVERIFY(textInputEnabledSpy.wait());
0291 }
0292 
0293 void TestTextInputV1Interface::testContentPurpose_data()
0294 {
0295     QTest::addColumn<QtWayland::zwp_text_input_v1::content_purpose>("clientPurpose");
0296     QTest::addColumn<KWin::TextInputContentPurpose>("serverPurpose");
0297 
0298     QTest::newRow("Alpha") << QtWayland::zwp_text_input_v1::content_purpose_alpha << TextInputContentPurpose::Alpha;
0299     QTest::newRow("Digits") << QtWayland::zwp_text_input_v1::content_purpose_digits << TextInputContentPurpose::Digits;
0300     QTest::newRow("Number") << QtWayland::zwp_text_input_v1::content_purpose_number << TextInputContentPurpose::Number;
0301     QTest::newRow("Phone") << QtWayland::zwp_text_input_v1::content_purpose_phone << TextInputContentPurpose::Phone;
0302     QTest::newRow("Url") << QtWayland::zwp_text_input_v1::content_purpose_url << TextInputContentPurpose::Url;
0303     QTest::newRow("Email") << QtWayland::zwp_text_input_v1::content_purpose_email << TextInputContentPurpose::Email;
0304     QTest::newRow("Name") << QtWayland::zwp_text_input_v1::content_purpose_name << TextInputContentPurpose::Name;
0305     QTest::newRow("Password") << QtWayland::zwp_text_input_v1::content_purpose_password << TextInputContentPurpose::Password;
0306     QTest::newRow("Date") << QtWayland::zwp_text_input_v1::content_purpose_date << TextInputContentPurpose::Date;
0307     QTest::newRow("Time") << QtWayland::zwp_text_input_v1::content_purpose_time << TextInputContentPurpose::Time;
0308     QTest::newRow("DateTime") << QtWayland::zwp_text_input_v1::content_purpose_datetime << TextInputContentPurpose::DateTime;
0309     QTest::newRow("Terminal") << QtWayland::zwp_text_input_v1::content_purpose_terminal << TextInputContentPurpose::Terminal;
0310 }
0311 
0312 void TestTextInputV1Interface::testContentPurpose()
0313 {
0314     // create a surface
0315     QSignalSpy serverSurfaceCreatedSpy(m_serverCompositor, &CompositorInterface::surfaceCreated);
0316     std::unique_ptr<KWayland::Client::Surface> clientSurface(m_clientCompositor->createSurface(this));
0317     QVERIFY(serverSurfaceCreatedSpy.wait());
0318     SurfaceInterface *serverSurface = serverSurfaceCreatedSpy.first().first().value<SurfaceInterface *>();
0319     QVERIFY(serverSurface);
0320 
0321     m_serverTextInputV1 = m_seat->textInputV1();
0322     QVERIFY(m_serverTextInputV1);
0323 
0324     QSignalSpy focusedSurfaceChangedSpy(m_seat, &SeatInterface::focusedTextInputSurfaceChanged);
0325     QSignalSpy textInputEnabledSpy(m_serverTextInputV1, &TextInputV1Interface::enabledChanged);
0326 
0327     // Enter the textinput
0328     QCOMPARE(focusedSurfaceChangedSpy.count(), 0);
0329 
0330     // Make sure that entering surface does not trigger the text input
0331     m_seat->setFocusedTextInputSurface(serverSurface);
0332     // FIXME: somehow this triggers BEFORE setFocusedTextInputSurface returns :(
0333     //  QVERIFY(focusedSurfaceChangedSpy.wait());
0334     QCOMPARE(focusedSurfaceChangedSpy.count(), 1);
0335 
0336     // Now enable the textInput
0337     m_clientTextInputV1->activate(*m_clientSeat, *clientSurface);
0338     QVERIFY(textInputEnabledSpy.wait());
0339     m_totalCommits++;
0340 
0341     // Default should be normal content purpose
0342     QCOMPARE(m_serverTextInputV1->contentPurpose(), TextInputContentPurpose::Normal);
0343 
0344     QSignalSpy contentTypeChangedSpy(m_serverTextInputV1, &TextInputV1Interface::contentTypeChanged);
0345 
0346     QFETCH(QtWayland::zwp_text_input_v1::content_purpose, clientPurpose);
0347     m_clientTextInputV1->activate(*m_clientSeat, *clientSurface);
0348     m_clientTextInputV1->set_content_type(QtWayland::zwp_text_input_v1::content_hint_none, clientPurpose);
0349     QVERIFY(contentTypeChangedSpy.wait());
0350     QTEST(m_serverTextInputV1->contentPurpose(), "serverPurpose");
0351     m_totalCommits++;
0352 
0353     // Setting same thing should not trigger update
0354     m_clientTextInputV1->activate(*m_clientSeat, *clientSurface);
0355     m_clientTextInputV1->set_content_type(QtWayland::zwp_text_input_v1::content_hint_none, clientPurpose);
0356     QVERIFY(!contentTypeChangedSpy.wait(100));
0357     m_totalCommits++;
0358 
0359     // unset to normal
0360     m_clientTextInputV1->activate(*m_clientSeat, *clientSurface);
0361     m_clientTextInputV1->set_content_type(QtWayland::zwp_text_input_v1::content_hint_none, QtWayland::zwp_text_input_v1::content_purpose_normal);
0362     QVERIFY(contentTypeChangedSpy.wait());
0363     m_totalCommits++;
0364     QCOMPARE(m_serverTextInputV1->contentPurpose(), TextInputContentPurpose::Normal);
0365 
0366     // Now disable the textInput
0367     m_clientTextInputV1->deactivate(*m_clientSeat);
0368     m_totalCommits++;
0369     QVERIFY(textInputEnabledSpy.wait());
0370 }
0371 
0372 void TestTextInputV1Interface::testContentHints_data()
0373 {
0374     QTest::addColumn<quint32>("clientHint");
0375     QTest::addColumn<KWin::TextInputContentHints>("serverHints");
0376 
0377     QTest::addRow("Spellcheck") << quint32(QtWayland::zwp_text_input_v1::content_hint_auto_correction)
0378                                 << TextInputContentHints(TextInputContentHint::AutoCorrection);
0379     QTest::addRow("Completion") << quint32(QtWayland::zwp_text_input_v1::content_hint_auto_completion)
0380                                 << TextInputContentHints(TextInputContentHint::AutoCompletion);
0381     QTest::addRow("AutoCapital") << quint32(QtWayland::zwp_text_input_v1::content_hint_auto_capitalization)
0382                                  << TextInputContentHints(TextInputContentHint::AutoCapitalization);
0383     QTest::addRow("Lowercase") << quint32(QtWayland::zwp_text_input_v1::content_hint_lowercase) << TextInputContentHints(TextInputContentHint::LowerCase);
0384     QTest::addRow("Uppercase") << quint32(QtWayland::zwp_text_input_v1::content_hint_uppercase) << TextInputContentHints(TextInputContentHint::UpperCase);
0385     QTest::addRow("Titlecase") << quint32(QtWayland::zwp_text_input_v1::content_hint_titlecase) << TextInputContentHints(TextInputContentHint::TitleCase);
0386     QTest::addRow("HiddenText") << quint32(QtWayland::zwp_text_input_v1::content_hint_hidden_text) << TextInputContentHints(TextInputContentHint::HiddenText);
0387     QTest::addRow("SensitiveData") << quint32(QtWayland::zwp_text_input_v1::content_hint_sensitive_data)
0388                                    << TextInputContentHints(TextInputContentHint::SensitiveData);
0389     QTest::addRow("Latin") << quint32(QtWayland::zwp_text_input_v1::content_hint_latin) << TextInputContentHints(TextInputContentHint::Latin);
0390     QTest::addRow("Multiline") << quint32(QtWayland::zwp_text_input_v1::content_hint_multiline) << TextInputContentHints(TextInputContentHint::MultiLine);
0391     QTest::addRow("Auto") << quint32(QtWayland::zwp_text_input_v1::content_hint_auto_completion | QtWayland::zwp_text_input_v1::content_hint_auto_correction
0392                                      | QtWayland::zwp_text_input_v1::content_hint_auto_capitalization)
0393                           << TextInputContentHints(TextInputContentHint::AutoCompletion | TextInputContentHint::AutoCorrection
0394                                                    | TextInputContentHint::AutoCapitalization);
0395 }
0396 
0397 void TestTextInputV1Interface::testContentHints()
0398 {
0399     // create a surface
0400     QSignalSpy serverSurfaceCreatedSpy(m_serverCompositor, &CompositorInterface::surfaceCreated);
0401     std::unique_ptr<KWayland::Client::Surface> clientSurface(m_clientCompositor->createSurface(this));
0402     QVERIFY(serverSurfaceCreatedSpy.wait());
0403     SurfaceInterface *serverSurface = serverSurfaceCreatedSpy.first().first().value<SurfaceInterface *>();
0404     QVERIFY(serverSurface);
0405 
0406     m_serverTextInputV1 = m_seat->textInputV1();
0407     QVERIFY(m_serverTextInputV1);
0408 
0409     QSignalSpy focusedSurfaceChangedSpy(m_seat, &SeatInterface::focusedTextInputSurfaceChanged);
0410     QSignalSpy textInputEnabledSpy(m_serverTextInputV1, &TextInputV1Interface::enabledChanged);
0411 
0412     // Enter the textinput
0413     QCOMPARE(focusedSurfaceChangedSpy.count(), 0);
0414 
0415     // Make sure that entering surface does not trigger the text input
0416     m_seat->setFocusedTextInputSurface(serverSurface);
0417     // FIXME: somehow this triggers BEFORE setFocusedTextInputSurface returns :(
0418     //  QVERIFY(focusedSurfaceChangedSpy.wait());
0419     QCOMPARE(focusedSurfaceChangedSpy.count(), 1);
0420 
0421     // Now enable the textInput
0422     m_clientTextInputV1->activate(*m_clientSeat, *clientSurface);
0423     QVERIFY(textInputEnabledSpy.wait());
0424     m_totalCommits++;
0425 
0426     QCOMPARE(m_serverTextInputV1->contentHints(), TextInputContentHint::None);
0427 
0428     // Now disable the textInput
0429     m_clientTextInputV1->deactivate(*m_clientSeat);
0430     QVERIFY(textInputEnabledSpy.wait());
0431     m_totalCommits++;
0432 
0433     QSignalSpy contentTypeChangedSpy(m_serverTextInputV1, &TextInputV1Interface::contentTypeChanged);
0434 
0435     QFETCH(quint32, clientHint);
0436     m_clientTextInputV1->activate(*m_clientSeat, *clientSurface);
0437     m_clientTextInputV1->set_content_type(clientHint, QtWayland::zwp_text_input_v1::content_purpose_normal);
0438     QVERIFY(contentTypeChangedSpy.wait());
0439     QTEST(m_serverTextInputV1->contentHints(), "serverHints");
0440     m_totalCommits++;
0441 
0442     // Setting same thing should not trigger update
0443     m_clientTextInputV1->activate(*m_clientSeat, *clientSurface);
0444     m_clientTextInputV1->set_content_type(clientHint, QtWayland::zwp_text_input_v1::content_purpose_normal);
0445     QVERIFY(!contentTypeChangedSpy.wait(100));
0446     m_totalCommits++;
0447 
0448     // unset to normal
0449     m_clientTextInputV1->activate(*m_clientSeat, *clientSurface);
0450     m_clientTextInputV1->set_content_type(QtWayland::zwp_text_input_v1::content_hint_none, QtWayland::zwp_text_input_v1::content_purpose_normal);
0451     QVERIFY(contentTypeChangedSpy.wait());
0452     m_totalCommits++;
0453 
0454     // Now disable the textInput
0455     m_clientTextInputV1->deactivate(*m_clientSeat);
0456     QVERIFY(textInputEnabledSpy.wait());
0457     m_totalCommits++;
0458 }
0459 
0460 QTEST_GUILESS_MAIN(TestTextInputV1Interface)
0461 
0462 #include "test_textinputv1_interface.moc"