Browse Source

[Web] Detect host OS and use macOS keys on mac hosts.

bruvzg 2 years ago
parent
commit
a5009f4d3c

+ 18 - 17
core/input/input_event.cpp

@@ -33,6 +33,7 @@
 #include "core/input/input_map.h"
 #include "core/input/input_map.h"
 #include "core/input/shortcut.h"
 #include "core/input/shortcut.h"
 #include "core/os/keyboard.h"
 #include "core/os/keyboard.h"
+#include "core/os/os.h"
 
 
 const int InputEvent::DEVICE_ID_EMULATION = -1;
 const int InputEvent::DEVICE_ID_EMULATION = -1;
 const int InputEvent::DEVICE_ID_INTERNAL = -2;
 const int InputEvent::DEVICE_ID_INTERNAL = -2;
@@ -145,13 +146,13 @@ int64_t InputEventFromWindow::get_window_id() const {
 void InputEventWithModifiers::set_command_or_control_autoremap(bool p_enabled) {
 void InputEventWithModifiers::set_command_or_control_autoremap(bool p_enabled) {
 	command_or_control_autoremap = p_enabled;
 	command_or_control_autoremap = p_enabled;
 	if (command_or_control_autoremap) {
 	if (command_or_control_autoremap) {
-#ifdef MACOS_ENABLED
-		ctrl_pressed = false;
-		meta_pressed = true;
-#else
-		ctrl_pressed = true;
-		meta_pressed = false;
-#endif
+		if (OS::get_singleton()->has_feature("macos") || OS::get_singleton()->has_feature("web_macos") || OS::get_singleton()->has_feature("web_ios")) {
+			ctrl_pressed = false;
+			meta_pressed = true;
+		} else {
+			ctrl_pressed = true;
+			meta_pressed = false;
+		}
 	} else {
 	} else {
 		ctrl_pressed = false;
 		ctrl_pressed = false;
 		meta_pressed = false;
 		meta_pressed = false;
@@ -164,11 +165,11 @@ bool InputEventWithModifiers::is_command_or_control_autoremap() const {
 }
 }
 
 
 bool InputEventWithModifiers::is_command_or_control_pressed() const {
 bool InputEventWithModifiers::is_command_or_control_pressed() const {
-#ifdef MACOS_ENABLED
-	return meta_pressed;
-#else
-	return ctrl_pressed;
-#endif
+	if (OS::get_singleton()->has_feature("macos") || OS::get_singleton()->has_feature("web_macos") || OS::get_singleton()->has_feature("web_ios")) {
+		return meta_pressed;
+	} else {
+		return ctrl_pressed;
+	}
 }
 }
 
 
 void InputEventWithModifiers::set_shift_pressed(bool p_enabled) {
 void InputEventWithModifiers::set_shift_pressed(bool p_enabled) {
@@ -231,11 +232,11 @@ BitField<KeyModifierMask> InputEventWithModifiers::get_modifiers_mask() const {
 		mask.set_flag(KeyModifierMask::META);
 		mask.set_flag(KeyModifierMask::META);
 	}
 	}
 	if (is_command_or_control_autoremap()) {
 	if (is_command_or_control_autoremap()) {
-#ifdef MACOS_ENABLED
-		mask.set_flag(KeyModifierMask::META);
-#else
-		mask.set_flag(KeyModifierMask::CTRL);
-#endif
+		if (OS::get_singleton()->has_feature("macos") || OS::get_singleton()->has_feature("web_macos") || OS::get_singleton()->has_feature("web_ios")) {
+			mask.set_flag(KeyModifierMask::META);
+		} else {
+			mask.set_flag(KeyModifierMask::CTRL);
+		}
 	}
 	}
 	return mask;
 	return mask;
 }
 }

+ 5 - 5
core/os/keyboard.cpp

@@ -367,11 +367,11 @@ String keycode_get_string(Key p_code) {
 		codestr += "+";
 		codestr += "+";
 	}
 	}
 	if ((p_code & KeyModifierMask::CMD_OR_CTRL) != Key::NONE) {
 	if ((p_code & KeyModifierMask::CMD_OR_CTRL) != Key::NONE) {
-#ifdef MACOS_ENABLED
-		codestr += find_keycode_name(Key::META);
-#else
-		codestr += find_keycode_name(Key::CTRL);
-#endif
+		if (OS::get_singleton()->has_feature("macos") || OS::get_singleton()->has_feature("web_macos") || OS::get_singleton()->has_feature("web_ios")) {
+			codestr += find_keycode_name(Key::META);
+		} else {
+			codestr += find_keycode_name(Key::CTRL);
+		}
 		codestr += "+";
 		codestr += "+";
 	}
 	}
 	if ((p_code & KeyModifierMask::CTRL) != Key::NONE) {
 	if ((p_code & KeyModifierMask::CTRL) != Key::NONE) {

+ 1 - 0
doc/classes/OS.xml

@@ -491,6 +491,7 @@
 			<description>
 			<description>
 				Returns [code]true[/code] if the feature for the given feature tag is supported in the currently running instance, depending on the platform, build, etc. Can be used to check whether you're currently running a debug build, on a certain platform or arch, etc. Refer to the [url=$DOCS_URL/tutorials/export/feature_tags.html]Feature Tags[/url] documentation for more details.
 				Returns [code]true[/code] if the feature for the given feature tag is supported in the currently running instance, depending on the platform, build, etc. Can be used to check whether you're currently running a debug build, on a certain platform or arch, etc. Refer to the [url=$DOCS_URL/tutorials/export/feature_tags.html]Feature Tags[/url] documentation for more details.
 				[b]Note:[/b] Tag names are case-sensitive.
 				[b]Note:[/b] Tag names are case-sensitive.
+				[b]Note:[/b] On the web platform, one of the following additional tags is defined to indicate host platform: [code]web_android[/code], [code]web_ios[/code], [code]web_linuxbsd[/code], [code]web_macos[/code], or [code]web_windows[/code].
 			</description>
 			</description>
 		</method>
 		</method>
 		<method name="is_debug_build" qualifiers="const">
 		<method name="is_debug_build" qualifiers="const">

+ 13 - 11
editor/editor_settings.cpp

@@ -1488,7 +1488,9 @@ void ED_SHORTCUT_OVERRIDE_ARRAY(const String &p_path, const String &p_feature, c
 
 
 	// Only add the override if the OS supports the provided feature.
 	// Only add the override if the OS supports the provided feature.
 	if (!OS::get_singleton()->has_feature(p_feature)) {
 	if (!OS::get_singleton()->has_feature(p_feature)) {
-		return;
+		if (!(p_feature == "macos" && (OS::get_singleton()->has_feature("web_macos") || OS::get_singleton()->has_feature("web_ios")))) {
+			return;
+		}
 	}
 	}
 
 
 	Array events;
 	Array events;
@@ -1496,12 +1498,12 @@ void ED_SHORTCUT_OVERRIDE_ARRAY(const String &p_path, const String &p_feature, c
 	for (int i = 0; i < p_keycodes.size(); i++) {
 	for (int i = 0; i < p_keycodes.size(); i++) {
 		Key keycode = (Key)p_keycodes[i];
 		Key keycode = (Key)p_keycodes[i];
 
 
-#ifdef MACOS_ENABLED
-		// Use Cmd+Backspace as a general replacement for Delete shortcuts on macOS
-		if (keycode == Key::KEY_DELETE) {
-			keycode = KeyModifierMask::META | Key::BACKSPACE;
+		if (OS::get_singleton()->has_feature("macos") || OS::get_singleton()->has_feature("web_macos") || OS::get_singleton()->has_feature("web_ios")) {
+			// Use Cmd+Backspace as a general replacement for Delete shortcuts on macOS
+			if (keycode == Key::KEY_DELETE) {
+				keycode = KeyModifierMask::META | Key::BACKSPACE;
+			}
 		}
 		}
-#endif
 
 
 		Ref<InputEventKey> ie;
 		Ref<InputEventKey> ie;
 		if (keycode != Key::NONE) {
 		if (keycode != Key::NONE) {
@@ -1530,12 +1532,12 @@ Ref<Shortcut> ED_SHORTCUT_ARRAY(const String &p_path, const String &p_name, cons
 	for (int i = 0; i < p_keycodes.size(); i++) {
 	for (int i = 0; i < p_keycodes.size(); i++) {
 		Key keycode = (Key)p_keycodes[i];
 		Key keycode = (Key)p_keycodes[i];
 
 
-#ifdef MACOS_ENABLED
-		// Use Cmd+Backspace as a general replacement for Delete shortcuts on macOS
-		if (keycode == Key::KEY_DELETE) {
-			keycode = KeyModifierMask::META | Key::BACKSPACE;
+		if (OS::get_singleton()->has_feature("macos") || OS::get_singleton()->has_feature("web_macos") || OS::get_singleton()->has_feature("web_ios")) {
+			// Use Cmd+Backspace as a general replacement for Delete shortcuts on macOS
+			if (keycode == Key::KEY_DELETE) {
+				keycode = KeyModifierMask::META | Key::BACKSPACE;
+			}
 		}
 		}
-#endif
 
 
 		Ref<InputEventKey> ie;
 		Ref<InputEventKey> ie;
 		if (keycode != Key::NONE) {
 		if (keycode != Key::NONE) {

+ 1 - 5
editor/editor_spin_slider.cpp

@@ -37,11 +37,7 @@
 
 
 String EditorSpinSlider::get_tooltip(const Point2 &p_pos) const {
 String EditorSpinSlider::get_tooltip(const Point2 &p_pos) const {
 	if (grabber->is_visible()) {
 	if (grabber->is_visible()) {
-#ifdef MACOS_ENABLED
-		Key key = Key::META;
-#else
-		Key key = Key::CTRL;
-#endif
+		Key key = (OS::get_singleton()->has_feature("macos") || OS::get_singleton()->has_feature("web_macos") || OS::get_singleton()->has_feature("web_ios")) ? Key::META : Key::CTRL;
 		return TS->format_number(rtos(get_value())) + "\n\n" + vformat(TTR("Hold %s to round to integers.\nHold Shift for more precise changes."), find_keycode_name(key));
 		return TS->format_number(rtos(get_value())) + "\n\n" + vformat(TTR("Hold %s to round to integers.\nHold Shift for more precise changes."), find_keycode_name(key));
 	}
 	}
 	return TS->format_number(rtos(get_value()));
 	return TS->format_number(rtos(get_value()));

+ 5 - 5
editor/event_listener_line_edit.cpp

@@ -65,11 +65,11 @@ String EventListenerLineEdit::get_event_text(const Ref<InputEvent> &p_event, boo
 		String mods_text = key->InputEventWithModifiers::as_text();
 		String mods_text = key->InputEventWithModifiers::as_text();
 		mods_text = mods_text.is_empty() ? mods_text : mods_text + "+";
 		mods_text = mods_text.is_empty() ? mods_text : mods_text + "+";
 		if (key->is_command_or_control_autoremap()) {
 		if (key->is_command_or_control_autoremap()) {
-#ifdef MACOS_ENABLED
-			mods_text = mods_text.replace("Command", "Command/Ctrl");
-#else
-			mods_text = mods_text.replace("Ctrl", "Command/Ctrl");
-#endif
+			if (OS::get_singleton()->has_feature("macos") || OS::get_singleton()->has_feature("web_macos") || OS::get_singleton()->has_feature("web_ios")) {
+				mods_text = mods_text.replace("Command", "Command/Ctrl");
+			} else {
+				mods_text = mods_text.replace("Ctrl", "Command/Ctrl");
+			}
 		}
 		}
 
 
 		if (key->get_keycode() != Key::NONE) {
 		if (key->get_keycode() != Key::NONE) {

+ 1 - 0
platform/web/godot_js.h

@@ -49,6 +49,7 @@ extern void godot_js_os_fs_sync(void (*p_callback)());
 extern int godot_js_os_execute(const char *p_json);
 extern int godot_js_os_execute(const char *p_json);
 extern void godot_js_os_shell_open(const char *p_uri);
 extern void godot_js_os_shell_open(const char *p_uri);
 extern int godot_js_os_hw_concurrency_get();
 extern int godot_js_os_hw_concurrency_get();
+extern int godot_js_os_has_feature(const char *p_ftr);
 extern int godot_js_pwa_cb(void (*p_callback)());
 extern int godot_js_pwa_cb(void (*p_callback)());
 extern int godot_js_pwa_update();
 extern int godot_js_pwa_update();
 
 

+ 22 - 0
platform/web/js/libs/library_godot_os.js

@@ -291,6 +291,28 @@ const GodotOS = {
 		});
 		});
 	},
 	},
 
 
+	godot_js_os_has_feature__sig: 'ii',
+	godot_js_os_has_feature: function (p_ftr) {
+		const ftr = GodotRuntime.parseString(p_ftr);
+		const ua = navigator.userAgent;
+		if (ftr === 'web_macos') {
+			return (ua.indexOf('Mac') !== -1) ? 1 : 0;
+		}
+		if (ftr === 'web_windows') {
+			return (ua.indexOf('Windows') !== -1) ? 1 : 0;
+		}
+		if (ftr === 'web_android') {
+			return (ua.indexOf('Android') !== -1) ? 1 : 0;
+		}
+		if (ftr === 'web_ios') {
+			return ((ua.indexOf('iPhone') !== -1) || (ua.indexOf('iPad') !== -1) || (ua.indexOf('iPod') !== -1)) ? 1 : 0;
+		}
+		if (ftr === 'web_linuxbsd') {
+			return ((ua.indexOf('CrOS') !== -1) || (ua.indexOf('BSD') !== -1) || (ua.indexOf('Linux') !== -1) || (ua.indexOf('X11') !== -1)) ? 1 : 0;
+		}
+		return 0;
+	},
+
 	godot_js_os_execute__sig: 'ii',
 	godot_js_os_execute__sig: 'ii',
 	godot_js_os_execute: function (p_json) {
 	godot_js_os_execute: function (p_json) {
 		const json_args = GodotRuntime.parseString(p_json);
 		const json_args = GodotRuntime.parseString(p_json);

+ 3 - 0
platform/web/os_web.cpp

@@ -136,6 +136,9 @@ bool OS_Web::_check_internal_feature_support(const String &p_feature) {
 	if (p_feature == "web") {
 	if (p_feature == "web") {
 		return true;
 		return true;
 	}
 	}
+	if (godot_js_os_has_feature(p_feature.utf8().get_data())) {
+		return true;
+	}
 	return false;
 	return false;
 }
 }
 
 

+ 2 - 5
scene/gui/code_edit.cpp

@@ -451,11 +451,8 @@ void CodeEdit::gui_input(const Ref<InputEvent> &p_gui_input) {
 	}
 	}
 
 
 	/* Ctrl + Hover symbols */
 	/* Ctrl + Hover symbols */
-#ifdef MACOS_ENABLED
-	if (k->get_keycode() == Key::META) {
-#else
-	if (k->get_keycode() == Key::CTRL) {
-#endif
+	bool mac_keys = OS::get_singleton()->has_feature("macos") || OS::get_singleton()->has_feature("web_macos") || OS::get_singleton()->has_feature("web_ios");
+	if ((mac_keys && k->get_keycode() == Key::META) || (!mac_keys && k->get_keycode() == Key::CTRL)) {
 		if (symbol_lookup_on_click_enabled) {
 		if (symbol_lookup_on_click_enabled) {
 			if (k->is_pressed() && !is_dragging_cursor()) {
 			if (k->is_pressed() && !is_dragging_cursor()) {
 				symbol_lookup_new_word = get_word_at_pos(get_local_mouse_pos());
 				symbol_lookup_new_word = get_word_at_pos(get_local_mouse_pos());