diff --git a/autotests/integration/screen_changes_test.cpp b/autotests/integration/screen_changes_test.cpp --- a/autotests/integration/screen_changes_test.cpp +++ b/autotests/integration/screen_changes_test.cpp @@ -24,6 +24,7 @@ #include "wayland_server.h" #include +#include #include using namespace KWin; @@ -84,6 +85,8 @@ QVERIFY(registry.isValid()); registry.setup(); QVERIFY(allAnnounced.wait()); + const auto xdgOMData = registry.interface(Registry::Interface::XdgOutputUnstableV1); + auto xdgOutputManager = registry.createXdgOutputManager(xdgOMData.name, xdgOMData.version); // should be one output QCOMPARE(screens()->count(), 1); @@ -138,6 +141,20 @@ QVERIFY(o2ChangedSpy.wait()); QCOMPARE(o2->geometry(), geometries.at(1)); + //and check XDGOutput is synced + QScopedPointer xdgO1(xdgOutputManager->getXdgOutput(o1.data())); + QSignalSpy xdgO1ChangedSpy(xdgO1.data(), &XdgOutput::changed); + QVERIFY(xdgO1ChangedSpy.isValid()); + QVERIFY(xdgO1ChangedSpy.wait()); + QCOMPARE(xdgO1->logicalPosition(), geometries.at(0).topLeft()); + QCOMPARE(xdgO1->logicalSize(), geometries.at(0).size()); + QScopedPointer xdgO2(xdgOutputManager->getXdgOutput(o2.data())); + QSignalSpy xdgO2ChangedSpy(xdgO2.data(), &XdgOutput::changed); + QVERIFY(xdgO2ChangedSpy.isValid()); + QVERIFY(xdgO2ChangedSpy.wait()); + QCOMPARE(xdgO2->logicalPosition(), geometries.at(1).topLeft()); + QCOMPARE(xdgO2->logicalSize(), geometries.at(1).size()); + // now let's try to remove one output again outputAnnouncedSpy.clear(); outputRemovedSpy.clear(); diff --git a/plugins/platforms/drm/drm_output.h b/plugins/platforms/drm/drm_output.h --- a/plugins/platforms/drm/drm_output.h +++ b/plugins/platforms/drm/drm_output.h @@ -41,6 +41,7 @@ class OutputDeviceInterface; class OutputChangeSet; class OutputManagementInterface; +class XdgOutputInterface; } } @@ -184,6 +185,7 @@ drmModeModeInfo m_mode; Edid m_edid; QPointer m_waylandOutput; + QPointer m_xdgOutput; QPointer m_waylandOutputDevice; QPointer m_changeset; KWin::ScopedDrmPointer<_drmModeProperty, &drmModeFreeProperty> m_dpms; diff --git a/plugins/platforms/drm/drm_output.cpp b/plugins/platforms/drm/drm_output.cpp --- a/plugins/platforms/drm/drm_output.cpp +++ b/plugins/platforms/drm/drm_output.cpp @@ -39,6 +39,7 @@ #include #include #include +#include // KF5 #include #include @@ -181,7 +182,7 @@ QRect DrmOutput::geometry() const { - return QRect(m_globalPos, pixelSize() / scale()); + return QRect(m_globalPos, pixelSize() / m_scale); } qreal DrmOutput::scale() const @@ -344,12 +345,17 @@ m_waylandOutput.clear(); } m_waylandOutput = waylandServer()->display()->createOutput(); + m_xdgOutput = waylandServer()->xdgOutputManager()->createXdgOutput(m_waylandOutput, m_waylandOutput); connect(this, &DrmOutput::modeChanged, this, [this] { if (m_waylandOutput.isNull()) { return; } m_waylandOutput->setCurrentMode(QSize(m_mode.hdisplay, m_mode.vdisplay), refreshRateForMode(&m_mode)); + if (m_xdgOutput) { + m_xdgOutput->setLogicalSize(pixelSize() / m_scale); + m_xdgOutput->done(); + } } ); m_waylandOutput->setManufacturer(m_waylandOutputDevice->manufacturer()); @@ -785,6 +791,10 @@ if (m_waylandOutputDevice) { m_waylandOutputDevice->setGlobalPosition(pos); } + if (m_xdgOutput) { + m_xdgOutput->setLogicalPosition(pos); + m_xdgOutput->done(); + } } void DrmOutput::setScale(qreal scale) @@ -796,6 +806,10 @@ if (m_waylandOutputDevice) { m_waylandOutputDevice->setScale(scale); } + if (m_xdgOutput) { + m_xdgOutput->setLogicalSize(pixelSize() / m_scale); + m_xdgOutput->done(); + } } void DrmOutput::setChanges(KWayland::Server::OutputChangeSet *changes) diff --git a/wayland_server.h b/wayland_server.h --- a/wayland_server.h +++ b/wayland_server.h @@ -60,6 +60,7 @@ class OutputConfigurationInterface; class XdgShellInterface; class XdgForeignInterface; +class XdgOutputManagerInterface; } } @@ -104,6 +105,10 @@ KWayland::Server::ServerSideDecorationManagerInterface *decorationManager() const { return m_decorationManager; } + KWayland::Server::XdgOutputManagerInterface *xdgOutputManager() const { + return m_xdgOutputManager; + } + QList clients() const { return m_clients; } @@ -227,6 +232,7 @@ KWayland::Server::AppMenuManagerInterface *m_appMenuManager = nullptr; KWayland::Server::ServerSideDecorationPaletteManagerInterface *m_paletteManager = nullptr; KWayland::Server::IdleInterface *m_idle = nullptr; + KWayland::Server::XdgOutputManagerInterface *m_xdgOutputManager = nullptr; struct { KWayland::Server::ClientConnection *client = nullptr; QMetaObject::Connection destroyConnection; diff --git a/wayland_server.cpp b/wayland_server.cpp --- a/wayland_server.cpp +++ b/wayland_server.cpp @@ -58,6 +58,8 @@ #include #include #include +#include + // Qt #include @@ -354,6 +356,9 @@ }); m_outputManagement->create(); + m_xdgOutputManager = m_display->createXdgOutputManager(m_display); + m_xdgOutputManager->create(); + m_display->createSubCompositor(m_display)->create(); m_XdgForeign = m_display->createXdgForeignInterface(m_display); @@ -453,11 +458,18 @@ Q_ASSERT(s); for (int i = 0; i < s->count(); ++i) { OutputInterface *output = m_display->createOutput(m_display); + auto xdgOutput = xdgOutputManager()->createXdgOutput(output, output); + output->setScale(s->scale(i)); const QRect &geo = s->geometry(i); output->setGlobalPosition(geo.topLeft()); output->setPhysicalSize(s->physicalSize(i).toSize()); output->addMode(geo.size()); + + xdgOutput->setLogicalPosition(geo.topLeft()); + xdgOutput->setLogicalSize(geo.size()); + xdgOutput->done(); + output->create(); } }