Skip to content

Commit c2d1072

Browse files
committed
refactor android input connection
1 parent 413ff78 commit c2d1072

File tree

5 files changed

+632
-332
lines changed

5 files changed

+632
-332
lines changed

src/Android/Avalonia.Android/AndroidInputMethod.cs renamed to src/Android/Avalonia.Android/Platform/Input/AndroidInputMethod.cs

Lines changed: 39 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,9 @@
55
using Android.Text;
66
using Android.Views;
77
using Android.Views.InputMethods;
8-
using Avalonia.Android.Platform.SkiaPlatform;
98
using Avalonia.Input.TextInput;
109

11-
namespace Avalonia.Android
10+
namespace Avalonia.Android.Platform.Input
1211
{
1312
internal interface IAndroidInputMethod
1413
{
@@ -21,18 +20,18 @@ internal interface IAndroidInputMethod
2120

2221
public InputMethodManager IMM { get; }
2322

24-
void OnBatchEditedEnded();
23+
void OnBatchEditEnded();
2524
}
2625

2726
enum CustomImeFlags
28-
{
27+
{
2928
ActionNone = 0x00000001,
30-
ActionGo = 0x00000002,
31-
ActionSearch = 0x00000003,
32-
ActionSend = 0x00000004,
33-
ActionNext = 0x00000005,
34-
ActionDone = 0x00000006,
35-
ActionPrevious = 0x00000007,
29+
ActionGo = 0x00000002,
30+
ActionSearch = 0x00000003,
31+
ActionSend = 0x00000004,
32+
ActionNext = 0x00000005,
33+
ActionDone = 0x00000006,
34+
ActionPrevious = 0x00000007,
3635
}
3736

3837
internal class AndroidInputMethod<TView> : ITextInputMethodImpl, IAndroidInputMethod
@@ -79,7 +78,7 @@ public void SetClient(TextInputMethodClient? client)
7978
{
8079
_host.RequestFocus();
8180

82-
_imm.RestartInput(View);
81+
_imm.RestartInput(View);
8382

8483
_imm.ShowSoftInput(_host, ShowFlags.Implicit);
8584

@@ -110,27 +109,29 @@ public void SetClient(TextInputMethodClient? client)
110109

111110
private void _client_SelectionChanged(object? sender, EventArgs e)
112111
{
113-
if (_inputConnection is null || _inputConnection.IsInBatchEdit)
112+
if (_inputConnection is null || _inputConnection.IsInBatchEdit || _inputConnection.IsInUpdate)
114113
return;
115114
OnSelectionChanged();
116115
}
117116

118117
private void OnSelectionChanged()
119118
{
120-
if (Client is null || _inputConnection is null)
119+
if (Client is null || _inputConnection is null || _inputConnection.IsInUpdate)
121120
{
122121
return;
123122
}
124123

125124
OnSurroundingTextChanged();
126125

127-
var selection = Client.Selection;
126+
_inputConnection.IsInUpdate = true;
128127

129-
_inputConnection.SetSelection(selection.Start, selection.End);
128+
var selection = Client.Selection;
130129

131-
var composition = _inputConnection.EditableWrapper.CurrentComposition;
130+
var composition = _inputConnection.EditBuffer.HasComposition ? _inputConnection.EditBuffer.Composition!.Value : new TextSelection(-1,-1);
132131

133132
_imm.UpdateSelection(_host, selection.Start, selection.End, composition.Start, composition.End);
133+
134+
_inputConnection.IsInUpdate = false;
134135
}
135136

136137
private void _client_SurroundingTextChanged(object? sender, EventArgs e)
@@ -140,7 +141,7 @@ private void _client_SurroundingTextChanged(object? sender, EventArgs e)
140141
OnSurroundingTextChanged();
141142
}
142143

143-
public void OnBatchEditedEnded()
144+
public void OnBatchEditEnded()
144145
{
145146
if (_inputConnection is null || _inputConnection.IsInBatchEdit)
146147
return;
@@ -149,56 +150,32 @@ public void OnBatchEditedEnded()
149150

150151
private void OnSurroundingTextChanged()
151152
{
152-
if(_client is null || _inputConnection is null)
153+
if (_client is null || _inputConnection is null || _inputConnection.IsInUpdate)
153154
{
154155
return;
155156
}
156157

157-
var surroundingText = _client.SurroundingText ?? "";
158-
var editableText = _inputConnection.EditableWrapper.ToString();
159-
160-
if (editableText != surroundingText)
158+
if (_inputConnection.IsInMonitorMode)
161159
{
162-
_inputConnection.EditableWrapper.IgnoreChange = true;
163-
164-
var diff = GetDiff();
165-
166-
_inputConnection.Editable.Replace(diff.index, editableText.Length, diff.diff);
167-
168-
_inputConnection.EditableWrapper.IgnoreChange = false;
169-
170-
if(diff.index == 0)
171-
{
172-
var selection = _client.Selection;
173-
_client.Selection = new TextSelection(selection.Start, 0);
174-
_client.Selection = selection;
175-
}
176-
}
177-
178-
(int index, string diff) GetDiff()
179-
{
180-
int index = 0;
160+
var surroundingText = _client.SurroundingText ?? "";
181161

182-
var longerLength = Math.Max(surroundingText.Length, editableText.Length);
162+
var selection = _client.Selection;
183163

184-
for (int i = 0; i < longerLength; i++)
164+
var extractedText = new ExtractedText
185165
{
186-
if (surroundingText.Length == i || editableText.Length == i || surroundingText[i] != editableText[i])
187-
{
188-
index = i;
189-
break;
190-
}
191-
}
192-
193-
var diffString = surroundingText.Substring(index, surroundingText.Length - index);
166+
Text = new Java.Lang.String(surroundingText),
167+
SelectionStart = selection.Start,
168+
SelectionEnd = selection.End,
169+
PartialEndOffset = surroundingText.Length
170+
};
194171

195-
return (index, diffString);
172+
_imm.UpdateExtractedText(_host, _inputConnection.ExtractedTextToken, extractedText);
196173
}
197174
}
198175

199176
public void SetCursorRect(Rect rect)
200177
{
201-
178+
202179
}
203180

204181
public void SetOptions(TextInputOptions options)
@@ -212,22 +189,22 @@ public void SetOptions(TextInputOptions options)
212189

213190
outAttrs.InputType = options.ContentType switch
214191
{
215-
TextInputContentType.Email => global::Android.Text.InputTypes.TextVariationEmailAddress,
216-
TextInputContentType.Number => global::Android.Text.InputTypes.ClassNumber,
217-
TextInputContentType.Password => global::Android.Text.InputTypes.TextVariationPassword,
218-
TextInputContentType.Digits => global::Android.Text.InputTypes.ClassPhone,
219-
TextInputContentType.Url => global::Android.Text.InputTypes.TextVariationUri,
220-
_ => global::Android.Text.InputTypes.ClassText
192+
TextInputContentType.Email => InputTypes.TextVariationEmailAddress,
193+
TextInputContentType.Number => InputTypes.ClassNumber,
194+
TextInputContentType.Password => InputTypes.TextVariationPassword,
195+
TextInputContentType.Digits => InputTypes.ClassPhone,
196+
TextInputContentType.Url => InputTypes.TextVariationUri,
197+
_ => InputTypes.ClassText
221198
};
222199

223200
if (options.AutoCapitalization)
224201
{
225-
outAttrs.InitialCapsMode = global::Android.Text.CapitalizationMode.Sentences;
226-
outAttrs.InputType |= global::Android.Text.InputTypes.TextFlagCapSentences;
202+
outAttrs.InitialCapsMode = CapitalizationMode.Sentences;
203+
outAttrs.InputType |= InputTypes.TextFlagCapSentences;
227204
}
228205

229206
if (options.Multiline)
230-
outAttrs.InputType |= global::Android.Text.InputTypes.TextFlagMultiLine;
207+
outAttrs.InputType |= InputTypes.TextFlagMultiLine;
231208

232209
outAttrs.ImeOptions = options.ReturnKeyType switch
233210
{

0 commit comments

Comments
 (0)