mirror of
https://github.com/hyprwm/wlroots-hyprland.git
synced 2024-11-05 05:05:57 +01:00
wlr_scene: Introduce scene_nodes_in_box
Will query the scene for all nodes that appear in the given wlr_box. The nodes will be sent to the iterator from closest to farthest from the eye. Refactor wlr_scene_node_at to use this new function.
This commit is contained in:
parent
c2359d0321
commit
7f17774d18
1 changed files with 85 additions and 40 deletions
|
@ -195,6 +195,50 @@ struct wlr_scene_tree *wlr_scene_tree_create(struct wlr_scene_tree *parent) {
|
||||||
|
|
||||||
static void scene_node_get_size(struct wlr_scene_node *node, int *lx, int *ly);
|
static void scene_node_get_size(struct wlr_scene_node *node, int *lx, int *ly);
|
||||||
|
|
||||||
|
typedef bool (*scene_node_box_iterator_func_t)(struct wlr_scene_node *node,
|
||||||
|
int sx, int sy, void *data);
|
||||||
|
|
||||||
|
static bool _scene_nodes_in_box(struct wlr_scene_node *node, struct wlr_box *box,
|
||||||
|
scene_node_box_iterator_func_t iterator, void *user_data, int lx, int ly) {
|
||||||
|
if (!node->enabled) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (node->type) {
|
||||||
|
case WLR_SCENE_NODE_TREE:;
|
||||||
|
struct wlr_scene_tree *scene_tree = scene_tree_from_node(node);
|
||||||
|
struct wlr_scene_node *child;
|
||||||
|
wl_list_for_each_reverse(child, &scene_tree->children, link) {
|
||||||
|
if (_scene_nodes_in_box(child, box, iterator, user_data, lx + child->x, ly + child->y)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case WLR_SCENE_NODE_RECT:
|
||||||
|
case WLR_SCENE_NODE_BUFFER:;
|
||||||
|
struct wlr_box node_box = { .x = lx, .y = ly };
|
||||||
|
scene_node_get_size(node, &node_box.width, &node_box.height);
|
||||||
|
bool intersects;
|
||||||
|
|
||||||
|
intersects = wlr_box_intersection(&node_box, &node_box, box);
|
||||||
|
|
||||||
|
if (intersects && iterator(node, lx, ly, user_data)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool scene_nodes_in_box(struct wlr_scene_node *node, struct wlr_box *box,
|
||||||
|
scene_node_box_iterator_func_t iterator, void *user_data) {
|
||||||
|
int x, y;
|
||||||
|
wlr_scene_node_coords(node, &x, &y);
|
||||||
|
|
||||||
|
return _scene_nodes_in_box(node, box, iterator, user_data, x, y);
|
||||||
|
}
|
||||||
|
|
||||||
// This function must be called whenever the coordinates/dimensions of a scene
|
// This function must be called whenever the coordinates/dimensions of a scene
|
||||||
// buffer or scene output change. It is not necessary to call when a scene
|
// buffer or scene output change. It is not necessary to call when a scene
|
||||||
// buffer's node is enabled/disabled or obscured by other nodes.
|
// buffer's node is enabled/disabled or obscured by other nodes.
|
||||||
|
@ -745,55 +789,56 @@ void wlr_scene_node_for_each_buffer(struct wlr_scene_node *node,
|
||||||
scene_node_for_each_scene_buffer(node, 0, 0, user_iterator, user_data);
|
scene_node_for_each_scene_buffer(node, 0, 0, user_iterator, user_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct wlr_scene_node *wlr_scene_node_at(struct wlr_scene_node *node,
|
struct node_at_data {
|
||||||
double lx, double ly, double *nx, double *ny) {
|
double lx, ly;
|
||||||
if (!node->enabled) {
|
double rx, ry;
|
||||||
return NULL;
|
struct wlr_scene_node *node;
|
||||||
}
|
};
|
||||||
|
|
||||||
// TODO: optimize by storing a bounding box in each node?
|
static bool scene_node_at_iterator(struct wlr_scene_node *node,
|
||||||
lx -= node->x;
|
int lx, int ly, void *data) {
|
||||||
ly -= node->y;
|
struct node_at_data *at_data = data;
|
||||||
|
|
||||||
bool intersects = false;
|
double rx = at_data->lx - lx;
|
||||||
switch (node->type) {
|
double ry = at_data->ly - ly;
|
||||||
case WLR_SCENE_NODE_TREE:;
|
|
||||||
struct wlr_scene_tree *scene_tree = scene_tree_from_node(node);
|
if (node->type == WLR_SCENE_NODE_BUFFER) {
|
||||||
struct wlr_scene_node *child;
|
|
||||||
wl_list_for_each_reverse(child, &scene_tree->children, link) {
|
|
||||||
struct wlr_scene_node *node =
|
|
||||||
wlr_scene_node_at(child, lx, ly, nx, ny);
|
|
||||||
if (node != NULL) {
|
|
||||||
return node;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case WLR_SCENE_NODE_RECT:;
|
|
||||||
int width, height;
|
|
||||||
scene_node_get_size(node, &width, &height);
|
|
||||||
intersects = lx >= 0 && lx < width && ly >= 0 && ly < height;
|
|
||||||
break;
|
|
||||||
case WLR_SCENE_NODE_BUFFER:;
|
|
||||||
struct wlr_scene_buffer *scene_buffer = wlr_scene_buffer_from_node(node);
|
struct wlr_scene_buffer *scene_buffer = wlr_scene_buffer_from_node(node);
|
||||||
|
|
||||||
if (scene_buffer->point_accepts_input) {
|
if (scene_buffer->point_accepts_input &&
|
||||||
intersects = scene_buffer->point_accepts_input(scene_buffer, lx, ly);
|
!scene_buffer->point_accepts_input(scene_buffer, rx, ry)) {
|
||||||
} else {
|
return false;
|
||||||
int width, height;
|
|
||||||
scene_node_get_size(node, &width, &height);
|
|
||||||
intersects = lx >= 0 && lx < width && ly >= 0 && ly < height;
|
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (intersects) {
|
at_data->rx = rx;
|
||||||
if (nx != NULL) {
|
at_data->ry = ry;
|
||||||
*nx = lx;
|
at_data->node = node;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
if (ny != NULL) {
|
|
||||||
*ny = ly;
|
struct wlr_scene_node *wlr_scene_node_at(struct wlr_scene_node *node,
|
||||||
|
double lx, double ly, double *nx, double *ny) {
|
||||||
|
struct wlr_box box = {
|
||||||
|
.x = floor(lx),
|
||||||
|
.y = floor(ly),
|
||||||
|
.width = 1,
|
||||||
|
.height = 1
|
||||||
|
};
|
||||||
|
|
||||||
|
struct node_at_data data = {
|
||||||
|
.lx = lx,
|
||||||
|
.ly = ly
|
||||||
|
};
|
||||||
|
|
||||||
|
if (scene_nodes_in_box(node, &box, scene_node_at_iterator, &data)) {
|
||||||
|
if (nx) {
|
||||||
|
*nx = data.rx;
|
||||||
}
|
}
|
||||||
return node;
|
if (ny) {
|
||||||
|
*ny = data.ry;
|
||||||
|
}
|
||||||
|
return data.node;
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
Loading…
Reference in a new issue