summaryrefslogtreecommitdiffstats
path: root/video/out/x11_common.c
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2014-03-18 20:38:23 +0100
committerwm4 <wm4@nowhere>2014-03-18 20:43:45 +0100
commit19f101db680f966a6e56035a16784541be390982 (patch)
tree28cbf61aa9d0c2ec05f141c79022cc90a5883ec5 /video/out/x11_common.c
parent4751fe408be9c1278149e234f45570b70f4a57ce (diff)
downloadmpv-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/out/x11_common.c')
-rw-r--r--video/out/x11_common.c34
1 files changed, 33 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);