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