Hi MacUsr, mark hunte,
i never thought that somebody would take this topic so seriously.
Nice, so noting becomes trivial in scripting. In the meantime i modified my script, after reading the blog post of mark and following the suggestions of MacUsr. Now the script closes finder windows in the current space only, considering locations and excluding spotlight search windows
#consider finder windows in current space only
tell application "System Events" to set spaces_win to name of windows of process "Finder"
tell application "Finder"
#sort unique paths and get duplicate locations, exclude spotlight searches
set {id_ls, pt_ls} to {{}, {}}
repeat with a in spaces_win
set {the_id, the_pt} to {id, target} of window a
set the_pt to (the_pt as text)
if the_pt is not in pt_ls then
copy the_pt to end of pt_ls
else
if the_pt is not "" then copy the_id to end of id_ls
end if
end repeat
if id_ls is {} then return
#finally, close finder windows
repeat with b in id_ls
close window id b
end repeat
end tell
I’m sure both scripts could be joined up with a dialog to ask if to close in a single space or all.
the simplest way is to put both scripts in a handler each. And then use…
display dialog "Close Duplicates in." buttons {"Current Space only", "All Spaces", "Cancel"} default button 3
set the button_pressed to the button returned of the result
if the button_pressed is "Current Space only" then
my joyScript()
else if the button_pressed is "All Spaces" then
my markScript()
end if
I wanted to time your script against mine, but for some odd reason the line with id, target fails.
@ Mark. I hope you update your blog, given the information above. And your script fails to, I get the message: “Can’t make «class alia» “” of application “Finder” into type alias.”
It is the line:
set windowNTargets to POSIX path of (windowTarget as alias) (*Convert the target to an alias path from a file system item reference and then get its Posix path*)
That fails for some odd reason. I think the reason to be, but aren’t sure it is because I have bundles open.
(On my machine, my script uses around 2 seconds to close 18 duplicate windows.)
Hi,
i wrote a final version.
This one should definitively work:
-added a dialog as mark hunte’s suggested.
-ignore spotlight windows, *Clipping- windows
-consider locations
-consider spaces
tell application "Finder" to set finder_icon to path to resource "Finder.icns"
try
set button_pressed to button returned of (display dialog "Close window Duplicates in." buttons {"Current Space only", "All Spaces", "Cancel"} default button 3 with icon finder_icon)
on error number the err
if err is -128 then return
end try
if button_pressed is "Current Space only" then
tell application "System Events" to set spaces_win to name of windows of process "Finder"
else
set spaces_win to 0
end if
tell application "Finder"
set { pt_ls, open_wins} to { {}, windows}
repeat with a in open_wins
if name of a does not end with "Clipping" then
set {the_id, the_pt} to {id, target} of a
set the_pt to (the_pt as text)
if the_pt is not in pt_ls then
copy the_pt to end of pt_ls
else
if spaces_win is 0 then
if the_pt is not "" then close a
else
if name of a is in spaces_win and the_pt is not "" then close a
end if
end if
end if
end repeat
end tell
i’m sorry, but the script compiles well and runs smootly on my machine. I’ll encourage you to debug the conflicting line as it is necessary for the continuation of the script.
try to split the finder window values in two lines:
set the_id to id of a
set the_pt to target of a as text
instead of
set {the_id, the_pt} to {id, target} of a
set the_pt to (the_pt as text)
Does it work well on your machine when you have open Finder windows into applications and bundles?
It is no big deal really, I just wanted to time them, out of curiousity. It is just that I have such windows open all the time.
Edit: Are you using 10.8? Because it doesn’t work for me with 10.6, with regular finder windows, containing regular folders, when I run from within Script Debugger 4.5.7.
Hi mark,
i did my best to help us all, first. The question is more, if the script working for you ?
The script i wrote considers and plays with window names simply.
tell application "System Events" to set spaces_win to name of windows of process "Finder"
Given the script i wrote, everybody should be able to adjust the variables and lines he/she dislikes. Other solutions aren’t that far, i think.
Since your script doesn’t do what mine does, I wonder if you can adjust your blog-post a tad.
You should also speed-test it. If I have say 30 windows open, and then opens 20 windows that are alike, my script closes the duplicate windows in 2 secs, on my machine.
i’ve no issues running my script for duplicate windows in application bundles too, as i do similar tests like you, always on the good old OS 10.6.
Check out if some of your osax-plugins or Script debugger interferes. Other Script editors may return different results as well, so i suggest to use the Applescript editor instead. Jo
I was just letting you know rather than wanting you to fix it.
To be honest I like the way my script works by getting rid of all the dupe windows in all the spaces.
Scripts like these risk being based on far too many variables related to individual Mac-User setup. We would be here for ever if we tried to accommodate them all.
As you say there is enough info here know for others to take the scripts in what ever direction they want.
FYI. Your script used 7 seconds, contra 2 seconds by mine, when both were executed from the scripts menu. My script where told to run, which I also did to your script, which made your script execute in 6 seconds.
I took all the trouble with my script for the speed.
And . I forgot to mention that: 1.2 seconds of the time of my script is used for showing a dialog within the test.
I also figured I’d test Mark Hunte’s script, although his script doesn’t quite fit the bill, as it operates on all spaces. I applied the same envelope script trick, to make it run faster before I ran it from the script menu, and alas it used 10 seconds, twice.
So much for what is necessary and not, in order to gain speed. 10 / 0.8 tells me that my script is 12,5 times faster than his. And that is where the complexity of the script stems from.
Hi McUsr,
sorry to disappoint you, but the speed factor isn’t related at the amount of code, but to the code structure one builds. Its not a novelty for me that putting scripts into a script-handler enhances the script execution dramatically. Then i get with my script 2 seconds for 33 duplicate windows, like you.
I write this not to have the last word, but to set the things right as they are.
You did, because I actually put your script inside a script, and told “joys” to run, with 30 unique windows, 20 duplicates, and then your script used 6 seconds. I started the timer after the dialog. and took the difference between that time, and the (current time) when your script was finished.
This is how your script looked when I ran the test, I ran the test twice, from the script menu, to be sure. It used 7 seconds both times. My script uses effectively 0.8 seconds, when we subtract the time it uses on showing the dialog. My script is 7 / 0.8 = 8.75 times faster than yours. (37 unique windows, 19 duplicates).
script joys
tell application "Finder" to set finder_icon to path to resource "Finder.icns"
try
set button_pressed to button returned of (display dialog "Close window Duplicates in." buttons {"Current Space only", "All Spaces", "Cancel"} default button 3 with icon finder_icon)
on error number the err
if err is -128 then return
end try
set t1 to (current date)
if button_pressed is "Current Space only" then
tell application "System Events" to set spaces_win to name of windows of process "Finder"
else
set spaces_win to 0
end if
tell application "Finder"
set {pt_ls, open_wins} to {{}, windows}
repeat with a in open_wins
if name of a does not end with "Clipping" then
set {the_id, the_pt} to {id, target} of a
set the_pt to (the_pt as text)
if the_pt is not in pt_ls then
copy the_pt to end of pt_ls
else
if spaces_win is 0 then
if the_pt is not "" then close a
else
if name of a is in spaces_win and the_pt is not "" then close a
end if
end if
end if
end repeat
set t2 to (current date)
activate
display dialog "" & (t2 - t1)
end tell
end script
tell joys to run
I am done with this now unless somebody has more to add.
The speed issue will also be different from Mac to Mac.
Your script does indeed run 2 seconds faster than mine on my Mac. (35 dupe windows) But I did not write it thinking about speed.
I only do that if the job it is going to do is intense. Which for me this task will never be. I will never have that many window open.
I could cut 2 seconds off mine. if I thought it important enough!, by changing all the individual calls to the target, id and name into a single call to properties.
Then just access the store of that.
set theProps to properties of this_item
set {windowID, windowTarget, windowName} to {id, target, name} of theProps (* get the windows target*)
and instead of closing each window with a call to finder for each. Just copy them to a list and close all of them at the end.
--close this_item (* close the Window *)
copy this_item to end of WindowClose