aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCharles Kerr <charles.kerr@canonical.com>2012-09-20 12:13:34 +0000
committerTarmac <Unknown>2012-09-20 12:13:34 +0000
commitcf60516dfb380e4679fb929422988033f21436eb (patch)
tree6b53e189ec3eef1cbba18e605a60204a48d0d5d9
parent4e28e95f3bf1320fa92e88f6f103eab5a3812efa (diff)
parent3f4134737085a73ab0b9379922d1db941f66137e (diff)
downloadayatana-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.c82
-rw-r--r--src/indicator-datetime.c5
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);