SUMMARY PowerDevil does not respect a user's request to prevent a laptop from going to sleep due to a lid switch action, using the `systemd-inhibit` command with the `--what=handle-lid-switch` option This issue was originally reported as a Bug #457859 comment #2 and was moved to a new ticket at the request of developers. STEPS TO REPRODUCE 1. Under _Energy Saving_ make sure the "When laptop lid closed" [sic] option for the current power state is set to "sleep". 2. Open a terminal and run `systemd-inhibit --what=handle-lid-switch --who=test --why=coz sleep infinity` 3. Close the laptop lid OBSERVED RESULT The laptop goes to sleep EXPECTED RESULT The laptop will not go to sleep SOFTWARE/OS VERSIONS Operating System: KDE neon Testing Edition KDE Plasma Version: 6.0.4 KDE Frameworks Version: 6.2.0 Qt Version: 6.7.0 Kernel Version: 6.5.0-27-generic (64-bit) Graphics Platform: Wayland Processors: 20 × 12th Gen Intel® Core™ i7-12700H Memory: 31.0 GiB of RAM Graphics Processor: Mesa Intel® Graphics ADDITIONAL INFORMATION The default systemd behavior can be achieved by stopping PowerDevil (for example using `systemctl --user stop plasma-powerdevil.service`), after which closing the lid without inhibition causes the laptop to sleep while with the above inhibition command the laptop will not sleep on lid close. When using `sudo` to run `systemd-inhibit`, PowerDevil will still attempt to put the laptop to sleep but it will first request authorization using a policykit dialog, and as the laptop lid is closed this authorization request will go unanswered and the laptop will not sleep, but its not really a good workaround due to requiring authorization to start and having an unexpected authorization dialog when opening the lid. Natalie Clarius in Bug #457859 comment #13 has opined that the behavior reported in this ticket is probably the desired behavior in order to prevent users from making mistakes - to which I will answer that having APIs to let users do things is all about letting users make their own mistakes, see `rm -rf /` - it is a legit operation a user is allowed to issue. Furthermore, I will contend the `systemd-inhibit --what=handle-lid-switch` is a real API with good use cases that is implemented and supported by various systems and environments and PowerDevil should not disable it.
I'll mark this as confirmed. Natalie's opinion in Bug 457859 comment #13 regarded the "sleep" and "idle" inhibitors, which thankfully you've left out of this bug report so the comment doesn't apply here. In a series of comments from Bug 457859 comment #5 to Bug 457859 comment #10, I fumbled my way toward a possible approach for fixing this. The current interfaces provided by systemd make it difficult to handle this correctly without polling, so I submitted https://github.com/systemd/systemd/issues/32196 to ask for interface improvements. With polling, it would still be possible right now to implement "handle-lid-switch" inhibitors somewhat correctly. Summarizing my comments from the other bug, we would want to do something like this: * Add an extra enum value for lid-switch inhibition to PolicyAgent::RequiredPolicy. * In PolicyAgent::checkLogindInhibitions(), check to see if any "handle-lid-switch" inhibitors other than PowerDevil's own inhibitor are active at the time of lid closure. Set the policy if this is the case. * Make PolicyAgent aware of the current lid switch state. Probably by adding a method PolicyAgent::setLidClosed(bool) to be called from HandleButtonEvents::onLidClosedChanged(). * When the lid is closed, manually call PolicyAgent::checkLogindInhibitions() to get the latest state of non-PowerDevil "handle-lid-switch" inhibitors, because systemd won't notify us of changes unless we can get the aforementioned interface improvements. * In HandleButtonEvents::onLidClosedChanged(), after policies are updated, replace any configured action with a "DPMS off" in case we have a "handle-lid-switch" inhibitor present. Ensure we always either suspend or turn off the screen when the lid is closed, and always turn the screen back when the lid is opened again. * In the absence of observable inhibitor change signals from systemd, if an inhibitor was present on lid closure, add a polling timer to periodically call PolicyAgent::checkLogindInhibitions() as long as the lid is still closed. Stop polling when the lid gets opened again. * Execute the suspend action if the lid-switch inhibitor policy disappears while the lid is still closed. This approximate approach should make "handle-lid-switch" inhibitors work as expected.
(In reply to Jakob Petsovits from comment #1) > * In the absence of observable inhibitor change signals from systemd, if an > inhibitor was present on lid closure, add a polling timer to periodically > call PolicyAgent::checkLogindInhibitions() as long as the lid is still > closed. Stop polling when the lid gets opened again. > > * Execute the suspend action if the lid-switch inhibitor policy disappears > while the lid is still closed. This is an important behavior - thanks for noting that. I've also failed to identify a way to implement this behavior without polling - and "polling sometimes" is even worse than "polling all the time". If that is the case, and as long as the systemd-logind RFE has not been rejected - maybe waiting for systemd-logind support is the right choice. In the mean time - maybe it is possible to implement a PowerDevil setting of "don't inhibit lid-switch and let systemd-logind handle lid switch"?
Created attachment 168638 [details] Mockup for PowerDevil lid-switch handle by systemd Maybe adding an "According to system configuration" option to the lid switch behavior selection. When switching to a policy where this is selected, PowerDevil will stop inhibiting lid-switch.
This is still an issue in Plasma 6.1.2. Is there a fix or workaround out there?
Found a workaround / fix. Lot's of stuff on the web about settings in .config/powerdevilrc (or the same file .config/powermanagementprofilesrc), and logind.conf in /etc. None of this worked. It's a setting in .config/kwinoutputconfig.json, but I don't know which one. Creating a new user and closing the lid works, so I tried just copying over their kwinoutputconfig.json file, but this file gets overwritten for some reason after you edit it or on logout or something. So I copied the file over again from the new user and set it read only (chmod 444). Now I can close the lid with an external monitor and the laptop stays awake.
(In reply to Eric from comment #5) > Now I can close the lid with an external monitor and the laptop stays > awake. The configuration of how powerdevil handles lid-switch when an external monitor is connected (vs. no external monitor) is in System Settings -> Power Management -> [profile] -> When laptop lid is closed, and there's a checkbox "Even when an external monitor is connected" - and should be off by default (due to a workaround for an unrelated bug, I have this turned on and it is marked as "non-default"). So by default Plasma will not sleep when you lid-switch and an external monitor is connected. This is a good default. The problem here is that when lid-switch is inhibited, and I have no external monitor (or sleeping with external monitor is enabled), Powerdevil ignores the inhibition and sleeps anyway when it gets a lid-switch.