Commit 1403fcf3 authored by David Edmundson's avatar David Edmundson

Add XDG Output support

Test Plan:
Very minimal expansion of unit tests which uses WaylandScreens
Wrote mini app to debug actual output of xdg-output for testing the DRM code

Main relevant user of this is xwayland > 1.20 which I don't have, so that
part remains untested

Reviewers: #plasma, graesslin

Reviewed By: #plasma, graesslin

Subscribers: romangg, graesslin, bshah, kwin

Tags: #kwin

Maniphest Tasks: T8501

Differential Revision: https://phabricator.kde.org/D12243
parent d4a825a9
......@@ -24,6 +24,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "wayland_server.h"
#include <KWayland/Client/output.h>
#include <KWayland/Client/xdgoutput.h>
#include <KWayland/Client/registry.h>
using namespace KWin;
......@@ -84,6 +85,8 @@ void ScreenChangesTest::testScreenAddRemove()
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 @@ void ScreenChangesTest::testScreenAddRemove()
QVERIFY(o2ChangedSpy.wait());
QCOMPARE(o2->geometry(), geometries.at(1));
//and check XDGOutput is synced
QScopedPointer<XdgOutput> 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<XdgOutput> 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();
......
......@@ -39,6 +39,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <KWayland/Server/outputdevice_interface.h>
#include <KWayland/Server/outputmanagement_interface.h>
#include <KWayland/Server/outputconfiguration_interface.h>
#include <KWayland/Server/xdgoutput_interface.h>
// KF5
#include <KConfigGroup>
#include <KLocalizedString>
......@@ -181,7 +182,7 @@ QSize DrmOutput::physicalSize() const
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 @@ void DrmOutput::initOutput()
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 @@ void DrmOutput::setGlobalPos(const QPoint &pos)
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 @@ void DrmOutput::setScale(qreal scale)
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)
......
......@@ -41,6 +41,7 @@ class OutputInterface;
class OutputDeviceInterface;
class OutputChangeSet;
class OutputManagementInterface;
class XdgOutputInterface;
}
}
......@@ -184,6 +185,7 @@ private:
drmModeModeInfo m_mode;
Edid m_edid;
QPointer<KWayland::Server::OutputInterface> m_waylandOutput;
QPointer<KWayland::Server::XdgOutputInterface> m_xdgOutput;
QPointer<KWayland::Server::OutputDeviceInterface> m_waylandOutputDevice;
QPointer<KWayland::Server::OutputChangeSet> m_changeset;
KWin::ScopedDrmPointer<_drmModeProperty, &drmModeFreeProperty> m_dpms;
......
......@@ -58,6 +58,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <KWayland/Server/outputconfiguration_interface.h>
#include <KWayland/Server/xdgshell_interface.h>
#include <KWayland/Server/xdgforeign_interface.h>
#include <KWayland/Server/xdgoutput_interface.h>
// Qt
#include <QThread>
......@@ -354,6 +356,9 @@ bool WaylandServer::init(const QByteArray &socketName, InitalizationFlags flags)
});
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 @@ void WaylandServer::syncOutputsToWayland()
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();
}
}
......
......@@ -60,6 +60,7 @@ class OutputManagementInterface;
class OutputConfigurationInterface;
class XdgShellInterface;
class XdgForeignInterface;
class XdgOutputManagerInterface;
}
}
......@@ -104,6 +105,10 @@ public:
KWayland::Server::ServerSideDecorationManagerInterface *decorationManager() const {
return m_decorationManager;
}
KWayland::Server::XdgOutputManagerInterface *xdgOutputManager() const {
return m_xdgOutputManager;
}
QList<ShellClient*> clients() const {
return m_clients;
}
......@@ -227,6 +232,7 @@ private:
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;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment