That is fair. And that does work.
It does not work if for any reason OmniFocus did not close normally or if the screen size changes - external monitor to laptop.
So I tried the below included scripts. They are clunky. But sort of work.
// this script prints in the console what the current windows are and their coordinates.
// this information as of now needs to be copied to the next script manually - copy paste etc.
function run() {
const omniFocus = Application("OmniFocus");
omniFocus.includeStandardAdditions = true;
const windows = omniFocus.defaultDocument.documentWindows();
for (window of windows) {
console.log(JSON.stringify(window.properties()));
if (window["visible"] === true){
console.log(JSON.stringify(window.properties()));
}
}
}
This script closes all existing windows, and then launches new windows per what is declared at the top in the script.
function run() {
const omniFocus = Application("OmniFocus");
omniFocus.includeStandardAdditions = true;
const curr_windows = omniFocus.defaultDocument.documentWindows();
// close all existing windows since new windows will be launched
for (window of curr_windows) {
console.log(window.name());
window.close();
delay(0.5);
}
target_windows_on_laptop = [
{"type":"window", "bounds":{"x":5,"y":24,"width":637,"height":530},"perspectiveName":"Forecast"},
{"type":"tab", "bounds":{"x":12,"y":25,"width":1036,"height":530},"perspectiveName":"daily"},
{"type":"tab", "bounds":{"x":9,"y":25,"width":636,"height":530},"perspectiveName":"Inbox"},
];
target_windows_on_external_monitor = [
{"type":"window","perspectiveName":"daily", "bounds":{"x":3,"y":909,"width":643,"height":521}, "Sidebar":"N", "Toolbar": "N", "Inspector":"N"},
{"type":"window","bounds":{"x":5,"y":523,"width":641,"height":385},"perspectiveName":"Inbox", "Sidebar":"N", "Toolbar": "N", "Inspector":"N"},
{"type":"window","bounds":{"x":650,"y":1041,"width":632,"height":389},"perspectiveName":"Calls", "Sidebar":"N", "Toolbar": "N", "Inspector":"N"},
]
// decide the target based on which screen
target_windows = target_windows_on_external_monitor;
for (window of target_windows){
var of_window = omniFocus.DocumentWindow({ perspectiveName: window["perspectiveName"], "bounds":window["bounds"]});
omniFocus.defaultDocument.documentWindows.push(of_window); // this will create the window
omniFocus.activate();
// now time to check if Sidebar, Toolbar and Inspector are the way they should be
// set_bar("Sidebar",window["Sidebar"]);
for (whichBar of ["Sidebar", "Toolbar", "Inspector"]) {
if (window[whichBar] === "N"){
menuItemString = "Hide " + whichBar;
} else {
menuItemString = "Show " + whichBar;
}
result = menuItemTestClick("OmniFocus", ['View', menuItemString]);
// console.log(window["perspectiveName"] + " Result of click for " + menuItemString + " is " + result);
}
var win = omniFocus.defaultDocument.documentWindows[0];
// return win.properties();
// console.log("Name of window is " + win.name);
win.bounds = window["bounds"];
// return;
}
}
// source: https://gist.github.com/bumaociyuan/a37c78cd5503f371b391
// TESTING VERSION: REPORTS ANY ERRORS IN DETAIL OF MENU PATHS
// Click an OS X app sub-menu item
// 2nd argument is an array of arbitrary length (exact menu item labels, giving full path)
//menuItemClick("InqScribe", ['View', 'Aspect Ratio', 'Use Media Ratio'])
function menuItemTestClick(strAppName, lstMenuPath) {
var oApp = Application(strAppName),
lngChain = lstMenuPath.length,
blnResult = false
var blnDebug = false; // edit to 'true' if you want warnings of errors in the path
// (NOTE this kind of checking slows the script, so edit to blnDebug=false for regular use)
if (lngChain > 1) {
var appSE = Application("System Events"),
lstApps = appSE.processes.where({
name: strAppName
}),
procApp = lstApps.length ? lstApps[0] : null;
if (procApp) {
var strMenu = lstMenuPath[0],
strPath = strMenu,
fnMenu = procApp.menuBars[0].menus.byName(strMenu),
lngLast = lngChain - 1,
mnuItem;
if (blnDebug) {
try {
fnMenu.class()
} catch (e) {
throw "Menu Name " + '"' + strMenu + '"' + " not found in " + strAppName
}
}
for (var i = 1; i < lngLast; i++) {
strMenu = lstMenuPath[i];
strPath = strPath + ' > ' + strMenu;
fnMenu = fnMenu.menuItems[strMenu].menus[strMenu];
if (blnDebug) {
try {
fnMenu.class()
} catch (e) {
throw "Menu item " + '"' + strPath + '"' + " not found in " + strAppName
}
}
}
strMenu = lstMenuPath[lngLast];
strPath = strPath + ' > ' + strMenu;
mnuItem = fnMenu.menuItems[strMenu];
if (blnDebug) {
try {
mnuItem.class()
} catch (e) {
throw "Menu item " + '"' + strPath + '"' + " not found in " + strAppName
}
}
oApp.activate()
try {
mnuItem.click();
delay(1);
blnResult = true;
} catch (e) {
if (blnDebug){
console.log("Menu item" + '"' + strPath + '"' + " not found in " + strAppName);
}
}
}
}
return blnResult;
}