UI kit: a field's scenario handle is where the field shows

A field scrolled out of a dialog's field area still published its handle at the centre of its
whole rect. The tapped hole's dialog has grown (thread hand, tap drill, thread end rows) past
1000 px, so its section's Thread depth field scrolls under the footer, and a click on that
handle pressed OK: the edit was applied (tapped_thread_depth_field_keeps_focus_and_typing_...
saw the model change at the click; focusing a field commits nothing). A field's handle is now
the middle of its visible part and is left out when none of it shows, so a scenario can only
click where a user could; the rect keeps its whole extent. The test opens a window tall enough
for the section.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
jyviko
2026-10-29 00:28:33 -04:00
committed by Irakli Kourtis
parent 6a6cd8f56c
commit 4a0c139106
2 changed files with 10 additions and 1 deletions
@@ -304,6 +304,9 @@ fn the_dialog_shows_the_sizes_beside_a_section_of_the_hole() {
#[test]
fn tapped_thread_depth_field_keeps_focus_and_typing_separate_from_acceptance() {
let mut h = Harness::new();
// Tall enough for the tapped hole's rows and its section, so the partial depth field shows
// above the dialog's footer (at 1000 px it scrolls under OK, and has no handle).
h.call("ui.resize", json!({"width": 1600, "height": 1400}));
h.app.run("solid.box", json!({"length":40,"width":30,"height":20})).unwrap();
let hole = h.app.run("solid.hole", json!({"position":[20,15,20],"thread":"M6","depth":12})).unwrap()["feature"].as_u64().unwrap();
let original = h.app.session.doc.to_json();
+7 -1
View File
@@ -351,7 +351,13 @@ pub(super) fn named_control<R>(ui: &mut Ui, label: &str, add: impl FnOnce(&mut U
/// Publish geometry without replacing native accessibility. Tokens: `none`.
pub(super) fn publish_geometry(ui: &Ui, response: &Response) {
let label = label(ui);
scenario::publish_target_as(&format!("dialog:{label}"), &format!("dialog:widget:{label}"), response.rect);
scenario::publish_rect(&format!("dialog:widget:{label}"), response.rect);
// A click lands where the field shows: a field scrolled out of a dialog's field area, under
// its footer, has no handle (a click at its centre would press the button over it).
let shown = response.rect.intersect(ui.clip_rect());
if shown.is_positive() {
scenario::publish_handle(&format!("dialog:{label}"), shown.center());
}
}
#[cfg(test)]