]> git.mdlowis.com Git - proto/labwc.git/commitdiff
osd-classic: add theme options for selected window item
authortokyo4j <hrak1529@gmail.com>
Wed, 1 Oct 2025 05:25:43 +0000 (14:25 +0900)
committerHiroaki Yamamoto <hrak1529@gmail.com>
Sun, 12 Oct 2025 16:46:43 +0000 (01:46 +0900)
This commit adds new theme options:
- osd.window-switcher.style-classic.item.active.border.color
- osd.window-switcher.style-classic.item.active.bg.color

These theme options configures the border/background of selected window
item in the `classic` style window switcher. Their default values are
identical to `thumbnail` style window switcher, which means the default
border color is now `osd.label.text.color` with 50% opacity and the
default background color is now `osd.label.text.color` with 15% opacity.

docs/labwc-theme.5.scd
docs/themerc
include/theme.h
src/osd/osd-classic.c
src/theme.c

index fad8a77ece04f6be56e0b93e7081e92df3db563c..8097615b3f6bbea47becaf78e03fb637f990ea11 100644 (file)
@@ -327,6 +327,14 @@ all are supported.
        Border width of the selection box in the window switcher in pixels.
        Default is 2.
 
+*osd.window-switcher.style-classic.item.active.border.color*
+       Border color around the selected window switcher item.
+       Default is *osd.label.text.color* with 50% opacity.
+
+*osd.window-switcher.style-classic.item.active.bg.color*
+       Background color of the selected window switcher item.
+       Default is *osd.label.text.color* with 15% opacity.
+
 *osd.window-switcher.style-classic.item.icon.size*
        Size of the icon in window switcher, in pixels.
        If not set, the font size derived from <theme><font place="OnScreenDisplay">
index a52dfacd99cce9a161567ee944f68df6c36bf35e..9139170c6f4e569133138c3e31158fdcf5800d60 100644 (file)
@@ -97,6 +97,8 @@ osd.window-switcher.style-classic.padding: 4
 osd.window-switcher.style-classic.item.padding.x: 10
 osd.window-switcher.style-classic.item.padding.y: 1
 osd.window-switcher.style-classic.item.active.border.width: 2
+osd.window-switcher.style-classic.item.active.border.color: #706f6d
+osd.window-switcher.style-classic.item.active.bg.color: #bfbcba
 # The icon size the same as the font size by default
 # osd.window-switcher.style-classic.item.icon.size: 50
 
index 797b5072dcd8294942745507056a82bdfcd62594..e7e13d66fa42b07f37d6ba8df9d68e84665b1d2f 100644 (file)
@@ -170,6 +170,8 @@ struct theme {
                int item_padding_x;
                int item_padding_y;
                int item_active_border_width;
+               float item_active_border_color[4];
+               float item_active_bg_color[4];
                int item_icon_size;
                bool width_is_percent;
 
index be740f2f786c282941025b221fec217cee0e898b..4cb9286769e802bfdf424b1f6566d30dadb70c09 100644 (file)
 
 struct osd_classic_scene_item {
        struct view *view;
-       struct wlr_scene_node *highlight_outline;
+       struct wlr_scene_tree *normal_tree, *active_tree;
 };
 
+static void
+create_fields_scene(struct server *server, struct view *view,
+               struct wlr_scene_tree *parent, const float *text_color,
+               const float *bg_color, int field_widths_sum, int x, int y)
+{
+       struct theme *theme = server->theme;
+       struct window_switcher_classic_theme *switcher_theme =
+               &theme->osd_window_switcher_classic;
+
+       struct window_switcher_field *field;
+       wl_list_for_each(field, &rc.window_switcher.fields, link) {
+               int field_width = field_widths_sum * field->width / 100.0;
+               struct wlr_scene_node *node = NULL;
+               int height = -1;
+
+               if (field->content == LAB_FIELD_ICON) {
+                       int icon_size = MIN(field_width,
+                               switcher_theme->item_icon_size);
+                       struct scaled_icon_buffer *icon_buffer =
+                               scaled_icon_buffer_create(parent,
+                                       server, icon_size, icon_size);
+                       scaled_icon_buffer_set_view(icon_buffer, view);
+                       node = &icon_buffer->scene_buffer->node;
+                       height = icon_size;
+               } else {
+                       struct buf buf = BUF_INIT;
+                       osd_field_get_content(field, &buf, view);
+
+                       if (!string_null_or_empty(buf.data)) {
+                               struct scaled_font_buffer *font_buffer =
+                                       scaled_font_buffer_create(parent);
+                               scaled_font_buffer_update(font_buffer,
+                                       buf.data, field_width,
+                                       &rc.font_osd, text_color, bg_color);
+                               node = &font_buffer->scene_buffer->node;
+                               height = font_height(&rc.font_osd);
+                       }
+
+                       buf_reset(&buf);
+               }
+
+               if (node) {
+                       int item_height = switcher_theme->item_height;
+                       wlr_scene_node_set_position(node,
+                               x, y + (item_height - height) / 2);
+               }
+               x += field_width + switcher_theme->item_padding_x;
+       }
+}
+
 static void
 osd_classic_create(struct output *output, struct wl_array *views)
 {
@@ -126,62 +176,33 @@ osd_classic_create(struct output *output, struct wl_array *views)
                        + 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);
+               wlr_scene_node_set_enabled(&item->active_tree->node, false);
 
-               struct window_switcher_field *field;
-               wl_list_for_each(field, &rc.window_switcher.fields, link) {
-                       int field_width = field_widths_sum * field->width / 100.0;
-                       struct wlr_scene_node *node = NULL;
-                       int height = -1;
-
-                       if (field->content == LAB_FIELD_ICON) {
-                               int icon_size = MIN(field_width,
-                                       switcher_theme->item_icon_size);
-                               struct scaled_icon_buffer *icon_buffer =
-                                       scaled_icon_buffer_create(item_root,
-                                               server, icon_size, icon_size);
-                               scaled_icon_buffer_set_view(icon_buffer, *view);
-                               node = &icon_buffer->scene_buffer->node;
-                               height = icon_size;
-                       } else {
-                               buf_clear(&buf);
-                               osd_field_get_content(field, &buf, *view);
-
-                               if (!string_null_or_empty(buf.data)) {
-                                       struct scaled_font_buffer *font_buffer =
-                                               scaled_font_buffer_create(item_root);
-                                       scaled_font_buffer_update(font_buffer,
-                                               buf.data, field_width,
-                                               &rc.font_osd, text_color, bg_color);
-                                       node = &font_buffer->scene_buffer->node;
-                                       height = font_height(&rc.font_osd);
-                               }
-                       }
-
-                       if (node) {
-                               int item_height = switcher_theme->item_height;
-                               wlr_scene_node_set_position(node,
-                                       x, y + (item_height - height) / 2);
-                       }
-                       x += field_width + switcher_theme->item_padding_x;
-               }
+               float *active_bg_color = switcher_theme->item_active_bg_color;
+               float *active_border_color = switcher_theme->item_active_border_color;
 
                /* Highlight around selected window's item */
                int highlight_x = theme->osd_border_width
                                + switcher_theme->padding;
                struct lab_scene_rect_options highlight_opts = {
-                       .border_colors = (float *[1]) {text_color},
+                       .border_colors = (float *[1]) {active_border_color},
+                       .bg_color = active_bg_color,
                        .nr_borders = 1,
                        .border_width = switcher_theme->item_active_border_width,
                        .width = w - 2 * theme->osd_border_width
                                - 2 * switcher_theme->padding,
                        .height = switcher_theme->item_height,
                };
-
                struct lab_scene_rect *highlight_rect = lab_scene_rect_create(
-                       output->osd_scene.tree, &highlight_opts);
-               item->highlight_outline = &highlight_rect->tree->node;
-               wlr_scene_node_set_position(item->highlight_outline, highlight_x, y);
-               wlr_scene_node_set_enabled(item->highlight_outline, false);
+                       item->active_tree, &highlight_opts);
+               wlr_scene_node_set_position(&highlight_rect->tree->node, highlight_x, 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,
+                       text_color, active_bg_color, field_widths_sum, x, y);
 
                y += switcher_theme->item_height;
        }
@@ -200,8 +221,9 @@ osd_classic_update(struct output *output)
 {
        struct osd_classic_scene_item *item;
        wl_array_for_each(item, &output->osd_scene.items) {
-               wlr_scene_node_set_enabled(item->highlight_outline,
-                       item->view == output->server->osd_state.cycle_view);
+               bool active = item->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 a3aec34a261c7c99a674166f8fde225a2a7d1e04..acdbc16beaf00a81588e32689762d7bb74a3c0c7 100644 (file)
@@ -604,6 +604,8 @@ theme_builtin(struct theme *theme, struct server *server)
        theme->osd_window_switcher_classic.item_padding_x = 10;
        theme->osd_window_switcher_classic.item_padding_y = 1;
        theme->osd_window_switcher_classic.item_active_border_width = 2;
+       theme->osd_window_switcher_classic.item_active_border_color[0] = FLT_MIN;
+       theme->osd_window_switcher_classic.item_active_bg_color[0] = FLT_MIN;
        theme->osd_window_switcher_classic.item_icon_size = -1;
 
        theme->osd_window_switcher_thumbnail.max_width = 80;
@@ -989,6 +991,12 @@ entry(struct theme *theme, const char *key, const char *value)
                        get_int_if_positive(value,
                                "osd.window-switcher.style-classic.item.active.border.width");
        }
+       if (match_glob(key, "osd.window-switcher.style-classic.item.active.border.color")) {
+               parse_color(value, switcher_classic_theme->item_active_border_color);
+       }
+       if (match_glob(key, "osd.window-switcher.style-classic.item.active.bg.color")) {
+               parse_color(value, switcher_classic_theme->item_active_bg_color);
+       }
        if (match_glob(key, "osd.window-switcher.style-classic.item.icon.size")
                        || match_glob(key, "osd.window-switcher.item.icon.size")) {
                switcher_classic_theme->item_icon_size =
@@ -1746,6 +1754,14 @@ post_processing(struct theme *theme)
                memcpy(theme->osd_border_color, theme->osd_label_text_color,
                        sizeof(theme->osd_border_color));
        }
+       if (switcher_classic_theme->item_active_border_color[0] == FLT_MIN) {
+               blend_color_with_bg(switcher_classic_theme->item_active_border_color,
+                       theme->osd_label_text_color, 0.50, theme->osd_bg_color);
+       }
+       if (switcher_classic_theme->item_active_bg_color[0] == FLT_MIN) {
+               blend_color_with_bg(switcher_classic_theme->item_active_bg_color,
+                       theme->osd_label_text_color, 0.15, theme->osd_bg_color);
+       }
        if (switcher_thumb_theme->item_active_border_color[0] == FLT_MIN) {
                blend_color_with_bg(switcher_thumb_theme->item_active_border_color,
                        theme->osd_label_text_color, 0.50, theme->osd_bg_color);