6589527: Window and Frame instances can hide their "Applet Warning"
Summary: Additional constraints have been added for the setBounds() operation.
Reviewed-by: son, art
--- 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();