|
|
@ -90,6 +90,7 @@ partial class AvaloniaView |
|
|
private int _inSurroundingTextUpdateEvent; |
|
|
private int _inSurroundingTextUpdateEvent; |
|
|
private readonly UITextPosition _beginningOfDocument = new AvaloniaTextPosition(0); |
|
|
private readonly UITextPosition _beginningOfDocument = new AvaloniaTextPosition(0); |
|
|
private readonly UITextInputStringTokenizer _tokenizer; |
|
|
private readonly UITextInputStringTokenizer _tokenizer; |
|
|
|
|
|
private bool _isInUpdate; |
|
|
|
|
|
|
|
|
public TextInputMethodClient? Client => _client; |
|
|
public TextInputMethodClient? Client => _client; |
|
|
|
|
|
|
|
|
@ -142,15 +143,15 @@ partial class AvaloniaView |
|
|
private void SurroundingTextChanged(object? sender, EventArgs e) |
|
|
private void SurroundingTextChanged(object? sender, EventArgs e) |
|
|
{ |
|
|
{ |
|
|
Logger.TryGet(LogEventLevel.Debug, ImeLog)?.Log(null, "SurroundingTextChanged"); |
|
|
Logger.TryGet(LogEventLevel.Debug, ImeLog)?.Log(null, "SurroundingTextChanged"); |
|
|
if (WeakInputDelegate == null) |
|
|
if (WeakInputDelegate == null || _isInUpdate) |
|
|
return; |
|
|
return; |
|
|
_inSurroundingTextUpdateEvent++; |
|
|
_inSurroundingTextUpdateEvent++; |
|
|
try |
|
|
try |
|
|
{ |
|
|
{ |
|
|
objc_msgSend(WeakInputDelegate.Handle.Handle, TextWillChange, Handle.Handle); |
|
|
objc_msgSend(WeakInputDelegate.Handle.Handle, TextWillChange, Handle.Handle); |
|
|
objc_msgSend(WeakInputDelegate.Handle.Handle, TextDidChange, Handle.Handle); |
|
|
objc_msgSend(WeakInputDelegate.Handle.Handle, TextDidChange, Handle.Handle); |
|
|
objc_msgSend(WeakInputDelegate.Handle.Handle, SelectionWillChange, this.Handle.Handle); |
|
|
objc_msgSend(WeakInputDelegate.Handle.Handle, SelectionWillChange, Handle.Handle); |
|
|
objc_msgSend(WeakInputDelegate.Handle.Handle, SelectionDidChange, this.Handle.Handle); |
|
|
objc_msgSend(WeakInputDelegate.Handle.Handle, SelectionDidChange, Handle.Handle); |
|
|
} |
|
|
} |
|
|
finally |
|
|
finally |
|
|
{ |
|
|
{ |
|
|
@ -160,6 +161,7 @@ partial class AvaloniaView |
|
|
|
|
|
|
|
|
private void KeyPress(Key key, PhysicalKey physicalKey, string? keySymbol) |
|
|
private void KeyPress(Key key, PhysicalKey physicalKey, string? keySymbol) |
|
|
{ |
|
|
{ |
|
|
|
|
|
_isInUpdate = true; |
|
|
Logger.TryGet(LogEventLevel.Debug, ImeLog)?.Log(null, "Triggering key press {key}", key); |
|
|
Logger.TryGet(LogEventLevel.Debug, ImeLog)?.Log(null, "Triggering key press {key}", key); |
|
|
|
|
|
|
|
|
if (_view._topLevelImpl.Input is { } input) |
|
|
if (_view._topLevelImpl.Input is { } input) |
|
|
@ -170,12 +172,15 @@ partial class AvaloniaView |
|
|
input.Invoke(new RawKeyEventArgs(KeyboardDevice.Instance!, 0, _view.InputRoot, |
|
|
input.Invoke(new RawKeyEventArgs(KeyboardDevice.Instance!, 0, _view.InputRoot, |
|
|
RawKeyEventType.KeyUp, key, RawInputModifiers.None, physicalKey, keySymbol)); |
|
|
RawKeyEventType.KeyUp, key, RawInputModifiers.None, physicalKey, keySymbol)); |
|
|
} |
|
|
} |
|
|
|
|
|
_isInUpdate = false; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
private void TextInput(string text) |
|
|
private void TextInput(string text) |
|
|
{ |
|
|
{ |
|
|
|
|
|
_isInUpdate = true; |
|
|
Logger.TryGet(LogEventLevel.Debug, ImeLog)?.Log(null, "Triggering text input {text}", text); |
|
|
Logger.TryGet(LogEventLevel.Debug, ImeLog)?.Log(null, "Triggering text input {text}", text); |
|
|
_view._topLevelImpl.Input?.Invoke(new RawTextInputEventArgs(KeyboardDevice.Instance!, 0, _view.InputRoot, text)); |
|
|
_view._topLevelImpl.Input?.Invoke(new RawTextInputEventArgs(KeyboardDevice.Instance!, 0, _view.InputRoot, text)); |
|
|
|
|
|
_isInUpdate = false; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
void IUIKeyInput.InsertText(string text) |
|
|
void IUIKeyInput.InsertText(string text) |
|
|
@ -214,23 +219,22 @@ partial class AvaloniaView |
|
|
var r = (AvaloniaTextRange)range; |
|
|
var r = (AvaloniaTextRange)range; |
|
|
var surroundingText = _client.SurroundingText; |
|
|
var surroundingText = _client.SurroundingText; |
|
|
|
|
|
|
|
|
var currentSelection = _client.Selection; |
|
|
|
|
|
|
|
|
|
|
|
Logger.TryGet(LogEventLevel.Debug, ImeLog)?.Log(null, "IUIKeyInput.TextInRange {start} {end}", r.StartIndex, r.EndIndex); |
|
|
Logger.TryGet(LogEventLevel.Debug, ImeLog)?.Log(null, "IUIKeyInput.TextInRange {start} {end}", r.StartIndex, r.EndIndex); |
|
|
|
|
|
|
|
|
string result = ""; |
|
|
string result = ""; |
|
|
if (string.IsNullOrEmpty(_markedText)) |
|
|
if (string.IsNullOrEmpty(_markedText)) |
|
|
{ |
|
|
{ |
|
|
if(surroundingText != null && r.EndIndex < surroundingText.Length) |
|
|
if (surroundingText != null && r.EndIndex <= surroundingText.Length) |
|
|
{ |
|
|
{ |
|
|
result = surroundingText[r.StartIndex..r.EndIndex]; |
|
|
result = surroundingText[r.StartIndex..r.EndIndex]; |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
else |
|
|
else |
|
|
{ |
|
|
{ |
|
|
var span = new CombinedSpan3<char>(surroundingText.AsSpan().Slice(0, currentSelection.Start), |
|
|
var currentSelection = _client.Selection; |
|
|
|
|
|
var span = new CombinedSpan3<char>(surroundingText.AsSpan(0, currentSelection.Start), |
|
|
_markedText, |
|
|
_markedText, |
|
|
surroundingText.AsSpan().Slice(currentSelection.Start, currentSelection.End - currentSelection.Start)); |
|
|
surroundingText.AsSpan(currentSelection.Start, currentSelection.End - currentSelection.Start)); |
|
|
var buf = new char[r.EndIndex - r.StartIndex]; |
|
|
var buf = new char[r.EndIndex - r.StartIndex]; |
|
|
span.CopyTo(buf, r.StartIndex); |
|
|
span.CopyTo(buf, r.StartIndex); |
|
|
result = new string(buf); |
|
|
result = new string(buf); |
|
|
|