diff --git a/osu.Framework.Android/AndroidGameView.cs b/osu.Framework.Android/AndroidGameView.cs index a24af49610..949b845341 100644 --- a/osu.Framework.Android/AndroidGameView.cs +++ b/osu.Framework.Android/AndroidGameView.cs @@ -64,6 +64,13 @@ public bool PointerCapture private readonly Game game; + private InputMethodManager inputMethodManager; + + /// + /// Whether is active. + /// + private bool textInputActive; + public AndroidGameView(AndroidGameActivity activity, Game game) : base(activity) { @@ -97,6 +104,8 @@ private void init() // disable ugly green border when view is focused via hardware keyboard/mouse. DefaultFocusHighlightEnabled = false; + + inputMethodManager = Activity.GetSystemService(Context.InputMethodService) as InputMethodManager; } protected override void CreateFrameBuffer() @@ -238,15 +247,43 @@ private void updateSafeArea() }; } - public override bool OnCheckIsTextEditor() => true; + public override bool OnCheckIsTextEditor() => textInputActive; + /// null to disable input methods public override IInputConnection OnCreateInputConnection(EditorInfo outAttrs) { + // Properly disable native input methods so that the software keyboard doesn't unexpectedly open. + // Eg. when pressing keys on a hardware keyboard. + if (!textInputActive) + return null; + outAttrs.ImeOptions = ImeFlags.NoExtractUi | ImeFlags.NoFullscreen; outAttrs.InputType = InputTypes.TextVariationVisiblePassword | InputTypes.TextFlagNoSuggestions; return new AndroidInputConnection(this, true); } + internal void StartTextInput() + { + textInputActive = true; + Activity.RunOnUiThread(() => + { + inputMethodManager.RestartInput(this); // this syncs the Android input method state with `OnCreateInputConnection()`. + RequestFocus(); + inputMethodManager?.ShowSoftInput(this, 0); + }); + } + + internal void StopTextInput() + { + textInputActive = false; + Activity.RunOnUiThread(() => + { + inputMethodManager.RestartInput(this); + inputMethodManager?.HideSoftInputFromWindow(WindowToken, HideSoftInputFlags.None); + ClearFocus(); + }); + } + public override void SwapBuffers() { try diff --git a/osu.Framework.Android/Input/AndroidTextInput.cs b/osu.Framework.Android/Input/AndroidTextInput.cs index 8af000777c..eab5a518d5 100644 --- a/osu.Framework.Android/Input/AndroidTextInput.cs +++ b/osu.Framework.Android/Input/AndroidTextInput.cs @@ -1,24 +1,18 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - -using Android.Content; using Android.Views; -using Android.Views.InputMethods; using osu.Framework.Input; namespace osu.Framework.Android.Input { - public class AndroidTextInput : TextInputSource + internal class AndroidTextInput : TextInputSource { private readonly AndroidGameView view; - private readonly InputMethodManager inputMethodManager; public AndroidTextInput(AndroidGameView view) { this.view = view; - inputMethodManager = view.Activity.GetSystemService(Context.InputMethodService) as InputMethodManager; } private void commitText(string text) @@ -36,33 +30,19 @@ protected override void ActivateTextInput(bool allowIme) { view.KeyDown += keyDown; view.CommitText += commitText; - - view.Activity.RunOnUiThread(() => - { - view.RequestFocus(); - inputMethodManager?.ShowSoftInput(view, 0); - }); + view.StartTextInput(); } protected override void EnsureTextInputActivated(bool allowIme) { - view.Activity.RunOnUiThread(() => - { - view.RequestFocus(); - inputMethodManager?.ShowSoftInput(view, 0); - }); + view.StartTextInput(); } protected override void DeactivateTextInput() { view.KeyDown -= keyDown; view.CommitText -= commitText; - - view.Activity.RunOnUiThread(() => - { - inputMethodManager?.HideSoftInputFromWindow(view.WindowToken, HideSoftInputFlags.None); - view.ClearFocus(); - }); + view.StopTextInput(); } } }