GUI contextual menu

To make GUI Scripting and access the contextual menu could be tricky.

I have test this on Safari and Finder and every application is different.

This example use ‘Finder’ so the first line in the code will activate it.
activate application “Finder”

This is the code that give the information we need.

tell application "System Events"
	set theApplication to first application process whose frontmost is true
	set theControl to value of attribute "AXFocusedUIElement" of theApplication
end tell

This is the result of the above code.

We will copy the code from outline 1 → window and include 1 so we will have a line of this

and include in the end of above line with

Now we will have a function to access contextual menu in ‘Finder’

tell application "System Events" to tell application process "Finder"
	set frontmost to true
	tell outline 1 of scroll area 1 of splitter group 1 of splitter group 1 of window 1 to perform action "AXShowMenu"
end tell

It could be a good advice to select a item first in Finder before execute below code.

tell application "System Events" to tell application process "Finder"
    activate
    --> COPY THE CODE BELOW TO HERE 
end tell

To access the ‘Services’ menu could look like this…

tell window 1
		tell splitter group 1
			tell splitter group 1
				tell scroll area 1
					tell outline 1
						perform action "AXShowMenu"
						tell menu 1
							get the name of every menu item
							{"Open in New Tab", "Open in New Window", missing value, "Move to Trash", missing value, "Rename", "Compress", "Compress", "Quick Actions", missing value, "Copy “”", "Import from iPhone", missing value, "Use Groups", "Sort By", "Show View Options", missing value, missing value, missing value, "Services"}
							click menu item "Services"
						end tell
					end tell
				end tell
			end tell
		end tell
	end tell


Very useful snippet. Thanks.

Before that, I used the “Follow me…” function (that is, recording user actions) of the Automator application. As I can see, with the help of your simple snippet, everything is simpler and faster.

Only I would have improved it a little. It is necessary to hide the script editor itself in the background. Then your script can be used as is, from script editor. Now I will show how this can be done (assuming that the needed process was frontmost before running the script editor process itself):


set ScriptEditors to {"Script Editor", "Script Debugger", "Smile", "ThisApp"}

tell application "System Events"
	set myFrontMost to name of the first process whose frontmost is true
	if myFrontMost is in ScriptEditors then set visible of process myFrontMost to false
	set theApplication to first application process whose frontmost is true
	set theControl to value of attribute "AXFocusedUIElement" of theApplication
end tell

Now, no need to activate again the application with hardcoded name before running the script (or script application). To experiment, right-click on above snippet here (on web page) to open contextual menu. Then run my script in the script editor. You should get this AXWebArea:

UI element 1 of scroll area 1 of group 1 of group 1 of tab group 1 of splitter group 1 of window “MacScripter / GUI contextual menu” of application process “Safari”

With hardcoded activation makes little sense finding the frontmost process, because you can do this:


set appName to "Safari"

tell application appName to activate
tell application "System Events" to ¬
	set theControl to value of attribute "AXFocusedUIElement" of application process appName

There is not so much information here on Attribute AXFocusedUIElement

Also when I did so much GUI Scripting, I run…

get its properties of UI elements
get its properties of attributes

I also did

perform action “AXShowMenu”

and after ask for properties.

Sometimes the information I look for are hidden in menu somewhere and need to be activated
before extractions could happen. Thats why it’s so easy to break GUI Scripting if wrong
element are active one.

Recently i discover that if I comment out a pop up button in Numbers the pop up button that
are still in the code will have different index number. It means the index will change
and not be the same.

I got lot of information and I was wonder what AXFocusedUIElement was all about.

===>

But one day I find information on Apple’s AppleScript List and from Stackoverflow
https://stackoverflow.com/questions/55204783/axfocuseduielement-does-not-get-focused-element-folder-file-it-points-t

You did something similar in this post
https://macscripter.net/viewtopic.php?pid=196969#p196969

Here is other post
https://macscripter.net/viewtopic.php?pid=148834#p148834

I thought a little and realized that the code I proposed (to hide used script editor or AppleScript application) can be further improved. It will allow you to analyze other script editors from the script editor or AppleScript application used, unlike my previous script:


set theFrontMost to name of current application

tell application "System Events"
	set visible of process theFrontMost to false
	set theFrontMost to first application process whose frontmost is true
	set theControl to value of attribute "AXFocusedUIElement" of theFrontMost
end tell

I have use this to also include the class of UI element

axFocusedUIElement("APPLICATION_NAME")

on axFocusedUIElement(_appName)
	activate application _appName
	tell application "System Events"
		set theApplication to first application process whose frontmost is true
		set theControl to value of attribute "AXFocusedUIElement" of theApplication
		tell theControl to set {theClass} to {its class of UI element}
	end tell
end axFocusedUIElement