ddcutil Wrapper
I wrote a small wrapper over ddcutil to be able to use the brightness up/down
keys to change the currently focused monitor brightness (even with external
ones). This way you can manage them independently.
This wrapper is very unstable and hacky, the worst of the worst. You have been
warned.
If you port all this into a single service without intermediate files (as it
should be), please ping me. It should be a C++ (or other) program using swayipc
lib that subscribes to the event and places a hook that updates an internal
state struct with the screens globally. Then it can create… sockets? So users
can interact with it, increasing and decreasing brightness. Something like
bulb service
and then bulb increase
and bulb decrease
, maybe with the
ability of tweaking the amount.
Put this in /usr/bin/bulb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
| #!/bin/bash
# Get the model of the currently focused display
outputs=$(swaymsg -t get_outputs)
model=$(echo ${outputs} | jq -r '.[] | select(.focused) | .model')
name=$(echo ${outputs} | jq -r '.[] | select(.focused) | .name')
echo "${model}"
exec 100>/tmp/ddcutil.lock || (echo "failed to lock"; exit -1)
flock -x -w 10 100
if [[ "$name" == "eDP"* ]];then
if [[ "$1" == "+" ]]; then
echo "Increase"
light -T 1.1
else
echo "Decrease"
light -T 0.9
fi
flock -u 100
exit 0
fi
# Cached as this is slow
i2c_bus=$(awk -v model="$model" '
/Invalid display/ {skip=1}
/Display/ {skip=0}
/Model:/ {if (!skip) current_model=$2}
/I2C bus:/ {if (!skip) i2c_bus=$3}
current_model == model {print i2c_bus; exit}
' ~/.cache/ddcutil-script/state | cut -d '-' -f 2)
# Output the result
if [[ -n "$i2c_bus" ]]; then
if [[ "$1" == "+" ]]; then
echo "Increase ${i2_cbus}"
ddcutil setvcp -b ${i2c_bus} 10 + 5
else
echo "Decrease ${i2_cbus}"
ddcutil setvcp -b ${i2c_bus} 10 - 5
fi
echo "${i2_cbus}"
fi
echo "${i2_cbus}"
flock -u 100
|
Now, we use ~/.cache/ddcutil-script/state
to cache the ddcutil detect
command, as its very slow and should only be run once per monitor state change.
Create the following systemd service in
~/.config/systemd/user/ddcutil-watcher.service
:
1
2
3
4
5
6
7
8
9
10
11
12
| [Unit]
Description=ddcutil watcher cache
Wants=graphical.target
Required=graphical.target
[Service]
Type=simple
ExecStart=%h/.local/bin/ddcutil-watcher
Restart=always
[Install]
WantedBy=default.target multi-user.target
|
Then create ~/.local/bin/ddcutil-watcher
:
1
2
3
4
5
6
| mkdir -p ~/.cache/ddcutil-script
ddcutil detect 2>/dev/null > ~/.cache/ddcutil-script/state
swaymsg -t subscribe '["output"]' | while read -r event; do
echo "Screen state changed, update ic2bus..."
ddcutil detect 2>/dev/null > ~/.cache/ddcutil-script/state
done
|
Now in your sway
config, you can put:
1
2
| bindsym --locked XF86MonBrightnessUp exec bulb +
bindsym --locked XF86MonBrightnessDown exec bulb -
|