August 20, 2010

Cleaning up Windows in a non-Scriptable Application

Here is an example of using User Interface scripting in Applescript to move windows around in an application that is not otherwise scriptable. Through UI Scripting you can do some limited interface tasks with an app that you otherwise have no access to. For even the worst applications in terms of scriptability, UI Scripting can provide access to things like windows that are open, their size and their position.
In the script, once I have collected an array of all open windows in an app, a series of "if" boolean statements are used to detect which window I'm now working with. Some of them have a title property that can be tested for, while others have a fixed window size that can be checked.

This example uses the Accordance application. Accordance has custom window classifications that do not respond to any "clean up windows" menu command. The app is not scriptable, and due to the custom nature of its user interface, the properties that UI scripting has access to are extremely limited. Windows can get moved around when connecting/disconnecting external displays. This app rearranges the windows how you would like them.

Here is the text of the script, and you can find a link to the script on the Downloads page. (On how to integrate such a script into your own workflow, look elsewhere on this blog or google Applescript to your hearts content.)

-- Clean up Accordance windows  v.1
-- This script will move the first main search window to the top left, and then move all palettes to the edges of the main display
-- Will have to be adjusted to meet your tastes and your external display setup.

tell application "Finder"
set screenBounds to bounds of window of desktop
set screenWidth to item 3 of screenBounds
set screenHeight to item 4 of screenBounds
end tell

tell application "Accordance" to activate
delay 0.5
tell application "System Events"
tell process "Accord"
set winCount to count windows
repeat with n from 1 to winCount
set thisWindow to window n
set winSize to size of thisWindow
set sw to item 1 of winSize
set sh to item 2 of winSize
set winPosition to position of thisWindow
set pw to item 1 of winPosition
set ph to item 2 of winPosition
if description of thisWindow is "dialog" then
-- it is a main search window
-- move to top left
set position of thisWindow to {1, 22}
else if size of thisWindow is {96, 552} then
-- it is a Resource palette
-- move to top right
set position of thisWindow to {(screenWidth - sw), 22}
else if size of thisWindow is {324, 46} then
-- it is a Text palette
-- move to middle bottom
set position of thisWindow to {(screenWidth / 2), (screenHeight - sh)}
else if ((get title of thisWindow) as string) is "Highlight" then
-- it is a Highlight palette
-- move to bottom right
set position of thisWindow to {(screenWidth - sw), (screenHeight - sh)}
else if ((get title of thisWindow) as string) contains "Keyboard Characters" then
-- it is a Character palette
-- move to top middle
set position of thisWindow to {(screenWidth / 2), 22}
else if ((get subrole of thisWindow) as string) is "AXFloatingWindow" then
-- is a palette, so only option left is Instant Details palette
-- move to bottom left
set position of thisWindow to {1, (screenHeight - sh)}
-- Must be another main search window
-- Can check for title, etc. to move them.
end if
end repeat
end tell
end tell

No comments: