quicksettings/screenrotation: Fix it by porting to changed API

It appears that the screen rotation DBus API was dropped with https://invent.kde.org/plasma/kscreen/-/merge_requests/237

Port to the new API.

Fixes https://invent.kde.org/plasma/plasma-mobile/-/issues/257
This commit is contained in:
Devin Lin 2023-11-05 15:09:33 -08:00
parent a96c948120
commit a0b9c2c569
8 changed files with 65 additions and 92 deletions

View file

@ -18,6 +18,7 @@ Dependencies:
'frameworks/modemmanager-qt': '@latest-kf6'
'frameworks/networkmanager-qt': '@latest-kf6'
'frameworks/kjobwidgets': '@latest-kf6'
'plasma/libkscreen': '@same'
'plasma/plasma-framework': '@same'
'plasma/kwin': '@same'
'plasma/plasma-workspace': '@same'

View file

@ -50,6 +50,7 @@ find_package(Qt6 ${QT_MIN_VERSION} CONFIG REQUIRED
Qml
Quick
Gui
Sensors
)
find_package(KF6 ${KF6_MIN_VERSION} REQUIRED COMPONENTS
@ -72,6 +73,8 @@ find_package(KF6 ${KF6_MIN_VERSION} REQUIRED COMPONENTS
JobWidgets
)
find_package(KF6Screen CONFIG REQUIRED)
find_package(PkgConfig REQUIRED)
pkg_check_modules(GOBJECT gobject-2.0 REQUIRED IMPORTED_TARGET)

View file

@ -1,12 +1,9 @@
# SPDX-FileCopyrightText: 2022 Devin Lin <devin@kde.org>
# SPDX-License-Identifier: GPL-2.0-or-later
qt_add_dbus_interfaces(DBUS_SRCS dbus/org.kde.KScreen.xml)
set(screenrotationplugin_SRCS
screenrotationplugin.cpp
screenrotationutil.cpp
${DBUS_SRCS}
)
add_library(screenrotationplugin ${screenrotationplugin_SRCS})
@ -16,11 +13,13 @@ target_link_libraries(screenrotationplugin
Qt::Qml
Qt::Quick
Qt::DBus
Qt::Sensors
KF6::CoreAddons
KF6::ConfigCore
KF6::ConfigGui
KF6::I18n
KF6::Notifications
KF6::Screen
)
set_property(TARGET screenrotationplugin PROPERTY LIBRARY_OUTPUT_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/org/kde/plasma/quicksetting/screenrotation)

View file

@ -1,31 +0,0 @@
<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
<!--
- SPDX-FileCopyrightText: 2020-2022 Luca Weiss <luca@z3ntu.xyz>
- SPDX-FileCopyrightText: 2020 Bhushan Shah <bshah@kde.org>
- SPDX-FileCopyrightText: 2018 Kai Uwe Broulik <kde@privat.broulik.de>
- SPDX-FileCopyrightText: 2013-2014 Daniel Vrátil <dvratil@kde.org>
- SPDX-License-Identifier: GPL-2.0-or-later
-->
<node>
<interface name="org.kde.KScreen">
<method name="applyLayoutPreset">
<arg type="s" name="presetName" direction="in" />
</method>
<method name="getAutoRotate">
<arg type="b" direction="out" />
</method>
<method name="setAutoRotate">
<arg type="b" name="value" direction="in" />
</method>
<method name="isAutoRotateAvailable">
<arg type="b" direction="out" />
</method>
<signal name="outputConnected">
<arg type="s" name="outputName" direction="out" />
</signal>
<signal name="unknownOutputConnected">
<arg type="s" name="outputName" direction="out" />
</signal>
</interface>
</node>

View file

@ -10,9 +10,10 @@ QS.QuickSetting {
text: i18n("Auto-rotate")
icon: "rotation-allowed"
settingsCommand: "plasma-open-settings kcm_kscreen"
enabled: ScreenRotationUtil.screenRotationEnabled
enabled: ScreenRotationUtil.autoScreenRotationEnabled
available: ScreenRotationUtil.available
function toggle() {
ScreenRotationUtil.screenRotationEnabled = !enabled
ScreenRotationUtil.autoScreenRotationEnabled = !enabled
}
}

View file

@ -1,8 +1,5 @@
/*
* SPDX-FileCopyrightText: 2022 by Devin Lin <devin@kde.org>
*
* SPDX-License-Identifier: GPL-2.0-or-later
*/
// SPDX-FileCopyrightText: 2022-2023 Devin Lin <devin@kde.org>
// SPDX-License-Identifier: GPL-2.0-or-later
#include "screenrotationplugin.h"

View file

@ -1,64 +1,68 @@
/*
* SPDX-FileCopyrightText: 2022 by Devin Lin <devin@kde.org>
*
* SPDX-License-Identifier: GPL-2.0-or-later
*/
// SPDX-FileCopyrightText: 2022-2023 Devin Lin <devin@kde.org>
// SPDX-License-Identifier: GPL-2.0-or-later
#include "screenrotationutil.h"
#include <fcntl.h>
#include <unistd.h>
#include <kscreen/configmonitor.h>
#include <kscreen/getconfigoperation.h>
#include <kscreen/output.h>
#include <kscreen/setconfigoperation.h>
#include <QDebug>
#include <QOrientationSensor>
ScreenRotationUtil::ScreenRotationUtil(QObject *parent)
: QObject{parent}
, m_config{nullptr}
, m_sensor{new QOrientationSensor(this)}
{
m_kscreenInterface = new org::kde::KScreen(QStringLiteral("org.kde.kded6"), QStringLiteral("/modules/kscreen"), QDBusConnection::sessionBus(), this);
connect(m_sensor, &QOrientationSensor::activeChanged, this, &ScreenRotationUtil::availableChanged);
connect(new KScreen::GetConfigOperation(), &KScreen::GetConfigOperation::finished, this, [this](auto *op) {
m_config = qobject_cast<KScreen::GetConfigOperation *>(op)->config();
Q_EMIT autoScreenRotationEnabledChanged();
});
}
bool ScreenRotationUtil::screenRotation()
bool ScreenRotationUtil::autoScreenRotationEnabled()
{
QDBusPendingReply<bool> reply = m_kscreenInterface->getAutoRotate();
reply.waitForFinished();
if (reply.isError()) {
qWarning() << "Getting auto rotate failed:" << reply.error().name() << reply.error().message();
if (!m_config) {
return false;
}
const auto outputs = m_config->outputs();
for (KScreen::OutputPtr output : outputs) {
if (output->autoRotatePolicy() != KScreen::Output::AutoRotatePolicy::Always) {
return false;
} else {
return reply.value();
}
}
void ScreenRotationUtil::setScreenRotation(bool value)
{
QDBusPendingReply<> reply = m_kscreenInterface->setAutoRotate(value);
reply.waitForFinished();
if (reply.isError()) {
qWarning() << "Setting auto rotate failed:" << reply.error().name() << reply.error().message();
} else {
Q_EMIT screenRotationChanged(value);
return true;
}
void ScreenRotationUtil::setAutoScreenRotationEnabled(bool value)
{
if (!m_config) {
return;
}
KScreen::Output::AutoRotatePolicy policy = value ? KScreen::Output::AutoRotatePolicy::Always : KScreen::Output::AutoRotatePolicy::Never;
const auto outputs = m_config->outputs();
for (KScreen::OutputPtr output : outputs) {
if (output->autoRotatePolicy() != policy) {
output->setAutoRotatePolicy(policy);
}
}
Q_EMIT autoScreenRotationEnabledChanged();
}
bool ScreenRotationUtil::isAvailable()
{
QDBusPendingReply<bool> reply = m_kscreenInterface->isAutoRotateAvailable();
QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(reply, this);
connect(watcher, &QDBusPendingCallWatcher::finished, this, [this](QDBusPendingCallWatcher *watcher) {
QDBusPendingReply<bool> reply = *watcher;
if (reply.isError()) {
qWarning() << "Getting available failed:" << reply.error().name() << reply.error().message();
} else {
// make sure we don't go into an infinite loop
if (m_available != reply.value()) {
Q_EMIT availableChanged(m_available);
}
m_available = reply.value();
}
watcher->deleteLater();
});
return m_available;
return m_sensor->connectToBackend();
}

View file

@ -1,35 +1,34 @@
/*
* SPDX-FileCopyrightText: 2022 by Devin Lin <devin@kde.org>
*
* SPDX-License-Identifier: GPL-2.0-or-later
*/
// SPDX-FileCopyrightText: 2022-2023 Devin Lin <devin@kde.org>
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include <QObject>
#include <QOrientationSensor>
#include "kscreeninterface.h"
#include <kscreen/config.h>
class ScreenRotationUtil : public QObject
{
Q_OBJECT
Q_PROPERTY(bool screenRotationEnabled READ screenRotation WRITE setScreenRotation NOTIFY screenRotationChanged);
Q_PROPERTY(bool autoScreenRotationEnabled READ autoScreenRotationEnabled WRITE setAutoScreenRotationEnabled NOTIFY autoScreenRotationEnabledChanged);
Q_PROPERTY(bool available READ isAvailable NOTIFY availableChanged);
public:
ScreenRotationUtil(QObject *parent = nullptr);
bool screenRotation();
void setScreenRotation(bool value);
bool autoScreenRotationEnabled();
void setAutoScreenRotationEnabled(bool value);
bool isAvailable();
Q_SIGNALS:
void screenRotationChanged(bool value);
void availableChanged(bool value);
void autoScreenRotationEnabledChanged();
void availableChanged();
private:
org::kde::KScreen *m_kscreenInterface;
KScreen::ConfigPtr m_config;
QOrientationSensor *m_sensor;
bool m_available;
};