Change the framerate of your linux/gnome/wayland laptop when you (un-)plug it
linux-change-hz-on-ac.md edited
92 lines 3.5 kB view raw view rendered
1## Install `displayconfig-mutter` (Fedora) 2```sh 3sudo dnf copr enable eaglesemanation/displayconfig-mutter 4sudo dnf install displayconfig-mutter 5``` 6```sh 7displayconfig-mutter list 8``` 9should return something along the lines of 10```sh 11┌───────────┬────────┬──────────────┬────────────┬──────────────┬─────────────────────┬─────┬─────┐ 12│ Connector │ Vendor │ Product name │ Resolution │ Refresh rate │ Scaling │ VRR │ HDR │ 13├───────────┼────────┼──────────────┼────────────┼──────────────┼─────────────────────┼─────┼─────┤ 14│ eDP-1 │ CSW │ MNG007ZA1-3 │ 3200x2000 │ 60 │ 166.66666269302368% │ No │ No │ 15└───────────┴────────┴──────────────┴────────────┴──────────────┴─────────────────────┴─────┴─────┘ 16``` 17In this case, my monitor is `eDP-1`. 18 19## Configure your env 20Here, you configure your desired connector (aka, your display), the framerate for when your laptop is unplugged (`LOW_HZ`) and the framerate for when AC is connected (`HIGH_HZ`). 21```sh 22cat > ~/.config/rr-autoswitch.env <<'EOF' 23CONNECTOR=eDP-1 24LOW_HZ=60 25HIGH_HZ=165 26EOF 27``` 28 29## Create the service 30```sh 31cat > ~/.local/bin/rr-watch-ac.sh <<'EOF' 32#!/usr/bin/env bash 33set -euo pipefail 34 35# Allow overrides via ~/.config/rr-autoswitch.env 36[ -f "$HOME/.config/rr-autoswitch.env" ] && source "$HOME/.config/rr-autoswitch.env" 37CONNECTOR="${CONNECTOR:-eDP-1}" 38LOW_HZ="${LOW_HZ:-60}" 39HIGH_HZ="${HIGH_HZ:-165}" 40 41apply_rr() { 42 local hz="$1" 43 # Keep current resolution, only change refresh rate 44 displayconfig-mutter set --connector "$CONNECTOR" --refresh-rate "$hz" 45} 46 47on_battery_now() { 48 # returns 0 if on battery, 1 otherwise 49 busctl get-property org.freedesktop.UPower /org/freedesktop/UPower org.freedesktop.UPower OnBattery \ 50 | grep -q 'true' 51} 52 53# Apply once at start 54if on_battery_now; then apply_rr "$LOW_HZ"; else apply_rr "$HIGH_HZ"; fi 55 56# React to future changes (UPower PropertiesChanged on /org/freedesktop/UPower) 57dbus-monitor --system "type='signal',sender='org.freedesktop.UPower',\ 58interface='org.freedesktop.DBus.Properties',member='PropertiesChanged',\ 59path='/org/freedesktop/UPower'" \ 60| while read -r line; do 61 if grep -q "OnBattery" <<<"$line"; then 62 # tiny debounce so we read the new state 63 sleep 0.3 64 if on_battery_now; then apply_rr "$LOW_HZ"; else apply_rr "$HIGH_HZ"; fi 65 fi 66 done 67EOF 68``` 69```sh 70chmod +x ~/.local/bin/rr-watch-ac.sh 71``` 72```sh 73cat > ~/.config/systemd/user/rr-autoswitch.service <<'EOF' 74[Unit] 75Description=Auto-switch monitor refresh rate on AC/battery (Wayland/GNOME) 76After=graphical-session.target 77Wants=graphical-session.target 78 79[Service] 80EnvironmentFile=%h/.config/rr-autoswitch.env 81ExecStart=%h/.local/bin/rr-watch-ac.sh 82Restart=always 83RestartSec=1 84 85[Install] 86WantedBy=default.target 87EOF 88``` 89```sh 90systemctl --user daemon-reload 91systemctl --user enable --now rr-autoswitch.service 92```