[colorcorrection] Add "Constant" mode

Summary:
Currently, the Night Color manager supports three operation modes:

* Automatic: in this mode, screen color temperature is computed based on
the current position of the Sun. In order to calculate sunrise & sunset
times, the manager needs coordinates of the user, which are provided by
Plasma;

* Location: this mode is very similar to the Automatic, except one minor
detail: user needs to provide his/her/their location. This mode can be
very useful if coordinates provided by Plasma are incorrect;

* Timings: unfortunately we can't compute timings of the Sun for people
living near Earth poles. This mode allows the user to specify timings of
sunrise and sunset as well the transition time.

This change introduces another mode, called Constant. With this mode the
screen color temperature is constant throughout the day. The new mode
can be useful for people wishing constant screen color temperature or
just for people living near Earth's North or South poles.

Reviewers: #kwin, davidedmundson

Reviewed By: #kwin, davidedmundson

Subscribers: ngraham, davidedmundson, romangg, kwin

Tags: #kwin

Differential Revision: https://phabricator.kde.org/D21948
This commit is contained in:
Vlad Zagorodniy 2019-07-22 00:30:38 +03:00
parent 93ab16b995
commit eafe7aee65
4 changed files with 80 additions and 17 deletions

View file

@ -83,9 +83,10 @@ void ColorCorrectNightColorTest::testConfigRead_data()
QTest::newRow("activeMode0") << "true" << 0 << 4500 << 45.5 << 35.1 << "0600" << "1800" << 30 << true;
QTest::newRow("activeMode1") << "true" << 1 << 2500 << -10.5 << -8. << "0020" << "2000" << 60 << true;
QTest::newRow("activeMode2") << "true" << 3 << 3500 << 45.5 << 35.1 << "0600" << "1800" << 60 << true;
QTest::newRow("notActiveMode2") << "false" << 2 << 5000 << 90. << -180. << "0600" << "1800" << 1 << true;
QTest::newRow("wrongData1") << "fa" << 3 << 7000 << 91. << -181. << "060" << "800" << 999999 << false;
QTest::newRow("wrongData2") << "fa" << 3 << 7000 << 91. << -181. << "060" << "800" << -2 << false;
QTest::newRow("wrongData1") << "fa" << 4 << 7000 << 91. << -181. << "060" << "800" << 999999 << false;
QTest::newRow("wrongData2") << "fa" << 4 << 7000 << 91. << -181. << "060" << "800" << -2 << false;
}
void ColorCorrectNightColorTest::testConfigRead()
@ -183,7 +184,8 @@ void ColorCorrectNightColorTest::testChangeConfiguration_data()
QTest::newRow("data0") << true << 0 << 4500 << 45.5 << 35.1 << QTime(6,0,0) << QTime(18,0,0) << 30 << true;
QTest::newRow("data1") << true << 1 << 2500 << -10.5 << -8. << QTime(0,2,0) << QTime(20,0,0) << 60 << true;
QTest::newRow("data2") << false << 2 << 5000 << 90. << -180. << QTime(6,0,0) << QTime(19,1,1) << 1 << true;
QTest::newRow("wrongData0") << true << 3 << 4500 << 0. << 0. << QTime(6,0,0) << QTime(18,0,0) << 30 << false;
QTest::newRow("data3") << false << 3 << 2000 << 90. << -180. << QTime(6,0,0) << QTime(18,0,0) << 1 << true;
QTest::newRow("wrongData0") << true << 4 << 4500 << 0. << 0. << QTime(6,0,0) << QTime(18,0,0) << 30 << false;
QTest::newRow("wrongData1") << true << 0 << 500 << 0. << 0. << QTime(6,0,0) << QTime(18,0,0) << 30 << false;
QTest::newRow("wrongData2") << true << 0 << 7000 << 0. << 0. << QTime(6,0,0) << QTime(18,0,0) << 30 << false;
QTest::newRow("wrongData3") << true << 0 << 4500 << 91. << -181. << QTime(6,0,0) << QTime(18,0,0) << 30 << false;

View file

@ -19,6 +19,7 @@
<choice name="Automatic"/>
<choice name="Location"/>
<choice name="Times"/>
<choice name="Constant"/>
</choices>
<default>NightColorMode::Automatic</default>
</entry>

View file

@ -70,8 +70,6 @@ void Manager::init()
readConfig();
if (!kwinApp()->platform()->supportsGammaControl()) {
// at least update the sun timings to make the values accessible via dbus
updateSunTimings(true);
return;
}
@ -141,7 +139,12 @@ void Manager::init()
void Manager::hardReset()
{
cancelAllTimers();
updateSunTimings(true);
// Timings of the Sun are not used in the constant mode.
if (m_mode != NightColorMode::Constant) {
updateSunTimings(true);
}
if (kwinApp()->platform()->supportsGammaControl() && m_active) {
m_running = true;
commitGammaRamps(currentTargetTemp());
@ -211,11 +214,17 @@ void Manager::readConfig()
m_active = s->active();
NightColorMode mode = s->mode();
if (mode == NightColorMode::Location || mode == NightColorMode::Timings) {
switch (s->mode()) {
case NightColorMode::Automatic:
case NightColorMode::Location:
case NightColorMode::Timings:
case NightColorMode::Constant:
m_mode = mode;
} else {
// also fallback for invalid setting values
break;
default:
// Fallback for invalid setting values.
m_mode = NightColorMode::Automatic;
break;
}
m_nightTargetTemp = qBound(MIN_TEMPERATURE, s->nightTemperature(), NEUTRAL_TEMPERATURE);
@ -293,7 +302,10 @@ void Manager::cancelAllTimers()
void Manager::resetQuickAdjustTimer()
{
updateSunTimings(false);
// We don't use timings of the Sun in the constant mode.
if (m_mode != NightColorMode::Constant) {
updateSunTimings(false);
}
int tempDiff = qAbs(currentTargetTemp() - m_currentTemp);
// allow tolerance of one TEMPERATURE_STEP to compensate if a slow update is coincidental
@ -347,6 +359,12 @@ void Manager::resetSlowUpdateStartTimer()
return;
}
// There is no need for starting the slow update timer. Screen color temperature
// will be constant all the time now.
if (m_mode == NightColorMode::Constant) {
return;
}
// set up the next slow update
m_slowUpdateStartTimer = new QTimer(this);
m_slowUpdateStartTimer->setSingleShot(true);
@ -536,6 +554,10 @@ int Manager::currentTargetTemp() const
return NEUTRAL_TEMPERATURE;
}
if (m_mode == NightColorMode::Constant) {
return m_nightTargetTemp;
}
QDateTime todayNow = QDateTime::currentDateTimeUtc();
auto f = [this, todayNow](int target1, int target2) {
@ -680,7 +702,7 @@ bool Manager::changeConfiguration(QHash<QString, QVariant> data)
return false;
}
int mo = iter1.value().toInt();
if (mo < 0 || 2 < mo) {
if (mo < 0 || 3 < mo) {
return false;
}
NightColorMode moM;
@ -693,6 +715,10 @@ bool Manager::changeConfiguration(QHash<QString, QVariant> data)
break;
case 2:
moM = NightColorMode::Timings;
break;
case 3:
moM = NightColorMode::Constant;
break;
}
modeUpdate = m_mode != moM;
mode = moM;

View file

@ -42,16 +42,50 @@ typedef QPair<QTime,QTime> Times;
class ColorCorrectDBusInterface;
/**
* This enum type is used to specify operation mode of the night color manager.
**/
enum NightColorMode {
// timings are based on provided location data
Automatic = 0,
// timings are based on fixed location data
/**
* Color temperature is computed based on the current position of the Sun.
*
* Location of the user is provided by Plasma.
**/
Automatic,
/**
* Color temperature is computed based on the current position of the Sun.
*
* Location of the user is provided by themselves.
**/
Location,
// fixed timings
Timings
/**
* Color temperature is computed based on the current time.
*
* Sunrise and sunset times have to be specified by the user.
**/
Timings,
/**
* Color temperature is constant thoughout the day.
**/
Constant,
};
/**
* The night color manager is a blue light filter similar to Redshift.
*
* There are four modes this manager can operate in: Automatic, Location, Timings,
* and Constant. Both Automatic and Location modes derive screen color temperature
* from the current position of the Sun, the only difference between two is how
* coordinates of the user are specified. If the user is located near the North or
* South pole, we can't compute correct position of the Sun, that's why we need
* Timings and Constant mode.
*
* With the Timings mode, screen color temperature is computed based on the clock
* time. The user needs to specify timings of the sunset and sunrise as well the
* transition time.
*
* With the Constant mode, screen color temperature is always constant.
**/
class KWIN_EXPORT Manager : public QObject
{
Q_OBJECT