Warning, file /plasma/kwin/autotests/integration/debug_console_test.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: 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"