8167652: Making a frame/dialog resizeble/unresizeble shifts its position on Unity

Reviewed-by: azvegint, serb
This commit is contained in:
Semyon Sadetsky 2016-12-28 12:43:57 +03:00
parent 2044170e89
commit 63d3e42189
3 changed files with 304 additions and 282 deletions

View File

@ -51,9 +51,9 @@ abstract class XDecoratedPeer extends XWindowPeer {
boolean insets_corrected; boolean insets_corrected;
XIconWindow iconWindow; XIconWindow iconWindow;
WindowDimensions dimensions; volatile WindowDimensions dimensions;
XContentWindow content; XContentWindow content;
Insets currentInsets; volatile Insets currentInsets;
XFocusProxyWindow focusProxy; XFocusProxyWindow focusProxy;
static final Map<Class<?>,Insets> lastKnownInsets = static final Map<Class<?>,Insets> lastKnownInsets =
Collections.synchronizedMap(new HashMap<>()); Collections.synchronizedMap(new HashMap<>());
@ -106,7 +106,7 @@ abstract class XDecoratedPeer extends XWindowPeer {
// The lines that follow need to be in a postInit, so they // The lines that follow need to be in a postInit, so they
// happen after the X window is created. // happen after the X window is created.
initResizability(); setResizable(winAttr.initialResizability);
XWM.requestWMExtents(getWindow()); XWM.requestWMExtents(getWindow());
content = XContentWindow.createContent(this); content = XContentWindow.createContent(this);
@ -130,7 +130,12 @@ abstract class XDecoratedPeer extends XWindowPeer {
public void updateMinimumSize() { public void updateMinimumSize() {
super.updateMinimumSize(); super.updateMinimumSize();
XToolkit.awtLock();
try {
updateMinSizeHints(); updateMinSizeHints();
} finally {
XToolkit.awtUnlock();
}
} }
private void updateMinSizeHints() { private void updateMinSizeHints() {
@ -193,8 +198,13 @@ abstract class XDecoratedPeer extends XWindowPeer {
if (log.isLoggable(PlatformLogger.Level.FINE)) { if (log.isLoggable(PlatformLogger.Level.FINE)) {
log.fine("Title is " + title); log.fine("Title is " + title);
} }
XToolkit.awtLock();
try {
winAttr.title = title; winAttr.title = title;
updateWMName(); updateWMName();
} finally {
XToolkit.awtUnlock();
}
} }
protected String getWMName() { protected String getWMName() {
@ -206,10 +216,10 @@ abstract class XDecoratedPeer extends XWindowPeer {
} }
void updateWMName() { void updateWMName() {
super.updateWMName();
String name = getWMName();
XToolkit.awtLock(); XToolkit.awtLock();
try { try {
super.updateWMName();
String name = getWMName();
if (name == null || name.trim().equals("")) { if (name == null || name.trim().equals("")) {
name = "Java"; name = "Java";
} }
@ -304,6 +314,8 @@ abstract class XDecoratedPeer extends XWindowPeer {
if (XWM.getWMID() != XWM.UNITY_COMPIZ_WM) { if (XWM.getWMID() != XWM.UNITY_COMPIZ_WM) {
currentInsets = new Insets(0, 0, 0, 0); currentInsets = new Insets(0, 0, 0, 0);
wm_set_insets = null; wm_set_insets = null;
} else {
insets_corrected = false;
} }
} }
@ -377,8 +389,6 @@ abstract class XDecoratedPeer extends XWindowPeer {
insLog.fine(xe.toString()); insLog.fine(xe.toString());
} }
reparent_serial = xe.get_serial(); reparent_serial = xe.get_serial();
XToolkit.awtLock();
try {
long root = XlibWrapper.RootWindow(XToolkit.getDisplay(), getScreenNumber()); long root = XlibWrapper.RootWindow(XToolkit.getDisplay(), getScreenNumber());
if (isEmbedded()) { if (isEmbedded()) {
@ -386,7 +396,6 @@ abstract class XDecoratedPeer extends XWindowPeer {
insets_corrected = true; insets_corrected = true;
return; return;
} }
Component t = target;
if (getDecorations() == XWindowAttributesData.AWT_DECOR_NONE) { if (getDecorations() == XWindowAttributesData.AWT_DECOR_NONE) {
setReparented(true); setReparented(true);
insets_corrected = true; insets_corrected = true;
@ -448,14 +457,9 @@ abstract class XDecoratedPeer extends XWindowPeer {
handleCorrectInsets(correctWM); handleCorrectInsets(correctWM);
} }
} }
} finally {
XToolkit.awtUnlock();
}
} }
protected void handleCorrectInsets(Insets correctWM) { private void handleCorrectInsets(Insets correctWM) {
XToolkit.awtLock();
try {
/* /*
* Ok, now see if we need adjust window size because * Ok, now see if we need adjust window size because
* initial insets were wrong (most likely they were). * initial insets were wrong (most likely they were).
@ -476,8 +480,9 @@ abstract class XDecoratedPeer extends XWindowPeer {
if (insLog.isLoggable(PlatformLogger.Level.FINER)) { if (insLog.isLoggable(PlatformLogger.Level.FINER)) {
insLog.finer("Dimensions before reparent: " + dimensions); insLog.finer("Dimensions before reparent: " + dimensions);
} }
WindowDimensions newDimensions = new WindowDimensions(dimensions);
dimensions.setInsets(getRealInsets()); newDimensions.setInsets(getRealInsets());
dimensions = newDimensions;
insets_corrected = true; insets_corrected = true;
if (isMaximized()) { if (isMaximized()) {
@ -495,19 +500,16 @@ abstract class XDecoratedPeer extends XWindowPeer {
} else { } else {
reshape(dimensions, SET_SIZE, false); reshape(dimensions, SET_SIZE, false);
} }
} finally {
XToolkit.awtUnlock();
}
} }
public void handleMoved(WindowDimensions dims) { void handleMoved(WindowDimensions dims) {
Point loc = dims.getLocation(); Point loc = dims.getLocation();
AWTAccessor.getComponentAccessor().setLocation(target, loc.x, loc.y); AWTAccessor.getComponentAccessor().setLocation(target, loc.x, loc.y);
postEvent(new ComponentEvent(target, ComponentEvent.COMPONENT_MOVED)); postEvent(new ComponentEvent(target, ComponentEvent.COMPONENT_MOVED));
} }
protected Insets guessInsets() { private Insets guessInsets() {
if (isEmbedded() || isTargetUndecorated()) { if (isEmbedded() || isTargetUndecorated()) {
return new Insets(0, 0, 0, 0); return new Insets(0, 0, 0, 0);
} else { } else {
@ -532,16 +534,7 @@ abstract class XDecoratedPeer extends XWindowPeer {
currentInsets = copy(guessed); currentInsets = copy(guessed);
} }
public void revalidate() { private Insets getRealInsets() {
XToolkit.executeOnEventHandlerThread(target, new Runnable() {
public void run() {
target.invalidate();
target.validate();
}
});
}
Insets getRealInsets() {
if (isNull(currentInsets)) { if (isNull(currentInsets)) {
applyGuessedInsets(); applyGuessedInsets();
} }
@ -578,7 +571,7 @@ abstract class XDecoratedPeer extends XWindowPeer {
// Coordinates are that of the target // Coordinates are that of the target
// Called only on Toolkit thread // Called only on Toolkit thread
public void reshape(WindowDimensions newDimensions, int op, private void reshape(WindowDimensions newDimensions, int op,
boolean userReshape) boolean userReshape)
{ {
if (insLog.isLoggable(PlatformLogger.Level.FINE)) { if (insLog.isLoggable(PlatformLogger.Level.FINE)) {
@ -599,8 +592,6 @@ abstract class XDecoratedPeer extends XWindowPeer {
} }
newDimensions = new WindowDimensions(newBounds, insets, newDimensions.isClientSizeSet()); newDimensions = new WindowDimensions(newBounds, insets, newDimensions.isClientSizeSet());
} }
XToolkit.awtLock();
try {
if (!isReparented() || !isVisible()) { if (!isReparented() || !isVisible()) {
if (insLog.isLoggable(PlatformLogger.Level.FINE)) { if (insLog.isLoggable(PlatformLogger.Level.FINE)) {
insLog.fine("- not reparented({0}) or not visible({1}), default reshape", insLog.fine("- not reparented({0}) or not visible({1}), default reshape",
@ -633,7 +624,6 @@ abstract class XDecoratedPeer extends XWindowPeer {
return; return;
} }
int wm = XWM.getWMID();
updateChildrenSizes(); updateChildrenSizes();
applyGuessedInsets(); applyGuessedInsets();
@ -671,9 +661,6 @@ abstract class XDecoratedPeer extends XWindowPeer {
} }
reconfigureContentWindow(newDimensions); reconfigureContentWindow(newDimensions);
} finally {
XToolkit.awtUnlock();
}
} }
/** /**
@ -682,8 +669,6 @@ abstract class XDecoratedPeer extends XWindowPeer {
private void reshape(int x, int y, int width, int height, int operation, private void reshape(int x, int y, int width, int height, int operation,
boolean userReshape) boolean userReshape)
{ {
Rectangle newRec;
boolean setClient = false;
WindowDimensions dims = new WindowDimensions(dimensions); WindowDimensions dims = new WindowDimensions(dimensions);
switch (operation & (~NO_EMBEDDED_CHECK)) { switch (operation & (~NO_EMBEDDED_CHECK)) {
case SET_LOCATION: case SET_LOCATION:
@ -726,7 +711,12 @@ abstract class XDecoratedPeer extends XWindowPeer {
*/ */
public void setBounds(int x, int y, int width, int height, int op) { public void setBounds(int x, int y, int width, int height, int op) {
// TODO: Rewrite with WindowDimensions // TODO: Rewrite with WindowDimensions
XToolkit.awtLock();
try {
reshape(x, y, width, height, op, true); reshape(x, y, width, height, op, true);
} finally {
XToolkit.awtUnlock();
}
validateSurface(); validateSurface();
} }
@ -861,54 +851,37 @@ abstract class XDecoratedPeer extends XWindowPeer {
checkShellRectPos(shellRect); checkShellRectPos(shellRect);
} }
public void setShellBounds(Rectangle rec) { private void setShellBounds(Rectangle rec) {
if (insLog.isLoggable(PlatformLogger.Level.FINE)) { if (insLog.isLoggable(PlatformLogger.Level.FINE)) {
insLog.fine("Setting shell bounds on " + this + " to " + rec); insLog.fine("Setting shell bounds on " + this + " to " + rec);
} }
XToolkit.awtLock();
try {
updateSizeHints(rec.x, rec.y, rec.width, rec.height); updateSizeHints(rec.x, rec.y, rec.width, rec.height);
XlibWrapper.XMoveResizeWindow(XToolkit.getDisplay(), getShell(), XlibWrapper.XMoveResizeWindow(XToolkit.getDisplay(), getShell(),
scaleUp(rec.x), scaleUp(rec.y), scaleUp(rec.x), scaleUp(rec.y),
scaleUp(rec.width), scaleUp(rec.height)); scaleUp(rec.width), scaleUp(rec.height));
} }
finally {
XToolkit.awtUnlock(); private void setShellSize(Rectangle rec) {
}
}
public void setShellSize(Rectangle rec) {
if (insLog.isLoggable(PlatformLogger.Level.FINE)) { if (insLog.isLoggable(PlatformLogger.Level.FINE)) {
insLog.fine("Setting shell size on " + this + " to " + rec); insLog.fine("Setting shell size on " + this + " to " + rec);
} }
XToolkit.awtLock();
try {
updateSizeHints(rec.x, rec.y, rec.width, rec.height); updateSizeHints(rec.x, rec.y, rec.width, rec.height);
XlibWrapper.XResizeWindow(XToolkit.getDisplay(), getShell(), XlibWrapper.XResizeWindow(XToolkit.getDisplay(), getShell(),
scaleUp(rec.width), scaleUp(rec.height)); scaleUp(rec.width), scaleUp(rec.height));
} }
finally {
XToolkit.awtUnlock(); private void setShellPosition(Rectangle rec) {
}
}
public void setShellPosition(Rectangle rec) {
if (insLog.isLoggable(PlatformLogger.Level.FINE)) { if (insLog.isLoggable(PlatformLogger.Level.FINE)) {
insLog.fine("Setting shell position on " + this + " to " + rec); insLog.fine("Setting shell position on " + this + " to " + rec);
} }
XToolkit.awtLock();
try {
updateSizeHints(rec.x, rec.y, rec.width, rec.height); updateSizeHints(rec.x, rec.y, rec.width, rec.height);
XlibWrapper.XMoveWindow(XToolkit.getDisplay(), getShell(), XlibWrapper.XMoveWindow(XToolkit.getDisplay(), getShell(),
scaleUp(rec.x), scaleUp(rec.y)); scaleUp(rec.x), scaleUp(rec.y));
} }
finally {
XToolkit.awtUnlock();
}
}
void initResizability() {
setResizable(winAttr.initialResizability);
}
public void setResizable(boolean resizable) { public void setResizable(boolean resizable) {
XToolkit.awtLock();
try {
int fs = winAttr.functions; int fs = winAttr.functions;
if (!isResizable() && resizable) { if (!isResizable() && resizable) {
resetWMSetInsets(); resetWMSetInsets();
@ -917,9 +890,11 @@ abstract class XDecoratedPeer extends XWindowPeer {
} }
winAttr.isResizable = resizable; winAttr.isResizable = resizable;
if ((fs & MWMConstants.MWM_FUNC_ALL) != 0) { if ((fs & MWMConstants.MWM_FUNC_ALL) != 0) {
fs &= ~(MWMConstants.MWM_FUNC_RESIZE | MWMConstants.MWM_FUNC_MAXIMIZE); fs &= ~(MWMConstants.MWM_FUNC_RESIZE
| MWMConstants.MWM_FUNC_MAXIMIZE);
} else { } else {
fs |= (MWMConstants.MWM_FUNC_RESIZE | MWMConstants.MWM_FUNC_MAXIMIZE); fs |= (MWMConstants.MWM_FUNC_RESIZE
| MWMConstants.MWM_FUNC_MAXIMIZE);
} }
winAttr.functions = fs; winAttr.functions = fs;
XWM.setShellResizable(this); XWM.setShellResizable(this);
@ -930,12 +905,20 @@ abstract class XDecoratedPeer extends XWindowPeer {
} }
winAttr.isResizable = resizable; winAttr.isResizable = resizable;
if ((fs & MWMConstants.MWM_FUNC_ALL) != 0) { if ((fs & MWMConstants.MWM_FUNC_ALL) != 0) {
fs |= (MWMConstants.MWM_FUNC_RESIZE | MWMConstants.MWM_FUNC_MAXIMIZE); fs |= (MWMConstants.MWM_FUNC_RESIZE
| MWMConstants.MWM_FUNC_MAXIMIZE);
} else { } else {
fs &= ~(MWMConstants.MWM_FUNC_RESIZE | MWMConstants.MWM_FUNC_MAXIMIZE); fs &= ~(MWMConstants.MWM_FUNC_RESIZE
| MWMConstants.MWM_FUNC_MAXIMIZE);
} }
winAttr.functions = fs; winAttr.functions = fs;
XWM.setShellNotResizable(this, dimensions, dimensions.getBounds(), false); XWM.setShellNotResizable(this, dimensions,
XWM.getWMID() == XWM.UNITY_COMPIZ_WM && configure_seen ?
dimensions.getScreenBounds() :
dimensions.getBounds(), false);
}
} finally {
XToolkit.awtUnlock();
} }
} }
@ -990,7 +973,10 @@ abstract class XDecoratedPeer extends XWindowPeer {
try { try {
if (configure_seen) { if (configure_seen) {
return toGlobal(0,0); return toGlobal(0,0);
} else { }
} finally {
XToolkit.awtUnlock();
}
Point location = target.getLocation(); Point location = target.getLocation();
if (insLog.isLoggable(PlatformLogger.Level.FINE)) { if (insLog.isLoggable(PlatformLogger.Level.FINE)) {
insLog.fine("getLocationOnScreen {0} not reparented: {1} ", insLog.fine("getLocationOnScreen {0} not reparented: {1} ",
@ -998,10 +984,6 @@ abstract class XDecoratedPeer extends XWindowPeer {
} }
return location; return location;
} }
} finally {
XToolkit.awtUnlock();
}
}
/*************************************************************************************** /***************************************************************************************
@ -1134,7 +1116,7 @@ abstract class XDecoratedPeer extends XWindowPeer {
return focusProxy; return focusProxy;
} }
public void handleQuit() { private void handleQuit() {
postEvent(new WindowEvent((Window)target, WindowEvent.WINDOW_CLOSING)); postEvent(new WindowEvent((Window)target, WindowEvent.WINDOW_CLOSING));
} }

View File

@ -1029,8 +1029,14 @@ final class XWM
} }
XToolkit.awtLock(); XToolkit.awtLock();
try { try {
Rectangle shellBounds = window.getShellBounds(); Rectangle shellBounds;
shellBounds.translate(-window.currentInsets.left, -window.currentInsets.top); if (getWMID() != UNITY_COMPIZ_WM) {
shellBounds = window.getShellBounds();
shellBounds.translate(-window.currentInsets.left,
-window.currentInsets.top);
} else {
shellBounds = window.getDimensions().getScreenBounds();
}
window.updateSizeHints(window.getDimensions()); window.updateSizeHints(window.getDimensions());
requestWMExtents(window.getWindow()); requestWMExtents(window.getWindow());
XlibWrapper.XMoveResizeWindow(XToolkit.getDisplay(), XlibWrapper.XMoveResizeWindow(XToolkit.getDisplay(),

View File

@ -23,7 +23,7 @@
/* @test /* @test
@key headful @key headful
@bug 8166897 @bug 8166897 8167652
@summary Some font overlap in the Optionpane dialog. @summary Some font overlap in the Optionpane dialog.
@run main ChangeWindowResizabiltyTest @run main ChangeWindowResizabiltyTest
*/ */
@ -34,24 +34,46 @@ import java.awt.Dimension;
import java.awt.Frame; import java.awt.Frame;
import java.awt.Panel; import java.awt.Panel;
import java.awt.Robot; import java.awt.Robot;
import java.awt.Point;
public class ChangeWindowResizabiltyTest { public class ChangeWindowResizabiltyTest {
public static void main(String[] args) throws Exception { public static void main(String[] args) throws Exception {
Robot robot = new Robot(); Robot robot = new Robot();
for(int i = 0; i < 10; i++) { for(int i = 0; i < 10; i++) {
Dialog dialog = new Dialog((Frame) null); Dialog dialog = new Dialog((Frame) null);
dialog.setLocation(100, 100);
Component panel = new Panel(); Component panel = new Panel();
panel.setPreferredSize(new Dimension(200, 100)); panel.setPreferredSize(new Dimension(200, 100));
dialog.add(panel); dialog.add(panel);
dialog.pack(); dialog.pack();
dialog.setVisible(true); dialog.setVisible(true);
robot.waitForIdle();
robot.delay(200);
Point frameLoc = dialog.getLocationOnScreen();
Point contentLoc = panel.getLocationOnScreen();
System.out.println("Decor location " + frameLoc);
System.out.println("Content location " + contentLoc);
dialog.setResizable(false); dialog.setResizable(false);
robot.waitForIdle(); robot.waitForIdle();
robot.delay(200); robot.delay(200);
System.out.println(panel.getLocationOnScreen()); Point l = dialog.getLocationOnScreen();
System.out.println(dialog.getLocationOnScreen()); if (!l.equals(frameLoc)) {
dialog.dispose();
throw new RuntimeException("Decorated frame location moved " +
"after setResizable(false)" + l);
}
l = panel.getLocationOnScreen();
if (!l.equals(contentLoc)) {
dialog.dispose();
throw new RuntimeException("Content location moved after " +
"setResizable(false)" + l);
}
if (panel.getLocationOnScreen().y < if (panel.getLocationOnScreen().y <
dialog.getLocationOnScreen().y + dialog.getInsets().top) { dialog.getLocationOnScreen().y + dialog.getInsets().top) {
dialog.dispose(); dialog.dispose();
@ -62,8 +84,20 @@ public class ChangeWindowResizabiltyTest {
dialog.setResizable(true); dialog.setResizable(true);
robot.waitForIdle(); robot.waitForIdle();
robot.delay(200); robot.delay(200);
System.out.println(panel.getLocationOnScreen());
System.out.println(dialog.getLocationOnScreen()); l = dialog.getLocationOnScreen();
if (!l.equals(frameLoc)) {
dialog.dispose();
throw new RuntimeException("Decorated frame location moved " +
"after setResizable(true)" + l);
}
l = panel.getLocationOnScreen();
if (!l.equals(contentLoc)) {
dialog.dispose();
throw new RuntimeException("Content location moved after " +
"setResizable(true)" + l);
}
if (panel.getLocationOnScreen().y < if (panel.getLocationOnScreen().y <
dialog.getLocationOnScreen().y + dialog.getInsets().top) { dialog.getLocationOnScreen().y + dialog.getInsets().top) {
dialog.dispose(); dialog.dispose();