vlc | branch: master | Rémi Denis-Courmont <[email protected]> | Thu May 24 20:27:07 2018 +0300| [3caea5a4e848410ce2f4d4c1d438c921cccde0d0] | committer: Rémi Denis-Courmont
xdg-shell: show/hide the left_ptr cursor Add timeout handling in the Wayland client loop, show the left pointer image as cursor on entry/movement/button/axis, and hide it after the usual timeout. This fixes #20531. > http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=3caea5a4e848410ce2f4d4c1d438c921cccde0d0 --- modules/video_output/wayland/input.c | 83 ++++++++++++++++++++++++++++++-- modules/video_output/wayland/input.h | 7 +++ modules/video_output/wayland/xdg-shell.c | 8 ++- 3 files changed, 92 insertions(+), 6 deletions(-) diff --git a/modules/video_output/wayland/input.c b/modules/video_output/wayland/input.c index eddbd11e02..8147df1d2f 100644 --- a/modules/video_output/wayland/input.c +++ b/modules/video_output/wayland/input.c @@ -45,7 +45,12 @@ struct seat_data { vout_window_t *owner; struct wl_seat *seat; + struct wl_pointer *pointer; + mtime_t cursor_timeout; + mtime_t cursor_deadline; + uint32_t cursor_serial; + #ifdef HAVE_XKBCOMMON struct xkb_context *xkb; struct wl_keyboard *keyboard; @@ -58,12 +63,27 @@ struct seat_data struct wl_list node; }; +static void pointer_show(struct seat_data *sd, struct wl_pointer *pointer) +{ + int hsx, hsy; + struct wl_surface *surface = window_get_cursor(sd->owner, &hsx, &hsy); + + if (surface != NULL) + { + wl_pointer_set_cursor(pointer, sd->cursor_serial, surface, hsx, hsy); + sd->cursor_deadline = mdate() + sd->cursor_timeout; + } +} + static void pointer_enter_cb(void *data, struct wl_pointer *pointer, uint32_t serial, struct wl_surface *surface, wl_fixed_t sx, wl_fixed_t sy) { - (void) data; (void) pointer; (void) serial; (void) surface; - (void) sx; (void) sy; /* TODO: set_cursor */ + struct seat_data *sd = data; + + sd->cursor_serial = serial; + pointer_show(sd, pointer); + (void) surface; (void) sx; (void) sy; } static void pointer_leave_cb(void *data, struct wl_pointer *pointer, @@ -77,9 +97,10 @@ static void pointer_motion_cb(void *data, struct wl_pointer *pointer, { struct seat_data *sd = data; + pointer_show(sd, pointer); vout_window_ReportMouseMoved(sd->owner, wl_fixed_to_int(sx), wl_fixed_to_int(sy)); - (void) pointer; (void) time; + (void) time; } static void pointer_button_cb(void *data, struct wl_pointer *pointer, @@ -89,6 +110,8 @@ static void pointer_button_cb(void *data, struct wl_pointer *pointer, struct seat_data *sd = data; int button; + pointer_show(sd, pointer); + switch (keycode) { case BTN_LEFT: @@ -114,7 +137,7 @@ static void pointer_button_cb(void *data, struct wl_pointer *pointer, break; } - (void) pointer; (void) serial; (void) time; + (void) serial; (void) time; } static void pointer_axis_cb(void *data, struct wl_pointer *pointer, @@ -125,6 +148,7 @@ static void pointer_axis_cb(void *data, struct wl_pointer *pointer, int button; bool plus = value > 0; + pointer_show(sd, pointer); value = abs(value); switch (type) @@ -145,7 +169,7 @@ static void pointer_axis_cb(void *data, struct wl_pointer *pointer, vout_window_ReportMouseReleased(wnd, button); value -= wl_fixed_from_int(10); } - (void) pointer; (void) serial; + (void) serial; } static void pointer_frame_cb(void *data, struct wl_pointer *pointer) @@ -192,6 +216,10 @@ static void pointer_create(struct seat_data *sd) sd->pointer = wl_seat_get_pointer(sd->seat); if (likely(sd->pointer != NULL)) wl_pointer_add_listener(sd->pointer, &pointer_cbs, sd); + + sd->cursor_timeout = var_InheritInteger(sd->owner, "mouse-hide-timeout") + * (CLOCK_FREQ / 1000); + sd->cursor_deadline = INT64_MAX; } static void pointer_destroy(struct seat_data *sd) @@ -425,6 +453,20 @@ int seat_create(vout_window_t *wnd, struct wl_registry *registry, return 0; } +static mtime_t seat_next_deadline(const struct seat_data *sd) +{ + return (sd->pointer != NULL) ? sd->cursor_deadline : INT64_MAX; +} + +static void seat_refresh(struct seat_data *sd, mtime_t now) +{ + if (sd->pointer != NULL && sd->cursor_deadline <= now) + { /* Hide cursor */ + wl_pointer_set_cursor(sd->pointer, sd->cursor_serial, NULL, 0, 0); + sd->cursor_deadline = INT64_MAX; + } +} + static void seat_destroy(struct seat_data *sd) { wl_list_remove(&sd->node); @@ -466,3 +508,34 @@ void seat_destroy_all(struct wl_list *list) while (!wl_list_empty(list)) seat_destroy(container_of(list->next, struct seat_data, node)); } + +int seat_next_timeout(const struct wl_list *list) +{ + struct seat_data *sd; + mtime_t deadline = INT64_MAX; + + wl_list_for_each(sd, list, node) + { + mtime_t d = seat_next_deadline(sd); + if (deadline > d) + deadline = d; + } + + if (deadline == INT64_MAX) + return -1; + + mtime_t now = mdate(); + if (now >= deadline) + return 0; + + return (deadline - now) / 1000 + 1; +} + +void seat_timeout(struct wl_list *list) +{ + struct seat_data *sd; + mtime_t now = mdate(); + + wl_list_for_each(sd, list, node) + seat_refresh(sd, now); +} diff --git a/modules/video_output/wayland/input.h b/modules/video_output/wayland/input.h index 6c34141f6e..c7df35bab3 100644 --- a/modules/video_output/wayland/input.h +++ b/modules/video_output/wayland/input.h @@ -20,9 +20,16 @@ struct vout_window_t; struct wl_registry; +struct wl_surface; struct wl_list; int seat_create(struct vout_window_t *wnd, struct wl_registry *, uint32_t name, uint32_t version, struct wl_list *list); int seat_destroy_one(struct wl_list *list, uint32_t name); void seat_destroy_all(struct wl_list *list); + +int seat_next_timeout(const struct wl_list *list); +void seat_timeout(struct wl_list *list); + +struct wl_surface *window_get_cursor(vout_window_t *wnd, int32_t *hotspot_x, + int32_t *hotspot_y); diff --git a/modules/video_output/wayland/xdg-shell.c b/modules/video_output/wayland/xdg-shell.c index c6ddc92341..c9e133e1ee 100644 --- a/modules/video_output/wayland/xdg-shell.c +++ b/modules/video_output/wayland/xdg-shell.c @@ -124,15 +124,21 @@ static void *Thread(void *data) for (;;) { + int timeout; + while (wl_display_prepare_read(display) != 0) wl_display_dispatch_pending(display); wl_display_flush(display); + timeout = seat_next_timeout(&sys->seats); vlc_restorecancel(canc); - while (poll(ufd, 1, -1) < 0); + int val = poll(ufd, 1, timeout); canc = vlc_savecancel(); + if (val == 0) + seat_timeout(&sys->seats); + wl_display_read_events(display); wl_display_dispatch_pending(display); } _______________________________________________ vlc-commits mailing list [email protected] https://mailman.videolan.org/listinfo/vlc-commits
