summaryrefslogtreecommitdiffstats
path: root/video
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2013-08-31 21:21:05 +0200
committerwm4 <wm4@nowhere>2013-09-01 20:17:51 +0200
commit0c7978cf9caa81d1e6ef7e32458a5ff1834fa004 (patch)
tree3378c6b2eea9c11485b18ac4593eec46eeccf7e7 /video
parent11d2f723d50307d88f7f828d8c6ff389ef76bf33 (diff)
downloadmpv-0c7978cf9caa81d1e6ef7e32458a5ff1834fa004.tar.bz2
mpv-0c7978cf9caa81d1e6ef7e32458a5ff1834fa004.tar.xz
input: deal with spurious X11 LeaveNotify events
If the mpv window is unfocus, clicking on the OSC should focus the window (done by the window manager) and allow interaction with the OSC. But somehow X sends a spurious LeaveNotify event, immediately followed by an EnterNotify event. This happens at least with IceWM. The result is that the OSC will disappear (due to receiving MOUSE_LEAVE). The OSC will stay invisible, because EnterNotify isn't handled, and there's nothing that could make the OSC appear again. Solve this by handling EnterNotify. We cause a redundant MOUSE_MOVE event to be sent, which triggers the code to make the OSC visible. We have to remove the code from input.c, which ignores redundant mouse move events. Since the code ignoring redundant mouse move events is still needed on Windows, move that code to w32_common.c. The need for this is documented in the code, also see commit 03fd2fe. (The original idea was to save some code by having this code in the core, but now it turns out that this didn't quite work out.)
Diffstat (limited to 'video')
-rw-r--r--video/out/w32_common.c16
-rw-r--r--video/out/w32_common.h3
-rw-r--r--video/out/x11_common.c6
3 files changed, 21 insertions, 4 deletions
diff --git a/video/out/w32_common.c b/video/out/w32_common.c
index b06f1e0aa3..78ea91fa1b 100644
--- a/video/out/w32_common.c
+++ b/video/out/w32_common.c
@@ -231,11 +231,21 @@ static LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam,
w32->tracking = FALSE;
mp_input_put_key(vo->input_ctx, MP_KEY_MOUSE_LEAVE);
break;
- case WM_MOUSEMOVE:
+ case WM_MOUSEMOVE: {
if (!w32->tracking)
- w32->tracking = TrackMouseEvent(&w32->trackEvent);;
- vo_mouse_movement(vo, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
+ w32->tracking = TrackMouseEvent(&w32->trackEvent);
+ // Windows can send spurious mouse events, which would make the mpv
+ // core unhide the mouse cursor on completely unrelated events. See:
+ // https://blogs.msdn.com/b/oldnewthing/archive/2003/10/01/55108.aspx
+ int x = GET_X_LPARAM(lParam);
+ int y = GET_Y_LPARAM(lParam);
+ if (x != w32->mouse_x || y != w32->mouse_y) {
+ w32->mouse_x = x;
+ w32->mouse_y = y;
+ vo_mouse_movement(vo, x, y);
+ }
break;
+ }
case WM_LBUTTONDOWN:
mouse_button = MP_MOUSE_BTN0 | MP_KEY_STATE_DOWN;
break;
diff --git a/video/out/w32_common.h b/video/out/w32_common.h
index 26b21e34ad..b8486b538a 100644
--- a/video/out/w32_common.h
+++ b/video/out/w32_common.h
@@ -52,6 +52,9 @@ struct vo_w32_state {
BOOL tracking;
TRACKMOUSEEVENT trackEvent;
+
+ int mouse_x;
+ int mouse_y;
};
struct vo;
diff --git a/video/out/x11_common.c b/video/out/x11_common.c
index 83bfe3946d..00c0f7625d 100644
--- a/video/out/x11_common.c
+++ b/video/out/x11_common.c
@@ -769,6 +769,9 @@ int vo_x11_check_events(struct vo *vo)
case MotionNotify:
vo_mouse_movement(vo, Event.xmotion.x, Event.xmotion.y);
break;
+ case EnterNotify:
+ vo_mouse_movement(vo, Event.xcrossing.x, Event.xcrossing.y);
+ break;
case LeaveNotify:
mp_input_put_key(vo->input_ctx, MP_KEY_MOUSE_LEAVE);
break;
@@ -1007,7 +1010,8 @@ static void vo_x11_map_window(struct vo *vo, int x, int y, int w, int h)
StructureNotifyMask | ExposureMask |
KeyPressMask | KeyReleaseMask |
ButtonPressMask | ButtonReleaseMask |
- PointerMotionMask | LeaveWindowMask);
+ PointerMotionMask | EnterWindowMask |
+ LeaveWindowMask);
XMapWindow(x11->display, x11->window);
vo_x11_clearwindow(vo, x11->window);
}