diff --git a/crates/ui-egui/src/prefs_dialog.rs b/crates/ui-egui/src/prefs_dialog.rs index b91c149f4..20502f0f6 100644 --- a/crates/ui-egui/src/prefs_dialog.rs +++ b/crates/ui-egui/src/prefs_dialog.rs @@ -109,6 +109,12 @@ fn canvas_color(key: &str) -> Option { /// Per frame: push UI-side preferences into egui / the renderer when they change. pub fn apply_runtime(app: &mut VectorcraftApp, ctx: &egui::Context) { + apply(app, ctx, false); +} + +/// [`apply_runtime`]; with `force`, the preferences are pushed into `ctx` even when nothing changed +/// since the last push. +fn apply(app: &mut VectorcraftApp, ctx: &egui::Context, force: bool) { let p = &app.session.prefs; if let Some(b) = Brightness::parse(&p.ui_brightness) && b != app.ui.brightness @@ -127,7 +133,7 @@ pub fn apply_runtime(app: &mut VectorcraftApp, ctx: &egui::Context) { }; let id = applied_id(); let prev: Option = ctx.data(|d| d.get_temp::>(id)).flatten(); - if prev != Some(want) { + if force || prev != Some(want) { theme::apply_with(ctx, want.brightness, want.accent, want.scheme); // General › Show Tool Tips: off, no button or field shows its tool tip (they never come // due), whichever widget asks for one. @@ -165,11 +171,11 @@ fn applied_id() -> egui::Id { egui::Id::unique("dc-applied-prefs") } -/// [`apply_runtime`] with nothing recorded as applied, so the theme (brightness, accent, color -/// scheme and canvas color) and the other UI-side preferences are pushed into `ctx` again. +/// [`apply_runtime`] even when nothing changed, so the theme (brightness, accent, color scheme and +/// canvas color) and the other UI-side preferences are pushed into `ctx` again. The record of what +/// was last applied stays, so a Render Threads change since then still restarts the renderer. pub(crate) fn reapply(app: &mut VectorcraftApp, ctx: &egui::Context) { - ctx.data_mut(|d| d.remove::>(applied_id())); - apply_runtime(app, ctx); + apply(app, ctx, true); } pub fn show(app: &mut VectorcraftApp, ctx: &egui::Context) { diff --git a/crates/ui-egui/src/prefs_dialog/tests.rs b/crates/ui-egui/src/prefs_dialog/tests.rs index 2e4711505..cbc429b5f 100644 --- a/crates/ui-egui/src/prefs_dialog/tests.rs +++ b/crates/ui-egui/src/prefs_dialog/tests.rs @@ -79,6 +79,23 @@ fn saved_scheme_accent_and_canvas_color_show_from_the_first_frame() { } } +/// A Render Threads change made after the preferences were applied, and before the first UI pass +/// applies them again, still restarts the canvas renderer. +#[test] +fn reapply_restarts_the_renderer_after_a_render_threads_change() { + let mut app = app(); + let ctx = egui::Context::default(); + apply_runtime(&mut app, &ctx); + app.canvas.worker_started = true; + // The automatic count as an explicit value: the process-wide count other tests read stays the same. + let threads = vectorcraft_render::default_threads(); + app.run("prefs.set", json!({"key": "renderThreads", "value": threads})).unwrap(); + reapply(&mut app, &ctx); + let restarted = !app.canvas.worker_started; + app.run("prefs.set", json!({"key": "renderThreads", "value": -1})).unwrap(); + assert!(restarted, "the canvas renderer kept its old thread count"); +} + fn app() -> VectorcraftApp { VectorcraftApp::new(Session::new(), Services::default()) }