]> git.mdlowis.com Git - proto/labwc.git/commitdiff
osd: allow clicking an osd item to focus the window
authortokyo4j <hrak1529@gmail.com>
Wed, 29 Oct 2025 18:22:45 +0000 (03:22 +0900)
committerJohan Malm <johanmalm@users.noreply.github.com>
Tue, 4 Nov 2025 21:29:13 +0000 (21:29 +0000)
include/common/node-type.h
include/node.h
include/osd.h
src/desktop.c
src/input/cursor.c
src/node.c
src/osd/osd-classic.c
src/osd/osd-thumbnail.c
src/osd/osd.c

index ac83b2b5ad18db048cccfc1bce624878a792bf1e..9987af38b696aa78fa4fe882dd758758b2451815 100644 (file)
@@ -47,7 +47,7 @@ enum lab_node_type {
        LAB_NODE_FRAME,
        LAB_NODE_ROOT,
        LAB_NODE_MENUITEM,
-       LAB_NODE_OSD,
+       LAB_NODE_OSD_ITEM,
        LAB_NODE_LAYER_SURFACE,
        LAB_NODE_UNMANAGED,
        LAB_NODE_ALL,
index bfad1373cbb37beca5d46a01558c53811aaa86a5..ad21f313ac749b31484b95b3b7ef96297bc3c210 100644 (file)
@@ -52,6 +52,13 @@ struct lab_layer_surface *node_layer_surface_from_node(
 struct menuitem *node_menuitem_from_node(
        struct wlr_scene_node *wlr_scene_node);
 
+/**
+ * node_osd_item_from_node - return osd item struct from node
+ * @wlr_scene_node: wlr_scene_node from which to return data
+ */
+struct osd_item *node_osd_item_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
index 3397ccf3b68492bb1f2f8eaa189d24c34aebe338..a9b4cdffcd332d42749ffbc5652c48bd8e85968a 100644 (file)
@@ -45,6 +45,7 @@ struct window_switcher_field {
 struct buf;
 struct view;
 struct server;
+struct wlr_scene_node;
 
 /* Begin window switcher */
 void osd_begin(struct server *server, enum lab_cycle_dir direction);
@@ -58,6 +59,9 @@ void osd_finish(struct server *server, bool switch_focus);
 /* Notify OSD about a destroying view */
 void osd_on_view_destroy(struct view *view);
 
+/* Focus the clicked window and close OSD */
+void osd_on_cursor_release(struct server *server, struct wlr_scene_node *node);
+
 /* Used by osd.c internally to render window switcher fields */
 void osd_field_get_content(struct window_switcher_field *field,
        struct buf *buf, struct view *view);
index 2d883445295064d09096e6504c3751694d930a7f..d805eae3b9858da93fd41820127a86cb32a27d57 100644 (file)
@@ -340,6 +340,11 @@ get_cursor_context(struct server *server)
                                ret.node = node;
                                ret.type = LAB_NODE_MENUITEM;
                                return ret;
+                       case LAB_NODE_OSD_ITEM:
+                               /* Always return the top scene node for osd items */
+                               ret.node = node;
+                               ret.type = LAB_NODE_OSD_ITEM;
+                               return ret;
                        case LAB_NODE_BUTTON_FIRST...LAB_NODE_BUTTON_LAST:
                        case LAB_NODE_SSD_ROOT:
                        case LAB_NODE_TITLE:
index fe694db4e81e719df1a66a4f83705cd8c24073f3..6c12d3da6898b0cc79e1135b8723fea60404a5c5 100644 (file)
@@ -30,6 +30,7 @@
 #include "labwc.h"
 #include "layers.h"
 #include "menu/menu.h"
+#include "osd.h"
 #include "output.h"
 #include "resistance.h"
 #include "resize-outlines.h"
@@ -1190,6 +1191,12 @@ cursor_process_button_release(struct seat *seat, uint32_t button,
                }
                return notify;
        }
+       if (server->input_mode == LAB_INPUT_STATE_WINDOW_SWITCHER) {
+               if (ctx.type == LAB_NODE_OSD_ITEM) {
+                       osd_on_cursor_release(server, ctx.node);
+               }
+               return notify;
+       }
 
        if (server->input_mode != LAB_INPUT_STATE_PASSTHROUGH) {
                return notify;
index ce4fb040c8ca451301bf7782c2981f6c1834a7df..1b3dce990528348e73642d31041fab72e6968ce4 100644 (file)
@@ -59,6 +59,15 @@ node_menuitem_from_node(struct wlr_scene_node *wlr_scene_node)
        return (struct menuitem *)node_descriptor->data;
 }
 
+struct osd_item *
+node_osd_item_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_OSD_ITEM);
+       return (struct osd_item *)node_descriptor->data;
+}
+
 struct ssd_button *
 node_try_ssd_button_from_node(struct wlr_scene_node *wlr_scene_node)
 {
index df33caac21080d8a391e57d95528246bfb3c21d4..0c80bd799ab3b7d567a98ac032d241b4871018aa 100644 (file)
@@ -161,6 +161,8 @@ osd_classic_create(struct output *output, struct wl_array *views)
                wl_list_append(&output->osd_scene.items, &item->base.link);
                item->base.view = *view;
                item->base.tree = wlr_scene_tree_create(output->osd_scene.tree);
+               node_descriptor_create(&item->base.tree->node,
+                       LAB_NODE_OSD_ITEM, NULL, item);
                /*
                 *    OSD border
                 * +---------------------------------+
@@ -200,6 +202,11 @@ osd_classic_create(struct output *output, struct wl_array *views)
                        item->active_tree, &highlight_opts);
                wlr_scene_node_set_position(&highlight_rect->tree->node, padding, y);
 
+               /* hitbox for mouse clicks */
+               struct wlr_scene_rect *hitbox = wlr_scene_rect_create(item->base.tree,
+                       w - 2 * padding, switcher_theme->item_height, (float[4]) {0});
+               wlr_scene_node_set_position(&hitbox->node, padding, y);
+
                create_fields_scene(server, *view, item->normal_tree,
                        text_color, bg_color, field_widths_sum, x, y);
                create_fields_scene(server, *view, item->active_tree,
index 14d7c846c7f40a93811ef6e97e8dbb6256693e9b..76cdf2777814c3667f7013d937affbc0839cd764 100644 (file)
@@ -128,6 +128,7 @@ create_item_scene(struct wlr_scene_tree *parent, struct view *view,
        struct osd_thumbnail_item *item = znew(*item);
        wl_list_append(&output->osd_scene.items, &item->base.link);
        struct wlr_scene_tree *tree = wlr_scene_tree_create(parent);
+       node_descriptor_create(&tree->node, LAB_NODE_OSD_ITEM, NULL, item);
        item->base.tree = tree;
        item->base.view = view;
 
@@ -142,6 +143,10 @@ create_item_scene(struct wlr_scene_tree *parent, struct view *view,
        };
        item->active_bg = lab_scene_rect_create(tree, &opts);
 
+       /* hitbox for mouse clicks */
+       wlr_scene_rect_create(tree, switcher_theme->item_width,
+               switcher_theme->item_height, (float[4]) {0});
+
        /* thumbnail */
        struct wlr_buffer *thumb_buffer = render_thumb(output, view);
        if (thumb_buffer) {
index 6191640e2340b57f3d3aeecc33b3302f6d4620b5..ca64920c0f196e9687ad577c5b9383fb2cb30300 100644 (file)
@@ -144,6 +144,16 @@ osd_on_view_destroy(struct view *view)
        }
 }
 
+void
+osd_on_cursor_release(struct server *server, struct wlr_scene_node *node)
+{
+       assert(server->input_mode == LAB_INPUT_STATE_WINDOW_SWITCHER);
+
+       struct osd_item *item = node_osd_item_from_node(node);
+       server->osd_state.cycle_view = item->view;
+       osd_finish(server, /*switch_focus*/ true);
+}
+
 static void
 restore_preview_node(struct server *server)
 {