File indexing completed on 2024-05-12 05:30:32

0001 /*
0002     KWin - the KDE window manager
0003     This file is part of the KDE project.
0004 
0005     SPDX-FileCopyrightText: 2015 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 "wayland_server.h"
0012 #include "window.h"
0013 #include "workspace.h"
0014 #include "x11window.h"
0015 
0016 #include <KDecoration2/Decoration>
0017 
0018 #include <QSignalSpy>
0019 
0020 namespace KWin
0021 {
0022 
0023 static const QString s_socketName = QStringLiteral("wayland_test_kwin_dont_crash_glxgears-0");
0024 
0025 class DontCrashGlxgearsTest : public QObject
0026 {
0027     Q_OBJECT
0028 private Q_SLOTS:
0029     void initTestCase();
0030     void testGlxgears();
0031 };
0032 
0033 void DontCrashGlxgearsTest::initTestCase()
0034 {
0035     qRegisterMetaType<KWin::Window *>();
0036     QSignalSpy applicationStartedSpy(kwinApp(), &Application::started);
0037     QVERIFY(waylandServer()->init(s_socketName));
0038     Test::setOutputConfig({
0039         QRect(0, 0, 1280, 1024),
0040         QRect(1280, 0, 1280, 1024),
0041     });
0042     kwinApp()->start();
0043     QVERIFY(applicationStartedSpy.wait());
0044 }
0045 
0046 void DontCrashGlxgearsTest::testGlxgears()
0047 {
0048     // closing a glxgears window through Aurorae themes used to crash KWin
0049     // Let's make sure that doesn't happen anymore
0050 
0051     QSignalSpy windowAddedSpy(workspace(), &Workspace::windowAdded);
0052 
0053     QProcess glxgears;
0054     glxgears.setProgram(QStringLiteral("glxgears"));
0055     glxgears.start();
0056     QVERIFY(glxgears.waitForStarted());
0057 
0058     QVERIFY(windowAddedSpy.wait());
0059     QCOMPARE(windowAddedSpy.count(), 1);
0060     QCOMPARE(workspace()->windows().count(), 1);
0061     Window *glxgearsWindow = workspace()->windows().first();
0062     QVERIFY(glxgearsWindow->isDecorated());
0063     QSignalSpy closedSpy(glxgearsWindow, &X11Window::closed);
0064     KDecoration2::Decoration *decoration = glxgearsWindow->decoration();
0065     QVERIFY(decoration);
0066 
0067     // send a mouse event to the position of the close button
0068     // TODO: position is dependent on the decoration in use. We should use a static target instead, a fake deco for autotests.
0069     QPointF pos = decoration->rect().topRight() + QPointF(-decoration->borderTop() / 2, decoration->borderTop() / 2);
0070     QHoverEvent event(QEvent::HoverMove, pos, pos);
0071     QCoreApplication::instance()->sendEvent(decoration, &event);
0072     // mouse press
0073     QMouseEvent mousePressevent(QEvent::MouseButtonPress, pos, pos, Qt::LeftButton, Qt::LeftButton, Qt::NoModifier);
0074     mousePressevent.setAccepted(false);
0075     QCoreApplication::sendEvent(decoration, &mousePressevent);
0076     QVERIFY(mousePressevent.isAccepted());
0077     // mouse Release
0078     QMouseEvent mouseReleaseEvent(QEvent::MouseButtonRelease, pos, pos, Qt::LeftButton, Qt::LeftButton, Qt::NoModifier);
0079     mouseReleaseEvent.setAccepted(false);
0080     QCoreApplication::sendEvent(decoration, &mouseReleaseEvent);
0081     QVERIFY(mouseReleaseEvent.isAccepted());
0082 
0083     QVERIFY(closedSpy.wait());
0084     QCOMPARE(closedSpy.count(), 1);
0085     xcb_flush(connection());
0086 
0087     if (glxgears.state() == QProcess::Running) {
0088         QVERIFY(glxgears.waitForFinished());
0089     }
0090 }
0091 
0092 }
0093 
0094 WAYLANDTEST_MAIN(KWin::DontCrashGlxgearsTest)
0095 #include "dont_crash_glxgears.moc"