Browse Source

[DisplayServer] Implement has_hardware_keyboard method for Android and iOS.

bruvzg 10 months ago
parent
commit
25f439c573

+ 7 - 0
doc/classes/DisplayServer.xml

@@ -893,6 +893,13 @@
 				Returns [code]true[/code] if the specified [param feature] is supported by the current [DisplayServer], [code]false[/code] otherwise.
 				Returns [code]true[/code] if the specified [param feature] is supported by the current [DisplayServer], [code]false[/code] otherwise.
 			</description>
 			</description>
 		</method>
 		</method>
+		<method name="has_hardware_keyboard" qualifiers="const">
+			<return type="bool" />
+			<description>
+				Returns [code]true[/code] if hardware keyboard is connected.
+				[b]Note:[/b] This method is implemented on Android and iOS, on other platforms this method always returns [code]true[/code].
+			</description>
+		</method>
 		<method name="help_set_search_callbacks">
 		<method name="help_set_search_callbacks">
 			<return type="void" />
 			<return type="void" />
 			<param index="0" name="search_callback" type="Callable" />
 			<param index="0" name="search_callback" type="Callable" />

+ 7 - 0
platform/android/display_server_android.cpp

@@ -304,6 +304,13 @@ int DisplayServerAndroid::virtual_keyboard_get_height() const {
 	return godot_io_java->get_vk_height();
 	return godot_io_java->get_vk_height();
 }
 }
 
 
+bool DisplayServerAndroid::has_hardware_keyboard() const {
+	GodotIOJavaWrapper *godot_io_java = OS_Android::get_singleton()->get_godot_io_java();
+	ERR_FAIL_NULL_V(godot_io_java, false);
+
+	return godot_io_java->has_hardware_keyboard();
+}
+
 void DisplayServerAndroid::window_set_window_event_callback(const Callable &p_callable, DisplayServer::WindowID p_window) {
 void DisplayServerAndroid::window_set_window_event_callback(const Callable &p_callable, DisplayServer::WindowID p_window) {
 	window_event_callback = p_callable;
 	window_event_callback = p_callable;
 }
 }

+ 1 - 0
platform/android/display_server_android.h

@@ -138,6 +138,7 @@ public:
 	virtual void virtual_keyboard_show(const String &p_existing_text, const Rect2 &p_screen_rect = Rect2(), VirtualKeyboardType p_type = KEYBOARD_TYPE_DEFAULT, int p_max_length = -1, int p_cursor_start = -1, int p_cursor_end = -1) override;
 	virtual void virtual_keyboard_show(const String &p_existing_text, const Rect2 &p_screen_rect = Rect2(), VirtualKeyboardType p_type = KEYBOARD_TYPE_DEFAULT, int p_max_length = -1, int p_cursor_start = -1, int p_cursor_end = -1) override;
 	virtual void virtual_keyboard_hide() override;
 	virtual void virtual_keyboard_hide() override;
 	virtual int virtual_keyboard_get_height() const override;
 	virtual int virtual_keyboard_get_height() const override;
+	virtual bool has_hardware_keyboard() const override;
 
 
 	virtual void window_set_window_event_callback(const Callable &p_callable, WindowID p_window = MAIN_WINDOW_ID) override;
 	virtual void window_set_window_event_callback(const Callable &p_callable, WindowID p_window = MAIN_WINDOW_ID) override;
 	virtual void window_set_input_event_callback(const Callable &p_callable, WindowID p_window = MAIN_WINDOW_ID) override;
 	virtual void window_set_input_event_callback(const Callable &p_callable, WindowID p_window = MAIN_WINDOW_ID) override;

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

@@ -216,6 +216,14 @@ public class GodotIO {
 		return result;
 		return result;
 	}
 	}
 
 
+	public boolean hasHardwareKeyboard() {
+		if (edit != null) {
+			return edit.hasHardwareKeyboard();
+		} else {
+			return false;
+		}
+	}
+
 	public void showKeyboard(String p_existing_text, int p_type, int p_max_input_length, int p_cursor_start, int p_cursor_end) {
 	public void showKeyboard(String p_existing_text, int p_type, int p_max_input_length, int p_cursor_start, int p_cursor_end) {
 		if (edit != null) {
 		if (edit != null) {
 			edit.showKeyboard(p_existing_text, GodotEditText.VirtualKeyboardType.values()[p_type], p_max_input_length, p_cursor_start, p_cursor_end);
 			edit.showKeyboard(p_existing_text, GodotEditText.VirtualKeyboardType.values()[p_type], p_max_input_length, p_cursor_start, p_cursor_end);

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

@@ -264,7 +264,7 @@ public class GodotEditText extends EditText {
 				isModifiedKey;
 				isModifiedKey;
 	}
 	}
 
 
-	boolean hasHardwareKeyboard() {
+	public boolean hasHardwareKeyboard() {
 		Configuration config = getResources().getConfiguration();
 		Configuration config = getResources().getConfiguration();
 		boolean hasHardwareKeyboardConfig = config.keyboard != Configuration.KEYBOARD_NOKEYS &&
 		boolean hasHardwareKeyboardConfig = config.keyboard != Configuration.KEYBOARD_NOKEYS &&
 				config.hardKeyboardHidden == Configuration.HARDKEYBOARDHIDDEN_NO;
 				config.hardKeyboardHidden == Configuration.HARDKEYBOARDHIDDEN_NO;

+ 11 - 0
platform/android/java_godot_io_wrapper.cpp

@@ -63,6 +63,7 @@ GodotIOJavaWrapper::GodotIOJavaWrapper(JNIEnv *p_env, jobject p_godot_io_instanc
 		_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;IIII)V");
 		_show_keyboard = p_env->GetMethodID(cls, "showKeyboard", "(Ljava/lang/String;IIII)V");
 		_hide_keyboard = p_env->GetMethodID(cls, "hideKeyboard", "()V");
 		_hide_keyboard = p_env->GetMethodID(cls, "hideKeyboard", "()V");
+		_has_hardware_keyboard = p_env->GetMethodID(cls, "hasHardwareKeyboard", "()Z");
 		_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");
 		_get_system_dir = p_env->GetMethodID(cls, "getSystemDir", "(IZ)Ljava/lang/String;");
 		_get_system_dir = p_env->GetMethodID(cls, "getSystemDir", "(IZ)Ljava/lang/String;");
@@ -220,6 +221,16 @@ bool GodotIOJavaWrapper::has_vk() {
 	return (_show_keyboard != nullptr) && (_hide_keyboard != nullptr);
 	return (_show_keyboard != nullptr) && (_hide_keyboard != nullptr);
 }
 }
 
 
+bool GodotIOJavaWrapper::has_hardware_keyboard() {
+	if (_has_hardware_keyboard) {
+		JNIEnv *env = get_jni_env();
+		ERR_FAIL_NULL_V(env, false);
+		return env->CallBooleanMethod(godot_io_instance, _has_hardware_keyboard);
+	} else {
+		return false;
+	}
+}
+
 void GodotIOJavaWrapper::show_vk(const String &p_existing, int p_type, int p_max_input_length, int p_cursor_start, int p_cursor_end) {
 void GodotIOJavaWrapper::show_vk(const String &p_existing, int p_type, int p_max_input_length, int p_cursor_start, int p_cursor_end) {
 	if (_show_keyboard) {
 	if (_show_keyboard) {
 		JNIEnv *env = get_jni_env();
 		JNIEnv *env = get_jni_env();

+ 2 - 0
platform/android/java_godot_io_wrapper.h

@@ -58,6 +58,7 @@ private:
 	jmethodID _get_unique_id = 0;
 	jmethodID _get_unique_id = 0;
 	jmethodID _show_keyboard = 0;
 	jmethodID _show_keyboard = 0;
 	jmethodID _hide_keyboard = 0;
 	jmethodID _hide_keyboard = 0;
+	jmethodID _has_hardware_keyboard = 0;
 	jmethodID _set_screen_orientation = 0;
 	jmethodID _set_screen_orientation = 0;
 	jmethodID _get_screen_orientation = 0;
 	jmethodID _get_screen_orientation = 0;
 	jmethodID _get_system_dir = 0;
 	jmethodID _get_system_dir = 0;
@@ -80,6 +81,7 @@ public:
 	Rect2i get_display_safe_area();
 	Rect2i get_display_safe_area();
 	String get_unique_id();
 	String get_unique_id();
 	bool has_vk();
 	bool has_vk();
+	bool has_hardware_keyboard();
 	void show_vk(const String &p_existing, int p_type, int p_max_input_length, int p_cursor_start, int p_cursor_end);
 	void show_vk(const String &p_existing, int p_type, 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();

+ 1 - 0
platform/ios/display_server_ios.h

@@ -224,6 +224,7 @@ public:
 
 
 	void virtual_keyboard_set_height(int height);
 	void virtual_keyboard_set_height(int height);
 	virtual int virtual_keyboard_get_height() const override;
 	virtual int virtual_keyboard_get_height() const override;
+	virtual bool has_hardware_keyboard() const override;
 
 
 	virtual void clipboard_set(const String &p_text) override;
 	virtual void clipboard_set(const String &p_text) override;
 	virtual String clipboard_get() const override;
 	virtual String clipboard_get() const override;

+ 10 - 0
platform/ios/display_server_ios.mm

@@ -45,6 +45,8 @@
 
 
 #import <sys/utsname.h>
 #import <sys/utsname.h>
 
 
+#import <GameController/GameController.h>
+
 static const float kDisplayServerIOSAcceleration = 1.f;
 static const float kDisplayServerIOSAcceleration = 1.f;
 
 
 DisplayServerIOS *DisplayServerIOS::get_singleton() {
 DisplayServerIOS *DisplayServerIOS::get_singleton() {
@@ -756,6 +758,14 @@ int DisplayServerIOS::virtual_keyboard_get_height() const {
 	return virtual_keyboard_height;
 	return virtual_keyboard_height;
 }
 }
 
 
+bool DisplayServerIOS::has_hardware_keyboard() const {
+	if (@available(iOS 14.0, *)) {
+		return [GCKeyboard coalescedKeyboard];
+	} else {
+		return false;
+	}
+}
+
 void DisplayServerIOS::clipboard_set(const String &p_text) {
 void DisplayServerIOS::clipboard_set(const String &p_text) {
 	[UIPasteboard generalPasteboard].string = [NSString stringWithUTF8String:p_text.utf8()];
 	[UIPasteboard generalPasteboard].string = [NSString stringWithUTF8String:p_text.utf8()];
 }
 }

+ 6 - 0
servers/display_server.cpp

@@ -634,6 +634,10 @@ int DisplayServer::virtual_keyboard_get_height() const {
 	ERR_FAIL_V_MSG(0, "Virtual keyboard not supported by this display server.");
 	ERR_FAIL_V_MSG(0, "Virtual keyboard not supported by this display server.");
 }
 }
 
 
+bool DisplayServer::has_hardware_keyboard() const {
+	return true;
+}
+
 void DisplayServer::cursor_set_shape(CursorShape p_shape) {
 void DisplayServer::cursor_set_shape(CursorShape p_shape) {
 	WARN_PRINT("Cursor shape not supported by this display server.");
 	WARN_PRINT("Cursor shape not supported by this display server.");
 }
 }
@@ -976,6 +980,8 @@ void DisplayServer::_bind_methods() {
 
 
 	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);
 
 
+	ClassDB::bind_method(D_METHOD("has_hardware_keyboard"), &DisplayServer::has_hardware_keyboard);
+
 	ClassDB::bind_method(D_METHOD("cursor_set_shape", "shape"), &DisplayServer::cursor_set_shape);
 	ClassDB::bind_method(D_METHOD("cursor_set_shape", "shape"), &DisplayServer::cursor_set_shape);
 	ClassDB::bind_method(D_METHOD("cursor_get_shape"), &DisplayServer::cursor_get_shape);
 	ClassDB::bind_method(D_METHOD("cursor_get_shape"), &DisplayServer::cursor_get_shape);
 	ClassDB::bind_method(D_METHOD("cursor_set_custom_image", "cursor", "shape", "hotspot"), &DisplayServer::cursor_set_custom_image, DEFVAL(CURSOR_ARROW), DEFVAL(Vector2()));
 	ClassDB::bind_method(D_METHOD("cursor_set_custom_image", "cursor", "shape", "hotspot"), &DisplayServer::cursor_set_custom_image, DEFVAL(CURSOR_ARROW), DEFVAL(Vector2()));

+ 2 - 0
servers/display_server.h

@@ -507,6 +507,8 @@ public:
 	// 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)
 	virtual int virtual_keyboard_get_height() const;
 	virtual int virtual_keyboard_get_height() const;
 
 
+	virtual bool has_hardware_keyboard() const;
+
 	enum CursorShape {
 	enum CursorShape {
 		CURSOR_ARROW,
 		CURSOR_ARROW,
 		CURSOR_IBEAM,
 		CURSOR_IBEAM,