File indexing completed on 2024-04-21 03:59:17

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