From 6accc77d444e80df5eddc04d54affe51433c9617 Mon Sep 17 00:00:00 2001 From: elviosak <33790211+elviosak@users.noreply.github.com> Date: Sun, 3 May 2026 06:05:25 -0300 Subject: [PATCH 1/3] When output is turned off and there is a mirror, assign it to views. --- src/output.c | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/src/output.c b/src/output.c index aea35062..8cb39c39 100644 --- a/src/output.c +++ b/src/output.c @@ -1080,18 +1080,44 @@ output_usable_area_in_layout_coords(struct output *output) return box; } +static struct output * +output_get_usable_mirror(struct output *output) +{ + struct output *mirror; + struct wlr_box mirror_box, output_box; + wlr_output_layout_get_box(server.output_layout, output->wlr_output, &output_box); + wl_list_for_each(mirror, &server.outputs, link) { + if (!output_is_usable(mirror) || output->id_bit == mirror->id_bit) { + continue; + } + wlr_output_layout_get_box(server.output_layout, mirror->wlr_output, &mirror_box); + if (wlr_box_equal(&output_box, &mirror_box)) { + return mirror; + } + } + return NULL; +} + void handle_output_power_manager_set_mode(struct wl_listener *listener, void *data) { struct wlr_output_power_v1_set_mode_event *event = data; struct output *output = event->output->data; assert(output); - + struct output *mirror = output_get_usable_mirror(output); switch (event->mode) { case ZWLR_OUTPUT_POWER_V1_MODE_OFF: if (!event->output->enabled) { return; } + if (mirror) { + struct view *view; + for_each_view(view, &server.views, LAB_VIEW_CRITERIA_NONE) { + if (view->output == output) { + view->output = mirror; + } + } + } wlr_output_state_set_enabled(&output->pending, false); output_state_commit(output); break; From c802c5875ad28e3d12e3fa74183e7f4e63f08a55 Mon Sep 17 00:00:00 2001 From: elviosak <33790211+elviosak@users.noreply.github.com> Date: Mon, 4 May 2026 00:15:58 -0300 Subject: [PATCH 2/3] add mirror check for output_nearest_to() --- src/output.c | 47 +++++++++++++++++++++++++++-------------------- 1 file changed, 27 insertions(+), 20 deletions(-) diff --git a/src/output.c b/src/output.c index 8cb39c39..11a60de0 100644 --- a/src/output.c +++ b/src/output.c @@ -927,6 +927,24 @@ output_from_name(const char *name) return NULL; } +static struct output * +output_get_usable_mirror(struct output *output) +{ + struct output *mirror; + struct wlr_box mirror_box, output_box; + wlr_output_layout_get_box(server.output_layout, output->wlr_output, &output_box); + wl_list_for_each(mirror, &server.outputs, link) { + if (!output_is_usable(mirror) || output->id_bit == mirror->id_bit) { + continue; + } + wlr_output_layout_get_box(server.output_layout, mirror->wlr_output, &mirror_box); + if (wlr_box_equal(&output_box, &mirror_box)) { + return mirror; + } + } + return NULL; +} + struct output * output_nearest_to(int lx, int ly) { @@ -934,8 +952,15 @@ output_nearest_to(int lx, int ly) wlr_output_layout_closest_point(server.output_layout, NULL, lx, ly, &closest_x, &closest_y); - return output_from_wlr_output(wlr_output_layout_output_at(server.output_layout, - closest_x, closest_y)); + struct output *output = output_from_wlr_output(wlr_output_layout_output_at( + server.output_layout, closest_x, closest_y)); + if (output && !output_is_usable(output)) { + struct output *mirror = output_get_usable_mirror(output); + if (mirror) { + return mirror; + } + } + return output; } struct output * @@ -1080,24 +1105,6 @@ output_usable_area_in_layout_coords(struct output *output) return box; } -static struct output * -output_get_usable_mirror(struct output *output) -{ - struct output *mirror; - struct wlr_box mirror_box, output_box; - wlr_output_layout_get_box(server.output_layout, output->wlr_output, &output_box); - wl_list_for_each(mirror, &server.outputs, link) { - if (!output_is_usable(mirror) || output->id_bit == mirror->id_bit) { - continue; - } - wlr_output_layout_get_box(server.output_layout, mirror->wlr_output, &mirror_box); - if (wlr_box_equal(&output_box, &mirror_box)) { - return mirror; - } - } - return NULL; -} - void handle_output_power_manager_set_mode(struct wl_listener *listener, void *data) { From abb7431a72990711294ca995b361f9ff6a4a0468 Mon Sep 17 00:00:00 2001 From: elviosak <33790211+elviosak@users.noreply.github.com> Date: Mon, 4 May 2026 00:44:51 -0300 Subject: [PATCH 3/3] send disabled output to the end of the list so mirror is picked first --- src/output.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/src/output.c b/src/output.c index 11a60de0..f8510e56 100644 --- a/src/output.c +++ b/src/output.c @@ -952,15 +952,8 @@ output_nearest_to(int lx, int ly) wlr_output_layout_closest_point(server.output_layout, NULL, lx, ly, &closest_x, &closest_y); - struct output *output = output_from_wlr_output(wlr_output_layout_output_at( - server.output_layout, closest_x, closest_y)); - if (output && !output_is_usable(output)) { - struct output *mirror = output_get_usable_mirror(output); - if (mirror) { - return mirror; - } - } - return output; + return output_from_wlr_output(wlr_output_layout_output_at(server.output_layout, + closest_x, closest_y)); } struct output * @@ -1124,6 +1117,14 @@ handle_output_power_manager_set_mode(struct wl_listener *listener, void *data) view->output = mirror; } } + /** + * Send the output that was turned off to the end of the list + * so wlr_output_* functions pick the mirror first + */ + struct wlr_output_layout_output *layout_output = + wlr_output_layout_get(server.output_layout, output->wlr_output); + wl_list_remove(&layout_output->link); + wl_list_insert(server.output_layout->outputs.prev, &layout_output->link); } wlr_output_state_set_enabled(&output->pending, false); output_state_commit(output);