Skip to content

Commit ec8e6ae

Browse files
committed
Merge pull request #108557 from syntaxerror247/Fix-system-bar-regression
Android: Fix system bar regression
2 parents 6c399bd + 0506299 commit ec8e6ae

File tree

5 files changed

+54
-6
lines changed

5 files changed

+54
-6
lines changed

platform/android/doc_classes/EditorExportPlatformAndroid.xml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -598,6 +598,9 @@
598598
<member name="permissions/write_user_dictionary" type="bool" setter="" getter="">
599599
Allows an application to write to the user dictionary.
600600
</member>
601+
<member name="screen/background_color" type="Color" setter="" getter="">
602+
The background color used for the root window. Default is [code]black[/code].
603+
</member>
601604
<member name="screen/edge_to_edge" type="bool" setter="" getter="">
602605
If [code]true[/code], this makes the navigation and status bars translucent and allows the application content to extend edge to edge.
603606
[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.

platform/android/export/export_plugin.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1070,6 +1070,8 @@ void EditorExportPlatformAndroid::_fix_themes_xml(const Ref<EditorExportPreset>
10701070
main_theme_attributes["android:windowIsTranslucent"] = bool_to_string(transparency_allowed);
10711071
if (transparency_allowed) {
10721072
main_theme_attributes["android:windowBackground"] = "@android:color/transparent";
1073+
} else {
1074+
main_theme_attributes["android:windowBackground"] = "#" + p_preset->get("screen/background_color").operator Color().to_html(false);
10731075
}
10741076

10751077
Dictionary splash_theme_attributes;
@@ -2179,6 +2181,7 @@ void EditorExportPlatformAndroid::get_export_options(List<ExportOption> *r_optio
21792181
r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "screen/support_large"), true));
21802182
r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "screen/support_xlarge"), true));
21812183
r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "screen/edge_to_edge"), false));
2184+
r_options->push_back(ExportOption(PropertyInfo(Variant::COLOR, "screen/background_color", PROPERTY_HINT_COLOR_NO_ALPHA), Color()));
21822185

21832186
r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "user_data_backup/allow"), false));
21842187

@@ -3099,6 +3102,13 @@ void EditorExportPlatformAndroid::get_command_line_flags(const Ref<EditorExportP
30993102
command_line_strings.push_back("--edge_to_edge");
31003103
}
31013104

3105+
String background_color = "#" + p_preset->get("screen/background_color").operator Color().to_html(false);
3106+
if (_is_transparency_allowed(p_preset) && p_preset->get("gradle_build/use_gradle_build")) {
3107+
background_color = "#00000000";
3108+
}
3109+
command_line_strings.push_back("--background_color");
3110+
command_line_strings.push_back(background_color);
3111+
31023112
bool debug_opengl = p_preset->get("graphics/opengl_debug");
31033113
if (debug_opengl) {
31043114
command_line_strings.push_back("--debug_opengl");

platform/android/java/app/src/com/godot/game/GodotApp.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -56,11 +56,12 @@ public class GodotApp extends GodotActivity {
5656
}
5757
}
5858

59-
private final Runnable updateImmersiveAndEdgeToEdgeModes = () -> {
59+
private final Runnable updateWindowAppearance = () -> {
6060
Godot godot = getGodot();
6161
if (godot != null) {
6262
godot.enableImmersiveMode(godot.isInImmersiveMode(), true);
6363
godot.enableEdgeToEdge(godot.isInEdgeToEdgeMode(), true);
64+
godot.setSystemBarsAppearance();
6465
}
6566
};
6667

@@ -74,12 +75,12 @@ public void onCreate(Bundle savedInstanceState) {
7475
@Override
7576
public void onResume() {
7677
super.onResume();
77-
updateImmersiveAndEdgeToEdgeModes.run();
78+
updateWindowAppearance.run();
7879
}
7980

8081
@Override
8182
public void onGodotMainLoopStarted() {
8283
super.onGodotMainLoopStarted();
83-
runOnUiThread(updateImmersiveAndEdgeToEdgeModes);
84+
runOnUiThread(updateWindowAppearance);
8485
}
8586
}

platform/android/java/editor/src/main/java/org/godotengine/editor/BaseGodotEditor.kt

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -324,12 +324,13 @@ abstract class BaseGodotEditor : GodotActivity(), GameMenuFragment.GameMenuListe
324324
}
325325
}
326326

327-
private fun updateImmersiveAndEdgeToEdgeModes() {
327+
private fun updateWindowAppearance() {
328328
val editorWindowInfo = getEditorWindowInfo()
329329
if (editorWindowInfo == EDITOR_MAIN_INFO || editorWindowInfo == RUN_GAME_INFO) {
330330
godot?.apply {
331331
enableImmersiveMode(isInImmersiveMode(), true)
332332
enableEdgeToEdge(isInEdgeToEdgeMode(), true)
333+
setSystemBarsAppearance()
333334
}
334335
}
335336
}
@@ -339,13 +340,13 @@ abstract class BaseGodotEditor : GodotActivity(), GameMenuFragment.GameMenuListe
339340
runOnUiThread {
340341
// Hide the loading indicator
341342
editorLoadingIndicator?.visibility = View.GONE
342-
updateImmersiveAndEdgeToEdgeModes()
343+
updateWindowAppearance()
343344
}
344345
}
345346

346347
override fun onResume() {
347348
super.onResume()
348-
updateImmersiveAndEdgeToEdgeModes()
349+
updateWindowAppearance()
349350

350351
if (getEditorWindowInfo() == EDITOR_MAIN_INFO &&
351352
godot?.isEditorHint() == true &&

platform/android/java/lib/src/org/godotengine/godot/Godot.kt

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ import android.content.pm.PackageManager
3838
import android.content.res.Configuration
3939
import android.content.res.Resources
4040
import android.graphics.Color
41+
import android.graphics.drawable.ColorDrawable
4142
import android.hardware.Sensor
4243
import android.hardware.SensorManager
4344
import android.os.*
@@ -47,6 +48,8 @@ import android.view.*
4748
import android.widget.FrameLayout
4849
import androidx.annotation.Keep
4950
import androidx.annotation.StringRes
51+
import androidx.core.graphics.ColorUtils
52+
import androidx.core.graphics.toColorInt
5053
import androidx.core.view.ViewCompat
5154
import androidx.core.view.WindowCompat
5255
import androidx.core.view.WindowInsetsAnimationCompat
@@ -187,6 +190,7 @@ class Godot private constructor(val context: Context) {
187190
private val isEdgeToEdge = AtomicBoolean(false)
188191
private var useDebugOpengl = false
189192
private var darkMode = false
193+
private var backgroundColor: Int = Color.BLACK
190194

191195
internal var containerLayout: FrameLayout? = null
192196
var renderView: GodotRenderView? = null
@@ -255,6 +259,17 @@ class Godot private constructor(val context: Context) {
255259
} else if (commandLine[i] == "--fullscreen") {
256260
useImmersive.set(true)
257261
newArgs.add(commandLine[i])
262+
} else if (commandLine[i] == "--background_color") {
263+
val colorStr = commandLine[i + 1]
264+
try {
265+
backgroundColor = colorStr.toColorInt()
266+
Log.d(TAG, "background color = $backgroundColor")
267+
} catch (e: java.lang.IllegalArgumentException) {
268+
Log.d(TAG, "Failed to parse background color: $colorStr")
269+
}
270+
runOnHostThread {
271+
getActivity()?.window?.decorView?.setBackgroundColor(backgroundColor)
272+
}
258273
} else if (commandLine[i] == "--use_apk_expansion") {
259274
useApkExpansion = true
260275
} else if (hasExtra && commandLine[i] == "--apk_expansion_md5") {
@@ -459,6 +474,24 @@ class Godot private constructor(val context: Context) {
459474
@Keep
460475
fun isInEdgeToEdgeMode() = isEdgeToEdge.get()
461476

477+
fun setSystemBarsAppearance() {
478+
val window = getActivity()?.window ?: return
479+
val isLight = ColorUtils.calculateLuminance(getWindowBackgroundColor(window)) > 0.5
480+
481+
val controller = WindowInsetsControllerCompat(window, window.decorView)
482+
controller.isAppearanceLightNavigationBars = isLight
483+
controller.isAppearanceLightStatusBars = isLight
484+
}
485+
486+
private fun getWindowBackgroundColor(window: Window): Int {
487+
val background = window.decorView.background
488+
return if (background is ColorDrawable) {
489+
background.color
490+
} else {
491+
backgroundColor
492+
}
493+
}
494+
462495
/**
463496
* Used to complete initialization of the view used by the engine for rendering.
464497
*

0 commit comments

Comments
 (0)