diff options
author | wm4 <wm4@nowhere> | 2014-03-18 20:38:23 +0100 |
---|---|---|
committer | wm4 <wm4@nowhere> | 2014-03-18 20:43:45 +0100 |
commit | 19f101db680f966a6e56035a16784541be390982 (patch) | |
tree | 28cbf61aa9d0c2ec05f141c79022cc90a5883ec5 /video | |
parent | 4751fe408be9c1278149e234f45570b70f4a57ce (diff) | |
download | mpv-19f101db680f966a6e56035a16784541be390982.tar.bz2 mpv-19f101db680f966a6e56035a16784541be390982.tar.xz |
x11: implement window dragging by grabbing
We don't check whether the WM supports _NET_WM_MOVERESIZE_MOVE, but
if it doesn't, nothing bad happens. There might be a race condition
when pressing a button, and then moving the mouse and releasing the
button at the same time; then the WM might get the message to initiate
moving the window after the mouse button has been released, in which
case the result will probably be annoying. This could possibly be fixed
by sending _NET_WM_MOVERESIZE_CANCEL on button release, but on the
other hand, we probably won't receive a button release event in this
situation, so ignore this problem.
The dragging is initiated only when moving the mouse pointer after a
click in order to reduce annoying behavior when the user is e.g.
doubleclicking.
Closes #608.
Diffstat (limited to 'video')
-rw-r--r-- | video/out/x11_common.c | 34 | ||||
-rw-r--r-- | video/out/x11_common.h | 4 |
2 files changed, 37 insertions, 1 deletions
diff --git a/video/out/x11_common.c b/video/out/x11_common.c index ebe0c40f4a..d92ffcdea4 100644 --- a/video/out/x11_common.c +++ b/video/out/x11_common.c @@ -405,6 +405,7 @@ static void init_atoms(struct vo_x11_state *x11) XA_INIT(_NET_WM_NAME); XA_INIT(_NET_WM_ICON_NAME); XA_INIT(_NET_WM_ICON); + XA_INIT(_NET_WM_MOVERESIZE); XA_INIT(_WIN_PROTOCOLS); XA_INIT(_WIN_LAYER); XA_INIT(_WIN_HINTS); @@ -940,20 +941,51 @@ int vo_x11_check_events(struct vo *vo) { if (x11->no_autorepeat) mp_input_put_key(vo->input_ctx, MP_INPUT_RELEASE_ALL); + x11->win_drag_button1_down = false; break; } case MotionNotify: - vo_mouse_movement(vo, Event.xmotion.x, Event.xmotion.y); + if (x11->win_drag_button1_down && !x11->fs && + !mp_input_test_dragging(vo->input_ctx, Event.xmotion.x, + Event.xmotion.y)) + { + XUngrabPointer(x11->display, CurrentTime); + x11->win_drag_button1_down = false; + + XEvent xev; + xev.xclient.type = ClientMessage; + xev.xclient.serial = 0; + xev.xclient.send_event = True; + xev.xclient.message_type = x11->XA_NET_WM_MOVERESIZE; + xev.xclient.window = x11->window; + xev.xclient.format = 32; + xev.xclient.data.l[0] = Event.xmotion.x_root; + xev.xclient.data.l[1] = Event.xmotion.y_root; + xev.xclient.data.l[2] = 8; // _NET_WM_MOVERESIZE_MOVE + xev.xclient.data.l[3] = 1; // button 1 + xev.xclient.data.l[4] = 1; // source indication: normal + + XSendEvent(x11->display, x11->rootwin, False, + SubstructureRedirectMask | SubstructureNotifyMask, + &xev); + } else { + vo_mouse_movement(vo, Event.xmotion.x, Event.xmotion.y); + } break; case LeaveNotify: + x11->win_drag_button1_down = false; mp_input_put_key(vo->input_ctx, MP_KEY_MOUSE_LEAVE); break; case ButtonPress: + if (Event.xbutton.button == 1) + x11->win_drag_button1_down = true; mp_input_put_key(vo->input_ctx, (MP_MOUSE_BTN0 + Event.xbutton.button - 1) | get_mods(Event.xbutton.state) | MP_KEY_STATE_DOWN); break; case ButtonRelease: + if (Event.xbutton.button == 1) + x11->win_drag_button1_down = false; mp_input_put_key(vo->input_ctx, (MP_MOUSE_BTN0 + Event.xbutton.button - 1) | get_mods(Event.xbutton.state) | MP_KEY_STATE_UP); diff --git a/video/out/x11_common.h b/video/out/x11_common.h index ac41f6e3ed..23ece3f9c3 100644 --- a/video/out/x11_common.h +++ b/video/out/x11_common.h @@ -107,6 +107,9 @@ struct vo_x11_state { Atom dnd_requested_format; Window dnd_src_window; + /* dragging the window */ + bool win_drag_button1_down; + Atom XA_NET_SUPPORTED; Atom XA_NET_WM_STATE; Atom XA_NET_WM_STATE_FULLSCREEN; @@ -117,6 +120,7 @@ struct vo_x11_state { Atom XA_NET_WM_NAME; Atom XA_NET_WM_ICON_NAME; Atom XA_NET_WM_ICON; + Atom XA_NET_WM_MOVERESIZE; Atom XA_WIN_PROTOCOLS; Atom XA_WIN_LAYER; Atom XA_WIN_HINTS; |