--- old/src/java.desktop/unix/classes/sun/awt/X11/XDecoratedPeer.java 2016-10-18 16:06:44.305798835 +0300 +++ new/src/java.desktop/unix/classes/sun/awt/X11/XDecoratedPeer.java 2016-10-18 16:06:44.225798838 +0300 @@ -129,8 +129,13 @@ } public void updateMinimumSize() { - super.updateMinimumSize(); - updateMinSizeHints(); + XToolkit.awtLock(); + try { + super.updateMinimumSize(); + updateMinSizeHints(); + } finally { + XToolkit.awtUnlock(); + } } private void updateMinSizeHints() { @@ -304,6 +309,8 @@ if (XWM.getWMID() != XWM.UNITY_COMPIZ_WM) { currentInsets = new Insets(0, 0, 0, 0); wm_set_insets = null; + } else { + insets_corrected = false; } } @@ -330,40 +337,48 @@ if (XWM.getWMID() != XWM.UNITY_COMPIZ_WM) { getWMSetInsets(XAtom.get(ev.get_atom())); } else { - if(!isReparented()) { + if (!isReparented()) { return; } - wm_set_insets = null; - Insets in = getWMSetInsets(XAtom.get(ev.get_atom())); - if (isNull(in)) { - return; - } - if (!isEmbedded() && !isTargetUndecorated()) { - lastKnownInsets.put(getClass(), in); - } - if (!in.equals(dimensions.getInsets())) { - if (insets_corrected || isMaximized()) { - currentInsets = in; + XToolkit.awtLock(); + try { + wm_set_insets = null; + Insets in = getWMSetInsets(XAtom.get(ev.get_atom())); + if (isNull(in)) { + return; + } + if (!isEmbedded() && !isTargetUndecorated()) { + lastKnownInsets.put(getClass(), in); + } + if (!in.equals(dimensions.getInsets())) { + if (insets_corrected || isMaximized()) { + currentInsets = in; + insets_corrected = true; + // insets were changed by WM. To handle this + // situation re-request window bounds because the + // current dimensions may be not actual as well. + XlibWrapper.XConfigureWindow(XToolkit.getDisplay(), + getWindow(), 0, 0); + } else { + // recalculate dimensions when window is just + // created and the initially guessed insets were + // wrong + handleCorrectInsets(in); + } + } else if (!insets_corrected || + !dimensions.isClientSizeSet()) { insets_corrected = true; - // insets were changed by WM. To handle this situation - // re-request window bounds because the current - // dimensions may be not actual as well. + // initial insets were guessed correctly. Re-request + // frame bounds because they may be changed by WM if + // the initial window position overlapped desktop's + // toolbars. This should initiate the final + // ConfigureNotify upon which the target will be + // notified with the final size. XlibWrapper.XConfigureWindow(XToolkit.getDisplay(), - getWindow(), 0, 0); - } else { - // recalculate dimensions when window is just created - // and the initially guessed insets were wrong - handleCorrectInsets(in); + getWindow(), 0, 0); } - } else if (!insets_corrected || !dimensions.isClientSizeSet()) { - insets_corrected = true; - // initial insets were guessed correctly. Re-request - // frame bounds because they may be changed by WM if the - // initial window position overlapped desktop's toolbars. - // This should initiate the final ConfigureNotify upon which - // the target will be notified with the final size. - XlibWrapper.XConfigureWindow(XToolkit.getDisplay(), - getWindow(), 0, 0); + } finally { + XToolkit.awtUnlock(); } } } @@ -682,40 +697,43 @@ private void reshape(int x, int y, int width, int height, int operation, boolean userReshape) { - Rectangle newRec; - boolean setClient = false; - WindowDimensions dims = new WindowDimensions(dimensions); - switch (operation & (~NO_EMBEDDED_CHECK)) { - case SET_LOCATION: - // Set location always sets bounds location. However, until the window is mapped we - // should use client coordinates - dims.setLocation(x, y); - break; - case SET_SIZE: - // Set size sets bounds size. However, until the window is mapped we - // should use client coordinates - dims.setSize(width, height); - break; - case SET_CLIENT_SIZE: { - // Sets client rect size. Width and height contain insets. - Insets in = currentInsets; - width -= in.left+in.right; - height -= in.top+in.bottom; - dims.setClientSize(width, height); - break; - } - case SET_BOUNDS: - default: - dims.setLocation(x, y); - dims.setSize(width, height); - break; - } - if (insLog.isLoggable(PlatformLogger.Level.FINE)) { - insLog.fine("For the operation {0} new dimensions are {1}", + XToolkit.awtLock(); + try { + WindowDimensions dims = new WindowDimensions(dimensions); + switch (operation & (~NO_EMBEDDED_CHECK)) { + case SET_LOCATION: + // Set location always sets bounds location. However, until the window is mapped we + // should use client coordinates + dims.setLocation(x, y); + break; + case SET_SIZE: + // Set size sets bounds size. However, until the window is mapped we + // should use client coordinates + dims.setSize(width, height); + break; + case SET_CLIENT_SIZE: { + // Sets client rect size. Width and height contain insets. + Insets in = currentInsets; + width -= in.left + in.right; + height -= in.top + in.bottom; + dims.setClientSize(width, height); + break; + } + case SET_BOUNDS: + default: + dims.setLocation(x, y); + dims.setSize(width, height); + break; + } + if (insLog.isLoggable(PlatformLogger.Level.FINE)) { + insLog.fine("For the operation {0} new dimensions are {1}", operationToString(operation), dims); - } + } - reshape(dims, operation, userReshape); + reshape(dims, operation, userReshape); + } finally { + XToolkit.awtUnlock(); + } } // This method gets overriden in XFramePeer & XDialogPeer. @@ -754,28 +772,29 @@ if (isReparented()) { configure_seen = true; } + XToolkit.awtLock(); + try { + if (!isMaximized() + && (xe.get_serial() == reparent_serial + || xe.get_window() != getShell()) + && !no_reparent_artifacts) { + insLog.fine("- reparent artifact, skipping"); + return; + } + no_reparent_artifacts = false; - if (!isMaximized() - && (xe.get_serial() == reparent_serial || xe.get_window() != getShell()) - && !no_reparent_artifacts) - { - insLog.fine("- reparent artifact, skipping"); - return; - } - no_reparent_artifacts = false; - - /** - * When there is a WM we receive some CN before being visible and after. - * We should skip all CN which are before being visible, because we assume - * the gravity is in action while it is not yet. - * - * When there is no WM we receive CN only _before_ being visible. - * We should process these CNs. - */ - if (!isVisible() && XWM.getWMID() != XWM.NO_WM) { - insLog.fine(" - not visible, skipping"); - return; - } + /** + * When there is a WM we receive some CN before being visible and + * after. We should skip all CN which are before being visible, + * because we assume the gravity is in action while it is not yet. + * + * When there is no WM we receive CN only _before_ being visible. + * We should process these CNs. + */ + if (!isVisible() && XWM.getWMID() != XWM.NO_WM) { + insLog.fine(" - not visible, skipping"); + return; + } /* * Some window managers configure before we are reparented and @@ -784,62 +803,71 @@ * this is just the WM shuffling us into position. Ignore * it!!!! or we wind up in a bogus location. */ - int runningWM = XWM.getWMID(); - if (insLog.isLoggable(PlatformLogger.Level.FINE)) { - insLog.fine("reparented={0}, visible={1}, WM={2}, decorations={3}", - isReparented(), isVisible(), runningWM, getDecorations()); - } - if (!isReparented() && isVisible() && runningWM != XWM.NO_WM - && !XWM.isNonReparentingWM() - && getDecorations() != XWindowAttributesData.AWT_DECOR_NONE) { - insLog.fine("- visible but not reparented, skipping"); - return; - } - //Last chance to correct insets - if (!insets_corrected && getDecorations() != XWindowAttributesData.AWT_DECOR_NONE) { - long parent = XlibUtil.getParentWindow(window); - Insets correctWM = (parent != -1) ? XWM.getWM().getInsets(this, window, parent) : null; - if (insLog.isLoggable(PlatformLogger.Level.FINER)) { + int runningWM = XWM.getWMID(); + if (insLog.isLoggable(PlatformLogger.Level.FINE)) { + insLog.fine("reparented={0}, visible={1}, WM={2}, " + + "decorations={3}", isReparented(), isVisible(), + runningWM, getDecorations()); + } + if (!isReparented() && isVisible() && runningWM != XWM.NO_WM + && !XWM.isNonReparentingWM() && getDecorations() != + XWindowAttributesData.AWT_DECOR_NONE) { + insLog.fine("- visible but not reparented, skipping"); + return; + } + //Last chance to correct insets + if (!insets_corrected && getDecorations() != + XWindowAttributesData.AWT_DECOR_NONE) { + long parent = XlibUtil.getParentWindow(window); + Insets correctWM = (parent != -1) ? XWM.getWM(). + getInsets(this, window, parent) : null; + if (insLog.isLoggable(PlatformLogger.Level.FINER)) { + if (correctWM != null) { + insLog.finer("Configure notify - insets : " + + correctWM); + } else { + insLog.finer("Configure notify - insets are still " + + " not available"); + } + } if (correctWM != null) { - insLog.finer("Configure notify - insets : " + correctWM); + handleCorrectInsets(copyAndScaleDown(correctWM)); } else { - insLog.finer("Configure notify - insets are still not available"); + //Only one attempt to correct insets is made (to lower risk) + //if insets are still not available we simply set the flag + insets_corrected = true; } } - if (correctWM != null) { - handleCorrectInsets(copyAndScaleDown(correctWM)); - } else { - //Only one attempt to correct insets is made (to lower risk) - //if insets are still not available we simply set the flag - insets_corrected = true; - } - } - updateChildrenSizes(); + updateChildrenSizes(); - Point newLocation = getNewLocation(xe, currentInsets.left, currentInsets.top); - WindowDimensions newDimensions = - new WindowDimensions(newLocation, - new Dimension(scaleDown(xe.get_width()), - scaleDown(xe.get_height())), - copy(currentInsets), true); + Point newLocation = getNewLocation(xe, currentInsets.left, + currentInsets.top); + WindowDimensions newDimensions = + new WindowDimensions(newLocation, + new Dimension(scaleDown(xe.get_width()), + scaleDown(xe.get_height())), + copy(currentInsets), true); - if (insLog.isLoggable(PlatformLogger.Level.FINER)) { - insLog.finer("Insets are {0}, new dimensions {1}", - currentInsets, newDimensions); - } + if (insLog.isLoggable(PlatformLogger.Level.FINER)) { + insLog.finer("Insets are {0}, new dimensions {1}", + currentInsets, newDimensions); + } - checkIfOnNewScreen(newDimensions.getBounds()); + checkIfOnNewScreen(newDimensions.getBounds()); - Point oldLocation = getLocation(); - dimensions = newDimensions; - if (!newLocation.equals(oldLocation)) { - handleMoved(newDimensions); - } - reconfigureContentWindow(newDimensions); - updateChildrenSizes(); + Point oldLocation = getLocation(); + dimensions = newDimensions; + if (!newLocation.equals(oldLocation)) { + handleMoved(newDimensions); + } + reconfigureContentWindow(newDimensions); + updateChildrenSizes(); - repositionSecurityWarning(); + repositionSecurityWarning(); + } finally { + XToolkit.awtUnlock(); + } } private void checkShellRectSize(Rectangle shellRect) { @@ -909,33 +937,45 @@ setResizable(winAttr.initialResizability); } public void setResizable(boolean resizable) { - int fs = winAttr.functions; - if (!isResizable() && resizable) { - resetWMSetInsets(); - if (!isEmbedded()) { - setReparented(false); - } - winAttr.isResizable = resizable; - if ((fs & MWMConstants.MWM_FUNC_ALL) != 0) { - fs &= ~(MWMConstants.MWM_FUNC_RESIZE | MWMConstants.MWM_FUNC_MAXIMIZE); - } else { - fs |= (MWMConstants.MWM_FUNC_RESIZE | MWMConstants.MWM_FUNC_MAXIMIZE); - } - winAttr.functions = fs; - XWM.setShellResizable(this); - } else if (isResizable() && !resizable) { - resetWMSetInsets(); - if (!isEmbedded()) { - setReparented(false); - } - winAttr.isResizable = resizable; - if ((fs & MWMConstants.MWM_FUNC_ALL) != 0) { - fs |= (MWMConstants.MWM_FUNC_RESIZE | MWMConstants.MWM_FUNC_MAXIMIZE); - } else { - fs &= ~(MWMConstants.MWM_FUNC_RESIZE | MWMConstants.MWM_FUNC_MAXIMIZE); + XToolkit.awtLock(); + try { + int fs = winAttr.functions; + if (!isResizable() && resizable) { + resetWMSetInsets(); + if (!isEmbedded()) { + setReparented(false); + } + winAttr.isResizable = resizable; + if ((fs & MWMConstants.MWM_FUNC_ALL) != 0) { + fs &= ~(MWMConstants.MWM_FUNC_RESIZE + | MWMConstants.MWM_FUNC_MAXIMIZE); + } else { + fs |= (MWMConstants.MWM_FUNC_RESIZE + | MWMConstants.MWM_FUNC_MAXIMIZE); + } + winAttr.functions = fs; + XWM.setShellResizable(this); + } else if (isResizable() && !resizable) { + resetWMSetInsets(); + if (!isEmbedded()) { + setReparented(false); + } + winAttr.isResizable = resizable; + if ((fs & MWMConstants.MWM_FUNC_ALL) != 0) { + fs |= (MWMConstants.MWM_FUNC_RESIZE + | MWMConstants.MWM_FUNC_MAXIMIZE); + } else { + fs &= ~(MWMConstants.MWM_FUNC_RESIZE + | MWMConstants.MWM_FUNC_MAXIMIZE); + } + winAttr.functions = fs; + XWM.setShellNotResizable(this, dimensions, + XWM.getWMID() == XWM.UNITY_COMPIZ_WM && configure_seen ? + dimensions.getScreenBounds() : + dimensions.getBounds(), false); } - winAttr.functions = fs; - XWM.setShellNotResizable(this, dimensions, dimensions.getBounds(), false); + } finally { + XToolkit.awtUnlock(); } } --- old/src/java.desktop/unix/classes/sun/awt/X11/XWM.java 2016-10-18 16:06:44.581798825 +0300 +++ new/src/java.desktop/unix/classes/sun/awt/X11/XWM.java 2016-10-18 16:06:44.501798828 +0300 @@ -1029,8 +1029,14 @@ } XToolkit.awtLock(); try { - Rectangle shellBounds = window.getShellBounds(); - shellBounds.translate(-window.currentInsets.left, -window.currentInsets.top); + Rectangle shellBounds; + 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()); requestWMExtents(window.getWindow()); XlibWrapper.XMoveResizeWindow(XToolkit.getDisplay(), --- old/test/java/awt/Window/ChangeWindowResizabilty/ChangeWindowResizabiltyTest.java 2016-10-18 16:06:44.829798816 +0300 +++ new/test/java/awt/Window/ChangeWindowResizabilty/ChangeWindowResizabiltyTest.java 2016-10-18 16:06:44.749798819 +0300 @@ -21,7 +21,9 @@ * questions. */ -/* @bug 8166897 +/* + @test + @bug 8166897 @summary Some font overlap in the Optionpane dialog. @run main ChangeWindowResizabiltyTest */ @@ -33,35 +35,68 @@ Robot robot = new Robot(); for(int i = 0; i < 10; i++) { Dialog dialog = new Dialog((Frame) null); + dialog.setLocation(100, 100); Component panel = new Panel(); panel.setPreferredSize(new Dimension(200, 100)); dialog.add(panel); dialog.pack(); 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); robot.waitForIdle(); robot.delay(200); - System.out.println(panel.getLocationOnScreen()); - System.out.println(dialog.getLocationOnScreen()); + Point l = 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 < - dialog.getLocationOnScreen().y + dialog.getInsets().top) { + dialog.getLocationOnScreen().y + dialog.getInsets().top) { dialog.dispose(); throw new RuntimeException( - "Wrong content position after setResizable(false)"); + "Wrong content position after setResizable(false)"); } dialog.setResizable(true); robot.waitForIdle(); 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 < - dialog.getLocationOnScreen().y + dialog.getInsets().top) { + dialog.getLocationOnScreen().y + dialog.getInsets().top) { dialog.dispose(); throw new RuntimeException( - "Wrong content position after setResizable(true)"); + "Wrong content position after setResizable(true)"); } dialog.dispose();