[gnome-settings-daemon] color: Smooth the transition between different temperature values
- From: Richard Hughes <rhughes src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-settings-daemon] color: Smooth the transition between different temperature values
- Date: Thu, 16 Feb 2017 15:07:00 +0000 (UTC)
commit 591c8860f76cffc21f77a259c4bd8a8129a7f4b8
Author: Richard Hughes <richard hughsie com>
Date: Wed Feb 15 15:43:35 2017 +0000
color: Smooth the transition between different temperature values
This makes the effect less jarring when enabling or disabling in the control
center or shell. This and also means we transition nicely when adjusting the
times in manual mode.
https://bugzilla.gnome.org/show_bug.cgi?id=778689
plugins/color/gcm-self-test.c | 3 +
plugins/color/gsd-night-light.c | 87 +++++++++++++++++++++++++++++++++++++-
plugins/color/gsd-night-light.h | 2 +
3 files changed, 89 insertions(+), 3 deletions(-)
---
diff --git a/plugins/color/gcm-self-test.c b/plugins/color/gcm-self-test.c
index 37ec133..8827ca4 100644
--- a/plugins/color/gcm-self-test.c
+++ b/plugins/color/gcm-self-test.c
@@ -73,6 +73,9 @@ gcm_test_night_light (void)
/* do not start geoclue */
gsd_night_light_set_geoclue_enabled (nlight, FALSE);
+ /* do not smooth the transition */
+ gsd_night_light_set_smooth_enabled (nlight, FALSE);
+
/* switch off */
settings = g_settings_new ("org.gnome.settings-daemon.plugins.color");
g_settings_set_boolean (settings, "night-light-enabled", FALSE);
diff --git a/plugins/color/gsd-night-light.c b/plugins/color/gsd-night-light.c
index b0bb4f2..67415f1 100644
--- a/plugins/color/gsd-night-light.c
+++ b/plugins/color/gsd-night-light.c
@@ -44,6 +44,10 @@ struct _GsdNightLight {
gdouble cached_sunset;
gdouble cached_temperature;
gboolean cached_active;
+ gboolean smooth_enabled;
+ GTimer *smooth_timer;
+ guint smooth_id;
+ gdouble smooth_target_temperature;
GCancellable *cancellable;
GDateTime *datetime_override;
};
@@ -61,6 +65,7 @@ enum {
#define GSD_NIGHT_LIGHT_SCHEDULE_TIMEOUT 5 /* seconds */
#define GSD_NIGHT_LIGHT_POLL_TIMEOUT 60 /* seconds */
#define GSD_NIGHT_LIGHT_POLL_SMEAR 1 /* hours */
+#define GSD_NIGHT_LIGHT_SMOOTH_SMEAR 5.f /* seconds */
#define GSD_FRAC_DAY_MAX_DELTA (1.f/60.f) /* 1 minute */
#define GSD_TEMPERATURE_MAX_DELTA (10.f) /* Kelvin */
@@ -88,6 +93,27 @@ gsd_night_light_set_date_time_now (GsdNightLight *self, GDateTime *datetime)
self->datetime_override = g_date_time_ref (datetime);
}
+static void
+poll_smooth_destroy (GsdNightLight *self)
+{
+ if (self->smooth_id != 0) {
+ g_source_remove (self->smooth_id);
+ self->smooth_id = 0;
+ }
+ if (self->smooth_timer != NULL)
+ g_clear_pointer (&self->smooth_timer, g_timer_destroy);
+}
+
+void
+gsd_night_light_set_smooth_enabled (GsdNightLight *self,
+ gboolean smooth_enabled)
+{
+ /* ensure the timeout is stopped if called at runtime */
+ if (!smooth_enabled)
+ poll_smooth_destroy (self);
+ self->smooth_enabled = smooth_enabled;
+}
+
static gdouble
linear_interpolate (gdouble val1, gdouble val2, gdouble factor)
{
@@ -136,12 +162,65 @@ update_cached_sunrise_sunset (GsdNightLight *self)
}
static void
+gsd_night_light_set_temperature_internal (GsdNightLight *self, gdouble temperature)
+{
+ if (ABS (self->cached_temperature - temperature) <= GSD_TEMPERATURE_MAX_DELTA)
+ return;
+ self->cached_temperature = temperature;
+ g_object_notify (G_OBJECT (self), "temperature");
+}
+
+static gboolean
+gsd_night_light_smooth_cb (gpointer user_data)
+{
+ GsdNightLight *self = GSD_NIGHT_LIGHT (user_data);
+ gdouble tmp;
+ gdouble frac;
+
+ /* find fraction */
+ frac = g_timer_elapsed (self->smooth_timer, NULL) / GSD_NIGHT_LIGHT_SMOOTH_SMEAR;
+ if (frac >= 1.f) {
+ gsd_night_light_set_temperature_internal (self,
+ self->smooth_target_temperature);
+ self->smooth_id = 0;
+ return G_SOURCE_REMOVE;
+ }
+
+ /* set new temperature step using log curve */
+ tmp = self->smooth_target_temperature - self->cached_temperature;
+ tmp *= frac;
+ tmp += self->cached_temperature;
+ gsd_night_light_set_temperature_internal (self, tmp);
+
+ return G_SOURCE_CONTINUE;
+}
+
+static void
+poll_smooth_create (GsdNightLight *self, gdouble temperature)
+{
+ poll_smooth_destroy (self);
+ self->smooth_target_temperature = temperature;
+ self->smooth_timer = g_timer_new ();
+ self->smooth_id = g_timeout_add (50, gsd_night_light_smooth_cb, self);
+}
+
+static void
gsd_night_light_set_temperature (GsdNightLight *self, gdouble temperature)
{
- if (ABS (self->cached_temperature - temperature) > GSD_TEMPERATURE_MAX_DELTA) {
- self->cached_temperature = temperature;
- g_object_notify (G_OBJECT (self), "temperature");
+ /* immediate */
+ if (!self->smooth_enabled) {
+ gsd_night_light_set_temperature_internal (self, temperature);
+ return;
}
+
+ /* small jump */
+ if (ABS (temperature - self->cached_temperature) < GSD_TEMPERATURE_MAX_DELTA) {
+ gsd_night_light_set_temperature_internal (self, temperature);
+ return;
+ }
+
+ /* smooth out the transition */
+ poll_smooth_create (self, temperature);
}
static void
@@ -460,6 +539,7 @@ gsd_night_light_finalize (GObject *object)
GsdNightLight *self = GSD_NIGHT_LIGHT (object);
poll_timeout_destroy (self);
+ poll_smooth_destroy (self);
g_clear_object (&self->settings);
g_clear_pointer (&self->datetime_override, (GDestroyNotify) g_date_time_unref);
@@ -596,6 +676,7 @@ static void
gsd_night_light_init (GsdNightLight *self)
{
self->geoclue_enabled = TRUE;
+ self->smooth_enabled = TRUE;
self->cached_sunrise = -1.f;
self->cached_sunset = -1.f;
self->cached_temperature = GSD_COLOR_TEMPERATURE_DEFAULT;
diff --git a/plugins/color/gsd-night-light.h b/plugins/color/gsd-night-light.h
index 2403307..4f086dc 100644
--- a/plugins/color/gsd-night-light.h
+++ b/plugins/color/gsd-night-light.h
@@ -46,6 +46,8 @@ void gsd_night_light_set_geoclue_enabled (GsdNightLight *self,
gboolean enabled);
void gsd_night_light_set_date_time_now (GsdNightLight *self,
GDateTime *datetime);
+void gsd_night_light_set_smooth_enabled (GsdNightLight *self,
+ gboolean smooth_enabled);
G_END_DECLS
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]