using global::Android.Content; using global::Android.Views.InputMethods; namespace DodoSSH.Client.Android.Platform; /// /// Puts the software keyboard away. /// /// /// /// There is no Avalonia way to do this, and it is worth knowing why rather than assuming. /// TopLevel.InputPane reports the keyboard — its state and the rectangle it occludes, which is what /// PhoneShell keeps the interface clear of — and offers nothing that closes it. The framework's model /// is that the keyboard belongs to whatever has focus, so the supported way to dismiss one is to move focus /// off the text box that raised it. /// /// /// That model does not reach the case this exists for. The keyboard over a terminal was raised by the /// WebView's own text input, inside the page, by a native view Avalonia's focus manager does not own. /// Clearing Avalonia's focus leaves it exactly where it is, because Avalonia never had it. So the request /// goes to the platform that does own it. /// /// /// HideSoftInputFromWindow needs a window token, and any attached view's will do — they all belong to /// the same window. The decor view is the one guaranteed to exist for as long as the activity does. /// /// /// Every step is allowed to be absent and none of them is an error: there is no activity while the app is /// backgrounded, no input-method manager on a system image without one, and no keyboard up most of the time. /// A method whose whole contract is "if a keyboard is showing, stop showing it" has nothing to report when /// one is not. /// /// internal static class SoftKeyboard { public static void Hide() { if (PhoneEnvironment.CurrentActivity?.Window?.DecorView is not { } view) { return; } if (view.Context?.GetSystemService(Context.InputMethodService) is not InputMethodManager manager) { return; } manager.HideSoftInputFromWindow(view.WindowToken, HideSoftInputFlags.None); } }