Added the options to allow workspaces to be indicated as active on multiple monitors. (#289)

* Added the options to allow workspaces to be indicated as active on multiple monitors.

* Add subtitle
This commit is contained in:
Jas Singh
2024-09-28 17:09:15 -07:00
committed by GitHub
parent a3ae60f621
commit 19a0ccf150
5 changed files with 55 additions and 9 deletions

View File

@@ -1,13 +1,18 @@
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'; import options from 'options';
import { Monitor } from 'types/service/hyprland';
const hyprland = await Service.import('hyprland'); const hyprland = await Service.import('hyprland');
const { monochrome, background } = options.theme.bar.buttons; const { monochrome, background } = options.theme.bar.buttons;
const { background: wsBackground, active } = options.theme.bar.buttons.workspaces; const { background: wsBackground, active } = options.theme.bar.buttons.workspaces;
const { showWsIcons } = options.bar.workspaces; const { showWsIcons, showAllActive, numbered_active_indicator: activeIndicator } = options.bar.workspaces;
const isWorkspaceActiveOnMonitor = (monitor: number, monitors: Monitor[], i: number): boolean => {
return showAllActive.value && monitors[monitor]?.activeWorkspace?.id === i;
};
const getWsIcon = (wsIconMap: WorkspaceIconMap, i: number): string => { const getWsIcon = (wsIconMap: WorkspaceIconMap, i: number): string => {
const iconEntry = wsIconMap[i]; const iconEntry = wsIconMap[i];
@@ -29,14 +34,25 @@ const getWsIcon = (wsIconMap: WorkspaceIconMap, i: number): string => {
return `${i}`; return `${i}`;
}; };
export const getWsColor = (wsIconMap: WorkspaceIconMap, i: number, smartHighlight: boolean): string => { export const getWsColor = (
wsIconMap: WorkspaceIconMap,
i: number,
smartHighlight: boolean,
monitor: number,
monitors: Monitor[],
): string => {
const iconEntry = wsIconMap[i]; const iconEntry = wsIconMap[i];
const hasColor = typeof iconEntry === 'object' && 'color' in iconEntry && isValidGjsColor(iconEntry.color); const hasColor = typeof iconEntry === 'object' && 'color' in iconEntry && isValidGjsColor(iconEntry.color);
if (!iconEntry) { if (!iconEntry) {
return ''; return '';
} }
if (showWsIcons.value && smartHighlight && hyprland.active.workspace.id === i) { if (
showWsIcons.value &&
smartHighlight &&
activeIndicator.value === 'highlight' &&
(hyprland.active.workspace.id === i || isWorkspaceActiveOnMonitor(monitor, monitors, i))
) {
const iconColor = monochrome.value ? background : wsBackground; const iconColor = monochrome.value ? background : wsBackground;
const iconBackground = hasColor && isValidGjsColor(iconEntry.color) ? iconEntry.color : active.value; const iconBackground = hasColor && isValidGjsColor(iconEntry.color) ? iconEntry.color : active.value;
const colorCss = `color: ${iconColor};`; const colorCss = `color: ${iconColor};`;
@@ -58,6 +74,8 @@ export const renderClassnames = (
numberedActiveIndicator: string, numberedActiveIndicator: string,
showWsIcons: boolean, showWsIcons: boolean,
smartHighlight: boolean, smartHighlight: boolean,
monitor: number,
monitors: Monitor[],
i: number, i: number,
): string => { ): string => {
if (showIcons) { if (showIcons) {
@@ -65,7 +83,11 @@ export const renderClassnames = (
} }
if (showNumbered || showWsIcons) { if (showNumbered || showWsIcons) {
const numActiveInd = hyprland.active.workspace.id === i ? numberedActiveIndicator : ''; const numActiveInd =
hyprland.active.workspace.id === i || isWorkspaceActiveOnMonitor(monitor, monitors, i)
? numberedActiveIndicator
: '';
const wsIconClass = showWsIcons ? 'txt-icon' : ''; const wsIconClass = showWsIcons ? 'txt-icon' : '';
const smartHighlightClass = smartHighlight ? 'smart-highlight' : ''; const smartHighlightClass = smartHighlight ? 'smart-highlight' : '';
@@ -88,9 +110,10 @@ export const renderLabel = (
i: number, i: number,
index: number, index: number,
monitor: number, monitor: number,
monitors: Monitor[],
): string => { ): string => {
if (showIcons) { if (showIcons) {
if (hyprland.active.workspace.id === i) { if (hyprland.active.workspace.id === i || isWorkspaceActiveOnMonitor(monitor, monitors, i)) {
return active; return active;
} }
if ((hyprland.getWorkspace(i)?.windows || 0) > 0) { if ((hyprland.getWorkspace(i)?.windows || 0) > 0) {

View File

@@ -5,6 +5,7 @@ import { range } from 'lib/utils';
import { BoxWidget } from 'lib/types/widget'; import { BoxWidget } from 'lib/types/widget';
import { getWsColor, renderClassnames, renderLabel } from '../utils'; import { getWsColor, renderClassnames, renderLabel } from '../utils';
import { WorkspaceIconMap } from 'lib/types/workspace'; import { WorkspaceIconMap } from 'lib/types/workspace';
import { Monitor } from 'types/service/hyprland';
const { workspaces, monitorSpecific, workspaceMask, spacing, ignored } = options.bar.workspaces; const { workspaces, monitorSpecific, workspaceMask, spacing, ignored } = options.bar.workspaces;
export const defaultWses = (monitor: number): BoxWidget => { export const defaultWses = (monitor: number): BoxWidget => {
@@ -42,6 +43,7 @@ export const defaultWses = (monitor: number): BoxWidget => {
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'), options.theme.bar.buttons.workspaces.smartHighlight.bind('value'),
hyprland.bind('monitors'),
hyprland.active.workspace.bind('id'), hyprland.active.workspace.bind('id'),
], ],
( (
@@ -50,10 +52,11 @@ export const defaultWses = (monitor: number): BoxWidget => {
workspaceIconMap: WorkspaceIconMap, workspaceIconMap: WorkspaceIconMap,
matugen: boolean, matugen: boolean,
smartHighlight: boolean, smartHighlight: boolean,
monitors: Monitor[],
) => { ) => {
return ( return (
`margin: 0rem ${0.375 * sp}rem;` + `margin: 0rem ${0.375 * sp}rem;` +
`${showWsIcons && !matugen ? getWsColor(workspaceIconMap, i, smartHighlight) : ''}` `${showWsIcons && !matugen ? getWsColor(workspaceIconMap, i, smartHighlight, monitor, monitors) : ''}`
); );
}, },
), ),
@@ -64,6 +67,7 @@ export const defaultWses = (monitor: number): BoxWidget => {
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.theme.bar.buttons.workspaces.smartHighlight.bind('value'),
hyprland.bind('monitors'),
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'),
@@ -74,6 +78,7 @@ export const defaultWses = (monitor: number): BoxWidget => {
numberedActiveIndicator: string, numberedActiveIndicator: string,
showWsIcons: boolean, showWsIcons: boolean,
smartHighlight: boolean, smartHighlight: boolean,
monitors: Monitor[],
) => { ) => {
return renderClassnames( return renderClassnames(
showIcons, showIcons,
@@ -81,6 +86,8 @@ export const defaultWses = (monitor: number): BoxWidget => {
numberedActiveIndicator, numberedActiveIndicator,
showWsIcons, showWsIcons,
smartHighlight, smartHighlight,
monitor,
monitors,
i, i,
); );
}, },
@@ -94,6 +101,7 @@ export const defaultWses = (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'),
workspaceMask.bind('value'), workspaceMask.bind('value'),
hyprland.bind('monitors'),
hyprland.active.workspace.bind('id'), hyprland.active.workspace.bind('id'),
], ],
( (
@@ -104,6 +112,7 @@ export const defaultWses = (monitor: number): BoxWidget => {
wsIconMap: WorkspaceIconMap, wsIconMap: WorkspaceIconMap,
showWsIcons: boolean, showWsIcons: boolean,
workspaceMask: boolean, workspaceMask: boolean,
monitors: Monitor[],
) => { ) => {
return renderLabel( return renderLabel(
showIcons, showIcons,
@@ -116,6 +125,7 @@ export const defaultWses = (monitor: number): BoxWidget => {
i, i,
index, index,
monitor, monitor,
monitors,
); );
}, },
), ),

View File

@@ -1,13 +1,13 @@
const hyprland = await Service.import('hyprland'); const hyprland = await Service.import('hyprland');
import options from 'options'; import options from 'options';
import { getWorkspaceRules, getWorkspacesForMonitor, isWorkspaceIgnored } from '../helpers'; import { getWorkspaceRules, getWorkspacesForMonitor, isWorkspaceIgnored } from '../helpers';
import { Workspace } from 'types/service/hyprland'; import { Monitor, Workspace } from 'types/service/hyprland';
import { getWsColor, renderClassnames, renderLabel } from '../utils'; import { getWsColor, renderClassnames, renderLabel } from '../utils';
import { range } from 'lib/utils'; import { range } from 'lib/utils';
import { BoxWidget } from 'lib/types/widget'; import { BoxWidget } from 'lib/types/widget';
import { WorkspaceIconMap } from 'lib/types/workspace'; import { WorkspaceIconMap } from 'lib/types/workspace';
const { workspaces, monitorSpecific, workspaceMask, spacing, ignored } = options.bar.workspaces; const { workspaces, monitorSpecific, workspaceMask, spacing, ignored, showAllActive } = options.bar.workspaces;
export const occupiedWses = (monitor: number): BoxWidget => { export const occupiedWses = (monitor: number): BoxWidget => {
return Widget.Box({ return Widget.Box({
@@ -29,7 +29,9 @@ export const occupiedWses = (monitor: number): BoxWidget => {
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'), options.theme.bar.buttons.workspaces.smartHighlight.bind('value'),
hyprland.bind('monitors'),
ignored.bind('value'), ignored.bind('value'),
showAllActive.bind('value'),
], ],
( (
monitorSpecific: boolean, monitorSpecific: boolean,
@@ -48,6 +50,7 @@ export const occupiedWses = (monitor: number): BoxWidget => {
showWsIcons: boolean, showWsIcons: boolean,
matugen: boolean, matugen: boolean,
smartHighlight: boolean, smartHighlight: boolean,
monitors: Monitor[],
) => { ) => {
let allWkspcs = range(totalWkspcs || 8); let allWkspcs = range(totalWkspcs || 8);
@@ -106,13 +109,15 @@ 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, smartHighlight) : ''}`, `${showWsIcons && !matugen ? getWsColor(wsIconMap, i, smartHighlight, monitor, monitors) : ''}`,
class_name: renderClassnames( class_name: renderClassnames(
showIcons, showIcons,
showNumbered, showNumbered,
numberedActiveIndicator, numberedActiveIndicator,
showWsIcons, showWsIcons,
smartHighlight, smartHighlight,
monitor,
monitors,
i, i,
), ),
label: renderLabel( label: renderLabel(
@@ -126,6 +131,7 @@ export const occupiedWses = (monitor: number): BoxWidget => {
i, i,
index, index,
monitor, monitor,
monitors,
), ),
setup: (self) => { setup: (self) => {
self.toggleClassName('active', activeId === i); self.toggleClassName('active', activeId === i);

View File

@@ -862,6 +862,7 @@ const options = mkOptions(OPTIONS, {
}, },
workspaces: { workspaces: {
show_icons: opt(false), show_icons: opt(false),
showAllActive: opt(true),
ignored: opt(''), ignored: opt(''),
show_numbered: opt(false), show_numbered: opt(false),
showWsIcons: opt(false), showWsIcons: opt(false),

View File

@@ -190,6 +190,12 @@ export const BarSettings = (): Scrollable<Gtk.Widget, Gtk.Widget> => {
title: 'Button Border', title: 'Button Border',
type: 'boolean', type: 'boolean',
}), }),
Option({
opt: options.bar.workspaces.showAllActive,
title: 'Mark Active Workspace On All Monitors',
subtitle: 'Marks the currently active workspace on each monitor.',
type: 'boolean',
}),
Option({ Option({
opt: options.theme.bar.buttons.workspaces.fontSize, opt: options.theme.bar.buttons.workspaces.fontSize,
title: 'Indicator Size', title: 'Indicator Size',