Plasma 6.2 brightness control

I like that we can now set the brightness level separately for multiple monitors. Great addition imo.

But if I press the function keys, I would like them to change the brightness only on the monitor where my cursor is located. When I use the brightness control on my keyboard, it changes the brightness on both monitors simultaneously.

image

I’m not aware of any settings where this could be changed. Is it only me who would like this addition? An extra tick somewhere in the settings for this?

Sorry, I didn’t manage to implement different brightness key behaviors for Plasma 6.2. It hasn’t been straightforward to associate the active screen with hardware brightness controls, and also the consensus in code review was that adjusting all screens is a good default.

I am interested in adding functionality to let users configure the behavior of the brightness key (and applet scrolling). Do you have any thoughts on how you would like the configuration interface to work?

1 Like

I guess the current behaviour is good as a default.

My mind just got tinkering, since back when I had a MacBook, I could change the brightness controls separately for the two monitors, but the brightness controls from the keyboard (or touchbar) worked only on the active monitor. And I quite liked it that way.

I did have to install a third party tool called MonitorControl for it.

So like in KDE, there was an icon in the system tray where I could adjust per monitor with a slider, but In the settings there was an option to choose what display did the keyboard setting apply to (“Screen to control”).

There was also a setting called “Sync brightness changes from Built-in and Apple displays” - “Changes that are caused by the Ambient light sensor or made using Touch Bar, Control Center, System Preferences will be replicated to all displays”. If I recall correctly, by unticking that option I was able to set it so the touchbar made changes only to the active monitor.

The settings layout can be seen on their GitHub page for reference.

For me personally, something similar being present in KDE would be very nice.

1 Like

I’d also like this feature, here’s something similar from BetterDisplay on Mac.

For now I rebound my brightness keys to this script (AI slop warning)

#!/bin/bash
# usage: ./smart_brightness.sh up
#        ./smart_brightness.sh down

DIRECTION=$1
STEP_PERCENT=5

# 0. STRICT INPUT VALIDATION
if [[ "$DIRECTION" != "up" && "$DIRECTION" != "down" ]]; then
    echo "Error: Invalid argument. Use 'up' or 'down'." >&2
    exit 1
fi

ACTIVE_OUTPUT=$(qdbus6 org.kde.KWin /KWin activeOutputName 2>/dev/null)
DISPLAYS=$(qdbus6 org.kde.ScreenBrightness /org/kde/ScreenBrightness DisplaysDBusNames 2>/dev/null)

if [[ -z "$DISPLAYS" ]]; then
    echo "Error: No displays found via org.kde.ScreenBrightness." >&2
    exit 1
fi

# Helper function to grab properties using the modern freedesktop standard
get_display_prop() {
    local disp=$1
    local prop=$2
    qdbus6 org.kde.ScreenBrightness "/org/kde/ScreenBrightness/$disp" org.freedesktop.DBus.Properties.Get org.kde.ScreenBrightness.Display "$prop" 2>/dev/null
}

TARGET_DISPLAY=""

# 1. DYNAMICALLY MAP THE ACTIVE MONITOR
if [[ "$ACTIVE_OUTPUT" == eDP* ]] || [[ "$ACTIVE_OUTPUT" == LVDS* ]]; then
    # If it's the laptop screen, just look for the internal display tag
    for disp in $DISPLAYS; do
        if [[ "$(get_display_prop "$disp" "IsInternal")" == "true" ]]; then
            TARGET_DISPLAY=$disp
            break
        fi
    done
elif [[ -n "$ACTIVE_OUTPUT" ]]; then
    # If it's an external monitor, cross-reference the D-Bus Label with the kernel's raw EDID
    EDID_FILE=$(ls /sys/class/drm/*-"$ACTIVE_OUTPUT"/edid 2>/dev/null | head -n 1)

    BEST_MATCH=""
    HIGHEST_SCORE=0

    # Pre-process EDID to extract only printable text (avoids binary grep weirdness)
    EDID_TEXT=""
    if [[ -f "$EDID_FILE" ]]; then
        EDID_TEXT=$(tr -cd '[:print:]' < "$EDID_FILE")
    fi

    for disp in $DISPLAYS; do
        if [[ "$(get_display_prop "$disp" "IsInternal")" == "true" ]]; then continue; fi

        LABEL=$(get_display_prop "$disp" "Label")
        if [[ -n "$LABEL" && -n "$EDID_TEXT" ]]; then
            # Split the label into an array
            read -ra WORDS <<< "$LABEL"
            NUM_WORDS=${#WORDS[@]}
            SUBSTRING=""
            CURRENT_MATCH_LEN=0

            # Start from the last word and prepend leftward
            for (( i=$NUM_WORDS-1; i>=0; i-- )); do
                if [[ -z "$SUBSTRING" ]]; then
                    SUBSTRING="${WORDS[$i]}"
                else
                    SUBSTRING="${WORDS[$i]} $SUBSTRING"
                fi

                # If this contiguous substring exists in the EDID, update our length score
                if echo "$EDID_TEXT" | grep -i -q "$SUBSTRING"; then
                    CURRENT_MATCH_LEN=${#SUBSTRING}
                else
                    # If a smaller right-hand substring doesn't match, prepending to it won't match either
                    break
                fi
            done

            # Keep track of the display with the longest matching substring
            if [[ "$CURRENT_MATCH_LEN" -gt "$HIGHEST_SCORE" ]]; then
                HIGHEST_SCORE=$CURRENT_MATCH_LEN
                BEST_MATCH=$disp
            fi
        fi
    done

    # If we got at least one valid length match, assign it
    if [[ "$HIGHEST_SCORE" -gt 0 ]]; then
        TARGET_DISPLAY=$BEST_MATCH
    fi
fi

if [[ -z "$TARGET_DISPLAY" ]]; then
    echo "Error: Could not map active output ($ACTIVE_OUTPUT) to a valid D-Bus display." >&2
    exit 1
fi

# 2. GET CURRENT AND MAX BRIGHTNESS
CURRENT=$(get_display_prop "$TARGET_DISPLAY" "Brightness")
MAX=$(get_display_prop "$TARGET_DISPLAY" "MaxBrightness")

if [[ -z "$CURRENT" ]] || [[ -z "$MAX" ]]; then
    echo "Error: Failed to fetch Brightness or MaxBrightness for $TARGET_DISPLAY." >&2
    exit 1
fi

# 3. CALCULATE STEP
STEP=$(( MAX * STEP_PERCENT / 100 ))
if [[ "$STEP" -eq 0 ]]; then STEP=1; fi

# 4. CALCULATE NEW VALUE
if [[ "$DIRECTION" == "up" ]]; then
    NEW_VAL=$((CURRENT + STEP))
else
    NEW_VAL=$((CURRENT - STEP))
fi

# 5. KEEP WITHIN HARDWARE LIMITS
if [[ "$NEW_VAL" -lt 0 ]]; then NEW_VAL=0; fi
if [[ "$NEW_VAL" -gt "$MAX" ]]; then NEW_VAL=$MAX; fi

# 6. APPLY BRIGHTNESS (0 = show OSD, 1 = silent)
qdbus6 org.kde.ScreenBrightness "/org/kde/ScreenBrightness/$TARGET_DISPLAY" org.kde.ScreenBrightness.Display.SetBrightness "$NEW_VAL" 0

When I had my 27 external monitor, there was a slider for the laptop screen and the external monitor, but now that my external is a 45inch ultra wide there is no slider for it. Only the laptop screen shows.