fix: compare AX elements via CFEqual in web_action_had_effect

AXUIElementCopyAttributeValue follows the CoreFoundation Create rule
and returns a freshly-allocated CF object on every call, so raw
pointer equality (`before.0 != after.0`) between two separate copies
of AXFocusedUIElement was ALWAYS true even when the focused element
was unchanged. That made Step 1 (AXPress) of activate_web_element
appear successful every time and left Steps 2-4 of the escalation
chain (AXConfirm bypass, child actions, CGClick fallback) dead code
on web elements.

Replace the pointer comparison with CFEqual, which compares
accessibility element identity rather than heap addresses.
This commit is contained in:
Lahfir 2026-04-14 00:47:57 -07:00
parent 0fcf4e8627
commit ae78cbc0f9

View file

@ -135,16 +135,13 @@ mod imp {
.is_ok()
}
/// Check if a web action actually changed something in the app.
/// Compares the focused UI element before vs after — if the app's
/// focused element changed, the action had a real DOM effect.
fn web_action_had_effect(app: &AXElement, focused_before: Option<&AXElement>) -> bool {
use core_foundation::base::{CFEqual, CFTypeRef};
let focused_after = crate::tree::copy_element_attr(app, "AXFocusedUIElement");
match (focused_before, &focused_after) {
(Some(before), Some(after)) => {
// Different element pointers = focus moved = real effect
before.0 != after.0
}
(Some(before), Some(after)) => unsafe {
CFEqual(before.0 as CFTypeRef, after.0 as CFTypeRef) == 0
},
(None, Some(_)) => true,
_ => false,
}