aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCharles Kerr <charles.kerr@canonical.com>2012-10-03 22:56:10 -0500
committerCharles Kerr <charles.kerr@canonical.com>2012-10-03 22:56:10 -0500
commit0048385ecec65c6bbfad527261ac9d8ac180d0ef (patch)
treeb6c02186a82d1ae992da0d6a4cf974e856da4197
parent6db1219ef000df92d5389922123fe85170fa9350 (diff)
downloadayatana-indicator-datetime-0048385ecec65c6bbfad527261ac9d8ac180d0ef.tar.gz
ayatana-indicator-datetime-0048385ecec65c6bbfad527261ac9d8ac180d0ef.tar.bz2
ayatana-indicator-datetime-0048385ecec65c6bbfad527261ac9d8ac180d0ef.zip
Our client code for EDS 3.5 is triggering a periodic loop of rebuilds:
1. We create an ESource and listen for its "changed" signal. 2. EDS appears to be emitting a "changed" idly after the source is created. 3. We handle the changed event by rebuilding our source list... goto 1. This commit breaks the loop by building the appointment source list once on startup and keeping it as a private field. It adds upkeep code to rebuild the list when the EDS registry tells us that sources have been added or removed.
-rw-r--r--src/datetime-service.c84
1 files changed, 54 insertions, 30 deletions
diff --git a/src/datetime-service.c b/src/datetime-service.c
index 0064519..6d3c56a 100644
--- a/src/datetime-service.c
+++ b/src/datetime-service.c
@@ -90,6 +90,8 @@ static GList * comp_instances = NULL;
static gboolean updating_appointments = FALSE;
static time_t start_time_appointments = (time_t) 0;
static GSettings * conf = NULL;
+static ESourceRegistry * source_registry = NULL;
+static GList * appointment_sources = NULL;
/* Geoclue trackers */
@@ -535,20 +537,8 @@ calendar_app_is_usable (void)
g_debug ("found calendar app: '%s'", evo);
g_free (evo);
- /* see if there are any enabled calendars */
- gboolean has_enabled_calendar_source = FALSE;
- ESourceRegistry * registry = e_source_registry_new_sync (NULL, NULL);
- if (registry != NULL) {
- GList * l = NULL;
- GList * sources = NULL;
- sources = e_source_registry_list_sources (registry, E_SOURCE_EXTENSION_CALENDAR);
- for (l=sources; !has_enabled_calendar_source && l!=NULL; l=l->next)
- has_enabled_calendar_source = e_source_get_enabled (E_SOURCE(l->data));
- g_list_free_full (sources, g_object_unref);
- g_object_unref (registry);
- }
-
- return has_enabled_calendar_source;
+ /* see if there are any calendar sources */
+ return appointment_sources > 0;
}
/* Looks for the calendar application and enables the item if
@@ -688,7 +678,6 @@ update_appointment_menu_items (gpointer unused)
GError *gerror = NULL;
gint i;
gint width = 0, height = 0;
- ESourceRegistry * src_registry = NULL;
GList * sources = NULL;
// Get today & work out query times
@@ -733,19 +722,10 @@ update_appointment_menu_items (gpointer unused)
g_list_free_full (comp_instances, (GDestroyNotify)comp_instance_free);
comp_instances = NULL;
- src_registry = e_source_registry_new_sync (NULL, &gerror);
- if (!src_registry) {
- g_debug("Failed to get access to source registry: %s\n", gerror->message);
- return FALSE;
- }
-
- sources = e_source_registry_list_sources(src_registry, E_SOURCE_EXTENSION_CALENDAR);
-
// Generate instances for all sources
- for (s = g_list_first (sources); s; s = g_list_next (s)) {
+ for (s=appointment_sources; s!=NULL; s=s->next) {
ESource *source = E_SOURCE (s->data);
- g_signal_connect (G_OBJECT(source), "changed", G_CALLBACK (update_appointment_menu_items), NULL);
ECalClient *ecal = e_cal_client_new(source, E_CAL_CLIENT_SOURCE_TYPE_EVENTS, &gerror);
icaltimezone* current_zone = icaltimezone_get_builtin_timezone(current_timezone);
@@ -767,14 +747,14 @@ update_appointment_menu_items (gpointer unused)
continue;
}
- e_cal_client_generate_instances (ecal, t1, t2, NULL,
- (ECalRecurInstanceFn) populate_appointment_instances,
- (gpointer) source,
- NULL);
+ e_cal_client_generate_instances_sync (ecal,
+ t1,
+ t2,
+ populate_appointment_instances,
+ source);
}
g_object_unref(ecal);
}
- g_list_free_full (sources, g_object_unref);
g_debug("Number of ECalComponents returned: %d", g_list_length(comp_instances));
GList *sorted_comp_instances = g_list_sort(comp_instances, compare_comp_instances);
@@ -1398,6 +1378,34 @@ service_shutdown (IndicatorService * service, gpointer user_data)
return;
}
+static void
+free_appointment_sources (void)
+{
+ g_list_free_full (appointment_sources, g_object_unref);
+ appointment_sources = NULL;
+}
+
+static void
+init_appointment_sources (void)
+{
+ GList * l;
+
+ appointment_sources = e_source_registry_list_sources (source_registry, E_SOURCE_EXTENSION_CALENDAR);
+
+ for (l=appointment_sources; l!=NULL; l=l->next)
+ g_signal_connect (G_OBJECT(l->data), "changed", G_CALLBACK (update_appointment_menu_items), NULL);
+}
+
+/* rebuilds both the appointment sources and menu */
+static void
+update_appointments (void)
+{
+ free_appointment_sources ();
+ init_appointment_sources ();
+
+ update_appointment_menu_items (NULL);
+}
+
/* Function to build everything up. Entry point from asm. */
int
main (int argc, char ** argv)
@@ -1418,6 +1426,19 @@ main (int argc, char ** argv)
conf = g_settings_new(SETTINGS_INTERFACE);
// TODO Add a signal handler to catch gsettings changes and respond to them
+ /* Build our list of appointment calendar sources.
+ When a source changes, update our menu items.
+ When sources are added or removed, update our list and menu items. */
+ source_registry = e_source_registry_new_sync (NULL, NULL);
+ g_object_connect (source_registry,
+ "signal::source-added", update_appointments,
+ "signal::source-removed", update_appointments,
+ "signal::source-changed", update_appointment_menu_items,
+ "signal::source-disabled", update_appointment_menu_items,
+ "signal::source-enabled", update_appointment_menu_items,
+ NULL);
+ init_appointment_sources ();
+
/* Building the base menu */
server = dbusmenu_server_new(MENU_OBJ);
root = dbusmenu_menuitem_new();
@@ -1458,12 +1479,15 @@ main (int argc, char ** argv)
mainloop = g_main_loop_new(NULL, FALSE);
g_main_loop_run(mainloop);
+ free_appointment_sources();
+
g_object_unref(G_OBJECT(conf));
g_object_unref(G_OBJECT(master));
g_object_unref(G_OBJECT(dbus));
g_object_unref(G_OBJECT(service));
g_object_unref(G_OBJECT(server));
g_object_unref(G_OBJECT(root));
+ g_object_unref(G_OBJECT(source_registry));
icaltimezone_free_builtin_timezones();