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

0001 
0002 /*
0003     KWin - the KDE window manager
0004     This file is part of the KDE project.
0005 
0006     SPDX-FileCopyrightText: 2016 Martin Gräßlin <mgraesslin@kde.org>
0007 
0008     SPDX-License-Identifier: GPL-2.0-or-later
0009 */
0010 #include "kwin_wayland_test.h"
0011 
0012 #include "composite.h"
0013 #include "core/output.h"
0014 #include "core/outputbackend.h"
0015 #include "core/renderbackend.h"
0016 #include "cursor.h"
0017 #include "wayland_server.h"
0018 #include "workspace.h"
0019 #include "x11window.h"
0020 #include <kwineffects.h>
0021 
0022 #include <KWayland/Client/surface.h>
0023 
0024 #include <KDecoration2/Decoration>
0025 
0026 #include <linux/input.h>
0027 
0028 namespace KWin
0029 {
0030 
0031 static const QString s_socketName = QStringLiteral("wayland_test_kwin_dont_crash_no_border-0");
0032 
0033 class DontCrashNoBorder : public QObject
0034 {
0035     Q_OBJECT
0036 private Q_SLOTS:
0037     void initTestCase();
0038     void init();
0039     void cleanup();
0040     void testCreateWindow();
0041 };
0042 
0043 void DontCrashNoBorder::initTestCase()
0044 {
0045     qRegisterMetaType<KWin::Window *>();
0046     QSignalSpy applicationStartedSpy(kwinApp(), &Application::started);
0047     QVERIFY(waylandServer()->init(s_socketName));
0048     QMetaObject::invokeMethod(kwinApp()->outputBackend(), "setVirtualOutputs", Qt::DirectConnection, Q_ARG(QVector<QRect>, QVector<QRect>() << QRect(0, 0, 1280, 1024) << QRect(1280, 0, 1280, 1024)));
0049 
0050     KSharedConfig::Ptr config = KSharedConfig::openConfig(QString(), KConfig::SimpleConfig);
0051     config->group("org.kde.kdecoration2").writeEntry("NoPlugin", true);
0052     config->sync();
0053     kwinApp()->setConfig(config);
0054 
0055     // this test needs to enforce OpenGL compositing to get into the crashy condition
0056     qputenv("KWIN_COMPOSE", QByteArrayLiteral("O2"));
0057     kwinApp()->start();
0058     QVERIFY(applicationStartedSpy.wait());
0059     const auto outputs = workspace()->outputs();
0060     QCOMPARE(outputs.count(), 2);
0061     QCOMPARE(outputs[0]->geometry(), QRect(0, 0, 1280, 1024));
0062     QCOMPARE(outputs[1]->geometry(), QRect(1280, 0, 1280, 1024));
0063     setenv("QT_QPA_PLATFORM", "wayland", true);
0064 
0065     QCOMPARE(Compositor::self()->backend()->compositingType(), KWin::OpenGLCompositing);
0066 }
0067 
0068 void DontCrashNoBorder::init()
0069 {
0070     QVERIFY(Test::setupWaylandConnection(Test::AdditionalWaylandInterface::XdgDecorationV1));
0071 
0072     workspace()->setActiveOutput(QPoint(640, 512));
0073     Cursors::self()->mouse()->setPos(QPoint(640, 512));
0074 }
0075 
0076 void DontCrashNoBorder::cleanup()
0077 {
0078     Test::destroyWaylandConnection();
0079 }
0080 
0081 void DontCrashNoBorder::testCreateWindow()
0082 {
0083     // create a window and ensure that this doesn't crash
0084     std::unique_ptr<KWayland::Client::Surface> surface(Test::createSurface());
0085     std::unique_ptr<Test::XdgToplevel> shellSurface(Test::createXdgToplevelSurface(surface.get(), Test::CreationSetup::CreateOnly));
0086     std::unique_ptr<Test::XdgToplevelDecorationV1> decoration(Test::createXdgToplevelDecorationV1(shellSurface.get()));
0087     QSignalSpy decorationConfigureRequestedSpy(decoration.get(), &Test::XdgToplevelDecorationV1::configureRequested);
0088     QSignalSpy surfaceConfigureRequestedSpy(shellSurface->xdgSurface(), &Test::XdgSurface::configureRequested);
0089 
0090     // Initialize the xdg-toplevel surface.
0091     decoration->set_mode(Test::XdgToplevelDecorationV1::mode_server_side);
0092     surface->commit(KWayland::Client::Surface::CommitFlag::None);
0093     QVERIFY(surfaceConfigureRequestedSpy.wait());
0094     QCOMPARE(decorationConfigureRequestedSpy.last().at(0).value<Test::XdgToplevelDecorationV1::mode>(), Test::XdgToplevelDecorationV1::mode_client_side);
0095 
0096     // let's render
0097     shellSurface->xdgSurface()->ack_configure(surfaceConfigureRequestedSpy.last().at(0).value<quint32>());
0098     auto window = Test::renderAndWaitForShown(surface.get(), QSize(500, 50), Qt::blue);
0099     QVERIFY(window);
0100     QCOMPARE(workspace()->activeWindow(), window);
0101     QVERIFY(!window->isDecorated());
0102 }
0103 
0104 }
0105 
0106 WAYLANDTEST_MAIN(KWin::DontCrashNoBorder)
0107 #include "dont_crash_no_border.moc"