From b15a362ed1349fe3aa5e9ce34533002f1beac602 Mon Sep 17 00:00:00 2001 From: nanahi <130121847+na-na-hi@users.noreply.github.com> Date: Wed, 23 Oct 2024 01:30:20 -0400 Subject: [PATCH 1/7] input: deduplicate mp_input_bind_key It's just a copypaste of bind_keys with some params set to hard coded values, so use bind_keys instead. --- input/input.c | 36 ++---------------------------------- 1 file changed, 2 insertions(+), 34 deletions(-) diff --git a/input/input.c b/input/input.c index 61547a90ad600..fa08ce2baa2b9 100644 --- a/input/input.c +++ b/input/input.c @@ -1646,40 +1646,8 @@ void mp_input_run_cmd(struct input_ctx *ictx, const char **cmd) void mp_input_bind_key(struct input_ctx *ictx, int key, bstr command) { input_lock(ictx); - struct cmd_bind_section *bs = get_bind_section(ictx, (bstr){0}); - struct cmd_bind *bind = NULL; - - for (int n = 0; n < bs->num_binds; n++) { - struct cmd_bind *b = &bs->binds[n]; - if (bind_matches_key(b, 1, &key) && b->is_builtin == false) { - bind = b; - break; - } - } - - if (!bind) { - struct cmd_bind empty = {{0}}; - MP_TARRAY_APPEND(bs, bs->binds, bs->num_binds, empty); - bind = &bs->binds[bs->num_binds - 1]; - } - - bind_dealloc(bind); - - *bind = (struct cmd_bind) { - .cmd = bstrdup0(bs->binds, command), - .location = talloc_strdup(bs->binds, "keybind-command"), - .owner = bs, - .is_builtin = false, - .num_keys = 1, - }; - memcpy(bind->keys, &key, 1 * sizeof(bind->keys[0])); - if (mp_msg_test(ictx->log, MSGL_DEBUG)) { - char *s = mp_input_get_key_combo_name(&key, 1); - MP_TRACE(ictx, "add:section='%.*s' key='%s'%s cmd='%s' location='%s'\n", - BSTR_P(bind->owner->section), s, bind->is_builtin ? " builtin" : "", - bind->cmd, bind->location); - talloc_free(s); - } + bind_keys(ictx, false, (bstr){0}, &key, 1, command, + "keybind-command", NULL); input_unlock(ictx); } From 3730a8c5aeb9ffdc26a61e77cb745d05b16fb46b Mon Sep 17 00:00:00 2001 From: nanahi <130121847+na-na-hi@users.noreply.github.com> Date: Wed, 23 Oct 2024 02:20:07 -0400 Subject: [PATCH 2/7] DOCS/man/input.rst: fix keybind command keyword argument name It's "cmd" rather than "command". --- DOCS/man/input.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/DOCS/man/input.rst b/DOCS/man/input.rst index 2039a9ab217c5..adf71560510a2 100644 --- a/DOCS/man/input.rst +++ b/DOCS/man/input.rst @@ -924,10 +924,10 @@ Remember to quote string arguments in input.conf (see `Flat command syntax`_). empty string, ``KEYUP`` will be set on all keys. Otherwise, ``KEYUP`` will only be set on the key specified by ``name``. -``keybind `` - Binds a key to an input command. ``command`` must be a complete command +``keybind `` + Binds a key to an input command. ``cmd`` must be a complete command containing all the desired arguments and flags. Both ``name`` and - ``command`` use the ``input.conf`` naming scheme. This is primarily + ``cmd`` use the ``input.conf`` naming scheme. This is primarily useful for the client API. ``audio-add [ [ [<lang>]]]`` From 387621fc59df113de1d8f873aacab29b0e6dc079 Mon Sep 17 00:00:00 2001 From: nanahi <130121847+na-na-hi@users.noreply.github.com> Date: Wed, 23 Oct 2024 02:01:40 -0400 Subject: [PATCH 3/7] command: add the ability to set comment for keybind command This allows the keybind to have a comment field which can be read from input-bindings, and displayed by e.g. stats.lua. --- DOCS/man/input.rst | 7 ++++--- input/input.c | 5 +++-- input/input.h | 3 ++- player/command.c | 8 ++++++-- 4 files changed, 15 insertions(+), 8 deletions(-) diff --git a/DOCS/man/input.rst b/DOCS/man/input.rst index adf71560510a2..a38332f5bcc4c 100644 --- a/DOCS/man/input.rst +++ b/DOCS/man/input.rst @@ -924,11 +924,12 @@ Remember to quote string arguments in input.conf (see `Flat command syntax`_). empty string, ``KEYUP`` will be set on all keys. Otherwise, ``KEYUP`` will only be set on the key specified by ``name``. -``keybind <name> <cmd>`` +``keybind <name> <cmd> [<comment>]`` Binds a key to an input command. ``cmd`` must be a complete command containing all the desired arguments and flags. Both ``name`` and - ``cmd`` use the ``input.conf`` naming scheme. This is primarily - useful for the client API. + ``cmd`` use the ``input.conf`` naming scheme. ``comment`` is an optional + string which can be read as the ``comment`` entry of ``input-bindings``. + This is primarily useful for the client API. ``audio-add <url> [<flags> [<title> [<lang>]]]`` Load the given audio file. See ``sub-add`` command. diff --git a/input/input.c b/input/input.c index fa08ce2baa2b9..37e6c3e21082e 100644 --- a/input/input.c +++ b/input/input.c @@ -1643,11 +1643,12 @@ void mp_input_run_cmd(struct input_ctx *ictx, const char **cmd) input_unlock(ictx); } -void mp_input_bind_key(struct input_ctx *ictx, int key, bstr command) +void mp_input_bind_key(struct input_ctx *ictx, int key, bstr command, + const char *desc) { input_lock(ictx); bind_keys(ictx, false, (bstr){0}, &key, 1, command, - "keybind-command", NULL); + "keybind-command", desc); input_unlock(ictx); } diff --git a/input/input.h b/input/input.h index aafabdb9cb7b7..d6ba12fe8372f 100644 --- a/input/input.h +++ b/input/input.h @@ -216,7 +216,8 @@ bool mp_input_use_media_keys(struct input_ctx *ictx); void mp_input_run_cmd(struct input_ctx *ictx, const char **cmd); // Binds a command to a key. -void mp_input_bind_key(struct input_ctx *ictx, int key, bstr command); +void mp_input_bind_key(struct input_ctx *ictx, int key, bstr command, + const char *desc); void mp_input_set_repeat_info(struct input_ctx *ictx, int rate, int delay); diff --git a/player/command.c b/player/command.c index 4a52b4fead0ff..8e24b2f5fb6df 100644 --- a/player/command.c +++ b/player/command.c @@ -6633,7 +6633,10 @@ static void cmd_key_bind(void *p) return; } const char *target_cmd = cmd->args[1].v.s; - mp_input_bind_key(mpctx->input, code, bstr0(target_cmd)); + const char *comment = cmd->args[2].v.s; + if (comment && !*comment) + comment = NULL; + mp_input_bind_key(mpctx->input, code, bstr0(target_cmd), comment); } static void cmd_apply_profile(void *p) @@ -7244,7 +7247,8 @@ const struct mp_cmd_def mp_cmds[] = { {"single", 0}, {"double", 1}), .flags = MP_CMD_OPT_ARG}}}, { "keybind", cmd_key_bind, { {"name", OPT_STRING(v.s)}, - {"cmd", OPT_STRING(v.s)} }}, + {"cmd", OPT_STRING(v.s)}, + {"comment", OPT_STRING(v.s), .flags = MP_CMD_OPT_ARG} }}, { "keypress", cmd_key, { {"name", OPT_STRING(v.s)}, {"scale", OPT_DOUBLE(v.d), OPTDEF_DOUBLE(1)} }, .priv = &(const int){0}}, From 7554c609dd17afd5148439def253e176e4b20830 Mon Sep 17 00:00:00 2001 From: nanahi <130121847+na-na-hi@users.noreply.github.com> Date: Wed, 23 Oct 2024 03:17:32 -0400 Subject: [PATCH 4/7] command: fix keybind command with sequence keys The command is documented to use the same syntax as input.conf, but it doesn't work with sequence keys because it uses mp_input_get_key_from_name for checking key names, when it should use mp_input_get_keys_from_string instead. Fix this by using the correct function. --- input/input.c | 14 ++++++++++++-- input/input.h | 4 ++-- player/command.c | 12 +++++------- 3 files changed, 19 insertions(+), 11 deletions(-) diff --git a/input/input.c b/input/input.c index 37e6c3e21082e..203c333c963cc 100644 --- a/input/input.c +++ b/input/input.c @@ -1643,13 +1643,23 @@ void mp_input_run_cmd(struct input_ctx *ictx, const char **cmd) input_unlock(ictx); } -void mp_input_bind_key(struct input_ctx *ictx, int key, bstr command, +bool mp_input_bind_key(struct input_ctx *ictx, const char *key, bstr command, const char *desc) { + char *name = talloc_strdup(NULL, key); + int keys[MP_MAX_KEY_DOWN]; + int num_keys = 0; + if (!mp_input_get_keys_from_string(name, MP_MAX_KEY_DOWN, &num_keys, keys)) { + talloc_free(name); + return false; + } + talloc_free(name); + input_lock(ictx); - bind_keys(ictx, false, (bstr){0}, &key, 1, command, + bind_keys(ictx, false, (bstr){0}, keys, num_keys, command, "keybind-command", desc); input_unlock(ictx); + return true; } struct mpv_node mp_input_get_bindings(struct input_ctx *ictx) diff --git a/input/input.h b/input/input.h index d6ba12fe8372f..8c5b85e117abf 100644 --- a/input/input.h +++ b/input/input.h @@ -215,8 +215,8 @@ bool mp_input_use_media_keys(struct input_ctx *ictx); // Like mp_input_parse_cmd_strv, but also run the command. void mp_input_run_cmd(struct input_ctx *ictx, const char **cmd); -// Binds a command to a key. -void mp_input_bind_key(struct input_ctx *ictx, int key, bstr command, +// Binds a command to a key. Returns true if the bind is successful. +bool mp_input_bind_key(struct input_ctx *ictx, const char *key, bstr command, const char *desc); void mp_input_set_repeat_info(struct input_ctx *ictx, int rate, int delay); diff --git a/player/command.c b/player/command.c index 8e24b2f5fb6df..3a59da0dbd937 100644 --- a/player/command.c +++ b/player/command.c @@ -6626,17 +6626,15 @@ static void cmd_key_bind(void *p) struct mp_cmd_ctx *cmd = p; struct MPContext *mpctx = cmd->mpctx; - int code = mp_input_get_key_from_name(cmd->args[0].v.s); - if (code < 0) { - MP_ERR(mpctx, "%s is not a valid input name.\n", cmd->args[0].v.s); - cmd->success = false; - return; - } + const char *key = cmd->args[0].v.s; const char *target_cmd = cmd->args[1].v.s; const char *comment = cmd->args[2].v.s; if (comment && !*comment) comment = NULL; - mp_input_bind_key(mpctx->input, code, bstr0(target_cmd), comment); + if (!mp_input_bind_key(mpctx->input, key, bstr0(target_cmd), comment)) { + MP_ERR(mpctx, "%s is not a valid input name.\n", key); + cmd->success = false; + } } static void cmd_apply_profile(void *p) From d4d1d40e21ad70a505bebb37e6de741234c65061 Mon Sep 17 00:00:00 2001 From: nanahi <130121847+na-na-hi@users.noreply.github.com> Date: Wed, 23 Oct 2024 03:21:51 -0400 Subject: [PATCH 5/7] input: fix style --- input/input.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/input/input.c b/input/input.c index 203c333c963cc..60b43e2032e35 100644 --- a/input/input.c +++ b/input/input.c @@ -1427,8 +1427,7 @@ static int parse_config(struct input_ctx *ictx, bool builtin, bstr data, char *name = bstrdup0(NULL, keyname); int keys[MP_MAX_KEY_DOWN]; int num_keys = 0; - if (!mp_input_get_keys_from_string(name, MP_MAX_KEY_DOWN, &num_keys, keys)) - { + if (!mp_input_get_keys_from_string(name, MP_MAX_KEY_DOWN, &num_keys, keys)) { talloc_free(name); MP_ERR(ictx, "Unknown key '%.*s' at %s\n", BSTR_P(keyname), cur_loc); continue; From 0ab46cd223eb80037b324282c5e7e831ed4f4f15 Mon Sep 17 00:00:00 2001 From: nanahi <130121847+na-na-hi@users.noreply.github.com> Date: Fri, 1 Nov 2024 12:49:46 -0400 Subject: [PATCH 6/7] command: use array index for checking first character --- player/command.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/player/command.c b/player/command.c index 3a59da0dbd937..1d31ca1e42a38 100644 --- a/player/command.c +++ b/player/command.c @@ -6549,7 +6549,7 @@ static void cmd_delete_watch_later_config(void *p) struct MPContext *mpctx = cmd->mpctx; char *filename = cmd->args[0].v.s; - if (filename && !*filename) + if (filename && !filename[0]) filename = NULL; mp_delete_watch_later_conf(mpctx, filename); } @@ -6629,7 +6629,7 @@ static void cmd_key_bind(void *p) const char *key = cmd->args[0].v.s; const char *target_cmd = cmd->args[1].v.s; const char *comment = cmd->args[2].v.s; - if (comment && !*comment) + if (comment && !comment[0]) comment = NULL; if (!mp_input_bind_key(mpctx->input, key, bstr0(target_cmd), comment)) { MP_ERR(mpctx, "%s is not a valid input name.\n", key); From 1b85ef2ff55999ce1cfd348e65991c7f3fd9e8f2 Mon Sep 17 00:00:00 2001 From: nanahi <130121847+na-na-hi@users.noreply.github.com> Date: Fri, 1 Nov 2024 12:51:11 -0400 Subject: [PATCH 7/7] command: quote input key names in log --- player/command.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/player/command.c b/player/command.c index 1d31ca1e42a38..de15e04f8419f 100644 --- a/player/command.c +++ b/player/command.c @@ -6612,7 +6612,7 @@ static void cmd_key(void *p) } else { int code = mp_input_get_key_from_name(key_name); if (code < 0) { - MP_ERR(mpctx, "%s is not a valid input name.\n", key_name); + MP_ERR(mpctx, "'%s' is not a valid input name.\n", key_name); cmd->success = false; return; } @@ -6632,7 +6632,7 @@ static void cmd_key_bind(void *p) if (comment && !comment[0]) comment = NULL; if (!mp_input_bind_key(mpctx->input, key, bstr0(target_cmd), comment)) { - MP_ERR(mpctx, "%s is not a valid input name.\n", key); + MP_ERR(mpctx, "'%s' is not a valid input name.\n", key); cmd->success = false; } }