On Mon, 17 Jul 2023 19:09:29 GMT, Harshitha Onkar <hon...@openjdk.org> wrote:
>> **Problem:** >> >> On macOS, Robot erroneously produces lowercase letter when mouse is moved >> (manually) in unison with Robot's keyEvents. This issue was originally >> logged by a developer of an on-screen accessibility keyboard - TouchBoard. >> Originally reported at >> https://github.com/adoptium/adoptium-support/issues/710 >> >> This issue is reproducible on JDK versions 22 to 11, but works fine on >> JDK-8. (details below) >> >> This issue is not restricted to the Shift modifier key and causes problems >> with other modifier keys as well and in some scenarios without any external >> mouse movement. >> >> - This works correctly on JDK-8 up to JDK-9+129 when Accessibility APIs >> (AXUIElementCreateSystemWide/ AXUIElementPostKeyboardEvent) were used. Later >> on it was changed to CGEvents. >> >> - With the present code, the issue occurs at >> [CRobot.m#L295](https://github.com/openjdk/jdk/blob/ac6af6a64099c182e982a0a718bc1b780cef616e/src/java.desktop/macosx/native/libawt_lwawt/awt/CRobot.m#L295.) >> The flags gets reset or cleared when mouse is moved physically in unison >> with Robot's key events. >> >> - The physical mouse movement causes the event flags to be reset. >> >> **Impact:** >> >> Modifier keys don't work as expected when using Robot with any simultaneous >> physical mouse movement and in case of TouchBoard, this behavior breaks the >> usability of the on-screen a11y keyboard. There is no known workaround for >> this particular use case except for reverting to JDK-8. More details on this >> use case >> [here.](https://github.com/adoptium/adoptium-support/issues/710#issuecomment-1594103280) >> >> **Proposed Fix:** >> >> - In order to avoid resetting of the CGEventFlags here >> [CRobot.m#L295](https://github.com/openjdk/jdk/blob/ac6af6a64099c182e982a0a718bc1b780cef616e/src/java.desktop/macosx/native/libawt_lwawt/awt/CRobot.m#L295.), >> the CGEvent flag state is obtained in `initRobot` (stored in initFlags) >> which is later used within `CRobot_keyEvent`. >> >> - The incoming keyCode is used to determine whether it is a modifier key and >> the corresponding modifierFlagMask is either added or cleared from the >> initFlags based on whether the modifier key was pressed or released. >> >> - Finally, only the required and known flag bits from initFlag are copied >> over to local flag which is used in `CGEventSetFlags()`. >> >> **Testing:** >> >> The newly added test - RobotModifierMaskTest.java tests for Shift, Caps, >> Control, Option and Command keys. >> The test runs in 2 modes - as automated and manual test. >> >> CASE 1 : ... > > Harshitha Onkar has updated the pull request incrementally with one > additional commit since the last revision: > > test changes: added CountDownLatch @mrserb > Just to clarify an idea of this change. We would like to maintain the "flag" > keys pressed by the user and maintain the list of current flags. So if the > user will press SHIFT key, we will use that modifier for all next keys until > shift will be released. That is correct. > It looks similar to how the mouseMove is implemented in CRobot, where we > maintain the mouseLastX/mouseLastY, and we ignore the current location of the > mouse for clicks, but use the latest saved value. > Probably we can do the same on the java side in this patch? it will simplify > the native code a bit. Yes, the code for mouseEvent looks similar to what we are trying to achieve for keyEvent but there are a few differences too- - `mouseEvent(int lastX, int lastY, int buttonsState, boolean isButtonsDownState, boolean isMouseMove)`, lastX & lastY are already part of the parameters being sent from Java to native side. - `keyEvent(int javaKeyCode, boolean keydown)` - Are you suggesting that a modifier flag state be sent from Java to native side? This would involve changing the present native `keyEvent` signature and adding code to native side to evaluate the new modifier flag state from Java and then map it to the corresponding [kCGEventFlagMask](https://developer.apple.com/documentation/coregraphics/cgeventflags/kcgeventflagmaskalphashift?language=objc). Having everything on native side seems to be easier because with the present fix, the equivalent modifier flag mask is obtained using javaKeyCode + key state and a quick `NSDictionary modifierKeyToMaskMap` lookup without the need of adding or changing keyEvent signature. > BTW do we need to set all this modifiers for the mouse clicks as well? I don't think so as the issue (details below) occurs only when flagState is obtained using - `CGEventSourceFlagsState(kCGEventSourceStateHIDSystemState)` which was the case for keyEvents. **Issue:** _With the present code, the issue occurs at [CRobot.m#L295](https://github.com/openjdk/jdk/blob/ac6af6a64099c182e982a0a718bc1b780cef616e/src/java.desktop/macosx/native/libawt_lwawt/awt/CRobot.m#L295.) The flags gets reset or cleared when mouse is moved physically in unison with Robot's key events. The physical mouse movement causes the event flags to be reset._ ------------- PR Comment: https://git.openjdk.org/jdk/pull/14744#issuecomment-1639050801