From a3ae60f621b9a12acca96f714de7ac0185ad02b2 Mon Sep 17 00:00:00 2001 From: Jas Singh Date: Sat, 28 Sep 2024 12:48:01 -0700 Subject: [PATCH] Added Smart Highlighting for mapped workspaces. (#288) * Improved workspace highlighting and added smart highlight option * Added to default workspace variant. * Remove hover effects * Remove unused functions. * Remove unused hover properties * Remove unused variable from utils. * Make hideUnoccupied the default option --- modules/bar/workspaces/utils.ts | 36 +++++++++++++++------ modules/bar/workspaces/variants/default.ts | 8 ++++- modules/bar/workspaces/variants/occupied.ts | 5 ++- options.ts | 3 +- scss/style/bar/notifications.scss | 1 + scss/style/bar/workspace.scss | 2 ++ widget/settings/pages/config/bar/index.ts | 8 +++++ 7 files changed, 51 insertions(+), 12 deletions(-) diff --git a/modules/bar/workspaces/utils.ts b/modules/bar/workspaces/utils.ts index ed29582..de810d0 100644 --- a/modules/bar/workspaces/utils.ts +++ b/modules/bar/workspaces/utils.ts @@ -1,8 +1,14 @@ import { WorkspaceIconMap } from 'lib/types/workspace'; import { isValidGjsColor } from 'lib/utils'; +import options from 'options'; const hyprland = await Service.import('hyprland'); +const { monochrome, background } = options.theme.bar.buttons; +const { background: wsBackground, active } = options.theme.bar.buttons.workspaces; + +const { showWsIcons } = options.bar.workspaces; + const getWsIcon = (wsIconMap: WorkspaceIconMap, i: number): string => { const iconEntry = wsIconMap[i]; @@ -23,16 +29,26 @@ const getWsIcon = (wsIconMap: WorkspaceIconMap, i: number): string => { return `${i}`; }; -export const getWsColor = (wsIconMap: WorkspaceIconMap, i: number): string => { +export const getWsColor = (wsIconMap: WorkspaceIconMap, i: number, smartHighlight: boolean): string => { const iconEntry = wsIconMap[i]; + const hasColor = typeof iconEntry === 'object' && 'color' in iconEntry && isValidGjsColor(iconEntry.color); if (!iconEntry) { return ''; } - const hasColor = typeof iconEntry === 'object' && 'color' in iconEntry && iconEntry.color !== ''; + if (showWsIcons.value && smartHighlight && hyprland.active.workspace.id === i) { + const iconColor = monochrome.value ? background : wsBackground; + const iconBackground = hasColor && isValidGjsColor(iconEntry.color) ? iconEntry.color : active.value; + const colorCss = `color: ${iconColor};`; + const backgroundCss = `background: ${iconBackground};`; + + return colorCss + backgroundCss; + } + if (hasColor && isValidGjsColor(iconEntry.color)) { return `color: ${iconEntry.color}; border-bottom-color: ${iconEntry.color};`; } + return ''; }; @@ -41,21 +57,23 @@ export const renderClassnames = ( showNumbered: boolean, numberedActiveIndicator: string, showWsIcons: boolean, + smartHighlight: boolean, i: number, ): string => { if (showIcons) { - return `workspace-icon txt-icon bar`; + return 'workspace-icon txt-icon bar'; } + if (showNumbered || showWsIcons) { - const numActiveInd = hyprland.active.workspace.id === i ? `${numberedActiveIndicator}` : ''; + const numActiveInd = hyprland.active.workspace.id === i ? numberedActiveIndicator : ''; + const wsIconClass = showWsIcons ? 'txt-icon' : ''; + const smartHighlightClass = smartHighlight ? 'smart-highlight' : ''; - const className = - `workspace-number can_${numberedActiveIndicator} ` + - `${numActiveInd} ` + - `${showWsIcons ? 'txt-icon' : ''}`; + const className = `workspace-number can_${numberedActiveIndicator} ${numActiveInd} ${wsIconClass} ${smartHighlightClass}`; - return className; + return className.trim(); } + return 'default'; }; diff --git a/modules/bar/workspaces/variants/default.ts b/modules/bar/workspaces/variants/default.ts index 2d4057c..c672d5e 100644 --- a/modules/bar/workspaces/variants/default.ts +++ b/modules/bar/workspaces/variants/default.ts @@ -41,16 +41,19 @@ export const defaultWses = (monitor: number): BoxWidget => { options.bar.workspaces.showWsIcons.bind('value'), options.bar.workspaces.workspaceIconMap.bind('value'), options.theme.matugen.bind('value'), + options.theme.bar.buttons.workspaces.smartHighlight.bind('value'), + hyprland.active.workspace.bind('id'), ], ( sp: number, showWsIcons: boolean, workspaceIconMap: WorkspaceIconMap, matugen: boolean, + smartHighlight: boolean, ) => { return ( `margin: 0rem ${0.375 * sp}rem;` + - `${showWsIcons && !matugen ? getWsColor(workspaceIconMap, i) : ''}` + `${showWsIcons && !matugen ? getWsColor(workspaceIconMap, i, smartHighlight) : ''}` ); }, ), @@ -60,6 +63,7 @@ export const defaultWses = (monitor: number): BoxWidget => { options.bar.workspaces.show_numbered.bind('value'), options.bar.workspaces.numbered_active_indicator.bind('value'), options.bar.workspaces.showWsIcons.bind('value'), + options.theme.bar.buttons.workspaces.smartHighlight.bind('value'), options.bar.workspaces.icons.available.bind('value'), options.bar.workspaces.icons.active.bind('value'), hyprland.active.workspace.bind('id'), @@ -69,12 +73,14 @@ export const defaultWses = (monitor: number): BoxWidget => { showNumbered: boolean, numberedActiveIndicator: string, showWsIcons: boolean, + smartHighlight: boolean, ) => { return renderClassnames( showIcons, showNumbered, numberedActiveIndicator, showWsIcons, + smartHighlight, i, ); }, diff --git a/modules/bar/workspaces/variants/occupied.ts b/modules/bar/workspaces/variants/occupied.ts index 0a4c72b..143c778 100644 --- a/modules/bar/workspaces/variants/occupied.ts +++ b/modules/bar/workspaces/variants/occupied.ts @@ -28,6 +28,7 @@ export const occupiedWses = (monitor: number): BoxWidget => { options.bar.workspaces.workspaceIconMap.bind('value'), options.bar.workspaces.showWsIcons.bind('value'), options.theme.matugen.bind('value'), + options.theme.bar.buttons.workspaces.smartHighlight.bind('value'), ignored.bind('value'), ], ( @@ -46,6 +47,7 @@ export const occupiedWses = (monitor: number): BoxWidget => { wsIconMap: WorkspaceIconMap, showWsIcons: boolean, matugen: boolean, + smartHighlight: boolean, ) => { let allWkspcs = range(totalWkspcs || 8); @@ -104,12 +106,13 @@ export const occupiedWses = (monitor: number): BoxWidget => { vpack: 'center', css: `margin: 0rem ${0.375 * spacing}rem;` + - `${showWsIcons && !matugen ? getWsColor(wsIconMap, i) : ''}`, + `${showWsIcons && !matugen ? getWsColor(wsIconMap, i, smartHighlight) : ''}`, class_name: renderClassnames( showIcons, showNumbered, numberedActiveIndicator, showWsIcons, + smartHighlight, i, ), label: renderLabel( diff --git a/options.ts b/options.ts index c2a2f60..ae92292 100644 --- a/options.ts +++ b/options.ts @@ -188,6 +188,7 @@ const options = mkOptions(OPTIONS, { workspaces: { background: opt(colors.base2), enableBorder: opt(false), + smartHighlight: opt(true), border: opt(colors.pink), available: opt(colors.sky), occupied: opt(colors.flamingo), @@ -874,7 +875,7 @@ const options = mkOptions(OPTIONS, { workspaces: opt(10), spacing: opt(1), monitorSpecific: opt(true), - hideUnoccupied: opt(false), + hideUnoccupied: opt(true), workspaceMask: opt(false), reverse_scroll: opt(false), scroll_speed: opt(5), diff --git a/scss/style/bar/notifications.scss b/scss/style/bar/notifications.scss index 56e500a..edf9147 100644 --- a/scss/style/bar/notifications.scss +++ b/scss/style/bar/notifications.scss @@ -27,6 +27,7 @@ $bar-buttons-radius * 0.4, $bar-buttons-radius ); + color: if($bar-buttons-monochrome, $bar-buttons-icon, $bar-buttons-notifications-icon); } .bar-button-label.notifications { diff --git a/scss/style/bar/workspace.scss b/scss/style/bar/workspace.scss index 07562e0..967cc74 100644 --- a/scss/style/bar/workspace.scss +++ b/scss/style/bar/workspace.scss @@ -44,9 +44,11 @@ &.underline { border-top: 0.1em solid transparent; border-bottom: 0.1em solid $bar-buttons-workspaces-numbered_active_underline_color; + transition: 0ms; } &.highlight { + transition: 0ms; color: $bar-buttons-workspaces-numbered_active_highlighted_text_color; border-radius: $bar-buttons-workspaces-numbered_active_highlight_border; background-color: $bar-buttons-workspaces-active; diff --git a/widget/settings/pages/config/bar/index.ts b/widget/settings/pages/config/bar/index.ts index 7dd3a80..9504803 100644 --- a/widget/settings/pages/config/bar/index.ts +++ b/widget/settings/pages/config/bar/index.ts @@ -230,6 +230,14 @@ export const BarSettings = (): Scrollable => { type: 'enum', enums: ['underline', 'highlight', 'color'], }), + Option({ + opt: options.theme.bar.buttons.workspaces.smartHighlight, + title: 'Smart Highlight', + subtitle: + 'Automatically determines the highlight color of the workspace icon.\n' + + 'Only compatible with mapped icons.', + type: 'boolean', + }), Option({ opt: options.theme.bar.buttons.workspaces.numbered_active_highlight_border, title: 'Highlight Radius',