Implemented strict linting standards and prettier formatting config. (#248)

* Implemented strict linting standards and prettier formatting config.

* More linter fixes and type updates.

* More linter updates and type fixes

* Remove noisy comments

* Linter and type updates

* Linter, formatting and type updates.

* Linter updates

* Type updates

* Type updates

* fixed all linter errors

* Fixed all linting, formatting and type issues.

* Resolve merge conflicts.
This commit is contained in:
Jas Singh
2024-09-14 16:20:05 -07:00
committed by GitHub
parent ff13e3dd3c
commit 2c72cc66d8
222 changed files with 13141 additions and 8433 deletions

View File

@@ -1,23 +1,21 @@
const hyprland = await Service.import("hyprland");
const hyprland = await Service.import('hyprland');
import { WorkspaceMap, WorkspaceRule } from "lib/types/workspace";
import options from "options";
import { Variable } from "types/variable";
const {
workspaces,
reverse_scroll,
} = options.bar.workspaces;
import { MonitorMap, WorkspaceMap, WorkspaceRule } from 'lib/types/workspace';
import options from 'options';
import { Variable } from 'types/variable';
const { workspaces, reverse_scroll } = options.bar.workspaces;
export const getWorkspacesForMonitor = (curWs: number, wsRules: WorkspaceMap, monitor: number): boolean => {
if (!wsRules || !Object.keys(wsRules).length) {
return true;
}
const monitorMap = {};
const workspaceMonitorList = hyprland?.workspaces?.map(m => ({ id: m.monitorID, name: m.monitor }));
const monitors = [...new Map([...workspaceMonitorList, ...hyprland.monitors].map(item => [item.id, item])).values()];
const monitorMap: MonitorMap = {};
const workspaceMonitorList = hyprland?.workspaces?.map((m) => ({ id: m.monitorID, name: m.monitor }));
const monitors = [
...new Map([...workspaceMonitorList, ...hyprland.monitors].map((item) => [item.id, item])).values(),
];
monitors.forEach((m) => (monitorMap[m.id] = m.name));
@@ -32,9 +30,9 @@ export const getWorkspacesForMonitor = (curWs: number, wsRules: WorkspaceMap, mo
export const getWorkspaceRules = (): WorkspaceMap => {
try {
const rules = Utils.exec("hyprctl workspacerules -j");
const rules = Utils.exec('hyprctl workspacerules -j');
const workspaceRules = {};
const workspaceRules: WorkspaceMap = {};
JSON.parse(rules).forEach((rule: WorkspaceRule, index: number) => {
if (Object.hasOwnProperty.call(workspaceRules, rule.monitor)) {
@@ -60,13 +58,13 @@ export const getCurrentMonitorWorkspaces = (monitor: number): number[] => {
}
const monitorWorkspaces = getWorkspaceRules();
const monitorMap = {};
const monitorMap: MonitorMap = {};
hyprland.monitors.forEach((m) => (monitorMap[m.id] = m.name));
const currentMonitorName = monitorMap[monitor];
return monitorWorkspaces[currentMonitorName];
}
};
export const goToNextWS = (currentMonitorWorkspaces: Variable<number[]>, activeWorkspaces: boolean): void => {
if (activeWorkspaces === true) {
@@ -74,18 +72,17 @@ export const goToNextWS = (currentMonitorWorkspaces: Variable<number[]>, activeW
let nextIndex = hyprland.active.workspace.id + 1;
if (nextIndex > activeWses[activeWses.length - 1].id) {
nextIndex = activeWses[0].id;
}
hyprland.messageAsync(`dispatch workspace ${nextIndex}`)
hyprland.messageAsync(`dispatch workspace ${nextIndex}`);
} else if (currentMonitorWorkspaces.value === undefined) {
let nextIndex = hyprland.active.workspace.id + 1;
if (nextIndex > workspaces.value) {
nextIndex = 0;
}
hyprland.messageAsync(`dispatch workspace ${nextIndex}`)
hyprland.messageAsync(`dispatch workspace ${nextIndex}`);
} else {
const curWorkspace = hyprland.active.workspace.id;
const indexOfWs = currentMonitorWorkspaces.value.indexOf(curWorkspace);
@@ -94,9 +91,9 @@ export const goToNextWS = (currentMonitorWorkspaces: Variable<number[]>, activeW
nextIndex = 0;
}
hyprland.messageAsync(`dispatch workspace ${currentMonitorWorkspaces.value[nextIndex]}`)
hyprland.messageAsync(`dispatch workspace ${currentMonitorWorkspaces.value[nextIndex]}`);
}
}
};
export const goToPrevWS = (currentMonitorWorkspaces: Variable<number[]>, activeWorkspaces: boolean): void => {
if (activeWorkspaces === true) {
@@ -104,11 +101,10 @@ export const goToPrevWS = (currentMonitorWorkspaces: Variable<number[]>, activeW
let prevIndex = hyprland.active.workspace.id - 1;
if (prevIndex < activeWses[0].id) {
prevIndex = activeWses[activeWses.length - 1].id;
}
hyprland.messageAsync(`dispatch workspace ${prevIndex}`)
hyprland.messageAsync(`dispatch workspace ${prevIndex}`);
} else if (currentMonitorWorkspaces.value === undefined) {
let prevIndex = hyprland.active.workspace.id - 1;
@@ -116,7 +112,7 @@ export const goToPrevWS = (currentMonitorWorkspaces: Variable<number[]>, activeW
prevIndex = workspaces.value;
}
hyprland.messageAsync(`dispatch workspace ${prevIndex}`)
hyprland.messageAsync(`dispatch workspace ${prevIndex}`);
} else {
const curWorkspace = hyprland.active.workspace.id;
const indexOfWs = currentMonitorWorkspaces.value.indexOf(curWorkspace);
@@ -125,11 +121,11 @@ export const goToPrevWS = (currentMonitorWorkspaces: Variable<number[]>, activeW
prevIndex = currentMonitorWorkspaces.value.length - 1;
}
hyprland.messageAsync(`dispatch workspace ${currentMonitorWorkspaces.value[prevIndex]}`)
hyprland.messageAsync(`dispatch workspace ${currentMonitorWorkspaces.value[prevIndex]}`);
}
}
};
export function throttle<T extends (...args: any[]) => void>(func: T, limit: number): T {
export function throttle<T extends (...args: unknown[]) => void>(func: T, limit: number): T {
let inThrottle: boolean;
return function (this: ThisParameterType<T>, ...args: Parameters<T>) {
if (!inThrottle) {
@@ -147,7 +143,11 @@ type ThrottledScrollHandlers = {
throttledScrollDown: () => void;
};
export const createThrottledScrollHandlers = (scrollSpeed: number, currentMonitorWorkspaces: Variable<number[]>, activeWorkspaces: boolean = false): ThrottledScrollHandlers => {
export const createThrottledScrollHandlers = (
scrollSpeed: number,
currentMonitorWorkspaces: Variable<number[]>,
activeWorkspaces: boolean = false,
): ThrottledScrollHandlers => {
const throttledScrollUp = throttle(() => {
if (reverse_scroll.value === true) {
goToPrevWS(currentMonitorWorkspaces, activeWorkspaces);
@@ -165,4 +165,4 @@ export const createThrottledScrollHandlers = (scrollSpeed: number, currentMonito
}, 200 / scrollSpeed);
return { throttledScrollUp, throttledScrollDown };
}
};

View File

@@ -1,42 +1,54 @@
const hyprland = await Service.import("hyprland");
import options from "options";
import { createThrottledScrollHandlers, getCurrentMonitorWorkspaces, getWorkspaceRules, getWorkspacesForMonitor } from "./helpers";
import { Workspace } from "types/service/hyprland";
const hyprland = await Service.import('hyprland');
import options from 'options';
import {
createThrottledScrollHandlers,
getCurrentMonitorWorkspaces,
getWorkspaceRules,
getWorkspacesForMonitor,
} from './helpers';
import { Workspace } from 'types/service/hyprland';
import { BoxWidget } from 'lib/types/widget';
import { BarBoxChild, SelfButton } from 'lib/types/bar';
const {
workspaces,
monitorSpecific,
workspaceMask,
scroll_speed,
spacing
} = options.bar.workspaces;
const { workspaces, monitorSpecific, workspaceMask, scroll_speed, spacing } = options.bar.workspaces;
function range(length: number, start = 1) {
function range(length: number, start = 1): number[] {
return Array.from({ length }, (_, i) => i + start);
}
const Workspaces = (monitor = -1) => {
const Workspaces = (monitor = -1): BarBoxChild => {
const currentMonitorWorkspaces = Variable(getCurrentMonitorWorkspaces(monitor));
workspaces.connect("changed", () => {
currentMonitorWorkspaces.value = getCurrentMonitorWorkspaces(monitor)
})
workspaces.connect('changed', () => {
currentMonitorWorkspaces.value = getCurrentMonitorWorkspaces(monitor);
});
const renderClassnames = (showIcons: boolean, showNumbered: boolean, numberedActiveIndicator: string, i: number) => {
const renderClassnames = (
showIcons: boolean,
showNumbered: boolean,
numberedActiveIndicator: string,
i: number,
): string => {
if (showIcons) {
return `workspace-icon txt-icon bar`;
}
if (showNumbered) {
const numActiveInd = hyprland.active.workspace.id === i
? numberedActiveIndicator
: "";
const numActiveInd = hyprland.active.workspace.id === i ? numberedActiveIndicator : '';
return `workspace-number can_${numberedActiveIndicator} ${numActiveInd}`;
}
return "default";
}
return 'default';
};
const renderLabel = (showIcons: boolean, available: string, active: string, occupied: string, workspaceMask: boolean, i: number, index: number) => {
const renderLabel = (
showIcons: boolean,
available: string,
active: string,
occupied: string,
workspaceMask: boolean,
i: number,
index: number,
): string => {
if (showIcons) {
if (hyprland.active.workspace.id === i) {
return active;
@@ -44,20 +56,16 @@ const Workspaces = (monitor = -1) => {
if ((hyprland.getWorkspace(i)?.windows || 0) > 0) {
return occupied;
}
if (
monitor !== -1
) {
if (monitor !== -1) {
return available;
}
}
return workspaceMask
? `${index + 1}`
: `${i}`;
}
const defaultWses = () => {
return workspaceMask ? `${index + 1}` : `${i}`;
};
const defaultWses = (): BoxWidget => {
return Widget.Box({
children: Utils.merge(
[workspaces.bind("value"), monitorSpecific.bind()],
[workspaces.bind('value'), monitorSpecific.bind()],
(workspaces: number, monitorSpecific: boolean) => {
return range(workspaces || 8)
.filter((i) => {
@@ -72,49 +80,57 @@ const Workspaces = (monitor = -1) => {
})
.map((i, index) => {
return Widget.Button({
class_name: "workspace-button",
class_name: 'workspace-button',
on_primary_click: () => {
hyprland.messageAsync(`dispatch workspace ${i}`)
hyprland.messageAsync(`dispatch workspace ${i}`);
},
child: Widget.Label({
attribute: i,
vpack: "center",
css: spacing.bind("value").as(sp => `margin: 0rem ${0.375 * sp}rem;`),
vpack: 'center',
css: spacing.bind('value').as((sp) => `margin: 0rem ${0.375 * sp}rem;`),
class_name: Utils.merge(
[
options.bar.workspaces.show_icons.bind("value"),
options.bar.workspaces.show_numbered.bind("value"),
options.bar.workspaces.numbered_active_indicator.bind("value"),
options.bar.workspaces.icons.available.bind("value"),
options.bar.workspaces.icons.active.bind("value"),
options.bar.workspaces.icons.occupied.bind("value"),
hyprland.active.workspace.bind("id")
options.bar.workspaces.show_icons.bind('value'),
options.bar.workspaces.show_numbered.bind('value'),
options.bar.workspaces.numbered_active_indicator.bind('value'),
options.bar.workspaces.icons.available.bind('value'),
options.bar.workspaces.icons.active.bind('value'),
options.bar.workspaces.icons.occupied.bind('value'),
hyprland.active.workspace.bind('id'),
],
(showIcons: boolean, showNumbered: boolean, numberedActiveIndicator: string) => {
(
showIcons: boolean,
showNumbered: boolean,
numberedActiveIndicator: string,
) => {
if (showIcons) {
return `workspace-icon txt-icon bar`;
}
if (showNumbered) {
const numActiveInd = hyprland.active.workspace.id === i
? numberedActiveIndicator
: "";
const numActiveInd =
hyprland.active.workspace.id === i ? numberedActiveIndicator : '';
return `workspace-number can_${numberedActiveIndicator} ${numActiveInd}`;
}
return "default";
return 'default';
},
),
label: Utils.merge(
[
options.bar.workspaces.show_icons.bind("value"),
options.bar.workspaces.icons.available.bind("value"),
options.bar.workspaces.icons.active.bind("value"),
options.bar.workspaces.icons.occupied.bind("value"),
workspaceMask.bind("value"),
hyprland.active.workspace.bind("id")
options.bar.workspaces.show_icons.bind('value'),
options.bar.workspaces.icons.available.bind('value'),
options.bar.workspaces.icons.active.bind('value'),
options.bar.workspaces.icons.occupied.bind('value'),
workspaceMask.bind('value'),
hyprland.active.workspace.bind('id'),
],
(showIcons: boolean, available: string, active: string, occupied: string, workspaceMask: boolean, _: number) => {
(
showIcons: boolean,
available: string,
active: string,
occupied: string,
workspaceMask: boolean,
) => {
if (showIcons) {
if (hyprland.active.workspace.id === i) {
return active;
@@ -122,52 +138,45 @@ const Workspaces = (monitor = -1) => {
if ((hyprland.getWorkspace(i)?.windows || 0) > 0) {
return occupied;
}
if (
monitor !== -1
) {
if (monitor !== -1) {
return available;
}
}
return workspaceMask
? `${index + 1}`
: `${i}`;
return workspaceMask ? `${index + 1}` : `${i}`;
},
),
setup: (self) => {
self.hook(hyprland, () => {
self.toggleClassName('active', hyprland.active.workspace.id === i);
self.toggleClassName(
"active",
hyprland.active.workspace.id === i,
);
self.toggleClassName(
"occupied",
'occupied',
(hyprland.getWorkspace(i)?.windows || 0) > 0,
);
});
},
})
}),
});
});
},
)
})
}
const occupiedWses = () => {
),
});
};
const occupiedWses = (): BoxWidget => {
return Widget.Box({
children: Utils.merge(
[
monitorSpecific.bind("value"),
hyprland.bind("workspaces"),
workspaceMask.bind("value"),
workspaces.bind("value"),
options.bar.workspaces.show_icons.bind("value"),
options.bar.workspaces.icons.available.bind("value"),
options.bar.workspaces.icons.active.bind("value"),
options.bar.workspaces.icons.occupied.bind("value"),
options.bar.workspaces.show_numbered.bind("value"),
options.bar.workspaces.numbered_active_indicator.bind("value"),
spacing.bind("value"),
hyprland.active.workspace.bind("id"),
monitorSpecific.bind('value'),
hyprland.bind('workspaces'),
workspaceMask.bind('value'),
workspaces.bind('value'),
options.bar.workspaces.show_icons.bind('value'),
options.bar.workspaces.icons.available.bind('value'),
options.bar.workspaces.icons.active.bind('value'),
options.bar.workspaces.icons.occupied.bind('value'),
options.bar.workspaces.show_numbered.bind('value'),
options.bar.workspaces.numbered_active_indicator.bind('value'),
spacing.bind('value'),
hyprland.active.workspace.bind('id'),
],
(
monitorSpecific: boolean,
@@ -185,29 +194,37 @@ const Workspaces = (monitor = -1) => {
) => {
let allWkspcs = range(totalWkspcs || 8);
const activeWorkspaces = wkSpaces.map(w => w.id);
const activeWorkspaces = wkSpaces.map((w) => w.id);
const workspaceRules = getWorkspaceRules();
// Sometimes hyprland doesn't have all the monitors in the list
// so we complement it with monitors from the workspace list
const workspaceMonitorList = hyprland?.workspaces?.map(m => ({ id: m.monitorID, name: m.monitor }));
const curMonitor = hyprland.monitors.find(m => m.id === monitor)
|| workspaceMonitorList.find(m => m.id === monitor);
const workspaceMonitorList = hyprland?.workspaces?.map((m) => ({
id: m.monitorID,
name: m.monitor,
}));
const curMonitor =
hyprland.monitors.find((m) => m.id === monitor) ||
workspaceMonitorList.find((m) => m.id === monitor);
// go through each key in workspaceRules and flatten the array
const workspacesWithRules = Object.keys(workspaceRules).reduce((acc: number[], k: string) => {
return [...acc, ...workspaceRules[k]];
}, [] as number[]);
const activesForMonitor = activeWorkspaces.filter(w => {
if (curMonitor && Object.hasOwnProperty.call(workspaceRules, curMonitor.name) && workspacesWithRules.includes(w)) {
const activesForMonitor = activeWorkspaces.filter((w) => {
if (
curMonitor &&
Object.hasOwnProperty.call(workspaceRules, curMonitor.name) &&
workspacesWithRules.includes(w)
) {
return workspaceRules[curMonitor.name].includes(w);
}
return true;
});
if (monitorSpecific) {
const wrkspcsInRange = range(totalWkspcs).filter(w => {
const wrkspcsInRange = range(totalWkspcs).filter((w) => {
return getWorkspacesForMonitor(w, workspaceRules, monitor);
});
allWkspcs = [...new Set([...activesForMonitor, ...wrkspcsInRange])];
@@ -221,51 +238,53 @@ const Workspaces = (monitor = -1) => {
})
.map((i, index) => {
return Widget.Button({
class_name: "workspace-button",
class_name: 'workspace-button',
on_primary_click: () => {
hyprland.messageAsync(`dispatch workspace ${i}`)
hyprland.messageAsync(`dispatch workspace ${i}`);
},
child: Widget.Label({
attribute: i,
vpack: "center",
vpack: 'center',
css: `margin: 0rem ${0.375 * spacing}rem;`,
class_name: renderClassnames(showIcons, showNumbered, numberedActiveIndicator, i),
label: renderLabel(showIcons, available, active, occupied, workspaceMask, i, index),
setup: (self) => {
self.toggleClassName(
"active",
activeId === i,
);
self.toggleClassName(
"occupied",
(hyprland.getWorkspace(i)?.windows || 0) > 0,
);
self.toggleClassName('active', activeId === i);
self.toggleClassName('occupied', (hyprland.getWorkspace(i)?.windows || 0) > 0);
},
})
}),
});
});
},
)
})
}
),
});
};
return {
component: Widget.Box({
class_name: "workspaces",
child: options.bar.workspaces.hideUnoccupied.bind("value").as(hideUnoccupied => hideUnoccupied ? occupiedWses() : defaultWses()),
class_name: 'workspaces',
child: options.bar.workspaces.hideUnoccupied
.bind('value')
.as((hideUnoccupied) => (hideUnoccupied ? occupiedWses() : defaultWses())),
}),
isVisible: true,
boxClass: "workspaces",
boxClass: 'workspaces',
props: {
setup: (self: any) => {
Utils.merge([scroll_speed.bind("value"), options.bar.workspaces.hideUnoccupied.bind("value")], (scroll_speed, hideUnoccupied) => {
const { throttledScrollUp, throttledScrollDown } = createThrottledScrollHandlers(scroll_speed, currentMonitorWorkspaces, hideUnoccupied)
self.on_scroll_up = throttledScrollUp;
self.on_scroll_down = throttledScrollDown;
});
}
}
setup: (self: SelfButton): void => {
Utils.merge(
[scroll_speed.bind('value'), options.bar.workspaces.hideUnoccupied.bind('value')],
(scroll_speed, hideUnoccupied) => {
const { throttledScrollUp, throttledScrollDown } = createThrottledScrollHandlers(
scroll_speed,
currentMonitorWorkspaces,
hideUnoccupied,
);
self.on_scroll_up = throttledScrollUp;
self.on_scroll_down = throttledScrollDown;
},
);
},
},
};
};

View File

@@ -0,0 +1,43 @@
const hyprland = await Service.import('hyprland');
export const renderClassnames = (
showIcons: boolean,
showNumbered: boolean,
numberedActiveIndicator: string,
i: number,
): string => {
if (showIcons) {
return `workspace-icon txt-icon bar`;
}
if (showNumbered) {
const numActiveInd = hyprland.active.workspace.id === i ? numberedActiveIndicator : '';
return `workspace-number can_${numberedActiveIndicator} ${numActiveInd}`;
}
return 'default';
};
export const renderLabel = (
showIcons: boolean,
available: string,
active: string,
occupied: string,
workspaceMask: boolean,
i: number,
index: number,
monitor: number,
): string => {
if (showIcons) {
if (hyprland.active.workspace.id === i) {
return active;
}
if ((hyprland.getWorkspace(i)?.windows || 0) > 0) {
return occupied;
}
if (monitor !== -1) {
return available;
}
}
return workspaceMask ? `${index + 1}` : `${i}`;
};

View File

@@ -0,0 +1,99 @@
const hyprland = await Service.import('hyprland');
import options from 'options';
import { getWorkspaceRules, getWorkspacesForMonitor } from '../helpers';
import { range } from 'lib/utils';
import { BoxWidget } from 'lib/types/widget';
const { workspaces, monitorSpecific, workspaceMask, spacing } = options.bar.workspaces;
export const defaultWses = (monitor: number): BoxWidget => {
return Widget.Box({
children: Utils.merge(
[workspaces.bind('value'), monitorSpecific.bind()],
(workspaces: number, monitorSpecific: boolean) => {
return range(workspaces || 8)
.filter((i) => {
if (!monitorSpecific) {
return true;
}
const workspaceRules = getWorkspaceRules();
return getWorkspacesForMonitor(i, workspaceRules, monitor);
})
.sort((a, b) => {
return a - b;
})
.map((i, index) => {
return Widget.Button({
class_name: 'workspace-button',
on_primary_click: () => {
hyprland.messageAsync(`dispatch workspace ${i}`);
},
child: Widget.Label({
attribute: i,
vpack: 'center',
css: spacing.bind('value').as((sp) => `margin: 0rem ${0.375 * sp}rem;`),
class_name: Utils.merge(
[
options.bar.workspaces.show_icons.bind('value'),
options.bar.workspaces.show_numbered.bind('value'),
options.bar.workspaces.numbered_active_indicator.bind('value'),
options.bar.workspaces.icons.available.bind('value'),
options.bar.workspaces.icons.active.bind('value'),
options.bar.workspaces.icons.occupied.bind('value'),
hyprland.active.workspace.bind('id'),
],
(showIcons: boolean, showNumbered: boolean, numberedActiveIndicator: string) => {
if (showIcons) {
return `workspace-icon txt-icon bar`;
}
if (showNumbered) {
const numActiveInd =
hyprland.active.workspace.id === i ? numberedActiveIndicator : '';
return `workspace-number can_${numberedActiveIndicator} ${numActiveInd}`;
}
return 'default';
},
),
label: Utils.merge(
[
options.bar.workspaces.show_icons.bind('value'),
options.bar.workspaces.icons.available.bind('value'),
options.bar.workspaces.icons.active.bind('value'),
options.bar.workspaces.icons.occupied.bind('value'),
workspaceMask.bind('value'),
hyprland.active.workspace.bind('id'),
],
(
showIcons: boolean,
available: string,
active: string,
occupied: string,
workspaceMask: boolean,
) => {
if (showIcons) {
if (hyprland.active.workspace.id === i) {
return active;
}
if ((hyprland.getWorkspace(i)?.windows || 0) > 0) {
return occupied;
}
if (monitor !== -1) {
return available;
}
}
return workspaceMask ? `${index + 1}` : `${i}`;
},
),
setup: (self) => {
self.hook(hyprland, () => {
self.toggleClassName('active', hyprland.active.workspace.id === i);
self.toggleClassName('occupied', (hyprland.getWorkspace(i)?.windows || 0) > 0);
});
},
}),
});
});
},
),
});
};

View File

@@ -0,0 +1,114 @@
const hyprland = await Service.import('hyprland');
import options from 'options';
import { getWorkspaceRules, getWorkspacesForMonitor } from '../helpers';
import { Workspace } from 'types/service/hyprland';
import { renderClassnames, renderLabel } from '../utils';
import { range } from 'lib/utils';
import { BoxWidget } from 'lib/types/widget';
const { workspaces, monitorSpecific, workspaceMask, spacing } = options.bar.workspaces;
export const occupiedWses = (monitor: number): BoxWidget => {
return Widget.Box({
children: Utils.merge(
[
monitorSpecific.bind('value'),
hyprland.bind('workspaces'),
workspaceMask.bind('value'),
workspaces.bind('value'),
options.bar.workspaces.show_icons.bind('value'),
options.bar.workspaces.icons.available.bind('value'),
options.bar.workspaces.icons.active.bind('value'),
options.bar.workspaces.icons.occupied.bind('value'),
options.bar.workspaces.show_numbered.bind('value'),
options.bar.workspaces.numbered_active_indicator.bind('value'),
spacing.bind('value'),
hyprland.active.workspace.bind('id'),
],
(
monitorSpecific: boolean,
wkSpaces: Workspace[],
workspaceMask: boolean,
totalWkspcs: number,
showIcons: boolean,
available: string,
active: string,
occupied: string,
showNumbered: boolean,
numberedActiveIndicator: string,
spacing: number,
activeId: number,
) => {
let allWkspcs = range(totalWkspcs || 8);
const activeWorkspaces = wkSpaces.map((w) => w.id);
const workspaceRules = getWorkspaceRules();
// Sometimes hyprland doesn't have all the monitors in the list
// so we complement it with monitors from the workspace list
const workspaceMonitorList = hyprland?.workspaces?.map((m) => ({ id: m.monitorID, name: m.monitor }));
const curMonitor =
hyprland.monitors.find((m) => m.id === monitor) ||
workspaceMonitorList.find((m) => m.id === monitor);
// go through each key in workspaceRules and flatten the array
const workspacesWithRules = Object.keys(workspaceRules).reduce((acc: number[], k: string) => {
return [...acc, ...workspaceRules[k]];
}, [] as number[]);
const activesForMonitor = activeWorkspaces.filter((w) => {
if (
curMonitor &&
Object.hasOwnProperty.call(workspaceRules, curMonitor.name) &&
workspacesWithRules.includes(w)
) {
return workspaceRules[curMonitor.name].includes(w);
}
return true;
});
if (monitorSpecific) {
const wrkspcsInRange = range(totalWkspcs).filter((w) => {
return getWorkspacesForMonitor(w, workspaceRules, monitor);
});
allWkspcs = [...new Set([...activesForMonitor, ...wrkspcsInRange])];
} else {
allWkspcs = [...new Set([...allWkspcs, ...activeWorkspaces])];
}
return allWkspcs
.sort((a, b) => {
return a - b;
})
.map((i, index) => {
return Widget.Button({
class_name: 'workspace-button',
on_primary_click: () => {
hyprland.messageAsync(`dispatch workspace ${i}`);
},
child: Widget.Label({
attribute: i,
vpack: 'center',
css: `margin: 0rem ${0.375 * spacing}rem;`,
class_name: renderClassnames(showIcons, showNumbered, numberedActiveIndicator, i),
label: renderLabel(
showIcons,
available,
active,
occupied,
workspaceMask,
i,
index,
monitor,
),
setup: (self) => {
self.toggleClassName('active', activeId === i);
self.toggleClassName('occupied', (hyprland.getWorkspace(i)?.windows || 0) > 0);
},
}),
});
});
},
),
});
};