@@ -325,7 +325,8 @@ - (void)setTextInputClient:(int)client {
325325 _textInputClient = client;
326326}
327327
328- - (void )setTextInputState : (NSDictionary *)state {
328+ // Return true if the new input state needs to be synced back to the framework.
329+ - (BOOL )setTextInputState : (NSDictionary *)state {
329330 NSString * newText = state[@" text" ];
330331 BOOL textChanged = ![self .text isEqualToString: newText];
331332 if (textChanged) {
@@ -356,8 +357,7 @@ - (void)setTextInputState:(NSDictionary*)state {
356357 selectedRange.length != oldSelectedRange.length ) {
357358 needsEditingStateUpdate = YES ;
358359 [self .inputDelegate selectionWillChange: self ];
359- [self setSelectedTextRange: [FlutterTextRange rangeWithNSRange: selectedRange]
360- updateEditingState: NO ];
360+ [self setSelectedTextRangeLocal: [FlutterTextRange rangeWithNSRange: selectedRange]];
361361 _selectionAffinity = _kTextAffinityDownstream;
362362 if ([state[@" selectionAffinity" ] isEqualToString: @(_kTextAffinityUpstream)])
363363 _selectionAffinity = _kTextAffinityUpstream;
@@ -367,10 +367,9 @@ - (void)setTextInputState:(NSDictionary*)state {
367367 if (textChanged) {
368368 [self .inputDelegate textDidChange: self ];
369369 }
370- if (needsEditingStateUpdate) {
371- // For consistency with Android behavior, send an update to the framework.
372- [self updateEditingState ];
373- }
370+
371+ // For consistency with Android behavior, send an update to the framework if anything changed.
372+ return needsEditingStateUpdate;
374373}
375374
376375- (NSRange )clampSelection : (NSRange )range forText : (NSString *)text {
@@ -401,11 +400,8 @@ - (UITextRange*)selectedTextRange {
401400 return [[_selectedTextRange copy ] autorelease ];
402401}
403402
404- - (void )setSelectedTextRange : (UITextRange*)selectedTextRange {
405- [self setSelectedTextRange: selectedTextRange updateEditingState: YES ];
406- }
407-
408- - (void )setSelectedTextRange : (UITextRange*)selectedTextRange updateEditingState : (BOOL )update {
403+ // Change the range of selected text, without notifying the framework.
404+ - (void )setSelectedTextRangeLocal : (UITextRange*)selectedTextRange {
409405 if (_selectedTextRange != selectedTextRange) {
410406 UITextRange* oldSelectedRange = _selectedTextRange;
411407 if (self.hasText ) {
@@ -416,12 +412,14 @@ - (void)setSelectedTextRange:(UITextRange*)selectedTextRange updateEditingState:
416412 _selectedTextRange = [selectedTextRange copy ];
417413 }
418414 [oldSelectedRange release ];
419-
420- if (update)
421- [self updateEditingState ];
422415 }
423416}
424417
418+ - (void )setSelectedTextRange : (UITextRange*)selectedTextRange {
419+ [self setSelectedTextRangeLocal: selectedTextRange];
420+ [self updateEditingState ];
421+ }
422+
425423- (id )insertDictationResultPlaceholder {
426424 return @" " ;
427425}
@@ -440,26 +438,32 @@ - (NSString*)textInRange:(UITextRange*)range {
440438 return [self .text substringWithRange: textRange];
441439}
442440
443- - (void )replaceRange : (UITextRange*)range withText : (NSString *)text {
444- NSRange replaceRange = ((FlutterTextRange*)range).range ;
441+ // Replace the text within the specified range with the given text,
442+ // without notifying the framework.
443+ - (void )replaceRangeLocal : (NSRange )range withText : (NSString *)text {
445444 NSRange selectedRange = _selectedTextRange.range ;
445+
446446 // Adjust the text selection:
447447 // * reduce the length by the intersection length
448448 // * adjust the location by newLength - oldLength + intersectionLength
449- NSRange intersectionRange = NSIntersectionRange (replaceRange , selectedRange);
450- if (replaceRange .location <= selectedRange.location )
451- selectedRange.location += text.length - replaceRange .length ;
449+ NSRange intersectionRange = NSIntersectionRange (range , selectedRange);
450+ if (range .location <= selectedRange.location )
451+ selectedRange.location += text.length - range .length ;
452452 if (intersectionRange.location != NSNotFound ) {
453453 selectedRange.location += intersectionRange.length ;
454454 selectedRange.length -= intersectionRange.length ;
455455 }
456456
457- [self .text replaceCharactersInRange: [self clampSelection: replaceRange forText: self .text]
457+ [self .text replaceCharactersInRange: [self clampSelection: range forText: self .text]
458458 withString: text];
459- [self setSelectedTextRange: [FlutterTextRange rangeWithNSRange: [self clampSelection: selectedRange
460- forText: self .text]]
461- updateEditingState: NO ];
459+ [self setSelectedTextRangeLocal: [FlutterTextRange
460+ rangeWithNSRange: [self clampSelection: selectedRange
461+ forText: self .text]]];
462+ }
462463
464+ - (void )replaceRange : (UITextRange*)range withText : (NSString *)text {
465+ NSRange replaceRange = ((FlutterTextRange*)range).range ;
466+ [self replaceRangeLocal: replaceRange withText: text];
463467 [self updateEditingState ];
464468}
465469
@@ -522,11 +526,11 @@ - (void)setMarkedText:(NSString*)markedText selectedRange:(NSRange)markedSelecte
522526
523527 if (markedTextRange.length > 0 ) {
524528 // Replace text in the marked range with the new text.
525- [self replaceRange: self . markedTextRange withText: markedText];
529+ [self replaceRangeLocal: markedTextRange withText: markedText];
526530 markedTextRange.length = markedText.length ;
527531 } else {
528532 // Replace text in the selected range with the new text.
529- [self replaceRange: _selectedTextRange withText: markedText];
533+ [self replaceRangeLocal: selectedRange withText: markedText];
530534 markedTextRange = NSMakeRange (selectedRange.location , markedText.length );
531535 }
532536
@@ -535,9 +539,10 @@ - (void)setMarkedText:(NSString*)markedText selectedRange:(NSRange)markedSelecte
535539
536540 NSUInteger selectionLocation = markedSelectedRange.location + markedTextRange.location ;
537541 selectedRange = NSMakeRange (selectionLocation, markedSelectedRange.length );
538- [self setSelectedTextRange: [FlutterTextRange rangeWithNSRange: [self clampSelection: selectedRange
539- forText: self .text]]
540- updateEditingState: YES ];
542+ [self setSelectedTextRangeLocal: [FlutterTextRange
543+ rangeWithNSRange: [self clampSelection: selectedRange
544+ forText: self .text]]];
545+ [self updateEditingState ];
541546}
542547
543548- (void )unmarkText {
@@ -1002,7 +1007,9 @@ + (void)setupInputView:(FlutterTextInputView*)inputView
10021007}
10031008
10041009- (void )setTextInputEditingState : (NSDictionary *)state {
1005- [_activeView setTextInputState: state];
1010+ if ([_activeView setTextInputState: state]) {
1011+ [_activeView updateEditingState ];
1012+ }
10061013}
10071014
10081015- (void )clearTextInputClient {
0 commit comments