File indexing completed on 2024-11-10 04:55:58
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 "pointer_input.h" 0013 #include "wayland_server.h" 0014 #include "workspace.h" 0015 #include "x11window.h" 0016 0017 #include <KDecoration2/Decoration> 0018 0019 #include <linux/input.h> 0020 0021 namespace KWin 0022 { 0023 0024 static const QString s_socketName = QStringLiteral("wayland_test_kwin_dont_crash_empty_decoration-0"); 0025 0026 class DontCrashEmptyDecorationTest : public QObject 0027 { 0028 Q_OBJECT 0029 private Q_SLOTS: 0030 void initTestCase(); 0031 void init(); 0032 void testBug361551(); 0033 }; 0034 0035 void DontCrashEmptyDecorationTest::initTestCase() 0036 { 0037 if (!Test::renderNodeAvailable()) { 0038 QSKIP("no render node available"); 0039 return; 0040 } 0041 qRegisterMetaType<KWin::Window *>(); 0042 QSignalSpy applicationStartedSpy(kwinApp(), &Application::started); 0043 QVERIFY(waylandServer()->init(s_socketName)); 0044 Test::setOutputConfig({ 0045 QRect(0, 0, 1280, 1024), 0046 QRect(1280, 0, 1280, 1024), 0047 }); 0048 0049 // this test needs to enforce OpenGL compositing to get into the crashy condition 0050 qputenv("KWIN_COMPOSE", QByteArrayLiteral("O2")); 0051 kwinApp()->start(); 0052 QVERIFY(applicationStartedSpy.wait()); 0053 const auto outputs = workspace()->outputs(); 0054 QCOMPARE(outputs.count(), 2); 0055 QCOMPARE(outputs[0]->geometry(), QRect(0, 0, 1280, 1024)); 0056 QCOMPARE(outputs[1]->geometry(), QRect(1280, 0, 1280, 1024)); 0057 setenv("QT_QPA_PLATFORM", "wayland", true); 0058 } 0059 0060 void DontCrashEmptyDecorationTest::init() 0061 { 0062 workspace()->setActiveOutput(QPoint(640, 512)); 0063 input()->pointer()->warp(QPoint(640, 512)); 0064 } 0065 0066 void DontCrashEmptyDecorationTest::testBug361551() 0067 { 0068 // this test verifies that resizing an X11 window to an invalid size does not result in crash on unmap 0069 // when the DecorationRenderer gets copied to the Deleted 0070 // there a repaint is scheduled and the resulting texture is invalid if the window size is invalid 0071 0072 // create an xcb window 0073 Test::XcbConnectionPtr connection = Test::createX11Connection(); 0074 auto c = connection.get(); 0075 0076 QVERIFY(c); 0077 QVERIFY(!xcb_connection_has_error(c)); 0078 0079 xcb_window_t windowId = xcb_generate_id(c); 0080 xcb_create_window(c, XCB_COPY_FROM_PARENT, windowId, rootWindow(), 0, 0, 10, 10, 0, XCB_WINDOW_CLASS_INPUT_OUTPUT, XCB_COPY_FROM_PARENT, 0, nullptr); 0081 xcb_map_window(c, windowId); 0082 xcb_flush(c); 0083 0084 // we should get a window for it 0085 QSignalSpy windowCreatedSpy(workspace(), &Workspace::windowAdded); 0086 QVERIFY(windowCreatedSpy.wait()); 0087 X11Window *window = windowCreatedSpy.first().first().value<X11Window *>(); 0088 QVERIFY(window); 0089 QCOMPARE(window->window(), windowId); 0090 QVERIFY(window->isDecorated()); 0091 0092 // let's set a stupid geometry 0093 window->moveResize({0, 0, 0, 0}); 0094 QCOMPARE(window->frameGeometry(), QRect(0, 0, 0, 0)); 0095 0096 // and destroy the window again 0097 xcb_unmap_window(c, windowId); 0098 xcb_destroy_window(c, windowId); 0099 xcb_flush(c); 0100 0101 QSignalSpy windowClosedSpy(window, &X11Window::closed); 0102 QVERIFY(windowClosedSpy.wait()); 0103 } 0104 0105 } 0106 0107 WAYLANDTEST_MAIN(KWin::DontCrashEmptyDecorationTest) 0108 #include "dont_crash_empty_deco.moc"