diff options
-rw-r--r-- | input/cmd_parse.c | 3 | ||||
-rw-r--r-- | input/input.c | 2 | ||||
-rw-r--r-- | input/input.h | 1 | ||||
-rw-r--r-- | player/command.c | 54 |
4 files changed, 43 insertions, 17 deletions
diff --git a/input/cmd_parse.c b/input/cmd_parse.c index b0c6c50753..0af9665cf0 100644 --- a/input/cmd_parse.c +++ b/input/cmd_parse.c @@ -140,7 +140,7 @@ struct mp_cmd *mp_input_parse_cmd_node(struct mp_log *log, mpv_node *node) { struct mp_cmd *cmd = talloc_ptrtype(NULL, cmd); talloc_set_destructor(cmd, destroy_cmd); - *cmd = (struct mp_cmd) { .scale = 1, }; + *cmd = (struct mp_cmd) { .scale = 1, .scale_units = 1 }; if (node->format != MPV_FORMAT_NODE_ARRAY) goto error; @@ -254,6 +254,7 @@ static struct mp_cmd *parse_cmd_str(struct mp_log *log, void *tmp, *cmd = (struct mp_cmd) { .flags = MP_ON_OSD_AUTO | MP_EXPAND_PROPERTIES, .scale = 1, + .scale_units = 1, }; ctx->str = bstr_lstrip(ctx->str); diff --git a/input/input.c b/input/input.c index 04b61cf3b4..c859e5e3db 100644 --- a/input/input.c +++ b/input/input.c @@ -618,11 +618,13 @@ static void interpret_key(struct input_ctx *ictx, int code, double scale, if (mp_input_is_scalable_cmd(cmd)) { cmd->scale = scale; + cmd->scale_units = scale_units; mp_input_queue_cmd(ictx, cmd); } else { // Non-scalable commands won't understand cmd->scale, so synthesize // multiple commands with cmd->scale = 1 cmd->scale = 1; + cmd->scale_units = 1; // Avoid spamming the player with too many commands scale_units = FFMIN(scale_units, 20); for (int i = 0; i < scale_units - 1; i++) diff --git a/input/input.h b/input/input.h index dfc14078f3..c2933e8bd3 100644 --- a/input/input.h +++ b/input/input.h @@ -85,6 +85,7 @@ typedef struct mp_cmd { int mouse_x, mouse_y; struct mp_cmd *queue_next; double scale; // for scaling numeric arguments + int scale_units; const struct mp_cmd_def *def; char *sender; // name of the client API user which sent this char *key_name; // string representation of the key binding diff --git a/player/command.c b/player/command.c index ad871e34b3..a65a187dd7 100644 --- a/player/command.c +++ b/player/command.c @@ -4783,6 +4783,20 @@ static bool check_property_autorepeat(char *property, struct MPContext *mpctx) return true; } +// Whether changes to this property (add/cycle cmds) benefit from cmd->scale +static bool check_property_scalable(char *property, struct MPContext *mpctx) +{ + struct m_option prop = {0}; + if (mp_property_do(property, M_PROPERTY_GET_TYPE, &prop, mpctx) <= 0) + return true; + + // These properties are backed by a floating-point number + return prop.type == &m_option_type_float || + prop.type == &m_option_type_double || + prop.type == &m_option_type_time || + prop.type == &m_option_type_aspect; +} + static struct mpv_node *add_map_entry(struct mpv_node *dst, const char *key) { struct mpv_node_list *list = dst->u.list; @@ -4925,27 +4939,35 @@ int run_command(struct MPContext *mpctx, struct mp_cmd *cmd, struct mpv_node *re case MP_CMD_CYCLE: { char *property = cmd->args[0].v.s; - struct m_property_switch_arg s = { - .inc = cmd->args[1].v.d * cmd->scale, - .wrap = cmd->id == MP_CMD_CYCLE, - }; if (cmd->repeated && !check_property_autorepeat(property, mpctx)) { MP_VERBOSE(mpctx, "Dropping command '%.*s' from auto-repeated key.\n", BSTR_P(cmd->original)); break; } - int r = mp_property_do(property, M_PROPERTY_SWITCH, &s, mpctx); - if (r == M_PROPERTY_OK || r == M_PROPERTY_UNAVAILABLE) { - show_property_osd(mpctx, property, on_osd); - } else if (r == M_PROPERTY_UNKNOWN) { - set_osd_msg(mpctx, osdl, osd_duration, - "Unknown property: '%s'", property); - return -1; - } else if (r <= 0) { - set_osd_msg(mpctx, osdl, osd_duration, - "Failed to increment property '%s' by %g", - property, s.inc); - return -1; + double scale = 1; + int scale_units = cmd->scale_units; + if (check_property_scalable(property, mpctx)) { + scale = cmd->scale; + scale_units = 1; + } + for (int i = 0; i < scale_units; i++) { + struct m_property_switch_arg s = { + .inc = cmd->args[1].v.d * scale, + .wrap = cmd->id == MP_CMD_CYCLE, + }; + int r = mp_property_do(property, M_PROPERTY_SWITCH, &s, mpctx); + if (r == M_PROPERTY_OK || r == M_PROPERTY_UNAVAILABLE) { + show_property_osd(mpctx, property, on_osd); + } else if (r == M_PROPERTY_UNKNOWN) { + set_osd_msg(mpctx, osdl, osd_duration, + "Unknown property: '%s'", property); + return -1; + } else if (r <= 0) { + set_osd_msg(mpctx, osdl, osd_duration, + "Failed to increment property '%s' by %g", + property, s.inc); + return -1; + } } break; } |