diff options
author | Charles Kerr <charles.kerr@canonical.com> | 2012-09-20 12:13:34 +0000 |
---|---|---|
committer | Tarmac <Unknown> | 2012-09-20 12:13:34 +0000 |
commit | cf60516dfb380e4679fb929422988033f21436eb (patch) | |
tree | 6b53e189ec3eef1cbba18e605a60204a48d0d5d9 | |
parent | 4e28e95f3bf1320fa92e88f6f103eab5a3812efa (diff) | |
parent | 3f4134737085a73ab0b9379922d1db941f66137e (diff) | |
download | ayatana-indicator-datetime-cf60516dfb380e4679fb929422988033f21436eb.tar.gz ayatana-indicator-datetime-cf60516dfb380e4679fb929422988033f21436eb.tar.bz2 ayatana-indicator-datetime-cf60516dfb380e4679fb929422988033f21436eb.zip |
When clock skew is detected, rebuild the date/time labels.. Fixes: https://bugs.launchpad.net/bugs/917236. Approved by jenkins, Lars Uebernickel.
-rw-r--r-- | src/datetime-service.c | 82 | ||||
-rw-r--r-- | src/indicator-datetime.c | 5 |
2 files changed, 64 insertions, 23 deletions
diff --git a/src/datetime-service.c b/src/datetime-service.c index 6b06b45..ccdfe14 100644 --- a/src/datetime-service.c +++ b/src/datetime-service.c @@ -52,6 +52,11 @@ with this program. If not, see <http://www.gnu.org/licenses/>. #include "settings-shared.h" #include "utils.h" +/* how often to check for clock skew */ +#define SKEW_CHECK_INTERVAL_SEC 10 + +#define SKEW_DIFF_THRESHOLD_SEC (SKEW_CHECK_INTERVAL_SEC + 5) + #ifdef HAVE_CCPANEL #define SETTINGS_APP_INVOCATION "gnome-control-center indicator-datetime" #else @@ -61,7 +66,7 @@ with this program. If not, see <http://www.gnu.org/licenses/>. static void geo_create_client (GeoclueMaster * master, GeoclueMasterClient * client, gchar * path, GError * error, gpointer user_data); static gboolean update_appointment_menu_items (gpointer user_data); static void update_location_menu_items (void); -static void setup_timer (void); +static void day_timer_reset (void); static void geo_client_invalid (GeoclueMasterClient * client, gpointer user_data); static gboolean get_greeter_mode (void); @@ -355,7 +360,7 @@ update_datetime (gpointer user_data) g_date_time_unref (datetime); g_free(utf8); - return FALSE; + return G_SOURCE_REMOVE; } /* Run a particular program based on an activation */ @@ -1106,14 +1111,26 @@ build_menus (DbusmenuMenuitem * root) return; } +static void +on_clock_skew (void) +{ + /* tell the indicators to refresh */ + if (IS_DATETIME_INTERFACE (dbus)) + datetime_interface_update (DATETIME_INTERFACE(dbus)); + + /* update our day label */ + update_datetime (NULL); + day_timer_reset(); + + return; +} + /* Run when the timezone file changes */ static void timezone_changed (GFileMonitor * monitor, GFile * file, GFile * otherfile, GFileMonitorEvent event, gpointer user_data) { update_current_timezone(); - datetime_interface_update(DATETIME_INTERFACE(user_data)); - update_datetime(NULL); - setup_timer(); + on_clock_skew(); return; } @@ -1133,42 +1150,58 @@ build_timezone (DatetimeInterface * dbus) } /* Source ID for the timer */ -static guint timer = 0; +static guint day_timer = 0; /* Execute at a given time, update and setup a new timer to go again. */ static gboolean -timer_func (gpointer user_data) +day_timer_func (gpointer user_data) { - timer = 0; + day_timer = 0; /* Reset up each time to reduce error */ - setup_timer(); + day_timer_reset(); update_datetime(NULL); - return FALSE; + return G_SOURCE_REMOVE; } /* Sets up the time to launch the timer to update the date in the datetime entry */ static void -setup_timer (void) +day_timer_reset (void) { - if (timer != 0) { - g_source_remove(timer); - timer = 0; + if (day_timer != 0) { + g_source_remove(day_timer); + day_timer = 0; } time_t t; t = time(NULL); struct tm * ltime = localtime(&t); - timer = g_timeout_add_seconds(((23 - ltime->tm_hour) * 60 * 60) + - ((59 - ltime->tm_min) * 60) + - ((60 - ltime->tm_sec)) + 60 /* one minute past */, - timer_func, NULL); + day_timer = g_timeout_add_seconds(((23 - ltime->tm_hour) * 60 * 60) + + ((59 - ltime->tm_min) * 60) + + ((60 - ltime->tm_sec)) + 60 /* one minute past */, + day_timer_func, NULL); return; } +static gboolean +skew_check_timer_func (gpointer unused G_GNUC_UNUSED) +{ + static time_t prev_time = 0; + const time_t cur_time = time (NULL); + const double diff_sec = fabs (difftime (cur_time, prev_time)); + + if (prev_time && (diff_sec > SKEW_DIFF_THRESHOLD_SEC)) { + g_debug (G_STRLOC" clock skew detected (%.0f seconds)", diff_sec); + on_clock_skew (); + } + + prev_time = cur_time; + return G_SOURCE_CONTINUE; +} + static void session_active_change_cb (GDBusProxy * proxy, gchar * sender_name, gchar * signal_name, GVariant * parameters, gpointer user_data) @@ -1178,9 +1211,7 @@ session_active_change_cb (GDBusProxy * proxy, gchar * sender_name, gchar * signa gboolean idle = FALSE; g_variant_get(parameters, "(b)", &idle); if (!idle) { - datetime_interface_update(DATETIME_INTERFACE(user_data)); - update_datetime(NULL); - setup_timer(); + on_clock_skew (); } } return; @@ -1427,8 +1458,13 @@ main (int argc, char ** argv) /* Setup timezone watch */ build_timezone(dbus); - /* Setup the timer */ - setup_timer(); + /* Set up the day timer */ + day_timer_reset(); + + /* Set up the skew-check timer */ + g_timeout_add_seconds (SKEW_CHECK_INTERVAL_SEC, + skew_check_timer_func, + NULL); /* And watch for system resumes */ g_dbus_proxy_new_for_bus (G_BUS_TYPE_SYSTEM, diff --git a/src/indicator-datetime.c b/src/indicator-datetime.c index 9e34a65..2356c6d 100644 --- a/src/indicator-datetime.c +++ b/src/indicator-datetime.c @@ -154,6 +154,7 @@ GType indicator_datetime_get_type (void) G_GNUC_CONST; static void indicator_datetime_class_init (IndicatorDatetimeClass *klass); static void indicator_datetime_init (IndicatorDatetime *self); +static void timezone_update_all_labels (IndicatorDatetime *self); static void set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec); static void get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec); static void indicator_datetime_dispose (GObject *object); @@ -280,6 +281,10 @@ menu_visible_notfy_cb(GtkWidget * menu, G_GNUC_UNUSED GParamSpec *pspec, gpointe // Set the calendar to todays date ido_calendar_menu_item_set_date (self->priv->ido_calendar, y, m-1, d); + /* Update in case date was changed outside of indicator-datetime */ + update_label(self, NULL); + timezone_update_all_labels(self); + // Make sure the day-selected signal is sent so the menu updates - may duplicate /*GVariant *variant = g_variant_new_uint32((guint)curtime); guint timestamp = (guint)time(NULL); |