0
0
mirror of https://github.com/mpv-player/mpv.git synced 2024-09-20 03:52:22 +02:00

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.
This commit is contained in:
wm4 2019-11-23 00:39:07 +01:00
parent 251069d9ea
commit f379cf0bf8
4 changed files with 105 additions and 1 deletions

View File

@ -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
----------------------------------------------

View File

@ -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;

View File

@ -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);

View File

@ -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().
*/