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:
@@ -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';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -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,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -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(
|
||||||
|
|||||||
@@ -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),
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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',
|
||||||
|
|||||||
Reference in New Issue
Block a user