[weston,v3,02/17] tablet: add handling of tablet focus

Submitted by Maniraj Devadoss on Dec. 19, 2017, 8:33 a.m.

Details

Message ID 1513672422-6010-3-git-send-email-Maniraj.Devadoss@in.bosch.com
State New
Headers show
Series "Tablet device support for weston" ( rev: 3 ) in Wayland

Not browsing as part of any series.

Commit Message

Maniraj Devadoss Dec. 19, 2017, 8:33 a.m.
From: Lyude Paul <thatslyude@gmail.com>

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>
---
 libweston/compositor.h | 10 ++++++
 libweston/input.c      | 92 ++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 102 insertions(+)

Patch hide | download patch | download mbox

diff --git a/libweston/compositor.h b/libweston/compositor.h
index 3513492..6a17a92 100644
--- a/libweston/compositor.h
+++ b/libweston/compositor.h
@@ -402,8 +402,14 @@  struct weston_touch {
 struct weston_tablet_tool {
 	struct weston_seat *seat;
 	enum zwp_tablet_tool_v1_type 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;
 
@@ -532,6 +538,10 @@  struct weston_tablet_tool *
 weston_tablet_tool_create(void);
 void
 weston_tablet_tool_destroy(struct weston_tablet_tool *tool);
+void
+weston_tablet_tool_set_focus(struct weston_tablet_tool *tool,
+			     struct weston_view *view,
+			     uint32_t time);
 
 bool
 weston_touch_has_focus_resource(struct weston_touch *touch);
diff --git a/libweston/input.c b/libweston/input.c
index 946621c..808e08e 100644
--- a/libweston/input.c
+++ b/libweston/input.c
@@ -300,6 +300,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);
@@ -922,6 +942,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.
  *
@@ -1201,6 +1231,61 @@  weston_tablet_destroy(struct weston_tablet *tablet)
 	wl_list_remove(&tablet->link);
 }
 
+WL_EXPORT void
+weston_tablet_tool_set_focus(struct weston_tablet_tool *tool,
+			     struct weston_view *view,
+			     uint32_t time)
+{
+	struct wl_list *focus_resource_list;
+	struct wl_resource *resource;
+	struct weston_seat *seat = tool->seat;
+
+	focus_resource_list = &tool->focus_resource_list;
+	if (tool->focus && !wl_list_empty(focus_resource_list)) {
+		wl_resource_for_each(resource, focus_resource_list) {
+			zwp_tablet_tool_v1_send_proximity_out(resource);
+			zwp_tablet_tool_v1_send_frame(resource, time);
+		}
+
+		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_v1_send_proximity_in(resource, tool->focus_serial,
+							   tr, view->surface->resource);
+			zwp_tablet_tool_v1_send_frame(resource, time);
+		}
+	}
+
+	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)
 {
@@ -1211,6 +1296,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;
 }