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
This commit is contained in:
parent
d4a825a9cc
commit
1403fcf316
5 changed files with 52 additions and 1 deletions
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue