File indexing completed on 2024-05-05 05:31:29

0001 /*
0002     KWin - the KDE window manager
0003     This file is part of the KDE project.
0004 
0005     SPDX-FileCopyrightText: 2013 Martin Gräßlin <mgraesslin@kde.org>
0006 
0007     SPDX-License-Identifier: GPL-2.0-or-later
0008 */
0009 #include "testutils.h"
0010 // KWin
0011 #include "utils/xcbutils.h"
0012 // Qt
0013 #include <QApplication>
0014 #include <QTest>
0015 #include <netwm.h>
0016 #include <private/qtx11extras_p.h>
0017 // xcb
0018 #include <xcb/xcb.h>
0019 
0020 using namespace KWin;
0021 
0022 class TestXcbWrapper : public QObject
0023 {
0024     Q_OBJECT
0025 private Q_SLOTS:
0026     void initTestCase();
0027     void init();
0028     void cleanup();
0029     void defaultCtor();
0030     void normalCtor();
0031     void copyCtorEmpty();
0032     void copyCtorBeforeRetrieve();
0033     void copyCtorAfterRetrieve();
0034     void assignementEmpty();
0035     void assignmentBeforeRetrieve();
0036     void assignmentAfterRetrieve();
0037     void discard();
0038     void testQueryTree();
0039     void testCurrentInput();
0040     void testTransientFor();
0041     void testPropertyByteArray();
0042     void testPropertyBool();
0043     void testAtom();
0044     void testMotifEmpty();
0045     void testMotif_data();
0046     void testMotif();
0047 
0048 private:
0049     void testEmpty(Xcb::WindowGeometry &geometry);
0050     void testGeometry(Xcb::WindowGeometry &geometry, const QRect &rect);
0051     Xcb::Window m_testWindow;
0052 };
0053 
0054 void TestXcbWrapper::initTestCase()
0055 {
0056     qApp->setProperty("x11RootWindow", QVariant::fromValue<quint32>(QX11Info::appRootWindow()));
0057     qApp->setProperty("x11Connection", QVariant::fromValue<void *>(QX11Info::connection()));
0058 }
0059 
0060 void TestXcbWrapper::init()
0061 {
0062     const uint32_t values[] = {true};
0063     m_testWindow.create(QRect(0, 0, 10, 10), XCB_WINDOW_CLASS_INPUT_ONLY, XCB_CW_OVERRIDE_REDIRECT, values);
0064     QVERIFY(m_testWindow.isValid());
0065 }
0066 
0067 void TestXcbWrapper::cleanup()
0068 {
0069     m_testWindow.reset();
0070 }
0071 
0072 void TestXcbWrapper::testEmpty(Xcb::WindowGeometry &geometry)
0073 {
0074     QCOMPARE(geometry.window(), KWin::noneWindow());
0075     QVERIFY(!geometry.data());
0076     QCOMPARE(geometry.isNull(), true);
0077     QCOMPARE(geometry.rect(), QRect());
0078     QVERIFY(!geometry);
0079 }
0080 
0081 void TestXcbWrapper::testGeometry(Xcb::WindowGeometry &geometry, const QRect &rect)
0082 {
0083     QCOMPARE(geometry.window(), (xcb_window_t)m_testWindow);
0084     // now lets retrieve some data
0085     QCOMPARE(geometry.rect(), rect);
0086     QVERIFY(geometry.isRetrieved());
0087     QCOMPARE(geometry.isNull(), false);
0088     QVERIFY(geometry);
0089     QVERIFY(geometry.data());
0090     QCOMPARE(geometry.data()->x, int16_t(rect.x()));
0091     QCOMPARE(geometry.data()->y, int16_t(rect.y()));
0092     QCOMPARE(geometry.data()->width, uint16_t(rect.width()));
0093     QCOMPARE(geometry.data()->height, uint16_t(rect.height()));
0094 }
0095 
0096 void TestXcbWrapper::defaultCtor()
0097 {
0098     Xcb::WindowGeometry geometry;
0099     testEmpty(geometry);
0100     QVERIFY(!geometry.isRetrieved());
0101 }
0102 
0103 void TestXcbWrapper::normalCtor()
0104 {
0105     Xcb::WindowGeometry geometry(m_testWindow);
0106     QVERIFY(!geometry.isRetrieved());
0107     testGeometry(geometry, QRect(0, 0, 10, 10));
0108 }
0109 
0110 void TestXcbWrapper::copyCtorEmpty()
0111 {
0112     Xcb::WindowGeometry geometry;
0113     Xcb::WindowGeometry other(geometry);
0114     testEmpty(geometry);
0115     QVERIFY(geometry.isRetrieved());
0116     testEmpty(other);
0117     QVERIFY(!other.isRetrieved());
0118 }
0119 
0120 void TestXcbWrapper::copyCtorBeforeRetrieve()
0121 {
0122     Xcb::WindowGeometry geometry(m_testWindow);
0123     QVERIFY(!geometry.isRetrieved());
0124     Xcb::WindowGeometry other(geometry);
0125     testEmpty(geometry);
0126     QVERIFY(geometry.isRetrieved());
0127 
0128     QVERIFY(!other.isRetrieved());
0129     testGeometry(other, QRect(0, 0, 10, 10));
0130 }
0131 
0132 void TestXcbWrapper::copyCtorAfterRetrieve()
0133 {
0134     Xcb::WindowGeometry geometry(m_testWindow);
0135     QVERIFY(geometry);
0136     QVERIFY(geometry.isRetrieved());
0137     QCOMPARE(geometry.rect(), QRect(0, 0, 10, 10));
0138     Xcb::WindowGeometry other(geometry);
0139     testEmpty(geometry);
0140     QVERIFY(geometry.isRetrieved());
0141 
0142     QVERIFY(other.isRetrieved());
0143     testGeometry(other, QRect(0, 0, 10, 10));
0144 }
0145 
0146 void TestXcbWrapper::assignementEmpty()
0147 {
0148     Xcb::WindowGeometry geometry;
0149     Xcb::WindowGeometry other;
0150     testEmpty(geometry);
0151     testEmpty(other);
0152 
0153     other = geometry;
0154     QVERIFY(geometry.isRetrieved());
0155     testEmpty(geometry);
0156     testEmpty(other);
0157     QVERIFY(!other.isRetrieved());
0158 
0159     QT_WARNING_PUSH
0160     QT_WARNING_DISABLE_CLANG("-Wself-assign-overloaded")
0161     // test assignment to self
0162     geometry = geometry;
0163     other = other;
0164     testEmpty(geometry);
0165     testEmpty(other);
0166     QT_WARNING_POP
0167 }
0168 
0169 void TestXcbWrapper::assignmentBeforeRetrieve()
0170 {
0171     Xcb::WindowGeometry geometry(m_testWindow);
0172     Xcb::WindowGeometry other = geometry;
0173     QVERIFY(geometry.isRetrieved());
0174     testEmpty(geometry);
0175 
0176     QVERIFY(!other.isRetrieved());
0177     testGeometry(other, QRect(0, 0, 10, 10));
0178 
0179     other = Xcb::WindowGeometry(m_testWindow);
0180     QVERIFY(!other.isRetrieved());
0181     QCOMPARE(other.window(), (xcb_window_t)m_testWindow);
0182     other = Xcb::WindowGeometry();
0183     testEmpty(geometry);
0184 
0185     QT_WARNING_PUSH
0186     QT_WARNING_DISABLE_CLANG("-Wself-assign-overloaded")
0187     // test assignment to self
0188     geometry = geometry;
0189     other = other;
0190     testEmpty(geometry);
0191     QT_WARNING_POP
0192 }
0193 
0194 void TestXcbWrapper::assignmentAfterRetrieve()
0195 {
0196     Xcb::WindowGeometry geometry(m_testWindow);
0197     QVERIFY(geometry);
0198     QVERIFY(geometry.isRetrieved());
0199     Xcb::WindowGeometry other = geometry;
0200     testEmpty(geometry);
0201 
0202     QVERIFY(other.isRetrieved());
0203     testGeometry(other, QRect(0, 0, 10, 10));
0204 
0205     QT_WARNING_PUSH
0206     QT_WARNING_DISABLE_CLANG("-Wself-assign-overloaded")
0207     // test assignment to self
0208     geometry = geometry;
0209     other = other;
0210     testEmpty(geometry);
0211     testGeometry(other, QRect(0, 0, 10, 10));
0212     QT_WARNING_POP
0213 
0214     // set to empty again
0215     other = Xcb::WindowGeometry();
0216     testEmpty(other);
0217 }
0218 
0219 void TestXcbWrapper::discard()
0220 {
0221     // discard of reply cannot be tested properly as we cannot check whether the reply has been discarded
0222     // therefore it's more or less just a test to ensure that it doesn't crash and the code paths
0223     // are taken.
0224     Xcb::WindowGeometry *geometry = new Xcb::WindowGeometry();
0225     delete geometry;
0226 
0227     geometry = new Xcb::WindowGeometry(m_testWindow);
0228     delete geometry;
0229 
0230     geometry = new Xcb::WindowGeometry(m_testWindow);
0231     QVERIFY(geometry->data());
0232     delete geometry;
0233 }
0234 
0235 void TestXcbWrapper::testQueryTree()
0236 {
0237     Xcb::Tree tree(m_testWindow);
0238     // should have root as parent
0239     QCOMPARE(tree.parent(), static_cast<xcb_window_t>(QX11Info::appRootWindow()));
0240     // shouldn't have any children
0241     QCOMPARE(tree->children_len, uint16_t(0));
0242     QVERIFY(!tree.children());
0243 
0244     // query for root
0245     Xcb::Tree root(QX11Info::appRootWindow());
0246     // shouldn't have a parent
0247     QCOMPARE(root.parent(), xcb_window_t(XCB_WINDOW_NONE));
0248     QVERIFY(root->children_len > 0);
0249     xcb_window_t *children = root.children();
0250     bool found = false;
0251     for (int i = 0; i < xcb_query_tree_children_length(root.data()); ++i) {
0252         if (children[i] == tree.window()) {
0253             found = true;
0254             break;
0255         }
0256     }
0257     QVERIFY(found);
0258 
0259     // query for not existing window
0260     Xcb::Tree doesntExist(XCB_WINDOW_NONE);
0261     QCOMPARE(doesntExist.parent(), xcb_window_t(XCB_WINDOW_NONE));
0262     QVERIFY(doesntExist.isNull());
0263     QVERIFY(doesntExist.isRetrieved());
0264 }
0265 
0266 void TestXcbWrapper::testCurrentInput()
0267 {
0268     xcb_connection_t *c = QX11Info::connection();
0269     m_testWindow.map();
0270     QX11Info::setAppTime(QX11Info::getTimestamp());
0271 
0272     // let's set the input focus
0273     m_testWindow.focus(XCB_INPUT_FOCUS_PARENT, QX11Info::appTime());
0274     xcb_flush(c);
0275 
0276     Xcb::CurrentInput input;
0277     QCOMPARE(input.window(), (xcb_window_t)m_testWindow);
0278 
0279     // creating a copy should make the input object have no window any more
0280     Xcb::CurrentInput input2(input);
0281     QCOMPARE(input2.window(), (xcb_window_t)m_testWindow);
0282     QCOMPARE(input.window(), xcb_window_t(XCB_WINDOW_NONE));
0283 }
0284 
0285 void TestXcbWrapper::testTransientFor()
0286 {
0287     Xcb::TransientFor transient(m_testWindow);
0288     QCOMPARE(transient.window(), (xcb_window_t)m_testWindow);
0289     // our m_testWindow doesn't have a transient for hint
0290     xcb_window_t compareWindow = XCB_WINDOW_NONE;
0291     QVERIFY(!transient.getTransientFor(&compareWindow));
0292     QCOMPARE(compareWindow, xcb_window_t(XCB_WINDOW_NONE));
0293     bool ok = true;
0294     QCOMPARE(transient.value<xcb_window_t>(32, XCB_ATOM_WINDOW, XCB_WINDOW_NONE, &ok), xcb_window_t(XCB_WINDOW_NONE));
0295     QVERIFY(!ok);
0296     ok = true;
0297     QCOMPARE(transient.value<xcb_window_t>(XCB_WINDOW_NONE, &ok), xcb_window_t(XCB_WINDOW_NONE));
0298     QVERIFY(!ok);
0299 
0300     // Create a Window with a transient for hint
0301     Xcb::Window transientWindow(KWin::createWindow());
0302     xcb_window_t testWindowId = m_testWindow;
0303     transientWindow.changeProperty(XCB_ATOM_WM_TRANSIENT_FOR, XCB_ATOM_WINDOW, 32, 1, &testWindowId);
0304 
0305     // let's get another transient object
0306     Xcb::TransientFor realTransient(transientWindow);
0307     QVERIFY(realTransient.getTransientFor(&compareWindow));
0308     QCOMPARE(compareWindow, (xcb_window_t)m_testWindow);
0309     ok = false;
0310     QCOMPARE(realTransient.value<xcb_window_t>(32, XCB_ATOM_WINDOW, XCB_WINDOW_NONE, &ok), (xcb_window_t)m_testWindow);
0311     QVERIFY(ok);
0312     ok = false;
0313     QCOMPARE(realTransient.value<xcb_window_t>(XCB_WINDOW_NONE, &ok), (xcb_window_t)m_testWindow);
0314     QVERIFY(ok);
0315     ok = false;
0316     QCOMPARE(realTransient.value<xcb_window_t>(), (xcb_window_t)m_testWindow);
0317     QCOMPARE(realTransient.value<xcb_window_t *>(nullptr, &ok)[0], (xcb_window_t)m_testWindow);
0318     QVERIFY(ok);
0319     QCOMPARE(realTransient.value<xcb_window_t *>()[0], (xcb_window_t)m_testWindow);
0320 
0321     // test for a not existing window
0322     Xcb::TransientFor doesntExist(XCB_WINDOW_NONE);
0323     QVERIFY(!doesntExist.getTransientFor(&compareWindow));
0324 }
0325 
0326 void TestXcbWrapper::testPropertyByteArray()
0327 {
0328     Xcb::Window testWindow(KWin::createWindow());
0329     Xcb::Property prop(false, testWindow, XCB_ATOM_WM_NAME, XCB_ATOM_STRING, 0, 100000);
0330     QCOMPARE(prop.toByteArray(), QByteArray());
0331     bool ok = true;
0332     QCOMPARE(prop.toByteArray(&ok), QByteArray());
0333     QVERIFY(!ok);
0334     ok = true;
0335     QVERIFY(!prop.value<const char *>());
0336     QCOMPARE(prop.value<const char *>("bar", &ok), "bar");
0337     QVERIFY(!ok);
0338     QCOMPARE(QByteArray(Xcb::StringProperty(testWindow, XCB_ATOM_WM_NAME)), QByteArray());
0339 
0340     testWindow.changeProperty(XCB_ATOM_WM_NAME, XCB_ATOM_STRING, 8, 3, "foo");
0341     prop = Xcb::Property(false, testWindow, XCB_ATOM_WM_NAME, XCB_ATOM_STRING, 0, 100000);
0342     QCOMPARE(prop.toByteArray(), QByteArrayLiteral("foo"));
0343     QCOMPARE(prop.toByteArray(&ok), QByteArrayLiteral("foo"));
0344     QVERIFY(ok);
0345     QCOMPARE(prop.value<const char *>(nullptr, &ok), "foo");
0346     QVERIFY(ok);
0347     QCOMPARE(QByteArray(Xcb::StringProperty(testWindow, XCB_ATOM_WM_NAME)), QByteArrayLiteral("foo"));
0348 
0349     // verify incorrect format and type
0350     QCOMPARE(prop.toByteArray(32), QByteArray());
0351     QCOMPARE(prop.toByteArray(8, XCB_ATOM_CARDINAL), QByteArray());
0352 
0353     // verify empty property
0354     testWindow.changeProperty(XCB_ATOM_WM_NAME, XCB_ATOM_STRING, 8, 0, nullptr);
0355     prop = Xcb::Property(false, testWindow, XCB_ATOM_WM_NAME, XCB_ATOM_STRING, 0, 100000);
0356     QCOMPARE(prop.toByteArray(), QByteArray());
0357     QCOMPARE(prop.toByteArray(&ok), QByteArray());
0358     // valid bytearray
0359     QVERIFY(ok);
0360     // The bytearray should be empty
0361     QVERIFY(prop.toByteArray().isEmpty());
0362     // The bytearray should be not null
0363     QVERIFY(!prop.toByteArray().isNull());
0364     QVERIFY(!prop.value<const char *>());
0365     QCOMPARE(QByteArray(Xcb::StringProperty(testWindow, XCB_ATOM_WM_NAME)), QByteArray());
0366 
0367     // verify non existing property
0368     Xcb::Atom invalid(QByteArrayLiteral("INVALID_ATOM"));
0369     prop = Xcb::Property(false, testWindow, invalid, XCB_ATOM_STRING, 0, 100000);
0370     QCOMPARE(prop.toByteArray(), QByteArray());
0371     QCOMPARE(prop.toByteArray(&ok), QByteArray());
0372     // invalid bytearray
0373     QVERIFY(!ok);
0374     // The bytearray should be empty
0375     QVERIFY(prop.toByteArray().isEmpty());
0376     // The bytearray should be not null
0377     QVERIFY(prop.toByteArray().isNull());
0378     QVERIFY(!prop.value<const char *>());
0379     QCOMPARE(QByteArray(Xcb::StringProperty(testWindow, XCB_ATOM_WM_NAME)), QByteArray());
0380 }
0381 
0382 void TestXcbWrapper::testPropertyBool()
0383 {
0384     Xcb::Window testWindow(KWin::createWindow());
0385     Xcb::Atom blockCompositing(QByteArrayLiteral("_KDE_NET_WM_BLOCK_COMPOSITING"));
0386     QVERIFY(blockCompositing != XCB_ATOM_NONE);
0387     NETWinInfo info(QX11Info::connection(), testWindow, QX11Info::appRootWindow(), NET::Properties(), NET::WM2BlockCompositing);
0388 
0389     Xcb::Property prop(false, testWindow, blockCompositing, XCB_ATOM_CARDINAL, 0, 100000);
0390     bool ok = true;
0391     QVERIFY(!prop.toBool());
0392     QVERIFY(!prop.toBool(&ok));
0393     QVERIFY(!ok);
0394 
0395     info.setBlockingCompositing(true);
0396     xcb_flush(QX11Info::connection());
0397     prop = Xcb::Property(false, testWindow, blockCompositing, XCB_ATOM_CARDINAL, 0, 100000);
0398     QVERIFY(prop.toBool());
0399     QVERIFY(prop.toBool(&ok));
0400     QVERIFY(ok);
0401 
0402     // incorrect type and format
0403     QVERIFY(!prop.toBool(8));
0404     QVERIFY(!prop.toBool(32, blockCompositing));
0405     QVERIFY(!prop.toBool(32, blockCompositing, &ok));
0406     QVERIFY(!ok);
0407 
0408     // incorrect value:
0409     uint32_t d[] = {1, 0};
0410     testWindow.changeProperty(blockCompositing, XCB_ATOM_CARDINAL, 32, 2, d);
0411     prop = Xcb::Property(false, testWindow, blockCompositing, XCB_ATOM_CARDINAL, 0, 100000);
0412     QVERIFY(!prop.toBool());
0413     ok = true;
0414     QVERIFY(!prop.toBool(&ok));
0415     QVERIFY(!ok);
0416 }
0417 
0418 void TestXcbWrapper::testAtom()
0419 {
0420     Xcb::Atom atom(QByteArrayLiteral("WM_CLIENT_MACHINE"));
0421     QCOMPARE(atom.name(), QByteArrayLiteral("WM_CLIENT_MACHINE"));
0422     QVERIFY(atom == XCB_ATOM_WM_CLIENT_MACHINE);
0423     QVERIFY(atom.isValid());
0424 
0425     // test the const paths
0426     const Xcb::Atom &atom2(atom);
0427     QVERIFY(atom2.isValid());
0428     QVERIFY(atom2 == XCB_ATOM_WM_CLIENT_MACHINE);
0429     QCOMPARE(atom2.name(), QByteArrayLiteral("WM_CLIENT_MACHINE"));
0430 
0431     // destroy before retrieved
0432     Xcb::Atom atom3(QByteArrayLiteral("WM_CLIENT_MACHINE"));
0433     QCOMPARE(atom3.name(), QByteArrayLiteral("WM_CLIENT_MACHINE"));
0434 }
0435 
0436 void TestXcbWrapper::testMotifEmpty()
0437 {
0438     Xcb::Atom atom(QByteArrayLiteral("_MOTIF_WM_HINTS"));
0439     Xcb::MotifHints hints(atom);
0440     // pre init
0441     QCOMPARE(hints.hasDecoration(), false);
0442     QCOMPARE(hints.noBorder(), false);
0443     QCOMPARE(hints.resize(), true);
0444     QCOMPARE(hints.move(), true);
0445     QCOMPARE(hints.minimize(), true);
0446     QCOMPARE(hints.maximize(), true);
0447     QCOMPARE(hints.close(), true);
0448     // post init, pre read
0449     hints.init(m_testWindow);
0450     QCOMPARE(hints.hasDecoration(), false);
0451     QCOMPARE(hints.noBorder(), false);
0452     QCOMPARE(hints.resize(), true);
0453     QCOMPARE(hints.move(), true);
0454     QCOMPARE(hints.minimize(), true);
0455     QCOMPARE(hints.maximize(), true);
0456     QCOMPARE(hints.close(), true);
0457     // post read
0458     hints.read();
0459     QCOMPARE(hints.hasDecoration(), false);
0460     QCOMPARE(hints.noBorder(), false);
0461     QCOMPARE(hints.resize(), true);
0462     QCOMPARE(hints.move(), true);
0463     QCOMPARE(hints.minimize(), true);
0464     QCOMPARE(hints.maximize(), true);
0465     QCOMPARE(hints.close(), true);
0466 }
0467 
0468 void TestXcbWrapper::testMotif_data()
0469 {
0470     QTest::addColumn<quint32>("flags");
0471     QTest::addColumn<quint32>("functions");
0472     QTest::addColumn<quint32>("decorations");
0473 
0474     QTest::addColumn<bool>("expectedHasDecoration");
0475     QTest::addColumn<bool>("expectedNoBorder");
0476     QTest::addColumn<bool>("expectedResize");
0477     QTest::addColumn<bool>("expectedMove");
0478     QTest::addColumn<bool>("expectedMinimize");
0479     QTest::addColumn<bool>("expectedMaximize");
0480     QTest::addColumn<bool>("expectedClose");
0481 
0482     QTest::newRow("none") << 0u << 0u << 0u << false << false << true << true << true << true << true;
0483     QTest::newRow("noborder") << 2u << 5u << 0u << true << true << true << true << true << true << true;
0484     QTest::newRow("border") << 2u << 5u << 1u << true << false << true << true << true << true << true;
0485     QTest::newRow("resize") << 1u << 2u << 1u << false << false << true << false << false << false << false;
0486     QTest::newRow("move") << 1u << 4u << 1u << false << false << false << true << false << false << false;
0487     QTest::newRow("minimize") << 1u << 8u << 1u << false << false << false << false << true << false << false;
0488     QTest::newRow("maximize") << 1u << 16u << 1u << false << false << false << false << false << true << false;
0489     QTest::newRow("close") << 1u << 32u << 1u << false << false << false << false << false << false << true;
0490 
0491     QTest::newRow("resize/all") << 1u << 3u << 1u << false << false << false << true << true << true << true;
0492     QTest::newRow("move/all") << 1u << 5u << 1u << false << false << true << false << true << true << true;
0493     QTest::newRow("minimize/all") << 1u << 9u << 1u << false << false << true << true << false << true << true;
0494     QTest::newRow("maximize/all") << 1u << 17u << 1u << false << false << true << true << true << false << true;
0495     QTest::newRow("close/all") << 1u << 33u << 1u << false << false << true << true << true << true << false;
0496 
0497     QTest::newRow("all") << 1u << 62u << 1u << false << false << true << true << true << true << true;
0498     QTest::newRow("all/all") << 1u << 63u << 1u << false << false << false << false << false << false << false;
0499     QTest::newRow("all/all/deco") << 3u << 63u << 1u << true << false << false << false << false << false << false;
0500 }
0501 
0502 void TestXcbWrapper::testMotif()
0503 {
0504     Xcb::Atom atom(QByteArrayLiteral("_MOTIF_WM_HINTS"));
0505     QFETCH(quint32, flags);
0506     QFETCH(quint32, functions);
0507     QFETCH(quint32, decorations);
0508     quint32 data[] = {
0509         flags,
0510         functions,
0511         decorations,
0512         0,
0513         0};
0514     xcb_change_property(QX11Info::connection(), XCB_PROP_MODE_REPLACE, m_testWindow, atom, atom, 32, 5, data);
0515     xcb_flush(QX11Info::connection());
0516     Xcb::MotifHints hints(atom);
0517     hints.init(m_testWindow);
0518     hints.read();
0519     QTEST(hints.hasDecoration(), "expectedHasDecoration");
0520     QTEST(hints.noBorder(), "expectedNoBorder");
0521     QTEST(hints.resize(), "expectedResize");
0522     QTEST(hints.move(), "expectedMove");
0523     QTEST(hints.minimize(), "expectedMinimize");
0524     QTEST(hints.maximize(), "expectedMaximize");
0525     QTEST(hints.close(), "expectedClose");
0526 }
0527 
0528 Q_CONSTRUCTOR_FUNCTION(forceXcb)
0529 QTEST_MAIN(TestXcbWrapper)
0530 #include "test_xcb_wrapper.moc"