[geany/geany] 7c2c9d: plugin api: add destroy_notify to the new keybinding APIs

Thomas Martitz git-noreply at xxxxx
Mon Oct 12 21:06:51 UTC 2015


Branch:      refs/heads/master
Author:      Thomas Martitz <kugel at rockbox.org>
Committer:   Thomas Martitz <kugel at rockbox.org>
Date:        Wed, 26 Aug 2015 21:49:45 UTC
Commit:      7c2c9dc27a909129007d74bb40ac67a643f6a2f4
             https://github.com/geany/geany/commit/7c2c9dc27a909129007d74bb40ac67a643f6a2f4

Log Message:
-----------
plugin api: add destroy_notify to the new keybinding APIs

The destroy_notify can be used to make Geany automatically free the
per-KeyGroup or per-KeyBinding user_data. This is particularly useful for
vala-based plugins or other (future) language bindings.

The destroy functions can be conviniently hooked into the destroy_notify of
the underlying GPtrArrays, therefore this commit also implements such notifies
internally.


Modified Paths:
--------------
    src/keybindings.c
    src/keybindings.h
    src/keybindingsprivate.h
    src/pluginutils.c
    src/pluginutils.h

Modified: src/keybindings.c
61 lines changed, 40 insertions(+), 21 deletions(-)
===================================================================
@@ -202,7 +202,7 @@ GeanyKeyBinding *keybindings_set_item(GeanyKeyGroup *group, gsize key_id,
 }
 
 
-/** Creates a new keybinding using a GeanyKeyBindingFunc and attaches is to a keybinding group
+/** Creates a new keybinding using a GeanyKeyBindingFunc and attaches it to a keybinding group
  *
  * If given the callback should return @c TRUE if the keybinding was handled, otherwise @c FALSE
  * to allow other callbacks to be run. This allows for multiplexing keybindings on the same keys,
@@ -211,14 +211,15 @@ GeanyKeyBinding *keybindings_set_item(GeanyKeyGroup *group, gsize key_id,
  *
  * @param group Group.
  * @param key_id Keybinding index for the group.
- * @param cb New-style callback to be called when activated, or @c NULL to use the group callback.
- * @param pdata Plugin-specific data passed back to the callback.
  * @param key (Lower case) default key, e.g. @c GDK_j, but usually 0 for unset.
  * @param mod Default modifier, e.g. @c GDK_CONTROL_MASK, but usually 0 for unset.
  * @param kf_name Key name for the configuration file, such as @c "menu_new".
  * @param label Label used in the preferences dialog keybindings tab. May contain
  * underscores - these won't be displayed.
  * @param menu_item Optional widget to set an accelerator for, or @c NULL.
+ * @param cb New-style callback to be called when activated, or @c NULL to use the group callback.
+ * @param pdata Plugin-specific data passed back to the callback.
+ * @param destroy_notify Function that is invoked to free the plugin data when not needed anymore.
  * @return The keybinding - normally this is ignored.
  *
  * @since 1.26 (API 226)
@@ -226,8 +227,9 @@ GeanyKeyBinding *keybindings_set_item(GeanyKeyGroup *group, gsize key_id,
  **/
 GEANY_API_SYMBOL
 GeanyKeyBinding *keybindings_set_item_full(GeanyKeyGroup *group, gsize key_id,
-		GeanyKeyBindingFunc cb, gpointer pdata, guint key, GdkModifierType mod,
-		const gchar *kf_name, const gchar *label, GtkWidget *menu_item)
+		guint key, GdkModifierType mod, const gchar *kf_name, const gchar *label,
+		GtkWidget *menu_item, GeanyKeyBindingFunc cb, gpointer pdata,
+		GDestroyNotify destroy_notify)
 {
 	GeanyKeyBinding *kb;
 
@@ -237,10 +239,23 @@ GeanyKeyBinding *keybindings_set_item_full(GeanyKeyGroup *group, gsize key_id,
 	kb = keybindings_set_item(group, key_id, NULL, key, mod, kf_name, label, menu_item);
 	kb->cb_func = cb;
 	kb->cb_data = pdata;
+	kb->cb_data_destroy = destroy_notify;
 	return kb;
 }
 
 
+static void free_key_binding(gpointer item)
+{
+	GeanyKeyBinding *kb = item;
+
+	g_free(kb->name);
+	g_free(kb->label);
+
+	if (kb->cb_data_destroy)
+		kb->cb_data_destroy(kb->cb_data);
+}
+
+
 static void add_kb_group(GeanyKeyGroup *group,
 		const gchar *name, const gchar *label, GeanyKeyGroupCallback callback, gboolean plugin)
 {
@@ -252,7 +267,8 @@ static void add_kb_group(GeanyKeyGroup *group,
 	group->cb_func = NULL;
 	group->cb_data = NULL;
 	group->plugin = plugin;
-	group->key_items = g_ptr_array_new();
+	/* Only plugins use the destroy notify thus far */
+	group->key_items = g_ptr_array_new_with_free_func(plugin ? free_key_binding : NULL);
 }
 
 
@@ -680,10 +696,27 @@ static void init_default_kb(void)
 }
 
 
+static void free_key_group(gpointer item)
+{
+	GeanyKeyGroup *group = item;
+
+	g_ptr_array_free(group->key_items, TRUE);
+
+	if (group->plugin)
+	{
+		if (group->cb_data_destroy)
+			group->cb_data_destroy(group->cb_data);
+		g_free(group->plugin_keys);
+		g_free(group);
+	}
+}
+
+
 void keybindings_init(void)
 {
 	memset(binding_ids, 0, sizeof binding_ids);
 	keybinding_groups = g_ptr_array_sized_new(GEANY_KEY_GROUP_COUNT);
+	g_ptr_array_set_free_func(keybinding_groups, free_key_group);
 	kb_accel_group = gtk_accel_group_new();
 
 	init_default_kb();
@@ -2591,19 +2624,5 @@ GeanyKeyGroup *keybindings_set_group(GeanyKeyGroup *group, const gchar *section_
 
 void keybindings_free_group(GeanyKeyGroup *group)
 {
-	GeanyKeyBinding *kb;
-
-	g_ptr_array_free(group->key_items, TRUE);
-
-	if (group->plugin)
-	{
-		foreach_c_array(kb, group->plugin_keys, group->plugin_key_count)
-		{
-			g_free(kb->name);
-			g_free(kb->label);
-		}
-		g_free(group->plugin_keys);
-		g_ptr_array_remove_fast(keybinding_groups, group);
-		g_free(group);
-	}
+	g_ptr_array_remove_fast(keybinding_groups, group);
 }


Modified: src/keybindings.h
6 lines changed, 4 insertions(+), 2 deletions(-)
===================================================================
@@ -89,6 +89,7 @@ struct GeanyKeyBinding
 	GdkModifierType default_mods;
 	GeanyKeyBindingFunc cb_func;
 	gpointer cb_data;
+	GDestroyNotify cb_data_destroy;
 };
 
 /* Note: we don't need to break the plugin ABI when appending keybinding or keygroup IDs,
@@ -276,8 +277,9 @@ GeanyKeyBinding *keybindings_set_item(GeanyKeyGroup *group, gsize key_id,
 		const gchar *name, const gchar *label, GtkWidget *menu_item);
 
 GeanyKeyBinding *keybindings_set_item_full(GeanyKeyGroup *group, gsize key_id,
-		GeanyKeyBindingFunc cb, gpointer pdata, guint key, GdkModifierType mod,
-		const gchar *kf_name, const gchar *label, GtkWidget *menu_item);
+		guint key, GdkModifierType mod, const gchar *kf_name, const gchar *label,
+		GtkWidget *menu_item, GeanyKeyBindingFunc func, gpointer pdata,
+		GDestroyNotify destroy_notify);
 
 GeanyKeyBinding *keybindings_get_item(GeanyKeyGroup *group, gsize key_id);
 


Modified: src/keybindingsprivate.h
1 lines changed, 1 insertions(+), 0 deletions(-)
===================================================================
@@ -40,6 +40,7 @@ struct GeanyKeyGroup
 	GeanyKeyBinding *plugin_keys;	/* array of GeanyKeyBinding structs */
 	GeanyKeyGroupFunc cb_func;	/* use this or individual keybinding callbacks (new style) */
 	gpointer cb_data;
+	GDestroyNotify cb_data_destroy; /* used to destroy handler_data */
 };
 
 G_END_DECLS


Modified: src/pluginutils.c
5 lines changed, 4 insertions(+), 1 deletions(-)
===================================================================
@@ -318,6 +318,7 @@ GeanyKeyGroup *plugin_set_key_group(GeanyPlugin *plugin,
  * @param count Number of keybindings for the group.
  * @param cb New-style group callback, or @c NULL if you only want individual keybinding callbacks.
  * @param pdata Plugin specific data, passed to the group callback.
+ * @param destroy_notify Function that is invoked to free the plugin data when not needed anymore.
  * @return The plugin's keybinding group.
  *
  * @since 1.26 (API 226)
@@ -326,13 +327,15 @@ GeanyKeyGroup *plugin_set_key_group(GeanyPlugin *plugin,
  **/
 GEANY_API_SYMBOL
 GeanyKeyGroup *plugin_set_key_group_full(GeanyPlugin *plugin,
-		const gchar *section_name, gsize count, GeanyKeyGroupFunc cb, gpointer pdata)
+		const gchar *section_name, gsize count,
+		GeanyKeyGroupFunc cb, gpointer pdata, GDestroyNotify destroy_notify)
 {
 	GeanyKeyGroup *group;
 
 	group = plugin_set_key_group(plugin, section_name, count, NULL);
 	group->cb_func = cb;
 	group->cb_data = pdata;
+	group->cb_data_destroy = destroy_notify;
 
 	return group;
 }


Modified: src/pluginutils.h
2 lines changed, 1 insertions(+), 1 deletions(-)
===================================================================
@@ -55,7 +55,7 @@ struct GeanyKeyGroup *plugin_set_key_group(struct GeanyPlugin *plugin,
 		const gchar *section_name, gsize count, GeanyKeyGroupCallback callback);
 
 GeanyKeyGroup *plugin_set_key_group_full(struct GeanyPlugin *plugin,
-		const gchar *section_name, gsize count, GeanyKeyGroupFunc cb, gpointer pdata);
+		const gchar *section_name, gsize count, GeanyKeyGroupFunc cb, gpointer pdata, GDestroyNotify destroy_notify);
 
 void plugin_show_configure(struct GeanyPlugin *plugin);
 



--------------
This E-Mail was brought to you by github_commit_mail.py (Source: https://github.com/geany/infrastructure).


More information about the Commits mailing list