aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libdbusmenu-gtk/client.c20
-rw-r--r--libdbusmenu-gtk/menuitem.c174
2 files changed, 105 insertions, 89 deletions
diff --git a/libdbusmenu-gtk/client.c b/libdbusmenu-gtk/client.c
index 91bc816..c73c90f 100644
--- a/libdbusmenu-gtk/client.c
+++ b/libdbusmenu-gtk/client.c
@@ -144,12 +144,12 @@ do_swap_agroup (DbusmenuMenuitem * mi, gpointer userdata) {
dbusmenu_menuitem_property_get_shortcut(mi, &key, &modifiers);
- g_debug("Setting shortcut on '%s': %d %X", dbusmenu_menuitem_property_get(mi, DBUSMENU_MENUITEM_PROP_LABEL), key, modifiers);
-
if (key == 0) {
return FALSE;
}
+ g_debug("Setting shortcut on '%s': %d %X", dbusmenu_menuitem_property_get(mi, DBUSMENU_MENUITEM_PROP_LABEL), key, modifiers);
+
GtkMenuItem * gmi = dbusmenu_gtkclient_menuitem_get(data->client, mi);
if (gmi == NULL) {
return FALSE;
@@ -197,16 +197,18 @@ refresh_shortcut (DbusmenuGtkClient * client, DbusmenuMenuitem * mi)
data.new_agroup = priv->agroup;
if (do_swap_agroup(mi, &data)) {
- guint key;
- GdkModifierType mod;
- GtkMenuItem *gmi = dbusmenu_gtkclient_menuitem_get (client, mi);
+ guint key = 0;
+ GdkModifierType mod = 0;
+ GtkMenuItem *gmi = dbusmenu_gtkclient_menuitem_get (client, mi);
- dbusmenu_menuitem_property_get_shortcut (mi, &key, &mod);
+ dbusmenu_menuitem_property_get_shortcut (mi, &key, &mod);
- gtk_widget_add_accelerator (GTK_WIDGET (gmi), "activate", priv->agroup, key, mod, GTK_ACCEL_VISIBLE);
- }
+ if (key != 0) {
+ gtk_widget_add_accelerator (GTK_WIDGET (gmi), "activate", priv->agroup, key, mod, GTK_ACCEL_VISIBLE);
+ }
+ }
- return;
+ return;
}
diff --git a/libdbusmenu-gtk/menuitem.c b/libdbusmenu-gtk/menuitem.c
index a7aa9d2..9924546 100644
--- a/libdbusmenu-gtk/menuitem.c
+++ b/libdbusmenu-gtk/menuitem.c
@@ -29,6 +29,7 @@ License version 3 and version 2.1 along with this program. If not, see
#include "menuitem.h"
#include <gdk/gdk.h>
#include <gtk/gtk.h>
+#include <dbus/dbus-gtype-specialized.h>
/**
dbusmenu_menuitem_property_set_image:
@@ -160,17 +161,6 @@ dbusmenu_menuitem_property_set_shortcut_string (DbusmenuMenuitem * menuitem, con
return dbusmenu_menuitem_property_set_shortcut(menuitem, key, modifier);
}
-/* Append strings to an g_value_array */
-static void
-_g_value_array_append_string (GValueArray * array, const gchar * string)
-{
- GValue value = {0};
- g_value_init(&value, G_TYPE_STRING);
- g_value_set_string(&value, string);
- g_value_array_append(array, &value);
- return;
-}
-
/**
dbusmenu_menuitem_property_set_shortcut:
@menuitem: The #DbusmenuMenuitem to set the shortcut on
@@ -188,32 +178,46 @@ dbusmenu_menuitem_property_set_shortcut (DbusmenuMenuitem * menuitem, guint key,
g_return_val_if_fail(DBUSMENU_IS_MENUITEM(menuitem), FALSE);
g_return_val_if_fail(gtk_accelerator_valid(key, modifier), FALSE);
- GValueArray * array = g_value_array_new(4); /* Four seems like the max we'd need, plus it's still small */
+ GArray * array = g_array_sized_new(TRUE, TRUE, sizeof(gchar *), 4); /* Four seems like the max we'd need, plus it's still small */
+
+ const gchar * control_val = DBUSMENU_MENUITEM_SHORTCUT_CONTROL;
+ const gchar * alt_val = DBUSMENU_MENUITEM_SHORTCUT_ALT;
+ const gchar * shift_val = DBUSMENU_MENUITEM_SHORTCUT_SHIFT;
+ const gchar * super_val = DBUSMENU_MENUITEM_SHORTCUT_SUPER;
if (modifier & GDK_CONTROL_MASK) {
- _g_value_array_append_string(array, DBUSMENU_MENUITEM_SHORTCUT_CONTROL);
+ g_array_append_val(array, control_val);
}
if (modifier & GDK_MOD1_MASK) {
- _g_value_array_append_string(array, DBUSMENU_MENUITEM_SHORTCUT_ALT);
+ g_array_append_val(array, alt_val);
}
if (modifier & GDK_SHIFT_MASK) {
- _g_value_array_append_string(array, DBUSMENU_MENUITEM_SHORTCUT_SHIFT);
+ g_array_append_val(array, shift_val);
}
if (modifier & GDK_SUPER_MASK) {
- _g_value_array_append_string(array, DBUSMENU_MENUITEM_SHORTCUT_SUPER);
+ g_array_append_val(array, super_val);
}
- _g_value_array_append_string(array, gdk_keyval_name(key));
+ const gchar * keyname = gdk_keyval_name(key);
+ g_array_append_val(array, keyname);
+
+ GType type = dbus_g_type_get_collection("GPtrArray", G_TYPE_STRV);
+ GPtrArray * wrapper = (GPtrArray *)dbus_g_type_specialized_construct(type);
+
+ GValue value = {0,};
+ g_value_init(&value, type);
+ g_value_take_boxed(&value, wrapper);
+
+ DBusGTypeSpecializedAppendContext ctx;
+ dbus_g_type_specialized_init_append(&value, &ctx);
- GValueArray * wrapper = g_value_array_new(1);
- GValue wrap_val = {0};
- g_value_init(&wrap_val, G_TYPE_VALUE_ARRAY);
- g_value_set_boxed(&wrap_val, array);
- g_value_array_append(wrapper, &wrap_val);
+ GValue strval = {0,};
+ g_value_init(&strval, G_TYPE_STRV);
+ g_value_take_boxed(&strval, array->data);
+ g_array_free(array, FALSE);
- GValue value = {0};
- g_value_init(&value, G_TYPE_VALUE_ARRAY);
- g_value_set_boxed(&value, wrapper);
+ dbus_g_type_specialized_collection_append(&ctx, &strval);
+ dbus_g_type_specialized_collection_end_append(&ctx);
dbusmenu_menuitem_property_set_value(menuitem, DBUSMENU_MENUITEM_PROP_SHORTCUT, &value);
@@ -274,90 +278,100 @@ dbusmenu_menuitem_property_set_shortcut_menuitem (DbusmenuMenuitem * menuitem, c
return dbusmenu_menuitem_property_set_shortcut(menuitem, key->accel_key, key->accel_mods);
}
-/**
- dbusmenu_menuitem_property_get_shortcut:
- @menuitem: The #DbusmenuMenuitem to get the shortcut off
- @key: Location to put the key value
- @modifier: Location to put the modifier mask
+/* A set of typed data for the interator */
+typedef struct _iter_data_t iter_data_t;
+struct _iter_data_t {
+ guint * key;
+ GdkModifierType * modifier;
+};
- This function gets a GTK shortcut as a key and a mask
- for use to set the accelerators.
-*/
-void
-dbusmenu_menuitem_property_get_shortcut (DbusmenuMenuitem * menuitem, guint * key, GdkModifierType * modifier)
+/* Goes through the wrapper items. In reality we only support one
+ so it checks to see if a key is set first. But, we could possibly,
+ support more in the future. */
+static void
+_wrapper_iterator (const GValue * value, gpointer user_data)
{
- *key = 0;
- *modifier = 0;
-
- g_return_if_fail(DBUSMENU_IS_MENUITEM(menuitem));
-
- const GValue * wrapper = dbusmenu_menuitem_property_get_value(menuitem, DBUSMENU_MENUITEM_PROP_SHORTCUT);
- if (wrapper == NULL) {
- return;
- }
- if (!G_VALUE_HOLDS(wrapper, G_TYPE_VALUE_ARRAY)) {
- g_warning("Unexpected shortcut structure. Wrapper is: %s", G_VALUE_TYPE_NAME(wrapper));
- return;
- }
+ iter_data_t * iter_data = (iter_data_t *)user_data;
- GValueArray * wrapperarray = (GValueArray *)g_value_get_boxed(wrapper);
- if (wrapperarray->n_values == 0) {
- return;
- }
-
- if (wrapperarray->n_values != 1) {
+ if (*iter_data->key != 0) {
g_warning("Shortcut is more than one entry. Which we don't currently support. Taking the first.");
+ return;
}
- GValue * ventryarray = g_value_array_get_nth(wrapperarray, 0);
- if (!G_VALUE_HOLDS(ventryarray, G_TYPE_VALUE_ARRAY)) {
- g_warning("Unexpected shortcut structure. Value array is: %s", G_VALUE_TYPE_NAME(ventryarray));
+ if (!G_VALUE_HOLDS(value, G_TYPE_STRV)) {
+ g_warning("Unexpected shortcut structure. Value array is: %s", G_VALUE_TYPE_NAME(value));
return;
}
- GValueArray * entryarray = (GValueArray *)g_value_get_boxed(ventryarray);
- if (entryarray->n_values == 0) {
- /* Seems a little odd, but really, we're saying that it isn't a
- shortcut, so I'm comfortable with exiting silently. */
+ gchar ** stringarray = (gchar **)g_value_get_boxed(value);
+ if (stringarray == NULL) {
return;
}
- /* Parse through modifiers */
+ const gchar * last_string = NULL;
int i;
- for (i = 0; i < entryarray->n_values - 1; i++) {
- GValue * value = g_value_array_get_nth(entryarray, i);
- if (!G_VALUE_HOLDS_STRING(value)) {
- continue;
- }
+ for (i = 0; stringarray[i] != NULL; i++) {
+ last_string = stringarray[i];
- if (g_strcmp0(g_value_get_string(value), DBUSMENU_MENUITEM_SHORTCUT_CONTROL) == 0) {
- *modifier |= GDK_CONTROL_MASK;
+ if (g_strcmp0(last_string, DBUSMENU_MENUITEM_SHORTCUT_CONTROL) == 0) {
+ *iter_data->modifier |= GDK_CONTROL_MASK;
continue;
}
- if (g_strcmp0(g_value_get_string(value), DBUSMENU_MENUITEM_SHORTCUT_ALT) == 0) {
- *modifier |= GDK_MOD1_MASK;
+ if (g_strcmp0(last_string, DBUSMENU_MENUITEM_SHORTCUT_ALT) == 0) {
+ *iter_data->modifier |= GDK_MOD1_MASK;
continue;
}
- if (g_strcmp0(g_value_get_string(value), DBUSMENU_MENUITEM_SHORTCUT_SHIFT) == 0) {
- *modifier |= GDK_SHIFT_MASK;
+ if (g_strcmp0(last_string, DBUSMENU_MENUITEM_SHORTCUT_SHIFT) == 0) {
+ *iter_data->modifier |= GDK_SHIFT_MASK;
continue;
}
- if (g_strcmp0(g_value_get_string(value), DBUSMENU_MENUITEM_SHORTCUT_SUPER) == 0) {
- *modifier |= GDK_SUPER_MASK;
+ if (g_strcmp0(last_string, DBUSMENU_MENUITEM_SHORTCUT_SUPER) == 0) {
+ *iter_data->modifier |= GDK_SUPER_MASK;
continue;
}
}
- GdkModifierType tempmod;
+ if (last_string != NULL) {
+ GdkModifierType tempmod;
+ gtk_accelerator_parse(last_string, iter_data->key, &tempmod);
+ }
+
+ return;
+}
+
+/**
+ dbusmenu_menuitem_property_get_shortcut:
+ @menuitem: The #DbusmenuMenuitem to get the shortcut off
+ @key: Location to put the key value
+ @modifier: Location to put the modifier mask
+
+ This function gets a GTK shortcut as a key and a mask
+ for use to set the accelerators.
+*/
+void
+dbusmenu_menuitem_property_get_shortcut (DbusmenuMenuitem * menuitem, guint * key, GdkModifierType * modifier)
+{
+ *key = 0;
+ *modifier = 0;
+
+ g_return_if_fail(DBUSMENU_IS_MENUITEM(menuitem));
- GValue * accelval = g_value_array_get_nth(entryarray, entryarray->n_values - 1);
- if (!G_VALUE_HOLDS_STRING(accelval)) {
- *modifier = 0;
+ const GValue * wrapper = dbusmenu_menuitem_property_get_value(menuitem, DBUSMENU_MENUITEM_PROP_SHORTCUT);
+ if (wrapper == NULL) {
+ return;
+ }
+ if (!dbus_g_type_is_collection(G_VALUE_TYPE(wrapper))) {
+ g_warning("Unexpected shortcut structure. Wrapper is: %s", G_VALUE_TYPE_NAME(wrapper));
return;
}
- gtk_accelerator_parse(g_value_get_string(accelval), key, &tempmod);
+ iter_data_t iter_data;
+ iter_data.key = key;
+ iter_data.modifier = modifier;
+
+ dbus_g_type_collection_value_iterate(wrapper, _wrapper_iterator, &iter_data);
return;
}
+