On Wed, 15 Dec 2021 21:30:41 GMT, Martin Fox <d...@openjdk.org> 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.
>
> I've decided that if this PR goes forward we should abandon #672. The changes 
> in #672 would be bypassed for KeyEvents generated by physical keystrokes. For 
> a while I thought it would be useful for handling KeyEvents created via the 
> API but have decided against it.
> 
> I've been going back and forth on how to handle synthetic events created 
> using the KeyEvent constructor i.e. events that don't have a hardwareCode 
> attached. One option is to just route them through the old 
> `getKeyCodeForChar` machinery to maintain the current level of support. 
> Unfortunately this varies widely, from mostly working on Windows to almost 
> never working on Mac. If we just maintain what we've got I would ditch #672 
> since it would be fine-tuning a feature on Windows that's largely busted on 
> other platforms.
> 
> The other option is to dive in and make synthetic events work as well as 
> possible on every platform. In this PR `getKeyCanGenerateCharacter` has a 
> KeyCode in hand and can use the existing Robot code to map that to a physical 
> key. It wouldn't be entirely reliable (particularly on Mac and Linux) but it 
> would be easy and improve support for synthetic events enough to forestall 
> bugs like [JDK-8087486](https://bugs.openjdk.java.net/browse/JDK-8087486). 
> And it would be behavior I could write automated and manual tests for.
> 
> I don't think synthetic events are all that useful for triggering 
> KeyCharacterCombinations (you have to know the current keyboard layout to 
> accurately target punctuation or symbols) but they exist and it's probably 
> best to get them to a testable state. This means fixing the Robot code which 
> has bugs on every platform but that was already on my to-do list and I've 
> prototyped most of the code. I'll get the Robot bugs entered in the next few 
> days.

@beldenfox would it be possible to make the same change to the .classpath file 
(though it might create a merge conflict later)?


<?xml version="1.0" encoding="UTF-8"?>
<classpath>
        <classpathentry combineaccessrules="false" kind="src" path="/base">
                <attributes>
                        <attribute name="module" value="true"/>
                </attributes>
        </classpathentry>
        <classpathentry combineaccessrules="false" kind="src" path="/controls">
                <attributes>
                        <attribute name="module" value="true"/>
                </attributes>
        </classpathentry>
        <classpathentry combineaccessrules="false" kind="src" path="/graphics">
                <attributes>
                        <attribute name="module" value="true"/>
                </attributes>
        </classpathentry>
        <classpathentry kind="con" 
path="org.eclipse.jdt.launching.JRE_CONTAINER">
                <attributes>
                        <attribute name="module" value="true"/>
                </attributes>
        </classpathentry>
        <classpathentry excluding=".classpath|.project|.settings" kind="src" 
output="bin" path=""/>
        <classpathentry kind="output" path="bin"/>
</classpath>

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

PR Comment: https://git.openjdk.org/jfx/pull/694#issuecomment-1518206571

Reply via email to