Register battery polling only for active automatic-refresh outputs

This commit is contained in:
Samuel Onoja committed 2026-10-02 08:18:47 +01:00
1 parent 79a968b0a6
commit 181b7bce9a
1 file changed
+48 -11
+48 -11
View File
@@ -57,6 +57,7 @@ pub struct DirectBackendState {
input_devices: Vec<LibinputDevice>, input_devices: Vec<LibinputDevice>,
presentation: HashMap<(DrmNode, crtc::Handle), PresentationClock>, presentation: HashMap<(DrmNode, crtc::Handle), PresentationClock>,
pub(crate) connected_outputs: Vec<ConnectedOutputInfo>, pub(crate) connected_outputs: Vec<ConnectedOutputInfo>,
battery_timer: Option<RegistrationToken>,
power_retry: Option<RegistrationToken>, power_retry: Option<RegistrationToken>,
animation_timer: Option<RegistrationToken>, animation_timer: Option<RegistrationToken>,
animation_deadline: Option<Instant>, animation_deadline: Option<Instant>,
@@ -237,6 +238,7 @@ pub fn init(event_loop: &mut EventLoop<Ferese>, state: &mut Ferese) -> Result<()
input_devices: Vec::new(), input_devices: Vec::new(),
presentation: HashMap::new(), presentation: HashMap::new(),
connected_outputs: Vec::new(), connected_outputs: Vec::new(),
battery_timer: None,
power_retry: None, power_retry: None,
animation_timer: None, animation_timer: None,
animation_deadline: None, animation_deadline: None,
@@ -244,12 +246,7 @@ pub fn init(event_loop: &mut EventLoop<Ferese>, state: &mut Ferese) -> Result<()
}); });
open_primary_device(event_loop, state, &primary_path)?; open_primary_device(event_loop, state, &primary_path)?;
event_loop sync_battery_timer(state);
.handle()
.insert_source(Timer::from_duration(Duration::from_secs(5)), |_, _, state| {
update_power_policy(state);
TimeoutAction::ToDuration(Duration::from_secs(5))
})?;
event_loop event_loop
.handle() .handle()
@@ -276,6 +273,9 @@ pub fn init(event_loop: &mut EventLoop<Ferese>, state: &mut Ferese) -> Result<()
let handle = state.loop_handle.clone(); let handle = state.loop_handle.clone();
if let Some(backend) = state.direct_backend.as_mut() { if let Some(backend) = state.direct_backend.as_mut() {
backend.active = false; backend.active = false;
if let Some(token) = backend.battery_timer.take() {
handle.remove(token);
}
if let Some(token) = backend.power_retry.take() { if let Some(token) = backend.power_retry.take() {
handle.remove(token); handle.remove(token);
} }
@@ -327,6 +327,7 @@ pub fn init(event_loop: &mut EventLoop<Ferese>, state: &mut Ferese) -> Result<()
} }
update_power_policy(state); update_power_policy(state);
sync_battery_timer(state);
state.reset_animation_clock(); state.reset_animation_clock();
tracing::info!("direct session activated"); tracing::info!("direct session activated");
state.lock_input_activity(); state.lock_input_activity();
@@ -396,12 +397,45 @@ pub(crate) fn reload_input_devices(state: &mut Ferese) {
} }
} }
fn automatic_refresh_active(backend: &DirectBackendState) -> bool {
backend.active
&& backend
.devices
.values()
.any(|device| device.outputs.values().any(|output| output.settings.auto_refresh))
}
fn sync_battery_timer(state: &mut Ferese) {
let Some(backend) = state.direct_backend.as_mut() else {
return;
};
if !automatic_refresh_active(backend) {
if let Some(token) = backend.battery_timer.take() {
state.loop_handle.remove(token);
}
return;
}
if backend.battery_timer.is_some() {
return;
}
match state
.loop_handle
.insert_source(Timer::from_duration(Duration::from_secs(5)), |_, _, state| {
if let Some(backend) = state.direct_backend.as_mut() {
backend.battery_timer = None;
}
update_power_policy(state);
sync_battery_timer(state);
TimeoutAction::Drop
}) {
Ok(token) => backend.battery_timer = Some(token),
Err(error) => tracing::warn!(%error, "could not arm automatic refresh battery timer"),
}
}
fn update_power_policy(state: &mut Ferese) { fn update_power_policy(state: &mut Ferese) {
if !state if !state.direct_backend.as_ref().is_some_and(automatic_refresh_active) {
.output_profiles
.iter()
.any(|profile| profile.outputs.iter().any(|output| output.auto_refresh))
{
return; return;
} }
let Some(backend) = state.direct_backend.as_mut() else { let Some(backend) = state.direct_backend.as_mut() else {
@@ -1336,6 +1370,8 @@ fn rescan_device(state: &mut Ferese, node: DrmNode) {
} }
restore_device(state, node, device); restore_device(state, node, device);
sync_battery_timer(state);
update_power_policy(state);
state.restore_output_focus(); state.restore_output_focus();
state.relayout(); state.relayout();
render_all(state); render_all(state);
@@ -1366,6 +1402,7 @@ fn remove_device(state: &mut Ferese, node: DrmNode) {
backend.connected_outputs.clear(); backend.connected_outputs.clear();
} }
sync_battery_timer(state);
arm_animation_timer(state); arm_animation_timer(state);
tracing::info!(?node, "removed DRM device"); tracing::info!(?node, "removed DRM device");
} }