fix: handle dynamic output changes while session is locked
When monitors are powered off (e.g. via niri power-off-monitors or physical power switches), niri destroys and re-advertises the Wayland outputs as they come back. Previously all three OutputHandler callbacks were no-ops, causing two bugs: - new_output: no lock surface was created for outputs that appeared after the initial lock, so the slowest monitor to wake up would show the compositor's red fallback instead of the lock screen. - output_destroyed: stale LockedSurface, SessionLockSurface, output, and captured_background entries accumulated for gone outputs. Fix new_output to create a lock surface (and register it with the lock manager) whenever a new output appears while the session is locked. Fix output_destroyed to remove the corresponding entries from lock_surfaces, lock_manager.surfaces, outputs, and captured_backgrounds, keeping all parallel vecs in sync. Add LockManager::remove_surface_by_output to support this, returning the removal index so lock_surfaces can be updated with the same index. The all-monitors-off scenario (all outputs destroyed simultaneously) is handled naturally: the vecs are emptied and repopulated as each monitor fires new_output on wake. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
+11
@@ -262,6 +262,17 @@ impl LockManager {
|
||||
action
|
||||
}
|
||||
|
||||
pub fn remove_surface_by_output(&mut self, output: &wl_output::WlOutput) -> Option<usize> {
|
||||
use wayland_client::Proxy;
|
||||
let output_id = Proxy::id(output);
|
||||
let idx = self
|
||||
.surfaces
|
||||
.iter()
|
||||
.position(|s| Proxy::id(s.output()) == output_id)?;
|
||||
self.surfaces.remove(idx);
|
||||
Some(idx)
|
||||
}
|
||||
|
||||
pub fn set_system_status(&mut self, status: SystemStatus) {
|
||||
for surface in &mut self.surfaces {
|
||||
surface.set_system_status(status.clone());
|
||||
|
||||
Reference in New Issue
Block a user