Merge pull request #106709 from m4gr3d/fix_transparency_flags
Fix transparency background issue on Android
This commit is contained in:
commit
ae33da972b
@ -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]
|
||||
</constant>
|
||||
<constant name="FEATURE_WINDOW_TRANSPARENCY" value="11" enum="Feature">
|
||||
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]
|
||||
</constant>
|
||||
<constant name="FEATURE_HIDPI" value="12" enum="Feature">
|
||||
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 @@
|
||||
<constant name="WINDOW_FLAG_TRANSPARENT" value="3" enum="WindowFlags">
|
||||
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.
|
||||
</constant>
|
||||
<constant name="WINDOW_FLAG_NO_FOCUS" value="4" enum="WindowFlags">
|
||||
The window can't be focused. No-focus window will ignore all input, except mouse clicks.
|
||||
|
@ -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<Image> &p_icon) {
|
||||
// NOT SUPPORTED
|
||||
}
|
||||
|
||||
bool DisplayServerAndroid::is_window_transparency_available() const {
|
||||
return GLOBAL_GET_CACHED(bool, "display/window/per_pixel_transparency/allowed");
|
||||
}
|
||||
|
@ -256,6 +256,8 @@ public:
|
||||
virtual void set_native_icon(const String &p_filename) override;
|
||||
virtual void set_icon(const Ref<Image> &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();
|
||||
};
|
||||
|
@ -1055,6 +1055,10 @@ void EditorExportPlatformAndroid::_write_tmp_manifest(const Ref<EditorExportPres
|
||||
store_string_at_path(manifest_path, manifest_text);
|
||||
}
|
||||
|
||||
bool EditorExportPlatformAndroid::_should_be_transparent(const Ref<EditorExportPreset> &p_preset) const {
|
||||
return (bool)get_project_setting(p_preset, "display/window/per_pixel_transparency/allowed");
|
||||
}
|
||||
|
||||
void EditorExportPlatformAndroid::_fix_themes_xml(const Ref<EditorExportPreset> &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<EditorExportPreset>
|
||||
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 Ref<Edit
|
||||
valid = false;
|
||||
}
|
||||
|
||||
if (p_preset->get("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<FileAccess> f = FileAccess::open(build_version_path, FileAccess::READ);
|
||||
if (f.is_valid()) {
|
||||
@ -2987,6 +2999,12 @@ bool EditorExportPlatformAndroid::has_valid_project_configuration(const Ref<Edit
|
||||
err += "\n";
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (_should_be_transparent(p_preset)) {
|
||||
// Warning only, so don't override `valid`.
|
||||
err += vformat(TTR("\"Use Gradle Build\" is required for transparent background on Android"));
|
||||
err += "\n";
|
||||
}
|
||||
}
|
||||
|
||||
String target_sdk_str = p_preset->get("gradle_build/target_sdk");
|
||||
|
@ -163,6 +163,8 @@ class EditorExportPlatformAndroid : public EditorExportPlatform {
|
||||
|
||||
void _write_tmp_manifest(const Ref<EditorExportPreset> &p_preset, bool p_give_internet, bool p_debug);
|
||||
|
||||
bool _should_be_transparent(const Ref<EditorExportPreset> &p_preset) const;
|
||||
|
||||
void _fix_themes_xml(const Ref<EditorExportPreset> &p_preset);
|
||||
|
||||
void _fix_manifest(const Ref<EditorExportPreset> &p_preset, Vector<uint8_t> &p_manifest, bool p_give_internet);
|
||||
|
@ -5,6 +5,7 @@
|
||||
<style name="GodotAppMainTheme" parent="@android:style/Theme.DeviceDefault.NoActionBar">
|
||||
<item name="android:windowDrawsSystemBarBackgrounds">false</item>
|
||||
<item name="android:windowSwipeToDismiss">false</item>
|
||||
<item name="android:windowIsTranslucent">false</item>
|
||||
</style>
|
||||
|
||||
<!-- GodotAppSplashTheme is auto-generated during export. Manual changes will be overwritten.
|
||||
@ -13,5 +14,6 @@
|
||||
<item name="android:windowSplashScreenBackground">@mipmap/icon_background</item>
|
||||
<item name="windowSplashScreenAnimatedIcon">@mipmap/icon_foreground</item>
|
||||
<item name="postSplashScreenTheme">@style/GodotAppMainTheme</item>
|
||||
<item name="android:windowIsTranslucent">false</item>
|
||||
</style>
|
||||
</resources>
|
||||
|
@ -70,6 +70,7 @@
|
||||
android:launchMode="singleTask"
|
||||
android:process=":GodotGame"
|
||||
android:autoRemoveFromRecents="true"
|
||||
android:theme="@style/GodotGameTheme"
|
||||
android:supportsPictureInPicture="true"
|
||||
android:screenOrientation="userLandscape">
|
||||
<layout
|
||||
|
@ -2,10 +2,14 @@
|
||||
<resources>
|
||||
<style name="GodotEditorTheme" parent="@android:style/Theme.DeviceDefault.NoActionBar.Fullscreen">
|
||||
<item name="android:statusBarColor">@android:color/transparent</item>
|
||||
<item name ="android:navigationBarColor">@android:color/transparent</item>
|
||||
<item name="android:navigationBarColor">@android:color/transparent</item>
|
||||
<item name="android:windowOptOutEdgeToEdgeEnforcement">true</item>
|
||||
</style>
|
||||
|
||||
<style name="GodotGameTheme" parent="GodotEditorTheme">
|
||||
<item name="android:windowIsTranslucent">true</item>
|
||||
</style>
|
||||
|
||||
<style name="GodotEditorSplashScreenTheme" parent="Theme.SplashScreen.IconBackground">
|
||||
<!-- Set the theme of the Activity that directly follows your splash
|
||||
screen. This is required. -->
|
||||
|
@ -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) {
|
||||
|
@ -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<PointerIcon> 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
|
||||
|
@ -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<PointerIcon> 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
|
||||
|
Loading…
x
Reference in New Issue
Block a user