RFR: 8089373: Translation from character to key code is not sufficient [v3]
Martin Fox
duke at openjdk.org
Fri Jun 9 18:28:34 UTC 2023
On Thu, 11 May 2023 02:46:47 GMT, Martin Fox <duke at 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.
>
> Martin Fox has updated the pull request incrementally with one additional commit since the last revision:
>
> Renamed notifyKeyEx to notifyKey
I added JDK-8274967 as an issue this PR fixes. Support for `Ctrl+'+'` and `Ctrl+'-'` is erratic on Windows without this PR. Currently the platform code finds the correct key but fails to generate the correct Java KeyCode (it uses a hard-coded table that may not correspond to the current layout). With this PR it just compares the platform key code it found to the `hardwareCode` passed in.
(BTW, bugs like this are under-represented in the Java bug tracking system. I was looking through the issues list for a JavaFX desktop and saw at least four bugs related to KeyCharacterCombinations spread across all three platforms. App developers have a hard time sorting this out since the behavior varies so much between platforms and layouts and the specific character being targeted.)
-------------
PR Comment: https://git.openjdk.org/jfx/pull/1126#issuecomment-1584979525
More information about the openjfx-dev
mailing list