Can Applescript send arrow keys via key down? - applescript

I am trying to control google earth using the arrow keys, however, I want to do this with applescript. Essentially this code should work and I'll tell you what it actually does.
tell application "System Events"
delay 3
key down 124 #Value of key right
delay 3
key up 124
end tell
This code should wait for me to go to google earth, then it will hold the right arrow key for 3 seconds. However, it just hits 'a'. I saw some recommendations to do the following:
key down (key code 124)
This sort of works, it press the right key only once and does not hold it.
If you do this with a key such as D (also used to navigate right in google earth) it works perfectly. (I think "key down 2" does that).
So my question is, is there a way to actually make the arrow keys work? "Working" here refers to sending a key down event that does not tie down the script and could later be canceled with a key up event. I would really like to be able to control the flight simulator (WASD does not work -- arrow keys do).
Thanks for all suggestions,
Jake

This script presses the right arrow key for 3 seconds:
tell application "System Events"
set now to the seconds of the (current date)
set later to now + 3
if later > 60 then set later to later - 60
repeat while the seconds of the (current date) is not later
key down (key code 124)
end repeat
end tell
I don't know if this will work with Google Earth, but I do know that the script is correct.

Related

Applescript - Looping through System Events is killing my Mac

I have a massive spreadsheet with a titanic number of rows/columns (e.g. ~250 columns, many thousands of rows) that I'm trying to convert into PDFs by looping through each row with AppleScript, copying that row's ~250 variables to TextEdit set to Rich Text (for bold formatting etc), and then using System Events to save the txt as a PDF. Here's a summary of the code:
on run
set initialRow to 1
tell application "System Events"
tell application process "TextEdit"
set frontmost to true
end tell
end tell
repeat
tell application "Microsoft Excel"
-- CLEAR MY ~250 VARIABLES FROM PREVIOUS ROW'S VALUES TO MAKE SURE NOTHING IS CARRIED OVER BY MISTAKE
-- THEN SET MY ~250 VARIABLES TO THE NEXT ROW'S VALUES
if exampleValue is "" then exit repeat
end tell
tell application "TextEdit"
set the text of the front document to ""
-- THEN SET FIRST PARAGRAPH TO MY FIRST VARIABLE PLUS A LINE BREAK SO THEN THERE'S A NEW PARAGRAPH FOR THE NEXT VARIABLE, ETC
-- THEN GO THROUGH ALL OF MY VARIABLES TO IMPORT THE IMPORTANT ONES INTO TEXTEDIT, SET SOME FORMATTING, ETC.
end tell
delay 1
tell application "System Events"
click menu item "Export as PDF…" of menu 1 of menu bar item "File" of menu bar 1 of application process "TextEdit"
delay 1
keystroke exampleValue -- SYSTEM EVENTS TYPES THE NAME OF THE PDF
delay 1
key code 36
delay 1
end tell
set myRow to (myRow + 1)
end repeat
end run
This all runs great, no bugs (seemingly!), no issues at all in small doses. The problem, however, is that something happens as the script runs where it seems to be tying up more and more memory somewhere; everything is fine for the first hundred or so rows, but at some point my Mac stops running anything at all, i.e. whether I let the script run until it starts producing super random errors (I could collect them if helpful, but it's like a random different error each time so not much help there) or even if I let the script run for a while and then stop it before it errors out - it will let me stop the script but then I can't actually quit out of Script Editor or TextEdit or Excel, my keyboard stops working, I can't Force Quit anything, can't Reset the computer, etc. It's just a complete meltdown of the machine unlike anything I've encountered, and the only way to get back to work is to force a hard boot with the power button.
I've never had this problem with my other scripts, but I also don't usually use System Events, so my hunch is that it's something to do with that. Do I need to be 'resetting' System Events somehow, or clearing out the memory for some reason, or...? Thanks for the help!!
Figured it out! After trying the script one more time with Activity Monitor running, I discovered that each time it iterates through, 3 new processes were popping up - Core Sync, Dropbox Finder Extension, and SnailSVNLite - and then never going away! So if I ran through the script 500 times, I'd end up with 1500 new processes running, which was almost certainly what was wrecking me though I have no idea why telling System Events anything was doing that. I looked around online, and it turns out those are all Finder Extensions that had been turned on at some point long ago, so just needed to go to System Preferences > Extensions > Added Extensions and then uncheck those 3 extensions - and then problem solved!!

How to select file using AppleScript in Finder prompt?

I am working with Selenium on macOS to automate sending images using WhatsApp web in Google Chrome. The task involves uploading the image, and for that a system(Finder) prompt comes up to select the file. It's done in Windows using AutoIt.
I tried looking up how to automate this task in macOS, and I believe AppleScript can be used for it. Since I have no experience in GUI scripting, any help would be appreciated.
Thanks.
I was able to find the answer on another post on Stack Overflow. I have added the answer for anyone who comes across the same problem.
tell application "System Events"
keystroke "G" using {command down, shift down}
delay 1
keystroke "/path/to/file"
delay 1
keystroke return
delay 1
keystroke return
delay 1
end tell
I don't advocate GUI scripting any more than the burning down of the Amazon, but it seems to be necessary for this task, and I wanted to provide you with an example of a GUI script that tries its best to minimise the unpleasantness of the user experience, and aim for fewer weak points in the code where GUI scripts are most likely to falter.
If you know the path to your file—which I assume you do in these sorts of situations, as your script keystrokes the filepath—then you might find the following technique saves a few steps, and feels a bit more graceful in how it gets executed:
set filepath to "/path/to/image.jpg"
-- Copy file object to clipboard
set the clipboard to filepath as «class furl»
-- Make sure Chrome is in focus and the
-- active tab is a WhatsApp tab
tell application id "com.google.Chrome"
activate
if the URL of the active tab in the front window ¬
does not contain "web.whatsapp.com" then return
end tell
-- Paste the clipboard contents
-- and hit return (send)
tell application id "com.apple.SystemEvents"
tell (process 1 where it is frontmost) to tell ¬
menu bar 1 to tell menu bar item "Edit" to tell ¬
menu 1 to tell menu item "Paste" to set Paste to it
if (click Paste) = Paste then keystroke return
end tell
The if (click Paste) = Paste check should negate the need for a delay, as it explicitly forces AppleScript to evaluate the click command before going on to issue a keystroke. However, I can't test this under all possible conditions, and if there are other factors, like CPU usage, or process freezes, that are likely to give the script a chance to jump ahead, then just insert a small delay after then and move keystroke return down onto its own line.
If you wish to remove the file object from the clipboard afterwards, then simply add as the final line set the clipboard to (and just leave it blank after the word "to", which will clear the clipboard's contents). Of course, this won't affect any clipboard history data you might have if you use a clipboard managing app, only the system clipboard's current item.

Applescript play music from iTunes URL

The following script will open a track in iTunes
use application "iTunes"
property trackURL : "itmss://itunes.apple.com/us/album/brahms-violin-concerto-in-d-major-op-77-iii-allegro/145533236?i=145533044&uo=4"
open location trackURL
Now, asking "iTunes" to play it does not work because the track is highlighted but not properly selected, i.e., it requires a manual mouse click to select it and play it.
How can I select the highlighted track? Or how could I ask "iTunes" to play the song?! Alternatively, is there a way to add a music to my library from an URL directly?
Disclaimer: I don't have the Apple Music subscription, so the UI on my end may not be exactly the same as yours. However, if I click the "Play" button, I get the little advertisement asking me to sign up for the service, which I assume would just play the music if you had the service. So, these are the steps I've been able to follow to get that box to pop up:
The first, and most convenient from AppleScript, thing to try is just to hit the space bar to start the music playing. This actually works great if I've selected the item manually by clicking on it. However, after open location, it doesn't work, and this appears to be because even though the row is highlighted in the viewer, the actual keyboard focus seems to be on the page itself (the iTunes Store and Apple Music appear to have their entire UI presented as web pages rendered by WebKit). You can verify this by tapping the up and down arrow keys on the keyboard; the page scrolls up and down instead of you switching to adjacent tracks.
My opinion is that this is actually a bug in iTunes; I'd consider the true solution to the problem to be to report this to Apple via the bug reporter. Using open location really should set the keyboard focus to the track you navigated to.
With that said, we can work around it in the short term by simulating a click on the "Play" button. Note that you'll probably need to add your app in System Preferences > Security and Privacy > Accessibility. Note also that this is incredibly fragile, and if Apple ever changes anything in the layout of the web pages they're serving, this whole thing will break. Finally, please note that this code is extremely ugly; the whole thing gives me hives just by looking at it, but it's the only thing I was able to get to work. Side effects of reading this code may include nausea, headaches, and suicidal thoughts. Do not read this code immediately after eating. Consult your doctor before reading this code if you have a history of depression or obsessive-compulsive disorder.
property trackURL : "itmss://itunes.apple.com/us/album/brahms-violin-concerto-in-d-major-op-77-iii-allegro/145533236?i=145533044&uo=4"
property trackTitle : "III. Allegro giocoso, ma non troppo vivace"
tell application "iTunes"
activate
open location trackURL
delay 1 -- give the page a second to load
end tell
tell application "System Events"
tell process "iTunes"
set theRows to the rows of table 1 of UI element 1 of scroll area 1 of group 1 of group 1 of front window
-- "repeat with eachRow in theRows" isn't working. I don't know why. Freaking AppleScript
repeat with i from 1 to the number of theRows
set eachRow to item i of theRows
if exists group 2 of UI element 2 of eachRow then
if value of static text 1 of group 1 of group 2 of UI element 2 of eachRow is trackTitle then
tell group 1 of UI element 2 of eachRow to click
end if
end if
end repeat
end tell
end tell
If Apple ever fixes the bug, of course, we should be able to just:
tell application "iTunes"
activate
open location trackURL
delay 1 -- give the page a second to load
end tell
tell application "System Events" to keystroke space

Applescript interacting with another applications file selection

I have an applescript that I can open up an application, enter the password, and get to a file selection dialog. I am wondering if it is possible to interact with the standard mac file dialog if i have my file path.
Since this is interacting with another developers application, I cannot change this dialog in anyway.
I can get to the search field by "tabbing" over and searching for the file, it is unique with a date/time stamp, but have no way of selecting it and the hitting open.
Found via a different website for anyone who may lurk later on. Since it uses the standard apple window you can use the keyboard short cut shift + cmd + g to get the "go to folder" option from finder, from there entering the file path and hitting return. Had to add in delays on the two returns or it may miss the second one.
tell application "System Events"
keystroke "g" using {shift down, command down}
keystroke "Your File Path Goes Here!"
delay 1
key stroke return
delay 1
key stroke return

applescript to invoke alt keypress on cmd+tap keypress to switch to hidden window without physically pressing alt

I've hated the fact that I have to use the alt key to cmd+tab to hidden windows ever since I switched to MAC.
I know there are apps ( like witch ) that replace the cmd+tab function but I like the current interface I don't want to change that. besides that I just want to build the apple script for it :)
So here is what I want to create:
when I press cmd+tap -> keydown alt
Then when I then release cmd it should release the alt key.
The result would be I never have to press the alt key again when switching to 'hidden' windows. Much like other OS systems.
But it looks to me like all apple scripts start with tell application
It isn't posible to detect key presses by the user in applescript. You can press keys programmatically though. To solve your problem of holding down a key use the "key down" command and issue the "key up" command when you need to release it. That will work in any application. Here's an example.
tell application "KeyboardViewer" to activate
tell application "System Events"
try --don't even consider not using a try block because down keys can get stuck!
key down control
delay 1
key down shift
delay 1
key down option
delay 1
key down command
delay 1
key up control
delay 1
key up shift
delay 1
key up option
delay 1
key up command
delay 1
key down {control, shift, option, command}
delay 1
key up {control, shift, option, command}
on error --logging out is the only other way to unstick these
key up {control, shift, option, command}
end try
end tell
tell application "KeyboardViewer" to quit
NOTE: you could also use the "keystroke" command if you wanted to sequentially press and release some keys. For example to press command-s you could do the following:
tell application "System Events"
keystroke "s" using command down
end tell

Resources