I am trying to write an Applescript to open three VLC windows in different screen positions. The script opens three instances of VLC but has them one on top of the other (using the position for window 1). Help with the code appreciated:
do shell script "open -n /Applications/Video/VLC.app"
tell application "System Events"
activate
set bounds of first window of application "VLC" to {13, 36, 790, 519}
end tell
do shell script "open -n /Applications/Video/VLC.app"
tell application "System Events"
activate
set bounds of second window of application "VLC" to {13, 544, 790, 1027}
end tell
do shell script "open -n /Applications/Video/VLC.app"
tell application "System Events"
activate
set bounds of third window of application "VLC" to {13, 1043, 790, 1526}
end tell
@khagler's comment provides the right pointer: the VLC instances must be distinguished by their PIDs (process IDs; called unix id in AppleScript) in the System Events context.
The code below should do what you want, arrived at after much toil and trouble -- par for the [AppleScript obstacle] course. One obstacle was that the VLC instances' main windows do not get created right away.
The comments provide more details.
Note that because user-interface elements are programmatically manipulated, the application running your script must be granted assistive access for security reasons.
Note that I'm starting the instances with do shell script "open -na VLC.app", relying on the location of the app being known to Launch services (should that not work for some reason, revert to your method of specifying the full path).
# Specify the desired window bounds.
# !! In the "System Events" context, windows do not
# !! have `bounds` properties, but separate `position` and
# !! `size` properties.
set WIN_POSITIONS to {{13, 36}, {13, 544}, {13, 1043}}
set WIN_SIZES to {{790, 519}, {790, 519}, {790, 519}}
# Launch the VLC instances.
repeat with i from 1 to count of WIN_POSITIONS
do shell script "open -na VLC.app"
end repeat
# Note:
# Instance-specific manipulation must
# be performed in the "System Events" context, because
# we must distinguish the VLC instances by their
# PIDs (process IDs; called `unix id` in AppleScript).
tell application "System Events"
# Get the PIDs (process IDs) of all VLC instances.
set vlcPids to get the unix id of every process whose name is "VLC"
# Loop over all instance PIDs.
# !! It is imperative to *continue* to use object specifiers
# !! with *filters based on the PID* so as to ensure that the
# !! individual instances are targeted.
# !! Attempting to store references to these instances in
# !! variables fails subtly, as evidenced by the "Events"
# !! tab in AppleScript editor later showing the non-specific
# !! process "VLC" of application "System Events" specifiers.
set winNdx to 1
repeat with vlcPid in vlcPids
# WAIT for each instance to create its main window, wich
# sadly, is not available right away.
# Once created, position it.
set haveWin to false
tell (first process whose unix id is vlcPid)
repeat with i from 1 to 25 # times out after 25 * .2 == 5 secs.
if (count of windows of it) > 0 then
set haveWin to true
tell front window of it
# !! In the "System Events" context, windows do not
# !! have `bounds` properties, but separate `position` and
# !! `size` properties.
set position to item winNdx of WIN_POSITIONS
set size to item winNdx of WIN_SIZES
end tell
exit repeat
end if
delay 0.2 # no window yet; sleep some and try again
end repeat
end tell
if not haveWin then error "VLC instance " & vlcPid & " unexpectedly did not create a window within the timeout period."
set winNdx to winNdx + 1
end repeat
end tell
How to make this work with Finder:
Targeting Finder changes the approach for two reasons:
open -na Finder.app; thankfully, this answer shows how to do it (see the comments there for quirks).Note that the following blindly opens additional Finder windows.
set WIN_POSITIONS to {{13, 36}, {13, 544}, {13, 1043}}
set WIN_SIZES to {{790, 519}, {790, 519}, {790, 519}}
# Sample target locations for the Finder windows.
# Note the use of the "System Events" context to faciliate use of
# POSIX-style *input* paths; note, however, that the paths are
# *stored* as HFS paths so that Finder accepts them.
tell application "System Events"
set WIN_TARGETS to {¬
path of desktop folder, ¬
path of folder "~/Downloads", ¬
path of folder "/Library/Audio"}
end tell
set winCount to count of WIN_POSITIONS
# Launch the Finder windows.
tell application "Finder"
# Create the windows in reverse orders.
repeat with i from winCount to 1 by -1
set newWin to make new Finder window
set target of newWin to item i of WIN_TARGETS
end repeat
end tell
tell application "System Events"
set i to 1
repeat with i from 1 to winCount
tell window i of application process "Finder"
# !! In the "System Events" context, windows do not
# !! have `bounds` properties, but separate `position` and
# !! `size` properties.
set position to item i of WIN_POSITIONS
set size to item i of WIN_SIZES
end tell
end repeat
end tell
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With