Skip to content

Android: Address API 35 UI behavior changes #107742

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jun 22, 2025

Conversation

m4gr3d
Copy link
Contributor

@m4gr3d m4gr3d commented Jun 20, 2025

Follow-up to #106810 (see #106810 (comment)).

Android 15+ (target SDK 35+) enforced edge-to-edge mode for all apps. Most Godot games are immersive by default, so they should be unaffected (system bars auto dismiss), but non-immersive Godot apps and games will now have part of their UI covered by (transparent) system bars.

#106810 addressed the issue for the Android editor by opting out of that behavior, however the opt-out request is no longer respected in Android 16 so it wasn't a full solution.
This PR instead addresses the issue for Godot apps and games (including the Android editor) by updating Godot's layout padding to take into account the system bars and the display cutout.

It also add a new screen/edge_to_edge export option to allow apps / games to enable edge to edge support.

In addition, the PR also fixes an issue on foldable where the embedded window would obscure the main window when launching.

@m4gr3d m4gr3d added this to the 4.5 milestone Jun 20, 2025
@m4gr3d m4gr3d requested a review from syntaxerror247 June 20, 2025 01:17
@m4gr3d m4gr3d requested a review from a team as a code owner June 20, 2025 01:17
@syntaxerror247
Copy link
Member

syntaxerror247 commented Jun 20, 2025

I don't think this is a good idea. This PR automatically adjusts the layout padding, which effectively disables edge-to-edge mode for all Godot apps.

While it might make sense to disable edge-to-edge for the Android editor but for exported projects, we should leave this decision to the users. Godot already provides methods like get_display_safe_area() and get_display_cutouts(), which can be used to handle edge-to-edge layout properly.

Also, Android 15 deprecates the ability to change system bar colors programmatically. So, if we go ahead with this change, every non-immersive Godot app would end up with black bars on the top and bottom, which would clash with the app theme.

Personally, I would prefer keeping my app in edge-to-edge mode, rendering the background across the full screen, and placing the main content within the safe area using DisplayServer.get_display_safe_area(). This way, the system bars remain colored and match the app theme.

There's already ways for users to workaround this new restriction without disabling the edge-to-edge mode entirely.

@m4gr3d
Copy link
Contributor Author

m4gr3d commented Jun 20, 2025

I don't think this is a good idea. This PR automatically adjusts the layout padding, which effectively disables edge-to-edge mode for all Godot apps.

While it might make sense to disable edge-to-edge for the Android editor but for exported projects, we should leave this decision to the users. Godot already provides methods like get_display_safe_area() and get_display_cutouts(), which can be used to handle edge-to-edge layout properly.

This PR maintains the current behavior prior to the bump to target SDK 35, which is that we only allow the app to be either immersive (system bars auto dismiss) or not edge-to-edge (system bars show and the content don't overlap them); you can test with a 4.4 build and validate that it's the case.

Supporting edge-to-edge would be a new feature and that's not the role of this PR. Also given that we're in feature freeze, that would be something to discuss for 4.6 if we want to consider it.

Also, Android 15 deprecates the ability to change system bar colors programmatically. So, if we go ahead with this change, every non-immersive Godot app would end up with black bars on the top and bottom, which would clash with the app theme.

The PR uses enableEdgeToEdge() which is recommended by Google to make the system bars transparent, so we're following the guideline.

@m4gr3d
Copy link
Contributor Author

m4gr3d commented Jun 20, 2025

In short the primary requirement for this PR should be does it maintain the existing behavior as in 4.4 when exporting to Android.

That's all this PR should be tested against, because for most users not paying close attention to Android changes, a change in layout behavior from one version of Godot to the next, in the same project is a breaking change.

Once we validate we are maintaining the existing (expected) behavior, we can then discuss how to surface the new edge-to-edge functionality in a way that's easy to integrate.
That'll be a new feature (so likely 4.6) and that'll be off by default, so users that don't want the feature don't have to deal with it.
For a proper integration, we'll also need to update the documentation and provide tutorials for how to enable it and use the existing APIs to figure where to safely draw content.

@syntaxerror247
Copy link
Member

I don't think this is a good idea. This PR automatically adjusts the layout padding, which effectively disables edge-to-edge mode for all Godot apps.
While it might make sense to disable edge-to-edge for the Android editor but for exported projects, we should leave this decision to the users. Godot already provides methods like get_display_safe_area() and get_display_cutouts(), which can be used to handle edge-to-edge layout properly.

This PR maintains the current behavior prior to the bump to target SDK 35, which is that we only allow the app to be either immersive (system bars auto dismiss) or not edge-to-edge (system bars show and the content don't overlap them); you can test with a 4.4 build and validate that it's the case.

Yeah, This PR does maintain the behaviour prior to the bump. However, edge-to-edge was achivable using a plugin but that won't be possible after this PR.

@m4gr3d
Copy link
Contributor Author

m4gr3d commented Jun 20, 2025

Yeah, This PR does maintain the behaviour prior to the bump. However, edge-to-edge was achivable using a plugin but that won't be possible after this PR.

Well it sounds that in either case the plugin is obsolete:

  • without this change, apps are edge-to-edge by default, so there's no longer a need for the plugin
  • with this change, we'll add the edge-to-edge capability in Godot 4.6 in the engine, so the plugin will be obsolete then

The only issue is that the capability may be lost in Godot 4.5.. If we think that's an issue, then adding an export option to enable edge-to-edge should be trivial; but that means updating the documentation and providing tutorials for 4.5.. if you're up for it, it's worth considering..

@syntaxerror247
Copy link
Member

syntaxerror247 commented Jun 20, 2025

without this change, apps are edge-to-edge by default, so there's no longer a need for the plugin

This is only the case for Android 15+ devices. Without this PR, plugin would work as expected on older devices.

@syntaxerror247
Copy link
Member

syntaxerror247 commented Jun 20, 2025

The only issue is that the capability may be lost in Godot 4.5.. If we think that's an issue, then adding an export option to enable edge-to-edge should be trivial; but that means updating the documentation and providing tutorials for 4.5.. if you're up for it, it's worth considering..

Yeah, that's my concern, the capability would be lost in 4.5. Okay, Let's go with this PR for now. I'll send one to enable edge-to-edge.

@m4gr3d m4gr3d force-pushed the address_api_35_ui_issues branch from aaf8c77 to cb8e30b Compare June 20, 2025 09:46
@m4gr3d m4gr3d force-pushed the address_api_35_ui_issues branch from cb8e30b to b9f0307 Compare June 20, 2025 10:29
@m4gr3d
Copy link
Contributor Author

m4gr3d commented Jun 20, 2025

The only issue is that the capability may be lost in Godot 4.5.. If we think that's an issue, then adding an export option to enable edge-to-edge should be trivial; but that means updating the documentation and providing tutorials for 4.5.. if you're up for it, it's worth considering..

Yeah, that's my concern, the capability would be lost in 4.5. Okay, Let's go with this PR for now. I'll send one to enable edge-to-edge.

@syntaxerror247 I've updated the PR and included an export option for edge-to-edge. Can you take another look.

@m4gr3d m4gr3d requested a review from syntaxerror247 June 20, 2025 10:30
@m4gr3d m4gr3d force-pushed the address_api_35_ui_issues branch from b9f0307 to 375bec9 Compare June 20, 2025 10:59
@m4gr3d m4gr3d requested a review from a team as a code owner June 20, 2025 10:59
@m4gr3d m4gr3d force-pushed the address_api_35_ui_issues branch 2 times, most recently from ff734d8 to 2b51e0d Compare June 20, 2025 11:05
@m4gr3d m4gr3d force-pushed the address_api_35_ui_issues branch 2 times, most recently from 0d44e10 to 6e66f8f Compare June 20, 2025 11:08
Copy link
Member

@syntaxerror247 syntaxerror247 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great!

@m4gr3d m4gr3d force-pushed the address_api_35_ui_issues branch 2 times, most recently from a76339a to 631479f Compare June 20, 2025 20:23
- Fix issue on foldable where the embedded window would obscure the main window when launching
- Fix edge-to-edge support for non-immersive apps / games
- Add edge-to-edge export option to allow non-immersive apps / games to extend edge to edge
@m4gr3d m4gr3d force-pushed the address_api_35_ui_issues branch from 631479f to 2f4c3d4 Compare June 20, 2025 20:29
@akien-mga akien-mga changed the title Address API 35 UI behavior changes Android: Address API 35 UI behavior changes Jun 20, 2025
Copy link
Member

@Alex2782 Alex2782 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good! Tested on Pixel 8a - Android 16

Suggestions:

https://docs.godotengine.org/en/stable/classes/class_displayserver.html#class-displayserver-method-window-set-mode

  • WINDOW_MODE_FULLSCREEN = 3 without edge_to_edge?
  • WINDOW_MODE_EXCLUSIVE_FULLSCREEN = 4 with edge_to_edge?

  • In the Window Management demo, I was also able to change Immersive Mode at runtime. Perhaps the export settings could be removed(?) if it works at runtime and can be changed via the project settings.
func _on_button_fullscreen_pressed() -> void:
	if DisplayServer.window_get_mode() == DisplayServer.WINDOW_MODE_FULLSCREEN:
		DisplayServer.window_set_mode(DisplayServer.WINDOW_MODE_WINDOWED)
	else:
		DisplayServer.window_set_mode(DisplayServer.WINDOW_MODE_FULLSCREEN)

image

image

@syntaxerror247
Copy link
Member

syntaxerror247 commented Jun 22, 2025

  • mention in the documentation that edge_to_edge does not support every device

I think, edge-to-edge should be supported for every SDK 24+ device. I haven't tested though.

  • Is it possible to change edge_to_edge at runtime?

Not yet! Let's not block this PR, I'll send one to change it at runtime using WINDOW_MODE_MAXIMIZED (for Godot 4.6).
Ideally, WINDOW_MODE_EXCLUSIVE_FULLSCREEN should be for immersive and WINDOW_MODE_FULLSCREEN for edge-to-edge but currently both are used for immersive and changing that would break compatibility.

  • In the Window Management demo, I was also able to change Immersive Mode at runtime. Perhaps the export settings could be removed(?) if it works at runtime and can be changed via the project settings.

We are keeping the export option to instantly apply the immersive/edge-to-edge mode on launch otherwise it would create a slight noticable delay. ProjectSettings are initialised a bit late in the process.

@akien-mga akien-mga merged commit 260190c into godotengine:master Jun 22, 2025
20 checks passed
@akien-mga
Copy link
Member

Thanks!

@Alex2782
Copy link
Member

  • mention in the documentation that edge_to_edge does not support every device

I think, edge-to-edge should be supported for every SDK 24+ device. I haven't tested though.

I wanted to try it on my Samsung Tab S7 first, but the device itself doesn't have it. (This setting has no effect.)

@m4gr3d m4gr3d deleted the address_api_35_ui_issues branch June 23, 2025 16:57
@m4gr3d
Copy link
Contributor Author

m4gr3d commented Jun 23, 2025

  • mention in the documentation that edge_to_edge does not support every device

I think, edge-to-edge should be supported for every SDK 24+ device. I haven't tested though.

I wanted to try it on my Samsung Tab S7 first, but the device itself doesn't have it. (This setting has no effect.)

@Alex2782 What Android version is your tablet running?

And can you send a screenshot or recording of what the test app looks like with the following options:

  • immersive enabled and edge-to-edge disabled
  • immersive disabled and edge-to-edge enabled
  • both immersive and edge-to-edge disabled

@Alex2782
Copy link
Member

Alex2782 commented Jun 23, 2025

And can you send a screenshot or recording of what the test app looks like with the following options:

  • immersive enabled and edge-to-edge disabled
  • immersive disabled and edge-to-edge enabled
  • both immersive and edge-to-edge disabled

Samsung Android 13.

Okay, it's a different issue (theme / style). I was able to identify the edge-to-edge impact (Default 2D project). It's harder to see on the tablet because the status bar is completely black. (and takes up very little space)
A few days ago, I tested it with another project, and the app background color was darker than here.

image

@m4gr3d
Copy link
Contributor Author

m4gr3d commented Jun 23, 2025

And can you send a screenshot or recording of what the test app looks like with the following options:

  • immersive enabled and edge-to-edge disabled
  • immersive disabled and edge-to-edge enabled
  • both immersive and edge-to-edge disabled

Samsung Android 13.

Okay, it's a different issue (theme / style). I was able to identify the edge-to-edge impact (Default 2D project). It's harder to see on the tablet because the status bar is completely black. (and takes up very little space) A few days ago, I tested it with another project, and the app background color was darker than here.

image

So it seems to work as expected. I would also expect the navigation bar to be affected when edge-to-edge and immersive are enabled.

@syntaxerror247
Copy link
Member

syntaxerror247 commented Jun 23, 2025

I noticed one issue. On dark mode, the status bar icons auto adjust it's color (white/black) based on the background, as expected. However, on light mode it doesn't adjust the color and stays black as seen in screenshot in Alex's comment.
It might be a device/Android issue though.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants