Hello.
To allow time for ongoing operations to complete, small timeout intervals are used using the delay command inside repeat while or repeat until loops.
repeat until application "System Preferences" is not running
delay 0.1
end repeat
The above loop waits until an application stops working.
However, I would not know how to indicate the waiting time until the end of some Finder jobs that take a time that is difficult to calculate as in the final part of this example:
I want to remove repeated tabs that might be in a Finder window.
ell application "Finder"
set countWind to (count of windows)
--Convert tabs to windows
repeat countWind - 1 times
tell application "System Events" to tell process "Finder"
set frontmost to true
click menu item "Move tab to new window" of menu "Window" of menu bar 1
tell application "Finder" to set the index of the last Finder window to 1
end tell
end repeat
set listWind to {}
set countWind to (count of windows)
-- Create list without repeated windows
if countWind is greater than 1 then --
repeat with i from 1 to countWind
set namWind to get the name of Finder window i
if namWind is in listWind then
close window i
else
copy namWind to end of listWind
end if
end repeat
end if
--==========================
delay 3 -- This is the place where there should be a waiting loop that I don't know how to build instead of an arbitrary timeout.
-- If the waiting time is not adequate, window merging fails.
--==========================
--Merging non-repeated tabs
tell application "System Events" to tell process "Finder"
click menu item "Merge all windows" of menu "Window" of menu bar 1
end tell
end tell
Another way to put the question would be how to tell the Finder to wait for the current operation to finish before starting the next one?
I would appreciate help on how to handle timeouts, especially Finder or system events, which are necessary for jobs that take a long time.
Model: iMac
AppleScript: 2.11
Browser: Google Chrome
Operating System: macOS 12
This following AppleScript code will take all of your currently opened Finder Windows (with or without tabs) , closing any duplicate windows or tabs, and combines the rest of them into one Finder window with tabs.
A lot of the code in this following script was actually taken from Script Libraries I have. I combined everything into one large script to make things easier for you.
global tabCountRef, totalTabs, windowNames, totalWindows, tabNames
showFinderTabs()
totalWindowCount()
if totalTabs is greater than 1 then
run removeDupes
mergeWindows()
tell application "Finder"
activate
set windowsRef to a reference to Finder windows
set collapsed of windowsRef to false
end tell
end if
to mergeWindows()
tell application "System Events" to tell application process "Finder"
set frontmost to true
repeat while not frontmost
delay 0.1
end repeat
repeat while not (exists of window 1)
delay 0.1
end repeat
click window 1
delay 0.1
key code 123 using {option down} -- ⌥ ← (Merge All Windows)
end tell
end mergeWindows
on totalWindowCount()
tell application "Finder"
activate
end tell
tell application "System Events"
set frontmost of application process "Finder" to true
repeat until radio buttons of tab group 1 of window 1 of application process "Finder" exists
delay 0.1
end repeat
set tabCountRef to a reference to radio buttons of tab groups of windows of application process "Finder"
set totalTabs to count of tabCountRef
set windowNames to name of windows of application process "Finder"
set totalWindows to count of windowNames
end tell
end totalWindowCount
on showFinderTabs()
tell application "Finder"
activate
delay 0.1
if not (exists of window 1) then reveal desktop
delay 0.1
tell its window 1
activate
repeat until visible
delay 0.5
end repeat
delay 1
tell application "System Events"
if not (exists of radio buttons of tab group 1 of window 1 of application process "Finder") then
key code 17 using {command down, shift down}
end if
end tell
end tell
end tell
end showFinderTabs
script removeDupes
tell application "Finder"
tell its Finder windows to set windowTargets to target
end tell
set newList to removeDuplicates(windowTargets)
tell application "Finder" to close windows
repeat with i from 1 to count of newList
set thisItem to item i of newList
tell application "Finder"
set target of (make new Finder window) to thisItem
end tell
end repeat
on removeDuplicates(theList)
local theList, itemRef, res, thisItem
try
if theList's class is not list then error "not a list." number -1704
script k
property kList : theList
property res : {}
end script
repeat with itemRef in k's kList
set thisItem to itemRef's contents
if k's res does not contain {thisItem} then ¬
set end of k's res to thisItem
end repeat
return k's res
on error eMsg number eNum
error "Can't removeDuplicates: " & eMsg number eNum
end try
end removeDuplicates
end script
on mergeFinderWindows()
tell application "Finder"
activate
set countFinderWindows to count of Finder windows
if countFinderWindows < 2 then return
set uniqueTargetList to {target of Finder window 1 as text}
repeat with i from countFinderWindows to 2 by -1
set nextTarget to (target of Finder window i) as text
if uniqueTargetList contains nextTarget then
close Finder window i
else
set end of uniqueTargetList to nextTarget
end if
end repeat
end tell
tell application "System Events" to tell process "Finder" to ¬
click menu item "Merge all windows" of menu "Window" of menu bar 1
end mergeFinderWindows
mergeFinderWindows()