Is there a way to make a bash script (or gnome extension) to set an custom wallpaper when change to AC/Battery?
11 Answer
You do it in three steps. First, you need to create an udev rule. I use my mouse as an example.
/etc/udev/rules.d/99-battery.rules:
ACTION=="change", \
KERNEL=="hidpp_battery_0", \
SUBSYSTEM=="power_supply", \
ATTR{model_name}=="Performance MX", \
TAG+="systemd", \
ENV{SYSTEMD_READY}="1", \
ENV{SYSTEMD_USER_WANTS}="battery@%E{POWER_SUPPLY_STATUS}.service"If you make any changes to your udev rule and the device is already connected, then you must explicitly apply your rule again with udevadm trigger.
The easiest way to find useful attributes for your device is to start an udev monitor, connect your charging cable. Now you should see the udev path and environment attributes.
$ udevadm monitor --udev --environmentWith your udev path, you can query your device for the rest of the attributes (in my case):
$ udevadm info -a --path='/sys/devices/pci0000:00/0000:00:13.1/usb6/6-3/6-3:1.2/0003:046D:C52B.0006/0003:046D:101A.0007/power_supply/hidpp_battery_0'Next, you need to create a systemd template. Such a service is called an "instantiated" service. It makes it possible to send a single argument via the service name. With %-specifiers, it is possible to access the "argument" within the service.
/etc/systemd/user/battery@.service
[Unit]
Description=Logitech Battery Service
[Service]
ExecStart=/opt/bin/battery.sh %iThere is no dbus method in KDE to change the background (at least that I'm aware of), so I had to use a javascript snippet.
/opt/bin/battery.sh:
#!/bin/bash
declare -l status=$1
[[ ! $status \
=~ (full|(dis)?charging) ]] && exit 0
if [[ $XDG_SESSION_DESKTOP = KDE ]]; then
javascript=$(cat << EOF
const o = { wallpaperPlugin: 'org.kde.image', currentConfigGroup: [ 'Wallpaper', 'org.kde.image', 'General' ]
}
for (i in (d = desktops())) { Object.assign(d[i], o).writeConfig('Image', 'file:///opt/wallpapers/battery_$status.png');
}
EOF
) busctl --user call org.kde.plasmashell /PlasmaShell org.kde.PlasmaShell evaluateScript s "$javascript"
elif [[ $XDG_SESSION_DESKTOP = GNOME ]]; then dconf gsettings set org.gnome.desktop.background picture-uri "'file:///opt/wallpapers/battery_$status.png'"
fiThe script will look for images named battery_full.png, battery_charging.png, and battery_discharging.png in the directory /opt/wallpapers/.