Applescript moving finder window or screen back to first screen - applescript

I am writing a script and want to hem in the user(s) in the future from errors. The big one I'm working on right now is that the Choose File command box for Finder or AppleScript (doesn't matter) do not contain the "giving up after" option. So while I can set the timeout to a very large number of seconds (5000 for example), I can't get the box to close and reopen without the Apple Events timing out.
So here is one option I've tried. but the problem I have is that if I swipe to another screen, even if I Activate the finder, it will say that it can't find the window "Choose a File"
Is there a way to get the window to follow the swipe or a command with activate that will bring the finder window to the current screen, even if I'm working in say Safari?
The error occurs when I swipe to another screen; see the error below:
error "System Events got an error: Can’t get window \"Choose a File\" of process \"Finder\"." number -1728 from window "Choose a File" of process "Finder"
Script:
try
with timeout of 5 seconds
tell application "Finder"
set theFilestoChoose to every item of (choose file with prompt "Please select the file(s) you would like to move and rename:" with multiple selections allowed) as list
end tell
end timeout
on error errStr number errorNumber
if errorNumber is -1712 then --timeout error
my closeWindow() --call handler to close window
end if
end try
on closeWindow()
tell application "System Events"
delay 2 -- for observation testing purposes
set frontmost of process "Finder" to true
delay 2 -- for observation testing purposes
click button "Cancel" of window "Choose a File" of process "Finder"
end tell
end closeWindow

You'll have to look into the defaults setting AutoSwoosh = true; defaults write com.apple.Dock workspaces-auto-swoosh -bool YES ; KillAll Dock which makes you go to the active app, if it isn't in the current space, the app itself, (Finder in this case?), shouldn't be assigned to a space.
If that is your basic configuration, then a simple activate before it, should bring you directly to your choose file dialog, if it is in another space.
Here is a fleshed out example of embedding the choose file with tell application (path to frontmost application as text):
tell application (path to frontmost application as text)
set theF to (choose file)
end tell

Related

How «Wait until application launch» applescript?

How to write the code correctly?
I run the application Photoshop in the automator
I'm waiting for it to fully load
Then I press 10 times Tab and press Enter.
I've tried that:
enter image description here
Looks like that part doesn't work. Because Tab starts to click before the application is fully loaded. What's wrong? Thanks!
repeat until application launch
delay 0.5 end repeat delay 0.5
Most likely, the OP does not understand the main thing: GUI scripting (in this case, sending 10 tabs, and then Enter, that is, keystroke tab and keystroke return in AppleScript language) only works with the frontmost window. And the launch command launches an application without bringing its window to the front.
The correct approach is 1) use the activate application "Photoshop" command 2) use the make new document command, 3) check if the new window exists, 4) send keystroke commands. In the Automator, the Run AppleScript action should be something like this:
on run {input, parameters}
tell application "Photoshop"
activate
make new document with properties {name:"myNewDocument"}
repeat until window "myNewDocument" exists
delay 0.1
end repeat
end tell
tell application "System Events"
repeat 10 times
delay 0.1
keystroke tab
end repeat
keystroke return
end tell
return input
end run
NOTE: not tested, because PhotoShop.app is not installed on my Mac. I am ready to correct my script, if needed. In general, the question is not quite clear.
I don't know much about Photoshop, but I know that it has a loading screen. I tried the following code in Affinity Photo which is a similar product to Photoshop.
tell application "Photoshop"
launch
set theBool to false
repeat until theBool
tell application "System Events" to ¬
if menu item "Close" of ¬
menu 1 of ¬
menu bar item "File" of ¬
menu bar 1 of ¬
application process "Photoshop" exists then ¬
set theBool to true
delay 0.2
end repeat
end tell
The repeat until theBool checks if the loading screen is over by checking if some menu item exists which isn't available when the loading screen is open. If the "Close" and the "File" don't work in Photoshop, you may choose something else.
This is the answer:
tell application "Your app"
launch
activate
end tell

Click on a specific place on a window, click on a specific button and control if the window changes

Actually I have 3 questions about the same problem: controlling a window with applescript.
What should I do if I would press on button "Close Window" of application "Google Chrome"?
Is it possible to check if the window changes? For example, to see if appear a pop-up or something like that...
What about clicking on a specific place into a window? I mean, I know I can use
tell application "System Events"
click at {x,y}
end tell
but this command use the entire screen as reference system, and I want it works only on a specific window. For example, if at "{x,y}" i put "{1,1}", applescript will click on the first item on the menu bar. Is there a way I can say to "System Events" to click at "{1,1}", but on the window "Google Chrome"?
Here are three examples of how to close the front window of Google Chrome using AppleScript:
Note: The following assumes Google Chrome is running with at least one window open when you test each example AppleScript code in Script Editor.
Example one is the most straight forward way:
tell application "Google Chrome" to close front window
Example two directly clicks the close button:
tell application "System Events" to tell ¬
application process "Google Chrome" to ¬
click button 1 of front window
Example three calculates the center of the close button and clicks there:
activate application "Google Chrome"
delay 0.5
tell application "System Events" to tell ¬
application process "Google Chrome" to tell ¬
front window
set posB1 to (position of button 1)
set szB1 to (size of button 1)
set x to (item 1 of posB1) + (item 1 of szB1) / 2 as integer
set y to (item 2 of posB1) + (item 2 of szB1) / 2 as integer
end tell
tell application "System Events" to click at {x, y}
Note that in the first two examples, the front window of Google Chrome doesn't even need to be the frontmost window on the Desktop; however, with the third example it does, otherwise the click at {x, y} will not go to the intended target.
That said, example three really shouldn't be used when there it a straight forward way, as in example one, to get the job done. Example three was just a proof of concept to get the coordinates to click at. This method may be useful in some fringe cases, especially in an app that doesn't directly support AppleScript.
Note: The example AppleScript code is just that and does not contain any error handling as may be appropriate. The onus is upon the user to add any error handling as may be appropriate, needed or wanted. Have a look at the try statement and error statement in the AppleScript Language Guide. See also, Working with Errors.
In applescript GUI scripting you can simply refer to an element by name or index and tell it to click or to perform an action. For instance to click the close button on the first open window in Chrome you could use:
tell application "System Events"
tell process "Google Chrome"
tell window 1
tell button 1
click
end tell
end tell
end tell
end tell
You don't actually need to know its physical position to click one it; you just need to know that the first button in the window is the close button.
System Events always returns the position of any element in screen pixels, so if you want the position of an element in terms of its window, get the position of the element, get the position of the window, and do some addition or subtraction (e.g., if you want to click at {5,5} in a window whose position is {100, 125}, click at {105, 130})
AppleScript isn't really designed to monitor GUI changes, though if you want to be tricky and you know what change you're looking for you can do something like this:
tell application "System Events"
tell process "..."
tell window 1's pop up button 3
repeat until (exists menu 1)
delay 0.2
end repeat
-- menu 1 now exists, so the pop up button is open
end tell
end tell
end tell
...but note that this will hang the script until the menu is opened. A more elegant way to handle that is to write a script application with an idle handler, like so:
on run
-- whatever initialization is needed
end run
on idle
tell application "System Events"
try
tell process "..."
tell window 1's pop up button 3
if exists menu 1 then
-- menu 1 now exists
-- the pop up button is open
-- do what must be done
end if
end tell
end tell
on error errstr
display alert "Something went wrong" message "The script sent this error: " & errstr
end try
end tell
return 0.2
end idle
You can leave that running in the background watching for specific changes in the GUI (the 'try' statement is in case the app you're watching quits, the window closes, or something unexpected happens to the GUI).
If you haven't already, open the System Events scripting definition in Script Editor and look at the Processes Suite. That will show you all the things you can do with GUI scripting.

How to set a window's index to last (furthest back) in applescript

I've seen a lot of posts for how to send a window to the front in applescript, but I want to be able to send it to the back. How do I write an applescript that will do this?
Maybe you don't actually need to move any windows. Maybe you can just hide your application so your window isn't showing. Since you don't want your window on the top then it's probably OK to just hide your application. It continues running and does its thing but its window doesn't cover any other windows.
Just change "Safari" to the name of your application.
set myAppName to "Safari"
tell application myAppName to activate
tell application "System Events"
-- wait until your application comes forward and then hide it
repeat
set p to first process whose frontmost is true
if name of p is myAppName then
set visible of p to false -- hide your application
exit repeat
end if
delay 0.2
end repeat
end tell
EDIT: if hiding your app doesn't work then you could just keystroke command-tab which is the application switcher command. Basically your app will come to the front and then the keystroke will make the previously frontmost application come to the front. So your window won't go all the way back but it won't be in the front. Maybe that will work.
set myAppName to "Safari"
tell application myAppName to activate
tell application "System Events"
-- wait until your application comes forward
repeat
set p to first process whose frontmost is true
if name of p is myAppName then exit repeat
delay 0.2
end repeat
-- use the application switcher to bring the previously frontmost application forward
keystroke tab using command down
end tell
Something like set index to 999 doesn't seem to work, but set index to (count windows) does:
tell application "TextEdit"
set index of window 1 to (count windows)
end tell
You might also raise all other windows:
tell application "System Events" to tell process "TextEdit"
repeat with w in windows 2 thru -1
perform action "AXRaise" of w
end repeat
end tell
This will move the front finder window to the back...
tell application "Finder" to set index of front Finder window to (count Finder windows)
I have not used "openFrameWorks" so I am not sure of how it works…
But rather than reinvent the wheel with Applescript.
Can you not set the window level in "openFrameWorks"
In xcode/Objective - c I would use the NSWindow Window Levels constants.
To set a normal window:
[awindow setLevel: NSNormalWindowLevel];
But set a window below other normal windows:
[awindow setLevel: NSNormalWindowLevel - 1000];
This will insure the window is always below any normal applications windows. Even when I click on it or drag it. It stays behind other windows.

Applescript check if window is one screen

I have written this script function
on GetWindowLocation()
set front_app to (path to frontmost application as Unicode text)
tell application front_app
item 1 of (get bounds of front window)
end tell
end GetWindowLocation
on GetDockStatus()
tell application "System Events" to get the autohide of the dock preferences
end GetDockStatus
if I am on the desktop with no windows up it errors.
How can I check if a window is on screen, so I can put an if statement to not
run it if a window is not on the screen.
Probably the easiest fix here would be to simply catch the error:
tell application front_app
try
return item 1 of (get bounds of front window)
on error
-- do something here to handle there being no front window
end try
end tell
You could also try checking the count of windows before trying to reference the front window, but that's somewhat more prone to errors (as the window may disappear before you grab its bounds).

Applescript studio - how do I get every control in a window

I'm trying to enable or disable all the control in a window as the programme changes from interactive to non-interactive mode. How can I ask a window to give me all its contents?
every control of window "mainWindow"
doesn't work, nor does
contents of window "mainWindow"
Actually, I haven't been able to find any good documentation for interacting with menu items from interface builder at all. Things like how to set the contents of popups, and buttons and so on.
thanks
The way I do it at the moment is:
property onlineControls: {"maxLength", "speed", "accelerationSlider", "accelerationField", "showInfo"} --and so on, listing all the controls by name
on enableControls(theList, enableState)
tell window "mainWindow"
repeat with theControl in theList
set the enabled of control theControl to enableState
end repeat
end tell
enableControls(onlineControls, true)
I've made several lists of controls tht get turned on or off depending on the state the programme is in. But it has to be hard coded, which I don't see as being the best way.
tell application "System Events"
tell process "Adium"
get entire contents of window 1
end tell
end tell
This script will give you as result all contents of front window of Adium: butons of window, tool bars of window, buttons of tool bars, etc. Enjoy =]
I haven't been able to find a way to get all the controls in a window, but here's an example of interacting with the menu of a popup button:
tell menu of popup button "somePopupButton" of window "mainWindow"
delete every menu item
repeat with i in someItems
make new menu item at end of menu items ¬
with properties {title:i, enabled:true}
end repeat
end tell
Is the same script as "BoB1990" with the possibility of getting back the information given by get entire contents of window in a string of whom you can observe or modify all the items listed :
tell application "System Events" to tell process "Adium"
set this_info to {}
try
display alert ((get entire contents of window (x as integer)))
on error errMsg set theText to errMsg
set this_info to do shell script " echo " & theText & " | sed 's#System Events got an error: Can’t make ##g;s# into type string.##g'"
end try
set info to {}
set info to do shell script " echo " & this_info
display alert (info)
end tell

Resources