Applescript; opening an app in Space number N - macos

I wonder if it is possible in applescript to create a script for which we give as input the application name and a number N, so this app gets opened in the Space's space number N.
I would like with this to create a meta-applescript, so when the computer boots and after login, on each space I get different apps, and important, I can change this in the script file, and not through mac os x Space's preferences
Thanks

In OS X 10.5 or 10.6, Spaces assignments can be accessed and changed via the scriptable interface to System Events.app:
tell application "System Events"
set x to application bindings of spaces preferences of expose preferences
set x to {|com.apple.textedit|:4} & x -- Have TextEdit appear in space 4
set application bindings of spaces preferences of expose preferences to x
end tell
If you don't already know it, you can get the bundle id of an application from the Finder:
tell application "Finder"
get id of application file "TextEdit" of folder "Applications" of startup disk
end tell

This works to switch to Space 2 and then back to Space 1:
tell application "System Events"
key code 19 using {control down} -- control+2 is switch to Display Space 2
end tell
delay 1.0
tell application "System Events"
key code 18 using {control down} -- control+1 is switch to Display Space 1
end tell
delay 1.0

Answer
Although it's useful to assign applications to workspaces this doesn't address the question properly. Because, for example, you may want to launch multiple chrome windows in different spaces hence the application-to-space binding wouldn't work.
I found a workaround made of two steps to make this happen.
Change space location
tell application "System Events"
# comment: 18 to 21 somehow refer to workspaces 1 to 4, therefore here we are going to space number 1
tell application "System Events" to key code 18 using {control down}
end tell
delay 1 # comment: add some delay before launching app. this is 1 second delay
Launch the application that you want: either through another applescript or by using Launch Application
repeat the process to go to another space, and launch another app.
some notes:
Unfortunately, I have not found the corresponding key code to place an app on space number 5, if you do please let me know.
Also, this only works on the assumption that you already have the 4 spaces available (otherwise it will open things in the same space).
If things start to chain with previous scripts output and not work properly, remember to tick on each script/task of the automation Options > Ignore this action's input.
As personal observation once or twice when the computer seems busy to do something else, the prioritization of the automation seems low and the delay may be a few seconds longer.
Full example (with 4 apple scripts)
The following opens 2 google chrome windows in 2 different spaces. Code is below for copy and paste.
Script 1
tell application "System Events"
tell application "System Events" to key code 18 using {control down}
end tell
delay 1
Script 2
tell application "Google Chrome"
make new window
open location "https://www.google.com"
open location "https://www.apple.com"
end tell
delay 1
Script 3
tell application "System Events"
tell application "System Events" to key code 19 using {control down}
end tell
delay 1
Script 4
tell application "Google Chrome"
make new window
open location "https://www.bbc.co.uk"
end tell
delay 1

Related

How can AppleScript be used to send key codes (or an equivalent) directly to an application?

For instance, while the following is able to send multiple keys (shift+h) to the application "System Events", the script won't compile when attempting to send those key codes to an application such as Google Chrome. Is there another way?
tell application "System Events" (* won't work with "Google Chrome" *)
key code 58
key code 4
end tell
You can send key codes via System Events to an application like this:
tell application "System Events"
tell process "Google Chrome"
set frontmost to true
key code 4
key code 14
key code 37
key code 35
end tell
end tell
You can try this by opening Google Chrome first and making sure the focus is on the (empty) URL field and then run the above script - it should type "help" into the URL field.
If you don’t want Chrome to remain in front you can hide it again after sending the key codes.
As "commented", key codes & keystrokes can NOT be sent to BG apps by AppleScript!
It is ONLY possible to trigger some other ("visible"!) UI elements while in background.
To this purpose you must°° can "select" an application without bringing it to front by:
do shell script "open -g /System/Library/PreferencePanes/Keyboard.prefPane/"
… which works even if the app is already "open" in background.
°°I was reminded though: AS can reveal Sys.Prefs in background, other apps can not.
A 2nd alternative in AS is launch which with some(!) apps will work like "open -g …".
As CJK mentions any next command can be sent via AppleScript:
tell application "System Events" to tell process "System Preferences" ¬
to click checkbox 1 of tab group 1 of window 1
I use this feature to toggle some Sys-Prefs settings without losing focus. *
Remember: ONLY commands for "visible elements" (checkboxes, buttons …) will be executed; menu items therefore are excluded (= not visible while in background).
* ["At home" I use these lines in a Karabiner-shortcut where AS need an osascript wrapping.]

Using AppleScript to modify settings/system preferences

I am trying to make an AppleScript that toggles automatic rearranging of spaces. I am able to get the AppleScript to open system preferences and go into mission control settings, however i am not sure how to check the box which i want to change.
tell application "System Preferences"
activate
end tell
tell application "System Events"
tell process "System Preferences"
click menu item "Mission Control" of menu "View" of menu bar 1
delay 2
tell window "Mission Control"
//additional code goes here
end tell
end tell
end tell
Is there a way to see what the components of the window are so i know if i need to go into a table, or something else, before i am able to access the check boxes that toggle the settings
This is an alternative method using a shell command via AppleScript, which has the benefit of not requiring System Preferences to be open/running/visible. It's also much faster.
If you do happen to have it open in order to monitor whether the script below works, bear in mind that the GUI (what you see) is not updated until you close System Preferences, and open it up again.
To set Automatically rearrange Spaces based on most recent use to true (i.e. so the checkbox is ticked):
do shell script "defaults write com.apple.dock 'mru-spaces' -bool true; killall Dock"
To set it to false, i.e. untick the checkbox, change true to false in the line of code above.
To toggle the setting, this short script will achieve that:
set currentSetting to ¬
(do shell script ¬
"defaults read com.apple.dock 'mru-spaces'") ¬
as integer as boolean
do shell script ¬
"defaults write com.apple.dock 'mru-spaces' -bool " & ¬
(not currentSetting) & ¬
"; killall Dock"
Note: Tested with MacOS High Sierra, but should work (I believe) in OS X Mavericks and later.
Other Settings
When switching to an application, switch to a Space with open windows for the application
do shell script "defaults write -g AppleSpacesSwitchOnActivate -bool true"
(or false if you want the option off.)
Group windows by application
do shell script "defaults write com.apple.dock 'expose-group-apps' -bool true; killall Dock"
(or false if you want the option off.)
Let me start by saying while both of the other answers prior to this one do work, nonetheless I wouldn't use either one of them for the following reasons.
The answer presented by shadowsheep works however it needlessly exposes the System Preferences GUI and I believe unless your system is really slow the value of the delay command is excessive by 50% and only one should be necessary in this use case.
The answer presented by CJK works however it uses killall Dock which is visually distracting and causes all minimized windows on all Desktops to be unminimized leading to further visual distractions, and clutters the Desktop(s), which can then require the User to cleanup the mess. Even without other windows open it's still more so a visual distraction then what I'll present.
Now every User has different work habits so maybe none of the reasons mentioned are of any consequence to you. Personally, I work between four virtual Desktops and can have dozens of windows opened in numerous apps across the Desktops with many, if not most minimized at times. Using killall Dock for me is the last thing I want to do most of the time.
With that said, here's an alternative to both of the existing answers prior to this one.
It's probably safe to say that most Users don't open and leave open System Preferences however the following example AppleScript code checks to see if it's running and if so closes it. This is so it can be opened without showing the GUI, so as not to have to see the the visual distraction of have the GUI change as the script progresses.
This example AppleScript code simply toggles the state of the target checkbox:
if running of application "System Preferences" then
quit application "System Preferences"
delay 1
end if
tell application "System Preferences"
reveal pane id "com.apple.preference.expose"
delay 1
tell application "System Events"
tell group 2 of window 1 of application process "System Preferences"
click checkbox "Automatically rearrange Spaces based on most recent use"
end tell
end tell
quit
end tell
This example AppleScript code conditionally clicks the target checkbox using 0 or 1 in if value is equal to 0 then click it. Use 0 to only click it if it's not checked and 1 to only click it if it's checked.
if running of application "System Preferences" then
quit application "System Preferences"
delay 1
end if
tell application "System Preferences"
reveal pane id "com.apple.preference.expose"
delay 1
tell application "System Events"
tell group 2 of window 1 of application process "System Preferences"
tell checkbox "Automatically rearrange Spaces based on most recent use"
if value is equal to 0 then click it
end tell
end tell
end tell
quit
end tell
Both example AppleScript code blocks shown work fast and without seeing the System Preferences GUI and the only visual effect is the Dock Tile for System Preferences does a single bounce and may not even be noticeable, especially when compared to the visual distraction of killall Dock.
Note that the value of the delay commands may need to be adjusted for your system, and or additional delay commands may or may not be needed. Adjust values of and or add/remove the delay commands as appropriate.
Note: The example AppleScript code is just that and does not employ any other error handling then what's shown and is meant only to show one of many ways accomplish a task. The onus is always upon the User to add/use appropriate error handling as needed/wanted.
This should to what you want.
In this example Automatically rearrange Spaces based on most recent use is the checkbox you want to check.
tell application "System Preferences"
activate
delay 2
set the current pane to pane id "com.apple.preference.expose"
delay 2
tell application "System Events"
click checkbox "Automatically rearrange Spaces based on most recent use" of group 2 of window "Mission Control" of application process "System Preferences"
end tell
quit
end tell
And this if you wanna check it only if it's not checked:
tell application "System Preferences"
activate
delay 2
set the current pane to pane id "com.apple.preference.expose"
delay 2
tell application "System Events"
tell checkbox "Automatically rearrange Spaces based on most recent use" of group 2 of window "Mission Control" of application process "System Preferences"
if (get its value) = 0 then click it
end tell
end tell
quit
end tell
And if you wanna list all the UIElements in the window:
set myArray to {}
tell application "System Preferences"
activate
delay 2
set the current pane to pane id "com.apple.preference.expose"
delay 2
tell application "System Events"
tell window "Mission Control" of application process "System Preferences"
repeat with uiElem in entire contents as list
set myArray to myArray & ((class of uiElem as string) & " : " & name of uiElem as string)
end repeat
end tell
end tell
end tell

AppleScript works in Script Editor but not as application

I am pretty new to programming, especially with AppleScript. I wrote a simple script for Valentine's Day to play a song from iTunes and then open a flash animation file in Safari. When I run the script in ScriptEditor, everything works as desired, but when I export as a standalone application, it fails at the command to enable full-screen mode. I am assuming it is an issue with System Events. To be clear, the application functions to the end, but at the keystroke command I hear an alert sound and the window remains as-is.
I am running Yosemite, and am fully updated.
Ideally, I would like to open the file in Google Chrome to utilize Presentation Mode, but I can't even get Chrome to open the file.
Thanks for any advice! Here is the code:
tell application "Finder"
set visible of every process whose visible is true and name is not "Finder" to false
close every window
end tell
set volume output volume 75
tell application "iTunes"
set currentVolume to sound volume
if player state is playing then
stop
back track
end if
play track "The Promise"
set player position to 6
end tell
delay 4
tell application "Safari"
activate
if (count of windows) is 0 then -- Remove "if" statement if you don't want to make a new window if there is none
make new window at front
end if
open (POSIX path of (path to home folder)) & "/Desktop/beMine/beMine.swf"
tell application "System Events"
tell process "Safari" to keystroke "f" using {command down, control down}
end tell
end tell
I agree with Jerry Stratton's comment that it could be an accessibility issue. However it also could be that you are issuing the keystroke command before Safari is ready to accept it. If it's opening a file then it could be busy and miss the keystroke command.
Also, I would move the system events code outside the Safari code and also just tell system events, rather than the Safari process, to perform the keystroke command. Try this as the Safari and System Events parts.
NOTE: I can't get Chrome to open a file either.
tell application "Safari"
activate
if (count of windows) is 0 then -- Remove "if" statement if you don't want to make a new window if there is none
make new window at front
end if
open (POSIX path of (path to home folder)) & "/Desktop/beMine/beMine.swf"
end tell
tell application "Safari" to activate
delay 1
tell application "System Events"
keystroke "f" using {command down, control down}
end tell
Most likely you’ll need to allow your standalone application to use System Events. At some point you needed to do that for Script Editor; you’ll need to do the same for your standalone app.
You’ll find the option in System Preferences under Security & Privacy, then Privacy, and then Accessibility. There’ll be a list of apps, and your app is probably listed there without a check for “Allow the apps below to control your computer.”
You may need to use the “+” button to add your app to the list.
I have verified that I can use this simple script to make Safari full-screen; it will work if the app is given permission under Accessibility, and it will silently fail if not.
tell application "Safari"
activate
end tell
tell application "System Events"
tell process "Safari" to keystroke "f" using {command down, control down}
end tell
This is Yosemite, Mac OS X 10.10; it may be different in other versions of Mac OS X.

How to a file uploading using Automator in apple script?

I’m new to automator. This is what I’m trying to achieve.
I have the code for uploading the file in Safari using applescript ( which will upload the file myFile points to):
on run argv
set myFile to item 1 of argv
activate application "Safari"
tell application "System Events" to tell process "Safari"
keystroke "G" using {command down, shift down}
delay 2
key code 51
delay 2
keystroke myFile
delay 30
key code 52
delay 10
key code 52
delay 5
end tell
end run
This applescript is been called by Java and it works fine.
This is working totally fine. But I want to put this in automator service, so that Safari has directly access to the applescripts, rather than Java doing it. Now I have two questions:
Many Safari will be running and calling this service. So which safari needs to give the file uploading process needs to be figured out. Is it possible for the automator to find the process id of the application which called it ?
If so, then how shall I pass the parameter (the file location to be uploaded) to the automator, when the service is called?
Thanks in advance.

Delay in an Alfred 2, using Automator and Apple Script to open "Stickies" and create a new note

Basically my goal is to code a key command (option-s) to activate Stickies and create a new note. Right now I have an Alfred 2 generated Automation which links the hot key to the following script:
on alfred_script(q)
tell application "Stickies" to activate
delay .2
tell application "Stickies" to activate
delay .01
tell application "System Events"
keystroke "n" using command down
end tell
end alfred_script
The two activate commands are my attempt to deal with a bug where it opens the application, but doesn't bring it to front. It works seamlessly when the application is open in the background, but it's slow and creates a screen flash when the application isn't already running. The delay is not coming from the application itself because I can open the application and hit command-n as fast as possible, and it always works.
(By the way if you have an idea for how I could hide all other notes and just show the new one, that would be awesome!)
Try this:
launch application "Stickies"
tell application "System Events" to tell process "Stickies"
click menu item "New Note" of menu "File" of menu bar 1
set frontmost to true
end tell
If you run the script by pressing option-s, there might not be enough time to release option before keystroke "n" using command down.
Or this doesn't raise the windows for other notes:
launch application "Stickies"
tell application "System Events" to tell process "Stickies"
click menu item "New Note" of menu "File" of menu bar 1
end tell
do shell script "open -a Stickies"
activate app "Appname" and set frontmost of "Appname" to true raise all windows, but do shell script "open -a Appname" raises only one window.
Hotkeys also have a short delay by default in Alfred, but you can reduce it by changing the trigger behavior:
You could try this alternate way, might have a different effect.
tell application "System Events"
tell process "Stickies"
set frontmost to true
keystroke "n" using command down
keystroke "Hello World" & linefeed & "I'm a new note!"
end tell
end tell
Hiding all other notes, i'd say start a new question for that.

Resources