From 6e8fb5509f2c94d09d4efa0f9b1f40b37bf73863 Mon Sep 17 00:00:00 2001 From: Simon Ser Date: Mon, 12 Jun 2023 11:19:13 +0200 Subject: [PATCH] cursor: only reset the cursor when the surface changes If the set_cursor request is used with the same surface, don't call cursor_output_cursor_reset_image(). That function sends wl_surface.leave and can cause an infinite feedback loop with some clients (submitting a LoDPI cursor when the surface leaves an HiDPI output). Closes: https://gitlab.freedesktop.org/wlroots/wlroots/-/issues/3669 --- types/wlr_cursor.c | 36 ++++++++++++++++++++---------------- 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/types/wlr_cursor.c b/types/wlr_cursor.c index f82d3c79..3d5c8b22 100644 --- a/types/wlr_cursor.c +++ b/types/wlr_cursor.c @@ -469,26 +469,30 @@ void wlr_cursor_set_surface(struct wlr_cursor *cur, struct wlr_surface *surface, continue; } - cursor_output_cursor_reset_image(output_cursor); + if (surface != output_cursor->surface) { + // Only send wl_surface.leave if the surface changes + cursor_output_cursor_reset_image(output_cursor); + + output_cursor->surface = surface; + + wl_signal_add(&surface->events.destroy, + &output_cursor->surface_destroy); + output_cursor->surface_destroy.notify = + output_cursor_output_handle_surface_destroy; + wl_signal_add(&surface->events.commit, + &output_cursor->surface_commit); + output_cursor->surface_commit.notify = + output_cursor_output_handle_surface_commit; + + wl_signal_add(&output_cursor->output_cursor->output->events.commit, + &output_cursor->output_commit); + output_cursor->output_commit.notify = + output_cursor_output_handle_output_commit; + } - output_cursor->surface = surface; output_cursor->surface_hotspot.x = hotspot_x; output_cursor->surface_hotspot.y = hotspot_y; - wl_signal_add(&surface->events.destroy, - &output_cursor->surface_destroy); - output_cursor->surface_destroy.notify = - output_cursor_output_handle_surface_destroy; - wl_signal_add(&surface->events.commit, - &output_cursor->surface_commit); - output_cursor->surface_commit.notify = - output_cursor_output_handle_surface_commit; - - wl_signal_add(&output_cursor->output_cursor->output->events.commit, - &output_cursor->output_commit); - output_cursor->output_commit.notify = - output_cursor_output_handle_output_commit; - output_cursor_output_commit_surface(output_cursor); } }