diff --git a/nix/module.nix b/nix/module.nix index 1c5932f5d..cfac59981 100644 --- a/nix/module.nix +++ b/nix/module.nix @@ -171,6 +171,8 @@ in bar.customModules.cpu.leftClick = mkStrOption ""; bar.customModules.cpu.middleClick = mkStrOption ""; bar.customModules.cpu.pollingInterval = mkIntOption 2000; + bar.customModules.cpu.historyLength = mkIntOption 10; + bar.customModules.cpu.showGraph = mkBoolOption false; bar.customModules.cpu.rightClick = mkStrOption ""; bar.customModules.cpu.round = mkBoolOption true; bar.customModules.cpu.scrollDown = mkStrOption ""; @@ -247,6 +249,8 @@ in bar.customModules.ram.icon = mkStrOption ""; bar.customModules.ram.label = mkBoolOption true; bar.customModules.ram.labelType = mkStrOption "percentage"; + bar.customModules.ram.historyLength = mkIntOption 10; + bar.customModules.ram.showGraph = mkBoolOption false; bar.customModules.ram.leftClick = mkStrOption ""; bar.customModules.ram.middleClick = mkStrOption ""; bar.customModules.ram.pollingInterval = mkIntOption 2000; diff --git a/src/components/bar/modules/cpu/index.tsx b/src/components/bar/modules/cpu/index.tsx index e87a03510..68db6020e 100644 --- a/src/components/bar/modules/cpu/index.tsx +++ b/src/components/bar/modules/cpu/index.tsx @@ -7,20 +7,62 @@ import { bind, Variable } from 'astal'; import { Astal } from 'astal/gtk3'; import { BarBoxChild } from 'src/lib/types/bar.types'; -const { label, round, leftClick, rightClick, middleClick, scrollUp, scrollDown, pollingInterval, icon } = - options.bar.customModules.cpu; +const { + label, + round, + leftClick, + rightClick, + middleClick, + scrollUp, + scrollDown, + pollingInterval, + showGraph, + historyLength, + icon, +} = options.bar.customModules.cpu; export const cpuUsage = Variable(0); +const cpuHistory = Variable([]); + +const historyLengthBinding = Variable.derive([bind(historyLength)], (length: number) => length); const cpuPoller = new FunctionPoller(cpuUsage, [bind(round)], bind(pollingInterval), computeCPU); cpuPoller.initialize('cpu'); +const getBarGraph = (usage: number): string => { + if (usage < 12.5) return '▁'; + if (usage < 25) return '▂'; + if (usage < 37.5) return '▃'; + if (usage < 50) return '▄'; + if (usage < 62.5) return '▅'; + if (usage < 75) return '▆'; + if (usage < 87.5) return '▇'; + return '█'; +}; + +const graphBinding = showGraph + ? Variable.derive([bind(cpuUsage), historyLengthBinding()], (cpuUsg: number, hstLength: number) => { + const history = cpuHistory.get(); + history.push(cpuUsg); + if (history.length > hstLength) { + history.shift(); + } + cpuHistory.set(history); + + return history.map(getBarGraph).join(''); + }) + : Variable.derive([], () => ''); + export const Cpu = (): BarBoxChild => { - const labelBinding = Variable.derive([bind(cpuUsage), bind(round)], (cpuUsg: number, round: boolean) => { + const percentageBinding = Variable.derive([bind(cpuUsage), bind(round)], (cpuUsg: number, round: boolean) => { return round ? `${Math.round(cpuUsg)}%` : `${cpuUsg.toFixed(2)}%`; }); + const labelBinding = Variable.derive([percentageBinding(), graphBinding()], (percentage: string, graph: string) => { + return showGraph ? `${percentage} ${graph}` : percentage; + }); + const cpuModule = Module({ textIcon: bind(icon), label: labelBinding(), @@ -48,6 +90,8 @@ export const Cpu = (): BarBoxChild => { }); }, onDestroy: () => { + percentageBinding.drop(); + graphBinding.drop(); labelBinding.drop(); }, }, diff --git a/src/components/bar/modules/ram/index.tsx b/src/components/bar/modules/ram/index.tsx index ba1b03d52..eb9659417 100644 --- a/src/components/bar/modules/ram/index.tsx +++ b/src/components/bar/modules/ram/index.tsx @@ -9,11 +9,14 @@ import { Astal } from 'astal/gtk3'; import { BarBoxChild, ResourceLabelType } from 'src/lib/types/bar.types'; import { GenericResourceData } from 'src/lib/types/customModules/generic.types'; -const { label, labelType, round, leftClick, rightClick, middleClick, pollingInterval, icon } = +const { label, labelType, round, leftClick, rightClick, middleClick, pollingInterval, showGraph, historyLength, icon } = options.bar.customModules.ram; const defaultRamData: GenericResourceData = { total: 0, used: 0, percentage: 0, free: 0 }; const ramUsage = Variable(defaultRamData); +const ramHistory = Variable([]); + +const historyLengthBinding = Variable.derive([bind(historyLength)], (length: number) => length); const ramPoller = new FunctionPoller]>( ramUsage, @@ -25,19 +28,46 @@ const ramPoller = new FunctionPoller]>( ramPoller.initialize('ram'); +const getBarGraph = (usage: number): string => { + if (usage < 12.5) return '▁'; + if (usage < 25) return '▂'; + if (usage < 37.5) return '▃'; + if (usage < 50) return '▄'; + if (usage < 62.5) return '▅'; + if (usage < 75) return '▆'; + if (usage < 87.5) return '▇'; + return '█'; +}; + +const graphBinding = showGraph + ? Variable.derive([bind(ramUsage), historyLengthBinding()], (rmUsg: GenericResourceData, hstLength: number) => { + const history = ramHistory.get(); + history.push(rmUsg.percentage); + if (history.length > hstLength) { + history.shift(); + } + ramHistory.set(history); + + return history.map(getBarGraph).join(''); + }) + : Variable.derive([], () => ''); + export const Ram = (): BarBoxChild => { const labelBinding = Variable.derive( [bind(ramUsage), bind(labelType), bind(round)], (rmUsg: GenericResourceData, lblTyp: ResourceLabelType, round: boolean) => { const returnValue = renderResourceLabel(lblTyp, rmUsg, round); - return returnValue; }, ); + const combinedLabelBinding = Variable.derive([labelBinding(), graphBinding()], (label: string, graph: string) => { + return showGraph ? `${label} ${graph}` : label; + }); + const ramModule = Module({ textIcon: bind(icon), - label: labelBinding(), + label: combinedLabelBinding(), tooltipText: bind(labelType).as((lblTyp) => { return formatTooltip('RAM', lblTyp); }), @@ -78,6 +108,8 @@ export const Ram = (): BarBoxChild => { }, onDestroy: () => { labelBinding.drop(); + graphBinding.drop(); + combinedLabelBinding.drop(); }, }, }); diff --git a/src/components/bar/settings/config.tsx b/src/components/bar/settings/config.tsx index 35bfd1bb1..86e84e5ac 100644 --- a/src/components/bar/settings/config.tsx +++ b/src/components/bar/settings/config.tsx @@ -86,6 +86,15 @@ export const CustomModuleSettings = (): JSX.Element => { max={60 * 24 * 1000} increment={1000} /> +