summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2013-12-01 17:59:20 +0100
committerwm4 <wm4@nowhere>2013-12-01 18:05:08 +0100
commit1136a8b6acf65c6345d8a25dbc56e9228d14e11a (patch)
tree4cab267bfdb86ba0fb223ef0509206be16b0a71e
parent071ae5613f4bbbc41f0780505bc30ef3611cad38 (diff)
downloadmpv-1136a8b6acf65c6345d8a25dbc56e9228d14e11a.tar.bz2
mpv-1136a8b6acf65c6345d8a25dbc56e9228d14e11a.tar.xz
input: don't emit command when using multiple mouse buttons at once
This is for key bindings that use multiple mouse buttons at once. (Yes, this is weird, but MPlayer always had this feature, and apparently there are people using it!) Before this commit, clicking another mouse button while still holding the previous mouse button forced the command bound to the previous mouse button to be emitted. This is usually needed to make sure the input consumer (the player and the OSC) stays in sync with the actual mouse button state. If there's no command sent, the OSC in particular would think the button is still held down. However, sending the command is undesired behavior if you want to use these multiple-key binds. Solve this by emitting commands in this situation only if a key down command was sent earlier. Since mouse button key bindings are normally executed on key-up only, this happens with special commands like script_dispatch only (used by the OSD to track mouse buttons, but also used for other OSC bindings). See github issue #390.
-rw-r--r--mpvcore/input/input.c26
1 files changed, 21 insertions, 5 deletions
diff --git a/mpvcore/input/input.c b/mpvcore/input/input.c
index b93b6521d8..c1711a94d8 100644
--- a/mpvcore/input/input.c
+++ b/mpvcore/input/input.c
@@ -568,6 +568,7 @@ struct input_ctx {
int key_down[MP_MAX_KEY_DOWN];
unsigned int num_key_down;
int64_t last_key_down;
+ bool current_down_cmd_need_release;
struct mp_cmd *current_down_cmd;
int doubleclick_time;
@@ -1450,9 +1451,20 @@ static void update_mouse_section(struct input_ctx *ictx)
}
}
-static void release_down_cmd(struct input_ctx *ictx)
+// Called when the currently held-down key is released. This (usually) sends
+// the a key-up versiob of the command associated with the keys that were held
+// down.
+// If the drop_current parameter is set to true, then don't send the key-up
+// command. Unless we've already sent a key-down event, in which case the
+// input receiver (the player) must get a key-up event, or it would get stuck
+// thinking a key is still held down.
+static void release_down_cmd(struct input_ctx *ictx, bool drop_current)
{
- if (ictx->current_down_cmd && ictx->current_down_cmd->key_up_follows) {
+ if (ictx->current_down_cmd_need_release)
+ drop_current = false;
+ if (!drop_current && ictx->current_down_cmd &&
+ ictx->current_down_cmd->key_up_follows)
+ {
ictx->current_down_cmd->key_up_follows = false;
queue_add_tail(&ictx->cmd_queue, ictx->current_down_cmd);
ictx->got_new_events = true;
@@ -1460,6 +1472,7 @@ static void release_down_cmd(struct input_ctx *ictx)
talloc_free(ictx->current_down_cmd);
}
ictx->current_down_cmd = NULL;
+ ictx->current_down_cmd_need_release = false;
ictx->last_key_down = 0;
ictx->ar_state = -1;
}
@@ -1542,7 +1555,7 @@ static void interpret_key(struct input_ctx *ictx, int code, double scale)
if (key_was_down)
return;
// Cancel current down-event (there can be only one)
- release_down_cmd(ictx);
+ release_down_cmd(ictx, true);
ictx->key_down[ictx->num_key_down] = code & ~MP_KEY_STATE_DOWN;
ictx->num_key_down++;
update_mouse_section(ictx);
@@ -1557,10 +1570,11 @@ static void interpret_key(struct input_ctx *ictx, int code, double scale)
if (cmd && (code & MP_KEY_EMIT_ON_UP))
cmd->key_up_follows = true;
ictx->current_down_cmd = mp_cmd_clone(cmd);
+ ictx->current_down_cmd_need_release = false;
} else if (code & MP_KEY_STATE_UP) {
if (key_was_down) {
remove_key_down(ictx, code);
- release_down_cmd(ictx);
+ release_down_cmd(ictx, false);
}
update_mouse_section(ictx);
} else {
@@ -1605,6 +1619,8 @@ static void interpret_key(struct input_ctx *ictx, int code, double scale)
cmd->scale = scale;
+ if (cmd->key_up_follows)
+ ictx->current_down_cmd_need_release = true;
queue_add_tail(&ictx->cmd_queue, cmd);
}
@@ -1613,7 +1629,7 @@ static void mp_input_feed_key(struct input_ctx *ictx, int code, double scale)
if (code == MP_INPUT_RELEASE_ALL) {
MP_DBG(ictx, "release all\n");
ictx->num_key_down = 0;
- release_down_cmd(ictx);
+ release_down_cmd(ictx, false);
update_mouse_section(ictx);
return;
}