System inhibition (which is essentially what the PowerDevil “manually block” feature does) is pretty easy to script. Maybe all you need is a command to request inhibition for how long you want, and then have some UI button to trigger it?
The command systemd-inhibit
allows you to inhibit idle sleep (or a few other power management conditions) while another command is running. The specific command you want to run is probably something like this:
systemd-inhibit --what=idle:sleep sleep 300
Which means: run the command sleep 300
and inhibit the idle timer or the sleep feature until that command ends. The command sleep 300
means “wait 300 seconds and then exit”. If you run this, you can see the effect in the PowerDevil widget:
This is not very informative, but that is because we didn’t specify the details that PowerDevil wants to display - namely the “who”, “what”, and “why” flags for systemd-inhibit
(see the explanation by typing man:systemd-inhibit
in krunner or main menu), and there are other missing features that you may want, such as - triggering with a GUI, knowing how long until the timer runs out, etc.
So, for exercise, I made this little script (attached at the end) that manages the unsleeping time for you. I’ve set it up as a widget on the desktop using the 3rd-party Command Output widget (also get it from the “Get New Widgets” button in the widgets menu) and it works like this:
- Configure the display command:
- Configure the click action command:
Then, when not blocking, it just shows the text “Not blocking”:
Click on it and a dialog box opens:
After selecting something and clicking “OK”, it starts blocking and you get a count down:
Here is the script - save it in a directory in your path (for example ~/.bin
or ~/.local/bin
) as unsleep-time
and give it “execute” permission:
#!/bin/bash -e
QUERY=
REMOVE=
ASK=
TIME_SPEC=
CLIARGS=( "" "$@" ) # OPTIND is 1 based
while [ "$OPTIND" -lt "${#CLIARGS[*]}" ]; do
if getopts "rqh?" OPT; then
case $OPT in
h|\?) echo "$0 <-q|-r|TIME-SPEC>" >&2; exit 5;;
q) QUERY=yes;;
r) REMOVE=yes;;
esac
else
TIME_SPEC="${CLIARGS[$OPTIND]}"
OPTIND=$(( $OPTIND + 1 ))
fi
done
if [ -n "$QUERY" ]; then
pid="$(systemd-inhibit --list | awk '$1=="unsleep-time"{print$4}')"
if [ -z "$pid" ]; then
echo "Not blocking"
exit 0
fi
running=$(ps h -p "$pid" -o etimes)
sleep_for="$(ps h -p "$pid" -o cmd | awk '{print$NF}')"
remaining=$(( sleep_for - running ))
printf "Blocking for %dm %02ds\n" $(( remaining / 60 )) $(( remaining % 60 ))
elif [ -n "$REMOVE" ]; then
pid="$(systemd-inhibit --list | awk '$1=="unsleep-time"{print$4}')"
if [ -n "$pid" ]; then
kill "$pid"
fi
else
if [ -z "$TIME_SPEC" ]; then
if which kdialog 2>&1 >/dev/null; then
TIME_SPEC="$(kdialog --slider "Inhibit idle sleep for how many minutes?" "1" "15" "1" || true)min"
else
TIME_SPEC="5min"
fi
fi
until="$(date -d "$TIME_SPEC" +%s)"
sleep_for=$(( $until - $(date +%s) ))
systemd-inhibit --what=idle:sleep --who=unsleep-time --why="Unsleeping for $TIME_SPEC" sleep "$sleep_for"
fi
So, this is a bit heavy handed but I like bash scripting A more “plasmay” approach will be to just create a standalone widget that implements the functionality directly using the PowerDevil DBus API, but that is too much for me at this time of night…