[Bf-blender-cvs] [0ef794b5534] master: macOS: support Chinese and Korean input for text buttons

Yuki Hashimoto noreply at git.blender.org
Mon Jul 5 17:26:08 CEST 2021


Commit: 0ef794b5534ab28901cbb18d69ba0e6642439ba9
Author: Yuki Hashimoto
Date:   Mon Jul 5 13:17:33 2021 +0200
Branches: master
https://developer.blender.org/rB0ef794b5534ab28901cbb18d69ba0e6642439ba9

macOS: support Chinese and Korean input for text buttons

This patch extends D11695 to provide full support for Chinese and Korean
input on macOS.

Chinese input notes:

You can input symbolic characters (such as '! , '$') during Chinese input.

The difference from Japanese input is that multiple `insertText` may be
called with a single key down (`keyDown` method). This happens when you input
a symbolic character (such as '! , '$') during conversion.

The conversion is confirmed (`insertText`) and the symbolic character is
entered (`insertText`). To solve this problem, I have `result_text` to
concatenate the strings and store them in `result`.

Korean input notes:

Korean does not display a conversion suggestion window.

Like Chinese, Korean input may call multiple `insertText` methods. Also,
in Korean, the previous confirmation (`setMarkedText` and `insertText`) and
the next conversion is processed (`setMarkedText`) may be called
simultaneously with a single key down (`keyDown` method).

For example:
1. press g ㅎ (`setMarkedText`)
2. press k 하 (`setMarkedText`)
3. press t 앗 (`setMarkedText`)
4. press k 하세 (`setMarkedText`, `insertText`, `setMarkedText`)

Fixed so that the `insertText` and the last `setMarkedText` are processed.

Also, if a control character (such as Arrow, Enter) is input during Korean
input, the conversion will be confirmed (`setMarkedText`, `insertText`) and
the original control character will be processed.

In other words, if you press the left arrow key while typing in Korean, the
cursor will move to the left after the character is confirmed. Therefore, I
modified the `keyDown` method so that the `handleKeyEvent` is called again
after the `insertText` is processed in the `interpretKeyEvents` method.

Differential Revision: https://developer.blender.org/D11699

===================================================================

M	intern/ghost/intern/GHOST_WindowCocoa.h
M	intern/ghost/intern/GHOST_WindowViewCocoa.h

===================================================================

diff --git a/intern/ghost/intern/GHOST_WindowCocoa.h b/intern/ghost/intern/GHOST_WindowCocoa.h
index fdc806e2167..8ac1a78b32a 100644
--- a/intern/ghost/intern/GHOST_WindowCocoa.h
+++ b/intern/ghost/intern/GHOST_WindowCocoa.h
@@ -356,6 +356,8 @@ enum {
   GHOST_IME_INPUT_FOCUSED = (1 << 0),
   GHOST_IME_ENABLED = (1 << 1),
   GHOST_IME_COMPOSING = (1 << 2),
-  GHOST_IME_KEY_CONTROL_CHAR = (1 << 3)
+  GHOST_IME_KEY_CONTROL_CHAR = (1 << 3),
+  GHOST_IME_COMPOSITION_EVENT = (1 << 4),  // For Korean input
+  GHOST_IME_RESULT_EVENT = (1 << 5)        // For Korean input
 };
 #endif /* WITH_INPUT_IME */
diff --git a/intern/ghost/intern/GHOST_WindowViewCocoa.h b/intern/ghost/intern/GHOST_WindowViewCocoa.h
index 42f0fcc6ac6..2aaf1d56116 100644
--- a/intern/ghost/intern/GHOST_WindowViewCocoa.h
+++ b/intern/ghost/intern/GHOST_WindowViewCocoa.h
@@ -47,6 +47,7 @@
     GHOST_TEventImeData event;
     std::string result;
     std::string composite;
+    std::string combined_result;
   } ime;
 #endif
 }
@@ -123,6 +124,20 @@
 
     // interpret event to call insertText
     [self interpretKeyEvents:[NSArray arrayWithObject:event]];  // calls insertText
+
+#ifdef WITH_INPUT_IME
+    // For Korean input, control characters are also processed by handleKeyEvent.
+    const int controlCharForKorean = (GHOST_IME_COMPOSITION_EVENT | GHOST_IME_RESULT_EVENT |
+                                      GHOST_IME_KEY_CONTROL_CHAR);
+    if (((ime.state_flag & controlCharForKorean) == controlCharForKorean)) {
+      systemCocoa->handleKeyEvent(event);
+    }
+
+    ime.state_flag &= ~(GHOST_IME_COMPOSITION_EVENT | GHOST_IME_RESULT_EVENT);
+
+    ime.combined_result.clear();
+#endif
+
     return;
   }
 }
@@ -261,9 +276,23 @@
       [self processImeEvent:GHOST_kEventImeCompositionStart];
     }
 
-    [self setImeResult:[self convertNSString:chars]];
+    // For Chinese and Korean input, insertText may be executed twice with a single keyDown.
+    if (ime.state_flag & GHOST_IME_RESULT_EVENT) {
+      ime.combined_result += [self convertNSString:chars];
+    }
+    else {
+      ime.combined_result = [self convertNSString:chars];
+    }
+
+    [self setImeResult:ime.combined_result];
+
+    /* For Korean input, both "Result Event" and "Composition Event"
+     * can occur in a single keyDown. */
+    if (![self ime_did_composition]) {
+      [self processImeEvent:GHOST_kEventImeComposition];
+    }
+    ime.state_flag |= GHOST_IME_RESULT_EVENT;
 
-    [self processImeEvent:GHOST_kEventImeComposition];
     [self processImeEvent:GHOST_kEventImeCompositionEnd];
     ime.state_flag &= ~GHOST_IME_COMPOSING;
   }
@@ -313,7 +342,11 @@
 
     [self setImeComposition:composing_text selectedRange:range];
 
-    [self processImeEvent:GHOST_kEventImeComposition];
+    // For Korean input, setMarkedText may be executed twice with a single keyDown.
+    if (![self ime_did_composition]) {
+      ime.state_flag |= GHOST_IME_COMPOSITION_EVENT;
+      [self processImeEvent:GHOST_kEventImeComposition];
+    }
   }
 #endif
 }
@@ -457,7 +490,11 @@
 - (void)setImeComposition:(NSString *)inString selectedRange:(NSRange)range
 {
   ime.composite = [self convertNSString:inString];
-  ime.result.clear();
+
+  // For Korean input, both "Result Event" and "Composition Event" can occur in a single keyDown.
+  if (!(ime.state_flag & GHOST_IME_RESULT_EVENT)) {
+    ime.result.clear();
+  }
 
   /* The target string is equivalent to the string in selectedRange of setMarkedText.
    * The cursor is displayed at the beginning of the target string. */
@@ -525,6 +562,12 @@
   }
 }
 
+- (bool)ime_did_composition
+{
+  return (ime.state_flag & GHOST_IME_COMPOSITION_EVENT) ||
+         (ime.state_flag & GHOST_IME_RESULT_EVENT);
+}
+
 /* Even if IME is enabled, when not composing, control characters
  * (such as arrow, enter, delete) are handled by handleKeyEvent. */
 - (bool)isProcessedByIme



More information about the Bf-blender-cvs mailing list