Commit 09cbed82 authored by Xaver Hugl's avatar Xaver Hugl
Browse files

Add adaptive sync setting

parent 18c7c051
......@@ -23,7 +23,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <QJsonDocument>
#include <kscreen/config.h>
#include <kscreen/output.h>
QString Control::s_dirName = QStringLiteral("control/");
......@@ -607,6 +606,75 @@ void ControlConfig::setOverscan(const QString &outputId, const QString &outputNa
setOutputOverscan();
}
KScreen::Output::VrrPolicy ControlConfig::getVrrPolicy(const KScreen::OutputPtr &output) const
{
return getVrrPolicy(output->hashMd5(), output->name());
}
KScreen::Output::VrrPolicy ControlConfig::getVrrPolicy(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("vrrpolicy")];
if (val.canConvert<uint>()) {
return static_cast<KScreen::Output::VrrPolicy>(val.toUInt());
} else {
return KScreen::Output::VrrPolicy::Automatic;
}
}
}
// Retention is global or info for output not in config control file.
if (auto *outputControl = getOutputControl(outputId, outputName)) {
return outputControl->vrrPolicy();
}
// Info for output not found.
return KScreen::Output::VrrPolicy::Automatic;
}
void ControlConfig::setVrrPolicy(const KScreen::OutputPtr &output, const KScreen::Output::VrrPolicy value)
{
setVrrPolicy(output->hashMd5(), output->name(), value);
}
void ControlConfig::setVrrPolicy(const QString &outputId, const QString &outputName, const KScreen::Output::VrrPolicy enumValue)
{
QList<QVariant>::iterator it;
QVariantList outputsInfo = getOutputs();
uint value = static_cast<uint>(enumValue);
auto setOutputVrr = [&outputId, &outputName, enumValue, this]() {
if (auto *control = getOutputControl(outputId, outputName)) {
control->setVrrPolicy(enumValue);
}
};
for (it = outputsInfo.begin(); it != outputsInfo.end(); ++it) {
QVariantMap outputInfo = (*it).toMap();
if (!infoIsOutput(outputInfo, outputId, outputName)) {
continue;
}
outputInfo[QStringLiteral("vrrpolicy")] = value;
*it = outputInfo;
setOutputs(outputsInfo);
setOutputVrr();
return;
}
// no entry yet, create one
auto outputInfo = createOutputInfo(outputId, outputName);
outputInfo[QStringLiteral("vrrpolicy")] = value;
outputsInfo << outputInfo;
setOutputs(outputsInfo);
setOutputVrr();
}
QVariantList ControlConfig::getOutputs() const
{
return constInfo()[QStringLiteral("outputs")].toList();
......@@ -719,3 +787,21 @@ void ControlOutput::setOverscan(uint32_t value)
}
infoMap[QStringLiteral("overscan")] = static_cast<uint>(value);
}
KScreen::Output::VrrPolicy ControlOutput::vrrPolicy() const
{
const auto val = constInfo()[QStringLiteral("vrrpolicy")];
if (val.canConvert<uint>()) {
return static_cast<KScreen::Output::VrrPolicy>(val.toUInt());
}
return KScreen::Output::VrrPolicy::Automatic;
}
void ControlOutput::setVrrPolicy(KScreen::Output::VrrPolicy value)
{
auto &infoMap = info();
if (infoMap.isEmpty()) {
infoMap = createOutputInfo(m_output->hashMd5(), m_output->name());
}
infoMap[QStringLiteral("vrrpolicy")] = static_cast<uint>(value);
}
......@@ -17,6 +17,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#ifndef COMMON_CONTROL_H
#define COMMON_CONTROL_H
#include <kscreen/output.h>
#include <kscreen/types.h>
#include <QObject>
......@@ -101,6 +102,11 @@ public:
void setOverscan(const KScreen::OutputPtr &output, const uint32_t value);
void setOverscan(const QString &outputId, const QString &outputName, const uint32_t value);
KScreen::Output::VrrPolicy getVrrPolicy(const KScreen::OutputPtr &output) const;
KScreen::Output::VrrPolicy getVrrPolicy(const QString &outputId, const QString &outputName) const;
void setVrrPolicy(const KScreen::OutputPtr &output, const KScreen::Output::VrrPolicy value);
void setVrrPolicy(const QString &outputId, const QString &outputName, const KScreen::Output::VrrPolicy value);
QString dirPath() const override;
QString filePath() const override;
......@@ -141,6 +147,9 @@ public:
uint32_t overscan() const;
void setOverscan(uint32_t value);
KScreen::Output::VrrPolicy vrrPolicy() const;
void setVrrPolicy(KScreen::Output::VrrPolicy value);
QString dirPath() const override;
QString filePath() const override;
......
......@@ -151,7 +151,8 @@ void ConfigHandler::checkNeedsSave()
|| autoRotate(output) != m_initialControl->getAutoRotate(output)
|| autoRotateOnlyInTabletMode(output)
!= m_initialControl->getAutoRotateOnlyInTabletMode(output)
|| output->overscan() != initialOutput->overscan();
|| output->overscan() != initialOutput->overscan()
|| output->vrrPolicy() != initialOutput->vrrPolicy();
}
// clang-format on
if (needsSave) {
......@@ -332,6 +333,16 @@ void ConfigHandler::setOverscan(const KScreen::OutputPtr &output, uint32_t value
m_control->setOverscan(output, value);
}
KScreen::Output::VrrPolicy ConfigHandler::vrrPolicy(const KScreen::OutputPtr &output) const
{
return m_control->getVrrPolicy(output);
}
void ConfigHandler::setVrrPolicy(const KScreen::OutputPtr &output, KScreen::Output::VrrPolicy value)
{
m_control->setVrrPolicy(output, value);
}
void ConfigHandler::writeControl()
{
if (!m_control) {
......
......@@ -68,6 +68,9 @@ public:
uint32_t overscan(const KScreen::OutputPtr &output) const;
void setOverscan(const KScreen::OutputPtr &output, uint32_t value);
KScreen::Output::VrrPolicy vrrPolicy(const KScreen::OutputPtr &output) const;
void setVrrPolicy(const KScreen::OutputPtr &output, KScreen::Output::VrrPolicy value);
void writeControl();
void checkNeedsSave();
......
......@@ -90,6 +90,8 @@ QVariant OutputModel::data(const QModelIndex &index, int role) const
return static_cast<uint32_t>(output->capabilities());
case OverscanRole:
return output->overscan();
case VrrPolicyRole:
return static_cast<uint32_t>(output->vrrPolicy());
}
return QVariant();
}
......@@ -193,6 +195,19 @@ bool OutputModel::setData(const QModelIndex &index, const QVariant &value, int r
return true;
}
break;
case VrrPolicyRole:
if (value.canConvert<uint32_t>()) {
Output &output = m_outputs[index.row()];
const auto policy = static_cast<KScreen::Output::VrrPolicy>(value.toUInt());
if (output.ptr->vrrPolicy() == policy) {
return false;
}
output.ptr->setVrrPolicy(policy);
m_config->setVrrPolicy(output.ptr, policy);
Q_EMIT dataChanged(index, index, {role});
return true;
}
break;
}
return false;
}
......@@ -219,6 +234,7 @@ QHash<int, QByteArray> OutputModel::roleNames() const
roles[ReplicasModelRole] = "replicasModel";
roles[CapabilitiesRole] = "capabilities";
roles[OverscanRole] = "overscan";
roles[VrrPolicyRole] = "vrrPolicy";
return roles;
}
......
......@@ -50,6 +50,7 @@ public:
ReplicasModelRole,
CapabilitiesRole,
OverscanRole,
VrrPolicyRole,
};
explicit OutputModel(ConfigHandler *configHandler);
......
......@@ -105,6 +105,21 @@ ColumnLayout {
onActivated: element.refreshRateIndex = currentIndex
}
Controls.ComboBox {
Kirigami.FormData.label: i18n("Adaptive sync:")
model: [
{ label: i18n("Never"), value: KScreen.Output.VrrPolicy.Never },
{ label: i18n("Always"), value: KScreen.Output.VrrPolicy.Always },
{ label: i18n("Automatic"), value: KScreen.Output.VrrPolicy.Automatic }
]
textRole: "label"
valueRole: "value"
visible: element.capabilities & KScreen.Output.Capability.Vrr
onActivated: element.vrrPolicy = currentValue
Component.onCompleted: currentIndex = indexOfValue(element.vrrPolicy);
}
Controls.SpinBox {
Kirigami.FormData.label: i18n("Overscan:")
from: 0
......
Supports Markdown
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