From 9f7e532852ba199b845f6ac9c98804010fbe378e Mon Sep 17 00:00:00 2001 From: tokyo4j Date: Tue, 9 Sep 2025 02:56:37 +0900 Subject: [PATCH] desktop: refactor get_cursor_context() This patch should not change any behaviors. This clarifies the semantics of cursor_context returned by get_cursor_context() as I described in cursor.h; when cursor is on a subsurface (e.g. xdg/x11/layer/session-lock), the returned ctx.surface and ctx.node points to the subsurface rather than its parent. --- include/input/cursor.h | 32 +++++++++++--------------------- src/desktop.c | 10 ++++------ 2 files changed, 15 insertions(+), 27 deletions(-) diff --git a/include/input/cursor.h b/include/input/cursor.h index 5afa831b..13ab72d1 100644 --- a/include/input/cursor.h +++ b/include/input/cursor.h @@ -39,30 +39,20 @@ struct cursor_context { }; /** - * get_cursor_context - find view and scene_node at cursor + * get_cursor_context - find view, surface and scene_node at cursor * - * Behavior if node points to a surface: - * - If surface is a layer-surface, type will be - * set to LAB_NODE_LAYER_SURFACE and view will be NULL. + * If the cursor is on a client-drawn surface: + * - ctx.{surface,node} points to the surface, which may be a subsurface. + * - ctx.view is set if the node is associated to a xdg/x11 window. + * - ctx.type is LAYER_SURFACE or UNMANAGED if the node is a layer-shell + * surface or an X11 unmanaged surface. Otherwise, CLIENT is set. * - * - If surface is a 'lost' unmanaged xsurface (one - * with a never-mapped parent view), type will - * be set to LAB_NODE_UNMANAGED and view will be NULL. - * - * 'Lost' unmanaged xsurfaces are usually caused by - * X11 applications opening popups without setting - * the main window as parent. Example: VLC submenus. - * - * - Any other surface will cause type to be set to - * LAB_NODE_CLIENT and return the attached view. - * - * Behavior if node points to internal elements: - * - type will be set to the appropriate enum value - * and view will be NULL if the node is not part of the SSD. - * - * If no node is found for the given layout coordinates, - * type will be set to LAB_NODE_ROOT and view will be NULL. + * If the cursor is on a server-side component (SSD part and menu item): + * - ctx.node points to the root node of that component + * - ctx.view is set if the component is a SSD part + * - ctx.type specifies the component (e.g. MENU_ITEM, BORDER_TOP, BUTTON_ICONIFY) * + * If no node is found at cursor, ctx.type is set to ROOT. */ struct cursor_context get_cursor_context(struct server *server); diff --git a/src/desktop.c b/src/desktop.c index 3ed19082..dc2aa1a2 100644 --- a/src/desktop.c +++ b/src/desktop.c @@ -262,18 +262,18 @@ get_cursor_context(struct server *server) dnd_icons_show(&server->seat, true); } - ret.node = node; if (!node) { ret.type = LAB_NODE_ROOT; return ret; } + ret.node = node; + ret.surface = lab_wlr_surface_from_node(node); #if HAVE_XWAYLAND + /* TODO: attach LAB_NODE_UNMANAGED node-descriptor to unmanaged surfaces */ if (node->type == WLR_SCENE_NODE_BUFFER) { - struct wlr_surface *surface = lab_wlr_surface_from_node(node); if (node->parent == server->unmanaged_tree) { ret.type = LAB_NODE_UNMANAGED; - ret.surface = surface; return ret; } } @@ -285,7 +285,6 @@ get_cursor_context(struct server *server) case LAB_NODE_VIEW: case LAB_NODE_XDG_POPUP: ret.view = desc->view; - ret.surface = lab_wlr_surface_from_node(ret.node); if (ret.surface) { ret.type = LAB_NODE_CLIENT; } else { @@ -295,13 +294,11 @@ get_cursor_context(struct server *server) return ret; case LAB_NODE_LAYER_SURFACE: ret.type = LAB_NODE_LAYER_SURFACE; - ret.surface = lab_wlr_surface_from_node(ret.node); return ret; case LAB_NODE_LAYER_POPUP: case LAB_NODE_SESSION_LOCK_SURFACE: 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 */ @@ -312,6 +309,7 @@ get_cursor_context(struct server *server) case LAB_NODE_SSD_ROOT: case LAB_NODE_TITLE: case LAB_NODE_TITLEBAR: + /* Always return the top scene node for ssd parts */ ret.node = node; ret.view = desc->view; /*