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.
This commit is contained in:
Brian Ashworth 2019-03-23 17:24:53 -04:00 committed by emersion
parent 7d2076cbff
commit cd8b4ace92
2 changed files with 32 additions and 4 deletions

View file

@ -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 {

View file

@ -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");
}