Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8282217

Key events (key char and key code) changed for Swiss keyboard

XMLWordPrintable

    • b01
    • x86_64
    • windows_10

      ADDITIONAL SYSTEM INFORMATION :
      OS:
      Windows 10 21H1

      Java Runtime:
      Confirmed to work as expected up to Java 8 Update 151
      Confirmed to behave unexpectedly starting with Java 8 Update 152, and also with current version Java 8 Update 321.
      Confirmed to behave unexpectedly also on Java 11.
      Suspected to behave unexpectedly also on Java 17.


      A DESCRIPTION OF THE PROBLEM :
      We use a barcode scanner that sends the Group Separator character as a delimiter (unicode character 29 / 0x1d).
      We cannot recognize this character any more when Swiss keyboard layout is chosen.

      When the Group Separator key code is sent, the character is now marked as an undefined character when a Swiss keyboard layout is chosen.
      For German or English keyboard layout, the character is not marked as undefined.
      For Swiss keyboard layout, the character is not marked as undefined up to Java 8 Update 151.
      It is marked as undefined for Swiss keyboard layout starting with Java 8 Update 152 (up to the current Update 321), however.
      The change has also been implemented on Java 9, hence the issue also exists on Java 11 (confirmed) and probably also on Java 17 (suspicion).

      The change has probably been introduced with https://bugs.openjdk.java.net/browse/JDK-8139189 (Java 9) / https://bugs.openjdk.java.net/browse/JDK-8169253 (Java 8 Update 152) where it seems "dead key detection" has been changed.
      It seems the change caused other undesired side effects, for example with Spanish keyboard (https://bugs.openjdk.java.net/browse/JDK-8169355 (Java 9) / https://bugs.openjdk.java.net/browse/JDK-8169498 (Java 8 Update 152)).
      Hence, I suppose the change for Swiss keyboard has also been unintentional.


      REGRESSION : Last worked in version 8

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      Preparation

      Instead of using a real barcode scanner and a barcode containing the Group Separator symbol, AutoHotkey can be used to reproduce the issue,
      Configure Autohotkey to send a string containing the GroupSeparator symbol, e.g. using Windows key + 1
      An appropriate string in the AutoHotkey configuration file would be
      #1::Send A(GS)B
      where you replace (GS) with the group separator symbol by pressing ALT + 0, 2, 9 on the numpad (resulting in unicode character 29 / 0x1d, i.e. the group separator) and using a unicode-aware text editor like Notepad++.
      (Note configuring AutoHotkey to send this unicode character via its unicode representation, i.e. {U+001d} yields a different result which does not match the behavior of the real hardware)

      Install at least an additional keyboard. Standard keyboard can be English (United States) or German (Germany), for example.
      Additional keyboard shall be German (Switzerland) with Swiss German keyboard.

      Reproduction

      Execute this using Java 8 Update 152 or later, e.g. Java 8 Update 321.
      And repeat this using Java 8 Update 151 (or before).

      Start the demo form.

      Select default keyboard, e.g. Engish (United States)
      Use AutoHotkey to type the input containing the Group Separator, e.g. Win+1
      Watch the output of the Demo program (written using System.out.println())

      Select Swiss keyboard
      Repeat steps using AutoHotkey to type and watching output


      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      I expect the similar output for Swiss keyboard, identifying the Group Separator character 29 / 0x1d for Java 8 Update 152 and later, as it has been for Java 8 Update 151 and before.

      Compared to "Actual result", results 1. a), 1. b) and 2. a) allow to identify the Group separator character (i.e. always for English (US) keyboard, independent of Java 8 Update version).
      But for case 2. b) I would expect that the Group Separator character 29 / 0x1 is identifiable also for Java 8 Updates > 151, as it has been for Updates <= 151.
      ACTUAL -
      1. Using English (United States) or German (Germany) keyboard:
      a) Using Java 8 Update 151
      Group separator is reported as corresponding character (29 / 0x1d)
      --- Key PRESS
      keyboard locale: en_US
      KEY CHAR: '' (defined=true; 29, 0x1d)
      KEY CODE: (Plus): 521, 0x209
      b) Using Java 8 Update 321
      Group separator is also reported as corresponding character (29 / 0x1d)
      (same output as above for 1. a))

      2. Using German (Switzerland) keyboard:
      a) Using Java 8 Update 151
      Group separator is also reported as corresponding character (29 / 0x1d)
      (similar output as above for 1. a) and 1. b) - except for a different key code)
      --- Key PRESS
      keyboard locale: de_CH
      KEY CHAR: '' (defined=true; 29, 0x1d)
      KEY CODE: (Dead Diaeresis): 135, 0x87
      b) Using Java 8 Update 321
      Group separator is NOT reported as corresponding character (29 / 0x1d), but as an undefined character. The information that the Group separator 29 / 0x1d has been sent is lost.
      --- Key PRESS
      keyboard locale: de_CH
      KEY CHAR: '?' (defined=false; 65535, 0xffff)
      KEY CODE: (Dead Diaeresis): 135, 0x87


      ---------- BEGIN SOURCE ----------
      The following simple form can be used to demonstrate the issue and is referenced in the Reproduction above

      import java.awt.BorderLayout;
      import java.awt.Dimension;
      import java.awt.event.KeyEvent;
      import java.awt.event.KeyListener;
      import java.awt.im.InputContext;

      import javax.swing.JFrame;
      import javax.swing.JPanel;
      import javax.swing.JTextField;
      import javax.swing.SwingUtilities;

      public class JavaInputTestForm extends JPanel {

          private static JFrame frame;

          public JavaInputTestForm() {
              super();
              setLayout(new BorderLayout());
              setPreferredSize(new Dimension(600, 400));

              JTextField textField = new JTextField();
              textField.addKeyListener(new KeyListener() {

                  @Override
                  public void keyTyped(KeyEvent e) {
                  }

                  @Override
                  public void keyPressed(KeyEvent evt) {
                      if (evt.getKeyCode() == KeyEvent.VK_WINDOWS) {
                          return;
                      }

                      System.out.println("--- Key PRESS");
                      System.out.println("\tkeyboard locale: " + InputContext.getInstance().getLocale());
                      System.out.println("\tKEY CHAR: '" + evt.getKeyChar() + "' (defined=" + (evt.getKeyChar() != KeyEvent.CHAR_UNDEFINED) + "; "
                              + ((int) evt.getKeyChar()) + ", 0x" + Integer.toHexString((int) evt.getKeyChar()) + ")");
                      System.out.println("\tKEY CODE: " + " (" + KeyEvent.getKeyText(evt.getKeyCode()) + "): " + evt.getKeyCode() + ", 0x"
                              + Integer.toHexString(evt.getKeyCode()));
                  }

                  @Override
                  public void keyReleased(KeyEvent e) {
                  }

              });
              add(textField, BorderLayout.NORTH);
          }

          private static void createAndShowGUI() {
              frame = new JFrame("Test Form");
              frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
              frame.add(new JavaInputTestForm(), BorderLayout.CENTER);

              frame.pack();
              frame.setLocationRelativeTo(null);
              frame.setVisible(true);
          }

          public static void main(String... args) {
              SwingUtilities.invokeLater(() -> createAndShowGUI());
          }

      }

      ---------- END SOURCE ----------

      FREQUENCY : always


            achung Alisen Chung
            webbuggrp Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            4 Start watching this issue

              Created:
              Updated: