IDEA-105576 MacOs Lion kbd feature "press-and-hold popup" incorrectly works in editor
authorDmitry Batrak <Dmitry.Batrak@jetbrains.com>
Tue, 24 Feb 2015 15:42:42 +0000 (18:42 +0300)
committerDmitry Batrak <Dmitry.Batrak@jetbrains.com>
Tue, 24 Feb 2015 15:44:16 +0000 (18:44 +0300)
workaround suitable for Oracle JDK

platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorComponentImpl.java
platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java
platform/util/resources/misc/registry.properties

index 95a4ab25444b4694d9fa0a96165f700265c7899f..866bc141d47f4c8b67a22af1f900822b1712575a 100644 (file)
@@ -63,19 +63,6 @@ public class EditorComponentImpl extends JComponent implements Scrollable, DataP
         return myEditor.visualPositionToXY(magnificationPosition);
       }
     });
-    putClientProperty("sun.lwawt.macosx.CInputMethod.selectPreviousGlyph.callback", new Runnable() {
-      @Override
-      public void run() {
-        // This is supposed to be called from sun.lwawt.macosx.CInputMethod class of a custom JDK, 
-        // built for IntelliJ platform running on MacOS.
-        // This is required to support input of accented characters using press-and-hold method (http://support.apple.com/kb/PH11264).
-        // Non-patched JDK supports this functionality only for TextComponent/JTextComponent descendants.
-        int caretOffset = myEditor.getCaretModel().getOffset();
-        if (caretOffset > 0) {
-          myEditor.getSelectionModel().setSelection(caretOffset - 1, caretOffset);
-        }
-      }
-    });
     myApplication = (ApplicationImpl)ApplicationManager.getApplication();
   }
 
index fcdbe2fc4147f0a2b69e0ac54ca5e2082633e58c..ea0ce0da254b46ac19f49e6a9620c73b250eeaf4 100644 (file)
@@ -308,6 +308,9 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
   public final boolean myUseNewRendering = Registry.is("editor.new.rendering");
   final EditorView myView;
 
+  private boolean myCharKeyPressed;
+  private boolean myNeedToSelectPreviousChar;
+
   private final TIntFunction myLineNumberAreaWidthFunction = new TIntFunction() {
     @Override
     public int execute(int lineNumber) {
@@ -902,9 +905,10 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
       myPanel.add(myScrollPane);
     }
 
-    myEditorComponent.addKeyListener(new KeyAdapter() {
+    myEditorComponent.addKeyListener(new KeyListener() {
       @Override
       public void keyTyped(@NotNull KeyEvent event) {
+        myNeedToSelectPreviousChar = false;
         if (event.isConsumed()) {
           return;
         }
@@ -912,6 +916,18 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
           event.consume();
         }
       }
+
+      @Override
+      public void keyPressed(KeyEvent e) {
+        if (e.getKeyCode() >= KeyEvent.VK_A && e.getKeyCode() <= KeyEvent.VK_Z) {
+          myCharKeyPressed = true;
+        }
+      }
+
+      @Override
+      public void keyReleased(KeyEvent e) {
+        myCharKeyPressed = false;
+      }
     });
 
     MyMouseAdapter mouseAdapter = new MyMouseAdapter();
@@ -5413,6 +5429,9 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
     @Override
     @Nullable
     public AttributedCharacterIterator getSelectedText(AttributedCharacterIterator.Attribute[] attributes) {
+      if (myCharKeyPressed) {
+        myNeedToSelectPreviousChar = true;
+      }
       String text = getSelectionModel().getSelectedText();
       return text == null ? null : new AttributedString(text).getIterator();
     }
@@ -5457,6 +5476,22 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
     }
 
     private void replaceInputMethodText(@NotNull InputMethodEvent e) {
+      if (myNeedToSelectPreviousChar && SystemInfo.isMac && Registry.is("ide.mac.pressAndHold.workaround")) {
+        // This is required to support input of accented characters using press-and-hold method (http://support.apple.com/kb/PH11264).
+        // JDK currently properly supports this functionality only for TextComponent/JTextComponent descendants.
+        // For our editor component we need this workaround.
+        myNeedToSelectPreviousChar = false;
+        getCaretModel().runForEachCaret(new CaretAction() {
+          @Override
+          public void perform(Caret caret) {
+            int caretOffset = caret.getOffset();
+            if (caretOffset > 0) {
+              caret.setSelection(caretOffset - 1, caretOffset);
+            }
+          }
+        });
+      }
+
       int commitCount = e.getCommittedCharacterCount();
       AttributedCharacterIterator text = e.getText();
 
index 1613d3e292e3e17060e3a24f219b7e8f8a07e0bb..114892b0266ecbed936185da101d79c27bead421 100644 (file)
@@ -159,6 +159,8 @@ ide.mac.boldEditorTabs=false
 ide.mac.disableMacScrollbars=false
 ide.mac.disableMacScrollbars.restartRequired=true
 ide.mac.disableMacScrollbars.description=Disables OS X overlay scrollbars
+ide.mac.pressAndHold.workaround=true
+ide.mac.pressAndHold.workaround.description=Enable workaround for press-and-hold input method for accented characters on Mac OS
 ide.perProjectModality=false
 ide.perProjectModality.description=New modality approach. All dialogs are DOCUMENT_MODAL expect ide-wide dialogs