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.