Accessibility: a set value in another unit keeps a number past the rail

A dialog slider whose field shows another unit, such as Transform Each's
Move in millimeters, converted the number back to points and held it to
the rail's range, so a set value past the rail that the field holds came
back as the rail's end.
This commit is contained in:
dotCooCoo
2026-11-04 21:37:57 +07:00
committed by bflatastic
parent d1e69239a7
commit 07e598c636
2 changed files with 20 additions and 2 deletions
+3 -2
View File
@@ -813,8 +813,9 @@ pub(super) fn slider_rail_valued(
let units = shown.as_ref().map(|s| s.range.clone());
let (dragged, _, keyed) =
crate::widgets::color_slider_stepped(ui, ("dlg-slider", key), name, shown, ((v - min) / (max - min)) as f32, SLIDER_WIDTH, track);
let keyed =
keyed.zip(units).map(|(k, u)| if u == range { k } else { (min + (k - u.start()) / (u.end() - u.start()) * (max - min)).clamp(min, max) });
// Not clamped to the rail: a screen reader's set value can reach a number past it that the
// field holds.
let keyed = keyed.zip(units).map(|(k, u)| if u == range { k } else { min + (k - u.start()) / (u.end() - u.start()) * (max - min) });
if let Some(n) = dragged.map(|x| (min + x as f64 * (max - min)).round()).or(keyed).filter(|n| *n != held) {
d.fields.insert(key.into(), json!(n));
}
+17
View File
@@ -2078,6 +2078,23 @@ fn screen_readers_set_a_dialog_slider_number() {
assert_eq!(scale(&app), 250.0, "within the range screen readers get");
f.run(&mut app, vec![set(400.0)]);
assert_eq!(scale(&app), 250.0, "past 250%, the range's end now");
// The same for a Move slider in millimeters, whose rail ends at 1000 pt: with the field at
// 1200 pt, 400 mm sets about 1134 pt.
app.ui.dialog = None;
app.run("document.setUnits", json!({"units": "millimeters"})).unwrap();
crate::menus::invoke(&mut app, "object.transformEach", json!({}));
app.ui.dialog.as_mut().expect("Transform Each is open").fields.insert("moveH".into(), json!(1200));
let mut f = Frames::new();
f.run(&mut app, vec![]);
let out = f.run(&mut app, vec![]);
let nodes = &out.platform_output.accesskit_update.as_ref().expect("an accessibility tree").nodes;
let mut horizontal = nodes.iter().filter(|(_, n)| n.role() == egui::accesskit::Role::Slider && n.label() == Some("Horizontal:"));
let (node, _) = horizontal.nth(1).expect("the Move slider named Horizontal:");
let request =
ActionRequest { action: Action::SetValue, target_node: *node, target_tree: TreeId::ROOT, data: Some(ActionData::NumericValue(400.0)) };
f.run(&mut app, vec![egui::Event::AccessKitActionRequest(request)]);
let moved = app.ui.dialog.as_ref().expect("Transform Each is open").f64("moveH", f64::NAN);
assert!((moved - 400.0 * 72.0 / 25.4).abs() < 1e-6, "{moved} pt");
}
#[test]