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 @@