Commit b3a8dbbb authored by Roman Gilg's avatar Roman Gilg
Browse files

feat: use Control and logical size APIs for replicas

Summary:
Use the new Control API to load and save output replica information and the
logical size API in libkscreen to send the data to the windowing system.

Test Plan: Tested on Wayland in a two output configuration.

Reviewers: #kwin

Subscribers: plasma-devel

Tags: #plasma

Maniphest Tasks: T11222

Differential Revision: https://phabricator.kde.org/D26310
parent 19e6756f
......@@ -389,8 +389,8 @@ void ControlConfig::setReplicationSource(const QString &outputId, const QString
{
QList<QVariant>::iterator it;
QVariantList outputsInfo = getOutputs();
const QString sourceHash = source->hashMd5();
const QString sourceName = source->name();
const QString sourceHash = source ? source->hashMd5() : QStringLiteral("");
const QString sourceName = source ? source->name() : QStringLiteral("");
for (it = outputsInfo.begin(); it != outputsInfo.end(); ++it) {
QVariantMap outputInfo = (*it).toMap();
......
......@@ -262,6 +262,17 @@ void ConfigHandler::setRetention(int retention)
Q_EMIT changed();
}
KScreen::OutputPtr ConfigHandler::replicationSource(const KScreen::OutputPtr &output) const
{
return m_control->getReplicationSource(output);
}
void ConfigHandler::setReplicationSource(KScreen::OutputPtr &output,
const KScreen::OutputPtr &source)
{
m_control->setReplicationSource(output, source);
}
void ConfigHandler::writeControl()
{
if (!m_control) {
......
......@@ -47,6 +47,9 @@ public:
int retention() const;
void setRetention(int retention);
KScreen::OutputPtr replicationSource(const KScreen::OutputPtr &output) const;
void setReplicationSource(KScreen::OutputPtr &output, const KScreen::OutputPtr &source);
void writeControl();
void checkNeedsSave();
......
......@@ -70,7 +70,7 @@ QVariant OutputModel::data(const QModelIndex &index, int role) const
case ReplicationSourceModelRole:
return replicationSourceModel(output);
case ReplicationSourceIndexRole:
return replicationSourceIndex(index.row(), output->replicationSource());
return replicationSourceIndex(index.row());
case ReplicasModelRole:
return replicasModel(output);
case RefreshRatesRole:
......@@ -491,17 +491,27 @@ QVector<float> OutputModel::refreshRates(const KScreen::OutputPtr
return hits;
}
int OutputModel::replicationSourceId(const Output &output) const
{
const KScreen::OutputPtr source = m_config->replicationSource(output.ptr);
if (!source) {
return 0;
}
return source->id();
}
QStringList OutputModel::replicationSourceModel(const KScreen::OutputPtr &output) const
{
QStringList ret = { i18n("None") };
for (const auto &out : m_outputs) {
if (out.ptr->id() != output->id()) {
if (out.ptr->replicationSource() == output->id()) {
const int outSourceId = replicationSourceId(out);
if (outSourceId == output->id()) {
// 'output' is already source for replication, can't be replica itself
return { i18n("Replicated by other output") };
}
if (out.ptr->replicationSource()) {
if (outSourceId) {
// This 'out' is a replica. Can't be a replication source.
continue;
}
......@@ -521,24 +531,26 @@ bool OutputModel::setReplicationSourceIndex(int outputIndex, int sourceIndex)
}
Output &output = m_outputs[outputIndex];
const int oldSourceId = output.ptr->replicationSource();
const int oldSourceId = replicationSourceId(output);
if (sourceIndex < 0) {
if (oldSourceId == 0) {
// no change
return false;
}
output.ptr->setReplicationSource(0);
m_config->setReplicationSource(output.ptr, nullptr);
output.ptr->setLogicalSize(QSizeF());
resetPosition(output);
} else {
const int sourceId = m_outputs[sourceIndex].ptr->id();
if (oldSourceId == sourceId) {
const auto source = m_outputs[sourceIndex].ptr;
if (oldSourceId == source->id()) {
// no change
return false;
}
output.ptr->setReplicationSource(sourceId);
m_config->setReplicationSource(output.ptr, source);
output.posReset = output.ptr->pos();
output.ptr->setPos(m_outputs[sourceIndex].ptr->pos());
output.ptr->setPos(source->pos());
output.ptr->setLogicalSize(source->logicalSize());
}
reposition();
......@@ -563,8 +575,12 @@ bool OutputModel::setReplicationSourceIndex(int outputIndex, int sourceIndex)
return true;
}
int OutputModel::replicationSourceIndex(int outputIndex, int sourceId) const
int OutputModel::replicationSourceIndex(int outputIndex) const
{
const int sourceId = replicationSourceId(m_outputs[outputIndex]);
if (!sourceId) {
return 0;
}
for (int i = 0; i < m_outputs.size(); i++) {
const Output &output = m_outputs[i];
if (output.ptr->id() == sourceId) {
......@@ -580,7 +596,7 @@ QVariantList OutputModel::replicasModel(const KScreen::OutputPtr &output) const
for (int i = 0; i < m_outputs.size(); i++) {
const Output &out = m_outputs[i];
if (out.ptr->id() != output->id()) {
if (out.ptr->replicationSource() == output->id()) {
if (replicationSourceId(out) == output->id()) {
ret << i;
}
}
......
......@@ -124,7 +124,8 @@ private:
QStringList replicationSourceModel(const KScreen::OutputPtr &output) const;
bool setReplicationSourceIndex(int outputIndex, int sourceIndex);
int replicationSourceIndex(int outputIndex, int sourceId) const;
int replicationSourceIndex(int outputIndex) const;
int replicationSourceId(const Output &output) const;
QVariantList replicasModel(const KScreen::OutputPtr &output) const;
......
......@@ -207,11 +207,6 @@ bool Config::writeFile(const QString &filePath)
if (!out) {
return;
}
QString replicationSourceHash;
if (int sourceId = out->replicationSource()) {
replicationSourceHash = m_data->output(sourceId)->hashMd5();
}
info[QStringLiteral("replicate")] = replicationSourceHash;
QVariantMap pos;
pos[QStringLiteral("x")] = out->pos().x();
......
......@@ -327,18 +327,6 @@ void Output::readInOutputs(KScreen::ConfigPtr config, const QVariantList &output
}
infoFound = true;
readIn(output, info, control.getOutputRetention(output));
const QString replicationSourceHash = info[QStringLiteral("replicate")].toString();
if (replicationSourceHash.isEmpty()) {
output->setReplicationSource(0);
} else {
for (const KScreen::OutputPtr out : outputs) {
if (out != output && out->hashMd5() == replicationSourceHash) {
output->setReplicationSource(out->id());
break;
}
}
}
break;
}
if (!infoFound) {
......@@ -352,8 +340,22 @@ void Output::readInOutputs(KScreen::ConfigPtr config, const QVariantList &output
}
}
}
for (KScreen::OutputPtr output : outputs) {
auto replicationSource = control.getReplicationSource(output);
if (replicationSource) {
output->setPos(replicationSource->pos());
output->setLogicalSize(replicationSource->logicalSize());
} else {
output->setLogicalSize(QSizeF());
}
}
// TODO: this does not work at the moment with logical size replication. Deactivate for now.
// correct positional config regressions on global output data changes
#if 0
adjustPositions(config, outputsInfo);
#endif
}
static QVariantMap metadata(const KScreen::OutputPtr &output)
......
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