From e82af2b68198682ce360a54ba693280396f39207 Mon Sep 17 00:00:00 2001 From: Devin Lin Date: Sun, 5 Nov 2023 20:10:20 -0800 Subject: [PATCH] initialstart: Use DBus api to set brightness Port away from deprecated P5Support.DataSource, doesn't seem to work anyway in this case --- initialstart/modules/prepare/CMakeLists.txt | 3 + ...erManagement.Actions.BrightnessControl.xml | 33 ++++++++ .../prepare/package/contents/ui/main.qml | 61 ++++---------- initialstart/modules/prepare/prepareutil.cpp | 83 +++++++++++++++++++ initialstart/modules/prepare/prepareutil.h | 26 +++++- 5 files changed, 159 insertions(+), 47 deletions(-) create mode 100644 initialstart/modules/prepare/dbus/org.kde.Solid.PowerManagement.Actions.BrightnessControl.xml diff --git a/initialstart/modules/prepare/CMakeLists.txt b/initialstart/modules/prepare/CMakeLists.txt index 99b9c306..875e2a90 100644 --- a/initialstart/modules/prepare/CMakeLists.txt +++ b/initialstart/modules/prepare/CMakeLists.txt @@ -1,9 +1,12 @@ # SPDX-FileCopyrightText: 2023 Devin Lin # SPDX-License-Identifier: GPL-2.0-or-later +qt_add_dbus_interfaces(DBUS_SRCS dbus/org.kde.Solid.PowerManagement.Actions.BrightnessControl.xml) + set(prepareplugin_SRCS prepareplugin.cpp prepareutil.cpp + ${DBUS_SRCS} ) add_library(prepareplugin ${prepareplugin_SRCS}) diff --git a/initialstart/modules/prepare/dbus/org.kde.Solid.PowerManagement.Actions.BrightnessControl.xml b/initialstart/modules/prepare/dbus/org.kde.Solid.PowerManagement.Actions.BrightnessControl.xml new file mode 100644 index 00000000..bc615049 --- /dev/null +++ b/initialstart/modules/prepare/dbus/org.kde.Solid.PowerManagement.Actions.BrightnessControl.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/initialstart/modules/prepare/package/contents/ui/main.qml b/initialstart/modules/prepare/package/contents/ui/main.qml index 40d117da..bb30374d 100644 --- a/initialstart/modules/prepare/package/contents/ui/main.qml +++ b/initialstart/modules/prepare/package/contents/ui/main.qml @@ -8,7 +8,6 @@ import QtQuick.Layouts 1.15 import org.kde.kirigami 2.20 as Kirigami import org.kde.kirigamiaddons.formcard 1.0 as FormCard import org.kde.plasma.mobileinitialstart.prepare 1.0 as Prepare -import org.kde.plasma.plasma5support 2.0 as P5Support Item { id: root @@ -16,48 +15,6 @@ Item { readonly property real cardWidth: Math.min(Kirigami.Units.gridUnit * 30, root.width - Kirigami.Units.gridUnit * 2) - // brightness controls - property int screenBrightness: 0 - property bool disableBrightnessUpdate: true - readonly property int maximumScreenBrightness: pmSource.data["PowerDevil"] ? pmSource.data["PowerDevil"]["Maximum Screen Brightness"] || 0 : 0 - property QtObject updateScreenBrightnessJob - - function updateBrightnessUI() { - if (updateScreenBrightnessJob) - return; - - root.disableBrightnessUpdate = true; - root.screenBrightness = pmSource.data["PowerDevil"]["Screen Brightness"]; - root.disableBrightnessUpdate = false; - } - - onScreenBrightnessChanged: { - brightnessSlider.value = root.screenBrightness - - if (!disableBrightnessUpdate) { - const service = pmSource.serviceForSource("PowerDevil"); - const operation = service.operationDescription("setBrightness"); - operation.brightness = screenBrightness; - operation.silent = true; // don't show OSD - - updateScreenBrightnessJob = service.startOperationCall(operation); - updateScreenBrightnessJob.finished.connect(function (job) { - root.updateBrightnessUI(); - }); - } - } - - P5Support.DataSource { - id: pmSource - engine: "powermanagement" - connectedSources: ["PowerDevil"] - onSourceAdded: if (source === "PowerDevil") { - disconnectSource(source); - connectSource(source); - } - onDataChanged: root.updateBrightnessUI() - } - ScrollView { anchors { fill: parent @@ -77,12 +34,15 @@ Item { Layout.alignment: Qt.AlignTop Layout.fillWidth: true + visible: Prepare.PrepareUtil.brightnessAvailable wrapMode: Text.Wrap horizontalAlignment: Text.AlignHCenter text: i18n("Adjust the screen brightness to be comfortable for the installation process.") } FormCard.FormCard { + id: brightnessCard + visible: Prepare.PrepareUtil.brightnessAvailable maximumWidth: root.cardWidth Layout.alignment: Qt.AlignTop | Qt.AlignHCenter @@ -103,9 +63,17 @@ Item { id: brightnessSlider Layout.fillWidth: true from: 1 - to: root.maximumScreenBrightness - value: root.screenBrightness - onMoved: root.screenBrightness = value; + to: Prepare.PrepareUtil.maxBrightness + value: Prepare.PrepareUtil.brightness + onMoved: Prepare.PrepareUtil.brightness = value; + + // HACK: for some reason, the slider initial value doesn't set without being done after the component completes loading + Timer { + interval: 0 + running: true + repeat: false + onTriggered: brightnessSlider.value = Qt.binding(() => Prepare.PrepareUtil.brightness) + } } Kirigami.Icon { @@ -129,6 +97,7 @@ Item { } FormCard.FormCard { + id: scalingCard maximumWidth: root.cardWidth Layout.alignment: Qt.AlignTop | Qt.AlignHCenter diff --git a/initialstart/modules/prepare/prepareutil.cpp b/initialstart/modules/prepare/prepareutil.cpp index ef12fcdd..09c802d9 100644 --- a/initialstart/modules/prepare/prepareutil.cpp +++ b/initialstart/modules/prepare/prepareutil.cpp @@ -8,9 +8,24 @@ #include #include +#include +#include + PrepareUtil::PrepareUtil(QObject *parent) : QObject{parent} { + m_brightnessInterface = + new org::kde::Solid::PowerManagement::Actions::BrightnessControl(QStringLiteral("org.kde.Solid.PowerManagement"), + QStringLiteral("/org/kde/Solid/PowerManagement/Actions/BrightnessControl"), + QDBusConnection::sessionBus(), + this); + + fetchBrightness(); + fetchMaxBrightness(); + + connect(m_brightnessInterface, &org::kde::Solid::PowerManagement::Actions::BrightnessControl::brightnessChanged, this, &PrepareUtil::fetchBrightness); + connect(m_brightnessInterface, &org::kde::Solid::PowerManagement::Actions::BrightnessControl::brightnessMaxChanged, this, &PrepareUtil::fetchMaxBrightness); + connect(new KScreen::GetConfigOperation(), &KScreen::GetConfigOperation::finished, this, [this](auto *op) { m_config = qobject_cast(op)->config(); @@ -28,6 +43,20 @@ PrepareUtil::PrepareUtil(QObject *parent) m_scaling = scaling; Q_EMIT scalingChanged(); }); + + // watch for brightness interface + m_brightnessInterfaceWatcher = new QDBusServiceWatcher(QStringLiteral("org.kde.Solid.PowerManagement.Actions.BrightnessControl"), + QDBusConnection::sessionBus(), + QDBusServiceWatcher::WatchForOwnerChange, + this); + + connect(m_brightnessInterfaceWatcher, &QDBusServiceWatcher::serviceRegistered, this, [this]() -> void { + Q_EMIT brightnessAvailableChanged(); + }); + + connect(m_brightnessInterfaceWatcher, &QDBusServiceWatcher::serviceUnregistered, this, [this]() -> void { + Q_EMIT brightnessAvailableChanged(); + }); } int PrepareUtil::scaling() const @@ -59,3 +88,57 @@ QStringList PrepareUtil::scalingOptions() { return {"50%", "100%", "150%", "200%", "250%", "300%"}; } + +int PrepareUtil::brightness() const +{ + return m_brightness; +} + +void PrepareUtil::setBrightness(int brightness) +{ + m_brightnessInterface->setBrightness(brightness); +} + +int PrepareUtil::maxBrightness() const +{ + return m_maxBrightness; +} + +bool PrepareUtil::brightnessAvailable() const +{ + return m_brightnessInterface->isValid(); +} + +void PrepareUtil::fetchBrightness() +{ + QDBusPendingReply reply = m_brightnessInterface->brightness(); + QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(reply, this); + + connect(watcher, &QDBusPendingCallWatcher::finished, this, [this](QDBusPendingCallWatcher *watcher) { + QDBusPendingReply reply = *watcher; + if (reply.isError()) { + qWarning() << "Getting brightness failed:" << reply.error().name() << reply.error().message(); + } else if (m_brightness != reply.value()) { + m_brightness = reply.value(); + Q_EMIT brightnessChanged(); + } + watcher->deleteLater(); + }); +} + +void PrepareUtil::fetchMaxBrightness() +{ + QDBusPendingReply reply = m_brightnessInterface->brightnessMax(); + QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(reply, this); + + connect(watcher, &QDBusPendingCallWatcher::finished, this, [this](QDBusPendingCallWatcher *watcher) { + QDBusPendingReply reply = *watcher; + if (reply.isError()) { + qWarning() << "Getting max brightness failed:" << reply.error().name() << reply.error().message(); + } else if (m_maxBrightness != reply.value()) { + m_maxBrightness = reply.value(); + Q_EMIT maxBrightnessChanged(); + } + watcher->deleteLater(); + }); +} diff --git a/initialstart/modules/prepare/prepareutil.h b/initialstart/modules/prepare/prepareutil.h index de749978..b4b0781a 100644 --- a/initialstart/modules/prepare/prepareutil.h +++ b/initialstart/modules/prepare/prepareutil.h @@ -3,16 +3,21 @@ #pragma once +#include #include -#include #include +#include "brightnesscontrolinterface.h" + class PrepareUtil : public QObject { Q_OBJECT Q_PROPERTY(int scaling READ scaling WRITE setScaling NOTIFY scalingChanged); Q_PROPERTY(QStringList scalingOptions READ scalingOptions CONSTANT); + Q_PROPERTY(int brightness READ brightness WRITE setBrightness NOTIFY brightnessChanged); + Q_PROPERTY(int maxBrightness READ maxBrightness NOTIFY maxBrightnessChanged) + Q_PROPERTY(bool brightnessAvailable READ brightnessAvailable NOTIFY brightnessAvailableChanged) public: PrepareUtil(QObject *parent = nullptr); @@ -22,10 +27,29 @@ public: QStringList scalingOptions(); + int brightness() const; + void setBrightness(int brightness); + + int maxBrightness() const; + + bool brightnessAvailable() const; + Q_SIGNALS: void scalingChanged(); + void brightnessChanged(); + void maxBrightnessChanged(); + void brightnessAvailableChanged(); + +private Q_SLOTS: + void fetchBrightness(); + void fetchMaxBrightness(); private: int m_scaling; + int m_brightness; + int m_maxBrightness; + KScreen::ConfigPtr m_config; + org::kde::Solid::PowerManagement::Actions::BrightnessControl *m_brightnessInterface; + QDBusServiceWatcher *m_brightnessInterfaceWatcher; };