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