Skip to content

native2: never press a web row's nested control on a click (#195) - #210

Merged
iamnbutler merged 3 commits into
mainfrom
fix-click-nested
Oct 25, 2026
Merged

iamnbutler merged 3 commits into
mainfrom
fix-click-nested

Conversation

@iamnbutler

Copy link
Copy Markdown
Contributor

Fixes #195

Root cause. WebKit's AXPress on an ARIA menu item, button, tab, toggle or list item presses the first native <button>/<select>/checkbox inside it (WebCore AccessibilityNodeObject::actionElement → nativeActionElement). Ace's project rows are Base UI role="menuitem" divs with a hover-only <button aria-label="Remove …"> inside, so a point click on the row (which hit-tests to the AXMenuItem and presses it) pressed Remove.

Fix (DesktopMac/Pointer.swift, pressNestedSafely): before pressing a WebKit web element in those roles that holds a button/pop-up/checkbox/radio descendant, the host

  • checks that Accessibility finds the element itself at the click point (WebKit frames for these rows can be wrong, e.g. 70 pt tall rows), else refuses;
  • sends a real left click routed to the exact window at the point when that window is the key window of the active app (WebKit drops the first click into a non-key window), else refuses, naming the nested control.

Every AX press result now carries pressed: {role, label}; the guarded route adds nested_control and a note. Chromium apps are excluded (Chromium presses the node itself).

Checked. Reproduced with a WKWebView fixture running Base UI 1.3 Menu + Tooltip in Ace's row markup, through the standalone host: before, a point click on the "desktop-tools" row logged REMOVE desktop-tools; after, the click is refused with the message naming "Remove desktop-tools" (fixture app inactive), an element-ID click is refused (center lands off the row), a point click on the remove button itself presses it and says pressed: AXButton "Remove desktop-tools", and the menu trigger still presses normally. Routed events reach the page (a routed double click selected the row). Not verified on an active WebKit window, since that would take keyboard focus. Unit tests in PressRedirectTests; swift test passes.

@iamnbutler
iamnbutler force-pushed the fix-click-nested branch 4 times, most recently from b226dc4 to f11fd39 Compare October 25, 2026 00:40
WebKit's AXPress on an ARIA menu item, button, tab or toggle presses the
first native button inside it (WebCore nativeActionElement), so a point
click on an Ace project row pressed its hover-only remove button. Such an
element now gets a pointer click routed to its window at the point when
that window is frontmost and Accessibility finds the element itself there,
and is refused otherwise, naming the nested control. Press results name
what was pressed.

Fixes #195

Why: native2/Sources/DesktopMac/Pointer.swift#pressNestedSafely | WebKit's AXPress on an ARIA menuitem/button/tab presses the first native <button>/<select>/checkbox inside it; never AXPress such a web element
Why: native2/Sources/DesktopMac/Pointer.swift#pressNestedSafely | a routed single click into a WKWebView window that isn't key in the active app is swallowed as first mouse, so it is only sent when the window is frontmost
@iamnbutler
iamnbutler merged commit e8a6ef6 into main Oct 25, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

A background point click on a menu row pressed the row's destructive action instead

1 participant