< prev index next >

src/java.desktop/windows/classes/sun/awt/windows/WFramePeer.java

Print this page
rev 60071 : 8211999: Window positioning bugs due to overlapping GraphicsDevice bounds (Windows/HiDPI)
Reviewed-by: XXX


  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package sun.awt.windows;
  27 
  28 import java.awt.Component;
  29 import java.awt.Dimension;
  30 import java.awt.Frame;
  31 import java.awt.GraphicsConfiguration;
  32 import java.awt.MenuBar;
  33 import java.awt.Rectangle;
  34 import java.awt.peer.FramePeer;
  35 import java.security.AccessController;
  36 
  37 import sun.awt.AWTAccessor;
  38 import sun.awt.im.InputMethodManager;
  39 import sun.security.action.GetPropertyAction;
  40 
  41 import static sun.java2d.SunGraphicsEnvironment.convertToDeviceSpace;


  42 
  43 class WFramePeer extends WWindowPeer implements FramePeer {
  44 
  45     static {
  46         initIDs();
  47     }
  48 
  49     // initialize JNI field and method IDs
  50     private static native void initIDs();
  51 
  52     // FramePeer implementation
  53     @Override
  54     public native void setState(int state);
  55     @Override
  56     public native int getState();
  57 
  58     // sync target and peer
  59     public void setExtendedState(int state) {
  60         AWTAccessor.getFrameAccessor().setExtendedState((Frame)target, state);
  61     }


  80         } else {
  81             b = adjustMaximizedBounds(b);
  82             setMaximizedBounds(b.x, b.y, b.width, b.height);
  83         }
  84     }
  85 
  86     /**
  87      * The incoming bounds describe the maximized size and position of the
  88      * window in the virtual coordinate system. But the window manager expects
  89      * that the bounds are based on the size of the primary monitor and
  90      * position is based on the actual window monitor, even if the window
  91      * ultimately maximizes onto a secondary monitor. And the window manager
  92      * adjusts these values to compensate for differences between the primary
  93      * monitor and the monitor that displays the window.
  94      * <p>
  95      * The method translates the incoming bounds to the values acceptable
  96      * by the window manager. For more details, please refer to 6699851.
  97      */
  98     private Rectangle adjustMaximizedBounds(Rectangle bounds) {
  99         // All calculations should be done in the device space
 100         bounds = convertToDeviceSpace(bounds);
 101 
 102         GraphicsConfiguration gc = getGraphicsConfiguration();
 103         Rectangle currentDevBounds = convertToDeviceSpace(gc, gc.getBounds());
 104         // Prepare data for WM_GETMINMAXINFO message.
 105         // ptMaxPosition should be in coordinate system of the current monitor,
 106         // not the main monitor, or monitor on which we maximize the window.
 107         bounds.x -= currentDevBounds.x;
 108         bounds.y -= currentDevBounds.y;
 109         // ptMaxSize will be used as-is if the size is smaller than the main
 110         // monitor. If the size is larger than the main monitor then the
 111         // window manager adjusts the size, like this:
 112         // result = bounds.w + (current.w - main.w); =>> wrong size
 113         // We can try to compensate for this adjustment like this:
 114         // result = bounds.w - (current.w - main.w);
 115         // but this can result to the size smaller than the main screen, so no
 116         // adjustment will be done by the window manager =>> wrong size.
 117         // So we skip compensation here and cut the adjustment on
 118         // WM_WINDOWPOSCHANGING event.
 119         // Note that the result does not depend on the monitor on which we
 120         // maximize the window.
 121         return bounds;
 122     }
 123 


 131         }
 132         return result;
 133     }
 134 
 135     @Override
 136     boolean isTargetUndecorated() {
 137         return ((Frame)target).isUndecorated();
 138     }
 139 
 140     @Override
 141     public void reshape(int x, int y, int width, int height) {
 142         if (((Frame)target).isUndecorated()) {
 143             super.reshape(x, y, width, height);
 144         } else {
 145             reshapeFrame(x, y, width, height);
 146         }
 147     }
 148 
 149     @Override
 150     public final Dimension getMinimumSize() {

 151         Dimension d = new Dimension();
 152         if (!((Frame)target).isUndecorated()) {
 153             d.setSize(scaleDownX(getSysMinWidth()),
 154                       scaleDownY(getSysMinHeight()));
 155         }
 156         if (((Frame)target).getMenuBar() != null) {
 157             d.height += scaleDownY(getSysMenuHeight());
 158         }
 159         return d;
 160     }
 161 
 162     // Note: Because this method calls resize(), which may be overridden
 163     // by client code, this method must not be executed on the toolkit
 164     // thread.
 165     @Override
 166     public void setMenuBar(MenuBar mb) {
 167         WMenuBarPeer mbPeer = (WMenuBarPeer) WToolkit.targetToPeer(mb);
 168         if (mbPeer != null) {
 169             if (mbPeer.framePeer != this) {
 170                 mb.removeNotify();
 171                 mb.addNotify();
 172                 mbPeer = (WMenuBarPeer) WToolkit.targetToPeer(mb);
 173                 if (mbPeer != null && mbPeer.framePeer != this) {
 174                     throw new IllegalStateException("Wrong parent peer");
 175                 }
 176             }
 177             if (mbPeer != null) {




  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package sun.awt.windows;
  27 
  28 import java.awt.Component;
  29 import java.awt.Dimension;
  30 import java.awt.Frame;
  31 import java.awt.GraphicsConfiguration;
  32 import java.awt.MenuBar;
  33 import java.awt.Rectangle;
  34 import java.awt.peer.FramePeer;
  35 import java.security.AccessController;
  36 
  37 import sun.awt.AWTAccessor;
  38 import sun.awt.im.InputMethodManager;
  39 import sun.security.action.GetPropertyAction;
  40 
  41 import static sun.java2d.SunGraphicsEnvironment.getGCDeviceBounds;
  42 import static sun.java2d.SunGraphicsEnvironment.toDeviceSpaceAbs;
  43 import static sun.java2d.SunGraphicsEnvironment.toUserSpace;
  44 
  45 class WFramePeer extends WWindowPeer implements FramePeer {
  46 
  47     static {
  48         initIDs();
  49     }
  50 
  51     // initialize JNI field and method IDs
  52     private static native void initIDs();
  53 
  54     // FramePeer implementation
  55     @Override
  56     public native void setState(int state);
  57     @Override
  58     public native int getState();
  59 
  60     // sync target and peer
  61     public void setExtendedState(int state) {
  62         AWTAccessor.getFrameAccessor().setExtendedState((Frame)target, state);
  63     }


  82         } else {
  83             b = adjustMaximizedBounds(b);
  84             setMaximizedBounds(b.x, b.y, b.width, b.height);
  85         }
  86     }
  87 
  88     /**
  89      * The incoming bounds describe the maximized size and position of the
  90      * window in the virtual coordinate system. But the window manager expects
  91      * that the bounds are based on the size of the primary monitor and
  92      * position is based on the actual window monitor, even if the window
  93      * ultimately maximizes onto a secondary monitor. And the window manager
  94      * adjusts these values to compensate for differences between the primary
  95      * monitor and the monitor that displays the window.
  96      * <p>
  97      * The method translates the incoming bounds to the values acceptable
  98      * by the window manager. For more details, please refer to 6699851.
  99      */
 100     private Rectangle adjustMaximizedBounds(Rectangle bounds) {
 101         // All calculations should be done in the device space
 102         bounds = toDeviceSpaceAbs(bounds);

 103         GraphicsConfiguration gc = getGraphicsConfiguration();
 104         Rectangle currentDevBounds = getGCDeviceBounds(gc);
 105         // Prepare data for WM_GETMINMAXINFO message.
 106         // ptMaxPosition should be in coordinate system of the current monitor,
 107         // not the main monitor, or monitor on which we maximize the window.
 108         bounds.x -= currentDevBounds.x;
 109         bounds.y -= currentDevBounds.y;
 110         // ptMaxSize will be used as-is if the size is smaller than the main
 111         // monitor. If the size is larger than the main monitor then the
 112         // window manager adjusts the size, like this:
 113         // result = bounds.w + (current.w - main.w); =>> wrong size
 114         // We can try to compensate for this adjustment like this:
 115         // result = bounds.w - (current.w - main.w);
 116         // but this can result to the size smaller than the main screen, so no
 117         // adjustment will be done by the window manager =>> wrong size.
 118         // So we skip compensation here and cut the adjustment on
 119         // WM_WINDOWPOSCHANGING event.
 120         // Note that the result does not depend on the monitor on which we
 121         // maximize the window.
 122         return bounds;
 123     }
 124 


 132         }
 133         return result;
 134     }
 135 
 136     @Override
 137     boolean isTargetUndecorated() {
 138         return ((Frame)target).isUndecorated();
 139     }
 140 
 141     @Override
 142     public void reshape(int x, int y, int width, int height) {
 143         if (((Frame)target).isUndecorated()) {
 144             super.reshape(x, y, width, height);
 145         } else {
 146             reshapeFrame(x, y, width, height);
 147         }
 148     }
 149 
 150     @Override
 151     public final Dimension getMinimumSize() {
 152         GraphicsConfiguration gc = getGraphicsConfiguration();
 153         Dimension d = new Dimension();
 154         if (!((Frame)target).isUndecorated()) {
 155             d.setSize(toUserSpace(gc, getSysMinWidth(), getSysMinHeight()));

 156         }
 157         if (((Frame) target).getMenuBar() != null) {
 158             d.height += toUserSpace(gc, 0, getSysMenuHeight()).height;
 159         }
 160         return d;
 161     }
 162 
 163     // Note: Because this method calls resize(), which may be overridden
 164     // by client code, this method must not be executed on the toolkit
 165     // thread.
 166     @Override
 167     public void setMenuBar(MenuBar mb) {
 168         WMenuBarPeer mbPeer = (WMenuBarPeer) WToolkit.targetToPeer(mb);
 169         if (mbPeer != null) {
 170             if (mbPeer.framePeer != this) {
 171                 mb.removeNotify();
 172                 mb.addNotify();
 173                 mbPeer = (WMenuBarPeer) WToolkit.targetToPeer(mb);
 174                 if (mbPeer != null && mbPeer.framePeer != this) {
 175                     throw new IllegalStateException("Wrong parent peer");
 176                 }
 177             }
 178             if (mbPeer != null) {


< prev index next >