Implement Primary Displays on the wayland session

Adopts the kde_outputmanagement_v2 hooks for it
This commit is contained in:
Aleix Pol 2021-10-25 02:05:23 +02:00 committed by Aleix Pol Gonzalez
parent 2e8f811d3f
commit c1e9cc283d
6 changed files with 57 additions and 0 deletions

View file

@ -450,12 +450,16 @@ void DrmBackend::readOutputsConfiguration()
}
const auto outputsInfo = KWinKScreenIntegration::outputsConfig(m_outputs);
AbstractOutput *primaryOutput = m_outputs.constFirst();
// default position goes from left to right
QPoint pos(0, 0);
for (auto it = m_outputs.begin(); it != m_outputs.end(); ++it) {
const QJsonObject outputInfo = outputsInfo[*it];
qCDebug(KWIN_DRM) << "Reading output configuration for " << *it;
if (!outputInfo.isEmpty()) {
if (outputInfo["primary"].toBool()) {
primaryOutput = *it;
}
const QJsonObject pos = outputInfo["pos"].toObject();
(*it)->moveTo({pos["x"].toInt(), pos["y"].toInt()});
if (const QJsonValue scale = outputInfo["scale"]; !scale.isUndefined()) {
@ -473,6 +477,7 @@ void DrmBackend::readOutputsConfiguration()
}
pos.setX(pos.x() + (*it)->geometry().width());
}
setPrimaryOutput(primaryOutput);
}
void DrmBackend::enableOutput(DrmAbstractOutput *output, bool enable)

View file

@ -40,6 +40,17 @@ Platform::Platform(QObject *parent)
{
setSoftwareCursorForced(false);
connect(Cursors::self(), &Cursors::currentCursorRendered, this, &Platform::cursorRendered);
connect(this, &Platform::outputDisabled, this, [this] (AbstractOutput *output) {
if (m_primaryOutput == output) {
setPrimaryOutput(enabledOutputs().value(0, nullptr));
}
});
connect(this, &Platform::outputEnabled, this, [this] (AbstractOutput *output) {
if (!m_primaryOutput) {
setPrimaryOutput(output);
}
});
}
Platform::~Platform()
@ -152,6 +163,10 @@ void Platform::requestOutputsChange(KWaylandServer::OutputConfigurationV2Interfa
}
}
if (config->primaryChanged()) {
setPrimaryOutput(findOutput(config->primary()->uuid()));
}
Q_EMIT screens()->changed();
config->setApplied();
}
@ -637,4 +652,14 @@ void Platform::setSceneEglGlobalShareContext(EGLContext context)
m_globalShareContext = context;
}
void Platform::setPrimaryOutput(AbstractOutput *primary)
{
if (primary == m_primaryOutput) {
return;
}
Q_ASSERT(kwinApp()->isTerminating() || primary->isEnabled());
m_primaryOutput = primary;
Q_EMIT primaryOutputChanged(primary);
}
}

View file

@ -398,6 +398,18 @@ public:
virtual AbstractOutput *createVirtualOutput(const QString &name, const QSize &size, qreal scaling);
virtual void removeVirtualOutput(AbstractOutput *output);
/**
* @returns the primary output amomg the enabled outputs
*/
AbstractOutput *primaryOutput() const {
return m_primaryOutput;
}
/**
* Assigns a the @p primary output among the enabled outputs
*/
void setPrimaryOutput(AbstractOutput *primary);
public Q_SLOTS:
void pointerMotion(const QPointF &position, quint32 time);
void pointerButtonPressed(quint32 button, quint32 time);
@ -455,6 +467,8 @@ Q_SIGNALS:
*/
void outputDisabled(AbstractOutput *output);
void primaryOutputChanged(AbstractOutput *primaryOutput);
protected:
explicit Platform(QObject *parent = nullptr);
void setSoftwareCursor(bool set);
@ -527,6 +541,7 @@ private:
bool m_supportsOutputChanges = false;
bool m_isPerScreenRenderingEnabled = false;
CompositingType m_selectedCompositor = NoCompositing;
AbstractOutput *m_primaryOutput = nullptr;
};
}

View file

@ -51,6 +51,7 @@
#include <KWaylandServer/blur_interface.h>
#include <KWaylandServer/outputmanagement_v2_interface.h>
#include <KWaylandServer/outputconfiguration_v2_interface.h>
#include <KWaylandServer/primaryoutput_v1_interface.h>
#include <KWaylandServer/xdgactivation_v1_interface.h>
#include <KWaylandServer/xdgdecoration_v1_interface.h>
#include <KWaylandServer/xdgshell_interface.h>
@ -274,6 +275,13 @@ void WaylandServer::initPlatform()
connect(kwinApp()->platform(), &Platform::outputEnabled, this, &WaylandServer::handleOutputEnabled);
connect(kwinApp()->platform(), &Platform::outputDisabled, this, &WaylandServer::handleOutputDisabled);
connect(kwinApp()->platform(), &Platform::primaryOutputChanged, this, [this] (AbstractOutput *primaryOutput) {
m_primary->setPrimaryOutput(primaryOutput->name());
});
if (auto primaryOutput = kwinApp()->platform()->primaryOutput()) {
m_primary->setPrimaryOutput(primaryOutput->name());
}
const QVector<AbstractOutput *> outputs = kwinApp()->platform()->outputs();
for (AbstractOutput *output : outputs) {
handleOutputAdded(output);
@ -493,6 +501,7 @@ bool WaylandServer::init(InitializationFlags flags)
this, [](KWaylandServer::OutputConfigurationV2Interface *config) {
kwinApp()->platform()->requestOutputsChange(config);
});
m_primary = new PrimaryOutputV1Interface(m_display, m_display);
m_xdgOutputManagerV1 = new XdgOutputManagerV1Interface(m_display, m_display);
new SubCompositorInterface(m_display, m_display);

View file

@ -38,6 +38,7 @@ class PlasmaShellInterface;
class PlasmaWindowActivationFeedbackInterface;
class PlasmaVirtualDesktopManagementInterface;
class PlasmaWindowManagementInterface;
class PrimaryOutputV1Interface;
class OutputManagementV2Interface;
class XdgForeignV2Interface;
class XdgOutputManagerV1Interface;
@ -269,6 +270,7 @@ private:
KWaylandServer::ClientConnection *m_screenLockerClientConnection = nullptr;
KWaylandServer::XdgForeignV2Interface *m_XdgForeign = nullptr;
KWaylandServer::KeyStateInterface *m_keyState = nullptr;
KWaylandServer::PrimaryOutputV1Interface *m_primary = nullptr;
QList<AbstractClient *> m_clients;
InitializationFlags m_initFlags;
QHash<AbstractWaylandOutput *, WaylandOutput *> m_waylandOutputs;

View file

@ -68,6 +68,7 @@ WaylandOutputDevice::WaylandOutputDevice(AbstractWaylandOutput *output, QObject
m_outputDeviceV2->setCapabilities(kwinCapabilitiesToOutputDeviceCapabilities(output->capabilities()));
m_outputDeviceV2->setVrrPolicy(kwinVrrPolicyToOutputDeviceVrrPolicy(output->vrrPolicy()));
m_outputDeviceV2->setRgbRange(kwinRgbRangeToOutputDeviceRgbRange(output->rgbRange()));
m_outputDeviceV2->setName(output->name());
updateModes(output);