Community
Participate
Working Groups
The KNIME analytics platform is an open source application based on Eclipse. Since we updated Eclipse to 2021-03, our users on Mac OS have problems when using the international keyboard layout. This seems to be related to the SWT_AWT bridge. To reproduce: Run the code example below on a Mac with U.S. international keyboard layout. Try to type in the text fields a) ' and then ␣ (space bar) this used to give a single quotation mark now gives a blank character b) ⇧ + ' and then ␣ (space bar) this used to result in a double quotation mark now also gives a blank character Interestingly, other combinations still work: for instance typing ' and then a will still give á. I tried this on Mac OS Big Sur using the swt-4.21RC2a-cocoa-macosx-x86_64 build. When tracking the key events on a text field, the java.awt.KeyEvent sequences differ between the working and not working text fields: Working sequence: [KEY_PRESSED keyCode=16 keyText=⇧ keyChar=ndf modifiers=⇧ extModifiers=⇧ keyLocation=LEFT extendedKeyCode=0x10] [KEY_RELEASED keyCode=222 keyText=' keyChar='"' modifiers=⇧ extModifiers=⇧ keyLocation=STANDARD extendedKeyCode=0x98] [KEY_RELEASED keyCode=16 keyText=⇧ keyChar=ndf keyLocation=LEFT extendedKeyCode=0x10] [KEY_TYPED keyCode=0 keyText=0x0 keyChar='"' keyLocation=UNKNOWN extendedKeyCode=0x0] [KEY_RELEASED keyCode=32 keyText=␣ keyChar=' ' keyLocation=STANDARD extendedKeyCode=0x20] Actually observed sequence, e.g., in a JTextField embedded into an SWT Composite via SWT_AWT.new_frame √ [KEY_PRESSED keyCode=16 keyText=⇧ keyChar=ndf modifiers=⇧ extModifiers=⇧ keyLocation=LEFT extendedKeyCode=0x10] // extended key code should be 0x98? X [KEY_RELEASED keyCode=222 keyText=' keyChar=ndf modifiers=⇧ extModifiers=⇧ keyLocation=STANDARD extendedKeyCode=0xde] √ [KEY_RELEASED keyCode=16 keyText=⇧ keyChar=ndf keyLocation=LEFT extendedKeyCode=0x10] // instead of this key pressed event, there should be a key typed event X [KEY_PRESSED keyCode=32 keyText=␣ keyChar=' ' keyLocation=STANDARD extendedKeyCode=0x20] // instead of keyChar=' ' the typed character should be '"' X [KEY_TYPED keyCode=0 keyText=0x0 keyChar=' ' keyLocation=UNKNOWN extendedKeyCode=0x20] √ [KEY_RELEASED keyCode=32 keyText=␣ keyChar=' ' keyLocation=STANDARD extendedKeyCode=0x20] import java.awt.BorderLayout; import java.awt.EventQueue; import java.awt.FlowLayout; import java.awt.Frame; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JTextField; import javax.swing.WindowConstants; import org.eclipse.swt.SWT; import org.eclipse.swt.awt.SWT_AWT; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.Text; public class MixGuiToolkits { public static void main(final String[] args) { final var display = new Display(); // problematic Shell mixToolkits = awtWithinSwt(display); mixToolkits.open(); // works Shell pureSwt = MixGuiToolkits.pureSWT(display); pureSwt.open(); // works pureSwing(display); while (!pureSwt.isDisposed()) { if (!display.readAndDispatch()) { display.sleep(); } } display.dispose(); } /** Create an SWT Composite with Swing and AWT text fields - does not work */ private static Shell awtWithinSwt(final Display display) { final var shell = new Shell(display); final var swtComposite = new Composite(shell, SWT.EMBEDDED); swtComposite.setBounds(5, 5, 300, 300); // use the SWT_AWT bridge to embed AWT or Swing into an SWT composite java.awt.Frame awtFrame = SWT_AWT.new_Frame(swtComposite); java.awt.Panel awtPanel = new java.awt.Panel(new java.awt.BorderLayout()); awtFrame.add(awtPanel); // these text fields have the bug awtPanel.add("North", new JTextField("Swing text field (has bug)")); awtPanel.add("South", new java.awt.TextField("AWT text fiel (has bug)")); return shell; } /** Create an SWT Composite with an SWT text field - works as expected */ private static Shell pureSWT(final Display display) { var shell = new Shell(display); shell.setLayout(new GridLayout()); shell.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); // The border gives the appearance of a single component final var baseComposite = new Composite(shell, SWT.BORDER); baseComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); final var baseCompositeGridLayout = new GridLayout(2, false); baseComposite.setLayout(baseCompositeGridLayout); final var text = new Text(baseComposite, SWT.SINGLE | SWT.RIGHT); text.setText("SWT Text (works)"); text.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); return shell; } /** Create a Swing window with a Swing text field - works as expected */ private static void pureSwing(final Display display) { EventQueue.invokeLater(() -> { final var mainFrame = new JFrame(); mainFrame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE); final var mainPanel = new JPanel(); mainPanel.setLayout(new FlowLayout()); mainPanel.add(new JTextField("JTextField (works)")); mainFrame.getContentPane().add(mainPanel, BorderLayout.CENTER); mainFrame.pack(); mainFrame.setVisible(true); }); display.addListener(SWT.Close, event -> EventQueue.invokeLater(() -> { Frame[] frames = Frame.getFrames(); for (Frame frame : frames) { frame.dispose(); } })); } }