How to get/set applescript property from string? - applescript

I'm trying to automate the position of my dock in MacOS with applescript.
I can successfully position the dock. This works perfectly:
tell application "System Events"
tell dock preferences
set properties to {screen edge:right}
end tell
end tell
The problem is that I want to accept the position as an argument, and it's provided as a string. So I end up with the equivalent of:
tell application "System Events"
tell dock preferences
set x to "right"
set properties to {screen edge:x}
end tell
end tell
This results in an error:
"System Events got an error: Can\U2019t make \"right\" into type constant.";
How do I 'resolve' my string into the constant that is expected?

right (without quotes) is an integer value, an enumerated constant. You cannot cast a string to an enum.
If you really need a string argument a workaround is an if - else chain
on setDockScreenEdge(theEdge)
tell application "System Events"
tell dock preferences
if theEdge is "right" then
set screen edge to right
else if theEdge is "left" then
set screen edge to left
else if theEdge is "bottom" then
set screen edge to bottom
end if
end tell
end tell
end setDockScreenEdge
Then you can change the edge with a string argument
setDockScreenEdge("right")
It's not necessary to set the properties record. You can set a single property directly

Related

Applescript - how do I affect the "main" window of an app if it's not at the front?

Logic has a "main window" which is not always technically at the front (there can be smaller floating windows etc). So I cannot do this:
tell application "System Events" to tell process "Logic Pro"
get value of UI element [xyz] of the front window
end tell
The main window is not consistently named (changes depending on the name of the saved project) so I cannot do this:
tell application "System Events" to tell process "Logic Pro"
get value of UI element [xyz] of window "my project"
end tell
Is there some way of consistently referring to the "main window"?
There are at least two ways:
Check if the window is the main window
tell application "System Events" to tell process "Logic Pro X"
tell (first window whose value of attribute "AXMain" is true)
-- do something
end tell
end tell
Check if the window is a document window
tell application "System Events" to tell process "Logic Pro X"
tell (first window whose value of attribute "AXDocument" starts with "file://")
-- do something
end tell
end tell

Tell preview to get the window whose document is named "book.pdf"

I'm trying to get the window whose document has the name "book.pdf". Here's my approach
tell application "Preview"
set w to every window whose document is named "book.pdf"
end
This doesn't work. I've tried about 100 permutations but I'm not getting anywhere. Any tips?
You can use AXTitle combined with contains, and tell System Events not Preview
Note I have it wrapped in a try block because myWindow will be undefined if no string match is found.
set n to "book.pdf" -- whatever substring you want to find
tell application "System Events" to tell process "Preview"
try
set myWindow to (1st window whose value of attribute "AXMain" is true and value of attribute "AXTitle" contains n)
log myWindow
on error
log "not found"
end try
end tell

AppleScript get attribute won't return value when app is in fullscreen

This script works when terminal application(or any application) is not in FullScreen mode. It will return the correct value of false. When you make the application fullscreen it returns any empty value. The only thing I can think of is that when you go fullscreen it puts it on a different desktop? Am I missing something to activate the app differently now that it is fullscreen?
tell application "System Events" to set the visible of every process to true
set white_list to {"Finder", "AppleScript Editor", "Google Chrome"}
tell application "System Events"
set process_list to the displayed name of every process whose visible is true
set process_number to (number of items in process_list)
set myList to process_list
end tell
repeat with theItem in myList
if theItem is not in white_list then
log theItem
tell application "System Events" to tell process theItem
set isFullScreen to the value of attribute "AXFullScreen" of windows
end tell
end if
end repeat
return theItem & " application is FullScreen: " & isFullScreen
This line won't work as written...
set isFullScreen to the value of attribute "AXFullScreen" of windows
"windows" will return a list of windows and you can't get that attribute from a list. So you would want to write it as...
set isFullScreen to the value of attribute "AXFullScreen" of window 1
However, with that said I tried this and it seems you can't get the windows from a full screen process. The list of windows is always empty {}. So this approach of determining if an application is full screen will not work.
You'll need to think of another way to figure out if an application is full screen. I tried a couple things and couldn't find a solution. Sorry.

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 - Bring window to foreground

I have an application with several windows opened at the same time.
I'd like to bring a specific window to foreground (I know its title).
At the moment I'm using a combination of keys to achieve this task but I'd like to try something different since I'm experiencing some problems with this approach.
tell application "System Events"
set frontmost of process "appIT" to true
keystroke "1" using command down
delay 0.2
end tell
This is possible by using the "AXRaise" action, except on certain window (applications that use X11 for example).
Try this.
set theTitle to "some title"
tell application "System Events"
tell process "appIT"
set frontmost to true
perform action "AXRaise" of (windows whose title is theTitle)
end tell
end tell
If your application is scriptable and allows setting the index of a window, you can do the following (based on an answer in How do I make a Safari window active using AppleScript (elegantly)?)
to raiseWindow of theApplicationName for theName
tell the application named theApplicationName
activate
set theWindow to the first item of ¬
(get the windows whose name is theName)
if index of theWindow is not 1 then
set index to 1
set visible to false
set visible to true
end if
end tell
end raiseWindow
The toggling of the visibility is necessary to deal with some weirdness that occurs with switching applications. If you don't toggle the visibility, the window won't be the first when you switch away from and back to the application. Unfortunately, this toggling shrinks the window to the dock then restores it, a very dramatic UI disruption.
Here's another way I've found to deal with the weirdness:
to raiseWindow2 of theApplicationName for theName
tell the application named theApplicationName
activate
set theWindow to the first item of ¬
(get the windows whose name is theName)
if the index of theWindow is not 1 then
set the index of theWindow to 2
tell application "System Events" to ¬
tell application process theApplicationName to ¬
keystroke "`" using command down
end if
end tell
end raiseWindow2
I don't think System Events can change the front window of a process. Of course you can close the front window until the window you want is on top. That's not really a solution though as you probably don't want to close windows. Really though the only way you could achieve this is if the application itself is apple-scriptable and allows you to do this.

Resources