File indexing completed on 2024-11-10 04:56:06

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 <netwm.h>
0020 #include <xcb/xcb_icccm.h>
0021 
0022 namespace KWin
0023 {
0024 
0025 static const QString s_socketName = QStringLiteral("wayland_test_kwin_shade-0");
0026 
0027 class ShadeTest : public QObject
0028 {
0029     Q_OBJECT
0030 private Q_SLOTS:
0031     void initTestCase();
0032     void init();
0033     void testShadeGeometry();
0034 };
0035 
0036 void ShadeTest::initTestCase()
0037 {
0038     qRegisterMetaType<KWin::Window *>();
0039     QSignalSpy applicationStartedSpy(kwinApp(), &Application::started);
0040     QVERIFY(waylandServer()->init(s_socketName));
0041     Test::setOutputConfig({
0042         QRect(0, 0, 1280, 1024),
0043         QRect(1280, 0, 1280, 1024),
0044     });
0045 
0046     kwinApp()->start();
0047     QVERIFY(applicationStartedSpy.wait());
0048     const auto outputs = workspace()->outputs();
0049     QCOMPARE(outputs.count(), 2);
0050     QCOMPARE(outputs[0]->geometry(), QRect(0, 0, 1280, 1024));
0051     QCOMPARE(outputs[1]->geometry(), QRect(1280, 0, 1280, 1024));
0052     setenv("QT_QPA_PLATFORM", "wayland", true);
0053 }
0054 
0055 void ShadeTest::init()
0056 {
0057     workspace()->setActiveOutput(QPoint(640, 512));
0058     input()->pointer()->warp(QPoint(640, 512));
0059 }
0060 
0061 void ShadeTest::testShadeGeometry()
0062 {
0063     // this test verifies that the geometry is properly restored after shading
0064     // see BUG: 362501
0065     // create an xcb window
0066 
0067     Test::XcbConnectionPtr c = Test::createX11Connection();
0068     QVERIFY(!xcb_connection_has_error(c.get()));
0069     const QRect windowGeometry(0, 0, 100, 200);
0070     xcb_window_t windowId = xcb_generate_id(c.get());
0071     xcb_create_window(c.get(), XCB_COPY_FROM_PARENT, windowId, rootWindow(),
0072                       windowGeometry.x(),
0073                       windowGeometry.y(),
0074                       windowGeometry.width(),
0075                       windowGeometry.height(),
0076                       0, XCB_WINDOW_CLASS_INPUT_OUTPUT, XCB_COPY_FROM_PARENT, 0, nullptr);
0077     xcb_size_hints_t hints;
0078     memset(&hints, 0, sizeof(hints));
0079     xcb_icccm_size_hints_set_position(&hints, 1, windowGeometry.x(), windowGeometry.y());
0080     xcb_icccm_size_hints_set_size(&hints, 1, windowGeometry.width(), windowGeometry.height());
0081     xcb_icccm_set_wm_normal_hints(c.get(), windowId, &hints);
0082     xcb_map_window(c.get(), windowId);
0083     xcb_flush(c.get());
0084 
0085     // we should get a window for it
0086     QSignalSpy windowCreatedSpy(workspace(), &Workspace::windowAdded);
0087     QVERIFY(windowCreatedSpy.wait());
0088     X11Window *window = windowCreatedSpy.first().first().value<X11Window *>();
0089     QVERIFY(window);
0090     QCOMPARE(window->window(), windowId);
0091     QVERIFY(window->isDecorated());
0092     QVERIFY(window->isShadeable());
0093     QVERIFY(!window->isShade());
0094     QVERIFY(window->isActive());
0095 
0096     // now shade the window
0097     const QRectF geoBeforeShade = window->frameGeometry();
0098     QVERIFY(geoBeforeShade.isValid());
0099     QVERIFY(!geoBeforeShade.isEmpty());
0100     workspace()->slotWindowShade();
0101     QVERIFY(window->isShade());
0102     QVERIFY(window->frameGeometry() != geoBeforeShade);
0103     // and unshade again
0104     workspace()->slotWindowShade();
0105     QVERIFY(!window->isShade());
0106     QCOMPARE(window->frameGeometry(), geoBeforeShade);
0107 
0108     // and destroy the window again
0109     xcb_unmap_window(c.get(), windowId);
0110     xcb_destroy_window(c.get(), windowId);
0111     xcb_flush(c.get());
0112     c.reset();
0113 
0114     QSignalSpy windowClosedSpy(window, &X11Window::closed);
0115     QVERIFY(windowClosedSpy.wait());
0116 }
0117 
0118 }
0119 
0120 WAYLANDTEST_MAIN(KWin::ShadeTest)
0121 #include "shade_test.moc"