Hi, Yvan.
I guessed that would probably be the case, given your previous experience. I’m beginning to believe that GUI Scripting is inherently unreliable, as several people have reported that GUI scripts of mine that should work “ and do work on my machine “ don’t work for them. I’ve no reason to believe that there’s anything wrong with my system or with theirs.
Interestingly, although ‘first menu bar item of menu bar 1 whose value of attribute “AXDescription” is “text input menu extra”’ works perfectly well for me in the “keyboard layout” script, the same construction doesn’t work for me in some other scripts. For instance, one way to identify the “Copy” item in an “Edit” menu is to find the menu item whose attribute “AXMenuItemCmdChar” has a value of “C”. (This indicates the character used for the menu item’s Command-keystroke equivalent. For completeness, we should also check that its attribute “AXMenuItemCmdModifiers” has a value of 0, but let’s ignore that for now.) Take this script:
tell application "System Events"
tell application process "TextEdit"
set frontmost to true
name of first menu item of menu 1 of menu bar item 4 of menu bar 1 whose value of attribute "AXMenuItemCmdChar" is "C"
end tell
end tell
Since the filter ‘. whose value of attribute “AXDescription” is “text input menu extra”’ works for me in the keyboard layout script, you’d expect ‘. whose value of attribute “AXMenuItemCmdChar” is “C”’ to work for me too. But in fact it doesn’t. The above script returns “Select All” instead of “Copy”. This accords with kai’s explanation, since “Select All” is the tenth menu item in the “Edit” menu and “AXMenuItemCmdChar” is the tenth attribute in each menu item’s list of attributes. However, if I replace the attribute’s name with its index number, the script returns the result I want:
tell application "System Events"
tell application process "TextEdit"
set frontmost to true
name of first menu item of menu 1 of menu bar item 4 of menu bar 1 whose value of attribute 10 is "C"
end tell
end tell
Since I don’t quite trust attributes to have particular positions in attribute lists, I currently prefer this:
tell application "System Events"
tell application process "TextEdit"
set frontmost to true
name of first menu item of menu 1 of menu bar item 4 of menu bar 1 whose value of attributes contains "C" and value of attributes contains 0
end tell
end tell
Feeding these ideas back into the “keyboard layout rotation” script, do either of these work for you? (Only their third lines differ.)
tell application "System Events"
tell application process "SystemUIServer"
tell (first menu bar item of menu bar 1 whose value of attribute 4 is "text input menu extra")
set currentKeyboard to its value
perform action "AXPress"
(*repeat until (menu 1 exists)
delay 0.2
end repeat*)
set menuItems to name of menu items of menu 1
repeat with i from 1 to (count menuItems)
if (item i of menuItems is currentKeyboard) then
set n to i + 1
if (item n of menuItems is missing value) then set n to 1
perform action "AXPress" of (menu item n of menu 1)
exit repeat
end if
end repeat
end tell
end tell
end tell
tell application "System Events"
tell application process "SystemUIServer"
tell (first menu bar item of menu bar 1 whose value of attributes contains "text input menu extra")
set currentKeyboard to its value
perform action "AXPress"
(*repeat until (menu 1 exists)
delay 0.2
end repeat*)
set menuItems to name of menu items of menu 1
repeat with i from 1 to (count menuItems)
if (item i of menuItems is currentKeyboard) then
set n to i + 1
if (item n of menuItems is missing value) then set n to 1
perform action "AXPress" of (menu item n of menu 1)
exit repeat
end if
end repeat
end tell
end tell
end tell