diff --git a/doc/classes/DisplayServer.xml b/doc/classes/DisplayServer.xml
index 15b3c997fbb..af17a38f8f3 100644
--- a/doc/classes/DisplayServer.xml
+++ b/doc/classes/DisplayServer.xml
@@ -2543,7 +2543,7 @@
Display server supports [url=https://en.wikipedia.org/wiki/Input_method]Input Method Editor[/url], which is commonly used for inputting Chinese/Japanese/Korean text. This is handled by the operating system, rather than by Godot. [b]Windows, macOS, Linux (X11)[/b]
- Display server supports windows can use per-pixel transparency to make windows behind them partially or fully visible. [b]Windows, macOS, Linux (X11/Wayland)[/b]
+ Display server supports windows can use per-pixel transparency to make windows behind them partially or fully visible. [b]Windows, macOS, Linux (X11/Wayland), Android[/b]
Display server supports querying the operating system's display scale factor. This allows automatically detecting the hiDPI display [i]reliably[/i], instead of guessing based on the screen resolution and the display's reported DPI (which might be unreliable due to broken monitor EDID). [b]Windows, Linux (Wayland), macOS[/b]
@@ -3073,7 +3073,7 @@
The window background can be transparent.
[b]Note:[/b] This flag has no effect if [method is_window_transparency_available] returns [code]false[/code].
- [b]Note:[/b] Transparency support is implemented on Linux (X11/Wayland), macOS, and Windows, but availability might vary depending on GPU driver, display manager, and compositor capabilities.
+ [b]Note:[/b] Transparency support is implemented on Android, Linux (X11/Wayland), macOS, and Windows, but availability might vary depending on GPU driver, display manager, and compositor capabilities.
The window can't be focused. No-focus window will ignore all input, except mouse clicks.
diff --git a/platform/android/display_server_android.cpp b/platform/android/display_server_android.cpp
index 32479316adf..64e1fea119d 100644
--- a/platform/android/display_server_android.cpp
+++ b/platform/android/display_server_android.cpp
@@ -76,7 +76,7 @@ bool DisplayServerAndroid::has_feature(Feature p_feature) const {
//case FEATURE_NATIVE_DIALOG_FILE_EXTRA:
case FEATURE_NATIVE_DIALOG_FILE_MIME:
//case FEATURE_NATIVE_ICON:
- //case FEATURE_WINDOW_TRANSPARENCY:
+ case FEATURE_WINDOW_TRANSPARENCY:
case FEATURE_CLIPBOARD:
case FEATURE_KEEP_SCREEN_ON:
case FEATURE_ORIENTATION:
@@ -592,7 +592,13 @@ void DisplayServerAndroid::window_set_flag(DisplayServer::WindowFlags p_flag, bo
}
bool DisplayServerAndroid::window_get_flag(DisplayServer::WindowFlags p_flag, DisplayServer::WindowID p_window) const {
- return false;
+ switch (p_flag) {
+ case WindowFlags::WINDOW_FLAG_TRANSPARENT:
+ return is_window_transparency_available();
+
+ default:
+ return false;
+ }
}
void DisplayServerAndroid::window_request_attention(DisplayServer::WindowID p_window) {
@@ -961,3 +967,7 @@ void DisplayServerAndroid::set_native_icon(const String &p_filename) {
void DisplayServerAndroid::set_icon(const Ref &p_icon) {
// NOT SUPPORTED
}
+
+bool DisplayServerAndroid::is_window_transparency_available() const {
+ return GLOBAL_GET_CACHED(bool, "display/window/per_pixel_transparency/allowed");
+}
diff --git a/platform/android/display_server_android.h b/platform/android/display_server_android.h
index 0b650f84fd8..5b09128ee3c 100644
--- a/platform/android/display_server_android.h
+++ b/platform/android/display_server_android.h
@@ -256,6 +256,8 @@ public:
virtual void set_native_icon(const String &p_filename) override;
virtual void set_icon(const Ref &p_icon) override;
+ virtual bool is_window_transparency_available() const override;
+
DisplayServerAndroid(const String &p_rendering_driver, WindowMode p_mode, DisplayServer::VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, int p_screen, Context p_context, int64_t p_parent_window, Error &r_error);
~DisplayServerAndroid();
};
diff --git a/platform/android/export/export_plugin.cpp b/platform/android/export/export_plugin.cpp
index 090b31e1290..b3f2327a607 100644
--- a/platform/android/export/export_plugin.cpp
+++ b/platform/android/export/export_plugin.cpp
@@ -1055,6 +1055,10 @@ void EditorExportPlatformAndroid::_write_tmp_manifest(const Ref &p_preset) const {
+ return (bool)get_project_setting(p_preset, "display/window/per_pixel_transparency/allowed");
+}
+
void EditorExportPlatformAndroid::_fix_themes_xml(const Ref &p_preset) {
const String themes_xml_path = ExportTemplateManager::get_android_build_directory(p_preset).path_join("res/values/themes.xml");
@@ -1063,15 +1067,22 @@ void EditorExportPlatformAndroid::_fix_themes_xml(const Ref
return;
}
+ bool should_be_transparent = _should_be_transparent(p_preset);
+
// 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) {
+ main_theme_attributes["android:windowBackground"] = "@android:color/transparent";
+ }
Dictionary splash_theme_attributes;
splash_theme_attributes["android:windowSplashScreenBackground"] = "@mipmap/icon_background";
splash_theme_attributes["windowSplashScreenAnimatedIcon"] = "@mipmap/icon_foreground";
splash_theme_attributes["postSplashScreenTheme"] = "@style/GodotAppMainTheme";
+ splash_theme_attributes["android:windowIsTranslucent"] = bool_to_string(should_be_transparent);
Dictionary custom_theme_attributes = p_preset->get("gradle_build/custom_theme_attributes");
@@ -2976,7 +2987,8 @@ bool EditorExportPlatformAndroid::has_valid_project_configuration(const Refget("gradle_build/use_gradle_build")) {
+ bool gradle_build_enabled = p_preset->get("gradle_build/use_gradle_build");
+ if (gradle_build_enabled) {
String build_version_path = ExportTemplateManager::get_android_build_directory(p_preset).get_base_dir().path_join(".build_version");
Ref f = FileAccess::open(build_version_path, FileAccess::READ);
if (f.is_valid()) {
@@ -2987,6 +2999,12 @@ bool EditorExportPlatformAndroid::has_valid_project_configuration(const Refget("gradle_build/target_sdk");
diff --git a/platform/android/export/export_plugin.h b/platform/android/export/export_plugin.h
index aefb74abcd7..0620c9f966e 100644
--- a/platform/android/export/export_plugin.h
+++ b/platform/android/export/export_plugin.h
@@ -163,6 +163,8 @@ class EditorExportPlatformAndroid : public EditorExportPlatform {
void _write_tmp_manifest(const Ref &p_preset, bool p_give_internet, bool p_debug);
+ bool _should_be_transparent(const Ref &p_preset) const;
+
void _fix_themes_xml(const Ref &p_preset);
void _fix_manifest(const Ref &p_preset, Vector &p_manifest, bool p_give_internet);
diff --git a/platform/android/java/app/res/values/themes.xml b/platform/android/java/app/res/values/themes.xml
index 53e3516154d..600775fb62e 100644
--- a/platform/android/java/app/res/values/themes.xml
+++ b/platform/android/java/app/res/values/themes.xml
@@ -5,6 +5,7 @@
diff --git a/platform/android/java/lib/src/org/godotengine/godot/Godot.kt b/platform/android/java/lib/src/org/godotengine/godot/Godot.kt
index ebe4e8960ae..8b4973d5771 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/Godot.kt
+++ b/platform/android/java/lib/src/org/godotengine/godot/Godot.kt
@@ -478,19 +478,24 @@ class Godot(private val context: Context) {
editText.setBackgroundColor(Color.TRANSPARENT)
// ...add to FrameLayout
containerLayout?.addView(editText)
+
+ // Check whether the render view should be made transparent
+ val shouldBeTransparent =
+ !isProjectManagerHint() && !isEditorHint() && java.lang.Boolean.parseBoolean(GodotLib.getGlobal("display/window/per_pixel_transparency/allowed"))
+ Log.d(TAG, "Render view should be transparent: $shouldBeTransparent")
renderView = if (usesVulkan()) {
if (meetsVulkanRequirements(activity.packageManager)) {
- GodotVulkanRenderView(host, this, godotInputHandler)
+ GodotVulkanRenderView(host, this, godotInputHandler, shouldBeTransparent)
} else if (canFallbackToOpenGL()) {
// Fallback to OpenGl.
- GodotGLRenderView(host, this, godotInputHandler, xrMode, useDebugOpengl)
+ GodotGLRenderView(host, this, godotInputHandler, xrMode, useDebugOpengl, shouldBeTransparent)
} else {
throw IllegalStateException(activity.getString(R.string.error_missing_vulkan_requirements_message))
}
} else {
// Fallback to OpenGl.
- GodotGLRenderView(host, this, godotInputHandler, xrMode, useDebugOpengl)
+ GodotGLRenderView(host, this, godotInputHandler, xrMode, useDebugOpengl, shouldBeTransparent)
}
if (host == primaryHost) {
diff --git a/platform/android/java/lib/src/org/godotengine/godot/GodotGLRenderView.java b/platform/android/java/lib/src/org/godotengine/godot/GodotGLRenderView.java
index 6b3f7c4a67c..bddea29b4d4 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/GodotGLRenderView.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/GodotGLRenderView.java
@@ -46,7 +46,6 @@ import android.content.res.AssetManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.PixelFormat;
-import android.os.Build;
import android.text.TextUtils;
import android.util.SparseArray;
import android.view.KeyEvent;
@@ -83,7 +82,7 @@ class GodotGLRenderView extends GLSurfaceView implements GodotRenderView {
private final GodotRenderer godotRenderer;
private final SparseArray customPointerIcons = new SparseArray<>();
- public GodotGLRenderView(GodotHost host, Godot godot, GodotInputHandler inputHandler, XRMode xrMode, boolean useDebugOpengl) {
+ public GodotGLRenderView(GodotHost host, Godot godot, GodotInputHandler inputHandler, XRMode xrMode, boolean useDebugOpengl, boolean shouldBeTranslucent) {
super(host.getActivity());
this.host = host;
@@ -91,7 +90,7 @@ class GodotGLRenderView extends GLSurfaceView implements GodotRenderView {
this.inputHandler = inputHandler;
this.godotRenderer = new GodotRenderer();
setPointerIcon(PointerIcon.getSystemIcon(getContext(), PointerIcon.TYPE_DEFAULT));
- init(xrMode, false, useDebugOpengl);
+ init(xrMode, shouldBeTranslucent, useDebugOpengl);
}
@Override
diff --git a/platform/android/java/lib/src/org/godotengine/godot/GodotVulkanRenderView.java b/platform/android/java/lib/src/org/godotengine/godot/GodotVulkanRenderView.java
index 64e8119ee83..f9a552fd23d 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/GodotVulkanRenderView.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/GodotVulkanRenderView.java
@@ -38,7 +38,7 @@ import android.annotation.SuppressLint;
import android.content.res.AssetManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
-import android.os.Build;
+import android.graphics.PixelFormat;
import android.text.TextUtils;
import android.util.SparseArray;
import android.view.KeyEvent;
@@ -57,7 +57,7 @@ class GodotVulkanRenderView extends VkSurfaceView implements GodotRenderView {
private final VkRenderer mRenderer;
private final SparseArray customPointerIcons = new SparseArray<>();
- public GodotVulkanRenderView(GodotHost host, Godot godot, GodotInputHandler inputHandler) {
+ public GodotVulkanRenderView(GodotHost host, Godot godot, GodotInputHandler inputHandler, boolean shouldBeTranslucent) {
super(host.getActivity());
this.host = host;
@@ -67,6 +67,10 @@ class GodotVulkanRenderView extends VkSurfaceView implements GodotRenderView {
setPointerIcon(PointerIcon.getSystemIcon(getContext(), PointerIcon.TYPE_DEFAULT));
setFocusableInTouchMode(true);
setClickable(false);
+
+ if (shouldBeTranslucent) {
+ this.getHolder().setFormat(PixelFormat.TRANSLUCENT);
+ }
}
@Override