On Thu, 4 May 2023 17:18:21 GMT, Martin Fox <d...@openjdk.org> wrote:

> Note: the Java-side changes in this PR are also in #694 which fixes the same 
> issue (and more) on Linux. Unfortunately the Linux Robot code is not working 
> making it difficult to test on that platform (see #718).
> 
> KeyCharacterCombinations allow the specification of accelerators based on 
> characters whose KeyCodes vary across keyboard layouts. For example, the + 
> character is on KeyCode.EQUALS on a U.S. English layout, KeyCode.PLUS on a 
> German layout, and KeyCode.DIGIT1 on a Mac Swiss German layout. 
> KeyCharacterCombinations finds the correct KeyCode by calling 
> `Toolkit.getKeyCodeForChar`.
> 
> `getKeyCodeForChar` can only return one KeyCode for a given character so it 
> can't easily handle characters which appear in more than one location, like + 
> which is on the main keyboard and the numeric keypad. It's also reliant on 
> KeyCodes which prevents KeyCharacterCombinations from working on keys with no 
> codes (e.g. the base character contains a diacritic). It also relies on the 
> platform to map from a character to a key which is the reverse of how key 
> mapping normally works making it slow and/or imprecise to implement on Mac 
> and Linux (Windows is the only platform with a system call to do this).
> 
> This PR introduces a new way for a platform to pass key information to the 
> Java core. `View.notifyKeyEx` takes an additional platform-specific 
> `hardwareCode` which identifies the key and is tracked in a private field in 
> the KeyEvent. This is opt-in; a platform can continue to call the old 
> `View.notifyKey` method and allow the `hardwareCode` to default to -1.
> 
> On the back-end `KeyCharacterCombination.match` calls the new routine 
> `Toolkit.getKeyCanGenerateCharacter` which unpacks the KeyEvent information 
> and sends it on to the Application. This is also opt-in; the default 
> implementation falls back to the Application's `getKeyCodeForChar` call. 
> Platforms which call `View.notifyKeyEx` will be handed the `hardwareCode` for 
> the key in addition to the Java KeyCode.
> 
> The new `View.notifyKeyEx` returns a boolean indicating whether the event was 
> consumed or not. This plays no role here but will be used later to fix 
> [JDK-8087863](https://bugs.openjdk.org/browse/JDK-8087863).
> 
> For testing I've included the manual KeyboardTest app that also appears in PR 
> #425. Tests with keypad combinations should now work.
> 
> Note: this PR only fixes Windows. Fixes for Mac and Linux but can't be 
> submitted until #425 and #718 are integrated.

Not entirely sure it is good to have a hidden variable in `KeyEvent`, but looks 
good other than that.

modules/javafx.graphics/src/main/java/com/sun/glass/ui/win/WinApplication.java 
line 382:

> 380:         // This platform has migrated to getKeyCanGenerateCharacter
> 381:         // so getKeyCodeForChar will no longer be called.
> 382:         return 0;

If you are sure it is never called, then how about going all in and throwing an 
exception here? Currently it just returns an incorrect result.

modules/javafx.graphics/src/main/java/com/sun/javafx/tk/TKSceneListener.java 
line 68:

> 66:      *
> 67:      * @param keyEvent The key event
> 68:      * @return true iff the event was consumed

Suggestion:

     * @return {@code true} if the event was consumed

modules/javafx.graphics/src/main/java/com/sun/javafx/tk/Toolkit.java line 709:

> 707:      * The default implementation bridges into the existing 
> getKeyCodeForChar call.
> 708:      */
> 709:     public boolean getKeyCanGenerateCharacter(KeyEvent event, String 
> character) {

I think this method can be narrowed a bit to accept a `KeyCode` instead of 
`KeyEvent`, making it bit more generally useful (and easier to test).  Also I 
think perhaps it can be named a bit more direct, like `canKeyGenerateCharacter`.

modules/javafx.graphics/src/main/java/com/sun/javafx/tk/quantum/GlassViewEventHandler.java
 line 169:

> 167:             WindowStage stage = scene.getWindowStage();
> 168:             Boolean consumed = Boolean.FALSE;
> 169: 

Consider not defining this variable, and just returning directly when a result 
has been determined.

modules/javafx.graphics/src/main/java/javafx/scene/Scene.java line 2183:

> 2181: 
> 2182:     /**
> 2183:      * @return true iff the event was consumed

Suggestion:

     * @return {@code true} if the event was consumed

modules/javafx.graphics/src/main/java/javafx/scene/input/KeyEvent.java line 388:

> 386:      * The hardware key code which is private to the implementation.
> 387:      */
> 388:     private int hardwareCode;

Does it need to be private? Events are public, and I think it should be 
possible to make your own events that act exactly like an event created by the 
system, which would preclude hidden variables.

modules/javafx.graphics/src/main/native-glass/win/KeyTable.cpp line 366:

> 364:         UINT keyChar = ::MapVirtualKeyEx(UINT(hardwareCode), 2, layout);
> 365:         // Filter out dead keys
> 366:         BOOL isDead = (keyChar & 0x80000000) != 0;

Wouldn't `hardwareCode >= 0` already filter out dead keys since when the 
highest bit is set the value is negative?

tests/manual/events/KeyboardTest.java line 134:

> 132:     static private class KeyList extends ArrayList<KeyData> {}
> 133: 
> 134:     static private class KeyListBuilder {

minor: standard keyword order is `private static class`

-------------

PR Review: https://git.openjdk.org/jfx/pull/1126#pullrequestreview-1415366666
PR Review Comment: https://git.openjdk.org/jfx/pull/1126#discussion_r1186465635
PR Review Comment: https://git.openjdk.org/jfx/pull/1126#discussion_r1186464101
PR Review Comment: https://git.openjdk.org/jfx/pull/1126#discussion_r1186448517
PR Review Comment: https://git.openjdk.org/jfx/pull/1126#discussion_r1186454982
PR Review Comment: https://git.openjdk.org/jfx/pull/1126#discussion_r1186456764
PR Review Comment: https://git.openjdk.org/jfx/pull/1126#discussion_r1186458329
PR Review Comment: https://git.openjdk.org/jfx/pull/1126#discussion_r1186460449
PR Review Comment: https://git.openjdk.org/jfx/pull/1126#discussion_r1186461172

Reply via email to