Fix xwayland configure request scratchpad crash

This fixes a crash in `container_init_floating` when a xwayland view
sends a configure request while in the scratchpad.

`container_init_floating` gets called so the configured minimum and
maximum sizes gets respected when resizing to the requested size. Since
the workspace was NULL, it would SIGSEGV when attempting to get the
workspace's output for the output box retrieval.

This extracts the resizing portion of `container_init_floating` into a
separate function. If the container is in the scratchpad, it will just
be resized and skip the centering.

Additionally, `container_init_floating` has been renamed to
`container_floating_resize_and_center` to more accurately describe what
it does.
This commit is contained in:
Brian Ashworth 2019-03-27 14:00:19 -04:00 committed by emersion
parent 31eeda11b0
commit dd28e6a6d6
5 changed files with 31 additions and 29 deletions

View file

@ -215,10 +215,7 @@ size_t container_titlebar_height(void);
void floating_calculate_constraints(int *min_width, int *max_width, void floating_calculate_constraints(int *min_width, int *max_width,
int *min_height, int *max_height); int *min_height, int *max_height);
/** void container_floating_resize_and_center(struct sway_container *con);
* Resize and center the container in its workspace.
*/
void container_init_floating(struct sway_container *container);
void container_set_floating(struct sway_container *container, bool enable); void container_set_floating(struct sway_container *container, bool enable);

View file

@ -435,7 +435,7 @@ static void handle_request_configure(struct wl_listener *listener, void *data) {
// Respect minimum and maximum sizes // Respect minimum and maximum sizes
view->natural_width = ev->width; view->natural_width = ev->width;
view->natural_height = ev->height; view->natural_height = ev->height;
container_init_floating(view->container); container_floating_resize_and_center(view->container);
configure(view, view->container->content_x, configure(view, view->container->content_x,
view->container->content_y, view->container->content_y,

View file

@ -649,8 +649,31 @@ void floating_calculate_constraints(int *min_width, int *max_width,
} }
void container_init_floating(struct sway_container *con) { static void floating_natural_resize(struct sway_container *con) {
int min_width, max_width, min_height, max_height;
floating_calculate_constraints(&min_width, &max_width,
&min_height, &max_height);
if (!con->view) {
con->width = max_width;
con->height = max_height;
} else {
struct sway_view *view = con->view;
con->content_width =
fmax(min_width, fmin(view->natural_width, max_width));
con->content_height =
fmax(min_height, fmin(view->natural_height, max_height));
container_set_geometry_from_content(con);
}
}
void container_floating_resize_and_center(struct sway_container *con) {
struct sway_workspace *ws = con->workspace; struct sway_workspace *ws = con->workspace;
if (!ws) {
// On scratchpad, just resize
floating_natural_resize(con);
return;
}
struct wlr_box *ob = wlr_output_layout_get_box(root->output_layout, struct wlr_box *ob = wlr_output_layout_get_box(root->output_layout,
ws->output->wlr_output); ws->output->wlr_output);
if (!ob) { if (!ob) {
@ -662,13 +685,8 @@ void container_init_floating(struct sway_container *con) {
return; return;
} }
int min_width, max_width, min_height, max_height; floating_natural_resize(con);
floating_calculate_constraints(&min_width, &max_width,
&min_height, &max_height);
if (!con->view) { if (!con->view) {
con->width = max_width;
con->height = max_height;
if (con->width > ws->width || con->height > ws->height) { if (con->width > ws->width || con->height > ws->height) {
con->x = ob->x + (ob->width - con->width) / 2; con->x = ob->x + (ob->width - con->width) / 2;
con->y = ob->y + (ob->height - con->height) / 2; con->y = ob->y + (ob->height - con->height) / 2;
@ -677,11 +695,6 @@ void container_init_floating(struct sway_container *con) {
con->y = ws->y + (ws->height - con->height) / 2; con->y = ws->y + (ws->height - con->height) / 2;
} }
} else { } else {
struct sway_view *view = con->view;
con->content_width =
fmax(min_width, fmin(view->natural_width, max_width));
con->content_height =
fmax(min_height, fmin(view->natural_height, max_height));
if (con->content_width > ws->width if (con->content_width > ws->width
|| con->content_height > ws->height) { || con->content_height > ws->height) {
con->content_x = ob->x + (ob->width - con->content_width) / 2; con->content_x = ob->x + (ob->width - con->content_width) / 2;
@ -711,7 +724,7 @@ void container_set_floating(struct sway_container *container, bool enable) {
struct sway_container *old_parent = container->parent; struct sway_container *old_parent = container->parent;
container_detach(container); container_detach(container);
workspace_add_floating(workspace, container); workspace_add_floating(workspace, container);
container_init_floating(container); container_floating_resize_and_center(container);
if (container->view) { if (container->view) {
view_set_tiled(container->view, false); view_set_tiled(container->view, false);
if (container->view->using_csd) { if (container->view->using_csd) {
@ -995,7 +1008,7 @@ void container_fullscreen_disable(struct sway_container *con) {
// criteria, it needs to be reinitialized as floating to get the proper // criteria, it needs to be reinitialized as floating to get the proper
// size and location // size and location
if (container_is_floating(con) && (con->width == 0 || con->height == 0)) { if (container_is_floating(con) && (con->width == 0 || con->height == 0)) {
container_init_floating(con); container_floating_resize_and_center(con);
} }
con->fullscreen_mode = FULLSCREEN_NONE; con->fullscreen_mode = FULLSCREEN_NONE;

View file

@ -77,7 +77,7 @@ static void restore_workspaces(struct sway_output *output) {
floater->y > output->ly + output->height || floater->y > output->ly + output->height ||
floater->x + floater->width < output->lx || floater->x + floater->width < output->lx ||
floater->y + floater->height < output->ly) { floater->y + floater->height < output->ly) {
container_init_floating(floater); container_floating_resize_and_center(floater);
} }
} }

View file

@ -124,15 +124,7 @@ void root_scratchpad_show(struct sway_container *con) {
struct wlr_box workspace_box; struct wlr_box workspace_box;
workspace_get_box(new_ws, &workspace_box); workspace_get_box(new_ws, &workspace_box);
if (!wlr_box_contains_point(&workspace_box, center_lx, center_ly)) { if (!wlr_box_contains_point(&workspace_box, center_lx, center_ly)) {
// Maybe resize it container_floating_resize_and_center(con);
if (con->width > new_ws->width || con->height > new_ws->height) {
container_init_floating(con);
}
// Center it
double new_lx = new_ws->x + (new_ws->width - con->width) / 2;
double new_ly = new_ws->y + (new_ws->height - con->height) / 2;
container_floating_move_to(con, new_lx, new_ly);
} }
arrange_workspace(new_ws); arrange_workspace(new_ws);