From 4b041bcf1f2b096fe268d413a88721cebb27e2ee Mon Sep 17 00:00:00 2001 From: Rubin Bhandari Date: Mon, 18 Nov 2024 01:14:36 +0545 Subject: [PATCH] feat: idle inhibit (#502) Co-authored-by: Jas Singh --- README.md | 5 +- customModules/config.ts | 71 +++++++++++++++++++++++++++++ customModules/hypridle/helpers.ts | 29 ++++++++++++ customModules/hypridle/index.ts | 65 ++++++++++++++++++++++++++ modules/bar/Bar.ts | 3 ++ modules/bar/Exports.ts | 2 + options.ts | 21 +++++++++ scss/style/customModules/style.scss | 54 ++++++++++++++++------ 8 files changed, 236 insertions(+), 14 deletions(-) create mode 100644 customModules/hypridle/helpers.ts create mode 100644 customModules/hypridle/index.ts diff --git a/README.md b/README.md index b0a7ec8..636600c 100644 --- a/README.md +++ b/README.md @@ -90,6 +90,9 @@ hyprpicker ## To enable hyprland's very own blue light filter hyprsunset +## To enable hyprland's very own idle inhibitor +hypridle + ## To click resource/stat bars in the dashboard and open btop btop @@ -111,7 +114,7 @@ sudo pacman -S pipewire libgtop bluez bluez-utils btop networkmanager dart-sass AUR: ```bash -yay -S grimblast-git gpu-screen-recorder hyprpicker matugen-bin python-gpustat aylurs-gtk-shell-git hyprsunset-git +yay -S grimblast-git gpu-screen-recorder hyprpicker matugen-bin python-gpustat aylurs-gtk-shell-git hyprsunset-git hypridle-git ``` ### Fedora diff --git a/customModules/config.ts b/customModules/config.ts index 2847a66..138839e 100644 --- a/customModules/config.ts +++ b/customModules/config.ts @@ -710,6 +710,77 @@ export const CustomModuleSettings = (): Scrollable => type: 'string', }), + /* + ************************************ + * HYPRIDLE * + ************************************ + */ + Header('Hypridle'), + Option({ + opt: options.theme.bar.buttons.modules.hypridle.enableBorder, + title: 'Button Border', + type: 'boolean', + }), + Option({ + opt: options.bar.customModules.hypridle.onIcon, + title: 'Enabled Icon', + type: 'string', + }), + Option({ + opt: options.bar.customModules.hypridle.offIcon, + title: 'Disabled Icon', + type: 'string', + }), + Option({ + opt: options.bar.customModules.hypridle.onLabel, + title: 'Enabled Label', + type: 'string', + }), + Option({ + opt: options.bar.customModules.hypridle.offLabel, + title: 'Disabled Label', + type: 'string', + }), + Option({ + opt: options.bar.customModules.hypridle.label, + title: 'Show Label', + type: 'boolean', + }), + Option({ + opt: options.theme.bar.buttons.modules.hypridle.spacing, + title: 'Spacing', + type: 'string', + }), + Option({ + opt: options.bar.customModules.hypridle.pollingInterval, + title: 'Polling Interval', + type: 'number', + subtitle: "WARNING: Be careful of your package manager's rate limit.", + min: 100, + max: 60 * 24 * 1000, + increment: 1000, + }), + Option({ + opt: options.bar.customModules.hypridle.rightClick, + title: 'Right Click', + type: 'string', + }), + Option({ + opt: options.bar.customModules.hypridle.middleClick, + title: 'Middle Click', + type: 'string', + }), + Option({ + opt: options.bar.customModules.hypridle.scrollUp, + title: 'Scroll Up', + type: 'string', + }), + Option({ + opt: options.bar.customModules.hypridle.scrollDown, + title: 'Scroll Down', + type: 'string', + }), + /* ************************************ * POWER * diff --git a/customModules/hypridle/helpers.ts b/customModules/hypridle/helpers.ts new file mode 100644 index 0000000..bfa223a --- /dev/null +++ b/customModules/hypridle/helpers.ts @@ -0,0 +1,29 @@ +import { Variable as TVariable } from 'types/variable'; + +export const isActiveCommand = `bash -c "pgrep -x "hypridle" > /dev/null && echo "yes" || echo "no""`; + +export const isActive = Variable(false); + +export const toggleIdle = (isActive: TVariable): void => { + Utils.execAsync(isActiveCommand).then((res) => { + if (res === 'no') { + Utils.execAsync(`bash -c "nohup hypridle > /dev/null 2>&1 &"`).then(() => { + Utils.execAsync(isActiveCommand).then((res) => { + isActive.value = res === 'yes'; + }); + }); + } else { + Utils.execAsync(`bash -c "pkill hypridle "`).then(() => { + Utils.execAsync(isActiveCommand).then((res) => { + isActive.value = res === 'yes'; + }); + }); + } + }); +}; + +export const checkIdleStatus = (): undefined => { + Utils.execAsync(isActiveCommand).then((res) => { + isActive.value = res === 'yes'; + }); +}; diff --git a/customModules/hypridle/index.ts b/customModules/hypridle/index.ts new file mode 100644 index 0000000..8895531 --- /dev/null +++ b/customModules/hypridle/index.ts @@ -0,0 +1,65 @@ +import options from 'options'; +import { module } from '../module'; + +import { inputHandler, throttleInput } from 'customModules/utils'; +import Button from 'types/widgets/button'; +import { Attribute, Child } from 'lib/types/widget'; +import { BarBoxChild } from 'lib/types/bar'; +import { pollVariable } from 'customModules/PollVar'; +import { checkIdleStatus, isActive, toggleIdle } from './helpers'; + +const { label, pollingInterval, onIcon, offIcon, onLabel, offLabel, rightClick, middleClick, scrollUp, scrollDown } = + options.bar.customModules.hypridle; + +const dummyVar = Variable(undefined); + +checkIdleStatus(); + +pollVariable(dummyVar, [], pollingInterval.bind('value'), checkIdleStatus); + +const throttledToggleIdle = throttleInput(() => toggleIdle(isActive), 1000); + +export const Hypridle = (): BarBoxChild => { + const hypridleModule = module({ + textIcon: Utils.merge( + [isActive.bind('value'), onIcon.bind('value'), offIcon.bind('value')], + (active, onIcn, offIcn) => { + return active ? onIcn : offIcn; + }, + ), + tooltipText: isActive.bind('value').as((active) => `Hypridle ${active ? 'enabled' : 'disabled'}`), + boxClass: 'hypridle', + label: Utils.merge( + [isActive.bind('value'), onLabel.bind('value'), offLabel.bind('value')], + (active, onLbl, offLbl) => { + return active ? onLbl : offLbl; + }, + ), + showLabelBinding: label.bind('value'), + props: { + setup: (self: Button) => { + inputHandler(self, { + onPrimaryClick: { + fn: () => { + throttledToggleIdle(); + }, + }, + onSecondaryClick: { + cmd: rightClick, + }, + onMiddleClick: { + cmd: middleClick, + }, + onScrollUp: { + cmd: scrollUp, + }, + onScrollDown: { + cmd: scrollDown, + }, + }); + }, + }, + }); + + return hypridleModule; +}; diff --git a/modules/bar/Bar.ts b/modules/bar/Bar.ts index ded9d11..adc7eef 100644 --- a/modules/bar/Bar.ts +++ b/modules/bar/Bar.ts @@ -25,6 +25,7 @@ import { Weather, Power, Hyprsunset, + Hypridle, } from './Exports'; import { BarItemBox as WidgetContainer } from '../shared/barItemBox.js'; @@ -66,6 +67,7 @@ type Section = | 'weather' | 'power' | 'systray' + | 'hypridle' | 'hyprsunset'; type Layout = { @@ -124,6 +126,7 @@ const widget = { weather: (): Button => WidgetContainer(Weather()), power: (): Button => WidgetContainer(Power()), hyprsunset: (): Button => WidgetContainer(Hyprsunset()), + hypridle: (): Button => WidgetContainer(Hypridle()), }; type GdkMonitors = { diff --git a/modules/bar/Exports.ts b/modules/bar/Exports.ts index 81499d3..03229c4 100644 --- a/modules/bar/Exports.ts +++ b/modules/bar/Exports.ts @@ -22,6 +22,7 @@ import { Submap } from 'customModules/submap/index'; import { Weather } from 'customModules/weather/index'; import { Power } from 'customModules/power/index'; import { Hyprsunset } from 'customModules/hyprsunset/index'; +import { Hypridle } from 'customModules/hypridle/index'; export { Menu, @@ -48,4 +49,5 @@ export { Weather, Power, Hyprsunset, + Hypridle, }; diff --git a/options.ts b/options.ts index 282c1fb..f3afc61 100644 --- a/options.ts +++ b/options.ts @@ -386,6 +386,15 @@ const options = mkOptions(OPTIONS, { icon_background: opt(colors.base2), spacing: opt('0.45em'), }, + hypridle: { + enableBorder: opt(false), + border: opt(colors.peach), + background: opt(colors.base2), + text: opt(colors.peach), + icon: opt(colors.peach), + icon_background: opt(colors.base2), + spacing: opt('0.45em'), + }, }, }, menus: { @@ -1117,6 +1126,18 @@ const options = mkOptions(OPTIONS, { scrollUp: opt(''), scrollDown: opt(''), }, + hypridle: { + label: opt(true), + onIcon: opt(''), + offIcon: opt(''), + onLabel: opt('On'), + offLabel: opt('Off'), + pollingInterval: opt(1000 * 2), + rightClick: opt(''), + middleClick: opt(''), + scrollUp: opt(''), + scrollDown: opt(''), + }, }, }, diff --git a/scss/style/customModules/style.scss b/scss/style/customModules/style.scss index 9ca3722..2dde47d 100644 --- a/scss/style/customModules/style.scss +++ b/scss/style/customModules/style.scss @@ -1,4 +1,4 @@ -/* +/* * ################################# * # Default Styling # * ################################# @@ -31,7 +31,7 @@ } } -/* +/* * ################################# * # Styling Function # * ################################# @@ -126,7 +126,7 @@ } } -/* +/* * ################################# * # Ram Module Styling # * ################################# @@ -152,7 +152,7 @@ $bar-buttons-modules-ram-border ); -/* +/* * ################################# * # Cpu Module Styling # * ################################# @@ -179,7 +179,7 @@ 1.05em // ); -/* +/* * ################################# * # Cpu Temp Module Styling # * ################################# @@ -206,7 +206,7 @@ 1.05em // ); -/* +/* * ################################# * # Storage Module Styling # * ################################# @@ -233,7 +233,7 @@ 1.3em // ); -/* +/* * ################################# * # Netstat Module Styling # * ################################# @@ -260,7 +260,7 @@ 1.2em // ); -/* +/* * ################################# * # KB Layout Module Styling # * ################################# @@ -287,7 +287,7 @@ 1.2em // ); -/* +/* * ################################# * # Updates Module Styling # * ################################# @@ -314,7 +314,7 @@ 1.2em // ); -/* +/* * ################################# * # Submap Module Styling # * ################################# @@ -341,7 +341,7 @@ 1.2em // ); -/* +/* * ################################# * # Weather Module Styling # * ################################# @@ -368,7 +368,7 @@ 1.2em // ); -/* +/* * ################################# * # Power Module Styling # * ################################# @@ -395,7 +395,7 @@ 1.3em // ); -/* +/* * ################################# * # Hyprsunset Styling # * ################################# @@ -421,3 +421,31 @@ // custom font size 1.3em // ); + + +/* + * ################################# + * # Hypridle Styling # + * ################################# + */ +@include styleModule( + // + // class name + 'hypridle', + // label color + $bar-buttons-modules-hypridle-text, + // icon color + $bar-buttons-modules-hypridle-icon, + // icon background if split style is used + $bar-buttons-modules-hypridle-icon_background, + // label background + $bar-buttons-modules-hypridle-background, + // inner spacing + $bar-buttons-modules-hypridle-spacing, + // if border enabled + $bar-buttons-modules-hypridle-enableBorder, + // border color + $bar-buttons-modules-hypridle-border, + // custom font size + 1em // +);