Merge lp:~mterry/indicator-application/gdbus into lp:indicator-application/0.4
- gdbus
- Merge into trunk
Proposed by
Michael Terry
Status: | Merged |
---|---|
Merged at revision: | 171 |
Proposed branch: | lp:~mterry/indicator-application/gdbus |
Merge into: | lp:indicator-application/0.4 |
Diff against target: |
2473 lines (+941/-842) 13 files modified
.bzrignore (+2/-5) configure.ac (+3/-0) data/indicator-application.service.in (+1/-1) src/Makefile.am (+21/-9) src/application-service-appstore.c (+645/-544) src/application-service.c (+0/-1) src/application-service.xml (+1/-1) src/dbus-properties.xml (+0/-23) src/dbus-shared.h (+3/-3) src/indicator-application.c (+155/-177) src/notification-item.xml (+0/-39) tests/Makefile.am (+1/-0) tests/test-approver.c (+109/-39) |
To merge this branch: | bzr merge lp:~mterry/indicator-application/gdbus |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Ted Gould (community) | Approve | ||
Review via email: mp+46009@code.launchpad.net |
Commit message
Description of the change
To post a comment you must log in.
- 173. By Michael Terry
-
fix issue where icons never went away
- 174. By Michael Terry
-
watch for name change, instead of name owner change for approver connections
- 175. By Michael Terry
-
don't second guess service's new application, which caused our positions to get out of sync with the service if it was a bit confused
- 176. By Michael Terry
-
actually request properties from applications; using cached properties doesn't seem to work
- 177. By Michael Terry
-
don't use cached properties for new icons or new aicons either. Instead, just ask for all properties again
- 178. By Michael Terry
-
reduce debug spew
- 179. By Michael Terry
-
make sure to free pre-validated applications; add applications to the app list as soon as we create them, to avoid apps that spam us (like gnome-power-
manager) from creating multiple apps in our list - 180. By Michael Terry
-
merge ken's com.canonical branch
Revision history for this message
Ted Gould (ted) : | # |
review:
Approve
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file '.bzrignore' |
2 | --- .bzrignore 2010-08-11 16:10:03 +0000 |
3 | +++ .bzrignore 2011-01-14 02:39:08 +0000 |
4 | @@ -4,8 +4,6 @@ |
5 | src/indicator-application-service |
6 | src/libappindicator.la |
7 | src/libappindicator_la-indicator-application.lo |
8 | -src/notification-item-client.h |
9 | -src/notification-item-server.h |
10 | src/notification-watcher-client.h |
11 | src/notification-watcher-server.h |
12 | src/libappindicator.la |
13 | @@ -23,13 +21,12 @@ |
14 | tests/test-libappindicator-dbus-server |
15 | tests/libappindicator-tests |
16 | tests/test-libappindicator-dbus |
17 | -src/application-service-client.h |
18 | +src/gen-application-service.xml.c |
19 | +src/gen-application-service.xml.h |
20 | src/application-service-server.h |
21 | src/application-service-marshal.c |
22 | src/application-service-marshal.h |
23 | src/stamp-marshal |
24 | -src/dbus-properties-client.h |
25 | -src/dbus-properties-server.h |
26 | tests/test-simple-app |
27 | example/.deps |
28 | example/.libs |
29 | |
30 | === modified file 'configure.ac' |
31 | --- configure.ac 2010-12-08 19:16:13 +0000 |
32 | +++ configure.ac 2011-01-14 02:39:08 +0000 |
33 | @@ -31,6 +31,7 @@ |
34 | |
35 | GTK_REQUIRED_VERSION=2.18 |
36 | GTK3_REQUIRED_VERSION=2.91 |
37 | +GIO_REQUIRED_VERSION=2.26 |
38 | INDICATOR_REQUIRED_VERSION=0.3.5 |
39 | DBUSMENUGTK_REQUIRED_VERSION=0.2.2 |
40 | JSON_GLIB_REQUIRED_VERSION=0.7.6 |
41 | @@ -43,6 +44,7 @@ |
42 | [with_gtk=2]) |
43 | AS_IF([test "x$with_gtk" = x3], |
44 | [PKG_CHECK_MODULES(INDICATOR, gtk+-3.0 >= $GTK3_REQUIRED_VERSION |
45 | + gio-2.0 >= $GIO_REQUIRED_VERSION |
46 | indicator3 >= $INDICATOR_REQUIRED_VERSION |
47 | json-glib-1.0 >= $JSON_GLIB_REQUIRED_VERSION |
48 | dbus-glib-1 >= $DBUS_GLIB_REQUIRED_VERSION |
49 | @@ -53,6 +55,7 @@ |
50 | ], |
51 | [test "x$with_gtk" = x2], |
52 | [PKG_CHECK_MODULES(INDICATOR, gtk+-2.0 >= $GTK_REQUIRED_VERSION |
53 | + gio-2.0 >= $GIO_REQUIRED_VERSION |
54 | indicator >= $INDICATOR_REQUIRED_VERSION |
55 | json-glib-1.0 >= $JSON_GLIB_REQUIRED_VERSION |
56 | dbus-glib-1 >= $DBUS_GLIB_REQUIRED_VERSION |
57 | |
58 | === modified file 'data/indicator-application.service.in' |
59 | --- data/indicator-application.service.in 2009-11-25 03:52:40 +0000 |
60 | +++ data/indicator-application.service.in 2011-01-14 02:39:08 +0000 |
61 | @@ -1,3 +1,3 @@ |
62 | [D-BUS Service] |
63 | -Name=org.ayatana.indicator.application |
64 | +Name=com.canonical.indicator.application |
65 | Exec=@libexecdir@/indicator-application-service |
66 | |
67 | === modified file 'src/Makefile.am' |
68 | --- src/Makefile.am 2010-12-08 19:09:39 +0000 |
69 | +++ src/Makefile.am 2011-01-14 02:39:08 +0000 |
70 | @@ -39,11 +39,8 @@ |
71 | libexec_PROGRAMS = indicator-application-service |
72 | |
73 | BUILT_SOURCES += \ |
74 | - application-service-server.h \ |
75 | application-service-marshal.h \ |
76 | application-service-marshal.c \ |
77 | - dbus-properties-client.h \ |
78 | - notification-item-client.h \ |
79 | notification-watcher-server.h |
80 | |
81 | indicator_application_service_SOURCES = \ |
82 | @@ -53,6 +50,7 @@ |
83 | application-service-marshal.c \ |
84 | application-service-watcher.h \ |
85 | application-service-watcher.c \ |
86 | + gen-application-service.xml.c \ |
87 | app-indicator-enum-types.c \ |
88 | dbus-shared.h \ |
89 | generate-id.h \ |
90 | @@ -81,11 +79,11 @@ |
91 | # DBus Specs |
92 | ################################## |
93 | |
94 | +GDBUS_SPECS = \ |
95 | + application-service.xml \ |
96 | + notification-approver.xml |
97 | + |
98 | DBUS_SPECS = \ |
99 | - dbus-properties.xml \ |
100 | - application-service.xml \ |
101 | - notification-approver.xml \ |
102 | - notification-item.xml \ |
103 | notification-watcher.xml |
104 | |
105 | %-client.h: %.xml |
106 | @@ -102,10 +100,24 @@ |
107 | --output=$@ \ |
108 | $< |
109 | |
110 | +gen-%.xml.c: %.xml |
111 | + @echo "Building $@ from $<" |
112 | + @echo "const char * _$(subst -,_,$(subst .,_,$(basename $<))) = " > $@ |
113 | + @sed -e "s:\":\\\\\":g" -e s:^:\": -e s:\$$:\\\\n\": $< >> $@ |
114 | + @echo ";" >> $@ |
115 | + |
116 | +gen-%.xml.h: %.xml |
117 | + @echo "Building $@ from $<" |
118 | + @echo "extern const char * _$(subst -,_,$(subst .,_,$(basename $<)));" > $@ |
119 | + |
120 | BUILT_SOURCES += \ |
121 | $(DBUS_SPECS:.xml=-client.h) \ |
122 | - $(DBUS_SPECS:.xml=-server.h) |
123 | + $(DBUS_SPECS:.xml=-server.h) \ |
124 | + gen-application-service.xml.c \ |
125 | + gen-application-service.xml.h \ |
126 | + gen-notification-approver.xml.c \ |
127 | + gen-notification-approver.xml.h |
128 | |
129 | CLEANFILES += $(BUILT_SOURCES) |
130 | |
131 | -EXTRA_DIST += $(DBUS_SPECS) |
132 | +EXTRA_DIST += $(DBUS_SPECS) $(GDBUS_SPECS) |
133 | |
134 | === modified file 'src/application-service-appstore.c' |
135 | --- src/application-service-appstore.c 2010-12-02 22:49:42 +0000 |
136 | +++ src/application-service-appstore.c 2011-01-14 02:39:08 +0000 |
137 | @@ -24,20 +24,19 @@ |
138 | #include "config.h" |
139 | #endif |
140 | |
141 | -#include <dbus/dbus-glib.h> |
142 | #include "libappindicator/app-indicator.h" |
143 | #include "app-indicator-enum-types.h" |
144 | #include "application-service-appstore.h" |
145 | #include "application-service-marshal.h" |
146 | -#include "dbus-properties-client.h" |
147 | #include "dbus-shared.h" |
148 | -#include "notification-approver-client.h" |
149 | #include "generate-id.h" |
150 | |
151 | /* DBus Prototypes */ |
152 | -static gboolean _application_service_server_get_applications (ApplicationServiceAppstore * appstore, GPtrArray ** apps, GError ** error); |
153 | +static GVariant * get_applications (ApplicationServiceAppstore * appstore); |
154 | +static void bus_method_call (GDBusConnection * connection, const gchar * sender, const gchar * path, const gchar * interface, const gchar * method, GVariant * params, GDBusMethodInvocation * invocation, gpointer user_data); |
155 | +static void props_cb (GObject * object, GAsyncResult * res, gpointer user_data); |
156 | |
157 | -#include "application-service-server.h" |
158 | +#include "gen-application-service.xml.h" |
159 | |
160 | #define NOTIFICATION_ITEM_PROP_ID "Id" |
161 | #define NOTIFICATION_ITEM_PROP_CATEGORY "Category" |
162 | @@ -61,7 +60,9 @@ |
163 | |
164 | /* Private Stuff */ |
165 | struct _ApplicationServiceAppstorePrivate { |
166 | - DBusGConnection * bus; |
167 | + GCancellable * bus_cancel; |
168 | + GDBusConnection * bus; |
169 | + guint dbus_registration; |
170 | GList * applications; |
171 | GList * approvers; |
172 | GHashTable * ordering_overrides; |
173 | @@ -76,8 +77,10 @@ |
174 | |
175 | typedef struct _Approver Approver; |
176 | struct _Approver { |
177 | - DBusGProxy * proxy; |
178 | - gboolean destroy_by_proxy; |
179 | + ApplicationServiceAppstore * appstore; /* not ref'd */ |
180 | + GCancellable * proxy_cancel; |
181 | + GDBusProxy * proxy; |
182 | + guint name_watcher; |
183 | }; |
184 | |
185 | typedef struct _Application Application; |
186 | @@ -87,8 +90,11 @@ |
187 | gchar * dbus_name; |
188 | gchar * dbus_object; |
189 | ApplicationServiceAppstore * appstore; /* not ref'd */ |
190 | - DBusGProxy * dbus_proxy; |
191 | - DBusGProxy * prop_proxy; |
192 | + GCancellable * dbus_proxy_cancel; |
193 | + GDBusProxy * dbus_proxy; |
194 | + GCancellable * props_cancel; |
195 | + gboolean queued_props; |
196 | + GDBusProxy * props; |
197 | gboolean validated; /* Whether we've gotten all the parameters and they look good. */ |
198 | AppIndicatorStatus status; |
199 | gchar * icon; |
200 | @@ -101,23 +107,21 @@ |
201 | guint ordering_index; |
202 | GList * approved_by; |
203 | visible_state_t visible_state; |
204 | + guint name_watcher; |
205 | }; |
206 | |
207 | #define APPLICATION_SERVICE_APPSTORE_GET_PRIVATE(o) \ |
208 | (G_TYPE_INSTANCE_GET_PRIVATE ((o), APPLICATION_SERVICE_APPSTORE_TYPE, ApplicationServiceAppstorePrivate)) |
209 | |
210 | -/* Signals Stuff */ |
211 | -enum { |
212 | - APPLICATION_ADDED, |
213 | - APPLICATION_REMOVED, |
214 | - APPLICATION_ICON_CHANGED, |
215 | - APPLICATION_LABEL_CHANGED, |
216 | - APPLICATION_ICON_THEME_PATH_CHANGED, |
217 | - LAST_SIGNAL |
218 | +/* GDBus Stuff */ |
219 | +static GDBusNodeInfo * node_info = NULL; |
220 | +static GDBusInterfaceInfo * interface_info = NULL; |
221 | +static GDBusInterfaceVTable interface_table = { |
222 | + method_call: bus_method_call, |
223 | + get_property: NULL, /* No properties */ |
224 | + set_property: NULL /* No properties */ |
225 | }; |
226 | |
227 | -static guint signals[LAST_SIGNAL] = { 0 }; |
228 | - |
229 | /* GObject stuff */ |
230 | static void application_service_appstore_class_init (ApplicationServiceAppstoreClass *klass); |
231 | static void application_service_appstore_init (ApplicationServiceAppstore *self); |
232 | @@ -132,6 +136,13 @@ |
233 | static void check_with_new_approver (gpointer papp, gpointer papprove); |
234 | static void check_with_old_approver (gpointer papprove, gpointer papp); |
235 | static Application * find_application (ApplicationServiceAppstore * appstore, const gchar * address, const gchar * object); |
236 | +static void bus_get_cb (GObject * object, GAsyncResult * res, gpointer user_data); |
237 | +static void dbus_proxy_cb (GObject * object, GAsyncResult * res, gpointer user_data); |
238 | +static void app_receive_signal (GDBusProxy * proxy, gchar * sender_name, gchar * signal_name, GVariant * parameters, gpointer user_data); |
239 | +static void approver_proxy_cb (GObject * object, GAsyncResult * res, gpointer user_data); |
240 | +static void approver_receive_signal (GDBusProxy * proxy, gchar * sender_name, gchar * signal_name, GVariant * parameters, gpointer user_data); |
241 | +static void get_all_properties (Application * app); |
242 | +static void application_free (Application * app); |
243 | |
244 | G_DEFINE_TYPE (ApplicationServiceAppstore, application_service_appstore, G_TYPE_OBJECT); |
245 | |
246 | @@ -145,56 +156,24 @@ |
247 | object_class->dispose = application_service_appstore_dispose; |
248 | object_class->finalize = application_service_appstore_finalize; |
249 | |
250 | - signals[APPLICATION_ADDED] = g_signal_new ("application-added", |
251 | - G_TYPE_FROM_CLASS(klass), |
252 | - G_SIGNAL_RUN_LAST, |
253 | - G_STRUCT_OFFSET (ApplicationServiceAppstoreClass, application_added), |
254 | - NULL, NULL, |
255 | - _application_service_marshal_VOID__STRING_INT_STRING_STRING_STRING_STRING_STRING, |
256 | - G_TYPE_NONE, 7, G_TYPE_STRING, G_TYPE_INT, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_NONE); |
257 | - signals[APPLICATION_REMOVED] = g_signal_new ("application-removed", |
258 | - G_TYPE_FROM_CLASS(klass), |
259 | - G_SIGNAL_RUN_LAST, |
260 | - G_STRUCT_OFFSET (ApplicationServiceAppstoreClass, application_removed), |
261 | - NULL, NULL, |
262 | - g_cclosure_marshal_VOID__INT, |
263 | - G_TYPE_NONE, 1, G_TYPE_INT, G_TYPE_NONE); |
264 | - signals[APPLICATION_ICON_CHANGED] = g_signal_new ("application-icon-changed", |
265 | - G_TYPE_FROM_CLASS(klass), |
266 | - G_SIGNAL_RUN_LAST, |
267 | - G_STRUCT_OFFSET (ApplicationServiceAppstoreClass, application_icon_changed), |
268 | - NULL, NULL, |
269 | - _application_service_marshal_VOID__INT_STRING, |
270 | - G_TYPE_NONE, 2, G_TYPE_INT, G_TYPE_STRING, G_TYPE_NONE); |
271 | - signals[APPLICATION_ICON_THEME_PATH_CHANGED] = g_signal_new ("application-icon-theme-path-changed", |
272 | - G_TYPE_FROM_CLASS(klass), |
273 | - G_SIGNAL_RUN_LAST, |
274 | - G_STRUCT_OFFSET (ApplicationServiceAppstoreClass, application_icon_theme_path_changed), |
275 | - NULL, NULL, |
276 | - _application_service_marshal_VOID__INT_STRING, |
277 | - G_TYPE_NONE, 2, G_TYPE_INT, G_TYPE_STRING, G_TYPE_NONE); |
278 | - signals[APPLICATION_LABEL_CHANGED] = g_signal_new ("application-label-changed", |
279 | - G_TYPE_FROM_CLASS(klass), |
280 | - G_SIGNAL_RUN_LAST, |
281 | - G_STRUCT_OFFSET (ApplicationServiceAppstoreClass, application_label_changed), |
282 | - NULL, NULL, |
283 | - _application_service_marshal_VOID__INT_STRING_STRING, |
284 | - G_TYPE_NONE, 3, G_TYPE_INT, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_NONE); |
285 | - |
286 | - dbus_g_object_register_marshaller(_application_service_marshal_VOID__STRING_STRING, |
287 | - G_TYPE_NONE, |
288 | - G_TYPE_STRING, |
289 | - G_TYPE_STRING, |
290 | - G_TYPE_INVALID); |
291 | - dbus_g_object_register_marshaller(_application_service_marshal_VOID__BOOLEAN_STRING_OBJECT, |
292 | - G_TYPE_NONE, |
293 | - G_TYPE_BOOLEAN, |
294 | - G_TYPE_STRING, |
295 | - G_TYPE_OBJECT, |
296 | - G_TYPE_INVALID); |
297 | - |
298 | - dbus_g_object_type_install_info(APPLICATION_SERVICE_APPSTORE_TYPE, |
299 | - &dbus_glib__application_service_server_object_info); |
300 | + /* Setting up the DBus interfaces */ |
301 | + if (node_info == NULL) { |
302 | + GError * error = NULL; |
303 | + |
304 | + node_info = g_dbus_node_info_new_for_xml(_application_service, &error); |
305 | + if (error != NULL) { |
306 | + g_error("Unable to parse Application Service Interface description: %s", error->message); |
307 | + g_error_free(error); |
308 | + } |
309 | + } |
310 | + |
311 | + if (interface_info == NULL) { |
312 | + interface_info = g_dbus_node_info_lookup_interface(node_info, INDICATOR_APPLICATION_DBUS_IFACE); |
313 | + |
314 | + if (interface_info == NULL) { |
315 | + g_error("Unable to find interface '" INDICATOR_APPLICATION_DBUS_IFACE "'"); |
316 | + } |
317 | + } |
318 | |
319 | return; |
320 | } |
321 | @@ -207,6 +186,8 @@ |
322 | |
323 | priv->applications = NULL; |
324 | priv->approvers = NULL; |
325 | + priv->bus_cancel = NULL; |
326 | + priv->dbus_registration = 0; |
327 | |
328 | priv->ordering_overrides = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL); |
329 | |
330 | @@ -214,21 +195,76 @@ |
331 | gchar * userfile = g_build_filename(g_get_user_data_dir(), "indicators", "application", OVERRIDE_FILE_NAME, NULL); |
332 | load_override_file(priv->ordering_overrides, userfile); |
333 | g_free(userfile); |
334 | - |
335 | + |
336 | + priv->bus_cancel = g_cancellable_new(); |
337 | + g_bus_get(G_BUS_TYPE_SESSION, |
338 | + priv->bus_cancel, |
339 | + bus_get_cb, |
340 | + self); |
341 | + |
342 | + self->priv = priv; |
343 | + |
344 | + return; |
345 | +} |
346 | + |
347 | +static void |
348 | +bus_get_cb (GObject * object, GAsyncResult * res, gpointer user_data) |
349 | +{ |
350 | GError * error = NULL; |
351 | - priv->bus = dbus_g_bus_get(DBUS_BUS_STARTER, &error); |
352 | - if (error != NULL) { |
353 | - g_error("Unable to get session bus: %s", error->message); |
354 | - g_error_free(error); |
355 | - return; |
356 | - } |
357 | - |
358 | - dbus_g_connection_register_g_object(priv->bus, |
359 | - INDICATOR_APPLICATION_DBUS_OBJ, |
360 | - G_OBJECT(self)); |
361 | - |
362 | - self->priv = priv; |
363 | - |
364 | + GDBusConnection * connection = g_bus_get_finish(res, &error); |
365 | + |
366 | + if (error != NULL) { |
367 | + g_error("OMG! Unable to get a connection to DBus: %s", error->message); |
368 | + g_error_free(error); |
369 | + return; |
370 | + } |
371 | + |
372 | + ApplicationServiceAppstorePrivate * priv = APPLICATION_SERVICE_APPSTORE_GET_PRIVATE (user_data); |
373 | + |
374 | + g_warn_if_fail(priv->bus == NULL); |
375 | + priv->bus = connection; |
376 | + |
377 | + if (priv->bus_cancel != NULL) { |
378 | + g_object_unref(priv->bus_cancel); |
379 | + priv->bus_cancel = NULL; |
380 | + } |
381 | + |
382 | + /* Now register our object on our new connection */ |
383 | + priv->dbus_registration = g_dbus_connection_register_object(priv->bus, |
384 | + INDICATOR_APPLICATION_DBUS_OBJ, |
385 | + interface_info, |
386 | + &interface_table, |
387 | + user_data, |
388 | + NULL, |
389 | + &error); |
390 | + |
391 | + if (error != NULL) { |
392 | + g_error("Unable to register the object to DBus: %s", error->message); |
393 | + g_error_free(error); |
394 | + return; |
395 | + } |
396 | + |
397 | + return; |
398 | +} |
399 | + |
400 | +/* A method has been called from our dbus inteface. Figure out what it |
401 | + is and dispatch it. */ |
402 | +static void |
403 | +bus_method_call (GDBusConnection * connection, const gchar * sender, |
404 | + const gchar * path, const gchar * interface, |
405 | + const gchar * method, GVariant * params, |
406 | + GDBusMethodInvocation * invocation, gpointer user_data) |
407 | +{ |
408 | + ApplicationServiceAppstore * service = APPLICATION_SERVICE_APPSTORE(user_data); |
409 | + GVariant * retval = NULL; |
410 | + |
411 | + if (g_strcmp0(method, "GetApplications") == 0) { |
412 | + retval = get_applications(service); |
413 | + } else { |
414 | + g_warning("Calling method '%s' on the indicator service and it's unknown", method); |
415 | + } |
416 | + |
417 | + g_dbus_method_invocation_return_value(invocation, retval); |
418 | return; |
419 | } |
420 | |
421 | @@ -249,6 +285,23 @@ |
422 | priv->approvers = NULL; |
423 | } |
424 | |
425 | + if (priv->dbus_registration != 0) { |
426 | + g_dbus_connection_unregister_object(priv->bus, priv->dbus_registration); |
427 | + /* Don't care if it fails, there's nothing we can do */ |
428 | + priv->dbus_registration = 0; |
429 | + } |
430 | + |
431 | + if (priv->bus != NULL) { |
432 | + g_object_unref(priv->bus); |
433 | + priv->bus = NULL; |
434 | + } |
435 | + |
436 | + if (priv->bus_cancel != NULL) { |
437 | + g_cancellable_cancel(priv->bus_cancel); |
438 | + g_object_unref(priv->bus_cancel); |
439 | + priv->bus_cancel = NULL; |
440 | + } |
441 | + |
442 | G_OBJECT_CLASS (application_service_appstore_parent_class)->dispose (object); |
443 | return; |
444 | } |
445 | @@ -323,94 +376,156 @@ |
446 | } |
447 | |
448 | /* Return from getting the properties from the item. We're looking at those |
449 | - and making sure we have everythign that we need. If we do, then we'll |
450 | + and making sure we have everything that we need. If we do, then we'll |
451 | move on up to sending this onto the indicator. */ |
452 | static void |
453 | -get_all_properties_cb (DBusGProxy * proxy, GHashTable * properties, GError * error, gpointer data) |
454 | +got_all_properties (GObject * source_object, GAsyncResult * res, |
455 | + gpointer user_data) |
456 | { |
457 | + Application * app = (Application *)user_data; |
458 | + g_return_if_fail(app != NULL); |
459 | + |
460 | + GError * error = NULL; |
461 | + ApplicationServiceAppstorePrivate * priv = app->appstore->priv; |
462 | + GVariant * menu = NULL, * id = NULL, * category = NULL, |
463 | + * status = NULL, * icon_name = NULL, * aicon_name = NULL, |
464 | + * icon_theme_path = NULL, * index = NULL, * label = NULL, |
465 | + * guide = NULL; |
466 | + |
467 | + GVariant * properties = g_dbus_proxy_call_finish(app->props, res, &error); |
468 | + |
469 | + if (app->props_cancel != NULL) { |
470 | + g_object_unref(app->props_cancel); |
471 | + app->props_cancel = NULL; |
472 | + } |
473 | + |
474 | if (error != NULL) { |
475 | - g_warning("Unable to get properties: %s", error->message); |
476 | - /* TODO: We need to free all the application data here */ |
477 | + g_error("Could not grab DBus properties for %s: %s", app->dbus_name, error->message); |
478 | + g_error_free(error); |
479 | + if (!app->validated) |
480 | + application_free(app); |
481 | return; |
482 | } |
483 | |
484 | - Application * app = (Application *)data; |
485 | + /* Grab all properties from variant */ |
486 | + GVariantIter * iter = NULL; |
487 | + const gchar * name = NULL; |
488 | + GVariant * value = NULL; |
489 | + g_variant_get(properties, "(a{sv})", &iter); |
490 | + while (g_variant_iter_loop (iter, "{&sv}", &name, &value)) { |
491 | + if (g_strcmp0(name, NOTIFICATION_ITEM_PROP_MENU) == 0) { |
492 | + menu = g_variant_ref(value); |
493 | + } else if (g_strcmp0(name, NOTIFICATION_ITEM_PROP_ID) == 0) { |
494 | + id = g_variant_ref(value); |
495 | + } else if (g_strcmp0(name, NOTIFICATION_ITEM_PROP_CATEGORY) == 0) { |
496 | + category = g_variant_ref(value); |
497 | + } else if (g_strcmp0(name, NOTIFICATION_ITEM_PROP_STATUS) == 0) { |
498 | + status = g_variant_ref(value); |
499 | + } else if (g_strcmp0(name, NOTIFICATION_ITEM_PROP_ICON_NAME) == 0) { |
500 | + icon_name = g_variant_ref(value); |
501 | + } else if (g_strcmp0(name, NOTIFICATION_ITEM_PROP_AICON_NAME) == 0) { |
502 | + aicon_name = g_variant_ref(value); |
503 | + } else if (g_strcmp0(name, NOTIFICATION_ITEM_PROP_ICON_THEME_PATH) == 0) { |
504 | + icon_theme_path = g_variant_ref(value); |
505 | + } else if (g_strcmp0(name, NOTIFICATION_ITEM_PROP_ORDERING_INDEX) == 0) { |
506 | + index = g_variant_ref(value); |
507 | + } else if (g_strcmp0(name, NOTIFICATION_ITEM_PROP_LABEL) == 0) { |
508 | + label = g_variant_ref(value); |
509 | + } else if (g_strcmp0(name, NOTIFICATION_ITEM_PROP_LABEL_GUIDE) == 0) { |
510 | + guide = g_variant_ref(value); |
511 | + } /* else ignore */ |
512 | + } |
513 | + g_variant_iter_free (iter); |
514 | |
515 | - if (g_hash_table_lookup(properties, NOTIFICATION_ITEM_PROP_MENU) == NULL || |
516 | - g_hash_table_lookup(properties, NOTIFICATION_ITEM_PROP_ID) == NULL || |
517 | - g_hash_table_lookup(properties, NOTIFICATION_ITEM_PROP_CATEGORY) == NULL || |
518 | - g_hash_table_lookup(properties, NOTIFICATION_ITEM_PROP_STATUS) == NULL || |
519 | - g_hash_table_lookup(properties, NOTIFICATION_ITEM_PROP_ICON_NAME) == NULL) { |
520 | + if (menu == NULL || id == NULL || category == NULL || status == NULL || |
521 | + icon_name == NULL) { |
522 | g_warning("Notification Item on object %s of %s doesn't have enough properties.", app->dbus_object, app->dbus_name); |
523 | g_free(app); // Need to do more than this, but it gives the idea of the flow we're going for. |
524 | - return; |
525 | - } |
526 | - |
527 | - app->validated = TRUE; |
528 | - |
529 | - app->id = g_value_dup_string(g_hash_table_lookup(properties, NOTIFICATION_ITEM_PROP_ID)); |
530 | - app->category = g_value_dup_string(g_hash_table_lookup(properties, NOTIFICATION_ITEM_PROP_CATEGORY)); |
531 | - app->status = string_to_status(g_value_get_string(g_hash_table_lookup(properties, NOTIFICATION_ITEM_PROP_STATUS))); |
532 | - |
533 | - ApplicationServiceAppstorePrivate * priv = app->appstore->priv; |
534 | - |
535 | - app->icon = g_value_dup_string(g_hash_table_lookup(properties, NOTIFICATION_ITEM_PROP_ICON_NAME)); |
536 | - |
537 | - GValue * menuval = (GValue *)g_hash_table_lookup(properties, NOTIFICATION_ITEM_PROP_MENU); |
538 | - if (G_VALUE_TYPE(menuval) == G_TYPE_STRING) { |
539 | - /* This is here to support an older version where we |
540 | - were using strings instea of object paths. */ |
541 | - app->menu = g_value_dup_string(menuval); |
542 | - } else { |
543 | - app->menu = g_strdup((gchar *)g_value_get_boxed(menuval)); |
544 | - } |
545 | - |
546 | - if (g_hash_table_lookup(properties, NOTIFICATION_ITEM_PROP_AICON_NAME) != NULL) { |
547 | - app->aicon = g_value_dup_string(g_hash_table_lookup(properties, NOTIFICATION_ITEM_PROP_AICON_NAME)); |
548 | - } |
549 | - |
550 | - gpointer icon_theme_path_data = g_hash_table_lookup(properties, NOTIFICATION_ITEM_PROP_ICON_THEME_PATH); |
551 | - if (icon_theme_path_data != NULL) { |
552 | - app->icon_theme_path = g_value_dup_string((GValue *)icon_theme_path_data); |
553 | - } else { |
554 | - app->icon_theme_path = g_strdup(""); |
555 | - } |
556 | - |
557 | - gpointer ordering_index_over = g_hash_table_lookup(priv->ordering_overrides, app->id); |
558 | - if (ordering_index_over == NULL) { |
559 | - gpointer ordering_index_data = g_hash_table_lookup(properties, NOTIFICATION_ITEM_PROP_ORDERING_INDEX); |
560 | - if (ordering_index_data == NULL || g_value_get_uint(ordering_index_data) == 0) { |
561 | - app->ordering_index = generate_id(string_to_cat(app->category), app->id); |
562 | - } else { |
563 | - app->ordering_index = g_value_get_uint(ordering_index_data); |
564 | - } |
565 | - } else { |
566 | - app->ordering_index = GPOINTER_TO_UINT(ordering_index_over); |
567 | - } |
568 | - g_debug("'%s' ordering index is '%X'", app->id, app->ordering_index); |
569 | - |
570 | - gpointer label_data = g_hash_table_lookup(properties, NOTIFICATION_ITEM_PROP_LABEL); |
571 | - if (label_data != NULL) { |
572 | - app->label = g_value_dup_string((GValue *)label_data); |
573 | - } else { |
574 | - app->label = g_strdup(""); |
575 | - } |
576 | - |
577 | - gpointer guide_data = g_hash_table_lookup(properties, NOTIFICATION_ITEM_PROP_LABEL_GUIDE); |
578 | - if (guide_data != NULL) { |
579 | - app->guide = g_value_dup_string((GValue *)guide_data); |
580 | - } else { |
581 | - app->guide = g_strdup(""); |
582 | - } |
583 | - |
584 | - priv->applications = g_list_insert_sorted_with_data (priv->applications, app, app_sort_func, NULL); |
585 | - g_list_foreach(priv->approvers, check_with_old_approver, app); |
586 | - |
587 | - apply_status(app); |
588 | + } |
589 | + else { |
590 | + app->validated = TRUE; |
591 | + |
592 | + app->id = g_variant_dup_string(id, NULL); |
593 | + app->category = g_variant_dup_string(category, NULL); |
594 | + app->status = string_to_status(g_variant_get_string(status, NULL)); |
595 | + app->icon = g_variant_dup_string(icon_name, NULL); |
596 | + app->menu = g_variant_dup_string(menu, NULL); |
597 | + |
598 | + /* Now the optional properties */ |
599 | + |
600 | + if (aicon_name != NULL) { |
601 | + app->aicon = g_variant_dup_string(aicon_name, NULL); |
602 | + } |
603 | + |
604 | + if (icon_theme_path != NULL) { |
605 | + app->icon_theme_path = g_variant_dup_string(icon_theme_path, NULL); |
606 | + } else { |
607 | + app->icon_theme_path = g_strdup(""); |
608 | + } |
609 | + |
610 | + gpointer ordering_index_over = g_hash_table_lookup(priv->ordering_overrides, app->id); |
611 | + if (ordering_index_over == NULL) { |
612 | + if (index == NULL || g_variant_get_uint32(index) == 0) { |
613 | + app->ordering_index = generate_id(string_to_cat(app->category), app->id); |
614 | + } else { |
615 | + app->ordering_index = g_variant_get_uint32(index); |
616 | + } |
617 | + } else { |
618 | + app->ordering_index = GPOINTER_TO_UINT(ordering_index_over); |
619 | + } |
620 | + g_debug("'%s' ordering index is '%X'", app->id, app->ordering_index); |
621 | + |
622 | + if (label != NULL) { |
623 | + app->label = g_variant_dup_string(label, NULL); |
624 | + } else { |
625 | + app->label = g_strdup(""); |
626 | + } |
627 | + |
628 | + if (guide != NULL) { |
629 | + app->guide = g_variant_dup_string(guide, NULL); |
630 | + } else { |
631 | + app->guide = g_strdup(""); |
632 | + } |
633 | + |
634 | + g_list_foreach(priv->approvers, check_with_old_approver, app); |
635 | + |
636 | + apply_status(app); |
637 | + |
638 | + if (app->queued_props) { |
639 | + get_all_properties(app); |
640 | + app->queued_props = FALSE; |
641 | + } |
642 | + } |
643 | + |
644 | + if (menu) g_variant_unref (menu); |
645 | + if (id) g_variant_unref (id); |
646 | + if (category) g_variant_unref (category); |
647 | + if (status) g_variant_unref (status); |
648 | + if (icon_name) g_variant_unref (icon_name); |
649 | + if (aicon_name) g_variant_unref (aicon_name); |
650 | + if (icon_theme_path) g_variant_unref (icon_theme_path); |
651 | + if (index) g_variant_unref (index); |
652 | + if (label) g_variant_unref (label); |
653 | + if (guide) g_variant_unref (guide); |
654 | |
655 | return; |
656 | } |
657 | |
658 | +static void |
659 | +get_all_properties (Application * app) |
660 | +{ |
661 | + if (app->props != NULL && app->props_cancel == NULL) { |
662 | + g_dbus_proxy_call(app->props, "GetAll", |
663 | + g_variant_new("(s)", NOTIFICATION_ITEM_DBUS_IFACE), |
664 | + G_DBUS_CALL_FLAGS_NONE, -1, app->props_cancel, |
665 | + got_all_properties, app); |
666 | + } |
667 | + else { |
668 | + g_debug("Queuing a properties check"); |
669 | + app->queued_props = TRUE; |
670 | + } |
671 | +} |
672 | + |
673 | /* Check the application against an approver */ |
674 | static void |
675 | check_with_old_approver (gpointer papprove, gpointer papp) |
676 | @@ -508,11 +623,32 @@ |
677 | if (app->currently_free) return; |
678 | app->currently_free = TRUE; |
679 | |
680 | + /* Remove from the application list */ |
681 | + app->appstore->priv->applications = g_list_remove(app->appstore->priv->applications, app); |
682 | + |
683 | + if (app->name_watcher != 0) { |
684 | + g_dbus_connection_signal_unsubscribe(g_dbus_proxy_get_connection(app->dbus_proxy), app->name_watcher); |
685 | + app->name_watcher = 0; |
686 | + } |
687 | + |
688 | + if (app->props) { |
689 | + g_object_unref(app->props); |
690 | + } |
691 | + |
692 | + if (app->props_cancel != NULL) { |
693 | + g_cancellable_cancel(app->props_cancel); |
694 | + g_object_unref(app->props_cancel); |
695 | + app->props_cancel = NULL; |
696 | + } |
697 | + |
698 | if (app->dbus_proxy) { |
699 | g_object_unref(app->dbus_proxy); |
700 | } |
701 | - if (app->prop_proxy) { |
702 | - g_object_unref(app->prop_proxy); |
703 | + |
704 | + if (app->dbus_proxy_cancel != NULL) { |
705 | + g_cancellable_cancel(app->dbus_proxy_cancel); |
706 | + g_object_unref(app->dbus_proxy_cancel); |
707 | + app->dbus_proxy_cancel = NULL; |
708 | } |
709 | |
710 | if (app->id != NULL) { |
711 | @@ -553,21 +689,18 @@ |
712 | return; |
713 | } |
714 | |
715 | -/* Gets called when the proxy is destroyed, which is usually when it |
716 | +/* Gets called when the proxy changes owners, which is usually when it |
717 | drops off of the bus. */ |
718 | static void |
719 | -application_removed_cb (DBusGProxy * proxy, gpointer userdata) |
720 | +application_died (Application * app) |
721 | { |
722 | - Application * app = (Application *)userdata; |
723 | + /* Application died */ |
724 | g_debug("Application proxy destroyed '%s'", app->id); |
725 | |
726 | /* Remove from the panel */ |
727 | app->status = APP_INDICATOR_STATUS_PASSIVE; |
728 | apply_status(app); |
729 | |
730 | - /* Remove from the application list */ |
731 | - app->appstore->priv->applications = g_list_remove(app->appstore->priv->applications, app); |
732 | - |
733 | /* Destroy the data */ |
734 | application_free(app); |
735 | return; |
736 | @@ -583,6 +716,30 @@ |
737 | return (appb->ordering_index/2) - (appa->ordering_index/2); |
738 | } |
739 | |
740 | +static void |
741 | +emit_signal (ApplicationServiceAppstore * appstore, const gchar * name, |
742 | + GVariant * variant) |
743 | +{ |
744 | + ApplicationServiceAppstorePrivate * priv = appstore->priv; |
745 | + GError * error = NULL; |
746 | + |
747 | + g_dbus_connection_emit_signal (priv->bus, |
748 | + NULL, |
749 | + INDICATOR_APPLICATION_DBUS_OBJ, |
750 | + INDICATOR_APPLICATION_DBUS_IFACE, |
751 | + name, |
752 | + variant, |
753 | + &error); |
754 | + |
755 | + if (error != NULL) { |
756 | + g_error("Unable to send %s signal: %s", name, error->message); |
757 | + g_error_free(error); |
758 | + return; |
759 | + } |
760 | + |
761 | + return; |
762 | +} |
763 | + |
764 | /* Change the status of the application. If we're going passive |
765 | it removes it from the panel. If we're coming online, then |
766 | it add it to the panel. Otherwise it changes the icon. */ |
767 | @@ -613,16 +770,17 @@ |
768 | return; |
769 | } |
770 | |
771 | - g_debug("Changing app '%s' state from %s to %s", app->id, STATE2STRING(app->visible_state), STATE2STRING(goal_state)); |
772 | + if (app->visible_state != goal_state) { |
773 | + g_debug("Changing app '%s' state from %s to %s", app->id, STATE2STRING(app->visible_state), STATE2STRING(goal_state)); |
774 | + } |
775 | |
776 | /* This means we're going off line */ |
777 | if (goal_state == VISIBLE_STATE_HIDDEN) { |
778 | gint position = get_position(app); |
779 | if (position == -1) return; |
780 | |
781 | - g_signal_emit(G_OBJECT(appstore), |
782 | - signals[APPLICATION_REMOVED], 0, |
783 | - position, TRUE); |
784 | + emit_signal (appstore, "ApplicationRemoved", |
785 | + g_variant_new ("(i)", position)); |
786 | } else { |
787 | /* Figure out which icon we should be using */ |
788 | gchar * newicon = app->icon; |
789 | @@ -633,24 +791,19 @@ |
790 | /* Determine whether we're already shown or not */ |
791 | if (app->visible_state == VISIBLE_STATE_HIDDEN) { |
792 | /* Put on panel */ |
793 | - g_signal_emit(G_OBJECT(app->appstore), |
794 | - signals[APPLICATION_ADDED], 0, |
795 | - newicon, |
796 | - get_position(app), /* Position */ |
797 | - app->dbus_name, |
798 | - app->menu, |
799 | - app->icon_theme_path, |
800 | - app->label, |
801 | - app->guide, |
802 | - TRUE); |
803 | + emit_signal (appstore, "ApplicationAdded", |
804 | + g_variant_new ("(sisosss)", newicon, |
805 | + get_position(app), |
806 | + app->dbus_name, app->menu, |
807 | + app->icon_theme_path, |
808 | + app->label, app->guide)); |
809 | } else { |
810 | /* Icon update */ |
811 | gint position = get_position(app); |
812 | if (position == -1) return; |
813 | |
814 | - g_signal_emit(G_OBJECT(appstore), |
815 | - signals[APPLICATION_ICON_CHANGED], 0, |
816 | - position, newicon, TRUE); |
817 | + emit_signal (appstore, "ApplicationIconChanged", |
818 | + g_variant_new ("(is)", position, newicon)); |
819 | } |
820 | } |
821 | |
822 | @@ -659,123 +812,11 @@ |
823 | return; |
824 | } |
825 | |
826 | -/* Gets the data back on an updated icon signal. Hopefully |
827 | - a new fun icon. */ |
828 | -static void |
829 | -new_icon_cb (DBusGProxy * proxy, GValue value, GError * error, gpointer userdata) |
830 | -{ |
831 | - /* Check for errors */ |
832 | - if (error != NULL) { |
833 | - g_warning("Unable to get updated icon name: %s", error->message); |
834 | - return; |
835 | - } |
836 | - |
837 | - /* Grab the icon and make sure we have one */ |
838 | - const gchar * newicon = g_value_get_string(&value); |
839 | - if (newicon == NULL) { |
840 | - g_warning("Bad new icon :("); |
841 | - return; |
842 | - } |
843 | - |
844 | - Application * app = (Application *) userdata; |
845 | - |
846 | - if (g_strcmp0(newicon, app->icon)) { |
847 | - /* If the new icon is actually a new icon */ |
848 | - if (app->icon != NULL) g_free(app->icon); |
849 | - app->icon = g_strdup(newicon); |
850 | - |
851 | - if (app->visible_state == VISIBLE_STATE_SHOWN && app->status == APP_INDICATOR_STATUS_ACTIVE) { |
852 | - gint position = get_position(app); |
853 | - if (position == -1) return; |
854 | - |
855 | - g_signal_emit(G_OBJECT(app->appstore), |
856 | - signals[APPLICATION_ICON_CHANGED], 0, |
857 | - position, newicon, TRUE); |
858 | - } |
859 | - } |
860 | - |
861 | - return; |
862 | -} |
863 | - |
864 | -/* Gets the data back on an updated aicon signal. Hopefully |
865 | - a new fun icon. */ |
866 | -static void |
867 | -new_aicon_cb (DBusGProxy * proxy, GValue value, GError * error, gpointer userdata) |
868 | -{ |
869 | - /* Check for errors */ |
870 | - if (error != NULL) { |
871 | - g_warning("Unable to get updated icon name: %s", error->message); |
872 | - return; |
873 | - } |
874 | - |
875 | - /* Grab the icon and make sure we have one */ |
876 | - const gchar * newicon = g_value_get_string(&value); |
877 | - if (newicon == NULL) { |
878 | - g_warning("Bad new icon :("); |
879 | - return; |
880 | - } |
881 | - |
882 | - Application * app = (Application *) userdata; |
883 | - |
884 | - if (g_strcmp0(newicon, app->aicon)) { |
885 | - /* If the new icon is actually a new icon */ |
886 | - if (app->aicon != NULL) g_free(app->aicon); |
887 | - app->aicon = g_strdup(newicon); |
888 | - |
889 | - if (app->visible_state == VISIBLE_STATE_SHOWN && app->status == APP_INDICATOR_STATUS_ATTENTION) { |
890 | - gint position = get_position(app); |
891 | - if (position == -1) return; |
892 | - |
893 | - g_signal_emit(G_OBJECT(app->appstore), |
894 | - signals[APPLICATION_ICON_CHANGED], 0, |
895 | - position, newicon, TRUE); |
896 | - } |
897 | - } |
898 | - |
899 | - return; |
900 | -} |
901 | - |
902 | -/* Called when the Notification Item signals that it |
903 | - has a new icon. */ |
904 | -static void |
905 | -new_icon (DBusGProxy * proxy, gpointer data) |
906 | -{ |
907 | - Application * app = (Application *)data; |
908 | - if (!app->validated) return; |
909 | - |
910 | - org_freedesktop_DBus_Properties_get_async(app->prop_proxy, |
911 | - NOTIFICATION_ITEM_DBUS_IFACE, |
912 | - NOTIFICATION_ITEM_PROP_ICON_NAME, |
913 | - new_icon_cb, |
914 | - app); |
915 | - return; |
916 | -} |
917 | - |
918 | -/* Called when the Notification Item signals that it |
919 | - has a new attention icon. */ |
920 | -static void |
921 | -new_aicon (DBusGProxy * proxy, gpointer data) |
922 | -{ |
923 | - Application * app = (Application *)data; |
924 | - if (!app->validated) return; |
925 | - |
926 | - org_freedesktop_DBus_Properties_get_async(app->prop_proxy, |
927 | - NOTIFICATION_ITEM_DBUS_IFACE, |
928 | - NOTIFICATION_ITEM_PROP_AICON_NAME, |
929 | - new_aicon_cb, |
930 | - app); |
931 | - |
932 | - return; |
933 | -} |
934 | - |
935 | /* Called when the Notification Item signals that it |
936 | has a new status. */ |
937 | static void |
938 | -new_status (DBusGProxy * proxy, const gchar * status, gpointer data) |
939 | +new_status (Application * app, const gchar * status) |
940 | { |
941 | - Application * app = (Application *)data; |
942 | - if (!app->validated) return; |
943 | - |
944 | app->status = string_to_status(status); |
945 | apply_status(app); |
946 | |
947 | @@ -785,11 +826,8 @@ |
948 | /* Called when the Notification Item signals that it |
949 | has a new icon theme path. */ |
950 | static void |
951 | -new_icon_theme_path (DBusGProxy * proxy, const gchar * icon_theme_path, gpointer data) |
952 | +new_icon_theme_path (Application * app, const gchar * icon_theme_path) |
953 | { |
954 | - Application * app = (Application *)data; |
955 | - if (!app->validated) return; |
956 | - |
957 | if (g_strcmp0(icon_theme_path, app->icon_theme_path)) { |
958 | /* If the new icon theme path is actually a new icon theme path */ |
959 | if (app->icon_theme_path != NULL) g_free(app->icon_theme_path); |
960 | @@ -799,9 +837,10 @@ |
961 | gint position = get_position(app); |
962 | if (position == -1) return; |
963 | |
964 | - g_signal_emit(G_OBJECT(app->appstore), |
965 | - signals[APPLICATION_ICON_THEME_PATH_CHANGED], 0, |
966 | - position, app->icon_theme_path, TRUE); |
967 | + emit_signal (app->appstore, |
968 | + "ApplicationIconThemePathChanged", |
969 | + g_variant_new ("(is)", position, |
970 | + app->icon_theme_path)); |
971 | } |
972 | } |
973 | |
974 | @@ -811,11 +850,8 @@ |
975 | /* Called when the Notification Item signals that it |
976 | has a new label. */ |
977 | static void |
978 | -new_label (DBusGProxy * proxy, const gchar * label, const gchar * guide, gpointer data) |
979 | +new_label (Application * app, const gchar * label, const gchar * guide) |
980 | { |
981 | - Application * app = (Application *)data; |
982 | - if (!app->validated) return; |
983 | - |
984 | gboolean changed = FALSE; |
985 | |
986 | if (g_strcmp0(app->label, label) != 0) { |
987 | @@ -840,11 +876,10 @@ |
988 | gint position = get_position(app); |
989 | if (position == -1) return; |
990 | |
991 | - g_signal_emit(app->appstore, signals[APPLICATION_LABEL_CHANGED], 0, |
992 | - position, |
993 | - app->label != NULL ? app->label : "", |
994 | - app->guide != NULL ? app->guide : "", |
995 | - TRUE); |
996 | + emit_signal (app->appstore, "ApplicationLabelChanged", |
997 | + g_variant_new ("(iss)", position, |
998 | + app->label != NULL ? app->label : "", |
999 | + app->guide != NULL ? app->guide : "")); |
1000 | } |
1001 | |
1002 | return; |
1003 | @@ -862,15 +897,11 @@ |
1004 | g_return_if_fail(IS_APPLICATION_SERVICE_APPSTORE(appstore)); |
1005 | g_return_if_fail(dbus_name != NULL && dbus_name[0] != '\0'); |
1006 | g_return_if_fail(dbus_object != NULL && dbus_object[0] != '\0'); |
1007 | - ApplicationServiceAppstorePrivate * priv = appstore->priv; |
1008 | Application * app = find_application(appstore, dbus_name, dbus_object); |
1009 | |
1010 | if (app != NULL) { |
1011 | - g_warning("Application already exists! Rerequesting properties."); |
1012 | - org_freedesktop_DBus_Properties_get_all_async(app->prop_proxy, |
1013 | - NOTIFICATION_ITEM_DBUS_IFACE, |
1014 | - get_all_properties_cb, |
1015 | - app); |
1016 | + g_warning("Application already exists, re-requesting properties."); |
1017 | + get_all_properties(app); |
1018 | return; |
1019 | } |
1020 | |
1021 | @@ -893,98 +924,169 @@ |
1022 | app->ordering_index = 0; |
1023 | app->approved_by = NULL; |
1024 | app->visible_state = VISIBLE_STATE_HIDDEN; |
1025 | + app->name_watcher = 0; |
1026 | + app->props_cancel = NULL; |
1027 | + app->props = NULL; |
1028 | + app->queued_props = FALSE; |
1029 | |
1030 | /* Get the DBus proxy for the NotificationItem interface */ |
1031 | - GError * error = NULL; |
1032 | - app->dbus_proxy = dbus_g_proxy_new_for_name_owner(priv->bus, |
1033 | - app->dbus_name, |
1034 | - app->dbus_object, |
1035 | - NOTIFICATION_ITEM_DBUS_IFACE, |
1036 | - &error); |
1037 | - |
1038 | - if (error != NULL) { |
1039 | - g_warning("Unable to get notification item proxy for object '%s' on host '%s': %s", dbus_object, dbus_name, error->message); |
1040 | - g_error_free(error); |
1041 | - g_free(app); |
1042 | - return; |
1043 | - } |
1044 | - |
1045 | - /* We've got it, let's watch it for destruction */ |
1046 | - g_signal_connect(G_OBJECT(app->dbus_proxy), "destroy", G_CALLBACK(application_removed_cb), app); |
1047 | - |
1048 | - /* Grab the property proxy interface */ |
1049 | - app->prop_proxy = dbus_g_proxy_new_for_name_owner(priv->bus, |
1050 | - app->dbus_name, |
1051 | - app->dbus_object, |
1052 | - DBUS_INTERFACE_PROPERTIES, |
1053 | - &error); |
1054 | - |
1055 | - if (error != NULL) { |
1056 | - g_warning("Unable to get property proxy for object '%s' on host '%s': %s", dbus_object, dbus_name, error->message); |
1057 | - g_error_free(error); |
1058 | - g_object_unref(app->dbus_proxy); |
1059 | - g_free(app); |
1060 | - return; |
1061 | - } |
1062 | - |
1063 | - /* Connect to signals */ |
1064 | - dbus_g_proxy_add_signal(app->dbus_proxy, |
1065 | - NOTIFICATION_ITEM_SIG_NEW_ICON, |
1066 | - G_TYPE_INVALID); |
1067 | - dbus_g_proxy_add_signal(app->dbus_proxy, |
1068 | - NOTIFICATION_ITEM_SIG_NEW_AICON, |
1069 | - G_TYPE_INVALID); |
1070 | - dbus_g_proxy_add_signal(app->dbus_proxy, |
1071 | - NOTIFICATION_ITEM_SIG_NEW_STATUS, |
1072 | - G_TYPE_STRING, |
1073 | - G_TYPE_INVALID); |
1074 | - dbus_g_proxy_add_signal(app->dbus_proxy, |
1075 | - NOTIFICATION_ITEM_SIG_NEW_ICON_THEME_PATH, |
1076 | - G_TYPE_STRING, |
1077 | - G_TYPE_INVALID); |
1078 | - dbus_g_proxy_add_signal(app->dbus_proxy, |
1079 | - NOTIFICATION_ITEM_SIG_NEW_LABEL, |
1080 | - G_TYPE_STRING, |
1081 | - G_TYPE_STRING, |
1082 | - G_TYPE_INVALID); |
1083 | - |
1084 | - dbus_g_proxy_connect_signal(app->dbus_proxy, |
1085 | - NOTIFICATION_ITEM_SIG_NEW_ICON, |
1086 | - G_CALLBACK(new_icon), |
1087 | - app, |
1088 | - NULL); |
1089 | - dbus_g_proxy_connect_signal(app->dbus_proxy, |
1090 | - NOTIFICATION_ITEM_SIG_NEW_AICON, |
1091 | - G_CALLBACK(new_aicon), |
1092 | - app, |
1093 | - NULL); |
1094 | - dbus_g_proxy_connect_signal(app->dbus_proxy, |
1095 | - NOTIFICATION_ITEM_SIG_NEW_STATUS, |
1096 | - G_CALLBACK(new_status), |
1097 | - app, |
1098 | - NULL); |
1099 | - dbus_g_proxy_connect_signal(app->dbus_proxy, |
1100 | - NOTIFICATION_ITEM_SIG_NEW_ICON_THEME_PATH, |
1101 | - G_CALLBACK(new_icon_theme_path), |
1102 | - app, |
1103 | - NULL); |
1104 | - dbus_g_proxy_connect_signal(app->dbus_proxy, |
1105 | - NOTIFICATION_ITEM_SIG_NEW_LABEL, |
1106 | - G_CALLBACK(new_label), |
1107 | - app, |
1108 | - NULL); |
1109 | - |
1110 | - /* Get all the propertiees */ |
1111 | - org_freedesktop_DBus_Properties_get_all_async(app->prop_proxy, |
1112 | - NOTIFICATION_ITEM_DBUS_IFACE, |
1113 | - get_all_properties_cb, |
1114 | - app); |
1115 | + app->dbus_proxy_cancel = g_cancellable_new(); |
1116 | + g_dbus_proxy_new_for_bus(G_BUS_TYPE_SESSION, |
1117 | + G_DBUS_PROXY_FLAGS_NONE, |
1118 | + NULL, |
1119 | + app->dbus_name, |
1120 | + app->dbus_object, |
1121 | + NOTIFICATION_ITEM_DBUS_IFACE, |
1122 | + app->dbus_proxy_cancel, |
1123 | + dbus_proxy_cb, |
1124 | + app); |
1125 | + |
1126 | + appstore->priv->applications = g_list_insert_sorted_with_data (appstore->priv->applications, app, app_sort_func, NULL); |
1127 | |
1128 | /* We're returning, nothing is yet added until the properties |
1129 | come back and give us more info. */ |
1130 | return; |
1131 | } |
1132 | |
1133 | +static void |
1134 | +name_changed (GDBusConnection * connection, const gchar * sender_name, |
1135 | + const gchar * object_path, const gchar * interface_name, |
1136 | + const gchar * signal_name, GVariant * parameters, |
1137 | + gpointer user_data) |
1138 | +{ |
1139 | + Application * app = (Application *)user_data; |
1140 | + |
1141 | + const gchar * new_name; |
1142 | + g_variant_get(parameters, "(&s&s&s)", NULL, NULL, &new_name); |
1143 | + |
1144 | + if (new_name == NULL || new_name[0] == 0) |
1145 | + application_died(app); |
1146 | +} |
1147 | + |
1148 | +/* Callback from trying to create the proxy for the app. */ |
1149 | +static void |
1150 | +dbus_proxy_cb (GObject * object, GAsyncResult * res, gpointer user_data) |
1151 | +{ |
1152 | + GError * error = NULL; |
1153 | + |
1154 | + Application * app = (Application *)user_data; |
1155 | + g_return_if_fail(app != NULL); |
1156 | + |
1157 | + GDBusProxy * proxy = g_dbus_proxy_new_for_bus_finish(res, &error); |
1158 | + |
1159 | + if (app->dbus_proxy_cancel != NULL) { |
1160 | + g_object_unref(app->dbus_proxy_cancel); |
1161 | + app->dbus_proxy_cancel = NULL; |
1162 | + } |
1163 | + |
1164 | + if (error != NULL) { |
1165 | + g_error("Could not grab DBus proxy for %s: %s", app->dbus_name, error->message); |
1166 | + g_error_free(error); |
1167 | + application_free(app); |
1168 | + return; |
1169 | + } |
1170 | + |
1171 | + /* Okay, we're good to grab the proxy at this point, we're |
1172 | + sure that it's ours. */ |
1173 | + app->dbus_proxy = proxy; |
1174 | + |
1175 | + /* We've got it, let's watch it for destruction */ |
1176 | + app->name_watcher = g_dbus_connection_signal_subscribe( |
1177 | + g_dbus_proxy_get_connection(proxy), |
1178 | + "org.freedesktop.DBus", |
1179 | + "org.freedesktop.DBus", |
1180 | + "NameOwnerChanged", |
1181 | + "/org/freedesktop/DBus", |
1182 | + g_dbus_proxy_get_name(proxy), |
1183 | + G_DBUS_SIGNAL_FLAGS_NONE, |
1184 | + name_changed, |
1185 | + app, |
1186 | + NULL); |
1187 | + |
1188 | + g_signal_connect(proxy, "g-signal", G_CALLBACK(app_receive_signal), app); |
1189 | + |
1190 | + app->props_cancel = g_cancellable_new(); |
1191 | + g_dbus_proxy_new(g_dbus_proxy_get_connection(proxy), |
1192 | + G_DBUS_PROXY_FLAGS_NONE, |
1193 | + NULL, |
1194 | + app->dbus_name, |
1195 | + app->dbus_object, |
1196 | + "org.freedesktop.DBus.Properties", |
1197 | + app->props_cancel, |
1198 | + props_cb, |
1199 | + app); |
1200 | + |
1201 | + return; |
1202 | +} |
1203 | + |
1204 | +/* Callback from trying to create the proxy for the app. */ |
1205 | +static void |
1206 | +props_cb (GObject * object, GAsyncResult * res, gpointer user_data) |
1207 | +{ |
1208 | + GError * error = NULL; |
1209 | + |
1210 | + Application * app = (Application *)user_data; |
1211 | + g_return_if_fail(app != NULL); |
1212 | + |
1213 | + GDBusProxy * proxy = g_dbus_proxy_new_for_bus_finish(res, &error); |
1214 | + |
1215 | + if (app->props_cancel != NULL) { |
1216 | + g_object_unref(app->props_cancel); |
1217 | + app->props_cancel = NULL; |
1218 | + } |
1219 | + |
1220 | + if (error != NULL) { |
1221 | + g_error("Could not grab Properties DBus proxy for %s: %s", app->dbus_name, error->message); |
1222 | + g_error_free(error); |
1223 | + application_free(app); |
1224 | + return; |
1225 | + } |
1226 | + |
1227 | + /* Okay, we're good to grab the proxy at this point, we're |
1228 | + sure that it's ours. */ |
1229 | + app->props = proxy; |
1230 | + |
1231 | + get_all_properties(app); |
1232 | + |
1233 | + return; |
1234 | +} |
1235 | + |
1236 | +/* Receives all signals from the service, routed to the appropriate functions */ |
1237 | +static void |
1238 | +app_receive_signal (GDBusProxy * proxy, gchar * sender_name, gchar * signal_name, |
1239 | + GVariant * parameters, gpointer user_data) |
1240 | +{ |
1241 | + Application * app = (Application *)user_data; |
1242 | + |
1243 | + if (!app->validated) return; |
1244 | + |
1245 | + if (g_strcmp0(signal_name, NOTIFICATION_ITEM_SIG_NEW_ICON) == 0) { |
1246 | + /* icon name isn't provided by signal, so look it up */ |
1247 | + get_all_properties(app); |
1248 | + } |
1249 | + else if (g_strcmp0(signal_name, NOTIFICATION_ITEM_SIG_NEW_AICON) == 0) { |
1250 | + /* aicon name isn't provided by signal, so look it up */ |
1251 | + get_all_properties(app); |
1252 | + } |
1253 | + else if (g_strcmp0(signal_name, NOTIFICATION_ITEM_SIG_NEW_STATUS) == 0) { |
1254 | + const gchar * status; |
1255 | + g_variant_get(parameters, "(&s)", &status); |
1256 | + new_status(app, status); |
1257 | + } |
1258 | + else if (g_strcmp0(signal_name, NOTIFICATION_ITEM_SIG_NEW_ICON_THEME_PATH) == 0) { |
1259 | + const gchar * icon_theme_path; |
1260 | + g_variant_get(parameters, "(&s)", &icon_theme_path); |
1261 | + new_icon_theme_path(app, icon_theme_path); |
1262 | + } |
1263 | + else if (g_strcmp0(signal_name, NOTIFICATION_ITEM_SIG_NEW_LABEL) == 0) { |
1264 | + const gchar * label, * guide; |
1265 | + g_variant_get(parameters, "(&s&s)", &label, &guide); |
1266 | + new_label(app, label, guide); |
1267 | + } |
1268 | + |
1269 | + return; |
1270 | +} |
1271 | + |
1272 | /* Looks for an application in the list of applications */ |
1273 | static Application * |
1274 | find_application (ApplicationServiceAppstore * appstore, const gchar * address, const gchar * object) |
1275 | @@ -1014,7 +1116,7 @@ |
1276 | |
1277 | Application * app = find_application(appstore, dbus_name, dbus_object); |
1278 | if (app != NULL) { |
1279 | - application_removed_cb(NULL, app); |
1280 | + application_died(app); |
1281 | } else { |
1282 | g_warning("Unable to find application %s:%s", dbus_name, dbus_object); |
1283 | } |
1284 | @@ -1050,12 +1152,12 @@ |
1285 | } |
1286 | |
1287 | /* DBus Interface */ |
1288 | -static gboolean |
1289 | -_application_service_server_get_applications (ApplicationServiceAppstore * appstore, GPtrArray ** apps, GError ** error) |
1290 | +static GVariant * |
1291 | +get_applications (ApplicationServiceAppstore * appstore) |
1292 | { |
1293 | ApplicationServiceAppstorePrivate * priv = appstore->priv; |
1294 | |
1295 | - *apps = g_ptr_array_new(); |
1296 | + GVariantBuilder * builder = g_variant_builder_new (G_VARIANT_TYPE_ARRAY); |
1297 | GList * listpntr; |
1298 | gint position = 0; |
1299 | |
1300 | @@ -1065,56 +1167,13 @@ |
1301 | continue; |
1302 | } |
1303 | |
1304 | - GValueArray * values = g_value_array_new(5); |
1305 | - |
1306 | - GValue value = {0}; |
1307 | - |
1308 | - /* Icon name */ |
1309 | - g_value_init(&value, G_TYPE_STRING); |
1310 | - g_value_set_string(&value, app->icon); |
1311 | - g_value_array_append(values, &value); |
1312 | - g_value_unset(&value); |
1313 | - |
1314 | - /* Position */ |
1315 | - g_value_init(&value, G_TYPE_INT); |
1316 | - g_value_set_int(&value, position++); |
1317 | - g_value_array_append(values, &value); |
1318 | - g_value_unset(&value); |
1319 | - |
1320 | - /* DBus Address */ |
1321 | - g_value_init(&value, G_TYPE_STRING); |
1322 | - g_value_set_string(&value, app->dbus_name); |
1323 | - g_value_array_append(values, &value); |
1324 | - g_value_unset(&value); |
1325 | - |
1326 | - /* DBus Object */ |
1327 | - g_value_init(&value, DBUS_TYPE_G_OBJECT_PATH); |
1328 | - g_value_set_static_boxed(&value, app->menu); |
1329 | - g_value_array_append(values, &value); |
1330 | - g_value_unset(&value); |
1331 | - |
1332 | - /* Icon path */ |
1333 | - g_value_init(&value, G_TYPE_STRING); |
1334 | - g_value_set_string(&value, app->icon_theme_path); |
1335 | - g_value_array_append(values, &value); |
1336 | - g_value_unset(&value); |
1337 | - |
1338 | - /* Label */ |
1339 | - g_value_init(&value, G_TYPE_STRING); |
1340 | - g_value_set_string(&value, app->label); |
1341 | - g_value_array_append(values, &value); |
1342 | - g_value_unset(&value); |
1343 | - |
1344 | - /* Guide */ |
1345 | - g_value_init(&value, G_TYPE_STRING); |
1346 | - g_value_set_string(&value, app->guide); |
1347 | - g_value_array_append(values, &value); |
1348 | - g_value_unset(&value); |
1349 | - |
1350 | - g_ptr_array_add(*apps, values); |
1351 | + g_variant_builder_add (builder, "(sisosss)", app->icon, |
1352 | + position++, app->dbus_name, app->menu, |
1353 | + app->icon_theme_path, app->label, |
1354 | + app->guide); |
1355 | } |
1356 | |
1357 | - return TRUE; |
1358 | + return g_variant_new("(a(sisosss))", builder); |
1359 | } |
1360 | |
1361 | /* Removes and approver from our list of approvers and |
1362 | @@ -1139,30 +1198,47 @@ |
1363 | ApplicationServiceAppstore * appstore = APPLICATION_SERVICE_APPSTORE(user_data); |
1364 | g_list_foreach(appstore->priv->applications, remove_approver, approver->proxy); |
1365 | |
1366 | + if (approver->name_watcher != 0) { |
1367 | + g_dbus_connection_signal_unsubscribe(g_dbus_proxy_get_connection(approver->proxy), approver->name_watcher); |
1368 | + approver->name_watcher = 0; |
1369 | + } |
1370 | + |
1371 | if (approver->proxy != NULL) { |
1372 | - if (!approver->destroy_by_proxy) { |
1373 | - g_object_unref(approver->proxy); |
1374 | - } |
1375 | + g_object_unref(approver->proxy); |
1376 | approver->proxy = NULL; |
1377 | } |
1378 | |
1379 | + if (approver->proxy_cancel != NULL) { |
1380 | + g_cancellable_cancel(approver->proxy_cancel); |
1381 | + g_object_unref(approver->proxy_cancel); |
1382 | + approver->proxy_cancel = NULL; |
1383 | + } |
1384 | + |
1385 | g_free(approver); |
1386 | return; |
1387 | } |
1388 | |
1389 | /* What did the approver tell us? */ |
1390 | static void |
1391 | -approver_request_cb (DBusGProxy *proxy, gboolean OUT_approved, GError *error, gpointer userdata) |
1392 | +approver_request_cb (GObject *object, GAsyncResult *res, gpointer user_data) |
1393 | { |
1394 | + GDBusProxy * proxy = G_DBUS_PROXY(object); |
1395 | + Application * app = (Application *)user_data; |
1396 | + GError * error = NULL; |
1397 | + gboolean approved = TRUE; /* default to approved */ |
1398 | + GVariant * result; |
1399 | + |
1400 | + result = g_dbus_proxy_call_finish(proxy, res, &error); |
1401 | + |
1402 | if (error == NULL) { |
1403 | - g_debug("Approver responded: %s", OUT_approved ? "approve" : "rejected"); |
1404 | - } else { |
1405 | + g_variant_get(result, "(b)", &approved); |
1406 | + g_debug("Approver responded: %s", approved ? "approve" : "rejected"); |
1407 | + } |
1408 | + else { |
1409 | g_debug("Approver responded error: %s", error->message); |
1410 | } |
1411 | |
1412 | - Application * app = (Application *)userdata; |
1413 | - |
1414 | - if (OUT_approved || error != NULL) { |
1415 | + if (approved) { |
1416 | app->approved_by = g_list_prepend(app->approved_by, proxy); |
1417 | } else { |
1418 | app->approved_by = g_list_remove(app->approved_by, proxy); |
1419 | @@ -1179,50 +1255,11 @@ |
1420 | Application * app = (Application *)papp; |
1421 | Approver * approver = (Approver *)papprove; |
1422 | |
1423 | - org_ayatana_StatusNotifierApprover_approve_item_async(approver->proxy, |
1424 | - app->id, |
1425 | - app->category, |
1426 | - 0, |
1427 | - app->dbus_name, |
1428 | - app->dbus_object, |
1429 | - approver_request_cb, |
1430 | - app); |
1431 | - |
1432 | - return; |
1433 | -} |
1434 | - |
1435 | -/* Look through all the approvers and find the one with a given |
1436 | - proxy. */ |
1437 | -static gint |
1438 | -approver_find_by_proxy (gconstpointer papprover, gconstpointer pproxy) |
1439 | -{ |
1440 | - Approver * approver = (Approver *)papprover; |
1441 | - |
1442 | - if (approver->proxy == pproxy) { |
1443 | - return 0; |
1444 | - } |
1445 | - |
1446 | - return -1; |
1447 | -} |
1448 | - |
1449 | -/* Tracks when a proxy gets destroyed so that we know that the |
1450 | - approver has dropped off the bus. */ |
1451 | -static void |
1452 | -approver_destroyed (gpointer pproxy, gpointer pappstore) |
1453 | -{ |
1454 | - ApplicationServiceAppstore * appstore = APPLICATION_SERVICE_APPSTORE(pappstore); |
1455 | - |
1456 | - GList * lapprover = g_list_find_custom(appstore->priv->approvers, pproxy, approver_find_by_proxy); |
1457 | - if (lapprover == NULL) { |
1458 | - g_warning("Approver proxy died, but we don't seem to have that approver."); |
1459 | - return; |
1460 | - } |
1461 | - |
1462 | - Approver * approver = (Approver *)lapprover->data; |
1463 | - approver->destroy_by_proxy = TRUE; |
1464 | - |
1465 | - appstore->priv->approvers = g_list_remove(appstore->priv->approvers, approver); |
1466 | - approver_free(approver, appstore); |
1467 | + g_dbus_proxy_call(approver->proxy, "ApproveItem", |
1468 | + g_variant_new("(ssuso)", app->id, app->category, |
1469 | + 0, app->dbus_name, app->dbus_object), |
1470 | + G_DBUS_CALL_FLAGS_NONE, -1, NULL, |
1471 | + approver_request_cb, app); |
1472 | |
1473 | return; |
1474 | } |
1475 | @@ -1230,17 +1267,12 @@ |
1476 | /* A signal when an approver changes the why that it thinks about |
1477 | a particular indicator. */ |
1478 | void |
1479 | -approver_revise_judgement (DBusGProxy * proxy, gboolean new_status, gchar * address, DBusGProxy * get_path, gpointer user_data) |
1480 | +approver_revise_judgement (Approver * approver, gboolean new_status, const gchar * address, const gchar * path) |
1481 | { |
1482 | - g_return_if_fail(IS_APPLICATION_SERVICE_APPSTORE(user_data)); |
1483 | g_return_if_fail(address != NULL && address[0] != '\0'); |
1484 | - g_return_if_fail(get_path != NULL); |
1485 | - const gchar * path = dbus_g_proxy_get_path(get_path); |
1486 | g_return_if_fail(path != NULL && path[0] != '\0'); |
1487 | |
1488 | - ApplicationServiceAppstore * appstore = APPLICATION_SERVICE_APPSTORE(user_data); |
1489 | - |
1490 | - Application * app = find_application(appstore, address, path); |
1491 | + Application * app = find_application(approver->appstore, address, path); |
1492 | |
1493 | if (app == NULL) { |
1494 | g_warning("Unable to update approver status of application (%s:%s) as it was not found", address, path); |
1495 | @@ -1248,9 +1280,9 @@ |
1496 | } |
1497 | |
1498 | if (new_status) { |
1499 | - app->approved_by = g_list_prepend(app->approved_by, proxy); |
1500 | + app->approved_by = g_list_prepend(app->approved_by, approver->proxy); |
1501 | } else { |
1502 | - app->approved_by = g_list_remove(app->approved_by, proxy); |
1503 | + app->approved_by = g_list_remove(app->approved_by, approver->proxy); |
1504 | } |
1505 | apply_status(app); |
1506 | |
1507 | @@ -1267,39 +1299,108 @@ |
1508 | ApplicationServiceAppstorePrivate * priv = APPLICATION_SERVICE_APPSTORE_GET_PRIVATE (appstore); |
1509 | |
1510 | Approver * approver = g_new0(Approver, 1); |
1511 | - approver->destroy_by_proxy = FALSE; |
1512 | - |
1513 | - GError * error = NULL; |
1514 | - approver->proxy = dbus_g_proxy_new_for_name_owner(priv->bus, |
1515 | - dbus_name, |
1516 | - dbus_object, |
1517 | - NOTIFICATION_APPROVER_DBUS_IFACE, |
1518 | - &error); |
1519 | - if (error != NULL) { |
1520 | - g_warning("Unable to get approver interface on '%s:%s' : %s", dbus_name, dbus_object, error->message); |
1521 | - g_error_free(error); |
1522 | - g_free(approver); |
1523 | - return; |
1524 | - } |
1525 | - |
1526 | - g_signal_connect(G_OBJECT(approver->proxy), "destroy", G_CALLBACK(approver_destroyed), appstore); |
1527 | - |
1528 | - dbus_g_proxy_add_signal(approver->proxy, |
1529 | - "ReviseJudgement", |
1530 | - G_TYPE_BOOLEAN, |
1531 | - G_TYPE_STRING, |
1532 | - DBUS_TYPE_G_OBJECT_PATH, |
1533 | - G_TYPE_INVALID); |
1534 | - dbus_g_proxy_connect_signal(approver->proxy, |
1535 | - "ReviseJudgement", |
1536 | - G_CALLBACK(approver_revise_judgement), |
1537 | - appstore, |
1538 | - NULL); |
1539 | + approver->appstore = appstore; |
1540 | + approver->proxy_cancel = NULL; |
1541 | + approver->proxy = NULL; |
1542 | + approver->name_watcher = 0; |
1543 | + |
1544 | + approver->proxy_cancel = g_cancellable_new(); |
1545 | + g_dbus_proxy_new_for_bus(G_BUS_TYPE_SESSION, |
1546 | + G_DBUS_PROXY_FLAGS_NONE, |
1547 | + NULL, |
1548 | + dbus_name, |
1549 | + dbus_object, |
1550 | + NOTIFICATION_APPROVER_DBUS_IFACE, |
1551 | + approver->proxy_cancel, |
1552 | + approver_proxy_cb, |
1553 | + approver); |
1554 | |
1555 | priv->approvers = g_list_prepend(priv->approvers, approver); |
1556 | |
1557 | + return; |
1558 | +} |
1559 | + |
1560 | +static void |
1561 | +approver_name_changed (GDBusConnection * connection, const gchar * sender_name, |
1562 | + const gchar * object_path, const gchar * interface_name, |
1563 | + const gchar * signal_name, GVariant * parameters, |
1564 | + gpointer user_data) |
1565 | +{ |
1566 | + Approver * approver = (Approver *)user_data; |
1567 | + ApplicationServiceAppstore * appstore = approver->appstore; |
1568 | + |
1569 | + const gchar * new_name; |
1570 | + g_variant_get(parameters, "(&s&s&s)", NULL, NULL, &new_name); |
1571 | + |
1572 | + if (new_name == NULL || new_name[0] == 0) { |
1573 | + appstore->priv->approvers = g_list_remove(appstore->priv->approvers, approver); |
1574 | + approver_free(approver, appstore); |
1575 | + } |
1576 | +} |
1577 | + |
1578 | +/* Callback from trying to create the proxy for the approver. */ |
1579 | +static void |
1580 | +approver_proxy_cb (GObject * object, GAsyncResult * res, gpointer user_data) |
1581 | +{ |
1582 | + GError * error = NULL; |
1583 | + |
1584 | + Approver * approver = (Approver *)user_data; |
1585 | + g_return_if_fail(approver != NULL); |
1586 | + |
1587 | + GDBusProxy * proxy = g_dbus_proxy_new_for_bus_finish(res, &error); |
1588 | + ApplicationServiceAppstorePrivate * priv = APPLICATION_SERVICE_APPSTORE_GET_PRIVATE (approver->appstore); |
1589 | + |
1590 | + if (approver->proxy_cancel != NULL) { |
1591 | + g_object_unref(approver->proxy_cancel); |
1592 | + approver->proxy_cancel = NULL; |
1593 | + } |
1594 | + |
1595 | + if (error != NULL) { |
1596 | + g_error("Could not grab DBus proxy for approver: %s", error->message); |
1597 | + g_error_free(error); |
1598 | + return; |
1599 | + } |
1600 | + |
1601 | + /* Okay, we're good to grab the proxy at this point, we're |
1602 | + sure that it's ours. */ |
1603 | + approver->proxy = proxy; |
1604 | + |
1605 | + /* We've got it, let's watch it for destruction */ |
1606 | + approver->name_watcher = g_dbus_connection_signal_subscribe( |
1607 | + g_dbus_proxy_get_connection(proxy), |
1608 | + "org.freedesktop.DBus", |
1609 | + "org.freedesktop.DBus", |
1610 | + "NameOwnerChanged", |
1611 | + "/org/freedesktop/DBus", |
1612 | + g_dbus_proxy_get_name(proxy), |
1613 | + G_DBUS_SIGNAL_FLAGS_NONE, |
1614 | + approver_name_changed, |
1615 | + approver, |
1616 | + NULL); |
1617 | + |
1618 | + g_signal_connect(proxy, "g-signal", G_CALLBACK(approver_receive_signal), |
1619 | + approver); |
1620 | + |
1621 | g_list_foreach(priv->applications, check_with_new_approver, approver); |
1622 | |
1623 | return; |
1624 | } |
1625 | |
1626 | +/* Receives all signals from the service, routed to the appropriate functions */ |
1627 | +static void |
1628 | +approver_receive_signal (GDBusProxy * proxy, gchar * sender_name, gchar * signal_name, |
1629 | + GVariant * parameters, gpointer user_data) |
1630 | +{ |
1631 | + Approver * approver = (Approver *)user_data; |
1632 | + |
1633 | + if (g_strcmp0(signal_name, "ReviseJudgement") == 0) { |
1634 | + gboolean approved; |
1635 | + const gchar * address; |
1636 | + const gchar * path; |
1637 | + g_variant_get(parameters, "(b&s&o)", &approved, &address, &path); |
1638 | + approver_revise_judgement(approver, approved, address, path); |
1639 | + } |
1640 | + |
1641 | + return; |
1642 | +} |
1643 | + |
1644 | |
1645 | === modified file 'src/application-service.c' |
1646 | --- src/application-service.c 2010-08-10 19:47:23 +0000 |
1647 | +++ src/application-service.c 2011-01-14 02:39:08 +0000 |
1648 | @@ -22,7 +22,6 @@ |
1649 | |
1650 | |
1651 | #include "libindicator/indicator-service.h" |
1652 | -#include "notification-item-client.h" |
1653 | #include "application-service-appstore.h" |
1654 | #include "application-service-watcher.h" |
1655 | #include "dbus-shared.h" |
1656 | |
1657 | === modified file 'src/application-service.xml' |
1658 | --- src/application-service.xml 2010-08-05 21:54:12 +0000 |
1659 | +++ src/application-service.xml 2011-01-14 02:39:08 +0000 |
1660 | @@ -20,7 +20,7 @@ |
1661 | with this program. If not, see <http://www.gnu.org/licenses/>. |
1662 | --> |
1663 | <node name="/"> |
1664 | - <interface name="org.ayatana.indicator.application.service"> |
1665 | + <interface name="com.canonical.indicator.application.service"> |
1666 | <!-- Properties --> |
1667 | <!-- None currently --> |
1668 | |
1669 | |
1670 | === removed file 'src/dbus-properties.xml' |
1671 | --- src/dbus-properties.xml 2009-11-07 04:50:48 +0000 |
1672 | +++ src/dbus-properties.xml 1970-01-01 00:00:00 +0000 |
1673 | @@ -1,23 +0,0 @@ |
1674 | -<?xml version="1.0" encoding="UTF-8"?> |
1675 | -<node name="/"> |
1676 | - <interface name="org.freedesktop.DBus.Properties"> |
1677 | - |
1678 | - <method name="Get"> |
1679 | - <arg direction="in" type="s" name="Interface_Name"/> |
1680 | - <arg direction="in" type="s" name="Property_Name"/> |
1681 | - <arg direction="out" type="v" name="Value"/> |
1682 | - </method> |
1683 | - |
1684 | - <method name="Set"> |
1685 | - <arg direction="in" type="s" name="Interface_Name"/> |
1686 | - <arg direction="in" type="s" name="Property_Name"/> |
1687 | - <arg direction="in" type="v" name="Value"/> |
1688 | - </method> |
1689 | - |
1690 | - <method name="GetAll"> |
1691 | - <arg direction="in" type="s" name="Interface_Name"/> |
1692 | - <arg direction="out" type="a{sv}" name="Properties"/> |
1693 | - </method> |
1694 | - |
1695 | - </interface> |
1696 | -</node> |
1697 | |
1698 | === modified file 'src/dbus-shared.h' |
1699 | --- src/dbus-shared.h 2010-07-09 21:06:37 +0000 |
1700 | +++ src/dbus-shared.h 2011-01-14 02:39:08 +0000 |
1701 | @@ -20,9 +20,9 @@ |
1702 | */ |
1703 | |
1704 | |
1705 | -#define INDICATOR_APPLICATION_DBUS_ADDR "org.ayatana.indicator.application" |
1706 | -#define INDICATOR_APPLICATION_DBUS_OBJ "/org/ayatana/indicator/application/service" |
1707 | -#define INDICATOR_APPLICATION_DBUS_IFACE "org.ayatana.indicator.application.service" |
1708 | +#define INDICATOR_APPLICATION_DBUS_ADDR "com.canonical.indicator.application" |
1709 | +#define INDICATOR_APPLICATION_DBUS_OBJ "/com/canonical/indicator/application/service" |
1710 | +#define INDICATOR_APPLICATION_DBUS_IFACE "com.canonical.indicator.application.service" |
1711 | |
1712 | #define NOTIFICATION_WATCHER_DBUS_ADDR "org.kde.StatusNotifierWatcher" |
1713 | #define NOTIFICATION_WATCHER_DBUS_OBJ "/StatusNotifierWatcher" |
1714 | |
1715 | === modified file 'src/indicator-application.c' |
1716 | --- src/indicator-application.c 2010-12-04 03:21:06 +0000 |
1717 | +++ src/indicator-application.c 2011-01-14 02:39:08 +0000 |
1718 | @@ -28,10 +28,10 @@ |
1719 | /* G Stuff */ |
1720 | #include <glib.h> |
1721 | #include <glib-object.h> |
1722 | +#include <gio/gio.h> |
1723 | #include <gtk/gtk.h> |
1724 | |
1725 | /* DBus Stuff */ |
1726 | -#include <dbus/dbus-glib.h> |
1727 | #ifdef HAVE_GTK3 |
1728 | #include <libdbusmenu-gtk3/menu.h> |
1729 | #else |
1730 | @@ -46,7 +46,7 @@ |
1731 | |
1732 | /* Local Stuff */ |
1733 | #include "dbus-shared.h" |
1734 | -#include "application-service-client.h" |
1735 | +#include "gen-application-service.xml.h" |
1736 | #include "application-service-marshal.h" |
1737 | |
1738 | #define PANEL_ICON_SUFFIX "panel" |
1739 | @@ -81,8 +81,8 @@ |
1740 | typedef struct _IndicatorApplicationPrivate IndicatorApplicationPrivate; |
1741 | struct _IndicatorApplicationPrivate { |
1742 | IndicatorServiceManager * sm; |
1743 | - DBusGConnection * bus; |
1744 | - DBusGProxy * service_proxy; |
1745 | + GCancellable * service_proxy_cancel; |
1746 | + GDBusProxy * service_proxy; |
1747 | GList * applications; |
1748 | GHashTable * theme_dirs; |
1749 | guint disconnect_kill; |
1750 | @@ -114,15 +114,17 @@ |
1751 | static void disconnected_helper (gpointer data, gpointer user_data); |
1752 | static gboolean disconnected_kill (gpointer user_data); |
1753 | static void disconnected_kill_helper (gpointer data, gpointer user_data); |
1754 | -static void application_added (DBusGProxy * proxy, const gchar * iconname, gint position, const gchar * dbusaddress, const gchar * dbusobject, const gchar * icon_theme_path, const gchar * label, const gchar * guide, IndicatorApplication * application); |
1755 | -static void application_removed (DBusGProxy * proxy, gint position , IndicatorApplication * application); |
1756 | -static void application_label_changed (DBusGProxy * proxy, gint position, const gchar * label, const gchar * guide, IndicatorApplication * application); |
1757 | -static void application_icon_changed (DBusGProxy * proxy, gint position, const gchar * iconname, IndicatorApplication * application); |
1758 | -static void application_icon_theme_path_changed (DBusGProxy * proxy, gint position, const gchar * icon_theme_path, IndicatorApplication * application); |
1759 | -static void get_applications (DBusGProxy *proxy, GPtrArray *OUT_applications, GError *error, gpointer userdata); |
1760 | -static void get_applications_helper (gpointer data, gpointer user_data); |
1761 | +static void application_added (IndicatorApplication * application, const gchar * iconname, gint position, const gchar * dbusaddress, const gchar * dbusobject, const gchar * icon_theme_path, const gchar * label, const gchar * guide); |
1762 | +static void application_removed (IndicatorApplication * application, gint position); |
1763 | +static void application_label_changed (IndicatorApplication * application, gint position, const gchar * label, const gchar * guide); |
1764 | +static void application_icon_changed (IndicatorApplication * application, gint position, const gchar * iconname); |
1765 | +static void application_icon_theme_path_changed (IndicatorApplication * application, gint position, const gchar * icon_theme_path); |
1766 | +static void get_applications (GObject * obj, GAsyncResult * res, gpointer user_data); |
1767 | +static void get_applications_helper (IndicatorApplication * self, GVariant * variant); |
1768 | static void theme_dir_unref(IndicatorApplication * ia, const gchar * dir); |
1769 | static void theme_dir_ref(IndicatorApplication * ia, const gchar * dir); |
1770 | +static void service_proxy_cb (GObject * object, GAsyncResult * res, gpointer user_data); |
1771 | +static void receive_signal (GDBusProxy * proxy, gchar * sender_name, gchar * signal_name, GVariant * parameters, gpointer user_data); |
1772 | |
1773 | G_DEFINE_TYPE (IndicatorApplication, indicator_application, INDICATOR_OBJECT_TYPE); |
1774 | |
1775 | @@ -141,28 +143,6 @@ |
1776 | io_class->get_entries = get_entries; |
1777 | io_class->get_location = get_location; |
1778 | |
1779 | - dbus_g_object_register_marshaller(_application_service_marshal_VOID__STRING_INT_STRING_STRING_STRING_STRING_STRING, |
1780 | - G_TYPE_NONE, |
1781 | - G_TYPE_STRING, |
1782 | - G_TYPE_INT, |
1783 | - G_TYPE_STRING, |
1784 | - G_TYPE_STRING, |
1785 | - G_TYPE_STRING, |
1786 | - G_TYPE_STRING, |
1787 | - G_TYPE_STRING, |
1788 | - G_TYPE_INVALID); |
1789 | - dbus_g_object_register_marshaller(_application_service_marshal_VOID__INT_STRING, |
1790 | - G_TYPE_NONE, |
1791 | - G_TYPE_INT, |
1792 | - G_TYPE_STRING, |
1793 | - G_TYPE_INVALID); |
1794 | - dbus_g_object_register_marshaller(_application_service_marshal_VOID__INT_STRING_STRING, |
1795 | - G_TYPE_NONE, |
1796 | - G_TYPE_INT, |
1797 | - G_TYPE_STRING, |
1798 | - G_TYPE_STRING, |
1799 | - G_TYPE_INVALID); |
1800 | - |
1801 | return; |
1802 | } |
1803 | |
1804 | @@ -172,7 +152,7 @@ |
1805 | IndicatorApplicationPrivate * priv = INDICATOR_APPLICATION_GET_PRIVATE(self); |
1806 | |
1807 | /* These are built in the connection phase */ |
1808 | - priv->bus = NULL; |
1809 | + priv->service_proxy_cancel = NULL; |
1810 | priv->service_proxy = NULL; |
1811 | priv->theme_dirs = NULL; |
1812 | priv->disconnect_kill = 0; |
1813 | @@ -197,9 +177,8 @@ |
1814 | } |
1815 | |
1816 | while (priv->applications != NULL) { |
1817 | - application_removed(priv->service_proxy, |
1818 | - 0, |
1819 | - INDICATOR_APPLICATION(object)); |
1820 | + application_removed(INDICATOR_APPLICATION(object), |
1821 | + 0); |
1822 | } |
1823 | |
1824 | if (priv->sm != NULL) { |
1825 | @@ -207,16 +186,17 @@ |
1826 | priv->sm = NULL; |
1827 | } |
1828 | |
1829 | - if (priv->bus != NULL) { |
1830 | - /* We're not incrementing the ref count on this one. */ |
1831 | - priv->bus = NULL; |
1832 | - } |
1833 | - |
1834 | if (priv->service_proxy != NULL) { |
1835 | g_object_unref(G_OBJECT(priv->service_proxy)); |
1836 | priv->service_proxy = NULL; |
1837 | } |
1838 | |
1839 | + if (priv->service_proxy_cancel != NULL) { |
1840 | + g_cancellable_cancel(priv->service_proxy_cancel); |
1841 | + g_object_unref(priv->service_proxy_cancel); |
1842 | + priv->service_proxy_cancel = NULL; |
1843 | + } |
1844 | + |
1845 | if (priv->theme_dirs != NULL) { |
1846 | while (g_hash_table_size(priv->theme_dirs)) { |
1847 | GList * keys = g_hash_table_get_keys(priv->theme_dirs); |
1848 | @@ -260,93 +240,59 @@ |
1849 | IndicatorApplicationPrivate * priv = INDICATOR_APPLICATION_GET_PRIVATE(application); |
1850 | g_debug("Connected to Application Indicator Service."); |
1851 | |
1852 | + if (priv->service_proxy_cancel == NULL && priv->service_proxy == NULL) { |
1853 | + /* Build the service proxy */ |
1854 | + priv->service_proxy_cancel = g_cancellable_new(); |
1855 | + |
1856 | + g_dbus_proxy_new_for_bus(G_BUS_TYPE_SESSION, |
1857 | + G_DBUS_PROXY_FLAGS_NONE, |
1858 | + NULL, |
1859 | + INDICATOR_APPLICATION_DBUS_ADDR, |
1860 | + INDICATOR_APPLICATION_DBUS_OBJ, |
1861 | + INDICATOR_APPLICATION_DBUS_IFACE, |
1862 | + priv->service_proxy_cancel, |
1863 | + service_proxy_cb, |
1864 | + application); |
1865 | + } |
1866 | + |
1867 | + return; |
1868 | +} |
1869 | + |
1870 | +/* Callback from trying to create the proxy for the service, this |
1871 | + could include starting the service. */ |
1872 | +static void |
1873 | +service_proxy_cb (GObject * object, GAsyncResult * res, gpointer user_data) |
1874 | +{ |
1875 | GError * error = NULL; |
1876 | |
1877 | - /* Grab the session bus */ |
1878 | - if (priv->bus == NULL) { |
1879 | - priv->bus = dbus_g_bus_get(DBUS_BUS_SESSION, &error); |
1880 | - |
1881 | - if (error != NULL) { |
1882 | - g_error("Unable to get session bus: %s", error->message); |
1883 | - g_error_free(error); |
1884 | - return; |
1885 | - } |
1886 | - } |
1887 | - |
1888 | - if (priv->service_proxy == NULL) { |
1889 | - /* Build the service proxy */ |
1890 | - priv->service_proxy = dbus_g_proxy_new_for_name(priv->bus, |
1891 | - INDICATOR_APPLICATION_DBUS_ADDR, |
1892 | - INDICATOR_APPLICATION_DBUS_OBJ, |
1893 | - INDICATOR_APPLICATION_DBUS_IFACE); |
1894 | - |
1895 | - /* Set up proxy signals */ |
1896 | - g_debug("Setup proxy signals"); |
1897 | - dbus_g_proxy_add_signal(priv->service_proxy, |
1898 | - "ApplicationAdded", |
1899 | - G_TYPE_STRING, |
1900 | - G_TYPE_INT, |
1901 | - G_TYPE_STRING, |
1902 | - G_TYPE_STRING, |
1903 | - G_TYPE_STRING, |
1904 | - G_TYPE_STRING, |
1905 | - G_TYPE_STRING, |
1906 | - G_TYPE_INVALID); |
1907 | - dbus_g_proxy_add_signal(priv->service_proxy, |
1908 | - "ApplicationRemoved", |
1909 | - G_TYPE_INT, |
1910 | - G_TYPE_INVALID); |
1911 | - dbus_g_proxy_add_signal(priv->service_proxy, |
1912 | - "ApplicationIconChanged", |
1913 | - G_TYPE_INT, |
1914 | - G_TYPE_STRING, |
1915 | - G_TYPE_INVALID); |
1916 | - dbus_g_proxy_add_signal(priv->service_proxy, |
1917 | - "ApplicationIconThemePathChanged", |
1918 | - G_TYPE_INT, |
1919 | - G_TYPE_STRING, |
1920 | - G_TYPE_INVALID); |
1921 | - dbus_g_proxy_add_signal(priv->service_proxy, |
1922 | - "ApplicationLabelChanged", |
1923 | - G_TYPE_INT, |
1924 | - G_TYPE_STRING, |
1925 | - G_TYPE_STRING, |
1926 | - G_TYPE_INVALID); |
1927 | - |
1928 | - /* Connect to them */ |
1929 | - g_debug("Connect to them."); |
1930 | - dbus_g_proxy_connect_signal(priv->service_proxy, |
1931 | - "ApplicationAdded", |
1932 | - G_CALLBACK(application_added), |
1933 | - application, |
1934 | - NULL /* Disconnection Signal */); |
1935 | - dbus_g_proxy_connect_signal(priv->service_proxy, |
1936 | - "ApplicationRemoved", |
1937 | - G_CALLBACK(application_removed), |
1938 | - application, |
1939 | - NULL /* Disconnection Signal */); |
1940 | - dbus_g_proxy_connect_signal(priv->service_proxy, |
1941 | - "ApplicationIconChanged", |
1942 | - G_CALLBACK(application_icon_changed), |
1943 | - application, |
1944 | - NULL /* Disconnection Signal */); |
1945 | - dbus_g_proxy_connect_signal(priv->service_proxy, |
1946 | - "ApplicationIconThemePathChanged", |
1947 | - G_CALLBACK(application_icon_theme_path_changed), |
1948 | - application, |
1949 | - NULL /* Disconnection Signal */); |
1950 | - dbus_g_proxy_connect_signal(priv->service_proxy, |
1951 | - "ApplicationLabelChanged", |
1952 | - G_CALLBACK(application_label_changed), |
1953 | - application, |
1954 | - NULL /* Disconnection Signal */); |
1955 | - } |
1956 | + IndicatorApplication * self = INDICATOR_APPLICATION(user_data); |
1957 | + g_return_if_fail(self != NULL); |
1958 | + |
1959 | + IndicatorApplicationPrivate * priv = INDICATOR_APPLICATION_GET_PRIVATE(self); |
1960 | + GDBusProxy * proxy = g_dbus_proxy_new_for_bus_finish(res, &error); |
1961 | + |
1962 | + if (priv->service_proxy_cancel != NULL) { |
1963 | + g_object_unref(priv->service_proxy_cancel); |
1964 | + priv->service_proxy_cancel = NULL; |
1965 | + } |
1966 | + |
1967 | + if (error != NULL) { |
1968 | + g_error("Could not grab DBus proxy for %s: %s", INDICATOR_APPLICATION_DBUS_ADDR, error->message); |
1969 | + g_error_free(error); |
1970 | + return; |
1971 | + } |
1972 | + |
1973 | + /* Okay, we're good to grab the proxy at this point, we're |
1974 | + sure that it's ours. */ |
1975 | + priv->service_proxy = proxy; |
1976 | + |
1977 | + g_signal_connect(proxy, "g-signal", G_CALLBACK(receive_signal), self); |
1978 | |
1979 | /* Query it for existing applications */ |
1980 | g_debug("Request current apps"); |
1981 | - org_ayatana_indicator_application_service_get_applications_async(priv->service_proxy, |
1982 | - get_applications, |
1983 | - application); |
1984 | + g_dbus_proxy_call(priv->service_proxy, "GetApplications", NULL, |
1985 | + G_DBUS_CALL_FLAGS_NONE, -1, NULL, |
1986 | + get_applications, self); |
1987 | |
1988 | return; |
1989 | } |
1990 | @@ -397,7 +343,7 @@ |
1991 | IndicatorApplicationPrivate * priv = INDICATOR_APPLICATION_GET_PRIVATE(user_data); |
1992 | ApplicationEntry * entry = (ApplicationEntry *)data; |
1993 | if (entry->old_service) { |
1994 | - application_removed(NULL, g_list_index(priv->applications, data), INDICATOR_APPLICATION(user_data)); |
1995 | + application_removed(INDICATOR_APPLICATION(user_data), g_list_index(priv->applications, data)); |
1996 | } |
1997 | return; |
1998 | } |
1999 | @@ -435,22 +381,6 @@ |
2000 | return g_list_index(priv->applications, entry); |
2001 | } |
2002 | |
2003 | -/* Searching for ApplicationEntries where the dbusobject and |
2004 | - address are the same. */ |
2005 | -static gint |
2006 | -application_added_search (gconstpointer a, gconstpointer b) |
2007 | -{ |
2008 | - ApplicationEntry * appa = (ApplicationEntry *)a; |
2009 | - ApplicationEntry * appb = (ApplicationEntry *)b; |
2010 | - |
2011 | - if (g_strcmp0(appa->dbusaddress, appb->dbusaddress) == 0 && |
2012 | - g_strcmp0(appa->dbusobject, appb->dbusobject) == 0) { |
2013 | - return 0; |
2014 | - } |
2015 | - |
2016 | - return -1; |
2017 | -} |
2018 | - |
2019 | /* Does a quick meausre of how big the string is in |
2020 | pixels with a Pango layout */ |
2021 | static gint |
2022 | @@ -495,25 +425,12 @@ |
2023 | ApplicationEntry and signaling the indicator host that |
2024 | we've got a new indicator. */ |
2025 | static void |
2026 | -application_added (DBusGProxy * proxy, const gchar * iconname, gint position, const gchar * dbusaddress, const gchar * dbusobject, const gchar * icon_theme_path, const gchar * label, const gchar * guide, IndicatorApplication * application) |
2027 | +application_added (IndicatorApplication * application, const gchar * iconname, gint position, const gchar * dbusaddress, const gchar * dbusobject, const gchar * icon_theme_path, const gchar * label, const gchar * guide) |
2028 | { |
2029 | g_return_if_fail(IS_INDICATOR_APPLICATION(application)); |
2030 | - g_debug("Building new application entry: %s with icon: %s", dbusaddress, iconname); |
2031 | + g_debug("Building new application entry: %s with icon: %s at position %i", dbusaddress, iconname, position); |
2032 | IndicatorApplicationPrivate * priv = INDICATOR_APPLICATION_GET_PRIVATE(application); |
2033 | |
2034 | - /* First search to see if we already have this entry */ |
2035 | - ApplicationEntry searchapp; |
2036 | - searchapp.dbusaddress = (gchar *)dbusaddress; /* Casting off const, but it's okay, we're not changing it */ |
2037 | - searchapp.dbusobject = (gchar *)dbusobject; /* Casting off const, but it's okay, we're not changing it */ |
2038 | - |
2039 | - GList * searchpointer = g_list_find_custom(priv->applications, &searchapp, application_added_search); |
2040 | - if (searchpointer != NULL) { |
2041 | - g_debug("\t...Already have that one."); |
2042 | - ApplicationEntry * app = (ApplicationEntry *)searchpointer->data; |
2043 | - app->old_service = FALSE; |
2044 | - return; |
2045 | - } |
2046 | - |
2047 | ApplicationEntry * app = g_new(ApplicationEntry, 1); |
2048 | |
2049 | app->old_service = FALSE; |
2050 | @@ -574,7 +491,7 @@ |
2051 | /* This removes the application from the list and free's all |
2052 | of the memory associated with it. */ |
2053 | static void |
2054 | -application_removed (DBusGProxy * proxy, gint position, IndicatorApplication * application) |
2055 | +application_removed (IndicatorApplication * application, gint position) |
2056 | { |
2057 | g_return_if_fail(IS_INDICATOR_APPLICATION(application)); |
2058 | IndicatorApplicationPrivate * priv = INDICATOR_APPLICATION_GET_PRIVATE(application); |
2059 | @@ -621,7 +538,7 @@ |
2060 | /* The callback for the signal that the label for an application |
2061 | has changed. */ |
2062 | static void |
2063 | -application_label_changed (DBusGProxy * proxy, gint position, const gchar * label, const gchar * guide, IndicatorApplication * application) |
2064 | +application_label_changed (IndicatorApplication * application, gint position, const gchar * label, const gchar * guide) |
2065 | { |
2066 | IndicatorApplicationPrivate * priv = INDICATOR_APPLICATION_GET_PRIVATE(application); |
2067 | ApplicationEntry * app = (ApplicationEntry *)g_list_nth_data(priv->applications, position); |
2068 | @@ -702,7 +619,7 @@ |
2069 | /* The callback for the signal that the icon for an application |
2070 | has changed. */ |
2071 | static void |
2072 | -application_icon_changed (DBusGProxy * proxy, gint position, const gchar * iconname, IndicatorApplication * application) |
2073 | +application_icon_changed (IndicatorApplication * application, gint position, const gchar * iconname) |
2074 | { |
2075 | IndicatorApplicationPrivate * priv = INDICATOR_APPLICATION_GET_PRIVATE(application); |
2076 | ApplicationEntry * app = (ApplicationEntry *)g_list_nth_data(priv->applications, position); |
2077 | @@ -732,7 +649,7 @@ |
2078 | /* The callback for the signal that the icon theme path for an application |
2079 | has changed. */ |
2080 | static void |
2081 | -application_icon_theme_path_changed (DBusGProxy * proxy, gint position, const gchar * icon_theme_path, IndicatorApplication * application) |
2082 | +application_icon_theme_path_changed (IndicatorApplication * application, gint position, const gchar * icon_theme_path) |
2083 | { |
2084 | IndicatorApplicationPrivate * priv = INDICATOR_APPLICATION_GET_PRIVATE(application); |
2085 | ApplicationEntry * app = (ApplicationEntry *)g_list_nth_data(priv->applications, position); |
2086 | @@ -758,16 +675,78 @@ |
2087 | return; |
2088 | } |
2089 | |
2090 | -/* This repsonds to the list of applications that the service |
2091 | +/* Receives all signals from the service, routed to the appropriate functions */ |
2092 | +static void |
2093 | +receive_signal (GDBusProxy * proxy, gchar * sender_name, gchar * signal_name, |
2094 | + GVariant * parameters, gpointer user_data) |
2095 | +{ |
2096 | + IndicatorApplication * self = INDICATOR_APPLICATION(user_data); |
2097 | + |
2098 | + if (g_strcmp0(signal_name, "ApplicationAdded") == 0) { |
2099 | + const gchar * iconname; |
2100 | + gint position; |
2101 | + const gchar * dbusaddress; |
2102 | + const gchar * dbusobject; |
2103 | + const gchar * icon_theme_path; |
2104 | + const gchar * label; |
2105 | + const gchar * guide; |
2106 | + g_variant_get (parameters, "(&si&s&o&s&s&s)", &iconname, |
2107 | + &position, &dbusaddress, &dbusobject, |
2108 | + &icon_theme_path, &label, &guide); |
2109 | + application_added(self, iconname, position, dbusaddress, |
2110 | + dbusobject, icon_theme_path, label, guide); |
2111 | + } |
2112 | + else if (g_strcmp0(signal_name, "ApplicationRemoved") == 0) { |
2113 | + gint position; |
2114 | + g_variant_get (parameters, "(i)", &position); |
2115 | + application_removed(self, position); |
2116 | + } |
2117 | + else if (g_strcmp0(signal_name, "ApplicationIconChanged") == 0) { |
2118 | + gint position; |
2119 | + const gchar * iconname; |
2120 | + g_variant_get (parameters, "(i&s)", &position, &iconname); |
2121 | + application_icon_changed(self, position, iconname); |
2122 | + } |
2123 | + else if (g_strcmp0(signal_name, "ApplicationIconThemePathChanged") == 0) { |
2124 | + gint position; |
2125 | + const gchar * icon_theme_path; |
2126 | + g_variant_get (parameters, "(i&s)", &position, &icon_theme_path); |
2127 | + application_icon_theme_path_changed(self, position, icon_theme_path); |
2128 | + } |
2129 | + else if (g_strcmp0(signal_name, "ApplicationLabelChanged") == 0) { |
2130 | + gint position; |
2131 | + const gchar * label; |
2132 | + const gchar * guide; |
2133 | + g_variant_get (parameters, "(i&s&s)", &position, &label, &guide); |
2134 | + application_label_changed(self, position, label, guide); |
2135 | + } |
2136 | + |
2137 | + return; |
2138 | +} |
2139 | + |
2140 | +/* This responds to the list of applications that the service |
2141 | has and calls application_added on each one of them. */ |
2142 | static void |
2143 | -get_applications (DBusGProxy *proxy, GPtrArray *OUT_applications, GError *error, gpointer userdata) |
2144 | +get_applications (GObject * obj, GAsyncResult * res, gpointer user_data) |
2145 | { |
2146 | + IndicatorApplication * self = INDICATOR_APPLICATION(user_data); |
2147 | + IndicatorApplicationPrivate * priv = INDICATOR_APPLICATION_GET_PRIVATE(self); |
2148 | + GError * error = NULL; |
2149 | + GVariant * result; |
2150 | + GVariant * child; |
2151 | + GVariantIter * iter; |
2152 | + |
2153 | + result = g_dbus_proxy_call_finish(priv->service_proxy, res, &error); |
2154 | + |
2155 | if (error != NULL) { |
2156 | g_warning("Unable to get application list: %s", error->message); |
2157 | return; |
2158 | } |
2159 | - g_ptr_array_foreach(OUT_applications, get_applications_helper, userdata); |
2160 | + |
2161 | + g_variant_get(result, "(a(sisosss))", &iter); |
2162 | + while ((child = g_variant_iter_next_value (iter))) |
2163 | + get_applications_helper(self, child); |
2164 | + g_variant_iter_free (iter); |
2165 | |
2166 | return; |
2167 | } |
2168 | @@ -775,21 +754,20 @@ |
2169 | /* A little helper that takes apart the DBus structure and calls |
2170 | application_added on every entry in the list. */ |
2171 | static void |
2172 | -get_applications_helper (gpointer data, gpointer user_data) |
2173 | +get_applications_helper (IndicatorApplication * self, GVariant * variant) |
2174 | { |
2175 | - GValueArray * array = (GValueArray *)data; |
2176 | - |
2177 | - g_return_if_fail(array->n_values == 7); |
2178 | - |
2179 | - const gchar * icon_name = g_value_get_string(g_value_array_get_nth(array, 0)); |
2180 | - gint position = g_value_get_int(g_value_array_get_nth(array, 1)); |
2181 | - const gchar * dbus_address = g_value_get_string(g_value_array_get_nth(array, 2)); |
2182 | - const gchar * dbus_object = g_value_get_boxed(g_value_array_get_nth(array, 3)); |
2183 | - const gchar * icon_theme_path = g_value_get_string(g_value_array_get_nth(array, 4)); |
2184 | - const gchar * label = g_value_get_string(g_value_array_get_nth(array, 5)); |
2185 | - const gchar * guide = g_value_get_string(g_value_array_get_nth(array, 6)); |
2186 | - |
2187 | - return application_added(NULL, icon_name, position, dbus_address, dbus_object, icon_theme_path, label, guide, user_data); |
2188 | + const gchar * icon_name; |
2189 | + gint position; |
2190 | + const gchar * dbus_address; |
2191 | + const gchar * dbus_object; |
2192 | + const gchar * icon_theme_path; |
2193 | + const gchar * label; |
2194 | + const gchar * guide; |
2195 | + g_variant_get(variant, "(sisosss)", &icon_name, &position, |
2196 | + &dbus_address, &dbus_object, &icon_theme_path, &label, |
2197 | + &guide); |
2198 | + |
2199 | + return application_added(self, icon_name, position, dbus_address, dbus_object, icon_theme_path, label, guide); |
2200 | } |
2201 | |
2202 | /* Unrefs a theme directory. This may involve removing it from |
2203 | |
2204 | === removed file 'src/notification-item.xml' |
2205 | --- src/notification-item.xml 2010-08-11 20:55:25 +0000 |
2206 | +++ src/notification-item.xml 1970-01-01 00:00:00 +0000 |
2207 | @@ -1,39 +0,0 @@ |
2208 | -<?xml version="1.0" encoding="UTF-8"?> |
2209 | -<node name="/StatusNotifierItem"> |
2210 | - <interface name="org.kde.StatusNotifierItem"> |
2211 | - |
2212 | -<!-- Properties --> |
2213 | - <property name="Id" type="s" access="read" /> |
2214 | - <property name="Category" type="s" access="read" /> |
2215 | - <property name="Status" type="s" access="read" /> |
2216 | - <property name="IconName" type="s" access="read" /> |
2217 | - <property name="AttentionIconName" type="s" access="read" /> |
2218 | - <!-- An additional path to add to the theme search path |
2219 | - to find the icons specified above. --> |
2220 | - <property name="IconThemePath" type="s" access="read" /> |
2221 | - <property name="Menu" type="o" access="read" /> |
2222 | - <property name="XAyatanaLabel" type="s" access="read" /> |
2223 | - <property name="XAyatanaLabelGuide" type="s" access="read" /> |
2224 | - <property name="XAyatanaOrderingIndex" type="u" access="read" /> |
2225 | - |
2226 | -<!-- Methods --> |
2227 | - <!-- None currently --> |
2228 | - |
2229 | -<!-- Signals --> |
2230 | - <signal name="NewIcon"> |
2231 | - </signal> |
2232 | - <signal name="NewIconThemePath"> |
2233 | - <arg type="s" name="icon_theme_path" direction="out" /> |
2234 | - </signal> |
2235 | - <signal name="NewAttentionIcon"> |
2236 | - </signal> |
2237 | - <signal name="NewStatus"> |
2238 | - <arg type="s" name="status" direction="out" /> |
2239 | - </signal> |
2240 | - <signal name="XAyatanaNewLabel"> |
2241 | - <arg type="s" name="label" direction="out" /> |
2242 | - <arg type="s" name="guide" direction="out" /> |
2243 | - </signal> |
2244 | - |
2245 | - </interface> |
2246 | -</node> |
2247 | |
2248 | === modified file 'tests/Makefile.am' |
2249 | --- tests/Makefile.am 2010-12-02 22:56:23 +0000 |
2250 | +++ tests/Makefile.am 2011-01-14 02:39:08 +0000 |
2251 | @@ -14,6 +14,7 @@ |
2252 | ######################################### |
2253 | |
2254 | test_approver_SOURCES = \ |
2255 | + $(top_srcdir)/src/gen-notification-approver.xml.c \ |
2256 | test-approver.c |
2257 | |
2258 | test_approver_CFLAGS = \ |
2259 | |
2260 | === modified file 'tests/test-approver.c' |
2261 | --- tests/test-approver.c 2010-12-02 22:56:23 +0000 |
2262 | +++ tests/test-approver.c 2011-01-14 02:39:08 +0000 |
2263 | @@ -1,11 +1,10 @@ |
2264 | #include <glib.h> |
2265 | #include <glib-object.h> |
2266 | - |
2267 | -#include <dbus/dbus-glib-bindings.h> |
2268 | - |
2269 | -#include "notification-watcher-client.h" |
2270 | +#include <gio/gio.h> |
2271 | + |
2272 | #include "dbus-shared.h" |
2273 | #include "libappindicator/app-indicator.h" |
2274 | +#include "gen-notification-approver.xml.h" |
2275 | |
2276 | #define APPROVER_PATH "/my/approver" |
2277 | |
2278 | @@ -35,13 +34,22 @@ |
2279 | |
2280 | static void test_approver_class_init (TestApproverClass *klass); |
2281 | static void test_approver_init (TestApprover *self); |
2282 | -static gboolean _notification_approver_server_approve_item (TestApprover * ta, const gchar * id, const gchar * category, guint pid, const gchar * address, const gchar * path, gboolean * approved, GError ** error); |
2283 | +static GVariant * approve_item (TestApprover * ta, const gchar * id); |
2284 | +static void bus_method_call (GDBusConnection * connection, const gchar * sender, const gchar * path, const gchar * interface, const gchar * method, GVariant * params, GDBusMethodInvocation * invocation, gpointer user_data); |
2285 | |
2286 | -#include "../src/notification-approver-server.h" |
2287 | +/* GDBus Stuff */ |
2288 | +static GDBusNodeInfo * node_info = NULL; |
2289 | +static GDBusInterfaceInfo * interface_info = NULL; |
2290 | +static GDBusInterfaceVTable interface_table = { |
2291 | + method_call: bus_method_call, |
2292 | + get_property: NULL, /* No properties */ |
2293 | + set_property: NULL /* No properties */ |
2294 | +}; |
2295 | |
2296 | GMainLoop * main_loop = NULL; |
2297 | -DBusGConnection * session_bus = NULL; |
2298 | -DBusGProxy * bus_proxy = NULL; |
2299 | +GDBusConnection * session_bus = NULL; |
2300 | +GDBusProxy * bus_proxy = NULL; |
2301 | +GDBusProxy * watcher_proxy = NULL; |
2302 | AppIndicator * app_indicator = NULL; |
2303 | gboolean passed = FALSE; |
2304 | |
2305 | @@ -50,8 +58,24 @@ |
2306 | static void |
2307 | test_approver_class_init (TestApproverClass *klass) |
2308 | { |
2309 | - dbus_g_object_type_install_info(TEST_APPROVER_TYPE, |
2310 | - &dbus_glib__notification_approver_server_object_info); |
2311 | + /* Setting up the DBus interfaces */ |
2312 | + if (node_info == NULL) { |
2313 | + GError * error = NULL; |
2314 | + |
2315 | + node_info = g_dbus_node_info_new_for_xml(_notification_approver, &error); |
2316 | + if (error != NULL) { |
2317 | + g_error("Unable to parse Approver Service Interface description: %s", error->message); |
2318 | + g_error_free(error); |
2319 | + } |
2320 | + } |
2321 | + |
2322 | + if (interface_info == NULL) { |
2323 | + interface_info = g_dbus_node_info_lookup_interface(node_info, NOTIFICATION_APPROVER_DBUS_IFACE); |
2324 | + |
2325 | + if (interface_info == NULL) { |
2326 | + g_error("Unable to find interface '" NOTIFICATION_APPROVER_DBUS_IFACE "'"); |
2327 | + } |
2328 | + } |
2329 | |
2330 | return; |
2331 | } |
2332 | @@ -59,17 +83,29 @@ |
2333 | static void |
2334 | test_approver_init (TestApprover *self) |
2335 | { |
2336 | - dbus_g_connection_register_g_object(session_bus, |
2337 | - APPROVER_PATH, |
2338 | - G_OBJECT(self)); |
2339 | + GError * error = NULL; |
2340 | + |
2341 | + /* Now register our object on our new connection */ |
2342 | + g_dbus_connection_register_object(session_bus, |
2343 | + APPROVER_PATH, |
2344 | + interface_info, |
2345 | + &interface_table, |
2346 | + self, |
2347 | + NULL, |
2348 | + &error); |
2349 | + |
2350 | + if (error != NULL) { |
2351 | + g_error("Unable to register the object to DBus: %s", error->message); |
2352 | + g_error_free(error); |
2353 | + return; |
2354 | + } |
2355 | |
2356 | return; |
2357 | } |
2358 | |
2359 | -static gboolean |
2360 | -_notification_approver_server_approve_item (TestApprover * ta, const gchar * id, const gchar * category, guint pid, const gchar * address, const gchar * path, gboolean * approved, GError ** error) |
2361 | +static GVariant * |
2362 | +approve_item (TestApprover * ta, const gchar * id) |
2363 | { |
2364 | - *approved = TRUE; |
2365 | g_debug("Asked to approve indicator"); |
2366 | |
2367 | if (g_strcmp0(id, INDICATOR_ID) == 0) { |
2368 | @@ -78,12 +114,41 @@ |
2369 | |
2370 | g_main_loop_quit(main_loop); |
2371 | |
2372 | - return TRUE; |
2373 | -} |
2374 | - |
2375 | -static void |
2376 | -register_cb (DBusGProxy * proxy, GError * error, gpointer user_data) |
2377 | -{ |
2378 | + return g_variant_new("(b)", TRUE); |
2379 | +} |
2380 | + |
2381 | +/* A method has been called from our dbus inteface. Figure out what it |
2382 | + is and dispatch it. */ |
2383 | +static void |
2384 | +bus_method_call (GDBusConnection * connection, const gchar * sender, |
2385 | + const gchar * path, const gchar * interface, |
2386 | + const gchar * method, GVariant * params, |
2387 | + GDBusMethodInvocation * invocation, gpointer user_data) |
2388 | +{ |
2389 | + TestApprover * ta = (TestApprover *)user_data; |
2390 | + GVariant * retval = NULL; |
2391 | + |
2392 | + if (g_strcmp0(method, "ApproveItem") == 0) { |
2393 | + const gchar * id; |
2394 | + g_variant_get(params, "(&ssuso)", &id, NULL, NULL, NULL, NULL); |
2395 | + retval = approve_item(ta, id); |
2396 | + } else { |
2397 | + g_warning("Calling method '%s' on the indicator service and it's unknown", method); |
2398 | + } |
2399 | + |
2400 | + g_dbus_method_invocation_return_value(invocation, retval); |
2401 | + return; |
2402 | +} |
2403 | + |
2404 | +static void |
2405 | +register_cb (GObject *object, GAsyncResult *res, gpointer user_data) |
2406 | +{ |
2407 | + GDBusProxy * proxy = G_DBUS_PROXY(object); |
2408 | + GError * error = NULL; |
2409 | + GVariant * result; |
2410 | + |
2411 | + result = g_dbus_proxy_call_finish(proxy, res, &error); |
2412 | + |
2413 | if (error != NULL) { |
2414 | g_warning("Unable to register approver: %s", error->message); |
2415 | g_error_free(error); |
2416 | @@ -118,18 +183,17 @@ |
2417 | owner_count++; |
2418 | |
2419 | gboolean has_owner = FALSE; |
2420 | - org_freedesktop_DBus_name_has_owner(bus_proxy, NOTIFICATION_WATCHER_DBUS_ADDR, &has_owner, NULL); |
2421 | + gchar * owner = g_dbus_proxy_get_name_owner(bus_proxy); |
2422 | + has_owner = (owner != NULL); |
2423 | + g_free (owner); |
2424 | |
2425 | if (has_owner) { |
2426 | - const char * cats = NULL; |
2427 | - DBusGProxy * proxy = dbus_g_proxy_new_for_name(session_bus, |
2428 | - NOTIFICATION_WATCHER_DBUS_ADDR, |
2429 | - NOTIFICATION_WATCHER_DBUS_OBJ, |
2430 | - NOTIFICATION_WATCHER_DBUS_IFACE); |
2431 | - |
2432 | g_debug("Registering Approver"); |
2433 | - org_kde_StatusNotifierWatcher_x_ayatana_register_notification_approver_async (proxy, APPROVER_PATH, &cats, register_cb, NULL); |
2434 | - |
2435 | + GVariantBuilder * builder = g_variant_builder_new(G_VARIANT_TYPE("as")); |
2436 | + g_dbus_proxy_call(bus_proxy, "XAyatanaRegisterNotificationApprover", |
2437 | + g_variant_new("(oas)", APPROVER_PATH, builder), |
2438 | + G_DBUS_CALL_FLAGS_NONE, -1, NULL, register_cb, |
2439 | + NULL); |
2440 | return FALSE; |
2441 | } |
2442 | |
2443 | @@ -152,16 +216,22 @@ |
2444 | gtk_init(&argc, &argv); |
2445 | g_debug("Initing"); |
2446 | |
2447 | - session_bus = dbus_g_bus_get(DBUS_BUS_SESSION, &error); |
2448 | - if (error != NULL) { |
2449 | - g_warning("Unable to get session bus: %s", error->message); |
2450 | - g_error_free(error); |
2451 | - return -1; |
2452 | - } |
2453 | - |
2454 | + session_bus = g_bus_get_sync(G_BUS_TYPE_SESSION, NULL, &error); |
2455 | TestApprover * approver = g_object_new(TEST_APPROVER_TYPE, NULL); |
2456 | |
2457 | - bus_proxy = dbus_g_proxy_new_for_name(session_bus, DBUS_SERVICE_DBUS, DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS); |
2458 | + bus_proxy = g_dbus_proxy_new_for_bus_sync(G_BUS_TYPE_SESSION, G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START, NULL, NOTIFICATION_WATCHER_DBUS_ADDR, NOTIFICATION_WATCHER_DBUS_OBJ, NOTIFICATION_WATCHER_DBUS_IFACE, NULL, &error); |
2459 | + if (error != NULL) { |
2460 | + g_warning("Unable to get bus proxy: %s", error->message); |
2461 | + g_error_free(error); |
2462 | + return -1; |
2463 | + } |
2464 | + |
2465 | + watcher_proxy = g_dbus_proxy_new_for_bus_sync(G_BUS_TYPE_SESSION, G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START, NULL, NOTIFICATION_WATCHER_DBUS_ADDR, NOTIFICATION_WATCHER_DBUS_OBJ, NOTIFICATION_WATCHER_DBUS_IFACE, NULL, &error); |
2466 | + if (error != NULL) { |
2467 | + g_warning("Unable to get watcher bus: %s", error->message); |
2468 | + g_error_free(error); |
2469 | + return -1; |
2470 | + } |
2471 | |
2472 | g_timeout_add(100, check_for_service, NULL); |
2473 | g_timeout_add_seconds(2, fail_timeout, NULL); |