aboutsummaryrefslogtreecommitdiff
path: root/libindicator/indicator-ng.c
diff options
context:
space:
mode:
Diffstat (limited to 'libindicator/indicator-ng.c')
-rw-r--r--libindicator/indicator-ng.c91
1 files changed, 60 insertions, 31 deletions
diff --git a/libindicator/indicator-ng.c b/libindicator/indicator-ng.c
index fd78662..88db31c 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);
@@ -254,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}")))
{
@@ -362,11 +361,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 +376,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
@@ -460,39 +458,70 @@ 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,
GError **error)
{
IndicatorNg *self = INDICATOR_NG (initable);
GKeyFile *keyfile;
+ gboolean success;
- 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;
+ self->bus_name = g_path_get_basename (self->service_file);
- if (!(self->bus_name = g_key_file_get_string (keyfile, "Indicator Service", "BusName", error)))
- goto out;
+ keyfile = g_key_file_new ();
+ if (g_key_file_load_from_file (keyfile, self->service_file, G_KEY_FILE_NONE, error) &&
+ indicator_ng_load_from_keyfile (self, keyfile, error))
+ {
+ self->entry.name_hint = self->name;
- if (!(self->object_path = g_key_file_get_string (keyfile, "Indicator Service", "ObjectPath", error)))
- goto out;
+ /* 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,
+ indicator_ng_service_appeared,
+ indicator_ng_service_vanished,
+ self, NULL);
+ }
- 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);
+ success = TRUE;
+ }
-out:
g_key_file_free (keyfile);
-
- return self->name_watch_id > 0;
+ return success;
}
static void