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

feat(kcm): control scale

Summary:
Some backends might not transmit scale information. For these save the scale
value in the control file on change.

Loading it from there is unproblematic in all three cases:
* No scale value in file. Then falls back to libkscreen's value (default = 1).
* Scale values are the same, that means backend transmits scale.
* Backend does not transmit and scale is different, then prefer control file.

Reviewers: #plasma

Subscribers: plasma-devel

Tags: #plasma

Differential Revision: https://phabricator.kde.org/D26481
parent b3a8dbbb
......@@ -277,6 +277,72 @@ void ControlConfig::setOutputRetention(const QString &outputId, const QString &o
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<qreal>() ? 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<QVariant>::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 @@ QString ControlOutput::filePath() const
return filePathFromHash(m_output->hashMd5());
}
qreal ControlOutput::getScale() const
{
const auto val = constInfo()[QStringLiteral("scale")];
return val.canConvert<qreal>() ? 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")];
......
......@@ -77,6 +77,11 @@ public:
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 @@ public:
// TODO: scale auto value
qreal getScale() const;
void setScale(qreal value);
bool getAutoRotate() const;
void setAutoRotate(bool value);
......
......@@ -67,9 +67,25 @@ void ConfigHandler::setConfig(KScreen::ConfigPtr config)
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 @@ void ConfigHandler::updateInitialConfig()
return;
}
m_initialConfig = qobject_cast<GetConfigOperation*>(op)->config();
for (auto output : m_config->outputs()) {
resetScale(output);
}
checkNeedsSave();
});
}
......@@ -262,6 +281,16 @@ void ConfigHandler::setRetention(int retention)
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);
......
......@@ -47,6 +47,9 @@ public:
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 @@ private:
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;
......
......@@ -90,7 +90,7 @@ bool OutputModel::setData(const QModelIndex &index,
return false;
}
const Output &output = m_outputs[index.row()];
Output &output = m_outputs[index.row()];
switch (role) {
case PositionRole:
if (value.canConvert<QPoint>()) {
......@@ -149,6 +149,7 @@ bool OutputModel::setData(const QModelIndex &index,
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;
......
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