diff --git a/include/common/borderset.h b/include/common/borderset.h index d3bd8860..445a261a 100644 --- a/include/common/borderset.h +++ b/include/common/borderset.h @@ -48,6 +48,8 @@ struct bufferset * generateBufferset(struct wlr_scene_tree * tree, struct border void renderBufferset(struct bufferset *, int width, int height, int y); +void renderBuffersetXY(struct bufferset *, int width, int height, int x, int y); + void clearBorderCache(struct borderset *borderset); #endif /* LABWC_LAB_SCENE_RECT_H */ diff --git a/include/ssd-internal.h b/include/ssd-internal.h index 1d2ff1da..5b888468 100644 --- a/include/ssd-internal.h +++ b/include/ssd-internal.h @@ -106,6 +106,7 @@ struct ssd { struct scaled_font_buffer *title; struct wl_list buttons_left; /* ssd_button.link */ struct wl_list buttons_right; /* ssd_button.link */ + struct bufferset * texturedBorders; } subtrees[2]; /* indexed by enum ssd_active_state */ } titlebar; diff --git a/include/theme.h b/include/theme.h index 6bf0473e..2612b46f 100644 --- a/include/theme.h +++ b/include/theme.h @@ -57,6 +57,11 @@ struct theme_background { float color_split_to[4]; float color_to[4]; float color_to_split_to[4]; + enum border_type border_type; + int border_width; + int bevel_width; + bool exclusive; + }; struct theme { diff --git a/src/common/borderset.c b/src/common/borderset.c index 214d6ab1..3ceccb1d 100644 --- a/src/common/borderset.c +++ b/src/common/borderset.c @@ -307,50 +307,55 @@ struct bufferset * generateBufferset(struct wlr_scene_tree * tree, struct border } void renderBufferset(struct bufferset *bufferset, int width, int height, int y) +{ + renderBuffersetXY(bufferset, width, height, 0, y); +} + +void renderBuffersetXY(struct bufferset *bufferset, int width, int height, int x, int y) { wlr_scene_buffer_set_dest_size(bufferset->top, width - 2 * bufferset->border_width, bufferset->border_width); wlr_scene_node_set_position(&bufferset->top->node, - bufferset->border_width,y); + x+bufferset->border_width,y); wlr_scene_buffer_set_dest_size(bufferset->bottom, width - 2 * bufferset->border_width, bufferset->border_width); wlr_scene_node_set_position(&bufferset->bottom->node, - bufferset->border_width, y+height - bufferset->border_width); + x+bufferset->border_width, y+height - bufferset->border_width); wlr_scene_buffer_set_dest_size(bufferset->left, bufferset->border_width, height - bufferset->border_width * 2); wlr_scene_node_set_position(&bufferset->left->node, - 0, bufferset->border_width+y); + x, bufferset->border_width+y); wlr_scene_buffer_set_dest_size(bufferset->right, bufferset->border_width, height - bufferset->border_width * 2); wlr_scene_node_set_position(&bufferset->right->node, - width - bufferset->border_width, y+ bufferset->border_width); + x+width - bufferset->border_width, y+ bufferset->border_width); wlr_scene_buffer_set_dest_size(bufferset->tl, bufferset->border_width, bufferset->border_width); wlr_scene_node_set_position(&bufferset->tl->node, - 0,y); + x,y); wlr_scene_buffer_set_dest_size(bufferset->tr, bufferset->border_width, bufferset->border_width); wlr_scene_node_set_position(&bufferset->tr->node, - width-bufferset->border_width, y); + x+width-bufferset->border_width, y); wlr_scene_buffer_set_dest_size(bufferset->br, bufferset->border_width, bufferset->border_width); wlr_scene_node_set_position(&bufferset->br->node, - width-bufferset->border_width , y+height-bufferset->border_width); + x+width-bufferset->border_width , y+height-bufferset->border_width); wlr_scene_buffer_set_dest_size(bufferset->bl, bufferset->border_width, bufferset->border_width); wlr_scene_node_set_position(&bufferset->bl->node, - 0, height-bufferset->border_width+y); + x, height-bufferset->border_width+y); } diff --git a/src/ssd/ssd-titlebar.c b/src/ssd/ssd-titlebar.c index d1a08810..79de5f1d 100644 --- a/src/ssd/ssd-titlebar.c +++ b/src/ssd/ssd-titlebar.c @@ -18,6 +18,7 @@ #include "ssd-internal.h" #include "theme.h" #include "view.h" +#include "common/borderset.h" static void set_squared_corners(struct ssd *ssd, bool enable); static void set_alt_button_icon(struct ssd *ssd, enum lab_node_type type, bool enable); @@ -52,6 +53,19 @@ ssd_titlebar_create(struct ssd *ssd) /* Background */ subtree->bar = lab_wlr_scene_buffer_create(parent, titlebar_fill); + + if (theme->window[active].title_bg.border_type) { + /* Beveled Titlebar */ + float *color = theme->window[active].title_bg.color; + float r = color[0]; + float g = color[1]; + float b = color[2]; + float a = color[3]; + + uint32_t colour32 = (uint32_t)(a*255) << 24 | (uint32_t)(r*255) << 16 | (uint32_t)(g*255) << 8 | (uint32_t)(b*255); + struct borderset * renderedborders = getBorders(colour32, theme->window[active].title_bg.border_width, theme->window[active].title_bg.border_type, theme->window[active].title_bg.bevel_width); + subtree->texturedBorders = generateBufferset(subtree->tree, renderedborders, theme->window[active].title_bg.border_width); + } /* * Work around the wlroots/pixman bug that widened 1px buffer * becomes translucent when bilinear filtering is used. @@ -318,10 +332,16 @@ ssd_titlebar_update(struct ssd *ssd) x = theme->window_titlebar_padding_width; struct ssd_button *button; + int button_count = 0; + + wl_list_for_each(button, &subtree->buttons_left, link) { wlr_scene_node_set_position(button->node, x, y); x += theme->window_button_width + theme->window_button_spacing; + button_count++; } + int exclusive_x = x; + x = width - corner_width; wlr_scene_node_set_position(&subtree->corner_right->node, @@ -331,7 +351,20 @@ ssd_titlebar_update(struct ssd *ssd) wl_list_for_each(button, &subtree->buttons_right, link) { x -= theme->window_button_width + theme->window_button_spacing; wlr_scene_node_set_position(button->node, x, y); + button_count++; } + + + if (theme->window[active].title_bg.border_type) { + int titlebar_x = 0; + int titlebar_width = MAX(width, 0); + if (theme->window[active].title_bg.exclusive) { + titlebar_x = exclusive_x+theme->window_titlebar_padding_width; + titlebar_width = MAX((theme->window_button_width + theme->window_button_spacing)* button_count, titlebar_width - (theme->window_button_width + theme->window_button_spacing)* button_count); + } + renderBuffersetXY(subtree->texturedBorders, titlebar_width, theme->titlebar_height, titlebar_x, 0); + } + } ssd_update_title(ssd); diff --git a/src/theme.c b/src/theme.c index 1a2781e2..f4dc8430 100644 --- a/src/theme.c +++ b/src/theme.c @@ -457,9 +457,6 @@ static enum border_type parse_border_type(const char *str) { if (strstr(lower, "doubleraised")) return BORDER_DOUBLE; if (strstr(lower, "raised")) return BORDER_SINGLE; return BORDER_FLAT; - - - } static void @@ -564,8 +561,16 @@ theme_builtin(struct theme *theme) theme->window[SSD_INACTIVE].title_bg.color_to_split_to[0] = FLT_MIN; theme->window[SSD_ACTIVE].bevel_width = 0; theme->window[SSD_ACTIVE].border_type = BORDER_FLAT; + theme->window[SSD_ACTIVE].title_bg.bevel_width = 0; + theme->window[SSD_ACTIVE].title_bg.border_width = 0; + theme->window[SSD_ACTIVE].title_bg.exclusive = FALSE; + theme->window[SSD_ACTIVE].title_bg.border_type = BORDER_FLAT; theme->window[SSD_INACTIVE].bevel_width = 0; theme->window[SSD_INACTIVE].border_type = BORDER_FLAT; + theme->window[SSD_INACTIVE].title_bg.bevel_width = 0; + theme->window[SSD_INACTIVE].title_bg.border_width = 0; + theme->window[SSD_INACTIVE].title_bg.exclusive = FALSE; + theme->window[SSD_INACTIVE].title_bg.border_type = BORDER_FLAT; parse_hexstr("#000000", theme->window[SSD_ACTIVE].label_text_color); parse_hexstr("#000000", theme->window[SSD_INACTIVE].label_text_color); @@ -736,7 +741,20 @@ entry(struct theme *theme, const char *key, const char *value) if (match_glob(key, "padding.height")) { wlr_log(WLR_INFO, "padding.height is no longer supported"); } - + + if (match_glob(key, "window.active.title.bg") && parse_border_type(value)) { + theme->window[SSD_ACTIVE].title_bg.border_type= parse_border_type(value); + } + if (match_glob(key, "window.active.title.bg.width")) { + theme->window[SSD_ACTIVE].title_bg.border_width = get_int_if_positive(value, "window.active.title.bg.width"); + } + + if (match_glob(key, "window.active.title.bg.exclusive")) { + set_bool(value, &theme->window[SSD_ACTIVE].title_bg.exclusive); + } + if (match_glob(key, "window.active.title.bg.bevel-width")) { + theme->window[SSD_ACTIVE].title_bg.bevel_width = get_int_if_positive(value, "window.active.title.bg.bevel-width"); + } if (match_glob(key, "window.active.border.color")) { parse_color(value, theme->window[SSD_ACTIVE].border_color); } @@ -772,6 +790,22 @@ entry(struct theme *theme, const char *key, const char *value) if (match_glob(key, "window.active.title.bg")) { theme->window[SSD_ACTIVE].title_bg.gradient = parse_gradient(value); } + + + if (match_glob(key, "window.inactive.title.bg") && parse_border_type(value)) { + theme->window[SSD_INACTIVE].title_bg.border_type= parse_border_type(value); + } + if (match_glob(key, "window.inactive.title.bg.width")) { + theme->window[SSD_INACTIVE].title_bg.border_width = get_int_if_positive(value, "window.inactive.title.bg.width"); + } + if (match_glob(key, "window.inactive.title.bg.bevel-width")) { + theme->window[SSD_INACTIVE].title_bg.bevel_width = get_int_if_positive(value, "window.inactive.title.bg.bevel-width"); + } + if (match_glob(key, "window.inactive.title.bg.exclusive")) { + set_bool(value, &theme->window[SSD_INACTIVE].title_bg.exclusive); + } + + if (match_glob(key, "window.inactive.title.bg")) { theme->window[SSD_INACTIVE].title_bg.gradient = parse_gradient(value); }