/*
* Copyright 2004 Timothy Wall
*
*/
package abbot.util;
import java.awt.Window;
import java.awt.event.InputEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import abbot.Log;
import abbot.Platform;
import abbot.i18n.Strings;
import abbot.tester.Robot;
/**
Provides extant bug characterization of the current platform. For any bug
encountered, there should be a static method indicating whether the bug is
expected on the current platform, for example
{@link #showAWTPopupMenuBlocks()}.
See the source for <code>
<a href=../../../../test/abbot/util/BugsTest.java>BugsTest</a></code> for the
test implementations.
@author twall
*/
public class Bugs {
private static java.util.ArrayList bugList = null;
private static boolean gotBug1Event = false;
private Bugs() { }
/** Returns whether AWT menus have enable/disable problems. */
public static boolean hasMenuDisableBug() {
return Platform.isOSX()
&& Platform.JAVA_VERSION >= Platform.JAVA_1_4
&& Platform.JAVA_VERSION < 0x1424; // when it got fixed
}
/** Returns whether KEY_TYPED events are sent to AWT listeners. */
public static boolean hasInputMethodInsteadOfKeyTyped() {
return Platform.isOSX()
&& Platform.JAVA_VERSION >= Platform.JAVA_1_4
&& Platform.JAVA_VERSION < 0x1424; // when it got fixed
}
/** Returns whether windows send mouse motion events to AWT listeners. */
public static boolean hasMissingWindowMouseMotion() {
return Platform.isOSX()
&& Platform.JAVA_VERSION >= Platform.JAVA_1_4
&& Platform.JAVA_VERSION <= 0x1425; // most recent tested
}
/** Returns whether mouse buttons 2/3 are swapped when using Robot. */
public static boolean hasRobotButtonsSwapped() {
return Platform.isOSX()
&& Platform.JAVA_VERSION >= Platform.JAVA_1_4
&& Platform.JAVA_VERSION <= 0x1425; // most recent tested
}
/** Do we get multiple clicks even when the individual clicks are on
* different frames?
*/
// Will we get incorrectly get multiple clicks on rapid robot clicks?
// frame1->click,frame2->click
// frame1->click,frame1->hide/show,frame1->click
public static boolean hasMultiClickFrameBug() {
// w32 (1.3.02) will count it even if it was on a different component!
// w32 (1.3.1_06) same
// w32 (1.4.1_02) same (sporadic)
// OSX (1.3.x, 1.4.1) has the same problem
// Haven't seen it on linux
return Platform.isWindows() || Platform.isOSX()
|| Platform.JAVA_VERSION < Platform.JAVA_1_3;
}
/** Returns whether there may be some scenarios in which the robot does
not function properly.
*/
public static boolean needsRobotVerification() {
return Platform.isWindows() || Platform.isOSX();
}
/** Prior to 1.4.1, hierarchy events are only sent if listeners are added
to a given component.
*/
public static boolean hasHierarchyEventGenerationBug() {
return Platform.JAVA_VERSION < Platform.JAVA_1_4;
}
/** OSX prior to 1.4 has really crappy key input handling. */
public static boolean hasKeyStrokeGenerationBug() {
return Platform.isOSX()
&& Platform.JAVA_VERSION < Platform.JAVA_1_4;
}
/** Returnes whether there a longer delay required between robot
generation and event queue posting for key events. */
public static boolean hasKeyInputDelay() {
return Platform.isOSX()
&& Platform.JAVA_VERSION >= Platform.JAVA_1_4
&& Platform.JAVA_VERSION <= 0x1425;
}
/** Some OSX releases wouldn't restore an iconified Frame. */
public static boolean hasFrameDeiconifyBug() {
return Platform.isOSX()
&& Platform.JAVA_VERSION > 0x1310
&& Platform.JAVA_VERSION < 0x1424;
}
/** OS X (as of 1.3.1, v10.1.5), will sometimes send a click to the wrong
component after a mouse move. This continues to be an issue in 1.4.1
<p>
Linux x86 (1.3.1) has a similar problem, although it manifests it at
different times (need a bug test case for this one).
<p>
Solaris and HPUX probably share code with the linux VM implementation,
so the bug there is probably identical.
<p>
*/
// FIXME add tests to determine presence of bug.
public static boolean hasRobotMotionBug() {
return Platform.isOSX()
|| (!Platform.isWindows()
&& Platform.JAVA_VERSION < Platform.JAVA_1_4)
|| Boolean.getBoolean("abbot.robot.need_jitter");
}
/** Choice popup activates on mouse press, but locks up when the Robot
* attempts to post a mouse release.
*/
public static boolean hasChoiceLockupBug() {
return Platform.isOSX()
&& Platform.JAVA_VERSION < Platform.JAVA_1_4;
}
/** Robot.keyPress(KeyEvent.VK_ESCAPE doesn't work. */
public static boolean hasEscapeGenerationBug() {
return Platform.isOSX()
&& Platform.JAVA_VERSION < Platform.JAVA_1_4;
}
/** Returns whether the Java event queue is suspended while an AWT popup
is showing. */
public static boolean showAWTPopupMenuBlocks() {
return Platform.isWindows()
&& Platform.JAVA_VERSION <= Platform.JAVA_1_5;
}
/** Locking key state is reported incorrectly. */
public static boolean reportsIncorrectLockingKeyState() {
return Platform.isLinux()
&& Platform.JAVA_VERSION <= 0x1424;
}
/** Whether drag/drop requires native events. */
// TODO: needs a test
public static boolean dragDropRequiresNativeEvents() {
return Platform.JAVA_VERSION <= 0x1425;
}
/** Returns whether a {@link java.awt.FileDialog} requires an explicit
dismiss (ok/cancel). Ordinarily {@link Window#dispose()} will work.
*/
public static boolean fileDialogRequiresDismiss() {
return Platform.isOSX() && Platform.JAVA_VERSION <= 0x1425
|| (Platform.isWindows()
&& Platform.JAVA_VERSION <= Platform.JAVA_1_5);
}
/** Returns whether a {@link java.awt.FileDialog} misreports its screen
location.
*/
public static boolean fileDialogMisreportsBounds() {
return (Platform.isOSX() && Platform.JAVA_VERSION <= 0x1425)
|| (Platform.isWindows()
&& Platform.JAVA_VERSION <= Platform.JAVA_1_5);
}
public static boolean fileDialogRequiresVisibleFrame() {
// Subsequent FileDialogs don't show up if the frame isn't visible,
// and a previous non-visible frame was disposed.
return Platform.isWindows() && Platform.JAVA_VERSION <= 0x1421;
}
public static boolean hasTextComponentSelectionDelay() {
// TODO: write a test for this one
// Select TextComponent text, wait for idle, selection end not updated
return (Platform.isLinux() || Platform.isWindows())
&& Platform.JAVA_VERSION <= 0x1424;
}
/** Check for certain robot-related bugs that will affect Abbot
* operation. Returns a String for each bug detected on the current
* system.
*/
public static String[] bugCheck(final Window window) {
if (bugList == null) {
bugList = new java.util.ArrayList();
final int x = window.getWidth() / 2;
final int y = window.getHeight() / 2;
if (Platform.isWindows() && !Platform.isWindowsXP()
&& Platform.JAVA_VERSION < Platform.JAVA_1_4) {
Log.debug("Checking for w32 bugs");
final int mask = InputEvent.BUTTON2_MASK;
MouseAdapter ma = new MouseAdapter() {
public void mouseClicked(MouseEvent e) {
gotBug1Event = true;
// w32 acceleration settings bug
if (e.getX() != x || e.getY() != y) {
bugList.add(Strings.get("Bug1"));
}
// w32 mouse button mapping bug
if ((e.getModifiers() & mask) != mask) {
bugList.add(Strings.get("Bug2"));
}
}
};
window.addMouseListener(ma);
Robot robot = new Robot();
robot.click(window, x, y, mask);
robot.waitForIdle();
window.toFront();
// Bogus acceleration may mean the event goes entirely
// elsewhere
if (!gotBug1Event) {
bugList.add(0, Strings.get("Bug1"));
}
window.removeMouseListener(ma);
}
else if (Platform.isOSX()
&& Platform.JAVA_VERSION < 0x1430) {
Log.debug("Checking for OSX bugs");
final int mask = InputEvent.BUTTON2_MASK;
MouseAdapter ma = new MouseAdapter() {
public void mouseClicked(MouseEvent e) {
if ((e.getModifiers() & mask) != mask) {
bugList.add(Strings.get("robot.bug3"));
}
}
};
window.addMouseListener(ma);
Robot robot = new Robot();
robot.click(window, x, y, mask);
robot.waitForIdle();
window.removeMouseListener(ma);
}
}
return (String[])bugList.toArray(new String[bugList.size()]);
}
}