Package: evolution-data-server
Version: 3.30.5-1
Tags: patch

Hi,

There's an issue in evolution-data-server/buster: reminders for events
stop working properly after suspending the system [1]. It makes them
mostly useless.

The bug was fixed in upstream commit 60fa52112. The fix is not too
large, and I believe it can be backported as-is. A cherry-picked patch
for 3.30.5-1 is attached. I've tested it and it works as expected.

 [1] https://gitlab.gnome.org/GNOME/evolution-data-server/issues/109
From 5e38fb160cb68d62abb6eab501b2fa84bd1ae893 Mon Sep 17 00:00:00 2001
From: Milan Crha <mc...@redhat.com>
Date: Mon, 6 May 2019 17:50:38 +0200
Subject: [PATCH] I#190 - Does not show reminders after resume from suspend

Closes https://gitlab.gnome.org/GNOME/evolution-data-server/issues/109
---
 src/calendar/libecal/e-reminder-watcher.c | 46 +++++++++++++++++++++++
 1 file changed, 46 insertions(+)

diff --git a/src/calendar/libecal/e-reminder-watcher.c b/src/calendar/libecal/e-reminder-watcher.c
index 79a07d619..4cec6e151 100644
--- a/src/calendar/libecal/e-reminder-watcher.c
+++ b/src/calendar/libecal/e-reminder-watcher.c
@@ -1787,6 +1787,43 @@ e_reminder_watcher_source_disappeared_cb (EReminderWatcher *watcher,
 	g_rec_mutex_unlock (&watcher->priv->lock);
 }
 
+static gboolean
+e_reminder_watcher_check_wall_clock_time_changed_cb (gpointer user_data)
+{
+	EReminderWatcher *watcher = user_data;
+	gint64 wall_clock_time;
+
+	if (g_source_is_destroyed (g_main_current_source ()))
+		return FALSE;
+
+	g_return_val_if_fail (E_IS_REMINDER_WATCHER (watcher), FALSE);
+
+	#define ADD_SECONDS(to, secs) ((to) + ((secs) * G_USEC_PER_SEC))
+
+	wall_clock_time = g_get_real_time ();
+
+	/* Use one second margin */
+	if (wall_clock_time > ADD_SECONDS (watcher->priv->expected_wall_clock_time, 1) ||
+	    wall_clock_time < ADD_SECONDS (watcher->priv->expected_wall_clock_time, -1)) {
+		gint64 diff = (wall_clock_time - watcher->priv->expected_wall_clock_time) / 1000;
+
+		e_reminder_watcher_debug_print ("Current wall-clock time differs from expected by %" G_GINT64_FORMAT " ms, rescheduling reminders\n", diff);
+
+		/* To make sure the timer is re-scheduled */
+		watcher->priv->next_trigger = 0;
+
+		e_reminder_watcher_maybe_schedule_next_trigger (watcher, 0);
+
+		wall_clock_time = g_get_real_time ();
+	}
+
+	watcher->priv->expected_wall_clock_time = ADD_SECONDS (wall_clock_time, 60);
+
+	#undef ADD_SECONDS
+
+	return TRUE;
+}
+
 static gboolean
 e_reminder_watcher_construct_idle_cb (gpointer user_data)
 {
@@ -1813,6 +1850,15 @@ e_reminder_watcher_construct_idle_cb (gpointer user_data)
 
 	e_source_registry_watcher_reclaim (watcher->priv->registry_watcher);
 
+	if (!watcher->priv->wall_clock_handler_id) {
+		/* Monotonic time doesn't change during hibernation, while the
+		 * wall clock time does, thus check for wall clock time changes
+		 * and reschedule alarms when it changes. */
+		watcher->priv->expected_wall_clock_time = g_get_real_time () + (60 * G_USEC_PER_SEC);
+		watcher->priv->wall_clock_handler_id = e_named_timeout_add_seconds (60,
+			e_reminder_watcher_check_wall_clock_time_changed_cb, watcher);
+	}
+
 	if (!watcher->priv->snoozed)
 		watcher->priv->snoozed = e_reminder_watcher_reminders_from_key (watcher, "reminders-snoozed");
 
-- 
2.20.1

Reply via email to