diff --git a/platform/android/doc_classes/EditorExportPlatformAndroid.xml b/platform/android/doc_classes/EditorExportPlatformAndroid.xml index b9840154e08..5acd121bd69 100644 --- a/platform/android/doc_classes/EditorExportPlatformAndroid.xml +++ b/platform/android/doc_classes/EditorExportPlatformAndroid.xml @@ -598,6 +598,10 @@ Allows an application to write to the user dictionary. + + If [code]true[/code], this makes the navigation and status bars translucent and allows the application content to extend edge to edge. + [b]Note:[/b] You should ensure that none of the application content is occluded by system elements by using the [method DisplayServer.get_display_safe_area] and [method DisplayServer.get_display_cutouts] methods. + If [code]true[/code], hides the navigation and status bar. Set [method DisplayServer.window_set_mode] to change this at runtime. diff --git a/platform/android/export/export_plugin.cpp b/platform/android/export/export_plugin.cpp index 55b09feb9a9..a68da744977 100644 --- a/platform/android/export/export_plugin.cpp +++ b/platform/android/export/export_plugin.cpp @@ -1054,7 +1054,6 @@ void EditorExportPlatformAndroid::_fix_themes_xml(const Ref // Default/Reserved theme attributes. Dictionary main_theme_attributes; - main_theme_attributes["android:windowDrawsSystemBarBackgrounds"] = "false"; main_theme_attributes["android:windowSwipeToDismiss"] = bool_to_string(p_preset->get("gesture/swipe_to_dismiss")); main_theme_attributes["android:windowIsTranslucent"] = bool_to_string(should_be_transparent); if (should_be_transparent) { @@ -2163,6 +2162,7 @@ void EditorExportPlatformAndroid::get_export_options(List *r_optio r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "screen/support_normal"), true)); r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "screen/support_large"), true)); r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "screen/support_xlarge"), true)); + r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "screen/edge_to_edge"), false)); r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "user_data_backup/allow"), false)); @@ -3078,6 +3078,11 @@ void EditorExportPlatformAndroid::get_command_line_flags(const Refget("screen/edge_to_edge"); + if (edge_to_edge) { + command_line_strings.push_back("--edge_to_edge"); + } + bool debug_opengl = p_preset->get("graphics/opengl_debug"); if (debug_opengl) { command_line_strings.push_back("--debug_opengl"); diff --git a/platform/android/java/app/res/values/themes.xml b/platform/android/java/app/res/values/themes.xml index 600775fb62e..af2dd509cf6 100644 --- a/platform/android/java/app/res/values/themes.xml +++ b/platform/android/java/app/res/values/themes.xml @@ -3,7 +3,6 @@ diff --git a/platform/android/java/app/src/com/godot/game/GodotApp.java b/platform/android/java/app/src/com/godot/game/GodotApp.java index 254222485d8..d83741ddb62 100644 --- a/platform/android/java/app/src/com/godot/game/GodotApp.java +++ b/platform/android/java/app/src/com/godot/game/GodotApp.java @@ -30,11 +30,13 @@ package com.godot.game; +import org.godotengine.godot.Godot; import org.godotengine.godot.GodotActivity; import android.os.Bundle; import android.util.Log; +import androidx.activity.EdgeToEdge; import androidx.core.splashscreen.SplashScreen; /** @@ -54,9 +56,30 @@ public class GodotApp extends GodotActivity { } } + private final Runnable updateImmersiveAndEdgeToEdgeModes = () -> { + Godot godot = getGodot(); + if (godot != null) { + godot.enableImmersiveMode(godot.isInImmersiveMode(), true); + godot.enableEdgeToEdge(godot.isInEdgeToEdgeMode(), true); + } + }; + @Override public void onCreate(Bundle savedInstanceState) { SplashScreen.installSplashScreen(this); + EdgeToEdge.enable(this); super.onCreate(savedInstanceState); } + + @Override + public void onResume() { + super.onResume(); + updateImmersiveAndEdgeToEdgeModes.run(); + } + + @Override + public void onGodotMainLoopStarted() { + super.onGodotMainLoopStarted(); + runOnUiThread(updateImmersiveAndEdgeToEdgeModes); + } } diff --git a/platform/android/java/editor/src/main/AndroidManifest.xml b/platform/android/java/editor/src/main/AndroidManifest.xml index 72dab3f7082..2dbaf9efb24 100644 --- a/platform/android/java/editor/src/main/AndroidManifest.xml +++ b/platform/android/java/editor/src/main/AndroidManifest.xml @@ -88,8 +88,7 @@ android:excludeFromRecents="true" android:launchMode="singleTask" android:process=":EmbeddedGodotGame" - android:supportsPictureInPicture="true" - android:screenOrientation="userLandscape" /> + android:supportsPictureInPicture="true" /> = Build.VERSION_CODES.P && getEditorWindowInfo() == EDITOR_MAIN_INFO) { - window.attributes.layoutInDisplayCutoutMode = WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER + val editorWindowInfo = getEditorWindowInfo() + if (editorWindowInfo == EDITOR_MAIN_INFO || editorWindowInfo == RUN_GAME_INFO) { + enableEdgeToEdge() } // We exclude certain permissions from the set we request at startup, as they'll be @@ -273,16 +273,29 @@ abstract class BaseGodotEditor : GodotActivity(), GameMenuFragment.GameMenuListe } } + private fun updateImmersiveAndEdgeToEdgeModes() { + val editorWindowInfo = getEditorWindowInfo() + if (editorWindowInfo == EDITOR_MAIN_INFO || editorWindowInfo == RUN_GAME_INFO) { + godot?.apply { + enableImmersiveMode(isInImmersiveMode(), true) + enableEdgeToEdge(isInEdgeToEdgeMode(), true) + } + } + } + override fun onGodotMainLoopStarted() { super.onGodotMainLoopStarted() runOnUiThread { // Hide the loading indicator editorLoadingIndicator?.visibility = View.GONE + updateImmersiveAndEdgeToEdgeModes() } } override fun onResume() { super.onResume() + updateImmersiveAndEdgeToEdgeModes() + if (getEditorWindowInfo() == EDITOR_MAIN_INFO && godot?.isEditorHint() == true && (editorMessageDispatcher.hasEditorConnection(EMBEDDED_RUN_GAME_INFO) || @@ -365,7 +378,7 @@ abstract class BaseGodotEditor : GodotActivity(), GameMenuFragment.GameMenuListe // fullscreen mode, we want to remain in fullscreen mode. // This doesn't apply to the play / game window since for that window fullscreen is // controlled by the game logic. - val updatedArgs = if (editorWindowInfo == EDITOR_MAIN_INFO && + val updatedArgs = if ((editorWindowInfo == EDITOR_MAIN_INFO || editorWindowInfo == RUN_GAME_INFO) && godot?.isInImmersiveMode() == true && !args.contains(FULLSCREEN_ARG) && !args.contains(FULLSCREEN_ARG_SHORT) diff --git a/platform/android/java/editor/src/main/java/org/godotengine/editor/embed/EmbeddedGodotGame.kt b/platform/android/java/editor/src/main/java/org/godotengine/editor/embed/EmbeddedGodotGame.kt index b9ee9afed78..006380b3ff7 100644 --- a/platform/android/java/editor/src/main/java/org/godotengine/editor/embed/EmbeddedGodotGame.kt +++ b/platform/android/java/editor/src/main/java/org/godotengine/editor/embed/EmbeddedGodotGame.kt @@ -87,8 +87,8 @@ class EmbeddedGodotGame : GodotGame() { override fun setRequestedOrientation(requestedOrientation: Int) { // Allow orientation change only if fullscreen mode is active - // or if the requestedOrientation is landscape (i.e switching to default). - if (isFullscreen || requestedOrientation == ActivityInfo.SCREEN_ORIENTATION_USER_LANDSCAPE) { + // or if the requestedOrientation is unspecified (i.e switching to default). + if (isFullscreen || requestedOrientation == ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED) { super.setRequestedOrientation(requestedOrientation) } else { // Cache the requestedOrientation to apply when switching to fullscreen. @@ -155,7 +155,7 @@ class EmbeddedGodotGame : GodotGame() { // Cache the last used orientation in fullscreen to reapply when re-entering fullscreen. gameRequestedOrientation = requestedOrientation - requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_USER_LANDSCAPE + requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED } updateWindowDimensions(layoutWidthInPx, layoutHeightInPx) } diff --git a/platform/android/java/editor/src/main/res/values/themes.xml b/platform/android/java/editor/src/main/res/values/themes.xml index a889504f2cd..151b61290dc 100644 --- a/platform/android/java/editor/src/main/res/values/themes.xml +++ b/platform/android/java/editor/src/main/res/values/themes.xml @@ -1,9 +1,6 @@