Branch: refs/heads/master Author: Thomas Martitz kugel@rockbox.org Committer: Thomas Martitz kugel@rockbox.org Date: Wed, 26 Aug 2015 21:46:45 UTC Commit: 1d08d3db4a0c7f6dc91309f3986d232b26cffb08 https://github.com/geany/geany/commit/1d08d3db4a0c7f6dc91309f3986d232b26cffb...
Log Message: ----------- plugin api: introduce GeanyKeyGroupFunc and GeanyKeyBindingFunc
These are new keybinding callback functions that take a few more parameters. Most importantly they have pdata pointer which allows plugins to store context information. This is especially useful for future plugins in OOP languages to store an instance pointer there, or interpreted ones to store interpreter context.
Modified Paths: -------------- src/keybindings.c src/keybindings.h src/keybindingsprivate.h
Modified: src/keybindings.c 58 lines changed, 33 insertions(+), 25 deletions(-) =================================================================== @@ -194,6 +194,8 @@ GeanyKeyBinding *keybindings_set_item(GeanyKeyGroup *group, gsize key_id, kb->default_key = key; kb->default_mods = mod; kb->callback = callback; + kb->cb_func = NULL; + kb->cb_data = NULL; kb->menu_item = menu_item; kb->id = key_id; return kb; @@ -208,6 +210,8 @@ static void add_kb_group(GeanyKeyGroup *group, group->name = name; group->label = label; group->callback = callback; + group->cb_func = NULL; + group->cb_data = NULL; group->plugin = plugin; group->key_items = g_ptr_array_new(); } @@ -1207,6 +1211,30 @@ gboolean keybindings_check_event(GdkEventKey *ev, GeanyKeyBinding *kb) }
+static gboolean run_kb(GeanyKeyBinding *kb, GeanyKeyGroup *group) +{ + gboolean handled = TRUE; + /* call the corresponding handler/callback functions for this shortcut. + * Check the individual keybindings first (handler first, callback second) and + * group second (again handler first, callback second) */ + if (kb->cb_func) + handled = kb->cb_func(kb, kb->id, kb->cb_data); + else if (kb->callback) + kb->callback(kb->id); + else if (group->cb_func) + handled = group->cb_func(group, kb->id, group->cb_data); + else if (group->callback) + handled = group->callback(kb->id); + else + { + g_warning("No callback or handler for keybinding %s: %s!", group->name, kb->name); + return FALSE; + } + + return handled; +} + + /* central keypress event handler, almost all keypress events go to this function */ static gboolean on_key_press_event(GtkWidget *widget, GdkEventKey *ev, gpointer user_data) { @@ -1249,20 +1277,8 @@ static gboolean on_key_press_event(GtkWidget *widget, GdkEventKey *ev, gpointer { if (keyval == kb->key && state == kb->mods) { - /* call the corresponding callback function for this shortcut */ - if (kb->callback) - { - kb->callback(kb->id); + if (run_kb(kb, group)) return TRUE; - } - else if (group->callback) - { - if (group->callback(kb->id)) - return TRUE; - else - continue; /* not handled */ - } - g_warning("No callback for keybinding %s: %s!", group->name, kb->name); } } } @@ -1296,20 +1312,12 @@ GEANY_API_SYMBOL void keybindings_send_command(guint group_id, guint key_id) { GeanyKeyBinding *kb; + GeanyKeyGroup *group;
kb = keybindings_lookup_item(group_id, key_id); - if (kb) - { - if (kb->callback) - kb->callback(key_id); - else - { - GeanyKeyGroup *group = keybindings_get_core_group(group_id); - - if (group->callback) - group->callback(key_id); - } - } + group = keybindings_get_core_group(group_id); + if (kb && group) + run_kb(kb, group); }
Modified: src/keybindings.h 48 lines changed, 34 insertions(+), 14 deletions(-) =================================================================== @@ -37,12 +37,42 @@ G_BEGIN_DECLS #define GEANY_PRIMARY_MOD_MASK GDK_CONTROL_MASK #endif
+/** A collection of keybindings grouped together. */ +typedef struct GeanyKeyGroup GeanyKeyGroup; +typedef struct GeanyKeyBinding GeanyKeyBinding; + +/** Function pointer type used for keybinding group callbacks. + * + * You should return @c TRUE to indicate handling the callback. (Occasionally, if the keybinding + * cannot apply in the current situation, it is useful to return @c FALSE to allow a later keybinding + * with the same key combination to handle it). */ +typedef gboolean (*GeanyKeyGroupCallback) (guint key_id); + +/** Function pointer type used for keybinding group callbacks, with userdata for passing context. + * + * You should return @c TRUE to indicate handling the callback. (Occasionally, if the keybinding + * cannot apply in the current situation, it is useful to return @c FALSE to allow a later keybinding + * with the same key combination to handle it). + * + * @since 1.26 (API 226) */ +typedef gboolean (*GeanyKeyGroupFunc)(GeanyKeyGroup *group, guint key_id, gpointer pdata); + /** Function pointer type used for keybinding callbacks. */ typedef void (*GeanyKeyCallback) (guint key_id);
+/** Function pointer type used for keybinding callbacks, with userdata for passing context + * + * You should return @c TRUE to indicate handling the callback. (Occasionally, if the keybinding + * cannot apply in the current situation, it is useful to return @c FALSE to allow a later keybinding + * with the same key combination to handle it). + * + * @since 1.26 (API 226) */ +typedef gboolean (*GeanyKeyBindingFunc)(GeanyKeyBinding *key, guint key_id, gpointer pdata); + /** Represents a single keybinding action. + * * Use keybindings_set_item() to set. */ -typedef struct GeanyKeyBinding +struct GeanyKeyBinding { guint key; /**< Key value in lower-case, such as @c GDK_a or 0 */ GdkModifierType mods; /**< Modifier keys, such as @c GDK_CONTROL_MASK or 0 */ @@ -57,19 +87,9 @@ typedef struct GeanyKeyBinding guint id; guint default_key; GdkModifierType default_mods; -} -GeanyKeyBinding; - - -/** Function pointer type used for keybinding group callbacks. - * You should return @c TRUE to indicate handling the callback. (Occasionally, if the keybinding - * cannot apply in the current situation, it is useful to return @c FALSE to allow a later keybinding - * with the same key combination to handle it). */ -typedef gboolean (*GeanyKeyGroupCallback) (guint key_id); - -/** A collection of keybindings grouped together. */ -typedef struct GeanyKeyGroup GeanyKeyGroup; - + GeanyKeyBindingFunc cb_func; + gpointer cb_data; +};
/* Note: we don't need to break the plugin ABI when appending keybinding or keygroup IDs, * just make sure to insert immediately before the _COUNT item, so
Modified: src/keybindingsprivate.h 2 lines changed, 2 insertions(+), 0 deletions(-) =================================================================== @@ -38,6 +38,8 @@ struct GeanyKeyGroup GPtrArray *key_items; /* pointers to GeanyKeyBinding structs */ gsize plugin_key_count; /* number of keybindings the group holds */ GeanyKeyBinding *plugin_keys; /* array of GeanyKeyBinding structs */ + GeanyKeyGroupFunc cb_func; /* use this or individual keybinding callbacks (new style) */ + gpointer cb_data; };
G_END_DECLS
-------------- This E-Mail was brought to you by github_commit_mail.py (Source: https://github.com/geany/infrastructure).