mirror of
https://github.com/mpv-player/mpv
synced 2025-03-11 08:37:59 +00:00
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.
This commit is contained in:
parent
fc422f5aeb
commit
831a7cf3ee
@ -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;
|
||||
|
@ -138,6 +138,7 @@ typedef struct mp_cmd {
|
||||
bool raw_args;
|
||||
enum mp_on_osd on_osd;
|
||||
bstr original;
|
||||
char *input_section;
|
||||
bool key_up_follows;
|
||||
bool mouse_move;
|
||||
int mouse_x, mouse_y;
|
||||
|
@ -206,6 +206,7 @@
|
||||
#define MP_KEY_CLOSE_WIN (MP_KEY_INTERN+0)
|
||||
// Generated by input.c (VOs use mp_input_set_mouse_pos())
|
||||
#define MP_KEY_MOUSE_MOVE ((MP_KEY_INTERN+1)|MP_NO_REPEAT_KEY)
|
||||
#define MP_KEY_MOUSE_LEAVE ((MP_KEY_INTERN+2)|MP_NO_REPEAT_KEY)
|
||||
|
||||
|
||||
#define MP_KEY_DEPENDS_ON_MOUSE_POS(code) \
|
||||
|
@ -176,6 +176,7 @@ JOY_BTN3 add volume -1
|
||||
|
||||
# Mostly for internal purposes
|
||||
MOUSE_MOVE ignore
|
||||
MOUSE_LEAVE ignore
|
||||
|
||||
#
|
||||
# Not assigned by default
|
||||
|
@ -756,6 +756,9 @@ int vo_x11_check_events(struct vo *vo)
|
||||
case MotionNotify:
|
||||
vo_mouse_movement(vo, Event.xmotion.x, Event.xmotion.y);
|
||||
break;
|
||||
case LeaveNotify:
|
||||
mplayer_put_key(vo->key_fifo, MP_KEY_MOUSE_LEAVE);
|
||||
break;
|
||||
case ButtonPress:
|
||||
mplayer_put_key(vo->key_fifo,
|
||||
(MP_MOUSE_BTN0 + Event.xbutton.button - 1)
|
||||
@ -987,10 +990,10 @@ static void vo_x11_map_window(struct vo *vo, int x, int y, int w, int h)
|
||||
vo_x11_decoration(vo, 0);
|
||||
// map window
|
||||
vo_x11_selectinput_witherr(vo, x11->display, x11->window,
|
||||
StructureNotifyMask |
|
||||
StructureNotifyMask | ExposureMask |
|
||||
KeyPressMask | KeyReleaseMask |
|
||||
ButtonPressMask | ButtonReleaseMask |
|
||||
PointerMotionMask | ExposureMask);
|
||||
PointerMotionMask | LeaveWindowMask);
|
||||
XMapWindow(x11->display, x11->window);
|
||||
vo_x11_clearwindow(vo, x11->window);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user