From e0a832d61908b832647aa587c67a3fbd98857659 Mon Sep 17 00:00:00 2001 From: Justin McCandless Date: Thu, 6 Oct 2022 10:18:26 -0700 Subject: [PATCH 1/5] Move scribble methods from TextInputClient namespace to Scribble --- .../darwin/ios/framework/Source/FlutterEngine.mm | 16 +++++++--------- .../framework/Source/FlutterTextInputPlugin.mm | 2 +- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm b/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm index 928bab1184605..7305629a2a0c4 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm @@ -965,7 +965,7 @@ - (void)flutterTextInputView:(FlutterTextInputView*)textInputView #pragma mark - FlutterViewEngineDelegate - (void)flutterTextInputView:(FlutterTextInputView*)textInputView showToolbar:(int)client { - [_textInputChannel.get() invokeMethod:@"TextInputClient.showToolbar" arguments:@[ @(client) ]]; + [_textInputChannel.get() invokeMethod:@"Scribble.showToolbar" arguments:@[ @(client) ]]; } - (void)flutterTextInputPlugin:(FlutterTextInputPlugin*)textInputPlugin @@ -973,7 +973,7 @@ - (void)flutterTextInputPlugin:(FlutterTextInputPlugin*)textInputPlugin atPoint:(CGPoint)referencePoint result:(FlutterResult)callback { [_textInputChannel.get() - invokeMethod:@"TextInputClient.focusElement" + invokeMethod:@"Scribble.focusElement" arguments:@[ elementIdentifier, @(referencePoint.x), @(referencePoint.y) ] result:callback]; } @@ -982,31 +982,29 @@ - (void)flutterTextInputPlugin:(FlutterTextInputPlugin*)textInputPlugin requestElementsInRect:(CGRect)rect result:(FlutterResult)callback { [_textInputChannel.get() - invokeMethod:@"TextInputClient.requestElementsInRect" + invokeMethod:@"Scribble.requestElementsInRect" arguments:@[ @(rect.origin.x), @(rect.origin.y), @(rect.size.width), @(rect.size.height) ] result:callback]; } - (void)flutterTextInputViewScribbleInteractionBegan:(FlutterTextInputView*)textInputView { - [_textInputChannel.get() invokeMethod:@"TextInputClient.scribbleInteractionBegan" arguments:nil]; + [_textInputChannel.get() invokeMethod:@"Scribble.scribbleInteractionBegan" arguments:nil]; } - (void)flutterTextInputViewScribbleInteractionFinished:(FlutterTextInputView*)textInputView { - [_textInputChannel.get() invokeMethod:@"TextInputClient.scribbleInteractionFinished" - arguments:nil]; + [_textInputChannel.get() invokeMethod:@"Scribble.scribbleInteractionFinished" arguments:nil]; } - (void)flutterTextInputView:(FlutterTextInputView*)textInputView insertTextPlaceholderWithSize:(CGSize)size withClient:(int)client { - [_textInputChannel.get() invokeMethod:@"TextInputClient.insertTextPlaceholder" + [_textInputChannel.get() invokeMethod:@"Scribble.insertTextPlaceholder" arguments:@[ @(client), @(size.width), @(size.height) ]]; } - (void)flutterTextInputView:(FlutterTextInputView*)textInputView removeTextPlaceholder:(int)client { - [_textInputChannel.get() invokeMethod:@"TextInputClient.removeTextPlaceholder" - arguments:@[ @(client) ]]; + [_textInputChannel.get() invokeMethod:@"Scribble.removeTextPlaceholder" arguments:@[ @(client) ]]; } - (void)flutterTextInputViewDidResignFirstResponder:(FlutterTextInputView*)textInputView { diff --git a/shell/platform/darwin/ios/framework/Source/FlutterTextInputPlugin.mm b/shell/platform/darwin/ios/framework/Source/FlutterTextInputPlugin.mm index 70ac5d1d784e7..dfffe03fdab53 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterTextInputPlugin.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterTextInputPlugin.mm @@ -48,7 +48,7 @@ @"TextInput.setEditableSizeAndTransform"; static NSString* const kSetMarkedTextRectMethod = @"TextInput.setMarkedTextRect"; static NSString* const kFinishAutofillContextMethod = @"TextInput.finishAutofillContext"; -static NSString* const kSetSelectionRectsMethod = @"TextInput.setSelectionRects"; +static NSString* const kSetSelectionRectsMethod = @"Scribble.setSelectionRects"; static NSString* const kStartLiveTextInputMethod = @"TextInput.startLiveTextInput"; #pragma mark - TextInputConfiguration Field Names From bb6a892e763fd955f36ddce391bf7a254bae16b0 Mon Sep 17 00:00:00 2001 From: Justin McCandless Date: Wed, 19 Oct 2022 15:52:31 -0700 Subject: [PATCH 2/5] Scribble channel --- .../ios/framework/Source/FlutterEngine.mm | 26 +++++++++++++------ 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm b/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm index 7305629a2a0c4..bb996706cb36e 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm @@ -126,6 +126,7 @@ @implementation FlutterEngine { fml::scoped_nsobject _platformViewsChannel; fml::scoped_nsobject _textInputChannel; fml::scoped_nsobject _undoManagerChannel; + fml::scoped_nsobject _scribbleChannel; fml::scoped_nsobject _spellCheckChannel; fml::scoped_nsobject _lifecycleChannel; fml::scoped_nsobject _systemChannel; @@ -471,6 +472,9 @@ - (FlutterMethodChannel*)textInputChannel { - (FlutterMethodChannel*)undoManagerChannel { return _undoManagerChannel.get(); } +- (FlutterMethodChannel*)scribbleChannel { + return _scribbleChannel.get(); +} - (FlutterMethodChannel*)spellCheckChannel { return _spellCheckChannel.get(); } @@ -499,6 +503,7 @@ - (void)resetChannels { _platformViewsChannel.reset(); _textInputChannel.reset(); _undoManagerChannel.reset(); + _scribbleChannel.reset(); _lifecycleChannel.reset(); _systemChannel.reset(); _settingsChannel.reset(); @@ -572,6 +577,11 @@ - (void)setupChannels { binaryMessenger:self.binaryMessenger codec:[FlutterJSONMethodCodec sharedInstance]]); + _scribbleChannel.reset([[FlutterMethodChannel alloc] + initWithName:@"flutter/scribble" + binaryMessenger:self.binaryMessenger + codec:[FlutterJSONMethodCodec sharedInstance]]); + _spellCheckChannel.reset([[FlutterMethodChannel alloc] initWithName:@"flutter/spellcheck" binaryMessenger:self.binaryMessenger @@ -965,14 +975,14 @@ - (void)flutterTextInputView:(FlutterTextInputView*)textInputView #pragma mark - FlutterViewEngineDelegate - (void)flutterTextInputView:(FlutterTextInputView*)textInputView showToolbar:(int)client { - [_textInputChannel.get() invokeMethod:@"Scribble.showToolbar" arguments:@[ @(client) ]]; + [_scribbleChannel.get() invokeMethod:@"Scribble.showToolbar" arguments:@[ @(client) ]]; } - (void)flutterTextInputPlugin:(FlutterTextInputPlugin*)textInputPlugin focusElement:(UIScribbleElementIdentifier)elementIdentifier atPoint:(CGPoint)referencePoint result:(FlutterResult)callback { - [_textInputChannel.get() + [_scribbleChannel.get() invokeMethod:@"Scribble.focusElement" arguments:@[ elementIdentifier, @(referencePoint.x), @(referencePoint.y) ] result:callback]; @@ -981,30 +991,30 @@ - (void)flutterTextInputPlugin:(FlutterTextInputPlugin*)textInputPlugin - (void)flutterTextInputPlugin:(FlutterTextInputPlugin*)textInputPlugin requestElementsInRect:(CGRect)rect result:(FlutterResult)callback { - [_textInputChannel.get() + [_scribbleChannel.get() invokeMethod:@"Scribble.requestElementsInRect" arguments:@[ @(rect.origin.x), @(rect.origin.y), @(rect.size.width), @(rect.size.height) ] result:callback]; } - (void)flutterTextInputViewScribbleInteractionBegan:(FlutterTextInputView*)textInputView { - [_textInputChannel.get() invokeMethod:@"Scribble.scribbleInteractionBegan" arguments:nil]; + [_scribbleChannel.get() invokeMethod:@"Scribble.scribbleInteractionBegan" arguments:nil]; } - (void)flutterTextInputViewScribbleInteractionFinished:(FlutterTextInputView*)textInputView { - [_textInputChannel.get() invokeMethod:@"Scribble.scribbleInteractionFinished" arguments:nil]; + [_scribbleChannel.get() invokeMethod:@"Scribble.scribbleInteractionFinished" arguments:nil]; } - (void)flutterTextInputView:(FlutterTextInputView*)textInputView insertTextPlaceholderWithSize:(CGSize)size withClient:(int)client { - [_textInputChannel.get() invokeMethod:@"Scribble.insertTextPlaceholder" - arguments:@[ @(client), @(size.width), @(size.height) ]]; + [_scribbleChannel.get() invokeMethod:@"Scribble.insertTextPlaceholder" + arguments:@[ @(client), @(size.width), @(size.height) ]]; } - (void)flutterTextInputView:(FlutterTextInputView*)textInputView removeTextPlaceholder:(int)client { - [_textInputChannel.get() invokeMethod:@"Scribble.removeTextPlaceholder" arguments:@[ @(client) ]]; + [_scribbleChannel.get() invokeMethod:@"Scribble.removeTextPlaceholder" arguments:@[ @(client) ]]; } - (void)flutterTextInputViewDidResignFirstResponder:(FlutterTextInputView*)textInputView { From 26d958b383e4e28007066baae3af38cbcd8222ab Mon Sep 17 00:00:00 2001 From: Justin McCandless Date: Thu, 20 Oct 2022 12:29:53 -0700 Subject: [PATCH 3/5] Test that includes a Scribble channel method --- .../Source/FlutterTextInputPluginTest.mm | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/shell/platform/darwin/ios/framework/Source/FlutterTextInputPluginTest.mm b/shell/platform/darwin/ios/framework/Source/FlutterTextInputPluginTest.mm index c83bd15640d99..d7cda8e32ef31 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterTextInputPluginTest.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterTextInputPluginTest.mm @@ -1854,6 +1854,40 @@ - (void)testGarbageInputViewsAreNotRemovedImmediately { [self commitAutofillContextAndVerify]; } +- (void)testScribbleSetSelectionRects { + NSMutableDictionary* regularField = self.mutableTemplateCopy; + NSDictionary* editingValue = @{ + @"text" : @"REGULAR_TEXT_FIELD", + @"composingBase" : @0, + @"composingExtent" : @3, + @"selectionBase" : @1, + @"selectionExtent" : @4 + }; + [regularField setValue:@{ + @"uniqueIdentifier" : @"field1", + @"hints" : @[ @"hint2" ], + @"editingValue" : editingValue, + } + forKey:@"autofill"]; + [regularField addEntriesFromDictionary:editingValue]; + [self setClientId:123 configuration:regularField]; + XCTAssertEqual(self.installedInputViews.count, 1ul); + XCTAssertNotEqual(textInputPlugin.activeView, nil); + XCTAssertEqual([textInputPlugin.activeView.selectionRects count], 0u); + + NSArray* selectionRect = [NSArray arrayWithObjects:@0, @0, @100, @100, @0, nil]; + NSArray* selectionRects = [NSArray arrayWithObjects:selectionRect, nil]; + FlutterMethodCall* methodCall = + [FlutterMethodCall methodCallWithMethodName:@"Scribble.setSelectionRects" + arguments:selectionRects]; + [textInputPlugin handleMethodCall:methodCall + result:^(id _Nullable result){ + }]; + + XCTAssertNotEqual(textInputPlugin.activeView.selectionRects, nil); + XCTAssertEqual([textInputPlugin.activeView.selectionRects count], 1u); +} + - (void)testDecommissionedViewAreNotReusedByAutofill { // Regression test for https://github.com/flutter/flutter/issues/84407. NSMutableDictionary* configuration = self.mutableTemplateCopy; From 080afc850c38000dcfb59b906beec26625811158 Mon Sep 17 00:00:00 2001 From: Justin McCandless Date: Fri, 21 Oct 2022 16:07:01 -0700 Subject: [PATCH 4/5] Remove unnecessary test assertions --- .../darwin/ios/framework/Source/FlutterTextInputPluginTest.mm | 2 -- 1 file changed, 2 deletions(-) diff --git a/shell/platform/darwin/ios/framework/Source/FlutterTextInputPluginTest.mm b/shell/platform/darwin/ios/framework/Source/FlutterTextInputPluginTest.mm index d7cda8e32ef31..462ea9e8359af 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterTextInputPluginTest.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterTextInputPluginTest.mm @@ -1872,7 +1872,6 @@ - (void)testScribbleSetSelectionRects { [regularField addEntriesFromDictionary:editingValue]; [self setClientId:123 configuration:regularField]; XCTAssertEqual(self.installedInputViews.count, 1ul); - XCTAssertNotEqual(textInputPlugin.activeView, nil); XCTAssertEqual([textInputPlugin.activeView.selectionRects count], 0u); NSArray* selectionRect = [NSArray arrayWithObjects:@0, @0, @100, @100, @0, nil]; @@ -1884,7 +1883,6 @@ - (void)testScribbleSetSelectionRects { result:^(id _Nullable result){ }]; - XCTAssertNotEqual(textInputPlugin.activeView.selectionRects, nil); XCTAssertEqual([textInputPlugin.activeView.selectionRects count], 1u); } From b28bdabd11a257ccd2001f25994335d91bca5f3e Mon Sep 17 00:00:00 2001 From: Justin McCandless Date: Fri, 21 Oct 2022 16:17:48 -0700 Subject: [PATCH 5/5] Use both TextInputClient and Scribble until the framework transitions to Scribble --- .../ios/framework/Source/FlutterEngine.mm | 37 +++++++++++++++++++ .../Source/FlutterTextInputPlugin.mm | 10 +++++ 2 files changed, 47 insertions(+) diff --git a/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm b/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm index bb996706cb36e..0ba83ef38090a 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm @@ -975,6 +975,10 @@ - (void)flutterTextInputView:(FlutterTextInputView*)textInputView #pragma mark - FlutterViewEngineDelegate - (void)flutterTextInputView:(FlutterTextInputView*)textInputView showToolbar:(int)client { + // TODO(justinmc): Remove the TextInputClient usage when the framework has + // finished transitioning to using the Scribble channel. + // https://github.com/flutter/flutter/pull/104128 + [_textInputChannel.get() invokeMethod:@"TextInputClient.showToolbar" arguments:@[ @(client) ]]; [_scribbleChannel.get() invokeMethod:@"Scribble.showToolbar" arguments:@[ @(client) ]]; } @@ -982,6 +986,13 @@ - (void)flutterTextInputPlugin:(FlutterTextInputPlugin*)textInputPlugin focusElement:(UIScribbleElementIdentifier)elementIdentifier atPoint:(CGPoint)referencePoint result:(FlutterResult)callback { + // TODO(justinmc): Remove the TextInputClient usage when the framework has + // finished transitioning to using the Scribble channel. + // https://github.com/flutter/flutter/pull/104128 + [_textInputChannel.get() + invokeMethod:@"TextInputClient.focusElement" + arguments:@[ elementIdentifier, @(referencePoint.x), @(referencePoint.y) ] + result:callback]; [_scribbleChannel.get() invokeMethod:@"Scribble.focusElement" arguments:@[ elementIdentifier, @(referencePoint.x), @(referencePoint.y) ] @@ -991,29 +1002,55 @@ - (void)flutterTextInputPlugin:(FlutterTextInputPlugin*)textInputPlugin - (void)flutterTextInputPlugin:(FlutterTextInputPlugin*)textInputPlugin requestElementsInRect:(CGRect)rect result:(FlutterResult)callback { + // TODO(justinmc): Remove the TextInputClient usage when the framework has + // finished transitioning to using the Scribble channel. + // https://github.com/flutter/flutter/pull/104128 [_scribbleChannel.get() invokeMethod:@"Scribble.requestElementsInRect" arguments:@[ @(rect.origin.x), @(rect.origin.y), @(rect.size.width), @(rect.size.height) ] result:callback]; + [_textInputChannel.get() + invokeMethod:@"TextInputClient.requestElementsInRect" + arguments:@[ @(rect.origin.x), @(rect.origin.y), @(rect.size.width), @(rect.size.height) ] + result:callback]; } - (void)flutterTextInputViewScribbleInteractionBegan:(FlutterTextInputView*)textInputView { + // TODO(justinmc): Remove the TextInputClient usage when the framework has + // finished transitioning to using the Scribble channel. + // https://github.com/flutter/flutter/pull/104128 + [_textInputChannel.get() invokeMethod:@"TextInputClient.scribbleInteractionBegan" arguments:nil]; [_scribbleChannel.get() invokeMethod:@"Scribble.scribbleInteractionBegan" arguments:nil]; } - (void)flutterTextInputViewScribbleInteractionFinished:(FlutterTextInputView*)textInputView { + // TODO(justinmc): Remove the TextInputClient usage when the framework has + // finished transitioning to using the Scribble channel. + // https://github.com/flutter/flutter/pull/104128 + [_textInputChannel.get() invokeMethod:@"TextInputClient.scribbleInteractionFinished" + arguments:nil]; [_scribbleChannel.get() invokeMethod:@"Scribble.scribbleInteractionFinished" arguments:nil]; } - (void)flutterTextInputView:(FlutterTextInputView*)textInputView insertTextPlaceholderWithSize:(CGSize)size withClient:(int)client { + // TODO(justinmc): Remove the TextInputClient usage when the framework has + // finished transitioning to using the Scribble channel. + // https://github.com/flutter/flutter/pull/104128 + [_textInputChannel.get() invokeMethod:@"TextInputClient.insertTextPlaceholder" + arguments:@[ @(client), @(size.width), @(size.height) ]]; [_scribbleChannel.get() invokeMethod:@"Scribble.insertTextPlaceholder" arguments:@[ @(client), @(size.width), @(size.height) ]]; } - (void)flutterTextInputView:(FlutterTextInputView*)textInputView removeTextPlaceholder:(int)client { + // TODO(justinmc): Remove the TextInputClient usage when the framework has + // finished transitioning to using the Scribble channel. + // https://github.com/flutter/flutter/pull/104128 + [_textInputChannel.get() invokeMethod:@"TextInputClient.removeTextPlaceholder" + arguments:@[ @(client) ]]; [_scribbleChannel.get() invokeMethod:@"Scribble.removeTextPlaceholder" arguments:@[ @(client) ]]; } diff --git a/shell/platform/darwin/ios/framework/Source/FlutterTextInputPlugin.mm b/shell/platform/darwin/ios/framework/Source/FlutterTextInputPlugin.mm index fc4230015cd26..4ecdc6845e73a 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterTextInputPlugin.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterTextInputPlugin.mm @@ -48,6 +48,10 @@ @"TextInput.setEditableSizeAndTransform"; static NSString* const kSetMarkedTextRectMethod = @"TextInput.setMarkedTextRect"; static NSString* const kFinishAutofillContextMethod = @"TextInput.finishAutofillContext"; +// TODO(justinmc): Remove the TextInput method constant when the framework has +// finished transitioning to using the Scribble channel. +// https://github.com/flutter/flutter/pull/104128 +static NSString* const kDeprecatedSetSelectionRectsMethod = @"TextInput.setSelectionRects"; static NSString* const kSetSelectionRectsMethod = @"Scribble.setSelectionRects"; static NSString* const kStartLiveTextInputMethod = @"TextInput.startLiveTextInput"; @@ -2170,6 +2174,12 @@ - (void)handleMethodCall:(FlutterMethodCall*)call result:(FlutterResult)result { } else if ([method isEqualToString:kFinishAutofillContextMethod]) { [self triggerAutofillSave:[args boolValue]]; result(nil); + // TODO(justinmc): Remove the TextInput method constant when the framework has + // finished transitioning to using the Scribble channel. + // https://github.com/flutter/flutter/pull/104128 + } else if ([method isEqualToString:kDeprecatedSetSelectionRectsMethod]) { + [self setSelectionRects:args]; + result(nil); } else if ([method isEqualToString:kSetSelectionRectsMethod]) { [self setSelectionRects:args]; result(nil);