File indexing completed on 2024-05-05 17:35:46

0001 /*
0002     KWin - the KDE window manager
0003     This file is part of the KDE project.
0004 
0005     SPDX-FileCopyrightText: 2017 Martin Flöser <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 "cursor.h"
0014 #include "keyboard_input.h"
0015 #include "pointer_input.h"
0016 #include "useractions.h"
0017 #include "wayland_server.h"
0018 #include "window.h"
0019 #include "workspace.h"
0020 
0021 #include <KWayland/Client/compositor.h>
0022 #include <KWayland/Client/keyboard.h>
0023 #include <KWayland/Client/pointer.h>
0024 #include <KWayland/Client/seat.h>
0025 #include <KWayland/Client/shm_pool.h>
0026 #include <KWayland/Client/surface.h>
0027 #include <KWayland/Client/touch.h>
0028 
0029 #include <linux/input.h>
0030 
0031 using namespace KWin;
0032 
0033 static const QString s_socketName = QStringLiteral("wayland_test_kwin_dont_crash_useractions_menu-0");
0034 
0035 class TestDontCrashUseractionsMenu : public QObject
0036 {
0037     Q_OBJECT
0038 private Q_SLOTS:
0039     void initTestCase();
0040     void init();
0041     void cleanup();
0042 
0043     void testShowHideShowUseractionsMenu();
0044 };
0045 
0046 void TestDontCrashUseractionsMenu::initTestCase()
0047 {
0048     qRegisterMetaType<KWin::Window *>();
0049     QSignalSpy applicationStartedSpy(kwinApp(), &Application::started);
0050     QVERIFY(waylandServer()->init(s_socketName));
0051     QMetaObject::invokeMethod(kwinApp()->outputBackend(), "setVirtualOutputs", Qt::DirectConnection, Q_ARG(QVector<QRect>, QVector<QRect>() << QRect(0, 0, 1280, 1024) << QRect(1280, 0, 1280, 1024)));
0052 
0053     // force style to breeze as that's the one which triggered the crash
0054     QVERIFY(kwinApp()->setStyle(QStringLiteral("breeze")));
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 }
0063 
0064 void TestDontCrashUseractionsMenu::init()
0065 {
0066     QVERIFY(Test::setupWaylandConnection());
0067 
0068     workspace()->setActiveOutput(QPoint(640, 512));
0069     KWin::Cursors::self()->mouse()->setPos(QPoint(640, 512));
0070 }
0071 
0072 void TestDontCrashUseractionsMenu::cleanup()
0073 {
0074     Test::destroyWaylandConnection();
0075 }
0076 
0077 void TestDontCrashUseractionsMenu::testShowHideShowUseractionsMenu()
0078 {
0079     // this test creates the condition of BUG 382063
0080     std::unique_ptr<KWayland::Client::Surface> surface1(Test::createSurface());
0081     std::unique_ptr<Test::XdgToplevel> shellSurface1(Test::createXdgToplevelSurface(surface1.get()));
0082     auto window = Test::renderAndWaitForShown(surface1.get(), QSize(100, 50), Qt::blue);
0083     QVERIFY(window);
0084 
0085     workspace()->showWindowMenu(QRect(), window);
0086     auto userActionsMenu = workspace()->userActionsMenu();
0087     QTRY_VERIFY(userActionsMenu->isShown());
0088     QVERIFY(userActionsMenu->hasWindow());
0089 
0090     Test::keyboardKeyPressed(KEY_ESC, 0);
0091     Test::keyboardKeyReleased(KEY_ESC, 1);
0092     QTRY_VERIFY(!userActionsMenu->isShown());
0093     QVERIFY(!userActionsMenu->hasWindow());
0094 
0095     // and show again, this triggers BUG 382063
0096     workspace()->showWindowMenu(QRect(), window);
0097     QTRY_VERIFY(userActionsMenu->isShown());
0098     QVERIFY(userActionsMenu->hasWindow());
0099 }
0100 
0101 WAYLANDTEST_MAIN(TestDontCrashUseractionsMenu)
0102 #include "dont_crash_useractions_menu.moc"