diff --git a/src/output.c b/src/output.c index 2eab8ec3..f4865cf1 100644 --- a/src/output.c +++ b/src/output.c @@ -1099,6 +1099,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) { @@ -1107,7 +1125,7 @@ output_nearest_to(int lx, int ly) &closest_x, &closest_y); return output_from_wlr_output(wlr_output_layout_output_at(server.output_layout, - closest_x, closest_y)); + closest_x, closest_y)); } struct output * @@ -1258,12 +1276,28 @@ 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; + } + } + /** + * 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); break;