diff --git a/autotests/wayland/CMakeLists.txt b/autotests/wayland/CMakeLists.txt index a7343e58aa..604acc1cec 100644 --- a/autotests/wayland/CMakeLists.txt +++ b/autotests/wayland/CMakeLists.txt @@ -26,3 +26,12 @@ add_executable(testQuickTiling ${testQuickTiling_SRCS}) target_link_libraries( testQuickTiling kwin Qt5::Test) add_test(kwin-testQuickTiling testQuickTiling) ecm_mark_as_test(testQuickTiling) + +######################################################## +# Don't Crash For glxgears +######################################################## +set( testDontCrashGlxgears_SRCS dont_crash_glxgears.cpp kwin_wayland_test.cpp ) +add_executable(testDontCrashGlxgears ${testDontCrashGlxgears_SRCS}) +target_link_libraries( testDontCrashGlxgears kwin Qt5::Test) +add_test(kwin-testDontCrashGlxgears testDontCrashGlxgears) +ecm_mark_as_test(testDontCrashGlxgears) diff --git a/autotests/wayland/dont_crash_glxgears.cpp b/autotests/wayland/dont_crash_glxgears.cpp new file mode 100644 index 0000000000..e3c0e2b48f --- /dev/null +++ b/autotests/wayland/dont_crash_glxgears.cpp @@ -0,0 +1,104 @@ +/******************************************************************** +KWin - the KDE window manager +This file is part of the KDE project. + +Copyright (C) 2015 Martin Gräßlin + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*********************************************************************/ +#include "kwin_wayland_test.h" +#include "abstract_backend.h" +#include "abstract_client.h" +#include "client.h" +#include "deleted.h" +#include "screens.h" +#include "wayland_server.h" +#include "workspace.h" + +#include + +namespace KWin +{ + +static const QString s_socketName = QStringLiteral("wayland_test_kwin_dont_crash_glxgears-0"); + +class DontCrashGlxgearsTest : public QObject +{ + Q_OBJECT +private Q_SLOTS: + void initTestCase(); + void testGlxgears(); +}; + +void DontCrashGlxgearsTest::initTestCase() +{ + qRegisterMetaType(); + QSignalSpy workspaceCreatedSpy(kwinApp(), &Application::workspaceCreated); + QVERIFY(workspaceCreatedSpy.isValid()); + waylandServer()->backend()->setInitialWindowSize(QSize(1280, 1024)); + waylandServer()->init(s_socketName.toLocal8Bit()); + kwinApp()->start(); + QVERIFY(workspaceCreatedSpy.wait()); +} + +void DontCrashGlxgearsTest::testGlxgears() +{ + // closing a glxgears window through Aurorae themes used to crash KWin + // Let's make sure that doesn't happen anymore + + QSignalSpy clientAddedSpy(workspace(), &Workspace::clientAdded); + QVERIFY(clientAddedSpy.isValid()); + + QProcess glxgears; + glxgears.start(QStringLiteral("glxgears")); + QVERIFY(glxgears.waitForStarted()); + + QVERIFY(clientAddedSpy.wait()); + QCOMPARE(clientAddedSpy.count(), 1); + QCOMPARE(workspace()->clientList().count(), 1); + Client *glxgearsClient = workspace()->clientList().first(); + QVERIFY(glxgearsClient->isDecorated()); + QSignalSpy closedSpy(glxgearsClient, &Client::windowClosed); + QVERIFY(closedSpy.isValid()); + KDecoration2::Decoration *decoration = glxgearsClient->decoration(); + QVERIFY(decoration); + + // send a mouse event to the position of the close button + QPointF pos = decoration->rect().topRight() + QPointF(-decoration->borderRight() * 2, decoration->borderRight() * 2); + QHoverEvent event(QEvent::HoverMove, pos, pos); + QCoreApplication::instance()->sendEvent(decoration, &event); + // mouse press + QMouseEvent mousePressevent(QEvent::MouseButtonPress, pos, pos, Qt::LeftButton, Qt::LeftButton, Qt::NoModifier); + mousePressevent.setAccepted(false); + QCoreApplication::sendEvent(decoration, &mousePressevent); + QVERIFY(mousePressevent.isAccepted()); + // mouse Release + QMouseEvent mouseReleaseEvent(QEvent::MouseButtonRelease, pos, pos, Qt::LeftButton, Qt::LeftButton, Qt::NoModifier); + mouseReleaseEvent.setAccepted(false); + QCoreApplication::sendEvent(decoration, &mouseReleaseEvent); + QVERIFY(mouseReleaseEvent.isAccepted()); + + QVERIFY(closedSpy.wait()); + QCOMPARE(closedSpy.count(), 1); + xcb_flush(connection()); + + if (glxgears.state() == QProcess::Running) { + QVERIFY(glxgears.waitForFinished()); + } +} + +} + +WAYLANTEST_MAIN(KWin::DontCrashGlxgearsTest) +#include "dont_crash_glxgears.moc"