https://bugs.kde.org/show_bug.cgi?id=523402

            Bug ID: 523402
           Summary: Keyboard backlight sometimes remains at 0 after resume
    Classification: Plasma
           Product: plasmashell
      Version First 6.7.3
       Reported In:
          Platform: Arch Linux
                OS: Linux
            Status: REPORTED
          Severity: normal
          Priority: NOR
         Component: Power management & brightness
          Assignee: [email protected]
          Reporter: [email protected]
  Target Milestone: 1.0

DESCRIPTION

On my ASUS ROG Flow X16 GV601VV, the keyboard backlight sometimes stays off
after resuming from suspend.

Before suspend, the brightness is normally 2 out of 3. After resume, it is
sometimes 0 and is not restored automatically. The brightness keys still work
and setting a non-zero value turns the backlight on immediately, so the
keyboard and the kernel brightness interface are still working.

The keyboard backlight is exposed by UPower at
`/org/freedesktop/UPower/KbdBacklight` and by the kernel at
`/sys/class/leds/asus::kbd_backlight`.

STEPS TO REPRODUCE

1. Set the keyboard backlight brightness to 2 out of 3.
2. Suspend the laptop from Plasma.
3. Resume the laptop and unlock the session.
4. Check the keyboard backlight.

OBSERVED RESULT

The keyboard backlight sometimes remains at 0 after resume. It stays off until
I increase the brightness manually.

EXPECTED RESULT

PowerDevil should restore the brightness that was active immediately before
suspend. If the keyboard backlight was already at 0 before suspend, it should
remain off.

POSSIBLE CAUSE

I looked at the PowerDevil 6.7.3 implementation and found a state-handling
issue that appears to match this behavior:

https://invent.kde.org/plasma/powerdevil/-/blob/v6.7.3/daemon/actions/bundled/keyboardbrightnesscontrol.cpp

`m_lastKeyboardBrightness` starts at `-1`. The current brightness read during
controller initialization does not appear to initialize this member.

Later, `onBrightnessChangedFromController()` stores every reported brightness
in `m_lastKeyboardBrightness`, including 0. If a temporary value of 0 is
reported or requested during the suspend transition, it replaces the previous
non-zero value.

The `resumeFromSuspend` handler restores the backlight only when
`m_lastKeyboardBrightness > 0`. If the value was never initialized, or was
replaced with the suspend value 0, nothing is restored after resume.

I also checked the keyboard backlight implementation in the exact Linux 7.1.4
driver used on this system:

https://github.com/gregkh/linux/blob/v7.1.4/drivers/platform/x86/asus-wmi.c

The `asus::kbd_backlight` LED is registered with `LED_BRIGHT_HW_CHANGED`, but
not `LED_CORE_SUSPENDRESUME`, so the LED core does not automatically set it to
0 during suspend. The ASUS WMI driver also does not have a suspend callback
that sets keyboard brightness to 0. Instead, `asus_hotk_resume()` calls
`kbd_led_update()` to reapply its cached brightness after resume.

This makes the kernel driver unlikely to be the original source of the
persistent 0. However, if UPower writes 0 before suspend, the driver correctly
stores 0 in its own cache and then reapplies that same 0 on resume.

UPower distinguishes these cases: a hardware change is emitted as
`BrightnessChangedWithSource(..., "internal")`, while a `SetBrightness(0)`
method call is an external userspace request. The value of 0 observed during
diagnosis was sent through `SetBrightness(0)`, not generated as a driver
notification.

The likely failure sequence is therefore:

1. The keyboard brightness is 2 before suspend.
2. A userspace brightness action sends 0 through UPower during the suspend
transition.
3. Both the driver cache and PowerDevil's `m_lastKeyboardBrightness` become 0.
4. On resume, the driver reapplies its cached 0 and PowerDevil does not restore
anything because its saved value is no longer greater than 0.

A possible fix would be to keep a separate pre-suspend value:

1. Read the current keyboard brightness when
`SuspendController::aboutToSuspend` is emitted.
2. Store it in a dedicated member that is not changed by brightness
notifications during suspend.
3. Restore that value on `resumeFromSuspend` when it is greater than 0.

This would also preserve intentional behavior: if the user turned the keyboard
backlight off before suspend, the saved value would be 0 and it would remain
off after resume.

This looks related to bug 489056. In comment 15, the remaining case where the
controls work but the brightness is 0 after wake was considered a separate
issue:

https://bugs.kde.org/show_bug.cgi?id=489056#c15

SOFTWARE/OS VERSIONS

Operating System: Artix Linux
KDE Plasma Version: 6.7.3
KDE Frameworks Version: 6.28.0
Qt Version: 6.11.1
Kernel Version: 7.1.4-artix1-1 (64-bit)
Graphics Platform: Wayland

ADDITIONAL INFORMATION

Laptop: ASUS ROG Flow X16 GV601VV
Keyboard backlight driver: `asus-nb-wmi`
Keyboard brightness range: 0-3

-- 
You are receiving this mail because:
You are watching all bug changes.

Reply via email to