Proof Portal

Project overview

Omarchy

ProbeLabs65 findings · 95 requirements

A proof layer — requirements, tests and verified fixes — for two of Omarchy's subsystems: the application menu (launcher scripts, QML model, JSONC config, search and selection) and the lock screen (lock scripts, QML, PAM authentication). Scope is deliberately limited to those components of omacom/omarchy; the rest of the distribution is not covered.

Inbox
ReportR-3337GitHub issuePublicReceived

Per-Monitor Brightness Control for Hyprland + Waybar

Reported by maietta · filed Oct 17, 2025Closed upstream on 2026-02-01. GitHub close reason: completed. No closing PR or commit is recorded — "completed" alone is not evidence of a fix.

Received and recorded verbatim. Nothing has been checked yet.

At a glance

1 · What is claimed?
Only the report text below — no validator has restated it as checkable claims yet.
2 · What does it affect?
Not yet mapped to any requirement or component.
3 · Is it reproducible?
No validation has been run yet.
4 · What remains unclear?
  • Not validated yet: no claims, no reproducer.
5 · What happens next?
Our staff decide whether the report is valid. Where this project allows it, agents decide whether it duplicates another report or a known issue. No decision has been recorded yet.

Original report

Per-Monitor Brightness Control for Hyprland + Waybarrevision 1 · captured 2026-10-04 11:42 UTC via poll

I could not get any sort of brightness control working in my system, so I opted to put together something that others might find useful. There's probably a better way, but I have not yet found it.

Per-Monitor Brightness Control for Hyprland + Waybar

A comprehensive solution for controlling brightness on multiple monitors in Hyprland, with per-monitor Waybar widgets and keyboard shortcuts.

Features

  • 🖥️ Per-Monitor Control: Each Waybar instance shows and controls its own monitor's brightness
  • ⌨️ Keyboard Shortcuts: Control focused monitor brightness with Right Ctrl + Arrow keys
  • 🖱️ Waybar Widget: Scroll to adjust, click to set 100% or 0%
  • 🔄 Smart Detection: Automatically handles different monitor types:
  • External monitors via DDC/CI (ddcutil)
  • Laptop displays via brightnessctl
  • Unsupported monitors show "N/A"
  • ⚡ Fast Updates: Async DDC/CI commands prevent UI lag

Requirements

Dependencies

Install the following packages on Arch Linux:

sudo pacman -S ddcutil i2c-tools brightnessctl
  • ddcutil: Controls external monitors via DDC/CI protocol
  • i2c-tools: I2C device utilities
  • brightnessctl: Controls laptop backlight

System Configuration

1. Load i2c Kernel Module

# Load the module immediately
sudo modprobe i2c-dev

# Make it load on boot
echo "i2c-dev" | sudo tee /etc/modules-load.d/i2c.conf

2. Set Up i2c Group Permissions

# Create i2c group (if it doesn't exist)
getent group i2c || sudo groupadd i2c

# Add your user to the i2c group
sudo usermod -aG i2c $USER

# Create udev rule for i2c device permissions
sudo sh -c 'echo "KERNEL==\"i2c-[0-9]*\", GROUP=\"i2c\", MODE=\"0660\"" > /etc/udev/rules.d/99-i2c.rules'

# Reload udev rules
sudo udevadm control --reload-rules && sudo udevadm trigger

⚠️ Important: Log out and log back in (or reboot) for group membership to take effect.

3. Detect Your Monitors

After installing ddcutil, check which monitors support DDC/CI:

ddcutil detect

Example output:

Display 1
   I2C bus:  /dev/i2c-14
   DRM_connector:           card1-DP-7
   EDID synopsis:
      Mfg id:               GSM - Goldstar Company Ltd (LG)
      Model:                LG ULTRAWIDE
      Product code:         30655  (0x77bf)
   VCP version:         2.1

Invalid display
   I2C bus:  /dev/i2c-9
   DRM_connector:           card1-eDP-1
   This is a laptop display.  Laptop displays do not support DDC/CI.

Note the display numbers and connector names (e.g., DP-7, eDP-1).

Installation

1. Create the Brightness Control Script

Create ~/.config/waybar/scripts/brightness-per-monitor.sh:

#!/bin/bash

# --- CONFIGURATION ---
STEP=5
STATE_FILE_PREFIX="/tmp/waybar_brightness"
# ---------------------

# Get monitor name - either from argument, env var, or focused monitor
get_monitor_name() {
    if [ -n "$1" ]; then
        echo "$1"
    elif [ -n "$WAYBAR_OUTPUT_NAME" ]; then
        echo "$WAYBAR_OUTPUT_NAME"
    else
        hyprctl monitors -j | jq -r '.[] | select(.focused == true) | .name'
    fi
}

# Get ddcutil display number for a monitor
get_ddcutil_display() {
    local monitor_name="$1"
    case "$monitor_name" in
        "DP-7")
            echo "1"  # LG ULTRAWIDE - ADJUST THIS FOR YOUR SETUP
            ;;
        # Add more monitors here as needed:
        # "DP-4")
        #     echo "2"
        #     ;;
        *)
            echo ""  # No DDC/CI support
            ;;
    esac
}

# Get state file for this monitor
get_state_file() {
    local monitor="$1"
    echo "${STATE_FILE_PREFIX}_${monitor}.tmp"
}

# Function to send DDC/CI command in background
set_brightness_ddcutil() {
    local display_num="$1"
    local brightness="$2"
    pkill -f "ddcutil.*setvcp 10"
    (ddcutil --display "$display_num" setvcp 10 "$brightness") &
}

# Function to set laptop brightness
set_brightness_laptop() {
    local brightness="$1"
    brightnessctl set "${brightness}%" > /dev/null 2>&1
}

# Get current brightness for a specific monitor
get_current_brightness() {
    local monitor="$1"
    local state_file=$(get_state_file "$monitor")
    local display_num=$(get_ddcutil_display "$monitor")
    
    if [ "$monitor" = "eDP-1" ]; then
        # Laptop display
        if [ ! -f "$state_file" ]; then
            local current=$(brightnessctl get 2>/dev/null || echo "0")
            local max=$(brightnessctl max 2>/dev/null || echo "1")
            local percent=$((current * 100 / max))
            echo "$percent" > "$state_file"
        fi
        cat "$state_file"
    elif [ -n "$display_num" ]; then
        # External monitor with DDC/CI
        if [ ! -f "$state_file" ]; then
            local brightness=$(ddcutil --display "$display_num" getvcp 10 -t 2>/dev/null | awk '{print $4}' || echo "100")
            echo "$brightness" > "$state_file"
        fi
        cat "$state_file"
    else
        echo "?"
    fi
}

# Set brightness for a specific monitor
set_brightness() {
    local monitor="$1"
    local new_brightness="$2"
    local state_file=$(get_state_file "$monitor")
    local display_num=$(get_ddcutil_display "$monitor")
    
    if [ "$monitor" = "eDP-1" ]; then
        # Laptop display
        echo "$new_brightness" > "$state_file"
        set_brightness_laptop "$new_brightness"
    elif [ -n "$display_num" ]; then
        # External monitor with DDC/CI
        echo "$new_brightness" > "$state_file"
        set_brightness_ddcutil "$display_num" "$new_brightness"
    else
        # Unsupported monitor
        return
    fi
    
    # Signal all waybar instances
    pkill -RTMIN+8 waybar
}

# Parse command - format: "command [monitor]"
# If monitor not specified, use WAYBAR_OUTPUT_NAME or focused monitor
COMMAND="$1"
MONITOR=$(get_monitor_name "$2")
current=$(get_current_brightness "$MONITOR")

case "$COMMAND" in
    "get")
        echo " $current"
        ;;
    "up")
        if [ "$current" = "?" ]; then
            echo " N/A"
        else
            new_brightness=$((current + STEP > 100 ? 100 : current + STEP))
            if [ "$current" -ne "$new_brightness" ]; then
                set_brightness "$MONITOR" "$new_brightness"
            fi
        fi
        ;;
    "down")
        if [ "$current" = "?" ]; then
            echo " N/A"
        else
            new_brightness=$((current - STEP < 0 ? 0 : current - STEP))
            if [ "$current" -ne "$new_brightness" ]; then
                set_brightness "$MONITOR" "$new_brightness"
            fi
        fi
        ;;
    "right_click")
        if [ "$current" != "?" ]; then
            new_brightness=0
            set_brightness "$MONITOR" "$new_brightness"
        fi
        ;;
    "left_click")
        if [ "$current" != "?" ]; then
            new_brightness=100
            set_brightness "$MONITOR" "$new_brightness"
        fi
        ;;
esac

Make it executable:

chmod +x ~/.config/waybar/scripts/brightness-per-monitor.sh

⚠️ Important: Edit the get_ddcutil_display() function to match your monitor setup. Use the display numbers and connector names from ddcutil detect.

2. Configure Waybar

Add this to your ~/.config/waybar/config.jsonc:

Add to modules-right array:

"modules-right": [
  "group/tray-expander",
  "bluetooth",
  "network",
  "pulseaudio",
  "custom/brightness",  // Add this line
  "cpu",
  "battery"
],

Add the brightness widget configuration:

"custom/brightness": {
  "format": "☀ {}%",
  "signal": 8,
  "exec": "~/.config/waybar/scripts/brightness-per-monitor.sh get",
  "on-scroll-up": "~/.config/waybar/scripts/brightness-per-monitor.sh up",
  "on-scroll-down": "~/.config/waybar/scripts/brightness-per-monitor.sh down",
  "on-click": "~/.config/waybar/scripts/brightness-per-monitor.sh left_click",
  "on-click-right": "~/.config/waybar/scripts/brightness-per-monitor.sh right_click",
  "tooltip-format": "Monitor Brightness\\nScroll: adjust\\nLeft click: 100%\\nRight click: 0%"
}

Reload Waybar:

pkill -SIGUSR2 waybar

3. Configure Hyprland Keybindings

Add to your ~/.config/hypr/bindings.conf:

# Monitor brightness control (controls focused monitor)
bindeld = RCTRL, Up, Brightness up, exec, ~/.config/waybar/scripts/brightness-per-monitor.sh up
bindeld = RCTRL, Down, Brightness down, exec, ~/.config/waybar/scripts/brightness-per-monitor.sh down

Reload Hyprland:

hyprctl reload

Usage

Keyboard Shortcuts

  • Right Ctrl + Up Arrow: Increase brightness of focused monitor by 5%
  • Right Ctrl + Down Arrow: Decrease brightness of focused monitor by 5%

Waybar Widget

Each Waybar instance (one per monitor) shows the brightness for its specific monitor:

  • Scroll Up/Down: Adjust brightness by 5%
  • Left Click: Set to 100%
  • Right Click: Set to 0%

Manual Control

You can also control brightness from the command line:

# Get brightness for current focused monitor
~/.config/waybar/scripts/brightness-per-monitor.sh get

# Adjust brightness for focused monitor
~/.config/waybar/scripts/brightness-per-monitor.sh up
~/.config/waybar/scripts/brightness-per-monitor.sh down

# Control specific monitor
~/.config/waybar/scripts/brightness-per-monitor.sh up DP-7
~/.config/waybar/scripts/brightness-per-monitor.sh down eDP-1

Configuration Options

Adjust Step Size

Edit the STEP variable in brightness-per-monitor.sh:

STEP=5  # Change to 10 for larger steps

Add More External Monitors

If you have multiple external monitors, add them to the get_ddcutil_display() function:

get_ddcutil_display() {
    local monitor_name="$1"
    case "$monitor_name" in
        "DP-7")
            echo "1"  # First external monitor
            ;;
        "DP-4")
            echo "2"  # Second external monitor
            ;;
        "HDMI-A-1")
            echo "3"  # HDMI monitor
            ;;
        *)
            echo ""  # No DDC/CI support
            ;;
    esac
}

Find your display numbers with:

ddcutil detect

Troubleshooting

Monitor Not Detected

# Check if i2c devices exist
ls -la /dev/i2c-*

# Verify i2c module is loaded
lsmod | grep i2c

# Check group membership
groups $USER

Permission Denied Errors

# Check if you're in the i2c group
groups | grep i2c

# If not, add yourself and log out/in
sudo usermod -aG i2c $USER

DDC/CI Not Working

Some monitors may need to enable DDC/CI in their OSD (On-Screen Display) settings. Look for options like:
- DDC/CI
- External Control
- PC Communication

Brightness Changes Are Slow

This is normal for DDC/CI. The script runs ddcutil commands in the background to prevent UI lag. The Waybar display updates immediately using cached values.

Test DDC/CI Manually

# Get current brightness
ddcutil --display 1 getvcp 10

# Set brightness to 50%
ddcutil --display 1 setvcp 10 50

How It Works

  1. Monitor Detection: The script uses WAYBAR_OUTPUT_NAME (set by Waybar for each instance) or queries the focused monitor via hyprctl
  1. Per-Monitor State: Each monitor's brightness is cached in /tmp/waybar_brightness_<monitor>.tmp for fast reads
  1. Backend Selection:
  • Laptop displays (eDP-1) use brightnessctl
  • External monitors use ddcutil with DDC/CI
  • Unsupported monitors show "?"
  1. Async Updates: DDC/CI commands run in the background to prevent blocking. The UI updates immediately from the cache, while the actual hardware change happens asynchronously.
  1. Waybar Signals: Uses RTMIN+8 signal to refresh all Waybar instances after brightness changes

License

This configuration is provided as-is for personal use. Feel free to modify and share.

Credits

Based on the brightness control gist by negoro26, adapted for per-monitor control in Hyprland with Waybar.

View raw text
### I could not get any sort of brightness control working in my system, so I opted to put together something that others might find useful. There's probably a better way, but I have not yet found it.

# Per-Monitor Brightness Control for Hyprland + Waybar

A comprehensive solution for controlling brightness on multiple monitors in Hyprland, with per-monitor Waybar widgets and keyboard shortcuts.

## Features

- 🖥️ **Per-Monitor Control**: Each Waybar instance shows and controls its own monitor's brightness
- ⌨️ **Keyboard Shortcuts**: Control focused monitor brightness with Right Ctrl + Arrow keys
- 🖱️ **Waybar Widget**: Scroll to adjust, click to set 100% or 0%
- 🔄 **Smart Detection**: Automatically handles different monitor types:
  - External monitors via DDC/CI (ddcutil)
  - Laptop displays via brightnessctl
  - Unsupported monitors show "N/A"
- ⚡ **Fast Updates**: Async DDC/CI commands prevent UI lag

## Requirements

### Dependencies

Install the following packages on Arch Linux:

```bash
sudo pacman -S ddcutil i2c-tools brightnessctl
```

- **ddcutil**: Controls external monitors via DDC/CI protocol
- **i2c-tools**: I2C device utilities
- **brightnessctl**: Controls laptop backlight

### System Configuration

#### 1. Load i2c Kernel Module

```bash
# Load the module immediately
sudo modprobe i2c-dev

# Make it load on boot
echo "i2c-dev" | sudo tee /etc/modules-load.d/i2c.conf
```

#### 2. Set Up i2c Group Permissions

```bash
# Create i2c group (if it doesn't exist)
getent group i2c || sudo groupadd i2c

# Add your user to the i2c group
sudo usermod -aG i2c $USER

# Create udev rule for i2c device permissions
sudo sh -c 'echo "KERNEL==\"i2c-[0-9]*\", GROUP=\"i2c\", MODE=\"0660\"" > /etc/udev/rules.d/99-i2c.rules'

# Reload udev rules
sudo udevadm control --reload-rules && sudo udevadm trigger
```

**⚠️ Important:** Log out and log back in (or reboot) for group membership to take effect.

#### 3. Detect Your Monitors

After installing ddcutil, check which monitors support DDC/CI:

```bash
ddcutil detect
```

Example output:
```
Display 1
   I2C bus:  /dev/i2c-14
   DRM_connector:           card1-DP-7
   EDID synopsis:
      Mfg id:               GSM - Goldstar Company Ltd (LG)
      Model:                LG ULTRAWIDE
      Product code:         30655  (0x77bf)
   VCP version:         2.1

Invalid display
   I2C bus:  /dev/i2c-9
   DRM_connector:           card1-eDP-1
   This is a laptop display.  Laptop displays do not support DDC/CI.
```

Note the display numbers and connector names (e.g., DP-7, eDP-1).

## Installation

### 1. Create the Brightness Control Script

Create `~/.config/waybar/scripts/brightness-per-monitor.sh`:

```bash
#!/bin/bash

# --- CONFIGURATION ---
STEP=5
STATE_FILE_PREFIX="/tmp/waybar_brightness"
# ---------------------

# Get monitor name - either from argument, env var, or focused monitor
get_monitor_name() {
    if [ -n "$1" ]; then
        echo "$1"
    elif [ -n "$WAYBAR_OUTPUT_NAME" ]; then
        echo "$WAYBAR_OUTPUT_NAME"
    else
        hyprctl monitors -j | jq -r '.[] | select(.focused == true) | .name'
    fi
}

# Get ddcutil display number for a monitor
get_ddcutil_display() {
    local monitor_name="$1"
    case "$monitor_name" in
        "DP-7")
            echo "1"  # LG ULTRAWIDE - ADJUST THIS FOR YOUR SETUP
            ;;
        # Add more monitors here as needed:
        # "DP-4")
        #     echo "2"
        #     ;;
        *)
            echo ""  # No DDC/CI support
            ;;
    esac
}

# Get state file for this monitor
get_state_file() {
    local monitor="$1"
    echo "${STATE_FILE_PREFIX}_${monitor}.tmp"
}

# Function to send DDC/CI command in background
set_brightness_ddcutil() {
    local display_num="$1"
    local brightness="$2"
    pkill -f "ddcutil.*setvcp 10"
    (ddcutil --display "$display_num" setvcp 10 "$brightness") &
}

# Function to set laptop brightness
set_brightness_laptop() {
    local brightness="$1"
    brightnessctl set "${brightness}%" > /dev/null 2>&1
}

# Get current brightness for a specific monitor
get_current_brightness() {
    local monitor="$1"
    local state_file=$(get_state_file "$monitor")
    local display_num=$(get_ddcutil_display "$monitor")
    
    if [ "$monitor" = "eDP-1" ]; then
        # Laptop display
        if [ ! -f "$state_file" ]; then
            local current=$(brightnessctl get 2>/dev/null || echo "0")
            local max=$(brightnessctl max 2>/dev/null || echo "1")
            local percent=$((current * 100 / max))
            echo "$percent" > "$state_file"
        fi
        cat "$state_file"
    elif [ -n "$display_num" ]; then
        # External monitor with DDC/CI
        if [ ! -f "$state_file" ]; then
            local brightness=$(ddcutil --display "$display_num" getvcp 10 -t 2>/dev/null | awk '{print $4}' || echo "100")
            echo "$brightness" > "$state_file"
        fi
        cat "$state_file"
    else
        echo "?"
    fi
}

# Set brightness for a specific monitor
set_brightness() {
    local monitor="$1"
    local new_brightness="$2"
    local state_file=$(get_state_file "$monitor")
    local display_num=$(get_ddcutil_display "$monitor")
    
    if [ "$monitor" = "eDP-1" ]; then
        # Laptop display
        echo "$new_brightness" > "$state_file"
        set_brightness_laptop "$new_brightness"
    elif [ -n "$display_num" ]; then
        # External monitor with DDC/CI
        echo "$new_brightness" > "$state_file"
        set_brightness_ddcutil "$display_num" "$new_brightness"
    else
        # Unsupported monitor
        return
    fi
    
    # Signal all waybar instances
    pkill -RTMIN+8 waybar
}

# Parse command - format: "command [monitor]"
# If monitor not specified, use WAYBAR_OUTPUT_NAME or focused monitor
COMMAND="$1"
MONITOR=$(get_monitor_name "$2")
current=$(get_current_brightness "$MONITOR")

case "$COMMAND" in
    "get")
        echo " $current"
        ;;
    "up")
        if [ "$current" = "?" ]; then
            echo " N/A"
        else
            new_brightness=$((current + STEP > 100 ? 100 : current + STEP))
            if [ "$current" -ne "$new_brightness" ]; then
                set_brightness "$MONITOR" "$new_brightness"
            fi
        fi
        ;;
    "down")
        if [ "$current" = "?" ]; then
            echo " N/A"
        else
            new_brightness=$((current - STEP < 0 ? 0 : current - STEP))
            if [ "$current" -ne "$new_brightness" ]; then
                set_brightness "$MONITOR" "$new_brightness"
            fi
        fi
        ;;
    "right_click")
        if [ "$current" != "?" ]; then
            new_brightness=0
            set_brightness "$MONITOR" "$new_brightness"
        fi
        ;;
    "left_click")
        if [ "$current" != "?" ]; then
            new_brightness=100
            set_brightness "$MONITOR" "$new_brightness"
        fi
        ;;
esac
```

Make it executable:

```bash
chmod +x ~/.config/waybar/scripts/brightness-per-monitor.sh
```

**⚠️ Important:** Edit the `get_ddcutil_display()` function to match your monitor setup. Use the display numbers and connector names from `ddcutil detect`.

### 2. Configure Waybar

Add this to your `~/.config/waybar/config.jsonc`:

#### Add to modules-right array:

```jsonc
"modules-right": [
  "group/tray-expander",
  "bluetooth",
  "network",
  "pulseaudio",
  "custom/brightness",  // Add this line
  "cpu",
  "battery"
],
```

#### Add the brightness widget configuration:

```jsonc
"custom/brightness": {
  "format": "☀ {}%",
  "signal": 8,
  "exec": "~/.config/waybar/scripts/brightness-per-monitor.sh get",
  "on-scroll-up": "~/.config/waybar/scripts/brightness-per-monitor.sh up",
  "on-scroll-down": "~/.config/waybar/scripts/brightness-per-monitor.sh down",
  "on-click": "~/.config/waybar/scripts/brightness-per-monitor.sh left_click",
  "on-click-right": "~/.config/waybar/scripts/brightness-per-monitor.sh right_click",
  "tooltip-format": "Monitor Brightness\\nScroll: adjust\\nLeft click: 100%\\nRight click: 0%"
}
```

Reload Waybar:

```bash
pkill -SIGUSR2 waybar
```

### 3. Configure Hyprland Keybindings

Add to your `~/.config/hypr/bindings.conf`:

```
# Monitor brightness control (controls focused monitor)
bindeld = RCTRL, Up, Brightness up, exec, ~/.config/waybar/scripts/brightness-per-monitor.sh up
bindeld = RCTRL, Down, Brightness down, exec, ~/.config/waybar/scripts/brightness-per-monitor.sh down
```

Reload Hyprland:

```bash
hyprctl reload
```

## Usage

### Keyboard Shortcuts

- **Right Ctrl + Up Arrow**: Increase brightness of focused monitor by 5%
- **Right Ctrl + Down Arrow**: Decrease brightness of focused monitor by 5%

### Waybar Widget

Each Waybar instance (one per monitor) shows the brightness for its specific monitor:

- **Scroll Up/Down**: Adjust brightness by 5%
- **Left Click**: Set to 100%
- **Right Click**: Set to 0%

### Manual Control

You can also control brightness from the command line:

```bash
# Get brightness for current focused monitor
~/.config/waybar/scripts/brightness-per-monitor.sh get

# Adjust brightness for focused monitor
~/.config/waybar/scripts/brightness-per-monitor.sh up
~/.config/waybar/scripts/brightness-per-monitor.sh down

# Control specific monitor
~/.config/waybar/scripts/brightness-per-monitor.sh up DP-7
~/.config/waybar/scripts/brightness-per-monitor.sh down eDP-1
```

## Configuration Options

### Adjust Step Size

Edit the `STEP` variable in `brightness-per-monitor.sh`:

```bash
STEP=5  # Change to 10 for larger steps
```

### Add More External Monitors

If you have multiple external monitors, add them to the `get_ddcutil_display()` function:

```bash
get_ddcutil_display() {
    local monitor_name="$1"
    case "$monitor_name" in
        "DP-7")
            echo "1"  # First external monitor
            ;;
        "DP-4")
            echo "2"  # Second external monitor
            ;;
        "HDMI-A-1")
            echo "3"  # HDMI monitor
            ;;
        *)
            echo ""  # No DDC/CI support
            ;;
    esac
}
```

Find your display numbers with:

```bash
ddcutil detect
```

## Troubleshooting

### Monitor Not Detected

```bash
# Check if i2c devices exist
ls -la /dev/i2c-*

# Verify i2c module is loaded
lsmod | grep i2c

# Check group membership
groups $USER
```

### Permission Denied Errors

```bash
# Check if you're in the i2c group
groups | grep i2c

# If not, add yourself and log out/in
sudo usermod -aG i2c $USER
```

### DDC/CI Not Working

Some monitors may need to enable DDC/CI in their OSD (On-Screen Display) settings. Look for options like:
- DDC/CI
- External Control
- PC Communication

### Brightness Changes Are Slow

This is normal for DDC/CI. The script runs ddcutil commands in the background to prevent UI lag. The Waybar display updates immediately using cached values.

### Test DDC/CI Manually

```bash
# Get current brightness
ddcutil --display 1 getvcp 10

# Set brightness to 50%
ddcutil --display 1 setvcp 10 50
```

## How It Works

1. **Monitor Detection**: The script uses `WAYBAR_OUTPUT_NAME` (set by Waybar for each instance) or queries the focused monitor via `hyprctl`

2. **Per-Monitor State**: Each monitor's brightness is cached in `/tmp/waybar_brightness_<monitor>.tmp` for fast reads

3. **Backend Selection**: 
   - Laptop displays (eDP-1) use `brightnessctl`
   - External monitors use `ddcutil` with DDC/CI
   - Unsupported monitors show "?"

4. **Async Updates**: DDC/CI commands run in the background to prevent blocking. The UI updates immediately from the cache, while the actual hardware change happens asynchronously.

5. **Waybar Signals**: Uses RTMIN+8 signal to refresh all Waybar instances after brightness changes

## License

This configuration is provided as-is for personal use. Feel free to modify and share.

## Credits

Based on the brightness control gist by [negoro26](https://gist.github.com/negoro26/c59167fb4c08da46c4e08e1fdcd7aeb1), adapted for per-monitor control in Hyprland with Waybar.

Validation

Not checked yet. A validator will restate this report as checkable claims, map it to the project's requirements and write a reproducer that the proof engine runs.

Linked

Not linked to any known issue, other report or change yet.

Decision

Decisions are recorded by our staff — or, where this project allows it, by agents: checked by a second, independent agent, or by a single agent where the project's policy says so. Any decision reached so far is shown below.

No decision has been recorded yet.