diff options
author | wm4 <wm4@nowhere> | 2013-06-19 18:19:45 +0200 |
---|---|---|
committer | wm4 <wm4@nowhere> | 2013-06-29 22:58:13 +0200 |
commit | 831a7cf3eea1015a76f4accba4f4d237a5336f7b (patch) | |
tree | 2f7206e2243936b7e030a81c80e99042575199b3 /core/input/input.c | |
parent | fc422f5aebbfe6dd2ea12b92fe9b13ba5fd65041 (diff) | |
download | mpv-831a7cf3eea1015a76f4accba4f4d237a5336f7b.tar.bz2 mpv-831a7cf3eea1015a76f4accba4f4d237a5336f7b.tar.xz |
input: trigger mouse_leave key bindings if mouse leaves mouse area
Also, implement mouse leave events for X11. But evne on other
platforms, these events will be generated if mouse crosses a section's
mouse area boundaries within the mpv window.
Diffstat (limited to 'core/input/input.c')
-rw-r--r-- | core/input/input.c | 62 |
1 files changed, 50 insertions, 12 deletions
diff --git a/core/input/input.c b/core/input/input.c index 5b9a31866c..ba35efd0e6 100644 --- a/core/input/input.c +++ b/core/input/input.c @@ -438,8 +438,9 @@ static const struct key_name key_names[] = { { MP_KEY_PREV, "XF86_PREV" }, { MP_KEY_NEXT, "XF86_NEXT" }, - { MP_KEY_CLOSE_WIN, "CLOSE_WIN" }, - { MP_KEY_MOUSE_MOVE, "MOUSE_MOVE" }, + { MP_KEY_CLOSE_WIN, "CLOSE_WIN" }, + { MP_KEY_MOUSE_MOVE, "MOUSE_MOVE" }, + { MP_KEY_MOUSE_LEAVE, "MOUSE_LEAVE" }, { 0, NULL } }; @@ -517,6 +518,7 @@ struct input_ctx { // Mouse position on the consumer side (as command.c sees it) int mouse_x, mouse_y; + char *mouse_section; // last section to receive mouse event // Mouse position on the producer side (as the VO sees it) // Unlike mouse_x/y, this can be used to resolve mouse click bindings. @@ -1202,8 +1204,21 @@ static struct cmd_bind_section *get_bind_section(struct input_ctx *ictx, } static struct cmd_bind *find_any_bind_for_key(struct input_ctx *ictx, + char *force_section, int n, int *keys) { + if (force_section) { + for (int b = 0; b < 2; b++) { + bool builtin = !!b; + struct cmd_bind_section *bs = get_bind_section(ictx, builtin, + bstr0(force_section)); + struct cmd_bind *cmd = find_bind_for_key(bs->cmd_binds, n, keys); + if (cmd) + return cmd; + } + return NULL; + } + for (int i = ictx->num_active_sections - 1; i >= 0; i--) { struct active_section *as = &ictx->active_sections[i]; bstr name = bstr0(as->name); @@ -1226,19 +1241,21 @@ static struct cmd_bind *find_any_bind_for_key(struct input_ctx *ictx, if (as->flags & MP_INPUT_EXCLUSIVE) break; } + return NULL; } -static mp_cmd_t *get_cmd_from_keys(struct input_ctx *ictx, int n, int *keys) +static mp_cmd_t *get_cmd_from_keys(struct input_ctx *ictx, char *force_section, + int n, int *keys) { if (ictx->test) return handle_test(ictx, n, keys); - struct cmd_bind *cmd = find_any_bind_for_key(ictx, n, keys); + struct cmd_bind *cmd = find_any_bind_for_key(ictx, force_section, n, keys); if (cmd == NULL && n > 1) { // Hitting two keys at once, and if there's no binding for this // combination, the key hit last should be checked. - cmd = find_any_bind_for_key(ictx, 1, (int[]){keys[n - 1]}); + cmd = find_any_bind_for_key(ictx, force_section, 1, (int[]){keys[n - 1]}); } if (cmd == NULL) { @@ -1249,7 +1266,9 @@ static mp_cmd_t *get_cmd_from_keys(struct input_ctx *ictx, int n, int *keys) return NULL; } mp_cmd_t *ret = mp_input_parse_cmd(bstr0(cmd->cmd), cmd->location); - if (!ret) { + if (ret) { + ret->input_section = cmd->owner->section; + } else { char *key_buf = get_key_combo_name(keys, n); mp_tmsg(MSGT_INPUT, MSGL_ERR, "Invalid command for bound key '%s': '%s'\n", key_buf, cmd->cmd); @@ -1276,9 +1295,6 @@ static mp_cmd_t *interpret_key(struct input_ctx *ictx, int code) unsigned int j; mp_cmd_t *ret; - if (code == MP_KEY_MOUSE_MOVE) - return get_cmd_from_keys(ictx, 1, (int[]){code}); - /* On normal keyboards shift changes the character code of non-special * keys, so don't count the modifier separately for those. In other words * we want to have "a" and "A" instead of "a" and "Shift+A"; but a separate @@ -1307,7 +1323,7 @@ static mp_cmd_t *interpret_key(struct input_ctx *ictx, int code) ictx->num_key_down++; ictx->last_key_down = mp_time_us(); ictx->ar_state = 0; - ictx->current_down_cmd = get_cmd_from_keys(ictx, ictx->num_key_down, + ictx->current_down_cmd = get_cmd_from_keys(ictx, NULL, ictx->num_key_down, ictx->key_down); if (ictx->current_down_cmd && (code & MP_KEY_EMIT_ON_UP)) ictx->current_down_cmd->key_up_follows = true; @@ -1344,7 +1360,7 @@ static mp_cmd_t *interpret_key(struct input_ctx *ictx, int code) // Interpret only maximal point of multibutton event ret = NULL; if (emit_key) - ret = get_cmd_from_keys(ictx, ictx->num_key_down, ictx->key_down); + ret = get_cmd_from_keys(ictx, NULL, ictx->num_key_down, ictx->key_down); if (doubleclick) { ictx->key_down[j] = code - MP_MOUSE_BTN0_DBL + MP_MOUSE_BTN0; return ret; @@ -1435,12 +1451,34 @@ void mp_input_feed_key(struct input_ctx *ictx, int code) add_key_cmd(ictx, cmd); } +static void trigger_mouse_leave(struct input_ctx *ictx, char *new_section) +{ + if (!new_section) + new_section = "default"; + + char *old = ictx->mouse_section; + ictx->mouse_section = new_section; + + if (old && strcmp(old, ictx->mouse_section) != 0) { + struct mp_cmd *cmd = + get_cmd_from_keys(ictx, old, 1, (int[]){MP_KEY_MOUSE_LEAVE}); + if (cmd) + add_key_cmd(ictx, cmd); + } +} + + void mp_input_set_mouse_pos(struct input_ctx *ictx, int x, int y) { ictx->mouse_event_counter++; ictx->mouse_vo_x = x; ictx->mouse_vo_y = y; - struct mp_cmd *cmd = interpret_key(ictx, MP_KEY_MOUSE_MOVE); + + struct mp_cmd *cmd = + get_cmd_from_keys(ictx, NULL, 1, (int[]){MP_KEY_MOUSE_MOVE}); + + trigger_mouse_leave(ictx, cmd ? cmd->input_section : NULL); + if (!cmd) return; cmd->mouse_move = true; |