From cd8b4ace926bd5a5289a5d5d6f6dddc1e4732287 Mon Sep 17 00:00:00 2001 From: Brian Ashworth Date: Sat, 23 Mar 2019 17:24:53 -0400 Subject: [PATCH] fix opening a floating view on the NOOP output Since the NOOP output has no size, the minimum floating size is greater than the workspace size for the NOOP output. In this case, the floater gets centered in the output instead of the workspace. However, the NOOP output is not part of the output layout and thus has a NULL box. Attempting to access the properties of this box was causing a segfault. This fixes the issue by just setting the floater's box to all zeroes when mapping on the NOOP output. When the workspace gets moved from the NOOP output to a new output, any floater whose width or height is zero or has an x or y location outside of the output, gets passed to `container_init_floating` again. This will then set the appropriate size and centering. For any floater that has a valid size and location, they are preserved. --- sway/tree/container.c | 15 +++++++++++---- sway/tree/output.c | 21 +++++++++++++++++++++ 2 files changed, 32 insertions(+), 4 deletions(-) diff --git a/sway/tree/container.c b/sway/tree/container.c index 93cff7ff..f84ce360 100644 --- a/sway/tree/container.c +++ b/sway/tree/container.c @@ -651,6 +651,17 @@ void floating_calculate_constraints(int *min_width, int *max_width, void container_init_floating(struct sway_container *con) { struct sway_workspace *ws = con->workspace; + struct wlr_box *ob = wlr_output_layout_get_box(root->output_layout, + ws->output->wlr_output); + if (!ob) { + // On NOOP output. Will be called again when moved to an output + con->x = 0; + con->y = 0; + con->width = 0; + con->height = 0; + return; + } + int min_width, max_width, min_height, max_height; floating_calculate_constraints(&min_width, &max_width, &min_height, &max_height); @@ -659,8 +670,6 @@ void container_init_floating(struct sway_container *con) { con->width = max_width; con->height = max_height; if (con->width > ws->width || con->height > ws->height) { - struct wlr_box *ob = wlr_output_layout_get_box(root->output_layout, - ws->output->wlr_output); con->x = ob->x + (ob->width - con->width) / 2; con->y = ob->y + (ob->height - con->height) / 2; } else { @@ -675,8 +684,6 @@ void container_init_floating(struct sway_container *con) { fmax(min_height, fmin(view->natural_height, max_height)); if (con->content_width > ws->width || con->content_height > ws->height) { - struct wlr_box *ob = wlr_output_layout_get_box(root->output_layout, - ws->output->wlr_output); con->content_x = ob->x + (ob->width - con->content_width) / 2; con->content_y = ob->y + (ob->height - con->content_height) / 2; } else { diff --git a/sway/tree/output.c b/sway/tree/output.c index 1202ba3c..7867c6bc 100644 --- a/sway/tree/output.c +++ b/sway/tree/output.c @@ -60,6 +60,27 @@ static void restore_workspaces(struct sway_output *output) { struct sway_workspace *ws = root->noop_output->workspaces->items[0]; workspace_detach(ws); output_add_workspace(output, ws); + + // If the floater was made floating while on the NOOP output, its width + // and height will be zero and it should be reinitialized as a floating + // container to get the appropriate size and location. Additionally, if + // the floater is wider or taller than the output or is completely + // outside of the output's bounds, do the same as the output layout has + // likely changed and the maximum size needs to be checked and the + // floater re-centered + for (int i = 0; i < ws->floating->length; i++) { + struct sway_container *floater = ws->floating->items[i]; + if (floater->width == 0 || floater->height == 0 || + floater->width > output->width || + floater->height > output->height || + floater->x > output->lx + output->width || + floater->y > output->ly + output->height || + floater->x + floater->width < output->lx || + floater->y + floater->height < output->ly) { + container_init_floating(floater); + } + } + ipc_event_workspace(NULL, ws, "move"); }