diff --git a/common/control.cpp b/common/control.cpp --- a/common/control.cpp +++ b/common/control.cpp @@ -389,8 +389,8 @@ { QList::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(); diff --git a/kcm/config_handler.h b/kcm/config_handler.h --- a/kcm/config_handler.h +++ b/kcm/config_handler.h @@ -47,6 +47,9 @@ 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(); diff --git a/kcm/config_handler.cpp b/kcm/config_handler.cpp --- a/kcm/config_handler.cpp +++ b/kcm/config_handler.cpp @@ -262,6 +262,17 @@ 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) { diff --git a/kcm/output_model.h b/kcm/output_model.h --- a/kcm/output_model.h +++ b/kcm/output_model.h @@ -124,7 +124,8 @@ 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; diff --git a/kcm/output_model.cpp b/kcm/output_model.cpp --- a/kcm/output_model.cpp +++ b/kcm/output_model.cpp @@ -70,7 +70,7 @@ 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 @@ 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 @@ } 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 @@ 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 @@ 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; } } diff --git a/kded/config.cpp b/kded/config.cpp --- a/kded/config.cpp +++ b/kded/config.cpp @@ -207,11 +207,6 @@ 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(); diff --git a/kded/output.cpp b/kded/output.cpp --- a/kded/output.cpp +++ b/kded/output.cpp @@ -327,18 +327,6 @@ } 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 @@ } } } + + 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)