diff --git a/src/Android/Avalonia.Android/Platform/Input/AndroidInputMethod.cs b/src/Android/Avalonia.Android/Platform/Input/AndroidInputMethod.cs index 1223fb9ece..8003db6607 100644 --- a/src/Android/Avalonia.Android/Platform/Input/AndroidInputMethod.cs +++ b/src/Android/Avalonia.Android/Platform/Input/AndroidInputMethod.cs @@ -72,6 +72,13 @@ namespace Avalonia.Android.Platform.Input public void SetClient(TextInputMethodClient? client) { + if(_client != null) + { + _client.SurroundingTextChanged -= _client_SurroundingTextChanged; + _client.SelectionChanged -= _client_SelectionChanged; + _client.InputPaneActivationRequested -= _client_InputPaneActivationRequested; + } + _client = client; if (IsActive) @@ -86,16 +93,24 @@ namespace Avalonia.Android.Platform.Input _client.SurroundingTextChanged += _client_SurroundingTextChanged; _client.SelectionChanged += _client_SelectionChanged; + _client.InputPaneActivationRequested += _client_InputPaneActivationRequested; } else { - _host.ClearFocus(); _imm.RestartInput(View); _inputConnection = null; _imm.HideSoftInputFromWindow(_host.WindowToken, HideSoftInputFlags.ImplicitOnly); } } + private void _client_InputPaneActivationRequested(object? sender, EventArgs e) + { + if(IsActive) + { + _imm.ShowSoftInput(_host, ShowFlags.Implicit); + } + } + private void _client_SelectionChanged(object? sender, EventArgs e) { if (_inputConnection is null || _inputConnection.IsInBatchEdit || _inputConnection.IsInUpdate) diff --git a/src/Avalonia.Base/Input/TextInput/TextInputMethodClient.cs b/src/Avalonia.Base/Input/TextInput/TextInputMethodClient.cs index ca91b861a8..7f9870315b 100644 --- a/src/Avalonia.Base/Input/TextInput/TextInputMethodClient.cs +++ b/src/Avalonia.Base/Input/TextInput/TextInputMethodClient.cs @@ -28,6 +28,11 @@ namespace Avalonia.Input.TextInput /// Fires when client wants to reset IME state /// public event EventHandler? ResetRequested; + + /// + /// Fires when client requests the input panel be opened. + /// + public event EventHandler? InputPaneActivationRequested; /// /// The visual that's showing the text @@ -78,7 +83,12 @@ namespace Avalonia.Input.TextInput SetPreeditText(preeditText); } - public virtual void ShowInputPanel() { } + //TODO12: remove + [Obsolete] + public virtual void ShowInputPanel() + { + RaiseInputPaneActivationRequested(); + } protected virtual void RaiseTextViewVisualChanged() { @@ -99,6 +109,11 @@ namespace Avalonia.Input.TextInput { SelectionChanged?.Invoke(this, EventArgs.Empty); } + + protected virtual void RaiseInputPaneActivationRequested() + { + InputPaneActivationRequested?.Invoke(this, EventArgs.Empty); + } protected virtual void RequestReset() { diff --git a/src/Avalonia.Controls/TextBox.cs b/src/Avalonia.Controls/TextBox.cs index a5728d44ea..3927fe3833 100644 --- a/src/Avalonia.Controls/TextBox.cs +++ b/src/Avalonia.Controls/TextBox.cs @@ -1791,8 +1791,6 @@ namespace Avalonia.Controls if (e.Pointer.Type != PointerType.Mouse && !_isDoubleTapped) { - _imClient.ShowInputPanel(); - var text = Text; var clickInfo = e.GetCurrentPoint(this); if (text != null && !(clickInfo.Pointer?.Captured is Border)) diff --git a/src/Avalonia.Controls/TextBoxTextInputMethodClient.cs b/src/Avalonia.Controls/TextBoxTextInputMethodClient.cs index 5d35124c69..12e8e97640 100644 --- a/src/Avalonia.Controls/TextBoxTextInputMethodClient.cs +++ b/src/Avalonia.Controls/TextBoxTextInputMethodClient.cs @@ -13,7 +13,6 @@ namespace Avalonia.Controls private TextPresenter? _presenter; private bool _selectionChanged; private bool _isInChange; - private ITextInputMethodImpl? _im; public override Visual TextViewVisual => _presenter!; @@ -119,6 +118,7 @@ namespace Avalonia.Controls if (_parent != null) { _parent.PropertyChanged -= OnParentPropertyChanged; + _parent.Tapped -= OnParentTapped; } _parent = parent; @@ -126,11 +126,7 @@ namespace Avalonia.Controls if (_parent != null) { _parent.PropertyChanged += OnParentPropertyChanged; - _im = (_parent.VisualRoot as ITextInputMethodRoot)?.InputMethod; - } - else - { - _im = null; + _parent.Tapped += OnParentTapped; } var oldPresenter = _presenter; @@ -154,6 +150,11 @@ namespace Avalonia.Controls RaiseCursorRectangleChanged(); } + private void OnParentTapped(object? sender, Input.TappedEventArgs e) + { + RaiseInputPaneActivationRequested(); + } + public override void SetPreeditText(string? preeditText) => SetPreeditText(preeditText, null); public override void SetPreeditText(string? preeditText, int? cursorPos) @@ -167,17 +168,6 @@ namespace Avalonia.Controls _presenter.SetCurrentValue(TextPresenter.PreeditTextCursorPositionProperty, cursorPos); } - public override void ShowInputPanel() - { - base.ShowInputPanel(); - - if (_parent is { } && _im is { }) - { - _im.SetOptions(TextInputOptions.FromStyledElement(_parent)); - _im.SetClient(this); - } - } - private static string GetTextLineText(TextLine textLine) { if (textLine.Length == 0) diff --git a/src/Browser/Avalonia.Browser/BrowserTextInputMethod.cs b/src/Browser/Avalonia.Browser/BrowserTextInputMethod.cs index fbcbf15ee5..11722851b7 100644 --- a/src/Browser/Avalonia.Browser/BrowserTextInputMethod.cs +++ b/src/Browser/Avalonia.Browser/BrowserTextInputMethod.cs @@ -29,11 +29,13 @@ internal class BrowserTextInputMethod( if (_client != null) { _client.SurroundingTextChanged -= SurroundingTextChanged; + _client.InputPaneActivationRequested -= InputPaneActivationRequested; } if (client != null) { client.SurroundingTextChanged += SurroundingTextChanged; + client.InputPaneActivationRequested += InputPaneActivationRequested; } InputHelper.ClearInputElement(_inputElement); @@ -42,8 +44,7 @@ internal class BrowserTextInputMethod( if (_client != null) { - InputHelper.ShowElement(_inputElement); - InputHelper.FocusElement(_inputElement); + ShowIme(); var surroundingText = _client.SurroundingText ?? ""; var selection = _client.Selection; @@ -56,6 +57,20 @@ internal class BrowserTextInputMethod( } } + private void InputPaneActivationRequested(object? sender, EventArgs e) + { + if (_client != null) + { + ShowIme(); + } + } + + private void ShowIme() + { + InputHelper.ShowElement(_inputElement); + InputHelper.FocusElement(_inputElement); + } + private void SurroundingTextChanged(object? sender, EventArgs e) { if (_client != null) diff --git a/src/Tizen/Avalonia.Tizen/NuiAvaloniaViewTextEditable.cs b/src/Tizen/Avalonia.Tizen/NuiAvaloniaViewTextEditable.cs index c3e7577674..c7e05afc52 100644 --- a/src/Tizen/Avalonia.Tizen/NuiAvaloniaViewTextEditable.cs +++ b/src/Tizen/Avalonia.Tizen/NuiAvaloniaViewTextEditable.cs @@ -118,6 +118,7 @@ internal class NuiAvaloniaViewTextEditable client.TextViewVisualChanged += OnTextViewVisualChanged; client.SurroundingTextChanged += OnSurroundingTextChanged; client.SelectionChanged += OnClientSelectionChanged; + client.InputPaneActivationRequested += OnInputPaneActivationRequested; TextInput.SelectWholeText(); OnClientSelectionChanged(this, EventArgs.Empty); @@ -125,6 +126,12 @@ internal class NuiAvaloniaViewTextEditable finally { _updating = false; } } + private void OnInputPaneActivationRequested(object? sender, EventArgs e) + { + var inputContext = TextInput.GetInputMethodContext(); + inputContext.ShowInputPanel(); + } + private void OnClientSelectionChanged(object? sender, EventArgs e) => InvokeUpdate(client => { if (client.Selection.End == 0 || client.Selection.Start == client.Selection.End) @@ -152,6 +159,7 @@ internal class NuiAvaloniaViewTextEditable _client!.TextViewVisualChanged -= OnTextViewVisualChanged; _client!.SurroundingTextChanged -= OnSurroundingTextChanged; _client!.SelectionChanged -= OnClientSelectionChanged; + _client!.InputPaneActivationRequested -= OnInputPaneActivationRequested; } if (Window.Instance.GetDefaultLayer().Children.Contains((View)TextInput))