diff --git a/src/inputpanelv1window.cpp b/src/inputpanelv1window.cpp index f581a1bf1d..751dd4548c 100644 --- a/src/inputpanelv1window.cpp +++ b/src/inputpanelv1window.cpp @@ -168,7 +168,7 @@ void InputPanelV1Window::setOutput(OutputInterface *outputIface) disconnect(m_output, &Output::geometryChanged, this, &InputPanelV1Window::reposition); } - m_output = waylandServer()->findOutput(outputIface); + m_output = outputIface ? outputIface->handle() : nullptr; if (m_output) { connect(m_output, &Output::geometryChanged, this, &InputPanelV1Window::reposition); diff --git a/src/layershellv1integration.cpp b/src/layershellv1integration.cpp index 5e2a2f1c93..f9cd45ef3d 100644 --- a/src/layershellv1integration.cpp +++ b/src/layershellv1integration.cpp @@ -10,6 +10,7 @@ #include "platform.h" #include "wayland/display.h" #include "wayland/layershell_v1_interface.h" +#include "wayland/output_interface.h" #include "wayland_server.h" #include "workspace.h" @@ -37,10 +38,7 @@ LayerShellV1Integration::LayerShellV1Integration(QObject *parent) void LayerShellV1Integration::createWindow(LayerSurfaceV1Interface *shellSurface) { - Output *output = waylandServer()->findOutput(shellSurface->output()); - if (!output) { - output = workspace()->activeOutput(); - } + Output *output = shellSurface->output() ? shellSurface->output()->handle() : workspace()->activeOutput(); if (!output) { qCWarning(KWIN_CORE) << "Could not find any suitable output for a layer surface"; shellSurface->sendClosed(); diff --git a/src/plugins/screencast/screencastmanager.cpp b/src/plugins/screencast/screencastmanager.cpp index 86875c90ce..13ac4bd0bf 100644 --- a/src/plugins/screencast/screencastmanager.cpp +++ b/src/plugins/screencast/screencastmanager.cpp @@ -121,7 +121,7 @@ void ScreencastManager::streamWaylandOutput(KWaylandServer::ScreencastStreamV1In KWaylandServer::OutputInterface *output, KWaylandServer::ScreencastV1Interface::CursorMode mode) { - streamOutput(waylandStream, waylandServer()->findOutput(output), mode); + streamOutput(waylandStream, output->handle(), mode); } void ScreencastManager::streamOutput(KWaylandServer::ScreencastStreamV1Interface *waylandStream, diff --git a/src/wayland/autotests/client/CMakeLists.txt b/src/wayland/autotests/client/CMakeLists.txt index 79cff410e6..b6e9210c7a 100644 --- a/src/wayland/autotests/client/CMakeLists.txt +++ b/src/wayland/autotests/client/CMakeLists.txt @@ -3,6 +3,7 @@ ######################################################## set( testWaylandOutput_SRCS test_wayland_output.cpp + ../../tests/fakeoutput.cpp ) add_executable(testWaylandOutput ${testWaylandOutput_SRCS}) target_link_libraries( testWaylandOutput Qt::Test Qt::Gui KF5::WaylandClient kwin Wayland::Client Wayland::Server) @@ -14,6 +15,7 @@ ecm_mark_as_test(testWaylandOutput) ######################################################## set( testWaylandSurface_SRCS test_wayland_surface.cpp + ../../tests/fakeoutput.cpp ) add_executable(testWaylandSurface ${testWaylandSurface_SRCS}) target_link_libraries( testWaylandSurface Qt::Test Qt::Gui KF5::WaylandClient kwin Wayland::Client Wayland::Server) @@ -231,7 +233,7 @@ ecm_mark_as_test(testXdgForeign) ######################################################## # Test XdgShell ######################################################## -set(testXdgShell_SRCS test_xdg_shell.cpp) +set(testXdgShell_SRCS test_xdg_shell.cpp ../../tests/fakeoutput.cpp) add_executable(testXdgShell ${testXdgShell_SRCS}) target_link_libraries( testXdgShell Qt::Test Qt::Gui kwin KF5::WaylandClient Wayland::Client) add_test(NAME kwayland-testXdgShell COMMAND testXdgShell) @@ -306,6 +308,7 @@ ecm_mark_as_test(testPlasmaActivities) ######################################################## set( testXdgOutput_SRCS test_xdg_output.cpp + ../../tests/fakeoutput.cpp ) add_executable(testXdgOutput ${testXdgOutput_SRCS}) target_link_libraries( testXdgOutput Qt::Test Qt::Gui KF5::WaylandClient kwin Wayland::Client Wayland::Server) diff --git a/src/wayland/autotests/client/test_wayland_output.cpp b/src/wayland/autotests/client/test_wayland_output.cpp index 4d09afb5af..565460bd18 100644 --- a/src/wayland/autotests/client/test_wayland_output.cpp +++ b/src/wayland/autotests/client/test_wayland_output.cpp @@ -7,15 +7,15 @@ #include // KWin #include "wayland/display.h" -#include "wayland/dpms_interface.h" #include "wayland/output_interface.h" #include "KWayland/Client/connection_thread.h" -#include "KWayland/Client/dpms.h" #include "KWayland/Client/event_queue.h" #include "KWayland/Client/output.h" #include "KWayland/Client/registry.h" +#include "../../tests/fakeoutput.h" + // Wayland #include @@ -38,15 +38,10 @@ private Q_SLOTS: void testTransform_data(); void testTransform(); - void testDpms_data(); - void testDpms(); - - void testDpmsRequestMode_data(); - void testDpmsRequestMode(); - private: KWaylandServer::Display *m_display; - KWaylandServer::OutputInterface *m_serverOutput; + std::unique_ptr m_outputHandle; + std::unique_ptr m_outputInterface; KWayland::Client::ConnectionThread *m_connection; KWayland::Client::EventQueue *m_queue; QThread *m_thread; @@ -57,7 +52,6 @@ static const QString s_socketName = QStringLiteral("kwin-test-wayland-output-0") TestWaylandOutput::TestWaylandOutput(QObject *parent) : QObject(parent) , m_display(nullptr) - , m_serverOutput(nullptr) , m_connection(nullptr) , m_thread(nullptr) { @@ -72,14 +66,11 @@ void TestWaylandOutput::init() m_display->start(); QVERIFY(m_display->isRunning()); - m_serverOutput = new OutputInterface(m_display, this); - QCOMPARE(m_serverOutput->pixelSize(), QSize()); - QCOMPARE(m_serverOutput->refreshRate(), 60000); - m_serverOutput->setMode(QSize(1024, 768)); - QCOMPARE(m_serverOutput->pixelSize(), QSize(1024, 768)); - QCOMPARE(m_serverOutput->refreshRate(), 60000); - QCOMPARE(m_serverOutput->isDpmsSupported(), false); - QCOMPARE(m_serverOutput->dpmsMode(), KWin::Output::DpmsMode::Off); + m_outputHandle = std::make_unique(); + m_outputHandle->setMode(QSize(1024, 768), 60000); + + m_outputInterface = std::make_unique(m_display, m_outputHandle.get()); + m_outputInterface->setMode(QSize(1024, 768), 60000); // setup connection m_connection = new KWayland::Client::ConnectionThread; @@ -117,32 +108,36 @@ void TestWaylandOutput::cleanup() delete m_display; m_display = nullptr; - // these are the children of the display - m_serverOutput = nullptr; + m_outputInterface.reset(); + m_outputHandle.reset(); } void TestWaylandOutput::testRegistry() { - QSignalSpy globalPositionChangedSpy(m_serverOutput, &KWaylandServer::OutputInterface::globalPositionChanged); + QSignalSpy globalPositionChangedSpy(m_outputInterface.get(), &KWaylandServer::OutputInterface::globalPositionChanged); QVERIFY(globalPositionChangedSpy.isValid()); - QCOMPARE(m_serverOutput->globalPosition(), QPoint(0, 0)); - m_serverOutput->setGlobalPosition(QPoint(100, 50)); - QCOMPARE(m_serverOutput->globalPosition(), QPoint(100, 50)); + QCOMPARE(m_outputInterface->globalPosition(), QPoint(0, 0)); + m_outputHandle->moveTo(QPoint(100, 50)); + m_outputInterface->setGlobalPosition(QPoint(100, 50)); + QCOMPARE(m_outputInterface->globalPosition(), QPoint(100, 50)); QCOMPARE(globalPositionChangedSpy.count(), 1); // changing again should not trigger signal - m_serverOutput->setGlobalPosition(QPoint(100, 50)); + m_outputHandle->moveTo(QPoint(100, 50)); + m_outputInterface->setGlobalPosition(QPoint(100, 50)); QCOMPARE(globalPositionChangedSpy.count(), 1); - QSignalSpy physicalSizeChangedSpy(m_serverOutput, &KWaylandServer::OutputInterface::physicalSizeChanged); + QSignalSpy physicalSizeChangedSpy(m_outputInterface.get(), &KWaylandServer::OutputInterface::physicalSizeChanged); QVERIFY(physicalSizeChangedSpy.isValid()); - QCOMPARE(m_serverOutput->physicalSize(), QSize()); - m_serverOutput->setPhysicalSize(QSize(200, 100)); - QCOMPARE(m_serverOutput->physicalSize(), QSize(200, 100)); + QCOMPARE(m_outputInterface->physicalSize(), QSize()); + m_outputHandle->setPhysicalSize(QSize(200, 100)); + m_outputInterface->setPhysicalSize(QSize(200, 100)); + QCOMPARE(m_outputInterface->physicalSize(), QSize(200, 100)); QCOMPARE(physicalSizeChangedSpy.count(), 1); // changing again should not trigger signal - m_serverOutput->setPhysicalSize(QSize(200, 100)); + m_outputHandle->setPhysicalSize(QSize(200, 100)); + m_outputInterface->setPhysicalSize(QSize(200, 100)); QCOMPARE(physicalSizeChangedSpy.count(), 1); - m_serverOutput->done(); + m_outputInterface->done(); KWayland::Client::Registry registry; QSignalSpy announced(®istry, &KWayland::Client::Registry::outputAnnounced); @@ -218,9 +213,10 @@ void TestWaylandOutput::testModeChange() QCOMPARE(output.refreshRate(), 60000); // change once more - m_serverOutput->setMode(QSize(1280, 1024), 90000); - QCOMPARE(m_serverOutput->refreshRate(), 90000); - m_serverOutput->done(); + m_outputHandle->setMode(QSize(1280, 1024), 90000); + m_outputInterface->setMode(QSize(1280, 1024), 90000); + QCOMPARE(m_outputInterface->refreshRate(), 90000); + m_outputInterface->done(); QVERIFY(outputChanged.wait()); QCOMPARE(modeAddedSpy.count(), 2); QCOMPARE(modeAddedSpy.at(1).first().value().size, QSize(1280, 1024)); @@ -251,24 +247,27 @@ void TestWaylandOutput::testScaleChange() // change the scale outputChanged.clear(); - QCOMPARE(m_serverOutput->scale(), 1); - QSignalSpy serverScaleChanged(m_serverOutput, &KWaylandServer::OutputInterface::scaleChanged); + QCOMPARE(m_outputInterface->scale(), 1); + QSignalSpy serverScaleChanged(m_outputInterface.get(), &KWaylandServer::OutputInterface::scaleChanged); QVERIFY(serverScaleChanged.isValid()); - m_serverOutput->setScale(2); - QCOMPARE(m_serverOutput->scale(), 2); - m_serverOutput->done(); + m_outputHandle->setScale(2); + m_outputInterface->setScale(2); + QCOMPARE(m_outputInterface->scale(), 2); + m_outputInterface->done(); QCOMPARE(serverScaleChanged.count(), 1); QVERIFY(outputChanged.wait()); QCOMPARE(output.scale(), 2); // changing to same value should not trigger - m_serverOutput->setScale(2); + m_outputHandle->setScale(2); + m_outputInterface->setScale(2); QCOMPARE(serverScaleChanged.count(), 1); QVERIFY(!outputChanged.wait(100)); // change once more outputChanged.clear(); - m_serverOutput->setScale(4); - m_serverOutput->done(); + m_outputHandle->setScale(4); + m_outputInterface->setScale(4); + m_outputInterface->done(); QVERIFY(outputChanged.wait()); QCOMPARE(output.scale(), 4); } @@ -292,14 +291,16 @@ void TestWaylandOutput::testSubPixel() using namespace KWayland::Client; using namespace KWaylandServer; QFETCH(KWin::Output::SubPixel, actual); - QCOMPARE(m_serverOutput->subPixel(), KWin::Output::SubPixel::Unknown); - QSignalSpy serverSubPixelChangedSpy(m_serverOutput, &KWaylandServer::OutputInterface::subPixelChanged); + QCOMPARE(m_outputInterface->subPixel(), KWin::Output::SubPixel::Unknown); + QSignalSpy serverSubPixelChangedSpy(m_outputInterface.get(), &KWaylandServer::OutputInterface::subPixelChanged); QVERIFY(serverSubPixelChangedSpy.isValid()); - m_serverOutput->setSubPixel(actual); - QCOMPARE(m_serverOutput->subPixel(), actual); + m_outputHandle->setSubPixel(actual); + m_outputInterface->setSubPixel(actual); + QCOMPARE(m_outputInterface->subPixel(), actual); QCOMPARE(serverSubPixelChangedSpy.count(), 1); // changing to same value should not trigger the signal - m_serverOutput->setSubPixel(actual); + m_outputHandle->setSubPixel(actual); + m_outputInterface->setSubPixel(actual); QCOMPARE(serverSubPixelChangedSpy.count(), 1); KWayland::Client::Registry registry; @@ -323,9 +324,10 @@ void TestWaylandOutput::testSubPixel() // change back to unknown outputChanged.clear(); - m_serverOutput->setSubPixel(KWin::Output::SubPixel::Unknown); - QCOMPARE(m_serverOutput->subPixel(), KWin::Output::SubPixel::Unknown); - m_serverOutput->done(); + m_outputHandle->setSubPixel(KWin::Output::SubPixel::Unknown); + m_outputInterface->setSubPixel(KWin::Output::SubPixel::Unknown); + QCOMPARE(m_outputInterface->subPixel(), KWin::Output::SubPixel::Unknown); + m_outputInterface->done(); QCOMPARE(serverSubPixelChangedSpy.count(), 2); if (outputChanged.isEmpty()) { QVERIFY(outputChanged.wait()); @@ -354,14 +356,16 @@ void TestWaylandOutput::testTransform() using namespace KWayland::Client; using namespace KWaylandServer; QFETCH(KWin::Output::Transform, actual); - QCOMPARE(m_serverOutput->transform(), KWin::Output::Transform::Normal); - QSignalSpy serverTransformChangedSpy(m_serverOutput, &KWaylandServer::OutputInterface::transformChanged); + QCOMPARE(m_outputInterface->transform(), KWin::Output::Transform::Normal); + QSignalSpy serverTransformChangedSpy(m_outputInterface.get(), &KWaylandServer::OutputInterface::transformChanged); QVERIFY(serverTransformChangedSpy.isValid()); - m_serverOutput->setTransform(actual); - QCOMPARE(m_serverOutput->transform(), actual); + m_outputHandle->setTransform(actual); + m_outputInterface->setTransform(actual); + QCOMPARE(m_outputInterface->transform(), actual); QCOMPARE(serverTransformChangedSpy.count(), 1); // changing to same should not trigger signal - m_serverOutput->setTransform(actual); + m_outputHandle->setTransform(actual); + m_outputInterface->setTransform(actual); QCOMPARE(serverTransformChangedSpy.count(), 1); KWayland::Client::Registry registry; @@ -384,9 +388,10 @@ void TestWaylandOutput::testTransform() // change back to normal outputChanged.clear(); - m_serverOutput->setTransform(KWin::Output::Transform::Normal); - QCOMPARE(m_serverOutput->transform(), KWin::Output::Transform::Normal); - m_serverOutput->done(); + m_outputHandle->setTransform(KWin::Output::Transform::Normal); + m_outputInterface->setTransform(KWin::Output::Transform::Normal); + QCOMPARE(m_outputInterface->transform(), KWin::Output::Transform::Normal); + m_outputInterface->done(); QCOMPARE(serverTransformChangedSpy.count(), 2); if (outputChanged.isEmpty()) { QVERIFY(outputChanged.wait()); @@ -394,161 +399,5 @@ void TestWaylandOutput::testTransform() QCOMPARE(output->transform(), Output::Transform::Normal); } -void TestWaylandOutput::testDpms_data() -{ - using namespace KWayland::Client; - using namespace KWaylandServer; - - QTest::addColumn("client"); - QTest::addColumn("server"); - - QTest::newRow("Standby") << Dpms::Mode::Standby << KWin::Output::DpmsMode::Standby; - QTest::newRow("Suspend") << Dpms::Mode::Suspend << KWin::Output::DpmsMode::Suspend; - QTest::newRow("On") << Dpms::Mode::On << KWin::Output::DpmsMode::On; -} - -void TestWaylandOutput::testDpms() -{ - using namespace KWayland::Client; - using namespace KWaylandServer; - - DpmsManagerInterface iface(m_display); - - // set Dpms on the Output - QSignalSpy serverDpmsSupportedChangedSpy(m_serverOutput, &OutputInterface::dpmsSupportedChanged); - QVERIFY(serverDpmsSupportedChangedSpy.isValid()); - QCOMPARE(m_serverOutput->isDpmsSupported(), false); - m_serverOutput->setDpmsSupported(true); - QCOMPARE(serverDpmsSupportedChangedSpy.count(), 1); - QCOMPARE(m_serverOutput->isDpmsSupported(), true); - - KWayland::Client::Registry registry; - registry.setEventQueue(m_queue); - QSignalSpy announced(®istry, &Registry::interfacesAnnounced); - QVERIFY(announced.isValid()); - QSignalSpy dpmsAnnouncedSpy(®istry, &Registry::dpmsAnnounced); - QVERIFY(dpmsAnnouncedSpy.isValid()); - registry.create(m_connection->display()); - QVERIFY(registry.isValid()); - registry.setup(); - m_connection->flush(); - QVERIFY(announced.wait()); - QCOMPARE(dpmsAnnouncedSpy.count(), 1); - - Output *output = - registry.createOutput(registry.interface(Registry::Interface::Output).name, registry.interface(Registry::Interface::Output).version, ®istry); - - DpmsManager *dpmsManager = - registry.createDpmsManager(dpmsAnnouncedSpy.first().first().value(), dpmsAnnouncedSpy.first().last().value(), ®istry); - QVERIFY(dpmsManager->isValid()); - - Dpms *dpms = dpmsManager->getDpms(output, ®istry); - QSignalSpy clientDpmsSupportedChangedSpy(dpms, &Dpms::supportedChanged); - QVERIFY(clientDpmsSupportedChangedSpy.isValid()); - QVERIFY(dpms->isValid()); - QCOMPARE(dpms->isSupported(), false); - QCOMPARE(dpms->mode(), Dpms::Mode::On); - m_connection->flush(); - QVERIFY(clientDpmsSupportedChangedSpy.wait()); - QCOMPARE(clientDpmsSupportedChangedSpy.count(), 1); - QCOMPARE(dpms->isSupported(), true); - - // and let's change to suspend - QSignalSpy serverDpmsModeChangedSpy(m_serverOutput, &KWaylandServer::OutputInterface::dpmsModeChanged); - QVERIFY(serverDpmsModeChangedSpy.isValid()); - QSignalSpy clientDpmsModeChangedSpy(dpms, &Dpms::modeChanged); - QVERIFY(clientDpmsModeChangedSpy.isValid()); - - QCOMPARE(m_serverOutput->dpmsMode(), KWin::Output::DpmsMode::Off); - QFETCH(KWin::Output::DpmsMode, server); - m_serverOutput->setDpmsMode(server); - QCOMPARE(m_serverOutput->dpmsMode(), server); - QCOMPARE(serverDpmsModeChangedSpy.count(), 1); - - QVERIFY(clientDpmsModeChangedSpy.wait()); - QCOMPARE(clientDpmsModeChangedSpy.count(), 1); - QTEST(dpms->mode(), "client"); - - // test supported changed - QSignalSpy supportedChangedSpy(dpms, &Dpms::supportedChanged); - QVERIFY(supportedChangedSpy.isValid()); - m_serverOutput->setDpmsSupported(false); - QVERIFY(supportedChangedSpy.wait()); - QCOMPARE(supportedChangedSpy.count(), 1); - QVERIFY(!dpms->isSupported()); - m_serverOutput->setDpmsSupported(true); - QVERIFY(supportedChangedSpy.wait()); - QCOMPARE(supportedChangedSpy.count(), 2); - QVERIFY(dpms->isSupported()); - - // and switch back to off - m_serverOutput->setDpmsMode(KWin::Output::DpmsMode::Off); - QVERIFY(clientDpmsModeChangedSpy.wait()); - QCOMPARE(clientDpmsModeChangedSpy.count(), 2); - QCOMPARE(dpms->mode(), Dpms::Mode::Off); -} - -void TestWaylandOutput::testDpmsRequestMode_data() -{ - using namespace KWayland::Client; - using namespace KWaylandServer; - - QTest::addColumn("client"); - QTest::addColumn("server"); - - QTest::newRow("Standby") << Dpms::Mode::Standby << KWin::Output::DpmsMode::Standby; - QTest::newRow("Suspend") << Dpms::Mode::Suspend << KWin::Output::DpmsMode::Suspend; - QTest::newRow("Off") << Dpms::Mode::Off << KWin::Output::DpmsMode::Off; - QTest::newRow("On") << Dpms::Mode::On << KWin::Output::DpmsMode::On; -} - -void TestWaylandOutput::testDpmsRequestMode() -{ - // this test verifies that requesting a dpms change from client side emits the signal on server side - using namespace KWayland::Client; - using namespace KWaylandServer; - - // setup code - DpmsManagerInterface iface(m_display); - - // set Dpms on the Output - QSignalSpy serverDpmsSupportedChangedSpy(m_serverOutput, &OutputInterface::dpmsSupportedChanged); - QVERIFY(serverDpmsSupportedChangedSpy.isValid()); - QCOMPARE(m_serverOutput->isDpmsSupported(), false); - m_serverOutput->setDpmsSupported(true); - QCOMPARE(serverDpmsSupportedChangedSpy.count(), 1); - QCOMPARE(m_serverOutput->isDpmsSupported(), true); - - KWayland::Client::Registry registry; - registry.setEventQueue(m_queue); - QSignalSpy announced(®istry, &Registry::interfacesAnnounced); - QVERIFY(announced.isValid()); - QSignalSpy dpmsAnnouncedSpy(®istry, &Registry::dpmsAnnounced); - QVERIFY(dpmsAnnouncedSpy.isValid()); - registry.create(m_connection->display()); - QVERIFY(registry.isValid()); - registry.setup(); - m_connection->flush(); - QVERIFY(announced.wait()); - QCOMPARE(dpmsAnnouncedSpy.count(), 1); - - Output *output = - registry.createOutput(registry.interface(Registry::Interface::Output).name, registry.interface(Registry::Interface::Output).version, ®istry); - - DpmsManager *dpmsManager = - registry.createDpmsManager(dpmsAnnouncedSpy.first().first().value(), dpmsAnnouncedSpy.first().last().value(), ®istry); - QVERIFY(dpmsManager->isValid()); - - Dpms *dpms = dpmsManager->getDpms(output, ®istry); - // and test request mode - QSignalSpy modeRequestedSpy(m_serverOutput, &KWaylandServer::OutputInterface::dpmsModeRequested); - QVERIFY(modeRequestedSpy.isValid()); - - QFETCH(Dpms::Mode, client); - dpms->requestMode(client); - QVERIFY(modeRequestedSpy.wait()); - QTEST(modeRequestedSpy.last().first().value(), "server"); -} - QTEST_GUILESS_MAIN(TestWaylandOutput) #include "test_wayland_output.moc" diff --git a/src/wayland/autotests/client/test_wayland_surface.cpp b/src/wayland/autotests/client/test_wayland_surface.cpp index cb73ea5b2a..3bf9645e3f 100644 --- a/src/wayland/autotests/client/test_wayland_surface.cpp +++ b/src/wayland/autotests/client/test_wayland_surface.cpp @@ -25,6 +25,8 @@ #include "KWayland/Client/shm_pool.h" #include "KWayland/Client/surface.h" +#include "../../tests/fakeoutput.h" + // Wayland #include @@ -1022,7 +1024,8 @@ void TestWaylandSurface::testOutput() QSignalSpy outputAnnouncedSpy(®istry, &Registry::outputAnnounced); QVERIFY(outputAnnouncedSpy.isValid()); - auto serverOutput = new OutputInterface(m_display, m_display); + auto outputHandle = std::make_unique(); + auto serverOutput = std::make_unique(m_display, outputHandle.get()); QVERIFY(outputAnnouncedSpy.wait()); std::unique_ptr clientOutput( registry.createOutput(outputAnnouncedSpy.first().first().value(), outputAnnouncedSpy.first().last().value())); @@ -1031,15 +1034,15 @@ void TestWaylandSurface::testOutput() m_display->dispatchEvents(); // now enter it - serverSurface->setOutputs(QVector{serverOutput}); - QCOMPARE(serverSurface->outputs(), QVector{serverOutput}); + serverSurface->setOutputs(QVector{serverOutput.get()}); + QCOMPARE(serverSurface->outputs(), QVector{serverOutput.get()}); QVERIFY(enteredSpy.wait()); QCOMPARE(enteredSpy.count(), 1); QCOMPARE(enteredSpy.first().first().value(), clientOutput.get()); QCOMPARE(s->outputs(), QVector{clientOutput.get()}); // adding to same should not trigger - serverSurface->setOutputs(QVector{serverOutput}); + serverSurface->setOutputs(QVector{serverOutput.get()}); // leave again serverSurface->setOutputs(QVector()); @@ -1054,15 +1057,16 @@ void TestWaylandSurface::testOutput() serverSurface->setOutputs(QVector()); // and enter again, just to verify - serverSurface->setOutputs(QVector{serverOutput}); - QCOMPARE(serverSurface->outputs(), QVector{serverOutput}); + serverSurface->setOutputs(QVector{serverOutput.get()}); + QCOMPARE(serverSurface->outputs(), QVector{serverOutput.get()}); QVERIFY(enteredSpy.wait()); QCOMPARE(enteredSpy.count(), 2); QCOMPARE(leftSpy.count(), 1); // delete output client is on. // client should get an exit and be left on no outputs (which is allowed) - serverOutput->deleteLater(); + serverOutput.reset(); + outputHandle.reset(); QVERIFY(leftSpy.wait()); QCOMPARE(serverSurface->outputs(), QVector()); } diff --git a/src/wayland/autotests/client/test_xdg_output.cpp b/src/wayland/autotests/client/test_xdg_output.cpp index 2ccf186bf1..1e8075a662 100644 --- a/src/wayland/autotests/client/test_xdg_output.cpp +++ b/src/wayland/autotests/client/test_xdg_output.cpp @@ -18,6 +18,8 @@ #include "KWayland/Client/registry.h" #include "KWayland/Client/xdgoutput.h" +#include "../../tests/fakeoutput.h" + class TestXdgOutput : public QObject { Q_OBJECT @@ -30,6 +32,7 @@ private Q_SLOTS: private: KWaylandServer::Display *m_display; + std::unique_ptr m_outputHandle; KWaylandServer::OutputInterface *m_serverOutput; KWaylandServer::XdgOutputManagerV1Interface *m_serverXdgOutputManager; KWaylandServer::XdgOutputV1Interface *m_serverXdgOutput; @@ -58,7 +61,10 @@ void TestXdgOutput::init() m_display->start(); QVERIFY(m_display->isRunning()); - m_serverOutput = new OutputInterface(m_display, this); + m_outputHandle = std::make_unique(); + m_outputHandle->setMode(QSize(1920, 1080), 60000); + + m_serverOutput = new OutputInterface(m_display, m_outputHandle.get(), this); m_serverOutput->setMode(QSize(1920, 1080)); m_serverXdgOutputManager = new XdgOutputManagerV1Interface(m_display, this); @@ -105,6 +111,7 @@ void TestXdgOutput::cleanup() delete m_serverOutput; m_serverOutput = nullptr; + m_outputHandle.reset(); delete m_display; m_display = nullptr; diff --git a/src/wayland/autotests/client/test_xdg_shell.cpp b/src/wayland/autotests/client/test_xdg_shell.cpp index 275324cac9..ec270c33b7 100644 --- a/src/wayland/autotests/client/test_xdg_shell.cpp +++ b/src/wayland/autotests/client/test_xdg_shell.cpp @@ -25,6 +25,8 @@ #include "wayland/surface_interface.h" #include "wayland/xdgshell_interface.h" +#include "../../tests/fakeoutput.h" + using namespace KWayland::Client; using namespace KWaylandServer; @@ -63,8 +65,10 @@ private: XdgShell *m_xdgShell = nullptr; KWaylandServer::Display *m_display = nullptr; CompositorInterface *m_compositorInterface = nullptr; - OutputInterface *m_o1Interface = nullptr; - OutputInterface *m_o2Interface = nullptr; + std::unique_ptr m_output1Handle; + OutputInterface *m_output1Interface = nullptr; + std::unique_ptr m_output2Handle; + OutputInterface *m_output2Interface = nullptr; SeatInterface *m_seatInterface = nullptr; ConnectionThread *m_connection = nullptr; QThread *m_thread = nullptr; @@ -93,10 +97,14 @@ void XdgShellTest::init() m_display->start(); QVERIFY(m_display->isRunning()); m_display->createShm(); - m_o1Interface = new OutputInterface(m_display, m_display); - m_o1Interface->setMode(QSize(1024, 768)); - m_o2Interface = new OutputInterface(m_display, m_display); - m_o2Interface->setMode(QSize(1024, 768)); + m_output1Handle = std::make_unique(); + m_output1Handle->setMode(QSize(1024, 768), 60000); + m_output1Interface = new OutputInterface(m_display, m_output1Handle.get(), m_display); + m_output1Interface->setMode(QSize(1024, 768)); + m_output2Handle = std::make_unique(); + m_output2Handle->setMode(QSize(1024, 768), 60000); + m_output2Interface = new OutputInterface(m_display, m_output2Handle.get(), m_display); + m_output2Interface->setMode(QSize(1024, 768)); m_seatInterface = new SeatInterface(m_display, m_display); m_seatInterface->setHasKeyboard(true); m_seatInterface->setHasPointer(true); @@ -193,8 +201,10 @@ void XdgShellTest::cleanup() // these are the children of the display m_compositorInterface = nullptr; m_xdgShellInterface = nullptr; - m_o1Interface = nullptr; - m_o2Interface = nullptr; + m_output1Handle.reset(); + m_output1Interface = nullptr; + m_output2Handle.reset(); + m_output2Interface = nullptr; m_seatInterface = nullptr; } @@ -329,13 +339,13 @@ void XdgShellTest::testFullscreen() xdgSurface->setFullscreen(true, m_output1); QVERIFY(fullscreenRequestedSpy.wait()); QCOMPARE(fullscreenRequestedSpy.count(), 2); - QCOMPARE(fullscreenRequestedSpy.last().at(0).value(), m_o1Interface); + QCOMPARE(fullscreenRequestedSpy.last().at(0).value(), m_output1Interface); // now other output xdgSurface->setFullscreen(true, m_output2); QVERIFY(fullscreenRequestedSpy.wait()); QCOMPARE(fullscreenRequestedSpy.count(), 3); - QCOMPARE(fullscreenRequestedSpy.last().at(0).value(), m_o2Interface); + QCOMPARE(fullscreenRequestedSpy.last().at(0).value(), m_output2Interface); } void XdgShellTest::testShowWindowMenu() diff --git a/src/wayland/autotests/server/CMakeLists.txt b/src/wayland/autotests/server/CMakeLists.txt index 96afe19374..504d49d54a 100644 --- a/src/wayland/autotests/server/CMakeLists.txt +++ b/src/wayland/autotests/server/CMakeLists.txt @@ -137,7 +137,7 @@ else() ${WaylandProtocols_DATADIR}/unstable/text-input/text-input-unstable-v1.xml ) endif() -target_sources(testInputMethodInterface PRIVATE test_inputmethod_interface.cpp ${INPUTMETHOD_SRCS}) +target_sources(testInputMethodInterface PRIVATE test_inputmethod_interface.cpp ../../tests/fakeoutput.cpp ${INPUTMETHOD_SRCS}) target_link_libraries(testInputMethodInterface Qt::Test kwin KF5::WaylandClient Wayland::Client) add_test(NAME kwayland-testInputMethodInterface COMMAND testInputMethodInterface) ecm_mark_as_test(testInputMethodInterface) diff --git a/src/wayland/autotests/server/test_display.cpp b/src/wayland/autotests/server/test_display.cpp index 4aa4e1871e..9c2640dcdb 100644 --- a/src/wayland/autotests/server/test_display.cpp +++ b/src/wayland/autotests/server/test_display.cpp @@ -8,7 +8,6 @@ // WaylandServer #include "wayland/clientconnection.h" #include "wayland/display.h" -#include "wayland/output_interface.h" // Wayland #include // system @@ -24,7 +23,6 @@ class TestWaylandServerDisplay : public QObject private Q_SLOTS: void testSocketName(); void testStartStop(); - void testAddRemoveOutput(); void testClientConnection(); void testConnectNoSocket(); void testAutoSocketName(); @@ -69,20 +67,6 @@ void TestWaylandServerDisplay::testStartStop() QVERIFY(!runtimeDir.exists(testSocketName)); } -void TestWaylandServerDisplay::testAddRemoveOutput() -{ - KWaylandServer::Display display; - display.addSocketName(QStringLiteral("kwin-wayland-server-display-test-output-0")); - display.start(); - - OutputInterface *output = new OutputInterface(&display); - QCOMPARE(display.outputs().size(), 1); - QCOMPARE(display.outputs().first(), output); - - delete output; - QVERIFY(display.outputs().isEmpty()); -} - void TestWaylandServerDisplay::testClientConnection() { KWaylandServer::Display display; diff --git a/src/wayland/autotests/server/test_inputmethod_interface.cpp b/src/wayland/autotests/server/test_inputmethod_interface.cpp index f9d088d450..f1ddb42798 100644 --- a/src/wayland/autotests/server/test_inputmethod_interface.cpp +++ b/src/wayland/autotests/server/test_inputmethod_interface.cpp @@ -8,6 +8,9 @@ #include #include #include + +#include "../../tests/fakeoutput.h" + // WaylandServer #include "wayland/compositor_interface.h" #include "wayland/display.h" @@ -174,6 +177,8 @@ private: KWaylandServer::Display m_display; SeatInterface *m_seat; CompositorInterface *m_serverCompositor; + std::unique_ptr m_outputHandle; + std::unique_ptr m_outputInterface; KWaylandServer::InputMethodV1Interface *m_inputMethodIface; KWaylandServer::InputPanelV1Interface *m_inputPanelIface; @@ -193,7 +198,9 @@ void TestInputMethodInterface::initTestCase() m_serverCompositor = new CompositorInterface(&m_display, this); m_inputMethodIface = new InputMethodV1Interface(&m_display, this); m_inputPanelIface = new InputPanelV1Interface(&m_display, this); - new OutputInterface(&m_display, this); + + m_outputHandle = std::make_unique(); + m_outputInterface = std::make_unique(&m_display, m_outputHandle.get()); connect(m_serverCompositor, &CompositorInterface::surfaceCreated, this, [this](SurfaceInterface *surface) { m_surfaces += surface; diff --git a/src/wayland/output_interface.cpp b/src/wayland/output_interface.cpp index 2da6a91524..bdf7eac438 100644 --- a/src/wayland/output_interface.cpp +++ b/src/wayland/output_interface.cpp @@ -9,6 +9,8 @@ #include "display_p.h" #include "utils.h" +#include "output.h" + #include "qwayland-server-wayland.h" #include @@ -21,7 +23,7 @@ static const int s_version = 3; class OutputInterfacePrivate : public QtWaylandServer::wl_output { public: - explicit OutputInterfacePrivate(Display *display, OutputInterface *q); + explicit OutputInterfacePrivate(Display *display, OutputInterface *q, KWin::Output *handle); void sendScale(Resource *resource); void sendGeometry(Resource *resource); @@ -32,6 +34,7 @@ public: OutputInterface *q; QPointer display; + QPointer handle; QSize physicalSize; QPoint globalPosition; QString manufacturer = QStringLiteral("org.kde.kwin"); @@ -52,10 +55,11 @@ private: void output_release(Resource *resource) override; }; -OutputInterfacePrivate::OutputInterfacePrivate(Display *display, OutputInterface *q) +OutputInterfacePrivate::OutputInterfacePrivate(Display *display, OutputInterface *q, KWin::Output *handle) : QtWaylandServer::wl_output(*display, s_version) , q(q) , display(display) + , handle(handle) { } @@ -167,9 +171,9 @@ void OutputInterfacePrivate::output_bind_resource(Resource *resource) Q_EMIT q->bound(display->getConnection(resource->client()), resource->handle); } -OutputInterface::OutputInterface(Display *display, QObject *parent) +OutputInterface::OutputInterface(Display *display, KWin::Output *handle, QObject *parent) : QObject(parent) - , d(new OutputInterfacePrivate(display, this)) + , d(new OutputInterfacePrivate(display, this, handle)) { DisplayPrivate *displayPrivate = DisplayPrivate::get(display); displayPrivate->outputs.append(this); @@ -180,6 +184,11 @@ OutputInterface::~OutputInterface() remove(); } +KWin::Output *OutputInterface::handle() const +{ + return d->handle; +} + void OutputInterface::remove() { if (d->isGlobalRemoved()) { diff --git a/src/wayland/output_interface.h b/src/wayland/output_interface.h index c0f5404675..dc23062c70 100644 --- a/src/wayland/output_interface.h +++ b/src/wayland/output_interface.h @@ -16,6 +16,11 @@ struct wl_resource; struct wl_client; +namespace KWin +{ +class Output; +} + namespace KWaylandServer { class ClientConnection; @@ -43,11 +48,13 @@ public: int refreshRate = 60000; }; - explicit OutputInterface(Display *display, QObject *parent = nullptr); + explicit OutputInterface(Display *display, KWin::Output *handle, QObject *parent = nullptr); ~OutputInterface() override; void remove(); + KWin::Output *handle() const; + QSize physicalSize() const; QPoint globalPosition() const; QString manufacturer() const; diff --git a/src/wayland/tests/CMakeLists.txt b/src/wayland/tests/CMakeLists.txt index b5e4caa3c2..1ef001a648 100644 --- a/src/wayland/tests/CMakeLists.txt +++ b/src/wayland/tests/CMakeLists.txt @@ -4,6 +4,7 @@ include(ECMMarkAsTest) include_directories(SYSTEM ${Qt5Core_PRIVATE_INCLUDE_DIRS}) set(testServer_SRCS waylandservertest.cpp + fakeoutput.cpp ) add_executable(testServer ${testServer_SRCS}) target_link_libraries(testServer kwin Qt::CorePrivate) @@ -13,6 +14,7 @@ find_package(Qt${QT_MAJOR_VERSION}Widgets ${QT_MIN_VERSION} CONFIG QUIET) if (TARGET Qt::Widgets) set(testRenderingServer_SRCS renderingservertest.cpp + fakeoutput.cpp ) add_executable(testRenderingServer ${testRenderingServer_SRCS}) target_link_libraries(testRenderingServer kwin Qt::Concurrent Qt::Widgets) diff --git a/src/wayland/tests/fakeoutput.cpp b/src/wayland/tests/fakeoutput.cpp new file mode 100644 index 0000000000..6726de5242 --- /dev/null +++ b/src/wayland/tests/fakeoutput.cpp @@ -0,0 +1,51 @@ +/* + KWin - the KDE window manager + This file is part of the KDE project. + + SPDX-FileCopyrightText: 2022 Xaver Hugl + + SPDX-License-Identifier: GPL-2.0-or-later +*/ +#include "fakeoutput.h" + +FakeOutput::FakeOutput() +{ + setMode(QSize(1024, 720), 60000); +} + +KWin::RenderLoop *FakeOutput::renderLoop() const +{ + return nullptr; +} + +void FakeOutput::setMode(QSize size, uint32_t refreshRate) +{ + auto mode = std::make_shared(size, refreshRate); + setModesInternal({mode}, mode); +} + +void FakeOutput::setSubPixel(SubPixel subPixel) +{ + setInformation({ + .subPixel = subPixel, + }); +} + +void FakeOutput::setDpmsSupported(bool supported) +{ + setInformation({ + .capabilities = supported ? Capability::Dpms : Capabilities(), + }); +} + +void FakeOutput::setPhysicalSize(QSize size) +{ + setInformation({ + .physicalSize = size, + }); +} + +void FakeOutput::setTransform(Transform transform) +{ + setTransformInternal(transform); +} diff --git a/src/wayland/tests/fakeoutput.h b/src/wayland/tests/fakeoutput.h new file mode 100644 index 0000000000..0c086f9d3a --- /dev/null +++ b/src/wayland/tests/fakeoutput.h @@ -0,0 +1,26 @@ +/* + KWin - the KDE window manager + This file is part of the KDE project. + + SPDX-FileCopyrightText: 2022 Xaver Hugl + + SPDX-License-Identifier: GPL-2.0-or-later +*/ +#pragma once + +#include "output.h" + +class FakeOutput : public KWin::Output +{ + Q_OBJECT + +public: + FakeOutput(); + + KWin::RenderLoop *renderLoop() const override; + void setMode(QSize size, uint32_t refreshRate); + void setSubPixel(SubPixel subPixel); + void setDpmsSupported(bool supported); + void setPhysicalSize(QSize size); + void setTransform(Transform transform); +}; diff --git a/src/wayland/tests/renderingservertest.cpp b/src/wayland/tests/renderingservertest.cpp index aa12f7e598..47e5242543 100644 --- a/src/wayland/tests/renderingservertest.cpp +++ b/src/wayland/tests/renderingservertest.cpp @@ -13,6 +13,8 @@ #include "../shmclientbuffer.h" #include "../xdgshell_interface.h" +#include "fakeoutput.h" + #include #include #include @@ -242,10 +244,17 @@ int main(int argc, char **argv) new CompositorInterface(&display, &display); XdgShellInterface *shell = new XdgShellInterface(&display); display.createShm(); - OutputInterface *output = new OutputInterface(&display, &display); - output->setPhysicalSize(QSize(269, 202)); + const QSize windowSize(1024, 768); - output->setMode(windowSize); + + auto outputHandle = std::make_unique(); + outputHandle->setPhysicalSize(QSize(269, 202)); + outputHandle->setMode(windowSize, 60000); + + OutputInterface *outputInterface = new OutputInterface(&display, outputHandle.get(), &display); + outputInterface->setPhysicalSize(QSize(269, 202)); + outputInterface->setMode(windowSize); + SeatInterface *seat = new SeatInterface(&display); seat->setHasKeyboard(true); seat->setHasPointer(true); diff --git a/src/wayland/tests/waylandservertest.cpp b/src/wayland/tests/waylandservertest.cpp index 04405dca4c..789ec3e495 100644 --- a/src/wayland/tests/waylandservertest.cpp +++ b/src/wayland/tests/waylandservertest.cpp @@ -9,6 +9,8 @@ #include "../seat_interface.h" #include "../xdgshell_interface.h" +#include "fakeoutput.h" + #include #include #include @@ -75,9 +77,14 @@ int main(int argc, char **argv) display.createShm(); new CompositorInterface(&display, &display); new XdgShellInterface(&display, &display); - OutputInterface *output = new OutputInterface(&display, &display); - output->setPhysicalSize(QSize(10, 10)); - output->setMode(QSize(1024, 768)); + + auto outputHandle = std::make_unique(); + outputHandle->setMode(QSize(1024, 768), 60000); + outputHandle->setPhysicalSize(QSize(10, 10)); + + OutputInterface *outputInterface = new OutputInterface(&display, outputHandle.get(), &display); + outputInterface->setPhysicalSize(QSize(10, 10)); + outputInterface->setMode(QSize(1024, 768)); // starts XWayland by forking and opening a pipe const int pipe = startXServer(); diff --git a/src/wayland_server.cpp b/src/wayland_server.cpp index 7f7145f8aa..df1100e98a 100644 --- a/src/wayland_server.cpp +++ b/src/wayland_server.cpp @@ -309,16 +309,6 @@ void WaylandServer::setEnablePrimarySelection(bool enable) } } -Output *WaylandServer::findOutput(KWaylandServer::OutputInterface *outputIface) const -{ - for (auto it = m_waylandOutputs.constBegin(); it != m_waylandOutputs.constEnd(); ++it) { - if ((*it)->waylandOutput() == outputIface) { - return it.key(); - } - } - return nullptr; -} - bool WaylandServer::start() { return m_display->start(); diff --git a/src/wayland_server.h b/src/wayland_server.h index 09c6c60f70..ccbb9f608c 100644 --- a/src/wayland_server.h +++ b/src/wayland_server.h @@ -222,8 +222,6 @@ public: } void setEnablePrimarySelection(bool enable); - Output *findOutput(KWaylandServer::OutputInterface *output) const; - /** * Returns the first socket name that can be used to connect to this server. * For a full list, use display()->socketNames() diff --git a/src/waylandoutput.cpp b/src/waylandoutput.cpp index 76c14ec932..2c7a18dbea 100644 --- a/src/waylandoutput.cpp +++ b/src/waylandoutput.cpp @@ -15,7 +15,7 @@ namespace KWin WaylandOutput::WaylandOutput(Output *output, QObject *parent) : QObject(parent) , m_platformOutput(output) - , m_waylandOutput(new KWaylandServer::OutputInterface(waylandServer()->display())) + , m_waylandOutput(new KWaylandServer::OutputInterface(waylandServer()->display(), output)) , m_xdgOutputV1(waylandServer()->xdgOutputManagerV1()->createXdgOutput(m_waylandOutput.get(), m_waylandOutput.get())) { const QRect geometry = m_platformOutput->geometry(); @@ -55,11 +55,6 @@ WaylandOutput::WaylandOutput(Output *output, QObject *parent) connect(output, &Output::scaleChanged, this, &WaylandOutput::scheduleUpdate); } -KWaylandServer::OutputInterface *WaylandOutput::waylandOutput() const -{ - return m_waylandOutput.get(); -} - void WaylandOutput::scheduleUpdate() { m_updateTimer.start(); diff --git a/src/waylandoutput.h b/src/waylandoutput.h index 8c95f07396..0abafdf4a2 100644 --- a/src/waylandoutput.h +++ b/src/waylandoutput.h @@ -23,8 +23,6 @@ class WaylandOutput : public QObject public: explicit WaylandOutput(Output *output, QObject *parent = nullptr); - KWaylandServer::OutputInterface *waylandOutput() const; - private Q_SLOTS: void handleDpmsModeChanged(); void handleDpmsModeRequested(KWin::Output::DpmsMode dpmsMode); diff --git a/src/window.cpp b/src/window.cpp index 2caf43f072..103fa370dd 100644 --- a/src/window.cpp +++ b/src/window.cpp @@ -2349,7 +2349,7 @@ void Window::setupWindowManagementInterface() setOnActivity(activityId, false); }); connect(w, &PlasmaWindowInterface::sendToOutput, this, [this](KWaylandServer::OutputInterface *output) { - sendToOutput(waylandServer()->findOutput(output)); + sendToOutput(output->handle()); }); m_windowManagementInterface = w; diff --git a/src/xdgshellwindow.cpp b/src/xdgshellwindow.cpp index 06b6c3714c..07bc8ccb43 100644 --- a/src/xdgshellwindow.cpp +++ b/src/xdgshellwindow.cpp @@ -1234,8 +1234,7 @@ void XdgToplevelWindow::handleUnmaximizeRequested() void XdgToplevelWindow::handleFullscreenRequested(OutputInterface *output) { - m_fullScreenRequestedOutput = waylandServer()->findOutput(output); - + m_fullScreenRequestedOutput = output ? output->handle() : nullptr; if (m_isInitialized) { setFullScreen(/* set */ true, /* user */ false); scheduleConfigure();