Improved management of multi-char keyboards (Vietnamese and Korean) - #418
Improved management of multi-char keyboards (Vietnamese and Korean)#418holzschu wants to merge 11 commits into
Conversation
|
Oh this is interesting - is this the expectation that folks have when using those keyboards? and can you tell me more about the Japanese crash? |
|
So one fear that I have is that this is not using UITextInput correctly, and it is working behind its back. I wonder if a proper UITExtInput support would address these |
Yes, definitely. That's one of the oldest feature request for a-Shell (proper support of Vietnamese and Korean keyboards). That is the most common way to enter the diacritics used by Vietnamese, as the "long-press-on-key-to-make-diacritics-appear" method is not convenient for them.
If I call if (keyboardLanguage.hasPrefix("vi") || keyboardLanguage.hasPrefix("ko") || keyboardLanguage.hasPrefix("ja")) {
resetInputBuffer()
}then the second set of Japanese ideograms I enter causes a crash in this function: func fullRange(in baseString: String) -> Range<String.Index> {
let beginIndex = baseString.index(baseString.startIndex, offsetBy: startPosition.offset)
let endIndex = baseString.index(beginIndex, offsetBy: endPosition.offset - startPosition.offset)
return beginIndex..<endIndex
}itself called by: textInputStorage.replaceSubrange(rangeToReplace.fullRange(in: textInputStorage), with: newText)The error is: "String index is out of bounds", because |
|
How could I test the Japanese behavior here? Alternatively, what is the value of startPosition? I wonder if just being defensive about that, making sure that beginIndex..<endIndex is within the range of the baseString is enough. Because what is happening is that the startPosition is out of sync with the request. startPosition is something that UIKit asks us to create. |
|
The easiest way to check for yourself for Japanese crash is to insert this snippet between lines 1110 and 1111 of else {
// resetInputBuffer is *required* for Tiếng Việt Telex and Korean keyboards
// it causes a crash with Japanese keyboards.
if let keyboardLanguage = self.textInputMode?.primaryLanguage {
if (keyboardLanguage.hasPrefix("vi") || keyboardLanguage.hasPrefix("ko") || keyboardLanguage.hasPrefix("ja")) {
resetInputBuffer()
}
}
self.send(txt: text)
} |
|
Could you try this patch? I tried using the Vietnamese telex keyboard and it works: https://gist.github.com/migueldeicaza/30c3a5e47ef64192127478eb0654e060 This works with the scenario you showed above for Vietnamese Telex, with a couple of caveats:
|
|
I'm going to try the patch. In my experiments, letter+s turning into accented letter is relatively robust (it happens all the time), but dd is more fragile: without the call to |
|
The last |
|
Ah yes, thank you, that was a mistake on my end (I pasted in the wrong buffer). Here are the results of my tests:
|
|
Ok, I can not seem to trick UITextInput into not composing the next value, despite repeated efforts. I instrumented the code, and I can not see in the logs the input method system using After "우" there is no replace sequence triggered with selectedTextRange -> deleteBackward -> insertText before I think that I will accept the band-aid at this point, but likely on top of the patch I pasted above. |
This is an alterantive to the proposal in #418 which was a follow up to #409 Rather than special casing the keyboards that way, this improves the existing UITextInput handling and it improves the chinese, japanese and vietnamese output - but still fails with Korean. I could not figure out why iOS refuses to let me participate in the composition of text, even if the system seems to do just fine on its own (like native UITextFields). In particular this problem as documented by Nicolas: > Korean input: ㅇ followed by ㅜ produces 우 (as expected), but ㅇ ㅜ ㅇ produces 우ㅇ instead of 웅. So for Korean, I add a dreaded special case.
|
Can you try the branch |
|
The branch As you say, it would be great if those protocols were actually documented. It's insane that the same code works for Tiếng Việt Telex and doesn't work for Korean. |
This is an alterantive to the proposal in #418 which was a follow up to #409 Rather than special casing the keyboards that way, this improves the existing UITextInput handling and it improves the chinese, japanese and vietnamese output - but still fails with Korean. I could not figure out why iOS refuses to let me participate in the composition of text, even if the system seems to do just fine on its own (like native UITextFields). In particular this problem as documented by Nicolas: > Korean input: ㅇ followed by ㅜ produces 우 (as expected), but ㅇ ㅜ ㅇ produces 우ㅇ instead of 웅. So for Korean, I add a dreaded special case.
|
Ok merged the alternative. |
This is an alterantive to the proposal in migueldeicaza#418 which was a follow up to migueldeicaza#409 Rather than special casing the keyboards that way, this improves the existing UITextInput handling and it improves the chinese, japanese and vietnamese output - but still fails with Korean. I could not figure out why iOS refuses to let me participate in the composition of text, even if the system seems to do just fine on its own (like native UITextFields). In particular this problem as documented by Nicolas: > Korean input: ㅇ followed by ㅜ produces 우 (as expected), but ㅇ ㅜ ㅇ produces 우ㅇ instead of 웅. So for Korean, I add a dreaded special case.
This is an alterantive to the proposal in migueldeicaza#418 which was a follow up to migueldeicaza#409 Rather than special casing the keyboards that way, this improves the existing UITextInput handling and it improves the chinese, japanese and vietnamese output - but still fails with Korean. I could not figure out why iOS refuses to let me participate in the composition of text, even if the system seems to do just fine on its own (like native UITextFields). In particular this problem as documented by Nicolas: > Korean input: ㅇ followed by ㅜ produces 우 (as expected), but ㅇ ㅜ ㅇ produces 우ㅇ instead of 웅. So for Korean, I add a dreaded special case.

These changes improve upon PR #409 in the following way:
allow Vietnamese keyboard input (Tiếng Việt Telex). To test:
improve Korean keybard input. To test:
The way these work is by calling
resetInputBuffer()after every text insertion ininsertText(), but only for Vietnamese and Korean keyboards. I tried enabling it for other multi-char keyboards (Japanese), but it causes a crash elsewhere (which may be due to a different issue, but we'll deal with it later).