7043963: AWT workaround missing for Mutter.
authoromajid
Mon, 04 Jun 2012 16:39:12 -0400
changeset 12829 506020af237a
parent 12828 8e71b2ed3d5f
child 12830 c5a77c735e39
7043963: AWT workaround missing for Mutter. Reviewed-by: art, anthony Contributed-by: Denis Lila <dlila@redhat.com>
jdk/src/solaris/classes/sun/awt/X11/XDecoratedPeer.java
jdk/src/solaris/classes/sun/awt/X11/XWM.java
jdk/test/java/awt/WMSpecificTests/Mutter/MutterMaximizeTest.java
jdk/test/java/awt/regtesthelpers/Util.java
--- a/jdk/src/solaris/classes/sun/awt/X11/XDecoratedPeer.java	Mon Jun 04 14:11:26 2012 +0400
+++ b/jdk/src/solaris/classes/sun/awt/X11/XDecoratedPeer.java	Mon Jun 04 16:39:12 2012 -0400
@@ -721,15 +721,17 @@
             // Location, Client size + insets
             newLocation = new Point(xe.get_x() - currentInsets.left, xe.get_y() - currentInsets.top);
         } else {
-            // CDE/MWM/Metacity/Sawfish bug: if shell is resized using
-            // top or left border, we don't receive synthetic
-            // ConfigureNotify, only the one from X with zero
-            // coordinates.  This is the workaround to get real
-            // location, 6261336
+            // ICCCM 4.1.5 states that a real ConfigureNotify will be sent when
+            // a window is resized but the client can not tell if the window was
+            // moved or not. The client should consider the position as unkown
+            // and use TranslateCoordinates to find the actual position.
+            //
+            // TODO this should be the default for every case.
             switch (XWM.getWMID()) {
                 case XWM.CDE_WM:
                 case XWM.MOTIF_WM:
                 case XWM.METACITY_WM:
+                case XWM.MUTTER_WM:
                 case XWM.SAWFISH_WM:
                 {
                     Point xlocation = queryXLocation();
--- a/jdk/src/solaris/classes/sun/awt/X11/XWM.java	Mon Jun 04 14:11:26 2012 +0400
+++ b/jdk/src/solaris/classes/sun/awt/X11/XWM.java	Mon Jun 04 16:39:12 2012 -0400
@@ -102,7 +102,8 @@
         METACITY_WM = 11,
         COMPIZ_WM = 12,
         LG3D_WM = 13,
-        CWM_WM = 14;
+        CWM_WM = 14,
+        MUTTER_WM = 15;
     public String toString() {
         switch  (WMID) {
           case NO_WM:
@@ -131,6 +132,8 @@
               return "LookingGlass";
           case CWM_WM:
               return "CWM";
+          case MUTTER_WM:
+              return "Mutter";
           case UNDETERMINED_WM:
           default:
               return "Undetermined WM";
@@ -573,6 +576,10 @@
 //                            getIntProperty(XToolkit.getDefaultRootWindow(), XAtom.XA_CARDINAL)) == 0);
     }
 
+    static boolean isMutter() {
+        return isNetWMName("Mutter");
+    }
+
     static boolean isNonReparentingWM() {
         return (XWM.getWMID() == XWM.COMPIZ_WM || XWM.getWMID() == XWM.LG3D_WM || XWM.getWMID() == XWM.CWM_WM);
     }
@@ -742,6 +749,8 @@
                 awt_wmgr = XWM.ENLIGHTEN_WM;
             } else if (isMetacity()) {
                 awt_wmgr = XWM.METACITY_WM;
+            } else if (isMutter()) {
+                awt_wmgr = XWM.MUTTER_WM;
             } else if (isSawfish()) {
                 awt_wmgr = XWM.SAWFISH_WM;
             } else if (isKDE2()) {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/awt/WMSpecificTests/Mutter/MutterMaximizeTest.java	Mon Jun 04 16:39:12 2012 -0400
@@ -0,0 +1,160 @@
+/*
+ * Copyright 2012 Red Hat, Inc.  All Rights Reserved.
+ * Copyright (c) 2012, 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      7043963
+  @summary  Tests  that the screen location of windows is
+            updated properly after a maximize.
+  @author   Denis Lila
+  @library  ../../regtesthelpers
+  @build    Util
+  @run      main MutterMaximizeTest
+*/
+
+import java.awt.AWTException;
+import java.awt.Dimension;
+import java.awt.Frame;
+import java.awt.Point;
+import java.awt.Robot;
+import java.awt.Window;
+import java.awt.event.InputEvent;
+import java.awt.event.WindowAdapter;
+import java.awt.event.WindowEvent;
+
+import test.java.awt.regtesthelpers.Util;
+
+@SuppressWarnings("serial")
+public class MutterMaximizeTest extends Frame {
+
+    public static void main(String[] args) throws InterruptedException {
+        if (Util.getWMID() != Util.MUTTER_WM) {
+            System.out.println("This test is only useful on Mutter");
+            return;
+        }
+        MutterMaximizeTest frame = new MutterMaximizeTest();
+        frame.addWindowListener(Util.getClosingWindowAdapter());
+
+        //Display the window.
+        frame.setSize(500, 500);
+        Util.showWindowWait(frame);
+        runRobotTest(frame);
+    }
+
+    private static void runRobotTest(Frame frame) {
+        try {
+            Thread robotThread = startRegTest(frame);
+            robotThread.start();
+            waitForThread(robotThread);
+        } finally {
+            frame.dispose();
+        }
+    }
+
+    private static void waitForThread(Thread t) {
+        while (t.isAlive()) {
+            try {
+                t.join();
+            } catch (InterruptedException e) {
+            }
+        }
+    }
+
+    private static void sleepFor(long millis) {
+        long dT = 0;
+        long start = System.nanoTime();
+        while (dT < millis) {
+            try {
+                long toSleep = millis - dT/1000000;
+                if (toSleep > 0) {
+                    Thread.sleep(toSleep);
+                }
+                // if this ends without an interrupted exception,
+                // that's good enough.
+                break;
+            } catch (InterruptedException e) {
+                long now = System.nanoTime();
+                dT = now - start;
+            }
+        }
+    }
+
+    private static void rmove(Robot robot, Point p) {
+        robot.mouseMove(p.x, p.y);
+    }
+    private static void rdown(Robot robot) {
+        robot.mousePress(InputEvent.BUTTON1_MASK);
+        robot.delay(50);
+    }
+    private static void rup(Robot robot) {
+        robot.mouseRelease(InputEvent.BUTTON1_MASK);
+        robot.delay(50);
+    }
+
+    public static void click(Robot robot) {
+        rdown(robot);
+        rup(robot);
+    }
+
+    public static void doubleClick(Robot robot) {
+        click(robot);
+        click(robot);
+    }
+
+    private static void dragWindow(Window w, int dx, int dy, Robot robot) {
+        Point p = Util.getTitlePoint(w);
+        rmove(robot, p);
+        rdown(robot);
+        p.translate(dx, dy);
+        rmove(robot, p);
+        rup(robot);
+    }
+
+    // f must be visible
+    private static Thread startRegTest(final Frame f) {
+        Thread robot = new Thread(new Runnable() {
+            public void run() {
+                Robot r = Util.createRobot();
+                dragWindow(f, 100, 100, r);
+                // wait for the location to be set.
+                sleepFor(2000);
+
+                final Point l2 = f.getLocationOnScreen();
+
+                // double click should maximize the frame
+                doubleClick(r);
+
+                // wait for location again.
+                sleepFor(2000);
+                final Point l3 = f.getLocationOnScreen();
+                if (l3.equals(l2)) {
+                    throw new RuntimeException("Bad location after maximize. Window location has not moved");
+                }
+            }
+        });
+        return robot;
+    }
+}
+
--- a/jdk/test/java/awt/regtesthelpers/Util.java	Mon Jun 04 14:11:26 2012 +0400
+++ b/jdk/test/java/awt/regtesthelpers/Util.java	Mon Jun 04 16:39:12 2012 -0400
@@ -162,16 +162,21 @@
         clickOnComp(comp, robot, 50);
     }
 
+    public static Point getTitlePoint(Window decoratedWindow) {
+        Point p = decoratedWindow.getLocationOnScreen();
+        Dimension d = decoratedWindow.getSize();
+        return new Point(p.x + (int)(d.getWidth()/2),
+                         p.y + (int)(decoratedWindow.getInsets().top/2));
+    }
+
     /*
      * Clicks on a title of Frame/Dialog.
      * WARNING: it may fail on some platforms when the window is not wide enough.
      */
     public static void clickOnTitle(final Window decoratedWindow, final Robot robot) {
-        Point p = decoratedWindow.getLocationOnScreen();
-        Dimension d = decoratedWindow.getSize();
-
         if (decoratedWindow instanceof Frame || decoratedWindow instanceof Dialog) {
-            robot.mouseMove(p.x + (int)(d.getWidth()/2), p.y + (int)decoratedWindow.getInsets().top/2);
+            Point p = getTitlePoint(decoratedWindow);
+            robot.mouseMove(p.x, p.y);
             robot.delay(50);
             robot.mousePress(InputEvent.BUTTON1_MASK);
             robot.delay(50);
@@ -409,7 +414,9 @@
         ICE_WM = 10,
         METACITY_WM = 11,
         COMPIZ_WM = 12,
-        LG3D_WM = 13;
+        LG3D_WM = 13,
+        CWM_WM = 14,
+        MUTTER_WM = 15;
 
     /*
      * Returns -1 in case of not X Window or any problems.