File indexing completed on 2024-11-10 04:56:25
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"