summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2013-06-19 18:19:45 +0200
committerwm4 <wm4@nowhere>2013-06-29 22:58:13 +0200
commit831a7cf3eea1015a76f4accba4f4d237a5336f7b (patch)
tree2f7206e2243936b7e030a81c80e99042575199b3
parentfc422f5aebbfe6dd2ea12b92fe9b13ba5fd65041 (diff)
downloadmpv-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.
-rw-r--r--core/input/input.c62
-rw-r--r--core/input/input.h1
-rw-r--r--core/input/keycodes.h1
-rw-r--r--etc/input.conf1
-rw-r--r--video/out/x11_common.c7
5 files changed, 58 insertions, 14 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;
diff --git a/core/input/input.h b/core/input/input.h
index 551ba80db6..071efe5def 100644
--- a/core/input/input.h
+++ b/core/input/input.h
@@ -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;
diff --git a/core/input/keycodes.h b/core/input/keycodes.h
index b086d82809..80e2561514 100644
--- a/core/input/keycodes.h
+++ b/core/input/keycodes.h
@@ -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) \
diff --git a/etc/input.conf b/etc/input.conf
index d2a39aca30..91382d58a5 100644
--- a/etc/input.conf
+++ b/etc/input.conf
@@ -176,6 +176,7 @@ JOY_BTN3 add volume -1
# Mostly for internal purposes
MOUSE_MOVE ignore
+MOUSE_LEAVE ignore
#
# Not assigned by default
diff --git a/video/out/x11_common.c b/video/out/x11_common.c
index 9d2db30924..bbb6fca997 100644
--- a/video/out/x11_common.c
+++ b/video/out/x11_common.c
@@ -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);
}