2023-11-05 23:09:33 +00:00
|
|
|
// SPDX-FileCopyrightText: 2022-2023 Devin Lin <devin@kde.org>
|
|
|
|
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
2022-03-17 04:33:13 +00:00
|
|
|
|
|
|
|
|
#include "screenrotationutil.h"
|
|
|
|
|
|
|
|
|
|
#include <fcntl.h>
|
|
|
|
|
#include <unistd.h>
|
|
|
|
|
|
2023-11-05 23:09:33 +00:00
|
|
|
#include <kscreen/configmonitor.h>
|
|
|
|
|
#include <kscreen/getconfigoperation.h>
|
|
|
|
|
#include <kscreen/output.h>
|
|
|
|
|
#include <kscreen/setconfigoperation.h>
|
|
|
|
|
|
2022-03-17 04:33:13 +00:00
|
|
|
#include <QDebug>
|
2023-11-05 23:09:33 +00:00
|
|
|
#include <QOrientationSensor>
|
2024-10-04 05:41:29 +00:00
|
|
|
#include <QTimer>
|
2022-03-17 04:33:13 +00:00
|
|
|
|
|
|
|
|
ScreenRotationUtil::ScreenRotationUtil(QObject *parent)
|
|
|
|
|
: QObject{parent}
|
2023-11-05 23:09:33 +00:00
|
|
|
, m_config{nullptr}
|
|
|
|
|
, m_sensor{new QOrientationSensor(this)}
|
2022-03-17 04:33:13 +00:00
|
|
|
{
|
2023-11-05 23:09:33 +00:00
|
|
|
connect(m_sensor, &QOrientationSensor::activeChanged, this, &ScreenRotationUtil::availableChanged);
|
|
|
|
|
|
2024-11-08 07:56:35 +00:00
|
|
|
connect(KScreen::ConfigMonitor::instance(), &KScreen::ConfigMonitor::configurationChanged, this, [this]() {
|
|
|
|
|
Q_EMIT autoScreenRotationEnabledChanged();
|
|
|
|
|
});
|
|
|
|
|
|
2023-11-05 23:09:33 +00:00
|
|
|
connect(new KScreen::GetConfigOperation(), &KScreen::GetConfigOperation::finished, this, [this](auto *op) {
|
|
|
|
|
m_config = qobject_cast<KScreen::GetConfigOperation *>(op)->config();
|
2025-10-08 00:30:48 +00:00
|
|
|
if (!m_config) {
|
|
|
|
|
qDebug() << "screenrotationutil: Unable to obtain kscreen config";
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2024-11-08 07:56:35 +00:00
|
|
|
KScreen::ConfigMonitor::instance()->addConfig(m_config);
|
2023-11-05 23:09:33 +00:00
|
|
|
|
2023-12-18 01:46:40 +00:00
|
|
|
// update all screens with event connect
|
|
|
|
|
for (KScreen::OutputPtr output : m_config->outputs()) {
|
|
|
|
|
connect(output.data(), &KScreen::Output::autoRotatePolicyChanged, this, &ScreenRotationUtil::autoScreenRotationEnabledChanged);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// listen to all new screens and connect
|
|
|
|
|
connect(m_config.data(), &KScreen::Config::outputAdded, this, [this](const auto &output) {
|
|
|
|
|
Q_EMIT autoScreenRotationEnabledChanged();
|
|
|
|
|
connect(output.data(), &KScreen::Output::autoRotatePolicyChanged, this, &ScreenRotationUtil::autoScreenRotationEnabledChanged);
|
|
|
|
|
});
|
2024-01-30 19:57:11 +00:00
|
|
|
|
|
|
|
|
// trigger update
|
|
|
|
|
Q_EMIT autoScreenRotationEnabledChanged();
|
2023-11-05 23:09:33 +00:00
|
|
|
});
|
2022-03-17 04:33:13 +00:00
|
|
|
}
|
|
|
|
|
|
2023-11-05 23:09:33 +00:00
|
|
|
bool ScreenRotationUtil::autoScreenRotationEnabled()
|
2022-03-17 04:33:13 +00:00
|
|
|
{
|
2023-11-05 23:09:33 +00:00
|
|
|
if (!m_config) {
|
2022-03-17 04:33:13 +00:00
|
|
|
return false;
|
|
|
|
|
}
|
2023-11-05 23:09:33 +00:00
|
|
|
const auto outputs = m_config->outputs();
|
2022-03-17 04:33:13 +00:00
|
|
|
|
2023-11-05 23:09:33 +00:00
|
|
|
for (KScreen::OutputPtr output : outputs) {
|
2024-01-30 19:57:11 +00:00
|
|
|
if (output->autoRotatePolicy() == KScreen::Output::AutoRotatePolicy::Never) {
|
2023-11-05 23:09:33 +00:00
|
|
|
return false;
|
|
|
|
|
}
|
2022-03-17 04:33:13 +00:00
|
|
|
}
|
2023-11-05 23:09:33 +00:00
|
|
|
|
|
|
|
|
return true;
|
2022-03-17 04:33:13 +00:00
|
|
|
}
|
2022-10-04 15:09:18 +00:00
|
|
|
|
2023-11-05 23:09:33 +00:00
|
|
|
void ScreenRotationUtil::setAutoScreenRotationEnabled(bool value)
|
2024-10-04 05:41:29 +00:00
|
|
|
{
|
|
|
|
|
// Don't execute immediately, in case the screen rotation
|
|
|
|
|
// deletes the caller mid-function call, causing a crash.
|
|
|
|
|
QTimer::singleShot(0, this, [this, value]() {
|
|
|
|
|
actuallySetAutoScreenRotationEnabled(value);
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool ScreenRotationUtil::isAvailable()
|
|
|
|
|
{
|
|
|
|
|
return m_sensor->connectToBackend();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ScreenRotationUtil::actuallySetAutoScreenRotationEnabled(bool value)
|
2022-10-04 15:09:18 +00:00
|
|
|
{
|
2023-11-05 23:09:33 +00:00
|
|
|
if (!m_config) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
2023-02-10 07:00:45 +00:00
|
|
|
|
2023-11-05 23:09:33 +00:00
|
|
|
KScreen::Output::AutoRotatePolicy policy = value ? KScreen::Output::AutoRotatePolicy::Always : KScreen::Output::AutoRotatePolicy::Never;
|
2023-02-10 07:00:45 +00:00
|
|
|
|
2023-11-05 23:09:33 +00:00
|
|
|
const auto outputs = m_config->outputs();
|
|
|
|
|
for (KScreen::OutputPtr output : outputs) {
|
2024-11-09 17:32:39 +00:00
|
|
|
if (!output) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
2023-11-05 23:09:33 +00:00
|
|
|
if (output->autoRotatePolicy() != policy) {
|
|
|
|
|
output->setAutoRotatePolicy(policy);
|
2023-02-10 07:00:45 +00:00
|
|
|
}
|
2023-11-05 23:09:33 +00:00
|
|
|
}
|
2023-02-10 07:00:45 +00:00
|
|
|
|
2023-11-06 02:56:50 +00:00
|
|
|
auto setop = new KScreen::SetConfigOperation(m_config, this);
|
2025-11-04 03:11:57 +00:00
|
|
|
connect(setop, &KScreen::SetConfigOperation::finished, this, [this]() {
|
|
|
|
|
Q_EMIT autoScreenRotationEnabledChanged();
|
|
|
|
|
});
|
2023-11-05 23:09:33 +00:00
|
|
|
}
|