-
Notifications
You must be signed in to change notification settings - Fork 6.1k
8294426: Two fingers tap generates wrong mouse modifiers on M2 MacBooks #10429
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
8294426: Two fingers tap generates wrong mouse modifiers on M2 MacBooks #10429
Conversation
👋 Welcome back NikitkoCent! A progress list of the required criteria for merging this PR into |
@NikitkoCent The following label will be automatically applied to this pull request:
When this pull request is ready to be reviewed, an "RFR" email will be sent to the corresponding mailing list. If you would like to change these labels, use the /label pull request command. |
I filed https://bugs.openjdk.org/browse/JDK-8294426 for this issue. |
Set missed mouse modifiers manually.
db07511
to
bacac5f
Compare
@@ -79,6 +79,14 @@ void handleMouseEvent(int eventType, int modifierFlags, int buttonNumber, | |||
} | |||
|
|||
int jmodifiers = NSEvent.nsToJavaModifiers(modifierFlags); | |||
if ((jeventType == MouseEvent.MOUSE_PRESSED) && (jbuttonNumber > MouseEvent.NOBUTTON)) { | |||
// 8294426: NSEvent.nsToJavaModifiers returns 0 on M2 MacBooks if the event is generated |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You say it returns 0, so you expect to only need to do that if jmodifiers is 0, yet you don't check that.
Why not ?
No way to test this on an M2 so being sure it doesn't regress something is all I can offer here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually I mean that it returns 0 if you're tapping without holding any modifiers e.g. keyboard modifiers.
But if you're tapping holding a keyboard modifier it will probably return only this keyboard modifier without InputEvent.BUTTON3_DOWN_MASK
. I didn't test this case but I would expect it that looking at the implementation of the NSEvent.nsToJavaModifiers
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't have an M2 device to check, but I think (judging to the code) if we add jmodifiers == 0
check here then users making a tap holding the Control will receive the mouse events with modifiers
== CTRL_DOWN_MASK | BUTTON3_MASK | CTRL_MASK
, i.e. without modern BUTTON3_DOWN_MASK
which is at least unusual and inconvenient.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK .. well I've at least run all our automated tests and no regressions were found, so I'll approve this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've checked behavior of tap holding modifiers on M2 and here are which mouse events are received:
- Ctrl + Two fingers tap:
- event:
java.awt.event.MouseEvent[MOUSE_PRESSED,(86,102),absolute(86,302),button=3,modifiers=⌘+⌃+Button3,extModifiers=⌃,clickCount=1] on MouseWindow$1[,0,136,200x200,layout=java.awt.FlowLayout,alignmentX=0.0,alignmentY=0.0,border=,flags=16777225,maximumSize=,minimumSize=,preferredSize=]
- modifiers: 6 (
⌘+⌃+Button3
) - modifiersEx: 128 (
⌃
)
- event:
- Option + Two fingers tap:
- event:
java.awt.event.MouseEvent[MOUSE_PRESSED,(63,135),absolute(63,335),button=3,modifiers=⌥+⌘+Button2+Button3,extModifiers=⌥,clickCount=1] on MouseWindow$1[,0,136,200x200,layout=java.awt.FlowLayout,alignmentX=0.0,alignmentY=0.0,border=,flags=16777225,maximumSize=,minimumSize=,preferredSize=]
- modifiers: 12 (
⌥+⌘+Button2+Button3
) - modifiersEx: 512 (
⌥
)
- event:
Thus, as I assumed, modifiersEx don't contain BUTTON3_DOWN_MASK
, so we shouldn't restrict the patch by the jmodifiers == 0
condition.
@NikitkoCent This change now passes all automated pre-integration checks. ℹ️ This project also has non-automated pre-integration requirements. Please see the file CONTRIBUTING.md for details. After integration, the commit message for the final commit will be:
You can use pull request commands such as /summary, /contributor and /issue to adjust it as needed. At the time when this comment was updated there had been 254 new commits pushed to the
As there are no conflicts, your changes will automatically be rebased on top of these commits when integrating. If you prefer to avoid this automatic rebasing, please check the documentation for the /integrate command for further details. As you do not have Committer status in this project an existing Committer must agree to sponsor your change. Possible candidates are the reviewers of this PR (@prrace) but any other Committer may sponsor as well. ➡️ To flag this PR as ready for integration with the above commit message, type |
/integrate |
@NikitkoCent |
/sponsor |
Going to push as commit 2da079c.
Your commit was automatically rebased without conflicts. |
@avu @NikitkoCent Pushed as commit 2da079c. 💡 You may see a message that your pull request was closed with unmerged commits. This can be safely ignored. |
Can we report this behaviour change to Apple for investigation? |
/backport jdk17u-dev |
@NikitkoCent To use the |
I think this is our problem here - we ask for the currently pressed modifiers only after the event has happened (and dispatched to us), so there is no guarantee that a user doesn't manage to release the mouse button before the press event is dispatched to us. Do you agree? |
Hi there!
JetBrains has faced with a bug on Apple M2 MacBooks when tapping (not pressing) with two fingers on a trackpad generates wrong mouse modifiers (which are returned by MouseEvent.getModifiersEx).
As far as I see, OpenJDK bug tracker still doesn't contain such a bug and I don't have rights to create a new one, so the PR doesn't refer any idUPD: fixed. Here is the bug link from the JetBrains own tracker: JBR-4765.The bug is 100% reproducible on M2 MacBooks (at least under macOS 12.5). It's also reproducible on M1 MacBooks, but much more rarely (about 10-15% of reproducibility).
Steps to reproduce
System Preferences
->Trackpad
->Tap to click
Expected
Printed mouse event has
modifiersEx
is4096
(which isInputEvent.BUTTON3_DOWN_MASK
)Actual
Printed mouse event has
modifiersEx
is4352
(which isInputEvent.BUTTON3_DOWN_MASK | InputEvent.META_DOWN_MASK
)Evaluation
The following happens when a native mouse event reaches Java:
NSEvent.nsToJavaModifiers(0)
called inside CPlatformResponder.handleMouseEvent():81 returns0
. Earlier it always returned4096
(InputEvent.BUTTON3_DOWN_MASK
) but not in the cases of M2 tapping. For a trackpad press (not a tap) it still returns4096
;0
modifier comes into MouseEvent constructor which then goes into MouseEvent.setOldModifiers() which initializes the field MouseEvent.modifiers to the value 4 (it'sInputEvent.BUTTON3_MASK
);MouseEvent
object is pushed into EDT queue.java.awt.LightweightDispatcher.retargetMouseEvent
and creates a new MouseEvent based on the pulled one with the new value of the modifiers ==getModifiersEx() | getModifiers()
. From the p.2 we know, thatMouseEvent.modifiers
of the pulled event is4
, sogetModifiersEx() | getModifiers()
is evaluated to4
.setOldModifiers
as in p.2) and initializes its own field modifiers to the value4356
(InputEvent.BUTTON3_MASK | InputEvent.BUTTON3_DOWN_MASK | InputEvent.META_DOWN_MASK
, see setNewModifiers():1099, setNewModifiers():1129).getModifiers()
==4
andgetModifiersEx()
==4352
so it thinks there is aCommand
keystroke.Fixing
Let's set manually inside
CPlatformResponder.handleMouseEvent
a mouse modifier which corresponds to the pressed button.What about a regression test
I've failed to write a regression test using Robot because it somehow forces the correct mouse modifiers (
NSEvent.nsToJavaModifiers()
correctly returnsInputEvent.BUTTON3_DOWN_MASK
), so I wrote a test that directly invokesCPlatformResponder.handleMouseEvent
via reflection.Progress
Issue
Reviewers
Reviewing
Using
git
Checkout this PR locally:
$ git fetch https://git.openjdk.org/jdk pull/10429/head:pull/10429
$ git checkout pull/10429
Update a local copy of the PR:
$ git checkout pull/10429
$ git pull https://git.openjdk.org/jdk pull/10429/head
Using Skara CLI tools
Checkout this PR locally:
$ git pr checkout 10429
View PR using the GUI difftool:
$ git pr show -t 10429
Using diff file
Download this PR as a diff file:
https://git.openjdk.org/jdk/pull/10429.diff