--- old/src/java.desktop/unix/classes/sun/awt/X11/XDecoratedPeer.java 2016-09-23 15:42:24.320487679 +0300 +++ new/src/java.desktop/unix/classes/sun/awt/X11/XDecoratedPeer.java 2016-09-23 15:42:24.176487684 +0300 @@ -308,6 +308,19 @@ super.handlePropertyNotify(xev); XPropertyEvent ev = xev.get_xproperty(); + if( !insets_corrected && isReparented() && + XWM.getWMID() == XWM.UNITY_COMPIZ_WM) { + int state = XWM.getWM().getState(this); + if ((state & Frame.MAXIMIZED_BOTH) == Frame.MAXIMIZED_BOTH) { + // Stop ignoring ConfigureNotify because no extents will be sent + // by WM for initially maximized decorated window. + // Re-request window bounds to ensure actual dimensions and + // notify the target with the initial size. + insets_corrected = true; + XlibWrapper.XConfigureWindow(XToolkit.getDisplay(), + getWindow(), 0, 0); + } + } if (ev.get_atom() == XWM.XA_KDE_NET_WM_FRAME_STRUT.getAtom() || ev.get_atom() == XWM.XA_NET_FRAME_EXTENTS.getAtom()) { @@ -325,11 +338,30 @@ if (!isEmbedded() && !isTargetUndecorated()) { lastKnownInsets.put(getClass(), in); } - if (!in.equals(dimensions.getInsets()) || - !dimensions.isClientSizeSet()) { - handleCorrectInsets(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 (!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); } - insets_corrected = true; } } } --- /dev/null 2016-09-23 10:03:50.405204967 +0300 +++ new/test/java/awt/Frame/DecoratedFrameInsets/DecoratedFrameInsetsTest.java 2016-09-23 15:42:24.484487673 +0300 @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8165619 + * @summary Frame is not repainted if created in state=MAXIMIZED_BOTH on Unity + * @run main DecoratedFrameInsetsTest + */ + +import java.awt.*; + +public class DecoratedFrameInsetsTest { + static Robot robot; + private static Insets expectedInsets; + + public static void main(String[] args) throws Exception { + robot = new Robot(); + expectedInsets = getExpectedInsets(); + System.out.println("Normal state insets: " + expectedInsets); + testState(Frame.MAXIMIZED_BOTH); + testState(Frame.ICONIFIED); + testState(Frame.MAXIMIZED_HORIZ); + testState(Frame.MAXIMIZED_VERT); + } + + private static Insets getExpectedInsets() { + Frame frame = new Frame(); + frame.setVisible(true); + robot.waitForIdle(); + robot.delay(200); + Insets expectedInsets = frame.getInsets(); + frame.dispose(); + return expectedInsets; + } + + static void testState(int state) { + Frame frame = new Frame(); + if( Toolkit.getDefaultToolkit().isFrameStateSupported(state)) { + frame.setBounds(150, 150, 200, 200); + frame.setExtendedState(state); + frame.setVisible(true); + robot.waitForIdle(); + robot.delay(200); + System.out.println("State " + state + + " insets: " + frame.getInsets()); + + frame.setExtendedState(Frame.NORMAL); + frame.toFront(); + robot.waitForIdle(); + robot.delay(200); + Insets insets = frame.getInsets(); + frame.dispose(); + System.out.println("State " + state + + " back to normal insets: " + insets); + if(!expectedInsets.equals(insets)) { + throw new RuntimeException("Insets are wrong " + insets); + } + } + } +}