diff --git a/crates/ui-egui/src/lib.rs b/crates/ui-egui/src/lib.rs index 9143a662..e52e78d5 100644 --- a/crates/ui-egui/src/lib.rs +++ b/crates/ui-egui/src/lib.rs @@ -359,6 +359,7 @@ pub struct FilmcraftApp { pub shortcut_editor: panels::shortcuts_dialog::EditorState, pub toast: Option<(String, f64)>, pub tl: panels::timeline::TlState, + pub(crate) transcript_cache: panels::transcript_cache::TranscriptCache, /// Commands from outside the UI (native menu bar), invoked on the UI thread. pub command_inbox: Option>, /// A V key press (or a Ctrl+V paste) reached the app and its release hasn't yet. @@ -585,6 +586,7 @@ impl FilmcraftApp { toast: None, graphics_notice: None, tl: Default::default(), + transcript_cache: Default::default(), command_inbox: None, v_down: false, stale_clipboard_media: None, diff --git a/crates/ui-egui/src/panels/effect_controls.rs b/crates/ui-egui/src/panels/effect_controls.rs index febe23a5..1750022a 100644 --- a/crates/ui-egui/src/panels/effect_controls.rs +++ b/crates/ui-egui/src/panels/effect_controls.rs @@ -112,7 +112,10 @@ pub fn show(app: &mut FilmcraftApp, ui: &mut egui::Ui, rect: Rect) { crate::dock::placeholder(ui, rect, &t, tl!("(no clip selected)")); return; }; - let Some(seq) = app.session.active_sequence().cloned() else { + // Keep the immutable project snapshot alive while UI commands mutate the session. + // Cloning a sequence here copies every clip and effect on every redraw. + let project = app.session.project.clone(); + let Some(seq) = app.session.state.active_sequence.and_then(|id| project.sequence(id)) else { crate::dock::placeholder(ui, rect, &t, tl!("(no sequences)")); return; }; diff --git a/crates/ui-egui/src/panels/misc.rs b/crates/ui-egui/src/panels/misc.rs index 0cb11388..744e9cfb 100644 --- a/crates/ui-egui/src/panels/misc.rs +++ b/crates/ui-egui/src/panels/misc.rs @@ -81,7 +81,10 @@ pub(crate) fn marker_label_menu(app: &mut FilmcraftApp, ui: &mut egui::Ui, marke /// `markers.filter.