File indexing completed on 2025-02-02 15:33:37
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 // xcb 0021 #include <xcb/xcb.h> 0022 0023 using namespace KWin; 0024 0025 class TestXcbWindow : public QObject 0026 { 0027 Q_OBJECT 0028 private Q_SLOTS: 0029 void initTestCase(); 0030 void defaultCtor(); 0031 void ctor(); 0032 void classCtor(); 0033 void create(); 0034 void mapUnmap(); 0035 void geometry(); 0036 void destroy(); 0037 void destroyNotManaged(); 0038 }; 0039 0040 void TestXcbWindow::initTestCase() 0041 { 0042 qApp->setProperty("x11RootWindow", QVariant::fromValue<quint32>(QX11Info::appRootWindow())); 0043 qApp->setProperty("x11Connection", QVariant::fromValue<void *>(QX11Info::connection())); 0044 } 0045 0046 void TestXcbWindow::defaultCtor() 0047 { 0048 Xcb::Window window; 0049 QCOMPARE(window.isValid(), false); 0050 xcb_window_t wId = window; 0051 QCOMPARE(wId, noneWindow()); 0052 0053 xcb_window_t nativeWindow = createWindow(); 0054 Xcb::Window window2(nativeWindow); 0055 QCOMPARE(window2.isValid(), true); 0056 wId = window2; 0057 QCOMPARE(wId, nativeWindow); 0058 } 0059 0060 void TestXcbWindow::ctor() 0061 { 0062 const QRect geometry(0, 0, 10, 10); 0063 const uint32_t values[] = {true}; 0064 Xcb::Window window(geometry, XCB_CW_OVERRIDE_REDIRECT, values); 0065 QCOMPARE(window.isValid(), true); 0066 QVERIFY(window != XCB_WINDOW_NONE); 0067 Xcb::WindowGeometry windowGeometry(window); 0068 QCOMPARE(windowGeometry.isNull(), false); 0069 QCOMPARE(windowGeometry.rect(), geometry); 0070 } 0071 0072 void TestXcbWindow::classCtor() 0073 { 0074 const QRect geometry(0, 0, 10, 10); 0075 const uint32_t values[] = {true}; 0076 Xcb::Window window(geometry, XCB_WINDOW_CLASS_INPUT_ONLY, XCB_CW_OVERRIDE_REDIRECT, values); 0077 QCOMPARE(window.isValid(), true); 0078 QVERIFY(window != XCB_WINDOW_NONE); 0079 Xcb::WindowGeometry windowGeometry(window); 0080 QCOMPARE(windowGeometry.isNull(), false); 0081 QCOMPARE(windowGeometry.rect(), geometry); 0082 0083 Xcb::WindowAttributes attribs(window); 0084 QCOMPARE(attribs.isNull(), false); 0085 QVERIFY(attribs->_class == XCB_WINDOW_CLASS_INPUT_ONLY); 0086 } 0087 0088 void TestXcbWindow::create() 0089 { 0090 Xcb::Window window; 0091 QCOMPARE(window.isValid(), false); 0092 xcb_window_t wId = window; 0093 QCOMPARE(wId, noneWindow()); 0094 0095 const QRect geometry(0, 0, 10, 10); 0096 const uint32_t values[] = {true}; 0097 window.create(geometry, XCB_CW_OVERRIDE_REDIRECT, values); 0098 QCOMPARE(window.isValid(), true); 0099 QVERIFY(window != XCB_WINDOW_NONE); 0100 // and reset again 0101 window.reset(); 0102 QCOMPARE(window.isValid(), false); 0103 QVERIFY(window == XCB_WINDOW_NONE); 0104 } 0105 0106 void TestXcbWindow::mapUnmap() 0107 { 0108 const QRect geometry(0, 0, 10, 10); 0109 const uint32_t values[] = {true}; 0110 Xcb::Window window(geometry, XCB_WINDOW_CLASS_INPUT_ONLY, XCB_CW_OVERRIDE_REDIRECT, values); 0111 Xcb::WindowAttributes attribs(window); 0112 QCOMPARE(attribs.isNull(), false); 0113 QVERIFY(attribs->map_state == XCB_MAP_STATE_UNMAPPED); 0114 0115 window.map(); 0116 Xcb::WindowAttributes attribs2(window); 0117 QCOMPARE(attribs2.isNull(), false); 0118 QVERIFY(attribs2->map_state != XCB_MAP_STATE_UNMAPPED); 0119 0120 window.unmap(); 0121 Xcb::WindowAttributes attribs3(window); 0122 QCOMPARE(attribs3.isNull(), false); 0123 QVERIFY(attribs3->map_state == XCB_MAP_STATE_UNMAPPED); 0124 0125 // map, unmap shouldn't fail for an invalid window, it's just ignored 0126 window.reset(); 0127 window.map(); 0128 window.unmap(); 0129 } 0130 0131 void TestXcbWindow::geometry() 0132 { 0133 const QRect geometry(0, 0, 10, 10); 0134 const uint32_t values[] = {true}; 0135 Xcb::Window window(geometry, XCB_WINDOW_CLASS_INPUT_ONLY, XCB_CW_OVERRIDE_REDIRECT, values); 0136 Xcb::WindowGeometry windowGeometry(window); 0137 QCOMPARE(windowGeometry.isNull(), false); 0138 QCOMPARE(windowGeometry.rect(), geometry); 0139 0140 const QRect geometry2(10, 20, 100, 200); 0141 window.setGeometry(geometry2); 0142 Xcb::WindowGeometry windowGeometry2(window); 0143 QCOMPARE(windowGeometry2.isNull(), false); 0144 QCOMPARE(windowGeometry2.rect(), geometry2); 0145 0146 // setting a geometry on an invalid window should be ignored 0147 window.reset(); 0148 window.setGeometry(geometry2); 0149 Xcb::WindowGeometry windowGeometry3(window); 0150 QCOMPARE(windowGeometry3.isNull(), true); 0151 } 0152 0153 void TestXcbWindow::destroy() 0154 { 0155 const QRect geometry(0, 0, 10, 10); 0156 const uint32_t values[] = {true}; 0157 Xcb::Window window(geometry, XCB_CW_OVERRIDE_REDIRECT, values); 0158 QCOMPARE(window.isValid(), true); 0159 xcb_window_t wId = window; 0160 0161 window.create(geometry, XCB_CW_OVERRIDE_REDIRECT, values); 0162 // wId should now be invalid 0163 xcb_generic_error_t *error = nullptr; 0164 UniqueCPtr<xcb_get_window_attributes_reply_t> attribs(xcb_get_window_attributes_reply( 0165 connection(), 0166 xcb_get_window_attributes(connection(), wId), 0167 &error)); 0168 QVERIFY(!attribs); 0169 QCOMPARE(error->error_code, uint8_t(3)); 0170 QCOMPARE(error->resource_id, wId); 0171 free(error); 0172 0173 // test the same for the dtor 0174 { 0175 Xcb::Window scopedWindow(geometry, XCB_CW_OVERRIDE_REDIRECT, values); 0176 QVERIFY(scopedWindow.isValid()); 0177 wId = scopedWindow; 0178 } 0179 error = nullptr; 0180 UniqueCPtr<xcb_get_window_attributes_reply_t> attribs2(xcb_get_window_attributes_reply( 0181 connection(), 0182 xcb_get_window_attributes(connection(), wId), 0183 &error)); 0184 QVERIFY(!attribs2); 0185 QCOMPARE(error->error_code, uint8_t(3)); 0186 QCOMPARE(error->resource_id, wId); 0187 free(error); 0188 } 0189 0190 void TestXcbWindow::destroyNotManaged() 0191 { 0192 Xcb::Window window; 0193 // just destroy the non-existing window 0194 window.reset(); 0195 0196 // now let's add a window 0197 window.reset(createWindow(), false); 0198 xcb_window_t w = window; 0199 window.reset(); 0200 Xcb::WindowAttributes attribs(w); 0201 QVERIFY(attribs); 0202 } 0203 0204 Q_CONSTRUCTOR_FUNCTION(forceXcb) 0205 QTEST_MAIN(TestXcbWindow) 0206 #include "test_xcb_window.moc"