feat: idle inhibit (#502)
Co-authored-by: Jas Singh <jaskiratpal.singh@outlook.com>
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -710,6 +710,77 @@ export const CustomModuleSettings = (): Scrollable<GtkWidget, Attribute> =>
|
||||
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 *
|
||||
|
||||
29
customModules/hypridle/helpers.ts
Normal file
29
customModules/hypridle/helpers.ts
Normal file
@@ -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<boolean>): 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';
|
||||
});
|
||||
};
|
||||
65
customModules/hypridle/index.ts
Normal file
65
customModules/hypridle/index.ts
Normal file
@@ -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<Child, Attribute>) => {
|
||||
inputHandler(self, {
|
||||
onPrimaryClick: {
|
||||
fn: () => {
|
||||
throttledToggleIdle();
|
||||
},
|
||||
},
|
||||
onSecondaryClick: {
|
||||
cmd: rightClick,
|
||||
},
|
||||
onMiddleClick: {
|
||||
cmd: middleClick,
|
||||
},
|
||||
onScrollUp: {
|
||||
cmd: scrollUp,
|
||||
},
|
||||
onScrollDown: {
|
||||
cmd: scrollDown,
|
||||
},
|
||||
});
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
return hypridleModule;
|
||||
};
|
||||
@@ -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<Child, Attribute> => WidgetContainer(Weather()),
|
||||
power: (): Button<Child, Attribute> => WidgetContainer(Power()),
|
||||
hyprsunset: (): Button<Child, Attribute> => WidgetContainer(Hyprsunset()),
|
||||
hypridle: (): Button<Child, Attribute> => WidgetContainer(Hypridle()),
|
||||
};
|
||||
|
||||
type GdkMonitors = {
|
||||
|
||||
@@ -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,
|
||||
};
|
||||
|
||||
21
options.ts
21
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(''),
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
|
||||
@@ -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 //
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user