From e481bbe32ab63a37dd8af4d99b8741ea4f99c3ab Mon Sep 17 00:00:00 2001 From: JGF <44821497+bommerts@users.noreply.github.com> Date: Wed, 21 Oct 2026 15:30:21 -0400 Subject: [PATCH] New Document: labels show the arrow, not a text cursor (#8331) In File > New, the field labels and headings (Width, Height, Resolution, Color Mode, Background Contents, PRESET DETAILS, the Saved tab's text) were selectable egui labels, so hovering them showed the I-beam as if they were editable. In Photoshop they are static text. - The dialog body turns off selectable labels, so every static label keeps the arrow. The name field keeps its text cursor and the size fields their scrub cursor. - The preset-save error message stays selectable so it can be copied. - Test: a kittest hovers the six labels and the empty Saved list (arrow) and the name field (text cursor). It fails without the fix. --- crates/ui-egui/src/new_doc_ui.rs | 37 +++++++++++++++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) diff --git a/crates/ui-egui/src/new_doc_ui.rs b/crates/ui-egui/src/new_doc_ui.rs index e615620d4c..7288419abe 100644 --- a/crates/ui-egui/src/new_doc_ui.rs +++ b/crates/ui-egui/src/new_doc_ui.rs @@ -488,7 +488,8 @@ fn save_preset(app: &mut crate::PhotocraftApp, ui: &mut egui::Ui, f: &mut Map) -> bool { let t = Tokens::get(ui.ctx()); + // Headings and field labels are static, as in Photoshop: no text cursor over them, no + // drag-selecting them (#8331). Text fields keep theirs. + ui.style_mut().interaction.selectable_labels = false; let cat = get_s(f, "__category", "Recent"); let mut create = false; // Category tabs. @@ -1273,6 +1277,37 @@ mod tests { } } + fn cursor_over(h: &mut Harness<'static, PhotocraftApp>, at: egui::Pos2) -> egui::CursorIcon { + h.hover_at(at); + h.run_steps(2); + h.output().platform_output.cursor_icon + } + + /// #8331: headings and field labels keep the arrow; only the text fields show the I-beam. + #[test] + fn labels_show_the_arrow_and_only_text_fields_the_text_cursor() { + use egui_kittest::kittest::NodeT; + let mut h = harness(); + let label_at = |h: &Harness<'static, PhotocraftApp>, text: &str| { + h.query_all_by_label(text) + .find(|n| n.accesskit_node().role() == Role::Label) + .map(|n| n.rect().center()) + .unwrap_or_else(|| panic!("a {text:?} label")) + }; + for text in ["PRESET DETAILS", "Width", "Height", "Resolution", "Color Mode", "Background Contents"] { + let at = label_at(&h, text); + assert_eq!(cursor_over(&mut h, at), egui::CursorIcon::Default, "over {text:?}"); + } + // The name field still shows the text cursor, so the check above can tell them apart. + let name = h.query_all_by_role(Role::TextInput).next().map(|n| n.rect().center()).expect("the name field"); + assert_eq!(cursor_over(&mut h, name), egui::CursorIcon::Text, "over the name field"); + // The Saved tab's labels too. + h.get_by_label("Saved").click(); + h.run_steps(2); + let at = label_at(&h, "No saved presets yet."); + assert_eq!(cursor_over(&mut h, at), egui::CursorIcon::Default, "over the empty Saved list"); + } + #[test] fn double_click_builtin_preset_creates_its_size_and_current_details() { let mut h = harness();