diff --git a/crates/ui-egui/src/menus.rs b/crates/ui-egui/src/menus.rs index b6dcc67858..49f2aeba1a 100644 --- a/crates/ui-egui/src/menus.rs +++ b/crates/ui-egui/src/menus.rs @@ -256,9 +256,13 @@ fn english(labeled: Labeled<'_>) -> Option { } fn translate(english: &'static str) -> String { - // The bundled UI fonts do not all cover the menu's mathematical ellipsis. + // craft_menu's bar writes "⋯" (U+22EF, MIDLINE HORIZONTAL ELLIPSIS) itself, for the menu of + // titles that don't fit: a sentinel to translate, not an English phrase, and the only one of + // its four reserved labels no font this app ships or falls back to has a glyph for. + // MissingGlyphPolicy::Panic (egui 0.37) crashes on it. The ordinary ellipsis every other + // truncated label in this app already uses is in the bundled faces. if english == "\u{22ef}" { - return "...".to_owned(); + return "…".to_owned(); } tl!(english).to_owned() } @@ -662,6 +666,22 @@ mod tests { bar.find(command).unwrap_or_else(|| panic!("{} is in the menus", command.key())) } + /// The bar's own overflow-menu sentinel is not rendered as typed: no font this app ships or + /// falls back to has U+22EF, and egui 0.37's `MissingGlyphPolicy::Panic` crashes on it when + /// the menu bar is narrow enough to need it. The editing tests that narrow the window while a + /// paragraph is open reproduce this end to end. The other three reserved labels are plain + /// ASCII, so untranslated is safe for them. + #[test] + fn the_overflow_menu_sentinel_is_not_passed_through_untranslated() { + crate::i18n::set_current(crate::i18n::Lang::EN); + let translated = translate("⋯"); + assert_ne!(translated, "⋯", "no installed font has this glyph"); + assert_eq!(translated, "…", "the ordinary ellipsis the rest of the app already uses"); + for label in ["Menu", "Scroll menu up", "Scroll menu down"] { + assert_eq!(translate(label), label, "plain ASCII reserved labels need no substitution"); + } + } + #[test] fn every_menu_command_is_listed_once_with_its_shortcut() { let (app, ctx) = app(&["a.pdf"]);