Widgets: a mixed checkbox is announced as mixed (#2089 review)

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Model-Effort: Opus 5.5 drove; Opus 5.5 briefed; Sonnet 5.5 wrote at medium
This commit is contained in:
Trevor BrownandClaude Sonnet 5.5 committed 2026-11-07 21:44:01 -05:00
1 parent a20415e154
commit 8a78214b48
3 files changed
+26 -2

No files matched your search

+9 -1
View File
@@ -883,9 +883,17 @@ pub fn tab(resp: &Response, label: &str, selected: bool) {
}
pub fn checkbox(resp: &Response, label: &str, on: bool) {
checkbox_tri(resp, label, Some(on));
}
/// A checkbox that can be mixed (`None`, announced as "mixed" rather than unchecked).
pub fn checkbox_tri(resp: &Response, label: &str, state: Option<bool>) {
node(resp, label, |n| {
n.set_role(Role::CheckBox);
n.set_toggled(toggled(on));
n.set_toggled(match state {
Some(on) => toggled(on),
None => Toggled::Mixed,
});
});
}
+16
View File
@@ -431,3 +431,19 @@ fn the_custom_panel_edges_never_enter_the_keyboard_or_focus_order() {
}
assert!(!seen.contains(&left) && !seen.contains(&right), "Tab never stops on a panel edge: {seen:?}");
}
#[test]
fn a_mixed_checkbox_is_announced_as_mixed_and_a_checked_one_as_true() {
let ctx = egui::Context::default();
ctx.enable_accesskit();
let mut out = ctx.run_ui(egui::RawInput::default(), |ui| {
crate::widgets::checkbox_tri(ui, None, "Mixed one");
crate::widgets::checkbox_tri(ui, Some(true), "Checked one");
crate::widgets::checkbox_tri(ui, Some(false), "Plain one");
});
out.textures_delta.clear();
let nodes: Vec<Node> = out.platform_output.accesskit_update.expect("an AccessKit update").nodes.into_iter().map(|(_, n)| n).collect();
assert_eq!(find(&nodes, Role::CheckBox, "Mixed one").toggled(), Some(Toggled::Mixed));
assert_eq!(find(&nodes, Role::CheckBox, "Checked one").toggled(), Some(Toggled::True));
assert_eq!(find(&nodes, Role::CheckBox, "Plain one").toggled(), Some(Toggled::False));
}
+1 -1
View File
@@ -1282,7 +1282,7 @@ pub fn checkbox(ui: &mut Ui, on: bool, label: &str) -> bool {
pub fn checkbox_tri(ui: &mut Ui, state: Option<bool>, label: &str) -> bool {
let t = Tokens::get(ui.ctx());
let (rect, resp) = ui.allocate_exact_size(vec2(ui.available_width().min(200.0), FIELD_H), Sense::click());
a11y::checkbox(&resp, label, state == Some(true));
a11y::checkbox_tri(&resp, label, state);
let b = Rect::from_min_size(pos2(rect.min.x, rect.center().y - 7.0), vec2(14.0, 14.0));
if state != Some(false) {
ui.painter().rect_filled(b, CornerRadius::same(3), t.accent);