]> git.mdlowis.com Git - proto/labwc.git/commitdiff
osd: generalize osd_{classic,thumbnail}_item
authortokyo4j <hrak1529@gmail.com>
Wed, 29 Oct 2025 17:51:05 +0000 (02:51 +0900)
committerJohan Malm <johanmalm@users.noreply.github.com>
Tue, 4 Nov 2025 21:29:13 +0000 (21:29 +0000)
This allows us to share common codes for dealing with osd items.
For example:
- Get the clicked osd item to focus its associated window
- Scroll the items when their total height is taller than output height

include/osd.h
include/output.h
src/osd/osd-classic.c
src/osd/osd-thumbnail.c
src/osd/osd.c
src/output.c

index 2af02ee6fc47e179057d5474afe63ae2ee3c8d4a..3397ccf3b68492bb1f2f8eaa189d24c34aebe338 100644 (file)
@@ -69,6 +69,12 @@ bool osd_field_is_valid(struct window_switcher_field *field);
 void osd_field_free(struct window_switcher_field *field);
 
 /* Internal API */
+struct osd_item {
+       struct view *view;
+       struct wlr_scene_tree *tree;
+       struct wl_list link;
+};
+
 struct osd_impl {
        /*
         * Create a scene-tree of OSD for an output.
index 888f62c7d6c0597484006bae7206c00c01b67505..7c34abc5646dbe0dd645ddbfa861de59d19b4aac 100644 (file)
@@ -20,7 +20,7 @@ struct output {
        struct wlr_scene_buffer *workspace_osd;
 
        struct osd_scene {
-               struct wl_array items; /* struct osd_scene_item */
+               struct wl_list items; /* struct osd_item */
                struct wlr_scene_tree *tree;
        } osd_scene;
 
index 4ed05c41793c4359d3016a3215e18266d0310a81..df33caac21080d8a391e57d95528246bfb3c21d4 100644 (file)
@@ -8,9 +8,11 @@
 #include "common/buf.h"
 #include "common/font.h"
 #include "common/lab-scene-rect.h"
+#include "common/list.h"
 #include "common/string-helpers.h"
 #include "config/rcxml.h"
 #include "labwc.h"
+#include "node.h"
 #include "osd.h"
 #include "output.h"
 #include "scaled-buffer/scaled-font-buffer.h"
@@ -19,7 +21,7 @@
 #include "workspaces.h"
 
 struct osd_classic_item {
-       struct view *view;
+       struct osd_item base;
        struct wlr_scene_tree *normal_tree, *active_tree;
 };
 
@@ -76,7 +78,7 @@ create_fields_scene(struct server *server, struct view *view,
 static void
 osd_classic_create(struct output *output, struct wl_array *views)
 {
-       assert(!output->osd_scene.tree);
+       assert(!output->osd_scene.tree && wl_list_empty(&output->osd_scene.items));
 
        struct server *server = output->server;
        struct theme *theme = server->theme;
@@ -155,9 +157,10 @@ osd_classic_create(struct output *output, struct wl_array *views)
        /* Draw text for each node */
        struct view **view;
        wl_array_for_each(view, views) {
-               struct osd_classic_item *item =
-                       wl_array_add(&output->osd_scene.items, sizeof(*item));
-               item->view = *view;
+               struct osd_classic_item *item = znew(*item);
+               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);
                /*
                 *    OSD border
                 * +---------------------------------+
@@ -177,10 +180,8 @@ osd_classic_create(struct output *output, struct wl_array *views)
                int x = padding
                        + switcher_theme->item_active_border_width
                        + switcher_theme->item_padding_x;
-               struct wlr_scene_tree *item_root =
-                       wlr_scene_tree_create(output->osd_scene.tree);
-               item->normal_tree = wlr_scene_tree_create(item_root);
-               item->active_tree = wlr_scene_tree_create(item_root);
+               item->normal_tree = wlr_scene_tree_create(item->base.tree);
+               item->active_tree = wlr_scene_tree_create(item->base.tree);
                wlr_scene_node_set_enabled(&item->active_tree->node, false);
 
                float *active_bg_color = switcher_theme->item_active_bg_color;
@@ -219,8 +220,8 @@ static void
 osd_classic_update(struct output *output)
 {
        struct osd_classic_item *item;
-       wl_array_for_each(item, &output->osd_scene.items) {
-               bool active = item->view == output->server->osd_state.cycle_view;
+       wl_list_for_each(item, &output->osd_scene.items, base.link) {
+               bool active = item->base.view == output->server->osd_state.cycle_view;
                wlr_scene_node_set_enabled(&item->normal_tree->node, !active);
                wlr_scene_node_set_enabled(&item->active_tree->node, active);
        }
index ad29ebe84f0ed61f0e88874a0e12a64ba90d5dec..14d7c846c7f40a93811ef6e97e8dbb6256693e9b 100644 (file)
@@ -8,7 +8,9 @@
 #include "common/array.h"
 #include "common/box.h"
 #include "common/lab-scene-rect.h"
+#include "common/list.h"
 #include "labwc.h"
+#include "node.h"
 #include "osd.h"
 #include "output.h"
 #include "scaled-buffer/scaled-font-buffer.h"
@@ -17,8 +19,7 @@
 #include "view.h"
 
 struct osd_thumbnail_item {
-       struct view *view;
-       struct wlr_scene_tree *tree;
+       struct osd_item base;
        struct scaled_font_buffer *normal_title;
        struct scaled_font_buffer *active_title;
        struct lab_scene_rect *active_bg;
@@ -124,10 +125,11 @@ create_item_scene(struct wlr_scene_tree *parent, struct view *view,
                return NULL;
        }
 
-       struct osd_thumbnail_item *item =
-               wl_array_add(&output->osd_scene.items, sizeof(*item));
-       item->tree = wlr_scene_tree_create(parent);
-       item->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);
+       item->base.tree = tree;
+       item->base.view = view;
 
        /* background for selected item */
        struct lab_scene_rect_options opts = {
@@ -138,13 +140,13 @@ create_item_scene(struct wlr_scene_tree *parent, struct view *view,
                .width = switcher_theme->item_width,
                .height = switcher_theme->item_height,
        };
-       item->active_bg = lab_scene_rect_create(item->tree, &opts);
+       item->active_bg = lab_scene_rect_create(tree, &opts);
 
        /* thumbnail */
        struct wlr_buffer *thumb_buffer = render_thumb(output, view);
        if (thumb_buffer) {
                struct wlr_scene_buffer *thumb_scene_buffer =
-                       wlr_scene_buffer_create(item->tree, thumb_buffer);
+                       wlr_scene_buffer_create(tree, thumb_buffer);
                wlr_buffer_drop(thumb_buffer);
                struct wlr_box thumb_box = box_fit_within(
                        thumb_buffer->width, thumb_buffer->height,
@@ -156,17 +158,17 @@ create_item_scene(struct wlr_scene_tree *parent, struct view *view,
        }
 
        /* title */
-       item->normal_title = create_title(item->tree, switcher_theme,
+       item->normal_title = create_title(tree, switcher_theme,
                view->title, theme->osd_label_text_color,
                theme->osd_bg_color, title_y);
-       item->active_title = create_title(item->tree, switcher_theme,
+       item->active_title = create_title(tree, switcher_theme,
                view->title, theme->osd_label_text_color,
                switcher_theme->item_active_bg_color, title_y);
 
        /* icon */
        int icon_size = switcher_theme->item_icon_size;
-       struct scaled_icon_buffer *icon_buffer = scaled_icon_buffer_create(
-               item->tree, server, icon_size, icon_size);
+       struct scaled_icon_buffer *icon_buffer =
+               scaled_icon_buffer_create(tree, server, icon_size, icon_size);
        scaled_icon_buffer_set_view(icon_buffer, view);
        int x = (switcher_theme->item_width - icon_size) / 2;
        int y = title_y - padding - icon_size + 10; /* slide by 10px */
@@ -210,7 +212,7 @@ get_items_geometry(struct output *output, struct theme *theme,
 static void
 osd_thumbnail_create(struct output *output, struct wl_array *views)
 {
-       assert(!output->osd_scene.tree);
+       assert(!output->osd_scene.tree && wl_list_empty(&output->osd_scene.items));
 
        struct server *server = output->server;
        struct theme *theme = server->theme;
@@ -236,7 +238,7 @@ osd_thumbnail_create(struct output *output, struct wl_array *views)
                }
                int x = (index % nr_cols) * switcher_theme->item_width + padding;
                int y = (index / nr_cols) * switcher_theme->item_height + padding;
-               wlr_scene_node_set_position(&item->tree->node, x, y);
+               wlr_scene_node_set_position(&item->base.tree->node, x, y);
                index++;
        }
 
@@ -266,8 +268,8 @@ static void
 osd_thumbnail_update(struct output *output)
 {
        struct osd_thumbnail_item *item;
-       wl_array_for_each(item, &output->osd_scene.items) {
-               bool active = (item->view == output->server->osd_state.cycle_view);
+       wl_list_for_each(item, &output->osd_scene.items, base.link) {
+               bool active = (item->base.view == output->server->osd_state.cycle_view);
                wlr_scene_node_set_enabled(&item->active_bg->tree->node, active);
                wlr_scene_node_set_enabled(
                        &item->active_title->scene_buffer->node, active);
index 865a58ddd3854033fb4055cf7f1aa2a695e6bae7..6191640e2340b57f3d3aeecc33b3302f6d4620b5 100644 (file)
@@ -24,12 +24,15 @@ destroy_osd_scenes(struct server *server)
 {
        struct output *output;
        wl_list_for_each(output, &server->outputs, link) {
+               struct osd_item *item, *tmp;
+               wl_list_for_each_safe(item, tmp, &output->osd_scene.items, link) {
+                       wl_list_remove(&item->link);
+                       free(item);
+               }
                if (output->osd_scene.tree) {
                        wlr_scene_node_destroy(&output->osd_scene.tree->node);
                        output->osd_scene.tree = NULL;
                }
-               wl_array_release(&output->osd_scene.items);
-               wl_array_init(&output->osd_scene.items);
        }
 }
 
index adee3f9d1eaf3f4c6eca863ba74b8981a678bb33..70266d5cc44ce88e950b7c760d9e4e80ec19b7c3 100644 (file)
@@ -500,7 +500,7 @@ handle_new_output(struct wl_listener *listener, void *data)
        wl_signal_add(&wlr_output->events.request_state, &output->request_state);
 
        wl_list_init(&output->regions);
-       wl_array_init(&output->osd_scene.items);
+       wl_list_init(&output->osd_scene.items);
 
        /*
         * Create layer-trees (background, bottom, top and overlay) and