From f379cf0bf89ca369e6cea957ef20e9e6579ec230 Mon Sep 17 00:00:00 2001 From: wm4 Date: Sat, 23 Nov 2019 00:39:07 +0100 Subject: command, input: add input-bindings property Read-only information about all bindings. Somewhat hoping someone can make a nice GUI-like overlay thing for it, which provides information about mapped keys. --- DOCS/man/input.rst | 37 +++++++++++++++++++++++++++++++++++++ input/input.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ input/input.h | 2 ++ player/command.c | 19 ++++++++++++++++++- 4 files changed, 105 insertions(+), 1 deletion(-) diff --git a/DOCS/man/input.rst b/DOCS/man/input.rst index 0ef5f9bb72..3788c4fd61 100644 --- a/DOCS/man/input.rst +++ b/DOCS/man/input.rst @@ -2641,6 +2641,43 @@ Property list information, but it's a valid feature request to extend this property if needed.) +``input-bindings`` + Return list of current input key bindings. This returns an array of maps, + where each map node represents a binding for a single key/command. This map + has the following entries: + + ``key`` + The key name. This is normalized and may look slightly different from + how it was specified in the source (e.g. in input.conf). + + ``cmd`` + The command mapped to the key. (Currently, this is exactly the same + string as specified in the source. It's possible that it will be + normalized in the future.) + + ``is_weak`` + If set to true, any existing and active user bindings will take priority. + + ``owner`` + If this entry exists, the name of the script (or similar) which added + this binding. + + ``section`` + Name of the section this binding is part of. This is a rarely used + mechanism. This entry may be removed or change meaning in the future. + + ``priority`` + A number. Bindings with a higher value are preferred over bindings + with a lower value. If the value is negative, this binding is inactive + and will not be triggered by input. Note that mpv does not use this + value internally, and matching of bindings may work slightly differently + in some cases. In addition, this value is dynamic and can change around + at runtime. + + This property is read-only, and change notification is not supported. + Currently, there is no mechanism to change key bindings at runtime, other + than scripts adding or removing their own bindings. + Inconsistencies between options and properties ---------------------------------------------- diff --git a/input/input.c b/input/input.c index a9ee42338e..77e882a2f2 100644 --- a/input/input.c +++ b/input/input.c @@ -46,6 +46,7 @@ #include "mpv_talloc.h" #include "options/options.h" #include "misc/bstr.h" +#include "misc/node.h" #include "stream/stream.h" #include "common/common.h" @@ -1487,6 +1488,53 @@ void mp_input_bind_key(struct input_ctx *ictx, int key, bstr command) } } +struct mpv_node mp_input_get_bindings(struct input_ctx *ictx) +{ + input_lock(ictx); + struct mpv_node root; + node_init(&root, MPV_FORMAT_NODE_ARRAY, NULL); + + for (struct cmd_bind_section *s = ictx->cmd_bind_sections; s; s = s->next) { + int priority = -1; + + for (int i = 0; i < ictx->num_active_sections; i++) { + struct active_section *as = &ictx->active_sections[i]; + if (strcmp(as->name, s->section) == 0) { + priority = i; + break; + } + } + + for (int n = 0; n < s->num_binds; n++) { + struct cmd_bind *b = &s->binds[n]; + struct mpv_node *entry = node_array_add(&root, MPV_FORMAT_NODE_MAP); + + int b_priority = priority; + if (b->is_builtin && !ictx->opts->default_bindings) + b_priority = -1; + + // Try to fixup the weird logic so consumer of this bindings list + // does not get too confused. + if (b_priority >= 0 && !b->is_builtin) + b_priority += ictx->num_active_sections; + + node_map_add_string(entry, "section", s->section); + if (s->owner) + node_map_add_string(entry, "owner", s->owner); + node_map_add_string(entry, "cmd", b->cmd); + node_map_add_flag(entry, "is_weak", b->is_builtin); + node_map_add_int64(entry, "priority", b_priority); + + char *key = mp_input_get_key_combo_name(b->keys, b->num_keys); + node_map_add_string(entry, "key", key); + talloc_free(key); + } + } + + input_unlock(ictx); + return root; +} + struct mp_input_src_internal { pthread_t thread; bool thread_running; diff --git a/input/input.h b/input/input.h index bdbfda2dcb..df51cb7ed4 100644 --- a/input/input.h +++ b/input/input.h @@ -205,6 +205,8 @@ void mp_input_bind_key(struct input_ctx *ictx, int key, bstr command); void mp_input_set_repeat_info(struct input_ctx *ictx, int rate, int delay); +struct mpv_node mp_input_get_bindings(struct input_ctx *ictx); + void mp_input_pipe_add(struct input_ctx *ictx, const char *filename); void mp_input_sdl_gamepad_add(struct input_ctx *ictx); diff --git a/player/command.c b/player/command.c index d667eb844f..e640ba933e 100644 --- a/player/command.c +++ b/player/command.c @@ -3505,6 +3505,22 @@ static int mp_property_commands(void *ctx, struct m_property *prop, return M_PROPERTY_NOT_IMPLEMENTED; } +static int mp_property_bindings(void *ctx, struct m_property *prop, + int action, void *arg) +{ + MPContext *mpctx = ctx; + switch (action) { + case M_PROPERTY_GET_TYPE: + *(struct m_option *)arg = (struct m_option){.type = CONF_TYPE_NODE}; + return M_PROPERTY_OK; + case M_PROPERTY_GET: { + *(struct mpv_node *)arg = mp_input_get_bindings(mpctx->input); + return M_PROPERTY_OK; + } + } + return M_PROPERTY_NOT_IMPLEMENTED; +} + // Redirect a property name to another #define M_PROPERTY_ALIAS(name, real_property) \ {(name), mp_property_alias, .priv = (real_property)} @@ -3691,6 +3707,7 @@ static const struct m_property mp_properties_base[] = { {"property-list", mp_property_list}, {"profile-list", mp_profile_list}, {"command-list", mp_property_commands}, + {"input-bindings", mp_property_bindings}, {"play-dir", mp_property_play_direction}, @@ -5806,7 +5823,7 @@ static void cmd_dump_cache_ab(void *p) * command has an arbitrary number of arguments, all using the type indicated by * the last argument (they are appended to mp_cmd.args[] starting at the last * argument's index). - * Arguments have named, which can be used by named argument functions, e.g. in + * Arguments have names, which can be used by named argument functions, e.g. in * Lua with mp.command_native(). */ -- cgit v1.2.3