Author: rwhitcomb Date: Thu Jul 17 22:50:15 2014 New Revision: 1611502 URL: http://svn.apache.org/r1611502 Log: PIVOT-953: Update startup positioning code to make sure that the final position for a desktop application is within the current virtual screen area. This is a better fix for earlier code that attempted to make the x and y values never go negative for two reasons: the previous code only worked on the --x and --y values specified on the command line, but not for saved positions, and for multiple monitor configurations where the secondary monitor(s) are left / above the primary monitor, the actual virtual screen coordinates could legitimately be negative and the window is still visible.
So, compute the bounds of the whole virtual screen space, by getting the union of all the screen device bounds, then make sure the x and y coordinates (just before using them to set the main window position) are within the virtual screen boundaries. This is a merge of revision 1610563 from trunk to branches/2.0.x. Modified: pivot/branches/2.0.x/ (props changed) pivot/branches/2.0.x/wtk/src/org/apache/pivot/wtk/DesktopApplicationContext.java Propchange: pivot/branches/2.0.x/ ------------------------------------------------------------------------------ Merged /pivot/trunk:r1610563 Modified: pivot/branches/2.0.x/wtk/src/org/apache/pivot/wtk/DesktopApplicationContext.java URL: http://svn.apache.org/viewvc/pivot/branches/2.0.x/wtk/src/org/apache/pivot/wtk/DesktopApplicationContext.java?rev=1611502&r1=1611501&r2=1611502&view=diff ============================================================================== --- pivot/branches/2.0.x/wtk/src/org/apache/pivot/wtk/DesktopApplicationContext.java (original) +++ pivot/branches/2.0.x/wtk/src/org/apache/pivot/wtk/DesktopApplicationContext.java Thu Jul 17 22:50:15 2014 @@ -18,8 +18,10 @@ package org.apache.pivot.wtk; import java.awt.AWTEvent; import java.awt.Graphics; +import java.awt.GraphicsConfiguration; import java.awt.GraphicsDevice; import java.awt.GraphicsEnvironment; +import java.awt.Rectangle; import java.awt.SplashScreen; import java.awt.event.InputEvent; import java.awt.event.KeyAdapter; @@ -456,6 +458,20 @@ public final class DesktopApplicationCon } /** + * Calculate the entire virtual desktop bounding rectangle + */ + private static Rectangle getVirtualDesktopBounds() { + Rectangle virtualBounds = new Rectangle(); + GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment(); + for (GraphicsDevice gd : ge.getScreenDevices()) { + for (GraphicsConfiguration gc : gd.getConfigurations()) { + virtualBounds = virtualBounds.union(gc.getBounds()); + } + } + return virtualBounds; + } + + /** * Primary application entry point. * * @param args @@ -493,17 +509,6 @@ public final class DesktopApplicationCon height = preferences.getInt(HEIGHT_ARGUMENT, height); maximized = preferences.getBoolean(MAXIMIZED_ARGUMENT, maximized); - // Update positioning if window is offscreen - GraphicsDevice[] screenDevices = GraphicsEnvironment.getLocalGraphicsEnvironment().getScreenDevices(); - if (screenDevices.length == 1) { - if (x < 0) { - x = 0; - } - - if (y < 0) { - y = 0; - } - } } catch (SecurityException exception) { System.err.println("Unable to retrieve startup preferences: " + exception); } @@ -572,11 +577,31 @@ public final class DesktopApplicationCon windowedHostFrame.setSize(width, height); windowedHostFrame.setResizable(resizable); + Rectangle screenSize = getVirtualDesktopBounds(); if (center) { - java.awt.Dimension screenSize = java.awt.Toolkit.getDefaultToolkit().getScreenSize(); - windowedHostFrame.setLocation((screenSize.width - width) / 2, - (screenSize.height - height) / 2); + // Center on the virtual desktop (which could span multiple physical displays) + windowedHostFrame.setLocation( + ((screenSize.width - width) / 2) + screenSize.x, + ((screenSize.height - height) / 2) + screenSize.y); } else { + // Ensure that if the position was from a display configuration that is no longer + // supported (like we last closed the app when there were two monitors and there + // is now only one) that we don't end up completely offscreen. + // This computation will always place the upper left corner of the app window somewhere + // on the virtual screen (noting that the virtual x,y location could be negative when + // secondary displays are left / above the primary one). + if (x >= screenSize.width) { + x = Math.max(screenSize.width - width, screenSize.x); + } + if (x < screenSize.x) { + x = screenSize.x; + } + if (y >= screenSize.height) { + y = Math.max(screenSize.height - height, screenSize.y); + } + if (y < screenSize.y) { + y = screenSize.y; + } windowedHostFrame.setLocation(x, y); }