From c941a1da5dc3735a99ab633e8b39a8abc604bc69 Mon Sep 17 00:00:00 2001 From: dotCooCoo Date: Wed, 11 Nov 2026 00:36:08 -0800 Subject: [PATCH] Contextual Task Bar: screen readers name the text buttons The bar's text buttons (Edit Path, Duplicate, Type on a Path Options and the others) were painted labels on a click area with no accessible name, so a screen reader announced them without one. Each button now reports its label as a button, as the Home screen's file rows do. --- crates/ui-egui/src/canvas/task_bar.rs | 1 + crates/ui-egui/src/canvas/tests.rs | 14 ++++++++++++++ 2 files changed, 15 insertions(+) diff --git a/crates/ui-egui/src/canvas/task_bar.rs b/crates/ui-egui/src/canvas/task_bar.rs index b5f8dac66..0ccba73de 100644 --- a/crates/ui-egui/src/canvas/task_bar.rs +++ b/crates/ui-egui/src/canvas/task_bar.rs @@ -233,6 +233,7 @@ pub(super) fn task_bar(app: &mut VectorcraftApp, ui: &mut Ui, xf: &Xf) { for (label, icon, cmd, params) in &items { let galley = ui.painter().layout_no_wrap(label.to_string(), egui::FontId::proportional(13.0), t.text_strong); let (r, resp) = ui.allocate_exact_size(vec2(galley.size().x + 38.0, 30.0), Sense::click()); + resp.widget_info(|| egui::WidgetInfo::labeled(egui::Role::Button, true, *label)); if resp.hovered() { ui.painter().rect_filled(r, CornerRadius::same(3), t.hover); } diff --git a/crates/ui-egui/src/canvas/tests.rs b/crates/ui-egui/src/canvas/tests.rs index a9ef2c228..172475daa 100644 --- a/crates/ui-egui/src/canvas/tests.rs +++ b/crates/ui-egui/src/canvas/tests.rs @@ -9198,6 +9198,20 @@ fn the_task_bar_offers_the_artboard_tools_actions() { assert_eq!(names(&mut app), ["Resize", "Duplicate", "Export"]); } +/// Screen readers name the Contextual Task Bar's text buttons by their labels. +#[test] +fn screen_readers_name_the_task_bars_text_buttons() { + use crate::widgets::accessibility_tests::{named, tree}; + let mut app = VectorcraftApp::new(Session::new(), Default::default()); + app.session.execute("file.new", &json!({"width": 400, "height": 300})).unwrap(); + app.session.execute("shape.rectangle", &json!({"x": 180, "y": 130, "width": 40, "height": 40})).unwrap(); + app.select_tool("selection"); + let tree = tree(|ui| show(&mut app, ui)); + for label in ["Edit Path", "Offset Path", "Simplify", "Duplicate"] { + assert_eq!(named(&tree, label).role(), egui::accesskit::Role::Button, "{label}"); + } +} + /// A selected group's Contextual Task Bar offers Ungroup and Isolate. While an opacity mask is /// edited, when Enter Isolation Mode is off, a group in the mask art gets Ungroup without Isolate. #[test]