diff --git a/video/out/wayland_common.c b/video/out/wayland_common.c index 78ce86ca74..3b69f60947 100644 --- a/video/out/wayland_common.c +++ b/video/out/wayland_common.c @@ -306,18 +306,21 @@ static void pointer_handle_button(void *data, struct wl_pointer *wl_pointer, if (button) mp_input_put_key(wl->vo->input_ctx, button | state | s->mpmod); + uint32_t edges; if (!mp_input_test_dragging(wl->vo->input_ctx, wl->mouse_x, wl->mouse_y) && - !wl->locked_size && (button == MP_MBTN_LEFT) && (state == MP_KEY_STATE_DOWN)) + !wl->locked_size && (button == MP_MBTN_LEFT) && (state == MP_KEY_STATE_DOWN) && + !wl->vo_opts->border && check_for_resize(wl, wl->opts->edge_pixels_pointer, &edges)) { - uint32_t edges; // Implement an edge resize zone if there are no decorations - if (!wl->vo_opts->border && check_for_resize(wl, wl->opts->edge_pixels_pointer, &edges)) { - xdg_toplevel_resize(wl->xdg_toplevel, s->seat, serial, edges); - } else { - xdg_toplevel_move(wl->xdg_toplevel, s->seat, serial); - } - // Explicitly send an UP event after the client finishes a move/resize + xdg_toplevel_resize(wl->xdg_toplevel, s->seat, serial, edges); + // Explicitly send an UP event after the client finishes a resize mp_input_put_key(wl->vo->input_ctx, button | MP_KEY_STATE_UP); + } else if (state == MP_KEY_STATE_DOWN) { + // Save the serial and seat for voctrl-initialized dragging requests. + s->pointer_serial = serial; + wl->last_button_seat = s; + } else { + wl->last_button_seat = NULL; } } @@ -427,12 +430,14 @@ static void touch_handle_down(void *data, struct wl_touch *wl_touch, wl->mouse_y = wl_fixed_to_int(y_w) * wl->scaling; enum xdg_toplevel_resize_edge edge; - if (!mp_input_test_dragging(wl->vo->input_ctx, wl->mouse_x, wl->mouse_y)) { - if (check_for_resize(wl, wl->opts->edge_pixels_touch, &edge)) { - xdg_toplevel_resize(wl->xdg_toplevel, s->seat, serial, edge); - } else { - xdg_toplevel_move(wl->xdg_toplevel, s->seat, serial); - } + if (!mp_input_test_dragging(wl->vo->input_ctx, wl->mouse_x, wl->mouse_y) && + check_for_resize(wl, wl->opts->edge_pixels_touch, &edge)) + { + xdg_toplevel_resize(wl->xdg_toplevel, s->seat, serial, edge); + } else { + // Save the serial and seat for voctrl-initialized dragging requests. + s->pointer_serial = serial; + wl->last_button_seat = s; } mp_input_set_mouse_pos(wl->vo->input_ctx, wl->mouse_x, wl->mouse_y); @@ -445,6 +450,7 @@ static void touch_handle_up(void *data, struct wl_touch *wl_touch, struct vo_wayland_seat *s = data; struct vo_wayland_state *wl = s->wl; mp_input_put_key(wl->vo->input_ctx, MP_MBTN_LEFT | MP_KEY_STATE_UP); + wl->last_button_seat = NULL; } static void touch_handle_motion(void *data, struct wl_touch *wl_touch, @@ -1908,6 +1914,8 @@ static void remove_seat(struct vo_wayland_seat *seat) MP_VERBOSE(seat->wl, "Deregistering seat 0x%x\n", seat->id); wl_list_remove(&seat->link); + if (seat == seat->wl->last_button_seat) + seat->wl->last_button_seat = NULL; if (seat->keyboard) wl_keyboard_destroy(seat->keyboard); if (seat->pointer) @@ -2199,6 +2207,18 @@ static void wayland_dispatch_events(struct vo_wayland_state *wl, int nfds, int64 wl_display_dispatch_pending(wl->display); } +static void begin_dragging(struct vo_wayland_state *wl) +{ + struct vo_wayland_seat *s = wl->last_button_seat; + if (!mp_input_test_dragging(wl->vo->input_ctx, wl->mouse_x, wl->mouse_y) && + !wl->locked_size && s) + { + xdg_toplevel_move(wl->xdg_toplevel, s->seat, s->pointer_serial); + wl->last_button_seat = NULL; + mp_input_put_key(wl->vo->input_ctx, MP_INPUT_RELEASE_ALL); + } +} + /* Non-static */ int vo_wayland_allocate_memfd(struct vo *vo, size_t size) { @@ -2369,6 +2389,9 @@ int vo_wayland_control(struct vo *vo, int *events, int request, void *arg) *(double *)arg = wl->scaling; return VO_TRUE; } + case VOCTRL_BEGIN_DRAGGING: + begin_dragging(wl); + return VO_TRUE; case VOCTRL_UPDATE_WINDOW_TITLE: return update_window_title(wl, (const char *)arg); case VOCTRL_SET_CURSOR_VISIBILITY: diff --git a/video/out/wayland_common.h b/video/out/wayland_common.h index 0554d308ba..721d4fb2eb 100644 --- a/video/out/wayland_common.h +++ b/video/out/wayland_common.h @@ -22,6 +22,8 @@ #include "input/event.h" #include "vo.h" +struct vo_wayland_seat; + typedef struct { uint32_t format; uint32_t padding; @@ -155,6 +157,7 @@ struct vo_wayland_state { struct wl_surface *cursor_surface; bool cursor_visible; int allocated_cursor_scale; + struct vo_wayland_seat *last_button_seat; }; bool vo_wayland_check_visible(struct vo *vo);