diff --git a/common/control.h b/common/control.h --- a/common/control.h +++ b/common/control.h @@ -77,6 +77,11 @@ void setOutputRetention(const KScreen::OutputPtr &output, OutputRetention value); void setOutputRetention(const QString &outputId, const QString &outputName, OutputRetention value); + qreal getScale(const KScreen::OutputPtr &output) const; + qreal getScale(const QString &outputId, const QString &outputName) const; + void setScale(const KScreen::OutputPtr &output, qreal value); + void setScale(const QString &outputId, const QString &outputName, qreal value); + bool getAutoRotate(const KScreen::OutputPtr &output) const; bool getAutoRotate(const QString &outputId, const QString &outputName) const; void setAutoRotate(const KScreen::OutputPtr &output, bool value); @@ -117,6 +122,9 @@ // TODO: scale auto value + qreal getScale() const; + void setScale(qreal value); + bool getAutoRotate() const; void setAutoRotate(bool value); diff --git a/common/control.cpp b/common/control.cpp --- a/common/control.cpp +++ b/common/control.cpp @@ -277,6 +277,72 @@ setOutputs(outputsInfo); } +qreal ControlConfig::getScale(const KScreen::OutputPtr &output) const +{ + return getScale(output->hashMd5(), output->name()); +} + +qreal ControlConfig::getScale(const QString &outputId, const QString &outputName) const +{ + const auto retention = getOutputRetention(outputId, outputName); + if (retention == OutputRetention::Individual) { + const QVariantList outputsInfo = getOutputs(); + for (const auto variantInfo : outputsInfo) { + const QVariantMap info = variantInfo.toMap(); + if (!infoIsOutput(info, outputId, outputName)) { + continue; + } + const auto val = info[QStringLiteral("scale")]; + return val.canConvert() ? val.toReal() : -1; + } + } + // Retention is global or info for output not in config control file. + if (auto *outputControl = getOutputControl(outputId, outputName)) { + return outputControl->getScale(); + } + + // Info for output not found. + return -1; + } + +void ControlConfig::setScale(const KScreen::OutputPtr &output, qreal value) +{ + setScale(output->hashMd5(), output->name(), value); +} + +// TODO: combine methods (templated functions) +void ControlConfig::setScale(const QString &outputId, const QString &outputName, qreal value) +{ + QList::iterator it; + QVariantList outputsInfo = getOutputs(); + + auto setOutputScale = [&outputId, &outputName, value, this]() { + if (auto *control = getOutputControl(outputId, outputName)) { + control->setScale(value); + } + + }; + + for (it = outputsInfo.begin(); it != outputsInfo.end(); ++it) { + QVariantMap outputInfo = (*it).toMap(); + if (!infoIsOutput(outputInfo, outputId, outputName)) { + continue; + } + outputInfo[QStringLiteral("scale")] = value; + *it = outputInfo; + setOutputs(outputsInfo); + setOutputScale(); + return; + } + // no entry yet, create one + auto outputInfo = createOutputInfo(outputId, outputName); + outputInfo[QStringLiteral("scale")] = value; + + outputsInfo << outputInfo; + setOutputs(outputsInfo); + setOutputScale(); +} + bool ControlConfig::getAutoRotate(const KScreen::OutputPtr &output) const { return getAutoRotate(output->hashMd5(), output->name()); @@ -465,6 +531,21 @@ return filePathFromHash(m_output->hashMd5()); } +qreal ControlOutput::getScale() const +{ + const auto val = constInfo()[QStringLiteral("scale")]; + return val.canConvert() ? val.toReal() : -1; +} + +void ControlOutput::setScale(qreal value) +{ + auto &infoMap = info(); + if (infoMap.isEmpty()) { + infoMap = createOutputInfo(m_output->hashMd5(), m_output->name()); + } + infoMap[QStringLiteral("scale")] = value; +} + bool ControlOutput::getAutoRotate() const { const auto val = constInfo()[QStringLiteral("autorotate")]; 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); + qreal scale(const KScreen::OutputPtr &output) const; + void setScale(KScreen::OutputPtr &output, qreal scale); + KScreen::OutputPtr replicationSource(const KScreen::OutputPtr &output) const; void setReplicationSource(KScreen::OutputPtr &output, const KScreen::OutputPtr &source); @@ -69,6 +72,7 @@ void primaryOutputSelected(int index); void primaryOutputChanged(const KScreen::OutputPtr &output); void initOutput(const KScreen::OutputPtr &output); + void resetScale(const KScreen::OutputPtr &output); KScreen::ConfigPtr m_config = nullptr; KScreen::ConfigPtr m_initialConfig; diff --git a/kcm/config_handler.cpp b/kcm/config_handler.cpp --- a/kcm/config_handler.cpp +++ b/kcm/config_handler.cpp @@ -67,9 +67,25 @@ Q_EMIT outputModelChanged(); } +void ConfigHandler::resetScale(const KScreen::OutputPtr &output) +{ + // Load scale control (either not set, same or windowing system does not transmit scale). + const qreal scale = m_control->getScale(output); + if (scale > 0) { + output->setScale(scale); + for (auto initialOutput : m_initialConfig->outputs()) { + if (initialOutput->id() == output->id()) { + initialOutput->setScale(scale); + break; + } + } + } +} + void ConfigHandler::initOutput(const KScreen::OutputPtr &output) { if (output->isConnected()) { + resetScale(output); m_outputs->add(output); } connect(output.data(), &KScreen::Output::isConnectedChanged, @@ -87,6 +103,9 @@ return; } m_initialConfig = qobject_cast(op)->config(); + for (auto output : m_config->outputs()) { + resetScale(output); + } checkNeedsSave(); }); } @@ -262,6 +281,16 @@ Q_EMIT changed(); } +qreal ConfigHandler::scale(const KScreen::OutputPtr &output) const +{ + return m_control->getScale(output); +} + +void ConfigHandler::setScale(KScreen::OutputPtr &output, qreal scale) +{ + m_control->setScale(output, scale); +} + KScreen::OutputPtr ConfigHandler::replicationSource(const KScreen::OutputPtr &output) const { return m_control->getReplicationSource(output); diff --git a/kcm/output_model.cpp b/kcm/output_model.cpp --- a/kcm/output_model.cpp +++ b/kcm/output_model.cpp @@ -90,7 +90,7 @@ return false; } - const Output &output = m_outputs[index.row()]; + Output &output = m_outputs[index.row()]; switch (role) { case PositionRole: if (value.canConvert()) { @@ -149,6 +149,7 @@ const qreal scale = value.toReal(&ok); if (ok && !qFuzzyCompare(output.ptr->scale(), scale)) { output.ptr->setScale(scale); + m_config->setScale(output.ptr, scale); Q_EMIT sizeChanged(); Q_EMIT dataChanged(index, index, {role, SizeRole}); return true;