From f12957177923153c2f611814abb5a8bd32270eaa Mon Sep 17 00:00:00 2001 From: John Lindgren Date: Wed, 3 Sep 2025 05:32:44 -0400 Subject: [PATCH] ssd: unify struct ssd_part with struct node_descriptor struct ssd_part and struct node_descriptor seem to have essentially the same purpose: tag a wlr_scene_node with some extra data indicating what we're using it for. Also, as with enum ssd_part_type (now lab_node_type), ssd_part is used for several types of nodes that are not part of SSD. So instead of the current chaining (node_descriptor -> ssd_part), let's flatten/unify the two structs. In detail: - First, merge node_descriptor_type into lab_node_type. - Add a separate view pointer in node_descriptor, since in the case of SSD buttons we need separate view and button data pointers. - Rename ssd_part_button to simply ssd_button. It no longer contains an ssd_part as base. - Add node_try_ssd_button_from_node() which replaces node_ssd_part_from_node() + button_try_from_ssd_part(). - Factor out ssd_button_free() to be called in node descriptor destroy. - Finally, get_cursor_context() needs a little reorganization to handle the unified structs. Overall, this simplifies the code a bit, and in my opinion makes it easier to understand. No functional change intended. --- include/common/node-type.h | 13 ++++- include/labwc.h | 2 +- include/node.h | 52 ++++++------------- include/ssd-internal.h | 22 ++------ include/ssd.h | 5 +- src/desktop.c | 76 +++++++++++++++------------- src/edges.c | 2 +- src/input/cursor.c | 4 +- src/input/ime.c | 3 +- src/layers.c | 4 +- src/menu/menu.c | 12 ++--- src/node.c | 56 ++++++++++---------- src/output.c | 8 +-- src/scaled-buffer/scaled-buffer.c | 2 +- src/session-lock.c | 2 +- src/ssd/meson.build | 2 +- src/ssd/{ssd-part.c => ssd-button.c} | 64 ++++------------------- src/ssd/ssd-titlebar.c | 53 +++++++++---------- src/ssd/ssd.c | 19 ++----- src/xdg-popup.c | 2 +- src/xdg.c | 2 +- src/xwayland.c | 3 +- 22 files changed, 169 insertions(+), 239 deletions(-) rename src/ssd/{ssd-part.c => ssd-button.c} (61%) diff --git a/include/common/node-type.h b/include/common/node-type.h index 92e7f4b9..0afa5f58 100644 --- a/include/common/node-type.h +++ b/include/common/node-type.h @@ -46,12 +46,23 @@ enum lab_node_type { LAB_NODE_CLIENT, LAB_NODE_FRAME, LAB_NODE_ROOT, - LAB_NODE_MENU, + LAB_NODE_MENUITEM, LAB_NODE_OSD, LAB_NODE_LAYER_SURFACE, LAB_NODE_LAYER_SUBSURFACE, LAB_NODE_UNMANAGED, LAB_NODE_ALL, + + /* translated to LAB_NODE_CLIENT by get_cursor_context() */ + LAB_NODE_VIEW, + LAB_NODE_XDG_POPUP, + LAB_NODE_LAYER_POPUP, + LAB_NODE_SESSION_LOCK_SURFACE, + LAB_NODE_IME_POPUP, + + /* never returned by get_cursor_context() */ + LAB_NODE_TREE, + LAB_NODE_SCALED_BUFFER, }; enum lab_node_type node_type_parse(const char *context); diff --git a/include/labwc.h b/include/labwc.h index 98e33575..2509292e 100644 --- a/include/labwc.h +++ b/include/labwc.h @@ -225,7 +225,7 @@ struct server { */ struct view *active_view; - struct ssd_part_button *hovered_button; + struct ssd_button *hovered_button; /* Tree for all non-layer xdg/xwayland-shell surfaces */ struct wlr_scene_tree *view_tree; diff --git a/include/node.h b/include/node.h index d28a8517..7e8b6b50 100644 --- a/include/node.h +++ b/include/node.h @@ -2,30 +2,11 @@ #ifndef LABWC_NODE_DESCRIPTOR_H #define LABWC_NODE_DESCRIPTOR_H #include - -struct view; -struct lab_layer_surface; -struct lab_layer_popup; -struct menuitem; -struct ssd_part; -struct scaled_buffer; - -enum node_descriptor_type { - LAB_NODE_DESC_NODE = 0, - LAB_NODE_DESC_VIEW, - LAB_NODE_DESC_XDG_POPUP, - LAB_NODE_DESC_LAYER_SURFACE, - LAB_NODE_DESC_LAYER_POPUP, - LAB_NODE_DESC_SESSION_LOCK_SURFACE, - LAB_NODE_DESC_IME_POPUP, - LAB_NODE_DESC_MENUITEM, - LAB_NODE_DESC_TREE, - LAB_NODE_DESC_SCALED_BUFFER, - LAB_NODE_DESC_SSD_PART, -}; +#include "common/node-type.h" struct node_descriptor { - enum node_descriptor_type type; + enum lab_node_type type; + struct view *view; void *data; struct wl_listener destroy; }; @@ -38,16 +19,15 @@ struct node_descriptor { * * @scene_node: wlr_scene_node to attached node_descriptor to * @type: node descriptor type + * @view: associated view * @data: struct to point to as follows: - * - LAB_NODE_DESC_VIEW struct view - * - LAB_NODE_DESC_XDG_POPUP struct view - * - LAB_NODE_DESC_LAYER_SURFACE struct lab_layer_surface - * - LAB_NODE_DESC_LAYER_POPUP struct lab_layer_popup - * - LAB_NODE_DESC_MENUITEM struct menuitem - * - LAB_NODE_DESC_SSD_PART struct ssd_part + * - LAB_NODE_LAYER_SURFACE struct lab_layer_surface + * - LAB_NODE_LAYER_POPUP struct lab_layer_popup + * - LAB_NODE_MENUITEM struct menuitem + * - LAB_NODE_BUTTON_* struct ssd_button */ void node_descriptor_create(struct wlr_scene_node *scene_node, - enum node_descriptor_type type, void *data); + enum lab_node_type type, struct view *view, void *data); /** * node_view_from_node - return view struct from node @@ -76,13 +56,6 @@ struct lab_layer_popup *node_layer_popup_from_node( struct menuitem *node_menuitem_from_node( struct wlr_scene_node *wlr_scene_node); -/** - * node_ssd_part_from_node - return ssd_part struct from node - * @wlr_scene_node: wlr_scene_node from which to return data - */ -struct ssd_part *node_ssd_part_from_node( - struct wlr_scene_node *wlr_scene_node); - /** * node_scaled_buffer_from_node - return scaled_buffer from node * @wlr_scene_node: wlr_scene_node from which to return data @@ -90,4 +63,11 @@ struct ssd_part *node_ssd_part_from_node( struct scaled_buffer *node_scaled_buffer_from_node( struct wlr_scene_node *wlr_scene_node); +/** + * node_try_ssd_button_from_node - return ssd_button or NULL from node + * @wlr_scene_node: wlr_scene_node from which to return data + */ +struct ssd_button *node_try_ssd_button_from_node( + struct wlr_scene_node *wlr_scene_node); + #endif /* LABWC_NODE_DESCRIPTOR_H */ diff --git a/include/ssd-internal.h b/include/ssd-internal.h index d1af095e..22f8ae45 100644 --- a/include/ssd-internal.h +++ b/include/ssd-internal.h @@ -135,23 +135,10 @@ struct ssd { struct border margin; }; -/* - * ssd_part wraps a scene-node with ssd-specific information and can be - * accessed with node_ssd_part_from_node(wlr_scene_node *). - * This allows get_cursor_context() in desktop.c to see which SSD part is under - * the cursor. - */ -struct ssd_part { - enum lab_node_type type; - struct view *view; - - /* This part represented in scene graph */ +struct ssd_button { struct wlr_scene_node *node; - struct wl_listener node_destroy; -}; + enum lab_node_type type; -struct ssd_part_button { - struct ssd_part base; /* * Bitmap of lab_button_state that represents a combination of * hover/toggled/rounded states. @@ -177,13 +164,10 @@ struct wlr_buffer; struct wlr_scene_tree; /* SSD internal helpers to create various SSD elements */ -struct ssd_part *attach_ssd_part(enum lab_node_type type, struct view *view, - struct wlr_scene_node *node); -struct ssd_part_button *attach_ssd_part_button(struct wl_list *button_parts, +struct ssd_button *attach_ssd_button(struct wl_list *button_parts, enum lab_node_type type, struct wlr_scene_tree *parent, struct lab_img *imgs[LAB_BS_ALL + 1], int x, int y, struct view *view); -struct ssd_part_button *button_try_from_ssd_part(struct ssd_part *part); /* SSD internal */ void ssd_titlebar_create(struct ssd *ssd); diff --git a/include/ssd.h b/include/ssd.h index 11fae7ab..7ae9ff1a 100644 --- a/include/ssd.h +++ b/include/ssd.h @@ -25,7 +25,7 @@ struct wlr_cursor; /* Forward declare arguments */ struct server; struct ssd; -struct ssd_part; +struct ssd_button; struct view; struct wlr_scene; struct wlr_scene_node; @@ -55,8 +55,7 @@ void ssd_enable_shade(struct ssd *ssd, bool enable); void ssd_update_hovered_button(struct server *server, struct wlr_scene_node *node); -enum lab_node_type ssd_part_get_type(const struct ssd_part *part); -struct view *ssd_part_get_view(const struct ssd_part *part); +void ssd_button_free(struct ssd_button *button); /* Public SSD helpers */ diff --git a/src/desktop.c b/src/desktop.c index f312c765..bb9b5dfd 100644 --- a/src/desktop.c +++ b/src/desktop.c @@ -247,11 +247,11 @@ get_surface_from_layer_node(struct wlr_scene_node *node) { assert(node->data); struct node_descriptor *desc = (struct node_descriptor *)node->data; - if (desc->type == LAB_NODE_DESC_LAYER_SURFACE) { + if (desc->type == LAB_NODE_LAYER_SURFACE) { struct lab_layer_surface *surface; surface = node_layer_surface_from_node(node); return surface->scene_layer_surface->layer_surface->surface; - } else if (desc->type == LAB_NODE_DESC_LAYER_POPUP) { + } else if (desc->type == LAB_NODE_LAYER_POPUP) { struct lab_layer_popup *popup; popup = node_layer_popup_from_node(node); return popup->wlr_popup->base->surface; @@ -299,9 +299,9 @@ get_cursor_context(struct server *server) struct node_descriptor *desc = node->data; if (desc) { switch (desc->type) { - case LAB_NODE_DESC_VIEW: - case LAB_NODE_DESC_XDG_POPUP: - ret.view = desc->data; + case LAB_NODE_VIEW: + case LAB_NODE_XDG_POPUP: + ret.view = desc->view; if (ret.node->type == WLR_SCENE_NODE_BUFFER && lab_wlr_surface_from_node(ret.node)) { ret.type = LAB_NODE_CLIENT; @@ -311,10 +311,43 @@ get_cursor_context(struct server *server) wlr_log(WLR_ERROR, "cursor not on client or ssd"); } return ret; - case LAB_NODE_DESC_SSD_PART: { - struct ssd_part *part = node_ssd_part_from_node(node); + case LAB_NODE_LAYER_SURFACE: ret.node = node; - ret.view = ssd_part_get_view(part); + ret.type = LAB_NODE_LAYER_SURFACE; + ret.surface = get_surface_from_layer_node(node); + return ret; + case LAB_NODE_LAYER_POPUP: + ret.node = node; + ret.type = LAB_NODE_CLIENT; + ret.surface = get_surface_from_layer_node(node); + return ret; + case LAB_NODE_SESSION_LOCK_SURFACE: /* fallthrough */ + case LAB_NODE_IME_POPUP: + ret.type = LAB_NODE_CLIENT; + ret.surface = lab_wlr_surface_from_node(ret.node); + return ret; + case LAB_NODE_MENUITEM: + /* Always return the top scene node for menu items */ + ret.node = node; + ret.type = LAB_NODE_MENUITEM; + return ret; + case LAB_NODE_TREE: + case LAB_NODE_SCALED_BUFFER: + /* Continue to parent node */ + break; + default: + /* + * All other node descriptors (buttons, title, + * etc.) should have an associated view. + */ + if (!desc->view) { + wlr_log(WLR_ERROR, "cursor not on any view " + "(node type %d)", desc->type); + return ret; + } + + ret.node = node; + ret.view = desc->view; /* Detect mouse contexts like Top, Left and TRCorner */ ret.type = ssd_get_resizing_type(ret.view->ssd, cursor); @@ -323,36 +356,11 @@ get_cursor_context(struct server *server) * Otherwise, detect mouse contexts like * Title, Titlebar and Iconify */ - ret.type = ssd_part_get_type(part); + ret.type = desc->type; } return ret; } - case LAB_NODE_DESC_LAYER_SURFACE: - ret.node = node; - ret.type = LAB_NODE_LAYER_SURFACE; - ret.surface = get_surface_from_layer_node(node); - return ret; - case LAB_NODE_DESC_LAYER_POPUP: - ret.node = node; - ret.type = LAB_NODE_CLIENT; - ret.surface = get_surface_from_layer_node(node); - return ret; - case LAB_NODE_DESC_SESSION_LOCK_SURFACE: /* fallthrough */ - case LAB_NODE_DESC_IME_POPUP: - ret.type = LAB_NODE_CLIENT; - ret.surface = lab_wlr_surface_from_node(ret.node); - return ret; - case LAB_NODE_DESC_MENUITEM: - /* Always return the top scene node for menu items */ - ret.node = node; - ret.type = LAB_NODE_MENU; - return ret; - case LAB_NODE_DESC_NODE: - case LAB_NODE_DESC_TREE: - case LAB_NODE_DESC_SCALED_BUFFER: - break; - } } /* Edge-case nodes without node-descriptors */ diff --git a/src/edges.c b/src/edges.c index f59107cf..79532226 100644 --- a/src/edges.c +++ b/src/edges.c @@ -314,7 +314,7 @@ subtract_node_tree(struct wlr_scene_tree *tree, pixman_region32_t *available, } node_desc = node->data; - if (node_desc && node_desc->type == LAB_NODE_DESC_VIEW) { + if (node_desc && node_desc->type == LAB_NODE_VIEW) { view = node_view_from_node(node); if (view != ignored_view) { subtract_view_from_space(view, available); diff --git a/src/input/cursor.c b/src/input/cursor.c index f25bce2d..42757128 100644 --- a/src/input/cursor.c +++ b/src/input/cursor.c @@ -609,7 +609,7 @@ cursor_process_motion(struct server *server, uint32_t time, double *sx, double * struct cursor_context ctx = get_cursor_context(server); struct seat *seat = &server->seat; - if (ctx.type == LAB_NODE_MENU) { + if (ctx.type == LAB_NODE_MENUITEM) { menu_process_cursor_motion(ctx.node); cursor_set(&server->seat, LAB_CURSOR_DEFAULT); return false; @@ -1173,7 +1173,7 @@ cursor_process_button_release(struct seat *seat, uint32_t button, if (server->input_mode == LAB_INPUT_STATE_MENU) { /* TODO: take into account overflow of time_msec */ if (time_msec - press_msec > rc.menu_ignore_button_release_period) { - if (ctx.type == LAB_NODE_MENU) { + if (ctx.type == LAB_NODE_MENUITEM) { menu_call_selected_actions(server); } else { menu_close_root(server); diff --git a/src/input/ime.c b/src/input/ime.c index f6e0ac99..fb88ee15 100644 --- a/src/input/ime.c +++ b/src/input/ime.c @@ -393,7 +393,8 @@ handle_input_method_new_popup_surface(struct wl_listener *listener, void *data) popup->tree = wlr_scene_subsurface_tree_create( relay->popup_tree, popup->popup_surface->surface); - node_descriptor_create(&popup->tree->node, LAB_NODE_DESC_IME_POPUP, NULL); + node_descriptor_create(&popup->tree->node, LAB_NODE_IME_POPUP, + /*view*/ NULL, /*data*/ NULL); wl_list_insert(&relay->popups, &popup->link); diff --git a/src/layers.c b/src/layers.c index d22c16ad..685f8973 100644 --- a/src/layers.c +++ b/src/layers.c @@ -473,7 +473,7 @@ create_popup(struct server *server, struct wlr_xdg_popup *wlr_popup, wlr_popup->base->surface->data = popup->scene_tree; node_descriptor_create(&popup->scene_tree->node, - LAB_NODE_DESC_LAYER_POPUP, popup); + LAB_NODE_LAYER_POPUP, /*view*/ NULL, popup); popup->destroy.notify = handle_popup_destroy; wl_signal_add(&wlr_popup->events.destroy, &popup->destroy); @@ -624,7 +624,7 @@ handle_new_layer_surface(struct wl_listener *listener, void *data) layer_surface->surface->data = surface->scene_layer_surface->tree; node_descriptor_create(&surface->scene_layer_surface->tree->node, - LAB_NODE_DESC_LAYER_SURFACE, surface); + LAB_NODE_LAYER_SURFACE, /*view*/ NULL, surface); surface->server = server; surface->scene_layer_surface->layer_surface = layer_surface; diff --git a/src/menu/menu.c b/src/menu/menu.c index 84db869c..e55f7626 100644 --- a/src/menu/menu.c +++ b/src/menu/menu.c @@ -246,8 +246,8 @@ item_create_scene(struct menuitem *menuitem, int *item_y) /* Menu item root node */ menuitem->tree = wlr_scene_tree_create(menu->scene_tree); - node_descriptor_create(&menuitem->tree->node, - LAB_NODE_DESC_MENUITEM, menuitem); + node_descriptor_create(&menuitem->tree->node, LAB_NODE_MENUITEM, + /*view*/ NULL, menuitem); /* Create scenes for unselected/selected states */ menuitem->normal_tree = item_create_scene_for_state(menuitem, @@ -295,8 +295,8 @@ separator_create_scene(struct menuitem *menuitem, int *item_y) /* Menu item root node */ menuitem->tree = wlr_scene_tree_create(menu->scene_tree); - node_descriptor_create(&menuitem->tree->node, - LAB_NODE_DESC_MENUITEM, menuitem); + node_descriptor_create(&menuitem->tree->node, LAB_NODE_MENUITEM, + /*view*/ NULL, menuitem); /* Tree to hold background and line buffer */ menuitem->normal_tree = wlr_scene_tree_create(menuitem->tree); @@ -343,8 +343,8 @@ title_create_scene(struct menuitem *menuitem, int *item_y) /* Menu item root node */ menuitem->tree = wlr_scene_tree_create(menu->scene_tree); - node_descriptor_create(&menuitem->tree->node, - LAB_NODE_DESC_MENUITEM, menuitem); + node_descriptor_create(&menuitem->tree->node, LAB_NODE_MENUITEM, + /*view*/ NULL, menuitem); /* Tree to hold background and text buffer */ menuitem->normal_tree = wlr_scene_tree_create(menuitem->tree); diff --git a/src/node.c b/src/node.c index 7a17c1ed..e5132e7c 100644 --- a/src/node.c +++ b/src/node.c @@ -3,31 +3,29 @@ #include #include #include "common/mem.h" - -static void -descriptor_destroy(struct node_descriptor *node_descriptor) -{ - if (!node_descriptor) { - return; - } - wl_list_remove(&node_descriptor->destroy.link); - free(node_descriptor); -} +#include "ssd.h" static void handle_node_destroy(struct wl_listener *listener, void *data) { struct node_descriptor *node_descriptor = wl_container_of(listener, node_descriptor, destroy); - descriptor_destroy(node_descriptor); + + if (node_type_contains(LAB_NODE_BUTTON, node_descriptor->type)) { + ssd_button_free(node_descriptor->data); + } + + wl_list_remove(&node_descriptor->destroy.link); + free(node_descriptor); } void node_descriptor_create(struct wlr_scene_node *scene_node, - enum node_descriptor_type type, void *data) + enum lab_node_type type, struct view *view, void *data) { struct node_descriptor *node_descriptor = znew(*node_descriptor); node_descriptor->type = type; + node_descriptor->view = view; node_descriptor->data = data; node_descriptor->destroy.notify = handle_node_destroy; wl_signal_add(&scene_node->events.destroy, &node_descriptor->destroy); @@ -39,9 +37,7 @@ node_view_from_node(struct wlr_scene_node *wlr_scene_node) { assert(wlr_scene_node->data); struct node_descriptor *node_descriptor = wlr_scene_node->data; - assert(node_descriptor->type == LAB_NODE_DESC_VIEW - || node_descriptor->type == LAB_NODE_DESC_XDG_POPUP); - return (struct view *)node_descriptor->data; + return node_descriptor->view; } struct lab_layer_surface * @@ -49,7 +45,7 @@ node_layer_surface_from_node(struct wlr_scene_node *wlr_scene_node) { assert(wlr_scene_node->data); struct node_descriptor *node_descriptor = wlr_scene_node->data; - assert(node_descriptor->type == LAB_NODE_DESC_LAYER_SURFACE); + assert(node_descriptor->type == LAB_NODE_LAYER_SURFACE); return (struct lab_layer_surface *)node_descriptor->data; } @@ -58,7 +54,7 @@ node_layer_popup_from_node(struct wlr_scene_node *wlr_scene_node) { assert(wlr_scene_node->data); struct node_descriptor *node_descriptor = wlr_scene_node->data; - assert(node_descriptor->type == LAB_NODE_DESC_LAYER_POPUP); + assert(node_descriptor->type == LAB_NODE_LAYER_POPUP); return (struct lab_layer_popup *)node_descriptor->data; } @@ -67,24 +63,28 @@ node_menuitem_from_node(struct wlr_scene_node *wlr_scene_node) { assert(wlr_scene_node->data); struct node_descriptor *node_descriptor = wlr_scene_node->data; - assert(node_descriptor->type == LAB_NODE_DESC_MENUITEM); + assert(node_descriptor->type == LAB_NODE_MENUITEM); return (struct menuitem *)node_descriptor->data; } -struct ssd_part * -node_ssd_part_from_node(struct wlr_scene_node *wlr_scene_node) -{ - assert(wlr_scene_node->data); - struct node_descriptor *node_descriptor = wlr_scene_node->data; - assert(node_descriptor->type == LAB_NODE_DESC_SSD_PART); - return (struct ssd_part *)node_descriptor->data; -} - struct scaled_buffer * node_scaled_buffer_from_node(struct wlr_scene_node *wlr_scene_node) { assert(wlr_scene_node->data); struct node_descriptor *node_descriptor = wlr_scene_node->data; - assert(node_descriptor->type == LAB_NODE_DESC_SCALED_BUFFER); + assert(node_descriptor->type == LAB_NODE_SCALED_BUFFER); return (struct scaled_buffer *)node_descriptor->data; } + +struct ssd_button * +node_try_ssd_button_from_node(struct wlr_scene_node *wlr_scene_node) +{ + assert(wlr_scene_node->data); + struct node_descriptor *node_descriptor = wlr_scene_node->data; + + if (node_type_contains(LAB_NODE_BUTTON, node_descriptor->type)) { + return (struct ssd_button *)node_descriptor->data; + } + + return NULL; +} diff --git a/src/output.c b/src/output.c index 7715b899..c5c88dfc 100644 --- a/src/output.c +++ b/src/output.c @@ -511,17 +511,17 @@ handle_new_output(struct wl_listener *listener, void *data) output->layer_tree[i] = wlr_scene_tree_create(&server->scene->tree); node_descriptor_create(&output->layer_tree[i]->node, - LAB_NODE_DESC_TREE, NULL); + LAB_NODE_TREE, /*view*/ NULL, /*data*/ NULL); } output->layer_popup_tree = wlr_scene_tree_create(&server->scene->tree); node_descriptor_create(&output->layer_popup_tree->node, - LAB_NODE_DESC_TREE, NULL); + LAB_NODE_TREE, /*view*/ NULL, /*data*/ NULL); output->osd_tree = wlr_scene_tree_create(&server->scene->tree); node_descriptor_create(&output->osd_tree->node, - LAB_NODE_DESC_TREE, NULL); + LAB_NODE_TREE, /*view*/ NULL, /*data*/ NULL); output->session_lock_tree = wlr_scene_tree_create(&server->scene->tree); node_descriptor_create(&output->session_lock_tree->node, - LAB_NODE_DESC_TREE, NULL); + LAB_NODE_TREE, /*view*/ NULL, /*data*/ NULL); /* * Set the z-positions to achieve the following order (from top to diff --git a/src/scaled-buffer/scaled-buffer.c b/src/scaled-buffer/scaled-buffer.c index c478ed00..c4a3219c 100644 --- a/src/scaled-buffer/scaled-buffer.c +++ b/src/scaled-buffer/scaled-buffer.c @@ -198,7 +198,7 @@ scaled_buffer_create(struct wlr_scene_tree *parent, return NULL; } node_descriptor_create(&self->scene_buffer->node, - LAB_NODE_DESC_SCALED_BUFFER, self); + LAB_NODE_SCALED_BUFFER, /*view*/ NULL, self); self->impl = impl; /* diff --git a/src/session-lock.c b/src/session-lock.c index 1dce3b6a..277233cc 100644 --- a/src/session-lock.c +++ b/src/session-lock.c @@ -135,7 +135,7 @@ handle_new_surface(struct wl_listener *listener, void *data) struct wlr_scene_tree *surface_tree = wlr_scene_subsurface_tree_create(lock_output->tree, lock_surface->surface); node_descriptor_create(&surface_tree->node, - LAB_NODE_DESC_SESSION_LOCK_SURFACE, NULL); + LAB_NODE_SESSION_LOCK_SURFACE, /*view*/ NULL, /*data*/ NULL); lock_output->surface_destroy.notify = handle_surface_destroy; wl_signal_add(&lock_surface->events.destroy, &lock_output->surface_destroy); diff --git a/src/ssd/meson.build b/src/ssd/meson.build index c37eef45..a316409b 100644 --- a/src/ssd/meson.build +++ b/src/ssd/meson.build @@ -1,7 +1,7 @@ labwc_sources += files( 'resize-indicator.c', 'ssd.c', - 'ssd-part.c', + 'ssd-button.c', 'ssd-titlebar.c', 'ssd-border.c', 'ssd-extents.c', diff --git a/src/ssd/ssd-part.c b/src/ssd/ssd-button.c similarity index 61% rename from src/ssd/ssd-part.c rename to src/ssd/ssd-button.c index 00cfe7af..af209f89 100644 --- a/src/ssd/ssd-part.c +++ b/src/ssd/ssd-button.c @@ -7,55 +7,13 @@ #include "node.h" #include "scaled-buffer/scaled-icon-buffer.h" #include "scaled-buffer/scaled-img-buffer.h" +#include "ssd.h" #include "ssd-internal.h" -/* Internal helpers */ -static void -handle_node_destroy(struct wl_listener *listener, void *data) -{ - struct ssd_part *part = wl_container_of(listener, part, node_destroy); - wl_list_remove(&part->node_destroy.link); - - struct ssd_part_button *button = button_try_from_ssd_part(part); - if (button) { - wl_list_remove(&button->link); - } - - free(part); -} - /* Internal API */ -/* - * Create a new node_descriptor containing a link to a new ssd_part struct. - * Both will be destroyed automatically once the scene_node they are attached - * to is destroyed. - */ -static void -init_ssd_part(struct ssd_part *part, enum lab_node_type type, - struct view *view, struct wlr_scene_node *node) -{ - part->type = type; - part->node = node; - part->view = view; - - node_descriptor_create(node, LAB_NODE_DESC_SSD_PART, part); - part->node_destroy.notify = handle_node_destroy; - wl_signal_add(&node->events.destroy, &part->node_destroy); -} - -struct ssd_part * -attach_ssd_part(enum lab_node_type type, struct view *view, - struct wlr_scene_node *node) -{ - assert(!node_type_contains(LAB_NODE_BUTTON, type)); - struct ssd_part *part = znew(*part); - init_ssd_part(part, type, view, node); - return part; -} - -struct ssd_part_button * -attach_ssd_part_button(struct wl_list *button_parts, enum lab_node_type type, +struct ssd_button * +attach_ssd_button(struct wl_list *button_parts, enum lab_node_type type, struct wlr_scene_tree *parent, struct lab_img *imgs[LAB_BS_ALL + 1], int x, int y, struct view *view) @@ -64,8 +22,10 @@ attach_ssd_part_button(struct wl_list *button_parts, enum lab_node_type type, wlr_scene_node_set_position(&root->node, x, y); assert(node_type_contains(LAB_NODE_BUTTON, type)); - struct ssd_part_button *button = znew(*button); - init_ssd_part(&button->base, type, view, &root->node); + struct ssd_button *button = znew(*button); + button->node = &root->node; + button->type = type; + node_descriptor_create(&root->node, type, view, button); wl_list_append(button_parts, &button->link); /* Hitbox */ @@ -117,11 +77,9 @@ attach_ssd_part_button(struct wl_list *button_parts, enum lab_node_type type, return button; } -struct ssd_part_button * -button_try_from_ssd_part(struct ssd_part *part) +/* called from node descriptor destroy */ +void ssd_button_free(struct ssd_button *button) { - if (node_type_contains(LAB_NODE_BUTTON, part->type)) { - return (struct ssd_part_button *)part; - } - return NULL; + wl_list_remove(&button->link); + free(button); } diff --git a/src/ssd/ssd-titlebar.c b/src/ssd/ssd-titlebar.c index 05cbdb9a..84dd527a 100644 --- a/src/ssd/ssd-titlebar.c +++ b/src/ssd/ssd-titlebar.c @@ -34,7 +34,8 @@ ssd_titlebar_create(struct ssd *ssd) int corner_width = ssd_get_corner_width(); ssd->titlebar.tree = wlr_scene_tree_create(ssd->tree); - attach_ssd_part(LAB_NODE_TITLEBAR, view, &ssd->titlebar.tree->node); + node_descriptor_create(&ssd->titlebar.tree->node, + LAB_NODE_TITLEBAR, view, /*data*/ NULL); enum ssd_active_state active; FOR_EACH_ACTIVE_STATE(active) { @@ -78,8 +79,8 @@ ssd_titlebar_create(struct ssd *ssd) subtree->tree, theme->titlebar_height, theme->window[active].titlebar_pattern); assert(subtree->title); - attach_ssd_part(LAB_NODE_TITLE, - view, &subtree->title->scene_buffer->node); + node_descriptor_create(&subtree->title->scene_buffer->node, + LAB_NODE_TITLE, view, /*data*/ NULL); /* Buttons */ struct title_button *b; @@ -94,7 +95,7 @@ ssd_titlebar_create(struct ssd *ssd) wl_list_for_each(b, &rc.title_buttons_left, link) { struct lab_img **imgs = theme->window[active].button_imgs[b->type]; - attach_ssd_part_button(&subtree->buttons_left, b->type, parent, + attach_ssd_button(&subtree->buttons_left, b->type, parent, imgs, x, y, view); x += theme->window_button_width + theme->window_button_spacing; } @@ -104,7 +105,7 @@ ssd_titlebar_create(struct ssd *ssd) x -= theme->window_button_width + theme->window_button_spacing; struct lab_img **imgs = theme->window[active].button_imgs[b->type]; - attach_ssd_part_button(&subtree->buttons_right, b->type, parent, + attach_ssd_button(&subtree->buttons_right, b->type, parent, imgs, x, y, view); } } @@ -134,7 +135,7 @@ ssd_titlebar_create(struct ssd *ssd) } static void -update_button_state(struct ssd_part_button *button, enum lab_button_state state, +update_button_state(struct ssd_button *button, enum lab_button_state state, bool enable) { if (enable) { @@ -177,7 +178,7 @@ set_squared_corners(struct ssd *ssd, bool enable) wlr_scene_node_set_enabled(&subtree->corner_right->node, !enable); /* (Un)round the corner buttons */ - struct ssd_part_button *button; + struct ssd_button *button; wl_list_for_each(button, &subtree->buttons_left, link) { update_button_state(button, LAB_BS_ROUNDED, !enable); break; @@ -196,15 +197,15 @@ set_alt_button_icon(struct ssd *ssd, enum lab_node_type type, bool enable) FOR_EACH_ACTIVE_STATE(active) { struct ssd_titlebar_subtree *subtree = &ssd->titlebar.subtrees[active]; - struct ssd_part_button *button; + struct ssd_button *button; wl_list_for_each(button, &subtree->buttons_left, link) { - if (button->base.type == type) { + if (button->type == type) { update_button_state(button, LAB_BS_TOGGLED, enable); } } wl_list_for_each(button, &subtree->buttons_right, link) { - if (button->base.type == type) { + if (button->type == type) { update_button_state(button, LAB_BS_TOGGLED, enable); } @@ -251,16 +252,16 @@ update_visible_buttons(struct ssd *ssd) struct ssd_titlebar_subtree *subtree = &ssd->titlebar.subtrees[active]; int button_count = 0; - struct ssd_part_button *button; + struct ssd_button *button; wl_list_for_each(button, &subtree->buttons_left, link) { - wlr_scene_node_set_enabled(button->base.node, + wlr_scene_node_set_enabled(button->node, button_count < button_count_left); button_count++; } button_count = 0; wl_list_for_each(button, &subtree->buttons_right, link) { - wlr_scene_node_set_enabled(button->base.node, + wlr_scene_node_set_enabled(button->node, button_count < button_count_right); button_count++; } @@ -317,9 +318,9 @@ ssd_titlebar_update(struct ssd *ssd) MAX(width - bg_offset * 2, 0), theme->titlebar_height); x = theme->window_titlebar_padding_width; - struct ssd_part_button *button; + struct ssd_button *button; wl_list_for_each(button, &subtree->buttons_left, link) { - wlr_scene_node_set_position(button->base.node, x, y); + wlr_scene_node_set_position(button->node, x, y); x += theme->window_button_width + theme->window_button_spacing; } @@ -330,7 +331,7 @@ ssd_titlebar_update(struct ssd *ssd) x = width - theme->window_titlebar_padding_width + theme->window_button_spacing; wl_list_for_each(button, &subtree->buttons_right, link) { x -= theme->window_button_width + theme->window_button_spacing; - wlr_scene_node_set_position(button->base.node, x, y); + wlr_scene_node_set_position(button->node, x, y); } } @@ -419,14 +420,14 @@ get_title_offsets(struct ssd *ssd, int *offset_left, int *offset_right) *offset_left = padding_width; *offset_right = padding_width; - struct ssd_part_button *button; + struct ssd_button *button; wl_list_for_each(button, &subtree->buttons_left, link) { - if (button->base.node->enabled) { + if (button->node->enabled) { *offset_left += button_width + button_spacing; } } wl_list_for_each(button, &subtree->buttons_right, link) { - if (button->base.node->enabled) { + if (button->node->enabled) { *offset_right += button_width + button_spacing; } } @@ -494,17 +495,13 @@ ssd_update_title(struct ssd *ssd) void ssd_update_hovered_button(struct server *server, struct wlr_scene_node *node) { - struct ssd_part_button *button = NULL; + struct ssd_button *button = NULL; if (node && node->data) { - struct node_descriptor *desc = node->data; - if (desc->type == LAB_NODE_DESC_SSD_PART) { - button = button_try_from_ssd_part( - node_ssd_part_from_node(node)); - if (button == server->hovered_button) { - /* Cursor is still on the same button */ - return; - } + button = node_try_ssd_button_from_node(node); + if (button == server->hovered_button) { + /* Cursor is still on the same button */ + return; } } diff --git a/src/ssd/ssd.c b/src/ssd/ssd.c index 67d5966b..afdbcdf9 100644 --- a/src/ssd/ssd.c +++ b/src/ssd/ssd.c @@ -14,6 +14,7 @@ #include "common/scene-helpers.h" #include "config/rcxml.h" #include "labwc.h" +#include "node.h" #include "ssd-internal.h" #include "theme.h" #include "view.h" @@ -145,7 +146,8 @@ ssd_create(struct view *view, bool active) ssd->view = view; ssd->tree = wlr_scene_tree_create(view->scene_tree); - attach_ssd_part(LAB_NODE_NONE, view, &ssd->tree->node); + node_descriptor_create(&ssd->tree->node, + LAB_NODE_NONE, view, /*data*/ NULL); wlr_scene_node_lower_to_bottom(&ssd->tree->node); ssd->titlebar.height = view->server->theme->titlebar_height; ssd_shadow_create(ssd); @@ -265,7 +267,8 @@ ssd_destroy(struct ssd *ssd) /* Maybe reset hover view */ struct view *view = ssd->view; struct server *server = view->server; - if (server->hovered_button && server->hovered_button->base.view == view) { + if (server->hovered_button && node_view_from_node( + server->hovered_button->node) == view) { server->hovered_button = NULL; } @@ -343,18 +346,6 @@ ssd_enable_keybind_inhibit_indicator(struct ssd *ssd, bool enable) wlr_scene_rect_set_color(ssd->border.subtrees[SSD_ACTIVE].top, color); } -enum lab_node_type -ssd_part_get_type(const struct ssd_part *part) -{ - return part ? part->type : LAB_NODE_NONE; -} - -struct view * -ssd_part_get_view(const struct ssd_part *part) -{ - return part ? part->view : NULL; -} - bool ssd_debug_is_root_node(const struct ssd *ssd, struct wlr_scene_node *node) { diff --git a/src/xdg-popup.c b/src/xdg-popup.c index cc14d920..722a32ff 100644 --- a/src/xdg-popup.c +++ b/src/xdg-popup.c @@ -164,5 +164,5 @@ xdg_popup_create(struct view *view, struct wlr_xdg_popup *wlr_popup) wlr_popup->base->surface->data = wlr_scene_xdg_surface_create(parent_tree, wlr_popup->base); node_descriptor_create(wlr_popup->base->surface->data, - LAB_NODE_DESC_XDG_POPUP, view); + LAB_NODE_XDG_POPUP, view, /*data*/ NULL); } diff --git a/src/xdg.c b/src/xdg.c index 00c4e226..f25a0e84 100644 --- a/src/xdg.c +++ b/src/xdg.c @@ -1023,7 +1023,7 @@ handle_new_xdg_toplevel(struct wl_listener *listener, void *data) } view->content_tree = tree; node_descriptor_create(&view->scene_tree->node, - LAB_NODE_DESC_VIEW, view); + LAB_NODE_VIEW, view, /*data*/ NULL); /* * The xdg_toplevel_decoration and kde_server_decoration protocols diff --git a/src/xwayland.c b/src/xwayland.c index 9776dd1d..2127bd52 100644 --- a/src/xwayland.c +++ b/src/xwayland.c @@ -1090,7 +1090,8 @@ xwayland_view_create(struct server *server, view->workspace = server->workspaces.current; view->scene_tree = wlr_scene_tree_create(view->workspace->tree); - node_descriptor_create(&view->scene_tree->node, LAB_NODE_DESC_VIEW, view); + node_descriptor_create(&view->scene_tree->node, + LAB_NODE_VIEW, view, /*data*/ NULL); CONNECT_SIGNAL(xsurface, view, destroy); CONNECT_SIGNAL(xsurface, view, request_minimize);