OK... I think I cleaned everything up enough for you. This is a small part of a larger scripting backend, so I had to strip out some overhead stuff, but I tested it and it is working.
Just to make sure you are understanding how we do things with the software we deploy.
Our screens that we have developed have three components. A header, a slide out navigation dock on the west side of the screen, and then a main window.
The header window has a custom property named MainDesc that is populated when a new main window is opened on that desktop.
This is the dataset simply called MultiMonitor in the client tags.
"#NAMES"
"Node","Header","Navigation","Monitor1","Monitor1Params","Monitor2","Monitor2Params","Monitor3","Monitor3Params","Monitor4","Monitor4Params","Setup"
"#TYPES"
"str","str","str","str","str","str","str","str","str","str","str","str"
"#ROWS","2"
"Default","Header/Top Header","Navigation/Popout Navigation Left","Main Windows/Analogs","","","","","","","",""
"ESPLAPBRS2021","Header/Top Header","Navigation/Popout Navigation Left","Main Windows/Motors","","Main Windows/Monitor 2","","","","","",""
Node is the client node as defined from system.net.getHostName()
Header is the string path to the the main header bar at the top.
Navigation is the string path to the docked slide out window.
Monitor# is the string path to the window to display on monitor #
Monitor#Params is a JSON string that is passed to the Monitor# as the parameters for that window (optional)
Setup is not used at this moment.
Now for the code. This is called either from the client startup, or we have a welcome popup that the operator acknowledges.
import sys
from java.lang import Throwable,System
import java.lang.Exception
from java.awt import GraphicsEnvironment
def loadHome():
logger = system.util.getLogger('Client.Startup.loadHome')
mmTagPath = '[Client]MultiMonitor'
#Load up the java graphic environment so we can get details about the screens
#Develop a list of tuples representing each of the screens on the client system. Tuple is index,monitor number,width,height,x,y
#screen index is 0 based, monitor number is 1 based
ge = GraphicsEnvironment.getLocalGraphicsEnvironment()
screens = [[i,i+1,gd.getDefaultConfiguration().getBounds().width,gd.getDefaultConfiguration().getBounds().height,gd.getDefaultConfiguration().getBounds().x,gd.getDefaultConfiguration().getBounds().y] for i,gd in enumerate(ge.getScreenDevices())]
logger.trace('screens reported from java: {}'.format(screens))
currentNode = system.net.getHostName()
#Grab the multiMonitor client tag
tagPaths = [mmTagPath]
tagVals = system.tag.readBlocking(tagPaths)
multiMonitorDataSet = system.dataset.toPyDataSet(tagVals[0].value)
#Now search for this node
nodeColIdx = multiMonitorDataSet.getColumnIndex('Node')
nodeColumn = multiMonitorDataSet.getColumnAsList(nodeColIdx)
multiMonitorSetup = None
try:
nodeIdx = nodeColumn.index(currentNode)
logger.debug('found node {} as index {}'.format(currentNode,nodeIdx))
multiMonitorSetup = dict(zip(multiMonitorDataSet.getColumnNames(),multiMonitorDataSet[nodeIdx])) #Create a dict of the multi-monitor setup. Easier to manipulate.
except:
logger.debugf('Node {} not found, trying for default'.format(currentNode))
try:
nodeIdx = nodeColumn.index('Default')
logger.debug('Found default node')
multiMonitorSetup = dict(zip(multiMonitorDataSet.getColumnNames(),multiMonitorDataSet[nodeIdx]))
except:
logger.debug('Exception when looking for the default setup.')
#If the current node is found in the multimonitor list then open the screens
if multiMonitorSetup is not None:
logger.trace('multiMonitorSetup: {}'.format(multiMonitorSetup))
logger.debug('setup found, loading')
#For each of the screens in the screens list, loadup the monitor setup from the multiMonitorSetup
for screen in screens:
__loadScreen(multiMonitorSetup,screen)
def __loadScreen(setup,screen):
"""
Called internally to load a monitor
setup (dictionary): The monitor setup
screen (tuple): tuple representing the screen index, monitor number, width and height
"""
logger = system.util.getLogger('Client.Startup.__loadScreen')
#Unpack the tuple
index,monitorNum,width,height,x,y = screen
#check if there is a mainWindow
if setup.get('Monitor{}'.format(monitorNum)) is not None and len(setup.get('Monitor{}'.format(monitorNum))) > 0:
headerPath = setup.get('Header')
navPath = setup.get('Navigation')
mainPath = setup.get('Monitor{}'.format(monitorNum))
mainParams = system.util.jsonDecode(setup.get('Monitor{}Params'.format(monitorNum)))
handleName = 'Monitor {}'.format(monitorNum)
#If the headerPath in globals isn't set then set it
if system.util.getGlobals().get('headerPath') is None:
system.util.getGlobals()['headerPath'] = headerPath
desktop = system.nav.desktop()
if index > 0:
if handleName not in system.gui.getDesktopHandles():
system.gui.openDesktop(screen=index, handle=handleName, width=width, height=height)
desktop = system.nav.desktop(handleName)
if desktop is not None:
#Open the header
if headerPath is not None and len(headerPath) > 0:
header = desktop.swapTo(headerPath,{'DesktopHandle':handleName})
if navPath is not None and len(navPath) > 0:
#Open the navigation. Note... this is assumed to be a east/west window
navWin = desktop.swapTo(navPath,{'DesktopHandle':handleName})
#If not a docked window then center
if navWin.dockPosition <=0:
navWin.setLocation(navWin.getX(),(height-navWin.height)/2)
if mainPath and len(mainPath) > 0:
params = {}
#check the params
if mainParams is not None and isinstance(mainParams,dict):
#params exist and it is a dictionary. So merge them into the existing params
params = {key: value for d in (params, mainParams) for key, value in d.items()}
mainWin = desktop.swapTo(mainPath,params)
if header:
try:
header.getRootContainer().MainDesc = mainWin.title
except:
#At least we tried
pass
else:
logger.fatal('Error getting desktop')