[gnome-settings-daemon/benzea/backport-smearing-fix: 1/2] color: Allow night light to be always on



commit a101e96b493751f7ca40ec8ee3d7e862030e2d5a
Author: Benjamin Berg <bberg redhat com>
Date:   Fri Feb 15 10:52:39 2019 +0100

    color: Allow night light to be always on
    
    Currently if the user configures the "from" and "to" times for the night
    light schedule to be close together or equal, g-s-d gets confused as it
    still tries to smear the transition over a full hour period.
    
    To fix this, first make sure that the smearing period is short enough to
    fit between sunrise and sunset. Also redefine equal start/end times when
    calculating whether a time falls into a range as the full 24h period.
    
    This effectively means that we will smear over the full day or night
    time when the sunrise and sunset are closer than an hour to each other.
    It also means that we always enable night light when the times are
    equal.
    
    Based on a patch by Matthew Leeds <matthew leeds endlessm com>.

 plugins/color/gcm-self-test.c          | 18 +++++++++++-------
 plugins/color/gsd-night-light-common.c | 19 +++++++++++++------
 plugins/color/gsd-night-light.c        | 27 ++++++++++++++++++---------
 3 files changed, 42 insertions(+), 22 deletions(-)
---
diff --git a/plugins/color/gcm-self-test.c b/plugins/color/gcm-self-test.c
index 5cdcf987..46171fc9 100644
--- a/plugins/color/gcm-self-test.c
+++ b/plugins/color/gcm-self-test.c
@@ -338,17 +338,21 @@ gcm_test_frac_day (void)
         g_assert_cmpfloat (fd, <, fd_actual + 0.01);
 
         /* test same day */
-        g_assert (gsd_night_light_frac_day_is_between (12, 6, 20));
-        g_assert (!gsd_night_light_frac_day_is_between (5, 6, 20));
-        g_assert (gsd_night_light_frac_day_is_between (12, 0, 24));
-        g_assert (gsd_night_light_frac_day_is_between (12, -1, 25));
+        g_assert_true (gsd_night_light_frac_day_is_between (12, 6, 20));
+        g_assert_false (gsd_night_light_frac_day_is_between (5, 6, 20));
+        g_assert_true (gsd_night_light_frac_day_is_between (12, 0, 24));
+        g_assert_true (gsd_night_light_frac_day_is_between (12, -1, 25));
 
         /* test rollover to next day */
-        g_assert (gsd_night_light_frac_day_is_between (23, 20, 6));
-        g_assert (!gsd_night_light_frac_day_is_between (12, 20, 6));
+        g_assert_true (gsd_night_light_frac_day_is_between (23, 20, 6));
+        g_assert_false (gsd_night_light_frac_day_is_between (12, 20, 6));
 
         /* test rollover to the previous day */
-        g_assert (gsd_night_light_frac_day_is_between (5, 16, 8));
+        g_assert_true (gsd_night_light_frac_day_is_between (5, 16, 8));
+
+        /* test equality */
+        g_assert_true (gsd_night_light_frac_day_is_between (12, 0.5, 24.5));
+        g_assert_true (gsd_night_light_frac_day_is_between (0.5, 0.5, 0.5));
 }
 
 int
diff --git a/plugins/color/gsd-night-light-common.c b/plugins/color/gsd-night-light-common.c
index fe82bbf2..5fe756e7 100644
--- a/plugins/color/gsd-night-light-common.c
+++ b/plugins/color/gsd-night-light-common.c
@@ -115,16 +115,23 @@ gsd_night_light_frac_day_from_dt (GDateTime *dt)
 }
 
 gboolean
-gsd_night_light_frac_day_is_between (gdouble value, gdouble start, gdouble end)
+gsd_night_light_frac_day_is_between (gdouble  value,
+                                     gdouble  start,
+                                     gdouble  end)
 {
-        /* wraparound to the next day */
-        if (end < start)
+        /* wrap end to the next day if it is before start,
+         * considering equal values as a full 24h period
+         */
+        if (end <= start)
                 end += 24;
 
-        /* wraparound to the previous day */
+        /* wrap value to the next day if it is before the range */
         if (value < start && value < end)
                 value += 24;
 
-        /* test limits */
-        return value > start && value <= end;
+        /* Check whether value falls into range; together with the 24h
+         * wrap around above this means that TRUE is always returned when
+         * start == end.
+         */
+        return value >= start && value < end;
 }
diff --git a/plugins/color/gsd-night-light.c b/plugins/color/gsd-night-light.c
index acbcecbc..701c7753 100644
--- a/plugins/color/gsd-night-light.c
+++ b/plugins/color/gsd-night-light.c
@@ -305,11 +305,12 @@ night_light_recheck (GsdNightLight *self)
                 if (time_span > (GTimeSpan) 24 * 60 * 60 * 1000000) {
                         g_debug ("night light disabled until tomorrow is older than 24h, resetting disabled 
until tomorrow");
                         reset = TRUE;
-                } else {
+                } else if (time_span > 0) {
                         /* Or if a sunrise lies between the time it was disabled and now. */
                         gdouble frac_disabled;
                         frac_disabled = gsd_night_light_frac_day_from_dt (self->disabled_until_tmw_dt);
-                        if (gsd_night_light_frac_day_is_between (schedule_to,
+                        if (frac_disabled != frac_day &&
+                            gsd_night_light_frac_day_is_between (schedule_to,
                                                                  frac_disabled,
                                                                  frac_day)) {
                                 g_debug ("night light sun rise happened, resetting disabled until tomorrow");
@@ -329,9 +330,14 @@ night_light_recheck (GsdNightLight *self)
                 }
         }
 
+        /* lower smearing period to be smaller than the time between start/stop */
+        smear = MIN (smear,
+                     MIN (     ABS (schedule_to - schedule_from),
+                          24 - ABS (schedule_to - schedule_from)));
+
         if (!gsd_night_light_frac_day_is_between (frac_day,
-                                                    schedule_from - smear,
-                                                    schedule_to)) {
+                                                  schedule_from - smear,
+                                                  schedule_to)) {
                 g_debug ("not time for night-light");
                 gsd_night_light_set_active (self, FALSE);
                 return;
@@ -348,15 +354,18 @@ night_light_recheck (GsdNightLight *self)
          *   \--------------------/
          */
         temperature = g_settings_get_uint (self->settings, "night-light-temperature");
-        if (gsd_night_light_frac_day_is_between (frac_day,
-                                                   schedule_from - smear,
-                                                   schedule_from)) {
+        if (smear < 0.01) {
+                /* Don't try to smear for extremely short or zero periods */
+                temp_smeared = temperature;
+        } else if (gsd_night_light_frac_day_is_between (frac_day,
+                                                        schedule_from - smear,
+                                                        schedule_from)) {
                 gdouble factor = 1.f - ((frac_day - (schedule_from - smear)) / smear);
                 temp_smeared = linear_interpolate (GSD_COLOR_TEMPERATURE_DEFAULT,
                                                    temperature, factor);
         } else if (gsd_night_light_frac_day_is_between (frac_day,
-                                                          schedule_to - smear,
-                                                          schedule_to)) {
+                                                        schedule_to - smear,
+                                                        schedule_to)) {
                 gdouble factor = (frac_day - (schedule_to - smear)) / smear;
                 temp_smeared = linear_interpolate (GSD_COLOR_TEMPERATURE_DEFAULT,
                                                    temperature, factor);


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]