https://bugs.kde.org/show_bug.cgi?id=517882
Bug ID: 517882
Summary: OutputConfigurationStore persists generated config
before DRM apply, allowing compositor failures to
permanently corrupt kwinoutputconfig.json
Classification: Plasma
Product: kwin
Version First 6.6.2
Reported In:
Platform: NixOS
OS: Linux
Status: REPORTED
Severity: major
Priority: NOR
Component: output configuration
Assignee: [email protected]
Reporter: [email protected]
CC: [email protected]
Target Milestone: ---
SUMMARY
OutputConfigurationStore persists generated config before DRM apply, allowing
compositor failures to permanently corrupt kwinoutputconfig.json
STEPS TO REPRODUCE
1. Have a laptop with internal display (eDP) and external monitor (HDMI through
NVIDIA dGPU), normally used lid-closed with external monitor only
2. Have a working kwinoutputconfig.json with correct lid-closed setup (eDP
disabled, HDMI enabled) which should be the default state anyways.
3. Boot into a system where the kwin compositor is degraded (in my case
Xwayland not available, try to remove Xwayland to reproduce)
4. kwin starts, fails to apply output configurations (journalctl -b -t
kwin_wayland shows "Failed to find a working output layer configuration!" and
"Applying output configuration failed!")
5. Reboot back into a healthy system (I just rolledback in NixOS, but on
non-atomic distros you can just install Xwayland back through TTY)
6. Close the laptop lid with external monitor connected
OBSERVED RESULT
The external monitor is disabled and the internal display (behind the closed
lid) is enabled when the lid closes. This causes PowerDevil to see no active
external monitor and suspend the system, despite even if "When laptop lid
closed" is set to "None" or "Even when an external monitor" remains unchecked.
EXPECTED RESULT
A failed DRM commit should not overwrite previously-correct persistent output
configuration. The known-good lid-closed setup (eDP disabled, HDMI enabled)
should be preserved.
SOFTWARE/OS VERSIONS
Linux/KDE Plasma:
KDE Plasma Version: 6.6.3
KDE Frameworks Version: 6.24.0
Qt Version: 6.10.2
Kernel Version: 6.19.8 (64-bit)
Graphics Platform: Wayland
Graphics Processor 1: AMD Radeon Graphics (Renoir iGPU, drives eDP-2)
Graphics Processor 2: NVIDIA GeForce GTX 1650 (Turing dGPU, drives HDMI-A-1)
OS: NixOS 26.05pre964859
NVIDIA Driver: 580.142 (open kernel modules)
ADDITIONAL INFORMATION
This was a quite perplexing bug since despite rolling back generations on
NixOS, the bug still persisted, even on older generations where it never
happened. Plus, the bug dosen't happen on the SDDM login screen. This all
points to a stateful plasma config file within the user directory since that
isn't rolled back, and the bug dosen't affect SDDM.
Inspecting ~/.config/kwinoutputconfig.json shows the lid-closed setup has been
inverted: the internal display is enabled: true and the external monitor is
enabled: false. This wrong config was written during the degraded boot and
persists permanently because kwin loads it on every subsequent boot, uses it,
and resaves it, making the corruption persistent.
The config file cannot be fixed while kwin is running because kwin's destructor
calls save() on exit, overwriting any manual edits with its in-memory (wrong)
state. I had to logout and edit kwinoutputconfig.json through TTY.
I think that the root cause is in outputconfigurationstore.cpp. In
queryConfig(), storeConfig() is called unconditionally after generating or
loading a config, before the caller applies it to hardware. There is no
feedback path from the DRM commit result back to the config store. If the
commit fails, the wrong config is already on disk.
generateLidClosedConfig() itself produces the correct result (disable internal,
keep external) when called on a healthy system. The problem is that during a
degraded boot, storeConfig() captures the failed/fallback output state and
persists it. On the next healthy boot, findSetup() finds the corrupted entry,
setupToConfig() uses it, and storeConfig() re-saves it.
Suggested fix: call storeConfig() only after successful DRM apply, or implement
rollback on failure. A minimal fix would be to not call storeConfig() for
ConfigType::Generated configs that haven't been successfully applied.
--
You are receiving this mail because:
You are watching all bug changes.