[PATCH weston 13/13] tablet: Remove tablet-specific tools on disconnect

Peter Hutterer peter.hutterer at who-t.net
Thu Nov 5 20:31:21 PST 2015


From: Stephen Chandler Paul <thatslyude at gmail.com>

Store all tablets that a tool was used on in a list. When the tablet
is removed, remove all tools only seen on this tablet.

Tools without a serial number are only ever bound to one tablet.

Co-authored-by: Peter Hutterer <peter.hutterer at who-t.net>
Signed-off-by: Stephen Chandler Paul <thatslyude at gmail.com>
Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
---
 src/compositor.h      |  2 ++
 src/input.c           | 26 ++++++++++++++++++++++++++
 src/libinput-device.c | 27 +++++++++++++++++++++++----
 3 files changed, 51 insertions(+), 4 deletions(-)

diff --git a/src/compositor.h b/src/compositor.h
index 8cc3cee..3f563f4 100644
--- a/src/compositor.h
+++ b/src/compositor.h
@@ -421,6 +421,7 @@ struct weston_tablet_tool {
 	uint32_t focus_serial;
 	uint32_t grab_serial;
 
+	struct wl_list tablet_list;
 	struct wl_list link;
 
 	uint64_t serial;
@@ -452,6 +453,7 @@ struct weston_tablet {
 	struct wl_list resource_list;
 
 	struct wl_list link;
+	struct wl_list tool_link;
 
 	char *name;
 	enum zwp_tablet1_type type;
diff --git a/src/input.c b/src/input.c
index b4e6c14..3761239 100644
--- a/src/input.c
+++ b/src/input.c
@@ -682,10 +682,30 @@ WL_EXPORT void
 weston_tablet_destroy(struct weston_tablet *tablet)
 {
 	struct wl_resource *resource;
+	struct weston_tablet_tool *tool, *tmp;
 
 	wl_resource_for_each(resource, &tablet->resource_list)
 		zwp_tablet1_send_removed(resource);
 
+	/* Check all tools whether they're linked with this tablet and break
+	 * that link. If the tool is left with no linked tablets after
+	 * this, we can destroy it. */
+	wl_list_for_each_safe(tool, tmp, &tablet->seat->tablet_tool_list, link) {
+		struct weston_tablet *t, *tmpt;
+		bool remove_tool = false;
+
+		wl_list_for_each_safe(t, tmpt, &tool->tablet_list, tool_link) {
+			if (t == tablet) {
+				wl_list_remove(&t->tool_link);
+				remove_tool = true;
+				break;
+			}
+		}
+
+		if (remove_tool && wl_list_empty(&tool->tablet_list))
+			weston_tablet_tool_destroy(tool);
+	}
+
 	wl_list_remove(&tablet->link);
 	free(tablet->name);
 	free(tablet);
@@ -978,6 +998,7 @@ weston_tablet_tool_create(void)
 
 	wl_list_init(&tool->resource_list);
 	wl_list_init(&tool->focus_resource_list);
+	wl_list_init(&tool->tablet_list);
 
 	wl_list_init(&tool->sprite_destroy_listener.link);
 	tool->sprite_destroy_listener.notify = tablet_tool_handle_sprite_destroy;
@@ -1003,6 +1024,11 @@ weston_tablet_tool_destroy(struct weston_tablet_tool *tool)
 {
 	struct wl_resource *resource, *tmp;
 
+	if (!wl_list_empty(&tool->tablet_list)) {
+		weston_log("error: tool still linked to a tablet\n");
+		return;
+	}
+
 	if (tool->sprite)
 		tablet_tool_unmap_sprite(tool);
 
diff --git a/src/libinput-device.c b/src/libinput-device.c
index ba89410..d8643c8 100644
--- a/src/libinput-device.c
+++ b/src/libinput-device.c
@@ -334,10 +334,12 @@ handle_tablet_proximity(struct libinput_device *libinput_device,
 		return;
 	}
 
-	wl_list_for_each(tool, &device->seat->tablet_tool_list, link) {
-		if (tool->serial == serial && tool->type == type) {
-			create = false;
-			break;
+	if (serial) {
+		wl_list_for_each(tool, &device->seat->tablet_tool_list, link) {
+			if (tool->serial == serial && tool->type == type) {
+				create = false;
+				break;
+			}
 		}
 	}
 
@@ -361,11 +363,28 @@ handle_tablet_proximity(struct libinput_device *libinput_device,
 		    tool->capabilities |= 1 << ZWP_TABLET_TOOL1_CAPABILITY_TILT;
 
 		wl_list_insert(&device->seat->tablet_tool_list, &tool->link);
+		wl_list_insert(&tool->tablet_list, &tablet->tool_link);
+
 		notify_tablet_tool_added(tool);
 
 		libinput_tool_set_user_data(libinput_tool, tool);
 	}
 
+	if (serial && !create) {
+		struct weston_tablet *t;
+		bool add = true;
+
+		wl_list_for_each(t, &tool->tablet_list, tool_link) {
+			if (t == tablet) {
+				add = false;
+				break;
+			}
+		}
+
+		if (add)
+			wl_list_insert(&tool->tablet_list, &tablet->tool_link);
+	}
+
 	notify_tablet_tool_proximity_in(tool, time, tablet);
 	/* FIXME: we should send axis updates  here */
 	notify_tablet_tool_frame(tool, time);
-- 
2.4.3



More information about the wayland-devel mailing list