Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit 2178248

Browse files
[iOS] Remove selectionDidChange call in UndoManager (#45657)
Fixes flutter/flutter#133424 The `-[TextInputDelegate selectionDidChange:]` call actually triggers some unwanted keyboard NLP actions that generate a bunch of candidates and automatically accept the first candidate. This causes `-[UITextInput setMarkedText:selection]` to be called with the first candidate and that inserts extraneous characters after the user types certain characters on the iPad software keyboard. [C++, Objective-C, Java style guides]: https://github.com/flutter/engine/blob/main/CONTRIBUTING.md#style
1 parent e1c784e commit 2178248

File tree

2 files changed

+27
-4
lines changed

2 files changed

+27
-4
lines changed

shell/platform/darwin/ios/framework/Source/FlutterUndoManagerPlugin.mm

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -104,9 +104,9 @@ - (void)setUndoState:(NSDictionary*)dictionary API_AVAILABLE(ios(9.0)) {
104104
// This is needed to notify the iPadOS keyboard that it needs to update the
105105
// state of the UIBarButtons. Otherwise, the state changes to NSUndoManager
106106
// will not show up until the next keystroke (or other trigger).
107-
id<UITextInputDelegate> inputDelegate =
108-
_viewController.engine.textInputPlugin.textInputView.inputDelegate;
109-
[inputDelegate selectionDidChange:_viewController.engine.textInputPlugin.textInputView];
107+
UITextInputAssistantItem* assistantItem =
108+
_viewController.engine.textInputPlugin.textInputView.inputAssistantItem;
109+
assistantItem.leadingBarButtonGroups = assistantItem.leadingBarButtonGroups;
110110
}
111111
[self undoManager].groupsByEvent = groupsByEvent;
112112
}

shell/platform/darwin/ios/framework/Source/FlutterUndoManagerPluginTest.mm

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,13 @@
1010
#import "flutter/shell/platform/darwin/common/framework/Headers/FlutterMacros.h"
1111
#import "flutter/shell/platform/darwin/ios/framework/Headers/FlutterEngine.h"
1212
#import "flutter/shell/platform/darwin/ios/framework/Headers/FlutterViewController.h"
13+
#import "flutter/shell/platform/darwin/ios/framework/Source/FlutterTextInputPlugin.h"
1314

1415
FLUTTER_ASSERT_ARC
1516

1617
@interface FlutterEngine ()
1718
- (nonnull FlutterUndoManagerPlugin*)undoManagerPlugin;
19+
- (nonnull FlutterTextInputPlugin*)textInputPlugin;
1820
@end
1921

2022
@interface FlutterUndoManagerPluginForTest : FlutterUndoManagerPlugin
@@ -50,7 +52,6 @@ - (void)setUp {
5052

5153
- (void)tearDown {
5254
[self.undoManager removeAllActionsWithTarget:self.undoManagerPlugin];
53-
self.undoManagerPlugin = nil;
5455
self.engine = nil;
5556
self.viewController = nil;
5657
self.undoManager = nil;
@@ -140,4 +141,26 @@ - (void)testSetUndoState {
140141
XCTAssertEqual(2, delegateRedoCount);
141142
}
142143

144+
- (void)testSetUndoStateDoesInteractWithInputDelegate {
145+
// Regression test for https://github.com/flutter/flutter/issues/133424
146+
FlutterViewController* viewController = OCMPartialMock(self.viewController);
147+
self.undoManagerPlugin.viewController = self.viewController;
148+
149+
FlutterTextInputPlugin* textInputPlugin = OCMClassMock([FlutterTextInputPlugin class]);
150+
FlutterTextInputView* textInputView = OCMClassMock([FlutterTextInputView class]);
151+
152+
OCMStub([viewController engine]).andReturn(self.engine);
153+
OCMStub([self.engine textInputPlugin]).andReturn(textInputPlugin);
154+
OCMStub([textInputPlugin textInputView]).andReturn(textInputView);
155+
156+
FlutterMethodCall* setUndoStateCall =
157+
[FlutterMethodCall methodCallWithMethodName:@"UndoManager.setUndoState"
158+
arguments:@{@"canUndo" : @NO, @"canRedo" : @NO}];
159+
[self.undoManagerPlugin handleMethodCall:setUndoStateCall
160+
result:^(id _Nullable result){
161+
}];
162+
163+
OCMVerify(never(), [textInputView inputDelegate]);
164+
}
165+
143166
@end

0 commit comments

Comments
 (0)