OpenJDK / jdk-updates / jdk12u
changeset 129:f995b9c9c5fa
6589527: Window and Frame instances can hide their "Applet Warning"
Summary: Additional constraints have been added for the setBounds() operation.
Reviewed-by: son, art
line wrap: on
line diff
--- a/jdk/src/solaris/classes/sun/awt/X11/XDecoratedPeer.java Tue Mar 18 15:07:42 2008 +0300 +++ b/jdk/src/solaris/classes/sun/awt/X11/XDecoratedPeer.java Tue Mar 18 16:19:03 2008 +0300 @@ -36,7 +36,7 @@ import sun.awt.ComponentAccessor; import sun.awt.SunToolkit; -class XDecoratedPeer extends XWindowPeer { +abstract class XDecoratedPeer extends XWindowPeer { private static final Logger log = Logger.getLogger("sun.awt.X11.XDecoratedPeer"); private static final Logger insLog = Logger.getLogger("sun.awt.X11.insets.XDecoratedPeer"); private static final Logger focusLog = Logger.getLogger("sun.awt.X11.focus.XDecoratedPeer"); @@ -456,6 +456,15 @@ if (insLog.isLoggable(Level.FINE)) { insLog.fine("Reshaping " + this + " to " + newDimensions + " op " + op + " user reshape " + userReshape); } + if (userReshape) { + // We handle only userReshape == true cases. It means that + // if the window manager or any other part of the windowing + // system sets inappropriate size for this window, we can + // do nothing but accept it. + Rectangle reqBounds = newDimensions.getBounds(); + Rectangle newBounds = constrainBounds(reqBounds.x, reqBounds.y, reqBounds.width, reqBounds.height); + newDimensions = new WindowDimensions(newBounds, newDimensions.getInsets(), newDimensions.isClientSizeSet()); + } XToolkit.awtLock(); try { if (!isReparented() || !isVisible()) { @@ -571,6 +580,49 @@ reshape(dims, operation, userReshape); } + // This method gets overriden in XFramePeer & XDialogPeer. + abstract boolean isTargetUndecorated(); + + @Override + Rectangle constrainBounds(int x, int y, int width, int height) { + // We don't restrict the setBounds() operation if the code is trusted. + if (!hasWarningWindow()) { + return new Rectangle(x, y, width, height); + } + + // If it's undecorated or is not currently visible, + // apply the same constraints as for the Window. + if (!isVisible() || isTargetUndecorated()) { + return super.constrainBounds(x, y, width, height); + } + + // If it's visible & decorated, constraint the size only + int newX = x; + int newY = y; + int newW = width; + int newH = height; + + GraphicsConfiguration gc = ((Window)target).getGraphicsConfiguration(); + Rectangle sB = gc.getBounds(); + Insets sIn = ((Window)target).getToolkit().getScreenInsets(gc); + + Rectangle curBounds = getBounds(); + + int maxW = Math.max(sB.width - sIn.left - sIn.right, curBounds.width); + int maxH = Math.max(sB.height - sIn.top - sIn.bottom, curBounds.height); + + // First make sure the size is withing the visible part of the screen + if (newW > maxW) { + newW = maxW; + } + + if (newH > maxH) { + newH = maxH; + } + + return new Rectangle(newX, newY, newW, newH); + } + /** * @see java.awt.peer.ComponentPeer#setBounds */
--- a/jdk/src/solaris/classes/sun/awt/X11/XDialogPeer.java Tue Mar 18 15:07:42 2008 +0300 +++ b/jdk/src/solaris/classes/sun/awt/X11/XDialogPeer.java Tue Mar 18 16:19:03 2008 +0300 @@ -88,7 +88,8 @@ } } - private boolean isTargetUndecorated() { + @Override + boolean isTargetUndecorated() { if (undecorated != null) { return undecorated.booleanValue(); } else {
--- a/jdk/src/solaris/classes/sun/awt/X11/XEmbeddedFramePeer.java Tue Mar 18 15:07:42 2008 +0300 +++ b/jdk/src/solaris/classes/sun/awt/X11/XEmbeddedFramePeer.java Tue Mar 18 16:19:03 2008 +0300 @@ -184,6 +184,12 @@ } } + @Override + Rectangle constrainBounds(int x, int y, int width, int height) { + // We don't constrain the bounds of the EmbeddedFrames + return new Rectangle(x, y, width, height); + } + // don't use getBounds() inherited from XDecoratedPeer public Rectangle getBounds() { return new Rectangle(x, y, width, height);
--- a/jdk/src/solaris/classes/sun/awt/X11/XFramePeer.java Tue Mar 18 15:07:42 2008 +0300 +++ b/jdk/src/solaris/classes/sun/awt/X11/XFramePeer.java Tue Mar 18 16:19:03 2008 +0300 @@ -95,7 +95,8 @@ } } - private boolean isTargetUndecorated() { + @Override + boolean isTargetUndecorated() { if (undecorated != null) { return undecorated.booleanValue(); } else {
--- a/jdk/src/solaris/classes/sun/awt/X11/XWindowPeer.java Tue Mar 18 15:07:42 2008 +0300 +++ b/jdk/src/solaris/classes/sun/awt/X11/XWindowPeer.java Tue Mar 18 16:19:03 2008 +0300 @@ -182,6 +182,9 @@ GraphicsConfiguration gc = getGraphicsConfiguration(); ((X11GraphicsDevice)gc.getDevice()).addDisplayChangedListener(this); + + Rectangle bounds = (Rectangle)(params.get(BOUNDS)); + params.put(BOUNDS, constrainBounds(bounds.x, bounds.y, bounds.width, bounds.height)); } private void initWMProtocols() { @@ -431,6 +434,56 @@ return ownerPeer; } + // This method is overriden at the XDecoratedPeer to handle + // decorated windows a bit differently. + Rectangle constrainBounds(int x, int y, int width, int height) { + // We don't restrict the setBounds() operation if the code is trusted. + if (!hasWarningWindow()) { + return new Rectangle(x, y, width, height); + } + + // The window bounds should be within the visible part of the screen + int newX = x; + int newY = y; + int newW = width; + int newH = height; + + // Now check each point is within the visible part of the screen + GraphicsConfiguration gc = ((Window)target).getGraphicsConfiguration(); + Rectangle sB = gc.getBounds(); + Insets sIn = ((Window)target).getToolkit().getScreenInsets(gc); + + int screenX = sB.x + sIn.left; + int screenY = sB.y + sIn.top; + int screenW = sB.width - sIn.left - sIn.right; + int screenH = sB.height - sIn.top - sIn.bottom; + + + // First make sure the size is withing the visible part of the screen + if (newW > screenW) { + newW = screenW; + } + + if (newH > screenH) { + newH = screenH; + } + + // Tweak the location if needed + if (newX < screenX) { + newX = screenX; + } else if (newX + newW > screenX + screenW) { + newX = screenX + screenW - newW; + } + + if (newY < screenY) { + newY = screenY; + } else if (newY + newH > screenY + screenH) { + newY = screenY + screenH - newH; + } + + return new Rectangle(newX, newY, newW, newH); + } + //Fix for 6318144: PIT:Setting Min Size bigger than current size enlarges //the window but fails to revalidate, Sol-CDE //This bug is regression for @@ -439,10 +492,14 @@ //Note that this function is overriden in XDecoratedPeer so event //posting is not changing for decorated peers public void setBounds(int x, int y, int width, int height, int op) { + Rectangle newBounds = constrainBounds(x, y, width, height); + XToolkit.awtLock(); try { Rectangle oldBounds = getBounds(); - super.setBounds(x, y, width, height, op); + + super.setBounds(newBounds.x, newBounds.y, newBounds.width, newBounds.height, op); + Rectangle bounds = getBounds(); XSizeHints hints = getHints(); @@ -1029,7 +1086,7 @@ return !(target instanceof Frame || target instanceof Dialog); } boolean hasWarningWindow() { - return warningWindow != null; + return ((Window)target).getWarningString() != null; } // The height of menu bar window
--- a/jdk/src/solaris/classes/sun/awt/motif/MDialogPeer.java Tue Mar 18 15:07:42 2008 +0300 +++ b/jdk/src/solaris/classes/sun/awt/motif/MDialogPeer.java Tue Mar 18 16:19:03 2008 +0300 @@ -102,4 +102,9 @@ public void blockWindows(java.util.List<Window> toBlock) { // do nothing } + + @Override + final boolean isTargetUndecorated() { + return ((Dialog)target).isUndecorated(); + } }
--- a/jdk/src/solaris/classes/sun/awt/motif/MEmbeddedFramePeer.java Tue Mar 18 15:07:42 2008 +0300 +++ b/jdk/src/solaris/classes/sun/awt/motif/MEmbeddedFramePeer.java Tue Mar 18 16:19:03 2008 +0300 @@ -204,4 +204,10 @@ } public native Rectangle getBoundsPrivate(); + + @Override + Rectangle constrainBounds(int x, int y, int width, int height) { + // We don't constrain the bounds of the EmbeddedFrames + return new Rectangle(x, y, width, height); + } }
--- a/jdk/src/solaris/classes/sun/awt/motif/MFramePeer.java Tue Mar 18 15:07:42 2008 +0300 +++ b/jdk/src/solaris/classes/sun/awt/motif/MFramePeer.java Tue Mar 18 16:19:03 2008 +0300 @@ -503,4 +503,9 @@ public Rectangle getBoundsPrivate() { return getBounds(); } + + @Override + final boolean isTargetUndecorated() { + return ((Frame)target).isUndecorated(); + } }
--- a/jdk/src/solaris/classes/sun/awt/motif/MWindowPeer.java Tue Mar 18 15:07:42 2008 +0300 +++ b/jdk/src/solaris/classes/sun/awt/motif/MWindowPeer.java Tue Mar 18 16:19:03 2008 +0300 @@ -113,6 +113,12 @@ insets.right = getInset("awt.frame.rightInset", -1); } + Rectangle bounds = target.getBounds(); + sysX = bounds.x; + sysY = bounds.y; + sysW = bounds.width; + sysH = bounds.height; + super.init(target); InputMethodManager imm = InputMethodManager.getInstance(); String menuString = imm.getTriggerMenuString(); @@ -150,6 +156,7 @@ GraphicsConfiguration gc = getGraphicsConfiguration(); ((X11GraphicsDevice)gc.getDevice()).addDisplayChangedListener(this); + } /* Support for multiple icons is not implemented in MAWT */ @@ -246,6 +253,8 @@ // NOTE: This method may be called by privileged threads. // DO NOT INVOKE CLIENT CODE ON THIS THREAD! public void handleResize(int width, int height) { + sysW = width; + sysH = height; // REMIND: Is this secure? Can client code subclass input method? if (!tcList.isEmpty() && @@ -268,6 +277,8 @@ } public void handleMoved(int x, int y) { + sysX = x; + sysY = y; postEvent(new ComponentEvent(target, ComponentEvent.COMPONENT_MOVED)); } @@ -505,4 +516,87 @@ } return false; } + + private final boolean hasWarningWindow() { + return ((Window)target).getWarningString() != null; + } + + // This method is overriden at Dialog and Frame peers. + boolean isTargetUndecorated() { + return true; + } + + private volatile int sysX = 0; + private volatile int sysY = 0; + private volatile int sysW = 0; + private volatile int sysH = 0; + + Rectangle constrainBounds(int x, int y, int width, int height) { + // We don't restrict the setBounds() operation if the code is trusted. + if (!hasWarningWindow()) { + return new Rectangle(x, y, width, height); + } + + int newX = x; + int newY = y; + int newW = width; + int newH = height; + + GraphicsConfiguration gc = ((Window)target).getGraphicsConfiguration(); + Rectangle sB = gc.getBounds(); + Insets sIn = ((Window)target).getToolkit().getScreenInsets(gc); + + int screenW = sB.width - sIn.left - sIn.right; + int screenH = sB.height - sIn.top - sIn.bottom; + + // If it's undecorated or is not currently visible, + // then check each point is within the visible part of the screen + if (!target.isVisible() || isTargetUndecorated()) { + int screenX = sB.x + sIn.left; + int screenY = sB.y + sIn.top; + + // First make sure the size is withing the visible part of the screen + if (newW > screenW) { + newW = screenW; + } + + if (newH > screenH) { + newH = screenH; + } + + // Tweak the location if needed + if (newX < screenX) { + newX = screenX; + } else if (newX + newW > screenX + screenW) { + newX = screenX + screenW - newW; + } + + if (newY < screenY) { + newY = screenY; + } else if (newY + newH > screenY + screenH) { + newY = screenY + screenH - newH; + } + } else { + int maxW = Math.max(screenW, sysW); + int maxH = Math.max(screenH, sysH); + + // Make sure the size is withing the visible part of the screen + // OR is less that the current size of the window. + if (newW > maxW) { + newW = maxW; + } + + if (newH > maxH) { + newH = maxH; + } + } + + return new Rectangle(newX, newY, newW, newH); + } + + public void setBounds(int x, int y, int width, int height, int op) { + Rectangle newBounds = constrainBounds(x, y, width, height); + super.setBounds(newBounds.x, newBounds.y, newBounds.width, newBounds.height, op); + } + }
--- a/jdk/src/windows/classes/sun/awt/windows/WDialogPeer.java Tue Mar 18 15:07:42 2008 +0300 +++ b/jdk/src/windows/classes/sun/awt/windows/WDialogPeer.java Tue Mar 18 16:19:03 2008 +0300 @@ -108,11 +108,18 @@ } } + @Override + boolean isTargetUndecorated() { + return ((Dialog)target).isUndecorated(); + } + public void reshape(int x, int y, int width, int height) { + Rectangle newBounds = constrainBounds(x, y, width, height); + if (((Dialog)target).isUndecorated()) { - super.reshape(x,y,width,height); + super.reshape(newBounds.x, newBounds.y, newBounds.width, newBounds.height); } else { - reshapeFrame(x,y,width,height); + reshapeFrame(newBounds.x, newBounds.y, newBounds.width, newBounds.height); } }
--- a/jdk/src/windows/classes/sun/awt/windows/WEmbeddedFramePeer.java Tue Mar 18 15:07:42 2008 +0300 +++ b/jdk/src/windows/classes/sun/awt/windows/WEmbeddedFramePeer.java Tue Mar 18 16:19:03 2008 +0300 @@ -65,4 +65,10 @@ public native Rectangle getBoundsPrivate(); public native void synthesizeWmActivate(boolean doActivate); + + @Override + Rectangle constrainBounds(int x, int y, int width, int height) { + // We don't constrain the bounds of the EmbeddedFrames + return new Rectangle(x, y, width, height); + } }
--- a/jdk/src/windows/classes/sun/awt/windows/WFramePeer.java Tue Mar 18 15:07:42 2008 +0300 +++ b/jdk/src/windows/classes/sun/awt/windows/WFramePeer.java Tue Mar 18 16:19:03 2008 +0300 @@ -64,11 +64,18 @@ } } + @Override + boolean isTargetUndecorated() { + return ((Frame)target).isUndecorated(); + } + public void reshape(int x, int y, int width, int height) { + Rectangle newBounds = constrainBounds(x, y, width, height); + if (((Frame)target).isUndecorated()) { - super.reshape(x,y,width,height); + super.reshape(newBounds.x, newBounds.y, newBounds.width, newBounds.height); } else { - reshapeFrame(x,y,width,height); + reshapeFrame(newBounds.x, newBounds.y, newBounds.width, newBounds.height); } }
--- a/jdk/src/windows/classes/sun/awt/windows/WWindowPeer.java Tue Mar 18 15:07:42 2008 +0300 +++ b/jdk/src/windows/classes/sun/awt/windows/WWindowPeer.java Tue Mar 18 16:19:03 2008 +0300 @@ -434,6 +434,97 @@ private native void nativeGrab(); private native void nativeUngrab(); + private final boolean hasWarningWindow() { + return ((Window)target).getWarningString() != null; + } + + boolean isTargetUndecorated() { + return true; + } + + // These are the peer bounds. They get updated at: + // 1. the WWindowPeer.setBounds() method. + // 2. the native code (on WM_SIZE/WM_MOVE) + private volatile int sysX = 0; + private volatile int sysY = 0; + private volatile int sysW = 0; + private volatile int sysH = 0; + + Rectangle constrainBounds(int x, int y, int width, int height) { + // We don't restrict the setBounds() operation if the code is trusted. + if (!hasWarningWindow()) { + return new Rectangle(x, y, width, height); + } + + int newX = x; + int newY = y; + int newW = width; + int newH = height; + + GraphicsConfiguration gc = ((Window)target).getGraphicsConfiguration(); + Rectangle sB = gc.getBounds(); + Insets sIn = ((Window)target).getToolkit().getScreenInsets(gc); + + int screenW = sB.width - sIn.left - sIn.right; + int screenH = sB.height - sIn.top - sIn.bottom; + + // If it's undecorated or is not currently visible + if (!((Window)target).isVisible() || isTargetUndecorated()) { + // Now check each point is within the visible part of the screen + int screenX = sB.x + sIn.left; + int screenY = sB.y + sIn.top; + + // First make sure the size is withing the visible part of the screen + if (newW > screenW) { + newW = screenW; + } + + if (newH > screenH) { + newH = screenH; + } + + // Tweak the location if needed + if (newX < screenX) { + newX = screenX; + } else if (newX + newW > screenX + screenW) { + newX = screenX + screenW - newW; + } + + if (newY < screenY) { + newY = screenY; + } else if (newY + newH > screenY + screenH) { + newY = screenY + screenH - newH; + } + } else { + int maxW = Math.max(screenW, sysW); + int maxH = Math.max(screenH, sysH); + + // Make sure the size is withing the visible part of the screen + // OR less that the current size of the window. + if (newW > maxW) { + newW = maxW; + } + + if (newH > maxH) { + newH = maxH; + } + } + + return new Rectangle(newX, newY, newW, newH); + } + + @Override + public void setBounds(int x, int y, int width, int height, int op) { + Rectangle newBounds = constrainBounds(x, y, width, height); + + sysX = newBounds.x; + sysY = newBounds.y; + sysW = newBounds.width; + sysH = newBounds.height; + + super.setBounds(newBounds.x, newBounds.y, newBounds.width, newBounds.height, op); + } + /* * The method maps the list of the active windows to the window's AppContext, * then the method registers ActiveWindowListener, GuiDisposedListener listeners;
--- a/jdk/src/windows/native/sun/windows/awt_Window.cpp Tue Mar 18 15:07:42 2008 +0300 +++ b/jdk/src/windows/native/sun/windows/awt_Window.cpp Tue Mar 18 16:19:03 2008 +0300 @@ -125,6 +125,11 @@ jclass AwtWindow::wwindowPeerCls; jmethodID AwtWindow::getActiveWindowsMID; +jfieldID AwtWindow::sysXID; +jfieldID AwtWindow::sysYID; +jfieldID AwtWindow::sysWID; +jfieldID AwtWindow::sysHID; + int AwtWindow::ms_instanceCounter = 0; HHOOK AwtWindow::ms_hCBTFilter; AwtWindow * AwtWindow::m_grabbedWindow = NULL; @@ -1052,6 +1057,8 @@ (env)->SetIntField(target, AwtComponent::xID, rect.left); (env)->SetIntField(target, AwtComponent::yID, rect.top); + (env)->SetIntField(peer, AwtWindow::sysXID, rect.left); + (env)->SetIntField(peer, AwtWindow::sysYID, rect.top); SendComponentEvent(java_awt_event_ComponentEvent_COMPONENT_MOVED); env->DeleteLocalRef(target); @@ -1115,6 +1122,11 @@ (env)->SetIntField(target, AwtComponent::widthID, newWidth); (env)->SetIntField(target, AwtComponent::heightID, newHeight); + + jobject peer = GetPeer(env); + (env)->SetIntField(peer, AwtWindow::sysWID, newWidth); + (env)->SetIntField(peer, AwtWindow::sysHID, newHeight); + if (!AwtWindow::IsResizing()) { WindowResized(); } @@ -1750,17 +1762,22 @@ // Fix for 4459064 : do not enforce thresholds for embedded frames if (!p->IsEmbeddedFrame()) { + jobject peer = p->GetPeer(env); int minWidth = ::GetSystemMetrics(SM_CXMIN); int minHeight = ::GetSystemMetrics(SM_CYMIN); if (w < minWidth) { env->SetIntField(target, AwtComponent::widthID, w = minWidth); + env->SetIntField(peer, AwtWindow::sysWID, + w); } if (h < minHeight) { env->SetIntField(target, AwtComponent::heightID, h = minHeight); + env->SetIntField(peer, AwtWindow::sysHID, + h); } } env->DeleteLocalRef(target); @@ -2144,6 +2161,11 @@ env->GetStaticMethodID(cls, "getActiveWindowHandles", "()[J"); DASSERT(AwtWindow::getActiveWindowsMID != NULL); + AwtWindow::sysXID = env->GetFieldID(cls, "sysX", "I"); + AwtWindow::sysYID = env->GetFieldID(cls, "sysY", "I"); + AwtWindow::sysWID = env->GetFieldID(cls, "sysW", "I"); + AwtWindow::sysHID = env->GetFieldID(cls, "sysH", "I"); + CATCH_BAD_ALLOC; }
--- a/jdk/src/windows/native/sun/windows/awt_Window.h Tue Mar 18 15:07:42 2008 +0300 +++ b/jdk/src/windows/native/sun/windows/awt_Window.h Tue Mar 18 16:19:03 2008 +0300 @@ -62,6 +62,12 @@ /* long[] getActiveWindowHandles() method in WWindowPeer */ static jmethodID getActiveWindowsMID; + // The coordinates at the peer. + static jfieldID sysXID; + static jfieldID sysYID; + static jfieldID sysWID; + static jfieldID sysHID; + AwtWindow(); virtual ~AwtWindow();