From 2891ff245e163339002e77c8d7c8a78544707353 Mon Sep 17 00:00:00 2001 From: Johan Malm Date: Fri, 25 Feb 2022 22:31:24 +0000 Subject: [PATCH] Add node-descriptor for wlr_scene_nodes Support identification of wlr_scene_node role to enable simplification of codebase including the avoidance of iterating over lists of layer-surface, menuitems, and so on. Use node-descriptors for xdg toplevels and popups --- include/node-descriptor.h | 23 +++++++++++++++++++++++ src/desktop.c | 26 ++++++++++++++++++++++---- src/meson.build | 1 + src/node-descriptor.c | 37 +++++++++++++++++++++++++++++++++++++ src/xdg-popup.c | 3 +++ src/xdg.c | 4 +++- src/xwayland.c | 4 +++- 7 files changed, 92 insertions(+), 6 deletions(-) create mode 100644 include/node-descriptor.h create mode 100644 src/node-descriptor.c diff --git a/include/node-descriptor.h b/include/node-descriptor.h new file mode 100644 index 00000000..d5225af9 --- /dev/null +++ b/include/node-descriptor.h @@ -0,0 +1,23 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +#ifndef __LABWC_NODE_DESCRIPTOR_H +#define __LABWC_NODE_DESCRIPTOR_H +#include + +enum node_descriptor_type { + LAB_NODE_DESC_NODE = 0, + LAB_NODE_DESC_VIEW, /* *data --> struct view */ + LAB_NODE_DESC_XDG_POPUP, /* *data --> struct view */ + LAB_NODE_DESC_LAYER_SURFACE, /* *data --> struct lab_layer_surface */ + LAB_NODE_DESC_LAYER_POPUP, /* *data --> struct lab_layer_popup */ +}; + +struct node_descriptor { + enum node_descriptor_type type; + void *data; + struct wl_listener destroy; +}; + +void node_descriptor_create(struct wlr_scene_node *node, + enum node_descriptor_type type, void *data); + +#endif /* __LABWC_NODE_DESCRIPTOR_H */ diff --git a/src/desktop.c b/src/desktop.c index e829c701..8e9a4bf0 100644 --- a/src/desktop.c +++ b/src/desktop.c @@ -3,6 +3,7 @@ #include #include "labwc.h" #include "layers.h" +#include "node-descriptor.h" #include "ssd.h" static void @@ -285,7 +286,21 @@ desktop_node_and_view_at(struct server *server, double lx, double ly, } struct wlr_scene_node *osd = &server->osd_tree->node; struct wlr_scene_node *menu = &server->menu_tree->node; - while (node && !node->data) { + while (node) { + struct node_descriptor *desc = node->data; + if (desc) { + if (desc->type == LAB_NODE_DESC_VIEW) { + goto has_view_data; + } + if (desc->type == LAB_NODE_DESC_XDG_POPUP) { + goto has_view_data; + } + if (desc->type == LAB_NODE_DESC_LAYER_POPUP) { + /* FIXME: we shouldn't have to set *view_area */ + *view_area = LAB_SSD_LAYER_SURFACE; + return NULL; + } + } if (node == osd) { *view_area = LAB_SSD_OSD; return NULL; @@ -297,10 +312,13 @@ desktop_node_and_view_at(struct server *server, double lx, double ly, } if (!node) { wlr_log(WLR_ERROR, "Unknown node detected"); - *view_area = LAB_SSD_NONE; - return NULL; } - struct view *view = node->data; + *view_area = LAB_SSD_NONE; + return NULL; + +has_view_data: + struct node_descriptor *desc = node->data; + struct view *view = desc->data; *view_area = ssd_get_part_type(view, *scene_node); return view; } diff --git a/src/meson.build b/src/meson.build index b318de8f..d690a63e 100644 --- a/src/meson.build +++ b/src/meson.build @@ -11,6 +11,7 @@ labwc_sources = files( 'key-state.c', 'layers.c', 'main.c', + 'node-descriptor.c', 'osd.c', 'output.c', 'resistance.c', diff --git a/src/node-descriptor.c b/src/node-descriptor.c new file mode 100644 index 00000000..efbcb048 --- /dev/null +++ b/src/node-descriptor.c @@ -0,0 +1,37 @@ +// SPDX-License-Identifier: GPL-2.0-only +#include +#include "node-descriptor.h" + +static void +descriptor_destroy(struct node_descriptor *node_descriptor) +{ + if (!node_descriptor) { + return; + } + wl_list_remove(&node_descriptor->destroy.link); + free(node_descriptor); +} + +static void +destroy_notify(struct wl_listener *listener, void *data) +{ + struct node_descriptor *node_descriptor = + wl_container_of(listener, node_descriptor, destroy); + descriptor_destroy(node_descriptor); +} + +void +node_descriptor_create(struct wlr_scene_node *node, + enum node_descriptor_type type, void *data) +{ + struct node_descriptor *node_descriptor = + calloc(1, sizeof(struct node_descriptor)); + if (!node_descriptor) { + return; + } + node_descriptor->type = type; + node_descriptor->data = data; + node_descriptor->destroy.notify = destroy_notify; + wl_signal_add(&node->events.destroy, &node_descriptor->destroy); + node->data = node_descriptor; +} diff --git a/src/xdg-popup.c b/src/xdg-popup.c index df500a8a..239a1332 100644 --- a/src/xdg-popup.c +++ b/src/xdg-popup.c @@ -8,6 +8,7 @@ */ #include "labwc.h" +#include "node-descriptor.h" struct view_child { struct wlr_surface *surface; @@ -93,6 +94,8 @@ xdg_popup_create(struct view *view, struct wlr_xdg_popup *wlr_popup) struct wlr_scene_node *parent_node = parent->surface->data; wlr_popup->base->surface->data = wlr_scene_xdg_surface_create(parent_node, wlr_popup->base); + node_descriptor_create(wlr_popup->base->surface->data, + LAB_NODE_DESC_XDG_POPUP, view); popup_unconstrain(view, wlr_popup); } diff --git a/src/xdg.c b/src/xdg.c index 5ab801f3..7b433c4a 100644 --- a/src/xdg.c +++ b/src/xdg.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-only #include #include "labwc.h" +#include "node-descriptor.h" #include "ssd.h" static void @@ -404,7 +405,8 @@ xdg_surface_new(struct wl_listener *listener, void *data) wl_resource_post_no_memory(view->surface->resource); return; } - view->scene_tree->node.data = view; + node_descriptor_create(&view->scene_tree->node, + LAB_NODE_DESC_VIEW, view); /* In support of xdg_toplevel_decoration */ xdg_surface->data = view; diff --git a/src/xwayland.c b/src/xwayland.c index 1dfb574a..f6756e4d 100644 --- a/src/xwayland.c +++ b/src/xwayland.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-only #include #include "labwc.h" +#include "node-descriptor.h" #include "ssd.h" static void @@ -394,7 +395,8 @@ xwayland_surface_new(struct wl_listener *listener, void *data) view->xwayland_surface = xsurface; view->scene_tree = wlr_scene_tree_create(&view->server->view_tree->node); - view->scene_tree->node.data = view; + node_descriptor_create(&view->scene_tree->node, + LAB_NODE_DESC_VIEW, view); xsurface->data = view; view->map.notify = handle_map;