summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--input/cmd_parse.c3
-rw-r--r--input/input.c2
-rw-r--r--input/input.h1
-rw-r--r--player/command.c54
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;
}