From 531704e35d9a5a4b143072d25657509138b5607c Mon Sep 17 00:00:00 2001 From: nanahi <130121847+na-na-hi@users.noreply.github.com> Date: Sat, 10 Feb 2024 14:43:50 -0500 Subject: x11_common: handle window dragging in ButtonPress event Begin the _NET_WM_MOVERESIZE window dragging in ButtonPress event to match the behavior of win32 and wayland, simplify logic by dropping the win_drag_button1_down hack required by the old method, and fix a race condition described in commit 19f101db680f966a6e56035a16784541be390982, which happens when moving the mouse and releasing the button at the same time. The race condition can be easily triggered when using a touch screen (tested with libinput driver), where a tap is translated to MotionNotify, ButtonPress, MotionNotify, and ButtonRelease in sequence, with the last 2 events having the same timestamp. This has caused some window managers to not stop dragging after the ButtonRelease, resulting in window being stuck in dragging state after a single tap. --- video/out/x11_common.c | 42 +++++++++++++++++------------------------- 1 file changed, 17 insertions(+), 25 deletions(-) (limited to 'video/out/x11_common.c') diff --git a/video/out/x11_common.c b/video/out/x11_common.c index 83584795fb..3437336619 100644 --- a/video/out/x11_common.c +++ b/video/out/x11_common.c @@ -1219,7 +1219,6 @@ static void release_all_keys(struct vo *vo) if (x11->no_autorepeat) mp_input_put_key(x11->input_ctx, MP_INPUT_RELEASE_ALL); - x11->win_drag_button1_down = false; } void vo_x11_check_events(struct vo *vo) @@ -1290,30 +1289,12 @@ void vo_x11_check_events(struct vo *vo) release_all_keys(vo); break; case MotionNotify: - if (x11->win_drag_button1_down && !x11->fs && - !mp_input_test_dragging(x11->input_ctx, Event.xmotion.x, - Event.xmotion.y)) - { - mp_input_put_key(x11->input_ctx, MP_INPUT_RELEASE_ALL); - XUngrabPointer(x11->display, CurrentTime); - - long params[5] = { - Event.xmotion.x_root, Event.xmotion.y_root, - 8, // _NET_WM_MOVERESIZE_MOVE - 1, // button 1 - 1, // source indication: normal - }; - x11_send_ewmh_msg(x11, "_NET_WM_MOVERESIZE", params); - } else { - mp_input_set_mouse_pos(x11->input_ctx, Event.xmotion.x, - Event.xmotion.y); - } - x11->win_drag_button1_down = false; + mp_input_set_mouse_pos(x11->input_ctx, Event.xmotion.x, + Event.xmotion.y); break; case LeaveNotify: if (Event.xcrossing.mode != NotifyNormal) break; - x11->win_drag_button1_down = false; mp_input_put_key(x11->input_ctx, MP_KEY_MOUSE_LEAVE); break; case EnterNotify: @@ -1324,19 +1305,30 @@ void vo_x11_check_events(struct vo *vo) case ButtonPress: if (Event.xbutton.button - 1 >= MP_KEY_MOUSE_BTN_COUNT) break; - if (Event.xbutton.button == 1) - x11->win_drag_button1_down = true; mp_input_put_key(x11->input_ctx, (MP_MBTN_BASE + Event.xbutton.button - 1) | get_mods(Event.xbutton.state) | MP_KEY_STATE_DOWN); long msg[4] = {XEMBED_REQUEST_FOCUS}; vo_x11_xembed_send_message(x11, msg); + if (Event.xbutton.button == 1 && !x11->fs && + !mp_input_test_dragging(x11->input_ctx, Event.xmotion.x, + Event.xmotion.y)) + { + mp_input_put_key(x11->input_ctx, MP_INPUT_RELEASE_ALL); + XUngrabPointer(x11->display, CurrentTime); + + long params[5] = { + Event.xmotion.x_root, Event.xmotion.y_root, + 8, // _NET_WM_MOVERESIZE_MOVE + 1, // button 1 + 1, // source indication: normal + }; + x11_send_ewmh_msg(x11, "_NET_WM_MOVERESIZE", params); + } break; case ButtonRelease: if (Event.xbutton.button - 1 >= MP_KEY_MOUSE_BTN_COUNT) break; - if (Event.xbutton.button == 1) - x11->win_drag_button1_down = false; mp_input_put_key(x11->input_ctx, (MP_MBTN_BASE + Event.xbutton.button - 1) | get_mods(Event.xbutton.state) | MP_KEY_STATE_UP); -- cgit v1.2.3