The Omni Group
These forums are now read-only. Please visit our new forums to participate in discussion. A new account will be required to post in the new forums. For more info on the switch, see this post. Thank you!

Go Back   The Omni Group Forums > OmniOutliner > OmniOutliner 3 for Mac
FAQ Members List Calendar Search Today's Posts Mark Forums Read

 
Automatically resizing and positioning a OmniOutliner window Thread Tools Search this Thread Display Modes
When I'm working with a single monitor I often have OO3 as a full-height window in the right-hand third of the screen, and some other application in the left-hand two thirds. (Taking notes, or working through some kind of list in OO3).

Here is a script which will resize and reposition the selected window (of any application, as it happens) to the rightmost third of the screen.

Edit the 1st four property values to get the window size and position that you want. (I personally use 3 or 4 of these scripts, with keystrokes assigned to each).

Code:
-- SET SIZE AND POSITION OF SELECTED WINDOW (ANY APPLICATION)

-- NB:
-- 		1. only for single monitor setups 
--		2. Not all windows can be arbitrarily resized )

-- EXAMPLE: A full-height window, rightmost third of the screen:

-- POSITION (origin: top left)
property pPosnAcross : 2 / 3
property pPosnDown : 0

-- SIZE (units: proportion of the desktop)
property pSizeAcross : 1 / 3
property pSizeDown : 1

property pMenuHeight : 22

tell application id "com.apple.finder"
	tell window of desktop
		set {_, _, lngwidth, lngHeight} to bounds
		set lngHeight to lngHeight - pMenuHeight
	end tell
end tell

tell application id "com.apple.systemevents"
	tell front window of (first application process where frontmost = true)
		set position to {pPosnAcross * lngwidth, (pPosnDown * lngHeight) + pMenuHeight}
		set size to {pSizeAcross * lngwidth, pSizeDown * lngHeight}
	end tell
end tell

Last edited by RobTrew; 2011-01-26 at 11:01 AM..
 
FWIW a version which should work with single or multiple display systems, and can be run from the command line with four arguments: OriginX, OriginY, Width, Depth [and, optionally Index - see next post].
(Useful for assigning keystrokes to a variety of screen positions with something like Keyboard Maestro).

Code:
property pVer : "1.2"
property pTitle : "Resize and reposition window by % of screen" & tab & pVer

-- SET SIZE AND POSITION OF SELECTED WINDOW (ANY APPLICATION)
-- (WORKS WITH SINGLE OR DUAL DISPLAY SYSTEMS)

-- Can be also used with arguments from the command line.

-- 				e.g. if saved as ~/Library/Scripts/PlaceWin.scpt then,
--				to resize the selected window to the left third of the screen:

-- 					osascript ~/Library/Scripts/PlaceWin.scpt 0 0  0.333 1

--				where the parameters are OriginX OriginY Width Depth

-- THUS, TO RESTORE A WORKSPACE, A COMMAND LINE BATCH SCRIPT LIKE		
-- open -a 'omnioutliner professional'
-- osascript ~/Library/Scripts/PlaceWin.scpt 0 0  0.667 1 2
-- open -a 'DEVONthink Pro'
-- osascript ~/Library/Scripts/PlaceWin.scpt 0 0  0.667 1 1

--		(Which can be assigned to a keystroke with something like KeyBoard Maestro)

-- Version history
-- Ver 0.4	Waits, up to pTimeOut seconds, for the frontmost process to present a window (useful if an app is loading)
-- Ver 0.5 Should support more than two monitors. Code has been slightly simplified.
-- Ver 0.7 Cycles between one-corner rectangles, and their left-right and top-down complements
-- Ver 0.8 Accepts a fifth argument: an index which suppresses toggling and selects a particular transform of the basic coordinates (usually 1)
--			(Useful when calling the script after an open -b or open -a to launch an application)
-- Ver 0.9 if the height or width is 0.5 toggles between vertical and horizontal splits
--			(Economises on the allocation of keyboard shortcuts through something like Keyboard Maestro)
-- Ver 1.0 if the height or width is < 0.5 and expressible as 1/N where N is a small integer (≤ 6),  then cycles between the N fitting rectangles
-- Ver 1.1 Restores compensation for menu bar space (though Microsoft Word still recalcitrant with landscape splits)
-- Ver 1.2 Defaults to the primary rectangle on the first call with a particular set of parameters
--			(Begins to cycle through any screen-tiling transforms on the first repeated call).

-- DEFAULT: A full-height window, rightmost third of the screen:
-- NB (Not all windows can be arbitrarily resized)

-- UNITS - proportion of whichever screen is displaying the selected window
-- POSITION - (origin: top left)
property pPosnAcross : 0
property pPosnDown : 0

-- SIZE 
property pSizeAcross : 1 / 3
property pSizeDown : 1

property pblnMenuWindow : false
property pMenuHeight : 22
property pstrWinPrefsPath : "/Library/Preferences/com.apple.windowserver.plist"
property pTimeout : 10 -- Maximum number of seconds to wait for a loading app to present a window

property plstDisplays : {}
property piBox : 0
property piSpecific : missing value
property pblnRepeat : false

on run argv
	-- PROCESS ANY ARGUMENTS PASSED BY AN OSASCRIPT SHELL COMMAND
	try
		if class of argv is list then
			-- FIRST FOUR ARGUMENTS REQUIRED: OriginX, OriginY, Width, Height
			set refPosnSize to a reference to items 1 thru 4 of argv
			repeat with i from 1 to 4
				set item i of refPosnSize to (item i of refPosnSize) as real
			end repeat
			
			-- RECORD WHETHER THESE ARGUMENTS MATCH THOSE OF THE PREVIOUS CALL 
			--		(WE MAY NEED TO CYCLE TO THE NEXT COMPLEMENTARY TRANSFORM)
			set pblnRepeat to (contents of refPosnSize) = {pPosnAcross, pPosnDown, pSizeAcross, pSizeDown}
			
			-- AND UPDATE THE PERSISTENT PARAMETERS IF THEY HAVE CHANGED
			if not pblnRepeat then set {pPosnAcross, pPosnDown, pSizeAcross, pSizeDown} to refPosnSize
			
			-- HANDLE THE OPTIONAL FIFTH ARGUMENT 
			--   (AN INDEX TO A SPECIFIC COMPLEMENTARY TRANSFORM (LEFT/RIGHT OR TOP/DOWN) OF THE BASE RECTANGLE)
			-- 	USEFUL IF THE OSASCRIPT CALL FOLLOWS AN OPEN -A CALL 
			--  WHICH AIMS TO OPEN A NAMED APP TO A SPECIFIC WINDOW SIZE/POSN
			if length of argv > 4 then
				set piSpecific to (item 5 of argv)
			else
				set piSpecific to missing value
			end if
			
			-- IF THIS IS NOT A REPEATED CALL WITH THE SAME ARGUMENTS, 
			-- (AND NO TRANSFORM HAS BEEN SPECIFIED),
			-- THEN DEFAULT TO THE BASE RECTANGLE (TRANSFORM 1)
			if (not pblnRepeat) and (piSpecific is missing value) then set piSpecific to 1
		end if
	on error strError
		return strError
	end try
	
	-- NOW REPOSITION AND RESIZE THE FRONT WINDOW, 
	-- USING THE GIVEN PROPORTIONS OF THE CURRENT SCREEN SIZE
	ReSizePosn()
end run

-- GET THE CURRENT SCREEN SIZE, 
-- AND MOVE AND RESIZE THE FRONT WINDOW USING PROPORTIONAL DIMENSIONS
on ReSizePosn()
	-- GET THE PROPERTIES OF THE REMEMBERED DISPLAYS
	tell application id "com.apple.systemevents"
		tell contents of property list file pstrWinPrefsPath
			set plstDisplays to (first item of ((value of (property list item "DisplaySets")) as list))
		end tell
		
		-- GET THE FRONT WINDOW AND ITS POSITION
		set refProc to a reference to (first application process where frontmost = true)
		set procFront to (first application process where frontmost = true)
		set oWin to missing value
		repeat with i from 1 to pTimeout * 2
			if (count of windows of procFront) > 0 then exit repeat
			do shell script "sleep 0.5"
		end repeat
		set blnMSWord to (name of procFront) contains "Microsoft Word"
		set oWin to front window of procFront
		if oWin is missing value then return
		set {lngWinX, lngWinY} to position of oWin
		
		-- FIND THE DISPLAY CONTAINING THE TOP LEFT CORNER OF THIS WINDOW
		set blnFound to false
		repeat with recDisplay in plstDisplays
			set {lngScreenX, lngScreenY, lngScreenAcross, lngScreenDown} to {OriginX, OriginY, Width, Height} of recDisplay
			if ((lngWinX ≥ lngScreenX) and (lngWinX < (lngScreenX + lngScreenAcross)) and ¬
				((lngWinY ≥ lngScreenY) and (lngWinY < (lngScreenY + lngScreenDown)))) then
				set pblnMenuWindow to {lngScreenX, lngScreenY} = {0, 0}
				set blnFound to true
				exit repeat
			end if
		end repeat
		if not blnFound then return
		
		set lstBoxes to my GetTransforms({pPosnAcross, pPosnDown, pSizeAcross, pSizeDown}, {lngScreenX, lngScreenY, lngScreenAcross, lngScreenDown})
		if piSpecific is missing value then
			set piBox to piBox + 1
			if piBox > length of lstBoxes then set piBox to 1
		else
			try
				set piBox to (piSpecific as integer) -- specified as fifth argument of the command line
			on error
				set piBox to 1
			end try
		end if
		
		set {lngWinX, lngWinY, lngWinWidth, lngWinHeight} to item piBox of lstBoxes
		if pblnMenuWindow then set lngWinY to lngWinY + pMenuHeight
		tell oWin
			if blnMSWord then
				tell application id "com.Microsoft.Word"
					tell front window of active document
						set position to {lngWinX, lngWinY + (pMenuHeight)}
						set width to lngWinWidth
						set height to lngWinHeight
					end tell
				end tell
			else
				set {position, size} to {{lngWinX, lngWinY}, {lngWinWidth, lngWinHeight}}
			end if
		end tell
	end tell
	return
end ReSizePosn

-- FOR RECTANGLES WHICH INCLUDE ONE OR TWO CORNERS OF THE SCREEN,
-- OR TOUCH OPPOSITE EDGES OF THE SCREEN, AND HAVE A HEIGHT OR WIDTH 
-- WHICH IS A SIMPLE FRACTION OF THE CORRESPONDING SCREEN DIMENSION
-- GENERATE THE SCREEN-TILING SET OF COMPLEMENTARY RECTANGLES.

-- (REPEATED CALLS OF THE SCRIPT WITH THE SAME PARAMETERS CYCLE THROUGH THESE COMPLEMENTARY TRANSFORMS,
-- ALLOWING SIMPLE TILING OF THE SCREEN WITH A SMALL NUMBER OF ASSIGNED KEYSTROKES)
on GetTransforms({pPosnAcross, pPosnDown, pSizeAcross, pSizeDown}, {lngScreenX, lngScreenY, lngScreenAcross, lngScreenDown})
	if pblnMenuWindow then
		set lngScreenDown to lngScreenDown - pMenuHeight
		--set lngScreenY to lngScreenY + pMenuHeight
	end if
	set {lngX, lngY, lngwidth, lngHeight} to {(pPosnAcross * lngScreenAcross) + lngScreenX, (pPosnDown * lngScreenDown) + lngScreenY, pSizeAcross * lngScreenAcross, pSizeDown * lngScreenDown}
	set {pSizeAcross, pSizeDown} to {pSizeAcross as real, pSizeDown as real}
	
	set {lngDeltaX, lngDeltaY} to {0, 0}
	if lngX = 0 then set lngDeltaX to lngwidth
	if lngY = 0 then set lngDeltaY to lngHeight
	
	if (pSizeAcross = 1.0) or (pSizeDown = 1.0) then -- Single split left/right or up/down
		if pSizeAcross = 1.0 then
			-- UP DOWN
			if pSizeDown = 0.5 then -- (vertical and horizontal splits)
				set {lngAltwidth, lngAltHeight} to {pSizeDown * lngScreenAcross, pSizeAcross * lngScreenDown}
				{{lngX, lngY, lngwidth, lngHeight}, {lngX, lngDeltaY, lngwidth, lngScreenDown - lngHeight}, ¬
					{0, 0, lngAltwidth, lngAltHeight}, {lngAltwidth, 0, lngScreenAcross - lngAltwidth, lngAltHeight}}
			else if pSizeDown ≥ (1 / 6) and IsSimpleFraction(pSizeDown) then
				set lst to {}
				set lngDeltaY to 0
				repeat with i from 1 to (1 / pSizeDown) as integer
					set end of lst to {lngX, lngDeltaY, lngwidth, lngHeight}
					set lngDeltaY to lngDeltaY + lngHeight
				end repeat
				lst
			else
				{{lngX, lngY, lngwidth, lngHeight}, {lngX, lngDeltaY, lngwidth, lngScreenDown - lngHeight}}
			end if
		else
			-- LEFT RIGHT
			if pSizeAcross = 0.5 then
				set {lngAltwidth, lngAltHeight} to {pSizeDown * lngScreenAcross, pSizeAcross * lngScreenDown}
				{{lngX, lngY, lngwidth, lngHeight}, {lngDeltaX, lngY, lngScreenAcross - lngwidth, lngHeight}, ¬
					{0, 0, lngAltwidth, lngAltHeight}, {0, lngAltHeight, lngAltwidth, lngScreenDown - lngAltHeight}}
			else if pSizeAcross ≥ (1 / 6) and IsSimpleFraction(pSizeAcross) then
				set lst to {}
				set lngDeltaX to 0
				repeat with i from 1 to (1 / pSizeAcross) as integer
					set end of lst to {lngDeltaX, lngY, lngwidth, lngHeight}
					set lngDeltaX to lngDeltaX + lngwidth
				end repeat
				lst
			else
				{{lngX, lngY, lngwidth, lngHeight}, {lngDeltaX, lngY, lngScreenAcross - lngwidth, lngHeight}}
			end if
		end if
	else -- does this have at least one corner ?  (at {0,0} or (height+y)=1) or ((width+x)=1)
		if ({lngX, lngY} = {0, 0}) or AlmostOne(pSizeDown + pPosnDown) or AlmostOne(pSizeAcross + pPosnAcross) then
			
			{{lngX, lngY, lngwidth, lngHeight}, ¬
				{lngX, lngDeltaY, lngwidth, lngScreenDown - lngHeight}, ¬
				{lngDeltaX, lngDeltaY, lngScreenAcross - lngwidth, lngScreenDown - lngHeight}, ¬
				{lngDeltaX, lngY, lngScreenAcross - lngwidth, lngHeight}}
		else
			{{lngX, lngY, lngwidth, lngHeight}}
		end if
	end if
end GetTransforms

on AlmostOne(rNumber)
	(1 - rNumber) < 0.01
end AlmostOne

on IsSimpleFraction(nNumber)
	if nNumber > 0.5 then
		return false
	else
		set n to 1 / nNumber
		Abs((n as real) - (n as integer)) < 0.01
	end if
end IsSimpleFraction

on Abs(n)
	if n < 0 then
		-n
	else
		n
	end if
end Abs
--

Last edited by RobTrew; 2011-01-30 at 03:58 AM.. Reason: ver 1.2 Defaults to the primary tile on first call with given parameters
 
Thus to restore a workspace with, for example, OO3 in the right-hand third of the screen, and DevonThink in the left-hand two thirds, you could use a batch of shell commands like this:
Code:
#!/bin/sh
open -a 'DEVONthink Pro'
osascript ~/Library/Scripts/PlaceWin.scpt 0 0  0.667 1 1
open -a 'omnioutliner professional'
osascript ~/Library/Scripts/PlaceWin.scpt 0 0  0.667 1 2
(The fifth argument is an index. Repeated calls with the same parameters make the script cycle through complementary screen-tiling rectangles. Index 1 gives the primary rectangle, Index 2 gives the first complementary tile. In this case the right-hand third of the screen, to fill the screen by complementing the left-hand two thirds.

Automatic cycling through complementary tiles makes it possible to fill the screen quickly using a small number of assigned keystrokes).

( Note that for this to work well you probably need to set your oo3 preference to OmniOutliner > Preferences > General > When OmniOutliner Starts Up > Create a new document )

A shell script like this can, of course, be assigned to a key-stroke using, for example, FastScripts or Keyboard Maestro.

--

Last edited by RobTrew; 2011-01-30 at 04:21 AM..
 
 


Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes


Similar Threads
Thread Thread Starter Forum Replies Last Post
Stupid Newbie Question: Automatically resizing shapes and text Turtleboy OmniGraffle General 1 2010-01-14 04:11 PM
Omnioutliner not locating search results in main text window ncdasa OmniOutliner 3 for Mac 1 2009-05-15 10:27 PM
Resizing Window Everytime Omni Opens ? Loveanale OmniWeb General 1 2007-06-05 09:44 PM
Window resizing bug? Agnostus OmniGraffle General 0 2006-09-06 12:36 AM
Option to Prevent Sites from Resizing Main Window danlurie OmniWeb Feature Requests 3 2006-05-15 05:33 PM


All times are GMT -8. The time now is 07:05 AM.


Powered by vBulletin® Version 3.8.7
Copyright ©2000 - 2024, vBulletin Solutions, Inc.