Powerdevil is (re)setting my display brightness after the display wakes up

I’ve noticed a new behavior since I updated my Manjaro system, I’m now running KDE/powerdevil version 6.1.5-1 (previously was running 6.0.5-1).

My system:

  • Manjaro Linux on x86_64, Intel CPU with built-in Intel graphics.
  • Two AOC displays connected over DisplayPort.

How to reproduce:

  • Use either vdu_controls or midi-pipewire-volume to change the screen brightness/constrast.
  • Lock the screen, then press ESC to let the screens turn off (i.e. enter power-saving mode). This usually happens automatically and I take a bathroom break or go grab a snack.
  • Come back, move the mouse and interact with the keyboard, to wake up the displays.
  • BUG: I notice the screen brightness changes as the displays turn back on.
  • After I unlock the system, I see the brightness was reset to the value that “Brightness and Color” widget had. Note that I didn’t touch that widget at all during this whole process. In fact, I even forgot this tray icon even existed.

The same happens when the displays switch the video input, which also happens very often, given I have two computers (one laptop, one desktop) connected to these displays.

Thus, I believe somehow the event of “display being connected/awake/available” triggers some handling that decides to (re)set the brightness to some arbitrary value.

I’m pretty sure this is related to powerdevil, as I can see these in the Journal:

08/10/2024 19:13	org_kde_powerdevil	Emitting DDCA_Display_Status_Event( 122908.696:  DDCA_EVENT_DPMS_ASLEEP, card1-DP-1, dref: Display_Ref[bus /dev/i2c-3], io_path:/dev/i2c-3]
08/10/2024 19:13	org_kde_powerdevil	Executed 1 registered callbacks.
08/10/2024 19:13	org_kde_powerdevil	Emitting DDCA_Display_Status_Event( 122908.696:  DDCA_EVENT_DPMS_ASLEEP, card1-DP-2, dref: Display_Ref[bus /dev/i2c-4], io_path:/dev/i2c-4]
08/10/2024 19:13	org_kde_powerdevil	Executed 1 registered callbacks.
08/10/2024 19:13	kscreenlocker_greet	pam_systemd_home(kde:auth): New sd-bus connection (system-bus-pam-systemd-home-366234) opened.
08/10/2024 19:13	org_kde_powerdevil	Emitting DDCA_Display_Status_Event( 122910.699:  DDCA_EVENT_DPMS_AWAKE, card1-DP-1, dref: Display_Ref[bus /dev/i2c-3], io_path:/dev/i2c-3]
08/10/2024 19:13	org_kde_powerdevil	Executed 1 registered callbacks.
08/10/2024 19:13	org_kde_powerdevil	Emitting DDCA_Display_Status_Event( 122910.699:  DDCA_EVENT_DPMS_AWAKE, card1-DP-2, dref: Display_Ref[bus /dev/i2c-4], io_path:/dev/i2c-4]
08/10/2024 19:13	org_kde_powerdevil	Executed 1 registered callbacks.
08/10/2024 19:13	org_kde_powerdevil	dh=Display_Handle[i2c-3: fd=129], Replacing adjusted sleep multiplier 0.10 with 1.00 for SE_POST_WRITE or SE_POST_SAVE_SETTINGS
08/10/2024 19:13	org_kde_powerdevil	dh=Display_Handle[i2c-4: fd=129], Replacing adjusted sleep multiplier 0.10 with 1.00 for SE_POST_WRITE or SE_POST_SAVE_SETTINGS

I initially thought this was a bug in vdu_controls, but then was pointed to another discussion. I believe @jpetso will be interested in this subject, as he has been making commits to powerdevil.

Yes, I’ve already checked Power Management → Display Brightness → Dim Automatically, it’s already off.

image

3 Likes

Yes, you may be right. I dug into the code to figure out which part would be responsible for (re)setting the brightness, and I believe it’s DDCutilDisplay::resumeWorker(), specific to ddcutil support. This is called in response to ddcutil’s DDCA_EVENT_DPMS_AWAKE event. The timer that’s started in resumeWorker() will end up writing the brightness at the currently configured level.

Please try out running PowerDevil with POWERDEVIL_NO_DDCUTIL=1, as described in the README. This may end up being a permanent solution for your use case.

The bigger question is what should be done about this, assuming my reading is correct. We could of course simply take out the brightness setter from resumeWorker(), although I think this isn’t desirable for most use cases. @Zamundaaa argued that KWin/PowerDevil should always be in control of screen brightness, which I have yet to respond to. I think desktop-independent tooling such as midi-pipewire-volume are a good example of why we should strive to co-exist with other brightness setter tools that use ddcutil directly instead of our new org.kde.ScreenBrightness interface.

Either way, we should try to figure out a way forward. Thanks for bringing this to my attention. (That said, this thread should have still been a bug on Bugzilla imho.)

1 Like

(I wasn’t sure if I should report as a bug or just report as a question in the forum. I wasn’t sure if this was actually a bug or not.)

There are two use-cases that seem to trigger this bug:

Case 1: same system

On the same system, some tool changes the brightness. It could be my own midi-pipewire-volume or the well known vdu_controls. It could be done for a variety of reasons:

  • A tool that calculates the absolute brightness value based on some input control (e.g. a MIDI slider).
  • A tool that calculates the absolute brightness value based on the time of the day.
  • A tool that calculates the absolute brightness value based on some ambient light sensor.
  • A tool that uses ddcutil directly because it changes more settings beyond just the brightness.
  • A keyboard shortcut that directly calls a shell script or some command-line tool.
  • etc.

One could argue that such use-cases could be rewritten to talk to KDE daemon instead of using ddcutil directly, but that restricts such tools to just KDE, while we all know Linux embraces several desktop environments.

Maybe KDE could provide a ddcutil wrapper that would notify KDE itself and then forward to ddcutil, but that sounds like something that will cause a lot of bugs and confusion.

Case 2: two systems or external factors

The user could use the display buttons to manually change the brightness. That’s been a thing since forever: all monitors have buttons and an OSD menu for various display settings, and it works regardless of what system is connected to the display.

In this case, KDE wouldn’t be notified of brightness changes, as they happened outside the computer itself.

Alternatively, a user could switch between to video inputs (computer A and computer B). While on one video input, the user decides to change the brightness (because the room is too bright or too dark). Then, the user switches to another video input, and gets surprised that the brightness has changed. No only that, but returning to the first video input won’t restore the brightness. (In other words, brightness setting is global; it is NOT scoped to each video input.)

In this case, KDE can’t be notified of brightness changes either, as they were triggered by a different system.

Conclusion

Based on these observations, I believe KDE should not try to restore the brightness. It doesn’t seem to make sense. (And personally I don’t yet see what problem it solves.)

The desire to always be in control of the screen brightness is, frankly, impossible, as the brightness can change due to external factors. In fact, KDE should just react (i.e. read) any brightness change and update its own state. (In other words, instead of forcing KDE state onto the display, KDE state should reflect the display state.)


Setting POWERDEVIL_NO_DDCUTIL=1 according to the README instructions worked for me. I lose the ability to change brightness from within the KDE system tray, but in practice I never use it anyway. Seems to be a good enough workaround, thank you!

2 Likes

How’s that going to work with monitors that have ambient light sensors and that control their own brightness? Will that work if I use my monitor’s own menu to switch it into Cinema mode?

I have, on Plasma 6.2, set
Power Management → Display Brightness → Dim Automatically
and just noticed that after not a system Wake Up (no screen-lock and or screen turn-off) just a “Wake Up” from that dimming the Displays are not set back to their previous individual settings but to the setting of the first slider.

In opposite to @denilsonsa problem, that always worked and was no issue for me with Plasma 6.1.x as there was only a Brightness control for one Monitor, now with Plasma 6.2 and two external Monitors connected there are 3 sliders, one for each, set to different values.

This is a different issue and fixed in Plasma 6.2.1. Sorry for not being able to get the fix into the initial 6.2.0 release.

2 Likes

Thanks guys for your feedback. I’m inclined to remove the restore-brightness-on-display-wake code. I think doing it right would entail more than just ripping out that one line, I’ll try destroying the whole DisplayBrightness object instead while the monitor is asleep.

Here’s the thing. The monitor doesn’t tell us when it changed its brightness, or why.

  • If the monitor doesn’t remember brightness across reboots, which is the case for some monitors, then we should reset it to what the user had previously configured.
  • If I switch to a different user session and the screen dims, brightness is now lower but instead of using that as the new baseline, we should reset it to the regular non-dimmed state.
  • If my partner was borrowing the monitor and adjusted its brightness to match her laptop brightness, it’s not an outlandish thought to reset it to what I had previously set up and working for my own system.

As anyone who has worked with reactive frameworks can attest to, two-way bindings introduce a whole bunch of complexity (i.e. bugs) and we have to consider carefully whether there really isn’t any other option. Especially given that I’ll have to make an argument toward KWin developers who are already dealing with a very complex system and are therefore wary of adding even more complexity.

Note that in all of these cases, Plasma won’t be able to tell if the brightness change is meant to be a temporary dimming-like action or if the user wanted a permanent change. The external tool also won’t know if the current reading is temporarily transformed or permanent. As soon as one of these tools interacts with Plasma’s internal brightness behaviors, something is bound to break in more or less subtle ways.

So my thinking is that either Plasma owns screen brightness, or Plasma disables brightness controls entirely lets the external tooling figure it out. Similar to how the Power and Battery applet can coexist with TLP by simply keeping out of the way. The awkward middle ground is where confusion and bug reports breed. We may have to react to external brightness changes anyway, out of necessity, but ideally let’s try to keep this to a manageable level of complexity.

The KWin model is that it owns all display-related state, including brightness. My gripe with it is that it’s all or nothing. I would like the user to be able to control per monitor whether or not Plasma and KWin should be involved. Imho we really need to bring this kind of setting into the Display Configuration settings page.

The PowerDevil-without-KWin-Wayland model is that Plasma owns screen brightness while the service is active, but it won’t persist any changes. At your next session login, it will continue from whichever changes you’ve made.

What I am not interested in is Plasma brightness controls being a tool to fire one-off commands. If Plasma handles brightness for a given screen then it should manage the full experience in a comprehensive, context-aware, sometimes automatic, way. From manual slider controls to dimming (or ambient light sensor adjustments) to restoring brightness across sessions. Using hardware or software brightness controls where it makes the most sense, automatically. Users who just want to send commands should disable Plasma brightness controls (once we provide that option) and use vdu_controls instead.

In order to make all the features interact cleanly, we need more context than the single ddcutil brightness value will give us. A Wayland or D-Bus protocol can eventually provide enough context, although it still needs additions to do the best possible job.

Sorry for rambling. Still pondering about how best to proceed from here.

I have a monitor with ambient light sensor that controls its own brightness. It simply ignores any incoming brightness commands. I can’t guarantee that this is the case for all monitors, that’s just the one data point I have available.

2 Likes

Yes, I know the monitor doesn’t tell the system that the brightness has changed. So, the only way (that I can see) in which KDE/Powerdevil/KWin can know if the value has changed is by polling the display at some interval. Maybe every minute is good enough.

Definitely not perfect, but probably good enough. If KDE did that, it would very likely detect the brightness changes I’ve done before the display went asleep, and thus upon waking up it would not reset the value to any arbitrary amount, but instead to my previously set amount.


By the way, I really appreciate the thought and care put into the project. I don’t mind the rant, it gave me some insight on other use-cases and on additional concerns from you.


As a sidenote, vdu_controls 2.1.0 is now reading the value from the display before setting it (when restoring a preset), just to avoid unnecessary writes.

1 Like

Because of the reasons @jpetso already explained, unless we can notice the user intentionally changing the setting with the display controls, it’s not really feasible to do that without causing tons of bugs.

It would certainly be a better UX to react to the user doing things on the monitor OSD though; maybe we can figure out some heuristics for when the user’s intentionally doing it, like for example poll the setting often and when it changes, check that

  • the display has been on for x seconds
  • we’ve already restored the setting
  • we don’t have any dimming applied at the moment
  • (if we can detect it) that the display’s OSD is currently open
  • (ideally also) the source is set to our PC

and only if all conditions apply, change our setting to match the display.

Of course there’s a pretty high chance it could still cause new bugs and regressions, so this kind of thing needs to be approached with care. For example I recall that interacting with DDC can cause performance issues on some NVidia cards, so even just polling the display setting regularly might cause problems.

It’s the same with my TV. I would expect a screen with an ALS to either

  • not support external brightness control
  • multiply the manual setting with the automatic thing
  • just provide the sensor to the OS and have it figure things out instead

Can’t say I’ve seen any do 2 or 3 yet either.

What ever you decide to do, it would be great if the user could easily tell that some automated brightness adjustments are in play. Perhaps some symbol in the panel beyond just the brightness symbol (maybe add a A(uto) superscript/subscript). Plus add a single setting that turns any automatic adjustments off.

Subsequent to KDE6, I’m now seeing quite few posts here and on other forums, questioning why monitor brightness is changing after reboots, power-cycling, or DPMS-sleep. I’ve even had one bug raised against vdu_controls. In some/many cases this may not be due to KDE6, but having a simple on/off switch would help with narrowing down causes.

Lastly, I’m unclear how these automated adjustments might affect professionals with calibration-equipment and carefully calibrated displays. Is there any risk such monitors could be moved off their calibrated settings?

5 Likes

Even with powerdevil 6.2.1-1 the system overrides my manual brightness settings on the monitors after powersaving or sometimes without any reason i am able to understand.
When i set the brightness in plasma, the problem appears that my 2nd monitor is also adjusted althogh it doesnt support brightness control - so a kind of grey layer is applied.
This is not a serious method. Calibrated colors and contrast a no longer valid.

2 Likes

To add one to this, that this is particularly bad in Wayland session.

I’ve commented in another thread before I’ve discovered this one - that now my external screen brightness is (more or less) being set at random on each screen wake up and there is not a place i can either turn off the brightness control or disable this behavior, resulting in either extremely dim monitor or full brightness blasting to my face.

this is happening both on my laptop and desktop.

1 Like

I’m not exactly sure how I have disabled this, but I have. Probably one of the following:

  • Under the KDE System Settings, Power Management, I have disabled Display and Brightness, Dim automatically.
  • I have disabled the brightness control in the system tray. The tray popup includes a configuration button on the top right, which brings up System tray settings. In that open the Entries item, scroll down and disable Brightness and Color.
  • In the KDE Background Services application I have disabled KScreen 2.

I’m pretty sure the first one on the list was needed to stop dimming after I upgraded to KDE6. But the others may be also contributing.

1 Like

Thanks! Gonna try it out later :wink:
I’ve done the first already but it has no effect, will try 2 and 3

If 2 and 3 don’t help, it could also be something specific to the Tumbleweed build that is contributing to my success.

As mentioned by jpetso, setting POWERDEVIL_NO_DDCUTIL=1 according to the README instructions worked for me. The systray widget doesn’t have the brightness slider anymore, and KDE Plasma hasn’t changed the brightness ever since.

2 Likes

Hello,

I am an EndeavourOS KDE user who recently faced this issue of screen brightness getting reset on wakeup from sleep. I see a similar report here: https://discuss.kde.org/t/wayland-rest-external-screen-brightness/23960

When I used a laptop, for a long time I wanted something like this, setting brightness through a slider in the panel, I remember setting acpi_backlight kernel parameter to make it work. However, I am not a laptop person anymore, and I use a desktop with multiple monitors. In such a use case where I calibrate my monitors with their OSD controls, the last thing I want is one of my OSes (I have multi-boot system) changing the monitor’s variables, even if it is just one, i.e. Brightness, which I have verified using gddccontrol (it is the only variable that gets changed because of this issue).

In one of my monitors, the OSD controls buttons do not work anymore. The monitor works fine otherwise. in such a setup, this new feature is actually a regression as I needed to open gddccontrol and change the brightness level back every time the PC woke from sleep.

I have set ‘Dim automatically’ to ‘Never’ in Power Management UI, but this did not resolve the issue. I don’t seem to have plasma-powerdevil.service in my system, so the env var solution did not work either.

Funnily enough, the solution was to simply use the new slider in Brightness and Color applet to set the brightness to value I had (set earlier through ddccontrol), which resolved the issue and persisted reboots too.

I would still like this new “feature” to be removed or at least put behind a checkbox in power settings UI, as proposed by jpesto above. Because

  1. Not all Linux users use laptops, and monitors have their own OSD controls for much better fine tuning.
  2. In general, hardware variables should not be changed by OS that persists reboots. It is anti pattern. Even tools like Ryzen Master does not do it by default.
  3. Brightness/ Contrast is a health emergency for many of us who cannot stare at bright screens for long. Lets not introduce regression here in the name of new feature.

Again, a simple checkbox to disable it is all we need to satisfy both camps.

Thanks,

1 Like

Thank sCarles_Rufus - using the Brightness and Color applet does seems to address the issue - before this for the most part i was running other desktop env to mitigate this issue

I agree that at the very least this needs to be behind a checkbox :slight_smile:, or the brightness tool to respect the setting I’ve made either via hardware control, or in another system.

The last thing i want is that a change i’ve made through one system gets overwritten and i’d need to repeat it for every other device/system pair i own.
(to put in perspective i have 3 device and 5 systems to work with, 2 of them are on dual boot)

might be a niche situation, but i’d imagine its not uncommon to dual boot for people working with linux