Automatically Set Finder Window Properties? (launchd Agent?)

Greetings, folks!

Is there any way to set a Finder folder’s window’s properties (bounds, arrange by list view, columns and column widths, toolbar hidden, etc.) whenever a new Finder folder is created, i.e. before opening it, or, if not, have a launchd (or eq.) agent run whenever any Finder window is opened?

I ask because Apple doesn’t make it possible to establish consistent, default folder window properties for new folder windows, (The Finder even ignores its own plist regarding the Toolbar’s visibility.) And assigning a generic .DS_Store file to a folder just doesn’t seem to be productive. :wink: (If only .DS_Store files were editable! )

Thus, I would like to create a launchd agent (or eq.) that will automate the process of setting such properties as soon as any Finder folder is created or opened. I would prefer not to have to create a stay-open background app, if possible, as I don’t want it running constantly (every second or faster) for the extended times I’m not in the Finder.

Thoughts?

Thank you!!

Richard Fairbanks

Model: 2.33GHz MBPC2D Running OS X 10.6.8
Browser: Google Chrome 18.0.1025.113
Operating System: Mac OS X (10.6)

I don’t think this is possible because of the underlying architecture. Warning- this is just (mildly informed) speculation! I think that the reason you can’t set properties ahead of time, is that there is not a “window” attached to a folder that you open.

Consider how things had changed from OS9 to OSX 10.4 (when this problem arose). Windows can stay in place and you can go up or down in different folder heirarchies, or change the view from list to column. Whereby in column view you aren’t even viewing only 1 folder, but can see a string of folders and change the view quickly.

So, look at it this way. The Finder (core OS) has a generic “window” object. It has its own bounds and setup of sidebar and style. Then inside that, can be shown the contents of any folder. And the display of that folder is dictated by the window’s style, NOT the settings of a folder’s contents. In OS9, each window had a space and size. Every folder opened a new window every time. To drill down deep in 5 folders for example, you’d get 5 windows opened (unless you held down option to close each one as you went). In Tiger and later, not every folder opens a new window. One window can show any folder or drive.

Now there also are exceptions to the general framework I described. If you are directly opening a folder with properties set, then usually the window preferences are respected. But if you then drill down into a folder inside that first folder, the sub-folders cannot use their own settings. They are locked into the first window’s view.

I think a lot of people have fretted about this topic a lot, and for many years since the Finder switched from spatially based windows to content based windows. Maybe check out PathFinder, that may be able to do what you want, but that’s a whole Finder replacement. Otherwise, you can make a script to open certain folders and position them where you want on screen, but they still have the behaviour of not keeping a default size/location/view whenever you close them or move it.

So I “did the dirty deed.” (for those who might recognize the oblique reference to National Lampoon’s "Animal House!) and wrote a stay-open applet (appended below) that does what needs to be done to solve this.

But it’s MORALLY WRONG!! :wink:

It uses up 3% of my CPU, running every second, when it should only be called when the Finder opens a new window. I know of no way of trapping for any newly opened Finder window or any changes to the Finder’s “Window” menu (which would change the list of open windows when a new window is opened).

I would expect that there must be a file that logs all currently open Finder windows (eg. to generate the Finder’s “Window” menu). If so, then I could probably use launchd’s “WatchPaths”, but I’m not aware of any such file.

Anyone?

Additional Notes:

  • To have the Finder retain the settings for the window, it is necessary to invoke the window’s “View Options” such that the window will "always open in . . . ". This is addressed in my obviously-personally-fine-tuned-and-now-ancient zoom-and-position-Finder-window script that I call from the applet, also appended below, just FYI.

  • It is necessary (at some point) to log out to ensure that the window’s newly assigned parameters are saved. This is yet another reason why so many of us have long been bemoaning Apple’s refusal to make the .DS_Store files (reliably) editable.

  • FYI, the applet can be made a background applet by control-clicking on it and add a new child to the Contents/Info.plist file. A long list of available options will appear and one of them is “Application is background only.” If you select that, a checkbox in the value column will appear when you tab to it. Checking that checkbox (i.e. making it “True”) will make the app a background app, i.e. it will not appear in the cmd-tab app list or any applications menus.

Blessings!

Richard Fairbanks

P.S.: Obviously you will need to adjust the file paths to suit your file locations.

-- humbly plundered from yet more Kai Edwards magic at: http://macscripter.net/viewtopic.php?id=14214

property idList : {}

on idle
	set x to 0
	try -- in case I delete the folder while the applet is running  :-)
		tell application "Finder" to if the number of windows > 0 then set n to (the name of window 1) -- in case another window opens
	end try
	-- make sure it is a standard window and not a text clipping, etc.
	-- run only if it is an unprocessed window; Apple's default window width is 770 pixels, which I never use. alter to taste
	tell application "System Events" to tell process "Finder" to try
		if the description of window n is "standard window" and item 1 of (the size of window n as list) = 770 then set x to 1
	end try
	if x is 1 then
		tell application "Finder" to try
			-- if the window hasn't already been processed . . . 
			-- replace the next line with your preferred code:
			if the id of window n is not in idList then run script alias "HD:Users:me:Scripts:Finder:Window Tiling:Position and Zoom Window" -- the script I've been running, and modifying, for many years
			set idList to the id of the windows
		end try
		1 -- seconds before next check
	else
		return 1 -- seconds before next check
	end if
end idle

on quit
	say "quitting automatic folder positioning" -- just to let me know it's no longer running  ;-)
	set idList to {}
	continue quit
end quit
global theFolder, xOffset, yOffset, screenHeight, noScrollBar

property sourceXOffset : 2
property sourceYOffset : 46
property constantXOffset : 22
property constantYOffset : 22
property constantWidth : 828

tell application "System Events" to set {{|Width|:screenWidth, |Height|:screenHeight}} to value of property list items of property list item 1 of property list item "DisplaySets" of property list file "HD:Library:Preferences:com.apple.windowserver.plist" -- the screen width isn't necessary here, but no reason to delete it
set alreadyOpen to true
set noScrollBar to 0

activate application "Finder"
tell application "System Events" to tell process "Finder" to if the description of window 1 is "system floating window" then click menu item "Hide View Options" of menu 1 of menu bar item "View" of menu bar 1

tell application "Finder"
	try
		if ((target of window 1 as text) contains "Mailsmith Notes:Incoming Count" and name of window 1 is in {"0", "1", "2", "3", "4", "5", "+"}) then
			set the bounds of window 1 to {-85, 900, 50, 1048}
			close window 1
			run me
		end if
	end try
	if the name of window 1 is "New Search" then -- if it is a search window
		set the properties of window "New Search" to {bounds:{800, 46, 1440, 900}, sidebar width:0}
	else if the class of window 1 is window then -- if it is a text clipping
		run script alias "HD:Users:me:Scripts:Finder:Center Quote Window"
	else if the name of the front Finder window is "Trash" then
		run script alias "HD:Users:me:Scripts:Finder:Open the Trash Folder"
	else
		my setWindow()
		set theFolder to the folder of the front Finder window
		my (setPosition for theFolder)
		my alwaysOpenInListView()
	end if
end tell

on setWindow()
	tell application "Finder"
		set statusbar visible of window 1 to true
		set toolbar visible of window 1 to false
		set the current view of window 1 to list view
		-- the following sets the default window width to 795 px:
		set properties of column name column of list view options of window 1 to {index:1, sort direction:normal, width:300}
		set properties of column size column of list view options of window 1 to {index:2, sort direction:reversed, width:100}
		set properties of column modification date column of list view options of window 1 to {index:3, sort direction:reversed, width:160}
		set properties of column kind column of list view options of window 1 to {index:5, sort direction:normal, width:220}
		set the calculates folder sizes of the list view options of window 1 to true
	end tell
end setWindow

to setPosition for theFolder
	tell application "Finder"
		tell theFolder to try -- this needs to be on a separate line
			tell container window
				set alreadyOpen to class is Finder window
				open
			end tell
		end try

		--calculate the offset multiplier
		set thePath to theFolder as string
		set offsetMultiplier to ((the number of items in (find text ":" in thePath with all occurrences)) - 1)
		set xOffset to (sourceXOffset + (constantXOffset * offsetMultiplier))
		set yOffset to (sourceYOffset + (constantYOffset * offsetMultiplier))
		tell the front Finder window
			set the position to {xOffset, yOffset}

			if the zoomed is false then my zoomWindow()

			-- if zooming it still leaves the vertical scroll bar showing
			tell application "System Events" to tell window 1 of application process "Finder"
				if scroll bar 1 of scroll area 1 of splitter group 1 exists then set noScrollBar to 1 -- this is if any scroll bar exists
			end tell

			if noScrollBar is 1 then -- if any scroll bar still exists then fix it
				set the bounds to {xOffset, yOffset, xOffset + 200, yOffset + 100}
				my zoomWindow()
			end if

			--check to see that zooming it hasn't bumped it up out of position
			set thePosition to the position
			set windowTop to (item 2 of thePosition)

			-- if the folder is too tall to fit in its position then reduce its height
			if (windowTop < yOffset) then set the bounds to {xOffset, yOffset, (xOffset + constantWidth), screenHeight}
		end tell

		tell theFolder
			tell container window to try
				if not alreadyOpen then close
			end try
		end tell
	end tell
end setPosition

on alwaysOpenInListView()
	tell application "System Events" to tell process "Finder"
		set frontmost to true
		if menu item "Show View Options" of menu "View" of menu bar 1 exists then click menu item "Show View Options" of menu "View" of menu bar 1
		repeat with i from 1 to the number of windows
			if the description of window i is "system floating window" then
				set the focused of window i to true
				if the value of (item 4 of (the value of item 7 of the attributes of window 1 as list)) is 0 then ¬
					click (item 4 of (the value of item 7 of the attributes of window 1 as list))
				-- the following is in case I set the window to icon view, it forces it to wrap the icons
				try
					click pop up button "Arrange by:" of group 1 of window 1
					-- return the value of item 3 of the attributes of item 1 of menu 1 of pop up button "Arrange by:" of group 1 of window 1 -- works!
					click menu item "Name" of menu 1 of pop up button "Arrange by:" of group 1 of window 1
				end try
				exit repeat
			end if
		end repeat
		click menu item "Hide View Options" of menu "View" of menu bar 1
	end tell
end alwaysOpenInListView

on zoomWindow()
	tell application "System Events" to tell process "Finder"
		tell window 1 to repeat with i in (buttons)
			if value of attribute "AXSubrole" of i is "AXZoomButton" then
				click i
				exit repeat
			end if
		end repeat
	end tell
end zoomWindow

Model: 2.33GHz MBPC2D Running OS X 10.6.8
Browser: Google Chrome 18.0.1025.113
Operating System: Mac OS X (10.6)

I read about this today on Macintouch: http://homepage.mac.com/nsekine/SYW/software/english/task3/. It apparently responds to system triggers without polling. Haven’t tried it myself.