Thanks for the Swift script, @griffman. It also works in macOS 27.
It works because of one single function:
syntheticClick(at: CGPoint(x: frame.midX, y: frame.midY))
…inside the pressOrClick function…
func pressOrClick(_ element: AXUIElement) -> Bool {
if axPress(element) { return true }
guard let frame = axFrame(element) else { return false }
syntheticClick(at: CGPoint(x: frame.midX, y: frame.midY))
return true
}
For the first two buttons (Markup toolbar and color well), the Swift script runs the axPress(element) branch (i.e., the same as the perform action "AXPress" in the original AppleScript). For the color button itself, where the AXPress of the AppleScript and the axPress(element) of the Swift script fails, it falls back to the syntheticClick(at:….
syntheticClick function
func syntheticClick(at point: CGPoint) {
let source = CGEventSource(stateID: .hidSystemState)
let down = CGEvent(mouseEventSource: source, mouseType: .leftMouseDown,
mouseCursorPosition: point, mouseButton: .left)
let up = CGEvent(mouseEventSource: source, mouseType: .leftMouseUp,
mouseCursorPosition: point, mouseButton: .left)
down?.post(tap: .cghidEventTap)
usleep(30_000)
up?.post(tap: .cghidEventTap)
}
In the AppleScript, I already tried click and click at <button xy> before, but it fails for the color button just like AXPress does.
Siri AI (yes, such a thing exists now
) explains the failure as follows:
The reason your AppleScript click and click at commands are failing—while the Swift script succeeds—comes down to how macOS now handles event routing for transient UI elements like popovers.
Starting in recent macOS versions, System Events attempts to be "helpful" by resolving clicks through the Accessibility API rather than the raw window server. Because the popover explicitly advertises AXPress: none, System Events aborts the click before it even posts a mouse event.
To bypass this in pure AppleScript, you must force the OS to post a raw, hardware-level mouse event (just like the Swift script's CGEvent fallback).
And Siri also provided a working solution, by simply running the relevant function from @griffman’s Swift script inside the old AppleScript:
-- Standalone demo script for ScriptEditor
use scripting additions
set btnIdx to 73
tell application "System Events"
tell application process "Preview"
set frontmost to true
tell first window
tell (first toolbar whose description is "toolbar")
if value of (first checkbox whose description is "Markup") is 0 then
tell (first checkbox whose description is "Markup")
perform action "AXPress"
end tell
end if
end tell
tell (first toolbar whose description is "edit toolbar")
tell (first color well whose description is "Border color")
perform action "AXPress"
tell first pop over
tell (UI element 2 whose description is "grid")
tell button btnIdx
-- perform action "AXPress" -- This fails here!
set btnPos to its position
my syntheticClick(item 1 of btnPos, item 2 of btnPos)
end tell
end tell
end tell
end tell
end tell
end tell
end tell
end tell
on syntheticClick(x, y)
set swiftScript to "import CoreGraphics\n" & ¬
"let down = CGEvent(mouseEventSource: nil, mouseType: .leftMouseDown, mouseCursorPosition: CGPoint(x: " & x & ", y: " & y & "), mouseButton: .left)\n" & ¬
"let up = CGEvent(mouseEventSource: nil, mouseType: .leftMouseUp, mouseCursorPosition: CGPoint(x: " & x & ", y: " & y & "), mouseButton: .left)\n" & ¬
"down?.post(tap: .cghidEventTap)\n" & ¬
"usleep(30000)\n" & ¬
"up?.post(tap: .cghidEventTap)"
do shell script "echo " & quoted form of swiftScript & " | swift -"
end syntheticClick
Here as KM macro:
Preview- Select Border Color (macOS 27).kmmacros (4.1 KB)
But honestly, you can as well use @griffman’s full-Swift script, as it will probably be faster. (In compiled form! See griffman’s instructions.)