Dimming rework
I started with code, but the topic has a bunch of considerations and it's worth jotting them down in a big-picture issue.
Why the need
In a nutshell: dimming and similar brightness adjustments are currently writing a lower brightness value into firmware storage, before sometimes losing track of the display and then using the lower value as a new baseline. PowerDevil (at least on X11) does not support config file persistence for brightness values, so it relies on firmware brightness. This causes a number of related bugs:
-
BUG: 452492 (dimming) - external monitor dims, then disappears. Brightness is not restored when it comes back.
- Will happen in a number of scenarios including system sleep, DMPS sleep, monitor disconnection, etc.
- BUG: 484663 (change screen brightness) - switching to power profile lowers brightness. Brightness is not restored when switching back.
On Wayland, KWin does have its own storage of brightness values, but does not currently have a separate API for dimming / temporary non-persisted brightness limits. Hence, even with brightness value persistence, we will still store the lower values which PowerDevil will use as incorrect baseline next time.
The recent per-display brightness control work for 6.2 exacerbates these issues for KWin users, because brightness changes now apply to all monitors as opposed to just the internal laptop screen for most users. (Users that only had external monitors before will continue to see these problems too, but aren't regressing.)
The goal of this issue is to define the API concept for PowerDevil actions (maybe later also for D-Bus clients) with PowerDevil's ScreenBrightnessController
, and based on this to define the more distilled API that ScreenBrightnessController
uses to communicate to KWin/Wayland. It would be nice if we can solve dimming persistence bugs not just on Wayland, but also on X11 where KWin is not involved.
Requirements
Here are some current and future use cases that need to be supported (or otherwise migrated).
Use Case | Implemented | Value | Condition | Screens affected | Challenges |
---|---|---|---|---|---|
Dimming on inactivity | Yes, poorly (DimDisplay ) |
Relative to current brightness | KIdleTime timeout & resume (on by default) | All screens (probably) | Restore after disappearance |
Change brightness per profile (KCM) | Yes, poorly (BrightnessControl ) |
Relative to max brightness | Power state entered (default 30% on Low Battery, nil otherwise) | Legacy display set? [1] see !420 (merged) | Undo change after leaving power state (e.g. plugging in) |
Automatic brightness via ambient light sensor (#21) | Draft MRs exist (!199, kwin!5876) | Relative to current brightness, absolute limit value, or some function combining both | Always | All screens (probably), but some may use different limits | Sensor/brightness mapping; co-existence with other dimming methods |
Dim other screens when game/video/etc. goes fullscreen | No | Relative to current brightness | Window goes fullscreen, has focus & is active screen | All screens apart from the main one | Some info only available to KWin; distinguish between full-attention app vs. simply maximizing screen estate |
[1] Ideally we'll want to re-interpret the profile-based brightness change setting as a temporary brightness limiter for the given power state, rather than a one-off setter. Having an existing config value based on max percentage complicates this: 30% of laptop screen brightness is not the same as 30% of external monitor brightness. So it makes little sense to apply one value to all screens. Ideally I'd like to make this into a per-screen setting, but we have to deal with the current config somehow and I think the legacy display set (internal display if exists, all external monitors otherwise) is the least bad option.