From 377726801b2b36f978976154d8fd71e735eed7fb Mon Sep 17 00:00:00 2001 From: Tobias Huttinger Date: Thu, 9 Jul 2026 21:51:46 +0200 Subject: [PATCH] Added brightnessctl on IS_DESKTOP=0 and configured waybar to include a power profiles daemon switch if the service is available --- 02-system/10-packages.sh | 5 ++ 03-user/dotfiles/.config/waybar/config.jsonc | 11 +++ .../.config/waybar/scripts/power-profile.sh | 71 +++++++++++++++++++ 03-user/dotfiles/.config/waybar/style.css | 1 + 4 files changed, 88 insertions(+) create mode 100644 03-user/dotfiles/.config/waybar/scripts/power-profile.sh diff --git a/02-system/10-packages.sh b/02-system/10-packages.sh index cc276cd..6431780 100644 --- a/02-system/10-packages.sh +++ b/02-system/10-packages.sh @@ -15,3 +15,8 @@ case "$GPU" in intel) pac_file packages/graphics-intel.txt ;; *) info "no GPU group for GPU='$GPU'" ;; esac + +# Laptop only: backlight control. Desktop monitors (DP/HDMI) don't expose a +# /sys/class/backlight device — they use DDC/CI (ddcutil) — so brightnessctl has +# nothing to control there and the XF86MonBrightness* binds just no-op. +[ "$IS_DESKTOP" = 0 ] && pacman -S --needed --noconfirm brightnessctl diff --git a/03-user/dotfiles/.config/waybar/config.jsonc b/03-user/dotfiles/.config/waybar/config.jsonc index 60cde1e..cd2abd3 100644 --- a/03-user/dotfiles/.config/waybar/config.jsonc +++ b/03-user/dotfiles/.config/waybar/config.jsonc @@ -23,6 +23,7 @@ "cpu", "memory", "battery", + "custom/power_profile", "custom/studio-sound", "bluetooth", "wireplumber", @@ -195,6 +196,16 @@ "return-type": "json" }, +"custom/power_profile": { + "format": "{}", + "exec": "~/.config/waybar/scripts/power-profile.sh", + "on-click": "~/.config/waybar/scripts/power-profile.sh toggle", + "interval": "once", + "signal": 9, + "return-type": "json", + "tooltip": true + }, + "custom/studio-sound": { "format": "{}", "exec": "~/.config/waybar/scripts/studio-sound.py", diff --git a/03-user/dotfiles/.config/waybar/scripts/power-profile.sh b/03-user/dotfiles/.config/waybar/scripts/power-profile.sh new file mode 100644 index 0000000..09226d3 --- /dev/null +++ b/03-user/dotfiles/.config/waybar/scripts/power-profile.sh @@ -0,0 +1,71 @@ +#!/bin/bash + +# Waybar power-profiles-daemon module. +# default : print the current profile as JSON (empty -> Waybar hides the module) +# toggle : cycle to the next available profile, then signal Waybar to refresh +# +# Wired as interval:"once" + signal in config.jsonc, so the script runs exactly +# once at Waybar startup and thereafter only when we signal it on click. On a +# desktop the single startup run hits an unavailable PPD, prints empty, and the +# module stays hidden forever with no recurring cost. +# +# Availability keys off the systemd unit being *enabled* rather than +# `powerprofilesctl get` succeeding: PPD is D-Bus-activatable and desktop CPUs +# expose EPP too, so `get` would answer on a desktop as well. The repo only +# enables the service on laptops (IS_DESKTOP=0), so `is-enabled` is the honest +# "is this a laptop that uses PPD" signal. + +SERVICE=power-profiles-daemon.service + +available() { + command -v powerprofilesctl >/dev/null 2>&1 || return 1 + systemctl is-enabled "$SERVICE" >/dev/null 2>&1 +} + +# Available profile names in the order PPD lists them (power-saver … performance). +# Profile header lines are just "name:" (optionally "* name:" for the active one); +# every other line (Driver:, Degraded:, …) has text after the colon. +profiles() { + powerprofilesctl list 2>/dev/null | sed -nE 's/^[[:space:]]*\*?[[:space:]]*([a-z-]+):[[:space:]]*$/\1/p' +} + +# FontAwesome glyphs (Nerd Font): f0e7 bolt, f6ad yin-yang, f06c leaf, f011 power. +icon() { + case "$1" in + performance) printf '' ;; + balanced) printf '' ;; + power-saver) printf '' ;; + *) printf '' ;; # power symbol, fallback + esac +} + +cycle() { + mapfile -t list < <(profiles) + [ "${#list[@]}" -eq 0 ] && exit 0 + cur=$(powerprofilesctl get 2>/dev/null) + next=0 + for i in "${!list[@]}"; do + if [ "${list[$i]}" = "$cur" ]; then + next=$(( (i + 1) % ${#list[@]} )) + break + fi + done + powerprofilesctl set "${list[$next]}" + pkill -SIGRTMIN+9 waybar +} + +output() { + if ! available; then + printf '{"text":""}\n' + exit 0 + fi + cur=$(powerprofilesctl get 2>/dev/null) + [ -z "$cur" ] && { printf '{"text":""}\n'; exit 0; } + printf '{"text":"%s","tooltip":"Power profile: %s\\nClick to cycle","class":"%s"}\n' \ + "$(icon "$cur")" "$cur" "$cur" +} + +case "$1" in + toggle|cycle) cycle ;; + *) output ;; +esac diff --git a/03-user/dotfiles/.config/waybar/style.css b/03-user/dotfiles/.config/waybar/style.css index 8dae1df..9c01009 100644 --- a/03-user/dotfiles/.config/waybar/style.css +++ b/03-user/dotfiles/.config/waybar/style.css @@ -137,6 +137,7 @@ tooltip { color: #a6e3a1; border-left: 0px; border-right: 0px; + min-width: 20px; } #window {