Skip to content

Commit

Permalink
JDK-8090930: Support mouse forward/back buttons.
Browse files Browse the repository at this point in the history
Platform native windows (for Windows, macOS, and Linux) are adapted to
listen for BACK/FORWARD mouse button activity and fire respective
MouseEvents, as is currently done for PRIMARY, MIDDLE, and RIGHT.

We also add support for emulating mouse button press/release with
BACK/FORWARD to the native robot implementations so that e.g.
Robot#mousePress(MouseButton.BACK) will work as intended on Windows,
macOS, and Linux.

This new functionality is tested in an integrated way by adding two
tests to test/robot/javafx/scene/RobotTest.java that firstly use the
Robot to press and release the BACK/FORWARD buttons on a scene-graph
Node and then secondly ensure that the onMouseClicked event listener
properly fires a MOUSE_CLICKED event for the respective BACK/FORWARD
button. This ensures that the new mouse buttons are supported not only
on the Java side, but on the native side as well.
  • Loading branch information
brcolow committed Dec 6, 2018
1 parent 53f42a4 commit b6270b4
Show file tree
Hide file tree
Showing 42 changed files with 865 additions and 43 deletions.
11 changes: 0 additions & 11 deletions .idea/misc.xml

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,8 @@ private void fireMouseEvent(EventType<MouseEvent> evtType, MouseButton button, i
button == MouseButton.PRIMARY, // primary button
button == MouseButton.MIDDLE, // middle button
button == MouseButton.SECONDARY, // secondary button
button == MouseButton.BACK, // back button
button == MouseButton.FORWARD, // forward button
false, // synthesized
button == MouseButton.SECONDARY, // is popup trigger
true, // still since pick
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@ public class KeyEvent {
@Native public final static int MODIFIER_BUTTON_PRIMARY = 1 << 5;
@Native public final static int MODIFIER_BUTTON_SECONDARY = 1 << 6;
@Native public final static int MODIFIER_BUTTON_MIDDLE = 1 << 7;
@Native public final static int MODIFIER_BUTTON_BACK = 1 << 8;
@Native public final static int MODIFIER_BUTTON_FORWARD = 1 << 9;

/*
* Key event key codes.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ public class MouseEvent {
@Native final static public int BUTTON_LEFT = 212;
@Native final static public int BUTTON_RIGHT = 213;
@Native final static public int BUTTON_OTHER = 214;
@Native final static public int BUTTON_BACK = 215;
@Native final static public int BUTTON_FORWARD = 216;

@Native final static public int DOWN = 221;
@Native final static public int UP = 222;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ public abstract class GlassRobot {
@Native public static final int MOUSE_LEFT_BTN = 1 << 0;
@Native public static final int MOUSE_RIGHT_BTN = 1 << 1;
@Native public static final int MOUSE_MIDDLE_BTN = 1 << 2;
@Native public static final int MOUSE_BACK_BTN = 1 << 3;
@Native public static final int MOUSE_FORWARD_BTN = 1 << 4;

/**
* Initializes any state necessary for this {@code Robot}. Called by
Expand Down Expand Up @@ -247,6 +249,8 @@ public static int convertToRobotMouseButton(MouseButton[] buttons) {
case PRIMARY: ret |= MOUSE_LEFT_BTN; break;
case SECONDARY: ret |= MOUSE_RIGHT_BTN; break;
case MIDDLE: ret |= MOUSE_MIDDLE_BTN; break;
case BACK: ret |= MOUSE_BACK_BTN; break;
case FORWARD: ret |= MOUSE_FORWARD_BTN; break;
default: throw new IllegalArgumentException("MouseButton: " + button + " not supported by Robot");
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,10 @@ private static int mouseButtonForKeyCode(int keyCode) {
return MouseEvent.BUTTON_OTHER;
case LinuxInput.BTN_RIGHT:
return MouseEvent.BUTTON_RIGHT;
case LinuxInput.BTN_BACK:
return MouseEvent.BUTTON_BACK;
case LinuxInput.BTN_FORWARD:
return MouseEvent.BUTTON_FORWARD;
default:
return -1;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,20 @@ private static MouseState convertToMouseState(boolean press, MouseState state, M
state.releaseButton(MouseEvent.BUTTON_OTHER);
}
break;
case BACK:
if (press) {
state.pressButton(MouseEvent.BUTTON_BACK);
} else {
state.releaseButton(MouseEvent.BUTTON_BACK);
}
break;
case FORWARD:
if (press) {
state.pressButton(MouseEvent.BUTTON_FORWARD);
} else {
state.releaseButton(MouseEvent.BUTTON_FORWARD);
}
break;
default: throw new IllegalArgumentException("MouseButton: " + button +
" not supported by Monocle Robot");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,12 @@ int getModifiers() {
case MouseEvent.BUTTON_RIGHT:
modifiers |= KeyEvent.MODIFIER_BUTTON_SECONDARY;
break;
case MouseEvent.BUTTON_BACK:
modifiers |= KeyEvent.MODIFIER_BUTTON_BACK;
break;
case MouseEvent.BUTTON_FORWARD:
modifiers |= KeyEvent.MODIFIER_BUTTON_FORWARD;
break;
}
}
return modifiers;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,7 @@ public void run() {
final MouseState state = new MouseState();
state.setX(x);
state.setY(y);
// These values are from RFC 6143 Section 7.5.5.
if (buttons.get(0)) {
state.pressButton(MouseEvent.BUTTON_LEFT);
}
Expand All @@ -284,6 +285,20 @@ public void run() {
if (buttons.get(2)) {
state.pressButton(MouseEvent.BUTTON_RIGHT);
}
if (buttons.get(3)) {
state.setWheel(MouseState.WHEEL_UP);
}
if (buttons.get(4)) {
state.setWheel(MouseState.WHEEL_DOWN);
}
// TODO: Buttons from here on are not officially mentioned in the docs, can someone confirm
// on a real device?
if (buttons.get(5)) {
state.pressButton(MouseEvent.BUTTON_BACK);
}
if (buttons.get(6)) {
state.pressButton(MouseEvent.BUTTON_FORWARD);
}
Platform.runLater(() -> MouseInput.getInstance().setState(state, false));
break;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,10 @@ private static void checkPermissions() {
static final int Button3 = 3;
static final int Button4 = 4;
static final int Button5 = 5;
// 4th button (aka browser backward button).
static final int Button8 = 8;
// 5th button (aka browser forward button).
static final int Button9 = 9;

static final long _NET_WM_STATE_REMOVE = 0;
static final long _NET_WM_STATE_ADD = 1;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,8 @@ private static int buttonToGlassButton(int button) {
case X.Button1: return MouseEvent.BUTTON_LEFT;
case X.Button2: return MouseEvent.BUTTON_OTHER;
case X.Button3: return MouseEvent.BUTTON_RIGHT;
case X.Button8: return MouseEvent.BUTTON_BACK;
case X.Button9: return MouseEvent.BUTTON_FORWARD;
default: return MouseEvent.BUTTON_NONE;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ public class AbstractEvents {
public final static int MOUSEEVENT_PRIMARY_BUTTON = 1;
public final static int MOUSEEVENT_SECONDARY_BUTTON = 2;
public final static int MOUSEEVENT_MIDDLE_BUTTON = 4;
public final static int MOUSEEVENT_BACK_BUTTON = 8;
public final static int MOUSEEVENT_FORWARD_BUTTON = 16;

public final static int KEYEVENT_PRESSED = 0;
public final static int KEYEVENT_RELEASED = 1;
Expand Down Expand Up @@ -118,6 +120,10 @@ public static MouseButton mouseButtonToFXMouseButton(int embedButton) {
return MouseButton.SECONDARY;
case MOUSEEVENT_MIDDLE_BUTTON:
return MouseButton.MIDDLE;
case MOUSEEVENT_BACK_BUTTON:
return MouseButton.BACK;
case MOUSEEVENT_FORWARD_BUTTON:
return MouseButton.FORWARD;
}
// Should never reach here
return MouseButton.NONE;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ public interface EmbeddedSceneInterface {
*/
public void mouseEvent(int type, int button,
boolean primaryBtnDown, boolean middleBtnDown, boolean secondaryBtnDown,
boolean backBtnDown, boolean forwardBtnDown,
int x, int y, int xAbs, int yAbs,
boolean shift, boolean ctrl, boolean alt, boolean meta,
boolean popupTrigger);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,8 @@ public interface TKSceneListener {
public void mouseEvent(EventType<MouseEvent> type, double x, double y, double screenX, double screenY,
MouseButton button, boolean popupTrigger, boolean synthesized,
boolean shiftDown, boolean controlDown, boolean altDown, boolean metaDown,
boolean primaryDown, boolean middleDown, boolean secondaryDown);
boolean primaryDown, boolean middleDown, boolean secondaryDown,
boolean backDown, boolean forwardDown);

/**
* Pass a key event to the scene to handle
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,7 @@ protected Color getClearColor() {
@Override
public void mouseEvent(final int type, final int button,
final boolean primaryBtnDown, final boolean middleBtnDown, final boolean secondaryBtnDown,
final boolean backBtnDown, final boolean forwardBtnDown,
final int x, final int y, final int xAbs, final int yAbs,
final boolean shift, final boolean ctrl, final boolean alt, final boolean meta,
final boolean popupTrigger)
Expand All @@ -287,7 +288,9 @@ public void mouseEvent(final int type, final int button,
AbstractEvents.mouseButtonToFXMouseButton(button),
popupTrigger, false, // do we know if it's synthesized? RT-20142
shift, ctrl, alt, meta,
primaryBtnDown, middleBtnDown, secondaryBtnDown);
primaryBtnDown, middleBtnDown, secondaryBtnDown,
backBtnDown, forwardBtnDown
);
return null;
}, getAccessControlContext());
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,10 @@ public static String getMouseEventString(int type) {
return "BUTTON_RIGHT";
case MouseEvent.BUTTON_OTHER:
return "BUTTON_OTHER";
case MouseEvent.BUTTON_BACK:
return "BUTTON_BACK";
case MouseEvent.BUTTON_FORWARD:
return "BUTTON_FORWARD";
case MouseEvent.DOWN:
return "DOWN";
case MouseEvent.UP:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,10 @@ private static MouseButton mouseEventButton(int glassButton) {
return MouseButton.SECONDARY;
case com.sun.glass.events.MouseEvent.BUTTON_OTHER:
return MouseButton.MIDDLE;
case com.sun.glass.events.MouseEvent.BUTTON_BACK:
return MouseButton.BACK;
case com.sun.glass.events.MouseEvent.BUTTON_FORWARD:
return MouseButton.FORWARD;
default:
return MouseButton.NONE;
}
Expand Down Expand Up @@ -319,6 +323,12 @@ public Void run() {
case MouseEvent.BUTTON_RIGHT:
buttonMask = KeyEvent.MODIFIER_BUTTON_SECONDARY;
break;
case MouseEvent.BUTTON_BACK:
buttonMask = KeyEvent.MODIFIER_BUTTON_BACK;
break;
case MouseEvent.BUTTON_FORWARD:
buttonMask = KeyEvent.MODIFIER_BUTTON_FORWARD;
break;
default:
buttonMask = 0;
break;
Expand Down Expand Up @@ -375,6 +385,8 @@ public Void run() {
boolean primaryButtonDown = (modifiers & KeyEvent.MODIFIER_BUTTON_PRIMARY) != 0;
boolean middleButtonDown = (modifiers & KeyEvent.MODIFIER_BUTTON_MIDDLE) != 0;
boolean secondaryButtonDown = (modifiers & KeyEvent.MODIFIER_BUTTON_SECONDARY) != 0;
boolean backButtonDown = (modifiers & KeyEvent.MODIFIER_BUTTON_BACK) != 0;
boolean forwardButtonDown = (modifiers & KeyEvent.MODIFIER_BUTTON_FORWARD) != 0;
final Window w = view.getWindow();
double pScaleX, pScaleY, spx, spy, sx, sy;
if (w != null) {
Expand All @@ -399,7 +411,8 @@ public Void run() {
sx + (xAbs - spx) / pScaleX, sy + (yAbs - spy) / pScaleY,
mouseEventButton(button), isPopupTrigger, isSynthesized,
shiftDown, controlDown, altDown, metaDown,
primaryButtonDown, middleButtonDown, secondaryButtonDown);
primaryButtonDown, middleButtonDown, secondaryButtonDown,
backButtonDown, forwardButtonDown);
}
} finally {
if (stage != null) {
Expand Down
22 changes: 17 additions & 5 deletions modules/javafx.graphics/src/main/java/javafx/scene/Scene.java
Original file line number Diff line number Diff line change
Expand Up @@ -2579,12 +2579,14 @@ public void changedSize(float w, float h) {
public void mouseEvent(EventType<MouseEvent> type, double x, double y, double screenX, double screenY,
MouseButton button, boolean popupTrigger, boolean synthesized,
boolean shiftDown, boolean controlDown, boolean altDown, boolean metaDown,
boolean primaryDown, boolean middleDown, boolean secondaryDown)
boolean primaryDown, boolean middleDown, boolean secondaryDown,
boolean backDown, boolean forwardDown)
{
MouseEvent mouseEvent = new MouseEvent(type, x, y, screenX, screenY, button,
0, // click count will be adjusted by clickGenerator later anyway
shiftDown, controlDown, altDown, metaDown,
primaryDown, middleDown, secondaryDown, synthesized, popupTrigger, false, null);
primaryDown, middleDown, secondaryDown, backDown, forwardDown,
synthesized, popupTrigger, false, null);
processMouseEvent(mouseEvent);
}

Expand Down Expand Up @@ -3518,7 +3520,8 @@ private MouseEvent preProcess(MouseEvent e) {
if (! e.isPrimaryButtonDown()) { counters.get(MouseButton.PRIMARY).clear(); }
if (! e.isSecondaryButtonDown()) { counters.get(MouseButton.SECONDARY).clear(); }
if (! e.isMiddleButtonDown()) { counters.get(MouseButton.MIDDLE).clear(); }

if (! e.isBackButtonDown()) { counters.get(MouseButton.BACK).clear(); }
if (! e.isForwardButtonDown()) { counters.get(MouseButton.FORWARD).clear(); }
cc.applyOut();
cc.inc();
cc.start(e.getSceneX(), e.getSceneY());
Expand All @@ -3530,6 +3533,7 @@ private MouseEvent preProcess(MouseEvent e) {
cc != null && e.getEventType() != MouseEvent.MOUSE_MOVED ? cc.get() : 0,
e.isShiftDown(), e.isControlDown(), e.isAltDown(), e.isMetaDown(),
e.isPrimaryButtonDown(), e.isMiddleButtonDown(), e.isSecondaryButtonDown(),
e.isBackButtonDown(), e.isForwardButtonDown(),
e.isSynthesized(), e.isPopupTrigger(), still, e.getPickResult());
}

Expand Down Expand Up @@ -3560,6 +3564,7 @@ private void postProcess(MouseEvent e, TargetWrapper target, TargetWrapper picke
cc.get(),
e.isShiftDown(), e.isControlDown(), e.isAltDown(), e.isMetaDown(),
e.isPrimaryButtonDown(), e.isMiddleButtonDown(), e.isSecondaryButtonDown(),
e.isBackButtonDown(), e.isForwardButtonDown(),
e.isSynthesized(), e.isPopupTrigger(), lastPress.isStill(), e.getPickResult());
Event.fireEvent(clickedTarget, click);
}
Expand Down Expand Up @@ -3588,6 +3593,8 @@ class MouseHandler {
private boolean primaryButtonDown = false;
private boolean secondaryButtonDown = false;
private boolean middleButtonDown = false;
private boolean backButtonDown = false;
private boolean forwardButtonDown = false;

private EventTarget fullPDRSource = null;
private TargetWrapper fullPDRTmpTargetWrapper = new TargetWrapper();
Expand Down Expand Up @@ -3780,7 +3787,8 @@ private void process(MouseEvent e, boolean onPulse) {
boolean gestureStarted = false;
if (!onPulse) {
if (e.getEventType() == MouseEvent.MOUSE_PRESSED) {
if (!(primaryButtonDown || secondaryButtonDown || middleButtonDown)) {
if (!(primaryButtonDown || secondaryButtonDown || middleButtonDown ||
backButtonDown || forwardButtonDown)) {
//old gesture ended and new one started
gestureStarted = true;
if (!PLATFORM_DRAG_GESTURE_INITIATION) {
Expand All @@ -3800,6 +3808,8 @@ private void process(MouseEvent e, boolean onPulse) {
primaryButtonDown = e.isPrimaryButtonDown();
secondaryButtonDown = e.isSecondaryButtonDown();
middleButtonDown = e.isMiddleButtonDown();
backButtonDown = e.isBackButtonDown();
forwardButtonDown = e.isForwardButtonDown();
}

pick(tmpTargetWrapper, e.getSceneX(), e.getSceneY());
Expand All @@ -3809,6 +3819,7 @@ private void process(MouseEvent e, boolean onPulse) {
e.getScreenX(), e.getScreenY(), e.getButton(), e.getClickCount(),
e.isShiftDown(), e.isControlDown(), e.isAltDown(), e.isMetaDown(),
e.isPrimaryButtonDown(), e.isMiddleButtonDown(), e.isSecondaryButtonDown(),
e.isBackButtonDown(), e.isForwardButtonDown(),
e.isSynthesized(), e.isPopupTrigger(), e.isStillSincePress(), res);
}

Expand Down Expand Up @@ -3885,7 +3896,8 @@ private void process(MouseEvent e, boolean onPulse) {
}

if (pdrInProgress &&
!(primaryButtonDown || secondaryButtonDown || middleButtonDown)) {
!(primaryButtonDown || secondaryButtonDown || middleButtonDown ||
backButtonDown || forwardButtonDown)) {
clearPDREventTargets();
exitFullPDR(e);
// we need to do new picking in case the originally picked node
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,21 @@ public enum MouseButton {
MIDDLE,

/**
* Represents seconday (button 3, usually the right) mouse button.
* Represents secondary (button 3, usually the right) mouse button.
*/
SECONDARY,

/**
* Represents back (button 4) mouse button.
*
* @since 12
*/
BACK,

/**
* Represents forward (button 5) mouse button.
*
* @since 12
*/
FORWARD,
}
Loading

0 comments on commit b6270b4

Please sign in to comment.