aboutsummaryrefslogtreecommitdiff
path: root/libindicator
diff options
context:
space:
mode:
Diffstat (limited to 'libindicator')
-rw-r--r--libindicator/indicator-desktop-shortcuts.c110
-rw-r--r--libindicator/indicator-object.c11
-rw-r--r--libindicator/indicator-service.c4
3 files changed, 101 insertions, 24 deletions
diff --git a/libindicator/indicator-desktop-shortcuts.c b/libindicator/indicator-desktop-shortcuts.c
index 2ae78f9..13c1667 100644
--- a/libindicator/indicator-desktop-shortcuts.c
+++ b/libindicator/indicator-desktop-shortcuts.c
@@ -28,15 +28,26 @@ License along with this library. If not, see
#include <gio/gdesktopappinfo.h>
#include "indicator-desktop-shortcuts.h"
-#define GROUP_SUFFIX "Shortcut Group"
-#define SHORTCUTS_KEY "X-Ayatana-Desktop-Shortcuts"
-#define ENVIRON_KEY "TargetEnvironment"
+#define ACTIONS_KEY "Actions"
+#define ACTION_GROUP_PREFIX "Desktop Action"
+
+#define OLD_GROUP_SUFFIX "Shortcut Group"
+#define OLD_SHORTCUTS_KEY "X-Ayatana-Desktop-Shortcuts"
+#define OLD_ENVIRON_KEY "TargetEnvironment"
#define PROP_DESKTOP_FILE_S "desktop-file"
#define PROP_IDENTITY_S "identity"
+typedef enum _actions_t actions_t;
+enum _actions_t {
+ ACTIONS_NONE,
+ ACTIONS_XAYATANA,
+ ACTIONS_DESKTOP_SPEC
+};
+
typedef struct _IndicatorDesktopShortcutsPrivate IndicatorDesktopShortcutsPrivate;
struct _IndicatorDesktopShortcutsPrivate {
+ actions_t actions;
GKeyFile * keyfile;
gchar * identity;
GArray * nicks;
@@ -104,6 +115,7 @@ indicator_desktop_shortcuts_init (IndicatorDesktopShortcuts *self)
priv->identity = NULL;
priv->domain = NULL;
priv->nicks = g_array_new(TRUE, TRUE, sizeof(gchar *));
+ priv->actions = ACTIONS_NONE;
return;
}
@@ -162,6 +174,12 @@ set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec
switch(prop_id) {
case PROP_DESKTOP_FILE: {
+ if (priv->keyfile != NULL) {
+ g_key_file_free(priv->keyfile);
+ priv->keyfile = NULL;
+ priv->actions = ACTIONS_NONE;
+ }
+
GError * error = NULL;
GKeyFile * keyfile = g_key_file_new();
g_key_file_load_from_file(keyfile, g_value_get_string(value), G_KEY_FILE_NONE, &error);
@@ -173,7 +191,18 @@ set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec
break;
}
- if (!g_key_file_has_key(keyfile, G_KEY_FILE_DESKTOP_GROUP, SHORTCUTS_KEY, NULL)) {
+ /* Always prefer the desktop spec if we can get it */
+ if (priv->actions == ACTIONS_NONE && g_key_file_has_key(keyfile, G_KEY_FILE_DESKTOP_GROUP, ACTIONS_KEY, NULL)) {
+ priv->actions = ACTIONS_DESKTOP_SPEC;
+ }
+
+ /* But fallback if we can't */
+ if (priv->actions == ACTIONS_NONE && g_key_file_has_key(keyfile, G_KEY_FILE_DESKTOP_GROUP, OLD_SHORTCUTS_KEY, NULL)) {
+ priv->actions = ACTIONS_XAYATANA;
+ g_warning("Desktop file '%s' is using a depracted format for it's actions that will be dropped soon.", g_value_get_string(value));
+ }
+
+ if (priv->actions == ACTIONS_NONE) {
g_key_file_free(keyfile);
break;
}
@@ -253,16 +282,41 @@ parse_keyfile (IndicatorDesktopShortcuts * ids)
priv->domain = g_key_file_get_string(priv->keyfile, G_KEY_FILE_DESKTOP_GROUP, "X-Ubuntu-Gettext-Domain", NULL);
}
+ /* We need to figure out what we're looking for and what we want to
+ look for in the rest of the file */
+ const gchar * list_name = NULL;
+ const gchar * group_format = NULL;
+ gboolean should_have_target = FALSE;
+
+ switch (priv->actions) {
+ case ACTIONS_NONE:
+ /* None, let's just get outta here */
+ return;
+ case ACTIONS_XAYATANA:
+ list_name = OLD_SHORTCUTS_KEY;
+ group_format = "%s " OLD_GROUP_SUFFIX;
+ should_have_target = TRUE;
+ break;
+ case ACTIONS_DESKTOP_SPEC:
+ list_name = ACTIONS_KEY;
+ group_format = ACTION_GROUP_PREFIX " %s";
+ should_have_target = FALSE;
+ break;
+ default:
+ g_assert_not_reached();
+ return;
+ }
+
/* Okay, we've got everything we need. Let's get it on! */
gint i;
gsize num_nicks = 0;
- gchar ** nicks = g_key_file_get_string_list(priv->keyfile, G_KEY_FILE_DESKTOP_GROUP, SHORTCUTS_KEY, &num_nicks, NULL);
+ gchar ** nicks = g_key_file_get_string_list(priv->keyfile, G_KEY_FILE_DESKTOP_GROUP, list_name, &num_nicks, NULL);
/* If there is an error from get_string_list num_nicks should still
be zero, so this loop will drop out. */
for (i = 0; i < num_nicks; i++) {
/* g_debug("Looking at group nick %s", nicks[i]); */
- gchar * groupname = g_strdup_printf("%s " GROUP_SUFFIX, nicks[i]);
+ gchar * groupname = g_strdup_printf(group_format, nicks[i]);
if (!g_key_file_has_group(priv->keyfile, groupname)) {
g_warning("Unable to find group '%s'", groupname);
g_free(groupname);
@@ -274,7 +328,7 @@ parse_keyfile (IndicatorDesktopShortcuts * ids)
continue;
}
- if (!should_show(priv->keyfile, groupname, priv->identity, TRUE)) {
+ if (!should_show(priv->keyfile, groupname, priv->identity, should_have_target)) {
g_free(groupname);
continue;
}
@@ -296,12 +350,12 @@ parse_keyfile (IndicatorDesktopShortcuts * ids)
static gboolean
should_show (GKeyFile * keyfile, const gchar * group, const gchar * identity, gboolean should_have_target)
{
- if (should_have_target && g_key_file_has_key(keyfile, group, ENVIRON_KEY, NULL)) {
+ if (should_have_target && g_key_file_has_key(keyfile, group, OLD_ENVIRON_KEY, NULL)) {
/* If we've got this key, we're going to return here and not
process the deprecated keys. */
gint j;
gsize num_env = 0;
- gchar ** envs = g_key_file_get_string_list(keyfile, group, ENVIRON_KEY, &num_env, NULL);
+ gchar ** envs = g_key_file_get_string_list(keyfile, group, OLD_ENVIRON_KEY, &num_env, NULL);
for (j = 0; j < num_env; j++) {
if (g_strcmp0(envs[j], identity) == 0) {
@@ -317,10 +371,6 @@ should_show (GKeyFile * keyfile, const gchar * group, const gchar * identity, gb
return FALSE;
}
return TRUE;
- } else {
- if (should_have_target) {
- g_warning(GROUP_SUFFIX " does not have key '" ENVIRON_KEY "' falling back to deprecated use of '" G_KEY_FILE_DESKTOP_KEY_ONLY_SHOW_IN "' and '" G_KEY_FILE_DESKTOP_KEY_NOT_SHOW_IN "'.");
- }
}
/* If there is a list of OnlyShowIn entries we need to check
@@ -449,10 +499,25 @@ indicator_desktop_shortcuts_nick_get_name (IndicatorDesktopShortcuts * ids, cons
g_return_val_if_fail(INDICATOR_IS_DESKTOP_SHORTCUTS(ids), NULL);
IndicatorDesktopShortcutsPrivate * priv = INDICATOR_DESKTOP_SHORTCUTS_GET_PRIVATE(ids);
+ g_return_val_if_fail(priv->actions != ACTIONS_NONE, NULL);
g_return_val_if_fail(priv->keyfile != NULL, NULL);
g_return_val_if_fail(is_valid_nick((gchar **)priv->nicks->data, nick), NULL);
- gchar * groupheader = g_strdup_printf("%s " GROUP_SUFFIX, nick);
+ const gchar * group_format = NULL;
+
+ switch (priv->actions) {
+ case ACTIONS_XAYATANA:
+ group_format = "%s " OLD_GROUP_SUFFIX;
+ break;
+ case ACTIONS_DESKTOP_SPEC:
+ group_format = ACTION_GROUP_PREFIX " %s";
+ break;
+ default:
+ g_assert_not_reached();
+ return NULL;
+ }
+
+ gchar * groupheader = g_strdup_printf(group_format, nick);
if (!g_key_file_has_group(priv->keyfile, groupheader)) {
g_warning("The group for nick '%s' doesn't exist anymore.", nick);
g_free(groupheader);
@@ -509,10 +574,25 @@ indicator_desktop_shortcuts_nick_exec (IndicatorDesktopShortcuts * ids, const gc
g_return_val_if_fail(INDICATOR_IS_DESKTOP_SHORTCUTS(ids), FALSE);
IndicatorDesktopShortcutsPrivate * priv = INDICATOR_DESKTOP_SHORTCUTS_GET_PRIVATE(ids);
+ g_return_val_if_fail(priv->actions != ACTIONS_NONE, FALSE);
g_return_val_if_fail(priv->keyfile != NULL, FALSE);
g_return_val_if_fail(is_valid_nick((gchar **)priv->nicks->data, nick), FALSE);
- gchar * groupheader = g_strdup_printf("%s " GROUP_SUFFIX, nick);
+ const gchar * group_format = NULL;
+
+ switch (priv->actions) {
+ case ACTIONS_XAYATANA:
+ group_format = "%s " OLD_GROUP_SUFFIX;
+ break;
+ case ACTIONS_DESKTOP_SPEC:
+ group_format = ACTION_GROUP_PREFIX " %s";
+ break;
+ default:
+ g_assert_not_reached();
+ return FALSE;
+ }
+
+ gchar * groupheader = g_strdup_printf(group_format, nick);
if (!g_key_file_has_group(priv->keyfile, groupheader)) {
g_warning("The group for nick '%s' doesn't exist anymore.", nick);
g_free(groupheader);
diff --git a/libindicator/indicator-object.c b/libindicator/indicator-object.c
index 17a6d1d..ca821af 100644
--- a/libindicator/indicator-object.c
+++ b/libindicator/indicator-object.c
@@ -464,21 +464,16 @@ indicator_object_new_from_file (const gchar * file)
goto unrefandout;
}
- IndicatorObjectPrivate * priv = INDICATOR_OBJECT_GET_PRIVATE(object);
/* Now we can track the module */
- priv->module = module;
+ INDICATOR_OBJECT_GET_PRIVATE(object)->module = module;
return INDICATOR_OBJECT(object);
/* Error, let's drop the object and return NULL. Sad when
this happens. */
unrefandout:
- if (object != NULL) {
- g_object_unref(object);
- }
- if (module != NULL) {
- g_object_unref(module);
- }
+ g_clear_object (&object);
+ g_clear_object (&module);
g_warning("Error building IndicatorObject from file: %s", file);
return NULL;
}
diff --git a/libindicator/indicator-service.c b/libindicator/indicator-service.c
index e9f3133..11171fc 100644
--- a/libindicator/indicator-service.c
+++ b/libindicator/indicator-service.c
@@ -588,7 +588,9 @@ unwatch_core (IndicatorService * service, const gchar * name)
/* Remove us from the watcher list here */
gpointer watcher_item = g_hash_table_lookup(priv->watchers, name);
if (watcher_item != NULL) {
- g_hash_table_remove(priv->watchers, name);
+ gchar * safe_name = g_strdup(name);
+ g_hash_table_remove(priv->watchers, safe_name);
+ g_free(safe_name);
} else {
/* Odd that we couldn't find the person, but, eh */
g_warning("Unable to find watcher who is unwatching: %s", name);