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
This commit is contained in:
Jas Singh
2024-09-28 12:48:01 -07:00
committed by GitHub
parent 233c97aff3
commit a3ae60f621
7 changed files with 51 additions and 12 deletions

View File

@@ -1,8 +1,14 @@
import { WorkspaceIconMap } from 'lib/types/workspace'; import { WorkspaceIconMap } from 'lib/types/workspace';
import { isValidGjsColor } from 'lib/utils'; import { isValidGjsColor } from 'lib/utils';
import options from 'options';
const hyprland = await Service.import('hyprland'); 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 getWsIcon = (wsIconMap: WorkspaceIconMap, i: number): string => {
const iconEntry = wsIconMap[i]; const iconEntry = wsIconMap[i];
@@ -23,16 +29,26 @@ const getWsIcon = (wsIconMap: WorkspaceIconMap, i: number): string => {
return `${i}`; 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 iconEntry = wsIconMap[i];
const hasColor = typeof iconEntry === 'object' && 'color' in iconEntry && isValidGjsColor(iconEntry.color);
if (!iconEntry) { if (!iconEntry) {
return ''; 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)) { if (hasColor && isValidGjsColor(iconEntry.color)) {
return `color: ${iconEntry.color}; border-bottom-color: ${iconEntry.color};`; return `color: ${iconEntry.color}; border-bottom-color: ${iconEntry.color};`;
} }
return ''; return '';
}; };
@@ -41,21 +57,23 @@ export const renderClassnames = (
showNumbered: boolean, showNumbered: boolean,
numberedActiveIndicator: string, numberedActiveIndicator: string,
showWsIcons: boolean, showWsIcons: boolean,
smartHighlight: boolean,
i: number, i: number,
): string => { ): string => {
if (showIcons) { if (showIcons) {
return `workspace-icon txt-icon bar`; return 'workspace-icon txt-icon bar';
} }
if (showNumbered || showWsIcons) { 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 = const className = `workspace-number can_${numberedActiveIndicator} ${numActiveInd} ${wsIconClass} ${smartHighlightClass}`;
`workspace-number can_${numberedActiveIndicator} ` +
`${numActiveInd} ` +
`${showWsIcons ? 'txt-icon' : ''}`;
return className; return className.trim();
} }
return 'default'; return 'default';
}; };

View File

@@ -41,16 +41,19 @@ export const defaultWses = (monitor: number): BoxWidget => {
options.bar.workspaces.showWsIcons.bind('value'), options.bar.workspaces.showWsIcons.bind('value'),
options.bar.workspaces.workspaceIconMap.bind('value'), options.bar.workspaces.workspaceIconMap.bind('value'),
options.theme.matugen.bind('value'), options.theme.matugen.bind('value'),
options.theme.bar.buttons.workspaces.smartHighlight.bind('value'),
hyprland.active.workspace.bind('id'),
], ],
( (
sp: number, sp: number,
showWsIcons: boolean, showWsIcons: boolean,
workspaceIconMap: WorkspaceIconMap, workspaceIconMap: WorkspaceIconMap,
matugen: boolean, matugen: boolean,
smartHighlight: boolean,
) => { ) => {
return ( return (
`margin: 0rem ${0.375 * sp}rem;` + `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.show_numbered.bind('value'),
options.bar.workspaces.numbered_active_indicator.bind('value'), options.bar.workspaces.numbered_active_indicator.bind('value'),
options.bar.workspaces.showWsIcons.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.available.bind('value'),
options.bar.workspaces.icons.active.bind('value'), options.bar.workspaces.icons.active.bind('value'),
hyprland.active.workspace.bind('id'), hyprland.active.workspace.bind('id'),
@@ -69,12 +73,14 @@ export const defaultWses = (monitor: number): BoxWidget => {
showNumbered: boolean, showNumbered: boolean,
numberedActiveIndicator: string, numberedActiveIndicator: string,
showWsIcons: boolean, showWsIcons: boolean,
smartHighlight: boolean,
) => { ) => {
return renderClassnames( return renderClassnames(
showIcons, showIcons,
showNumbered, showNumbered,
numberedActiveIndicator, numberedActiveIndicator,
showWsIcons, showWsIcons,
smartHighlight,
i, i,
); );
}, },

View File

@@ -28,6 +28,7 @@ export const occupiedWses = (monitor: number): BoxWidget => {
options.bar.workspaces.workspaceIconMap.bind('value'), options.bar.workspaces.workspaceIconMap.bind('value'),
options.bar.workspaces.showWsIcons.bind('value'), options.bar.workspaces.showWsIcons.bind('value'),
options.theme.matugen.bind('value'), options.theme.matugen.bind('value'),
options.theme.bar.buttons.workspaces.smartHighlight.bind('value'),
ignored.bind('value'), ignored.bind('value'),
], ],
( (
@@ -46,6 +47,7 @@ export const occupiedWses = (monitor: number): BoxWidget => {
wsIconMap: WorkspaceIconMap, wsIconMap: WorkspaceIconMap,
showWsIcons: boolean, showWsIcons: boolean,
matugen: boolean, matugen: boolean,
smartHighlight: boolean,
) => { ) => {
let allWkspcs = range(totalWkspcs || 8); let allWkspcs = range(totalWkspcs || 8);
@@ -104,12 +106,13 @@ export const occupiedWses = (monitor: number): BoxWidget => {
vpack: 'center', vpack: 'center',
css: css:
`margin: 0rem ${0.375 * spacing}rem;` + `margin: 0rem ${0.375 * spacing}rem;` +
`${showWsIcons && !matugen ? getWsColor(wsIconMap, i) : ''}`, `${showWsIcons && !matugen ? getWsColor(wsIconMap, i, smartHighlight) : ''}`,
class_name: renderClassnames( class_name: renderClassnames(
showIcons, showIcons,
showNumbered, showNumbered,
numberedActiveIndicator, numberedActiveIndicator,
showWsIcons, showWsIcons,
smartHighlight,
i, i,
), ),
label: renderLabel( label: renderLabel(

View File

@@ -188,6 +188,7 @@ const options = mkOptions(OPTIONS, {
workspaces: { workspaces: {
background: opt(colors.base2), background: opt(colors.base2),
enableBorder: opt(false), enableBorder: opt(false),
smartHighlight: opt(true),
border: opt(colors.pink), border: opt(colors.pink),
available: opt(colors.sky), available: opt(colors.sky),
occupied: opt(colors.flamingo), occupied: opt(colors.flamingo),
@@ -874,7 +875,7 @@ const options = mkOptions(OPTIONS, {
workspaces: opt(10), workspaces: opt(10),
spacing: opt(1), spacing: opt(1),
monitorSpecific: opt(true), monitorSpecific: opt(true),
hideUnoccupied: opt(false), hideUnoccupied: opt(true),
workspaceMask: opt(false), workspaceMask: opt(false),
reverse_scroll: opt(false), reverse_scroll: opt(false),
scroll_speed: opt(5), scroll_speed: opt(5),

View File

@@ -27,6 +27,7 @@
$bar-buttons-radius * 0.4, $bar-buttons-radius * 0.4,
$bar-buttons-radius $bar-buttons-radius
); );
color: if($bar-buttons-monochrome, $bar-buttons-icon, $bar-buttons-notifications-icon);
} }
.bar-button-label.notifications { .bar-button-label.notifications {

View File

@@ -44,9 +44,11 @@
&.underline { &.underline {
border-top: 0.1em solid transparent; border-top: 0.1em solid transparent;
border-bottom: 0.1em solid $bar-buttons-workspaces-numbered_active_underline_color; border-bottom: 0.1em solid $bar-buttons-workspaces-numbered_active_underline_color;
transition: 0ms;
} }
&.highlight { &.highlight {
transition: 0ms;
color: $bar-buttons-workspaces-numbered_active_highlighted_text_color; color: $bar-buttons-workspaces-numbered_active_highlighted_text_color;
border-radius: $bar-buttons-workspaces-numbered_active_highlight_border; border-radius: $bar-buttons-workspaces-numbered_active_highlight_border;
background-color: $bar-buttons-workspaces-active; background-color: $bar-buttons-workspaces-active;

View File

@@ -230,6 +230,14 @@ export const BarSettings = (): Scrollable<Gtk.Widget, Gtk.Widget> => {
type: 'enum', type: 'enum',
enums: ['underline', 'highlight', 'color'], 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({ Option({
opt: options.theme.bar.buttons.workspaces.numbered_active_highlight_border, opt: options.theme.bar.buttons.workspaces.numbered_active_highlight_border,
title: 'Highlight Radius', title: 'Highlight Radius',