From 2712010f2411973ff1687be63e3961f5c76acec3 Mon Sep 17 00:00:00 2001 From: Lars Uebernickel Date: Fri, 24 May 2013 17:10:40 -0400 Subject: refactor indicator_ng_initable_init This makes the flow a bit more apparent. Also gets rid of a goto. --- libindicator/indicator-ng.c | 38 ++++++++++++++++---------------------- 1 file changed, 16 insertions(+), 22 deletions(-) (limited to 'libindicator') diff --git a/libindicator/indicator-ng.c b/libindicator/indicator-ng.c index fd78662..0bd3981 100644 --- a/libindicator/indicator-ng.c +++ b/libindicator/indicator-ng.c @@ -468,30 +468,24 @@ indicator_ng_initable_init (GInitable *initable, GKeyFile *keyfile; keyfile = g_key_file_new (); - if (!g_key_file_load_from_file (keyfile, self->service_file, G_KEY_FILE_NONE, error)) - goto out; - - if (!(self->name = g_key_file_get_string (keyfile, "Indicator Service", "Name", error))) - goto out; - - self->entry.name_hint = self->name; - - if (!(self->bus_name = g_key_file_get_string (keyfile, "Indicator Service", "BusName", error))) - goto out; - - if (!(self->object_path = g_key_file_get_string (keyfile, "Indicator Service", "ObjectPath", error))) - goto out; - - self->name_watch_id = g_bus_watch_name (G_BUS_TYPE_SESSION, - self->bus_name, - G_BUS_NAME_WATCHER_FLAGS_AUTO_START, - indicator_ng_service_appeared, - indicator_ng_service_vanished, - self, NULL); + if (g_key_file_load_from_file (keyfile, self->service_file, G_KEY_FILE_NONE, error)) + { + if ((self->name = g_key_file_get_string (keyfile, "Indicator Service", "Name", error)) && + (self->bus_name = g_key_file_get_string (keyfile, "Indicator Service", "BusName", error)) && + (self->object_path = g_key_file_get_string (keyfile, "Indicator Service", "ObjectPath", error))) + { + self->entry.name_hint = self->name; + + self->name_watch_id = g_bus_watch_name (G_BUS_TYPE_SESSION, + self->bus_name, + G_BUS_NAME_WATCHER_FLAGS_AUTO_START, + indicator_ng_service_appeared, + indicator_ng_service_vanished, + self, NULL); + } + } -out: g_key_file_free (keyfile); - return self->name_watch_id > 0; } -- cgit v1.2.3 From 9627530cdaeb8d0ad9984f55f6fb0804740a1343 Mon Sep 17 00:00:00 2001 From: Lars Uebernickel Date: Fri, 24 May 2013 18:17:45 -0400 Subject: IndicatorNg: update indicator file format The old file format had some shortcomings: (1) It was impossible to efficiently reuse a menu for different profiles, because the profile name was implicit in the object path. The only way to do this was to export the same menu twice. Now, object paths have to be set explicitly in the indicator file. (2) The well-known dbus name of a service and the name of its service file were similar but slightly different (com.canonical.indicator.test vs com.canonical.test.indicator), which caused some confusion on when to use which. Now, the file name *is* the bus name, and the `BusName` key has been dropped. The new file format is documented in README. --- libindicator/indicator-ng.c | 62 ++++++++++++++++++++++++++++++++++++--------- 1 file changed, 50 insertions(+), 12 deletions(-) (limited to 'libindicator') diff --git a/libindicator/indicator-ng.c b/libindicator/indicator-ng.c index 0bd3981..fbf1e97 100644 --- a/libindicator/indicator-ng.c +++ b/libindicator/indicator-ng.c @@ -29,6 +29,7 @@ struct _IndicatorNg gchar *service_file; gchar *name; gchar *object_path; + gchar *menu_object_path; gchar *bus_name; gchar *profile; gchar *header_action; @@ -152,6 +153,7 @@ indicator_ng_finalize (GObject *object) g_free (self->service_file); g_free (self->name); g_free (self->object_path); + g_free (self->menu_object_path); g_free (self->bus_name); g_free (self->accessible_desc); g_free (self->header_action); @@ -362,11 +364,13 @@ indicator_ng_service_appeared (GDBusConnection *connection, gpointer user_data) { IndicatorNg *self = user_data; - gchar *menu_object_path; g_assert (!self->actions); g_assert (!self->menu); + /* watch is not established when menu_object_path == NULL */ + g_assert (self->menu_object_path); + self->session_bus = g_object_ref (connection); self->actions = G_ACTION_GROUP (g_dbus_action_group_get (connection, name_owner, self->object_path)); @@ -375,15 +379,12 @@ indicator_ng_service_appeared (GDBusConnection *connection, g_signal_connect_swapped (self->actions, "action-removed", G_CALLBACK (indicator_ng_update_entry), self); g_signal_connect_swapped (self->actions, "action-state-changed", G_CALLBACK (indicator_ng_update_entry), self); - menu_object_path = g_strconcat (self->object_path, "/", self->profile, NULL); - self->menu = G_MENU_MODEL (g_dbus_menu_model_get (connection, name_owner, menu_object_path)); + self->menu = G_MENU_MODEL (g_dbus_menu_model_get (connection, name_owner, self->menu_object_path)); g_signal_connect (self->menu, "items-changed", G_CALLBACK (indicator_ng_menu_changed), self); if (g_menu_model_get_n_items (self->menu)) indicator_ng_menu_changed (self->menu, 0, 0, 1, self); indicator_ng_update_entry (self); - - g_free (menu_object_path); } static void @@ -459,6 +460,38 @@ indicator_ng_service_vanished (GDBusConnection *connection, } } +static gboolean +indicator_ng_load_from_keyfile (IndicatorNg *self, + GKeyFile *keyfile, + GError **error) +{ + g_assert (self->name == NULL); + g_assert (self->object_path == NULL); + g_assert (self->menu_object_path == NULL); + + self->name = g_key_file_get_string (keyfile, "Indicator Service", "Name", error); + if (self->name == NULL) + return FALSE; + + self->object_path = g_key_file_get_string (keyfile, "Indicator Service", "ObjectPath", error); + if (self->object_path == NULL) + return FALSE; + + /* + * Don't throw an error when the profile doesn't exist. Non-existant + * profiles are silently ignored by not showing an indicator at all. + */ + if (g_key_file_has_group (keyfile, self->profile)) + { + /* however, if the profile exists, it must have "ObjectPath" */ + self->menu_object_path = g_key_file_get_string (keyfile, self->profile, "ObjectPath", error); + if (self->menu_object_path == NULL) + return FALSE; + } + + return TRUE; +} + static gboolean indicator_ng_initable_init (GInitable *initable, GCancellable *cancellable, @@ -466,16 +499,19 @@ indicator_ng_initable_init (GInitable *initable, { IndicatorNg *self = INDICATOR_NG (initable); GKeyFile *keyfile; + gboolean success; + + self->bus_name = g_path_get_basename (self->service_file); keyfile = g_key_file_new (); - if (g_key_file_load_from_file (keyfile, self->service_file, G_KEY_FILE_NONE, error)) + if (g_key_file_load_from_file (keyfile, self->service_file, G_KEY_FILE_NONE, error) && + indicator_ng_load_from_keyfile (self, keyfile, error)) { - if ((self->name = g_key_file_get_string (keyfile, "Indicator Service", "Name", error)) && - (self->bus_name = g_key_file_get_string (keyfile, "Indicator Service", "BusName", error)) && - (self->object_path = g_key_file_get_string (keyfile, "Indicator Service", "ObjectPath", error))) - { - self->entry.name_hint = self->name; + self->entry.name_hint = self->name; + /* only watch the service when it supports the proile we're interested in */ + if (self->menu_object_path) + { self->name_watch_id = g_bus_watch_name (G_BUS_TYPE_SESSION, self->bus_name, G_BUS_NAME_WATCHER_FLAGS_AUTO_START, @@ -483,10 +519,12 @@ indicator_ng_initable_init (GInitable *initable, indicator_ng_service_vanished, self, NULL); } + + success = TRUE; } g_key_file_free (keyfile); - return self->name_watch_id > 0; + return success; } static void -- cgit v1.2.3 From 0d3ebcb5cf74eef75f2153400b7b8a1d450573a5 Mon Sep 17 00:00:00 2001 From: Lars Uebernickel Date: Wed, 29 May 2013 14:54:35 -0400 Subject: indicator-ng: fix crash --- libindicator/indicator-ng.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'libindicator') diff --git a/libindicator/indicator-ng.c b/libindicator/indicator-ng.c index fbf1e97..88db31c 100644 --- a/libindicator/indicator-ng.c +++ b/libindicator/indicator-ng.c @@ -256,15 +256,12 @@ indicator_ng_update_entry (IndicatorNg *self) state = g_action_group_get_action_state (self->actions, self->header_action); if (state && g_variant_is_of_type (state, G_VARIANT_TYPE ("(sssb)"))) { - gchar *iconstr = NULL; + const gchar *iconstr = NULL; g_variant_get (state, "(&s&s&sb)", &label, &iconstr, &accessible_desc, &visible); if (iconstr) - { - icon = g_variant_ref_sink (g_variant_new_string (iconstr)); - g_free (iconstr); - } + icon = g_variant_ref_sink (g_variant_new_string (iconstr)); } else if (state && g_variant_is_of_type (state, G_VARIANT_TYPE ("a{sv}"))) { -- cgit v1.2.3