Changeset View
Changeset View
Standalone View
Standalone View
autotests/integration/dont_crash_empty_deco.cpp
Show All 22 Lines | |||||
23 | #include "cursor.h" | 23 | #include "cursor.h" | ||
24 | #include "screenedge.h" | 24 | #include "screenedge.h" | ||
25 | #include "screens.h" | 25 | #include "screens.h" | ||
26 | #include "wayland_server.h" | 26 | #include "wayland_server.h" | ||
27 | #include "workspace.h" | 27 | #include "workspace.h" | ||
28 | #include "shell_client.h" | 28 | #include "shell_client.h" | ||
29 | #include <kwineffects.h> | 29 | #include <kwineffects.h> | ||
30 | 30 | | |||
31 | #include <KWayland/Client/connection_thread.h> | | |||
32 | #include <KWayland/Client/compositor.h> | | |||
33 | #include <KWayland/Client/event_queue.h> | | |||
34 | #include <KWayland/Client/registry.h> | | |||
35 | #include <KWayland/Client/pointer.h> | | |||
36 | #include <KWayland/Client/server_decoration.h> | | |||
37 | #include <KWayland/Client/shell.h> | | |||
38 | #include <KWayland/Client/seat.h> | | |||
39 | #include <KWayland/Client/shm_pool.h> | | |||
40 | #include <KWayland/Client/surface.h> | | |||
41 | | ||||
42 | #include <KDecoration2/Decoration> | 31 | #include <KDecoration2/Decoration> | ||
43 | 32 | | |||
44 | #include <linux/input.h> | 33 | #include <linux/input.h> | ||
45 | 34 | | |||
46 | namespace KWin | 35 | namespace KWin | ||
47 | { | 36 | { | ||
48 | 37 | | |||
49 | static const QString s_socketName = QStringLiteral("wayland_test_kwin_dont_crash_empty_decoration-0"); | 38 | static const QString s_socketName = QStringLiteral("wayland_test_kwin_dont_crash_empty_decoration-0"); | ||
50 | 39 | | |||
51 | class DontCrashEmptyDecorationTest : public QObject | 40 | class DontCrashEmptyDecorationTest : public QObject | ||
52 | { | 41 | { | ||
53 | Q_OBJECT | 42 | Q_OBJECT | ||
54 | private Q_SLOTS: | 43 | private Q_SLOTS: | ||
55 | void initTestCase(); | 44 | void initTestCase(); | ||
56 | void init(); | 45 | void init(); | ||
57 | void cleanup(); | | |||
58 | void testBug361551(); | 46 | void testBug361551(); | ||
59 | | ||||
60 | private: | | |||
61 | KWayland::Client::ConnectionThread *m_connection = nullptr; | | |||
62 | KWayland::Client::Compositor *m_compositor = nullptr; | | |||
63 | KWayland::Client::ServerSideDecorationManager *m_deco = nullptr; | | |||
64 | KWayland::Client::Seat *m_seat = nullptr; | | |||
65 | KWayland::Client::ShmPool *m_shm = nullptr; | | |||
66 | KWayland::Client::Shell *m_shell = nullptr; | | |||
67 | KWayland::Client::EventQueue *m_queue = nullptr; | | |||
68 | QThread *m_thread = nullptr; | | |||
69 | }; | 47 | }; | ||
70 | 48 | | |||
71 | void DontCrashEmptyDecorationTest::initTestCase() | 49 | void DontCrashEmptyDecorationTest::initTestCase() | ||
72 | { | 50 | { | ||
73 | if (!QFile::exists(QStringLiteral("/dev/dri/card0"))) { | 51 | if (!QFile::exists(QStringLiteral("/dev/dri/card0"))) { | ||
74 | QSKIP("Needs a dri device"); | 52 | QSKIP("Needs a dri device"); | ||
75 | } | 53 | } | ||
76 | qRegisterMetaType<KWin::ShellClient*>(); | 54 | qRegisterMetaType<KWin::ShellClient*>(); | ||
Show All 12 Lines | |||||
89 | QCOMPARE(screens()->geometry(0), QRect(0, 0, 1280, 1024)); | 67 | QCOMPARE(screens()->geometry(0), QRect(0, 0, 1280, 1024)); | ||
90 | QCOMPARE(screens()->geometry(1), QRect(1280, 0, 1280, 1024)); | 68 | QCOMPARE(screens()->geometry(1), QRect(1280, 0, 1280, 1024)); | ||
91 | setenv("QT_QPA_PLATFORM", "wayland", true); | 69 | setenv("QT_QPA_PLATFORM", "wayland", true); | ||
92 | waylandServer()->initWorkspace(); | 70 | waylandServer()->initWorkspace(); | ||
93 | } | 71 | } | ||
94 | 72 | | |||
95 | void DontCrashEmptyDecorationTest::init() | 73 | void DontCrashEmptyDecorationTest::init() | ||
96 | { | 74 | { | ||
97 | using namespace KWayland::Client; | | |||
98 | // setup connection | | |||
99 | m_connection = new ConnectionThread; | | |||
100 | QSignalSpy connectedSpy(m_connection, &ConnectionThread::connected); | | |||
101 | QVERIFY(connectedSpy.isValid()); | | |||
102 | m_connection->setSocketName(s_socketName); | | |||
103 | | ||||
104 | m_thread = new QThread(this); | | |||
105 | m_connection->moveToThread(m_thread); | | |||
106 | m_thread->start(); | | |||
107 | | ||||
108 | m_connection->initConnection(); | | |||
109 | QVERIFY(connectedSpy.wait()); | | |||
110 | | ||||
111 | m_queue = new EventQueue(this); | | |||
112 | QVERIFY(!m_queue->isValid()); | | |||
113 | m_queue->setup(m_connection); | | |||
114 | QVERIFY(m_queue->isValid()); | | |||
115 | | ||||
116 | Registry registry; | | |||
117 | registry.setEventQueue(m_queue); | | |||
118 | QSignalSpy compositorSpy(®istry, &Registry::compositorAnnounced); | | |||
119 | QSignalSpy shmSpy(®istry, &Registry::shmAnnounced); | | |||
120 | QSignalSpy shellSpy(®istry, &Registry::shellAnnounced); | | |||
121 | QSignalSpy seatSpy(®istry, &Registry::seatAnnounced); | | |||
122 | QSignalSpy decorationSpy(®istry, &Registry::serverSideDecorationManagerAnnounced); | | |||
123 | QSignalSpy allAnnounced(®istry, &Registry::interfacesAnnounced); | | |||
124 | QVERIFY(allAnnounced.isValid()); | | |||
125 | QVERIFY(shmSpy.isValid()); | | |||
126 | QVERIFY(shellSpy.isValid()); | | |||
127 | QVERIFY(compositorSpy.isValid()); | | |||
128 | QVERIFY(seatSpy.isValid()); | | |||
129 | QVERIFY(decorationSpy.isValid()); | | |||
130 | registry.create(m_connection->display()); | | |||
131 | QVERIFY(registry.isValid()); | | |||
132 | registry.setup(); | | |||
133 | QVERIFY(allAnnounced.wait()); | | |||
134 | QVERIFY(!compositorSpy.isEmpty()); | | |||
135 | QVERIFY(!shmSpy.isEmpty()); | | |||
136 | QVERIFY(!shellSpy.isEmpty()); | | |||
137 | QVERIFY(!seatSpy.isEmpty()); | | |||
138 | QVERIFY(!decorationSpy.isEmpty()); | | |||
139 | | ||||
140 | m_compositor = registry.createCompositor(compositorSpy.first().first().value<quint32>(), compositorSpy.first().last().value<quint32>(), this); | | |||
141 | QVERIFY(m_compositor->isValid()); | | |||
142 | m_shm = registry.createShmPool(shmSpy.first().first().value<quint32>(), shmSpy.first().last().value<quint32>(), this); | | |||
143 | QVERIFY(m_shm->isValid()); | | |||
144 | m_shell = registry.createShell(shellSpy.first().first().value<quint32>(), shellSpy.first().last().value<quint32>(), this); | | |||
145 | QVERIFY(m_shell->isValid()); | | |||
146 | m_seat = registry.createSeat(seatSpy.first().first().value<quint32>(), seatSpy.first().last().value<quint32>(), this); | | |||
147 | QVERIFY(m_seat->isValid()); | | |||
148 | m_deco = registry.createServerSideDecorationManager(decorationSpy.first().first().value<quint32>(), decorationSpy.first().last().value<quint32>()); | | |||
149 | QVERIFY(m_deco->isValid()); | | |||
150 | QSignalSpy hasPointerSpy(m_seat, &Seat::hasPointerChanged); | | |||
151 | QVERIFY(hasPointerSpy.isValid()); | | |||
152 | QVERIFY(hasPointerSpy.wait()); | | |||
153 | | ||||
154 | screens()->setCurrent(0); | 75 | screens()->setCurrent(0); | ||
155 | Cursor::setPos(QPoint(640, 512)); | 76 | Cursor::setPos(QPoint(640, 512)); | ||
156 | } | 77 | } | ||
157 | 78 | | |||
158 | void DontCrashEmptyDecorationTest::cleanup() | | |||
159 | { | | |||
160 | delete m_compositor; | | |||
161 | m_compositor = nullptr; | | |||
162 | delete m_deco; | | |||
163 | m_deco = nullptr; | | |||
164 | delete m_seat; | | |||
165 | m_seat = nullptr; | | |||
166 | delete m_shm; | | |||
167 | m_shm = nullptr; | | |||
168 | delete m_shell; | | |||
169 | m_shell = nullptr; | | |||
170 | delete m_queue; | | |||
171 | m_queue = nullptr; | | |||
172 | if (m_thread) { | | |||
173 | m_connection->deleteLater(); | | |||
174 | m_thread->quit(); | | |||
175 | m_thread->wait(); | | |||
176 | delete m_thread; | | |||
177 | m_thread = nullptr; | | |||
178 | m_connection = nullptr; | | |||
179 | } | | |||
180 | } | | |||
181 | | ||||
182 | void DontCrashEmptyDecorationTest::testBug361551() | 79 | void DontCrashEmptyDecorationTest::testBug361551() | ||
183 | { | 80 | { | ||
184 | // this test verifies that resizing an X11 window to an invalid size does not result in crash on unmap | 81 | // this test verifies that resizing an X11 window to an invalid size does not result in crash on unmap | ||
185 | // when the DecorationRenderer gets copied to the Deleted | 82 | // when the DecorationRenderer gets copied to the Deleted | ||
186 | // there a repaint is scheduled and the resulting texture is invalid if the window size is invalid | 83 | // there a repaint is scheduled and the resulting texture is invalid if the window size is invalid | ||
187 | 84 | | |||
188 | // create an xcb window | 85 | // create an xcb window | ||
189 | xcb_connection_t *c = xcb_connect(nullptr, nullptr); | 86 | xcb_connection_t *c = xcb_connect(nullptr, nullptr); | ||
Show All 35 Lines |