5
5
using Android . Text ;
6
6
using Android . Views ;
7
7
using Android . Views . InputMethods ;
8
- using Avalonia . Android . Platform . SkiaPlatform ;
9
8
using Avalonia . Input . TextInput ;
10
9
11
- namespace Avalonia . Android
10
+ namespace Avalonia . Android . Platform . Input
12
11
{
13
12
internal interface IAndroidInputMethod
14
13
{
@@ -21,18 +20,18 @@ internal interface IAndroidInputMethod
21
20
22
21
public InputMethodManager IMM { get ; }
23
22
24
- void OnBatchEditedEnded ( ) ;
23
+ void OnBatchEditEnded ( ) ;
25
24
}
26
25
27
26
enum CustomImeFlags
28
- {
27
+ {
29
28
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 ,
36
35
}
37
36
38
37
internal class AndroidInputMethod < TView > : ITextInputMethodImpl , IAndroidInputMethod
@@ -79,7 +78,7 @@ public void SetClient(TextInputMethodClient? client)
79
78
{
80
79
_host . RequestFocus ( ) ;
81
80
82
- _imm . RestartInput ( View ) ;
81
+ _imm . RestartInput ( View ) ;
83
82
84
83
_imm . ShowSoftInput ( _host , ShowFlags . Implicit ) ;
85
84
@@ -110,27 +109,29 @@ public void SetClient(TextInputMethodClient? client)
110
109
111
110
private void _client_SelectionChanged ( object ? sender , EventArgs e )
112
111
{
113
- if ( _inputConnection is null || _inputConnection . IsInBatchEdit )
112
+ if ( _inputConnection is null || _inputConnection . IsInBatchEdit || _inputConnection . IsInUpdate )
114
113
return ;
115
114
OnSelectionChanged ( ) ;
116
115
}
117
116
118
117
private void OnSelectionChanged ( )
119
118
{
120
- if ( Client is null || _inputConnection is null )
119
+ if ( Client is null || _inputConnection is null || _inputConnection . IsInUpdate )
121
120
{
122
121
return ;
123
122
}
124
123
125
124
OnSurroundingTextChanged ( ) ;
126
125
127
- var selection = Client . Selection ;
126
+ _inputConnection . IsInUpdate = true ;
128
127
129
- _inputConnection . SetSelection ( selection . Start , selection . End ) ;
128
+ var selection = Client . Selection ;
130
129
131
- var composition = _inputConnection . EditableWrapper . CurrentComposition ;
130
+ var composition = _inputConnection . EditBuffer . HasComposition ? _inputConnection . EditBuffer . Composition ! . Value : new TextSelection ( - 1 , - 1 ) ;
132
131
133
132
_imm . UpdateSelection ( _host , selection . Start , selection . End , composition . Start , composition . End ) ;
133
+
134
+ _inputConnection . IsInUpdate = false ;
134
135
}
135
136
136
137
private void _client_SurroundingTextChanged ( object ? sender , EventArgs e )
@@ -140,7 +141,7 @@ private void _client_SurroundingTextChanged(object? sender, EventArgs e)
140
141
OnSurroundingTextChanged ( ) ;
141
142
}
142
143
143
- public void OnBatchEditedEnded ( )
144
+ public void OnBatchEditEnded ( )
144
145
{
145
146
if ( _inputConnection is null || _inputConnection . IsInBatchEdit )
146
147
return ;
@@ -149,56 +150,32 @@ public void OnBatchEditedEnded()
149
150
150
151
private void OnSurroundingTextChanged ( )
151
152
{
152
- if ( _client is null || _inputConnection is null )
153
+ if ( _client is null || _inputConnection is null || _inputConnection . IsInUpdate )
153
154
{
154
155
return ;
155
156
}
156
157
157
- var surroundingText = _client . SurroundingText ?? "" ;
158
- var editableText = _inputConnection . EditableWrapper . ToString ( ) ;
159
-
160
- if ( editableText != surroundingText )
158
+ if ( _inputConnection . IsInMonitorMode )
161
159
{
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 ?? "" ;
181
161
182
- var longerLength = Math . Max ( surroundingText . Length , editableText . Length ) ;
162
+ var selection = _client . Selection ;
183
163
184
- for ( int i = 0 ; i < longerLength ; i ++ )
164
+ var extractedText = new ExtractedText
185
165
{
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
+ } ;
194
171
195
- return ( index , diffString ) ;
172
+ _imm . UpdateExtractedText ( _host , _inputConnection . ExtractedTextToken , extractedText ) ;
196
173
}
197
174
}
198
175
199
176
public void SetCursorRect ( Rect rect )
200
177
{
201
-
178
+
202
179
}
203
180
204
181
public void SetOptions ( TextInputOptions options )
@@ -212,22 +189,22 @@ public void SetOptions(TextInputOptions options)
212
189
213
190
outAttrs . InputType = options . ContentType switch
214
191
{
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
221
198
} ;
222
199
223
200
if ( options . AutoCapitalization )
224
201
{
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 ;
227
204
}
228
205
229
206
if ( options . Multiline )
230
- outAttrs . InputType |= global :: Android . Text . InputTypes . TextFlagMultiLine ;
207
+ outAttrs . InputType |= InputTypes . TextFlagMultiLine ;
231
208
232
209
outAttrs . ImeOptions = options . ReturnKeyType switch
233
210
{
0 commit comments