diff --git a/crates/ui-egui/src/lib.rs b/crates/ui-egui/src/lib.rs index 37fb86df3..35d29e06b 100644 --- a/crates/ui-egui/src/lib.rs +++ b/crates/ui-egui/src/lib.rs @@ -1021,13 +1021,17 @@ impl LightcraftApp { if ctx.input(|i| i.viewport().close_requested()) && !panels::notices::may_close(self) { ctx.send_viewport_cmd(egui::ViewportCommand::CancelClose); } - let now = ctx.input(|i| i.time); - let dt = now - self.last_time; - if dt > 0.0 { - self.perf.fps = self.perf.fps * 0.9 + (1.0 / dt).min(240.0) * 0.1; + // (once a frame: a pass drawn again after a discard has no input of its own, and still the + // widgets of the pass thrown away, where a request would find them out of place) + if ctx.current_pass_index() == 0 { + let now = ctx.input(|i| i.time); + let dt = now - self.last_time; + if dt > 0.0 { + self.perf.fps = self.perf.fps * 0.9 + (1.0 / dt).min(240.0) * 0.1; + } + self.last_time = now; + self.drain_control(ctx); } - self.last_time = now; - self.drain_control(ctx); self.apply_settings(ctx); if !self.synthetic.is_empty() { ctx.request_repaint(); diff --git a/crates/ui-egui/src/panels/right.rs b/crates/ui-egui/src/panels/right.rs index 612053308..49f1949d0 100644 --- a/crates/ui-egui/src/panels/right.rs +++ b/crates/ui-egui/src/panels/right.rs @@ -15,7 +15,7 @@ pub fn show(app: &mut LightcraftApp, ui: &mut egui::Ui) { let t = Tokens::get(ui.ctx()); let frame = egui::Frame::NONE.fill(t.chrome).stroke(egui::Stroke::new(1.0, t.divider)); frame.show(ui, |ui| { - // (taken on every pass, so a hold the panel was not drawn for is forgotten) + // (taken on every pass the panel is drawn; one from earlier than the pass before is forgotten) let held = held_offset(ui.ctx()); let Some(id) = app.session.active() else { // the Keyword List is the library's, not a photo's: it is there without a selection @@ -77,7 +77,10 @@ const HOLD: &str = "right-scroll-hold"; /// the Keywords box grew. Set on the scroll area as it starts, so the pass drawn again shows the list /// in place (a scroll asked for during a pass only lands a frame later). fn held_offset(ctx: &egui::Context) -> Option { - let grew = ctx.data_mut(|d| d.remove_temp::(egui::Id::new(HOLD)))?; + let (grew, asked) = ctx.data_mut(|d| d.remove_temp::<(f32, u64)>(egui::Id::new(HOLD)))?; + if asked.checked_add(1) != Some(ctx.cumulative_pass_nr()) { + return None; + } let offset = ctx.data(|d| d.get_temp::(egui::Id::new(OFFSET)))?; Some((offset + grew).max(0.0)).filter(|o| o.is_finite()) } @@ -957,7 +960,7 @@ fn hold_list_in_place(ui: &mut egui::Ui, top: f32) { if on_box || typing { return; } - ui.data_mut(|d| d.insert_temp(egui::Id::new(HOLD), grew)); + ui.data_mut(|d| d.insert_temp(egui::Id::new(HOLD), (grew, pass))); // (drawn again at once at the new offset, so the list never shows a frame out of place) ui.ctx().request_discard("the Keyword List holds its place"); }