close 'duplicate' finder windows - just for fun

Hi MacUsr, mark hunte,
i never thought that somebody would take this topic so seriously. :smiley:
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

Hi Joy,

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

:D:D

Hello Joy.

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


Hello:

I get “Can’t make «class alia» “” of application “Finder” into type text.”
from this line:

set the_pt to (the_pt as text)

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. :slight_smile:

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 Joy,

hmm, you new script is not considering spaces when chosen on my Mac 10.8, finder options:Assign to:none

Hello Mark.

Your script fails in Mac Os X 10.6 as I noted above.

Sorry about that, I will test it on 10.6 tomorrow. But I cannot do that right now as I do not have a 10.6 build to hand.

But should be simple enough to figure out if it is that line.

Cheers.

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.

greets,
Jo

Hello Mark.

Since your script doesn’t do what mine does, I wonder if you can adjust your blog-post a tad. :slight_smile:

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.

Hi MacUsr,

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

Hi MacUsr,

Don’t worry I will. Although I most likely will not do a speed test. :wink:

Hi Joy,

I was just letting you know rather than wanting you to fix it.:slight_smile:

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.

And cheers for the idea.

Hello Joy.

It worked after I restarted Finder.

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. :slight_smile:

And . I forgot to mention that: 1.2 seconds of the time of my script is used for showing a dialog within the test. :slight_smile:

Hello!

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. :wink:

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.

McUsr,

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
end repeat
	close items of WindowClose

Cheers.