From ce8f9dfea83c8352a256f40f44af9444e61144ce Mon Sep 17 00:00:00 2001 From: Fredia Huya-Kouadio Date: Tue, 16 Sep 2025 23:03:18 -0700 Subject: [PATCH 1/7] Fix the bug causing `java.lang.StringIndexOutOfBoundsException` crashes when showing the virtual keyboard (cherry picked from commit ff3eee7df6071f3d05b5b4c74a090326f833a40f) --- .../godot/input/GodotEditText.java | 20 +++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/platform/android/java/lib/src/org/godotengine/godot/input/GodotEditText.java b/platform/android/java/lib/src/org/godotengine/godot/input/GodotEditText.java index afaafe1d9fc..a0ec7312911 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/input/GodotEditText.java +++ b/platform/android/java/lib/src/org/godotengine/godot/input/GodotEditText.java @@ -276,16 +276,20 @@ public class GodotEditText extends EditText { return; } + int cursorStart = p_cursor_start; + int cursorEnd = p_cursor_end; int maxInputLength = (p_max_input_length <= 0) ? Integer.MAX_VALUE : p_max_input_length; - if (p_cursor_start == -1) { // cursor position not given + if (cursorStart == -1) { // cursor position not given this.mOriginText = p_existing_text; this.mMaxInputLength = maxInputLength; - } else if (p_cursor_end == -1) { // not text selection - this.mOriginText = p_existing_text.substring(0, p_cursor_start); - this.mMaxInputLength = maxInputLength - (p_existing_text.length() - p_cursor_start); + } else if (cursorEnd == -1) { // not text selection + cursorStart = Math.min(p_existing_text.length(), cursorStart); + this.mOriginText = p_existing_text.substring(0, cursorStart); + this.mMaxInputLength = maxInputLength - (p_existing_text.length() - cursorStart); } else { - this.mOriginText = p_existing_text.substring(0, p_cursor_end); - this.mMaxInputLength = maxInputLength - (p_existing_text.length() - p_cursor_end); + cursorEnd = Math.min(p_existing_text.length(), cursorEnd); + this.mOriginText = p_existing_text.substring(0, cursorEnd); + this.mMaxInputLength = maxInputLength - (p_existing_text.length() - cursorEnd); } this.mKeyboardType = p_type; @@ -293,8 +297,8 @@ public class GodotEditText extends EditText { final Message msg = new Message(); msg.what = HANDLER_OPEN_IME_KEYBOARD; msg.obj = this; - msg.arg1 = p_cursor_start; - msg.arg2 = p_cursor_end; + msg.arg1 = cursorStart; + msg.arg2 = cursorEnd; sHandler.sendMessage(msg); } From 07596299e6b8af76b3994334e18fe487bc2eb354 Mon Sep 17 00:00:00 2001 From: kobewi Date: Thu, 9 Oct 2025 16:33:07 +0200 Subject: [PATCH 2/7] Enable script templates by default (cherry picked from commit a29900462270b84c7295c64898123be736bf7794) --- editor/script/script_create_dialog.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/editor/script/script_create_dialog.cpp b/editor/script/script_create_dialog.cpp index 6395c7b8e2f..17dc2f2fc63 100644 --- a/editor/script/script_create_dialog.cpp +++ b/editor/script/script_create_dialog.cpp @@ -124,7 +124,7 @@ void ScriptCreateDialog::_notification(int p_what) { } else { language_menu->select(default_language); } - is_using_templates = EDITOR_DEF("_script_setup_use_script_templates", false); + is_using_templates = EDITOR_GET("_script_setup_use_script_templates"); use_templates->set_pressed(is_using_templates); } break; @@ -849,6 +849,7 @@ void ScriptCreateDialog::_bind_methods() { ScriptCreateDialog::ScriptCreateDialog() { if (EditorSettings::get_singleton()) { EDITOR_DEF("_script_setup_templates_dictionary", Dictionary()); + EDITOR_DEF("_script_setup_use_script_templates", true); } /* Main Controls */ From 1c078fee0187b36337fb6096fa64846bb540e196 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Verschelde?= Date: Wed, 8 Oct 2025 15:47:07 +0200 Subject: [PATCH 3/7] SCons: Don't activate `fast_unsafe` automatically on `dev_build` We experienced first hand why it's called unsafe, and so we should leave it as an explicit choice for contributors, informing themselves of the caveats. See #111408. (cherry picked from commit fa57282a1e76cf295b6ca20bbf98e2798660bc27) --- SConstruct | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/SConstruct b/SConstruct index 2386069389f..a450b04a8e9 100644 --- a/SConstruct +++ b/SConstruct @@ -210,7 +210,7 @@ opts.Add( ) ) opts.Add(BoolVariable("tests", "Build the unit tests", False)) -opts.Add(BoolVariable("fast_unsafe", "Enable unsafe options for faster rebuilds", False)) +opts.Add(BoolVariable("fast_unsafe", "Enable unsafe options for faster incremental builds", False)) opts.Add(BoolVariable("ninja", "Use the ninja backend for faster rebuilds", False)) opts.Add(BoolVariable("ninja_auto_run", "Run ninja automatically after generating the ninja file", True)) opts.Add("ninja_file", "Path to the generated ninja file", "build.ninja") @@ -520,10 +520,10 @@ env.Decider("MD5-timestamp") # SCons speed optimization controlled by the `fast_unsafe` option, which provide # more than 10 s speed up for incremental rebuilds. -# Unsafe as they reduce the certainty of rebuilding all changed files, so it's -# enabled by default for `debug` builds, and can be overridden from command line. +# Unsafe as they reduce the certainty of rebuilding all changed files. +# If you use it and run into corrupted incremental builds, try to turn it off. # Ref: https://github.com/SCons/scons/wiki/GoFastButton -if methods.get_cmdline_bool("fast_unsafe", env.dev_build): +if env["fast_unsafe"]: env.SetOption("implicit_cache", 1) env.SetOption("max_drift", 60) From 83a78186ca002154b4c54f78a8f6af5595cd8d0c Mon Sep 17 00:00:00 2001 From: Artemy Fedotov Date: Thu, 11 Sep 2025 14:25:49 +0400 Subject: [PATCH 4/7] Fix crash due to null pointer dereference when moving/renaming folders in `FileSystemDock` (cherry picked from commit 4e3a39a2e816272b4b29fc7f9d807d6e34b2100e) --- editor/docks/filesystem_dock.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/editor/docks/filesystem_dock.cpp b/editor/docks/filesystem_dock.cpp index 529786c5e70..e455102fa70 100644 --- a/editor/docks/filesystem_dock.cpp +++ b/editor/docks/filesystem_dock.cpp @@ -2033,6 +2033,7 @@ void FileSystemDock::_before_move(HashMap &r_uids, Hash } } else { EditorFileSystemDirectory *current_folder = EditorFileSystem::get_singleton()->get_filesystem_path(to_move[i].path); + ERR_CONTINUE(current_folder == nullptr); List folders; folders.push_back(current_folder); while (folders.front()) { From 183f6cdd63b1b1c66feb5b24964d24a620386cf1 Mon Sep 17 00:00:00 2001 From: Artemy Fedotov Date: Thu, 11 Sep 2025 16:44:40 +0400 Subject: [PATCH 5/7] Fix favorite folders that are outside of the project being displayed in `FileSystemDock`'s file list (cherry picked from commit 8d137bcd2966a0bdb9b66e3b4a56276875f6dbc4) --- editor/docks/filesystem_dock.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/editor/docks/filesystem_dock.cpp b/editor/docks/filesystem_dock.cpp index e455102fa70..e9629d3ebe9 100644 --- a/editor/docks/filesystem_dock.cpp +++ b/editor/docks/filesystem_dock.cpp @@ -991,6 +991,9 @@ void FileSystemDock::_update_file_list(bool p_keep_selection) { // Display the favorites. Vector favorites_list = EditorSettings::get_singleton()->get_favorites(); for (const String &favorite : favorites_list) { + if (!favorite.begins_with("res://")) { + continue; + } String text; Ref icon; if (favorite == "res://") { From eb7c869f8450e6c942b91cfed928423325776ccd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pa=CC=84vels=20Nadtoc=CC=8Cajevs?= <7645683+bruvzg@users.noreply.github.com> Date: Sat, 13 Sep 2025 17:56:16 +0300 Subject: [PATCH 6/7] [macOS] Remove old embedded window joystick init code. (cherry picked from commit 77dd83efbf4130c5bb7f1f5edee1741e7f310fb6) --- platform/macos/editor/embedded_process_macos.mm | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/platform/macos/editor/embedded_process_macos.mm b/platform/macos/editor/embedded_process_macos.mm index 7cd4fb13603..d9bd1ce018f 100644 --- a/platform/macos/editor/embedded_process_macos.mm +++ b/platform/macos/editor/embedded_process_macos.mm @@ -150,16 +150,6 @@ void EmbeddedProcessMacOS::_try_embed_process() { queue_redraw(); emit_signal(SNAME("embedding_completed")); - // Send initial joystick state. - { - Input *input = Input::get_singleton(); - TypedArray joy_pads = input->get_connected_joypads(); - for (const Variant &idx : joy_pads) { - String name = input->get_joy_name(idx); - script_debugger->send_message("embed:joy_add", { idx, name }); - } - } - layer_host->grab_focus(); } else { // Another unknown error. From d632731ba866ad4fefb76b632df70da736d06838 Mon Sep 17 00:00:00 2001 From: Anish Mishra Date: Wed, 13 Aug 2025 13:35:50 +0530 Subject: [PATCH 7/7] Android: Only validate keystore relevant to current export mode - Debug builds skip release keystore validation. - Release builds skip debug keystore validation. (cherry picked from commit 097ccbc5cda1bbb20b3b499d5622da2bb3b25642) --- platform/android/export/export_plugin.cpp | 50 ++++++++++++----------- 1 file changed, 26 insertions(+), 24 deletions(-) diff --git a/platform/android/export/export_plugin.cpp b/platform/android/export/export_plugin.cpp index b7d2618c22f..4bb7263db45 100644 --- a/platform/android/export/export_plugin.cpp +++ b/platform/android/export/export_plugin.cpp @@ -2853,36 +2853,38 @@ bool EditorExportPlatformAndroid::has_valid_export_configuration(const Refget_or_env("keystore/debug_user", ENV_ANDROID_KEYSTORE_DEBUG_USER); - String dk_password = p_preset->get_or_env("keystore/debug_password", ENV_ANDROID_KEYSTORE_DEBUG_PASS); + if (p_debug) { + String dk = _get_keystore_path(p_preset, true); + String dk_user = p_preset->get_or_env("keystore/debug_user", ENV_ANDROID_KEYSTORE_DEBUG_USER); + String dk_password = p_preset->get_or_env("keystore/debug_password", ENV_ANDROID_KEYSTORE_DEBUG_PASS); - if ((dk.is_empty() || dk_user.is_empty() || dk_password.is_empty()) && (!dk.is_empty() || !dk_user.is_empty() || !dk_password.is_empty())) { - valid = false; - err += TTR("Either Debug Keystore, Debug User AND Debug Password settings must be configured OR none of them.") + "\n"; - } - - // Use OR to make the export UI able to show this error. - if ((p_debug || !dk.is_empty()) && !FileAccess::exists(dk)) { - dk = EDITOR_GET("export/android/debug_keystore"); - if (!FileAccess::exists(dk)) { + if ((dk.is_empty() || dk_user.is_empty() || dk_password.is_empty()) && (!dk.is_empty() || !dk_user.is_empty() || !dk_password.is_empty())) { valid = false; - err += TTR("Debug keystore not configured in the Editor Settings nor in the preset.") + "\n"; + err += TTR("Either Debug Keystore, Debug User AND Debug Password settings must be configured OR none of them.") + "\n"; } - } - String rk = _get_keystore_path(p_preset, false); - String rk_user = p_preset->get_or_env("keystore/release_user", ENV_ANDROID_KEYSTORE_RELEASE_USER); - String rk_password = p_preset->get_or_env("keystore/release_password", ENV_ANDROID_KEYSTORE_RELEASE_PASS); + // Use OR to make the export UI able to show this error. + if (!dk.is_empty() && !FileAccess::exists(dk)) { + dk = EDITOR_GET("export/android/debug_keystore"); + if (!FileAccess::exists(dk)) { + valid = false; + err += TTR("Debug keystore not configured in the Editor Settings nor in the preset.") + "\n"; + } + } + } else { + String rk = _get_keystore_path(p_preset, false); + String rk_user = p_preset->get_or_env("keystore/release_user", ENV_ANDROID_KEYSTORE_RELEASE_USER); + String rk_password = p_preset->get_or_env("keystore/release_password", ENV_ANDROID_KEYSTORE_RELEASE_PASS); - if ((rk.is_empty() || rk_user.is_empty() || rk_password.is_empty()) && (!rk.is_empty() || !rk_user.is_empty() || !rk_password.is_empty())) { - valid = false; - err += TTR("Either Release Keystore, Release User AND Release Password settings must be configured OR none of them.") + "\n"; - } + if ((rk.is_empty() || rk_user.is_empty() || rk_password.is_empty()) && (!rk.is_empty() || !rk_user.is_empty() || !rk_password.is_empty())) { + valid = false; + err += TTR("Either Release Keystore, Release User AND Release Password settings must be configured OR none of them.") + "\n"; + } - if (!p_debug && !rk.is_empty() && !FileAccess::exists(rk)) { - valid = false; - err += TTR("Release keystore incorrectly configured in the export preset.") + "\n"; + if (!rk.is_empty() && !FileAccess::exists(rk)) { + valid = false; + err += TTR("Release keystore incorrectly configured in the export preset.") + "\n"; + } } #ifndef ANDROID_ENABLED