App to prevent sleep temporarily (a la Amphetamine on macOS)

On my macbook, I have the app Amphetamine which allows me to temporarily stop it from sleeping/locking for an arbitrary amount of time. I find it very useful when I am compiling stuff, building packages with Nix, just to give an example.
Is there something I could add to my NixOS machine to do something similar?

I don’t know about compiling but for consuming media I have this (home-manager systemd user service)

❯ cat -p src/global/systemd/user/services/wayland-pipewire-idle-inhibit.nix
{ lib, pkgs, ... }:
lib.mkIf pkgs.hostPlatform.isLinux {
  Unit = {
    Description = "Inhibit wayland idle when pipewire is playing media";
    ConditionEnvironment = "WAYLAND_DISPLAY";
    PartOf = [ "graphical-session.target" ];
    After = [ "graphical-session.target" ];
  };
  Install = {
    WantedBy = [ "graphical-session.target" ];
  };
  Service = {
    ExecStart = "${lib.getExe pkgs.wayland-pipewire-idle-inhibit}";
    Restart = "always";
  };
}

I am pretty sure it’s a simple dbus call to install an inhibitor generally, but I’ve not needed it for anything outside of what this offers so I haven’t bothered.

EDIT: seems like there is a dbus api being used: wayland-pipewire-idle-inhibit/src/idle_inhibitor/dbus/mod.rs at 952aef94b0d8a48c028b1ba7c3a9209fe0c64e46 · rafaelrc7/wayland-pipewire-idle-inhibit · GitHub

EDIT2: spec is here

All you really need is a script to call xdg-screensaver reset regularly. If you have a windowID to lock it to, you can avoid the need to repeatedly call it, though.

1 Like

Interesting - if this doesn’t exist I might just have to make a utility

Also interesting. I’ve mostly been using Linux distros for server stuff (including NixOS) and only got a laptop for NixOS recently so I don’t have much experience with the various APIs and whatnot for WM/DE stuff

just invoke the build or whatever task with systemd-inhibit

1 Like

If you’re on X11, caffeine does what you want. AIUI amphetamine is inspired by it, or the other way around.

On wayland it’s indeed a bit more tricky. The pipewire inhibit thing is cute, but since it just detects whether audio is playing it’s not what you want 99% of the time.

The systemd-inhibit script is great, but it requires that you know you want to keep your screen awake before you start a process. Often I notice things are wrong in the middle of a game’s cutscene…

I use sway, and built my own tray with eww. This is the script I use to launch and exit systemd-inhibit interactively: dotfiles/home-config/dotfiles/eww/inhibit.sh at 5e23c056a9af2d23681bcf7338d7df61371e754b · TLATER/dotfiles · GitHub

If you get rid of the eww-specific stuff, you can just run that script to toggle whether your screen will idle or not (which also inhibits sleep). It uses some fancy file signal shenanigans to prevent a busy wait, hence the complex shell script.

Hook it up to a UI however you fancy. This does require that your compositor’s sleep thing respects the spec, but the popular ones do.

1 Like

If you’re using Gnome there is a nice extension: https://search.nixos.org/packages?channel=25.05&show=gnomeExtensions.caffeine that offers you a nice button within the UI.

2 Likes

True, I’m forgetful like this too.

But it’s entirely possible to run systemd-inhibit on a small shell script that (for example) sleeps and loops while another process is still listed in ps

That’s what the script I linked to does, except without the busy loop :smiley:

Well, that’s blocking on a fifo to avoid looping, sure, but still needs to be manually released with another invocation of the script — which is perfectly fine in some cases. When I want that, I normally just toggle the actual desktop suspend-on-idle setting instead, because the button is easy enough to find and I have the commandline versions in atuin too.

What I normally want is for the computer to not go to sleep until the build has finished, but then to still go to sleep once it has.

Sometimes, I run these jobs in pueue, so if I happened to do that I can also take an inhibit hold on “pueue wait”

1 Like