tree/container: refactor tiling_container_at to check bounds

This fixes bugs where a floating container would take input way past its
borders when its parent was fullscreen, since the call to
`tiling_container_at` in input/cursor.c's `node_at_coords` did not check
bounds.
This commit is contained in:
Tudor Brindus 2020-05-29 23:33:03 -04:00 committed by Brian Ashworth
parent 0cbd26f0da
commit 83866558d3

View file

@ -274,14 +274,10 @@ static struct sway_container *container_at_linear(struct sway_node *parent,
list_t *children = node_get_children(parent); list_t *children = node_get_children(parent);
for (int i = 0; i < children->length; ++i) { for (int i = 0; i < children->length; ++i) {
struct sway_container *child = children->items[i]; struct sway_container *child = children->items[i];
struct wlr_box box = { struct sway_container *container =
.x = child->x, tiling_container_at(&child->node, lx, ly, surface, sx, sy);
.y = child->y, if (container) {
.width = child->width, return container;
.height = child->height,
};
if (wlr_box_contains_point(&box, lx, ly)) {
return tiling_container_at(&child->node, lx, ly, surface, sx, sy);
} }
} }
return NULL; return NULL;
@ -303,15 +299,10 @@ static struct sway_container *floating_container_at(double lx, double ly,
// reverse. // reverse.
for (int k = ws->floating->length - 1; k >= 0; --k) { for (int k = ws->floating->length - 1; k >= 0; --k) {
struct sway_container *floater = ws->floating->items[k]; struct sway_container *floater = ws->floating->items[k];
struct wlr_box box = { struct sway_container *container =
.x = floater->x, tiling_container_at(&floater->node, lx, ly, surface, sx, sy);
.y = floater->y, if (container) {
.width = floater->width, return container;
.height = floater->height,
};
if (wlr_box_contains_point(&box, lx, ly)) {
return tiling_container_at(&floater->node, lx, ly,
surface, sx, sy);
} }
} }
} }
@ -319,12 +310,34 @@ static struct sway_container *floating_container_at(double lx, double ly,
return NULL; return NULL;
} }
struct sway_container *view_container_at(struct sway_node *parent,
double lx, double ly,
struct wlr_surface **surface, double *sx, double *sy) {
if (!sway_assert(node_is_view(parent), "Expected a view")) {
return NULL;
}
struct sway_container *container = parent->sway_container;
struct wlr_box box = {
.x = container->x,
.y = container->y,
.width = container->width,
.height = container->height,
};
if (wlr_box_contains_point(&box, lx, ly)) {
surface_at_view(parent->sway_container, lx, ly, surface, sx, sy);
return container;
}
return NULL;
}
struct sway_container *tiling_container_at(struct sway_node *parent, struct sway_container *tiling_container_at(struct sway_node *parent,
double lx, double ly, double lx, double ly,
struct wlr_surface **surface, double *sx, double *sy) { struct wlr_surface **surface, double *sx, double *sy) {
if (node_is_view(parent)) { if (node_is_view(parent)) {
surface_at_view(parent->sway_container, lx, ly, surface, sx, sy); return view_container_at(parent, lx, ly, surface, sx, sy);
return parent->sway_container;
} }
if (!node_get_children(parent)) { if (!node_get_children(parent)) {
return NULL; return NULL;