From eb64449f9b7bfaf7d566c432360ddf97aabc171c Mon Sep 17 00:00:00 2001 From: Jakub Valtar Date: Sun, 7 Oct 2018 21:55:14 +0200 Subject: [PATCH 1/2] Make sure Ctrl+Left Mouse on MacOS is consistent Make sure PRESS, DRAG and RELEASE report the same mouse button on MacOS. - If CTRL was pressed during Left PRESS, report Right Button until the button is released, regardless of whether CTRL is still down. - If CTRL was not pressed during Left PRESS, report Left Button until the button is released, regardless of CTRL state. Fixes #5672 --- core/src/processing/awt/PSurfaceAWT.java | 19 ++++++++++++--- core/src/processing/javafx/PSurfaceFX.java | 25 ++++++++++++++++---- core/src/processing/opengl/PSurfaceJOGL.java | 21 +++++++++++++--- 3 files changed, 55 insertions(+), 10 deletions(-) diff --git a/core/src/processing/awt/PSurfaceAWT.java b/core/src/processing/awt/PSurfaceAWT.java index 4cf50e87f..2c56d2546 100644 --- a/core/src/processing/awt/PSurfaceAWT.java +++ b/core/src/processing/awt/PSurfaceAWT.java @@ -1231,6 +1231,14 @@ public class PSurfaceAWT extends PSurfaceNone { */ + // MACOSX: CTRL + Left Mouse is converted to Right Mouse. This boolean keeps + // track of whether the conversion happened on PRESS, because we should report + // the same button during DRAG and on RELEASE, even though CTRL might have + // been released already. Otherwise the events are inconsistent, e.g. + // Left Pressed - Left Drag - CTRL Pressed - Right Drag - Right Released. + // See: https://github.com/processing/processing/issues/5672 + private boolean macosxLeftButtonWithCtrlPressed; + /** * Figure out how to process a mouse event. When loop() has been * called, the events will be queued up until drawing is complete. @@ -1319,11 +1327,16 @@ public class PSurfaceAWT extends PSurfaceNone { // If running on Mac OS, allow ctrl-click as right mouse. Prior to 0215, // this used isPopupTrigger() on the native event, but that doesn't work // for mouseClicked and mouseReleased (or others). - if (PApplet.platform == PConstants.MACOSX) { - //if (nativeEvent.isPopupTrigger()) { - if ((modifiers & InputEvent.CTRL_MASK) != 0) { + if (/*PApplet.platform == PConstants.MACOSX &&*/ peButton == PConstants.LEFT) { + if (peAction == MouseEvent.PRESS && (modifiers & InputEvent.CTRL_MASK) != 0) { + macosxLeftButtonWithCtrlPressed = true; + } + if (macosxLeftButtonWithCtrlPressed) { peButton = PConstants.RIGHT; } + if (peAction == MouseEvent.RELEASE) { + macosxLeftButtonWithCtrlPressed = false; + } } sketch.postEvent(new MouseEvent(nativeEvent, nativeEvent.getWhen(), diff --git a/core/src/processing/javafx/PSurfaceFX.java b/core/src/processing/javafx/PSurfaceFX.java index e9f8243d7..acd80abf5 100644 --- a/core/src/processing/javafx/PSurfaceFX.java +++ b/core/src/processing/javafx/PSurfaceFX.java @@ -27,6 +27,7 @@ import com.sun.glass.ui.Screen; import java.awt.GraphicsDevice; import java.awt.GraphicsEnvironment; import java.awt.Rectangle; +import java.awt.event.InputEvent; import java.net.URL; import java.util.ArrayList; import java.util.HashMap; @@ -823,6 +824,16 @@ public class PSurfaceFX implements PSurface { mouseMap.put(MouseEvent.MOUSE_EXITED, processing.event.MouseEvent.EXIT); } + + // MACOSX: CTRL + Left Mouse is converted to Right Mouse. This boolean keeps + // track of whether the conversion happened on PRESS, because we should report + // the same button during DRAG and on RELEASE, even though CTRL might have + // been released already. Otherwise the events are inconsistent, e.g. + // Left Pressed - Left Drag - CTRL Pressed - Right Drag - Right Released. + // See: https://github.com/processing/processing/issues/5672 + private boolean macosxLeftButtonWithCtrlPressed; + + protected void fxMouseEvent(MouseEvent fxEvent) { // the 'amount' is the number of button clicks for a click event, // or the number of steps/clicks on the wheel for a mouse wheel event. @@ -862,10 +873,16 @@ public class PSurfaceFX implements PSurface { // If running on Mac OS, allow ctrl-click as right mouse. // Verified to be necessary with Java 8u45. - if (PApplet.platform == PConstants.MACOSX && - fxEvent.isControlDown() && - button == PConstants.LEFT) { - button = PConstants.RIGHT; + if (PApplet.platform == PConstants.MACOSX && button == PConstants.LEFT) { + if (action == processing.event.MouseEvent.PRESS && fxEvent.isControlDown()) { + macosxLeftButtonWithCtrlPressed = true; + } + if (macosxLeftButtonWithCtrlPressed) { + button = PConstants.RIGHT; + } + if (action == processing.event.MouseEvent.RELEASE) { + macosxLeftButtonWithCtrlPressed = false; + } } //long when = nativeEvent.getWhen(); // from AWT diff --git a/core/src/processing/opengl/PSurfaceJOGL.java b/core/src/processing/opengl/PSurfaceJOGL.java index 17d2d916e..1526047d0 100644 --- a/core/src/processing/opengl/PSurfaceJOGL.java +++ b/core/src/processing/opengl/PSurfaceJOGL.java @@ -1011,6 +1011,15 @@ public class PSurfaceJOGL implements PSurface { } + // MACOSX: CTRL + Left Mouse is converted to Right Mouse. This boolean keeps + // track of whether the conversion happened on PRESS, because we should report + // the same button during DRAG and on RELEASE, even though CTRL might have + // been released already. Otherwise the events are inconsistent, e.g. + // Left Pressed - Left Drag - CTRL Pressed - Right Drag - Right Released. + // See: https://github.com/processing/processing/issues/5672 + private boolean macosxLeftButtonWithCtrlPressed; + + protected void nativeMouseEvent(com.jogamp.newt.event.MouseEvent nativeEvent, int peAction) { int modifiers = nativeEvent.getModifiers(); @@ -1033,11 +1042,17 @@ public class PSurfaceJOGL implements PSurface { break; } - if (PApplet.platform == PConstants.MACOSX) { - //if (nativeEvent.isPopupTrigger()) { - if ((modifiers & InputEvent.CTRL_MASK) != 0) { + // If running on Mac OS, allow ctrl-click as right mouse. + if (PApplet.platform == PConstants.MACOSX && peButton == PConstants.LEFT) { + if (peAction == MouseEvent.PRESS && (modifiers & InputEvent.CTRL_MASK) != 0) { + macosxLeftButtonWithCtrlPressed = true; + } + if (macosxLeftButtonWithCtrlPressed) { peButton = PConstants.RIGHT; } + if (peAction == MouseEvent.RELEASE) { + macosxLeftButtonWithCtrlPressed = false; + } } int peCount = 0; From d512d21fcf329b3b7c199f5582744a12a4a378d3 Mon Sep 17 00:00:00 2001 From: Jakub Valtar Date: Tue, 9 Oct 2018 09:19:36 +0200 Subject: [PATCH 2/2] Move Ctrl+Left Mouse code from surfaces to PApplet --- core/src/processing/awt/PSurfaceAWT.java | 23 ---------------- core/src/processing/core/PApplet.java | 29 +++++++++++++++++++- core/src/processing/javafx/PSurfaceFX.java | 25 ----------------- core/src/processing/opengl/PSurfaceJOGL.java | 22 --------------- 4 files changed, 28 insertions(+), 71 deletions(-) diff --git a/core/src/processing/awt/PSurfaceAWT.java b/core/src/processing/awt/PSurfaceAWT.java index 2c56d2546..71a59e87f 100644 --- a/core/src/processing/awt/PSurfaceAWT.java +++ b/core/src/processing/awt/PSurfaceAWT.java @@ -1231,14 +1231,6 @@ public class PSurfaceAWT extends PSurfaceNone { */ - // MACOSX: CTRL + Left Mouse is converted to Right Mouse. This boolean keeps - // track of whether the conversion happened on PRESS, because we should report - // the same button during DRAG and on RELEASE, even though CTRL might have - // been released already. Otherwise the events are inconsistent, e.g. - // Left Pressed - Left Drag - CTRL Pressed - Right Drag - Right Released. - // See: https://github.com/processing/processing/issues/5672 - private boolean macosxLeftButtonWithCtrlPressed; - /** * Figure out how to process a mouse event. When loop() has been * called, the events will be queued up until drawing is complete. @@ -1324,21 +1316,6 @@ public class PSurfaceAWT extends PSurfaceNone { peButton = PConstants.RIGHT; } - // If running on Mac OS, allow ctrl-click as right mouse. Prior to 0215, - // this used isPopupTrigger() on the native event, but that doesn't work - // for mouseClicked and mouseReleased (or others). - if (/*PApplet.platform == PConstants.MACOSX &&*/ peButton == PConstants.LEFT) { - if (peAction == MouseEvent.PRESS && (modifiers & InputEvent.CTRL_MASK) != 0) { - macosxLeftButtonWithCtrlPressed = true; - } - if (macosxLeftButtonWithCtrlPressed) { - peButton = PConstants.RIGHT; - } - if (peAction == MouseEvent.RELEASE) { - macosxLeftButtonWithCtrlPressed = false; - } - } - sketch.postEvent(new MouseEvent(nativeEvent, nativeEvent.getWhen(), peAction, peModifiers, nativeEvent.getX() / windowScaleFactor, diff --git a/core/src/processing/core/PApplet.java b/core/src/processing/core/PApplet.java index 457b50ea4..85f0fb81a 100644 --- a/core/src/processing/core/PApplet.java +++ b/core/src/processing/core/PApplet.java @@ -561,6 +561,14 @@ public class PApplet implements PConstants { */ public boolean mousePressed; + // MACOSX: CTRL + Left Mouse is converted to Right Mouse. This boolean keeps + // track of whether the conversion happened on PRESS, because we should report + // the same button during DRAG and on RELEASE, even though CTRL might have + // been released already. Otherwise the events are inconsistent, e.g. + // Left Pressed - Left Drag - CTRL Pressed - Right Drag - Right Released. + // See: https://github.com/processing/processing/issues/5672 + private boolean macosxLeftButtonWithCtrlPressed; + /** @deprecated Use a mouse event handler that passes an event instead. */ @Deprecated @@ -2650,8 +2658,27 @@ public class PApplet implements PConstants { mouseY = event.getY(); } + int button = event.getButton(); + + // If running on Mac OS, allow ctrl-click as right mouse. + if (PApplet.platform == PConstants.MACOSX && event.getButton() == PConstants.LEFT) { + if (action == MouseEvent.PRESS && event.isControlDown()) { + macosxLeftButtonWithCtrlPressed = true; + } + if (macosxLeftButtonWithCtrlPressed) { + button = PConstants.RIGHT; + event = new MouseEvent(event.getNative(), event.getMillis(), + event.getAction(), event.getModifiers(), + event.getX(), event.getY(), + button, event.getCount()); + } + if (button == MouseEvent.RELEASE) { + macosxLeftButtonWithCtrlPressed = false; + } + } + // Get the (already processed) button code - mouseButton = event.getButton(); + mouseButton = button; /* // Compatibility for older code (these have AWT object params, not P5) diff --git a/core/src/processing/javafx/PSurfaceFX.java b/core/src/processing/javafx/PSurfaceFX.java index acd80abf5..4061f36fc 100644 --- a/core/src/processing/javafx/PSurfaceFX.java +++ b/core/src/processing/javafx/PSurfaceFX.java @@ -27,7 +27,6 @@ import com.sun.glass.ui.Screen; import java.awt.GraphicsDevice; import java.awt.GraphicsEnvironment; import java.awt.Rectangle; -import java.awt.event.InputEvent; import java.net.URL; import java.util.ArrayList; import java.util.HashMap; @@ -824,16 +823,6 @@ public class PSurfaceFX implements PSurface { mouseMap.put(MouseEvent.MOUSE_EXITED, processing.event.MouseEvent.EXIT); } - - // MACOSX: CTRL + Left Mouse is converted to Right Mouse. This boolean keeps - // track of whether the conversion happened on PRESS, because we should report - // the same button during DRAG and on RELEASE, even though CTRL might have - // been released already. Otherwise the events are inconsistent, e.g. - // Left Pressed - Left Drag - CTRL Pressed - Right Drag - Right Released. - // See: https://github.com/processing/processing/issues/5672 - private boolean macosxLeftButtonWithCtrlPressed; - - protected void fxMouseEvent(MouseEvent fxEvent) { // the 'amount' is the number of button clicks for a click event, // or the number of steps/clicks on the wheel for a mouse wheel event. @@ -871,20 +860,6 @@ public class PSurfaceFX implements PSurface { break; } - // If running on Mac OS, allow ctrl-click as right mouse. - // Verified to be necessary with Java 8u45. - if (PApplet.platform == PConstants.MACOSX && button == PConstants.LEFT) { - if (action == processing.event.MouseEvent.PRESS && fxEvent.isControlDown()) { - macosxLeftButtonWithCtrlPressed = true; - } - if (macosxLeftButtonWithCtrlPressed) { - button = PConstants.RIGHT; - } - if (action == processing.event.MouseEvent.RELEASE) { - macosxLeftButtonWithCtrlPressed = false; - } - } - //long when = nativeEvent.getWhen(); // from AWT long when = System.currentTimeMillis(); int x = (int) fxEvent.getX(); // getSceneX()? diff --git a/core/src/processing/opengl/PSurfaceJOGL.java b/core/src/processing/opengl/PSurfaceJOGL.java index 1526047d0..a9de3f0b8 100644 --- a/core/src/processing/opengl/PSurfaceJOGL.java +++ b/core/src/processing/opengl/PSurfaceJOGL.java @@ -1011,15 +1011,6 @@ public class PSurfaceJOGL implements PSurface { } - // MACOSX: CTRL + Left Mouse is converted to Right Mouse. This boolean keeps - // track of whether the conversion happened on PRESS, because we should report - // the same button during DRAG and on RELEASE, even though CTRL might have - // been released already. Otherwise the events are inconsistent, e.g. - // Left Pressed - Left Drag - CTRL Pressed - Right Drag - Right Released. - // See: https://github.com/processing/processing/issues/5672 - private boolean macosxLeftButtonWithCtrlPressed; - - protected void nativeMouseEvent(com.jogamp.newt.event.MouseEvent nativeEvent, int peAction) { int modifiers = nativeEvent.getModifiers(); @@ -1042,19 +1033,6 @@ public class PSurfaceJOGL implements PSurface { break; } - // If running on Mac OS, allow ctrl-click as right mouse. - if (PApplet.platform == PConstants.MACOSX && peButton == PConstants.LEFT) { - if (peAction == MouseEvent.PRESS && (modifiers & InputEvent.CTRL_MASK) != 0) { - macosxLeftButtonWithCtrlPressed = true; - } - if (macosxLeftButtonWithCtrlPressed) { - peButton = PConstants.RIGHT; - } - if (peAction == MouseEvent.RELEASE) { - macosxLeftButtonWithCtrlPressed = false; - } - } - int peCount = 0; if (peAction == MouseEvent.WHEEL) { // Invert wheel rotation count so it matches JAVA2D's