How to get Information of a Selected UI Element? - user-interface
How can I get identify the UI element in AppleScript?
In AppleScript it is possible to make a click on to an UI element like this:
click item 1 of text field 1 of sheet 1 of window 1 of application process "Umsatz" of application "System Events"
But is it also possible to read the active element?
Screenshot shows an active UI element
Here's a handler that will return a record of all the properties, attributes, and actions belonging to a specific UI element:
on info about UIElement
set my text item delimiters to linefeed & linefeed
tell application id "com.apple.SystemEvents" to script Object
property parent : UIElement
property AXAttributes : a reference to my (the ¬
attributes whose name ≠ "AXURL")
property AXValues : value of AXAttributes
property AXRecord : a reference to the ¬
contents of {«class usrf»:my AXList}
property AXList : name of AXAttributes
end script
tell (a reference to the Object's AXList) to set the ¬
contents to paragraphs of (it as text) & ""
tell the Object to repeat with i from 1 to length of its AXValues
set item (i * 2) of its AXList to ¬
item i of its AXValues
end repeat
tell application id "com.apple.SystemEvents" to return ¬
{UI element:the Object's contents} & the properties ¬
of the Object & (the Object's AXRecord as any) & ¬
{_AXActions:every action's name of the Object}
end info
To use it, you pass it the reference of a particular UI element, such as that which is returned by the click or click at commands. In your case, this could be:
tell application id "com.apple.systemevents" to tell process "Umsatz"
return info about window 1's sheet 1's text field 1's ui element 1
It will only work on single elements, so passing it a collection of elements will throw an error. Upon success, you'll get a result like this one returned detailing information about my window in Script Editor when running the following command:
tell application id "com.apple.systemevents" to tell process ¬
"Script Editor" to return my info about window 1
Result:
{UI element:window "Untitled 161.scpt" of application
process "Script Editor" of application "System Events",
minimum value:missing value, orientation:missing value,
position:{1000, 25}, class:window, accessibility
description:missing value, role description:"standard
window", focused:false, title:"Untitled 161.scpt",
size:{623, 1095}, help:missing value, entire contents:{},
enabled:missing value, maximum value:missing value,
role:"AXWindow", value:missing value,
subrole:"AXStandardWindow", selected:missing value,
name:"Untitled 161.scpt", description:"standard window",
AXFocused:false, AXFullScreen:false, AXTitle:"Untitled
161.scpt", AXChildrenInNavigationOrder:{application "System
Events", application "System Events", application "System
Events", application "System Events", application "System
Events", application "System Events", application "System
Events", application "System Events", application "System
Events", application "System Events", application "System
Events"}, AXFrame:{1000, 25, 1623, 1120}, AXPosition:{1000,
25}, AXGrowArea:missing value, AXMinimizeButton:button 3 of
window "Untitled 161.scpt" of application process "Script
Editor" of application "System Events",
AXDocument:"file:///Users/CK/Library/Mobile%20Documents/com~
apple~ScriptEditor2/Documents/Untitled%20161.scpt",
AXSections:{{SectionUniqueID:"AXToolbar",
SectionDescription:"Toolbar"},
{SectionUniqueID:"AXContent",
SectionDescription:"Content"},
{SectionUniqueID:"AXTopLevelNavigator",
SectionDescription:"Top Level Navigator"}},
AXCloseButton:button 1 of window "Untitled 161.scpt" of
application process "Script Editor" of application "System
Events", AXMain:true, AXActivationPoint:{1010, 39},
AXFullScreenButton:button 2 of window "Untitled 161.scpt"
of application process "Script Editor" of application
"System Events", AXProxy:missing value,
AXDefaultButton:missing value, AXMinimized:false,
AXChildren:{group 1 of window "Untitled 161.scpt" of
application process "Script Editor" of application "System
Events", busy indicator 1 of window "Untitled 161.scpt" of
application process "Script Editor" of application "System
Events", static text "Running…" of window "Untitled
161.scpt" of application process "Script Editor" of
application "System Events", radio group 1 of window
"Untitled 161.scpt" of application process "Script Editor"
of application "System Events", splitter group 1 of window
"Untitled 161.scpt" of application process "Script Editor"
of application "System Events", toolbar 1 of window
"Untitled 161.scpt" of application process "Script Editor"
of application "System Events", tab group "tab bar" of
window "Untitled 161.scpt" of application process "Script
Editor" of application "System Events", button 1 of window
"Untitled 161.scpt" of application process "Script Editor"
of application "System Events", button 2 of window
"Untitled 161.scpt" of application process "Script Editor"
of application "System Events", button 3 of window
"Untitled 161.scpt" of application process "Script Editor"
of application "System Events", static text "Untitled
161.scpt" of window "Untitled 161.scpt" of application
process "Script Editor" of application "System Events"},
AXRole:"AXWindow", AXParent:application process "Script
Editor" of application "System Events",
AXTitleUIElement:static text "Untitled 161.scpt" of window
"Untitled 161.scpt" of application process "Script Editor"
of application "System Events", AXCancelButton:missing
value, AXModal:false, AXSubrole:"AXStandardWindow",
AXZoomButton:button 2 of window "Untitled 161.scpt" of
application process "Script Editor" of application "System
Events", AXRoleDescription:"standard window", AXSize:{623,
1095}, AXToolbarButton:missing value,
AXIdentifier:"_NS:794", _AXActions:{"AXRaise"}}
Focused UI Elements of front window may be more than 1. That is, it may be list of focused UI Elements. The element you need will in most cases be the element deepest in the structure.
I tested script in the Safari with Login window of our Stack Overflow site. To test like me, open Login form, tape in the some text field of this form (to make it focused), run script.
on getDeeppestFocusedUIelement(processName)
tell application "System Events" to tell process processName
set frontmost to true
repeat until window 1 exists
delay 0.1
end repeat
repeat with UIElement in reverse of (get entire contents of window 1)
try
if focused of UIElement then return (contents of UIElement)
end try
end repeat
end tell
return {}
end getDeeppestFocusedUIelement
set focusedUIElement to getDeeppestFocusedUIelement("Safari")
Related
How to click the checkbox of a System Preferences UI element by name
I've got a piece of Applescript that is currently functional and clicks a checkbox in System Prefs > Security & Privacy > Contacts. However, right now it only works because I am explicitly stating the row of the app that I'm targeting (in this case, row 2). This works fine for now, but if in the future I end up with a different app order in that pane, it will break. Is there a way to loop through all the items of a given window and say "if UI element is Alfred 4.app, then click the checkbox"? I'd like to harden the code so that it will work regardless of which order the apps are listed in this pane. set appName to "Alfred 4.app" tell application "System Preferences" activate set the current pane to pane id "com.apple.preference.security.Privacy_Contacts" delay 1 end tell tell application "System Events" click checkbox 1 of UI element appName of row 2 of table 1 of scroll area 1 of group 1 of tab group 1 of window "Security & Privacy" of application process "System Preferences" end tell
Following script is tested on the Catalina: set appName to "Alfred 4.app" tell application "System Preferences" activate reveal anchor "Privacy_Contacts" of pane id "com.apple.preference.security" end tell delay 1 tell application "System Events" to tell process "System Preferences" repeat with aRow in (rows of table 1 of scroll area 1 of group 1 of tab group 1 of window "Security & Privacy") if name of UI element 1 of aRow is appName then click checkbox 1 of UI element 1 of aRow exit repeat end if end repeat end tell
Using AppleScript to uncheck HDR in system preferences
I have a 4K HDR Monitor, and sometimes Macbook causes the colors to be washed, the fix is to Disable and then Re-Enable HDR. I am trying to create an AppleScript to then incorporate that in Automator to do so. I was able to get some traction but not able to identify how to do the actual uncheck and identify the group. Here is what i had so far: tell application "System Preferences" activate delay 2 set the current pane to pane id "com.apple.preference.displays" delay 2 tell application "System Events" click checkbox "High Dynamic Range" of group 2 of window "LG HDR 4K" of application process "System Preferences" end tell quit end tell Here is the error I get: error "System Events got an error: Can’t get group 2 of window \"LG HDR 4K\" of application process \"System Preferences\". Invalid index." number -1719 from group 2 of the window "LG HDR 4K" of application process "System Preferences" here is a screenshot of the page I am trying to uncheck and re-check HDR: Any advice would be appreciated, thank you.
I don't have a high-def display, so I don't see this particular option, but if I run the following code, I get a full list of all the subelements of the window: tell application "System Preferences" activate delay 2 set the current pane to pane id "com.apple.preference.displays" delay 2 tell application "System Events" tell window 1 of application process "System Preferences" entire contents end tell end tell end tell Subelements you are interested in seem to have the following form: radio button "Scaled" of tab group 1 of window "Built-in Retina Display" of application process "System Preferences" of application "System Events" Note that it includes a tab group 1 entry (referring to the fact that you are on the 'Display' tab of the four tabs available which is missing from your chain.
The Display pane UI layout has changed a bit in macOS Monterey, and now looks like this: Display Prefs UI Layout In my case I wanted to enable HDR on my second monitor, so using the following code I was able to get Script Editor to test whether the High Dynamic Range checkbox was true or false, and if false to enable it: tell application "System Preferences" activate delay 1 set the current pane to pane id "com.apple.preference.displays" delay 1 tell application "System Events" click button "Display Settings…" of window "Displays" of application process "System Preferences" of application "System Events" delay 1 tell sheet 1 of window 1 of application process "System Preferences" select row 2 of outline 1 of scroll area 1 set theCheckbox to checkbox "High Dynamic Range, Automatically adjust the display to show high dynamic range content." tell theCheckbox set checkboxStatus to value of theCheckbox as boolean if checkboxStatus is false then click theCheckbox end tell end tell end tell end tell If I wanted to select a different monitor, I would change the index of "row 2" in this line: select row 2 of outline 1 of scroll area 1 of sheet 1 of window "Displays" of application process "System Preferences" of application "System Events"
change screen resolution with AppleScript
I am trying to click at radio buttons in Displays panel of System Prefernces, namely to change Screen resolution. This is the code I use to identify radio buttons: tell application "System Preferences" activate reveal anchor "displaysDisplayTab" of pane id "com.apple.preference.displays" end tell tell application "System Events" tell application process "System Preferences" set frontmost to true get every radio button of window 0 --click button 1 of window 0 of application process "System Preferences" of application "System Events" --click radio button "Scaled" of radio group of window "com.apple.preference.displays" end tell end tell The radio buttons returned are none. Based on what I see, window has zero radio buttons. This leads to a conclusion that radio buttons are part of sub window, namely the Displays subwindow and not the main window. How can I navigate to this "subwindow" and click radiobuttons?
The radio buttons are part of the radio group. The radio group is part of the tab group. Here's the script: tell application "System Preferences" activate reveal anchor "displaysDisplayTab" of pane id "com.apple.preference.displays" end tell tell application "System Events" tell application process "System Preferences" set frontmost to true tell tab group 1 of window 1 click radio button 2 of radio group 1 -- "Scaled" select row 2 of table 1 of scroll area 1 -- select the second row in the table to change the resolution of the monitor end tell end tell end tell
For Mac OS 10.15, you'll need this instead. Set 'q' to the display button preference you want (1-4) set tabNum to q as number tell application "System Preferences" to reveal pane "com.apple.preference.displays" tell application "System Events" to tell process "System Preferences" set activeWindow to window 1 repeat until exists activeWindow end repeat set tabGroup to tab group 1 of activeWindow tell tabGroup to click radio button "Scaled" set subGroup to group 1 of tabGroup set radioGroup to radio group 1 of subGroup tell radioGroup to click radio button tabNum --log activeWindow --delay 0.5 tell application "System Preferences" quit end tell end tell
Localized menu bar item strings in iTunes
The following code will disable shuffle mode in iTunes: tell application "System Events" tell process "iTunes" click menu item "Off" of menu 1 of menu item "Shuffle" of menu 1 of menu bar item "Controls" of menu bar 1 end tell end tell However it only works if the system language is English. I would prefer not to use indices, so I tried using localized string of on "Off", "Shuffle" and "Controls", but it doesn't seem to work. Test code: tell application "iTunes" to get localized string of "Shuffle" Is there another way of getting the localized string or at least avoid having to hardcode the menu bar item indices?
You need to know the key's name because iTunes don't use the english menu's title as the key name. To know the key name (the "Localizable.strings" file in the iTunes bundle is a plist format): Open the TextWrangler application, drag the "/Applications/iTunes.app/Contents/Resources/English.lproj/Localizable.strings" file and drop it on the icon of the TextWrangler application. Search "string>Shuffle<" in the document to get the key name. set iTunesPath to "/Applications/iTunes.app" as POSIX file as alias set contr to localized string "8d2vvyy7c7" in bundle iTunesPath set shuf to localized string "atmqaez8y8" in bundle iTunesPath set off to localized string "ve0frz64yk" in bundle iTunesPath activate application "iTunes" tell application "System Events" tell process "iTunes" click menu item off of menu 1 of menu item shuf of menu 1 of menu bar item contr of menu bar 1 end tell end tell
I opened the Accessibility Inspector in Xcode's Development Tools to see what objects I could find enumerating through UI elements First I ran this to get a good idea, which returns the name I need to start, menu bar 1 tell application "System Events to tell process "iTunes" UI elements end tell After this you can get a list of elements to work with, once you run tell menu bar 1 to display its UI elements. {menu bar item "Apple" of menu bar 1 of application process "iTunes" of application "System Events", menu bar item "iTunes" of menu bar 1 of application process "iTunes" of application "System Events", menu bar item "File" of menu bar 1 of application process "iTunes" of application "System Events", menu bar item "Edit" of menu bar 1 of application process "iTunes" of application "System Events", menu bar item "View" of menu bar 1 of application process "iTunes" of application "System Events", menu bar item "Controls" of menu bar 1 of application process "iTunes" of application "System Events", menu bar item "Store" of menu bar 1 of application process "iTunes" of application "System Events", menu bar item "Window" of menu bar 1 of application process "iTunes" of application "System Events", menu bar item "Help" of menu bar 1 of application process "iTunes" of application "System Events"} I'm thinking next you could do use what is returned here to iterate through and find the item, store this in a variable and make it less dependent on name, since the index won't change based on the language and this can be verified in Accessibility Inspector which will show object references. I tried something along these lines: tell menu bar 1 set a to UI Elements return item 6 of a end tell Output: menu bar item "Controls" of menu bar 1 of application process "iTunes" of application "System Events" All right, going further you will want to find the specific menu item and value. Which values are being affected by the language changes too. tell application "System Events" to tell process "iTunes" tell menu bar 1 set a to UI elements set b to item 6 of a set c to UI elements of b -- c = {menu "Controls" of menu bar item "Controls" of menu bar 1 of application process "iTunes" of application "System Events"} tell menu "Controls" set d to item 16 of UI elements tell menu "Shuffle" of d --click menu item 1 (On) --click menu item 2 (Off) end tell end tell end tell end tell
in the GUI script below, why isn't "click button "Advanced..." working?
tell application "System Preferences" activate end tell tell application "System Events" set preferencesLocked to false tell process "System Preferences" delay 1 click menu item "Security & Privacy" of menu "View" of menu bar 1 delay 2.5 if title of button 4 of window 1 is "Click the lock to make changes." then set preferencesLocked to true click button "Click the lock to make changes." of window 1 end if end tell if preferencesLocked is true then delay 2.5 activate application "SecurityAgent" tell application "System Events" tell process "SecurityAgent" set value of text field 1 of scroll area 1 of group 1 of window 1 to "admin" set value of text field 2 of scroll area of group 1 of window 1 to "XXXXXXX" click button "Unlock" of group 2 of window 1 tell application "System Events" tell process "SecurityAgent" **click button "Advanced..."** end tell end tell end tell end tell end if end tell
You just have to replace the three periods with an ellipsis character: tell application "System Preferences" reveal pane id "com.apple.preference.security" activate end tell tell application "System Events" if title of button 4 of window 1 of process "System Preferences" is "Click the lock to make changes." then click button "Click the lock to make changes." of window 1 of process "System Preferences" delay 5 tell process "SecurityAgent" set value of text field 2 of scroll area 1 of group 1 of window 1 to "password" click button 2 of group 2 of window 1 end tell end if tell process "System Preferences" click button "Advanced…" of window 1 end tell end tell