Dual monitor screen number issue

I read in the Ignition manual about setting up a multi-monitor project and used the example startup script to test this out. My problem is that the primary monitor always starts on my right monitor instead of the left, which is monitor 1 in Windows. In order to get this to work correctly, I had to configure the client launcher to start on screen 1 (right monitor, monitor 2 in Windows) and then have the startup script open the second desktop on screen 0. In this configuration I get my primary main window to open on the left and the secondary main window to open on the right, as is desired. The default launch mode in the project properties is set to full screen. While this configuration works, it is certainly not the expected behavior, and I expect it will be different on the production computer. Can anyone explain to me how I might set Windows (or something) so that the left monitor is considered screen 0 and the right monitor is considered screen 1? Below is my project startup script:

system.nav.swapTo('New Windows/Navigation')
system.nav.openWindow('New Windows/Left Window')

system.gui.openDesktop(screen = 0, windows = ["New Windows/Right Window"], \
handle = "Secondary Window", x = 0, y = 0, width = 1920, height = 1080)

There is no way to configure from software the assigned monitor number (because, Windows).

The BIOS may have a setting that determines which monitor is considered Monitor 1.

The only solution that I have found to this which works across all windows machines is to take these steps:

  1. Shutdown machine
  2. Unplug all monitors except the one you would like to be Monitor 1.
  3. Start machine.
  4. Plug in other monitors in the order you want them to be. Monitor 2, Monitor 3, etc...
  5. Make sure your display settings are configured correctly to the way you would like them to be used. (e.g. make certain that monitors are set in their correct position so extended desktops work as expected).
  6. Restart machine.

Generally windows will remember which monitor was 'Monitor 1'. If these steps don't work then your system may require that a particular monitor port has 'Monitor 1' connected and so the only way to switch would be to plug the monitors into different ports.

1 Like

I had this problem with two machines, one was running windows 10, the other windows 11. Same monitor setup, but windows 11 would identify them in a different order than windows 10 no matter what I tried.

Also, the number changed if I switched between using a display port with converter cable to hdmi versus hdmi to hdmi. Though just swapping the ports for both monitors did not work, windows 11 kept the previous assigned numbers!

In the end, I lucked up because the two montiors had different resolutions, the 2560-pixel monitor was the HMI display and the 1920 was an offload display, so I used that to determine screen "number"

1 Like

Thanks. I understand the uselessness of Windows so I was kind of hoping for a way to interrogate the system to be able to force the proper window to show up on the proper desktop during my client startup script. Once that's done, I should be fine with simple navigation using "swapTo" commands.

You may find this topic helpful:

I went a different route for multi-monitor clients. Not all clients are multi-monitor, and not all multi-monitor clients have the same number of monitors.

I have one button to toggle between fullscreen and windowed mode and another button to add a desktop.

The client launches with the main desktop on the main screen. Users can then add a desktop, switch to windowed mode, drag it to the other screen, and switch back to fullscreen mode. It's a little more manual, but much more flexible and clients are not re-launched all that often.

image

1 Like

Additionally, I sometimes have large monitors where I want to display multiple desktops within the same monitor, and sometimes, the orientation of monitors can vary. Nevertheless, I like to automate the positioning process.

Here is a basic example of how I do it:

Example Library Script
from java.awt import GraphicsEnvironment
from javax.swing import JFrame, SwingUtilities
'''
Adds a desktop instance in each monitor incrementally numbered from left to right, top to bottom
...or restores missing or moved desktops to their assigned position if they've been rearranged or closed.
'''
def setAllMonitors():
	# Get a list of any desktops that have already been opened
	desktopHandles = system.gui.getDesktopHandles()
	
	# Get the bounds of each screen from the graphics environment and sort them from right to left, top to bottom
	screens = sorted([device.defaultConfiguration.bounds for device in GraphicsEnvironment.getLocalGraphicsEnvironment().screenDevices], key=lambda screen: (screen.x, screen.y))
	
	# Check to see if there is more than one screen to open desktops in
	multiMonitor = False if len(screens) < 1 else True

	# Get the JFrame of the primary open window
	primaryDesktop = SwingUtilities.getAncestorOfClass(JFrame, system.gui.getOpenedWindows()[0])
	
	# Assumes a standard height menu bar across the bottom of the window
	menuBarOffset = 32
	
	# If multimode is not active, we can stop right here
	if not multiMonitor:
		return
	
	# Iterate through each screen, putting the primary in the top left, 
	# ...and opening a new desktop in each of the other screens,
	for index, screen in enumerate(screens):
		if index == 0: # This will be the upper left screen
			primaryDesktop.setLocation(screen.x, screen.y)
			primaryDesktop.setSize(screen.width, screen.height - menuBarOffset)
		
		else:
			# Desktop {}".format(index + 1) = Each desktop opened after the primary desktop, 
			# will be assigned incrementally named handles "Desktop 2", "Desktop 3", etc	
			# By not specifying a screen index in the openDesktop call,
			# ...openDesktop will automatically map the screens according to the graphics environment coordinates instead of specific screen coordinates
			desktopName = "Desktop {}".format(index + 1) # The + 1 is needed to make the secondary desktop start at 2
			
			# If it's found that a certain desktop already exists, simply move it back to its assigned location
			if desktopName in desktopHandles:
				window = SwingUtilities.getAncestorOfClass(JFrame, system.gui.desktop(desktopName).getWindow(system.nav.desktop(desktopName).getCurrentWindow()))
				window.setLocation(screen.x, screen.y)
				window.setSize(screen.width, screen.height - menuBarOffset)
			
			# If the desktop is missing or has never been opened, create it and set it to the appropriate monitor
			else:
				system.gui.openDesktop(handle = desktopName, x = screen.x, y = screen.y, width = screen.width, height = screen.height - menuBarOffset)

				# Without a swap to call, the desktop will open to a useless blank screen
				system.nav.desktop(desktopName).swapTo('Some/Window/Path')

Here are the main advantages of this approach:
• The primary desktop is always placed in the top left monitor, and all additional desktops are numbered according to their relative positions from left to right, top to bottom regardless of what indexes the OS has assigned each monitor

• Additionally, the script can be called at any time to restore desktop instances that have been closed or to reposition desktops to their respective monitors if the desktop instances have been moved or rearranged.

4 Likes