File indexing completed on 2024-11-10 04:55:56
0001 /* 0002 KWin - the KDE window manager 0003 This file is part of the KDE project. 0004 0005 SPDX-FileCopyrightText: 2018 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 "cursor.h" 0012 #include "effect/effecthandler.h" 0013 #include "effect/effectloader.h" 0014 #include "wayland_server.h" 0015 #include "workspace.h" 0016 #include "x11window.h" 0017 0018 #include <KConfigGroup> 0019 0020 #include <KWayland/Client/connection_thread.h> 0021 #include <KWayland/Client/registry.h> 0022 #include <KWayland/Client/slide.h> 0023 #include <KWayland/Client/surface.h> 0024 0025 #include <netwm.h> 0026 #include <xcb/xcb_icccm.h> 0027 0028 using namespace KWin; 0029 static const QString s_socketName = QStringLiteral("wayland_test_effects_wobbly_shade-0"); 0030 0031 class WobblyWindowsShadeTest : public QObject 0032 { 0033 Q_OBJECT 0034 private Q_SLOTS: 0035 void initTestCase(); 0036 void init(); 0037 void cleanup(); 0038 0039 void testShadeMove(); 0040 }; 0041 0042 void WobblyWindowsShadeTest::initTestCase() 0043 { 0044 if (!Test::renderNodeAvailable()) { 0045 QSKIP("no render node available"); 0046 return; 0047 } 0048 qRegisterMetaType<KWin::Window *>(); 0049 qRegisterMetaType<KWin::Effect *>(); 0050 QSignalSpy applicationStartedSpy(kwinApp(), &Application::started); 0051 QVERIFY(waylandServer()->init(s_socketName)); 0052 Test::setOutputConfig({ 0053 QRect(0, 0, 1280, 1024), 0054 QRect(1280, 0, 1280, 1024), 0055 }); 0056 0057 // disable all effects - we don't want to have it interact with the rendering 0058 auto config = KSharedConfig::openConfig(QString(), KConfig::SimpleConfig); 0059 KConfigGroup plugins(config, QStringLiteral("Plugins")); 0060 const auto builtinNames = EffectLoader().listOfKnownEffects(); 0061 for (QString name : builtinNames) { 0062 plugins.writeEntry(name + QStringLiteral("Enabled"), false); 0063 } 0064 0065 config->sync(); 0066 kwinApp()->setConfig(config); 0067 0068 qputenv("KWIN_COMPOSE", QByteArrayLiteral("O2")); 0069 qputenv("KWIN_EFFECTS_FORCE_ANIMATIONS", "1"); 0070 kwinApp()->start(); 0071 QVERIFY(applicationStartedSpy.wait()); 0072 } 0073 0074 void WobblyWindowsShadeTest::init() 0075 { 0076 QVERIFY(Test::setupWaylandConnection()); 0077 } 0078 0079 void WobblyWindowsShadeTest::cleanup() 0080 { 0081 Test::destroyWaylandConnection(); 0082 0083 effects->unloadAllEffects(); 0084 QVERIFY(effects->loadedEffects().isEmpty()); 0085 } 0086 0087 void WobblyWindowsShadeTest::testShadeMove() 0088 { 0089 // this test simulates the condition from BUG 390953 0090 QVERIFY(effects->loadEffect(QStringLiteral("wobblywindows"))); 0091 QVERIFY(effects->isEffectLoaded(QStringLiteral("wobblywindows"))); 0092 0093 Test::XcbConnectionPtr c = Test::createX11Connection(); 0094 QVERIFY(!xcb_connection_has_error(c.get())); 0095 const QRect windowGeometry(0, 0, 100, 200); 0096 xcb_window_t windowId = xcb_generate_id(c.get()); 0097 xcb_create_window(c.get(), XCB_COPY_FROM_PARENT, windowId, rootWindow(), 0098 windowGeometry.x(), 0099 windowGeometry.y(), 0100 windowGeometry.width(), 0101 windowGeometry.height(), 0102 0, XCB_WINDOW_CLASS_INPUT_OUTPUT, XCB_COPY_FROM_PARENT, 0, nullptr); 0103 xcb_size_hints_t hints; 0104 memset(&hints, 0, sizeof(hints)); 0105 xcb_icccm_size_hints_set_position(&hints, 1, windowGeometry.x(), windowGeometry.y()); 0106 xcb_icccm_size_hints_set_size(&hints, 1, windowGeometry.width(), windowGeometry.height()); 0107 xcb_icccm_set_wm_normal_hints(c.get(), windowId, &hints); 0108 xcb_map_window(c.get(), windowId); 0109 xcb_flush(c.get()); 0110 0111 // we should get a window for it 0112 QSignalSpy windowCreatedSpy(workspace(), &Workspace::windowAdded); 0113 QVERIFY(windowCreatedSpy.wait()); 0114 X11Window *window = windowCreatedSpy.first().first().value<X11Window *>(); 0115 QVERIFY(window); 0116 QCOMPARE(window->window(), windowId); 0117 QVERIFY(window->isDecorated()); 0118 QVERIFY(window->isShadeable()); 0119 QVERIFY(!window->isShade()); 0120 QVERIFY(window->isActive()); 0121 0122 QSignalSpy readyForPaintingChangedSpy(window, &Window::readyForPaintingChanged); 0123 QVERIFY(readyForPaintingChangedSpy.wait()); 0124 0125 // now shade the window 0126 workspace()->slotWindowShade(); 0127 QVERIFY(window->isShade()); 0128 0129 QSignalSpy interactiveMoveResizeStartedSpy(window, &Window::interactiveMoveResizeStarted); 0130 0131 // begin move 0132 QVERIFY(workspace()->moveResizeWindow() == nullptr); 0133 QCOMPARE(window->isInteractiveMove(), false); 0134 workspace()->slotWindowMove(); 0135 QCOMPARE(workspace()->moveResizeWindow(), window); 0136 QCOMPARE(window->isInteractiveMove(), true); 0137 QCOMPARE(interactiveMoveResizeStartedSpy.count(), 1); 0138 0139 // wait for frame rendered 0140 QTest::qWait(100); 0141 0142 // send some key events, not going through input redirection 0143 window->keyPressEvent(Qt::Key_Right); 0144 window->updateInteractiveMoveResize(KWin::Cursors::self()->mouse()->pos()); 0145 0146 // wait for frame rendered 0147 QTest::qWait(100); 0148 0149 window->keyPressEvent(Qt::Key_Right); 0150 window->updateInteractiveMoveResize(KWin::Cursors::self()->mouse()->pos()); 0151 0152 // wait for frame rendered 0153 QTest::qWait(100); 0154 0155 window->keyPressEvent(Qt::Key_Down | Qt::ALT); 0156 window->updateInteractiveMoveResize(KWin::Cursors::self()->mouse()->pos()); 0157 0158 // wait for frame rendered 0159 QTest::qWait(100); 0160 0161 // let's end 0162 window->keyPressEvent(Qt::Key_Enter); 0163 0164 // wait for frame rendered 0165 QTest::qWait(100); 0166 } 0167 0168 WAYLANDTEST_MAIN(WobblyWindowsShadeTest) 0169 #include "wobbly_shade_test.moc"