Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Web] Detect host OS and use macOS keys on Mac hosts. #75451

Merged
merged 1 commit into from
Apr 11, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 18 additions & 17 deletions core/input/input_event.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand All @@ -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) {
Expand Down Expand Up @@ -231,11 +232,11 @@ BitField<KeyModifierMask> 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;
}
Expand Down
10 changes: 5 additions & 5 deletions core/os/keyboard.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
1 change: 1 addition & 0 deletions doc/classes/OS.xml
Original file line number Diff line number Diff line change
Expand Up @@ -491,6 +491,7 @@
<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.
[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>
</method>
<method name="is_debug_build" qualifiers="const">
Expand Down
24 changes: 13 additions & 11 deletions editor/editor_settings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1488,20 +1488,22 @@ 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;

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<InputEventKey> ie;
if (keycode != Key::NONE) {
Expand Down Expand Up @@ -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++) {
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;
if (keycode != Key::NONE) {
Expand Down
6 changes: 1 addition & 5 deletions editor/editor_spin_slider.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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()));
Expand Down
10 changes: 5 additions & 5 deletions editor/event_listener_line_edit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,11 +65,11 @@ String EventListenerLineEdit::get_event_text(const Ref<InputEvent> &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) {
Expand Down
1 change: 1 addition & 0 deletions platform/web/godot_js.h
Original file line number Diff line number Diff line change
Expand Up @@ -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();

Expand Down
22 changes: 22 additions & 0 deletions platform/web/js/libs/library_godot_os.js
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
3 changes: 3 additions & 0 deletions platform/web/os_web.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand Down
7 changes: 2 additions & 5 deletions scene/gui/code_edit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -451,11 +451,8 @@ void CodeEdit::gui_input(const Ref<InputEvent> &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());
Expand Down