Check what screen a client is open on

v7.9.14

How would I check what screen a client is open on? E.g. I have 2 TV screens connected to Ignition and have two separate clients open (not two desktops, as these don’t work with the Windows scaling I have configured :/), and I want to know if the client i’m looking at is on screen 1 or screen 2.

Also, how do I get a reference to the FPMIApp?

In 8.x you’d use system.gui.getScreenIndex. In 7.9 I expect you’ll need to dig into Java something like examples here.

https://docs.inductiveautomation.com/display/DOC79/system.gui.getScreens
??
We use this to determine if we load the full side navigation or a popup window.

That function gets the screens available, but doesn't tell you what screen an open client is already on.

That is what getCurrentDesktop is for.
Run that on the clients, write it to a memory tag and then you will have the references.
Then you can check for the values and do whatever you need to do.

https://docs.inductiveautomation.com/display/DOC79/system.gui.getCurrentDesktop

Maybe I’m missing something, but I still don’t see how I can get the current screen (as in the monitor) that the client/desktop is on from that? system.gui.getCurrentDesktop just returns a handle as a string of the current client desktop, with which you can get a reference to system.gui.* functions relative to the handle.
There is a function system.gui.setScreenIndex, but I need system.gui.getScreenIndex (as witman pointed out is available in 8).
I want to open a particular page on client startup based on the monitor/screen it’s on.

https://docs.inductiveautomation.com/display/DOC79/system.gui.getScreens

??

That gets a list of all monitors that are available on the PC…
??

Correct, and the screen index of each corresponds to the screen index in the system.
When you open the display properties in Windows, click the Identify button and it shows 1,2,3 etc on each screen. You can then tell the client to open whatever window or desktop on whatever screen index you want.

I’m not sure what actual value you are looking to get, you can’t get any system level stuff like serial numbers of the screens without doing some outside power scripting.

I think you’re misunderstanding what I have. I already have a client running on the screen I want it on, the problem is that I have two clients, one running on either or 2 screens. I want to know which client is running on screen 2 so that I can launch the right screens. I set the screen for it to launch on within the client’s shortcut switches

I actually tried this already as @PGriffith posted something similar using that library a while back, but all it ever states is that it's on screen 0, despite moving it to other monitors :frowning:

When you open the client, name the screen with a handle.
Then you can use that desktop “name” in the navigation.
We launch other instances from the main client onto other monitors.
Maybe that is the issue? We have a few locations that actually launch up to 8 instances on separate monitors all driven off of one computer.

Hmm, to set the handle I would need to set it via the Windows shortcut startup parameters, however I don’t see the handle being possible to pass in (Native Client Launchers - Ignition User Manual 7.9 - Ignition Documentation)
I can’t set this from the startup script (otherwise there would be no use for this post :slight_smile: )

I initially was starting this second screen using system.gui.openDesktop(), however with the TV setup we have onsite, I couldn’t get both screens to display as fullscreen, and I spent a while trying to work it out. Windows scaling had to be set to 175% on one TV and 100% on the other, but even testing them both at 100% I couldn’t get them both fullscreen either - one would go fullscreen and the other would be at some stupid zoom but the client itself would be clipped to about 3/4 of the TV screen… The only way I could get it working was to launch independent clients, and even then I still have to coerce the second client to go fullscreen by manually nudging the client… It’s a PITA!

@nminchin would a script like this work to set the windows full screen for you? It works to maximize a window to full screen mode (a second desktop, not a separate client) on two different monitors with different scaling on Windows 10 for me.

I should note the position recall on return to windowed state does not work well on the right monitor in a dual monitor setup with different scaling. It has the same issues as Designer windows that do weird stuff when switching between scaling on the monitors. But the swap to full screen mode works reliably filling the entire monitor on whichever monitor it is on.

I initially was starting this second screen using system.gui.openDesktop() , however with the TV setup we have onsite, I couldn’t get both screens to display as fullscreen, and I spent a while trying to work it out. Windows scaling had to be set to 175% on one TV and 100% on the other, but even testing them both at 100% I couldn’t get them both fullscreen either - one would go fullscreen and the other would be at some stupid zoom but the client itself would be clipped to about 3/4 of the TV screen… The only way I could get it working was to launch independent clients, and even then I still have to coerce the second client to go fullscreen by manually nudging the client… It’s a PITA!

Sounds like you could justify a properly engineered and configured set of monitors. :wink:
Curious to see what the programming solution is to this mechanical problem.

I use something that you could possibly use for this purpose:

  • a Global (shared) script, that implements functions WindowOpened and WindowClosed, to write who opened/closed what window to the audit_events table
  • a script on the visionWindowOpened event (and a corresponding script on the visionWindowClosed event) on every window in the project.

I use this so I can track operator actions. I’m thinking you could query the most recent WindowOpened event in the audit_events table, to see which window was most recently opened for the client of interest. I don’t know if this is the most effficient way to accomplish what I want, but it works for me.

visionWindowOpened event:

shared.WindowScript.WindowOpened(system.gui.getParentWindow(event).name, '')

Global (shared) script (named “windowScript”)

# these scripts by HAB are used to log all Operator Screen opens/closes to Audit_Events table
# called by event handler scripts on every screen - one script for ScreenOpen, one script for ScreenClosed 
def WindowOpened(WindowName, TagPath):
	Actor = system.tag.read("[System]Client/User/Username").value
	ActorHost = system.tag.read("[System]Client/Network/Hostname").value
	Action = 'OpenWindow'
	ActionTarget = WindowName
	ActionValue = TagPath
	from java.util import Date
	CurrTime = Date()
	StatusCode = 0
	OriginatingSystem = 'project='+system.tag.read("[System]Client/System/ProjectName").value
	OriginatingContext = 22  #value to enable searching for tag events
	try:
		system.db.runPrepUpdate("INSERT INTO audit_events " \
        	                    "(event_timestamp, actor, actor_host, action, action_target, " \
        	                    "action_value, status_code, originating_system, originating_context) " \
	                            "VALUES " \
	                            "(?, ?, ?, ?, ?, " \
	                            "?, ?, ?, ?)", 
 	                            [CurrTime, Actor, ActorHost, Action, ActionTarget,
	                            ActionValue, StatusCode, OriginatingSystem, OriginatingContext], 
	                            database='Ignition_SQL_App001') #must include database connection name
	except:
		pass 

Been meaning to get back to this topic, but my daughter’s wedding has been keeping my household busy.

# get the source of a component
component = event.source

# get Screen number that component is in.
screen = component.getGraphicsConfiguration().getDevice().getScreen()

print screen

Lots of good solutions! However keep in mind that I’m looking to get the screen the client is open on, before any Windows are open (i.e. it’s just the blank grey client area). I guess I could open up a dummy window first to use some of these solutions, but if I can get the screen without having a Window open, then that’d be far more efficient

I'm not at my desk, so no extra screens, but this seems to work in a Client Startup Script.

import java.awt

gd=java.awt.GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice()

screen = gd.getScreen()
width = gd.getDisplayMode().getWidth()
height = gd.getDisplayMode().getHeight()

tagNames = ['[client]ScreenNum', '[client]ScreenWidth', '[client]ScreenHeight']
values = [screen, width, height]

system.tag.writeBlocking(tagNames, values)

I did try using that and @witman mentioned looking at it as well, however the gd.getScreen() (or gd.screen) always displays 0, regardless of what screen it's actually on :confused: