1 /* 2 * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 /* 25 @test 26 @key headful 27 @bug 5039416 6404008 28 @summary REGRESSION: Extra mouse click dispatched after press-drag- release sequence. 29 @library ../../regtesthelpers 30 @build Util 31 @run main ExtraMouseClick 32 */ 33 34 import java.awt.AWTException; 35 import java.awt.Frame; 36 import java.awt.Point; 37 import java.awt.Robot; 38 import java.awt.Toolkit; 39 import java.awt.event.InputEvent; 40 import java.awt.event.MouseAdapter; 41 import java.awt.event.MouseEvent; 42 import java.awt.event.MouseMotionAdapter; 43 import test.java.awt.regtesthelpers.Util; 44 45 //** 46 // Here are two values of smugde used in this test (2 and 5). They should be on 47 // different sides from value 4 (smudge distance on both toolkits). 48 // Note that this test may not fail easily. But it must always pass on 49 // patched workspace. 50 //** 51 public class ExtraMouseClick { 52 Frame frame = new Frame("Extra Click After MouseDrag"); 53 final int TRIALS = 10; 54 final int SMUDGE_WIDTH = 4; 55 final int SMUDGE_HEIGHT = 4; 56 Robot robot; 57 Point fp; //frame's location on screen 58 boolean dragged = false; 59 boolean clicked = false; 60 boolean pressed = false; 61 boolean released = false; 62 63 public static void main(final String[] args) { 64 ExtraMouseClick app = new ExtraMouseClick(); 65 app.init(); 66 app.start(); 67 } 68 69 public void init() 70 { 71 frame.addMouseListener(new MouseAdapter() { 72 public void mousePressed(MouseEvent e) { 73 System.out.println("MousePressed"); 74 pressed = true; 75 } 76 77 public void mouseReleased(MouseEvent e) { 78 System.out.println("MouseReleased"); 79 released = true; 80 } 81 82 public void mouseClicked(MouseEvent e) { 83 System.out.println("MouseClicked!!!!"); 84 clicked = true; 85 } 86 }); 87 frame.addMouseMotionListener(new MouseMotionAdapter() { 88 public void mouseDragged(MouseEvent e) { 89 System.out.println("MouseDragged--"+e); 90 dragged = true; 91 } 92 public void mouseMoved(MouseEvent e) { 93 } 94 }); 95 96 }//End init() 97 98 99 public void start () 100 { 101 frame.setSize(480, 300); 102 frame.setLocationRelativeTo(null); 103 frame.setVisible(true); 104 try{ 105 robot = new Robot(); 106 }catch(AWTException e){ 107 throw new RuntimeException(e); 108 } 109 110 Util.waitForIdle(robot); //a time to show Frame 111 112 fp = frame.getLocationOnScreen(); 113 114 for (int i = 0; i< TRIALS; i++){ 115 checkClicked(); 116 clearFlags(); 117 } 118 119 for (int i = 0; i< TRIALS; i++){ 120 oneDrag(2); 121 clearFlags(); 122 } 123 124 for (int i = 0; i< TRIALS; i++){ 125 oneDrag(5); 126 clearFlags(); 127 } 128 129 for (int i = 0; i< TRIALS; i++){ 130 oneDrag(70); 131 clearFlags(); 132 } 133 134 //Check that no Drag event occur in the SMUDGE area 135 String sToolkit = Toolkit.getDefaultToolkit().getClass().getName(); 136 System.out.println("Toolkit == "+sToolkit); 137 if ("sun.awt.windows.WToolkit".equals(sToolkit)){ 138 int dragWidth = ((Integer)Toolkit.getDefaultToolkit(). 139 getDesktopProperty("win.drag.width")).intValue(); 140 int dragHeight = ((Integer)Toolkit.getDefaultToolkit(). 141 getDesktopProperty("win.drag.height")).intValue(); 142 System.out.println("dragWidth=="+dragWidth+":: dragHeight=="+dragHeight); 143 // DragWidth and dragHeight may be equal to 1. In that case the SMUDGE rectangle 144 // narrowed into 1x1 pixel and we can't drag a mouse in it. 145 // In that case we may skip following testcase but I'd prefer if we move mouse on 1 pixel only. 146 // And that should pass as well. 147 dragWidth = dragWidth > 1? dragWidth/2:1; 148 dragHeight = dragHeight > 1? dragHeight/2:1; 149 for (int i = 0; i< TRIALS; i++){ 150 smallWin32Drag(dragWidth, dragHeight); 151 clearFlags(); 152 } 153 } else if ("sun.lwawt.macosx.LWCToolkit".equals(sToolkit)) { 154 // On MacOS X every mouse move event is MOUSE_DRAGGED event and 155 // MOUSE_DRAGGED is sent back form the Native code to the java code 156 // for every mouse move. Therefore 'smallDrag test should be 157 // disabled for toolkit 'sun.lwawt.macosx.LWCToolkit'. 158 } else { 159 for (int i = 0; i< TRIALS; i++){ 160 smallDrag(SMUDGE_WIDTH - 1, SMUDGE_HEIGHT - 1); //on Motif and XAWT SMUDGE area is 4-pixels wide 161 clearFlags(); 162 } 163 } 164 System.out.println("Test passed."); 165 }// start() 166 167 public void oneDrag(int pixels){ 168 robot.mouseMove(fp.x + frame.getWidth()/2, fp.y + frame.getHeight()/2 ); 169 //drag for a short distance 170 robot.mousePress(InputEvent.BUTTON1_MASK ); 171 for (int i = 1; i<pixels;i++){ 172 robot.mouseMove(fp.x + frame.getWidth()/2 + i, fp.y + frame.getHeight()/2 ); 173 } 174 robot.waitForIdle(); 175 robot.mouseRelease(InputEvent.BUTTON1_MASK ); 176 robot.waitForIdle(); 177 178 if (dragged && clicked){ 179 throw new RuntimeException("Test failed. Clicked event follows by Dragged. Dragged = "+dragged +". Clicked = "+clicked + " : distance = "+pixels); 180 } 181 } 182 183 public void smallDrag(int pixelsX, int pixelsY){ 184 // by the X-axis 185 robot.mouseMove(fp.x + frame.getWidth()/2, fp.y + frame.getHeight()/2 ); 186 //drag for a short distance 187 robot.mousePress(InputEvent.BUTTON1_MASK ); 188 for (int i = 1; i<pixelsX;i++){ 189 robot.mouseMove(fp.x + frame.getWidth()/2 + i, fp.y + frame.getHeight()/2 ); 190 } 191 robot.mouseRelease(InputEvent.BUTTON1_MASK ); 192 robot.delay(1000); 193 if (dragged){ 194 throw new RuntimeException("Test failed. Dragged event (by the X-axis) occured in SMUDGE area. Dragged = "+dragged +". Clicked = "+clicked); 195 } 196 197 // the same with Y-axis 198 robot.mouseMove(fp.x + frame.getWidth()/2, fp.y + frame.getHeight()/2 ); 199 robot.mousePress(InputEvent.BUTTON1_MASK ); 200 for (int i = 1; i<pixelsY;i++){ 201 robot.mouseMove(fp.x + frame.getWidth()/2, fp.y + frame.getHeight()/2 + i ); 202 } 203 robot.mouseRelease(InputEvent.BUTTON1_MASK ); 204 robot.delay(1000); 205 if (dragged){ 206 throw new RuntimeException("Test failed. Dragged event (by the Y-axis) occured in SMUDGE area. Dragged = "+dragged +". Clicked = "+clicked); 207 } 208 209 } 210 211 // The difference between X-system and Win32: on Win32 Dragged event start to be generated after any mouse drag. 212 // On X-systems Dragged event first fired when mouse has left the SMUDGE area 213 public void smallWin32Drag(int pixelsX, int pixelsY){ 214 // by the X-axis 215 robot.mouseMove(fp.x + frame.getWidth()/2, fp.y + frame.getHeight()/2 ); 216 //drag for a short distance 217 robot.mousePress(InputEvent.BUTTON1_MASK ); 218 System.out.println(" pixelsX = "+ pixelsX +" pixelsY = " +pixelsY); 219 for (int i = 1; i<=pixelsX;i++){ 220 System.out.println("Moving a mouse by X"); 221 robot.mouseMove(fp.x + frame.getWidth()/2 + i, fp.y + frame.getHeight()/2 ); 222 } 223 robot.mouseRelease(InputEvent.BUTTON1_MASK ); 224 robot.delay(1000); 225 if (!dragged){ 226 throw new RuntimeException("Test failed. Dragged event (by the X-axis) didn't occur in the SMUDGE area. Dragged = "+dragged); 227 } 228 229 // the same with Y-axis 230 robot.mouseMove(fp.x + frame.getWidth()/2, fp.y + frame.getHeight()/2 ); 231 robot.mousePress(InputEvent.BUTTON1_MASK ); 232 for (int i = 1; i<=pixelsY;i++){ 233 System.out.println("Moving a mouse by Y"); 234 robot.mouseMove(fp.x + frame.getWidth()/2, fp.y + frame.getHeight()/2 + i ); 235 } 236 robot.mouseRelease(InputEvent.BUTTON1_MASK ); 237 robot.delay(1000); 238 if (!dragged){ 239 throw new RuntimeException("Test failed. Dragged event (by the Y-axis) didn't occur in the SMUDGE area. Dragged = "+dragged); 240 } 241 } 242 243 public void checkClicked(){ 244 robot.mouseMove(fp.x + frame.getWidth()/2, fp.y + frame.getHeight()/2 ); 245 robot.mousePress(InputEvent.BUTTON1_MASK ); 246 robot.delay(10); 247 robot.mouseRelease(InputEvent.BUTTON1_MASK ); 248 robot.delay(1000); 249 if (!clicked || !pressed || !released || dragged){ 250 throw new RuntimeException("Test failed. Some of Pressed/Released/Clicked events are missed or dragged occured. Pressed/Released/Clicked/Dragged = "+pressed + ":"+released+":"+clicked +":" +dragged); 251 } 252 } 253 254 public void clearFlags(){ 255 clicked = false; 256 pressed = false; 257 released = false; 258 dragged = false; 259 } 260 }// class