File indexing completed on 2024-11-10 04:55:57
0001 /* 0002 KWin - the KDE window manager 0003 This file is part of the KDE project. 0004 0005 SPDX-FileCopyrightText: 2016 Martin Gräßlin <mgraesslin@kde.org> 0006 0007 SPDX-License-Identifier: GPL-2.0-or-later 0008 */ 0009 #include "kwin_wayland_test.h" 0010 0011 #include "core/output.h" 0012 #include "debug_console.h" 0013 #include "internalwindow.h" 0014 #include "utils/xcbutils.h" 0015 #include "wayland_server.h" 0016 #include "window.h" 0017 #include "workspace.h" 0018 0019 #include <KWayland/Client/compositor.h> 0020 #include <KWayland/Client/connection_thread.h> 0021 #include <KWayland/Client/shm_pool.h> 0022 #include <KWayland/Client/surface.h> 0023 0024 #include <QPainter> 0025 #include <QRasterWindow> 0026 #include <QSignalSpy> 0027 0028 namespace KWin 0029 { 0030 0031 static const QString s_socketName = QStringLiteral("wayland_test_kwin_debug_console-0"); 0032 0033 class DebugConsoleTest : public QObject 0034 { 0035 Q_OBJECT 0036 private Q_SLOTS: 0037 void initTestCase(); 0038 void cleanup(); 0039 void topLevelTest_data(); 0040 void topLevelTest(); 0041 void testX11Window(); 0042 void testX11Unmanaged(); 0043 void testWaylandClient(); 0044 void testInternalWindow(); 0045 void testClosingDebugConsole(); 0046 }; 0047 0048 void DebugConsoleTest::initTestCase() 0049 { 0050 qRegisterMetaType<KWin::Window *>(); 0051 qRegisterMetaType<KWin::InternalWindow *>(); 0052 QSignalSpy applicationStartedSpy(kwinApp(), &Application::started); 0053 QVERIFY(waylandServer()->init(s_socketName)); 0054 Test::setOutputConfig({ 0055 QRect(0, 0, 1280, 1024), 0056 QRect(1280, 0, 1280, 1024), 0057 }); 0058 0059 kwinApp()->start(); 0060 QVERIFY(applicationStartedSpy.wait()); 0061 const auto outputs = workspace()->outputs(); 0062 QCOMPARE(outputs.count(), 2); 0063 QCOMPARE(outputs[0]->geometry(), QRect(0, 0, 1280, 1024)); 0064 QCOMPARE(outputs[1]->geometry(), QRect(1280, 0, 1280, 1024)); 0065 setenv("QT_QPA_PLATFORM", "wayland", true); 0066 } 0067 0068 void DebugConsoleTest::cleanup() 0069 { 0070 Test::destroyWaylandConnection(); 0071 } 0072 0073 void DebugConsoleTest::topLevelTest_data() 0074 { 0075 QTest::addColumn<int>("row"); 0076 QTest::addColumn<int>("column"); 0077 QTest::addColumn<bool>("expectedValid"); 0078 0079 // this tests various combinations of row/column on the top level whether they are valid 0080 // valid are rows 0-4 with column 0, everything else is invalid 0081 QTest::newRow("0/0") << 0 << 0 << true; 0082 QTest::newRow("0/1") << 0 << 1 << false; 0083 QTest::newRow("0/3") << 0 << 3 << false; 0084 QTest::newRow("1/0") << 1 << 0 << true; 0085 QTest::newRow("1/1") << 1 << 1 << false; 0086 QTest::newRow("1/3") << 1 << 3 << false; 0087 QTest::newRow("2/0") << 2 << 0 << true; 0088 QTest::newRow("3/0") << 3 << 0 << true; 0089 QTest::newRow("4/0") << 4 << 0 << false; 0090 QTest::newRow("100/0") << 4 << 0 << false; 0091 } 0092 0093 void DebugConsoleTest::topLevelTest() 0094 { 0095 DebugConsoleModel model; 0096 QCOMPARE(model.rowCount(QModelIndex()), 4); 0097 QCOMPARE(model.columnCount(QModelIndex()), 2); 0098 QFETCH(int, row); 0099 QFETCH(int, column); 0100 const QModelIndex index = model.index(row, column, QModelIndex()); 0101 QTEST(index.isValid(), "expectedValid"); 0102 if (index.isValid()) { 0103 QVERIFY(!model.parent(index).isValid()); 0104 QVERIFY(model.data(index, Qt::DisplayRole).isValid()); 0105 QCOMPARE(model.data(index, Qt::DisplayRole).userType(), int(QMetaType::QString)); 0106 for (int i = Qt::DecorationRole; i <= Qt::UserRole; i++) { 0107 QVERIFY(!model.data(index, i).isValid()); 0108 } 0109 } 0110 } 0111 0112 void DebugConsoleTest::testX11Window() 0113 { 0114 DebugConsoleModel model; 0115 QModelIndex x11TopLevelIndex = model.index(0, 0, QModelIndex()); 0116 QVERIFY(x11TopLevelIndex.isValid()); 0117 // we don't have any windows yet 0118 QCOMPARE(model.rowCount(x11TopLevelIndex), 0); 0119 QVERIFY(!model.hasChildren(x11TopLevelIndex)); 0120 // child index must be invalid 0121 QVERIFY(!model.index(0, 0, x11TopLevelIndex).isValid()); 0122 QVERIFY(!model.index(0, 1, x11TopLevelIndex).isValid()); 0123 QVERIFY(!model.index(0, 2, x11TopLevelIndex).isValid()); 0124 QVERIFY(!model.index(1, 0, x11TopLevelIndex).isValid()); 0125 0126 // start glxgears, to get a window, which should be added to the model 0127 QSignalSpy rowsInsertedSpy(&model, &QAbstractItemModel::rowsInserted); 0128 0129 QProcess glxgears; 0130 glxgears.setProgram(QStringLiteral("glxgears")); 0131 glxgears.start(); 0132 QVERIFY(glxgears.waitForStarted()); 0133 0134 QVERIFY(rowsInsertedSpy.wait()); 0135 QCOMPARE(rowsInsertedSpy.count(), 1); 0136 QVERIFY(model.hasChildren(x11TopLevelIndex)); 0137 QCOMPARE(model.rowCount(x11TopLevelIndex), 1); 0138 QCOMPARE(rowsInsertedSpy.first().at(0).value<QModelIndex>(), x11TopLevelIndex); 0139 QCOMPARE(rowsInsertedSpy.first().at(1).value<int>(), 0); 0140 QCOMPARE(rowsInsertedSpy.first().at(2).value<int>(), 0); 0141 0142 QModelIndex windowIndex = model.index(0, 0, x11TopLevelIndex); 0143 QVERIFY(windowIndex.isValid()); 0144 QCOMPARE(model.parent(windowIndex), x11TopLevelIndex); 0145 QVERIFY(model.hasChildren(windowIndex)); 0146 QVERIFY(model.rowCount(windowIndex) != 0); 0147 QCOMPARE(model.columnCount(windowIndex), 2); 0148 // other indexes are still invalid 0149 QVERIFY(!model.index(0, 1, x11TopLevelIndex).isValid()); 0150 QVERIFY(!model.index(0, 2, x11TopLevelIndex).isValid()); 0151 QVERIFY(!model.index(1, 0, x11TopLevelIndex).isValid()); 0152 0153 // the windowIndex has children and those are properties 0154 for (int i = 0; i < model.rowCount(windowIndex); i++) { 0155 const QModelIndex propNameIndex = model.index(i, 0, windowIndex); 0156 QVERIFY(propNameIndex.isValid()); 0157 QCOMPARE(model.parent(propNameIndex), windowIndex); 0158 QVERIFY(!model.hasChildren(propNameIndex)); 0159 QVERIFY(!model.index(0, 0, propNameIndex).isValid()); 0160 QVERIFY(model.data(propNameIndex, Qt::DisplayRole).isValid()); 0161 QCOMPARE(model.data(propNameIndex, Qt::DisplayRole).userType(), int(QMetaType::QString)); 0162 0163 // and the value 0164 const QModelIndex propValueIndex = model.index(i, 1, windowIndex); 0165 QVERIFY(propValueIndex.isValid()); 0166 QCOMPARE(model.parent(propValueIndex), windowIndex); 0167 QVERIFY(!model.index(0, 0, propValueIndex).isValid()); 0168 QVERIFY(!model.hasChildren(propValueIndex)); 0169 // TODO: how to test whether the values actually work? 0170 0171 // and on third column we should not get an index any more 0172 QVERIFY(!model.index(i, 2, windowIndex).isValid()); 0173 } 0174 // row after count should be invalid 0175 QVERIFY(!model.index(model.rowCount(windowIndex), 0, windowIndex).isValid()); 0176 0177 // creating a second model should be initialized directly with the X11 child 0178 DebugConsoleModel model2; 0179 QVERIFY(model2.hasChildren(model2.index(0, 0, QModelIndex()))); 0180 0181 // now close the window again, it should be removed from the model 0182 QSignalSpy rowsRemovedSpy(&model, &QAbstractItemModel::rowsRemoved); 0183 0184 glxgears.terminate(); 0185 QVERIFY(glxgears.waitForFinished()); 0186 0187 QVERIFY(rowsRemovedSpy.wait()); 0188 QCOMPARE(rowsRemovedSpy.count(), 1); 0189 QCOMPARE(rowsRemovedSpy.first().first().value<QModelIndex>(), x11TopLevelIndex); 0190 QCOMPARE(rowsRemovedSpy.first().at(1).value<int>(), 0); 0191 QCOMPARE(rowsRemovedSpy.first().at(2).value<int>(), 0); 0192 0193 // the child should be gone again 0194 QVERIFY(!model.hasChildren(x11TopLevelIndex)); 0195 QVERIFY(!model2.hasChildren(model2.index(0, 0, QModelIndex()))); 0196 } 0197 0198 void DebugConsoleTest::testX11Unmanaged() 0199 { 0200 DebugConsoleModel model; 0201 QModelIndex unmanagedTopLevelIndex = model.index(1, 0, QModelIndex()); 0202 QVERIFY(unmanagedTopLevelIndex.isValid()); 0203 // we don't have any windows yet 0204 QCOMPARE(model.rowCount(unmanagedTopLevelIndex), 0); 0205 QVERIFY(!model.hasChildren(unmanagedTopLevelIndex)); 0206 // child index must be invalid 0207 QVERIFY(!model.index(0, 0, unmanagedTopLevelIndex).isValid()); 0208 QVERIFY(!model.index(0, 1, unmanagedTopLevelIndex).isValid()); 0209 QVERIFY(!model.index(0, 2, unmanagedTopLevelIndex).isValid()); 0210 QVERIFY(!model.index(1, 0, unmanagedTopLevelIndex).isValid()); 0211 0212 // we need to create an unmanaged window 0213 QSignalSpy rowsInsertedSpy(&model, &QAbstractItemModel::rowsInserted); 0214 0215 // let's create an override redirect window 0216 const uint32_t values[] = {true}; 0217 Xcb::Window window(QRect(0, 0, 10, 10), XCB_CW_OVERRIDE_REDIRECT, values); 0218 window.map(); 0219 0220 QVERIFY(rowsInsertedSpy.wait()); 0221 QCOMPARE(rowsInsertedSpy.count(), 1); 0222 QVERIFY(model.hasChildren(unmanagedTopLevelIndex)); 0223 QCOMPARE(model.rowCount(unmanagedTopLevelIndex), 1); 0224 QCOMPARE(rowsInsertedSpy.first().at(0).value<QModelIndex>(), unmanagedTopLevelIndex); 0225 QCOMPARE(rowsInsertedSpy.first().at(1).value<int>(), 0); 0226 QCOMPARE(rowsInsertedSpy.first().at(2).value<int>(), 0); 0227 0228 QModelIndex windowIndex = model.index(0, 0, unmanagedTopLevelIndex); 0229 QVERIFY(windowIndex.isValid()); 0230 QCOMPARE(model.parent(windowIndex), unmanagedTopLevelIndex); 0231 QVERIFY(model.hasChildren(windowIndex)); 0232 QVERIFY(model.rowCount(windowIndex) != 0); 0233 QCOMPARE(model.columnCount(windowIndex), 2); 0234 // other indexes are still invalid 0235 QVERIFY(!model.index(0, 1, unmanagedTopLevelIndex).isValid()); 0236 QVERIFY(!model.index(0, 2, unmanagedTopLevelIndex).isValid()); 0237 QVERIFY(!model.index(1, 0, unmanagedTopLevelIndex).isValid()); 0238 0239 QCOMPARE(model.data(windowIndex, Qt::DisplayRole).toString(), QStringLiteral("0x%1").arg(window, 0, 16)); 0240 0241 // the windowIndex has children and those are properties 0242 for (int i = 0; i < model.rowCount(windowIndex); i++) { 0243 const QModelIndex propNameIndex = model.index(i, 0, windowIndex); 0244 QVERIFY(propNameIndex.isValid()); 0245 QCOMPARE(model.parent(propNameIndex), windowIndex); 0246 QVERIFY(!model.hasChildren(propNameIndex)); 0247 QVERIFY(!model.index(0, 0, propNameIndex).isValid()); 0248 QVERIFY(model.data(propNameIndex, Qt::DisplayRole).isValid()); 0249 QCOMPARE(model.data(propNameIndex, Qt::DisplayRole).userType(), int(QMetaType::QString)); 0250 0251 // and the value 0252 const QModelIndex propValueIndex = model.index(i, 1, windowIndex); 0253 QVERIFY(propValueIndex.isValid()); 0254 QCOMPARE(model.parent(propValueIndex), windowIndex); 0255 QVERIFY(!model.index(0, 0, propValueIndex).isValid()); 0256 QVERIFY(!model.hasChildren(propValueIndex)); 0257 // TODO: how to test whether the values actually work? 0258 0259 // and on third column we should not get an index any more 0260 QVERIFY(!model.index(i, 2, windowIndex).isValid()); 0261 } 0262 // row after count should be invalid 0263 QVERIFY(!model.index(model.rowCount(windowIndex), 0, windowIndex).isValid()); 0264 0265 // creating a second model should be initialized directly with the X11 child 0266 DebugConsoleModel model2; 0267 QVERIFY(model2.hasChildren(model2.index(1, 0, QModelIndex()))); 0268 0269 // now close the window again, it should be removed from the model 0270 QSignalSpy rowsRemovedSpy(&model, &QAbstractItemModel::rowsRemoved); 0271 0272 window.unmap(); 0273 0274 QVERIFY(rowsRemovedSpy.wait()); 0275 QCOMPARE(rowsRemovedSpy.count(), 1); 0276 QCOMPARE(rowsRemovedSpy.first().first().value<QModelIndex>(), unmanagedTopLevelIndex); 0277 QCOMPARE(rowsRemovedSpy.first().at(1).value<int>(), 0); 0278 QCOMPARE(rowsRemovedSpy.first().at(2).value<int>(), 0); 0279 0280 // the child should be gone again 0281 QVERIFY(!model.hasChildren(unmanagedTopLevelIndex)); 0282 QVERIFY(!model2.hasChildren(model2.index(1, 0, QModelIndex()))); 0283 } 0284 0285 void DebugConsoleTest::testWaylandClient() 0286 { 0287 DebugConsoleModel model; 0288 QModelIndex waylandTopLevelIndex = model.index(2, 0, QModelIndex()); 0289 QVERIFY(waylandTopLevelIndex.isValid()); 0290 0291 // we don't have any windows yet 0292 QCOMPARE(model.rowCount(waylandTopLevelIndex), 0); 0293 QVERIFY(!model.hasChildren(waylandTopLevelIndex)); 0294 // child index must be invalid 0295 QVERIFY(!model.index(0, 0, waylandTopLevelIndex).isValid()); 0296 QVERIFY(!model.index(0, 1, waylandTopLevelIndex).isValid()); 0297 QVERIFY(!model.index(0, 2, waylandTopLevelIndex).isValid()); 0298 QVERIFY(!model.index(1, 0, waylandTopLevelIndex).isValid()); 0299 0300 // we need to create a wayland window 0301 QSignalSpy rowsInsertedSpy(&model, &QAbstractItemModel::rowsInserted); 0302 0303 // create our connection 0304 QVERIFY(Test::setupWaylandConnection()); 0305 0306 // create the Surface and ShellSurface 0307 std::unique_ptr<KWayland::Client::Surface> surface(Test::createSurface()); 0308 QVERIFY(surface->isValid()); 0309 std::unique_ptr<Test::XdgToplevel> shellSurface(Test::createXdgToplevelSurface(surface.get())); 0310 QVERIFY(shellSurface != nullptr); 0311 Test::render(surface.get(), QSize(10, 10), Qt::red); 0312 0313 // now we have the window, it should be added to our model 0314 QVERIFY(rowsInsertedSpy.wait()); 0315 QCOMPARE(rowsInsertedSpy.count(), 1); 0316 0317 QVERIFY(model.hasChildren(waylandTopLevelIndex)); 0318 QCOMPARE(model.rowCount(waylandTopLevelIndex), 1); 0319 QCOMPARE(rowsInsertedSpy.first().at(0).value<QModelIndex>(), waylandTopLevelIndex); 0320 QCOMPARE(rowsInsertedSpy.first().at(1).value<int>(), 0); 0321 QCOMPARE(rowsInsertedSpy.first().at(2).value<int>(), 0); 0322 0323 QModelIndex windowIndex = model.index(0, 0, waylandTopLevelIndex); 0324 QVERIFY(windowIndex.isValid()); 0325 QCOMPARE(model.parent(windowIndex), waylandTopLevelIndex); 0326 QVERIFY(model.hasChildren(windowIndex)); 0327 QVERIFY(model.rowCount(windowIndex) != 0); 0328 QCOMPARE(model.columnCount(windowIndex), 2); 0329 // other indexes are still invalid 0330 QVERIFY(!model.index(0, 1, waylandTopLevelIndex).isValid()); 0331 QVERIFY(!model.index(0, 2, waylandTopLevelIndex).isValid()); 0332 QVERIFY(!model.index(1, 0, waylandTopLevelIndex).isValid()); 0333 0334 // the windowIndex has children and those are properties 0335 for (int i = 0; i < model.rowCount(windowIndex); i++) { 0336 const QModelIndex propNameIndex = model.index(i, 0, windowIndex); 0337 QVERIFY(propNameIndex.isValid()); 0338 QCOMPARE(model.parent(propNameIndex), windowIndex); 0339 QVERIFY(!model.hasChildren(propNameIndex)); 0340 QVERIFY(!model.index(0, 0, propNameIndex).isValid()); 0341 QVERIFY(model.data(propNameIndex, Qt::DisplayRole).isValid()); 0342 QCOMPARE(model.data(propNameIndex, Qt::DisplayRole).userType(), int(QMetaType::QString)); 0343 0344 // and the value 0345 const QModelIndex propValueIndex = model.index(i, 1, windowIndex); 0346 QVERIFY(propValueIndex.isValid()); 0347 QCOMPARE(model.parent(propValueIndex), windowIndex); 0348 QVERIFY(!model.index(0, 0, propValueIndex).isValid()); 0349 QVERIFY(!model.hasChildren(propValueIndex)); 0350 // TODO: how to test whether the values actually work? 0351 0352 // and on third column we should not get an index any more 0353 QVERIFY(!model.index(i, 2, windowIndex).isValid()); 0354 } 0355 // row after count should be invalid 0356 QVERIFY(!model.index(model.rowCount(windowIndex), 0, windowIndex).isValid()); 0357 0358 // creating a second model should be initialized directly with the X11 child 0359 DebugConsoleModel model2; 0360 QVERIFY(model2.hasChildren(model2.index(2, 0, QModelIndex()))); 0361 0362 // now close the window again, it should be removed from the model 0363 QSignalSpy rowsRemovedSpy(&model, &QAbstractItemModel::rowsRemoved); 0364 0365 surface->attachBuffer(KWayland::Client::Buffer::Ptr()); 0366 surface->commit(KWayland::Client::Surface::CommitFlag::None); 0367 QVERIFY(rowsRemovedSpy.wait()); 0368 0369 QCOMPARE(rowsRemovedSpy.count(), 1); 0370 QCOMPARE(rowsRemovedSpy.first().first().value<QModelIndex>(), waylandTopLevelIndex); 0371 QCOMPARE(rowsRemovedSpy.first().at(1).value<int>(), 0); 0372 QCOMPARE(rowsRemovedSpy.first().at(2).value<int>(), 0); 0373 0374 // the child should be gone again 0375 QVERIFY(!model.hasChildren(waylandTopLevelIndex)); 0376 QVERIFY(!model2.hasChildren(model2.index(2, 0, QModelIndex()))); 0377 } 0378 0379 class HelperWindow : public QRasterWindow 0380 { 0381 Q_OBJECT 0382 public: 0383 HelperWindow() 0384 : QRasterWindow(nullptr) 0385 { 0386 } 0387 ~HelperWindow() override = default; 0388 0389 Q_SIGNALS: 0390 void entered(); 0391 void left(); 0392 void mouseMoved(const QPoint &global); 0393 void mousePressed(); 0394 void mouseReleased(); 0395 void wheel(); 0396 void keyPressed(); 0397 void keyReleased(); 0398 0399 protected: 0400 void paintEvent(QPaintEvent *event) override 0401 { 0402 QPainter p(this); 0403 p.fillRect(0, 0, width(), height(), Qt::red); 0404 } 0405 }; 0406 0407 void DebugConsoleTest::testInternalWindow() 0408 { 0409 DebugConsoleModel model; 0410 QModelIndex internalTopLevelIndex = model.index(3, 0, QModelIndex()); 0411 QVERIFY(internalTopLevelIndex.isValid()); 0412 0413 // there might already be some internal windows, so we cannot reliable test whether there are children 0414 // given that we just test whether adding a window works. 0415 0416 QSignalSpy rowsInsertedSpy(&model, &QAbstractItemModel::rowsInserted); 0417 0418 std::unique_ptr<HelperWindow> w(new HelperWindow); 0419 w->setGeometry(0, 0, 100, 100); 0420 w->show(); 0421 0422 QTRY_COMPARE(rowsInsertedSpy.count(), 1); 0423 QCOMPARE(rowsInsertedSpy.first().first().value<QModelIndex>(), internalTopLevelIndex); 0424 0425 QModelIndex windowIndex = model.index(rowsInsertedSpy.first().last().toInt(), 0, internalTopLevelIndex); 0426 QVERIFY(windowIndex.isValid()); 0427 QCOMPARE(model.parent(windowIndex), internalTopLevelIndex); 0428 QVERIFY(model.hasChildren(windowIndex)); 0429 QVERIFY(model.rowCount(windowIndex) != 0); 0430 QCOMPARE(model.columnCount(windowIndex), 2); 0431 // other indexes are still invalid 0432 QVERIFY(!model.index(rowsInsertedSpy.first().last().toInt(), 1, internalTopLevelIndex).isValid()); 0433 QVERIFY(!model.index(rowsInsertedSpy.first().last().toInt(), 2, internalTopLevelIndex).isValid()); 0434 QVERIFY(!model.index(rowsInsertedSpy.first().last().toInt() + 1, 0, internalTopLevelIndex).isValid()); 0435 0436 // the wayland shell client top level should not have gained this window 0437 QVERIFY(!model.hasChildren(model.index(2, 0, QModelIndex()))); 0438 0439 // the windowIndex has children and those are properties 0440 for (int i = 0; i < model.rowCount(windowIndex); i++) { 0441 const QModelIndex propNameIndex = model.index(i, 0, windowIndex); 0442 QVERIFY(propNameIndex.isValid()); 0443 QCOMPARE(model.parent(propNameIndex), windowIndex); 0444 QVERIFY(!model.hasChildren(propNameIndex)); 0445 QVERIFY(!model.index(0, 0, propNameIndex).isValid()); 0446 QVERIFY(model.data(propNameIndex, Qt::DisplayRole).isValid()); 0447 QCOMPARE(model.data(propNameIndex, Qt::DisplayRole).userType(), int(QMetaType::QString)); 0448 0449 // and the value 0450 const QModelIndex propValueIndex = model.index(i, 1, windowIndex); 0451 QVERIFY(propValueIndex.isValid()); 0452 QCOMPARE(model.parent(propValueIndex), windowIndex); 0453 QVERIFY(!model.index(0, 0, propValueIndex).isValid()); 0454 QVERIFY(!model.hasChildren(propValueIndex)); 0455 // TODO: how to test whether the values actually work? 0456 0457 // and on third column we should not get an index any more 0458 QVERIFY(!model.index(i, 2, windowIndex).isValid()); 0459 } 0460 // row after count should be invalid 0461 QVERIFY(!model.index(model.rowCount(windowIndex), 0, windowIndex).isValid()); 0462 0463 // now close the window again, it should be removed from the model 0464 QSignalSpy rowsRemovedSpy(&model, &QAbstractItemModel::rowsRemoved); 0465 0466 w->hide(); 0467 w.reset(); 0468 0469 QTRY_COMPARE(rowsRemovedSpy.count(), 1); 0470 QCOMPARE(rowsRemovedSpy.first().first().value<QModelIndex>(), internalTopLevelIndex); 0471 } 0472 0473 void DebugConsoleTest::testClosingDebugConsole() 0474 { 0475 // this test verifies that the DebugConsole gets destroyed when closing the window 0476 // BUG: 369858 0477 0478 DebugConsole *console = new DebugConsole; 0479 QSignalSpy destroyedSpy(console, &QObject::destroyed); 0480 0481 QSignalSpy windowAddedSpy(workspace(), &Workspace::windowAdded); 0482 console->show(); 0483 QCOMPARE(console->windowHandle()->isVisible(), true); 0484 QTRY_COMPARE(windowAddedSpy.count(), 1); 0485 InternalWindow *window = windowAddedSpy.first().first().value<InternalWindow *>(); 0486 QVERIFY(window->isInternal()); 0487 QCOMPARE(window->handle(), console->windowHandle()); 0488 QVERIFY(window->isDecorated()); 0489 QCOMPARE(window->isMinimizable(), false); 0490 window->closeWindow(); 0491 QVERIFY(destroyedSpy.wait()); 0492 } 0493 0494 } 0495 0496 WAYLANDTEST_MAIN(KWin::DebugConsoleTest) 0497 #include "debug_console_test.moc"