aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTudor Brindus <me@tbrindus.ca>2020-04-28 16:15:00 -0400
committerSimon Ser <contact@emersion.fr>2020-04-30 12:08:42 +0200
commitd6983346209fc97991f3c2d8abdc57cb90f40ffe (patch)
tree3dbf881e3911f03442d98853e25144899fda99cd
parent906c0766df2fec4bd32c316fd1b0d46fded5fc84 (diff)
input/tablet: clear focused surface on surface destroy
Otherwise, we can end up left with a dangling pointer to a previously-focused, now-destroyed surface. Fixes swaywm/sway#5264.
-rw-r--r--types/tablet_v2/.wlr_tablet_v2_tool.c.swpbin0 -> 49152 bytes
-rw-r--r--types/tablet_v2/wlr_tablet_v2_tool.c17
2 files changed, 16 insertions, 1 deletions
diff --git a/types/tablet_v2/.wlr_tablet_v2_tool.c.swp b/types/tablet_v2/.wlr_tablet_v2_tool.c.swp
new file mode 100644
index 00000000..5b28efe4
--- /dev/null
+++ b/types/tablet_v2/.wlr_tablet_v2_tool.c.swp
Binary files differ
diff --git a/types/tablet_v2/wlr_tablet_v2_tool.c b/types/tablet_v2/wlr_tablet_v2_tool.c
index 7ebe5030..e2936bcb 100644
--- a/types/tablet_v2/wlr_tablet_v2_tool.c
+++ b/types/tablet_v2/wlr_tablet_v2_tool.c
@@ -192,6 +192,7 @@ static void handle_wlr_tablet_tool_destroy(struct wl_listener *listener, void *d
wl_list_remove(&tool->link);
wl_list_remove(&tool->tool_destroy.link);
wl_list_remove(&tool->events.set_cursor.listener_list);
+ wl_list_remove(&tool->surface_destroy.link);
free(tool);
}
@@ -226,11 +227,11 @@ struct wlr_tablet_v2_tablet_tool *wlr_tablet_tool_create(
tool->wlr_tool = wlr_tool;
wl_list_init(&tool->clients);
+ wl_list_init(&tool->surface_destroy.link);
tool->default_grab.tool = tool;
tool->default_grab.interface = &default_tool_grab_interface;
tool->grab = &tool->default_grab;
-
tool->tool_destroy.notify = handle_wlr_tablet_tool_destroy;
wl_signal_add(&wlr_tool->events.destroy, &tool->tool_destroy);
wl_list_insert(&seat->tools, &tool->link);
@@ -322,6 +323,13 @@ static void queue_tool_frame(struct wlr_tablet_tool_client_v2 *tool) {
}
}
+static void handle_tablet_tool_surface_destroy(struct wl_listener *listener,
+ void *data) {
+ struct wlr_tablet_v2_tablet_tool *tool =
+ wl_container_of(listener, tool, surface_destroy);
+ wlr_send_tablet_v2_tablet_tool_proximity_out(tool);
+}
+
void wlr_send_tablet_v2_tablet_tool_proximity_in(
struct wlr_tablet_v2_tablet_tool *tool,
struct wlr_tablet_v2_tablet *tablet,
@@ -366,6 +374,11 @@ void wlr_send_tablet_v2_tablet_tool_proximity_in(
return;
}
+ // Reinitialize the focus destroy events
+ wl_list_remove(&tool->surface_destroy.link);
+ wl_signal_add(&surface->events.destroy, &tool->surface_destroy);
+ tool->surface_destroy.notify = handle_tablet_tool_surface_destroy;
+
tool->current_client = tool_client;
uint32_t serial = wlr_seat_client_next_serial(tool_client->seat->seat_client);
@@ -418,6 +431,8 @@ void wlr_send_tablet_v2_tablet_tool_proximity_out(
zwp_tablet_tool_v2_send_proximity_out(tool->current_client->resource);
send_tool_frame(tool->current_client);
+ wl_list_remove(&tool->surface_destroy.link);
+ wl_list_init(&tool->surface_destroy.link);
tool->current_client = NULL;
tool->focused_surface = NULL;
}