Skip to content

Fix immersive mode and virtual keyboard height issue on Android #108287

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

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

syntaxerror247
Copy link
Member

@syntaxerror247 syntaxerror247 commented Jul 4, 2025

Fixes #86663

This PR fixes the incorrect virtual keyboard height issue and adds support on API 29 and older.
Fixes all the known immersive and edge-to-edge mode issues.

@Calinou
Copy link
Member

Calinou commented Jul 4, 2025

@kilojool Can you test this PR locally to see if it resolves the issue?

@llama-nl

This comment was marked as outdated.

@syntaxerror247
Copy link
Member Author

@llama-nl It might not work on embedded window. Can you test with exported project, or try disabling embedded window and with gamebar hidden.

@llama-nl
Copy link

llama-nl commented Jul 5, 2025

@syntaxerror247 ok, it works in protrait mode. I think it doesn't working in landscape mode?
Screenshot_20250705_103759

@syntaxerror247
Copy link
Member Author

@syntaxerror247 ok, it works in protrait mode. I think it doesn't working in landscape mode? Screenshot_20250705_103759

That's an issue with the MRP project. Stretch mode is set to canvas_item, which scales the viewport (as seen in landscape). But the keyboard height is not scaled, it's in physical pixels.

To fix this, either set stretch mode to disabled, or divide the keyboard height by the scale

size.y = get_viewport_rect().size.y - (DisplayServer.virtual_keyboard_get_height() / get_viewport_transform().get_scale().y)

@kilojool
Copy link
Contributor

kilojool commented Jul 5, 2025

It works great on Android 12 for me, but on Android 9 it always returns 0 regardless if the keyboard is visible or not.

@syntaxerror247 syntaxerror247 force-pushed the fix-virtual-keyboard-height branch from e844e5e to ff3c944 Compare July 6, 2025 12:49
@syntaxerror247
Copy link
Member Author

It works great on Android 12 for me, but on Android 9 it always returns 0 regardless if the keyboard is visible or not.

@kilojool The method used to calculate the virtual keyboard height is only available on Android 11 and above. I’ve now added support for older versions as well. Could you please test it again and let me know if it works now?

@syntaxerror247 syntaxerror247 force-pushed the fix-virtual-keyboard-height branch from ff3c944 to 63aacd5 Compare July 6, 2025 14:04
@kilojool
Copy link
Contributor

kilojool commented Jul 6, 2025

@syntaxerror247 Yes, that fixed it for me on Android 9 also! Nice work! =D

@syntaxerror247 syntaxerror247 requested a review from Alex2782 July 6, 2025 14:10
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.

Test project: NavigationBarProblem.zip

Tested on Samsung Tab S7 (Android 13) and LG Nexus 5X (Android 8)

I had to modify MRP, disable Gradle build (Godot 4.3 custom mods, probably no longer compatible), and take scaling into account.

func _process(_delta):
	#https://github.com/godotengine/godot/issues/86663#issuecomment-2132230189
	var keyboard_height := DisplayServer.virtual_keyboard_get_height()
	self.size.y = get_viewport_rect().size.y - (keyboard_height / get_viewport_transform().get_scale().y)

On the LG Nexus 5X (Android 8), there are problems when Immersive mode is enabled. As soon as the keyboard appears, Immersive mode is exited. Probably OS specific. On Samsung Tab S7 (Android 13), I couldn't find any issues.

Video: Issues / Test LG Nexus 5X, Immersive mode + Edge To Edge
nexus_5x.mp4

Input field is suddenly behind the navigation bar when the keyboard is hidden again.

@syntaxerror247
Copy link
Member Author

syntaxerror247 commented Jul 7, 2025

On the LG Nexus 5X (Android 8), there are problems when Immersive mode is enabled. As soon as the keyboard appears, Immersive mode is exited. Probably OS specific. On Samsung Tab S7 (Android 13), I couldn't find any issues.

Video: Issues / Test LG Nexus 5X, Immersive mode + Edge To Edge
Input field is suddenly behind the navigation bar when the keyboard is hidden again.

I also noticed issues with immersive/edge-to-edge mode on android 9 (emulator), I'm looking into it.

@syntaxerror247 syntaxerror247 force-pushed the fix-virtual-keyboard-height branch from 63aacd5 to 80cce84 Compare July 8, 2025 13:17
@syntaxerror247 syntaxerror247 requested review from Alex2782 and m4gr3d July 8, 2025 13:24
@syntaxerror247 syntaxerror247 changed the title Fix virtual keyboard height issue on Android Fix immersive mode and virtual keyboard height issue on Android Jul 8, 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.

It works better than before on Nexus 5X Android 8, in Immersive Mode.

However, if Immersive Mode is disabled and Edge to Edge is enabled, the input field behind the navigation bar disappears. Partially on the Samsung Tab S7, and completely on the Nexus 5X.

Screenshots

image

Samsung Tab S7 (Android 13)

image

Bildschirmfoto 2025-07-09 um 23 25 16


Google Nexus 5X (Android 8)

image

image

@Alex2782
Copy link
Member

Alex2782 commented Jul 9, 2025

Test project: NavigationBarProblem.zip

DisplayServer.virtual_keyboard_get_height()

Now the function returns 0 (Android 8) if Immersive Mode is disabled.
Only the first time the keyboard is displayed height = 0, the second time it works.

image

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.

See above.

Can you reproduce it? Otherwise, I'll check it more closely on my device later.

@syntaxerror247
Copy link
Member Author

However, if Immersive Mode is disabled and Edge to Edge is enabled, the input field behind the navigation bar disappears. Partially on the Samsung Tab S7, and completely on the Nexus 5X.

That's an exected behaviour. App shouldn't place any interactable node at bottom, if using use edge-to-edge mode.

@syntaxerror247
Copy link
Member Author

DisplayServer.virtual_keyboard_get_height()

Now the function returns 0 (Android 8) if Immersive Mode is disabled.
Only the first time the keyboard is displayed height = 0, the second time it works.

Yes, I can reproduce this on an Android 7 emulator (not reproducible on Android 9; I haven't tested on 8).
The WindowInsetsAnimationCallback doesn’t get triggered the first time the keyboard opens. I looked into it but couldn’t find anything. Initially, I suspected it might be an emulator bug, but since it can be reproduced on a physical device as well, it's likely a bug in the API itself.

We have two possible solutions:

  1. Revert to my previous approach using OnGlobalLayoutListener for Android 7 and 8.

  2. Document this behavior: the keyboard height is not returned the first time the keyboard opens for non-immersive mode on Android 7 and 8.

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.

Virtual keyboard height is wrong when making navigation bar permanently visible
5 participants