File indexing completed on 2024-12-15 05:06:51

0001 /*
0002  *   SPDX-FileCopyrightText: 2010 Dario Freddi <drf@kde.org>
0003  *
0004  *   SPDX-License-Identifier: GPL-2.0-or-later
0005  */
0006 
0007 #include "dimdisplay.h"
0008 
0009 #include <PowerDevilProfileSettings.h>
0010 #include <powerdevil_debug.h>
0011 #include <powerdevilcore.h>
0012 
0013 #include <QDebug>
0014 #include <QTimer>
0015 
0016 #include <KLocalizedString>
0017 #include <KPluginFactory>
0018 
0019 K_PLUGIN_CLASS_WITH_JSON(PowerDevil::BundledActions::DimDisplay, "powerdevildimdisplayaction.json")
0020 
0021 namespace PowerDevil::BundledActions
0022 {
0023 DimDisplay::DimDisplay(QObject *parent)
0024     : Action(parent)
0025 {
0026     setRequiredPolicies(PowerDevil::PolicyAgent::ChangeScreenSettings);
0027 }
0028 
0029 void DimDisplay::onWakeupFromIdle()
0030 {
0031     if (!m_dimmed) {
0032         return;
0033     }
0034     // An active inhibition may not let us restore the brightness.
0035     // We should wait a bit screen to wake-up from sleep
0036     QTimer::singleShot(0, this, [this]() {
0037         setBrightnessHelper(m_oldScreenBrightness, m_oldKeyboardBrightness, true);
0038     });
0039     m_dimmed = false;
0040 }
0041 
0042 void DimDisplay::onIdleTimeout(std::chrono::milliseconds timeout)
0043 {
0044     Q_ASSERT(timeout == m_dimOnIdleTime);
0045     if (core()->screenBrightnessController()->screenBrightness() == 0) {
0046         // Some drivers report brightness == 0 when display is off because of DPMS
0047         //(especially Intel driver). Don't change brightness in this case, or
0048         // backlight won't switch on later.
0049         // Furthermore, we can't dim if brightness is 0 already.
0050         return;
0051     }
0052 
0053 
0054     m_oldScreenBrightness = core()->screenBrightnessController()->screenBrightness();
0055     m_oldKeyboardBrightness = core()->keyboardBrightnessController()->keyboardBrightness();
0056 
0057 
0058     // Dim brightness to 30% of the original. 30% is chosen arbitrarily based on
0059     // assumption that e.g. 50% may be too bright for returning user to notice that
0060     // the screen is going to go off, while 20% may be too dark to be able to read
0061     // something on the screen.
0062     const int newBrightness = qRound(m_oldScreenBrightness * 0.3);
0063     setBrightnessHelper(newBrightness, 0);
0064 
0065     m_dimmed = true;
0066 }
0067 
0068 void DimDisplay::setBrightnessHelper(int screen, int keyboard, bool force)
0069 {
0070     trigger({
0071         {QStringLiteral("_ScreenBrightness"), QVariant::fromValue(screen)},
0072         {QStringLiteral("_KeyboardBrightness"), QVariant::fromValue(keyboard)},
0073         {QStringLiteral("Explicit"), QVariant::fromValue(force)},
0074     });
0075 }
0076 
0077 void DimDisplay::triggerImpl(const QVariantMap &args)
0078 {
0079     core()->screenBrightnessController()->setScreenBrightness(args.value(QStringLiteral("_ScreenBrightness")).toInt());
0080 
0081     // don't manipulate keyboard brightness if it's already zero to prevent races with DPMS action
0082     if (m_oldKeyboardBrightness > 0) {
0083         core()->keyboardBrightnessController()->setKeyboardBrightness(args.value(QStringLiteral("_KeyboardBrightness")).toInt());
0084     }
0085 }
0086 
0087 bool DimDisplay::isSupported()
0088 {
0089     return core()->screenBrightnessController()->screenBrightnessAvailable();
0090 }
0091 
0092 bool DimDisplay::loadAction(const PowerDevil::ProfileSettings &profileSettings)
0093 {
0094     qCDebug(POWERDEVIL);
0095     if (!profileSettings.dimDisplayWhenIdle()) {
0096         return false;
0097     }
0098 
0099     m_dimOnIdleTime = std::chrono::seconds(profileSettings.dimDisplayIdleTimeoutSec());
0100     qCDebug(POWERDEVIL) << "Loading timeouts with " << m_dimOnIdleTime.count();
0101     registerIdleTimeout(m_dimOnIdleTime);
0102     return true;
0103 }
0104 
0105 }
0106 
0107 #include "dimdisplay.moc"
0108 
0109 #include "moc_dimdisplay.cpp"