initialstart: Use proper libkscreen APIs to set display scaling

This commit is contained in:
Devin Lin 2023-11-05 19:08:28 -08:00
parent 5b429b49d1
commit a83a723e97
3 changed files with 39 additions and 49 deletions

View file

@ -17,6 +17,7 @@ target_link_libraries(prepareplugin
KF6::ConfigGui
KF6::I18n
KF6::Notifications
KF6::Screen
)
set_property(TARGET prepareplugin PROPERTY LIBRARY_OUTPUT_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/org/kde/plasma/mobileinitialstart/prepare)

View file

@ -3,17 +3,31 @@
#include "prepareutil.h"
#include <QDebug>
#include <QRegularExpression>
#include <kscreen/configmonitor.h>
#include <kscreen/getconfigoperation.h>
#include <kscreen/output.h>
#include <kscreen/setconfigoperation.h>
PrepareUtil::PrepareUtil(QObject *parent)
: QObject{parent}
, m_process{new QProcess{this}}
{
connect(m_process, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished), this, &PrepareUtil::receiveScalingFactor);
connect(new KScreen::GetConfigOperation(), &KScreen::GetConfigOperation::finished, this, [this](auto *op) {
m_config = qobject_cast<KScreen::GetConfigOperation *>(op)->config();
// HACK: we are using kscreen-doctor to determine scaling, should switch to API
m_process->start("kscreen-doctor", {"-o"});
int scaling = 100;
// to determine the scaling value:
// try to take the primary display's scaling, otherwise use the scaling of any of the displays
for (KScreen::OutputPtr output : m_config->outputs()) {
scaling = output->scale() * 100;
if (output->isPrimary()) {
break;
}
}
m_scaling = scaling;
Q_EMIT scalingChanged();
});
}
int PrepareUtil::scaling() const
@ -23,47 +37,25 @@ int PrepareUtil::scaling() const
void PrepareUtil::setScaling(int scaling)
{
if (scaling != m_scaling) {
const QString scalingNum = QString::number(((double)scaling) / 100);
qDebug() << "scaling" << scalingNum;
m_process->start("kscreen-doctor", {"output." + m_display + ".scale." + scalingNum});
m_scaling = scaling;
Q_EMIT scalingChanged();
if (!m_config) {
return;
}
const auto outputs = m_config->outputs();
qreal scalingNum = ((double)scaling) / 100;
for (KScreen::OutputPtr output : outputs) {
output->setScale(scalingNum);
}
auto setop = new KScreen::SetConfigOperation(m_config, this);
setop->exec();
m_scaling = scaling;
Q_EMIT scalingChanged();
}
QStringList PrepareUtil::scalingOptions()
{
return {"50%", "100%", "150%", "200%", "250%", "300%"};
}
void PrepareUtil::receiveScalingFactor(int exitCode, QProcess::ExitStatus exitStatus)
{
Q_UNUSED(exitCode)
Q_UNUSED(exitStatus)
// only trigger this slot once, on first time
disconnect(m_process, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished), this, &PrepareUtil::receiveScalingFactor);
// remove ansi color codes
const auto ansiEscape = QRegularExpression{"\\\u001B\\[.*?m"};
const auto output = QString::fromUtf8(m_process->readAllStandardOutput()).replace(ansiEscape, "").replace("\\n", " ");
auto split = output.split(" ");
// HACK: hardcode how we get the output from kscreen-doctor
// we assume the first display is the phone screen
for (int i = 0; i < split.size(); ++i) {
if (i == 2) {
m_display = split[i];
} else if (split[i] == "Scale:") {
if (i + 1 < split.size()) {
m_scaling = split[i + 1].toDouble() * 100;
Q_EMIT scalingChanged();
}
break;
}
}
}

View file

@ -6,6 +6,8 @@
#include <QObject>
#include <QProcess>
#include <kscreen/config.h>
class PrepareUtil : public QObject
{
Q_OBJECT
@ -23,12 +25,7 @@ public:
Q_SIGNALS:
void scalingChanged();
public Q_SLOTS:
void receiveScalingFactor(int exitCode, QProcess::ExitStatus exitStatus);
private:
int m_scaling;
QString m_display;
QProcess *m_process;
KScreen::ConfigPtr m_config;
};