diff --git a/core/input/input_event.cpp b/core/input/input_event.cpp index 9d5d84a50808..46f07fe04112 100644 --- a/core/input/input_event.cpp +++ b/core/input/input_event.cpp @@ -33,6 +33,7 @@ #include "core/input/input_map.h" #include "core/input/shortcut.h" #include "core/os/keyboard.h" +#include "core/os/os.h" const int InputEvent::DEVICE_ID_EMULATION = -1; 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) { command_or_control_autoremap = p_enabled; 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 { ctrl_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 { -#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) { @@ -231,11 +232,11 @@ BitField InputEventWithModifiers::get_modifiers_mask() const { mask.set_flag(KeyModifierMask::META); } 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; } diff --git a/core/os/keyboard.cpp b/core/os/keyboard.cpp index 25a4b320cd38..1e32e6e096a2 100644 --- a/core/os/keyboard.cpp +++ b/core/os/keyboard.cpp @@ -367,11 +367,11 @@ String keycode_get_string(Key p_code) { codestr += "+"; } 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 += "+"; } if ((p_code & KeyModifierMask::CTRL) != Key::NONE) { diff --git a/doc/classes/OS.xml b/doc/classes/OS.xml index 1b98d357ae46..28c6247338f8 100644 --- a/doc/classes/OS.xml +++ b/doc/classes/OS.xml @@ -491,6 +491,7 @@ 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] 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]. diff --git a/editor/editor_settings.cpp b/editor/editor_settings.cpp index 25c84e744755..835eecdeb3b7 100644 --- a/editor/editor_settings.cpp +++ b/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. 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; @@ -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++) { 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 ie; if (keycode != Key::NONE) { @@ -1530,12 +1532,12 @@ Ref ED_SHORTCUT_ARRAY(const String &p_path, const String &p_name, cons for (int i = 0; i < p_keycodes.size(); 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 ie; if (keycode != Key::NONE) { diff --git a/editor/editor_spin_slider.cpp b/editor/editor_spin_slider.cpp index 2d3ec437c6ba..2e67893facc7 100644 --- a/editor/editor_spin_slider.cpp +++ b/editor/editor_spin_slider.cpp @@ -37,11 +37,7 @@ String EditorSpinSlider::get_tooltip(const Point2 &p_pos) const { 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())); diff --git a/editor/event_listener_line_edit.cpp b/editor/event_listener_line_edit.cpp index ee401810ad62..fa494636ea72 100644 --- a/editor/event_listener_line_edit.cpp +++ b/editor/event_listener_line_edit.cpp @@ -65,11 +65,11 @@ String EventListenerLineEdit::get_event_text(const Ref &p_event, boo String mods_text = key->InputEventWithModifiers::as_text(); mods_text = mods_text.is_empty() ? mods_text : mods_text + "+"; 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) { diff --git a/platform/web/godot_js.h b/platform/web/godot_js.h index 3a41f63fa397..660822e29106 100644 --- a/platform/web/godot_js.h +++ b/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 void godot_js_os_shell_open(const char *p_uri); 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_update(); diff --git a/platform/web/js/libs/library_godot_os.js b/platform/web/js/libs/library_godot_os.js index c4c45a3036af..00ae3995831f 100644 --- a/platform/web/js/libs/library_godot_os.js +++ b/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: function (p_json) { const json_args = GodotRuntime.parseString(p_json); diff --git a/platform/web/os_web.cpp b/platform/web/os_web.cpp index 964bce01da48..0f84e7e841c7 100644 --- a/platform/web/os_web.cpp +++ b/platform/web/os_web.cpp @@ -136,6 +136,9 @@ bool OS_Web::_check_internal_feature_support(const String &p_feature) { if (p_feature == "web") { return true; } + if (godot_js_os_has_feature(p_feature.utf8().get_data())) { + return true; + } return false; } diff --git a/scene/gui/code_edit.cpp b/scene/gui/code_edit.cpp index 0c9b6ffeaf17..443f6339690f 100644 --- a/scene/gui/code_edit.cpp +++ b/scene/gui/code_edit.cpp @@ -451,11 +451,8 @@ void CodeEdit::gui_input(const Ref &p_gui_input) { } /* 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 (k->is_pressed() && !is_dragging_cursor()) { symbol_lookup_new_word = get_word_at_pos(get_local_mouse_pos());