diff options
author | Michael Olbrich <m.olbrich@pengutronix.de> | 2021-01-20 09:11:41 +0100 |
---|---|---|
committer | Daniel Stone <daniels@collabora.com> | 2023-03-31 12:10:26 +0000 |
commit | d24af4323300c737b2da19f23af5c42d593c4df9 (patch) | |
tree | efdbe76035c1a0b6c7dab56e8c993ce74caba075 | |
parent | 03596a9d065ccb38059c9b782e1d4cd4eaf5a59e (diff) | |
download | weston-d24af4323300c737b2da19f23af5c42d593c4df9.tar.gz |
input: add tablet focus handling
Closely modelled after the pointer focus handling
Co-authored-by: Peter Hutterer <peter.hutterer@who-t.net>
Signed-off-by: Lyude Paul <thatslyude@gmail.com>
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Signed-off-by: Bastian Farkas <bfarkas@de.adit-jv.com>
Based on a patch from
Peter Hutterer <peter.hutterer@who-t.net>
Lyude Paul <thatslyude@gmail.com>
Signed-off-by: Michael Olbrich <m.olbrich@pengutronix.de>
-rw-r--r-- | include/libweston/libweston.h | 12 | ||||
-rw-r--r-- | libweston/input.c | 101 |
2 files changed, 113 insertions, 0 deletions
diff --git a/include/libweston/libweston.h b/include/libweston/libweston.h index 1aa146e1..19ae42f2 100644 --- a/include/libweston/libweston.h +++ b/include/libweston/libweston.h @@ -845,8 +845,14 @@ struct weston_touch { struct weston_tablet_tool { struct weston_seat *seat; uint32_t type; + struct weston_tablet *current_tablet; struct wl_list resource_list; + struct wl_list focus_resource_list; + struct weston_view *focus; + struct wl_listener focus_view_listener; + struct wl_listener focus_resource_listener; + uint32_t focus_serial; struct wl_list link; @@ -957,6 +963,12 @@ weston_touch_send_frame(struct weston_touch *touch); void +weston_tablet_tool_set_focus(struct weston_tablet_tool *tool, + struct weston_view *view, + const struct timespec *time); + + +void weston_seat_set_selection(struct weston_seat *seat, struct weston_data_source *source, uint32_t serial); diff --git a/libweston/input.c b/libweston/input.c index 1365502a..30a76161 100644 --- a/libweston/input.c +++ b/libweston/input.c @@ -425,6 +425,26 @@ touch_focus_resource_destroyed(struct wl_listener *listener, void *data) } static void +tablet_tool_focus_view_destroyed(struct wl_listener *listener, void *data) +{ + struct weston_tablet_tool *tool = + container_of(listener, struct weston_tablet_tool, + focus_view_listener); + + weston_tablet_tool_set_focus(tool, NULL, 0); +} + +static void +tablet_tool_focus_resource_destroyed(struct wl_listener *listener, void *data) +{ + struct weston_tablet_tool *tool = + container_of(listener, struct weston_tablet_tool, + focus_resource_listener); + + weston_tablet_tool_set_focus(tool, NULL, 0); +} + +static void move_resources(struct wl_list *destination, struct wl_list *source) { wl_list_insert_list(destination, source); @@ -1120,6 +1140,16 @@ find_resource_for_surface(struct wl_list *list, struct weston_surface *surface) return wl_resource_find_for_client(list, wl_resource_get_client(surface->resource)); } +static struct wl_resource * +find_resource_for_view(struct wl_list *list, struct weston_view *view) +{ + if (!view) + return NULL; + + return find_resource_for_surface(list, + view->surface); +} + /** Send wl_keyboard.modifiers events to focused resources and pointer * focused resources. * @@ -1441,6 +1471,64 @@ weston_tablet_destroy(struct weston_tablet *tablet) } } +WL_EXPORT void +weston_tablet_tool_set_focus(struct weston_tablet_tool *tool, + struct weston_view *view, + const struct timespec *time) +{ + struct wl_list *focus_resource_list; + struct wl_resource *resource; + struct weston_seat *seat = tool->seat; + uint32_t msecs; + + focus_resource_list = &tool->focus_resource_list; + /* FIXME: correct timestamp? */ + msecs = time ? timespec_to_msec(time) : 0; + if (tool->focus && !wl_list_empty(focus_resource_list)) { + wl_resource_for_each(resource, focus_resource_list) { + zwp_tablet_tool_v2_send_proximity_out(resource); + zwp_tablet_tool_v2_send_frame(resource, msecs); + } + + move_resources(&tool->resource_list, focus_resource_list); + } + + if (find_resource_for_view(&tool->resource_list, view)) { + struct wl_client *surface_client = + wl_resource_get_client(view->surface->resource); + + move_resources_for_client(focus_resource_list, + &tool->resource_list, + surface_client); + + tool->focus_serial = wl_display_next_serial(seat->compositor->wl_display); + wl_resource_for_each(resource, focus_resource_list) { + struct wl_resource *tr; + + tr = wl_resource_find_for_client(&tool->current_tablet->resource_list, + surface_client); + + zwp_tablet_tool_v2_send_proximity_in(resource, tool->focus_serial, + tr, view->surface->resource); + zwp_tablet_tool_v2_send_frame(resource, msecs); + } + } + + wl_list_remove(&tool->focus_view_listener.link); + wl_list_init(&tool->focus_view_listener.link); + wl_list_remove(&tool->focus_resource_listener.link); + wl_list_init(&tool->focus_resource_listener.link); + + if (view) + wl_signal_add(&view->destroy_signal, + &tool->focus_view_listener); + if (view && view->surface->resource) + wl_resource_add_destroy_listener(view->surface->resource, + &tool->focus_resource_listener); + tool->focus = view; + tool->focus_view_listener.notify = tablet_tool_focus_view_destroyed; +} + WL_EXPORT struct weston_tablet_tool * weston_tablet_tool_create(void) { @@ -1451,6 +1539,13 @@ weston_tablet_tool_create(void) return NULL; wl_list_init(&tool->resource_list); + wl_list_init(&tool->focus_resource_list); + + wl_list_init(&tool->focus_view_listener.link); + tool->focus_view_listener.notify = tablet_tool_focus_view_destroyed; + + wl_list_init(&tool->focus_resource_listener.link); + tool->focus_resource_listener.notify = tablet_tool_focus_resource_destroyed; return tool; } @@ -1464,9 +1559,15 @@ weston_tablet_tool_destroy(struct weston_tablet_tool *tool) zwp_tablet_tool_v2_send_removed(resource); wl_resource_set_user_data(resource, NULL); } + wl_resource_for_each(resource, &tool->focus_resource_list) { + wl_resource_set_user_data(resource, NULL); + } wl_list_remove(&tool->link); wl_list_remove(&tool->resource_list); + wl_list_remove(&tool->focus_resource_list); + wl_list_remove(&tool->focus_view_listener.link); + wl_list_remove(&tool->focus_resource_listener.link); free(tool); } |