diff --git a/include/ssd-internal.h b/include/ssd-internal.h index 82652f2c..a8bd19f6 100644 --- a/include/ssd-internal.h +++ b/include/ssd-internal.h @@ -129,7 +129,7 @@ add_toggled_icon(struct wl_list *part_list, enum ssd_part_type type, struct ssd_part *add_scene_button_corner( struct wl_list *part_list, enum ssd_part_type type, enum ssd_part_type corner_type, struct wlr_scene_tree *parent, - struct wlr_buffer *corner_buffer, struct wlr_buffer *icon_buffer, + float *bg_color, struct wlr_buffer *corner_buffer, struct wlr_buffer *icon_buffer, struct wlr_buffer *hover_buffer, int x, struct view *view); /* SSD internal helpers */ diff --git a/include/theme.h b/include/theme.h index b4c0e738..26232611 100644 --- a/include/theme.h +++ b/include/theme.h @@ -128,4 +128,13 @@ void theme_init(struct theme *theme, const char *theme_name); */ void theme_finish(struct theme *theme); +void theme_parse_hexstr(const char *hex, float *rgba); + +/** + * get_theme_for_view - get theme with check for custom color + * @view: view data + * @return: theme struct with color customization + */ +struct theme get_theme_for_view(struct view *view); + #endif /* LABWC_THEME_H */ diff --git a/include/window-rules.h b/include/window-rules.h index 626fb540..7dc4e418 100644 --- a/include/window-rules.h +++ b/include/window-rules.h @@ -18,6 +18,7 @@ enum property { * - 'app_id' for native Wayland windows * - 'WM_CLASS' for XWayland clients */ + struct window_rule { char *identifier; char *title; @@ -33,6 +34,10 @@ struct window_rule { enum property fixed_position; struct wl_list link; /* struct rcxml.window_rules */ + + /* Customisation window title and borders*/ + bool has_custom_border; + float custom_border_color[4]; }; struct view; @@ -40,4 +45,11 @@ struct view; void window_rules_apply(struct view *view, enum window_rule_event event); enum property window_rules_get_property(struct view *view, const char *property); +/** + * window_rules_get_custom_border_color - check for presence of custom color in window rules + * @view: view data + * @return: pointer to custom color or NULL if there is no custom color + */ +float *window_rules_get_custom_border_color(struct view *view); + #endif /* LABWC_WINDOW_RULES_H */ diff --git a/src/config/rcxml.c b/src/config/rcxml.c index 56f93e36..e0b3f2ec 100644 --- a/src/config/rcxml.c +++ b/src/config/rcxml.c @@ -31,6 +31,7 @@ #include "view.h" #include "window-rules.h" #include "workspaces.h" +#include "theme.h" static bool in_regions; static bool in_usable_area_override; @@ -137,6 +138,7 @@ fill_window_rule(char *nodename, char *content) } else if (!strcmp(nodename, "identifier")) { free(current_window_rule->identifier); current_window_rule->identifier = xstrdup(content); + wlr_log(WLR_INFO, "Identifier found: %s=\"%s\"", nodename, content); } else if (!strcmp(nodename, "title")) { free(current_window_rule->title); current_window_rule->title = xstrdup(content); @@ -165,6 +167,11 @@ fill_window_rule(char *nodename, char *content) } else if (!strcasecmp(nodename, "fixedPosition")) { set_property(content, ¤t_window_rule->fixed_position); + /* Custom border properties: color */ + } else if (!strcasecmp(nodename, "borderColor")) { + theme_parse_hexstr(content, current_window_rule->custom_border_color); + current_window_rule->has_custom_border = true; + /* Actions */ } else if (!strcmp(nodename, "name.action")) { current_window_rule_action = action_create(content); diff --git a/src/ssd/ssd.c b/src/ssd/ssd.c index dd7f1b60..cdc691c2 100644 --- a/src/ssd/ssd.c +++ b/src/ssd/ssd.c @@ -13,6 +13,7 @@ #include "ssd-internal.h" #include "theme.h" #include "view.h" +#include "window-rules.h" struct border ssd_thickness(struct view *view) @@ -358,9 +359,11 @@ ssd_enable_keybind_inhibit_indicator(struct ssd *ssd, bool enable) return; } - float *color = enable - ? rc.theme->window_toggled_keybinds_color - : rc.theme->window_active_border_color; + float *custom_color = window_rules_get_custom_border_color(ssd->view); + + float *color = custom_color ? custom_color : + (enable ? rc.theme->window_toggled_keybinds_color + : rc.theme->window_active_border_color); struct ssd_part *part = ssd_get_part(&ssd->border.active.parts, LAB_SSD_PART_TOP); struct wlr_scene_rect *rect = wlr_scene_rect_from_node(part->node); diff --git a/src/ssd/ssd_border.c b/src/ssd/ssd_border.c index 74f29ffa..48a214b5 100644 --- a/src/ssd/ssd_border.c +++ b/src/ssd/ssd_border.c @@ -6,6 +6,7 @@ #include "ssd-internal.h" #include "theme.h" #include "view.h" +#include "window-rules.h" #define FOR_EACH_STATE(ssd, tmp) FOR_EACH(tmp, \ &(ssd)->border.active, \ @@ -33,12 +34,21 @@ ssd_border_create(struct ssd *ssd) FOR_EACH_STATE(ssd, subtree) { subtree->tree = wlr_scene_tree_create(ssd->border.tree); parent = subtree->tree; - if (subtree == &ssd->border.active) { - color = theme->window_active_border_color; + + /* Here the color changing is enough */ + float *custom_color = window_rules_get_custom_border_color(view); + if (custom_color) { + color = custom_color; } else { - color = theme->window_inactive_border_color; - wlr_scene_node_set_enabled(&parent->node, false); + if (subtree == &ssd->border.active) { + color = theme->window_active_border_color; + wlr_scene_node_set_enabled(&parent->node, true); + } else { + color = theme->window_inactive_border_color; + wlr_scene_node_set_enabled(&parent->node, false); + } } + wl_list_init(&subtree->parts); add_scene_rect(&subtree->parts, LAB_SSD_PART_LEFT, parent, theme->border_width, height, 0, 0, color); diff --git a/src/ssd/ssd_part.c b/src/ssd/ssd_part.c index f8a693f0..5d6c6013 100644 --- a/src/ssd/ssd_part.c +++ b/src/ssd/ssd_part.c @@ -80,12 +80,11 @@ add_scene_buffer(struct wl_list *list, enum ssd_part_type type, struct ssd_part * add_scene_button_corner(struct wl_list *part_list, enum ssd_part_type type, - enum ssd_part_type corner_type, struct wlr_scene_tree *parent, + enum ssd_part_type corner_type, struct wlr_scene_tree *parent, float *bg_color, struct wlr_buffer *corner_buffer, struct wlr_buffer *icon_buffer, struct wlr_buffer *hover_buffer, int x, struct view *view) { int offset_x; - float invisible[4] = { 0, 0, 0, 0 }; if (corner_type == LAB_SSD_PART_CORNER_TOP_LEFT) { offset_x = rc.theme->border_width; @@ -110,7 +109,7 @@ add_scene_button_corner(struct wl_list *part_list, enum ssd_part_type type, -offset_x, -rc.theme->border_width); /* Finally just put a usual theme button on top, using an invisible hitbox */ - add_scene_button(part_list, type, parent, invisible, icon_buffer, hover_buffer, 0, view); + add_scene_button(part_list, type, parent, bg_color, icon_buffer, hover_buffer, 0, view); return button_root; } diff --git a/src/ssd/ssd_titlebar.c b/src/ssd/ssd_titlebar.c index b0ffe8a0..c84b8139 100644 --- a/src/ssd/ssd_titlebar.c +++ b/src/ssd/ssd_titlebar.c @@ -13,6 +13,7 @@ #include "ssd-internal.h" #include "theme.h" #include "view.h" +#include "window-rules.h" #define FOR_EACH_STATE(ssd, tmp) FOR_EACH(tmp, \ &(ssd)->titlebar.active, \ @@ -25,7 +26,9 @@ void ssd_titlebar_create(struct ssd *ssd) { struct view *view = ssd->view; - struct theme *theme = view->server->theme; + /* Here the whole theme changing is more preferable */ + struct theme theme = get_theme_for_view(view); + int width = view->current.width; float *color; @@ -51,51 +54,52 @@ ssd_titlebar_create(struct ssd *ssd) FOR_EACH_STATE(ssd, subtree) { subtree->tree = wlr_scene_tree_create(ssd->titlebar.tree); parent = subtree->tree; - wlr_scene_node_set_position(&parent->node, 0, -theme->title_height); + wlr_scene_node_set_position(&parent->node, 0, -theme.title_height); if (subtree == &ssd->titlebar.active) { - color = theme->window_active_title_bg_color; - corner_top_left = &theme->corner_top_left_active_normal->base; - corner_top_right = &theme->corner_top_right_active_normal->base; - menu_button_unpressed = &theme->button_menu_active_unpressed->base; - iconify_button_unpressed = &theme->button_iconify_active_unpressed->base; - close_button_unpressed = &theme->button_close_active_unpressed->base; - maximize_button_unpressed = &theme->button_maximize_active_unpressed->base; - restore_button_unpressed = &theme->button_restore_active_unpressed->base; + color = theme.window_active_title_bg_color; + corner_top_left = &theme.corner_top_left_active_normal->base; + corner_top_right = &theme.corner_top_right_active_normal->base; + menu_button_unpressed = &theme.button_menu_active_unpressed->base; + iconify_button_unpressed = &theme.button_iconify_active_unpressed->base; + close_button_unpressed = &theme.button_close_active_unpressed->base; + maximize_button_unpressed = &theme.button_maximize_active_unpressed->base; + restore_button_unpressed = &theme.button_restore_active_unpressed->base; - menu_button_hover = &theme->button_menu_active_hover->base; - iconify_button_hover = &theme->button_iconify_active_hover->base; - close_button_hover = &theme->button_close_active_hover->base; - maximize_button_hover = &theme->button_maximize_active_hover->base; - restore_button_hover = &theme->button_restore_active_hover->base; + menu_button_hover = &theme.button_menu_active_hover->base; + iconify_button_hover = &theme.button_iconify_active_hover->base; + close_button_hover = &theme.button_close_active_hover->base; + maximize_button_hover = &theme.button_maximize_active_hover->base; + restore_button_hover = &theme.button_restore_active_hover->base; } else { - color = theme->window_inactive_title_bg_color; - corner_top_left = &theme->corner_top_left_inactive_normal->base; - corner_top_right = &theme->corner_top_right_inactive_normal->base; - menu_button_unpressed = &theme->button_menu_inactive_unpressed->base; - iconify_button_unpressed = &theme->button_iconify_inactive_unpressed->base; + color = theme.window_inactive_title_bg_color; + corner_top_left = &theme.corner_top_left_inactive_normal->base; + corner_top_right = &theme.corner_top_right_inactive_normal->base; + menu_button_unpressed = &theme.button_menu_inactive_unpressed->base; + iconify_button_unpressed = &theme.button_iconify_inactive_unpressed->base; maximize_button_unpressed = - &theme->button_maximize_inactive_unpressed->base; - restore_button_unpressed = &theme->button_restore_inactive_unpressed->base; - close_button_unpressed = &theme->button_close_inactive_unpressed->base; + &theme.button_maximize_inactive_unpressed->base; + restore_button_unpressed = &theme.button_restore_inactive_unpressed->base; + close_button_unpressed = &theme.button_close_inactive_unpressed->base; - menu_button_hover = &theme->button_menu_inactive_hover->base; - iconify_button_hover = &theme->button_iconify_inactive_hover->base; - close_button_hover = &theme->button_close_inactive_hover->base; - maximize_button_hover = &theme->button_maximize_inactive_hover->base; - restore_button_hover = &theme->button_restore_inactive_hover->base; + menu_button_hover = &theme.button_menu_inactive_hover->base; + iconify_button_hover = &theme.button_iconify_inactive_hover->base; + close_button_hover = &theme.button_close_inactive_hover->base; + maximize_button_hover = &theme.button_maximize_inactive_hover->base; + restore_button_hover = &theme.button_restore_inactive_hover->base; wlr_scene_node_set_enabled(&parent->node, false); } + wl_list_init(&subtree->parts); /* Title */ add_scene_rect(&subtree->parts, LAB_SSD_PART_TITLEBAR, parent, - width - SSD_BUTTON_WIDTH * SSD_BUTTON_COUNT, theme->title_height, + width - SSD_BUTTON_WIDTH * SSD_BUTTON_COUNT, theme.title_height, SSD_BUTTON_WIDTH, 0, color); /* Buttons */ add_scene_button_corner(&subtree->parts, LAB_SSD_BUTTON_WINDOW_MENU, LAB_SSD_PART_CORNER_TOP_LEFT, parent, - corner_top_left, menu_button_unpressed, menu_button_hover, 0, view); + color, corner_top_left, menu_button_unpressed, menu_button_hover, 0, view); add_scene_button(&subtree->parts, LAB_SSD_BUTTON_ICONIFY, parent, color, iconify_button_unpressed, iconify_button_hover, width - SSD_BUTTON_WIDTH * 3, view); @@ -106,7 +110,7 @@ ssd_titlebar_create(struct ssd *ssd) restore_button_unpressed, restore_button_hover); add_scene_button_corner(&subtree->parts, LAB_SSD_BUTTON_CLOSE, LAB_SSD_PART_CORNER_TOP_RIGHT, parent, - corner_top_right, close_button_unpressed, close_button_hover, + color, corner_top_right, close_button_unpressed, close_button_hover, width - SSD_BUTTON_WIDTH * 1, view); } FOR_EACH_END @@ -139,10 +143,18 @@ set_squared_corners(struct ssd *ssd, bool enable) /* Toggle background between invisible and titlebar background color */ struct wlr_scene_rect *rect = wlr_scene_rect_from_node(button->background); - wlr_scene_rect_set_color(rect, !enable ? (float[4]) {0, 0, 0, 0} : ( - subtree == &ssd->titlebar.active - ? rc.theme->window_active_title_bg_color - : rc.theme->window_inactive_title_bg_color)); + /*Check for custom color as well*/ + float *custom_color = window_rules_get_custom_border_color(ssd->view); + float *rect_color; + if (custom_color) { + rect_color = custom_color; + } else { + rect_color = !enable ? (float[4]) {0, 0, 0, 0} + : (subtree == &ssd->titlebar.active + ? rc.theme->window_active_title_bg_color + : rc.theme->window_inactive_title_bg_color); + } + wlr_scene_rect_set_color(rect, rect_color); /* Toggle rounded corner image itself */ struct wlr_scene_node *rounded_corner = diff --git a/src/theme.c b/src/theme.c index fda8b742..262f05d6 100644 --- a/src/theme.c +++ b/src/theme.c @@ -36,7 +36,9 @@ #include "theme.h" #include "buffer.h" #include "ssd.h" - +#include "view.h" +#include "labwc.h" +#include "window-rules.h" struct button { const char *name; const char *alt_name; @@ -395,8 +397,8 @@ hex_to_dec(char c) * @hex: hex string to be parsed * @rgba: pointer to float[4] for return value */ -static void -parse_hexstr(const char *hex, float *rgba) +void +theme_parse_hexstr(const char *hex, float *rgba) { if (!hex || hex[0] != '#' || strlen(hex) < 7) { return; @@ -444,39 +446,39 @@ theme_builtin(struct theme *theme) theme->menu_overlap_x = 0; theme->menu_overlap_y = 0; - parse_hexstr("#e1dedb", theme->window_active_border_color); - parse_hexstr("#f6f5f4", theme->window_inactive_border_color); + theme_parse_hexstr("#e1dedb", theme->window_active_border_color); + theme_parse_hexstr("#f6f5f4", theme->window_inactive_border_color); - parse_hexstr("#ff0000", theme->window_toggled_keybinds_color); + theme_parse_hexstr("#ff0000", theme->window_toggled_keybinds_color); - parse_hexstr("#e1dedb", theme->window_active_title_bg_color); - parse_hexstr("#f6f5f4", theme->window_inactive_title_bg_color); + theme_parse_hexstr("#e1dedb", theme->window_active_title_bg_color); + theme_parse_hexstr("#f6f5f4", theme->window_inactive_title_bg_color); - parse_hexstr("#000000", theme->window_active_label_text_color); - parse_hexstr("#000000", theme->window_inactive_label_text_color); + theme_parse_hexstr("#000000", theme->window_active_label_text_color); + theme_parse_hexstr("#000000", theme->window_inactive_label_text_color); theme->window_label_text_justify = parse_justification("Center"); - parse_hexstr("#000000", + theme_parse_hexstr("#000000", theme->window_active_button_menu_unpressed_image_color); - parse_hexstr("#000000", + theme_parse_hexstr("#000000", theme->window_active_button_iconify_unpressed_image_color); - parse_hexstr("#000000", + theme_parse_hexstr("#000000", theme->window_active_button_max_unpressed_image_color); - parse_hexstr("#000000", + theme_parse_hexstr("#000000", theme->window_active_button_close_unpressed_image_color); - parse_hexstr("#000000", + theme_parse_hexstr("#000000", theme->window_inactive_button_menu_unpressed_image_color); - parse_hexstr("#000000", + theme_parse_hexstr("#000000", theme->window_inactive_button_iconify_unpressed_image_color); - parse_hexstr("#000000", + theme_parse_hexstr("#000000", theme->window_inactive_button_max_unpressed_image_color); - parse_hexstr("#000000", + theme_parse_hexstr("#000000", theme->window_inactive_button_close_unpressed_image_color); - parse_hexstr("#fcfbfa", theme->menu_items_bg_color); - parse_hexstr("#000000", theme->menu_items_text_color); - parse_hexstr("#e1dedb", theme->menu_items_active_bg_color); - parse_hexstr("#000000", theme->menu_items_active_text_color); + theme_parse_hexstr("#fcfbfa", theme->menu_items_bg_color); + theme_parse_hexstr("#000000", theme->menu_items_text_color); + theme_parse_hexstr("#e1dedb", theme->menu_items_active_bg_color); + theme_parse_hexstr("#000000", theme->menu_items_active_text_color); theme->menu_item_padding_x = 7; theme->menu_item_padding_y = 4; @@ -487,7 +489,7 @@ theme_builtin(struct theme *theme) theme->menu_separator_line_thickness = 1; theme->menu_separator_padding_width = 6; theme->menu_separator_padding_height = 3; - parse_hexstr("#888888", theme->menu_separator_color); + theme_parse_hexstr("#888888", theme->menu_separator_color); theme->osd_window_switcher_width = 600; theme->osd_window_switcher_padding = 4; @@ -539,33 +541,33 @@ entry(struct theme *theme, const char *key, const char *value) } if (match_glob(key, "window.active.border.color")) { - parse_hexstr(value, theme->window_active_border_color); + theme_parse_hexstr(value, theme->window_active_border_color); } if (match_glob(key, "window.inactive.border.color")) { - parse_hexstr(value, theme->window_inactive_border_color); + theme_parse_hexstr(value, theme->window_inactive_border_color); } /* border.color is obsolete, but handled for backward compatibility */ if (match_glob(key, "border.color")) { - parse_hexstr(value, theme->window_active_border_color); - parse_hexstr(value, theme->window_inactive_border_color); + theme_parse_hexstr(value, theme->window_active_border_color); + theme_parse_hexstr(value, theme->window_inactive_border_color); } if (match_glob(key, "window.active.indicator.toggled-keybind.color")) { - parse_hexstr(value, theme->window_toggled_keybinds_color); + theme_parse_hexstr(value, theme->window_toggled_keybinds_color); } if (match_glob(key, "window.active.title.bg.color")) { - parse_hexstr(value, theme->window_active_title_bg_color); + theme_parse_hexstr(value, theme->window_active_title_bg_color); } if (match_glob(key, "window.inactive.title.bg.color")) { - parse_hexstr(value, theme->window_inactive_title_bg_color); + theme_parse_hexstr(value, theme->window_inactive_title_bg_color); } if (match_glob(key, "window.active.label.text.color")) { - parse_hexstr(value, theme->window_active_label_text_color); + theme_parse_hexstr(value, theme->window_active_label_text_color); } if (match_glob(key, "window.inactive.label.text.color")) { - parse_hexstr(value, theme->window_inactive_label_text_color); + theme_parse_hexstr(value, theme->window_inactive_label_text_color); } if (match_glob(key, "window.label.text.justify")) { theme->window_label_text_justify = parse_justification(value); @@ -573,57 +575,57 @@ entry(struct theme *theme, const char *key, const char *value) /* universal button */ if (match_glob(key, "window.active.button.unpressed.image.color")) { - parse_hexstr(value, + theme_parse_hexstr(value, theme->window_active_button_menu_unpressed_image_color); - parse_hexstr(value, + theme_parse_hexstr(value, theme->window_active_button_iconify_unpressed_image_color); - parse_hexstr(value, + theme_parse_hexstr(value, theme->window_active_button_max_unpressed_image_color); - parse_hexstr(value, + theme_parse_hexstr(value, theme->window_active_button_close_unpressed_image_color); } if (match_glob(key, "window.inactive.button.unpressed.image.color")) { - parse_hexstr(value, + theme_parse_hexstr(value, theme->window_inactive_button_menu_unpressed_image_color); - parse_hexstr(value, + theme_parse_hexstr(value, theme->window_inactive_button_iconify_unpressed_image_color); - parse_hexstr(value, + theme_parse_hexstr(value, theme->window_inactive_button_max_unpressed_image_color); - parse_hexstr(value, + theme_parse_hexstr(value, theme->window_inactive_button_close_unpressed_image_color); } /* individual buttons */ if (match_glob(key, "window.active.button.menu.unpressed.image.color")) { - parse_hexstr(value, + theme_parse_hexstr(value, theme->window_active_button_menu_unpressed_image_color); } if (match_glob(key, "window.active.button.iconify.unpressed.image.color")) { - parse_hexstr(value, + theme_parse_hexstr(value, theme->window_active_button_iconify_unpressed_image_color); } if (match_glob(key, "window.active.button.max.unpressed.image.color")) { - parse_hexstr(value, + theme_parse_hexstr(value, theme->window_active_button_max_unpressed_image_color); } if (match_glob(key, "window.active.button.close.unpressed.image.color")) { - parse_hexstr(value, + theme_parse_hexstr(value, theme->window_active_button_close_unpressed_image_color); } if (match_glob(key, "window.inactive.button.menu.unpressed.image.color")) { - parse_hexstr(value, + theme_parse_hexstr(value, theme->window_inactive_button_menu_unpressed_image_color); } if (match_glob(key, "window.inactive.button.iconify.unpressed.image.color")) { - parse_hexstr(value, + theme_parse_hexstr(value, theme->window_inactive_button_iconify_unpressed_image_color); } if (match_glob(key, "window.inactive.button.max.unpressed.image.color")) { - parse_hexstr(value, + theme_parse_hexstr(value, theme->window_inactive_button_max_unpressed_image_color); } if (match_glob(key, "window.inactive.button.close.unpressed.image.color")) { - parse_hexstr(value, + theme_parse_hexstr(value, theme->window_inactive_button_close_unpressed_image_color); } @@ -635,16 +637,16 @@ entry(struct theme *theme, const char *key, const char *value) } if (match_glob(key, "menu.items.bg.color")) { - parse_hexstr(value, theme->menu_items_bg_color); + theme_parse_hexstr(value, theme->menu_items_bg_color); } if (match_glob(key, "menu.items.text.color")) { - parse_hexstr(value, theme->menu_items_text_color); + theme_parse_hexstr(value, theme->menu_items_text_color); } if (match_glob(key, "menu.items.active.bg.color")) { - parse_hexstr(value, theme->menu_items_active_bg_color); + theme_parse_hexstr(value, theme->menu_items_active_bg_color); } if (match_glob(key, "menu.items.active.text.color")) { - parse_hexstr(value, theme->menu_items_active_text_color); + theme_parse_hexstr(value, theme->menu_items_active_text_color); } if (match_glob(key, "menu.separator.width")) { @@ -657,17 +659,17 @@ entry(struct theme *theme, const char *key, const char *value) theme->menu_separator_padding_height = atoi(value); } if (match_glob(key, "menu.separator.color")) { - parse_hexstr(value, theme->menu_separator_color); + theme_parse_hexstr(value, theme->menu_separator_color); } if (match_glob(key, "osd.bg.color")) { - parse_hexstr(value, theme->osd_bg_color); + theme_parse_hexstr(value, theme->osd_bg_color); } if (match_glob(key, "osd.border.width")) { theme->osd_border_width = atoi(value); } if (match_glob(key, "osd.border.color")) { - parse_hexstr(value, theme->osd_border_color); + theme_parse_hexstr(value, theme->osd_border_color); } if (match_glob(key, "osd.window-switcher.width")) { theme->osd_window_switcher_width = atoi(value); @@ -691,7 +693,7 @@ entry(struct theme *theme, const char *key, const char *value) theme->osd_workspace_switcher_boxes_height = atoi(value); } if (match_glob(key, "osd.label.text.color")) { - parse_hexstr(value, theme->osd_label_text_color); + theme_parse_hexstr(value, theme->osd_label_text_color); } } @@ -1042,3 +1044,40 @@ theme_finish(struct theme *theme) zdrop(&theme->corner_top_right_active_normal); zdrop(&theme->corner_top_right_inactive_normal); } + +struct theme +get_theme_for_view(struct view *view) +{ + float *custom_color = window_rules_get_custom_border_color(view); + if (!custom_color) { + return *view->server->theme; + } + + struct theme theme = { 0 }; + + /* The same code as in theme_init*(), but with introducing custom color*/ + theme_builtin(&theme); + + struct wl_list paths; + paths_theme_create(&paths, rc.theme_name, "themerc"); + theme_read(&theme, &paths); + paths_destroy(&paths); + + paths_config_create(&paths, "themerc-override"); + theme_read(&theme, &paths); + paths_destroy(&paths); + + memcpy(theme.window_active_border_color, custom_color, sizeof(float)*4); + memcpy(theme.window_inactive_border_color, custom_color, sizeof(float)*4); + memcpy(theme.window_active_title_bg_color, custom_color, sizeof(float)*4); + memcpy(theme.window_inactive_title_bg_color, custom_color, sizeof(float)*4); + memcpy(theme.osd_bg_color, custom_color, sizeof(float)*4); + memcpy(theme.osd_border_color, custom_color, sizeof(float)*4); + memcpy(theme.window_toggled_keybinds_color, custom_color, sizeof(float)*4); + + post_processing(&theme); + create_corners(&theme); + load_buttons(&theme); + + return theme; +} diff --git a/src/window-rules.c b/src/window-rules.c index 3ee83a5b..480f7d50 100644 --- a/src/window-rules.c +++ b/src/window-rules.c @@ -135,3 +135,17 @@ window_rules_get_property(struct view *view, const char *property) } return LAB_PROP_UNSPECIFIED; } + +float* +window_rules_get_custom_border_color(struct view *view) +{ + struct window_rule *rule; + wl_list_for_each_reverse(rule, &rc.window_rules, link) { + if (view_matches_criteria(rule, view)) { + if (rule->has_custom_border) { + return rule->custom_border_color; + } + } + } + return NULL; +}