diff --git a/src/stack.ts b/src/stack.ts index 60d553bb..332cf87a 100644 --- a/src/stack.ts +++ b/src/stack.ts @@ -14,7 +14,7 @@ import St from 'gi://St'; const ACTIVE_TAB = 'pop-shell-tab pop-shell-tab-active'; const INACTIVE_TAB = 'pop-shell-tab pop-shell-tab-inactive'; const URGENT_TAB = 'pop-shell-tab pop-shell-tab-urgent'; -const INACTIVE_TAB_STYLE = '#9B8E8A'; +const INACTIVE_DARKEN_AMOUNT = -0.2; export var TAB_HEIGHT: number = 24; @@ -246,17 +246,20 @@ export class Stack { let button = this.buttons.get(component.button); if (button) { button.set_style_class_name(name); - let tab_color = ''; + + let settings = this.ext.settings; + let color_value = settings.hint_color_rgba(); + + let tab_style = ''; if (component.active) { - let settings = this.ext.settings; - let color_value = settings.hint_color_rgba(); - tab_color = `${color_value}; color: ${utils.is_dark(color_value) ? 'white' : 'black'}`; + tab_style = `background: ${color_value}; color: ${utils.is_dark(color_value) ? 'white' : 'black'};`; } else { - tab_color = `${INACTIVE_TAB_STYLE}`; + tab_style = `background: ${utils.shadeRGBA(color_value, INACTIVE_DARKEN_AMOUNT)}; ` + + `color: ${utils.is_dark(color_value) ? '#858585' : '#3d3d3d'};`; } const tab_border_radius = this.get_tab_border_radius(idx); - button.set_style(`background: ${tab_color}; border-radius: ${tab_border_radius};`); + button.set_style(`${tab_style} border-radius: ${tab_border_radius};`); } }); @@ -349,14 +352,15 @@ export class Stack { let settings = this.ext.settings; let button = this.buttons.get(tab.button); if (button) { - let tab_color = ''; + let tab_style = ''; + let color_value = settings.hint_color_rgba(); if (Ecs.entity_eq(tab.entity, this.active)) { - let color_value = settings.hint_color_rgba(); - tab_color = `background: ${color_value}; color: ${utils.is_dark(color_value) ? 'white' : 'black'}`; + tab_style = `background: ${color_value}; color: ${utils.is_dark(color_value) ? 'white' : 'black'};`; } else { - tab_color = `background: ${INACTIVE_TAB_STYLE}`; + tab_style = `background: ${utils.shadeRGBA(color_value, INACTIVE_DARKEN_AMOUNT)}; ` + + `color: ${utils.is_dark(color_value) ? '#858585' : '#3d3d3d'};`; } - button.set_style(tab_color); + button.set_style(tab_style); } } diff --git a/src/utils.ts b/src/utils.ts index e89a15c6..6ba376dd 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -82,6 +82,34 @@ export function is_dark(color: string): boolean { return L <= 0.179; } +/** + * Shades an rgba string. + * @param rgba format: 'rgba(255,255,255,1.0)' + * @param percent -0.2 to make 20% darker, 0.3 to make 30% lighter + * @returns the shaded rgba string + */ +export function shadeRGBA(rgba: string, percent: number): string { + + // handle rgba(255,255,255,1.0) format + const match = rgba.match(/rgba?\((\d+),\s*(\d+),\s*(\d+),?\s*([0-9.]+)?\)/); + if (!match) return rgba; + + let [, r, g, b, a] = match; + let rNum = parseInt(r, 10); + let gNum = parseInt(g, 10); + let bNum = parseInt(b, 10); + let aNum = a !== undefined ? parseFloat(a) : 1; + + // adjust brightness: percent > 0 lighten, percent < 0 darken + const adjust = (c: number) => Math.min(255, Math.max(0, Math.round(c + c * percent))); + + rNum = adjust(rNum); + gNum = adjust(gNum); + bNum = adjust(bNum); + + return `rgba(${rNum}, ${gNum}, ${bNum}, ${aNum})`; +} + /** Utility function for running a process in the background and fetching its standard output as a string. */ export function async_process(argv: Array, input = null, cancellable: null | any = null): Promise { let flags = Gio.SubprocessFlags.STDOUT_PIPE;