godotengine / godot

Godot Engine – Multi-platform 2D and 3D game engine
https://godotengine.org
MIT License
90.87k stars 21.14k forks source link

Virtual Keyboard is covering focused LineEdit on games exported to Android #87411

Open Melon-The-Dev opened 9 months ago

Melon-The-Dev commented 9 months ago

Tested versions

tested on version 4.0 to 4.2, the issue still happens

System information

Windows 10 - Godot_v4.2 - mobile rendering

Issue description

i have a mobile game with lineedits, and when i tap the line edit to type some stuff to it, the virtual keyboard just shows up on top of the line edit making it impossible for me to see and move the caret around. i expect it to move the lineedit above the virtual keyboard so i could see where i am typing and move the caret around/selecting text.

same issue, but posted on reddit

Steps to reproduce

create a new project add a lineedit near or at the bottom part of the scene save and export as apk then testing the game and pressing the lineedit, it just get covered up by the virtual keyboard

Minimal reproduction project (MRP)

~none~

Veradictus commented 7 months ago

Still present, makes having to code whacky workarounds for mobile games.

akien-mga commented 4 months ago

Duplicate #76803

Technically that issue is about the Android editor port, while this one is about a game using LineEdit on Android.

Both have the same underlying cause, but the solutions might be different (a custom virtual keyboard implementation that's better for coding/editor), and a more generic way to adjust the default virtual keyboard position for common game needs (e.g. typing user login and password).

CC @m4gr3d

Anixias commented 4 months ago

Here's how you implement it (in C# - works the same way in gdscript):

  1. Create a scene with a root node of type MarginContainer. Name the scene VirtualKeyboardSpacer, or similar.
  2. Attach the script below to the VirtualKeyboardSpacer.
  3. When you use a LineEdit in your game/app, place it as a child of a VirtualKeyboardSpacer.

C# script:

#if GODOT_MOBILE
using System;
#endif

using Godot;

public partial class VirtualKeyboardSpacer : MarginContainer
{
    #if GODOT_MOBILE
    public override void _Process(double delta)
    {
        var margin = (double)DisplayServer.VirtualKeyboardGetHeight();
        margin /= DisplayServer.ScreenGetScale();
        margin -= GetViewportRect().End.Y - GetGlobalRect().End.Y;
        AddThemeConstantOverride("margin_bottom", Math.Max(Mathf.FloorToInt(margin), 0));
    }
    #endif
}