From 68c8cef38edafa5e52532e0b43a4888554168361 Mon Sep 17 00:00:00 2001 From: John Lindgren Date: Tue, 20 Sep 2022 14:51:39 -0400 Subject: [PATCH] cursor: Don't warp to (0,0) when last output is disconnected There doesn't appear to be any good reason to warp the cursor to the top-left corner when all outputs are disconnected; it's no more valid than any other (x,y) point in that case. The real-world case here is a user with a single external monitor turning it off (which apparently counts as disconnected depending on the connection type/hardware). For that user, it's desirable to have the cursor remain in its original location when the monitor is turned back on. --- types/wlr_cursor.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/types/wlr_cursor.c b/types/wlr_cursor.c index 4c8a801d..46a196df 100644 --- a/types/wlr_cursor.c +++ b/types/wlr_cursor.c @@ -300,9 +300,19 @@ void wlr_cursor_warp_closest(struct wlr_cursor *cur, get_mapping(cur, dev, &mapping); if (!wlr_box_empty(&mapping)) { wlr_box_closest_point(&mapping, lx, ly, &lx, &ly); - } else { + } else if (!wl_list_empty(&cur->state->layout->outputs)) { wlr_output_layout_closest_point(cur->state->layout, NULL, lx, ly, &lx, &ly); + } else { + /* + * There is no mapping box for the input device and the + * output layout is empty. This can happen for example + * when external monitors are turned off/disconnected. + * In this case, all (x,y) points are equally invalid, + * so leave the cursor in its current location (better + * from a user standpoint than warping it to (0,0)). + */ + return; } cursor_warp_unchecked(cur, lx, ly); @@ -819,9 +829,9 @@ static void handle_layout_change(struct wl_listener *listener, void *data) { struct wlr_output_layout *layout = data; if (!wlr_output_layout_contains_point(layout, NULL, state->cursor->x, - state->cursor->y)) { + state->cursor->y) && !wl_list_empty(&layout->outputs)) { // the output we were on has gone away so go to the closest boundary - // point + // point (unless the layout is empty; compare warp_closest()) double x, y; wlr_output_layout_closest_point(layout, NULL, state->cursor->x, state->cursor->y, &x, &y);