Is it possible to make use of multiple monitors with a single Vision client?
For example, at one of our larger plants, the operators in the control room currently keep 7 main windows and 2 popup windows that can be moved independantly of their parent windows (as in, outside the constraints of their parent window borders) open at all times–4 on the left monitor, and 5 on the right. They have the windows partially overlapping in a layout that allows them to see the basic status in all 9 windows, and they can quickly see the rest of any one window simply by clicking on it. Is it possible to recreate this (9 individual screens in windowed mode, arranged as desired on two monitors setup as an extended desktop in MS Windows) in Ignition without running 9 separate vision clients on one PC?
In another scenario, we have two touch screens on one machine in the plant where we would like to display a separate screen on each, both in FSE (full screen exclusive) mode. I understand this could be done by launching two separate Vision clients, and that the client launcher settings may be used to specify which screen each FSE mode Vision client will be maximized to. Is it possible to accomplish this with one Vision client? For example, can a single double monitor width main window be maximized across an entire extended desktop spanning the two touch screens?
Ive never tried it but I know you can set minimum client sizes. maybe if you set the client to be the same size as the desktop area then set the windows x-y positions to correlate to each monitor.
of course this wouldnt work if you have other clients connecting to the gateway besides the pc in the ocntrol room
Thanks all! What I’ve gathered so far (please correct me if I’ve misunderstood):
1 - It is not possible to have more than one main window open at once under a single Vision client (by “main window”, I mean a window that would show up separately on the MS Windows taskbar). 1 Vision client = 1 main window. Need more main windows? 2 Vision clients = 2 main windows, etc.
2 - It is possible to span a single main window across multiple monitors if your monitor driver supports spanning (with an Intel GMA 3500 Series, spanning does not appear to be supported). In this case, 1 Vision client covers multiple monitors with 1 main window, however frameless popups positioned and sized appropriately could give the appearance of two separate full screen clients. This will of course show only 1 Vision window on the taskbar–it’s just a big window that spans more than one monitor. This also means that in a multi-tasking environment, you won’t be able to show another application on part or all of one monitor while clicking in the Vision client on the other monitor–clicking in the Vision client will bring the multi-monitor size window back in front of everything else on the desktop. All of this is not a real problem on terminals that are only use for the Vision clients. Note however, that spanning may not work well if the two screens are not the same resolution.
For the dual touch screens on one PC, launching two Vision clients in full screen mode with startup parameters specifying the two screens worked well. This required a client startup script to confirm which PC the clients were on (don’t want it to affect remote clients) and which screen they were on in order to automatically open the correct window on each touch screen. No problems here after a little scripting work (Kyle’s script gives a good start on this–thanks Kyle!–although I agree with mazeyrat that getting monitor management built into Ignition would be really helpful). The only known drawback at this time is each client eats up more memory.
The above points mean that to get the kind of window flexibility operators are used to in the more complex plant I mentioned (they also use MS Office, web applications, etc. on the job so a single spanned window covering both monitors isn’t a great solution) we would need to run each window (9 of them!) in separate Vision clients. The operators are used to dealing with HMI pages in separate windows as any other Windows application in a multitasking environment. Nine Vision clients take a while to start up (a lot longer than opening 9 pages) and will use quite a bit of memory (64-bit OS likely a must). And operators sometimes close a window or two and then want to re-open them later. With the present 1 client = 1 window limitation, Ignition doesn’t look like an ideal fit for this kind of a heavy multi-tasking usage scenario.
I think this is possible but quite tricky... The main issue I think is that it is not possible to design a simple container without embedding it in a main or popup window.
For example the code below will "steal" the content of an existing window and show it an independent window with its own icon in the taskbar. I don't know if there is a better way or what are the consequences but this could get you started. Obviously I am pretty sure there are some drawbacks, but this could get you started... For this example I assume the window "About" exists and is opened. I have tested this only in the designer using the Script Playground.
Thanks nclemeur! I will try this out. A resolution to this issue would be excellent as it would open the way for us to use Ignition in some applications where we would really like to benefit from its ease of deployment without creating ease of use hurdles.
I think this is possible but quite tricky...[/quote]
I tried a simple test case first - we have two basic touch screens connected to one PC. In this case we want full screen windows on both. Modifying your code a bit for this full screen use case, it seems to do the trick (as a Client Startup Event Script). We open the client maximized on Display0 and the startup script handles the rest to get full screen displays on both displays.
def initializeOITs():
import system
# only execute this on the specific computer it applies to
if system.net.getHostName() == "computer name":
from javax.swing import JFrame
system.nav.openWindow('Display1')
contentPane = system.gui.getWindow('Display1').rootContainer.getRootPane().getContentPane()
system.nav.openWindow('Display0')
newWindow = JFrame()
# update new window title (it is not included in contentPane and is blank otherwise)
newWindow.title = 'Display 1'
newWindow.setContentPane(contentPane)
# set size and location--will vary with graphic device configuration
newWindow.setSize(1280,1024)
newWindow.setLocation(1680, 0)
newWindow.setUndecorated(1)
newWindow.setVisible(1)
system.util.invokeLater(initializeOITs) The Good: - Startup is much faster with one client and two windows (rather than two clients) on the one PC. Second window opens nearly instantaneously. - Memory usuage should be lower with only one client, though I have not verified this. - This looks like it won't be hard to improve and wrap up in some standard functions to open different windows in separate main windows (with Taskbar icons) just like the operators in the plant I mentioned currently do with a different SCADA package. And it looks likely to resolve the challenges I noted earlier with using Ignition for their heavy multi-tasking usage scenario.
The Less than Ideal: 1 - Designer updates are NOT pushed to the new window(s). Regrabbing the contentPane for the new window(s) from an actionPerformed on a button in the new window(s) along with re-fixing sizing (screens are different sizes in this case) fixes this. If we could automate this based on a property change in the root container of each window (with a custom property tied to [System]Client/System/EditCount) it would be completely resolved. I believe the trick will be triggering the contentPane grab ONLY in the new window (not the original window we grab the contents from, which not surprisingly freezes java). 2 - Dialogues (such as action confirmations) raised from the new window will show up on the screen its contents were grabbed from (where the main Ignition window is) rather than where the new window presently is. I think some scripting would easily fix this, but haven't tried it yet.
There may be other issues I have not encountered yet, but so far this looks promising. Thanks again Nicolas!
It turns out Designer updates not pushing to the new window was worse than I realized at first. What happens is the original window is redrawn and the new window quits running (though it still displays everything that was there, bindings stop updating, etc).
Solution found for automating contentPane update on Designer update push: The trick is updating only the new window (not the original contentPane is grabbed from). This is accomplished by checking for a unique title assigned to the new window on creation (see code above). It is not possible to use a custom property bound to edit count to trigger the update as bindings in the new window stop updating. Instead we filter for a property change on componentRunning and then regrab the contentPane. It is necessary to use invokeLater with a bit of additional delay (using 10,000ms) for the redrawn original screen to show up as open for grabbing (otherwise get an error for window not open).
So far this update solution appears to work great with no known bad side effects.