File indexing completed on 2025-03-02 05:10:50

0001 // SPDX-FileCopyrightText: 2023 by Devin Lin <devin@kde.org>
0002 // SPDX-License-Identifier: GPL-2.0-or-later
0003 
0004 #include "prepareutil.h"
0005 
0006 #include <kscreen/configmonitor.h>
0007 #include <kscreen/getconfigoperation.h>
0008 #include <kscreen/output.h>
0009 #include <kscreen/setconfigoperation.h>
0010 
0011 #include <QDBusPendingCallWatcher>
0012 #include <QDBusPendingReply>
0013 
0014 PrepareUtil::PrepareUtil(QObject *parent)
0015     : QObject{parent}
0016     , m_colorsSettings{new ColorsSettings(this)}
0017 {
0018     m_brightnessInterface =
0019         new org::kde::Solid::PowerManagement::Actions::BrightnessControl(QStringLiteral("org.kde.Solid.PowerManagement"),
0020                                                                          QStringLiteral("/org/kde/Solid/PowerManagement/Actions/BrightnessControl"),
0021                                                                          QDBusConnection::sessionBus(),
0022                                                                          this);
0023 
0024     fetchBrightness();
0025     fetchMaxBrightness();
0026 
0027     connect(m_brightnessInterface, &org::kde::Solid::PowerManagement::Actions::BrightnessControl::brightnessChanged, this, &PrepareUtil::fetchBrightness);
0028     connect(m_brightnessInterface, &org::kde::Solid::PowerManagement::Actions::BrightnessControl::brightnessMaxChanged, this, &PrepareUtil::fetchMaxBrightness);
0029 
0030     connect(new KScreen::GetConfigOperation(), &KScreen::GetConfigOperation::finished, this, [this](auto *op) {
0031         m_config = qobject_cast<KScreen::GetConfigOperation *>(op)->config();
0032 
0033         int scaling = 100;
0034 
0035         // to determine the scaling value:
0036         // try to take the primary display's scaling, otherwise use the scaling of any of the displays
0037         for (KScreen::OutputPtr output : m_config->outputs()) {
0038             scaling = output->scale() * 100;
0039             if (output->isPrimary()) {
0040                 break;
0041             }
0042         }
0043 
0044         m_scaling = scaling;
0045         Q_EMIT scalingChanged();
0046     });
0047 
0048     // watch for brightness interface
0049     m_brightnessInterfaceWatcher = new QDBusServiceWatcher(QStringLiteral("org.kde.Solid.PowerManagement.Actions.BrightnessControl"),
0050                                                            QDBusConnection::sessionBus(),
0051                                                            QDBusServiceWatcher::WatchForOwnerChange,
0052                                                            this);
0053 
0054     connect(m_brightnessInterfaceWatcher, &QDBusServiceWatcher::serviceRegistered, this, [this]() -> void {
0055         Q_EMIT brightnessAvailableChanged();
0056     });
0057 
0058     connect(m_brightnessInterfaceWatcher, &QDBusServiceWatcher::serviceUnregistered, this, [this]() -> void {
0059         Q_EMIT brightnessAvailableChanged();
0060     });
0061 
0062     // set property initially
0063     m_usingDarkTheme = m_colorsSettings->colorScheme() == "BreezeDark";
0064 }
0065 
0066 int PrepareUtil::scaling() const
0067 {
0068     return m_scaling;
0069 }
0070 
0071 void PrepareUtil::setScaling(int scaling)
0072 {
0073     if (!m_config) {
0074         return;
0075     }
0076 
0077     const auto outputs = m_config->outputs();
0078     qreal scalingNum = ((double)scaling) / 100;
0079 
0080     for (KScreen::OutputPtr output : outputs) {
0081         output->setScale(scalingNum);
0082     }
0083 
0084     auto setop = new KScreen::SetConfigOperation(m_config, this);
0085     setop->exec();
0086 
0087     m_scaling = scaling;
0088     Q_EMIT scalingChanged();
0089 }
0090 
0091 QStringList PrepareUtil::scalingOptions()
0092 {
0093     return {"50%", "100%", "150%", "200%", "250%", "300%"};
0094 }
0095 
0096 int PrepareUtil::brightness() const
0097 {
0098     return m_brightness;
0099 }
0100 
0101 void PrepareUtil::setBrightness(int brightness)
0102 {
0103     m_brightnessInterface->setBrightness(brightness);
0104 }
0105 
0106 int PrepareUtil::maxBrightness() const
0107 {
0108     return m_maxBrightness;
0109 }
0110 
0111 bool PrepareUtil::brightnessAvailable() const
0112 {
0113     return m_brightnessInterface->isValid();
0114 }
0115 
0116 bool PrepareUtil::usingDarkTheme() const
0117 {
0118     return m_usingDarkTheme;
0119 }
0120 
0121 void PrepareUtil::setUsingDarkTheme(bool usingDarkTheme)
0122 {
0123     // use plasma-apply-colorscheme since it has logic for notifying the shell of changes
0124     if (usingDarkTheme) {
0125         QProcess::execute("plasma-apply-colorscheme", {QStringLiteral("BreezeDark")});
0126     } else {
0127         QProcess::execute("plasma-apply-colorscheme", {QStringLiteral("BreezeLight")});
0128     }
0129 
0130     m_usingDarkTheme = usingDarkTheme;
0131     Q_EMIT usingDarkThemeChanged();
0132 }
0133 
0134 void PrepareUtil::fetchBrightness()
0135 {
0136     QDBusPendingReply<int> reply = m_brightnessInterface->brightness();
0137     QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(reply, this);
0138 
0139     connect(watcher, &QDBusPendingCallWatcher::finished, this, [this](QDBusPendingCallWatcher *watcher) {
0140         QDBusPendingReply<int> reply = *watcher;
0141         if (reply.isError()) {
0142             qWarning() << "Getting brightness failed:" << reply.error().name() << reply.error().message();
0143         } else if (m_brightness != reply.value()) {
0144             m_brightness = reply.value();
0145             Q_EMIT brightnessChanged();
0146         }
0147         watcher->deleteLater();
0148     });
0149 }
0150 
0151 void PrepareUtil::fetchMaxBrightness()
0152 {
0153     QDBusPendingReply<int> reply = m_brightnessInterface->brightnessMax();
0154     QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(reply, this);
0155 
0156     connect(watcher, &QDBusPendingCallWatcher::finished, this, [this](QDBusPendingCallWatcher *watcher) {
0157         QDBusPendingReply<int> reply = *watcher;
0158         if (reply.isError()) {
0159             qWarning() << "Getting max brightness failed:" << reply.error().name() << reply.error().message();
0160         } else if (m_maxBrightness != reply.value()) {
0161             m_maxBrightness = reply.value();
0162             Q_EMIT maxBrightnessChanged();
0163         }
0164         watcher->deleteLater();
0165     });
0166 }