Browse Source

Merge pull request #69966 from bruvzg/ios_fix_single_line_input_and_offsets

[iOS] Fix broken single line input and incorrect selection / caret position.
Rémi Verschelde 2 years ago
parent
commit
8ab653c7ea

+ 1 - 1
platform/ios/display_server_ios.h

@@ -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
 
 

+ 14 - 4
platform/ios/display_server_ios.mm

@@ -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
-								 cursorEnd:p_cursor_end];
+							   cursorStart:_convert_utf32_offset_to_utf16(p_existing_text, p_cursor_start)
+								 cursorEnd:_convert_utf32_offset_to_utf16(p_existing_text, p_cursor_end)];
 }
 }
 
 
 void DisplayServerIOS::virtual_keyboard_hide() {
 void DisplayServerIOS::virtual_keyboard_hide() {

+ 22 - 14
platform/ios/keyboard_input_view.mm

@@ -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, false);
+		DisplayServerIOS::get_singleton()->key(Key::BACKSPACE, 0, true);
+		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];
-
-		switch (character) {
-			case 10:
-				character = (int)Key::ENTER;
-				break;
-			case 8198:
-				character = (int)Key::SPACE;
-				break;
-			default:
-				break;
+		Key key = Key::NONE;
+
+		if (character == '\t') { // 0x09
+			key = Key::TAB;
+		} else if (character == '\n') { // 0x0A
+			key = Key::ENTER;
+		} else if (character == 0x2006) {
+			key = Key::SPACE;
+		} else if (character == U'¥') {
+			key = Key::YEN;
+		} 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, false);
+		DisplayServerIOS::get_singleton()->key(key, character, true);
+		DisplayServerIOS::get_singleton()->key(key, character, false);
 	}
 	}
 }
 }