RFR: 8273743: KeyCharacterCombination for "+" does not work on US QWERTY keyboard layout
Martin Fox
duke at openjdk.java.net
Wed Dec 15 01:06:58 UTC 2021
On Mon, 13 Dec 2021 19:46:27 GMT, Martin Fox <duke at openjdk.java.net> wrote:
> The algorithm in `KeyCharacterCombination.match` relies on the call `Toolkit.getKeyCodeForChar` which is difficult to implement correctly. It defies the way most keyboard API’s work and no platform has got it right yet. In particular the Mac and Linux implementations have to resort to a brute-force approach which monitors keystrokes to learn the relationship between keys and characters.
>
> This PR introduces an alternative mechanism which directly asks the platform whether a given key can generate a specific character. It also allows the platform to attach identifying key information to each KeyEvent to make it easier to answer the question (much, much easier).
>
> This is mostly dumb plumbing. On the front-end there’s a new call `View.notifyKeyEx` that takes an additional platform-specific `hardwareCode` parameter. It also returns a boolean indicating whether the event was consumed or not so I can fix JDK-8087863. If you want to follow the path visit the files in this order:
>
> View.java
> GlassViewEventHandler.java
> TKSceneListener.java
> Scene.java
>
> The `KeyEvent` class has been expanded with an additional `hardwareCode` member that can only be accessed internally. See KeyEvent.java and KeyEventHelper.java.
>
> On the back-end `KeyCharacterCombination.match` calls a new routine `Toolkit.getKeyCanGenerateCharacter` which unpacks the `KeyEvent` information and sends it on to the Application. The default implementation falls back to the old `getKeyCodeForChar` call but platform specific Applications can send it on to the native glass code.
>
> KeyCharacterCombination.java
> Toolkit.java
> QuantumToolkit.java
> Application.java
> GtkApplication.java
>
> The glass code can use the `hardwareCode` to answer the question directly. It also has enough information to fall back on the old `getKeyCodeForChar` logic while also enabling the keypad (a common complaint is that Ctrl+’+’ only works on the main keyboard and not the keypad, see JDK-8090275).
>
> This PR improves the situation for key events generated by keystrokes. Manually constructed key events won’t work any better or worse than they already do. Based on the bug database I don't think this is an issue.
1. No drawbacks that I can think of. With this approach the platform glass code will have enough information to recreate the original `getKeyCodeForChar` algorithm so it can at least maintain the existing behavior. This PR just gives it enough information to do better. For example, even in the absence of a `hardwareCode` the platform will be able to use the event's `KeyCode` to allow matching on keypad keys.
2. I've written and tested Windows and Mac implementations. They both address [JDK-8090275](https://bugs.openjdk.java.net/browse/JDK-8090275). The Mac implementation requires more testing and uses some code from PR #425. The Windows implementation is just a tweak on the existing code to enable the keypad.
3. I'm not sure what to say about #672. It boils down to how we want to deal with `KeyEvents` that are created using the API vs. a physical keystroke. I'll address that in a follow-up comment.
4. I'll add the test case modified to enable testing on the keypad. It might take a day or two, there's a few other tweaks that would be useful to have.
-------------
PR: https://git.openjdk.java.net/jfx/pull/694
More information about the openjfx-dev
mailing list