Workaround iOS text input crash for emoji+Korean text#36295
Workaround iOS text input crash for emoji+Korean text#36295auto-submit[bot] merged 2 commits intoflutter:mainfrom
Conversation
| if (emoji) { | ||
| self.lastEmoji = emoji; | ||
| } | ||
| if (text.length == 1 && !text.UTF8String && |
This comment was marked as outdated.
This comment was marked as outdated.
Sorry, something went wrong.
| dispatch_once(&onceToken, ^{ | ||
| set = CFCharacterSetCreateMutableCopy( | ||
| kCFAllocatorDefault, | ||
| CTFontCopyCharacterSet(CTFontCreateWithName(CFSTR("AppleColorEmoji"), 0.0, NULL))); |
This comment was marked as outdated.
This comment was marked as outdated.
Sorry, something went wrong.
99125e9 to
12dff9a
Compare
12dff9a to
ad3c308
Compare
|
#34508 seems similar and we might be able to use some of the tests in the PR. |
LongCatIsLooong
left a comment
There was a problem hiding this comment.
This approach LGTM. I think the keyboard also handles grapheme clusters wrong. I'll check what the exact behavior is.
| } | ||
| // Only need to use lastComposedCharacters for the one insertion right after deletion. | ||
| // Clear it even it is not used in the above if block. | ||
| self.lastComposedCharacters = nil; |
There was a problem hiding this comment.
also maybe set the stored value to nil at the end of the runloop?
| // Workaround for https://github.com/flutter/flutter/issues/111494 | ||
| // TODO(cyanglaz): revert this workaround if when flutter supports a minimum iOS version which | ||
| // this bug is fixed by Apple. | ||
| text = self.lastComposedCharacters; |
There was a problem hiding this comment.
So this step adds the emoji back, then the IME will call insertText: again to insert "어"?
There was a problem hiding this comment.
why the text.length == 1 check? Shouldn't !text.UTF8String be enough (I'm assuming this checks the string is not malformed)?
There was a problem hiding this comment.
nvm. I tried some grapheme clusters, the keyboard always inserts the first code unit.
There was a problem hiding this comment.
So this step adds the emoji back, then the IME will call
insertText:again to insert "어"?
Yes. I'm going to add what the "bugged" behavior actually is in the PR description.
| // TODO(cyanglaz): revert this workaround if when flutter supports a minimum iOS version which | ||
| // this bug is fixed by Apple. | ||
| text = self.lastComposedCharacters; | ||
| text = self.temporarilyDeletedComposedCharacter; |
There was a problem hiding this comment.
nit: also clear the stored string here since it's consumed?
| [inputView deleteBackward]; | ||
| [inputView shouldChangeTextInRange:OCMClassMock([UITextRange class]) replacementText:@""]; | ||
|
|
||
| // Insert the first unicode in the emoji. |
There was a problem hiding this comment.
nit: first unicode -> first unichar
| @@ -1956,9 +1961,8 @@ - (void)deleteBackward { | |||
| NSString* deletedText = [self.text substringWithRange:_selectedTextRange.range]; | |||
| CFRange range = | |||
There was a problem hiding this comment.
nit: consider using fml::RangeForCharacterAtIndex
|
@cyanglaz is out this week, he will pick the nits for next week. |
b2806a2 to
b5856e7
Compare
|
@cyanglaz is this ready to merge? |
|
@LongCatIsLooong Updated to use |
| range:charRange | ||
| remainingRange:NULL]; | ||
| if (gotCodePoint && u_hasBinaryProperty(codePoint, UCHAR_EMOJI)) { | ||
| if (IsEmoji(self.text, charRange)) { |
There was a problem hiding this comment.
nit: some emojis are in plane 0 and require only one code point to encode, e.g.: https://www.compart.com/en/unicode/U+2764
This is what iOS 16 does when transforming 2 Korean characters into 1 (for example ㅇ ㅏ) right after a unicode composed character (emoji etc):
However, in iOS 16.0, there is a bug that in step 2, only the first unicode is inserted, which creates an incomplete or different composed character.
To workaround this issue, this PR:
The issue is caused by an iOS bug and this PR only provides a workaround, we should revert this workaround when the issue is fixed by iOS.
fixes flutter/flutter#111494
Pre-launch Checklist
writing and running engine tests.
///).If you need help, consider asking for advice on the #hackers-new channel on Discord.