#6429: the Appearance popup's last frame puts surrender_focus_on back however it ends

A drop guard restores egui's app-wide option, so a panic in the popup's panel
(caught by the app's guard) no longer leaves presses ending every field's edit.
This commit is contained in:
Sven Lafebre
2026-11-10 20:15:44 +01:00
parent 332e8fe15c
commit 40368e77e0
2 changed files with 24 additions and 6 deletions
+22 -6
View File
@@ -398,11 +398,9 @@ pub(crate) fn row_popup(app: &mut VectorcraftApp, ctx: &egui::Context, panel: Re
}
last = true;
}
// Fields let go of the keyboard on a click, which this press isn't yet.
let surrender = ctx.options(|o| o.input_options.surrender_focus_on);
if last {
ctx.options_mut(|o| o.input_options.surrender_focus_on = egui::SurrenderFocusOn::Presses);
}
// Fields let go of the keyboard on a click, which this press isn't yet. The app-wide option
// goes back however this function ends, a panic in the panel included.
let _surrender = last.then(|| SurrenderOnPress::set(ctx));
let screen = ctx.content_rect();
let left = panel.left() - POPUP_GAP - POPUP_W;
let x = if left >= screen.left() + POPUP_GAP { left } else { (panel.right() + POPUP_GAP).min(screen.right() - POPUP_W - POPUP_GAP) };
@@ -430,11 +428,29 @@ pub(crate) fn row_popup(app: &mut VectorcraftApp, ctx: &egui::Context, panel: Re
});
});
if last {
ctx.options_mut(|o| o.input_options.surrender_focus_on = surrender);
close(app);
}
}
/// While it lives, a press anywhere makes a field let go of the keyboard, as a click does
/// otherwise; dropped, egui's previous `surrender_focus_on` is back ([`row_popup`]'s last frame).
struct SurrenderOnPress(egui::Context, egui::SurrenderFocusOn);
impl SurrenderOnPress {
fn set(ctx: &egui::Context) -> Self {
let before = ctx.options(|o| o.input_options.surrender_focus_on);
ctx.options_mut(|o| o.input_options.surrender_focus_on = egui::SurrenderFocusOn::Presses);
Self(ctx.clone(), before)
}
}
impl Drop for SurrenderOnPress {
fn drop(&mut self) {
let before = self.1;
self.0.options_mut(|o| o.input_options.surrender_focus_on = before);
}
}
/// A row's name that edits the row when clicked ([`link`]), with the tooltip "Click to edit".
fn name_link(ui: &mut Ui, pos: egui::Pos2, id: impl std::hash::Hash + std::fmt::Debug, s: &str) -> egui::Response {
link(ui, pos, id, s).on_hover_text(tl!("Click to edit"))
@@ -2016,6 +2016,8 @@ fn a_dash_typed_in_a_stroke_popup_sticks_when_a_click_outside_closes_it() {
let dash = |app: &VectorcraftApp| current_stroke(app).and_then(|s| s.dash).map(|d| d.pattern);
assert_eq!(dash(&app), Some(vec![10.0]), "{link}: nothing set while typing");
click(&ctx, &mut app, egui::pos2(5.0, 3000.0), show);
let surrender = ctx.options(|o| o.input_options.surrender_focus_on);
assert_eq!(surrender, egui::SurrenderFocusOn::Clicks, "{link}: fields let go of the keyboard on a click again");
frame_events(&ctx, &mut app, vec![], show);
assert_eq!(dash(&app).and_then(|p| p.first().copied()), Some(4.0), "{link}: the typed dash stuck: {:?}", dash(&app));
let texts = frame_events(&ctx, &mut app, vec![], show);