Skip to content

Instantly share code, notes, and snippets.

@ar7eniyan
Last active January 9, 2026 21:25
Show Gist options
  • Select an option

  • Save ar7eniyan/42567870ad2ce47143ffeb41754b4484 to your computer and use it in GitHub Desktop.

Select an option

Save ar7eniyan/42567870ad2ce47143ffeb41754b4484 to your computer and use it in GitHub Desktop.
Waybar module for controlling brightness of an external display
// insert into ~/.config/waybar/config
"custom/ddc_brightness": {
// I don't even want to know why this works.
// Change it to the following for your custom icons,
// current format is a hack for Material Symbols to display normally:
// "format": "{icon} {percentage}%",
"format": "<span rise='-2pt' size='12pt'>{icon}</span> <span rise='1pt' size='10pt'>{percentage}%</span>",
"format-icons": [
// Icons from Google Material Symbols.
// Put your icons here.
"\ue3a6", "\ue3a7", "\ue3a8", "\ue3a9", "\ue3aa", "\ue3ab", "\ue3ac"
],
"exec": "~/.config/waybar/waybar-ddc-module.sh",
"return-type": "json",
"on-scroll-up": "echo '+' > /tmp/waybar-ddc-module-rx",
"on-scroll-down": "echo '-' > /tmp/waybar-ddc-module-rx",
"on-click": "echo 'min' > /tmp/waybar-ddc-module-rx",
"on-click-right": "echo 'max' > /tmp/waybar-ddc-module-rx",
"tooltip": false,
},
#!/usr/bin/env bash
receive_pipe="/tmp/waybar-ddc-module-rx"
step=5
ddcutil_fast() {
# adjust the bus number and the multiplier for your display
# multiplier should be chosen so that it both works reliably and fast enough
ddcutil --noverify --bus 5 --sleep-multiplier .03 "$@" 2>/dev/null
}
ddcutil_slow() {
ddcutil --maxtries 15,15,15 "$@" 2>/dev/null
}
# takes ddcutil commandline as arguments
print_brightness() {
if brightness=$("$@" -t getvcp 10); then
brightness=$(echo "$brightness" | cut -d ' ' -f 4)
else
brightness=-1
fi
echo '{ "percentage":' "$brightness" '}'
}
rm -rf $receive_pipe
mkfifo $receive_pipe
# in case waybar restarted the script after restarting/replugging a monitor
print_brightness ddcutil_slow
while true; do
read -r command < $receive_pipe
case $command in
+ | -)
ddcutil_fast setvcp 10 $command $step
;;
max)
ddcutil_fast setvcp 10 100
;;
min)
ddcutil_fast setvcp 10 0
;;
esac
print_brightness ddcutil_fast
done
@ar7eniyan
Copy link
Author

Dependencies:

  • ddcutil (any version)

@leoleguizamon
Copy link

leoleguizamon commented Jan 9, 2026

Hi!, i want to share a little modification of this module:

Pros:

  • Now can change contrast and brightness (on-click-middle)
  • Tooltip implemented
  • Hide if no DDC monitors detected

Cons:

  • Same icon no matter the % (Nerd font icon in file)

config

    "custom/DDC10": {
        "format": "{}",
        "exec": "~/.config/waybar/ddc-control.sh",
        "return-type": "json",
        "on-scroll-up": "echo 'up' > /tmp/waybar-ddc-module-rx",
        "on-scroll-down": "echo 'down' > /tmp/waybar-ddc-module-rx",
        "on-click": "echo 'max' > /tmp/waybar-ddc-module-rx",
        "on-click-right": "echo 'min' > /tmp/waybar-ddc-module-rx",
        "on-click-middle": "echo 'toggle' > /tmp/waybar-ddc-module-rx"
    },

ddc-control.sh

#!/bin/bash

RECEIVE_PIPE="/tmp/waybar-ddc-module-rx"
STEP=10

# Valores VCP
BRIGHTNESS_VCP=10
CONTRAST_VCP=12

# Estado inicial
MODE="brightness"
VCP=$BRIGHTNESS_VCP
ICON="󰃠"
LABEL="Brightness"

ddcutil_fast() {
    ddcutil --noverify --sleep-multiplier .01 "$@" 2>/dev/null
}

ddcutil_slow() {
    ddcutil --maxtries 15,15,15 "$@" 2>/dev/null
}

print_value() {
    # Obtener valor actual con la función pasada como argumento
    if VALUE=$("$@" -t getvcp "$VCP"); then
        # Extraer solo el valor numérico (campo 4)
        VALUE=$(echo "$VALUE" | cut -d ' ' -f 4)
    else
        VALUE=-1
    fi
    
    # Salida JSON para Waybar
    echo "{\"text\": \"${VALUE}% $ICON\", \"tooltip\": \"$LABEL: ${VALUE}%\"}"
}

# Verificar si hay monitores DDC disponibles
if ! command -v ddcutil &> /dev/null; then
    exit 0
fi

if ! ddcutil detect --brief &> /dev/null; then
    exit 0
fi

# Limpiar y crear pipe
rm -rf "$RECEIVE_PIPE"
mkfifo "$RECEIVE_PIPE"

# Primera lectura
print_value ddcutil_slow

# Bucle principal
while true; do
    read -r command < "$RECEIVE_PIPE"
    
    case "$command" in
        up)
            ddcutil_fast setvcp "$VCP" + "$STEP"
            print_value ddcutil_fast
            ;;
        down)
            ddcutil_fast setvcp "$VCP" - "$STEP"
            print_value ddcutil_fast
            ;;
        max)
            ddcutil_fast setvcp "$VCP" 100
            print_value ddcutil_fast
            ;;
        min)
            ddcutil_fast setvcp "$VCP" 0
            print_value ddcutil_fast
            ;;
        toggle)
            # Cambiar entre brillo y contraste
            if [ "$MODE" = "brightness" ]; then
                VCP=$CONTRAST_VCP
                ICON="󰆗"
                LABEL="Contrast"
                MODE="contrast"
            else
                VCP=$BRIGHTNESS_VCP
                ICON="󰃠"
                LABEL="Brightness"
                MODE="brightness"
            fi
            print_value ddcutil_fast
            ;;
        *)
            ;;
    esac
done

Brightness

ss090126-161922

Contrast

ss090126-161926

(Sorry for my bad English) jaja :D

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment