Merge pull request #69966 from bruvzg/ios_fix_single_line_input_and_offsets

[iOS] Fix broken single line input and incorrect selection / caret position.
This commit is contained in:
Rémi Verschelde
2022-12-12 17:30:11 +01:00
3 changed files with 36 additions and 18 deletions

View File

@@ -113,7 +113,7 @@ public:
// MARK: Keyboard // MARK: Keyboard
void key(Key p_key, bool p_pressed); void key(Key p_key, char32_t p_char, bool p_pressed);
// MARK: Motion // MARK: Motion

View File

@@ -260,14 +260,14 @@ void DisplayServerIOS::touches_cancelled(int p_idx) {
// MARK: Keyboard // MARK: Keyboard
void DisplayServerIOS::key(Key p_key, bool p_pressed) { void DisplayServerIOS::key(Key p_key, char32_t p_char, bool p_pressed) {
Ref<InputEventKey> ev; Ref<InputEventKey> ev;
ev.instantiate(); ev.instantiate();
ev->set_echo(false); ev->set_echo(false);
ev->set_pressed(p_pressed); ev->set_pressed(p_pressed);
ev->set_keycode(p_key); ev->set_keycode(p_key);
ev->set_physical_keycode(p_key); ev->set_physical_keycode(p_key);
ev->set_unicode((char32_t)p_key); ev->set_unicode(p_char);
perform_event(ev); perform_event(ev);
} }
@@ -589,6 +589,16 @@ bool DisplayServerIOS::is_touchscreen_available() const {
return true; return true;
} }
_FORCE_INLINE_ int _convert_utf32_offset_to_utf16(const String &p_existing_text, int p_pos) {
int limit = p_pos;
for (int i = 0; i < MIN(p_existing_text.length(), p_pos); i++) {
if (p_existing_text[i] > 0xffff) {
limit++;
}
}
return limit;
}
void DisplayServerIOS::virtual_keyboard_show(const String &p_existing_text, const Rect2 &p_screen_rect, VirtualKeyboardType p_type, int p_max_length, int p_cursor_start, int p_cursor_end) { void DisplayServerIOS::virtual_keyboard_show(const String &p_existing_text, const Rect2 &p_screen_rect, VirtualKeyboardType p_type, int p_max_length, int p_cursor_start, int p_cursor_end) {
NSString *existingString = [[NSString alloc] initWithUTF8String:p_existing_text.utf8().get_data()]; NSString *existingString = [[NSString alloc] initWithUTF8String:p_existing_text.utf8().get_data()];
@@ -627,8 +637,8 @@ void DisplayServerIOS::virtual_keyboard_show(const String &p_existing_text, cons
[AppDelegate.viewController.keyboardView [AppDelegate.viewController.keyboardView
becomeFirstResponderWithString:existingString becomeFirstResponderWithString:existingString
cursorStart:p_cursor_start cursorStart:_convert_utf32_offset_to_utf16(p_existing_text, p_cursor_start)
cursorEnd:p_cursor_end]; cursorEnd:_convert_utf32_offset_to_utf16(p_existing_text, p_cursor_end)];
} }
void DisplayServerIOS::virtual_keyboard_hide() { void DisplayServerIOS::virtual_keyboard_hide() {

View File

@@ -115,8 +115,8 @@
- (void)deleteText:(NSInteger)charactersToDelete { - (void)deleteText:(NSInteger)charactersToDelete {
for (int i = 0; i < charactersToDelete; i++) { for (int i = 0; i < charactersToDelete; i++) {
DisplayServerIOS::get_singleton()->key(Key::BACKSPACE, true); DisplayServerIOS::get_singleton()->key(Key::BACKSPACE, 0, true);
DisplayServerIOS::get_singleton()->key(Key::BACKSPACE, false); DisplayServerIOS::get_singleton()->key(Key::BACKSPACE, 0, false);
} }
} }
@@ -126,20 +126,28 @@
for (int i = 0; i < characters.size(); i++) { for (int i = 0; i < characters.size(); i++) {
int character = characters[i]; int character = characters[i];
Key key = Key::NONE;
switch (character) { if (character == '\t') { // 0x09
case 10: key = Key::TAB;
character = (int)Key::ENTER; } else if (character == '\n') { // 0x0A
break; key = Key::ENTER;
case 8198: } else if (character == 0x2006) {
character = (int)Key::SPACE; key = Key::SPACE;
break; } else if (character == U'¥') {
default: key = Key::YEN;
break; } else if (character == U'§') {
key = Key::SECTION;
} else if (character >= 0x20 && character <= 0x7E) { // ASCII.
if (character > 0x60 && character < 0x7B) { // Lowercase ASCII.
key = (Key)(character - 32);
} else {
key = (Key)character;
}
} }
DisplayServerIOS::get_singleton()->key((Key)character, true); DisplayServerIOS::get_singleton()->key(key, character, true);
DisplayServerIOS::get_singleton()->key((Key)character, false); DisplayServerIOS::get_singleton()->key(key, character, false);
} }
} }