File indexing completed on 2024-04-14 14:29:39

0001 /*
0002     This file is part of the KDE Libraries
0003 
0004     SPDX-FileCopyrightText: 2009 Lubos Lunak <l.lunak@kde.org>
0005     SPDX-FileCopyrightText: 2013 Martin Gräßlin <mgraesslin@kde.org>
0006 
0007     SPDX-License-Identifier: LGPL-2.1-or-later
0008 */
0009 
0010 #include "kmanagerselectiontest.h"
0011 #include "cptr_p.h"
0012 
0013 #include <QSignalSpy>
0014 #include <kselectionowner.h>
0015 #include <kselectionwatcher.h>
0016 
0017 #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
0018 #include <private/qtx11extras_p.h>
0019 #else
0020 #include <QX11Info>
0021 #endif
0022 
0023 #define SNAME "_KDE_KMANAGERSELECTIONTEST"
0024 
0025 using namespace QTest;
0026 
0027 void KManagerSelectionTest::xSync()
0028 {
0029     xcb_connection_t *c = QX11Info::connection();
0030     const xcb_get_input_focus_cookie_t cookie = xcb_get_input_focus(c);
0031     xcb_generic_error_t *error = nullptr;
0032     UniqueCPointer<xcb_get_input_focus_reply_t> sync(xcb_get_input_focus_reply(c, cookie, &error));
0033     if (error) {
0034         free(error);
0035     }
0036 }
0037 
0038 void KManagerSelectionTest::claim(KSelectionOwner *owner, bool force, bool forceKill)
0039 {
0040     QSignalSpy claimSpy(owner, &KSelectionOwner::claimedOwnership);
0041     owner->claim(force, forceKill);
0042     xSync();
0043     QVERIFY(claimSpy.wait());
0044     QCOMPARE(claimSpy.count(), 1);
0045 }
0046 
0047 void KManagerSelectionTest::testAcquireRelease()
0048 {
0049     // test that newOwner() is emitted when there is a new selection owner
0050     KSelectionWatcher watcher(SNAME);
0051     KSelectionOwner owner(SNAME);
0052     QVERIFY(owner.ownerWindow() == XCB_WINDOW_NONE);
0053     QVERIFY(watcher.owner() == XCB_WINDOW_NONE);
0054     SigCheckWatcher sw(watcher);
0055     SigCheckOwner so(owner);
0056     claim(&owner);
0057     QSignalSpy newOwnerSpy(&watcher, &KSelectionWatcher::newOwner);
0058     QVERIFY(newOwnerSpy.wait());
0059     QVERIFY(sw.newowner == true);
0060     QVERIFY(sw.lostowner == false);
0061     QVERIFY(so.lostownership == false);
0062 }
0063 
0064 void KManagerSelectionTest::testInitiallyOwned()
0065 {
0066     // test that lostOwner() is emitted when the selection is disowned
0067     KSelectionOwner owner(SNAME);
0068     SigCheckOwner so(owner);
0069     claim(&owner);
0070     KSelectionWatcher watcher(SNAME);
0071     SigCheckWatcher sw(watcher);
0072     owner.release();
0073     QSignalSpy lostOwnerSpy(&watcher, &KSelectionWatcher::lostOwner);
0074     QVERIFY(lostOwnerSpy.wait(2000));
0075     QVERIFY(sw.newowner == false);
0076     QVERIFY(sw.lostowner == true);
0077     QVERIFY(so.lostownership == false);
0078 }
0079 
0080 void KManagerSelectionTest::testLostOwnership()
0081 {
0082     // test that lostOwnership() is emitted when something else forces taking the ownership
0083     KSelectionOwner owner1(SNAME);
0084     KSelectionOwner owner2(SNAME);
0085     claim(&owner1);
0086 
0087     QSignalSpy claimSpy(&owner2, &KSelectionOwner::failedToClaimOwnership);
0088     owner2.claim(false);
0089     claimSpy.wait();
0090     QCOMPARE(claimSpy.count(), 1);
0091     claim(&owner2, true, false);
0092 
0093     QEXPECT_FAIL("", "selectionClear event is not sent to the same X client", Abort);
0094     QSignalSpy lostOwnershipSpy(&owner1, &KSelectionOwner::lostOwnership);
0095     QVERIFY(lostOwnershipSpy.wait());
0096     QVERIFY(owner1.ownerWindow() == XCB_WINDOW_NONE);
0097     QVERIFY(owner2.ownerWindow() != XCB_WINDOW_NONE);
0098 }
0099 
0100 void KManagerSelectionTest::testWatching()
0101 {
0102     // test that KSelectionWatcher reports changes properly
0103     KSelectionWatcher watcher(SNAME);
0104     KSelectionOwner owner1(SNAME);
0105     KSelectionOwner owner2(SNAME);
0106     SigCheckWatcher sw(watcher);
0107     QSignalSpy newOwnerSpy(&watcher, &KSelectionWatcher::newOwner);
0108     QVERIFY(newOwnerSpy.isValid());
0109     claim(&owner1);
0110     if (newOwnerSpy.isEmpty()) {
0111         QVERIFY(newOwnerSpy.wait());
0112     }
0113     QCOMPARE(newOwnerSpy.count(), 1);
0114     QVERIFY(sw.newowner == true);
0115     QVERIFY(sw.lostowner == false);
0116     sw.newowner = sw.lostowner = false;
0117     newOwnerSpy.clear();
0118     QVERIFY(newOwnerSpy.isEmpty());
0119     claim(&owner2, true, false);
0120     xSync();
0121     if (newOwnerSpy.isEmpty()) {
0122         QVERIFY(newOwnerSpy.wait());
0123     }
0124     QCOMPARE(newOwnerSpy.count(), 1);
0125     QVERIFY(sw.newowner == true);
0126     QVERIFY(sw.lostowner == false);
0127     sw.newowner = sw.lostowner = false;
0128     QSignalSpy lostOwnerSpy(&watcher, &KSelectionWatcher::lostOwner);
0129     owner2.release();
0130     xSync();
0131     QVERIFY(lostOwnerSpy.wait());
0132     QVERIFY(sw.newowner == false);
0133     QVERIFY(sw.lostowner == true);
0134     sw.newowner = sw.lostowner = false;
0135     claim(&owner2);
0136     QVERIFY(newOwnerSpy.wait(2000));
0137     QVERIFY(sw.newowner == true);
0138     QVERIFY(sw.lostowner == false);
0139 }
0140 
0141 SigCheckOwner::SigCheckOwner(const KSelectionOwner &owner)
0142     : lostownership(false)
0143 {
0144     connect(&owner, &KSelectionOwner::lostOwnership, this, &SigCheckOwner::lostOwnership);
0145 }
0146 
0147 void SigCheckOwner::lostOwnership()
0148 {
0149     lostownership = true;
0150 }
0151 
0152 SigCheckWatcher::SigCheckWatcher(const KSelectionWatcher &watcher)
0153     : newowner(false)
0154     , lostowner(false)
0155 {
0156     connect(&watcher, &KSelectionWatcher::newOwner, this, &SigCheckWatcher::newOwner);
0157     connect(&watcher, &KSelectionWatcher::lostOwner, this, &SigCheckWatcher::lostOwner);
0158 }
0159 
0160 void SigCheckWatcher::newOwner()
0161 {
0162     newowner = true;
0163 }
0164 
0165 void SigCheckWatcher::lostOwner()
0166 {
0167     lostowner = true;
0168 }
0169 
0170 QTEST_MAIN(KManagerSelectionTest)
0171 
0172 #include "moc_kmanagerselectiontest.cpp"