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