Clicking an applications menu bar item with AppleScript - applescript

I use Time Tracker For Mac as my, well, time tracker. It has a menu bar item which I want to be able to access via keyboard shortcut.
I found a way to click the item with GUI scripting:
tell application "System Events" to tell process "Time Tracker"
click menu bar item of menu bar 2
end tell
Unfortunately the script does not return success unless I acted on the menu (i.e. pressing Enter or Esc key). So if I want to trigger the down arrow key...
tell application "System Events" to tell process "Time Tracker"
click menu bar item of menu bar 2
-- hangs here forever until menu is closed
tell application "System Events" to key code 124
end tell
the script just waits forever. If I hit escape the menu bar item closes and only then the down arrow key will be triggered.
It's kind weird. I just need the menu bar item's click to not block further script execution.
Any suggestions?

The click command returns after about 5 seconds for me. One workaround is to use ignoring application responses and terminate System Events:
ignoring application responses
tell application "System Events" to tell process "Time Tracker"
click menu bar item 1 of menu bar 2
end tell
end ignoring
do shell script "killall System\\ Events"
delay 0.1
tell application "System Events" to tell process "Time Tracker"
tell menu bar item 1 of menu bar 2
click menu item 2 of menu 1
end tell
end tell
Related questions:
Applescript: on clicking Menu Bar item via gui script
Is AppleScript UI Scripting very slow in general, or is it my script, or something else?

Actually, the key code for the down arrow seems to be 125. Try this:
tell application "System Events" to tell process "Time Tracker"
click menu bar item of menu bar 2
key code 125
key code 36
end tell
There is a short delay (a couple of seconds) after the click menu bar... command, I don't know why.

Related

Applescript clicking unknown menu item?

I'm using the LG OnScreen Control app to switch between different monitor layouts which have no names in the menu item as it uses pictures. I want to write an applescript that clicks either the first one or the 9th one, my favourite selections. =)
How can I click them? I only managed to select them with the below code
ignoring application responses
tell application "System Events" to tell process "OnScreen Control"
click menu bar item 1 of menu bar 2
end tell
end ignoring
delay 0.1
do shell script "killall System\\ Events"
tell application "System Events" to tell process "OnScreen Control"
tell menu bar item 1 of menu bar 2
click menu item "Screen Split" of menu 1
end tell
end tell
UPDATE1: Ah silly me, I figured I can use "key code 125" several times to click the down arrow and "key code 76" to hit enter.
ignoring application responses
tell application "System Events" to tell process "OnScreen Control"
click menu bar item 1 of menu bar 2
end tell
end ignoring
delay 0.1
do shell script "killall System\\ Events"
tell application "System Events" to tell process "OnScreen Control"
tell menu bar item 1 of menu bar 2
click menu item "Screen Split" of menu 1
key code 125
key code 125
key code 125
key code 125
key code 125
key code 125
key code 125
key code 125
key code 76
end tell
end tell
Wondering though if there is a better and quicker way to execute this? Addressing the sub-items directly despite not having a name?
UDPATE2 with solution thanks to #user3439894
ignoring application responses
tell application "System Events" to tell process "OnScreen Control"
click menu bar item 1 of menu bar 2
end tell
end ignoring
delay 0.1
do shell script "killall System\\ Events"
tell application "System Events" to tell process "OnScreen Control"
tell menu bar item 1 of menu bar 2
click menu item "Screen Split" of menu 1
click menu item 9 of menu 1 of menu item "Screen Split" of menu 1
end tell
end tell
After:
click menu item "Screen Split" of menu 1
Use:
click menu item 9 of menu 1 of menu item "Screen Split" of menu 1
Getting rid of all the key code commands

Applescript to click menu item of status bar app

I have an app called Fenêtre, when looking process name using top command it gives the name Fene?~Btre H.
I would like to click the item called 'a.py' under its menubar item as shown in figure.
My attempt:
attempt 1
tell application "System Events" to tell process "Fenêtre"
tell menu bar item 1 of menu bar 1
click
click menu item "Show all" of menu 1
end tell
end tell
Error:
$ osascript a.applescript
a.applescript:121:157: execution error: System Events got an error: Can’t get menu item "Show all" of menu 1 of menu bar item 1 of menu bar 1 of process "Fenêtre". (-1728)
Note that, when I run only first and last line of attemp1 it runs good, when I add middle lines it fails to run.
attempt 2
ignoring application responses
tell application "System Events" to tell process "Fenêtre"
click menu bar item 1 of menu bar 2
end tell
end ignoring
do shell script "killall System\\ Events"
delay 0.1
tell application "System Events" to tell process "Fenêtre"
tell menu bar item 1 of menu bar 2
click menu item "a.py" of menu 1
-- click menu item 1 of menu 1 -- another try
end tell
end tell
Updates (Still get errors)
tell application "System Events" to tell process "Fenêtre"
get entire contents of menu bar 2
end tell
This gives:
{menu bar item 1 of menu bar 2 of application process "Fenêtre" of application "System Events"}
References:
Applescript: on clicking Menu Bar item via gui script
applescript click menu bar option
https://superuser.com/questions/587815/can-applescript-osascript-be-used-to-click-menu-extra-menu-items
Applescript to show Apple menu bar items
Is AppleScript UI Scripting very slow in general, or is it my script, or something else?
Clicking an applications menu bar item with AppleScript
Thanks a lot.
Use a bundle identifier instead of the app name:
tell application "System Events"
tell (first application process whose bundle identifier is "BUNDLE_IDENTIFIER_HERE")
tell menu bar item 1 of menu bar 1
click
click menu item "Show all" of menu 1
end tell
end tell
end tell

Using AppleScript to navigate menu bar item

I have made an AppleScript to interact with a menu bar item (NordVPN). Basically, it clicks the item, selects connect or disconnect, and that's it.
In developing this, I followed some advice in a response found here
It worked a couple of times, but now it just hangs and keeps "Running". Nothing is happening. I am wondering if the ignore responses is an issue? This was done to prevent a 5 second delay between clicks. Or could the two tries cause issue? I'm trying to ensure the script runs, whether there's "Connect" or "Disconnect".
Any advice is helpful. If someone has a suggestion for a better way to do this, I'll appreciate it. Thanks
Here's the code:
ignoring application responses
tell application "System Events" to tell process "NordVPN IKE"
click menu bar item 1 of menu bar 2
end tell
end ignoring
do shell script "killall System\\ Events"
delay 0.1
tell application "System Events" to tell process "NordVPN IKE"
tell menu bar item 1 of menu bar 2
try
click menu item "Connect" of menu 1
end try
try
click menu item "Disconnect" of menu 1
end try
end tell
end tell
EDIT: And now it's working again. It seems to work some of the time... But I cannot figure out why it stops working other times.
EDIT 2: It appears the issue arises when the Mac goes to sleep. When I wake it back up and try to run the script, it hangs. But if I manually click the menu bar item and then run the script, it'll work.
This works for me using the latest version of macOS high Sierra. Maybe this code will work a little better for you.
set disconnectExists to false
set connectExists to false
ignoring application responses
tell application "System Events"
launch application "NordVPN IKE"
delay 1
click menu bar item 1 of menu bar 2 of application process "NordVPN IKE"
end tell
end ignoring
do shell script "killall System\\ Events"
tell application "System Events"
repeat until disconnectExists or connectExists is true
set disconnectExists to menu item "Disconnect" of menu 1 of menu bar item 1 of menu bar 2 ¬
of application process "NordVPN IKE" exists
set connectExists to menu item "Connect" of menu 1 of menu bar item 1 of menu bar 2 ¬
of application process "NordVPN IKE" exists
end repeat
try
if connectExists is true then
delay 0.2
click menu item "Connect" of menu 1 of menu bar item 1 of menu bar 2 of ¬
application process "NordVPN IKE"
else if disconnectExists is true then
delay 0.2
click menu item "Disconnect" of menu 1 of menu bar item 1 of menu bar 2 of ¬
application process "NordVPN IKE"
end if
end try
end tell

Speed up AppleScript UI scripting?

I'm using NetShade as a proxy service and thought I could try to automate the switching between the different proxies as a nice start for my first AppleScript script.
The NetShade-app has no AppleScript support, so I have to use UI scripting. After a few tries (and some posts here) I managed to have a script, that switches the proxies via the menu bar item (here is a picture of it, since I can't post it inline due to reputation limit).
Unfortunately my code is extremely slow (≈6sec), which makes it kind of impractical as a script. The first menu opens immediately, but the selection of the sub-menu and the proxy server takes several seconds.
I'm using the following code:
set theProxy to "Netshade US 4"
tell application "System Events" to tell process "NetShade"
tell menu bar item 1 of menu bar 2
click
tell menu item "NetShade Proxy" of menu 1
click
tell menu item theProxy of menu 1
click
end tell
end tell
end tell
end tell
I already tried to add ignoring application responses, like suggested in a different thread (link), but that didn't help.
So finally my questions:
Is there a way to speed the process up? Maybe even a way to do all this in the background, without showing the menu items?
P.S.: I'm running OS X 10.9.1
Summary of the fix
To remove delay you need to do two things:
(I) Identify the click which is causing the delay and enclose only that line in the ignoring application responses block as shown below. In my case, it was click bt after which the execution was going into a wait mode for 5 to 6 seconds.
ignoring application responses
click bt
end ignoring
(II) I then also had to kill System Events to and start it again using the following commands.
do shell script "killall System\\ Events"
delay 0.1
-- Rest of the code to click stuff or send keycodes
This resolved the delay issue.
Details
I was having the same problem where I created a script to connect/disconnect my bluetooth headset through AppleScript. The script is given below.
tell application "System Events" to tell process "SystemUIServer"
set bt to (first menu bar item whose description is "bluetooth") of menu bar 1
click bt
tell (first menu item whose title is "SBH80") of menu of bt
click
tell menu 1
if exists menu item "Disconnect" then
click menu item "Disconnect"
else
click menu item "Connect"
end if
end tell
end tell
end tell
The script was working fine but had a problem where it would wait for 5 to 6 seconds after executing "click bt" above. I modified the code as follows and it is working absolutely fine now without any delay.
tell application "System Events" to tell process "SystemUIServer"
set bt to (first menu bar item whose description is "bluetooth") of menu bar 1
ignoring application responses
click bt
end ignoring
end tell
do shell script "killall System\\ Events"
delay 0.1
tell application "System Events" to tell process "SystemUIServer"
tell (first menu item whose title is "SBH80") of menu of bt
click
tell menu 1
if exists menu item "Disconnect" then
click menu item "Disconnect"
else
click menu item "Connect"
end if
end tell
end tell
end tell

Applescript: on clicking Menu Bar item via gui script

I'm trying to make an applescript for an application called F.lux that clicks the menu item "Disable for an Hour" as indicated in the screenshot below:
The element path is indicated in the screenshot below:
Here is my code thus far:
tell application "System Events"
tell process "Flux"
click (menu bar item 1 of menu bar 2)
click menu item "Disable for an hour" of menu 1 of menu bar item 1 of
menu bar 2
end tell
end tell
Everything compiles fine, however I keep getting the error message below when I attempt to run the script:
error "System Events got an error: Can’t get menu 1 of menu bar item 1 of menu bar 2 of process "Flux". Invalid index." number -1719 from menu 1 of menu bar item 1 of menu bar 2 of process "Flux"
Can someone pinpoint where I'm going wrong with this?
This worked for me, but there is a delay of about 5 seconds after the first click command.
tell application "System Events" to tell process "Flux"
tell menu bar item 1 of menu bar 2
click
click menu item "Disable for an hour" of menu 1
end tell
end tell
One workaround is to use ignoring application responses and terminate System Events after the click command:
ignoring application responses
tell application "System Events" to tell process "Flux"
click menu bar item 1 of menu bar 2
end tell
end ignoring
do shell script "killall System\\ Events"
delay 0.1
tell application "System Events" to tell process "Flux"
tell menu bar item 1 of menu bar 2
click menu item "Disable for an hour" of menu 1
end tell
end tell

Resources