From 0f6d5cc26a9d76954f995b82addfd5e9aac963b9 Mon Sep 17 00:00:00 2001 From: John Lindgren Date: Thu, 1 Aug 2024 22:15:27 -0400 Subject: [PATCH] view: stay fullscreen when view's output is disconnected I intended to fix this quite some time ago but didn't get around to it. I don't think there's any good reason why we need to un-fullscreen a view when its output is disconnected. We can handle it the same as a maximized view, and move it to a new output (remaining fullscreen) or, if all outputs are disconnected, just leave it as-is. This is helpful for a media-center use-case, where you have just one view (e.g. Kodi) fullscreen all the time, but the TV might appear to be disconnected if you switch it to a different source. Tested with a couple different scenarios: 1. Single output disconnected and re-connected: view stayed fullscreen. 2. Secondary output disconnected: view stayed fullscreen but moved to the primary output, and the layer-shell panel on that output was hidden as expected. When the secondary output was re-connected, the view was moved back (still fullscreen) and the panel on the primary appeared again. Fixes: #864 --- src/view.c | 35 +++++++++++++---------------------- 1 file changed, 13 insertions(+), 22 deletions(-) diff --git a/src/view.c b/src/view.c index 8dd5e796..d6668d8a 100644 --- a/src/view.c +++ b/src/view.c @@ -349,7 +349,6 @@ static bool view_discover_output(struct view *view, struct wlr_box *geometry) { assert(view); - assert(!view->fullscreen); if (!geometry) { geometry = &view->current; @@ -362,6 +361,10 @@ view_discover_output(struct view *view, struct wlr_box *geometry) if (output && output != view->output) { view->output = output; + /* Show fullscreen views above top-layer */ + if (view->fullscreen) { + desktop_update_top_layer_visiblity(view->server); + } return true; } @@ -409,12 +412,15 @@ void view_set_output(struct view *view, struct output *output) { assert(view); - assert(!view->fullscreen); if (!output_is_usable(output)) { wlr_log(WLR_ERROR, "invalid output set for view"); return; } view->output = output; + /* Show fullscreen views above top-layer */ + if (view->fullscreen) { + desktop_update_top_layer_visiblity(view->server); + } } void @@ -1701,23 +1707,14 @@ view_adjust_for_layout_change(struct view *view) { assert(view); - bool was_fullscreen = view->fullscreen; bool is_floating = view_is_floating(view); + bool use_natural = false; if (!output_is_usable(view->output)) { /* A view losing an output should have a last-layout geometry */ update_last_layout_geometry(view); - - /* Exit fullscreen and re-assess floating status */ - if (was_fullscreen) { - set_fullscreen(view, false); - is_floating = view_is_floating(view); - } } - /* Restore any full-screen window to natural geometry */ - bool use_natural = was_fullscreen; - /* Capture a pointer to the last-layout geometry (only if valid) */ struct wlr_box *last_geometry = NULL; if (last_layout_geometry_is_valid(view)) { @@ -1757,8 +1754,8 @@ view_adjust_for_layout_change(struct view *view) view_apply_special_geometry(view); } else if (use_natural) { /* - * Move the window to its natural location, either because it - * was fullscreen or we are trying to restore a prior layout. + * Move the window to its natural location, because + * we are trying to restore a prior layout. */ view_apply_natural_geometry(view); } else { @@ -1788,11 +1785,6 @@ void view_on_output_destroy(struct view *view) { assert(view); - /* - * This is the only time we modify view->output for a fullscreen - * view. We expect view_adjust_for_layout_change() to be called - * shortly afterward, which will exit fullscreen. - */ view->output = NULL; } @@ -2194,9 +2186,6 @@ void view_move_to_output(struct view *view, struct output *output) { assert(view); - if (view->fullscreen) { - return; - } view_invalidate_last_layout_geometry(view); view_set_output(view, output); @@ -2206,6 +2195,8 @@ view_move_to_output(struct view *view, struct output *output) view->pending.y = output_area.y; view_place_by_policy(view, /* allow_cursor */ false, rc.placement_policy); + } else if (view->fullscreen) { + view_apply_fullscreen_geometry(view); } else if (view->maximized != VIEW_AXIS_NONE) { view_apply_maximized_geometry(view); } else if (view->tiled) {