1 /* 2 KWin - the KDE window manager 3 This file is part of the KDE project. 4 5 SPDX-FileCopyrightText: 2017 Roman Gilg <subdiff@gmail.com> 6 7 SPDX-License-Identifier: GPL-2.0-or-later 8 */ 9 10 #pragma once 11 12 #include "constants.h" 13 #include "plugin.h" 14 15 #include <QObject> 16 #include <QPair> 17 #include <QDateTime> 18 19 class QTimer; 20 21 namespace KWin 22 { 23 24 class ClockSkewNotifier; 25 class NightColorDBusInterface; 26 27 typedef QPair<QDateTime,QDateTime> DateTimes; 28 typedef QPair<QTime,QTime> Times; 29 30 /** 31 * This enum type is used to specify operation mode of the night color manager. 32 */ 33 enum NightColorMode { 34 /** 35 * Color temperature is computed based on the current position of the Sun. 36 * 37 * Location of the user is provided by Plasma. 38 */ 39 Automatic, 40 /** 41 * Color temperature is computed based on the current position of the Sun. 42 * 43 * Location of the user is provided by themselves. 44 */ 45 Location, 46 /** 47 * Color temperature is computed based on the current time. 48 * 49 * Sunrise and sunset times have to be specified by the user. 50 */ 51 Timings, 52 /** 53 * Color temperature is constant thoughout the day. 54 */ 55 Constant, 56 }; 57 58 /** 59 * The night color manager is a blue light filter similar to Redshift. 60 * 61 * There are four modes this manager can operate in: Automatic, Location, Timings, 62 * and Constant. Both Automatic and Location modes derive screen color temperature 63 * from the current position of the Sun, the only difference between two is how 64 * coordinates of the user are specified. If the user is located near the North or 65 * South pole, we can't compute correct position of the Sun, that's why we need 66 * Timings and Constant mode. 67 * 68 * With the Timings mode, screen color temperature is computed based on the clock 69 * time. The user needs to specify timings of the sunset and sunrise as well the 70 * transition time. 71 * 72 * With the Constant mode, screen color temperature is always constant. 73 */ 74 class KWIN_EXPORT NightColorManager : public Plugin 75 { 76 Q_OBJECT 77 78 public: 79 explicit NightColorManager(QObject *parent = nullptr); 80 ~NightColorManager() override; 81 82 void init(); 83 84 /** 85 * Get current configuration 86 * @see changeConfiguration 87 * @since 5.12 88 */ 89 QHash<QString, QVariant> info() const; 90 /** 91 * Change configuration 92 * @see info 93 * @since 5.12 94 */ 95 bool changeConfiguration(QHash<QString, QVariant> data); 96 void autoLocationUpdate(double latitude, double longitude); 97 98 /** 99 * Toggles the active state of the filter. 100 * 101 * A quick transition will be started if the difference between current screen 102 * color temperature and target screen color temperature is too large. Target 103 * temperature is defined in context of the new active state. 104 * 105 * If the filter becomes inactive after calling this method, the target color 106 * temperature is 6500 K. 107 * 108 * If the filter becomes active after calling this method, the target screen 109 * color temperature is defined by the current operation mode. 110 * 111 * Note that this method is a no-op if the underlying platform doesn't support 112 * adjusting gamma ramps. 113 */ 114 void toggle(); 115 116 /** 117 * Returns @c true if the night color manager is blocked; otherwise @c false. 118 */ 119 bool isInhibited() const; 120 121 /** 122 * Temporarily blocks the night color manager. 123 * 124 * After calling this method, the screen color temperature will be reverted 125 * back to 6500C. When you're done, call uninhibit() method. 126 */ 127 void inhibit(); 128 129 /** 130 * Attempts to unblock the night color manager. 131 */ 132 void uninhibit(); 133 134 /** 135 * Returns @c true if Night Color is enabled; otherwise @c false. 136 */ 137 bool isEnabled() const; 138 139 /** 140 * Returns @c true if Night Color is currently running; otherwise @c false. 141 */ 142 bool isRunning() const; 143 144 /** 145 * Returns @c true if Night Color is supported by platform; otherwise @c false. 146 */ 147 bool isAvailable() const; 148 149 /** 150 * Returns the current screen color temperature. 151 */ 152 int currentTemperature() const; 153 154 /** 155 * Returns the target screen color temperature. 156 */ 157 int targetTemperature() const; 158 159 /** 160 * Returns the mode in which Night Color is operating. 161 */ 162 NightColorMode mode() const; 163 164 /** 165 * Returns the datetime that specifies when the previous screen color temperature transition 166 * had started. Notice that when Night Color operates in the Constant mode, the returned date 167 * time object is not valid. 168 */ 169 QDateTime previousTransitionDateTime() const; 170 171 /** 172 * Returns the duration of the previous screen color temperature transition, in milliseconds. 173 */ 174 qint64 previousTransitionDuration() const; 175 176 /** 177 * Returns the datetime that specifies when the next screen color temperature transition will 178 * start. Notice that when Night Color operates in the Constant mode, the returned date time 179 * object is not valid. 180 */ 181 QDateTime scheduledTransitionDateTime() const; 182 183 /** 184 * Returns the duration of the next screen color temperature transition, in milliseconds. 185 */ 186 qint64 scheduledTransitionDuration() const; 187 188 // for auto tests 189 void reparseConfigAndReset(); 190 static NightColorManager *self(); 191 192 public Q_SLOTS: 193 void resetSlowUpdateStartTimer(); 194 void quickAdjust(); 195 196 Q_SIGNALS: 197 void configChange(QHash<QString, QVariant> data); 198 199 /** 200 * Emitted whenever the night color manager is blocked or unblocked. 201 */ 202 void inhibitedChanged(); 203 204 /** 205 * Emitted whenever the night color manager is enabled or disabled. 206 */ 207 void enabledChanged(); 208 209 /** 210 * Emitted whenever the night color manager starts or stops running. 211 */ 212 void runningChanged(); 213 214 /** 215 * Emitted whenever the current screen color temperature has changed. 216 */ 217 void currentTemperatureChanged(); 218 219 /** 220 * Emitted whenever the target screen color temperature has changed. 221 */ 222 void targetTemperatureChanged(); 223 224 /** 225 * Emitted whenver the operation mode has changed. 226 */ 227 void modeChanged(); 228 229 /** 230 * Emitted whenever the timings of the previous color temperature transition have changed. 231 */ 232 void previousTransitionTimingsChanged(); 233 234 /** 235 * Emitted whenever the timings of the next color temperature transition have changed. 236 */ 237 void scheduledTransitionTimingsChanged(); 238 239 private: 240 void readConfig(); 241 void hardReset(); 242 void slowUpdate(int targetTemp); 243 void resetAllTimers(); 244 int currentTargetTemp() const; 245 void cancelAllTimers(); 246 /** 247 * Quick shift on manual change to current target Temperature 248 */ 249 void resetQuickAdjustTimer(); 250 /** 251 * Slow shift to daytime target Temperature 252 */ 253 void resetSlowUpdateTimer(); 254 255 void updateTargetTemperature(); 256 void updateTransitionTimings(bool force); 257 DateTimes getSunTimings(const QDateTime &dateTime, double latitude, double longitude, bool morning) const; 258 bool checkAutomaticSunTimings() const; 259 bool daylight() const; 260 261 void commitGammaRamps(int temperature); 262 263 void setEnabled(bool enabled); 264 void setRunning(bool running); 265 void setCurrentTemperature(int temperature); 266 void setMode(NightColorMode mode); 267 268 NightColorDBusInterface *m_iface; 269 ClockSkewNotifier *m_skewNotifier; 270 271 // Specifies whether Night Color is enabled. 272 bool m_active = false; 273 274 // Specifies whether Night Color is currently running. 275 bool m_running = false; 276 277 // Specifies whether Night Color is inhibited globally. 278 bool m_isGloballyInhibited = false; 279 280 NightColorMode m_mode = NightColorMode::Automatic; 281 282 // the previous and next sunrise/sunset intervals - in UTC time 283 DateTimes m_prev = DateTimes(); 284 DateTimes m_next = DateTimes(); 285 286 // manual times from config 287 QTime m_morning = QTime(6,0); 288 QTime m_evening = QTime(18,0); 289 int m_trTime = 30; // saved in minutes > 1 290 291 // auto location provided by work space 292 double m_latAuto; 293 double m_lngAuto; 294 // manual location from config 295 double m_latFixed; 296 double m_lngFixed; 297 298 QTimer *m_slowUpdateStartTimer = nullptr; 299 QTimer *m_slowUpdateTimer = nullptr; 300 QTimer *m_quickAdjustTimer = nullptr; 301 302 int m_currentTemp = NEUTRAL_TEMPERATURE; 303 int m_targetTemperature = NEUTRAL_TEMPERATURE; 304 int m_dayTargetTemp = NEUTRAL_TEMPERATURE; 305 int m_nightTargetTemp = DEFAULT_NIGHT_TEMPERATURE; 306 307 int m_inhibitReferenceCount = 0; 308 }; 309 310 } // namespace KWin 311