diff --git a/src/input/mod.rs b/src/input/mod.rs index af160ae2..7bf350a5 100644 --- a/src/input/mod.rs +++ b/src/input/mod.rs @@ -220,7 +220,16 @@ impl State { ) where ::Device: 'static, { - crate::wayland::handlers::output_power::set_all_surfaces_dpms_on(self); + // An input device going away is not user activity, e.g. a wireless keyboard + // dropping its link when it sleeps, so it must not power displays back on. + // Device additions still wake: after a system resume the re-enumerated + // devices may be the only input seen, and the wake resets idle anyway. + if !matches!( + &event, + InputEvent::DeviceRemoved { .. } | InputEvent::Special(_) + ) { + crate::wayland::handlers::output_power::set_all_surfaces_dpms_on(self); + } use smithay::backend::input::Event; match event { diff --git a/src/wayland/handlers/output_power.rs b/src/wayland/handlers/output_power.rs index 2675009a..333aacc6 100644 --- a/src/wayland/handlers/output_power.rs +++ b/src/wayland/handlers/output_power.rs @@ -21,6 +21,11 @@ pub fn set_all_surfaces_dpms_on(state: &mut State) { } if changed { + // Powering an output on because of input is activity. Without this the idle + // notifier stays idled, the idle daemon never sees `resumed`, and nothing + // powers the output off again until real input arrives. + let seat = state.common.shell.read().seats.last_active().clone(); + state.common.idle_notifier_state.notify_activity(&seat); OutputPowerState::refresh(state); } }