Browse Source

Merge pull request #40487 from nekomatata/virtual-keyboard-enter-fixes

Fix Return key events in LineEdit & TextEdit on Android
Rémi Verschelde 5 years ago
parent
commit
b19b896e06

+ 15 - 3
doc/classes/DisplayServer.xml

@@ -627,12 +627,14 @@
 			<return type="int">
 			<return type="int">
 			</return>
 			</return>
 			<description>
 			<description>
+				Returns the on-screen keyboard's height in pixels. Returns 0 if there is no keyboard or if it is currently hidden.
 			</description>
 			</description>
 		</method>
 		</method>
 		<method name="virtual_keyboard_hide">
 		<method name="virtual_keyboard_hide">
 			<return type="void">
 			<return type="void">
 			</return>
 			</return>
 			<description>
 			<description>
+				Hides the virtual keyboard if it is shown, does nothing otherwise.
 			</description>
 			</description>
 		</method>
 		</method>
 		<method name="virtual_keyboard_show">
 		<method name="virtual_keyboard_show">
@@ -642,13 +644,23 @@
 			</argument>
 			</argument>
 			<argument index="1" name="position" type="Rect2" default="Rect2i( 0, 0, 0, 0 )">
 			<argument index="1" name="position" type="Rect2" default="Rect2i( 0, 0, 0, 0 )">
 			</argument>
 			</argument>
-			<argument index="2" name="max_length" type="int" default="-1">
+			<argument index="2" name="multiline" type="bool" default="false">
 			</argument>
 			</argument>
-			<argument index="3" name="cursor_start" type="int" default="-1">
+			<argument index="3" name="max_length" type="int" default="-1">
 			</argument>
 			</argument>
-			<argument index="4" name="cursor_end" type="int" default="-1">
+			<argument index="4" name="cursor_start" type="int" default="-1">
+			</argument>
+			<argument index="5" name="cursor_end" type="int" default="-1">
 			</argument>
 			</argument>
 			<description>
 			<description>
+				Shows the virtual keyboard if the platform has one.
+				[code]existing_text[/code] parameter is useful for implementing your own [LineEdit] or [TextEdit], as it tells the virtual keyboard what text has already been typed (the virtual keyboard uses it for auto-correct and predictions).
+				[code]position[/code] parameter is the screen space [Rect2] of the edited text.
+				[code]multiline[/code] parameter needs to be set to [code]true[/code] to be able to enter multiple lines of text, as in [TextEdit].
+				[code]max_length[/code] limits the number of characters that can be entered if different from [code]-1[/code].
+				[code]cursor_start[/code] can optionally define the current text cursor position if [code]cursor_end[/code] is not set.
+				[code]cursor_start[/code] and [code]cursor_end[/code] can optionally define the current text selection.
+				[b]Note:[/b] This method is implemented on Android, iOS and UWP.
 			</description>
 			</description>
 		</method>
 		</method>
 		<method name="vsync_is_enabled" qualifiers="const">
 		<method name="vsync_is_enabled" qualifiers="const">

+ 2 - 2
platform/android/display_server_android.cpp

@@ -155,12 +155,12 @@ bool DisplayServerAndroid::screen_is_touchscreen(int p_screen) const {
 	return true;
 	return true;
 }
 }
 
 
-void DisplayServerAndroid::virtual_keyboard_show(const String &p_existing_text, const Rect2 &p_screen_rect, int p_max_length, int p_cursor_start, int p_cursor_end) {
+void DisplayServerAndroid::virtual_keyboard_show(const String &p_existing_text, const Rect2 &p_screen_rect, bool p_multiline, int p_max_length, int p_cursor_start, int p_cursor_end) {
 	GodotIOJavaWrapper *godot_io_java = OS_Android::get_singleton()->get_godot_io_java();
 	GodotIOJavaWrapper *godot_io_java = OS_Android::get_singleton()->get_godot_io_java();
 	ERR_FAIL_COND(!godot_io_java);
 	ERR_FAIL_COND(!godot_io_java);
 
 
 	if (godot_io_java->has_vk()) {
 	if (godot_io_java->has_vk()) {
-		godot_io_java->show_vk(p_existing_text, p_max_length, p_cursor_start, p_cursor_end);
+		godot_io_java->show_vk(p_existing_text, p_multiline, p_max_length, p_cursor_start, p_cursor_end);
 	} else {
 	} else {
 		ERR_PRINT("Virtual keyboard not available");
 		ERR_PRINT("Virtual keyboard not available");
 	}
 	}

+ 1 - 1
platform/android/display_server_android.h

@@ -113,7 +113,7 @@ public:
 	virtual int screen_get_dpi(int p_screen = SCREEN_OF_MAIN_WINDOW) const;
 	virtual int screen_get_dpi(int p_screen = SCREEN_OF_MAIN_WINDOW) const;
 	virtual bool screen_is_touchscreen(int p_screen = SCREEN_OF_MAIN_WINDOW) const;
 	virtual bool screen_is_touchscreen(int p_screen = SCREEN_OF_MAIN_WINDOW) const;
 
 
-	virtual void virtual_keyboard_show(const String &p_existing_text, const Rect2 &p_screen_rect = Rect2(), int p_max_length = -1, int p_cursor_start = -1, int p_cursor_end = -1);
+	virtual void virtual_keyboard_show(const String &p_existing_text, const Rect2 &p_screen_rect = Rect2(), bool p_multiline = false, int p_max_length = -1, int p_cursor_start = -1, int p_cursor_end = -1);
 	virtual void virtual_keyboard_hide();
 	virtual void virtual_keyboard_hide();
 	virtual int virtual_keyboard_get_height() const;
 	virtual int virtual_keyboard_get_height() const;
 
 

+ 2 - 2
platform/android/java/lib/src/org/godotengine/godot/GodotIO.java

@@ -461,9 +461,9 @@ public class GodotIO {
 		return (int)(metrics.density * 160f);
 		return (int)(metrics.density * 160f);
 	}
 	}
 
 
-	public void showKeyboard(String p_existing_text, int p_max_input_length, int p_cursor_start, int p_cursor_end) {
+	public void showKeyboard(String p_existing_text, boolean p_multiline, int p_max_input_length, int p_cursor_start, int p_cursor_end) {
 		if (edit != null)
 		if (edit != null)
-			edit.showKeyboard(p_existing_text, p_max_input_length, p_cursor_start, p_cursor_end);
+			edit.showKeyboard(p_existing_text, p_multiline, p_max_input_length, p_cursor_start, p_cursor_end);
 
 
 		//InputMethodManager inputMgr = (InputMethodManager)activity.getSystemService(Context.INPUT_METHOD_SERVICE);
 		//InputMethodManager inputMgr = (InputMethodManager)activity.getSystemService(Context.INPUT_METHOD_SERVICE);
 		//inputMgr.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0);
 		//inputMgr.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0);

+ 17 - 3
platform/android/java/lib/src/org/godotengine/godot/input/GodotEditText.java

@@ -36,6 +36,7 @@ import android.content.Context;
 import android.os.Handler;
 import android.os.Handler;
 import android.os.Message;
 import android.os.Message;
 import android.text.InputFilter;
 import android.text.InputFilter;
+import android.text.InputType;
 import android.util.AttributeSet;
 import android.util.AttributeSet;
 import android.view.KeyEvent;
 import android.view.KeyEvent;
 import android.view.inputmethod.EditorInfo;
 import android.view.inputmethod.EditorInfo;
@@ -58,7 +59,8 @@ public class GodotEditText extends EditText {
 	private GodotTextInputWrapper mInputWrapper;
 	private GodotTextInputWrapper mInputWrapper;
 	private EditHandler sHandler = new EditHandler(this);
 	private EditHandler sHandler = new EditHandler(this);
 	private String mOriginText;
 	private String mOriginText;
-	private int mMaxInputLength;
+	private int mMaxInputLength = Integer.MAX_VALUE;
+	private boolean mMultiline = false;
 
 
 	private static class EditHandler extends Handler {
 	private static class EditHandler extends Handler {
 		private final WeakReference<GodotEditText> mEdit;
 		private final WeakReference<GodotEditText> mEdit;
@@ -95,7 +97,11 @@ public class GodotEditText extends EditText {
 
 
 	protected void initView() {
 	protected void initView() {
 		setPadding(0, 0, 0, 0);
 		setPadding(0, 0, 0, 0);
-		setImeOptions(EditorInfo.IME_FLAG_NO_EXTRACT_UI);
+		setImeOptions(EditorInfo.IME_FLAG_NO_EXTRACT_UI | EditorInfo.IME_ACTION_DONE);
+	}
+
+	public boolean isMultiline() {
+		return mMultiline;
 	}
 	}
 
 
 	private void handleMessage(final Message msg) {
 	private void handleMessage(final Message msg) {
@@ -115,6 +121,12 @@ public class GodotEditText extends EditText {
 						edit.mInputWrapper.setSelection(false);
 						edit.mInputWrapper.setSelection(false);
 					}
 					}
 
 
+					int inputType = InputType.TYPE_CLASS_TEXT;
+					if (edit.isMultiline()) {
+						inputType |= InputType.TYPE_TEXT_FLAG_MULTI_LINE;
+					}
+					edit.setInputType(inputType);
+
 					edit.mInputWrapper.setOriginText(text);
 					edit.mInputWrapper.setOriginText(text);
 					edit.addTextChangedListener(edit.mInputWrapper);
 					edit.addTextChangedListener(edit.mInputWrapper);
 					final InputMethodManager imm = (InputMethodManager)mRenderView.getView().getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
 					final InputMethodManager imm = (InputMethodManager)mRenderView.getView().getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
@@ -189,7 +201,7 @@ public class GodotEditText extends EditText {
 	// ===========================================================
 	// ===========================================================
 	// Methods
 	// Methods
 	// ===========================================================
 	// ===========================================================
-	public void showKeyboard(String p_existing_text, int p_max_input_length, int p_cursor_start, int p_cursor_end) {
+	public void showKeyboard(String p_existing_text, boolean p_multiline, int p_max_input_length, int p_cursor_start, int p_cursor_end) {
 		int maxInputLength = (p_max_input_length <= 0) ? Integer.MAX_VALUE : p_max_input_length;
 		int maxInputLength = (p_max_input_length <= 0) ? Integer.MAX_VALUE : p_max_input_length;
 		if (p_cursor_start == -1) { // cursor position not given
 		if (p_cursor_start == -1) { // cursor position not given
 			this.mOriginText = p_existing_text;
 			this.mOriginText = p_existing_text;
@@ -202,6 +214,8 @@ public class GodotEditText extends EditText {
 			this.mMaxInputLength = maxInputLength - (p_existing_text.length() - p_cursor_end);
 			this.mMaxInputLength = maxInputLength - (p_existing_text.length() - p_cursor_end);
 		}
 		}
 
 
+		this.mMultiline = p_multiline;
+
 		final Message msg = new Message();
 		final Message msg = new Message();
 		msg.what = HANDLER_OPEN_IME_KEYBOARD;
 		msg.what = HANDLER_OPEN_IME_KEYBOARD;
 		msg.obj = this;
 		msg.obj = this;

+ 2 - 2
platform/android/java/lib/src/org/godotengine/godot/input/GodotTextInputWrapper.java

@@ -123,7 +123,7 @@ public class GodotTextInputWrapper implements TextWatcher, OnEditorActionListene
 			public void run() {
 			public void run() {
 				for (int i = 0; i < count; ++i) {
 				for (int i = 0; i < count; ++i) {
 					int key = newChars[i];
 					int key = newChars[i];
-					if (key == '\n') {
+					if ((key == '\n') && !mEdit.isMultiline()) {
 						// Return keys are handled through action events
 						// Return keys are handled through action events
 						continue;
 						continue;
 					}
 					}
@@ -151,7 +151,7 @@ public class GodotTextInputWrapper implements TextWatcher, OnEditorActionListene
 			});
 			});
 		}
 		}
 
 
-		if (pActionID == EditorInfo.IME_NULL) {
+		if (pActionID == EditorInfo.IME_ACTION_DONE) {
 			// Enter key has been pressed
 			// Enter key has been pressed
 			GodotLib.key(KeyEvent.KEYCODE_ENTER, KeyEvent.KEYCODE_ENTER, 0, true);
 			GodotLib.key(KeyEvent.KEYCODE_ENTER, KeyEvent.KEYCODE_ENTER, 0, true);
 			GodotLib.key(KeyEvent.KEYCODE_ENTER, KeyEvent.KEYCODE_ENTER, 0, false);
 			GodotLib.key(KeyEvent.KEYCODE_ENTER, KeyEvent.KEYCODE_ENTER, 0, false);

+ 3 - 3
platform/android/java_godot_io_wrapper.cpp

@@ -53,7 +53,7 @@ GodotIOJavaWrapper::GodotIOJavaWrapper(JNIEnv *p_env, jobject p_godot_io_instanc
 		_get_model = p_env->GetMethodID(cls, "getModel", "()Ljava/lang/String;");
 		_get_model = p_env->GetMethodID(cls, "getModel", "()Ljava/lang/String;");
 		_get_screen_DPI = p_env->GetMethodID(cls, "getScreenDPI", "()I");
 		_get_screen_DPI = p_env->GetMethodID(cls, "getScreenDPI", "()I");
 		_get_unique_id = p_env->GetMethodID(cls, "getUniqueID", "()Ljava/lang/String;");
 		_get_unique_id = p_env->GetMethodID(cls, "getUniqueID", "()Ljava/lang/String;");
-		_show_keyboard = p_env->GetMethodID(cls, "showKeyboard", "(Ljava/lang/String;III)V");
+		_show_keyboard = p_env->GetMethodID(cls, "showKeyboard", "(Ljava/lang/String;ZIII)V");
 		_hide_keyboard = p_env->GetMethodID(cls, "hideKeyboard", "()V");
 		_hide_keyboard = p_env->GetMethodID(cls, "hideKeyboard", "()V");
 		_set_screen_orientation = p_env->GetMethodID(cls, "setScreenOrientation", "(I)V");
 		_set_screen_orientation = p_env->GetMethodID(cls, "setScreenOrientation", "(I)V");
 		_get_screen_orientation = p_env->GetMethodID(cls, "getScreenOrientation", "()I");
 		_get_screen_orientation = p_env->GetMethodID(cls, "getScreenOrientation", "()I");
@@ -132,11 +132,11 @@ bool GodotIOJavaWrapper::has_vk() {
 	return (_show_keyboard != 0) && (_hide_keyboard != 0);
 	return (_show_keyboard != 0) && (_hide_keyboard != 0);
 }
 }
 
 
-void GodotIOJavaWrapper::show_vk(const String &p_existing, int p_max_input_length, int p_cursor_start, int p_cursor_end) {
+void GodotIOJavaWrapper::show_vk(const String &p_existing, bool p_multiline, int p_max_input_length, int p_cursor_start, int p_cursor_end) {
 	if (_show_keyboard) {
 	if (_show_keyboard) {
 		JNIEnv *env = ThreadAndroid::get_env();
 		JNIEnv *env = ThreadAndroid::get_env();
 		jstring jStr = env->NewStringUTF(p_existing.utf8().get_data());
 		jstring jStr = env->NewStringUTF(p_existing.utf8().get_data());
-		env->CallVoidMethod(godot_io_instance, _show_keyboard, jStr, p_max_input_length, p_cursor_start, p_cursor_end);
+		env->CallVoidMethod(godot_io_instance, _show_keyboard, jStr, p_multiline, p_max_input_length, p_cursor_start, p_cursor_end);
 	}
 	}
 }
 }
 
 

+ 1 - 1
platform/android/java_godot_io_wrapper.h

@@ -70,7 +70,7 @@ public:
 	int get_screen_dpi();
 	int get_screen_dpi();
 	String get_unique_id();
 	String get_unique_id();
 	bool has_vk();
 	bool has_vk();
-	void show_vk(const String &p_existing, int p_max_input_length, int p_cursor_start, int p_cursor_end);
+	void show_vk(const String &p_existing, bool p_multiline, int p_max_input_length, int p_cursor_start, int p_cursor_end);
 	void hide_vk();
 	void hide_vk();
 	int get_vk_height();
 	int get_vk_height();
 	void set_vk_height(int p_height);
 	void set_vk_height(int p_height);

+ 1 - 1
platform/iphone/display_server_iphone.h

@@ -178,7 +178,7 @@ public:
 
 
 	virtual bool screen_is_touchscreen(int p_screen) const override;
 	virtual bool screen_is_touchscreen(int p_screen) const override;
 
 
-	virtual void virtual_keyboard_show(const String &p_existing_text, const Rect2 &p_screen_rect, int p_max_length, int p_cursor_start, int p_cursor_end) override;
+	virtual void virtual_keyboard_show(const String &p_existing_text, const Rect2 &p_screen_rect, bool p_multiline, int p_max_length, int p_cursor_start, int p_cursor_end) override;
 	virtual void virtual_keyboard_hide() override;
 	virtual void virtual_keyboard_hide() override;
 
 
 	void virtual_keyboard_set_height(int height);
 	void virtual_keyboard_set_height(int height);

+ 1 - 1
platform/iphone/display_server_iphone.mm

@@ -638,7 +638,7 @@ bool DisplayServerIPhone::screen_is_touchscreen(int p_screen) const {
 	return true;
 	return true;
 }
 }
 
 
-void DisplayServerIPhone::virtual_keyboard_show(const String &p_existing_text, const Rect2 &p_screen_rect, int p_max_length, int p_cursor_start, int p_cursor_end) {
+void DisplayServerIPhone::virtual_keyboard_show(const String &p_existing_text, const Rect2 &p_screen_rect, bool p_multiline, int p_max_length, int p_cursor_start, int p_cursor_end) {
 	[AppDelegate.viewController.godotView becomeFirstResponderWithString:p_existing_text];
 	[AppDelegate.viewController.godotView becomeFirstResponderWithString:p_existing_text];
 }
 }
 
 

+ 1 - 1
platform/uwp/os_uwp.cpp

@@ -715,7 +715,7 @@ bool OS_UWP::has_virtual_keyboard() const {
 	return UIViewSettings::GetForCurrentView()->UserInteractionMode == UserInteractionMode::Touch;
 	return UIViewSettings::GetForCurrentView()->UserInteractionMode == UserInteractionMode::Touch;
 }
 }
 
 
-void OS_UWP::show_virtual_keyboard(const String &p_existing_text, const Rect2 &p_screen_rect, int p_max_input_length, int p_cursor_start, int p_cursor_end) {
+void OS_UWP::show_virtual_keyboard(const String &p_existing_text, const Rect2 &p_screen_rect, bool p_multiline, int p_max_input_length, int p_cursor_start, int p_cursor_end) {
 	InputPane ^ pane = InputPane::GetForCurrentView();
 	InputPane ^ pane = InputPane::GetForCurrentView();
 	pane->TryShow();
 	pane->TryShow();
 }
 }

+ 1 - 1
platform/uwp/os_uwp.h

@@ -234,7 +234,7 @@ public:
 	virtual bool has_touchscreen_ui_hint() const;
 	virtual bool has_touchscreen_ui_hint() const;
 
 
 	virtual bool has_virtual_keyboard() const;
 	virtual bool has_virtual_keyboard() const;
-	virtual void show_virtual_keyboard(const String &p_existing_text, const Rect2 &p_screen_rect = Rect2(), int p_max_input_length = -1, int p_cursor_start = -1, int p_cursor_end = -1);
+	virtual void show_virtual_keyboard(const String &p_existing_text, const Rect2 &p_screen_rect = Rect2(), bool p_multiline = false, int p_max_input_length = -1, int p_cursor_start = -1, int p_cursor_end = -1);
 	virtual void hide_virtual_keyboard();
 	virtual void hide_virtual_keyboard();
 
 
 	virtual Error open_dynamic_library(const String p_path, void *&p_library_handle, bool p_also_set_library_path = false);
 	virtual Error open_dynamic_library(const String p_path, void *&p_library_handle, bool p_also_set_library_path = false);

+ 5 - 4
scene/gui/line_edit.cpp

@@ -120,9 +120,9 @@ void LineEdit::_gui_input(Ref<InputEvent> p_event) {
 
 
 			if (DisplayServer::get_singleton()->has_feature(DisplayServer::FEATURE_VIRTUAL_KEYBOARD) && virtual_keyboard_enabled) {
 			if (DisplayServer::get_singleton()->has_feature(DisplayServer::FEATURE_VIRTUAL_KEYBOARD) && virtual_keyboard_enabled) {
 				if (selection.enabled) {
 				if (selection.enabled) {
-					DisplayServer::get_singleton()->virtual_keyboard_show(text, get_global_rect(), max_length, selection.begin, selection.end);
+					DisplayServer::get_singleton()->virtual_keyboard_show(text, get_global_rect(), false, max_length, selection.begin, selection.end);
 				} else {
 				} else {
-					DisplayServer::get_singleton()->virtual_keyboard_show(text, get_global_rect(), max_length, cursor_pos);
+					DisplayServer::get_singleton()->virtual_keyboard_show(text, get_global_rect(), false, max_length, cursor_pos);
 				}
 				}
 			}
 			}
 		}
 		}
@@ -313,6 +313,7 @@ void LineEdit::_gui_input(Ref<InputEvent> p_event) {
 						DisplayServer::get_singleton()->virtual_keyboard_hide();
 						DisplayServer::get_singleton()->virtual_keyboard_hide();
 					}
 					}
 
 
+					return;
 				} break;
 				} break;
 
 
 				case KEY_BACKSPACE: {
 				case KEY_BACKSPACE: {
@@ -943,9 +944,9 @@ void LineEdit::_notification(int p_what) {
 
 
 			if (DisplayServer::get_singleton()->has_feature(DisplayServer::FEATURE_VIRTUAL_KEYBOARD) && virtual_keyboard_enabled) {
 			if (DisplayServer::get_singleton()->has_feature(DisplayServer::FEATURE_VIRTUAL_KEYBOARD) && virtual_keyboard_enabled) {
 				if (selection.enabled) {
 				if (selection.enabled) {
-					DisplayServer::get_singleton()->virtual_keyboard_show(text, get_global_rect(), max_length, selection.begin, selection.end);
+					DisplayServer::get_singleton()->virtual_keyboard_show(text, get_global_rect(), false, max_length, selection.begin, selection.end);
 				} else {
 				} else {
-					DisplayServer::get_singleton()->virtual_keyboard_show(text, get_global_rect(), max_length, cursor_pos);
+					DisplayServer::get_singleton()->virtual_keyboard_show(text, get_global_rect(), false, max_length, cursor_pos);
 				}
 				}
 			}
 			}
 
 

+ 1 - 1
scene/gui/text_edit.cpp

@@ -1632,7 +1632,7 @@ void TextEdit::_notification(int p_what) {
 			}
 			}
 
 
 			if (DisplayServer::get_singleton()->has_feature(DisplayServer::FEATURE_VIRTUAL_KEYBOARD)) {
 			if (DisplayServer::get_singleton()->has_feature(DisplayServer::FEATURE_VIRTUAL_KEYBOARD)) {
-				DisplayServer::get_singleton()->virtual_keyboard_show(get_text(), get_global_rect());
+				DisplayServer::get_singleton()->virtual_keyboard_show(get_text(), get_global_rect(), true);
 			}
 			}
 		} break;
 		} break;
 		case NOTIFICATION_FOCUS_EXIT: {
 		case NOTIFICATION_FOCUS_EXIT: {

+ 3 - 2
servers/display_server.cpp

@@ -31,6 +31,7 @@
 #include "display_server.h"
 #include "display_server.h"
 
 
 #include "core/input/input.h"
 #include "core/input/input.h"
+#include "core/method_bind_ext.gen.inc"
 #include "scene/resources/texture.h"
 #include "scene/resources/texture.h"
 
 
 DisplayServer *DisplayServer::singleton = nullptr;
 DisplayServer *DisplayServer::singleton = nullptr;
@@ -217,7 +218,7 @@ bool DisplayServer::is_console_visible() const {
 	return false;
 	return false;
 }
 }
 
 
-void DisplayServer::virtual_keyboard_show(const String &p_existing_text, const Rect2 &p_screen_rect, int p_max_length, int p_cursor_start, int p_cursor_end) {
+void DisplayServer::virtual_keyboard_show(const String &p_existing_text, const Rect2 &p_screen_rect, bool p_multiline, int p_max_length, int p_cursor_start, int p_cursor_end) {
 	WARN_PRINT("Virtual keyboard not supported by this display server.");
 	WARN_PRINT("Virtual keyboard not supported by this display server.");
 }
 }
 
 
@@ -459,7 +460,7 @@ void DisplayServer::_bind_methods() {
 	ClassDB::bind_method(D_METHOD("console_set_visible", "console_visible"), &DisplayServer::console_set_visible);
 	ClassDB::bind_method(D_METHOD("console_set_visible", "console_visible"), &DisplayServer::console_set_visible);
 	ClassDB::bind_method(D_METHOD("is_console_visible"), &DisplayServer::is_console_visible);
 	ClassDB::bind_method(D_METHOD("is_console_visible"), &DisplayServer::is_console_visible);
 
 
-	ClassDB::bind_method(D_METHOD("virtual_keyboard_show", "existing_text", "position", "max_length", "cursor_start", "cursor_end"), &DisplayServer::virtual_keyboard_show, DEFVAL(Rect2i()), DEFVAL(-1), DEFVAL(-1), DEFVAL(-1));
+	ClassDB::bind_method(D_METHOD("virtual_keyboard_show", "existing_text", "position", "multiline", "max_length", "cursor_start", "cursor_end"), &DisplayServer::virtual_keyboard_show, DEFVAL(Rect2i()), DEFVAL(false), DEFVAL(-1), DEFVAL(-1), DEFVAL(-1));
 	ClassDB::bind_method(D_METHOD("virtual_keyboard_hide"), &DisplayServer::virtual_keyboard_hide);
 	ClassDB::bind_method(D_METHOD("virtual_keyboard_hide"), &DisplayServer::virtual_keyboard_hide);
 
 
 	ClassDB::bind_method(D_METHOD("virtual_keyboard_get_height"), &DisplayServer::virtual_keyboard_get_height);
 	ClassDB::bind_method(D_METHOD("virtual_keyboard_get_height"), &DisplayServer::virtual_keyboard_get_height);

+ 1 - 1
servers/display_server.h

@@ -289,7 +289,7 @@ public:
 	virtual void console_set_visible(bool p_enabled);
 	virtual void console_set_visible(bool p_enabled);
 	virtual bool is_console_visible() const;
 	virtual bool is_console_visible() const;
 
 
-	virtual void virtual_keyboard_show(const String &p_existing_text, const Rect2 &p_screen_rect = Rect2(), int p_max_length = -1, int p_cursor_start = -1, int p_cursor_end = -1);
+	virtual void virtual_keyboard_show(const String &p_existing_text, const Rect2 &p_screen_rect = Rect2(), bool p_multiline = false, int p_max_length = -1, int p_cursor_start = -1, int p_cursor_end = -1);
 	virtual void virtual_keyboard_hide();
 	virtual void virtual_keyboard_hide();
 
 
 	// returns height of the currently shown virtual keyboard (0 if keyboard is hidden)
 	// returns height of the currently shown virtual keyboard (0 if keyboard is hidden)