Input-based dynamic FPS limiter for Linux. Monitors input devices via evdev and adjusts the FPS limit sent to MangoHud based on user activity. When you're actively using your mouse, FPS ramps up; when idle, it tapers off to save power.
Read more in the blog post. Try the interactive tuner to experiment with parameters using your own mouse.
mangochill-demo.webm
Uses an exponentially weighted envelope follower with asymmetric attack and release half-lives, borrowed from audio signal processing. The attack/release asymmetry lets FPS ramp up quickly for responsiveness while decaying slowly for smoothness. Device polling rates are detected automatically so the algorithm behaves consistently regardless of your mouse.
- server -- privileged daemon that reads evdev input devices and exposes an RPC interface over a Unix socket. Runs as a dedicated system user with minimal permissions.
- client -- unprivileged process that subscribes to FPS limit updates from the server and forwards them to MangoHud's control socket.
- raw_export -- utility to stream raw input event timestamps as newline-delimited JSON for debugging.
$ nix run github:farnoy/mangochill#mangochill-client -- -vv --min-fps 10 --max-fps 60 --attack-half-life-ms 600 --release-half-life-ms 2000
# use mangochill in your command line chain:
PROTON_ADD_CONFIG=... gamemoderun mangochill-client ... -- mangohud %command%
# works with gamescope too:
gamescope --mangoapp mangochill-client ... %command%If stdout/stderr is unavailable, set MANGOCHILL_LOG=/path/to/mangochill.log to append logs to a file instead of stderr. RUST_LOG and -v/-vv still control filtering.
$ direnv allow
# or:
$ nix developWith the environment set up, you can now modify & run the binaries directly:
$ cargo run --bin mangochill-client -- ...Add the flake as an input to your NixOS configuration:
# flake.nix
{
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
mangochill = {
url = "github:farnoy/mangochill";
inputs.nixpkgs.follows = "nixpkgs";
inputs.flake-parts.follows = "flake-parts";
};
};
outputs = { nixpkgs, mangochill, ... }: {
nixosConfigurations.myhost = nixpkgs.lib.nixosSystem {
system = "x86_64-linux";
modules = [
mangochill.nixosModules.default
{
services.mangochill.enable = true;
}
];
};
};
}This sets up:
- A
mangochill-serversystemd service running as a dedicated system user - udev rules granting the service read access to input devices
mangochill-server,mangochill-client, andmangochill-raw-exportbinaries inPATH
The server needs less than 10 MiB of memory and only subscribes to input devices during active sessions. Input events are easy to process but I paid some attention to vectorize the hot loops and made the NixOS module compile using -C target-cpu=native.
Run an app through MangoHud, and then:
$ mangochill-client -vv --min-fps 10 --max-fps 60 --attack-half-life-ms 600 --release-half-life-ms 2000- Gamepad support
- Keyboard support
- Packaging for other distros
-
EVIOCG*re-synchronization afterSYN_DROPPED- may or may not be necessary