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 19f101db68,
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.
This commit is contained in:
nanahi 2024-02-10 14:43:50 -05:00 committed by sfan5
parent d954646d29
commit 531704e35d
2 changed files with 22 additions and 33 deletions

View File

@ -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,7 +1289,28 @@ 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_set_mouse_pos(x11->input_ctx, Event.xmotion.x,
Event.xmotion.y);
break;
case LeaveNotify:
if (Event.xcrossing.mode != NotifyNormal)
break;
mp_input_put_key(x11->input_ctx, MP_KEY_MOUSE_LEAVE);
break;
case EnterNotify:
if (Event.xcrossing.mode != NotifyNormal)
break;
mp_input_put_key(x11->input_ctx, MP_KEY_MOUSE_ENTER);
break;
case ButtonPress:
if (Event.xbutton.button - 1 >= MP_KEY_MOUSE_BTN_COUNT)
break;
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))
{
@ -1304,39 +1324,11 @@ void vo_x11_check_events(struct vo *vo)
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;
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:
if (Event.xcrossing.mode != NotifyNormal)
break;
mp_input_put_key(x11->input_ctx, MP_KEY_MOUSE_ENTER);
break;
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);
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);

View File

@ -137,9 +137,6 @@ struct vo_x11_state {
Atom dnd_requested_action;
Window dnd_src_window;
/* dragging the window */
bool win_drag_button1_down;
Atom icc_profile_property;
};