fix: stop redrawing endlessly while idle (battery drain)

egui-winit reports `repaint: true` for every RedrawRequested, and the app
followed that with another request_redraw – so it redrew at full frame
rate all the time, keeping the app and the compositor (gnome-shell) busy.
Follow-up frames egui needs already come via `repaint_delay`.

The toast no longer redraws every frame either: one wake-up when its
fade-out starts is enough. While the updater checks or downloads, the
loop looks for its results every 100 ms instead.

Idle CPU under Xvfb/lavapipe: 187 % before, 0 % after.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
haraldandClaude Opus 5.5 committed 2026-10-27 20:14:46 +01:00
1 parent 7faf78ddeb
commit 6b80cd672a
1 file changed
+21 -4
+21 -4
View File
@@ -2409,7 +2409,6 @@ pub fn run_with(
// Bei anstehenden Änderungen, aktivem Toast, Stylus in Proximity oder aktivem Zeichnen regelmäßig aufwachen
if new_status == AutosaveStatus::Pending
|| new_status == AutosaveStatus::Saving
|| ui_state.export_message.is_some()
|| (is_drawing && !stroke_already_snapped)
|| is_stylus_drawing
|| is_stylus_in_proximity
@@ -2420,6 +2419,13 @@ pub fn run_with(
egui_repaint_at,
long_press.deadline(),
Some(disk_watch.deadline()),
// The updater thread does not wake the loop: look for its results now and then
matches!(
updater.status(),
crate::updater::UpdaterStatus::Checking
| crate::updater::UpdaterStatus::Downloading { .. }
)
.then(|| Instant::now() + Duration::from_millis(100)),
]
.into_iter()
.flatten()
@@ -2457,7 +2463,10 @@ pub fn run_with(
} else {
egui_winit_state.on_window_event(&window, &event)
};
if egui_response.repaint {
// egui-winit asks for a repaint after every RedrawRequested as well; following
// that would redraw endlessly even when idle (high CPU load in the app and the
// compositor). Follow-up frames egui needs come via `repaint_delay` instead.
if egui_response.repaint && !matches!(event, WindowEvent::RedrawRequested) {
window.request_redraw();
}
@@ -5513,8 +5522,16 @@ pub fn run_with(
pixels_per_point: egui_ctx.pixels_per_point(),
};
if ui_state.export_message.is_some() {
window.request_redraw();
// The toast only changes while it fades out (its last second); until
// then a single wake-up at the start of the fade is enough
if let Some((_, shown)) = &ui_state.export_message {
let fade = *shown + Duration::from_secs(3);
if Instant::now() >= fade {
window.request_redraw();
} else {
egui_repaint_at =
Some(egui_repaint_at.map_or(fade, |at| at.min(fade)));
}
}
// 5. Canvas (Pass 1) und egui UI (Pass 2) in Surface-Textur rendern