Merge lp:~ted/indicator-application/repeating-items into lp:indicator-application/0.4

Proposed by Ted Gould on 2011-03-11
Status: Merged
Merged at revision: 189
Proposed branch: lp:~ted/indicator-application/repeating-items
Merge into: lp:indicator-application/0.4
Diff against target: 115 lines (+57/-2)
1 file modified
src/indicator-application.c (+57/-2)
To merge this branch: bzr merge lp:~ted/indicator-application/repeating-items
Reviewer Review Type Date Requested Status
Conor Curran (community) 2011-03-11 Approve on 2011-03-15
Review via email: mp+53102@code.launchpad.net

Description of the change

Fixes the duplicate indicators by handling the case when signals are emitted while we have a GetApplications in flight. We basically ignore the signals and recall the GetApplications to ensure that the response is in the correct state. This can delay startup in a few cases, but gaurantees that we won't end up in an inconsistent state.

To post a comment you must log in.
Conor Curran (cjcurran) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/indicator-application.c'
2--- src/indicator-application.c 2011-02-25 03:53:44 +0000
3+++ src/indicator-application.c 2011-03-11 22:44:29 +0000
4@@ -86,6 +86,7 @@
5 GList * applications;
6 GHashTable * theme_dirs;
7 guint disconnect_kill;
8+ GCancellable * get_apps_cancel;
9 };
10
11 typedef struct _ApplicationEntry ApplicationEntry;
12@@ -166,6 +167,8 @@
13
14 priv->theme_dirs = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL);
15
16+ priv->get_apps_cancel = NULL;
17+
18 return;
19 }
20
21@@ -178,6 +181,12 @@
22 g_source_remove(priv->disconnect_kill);
23 }
24
25+ if (priv->get_apps_cancel != NULL) {
26+ g_cancellable_cancel(priv->get_apps_cancel);
27+ g_object_unref(priv->get_apps_cancel);
28+ priv->get_apps_cancel = NULL;
29+ }
30+
31 while (priv->applications != NULL) {
32 application_removed(INDICATOR_APPLICATION(object),
33 0);
34@@ -290,10 +299,20 @@
35
36 g_signal_connect(proxy, "g-signal", G_CALLBACK(receive_signal), self);
37
38+ /* We shouldn't be in a situation where we've already
39+ called this function. It doesn't *hurt* anything, but
40+ man we should look into it more. */
41+ if (priv->get_apps_cancel != NULL) {
42+ g_warning("Already getting applications? Odd.");
43+ return;
44+ }
45+
46+ priv->get_apps_cancel = g_cancellable_new();
47+
48 /* Query it for existing applications */
49 g_debug("Request current apps");
50 g_dbus_proxy_call(priv->service_proxy, "GetApplications", NULL,
51- G_DBUS_CALL_FLAGS_NONE, -1, NULL,
52+ G_DBUS_CALL_FLAGS_NONE, -1, priv->get_apps_cancel,
53 get_applications, self);
54
55 return;
56@@ -730,6 +749,22 @@
57 GVariant * parameters, gpointer user_data)
58 {
59 IndicatorApplication * self = INDICATOR_APPLICATION(user_data);
60+ IndicatorApplicationPrivate * priv = INDICATOR_APPLICATION_GET_PRIVATE(self);
61+
62+ /* If we're in the middle of a GetApplications call and we get
63+ any of these our state is probably going to just be confused. Let's
64+ cancel the call we had and try again to try and get a clear answer */
65+ if (priv->get_apps_cancel != NULL) {
66+ g_cancellable_cancel(priv->get_apps_cancel);
67+ g_object_unref(priv->get_apps_cancel);
68+
69+ priv->get_apps_cancel = g_cancellable_new();
70+
71+ g_dbus_proxy_call(priv->service_proxy, "GetApplications", NULL,
72+ G_DBUS_CALL_FLAGS_NONE, -1, priv->get_apps_cancel,
73+ get_applications, self);
74+ return;
75+ }
76
77 if (g_strcmp0(signal_name, "ApplicationAdded") == 0) {
78 const gchar * iconname;
79@@ -791,15 +826,35 @@
80
81 result = g_dbus_proxy_call_finish(priv->service_proxy, res, &error);
82
83+ /* No one can cancel us anymore, we've completed! */
84+ if (priv->get_apps_cancel != NULL) {
85+ if (error == NULL || error->domain != G_IO_ERROR || error->code != G_IO_ERROR_CANCELLED) {
86+ g_object_unref(priv->get_apps_cancel);
87+ priv->get_apps_cancel = NULL;
88+ }
89+ }
90+
91+ /* If we got an error, print it and exit out */
92 if (error != NULL) {
93 g_warning("Unable to get application list: %s", error->message);
94+ g_error_free(error);
95 return;
96 }
97
98+ /* Remove all applications that we previously had
99+ as we're going to repopulate the list. */
100+ while (priv->applications != NULL) {
101+ application_removed(self, 0);
102+ }
103+
104+ /* Get our new applications that we got in the request */
105 g_variant_get(result, "(a(sisossss))", &iter);
106- while ((child = g_variant_iter_next_value (iter)))
107+ while ((child = g_variant_iter_next_value (iter))) {
108 get_applications_helper(self, child);
109+ g_variant_unref(child);
110+ }
111 g_variant_iter_free (iter);
112+ g_variant_unref(result);
113
114 return;
115 }

Subscribers

People subscribed via source and target branches