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

[iOS text input] move FlutterTextInputView implementation to a different file #38044

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions ci/licenses_golden/licenses_flutter
Original file line number Diff line number Diff line change
Expand Up @@ -2491,6 +2491,8 @@ ORIGIN: ../../../flutter/shell/platform/darwin/ios/framework/Source/FlutterSeman
ORIGIN: ../../../flutter/shell/platform/darwin/ios/framework/Source/FlutterSpellCheckPlugin.h + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/shell/platform/darwin/ios/framework/Source/FlutterSpellCheckPlugin.mm + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/shell/platform/darwin/ios/framework/Source/FlutterSpellCheckPluginTest.mm + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/shell/platform/darwin/ios/framework/Source/FlutterTextInputClient.h + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/shell/platform/darwin/ios/framework/Source/FlutterTextInputClient_UITextInput.mm + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/shell/platform/darwin/ios/framework/Source/FlutterTextInputDelegate.h + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/shell/platform/darwin/ios/framework/Source/FlutterTextInputPlugin.h + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/shell/platform/darwin/ios/framework/Source/FlutterTextInputPlugin.mm + ../../../flutter/LICENSE
Expand Down Expand Up @@ -4947,6 +4949,8 @@ FILE: ../../../flutter/shell/platform/darwin/ios/framework/Source/FlutterSemanti
FILE: ../../../flutter/shell/platform/darwin/ios/framework/Source/FlutterSpellCheckPlugin.h
FILE: ../../../flutter/shell/platform/darwin/ios/framework/Source/FlutterSpellCheckPlugin.mm
FILE: ../../../flutter/shell/platform/darwin/ios/framework/Source/FlutterSpellCheckPluginTest.mm
FILE: ../../../flutter/shell/platform/darwin/ios/framework/Source/FlutterTextInputClient.h
FILE: ../../../flutter/shell/platform/darwin/ios/framework/Source/FlutterTextInputClient_UITextInput.mm
FILE: ../../../flutter/shell/platform/darwin/ios/framework/Source/FlutterTextInputDelegate.h
FILE: ../../../flutter/shell/platform/darwin/ios/framework/Source/FlutterTextInputPlugin.h
FILE: ../../../flutter/shell/platform/darwin/ios/framework/Source/FlutterTextInputPlugin.mm
Expand Down
2 changes: 2 additions & 0 deletions shell/platform/darwin/ios/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ source_set("flutter_framework_source_arc") {
public_configs = [ "//flutter:config" ]

sources = [
"framework/Source/FlutterTextInputClient.h",
"framework/Source/FlutterTextInputClient_UITextInput.mm",
"framework/Source/FlutterTextInputDelegate.h",
"framework/Source/FlutterTextInputPlugin.h",
"framework/Source/FlutterTextInputPlugin.mm",
Expand Down
27 changes: 15 additions & 12 deletions shell/platform/darwin/ios/framework/Source/FlutterEngine.mm
Original file line number Diff line number Diff line change
Expand Up @@ -875,29 +875,29 @@ - (void)notifyLowMemory {

#pragma mark - Text input delegate

- (void)flutterTextInputView:(FlutterTextInputView*)textInputView
- (void)flutterTextInputView:(UIView<FlutterTextInputClient>*)textInputView
updateEditingClient:(int)client
withState:(NSDictionary*)state {
[_textInputChannel.get() invokeMethod:@"TextInputClient.updateEditingState"
arguments:@[ @(client), state ]];
}

- (void)flutterTextInputView:(FlutterTextInputView*)textInputView
- (void)flutterTextInputView:(UIView<FlutterTextInputClient>*)textInputView
updateEditingClient:(int)client
withState:(NSDictionary*)state
withTag:(NSString*)tag {
[_textInputChannel.get() invokeMethod:@"TextInputClient.updateEditingStateWithTag"
arguments:@[ @(client), @{tag : state} ]];
}

- (void)flutterTextInputView:(FlutterTextInputView*)textInputView
- (void)flutterTextInputView:(UIView<FlutterTextInputClient>*)textInputView
updateEditingClient:(int)client
withDelta:(NSDictionary*)delta {
[_textInputChannel.get() invokeMethod:@"TextInputClient.updateEditingStateWithDeltas"
arguments:@[ @(client), delta ]];
}

- (void)flutterTextInputView:(FlutterTextInputView*)textInputView
- (void)flutterTextInputView:(UIView<FlutterTextInputClient>*)textInputView
updateFloatingCursor:(FlutterFloatingCursorDragState)state
withClient:(int)client
withPosition:(NSDictionary*)position {
Expand All @@ -917,7 +917,7 @@ - (void)flutterTextInputView:(FlutterTextInputView*)textInputView
arguments:@[ @(client), stateString, position ]];
}

- (void)flutterTextInputView:(FlutterTextInputView*)textInputView
- (void)flutterTextInputView:(UIView<FlutterTextInputClient>*)textInputView
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

are these change required as part of the ARC migration?

performAction:(FlutterTextInputAction)action
withClient:(int)client {
NSString* actionString;
Expand Down Expand Up @@ -964,7 +964,7 @@ - (void)flutterTextInputView:(FlutterTextInputView*)textInputView
arguments:@[ @(client), actionString ]];
}

- (void)flutterTextInputView:(FlutterTextInputView*)textInputView
- (void)flutterTextInputView:(UIView<FlutterTextInputClient>*)textInputView
showAutocorrectionPromptRectForStart:(NSUInteger)start
end:(NSUInteger)end
withClient:(int)client {
Expand All @@ -974,7 +974,8 @@ - (void)flutterTextInputView:(FlutterTextInputView*)textInputView

#pragma mark - FlutterViewEngineDelegate

- (void)flutterTextInputView:(FlutterTextInputView*)textInputView showToolbar:(int)client {
- (void)flutterTextInputView:(UIView<FlutterTextInputClient>*)textInputView
showToolbar:(int)client {
[_scribbleChannel.get() invokeMethod:@"Scribble.showToolbar" arguments:@[ @(client) ]];
}

Expand All @@ -997,27 +998,29 @@ - (void)flutterTextInputPlugin:(FlutterTextInputPlugin*)textInputPlugin
result:callback];
}

- (void)flutterTextInputViewScribbleInteractionBegan:(FlutterTextInputView*)textInputView {
- (void)flutterTextInputViewScribbleInteractionBegan:
(UIView<FlutterTextInputClient>*)textInputView {
[_scribbleChannel.get() invokeMethod:@"Scribble.scribbleInteractionBegan" arguments:nil];
}

- (void)flutterTextInputViewScribbleInteractionFinished:(FlutterTextInputView*)textInputView {
- (void)flutterTextInputViewScribbleInteractionFinished:
(UIView<FlutterTextInputClient>*)textInputView {
[_scribbleChannel.get() invokeMethod:@"Scribble.scribbleInteractionFinished" arguments:nil];
}

- (void)flutterTextInputView:(FlutterTextInputView*)textInputView
- (void)flutterTextInputView:(UIView<FlutterTextInputClient>*)textInputView
insertTextPlaceholderWithSize:(CGSize)size
withClient:(int)client {
[_scribbleChannel.get() invokeMethod:@"Scribble.insertTextPlaceholder"
arguments:@[ @(client), @(size.width), @(size.height) ]];
}

- (void)flutterTextInputView:(FlutterTextInputView*)textInputView
- (void)flutterTextInputView:(UIView<FlutterTextInputClient>*)textInputView
removeTextPlaceholder:(int)client {
[_scribbleChannel.get() invokeMethod:@"Scribble.removeTextPlaceholder" arguments:@[ @(client) ]];
}

- (void)flutterTextInputViewDidResignFirstResponder:(FlutterTextInputView*)textInputView {
- (void)flutterTextInputViewDidResignFirstResponder:(UIView<FlutterTextInputClient>*)textInputView {
// Platform view's first responder detection logic:
//
// All text input widgets (e.g. EditableText) are backed by a dummy UITextInput view
Expand Down
112 changes: 112 additions & 0 deletions shell/platform/darwin/ios/framework/Source/FlutterTextInputClient.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef SHELL_PLATFORM_IOS_FRAMEWORK_SOURCE_FLUTTERTEXTINPUTCLIENT_H_
#define SHELL_PLATFORM_IOS_FRAMEWORK_SOURCE_FLUTTERTEXTINPUTCLIENT_H_

#import <UIKit/UIKit.h>
#import "FlutterMacros.h"

#define RegularInputClient FlutterTextInputView
#define SecureInputClient FlutterSecureTextInputView

@class FlutterTextInputPlugin;
@class FlutterTextSelectionRect;

@protocol FlutterViewResponder;

typedef NS_ENUM(NSInteger, FlutterScribbleFocusStatus) {
FlutterScribbleFocusStatusUnfocused,
FlutterScribbleFocusStatusFocusing,
FlutterScribbleFocusStatusFocused,
};

typedef NS_ENUM(NSInteger, FlutterScribbleInteractionStatus) {
FlutterScribbleInteractionStatusNone,
FlutterScribbleInteractionStatusStarted,
FlutterScribbleInteractionStatusEnding,
};

/** An indexed position in the buffer of a Flutter text editing widget. */
@interface FlutterTextPosition : UITextPosition

@property(nonatomic, readonly) NSUInteger index;

+ (instancetype)positionWithIndex:(NSUInteger)index;
- (instancetype)initWithIndex:(NSUInteger)index;

@end

/** A range of text in the buffer of a Flutter text editing widget. */
@interface FlutterTextRange : UITextRange <NSCopying>

@property(nonatomic, readonly) NSRange range;

+ (instancetype)rangeWithNSRange:(NSRange)range;

@end

/** An object that represents a framework text editing widget and interacts with the iOS text input
* system on behalf of that widget.
* A FlutterTextInputClient can receive editing state updates from the setTextInputState: method,
* and it should typically relay editing state changes made by the iOS text input system to the
* framework, via the textInputPlugin.textInputDelegate method. */
@protocol FlutterTextInputClient <NSObject, UITextInput>
/** The framework issued id of this client. */
@property(nonatomic, assign) int clientID;
@property(nonatomic, assign) BOOL accessibilityEnabled;
@property(nonatomic, assign) FlutterScribbleFocusStatus scribbleFocusStatus;
@property(nonatomic, weak) UIAccessibilityElement* backingTextInputAccessibilityObject;

- (instancetype)initWithOwner:(FlutterTextInputPlugin*)textInputPlugin;
/** Updates the rect that describes the bounding box of the framework blinking cursor, in the
* framework widget's coordinates.
* See the setEditableSize:transform: method. */
- (void)setMarkedRect:(CGRect)rect;
- (void)setViewResponder:(id<FlutterViewResponder>)viewResponder;
/** Updates the visible glyph boxes in the framework, in the framework widget's coordinates.
* See the setEditableSize:transform: method. */
- (void)setSelectionRects:(NSArray*)rects;
/** Called by the framework to update the editing state (text, selection, composing region). */
- (void)setTextInputState:(NSDictionary*)state;
/** Updates the transform and the size of the framework text editing widget's text editing region.
* The information describes the paint transform and paint bounds of the framework widget. */
- (void)setEditableSize:(CGSize)size transform:(NSArray*)matrix;
- (void)setEnableDeltaModel:(BOOL)enableDeltaModel;
- (void)setEnableSoftwareKeyboard:(BOOL)enabled;
- (void)setEnableInteractiveSelection:(BOOL)enabled;
@end

@protocol FlutterTextAutofillClient <NSObject>

/** A framework issued id used to uniquely identify an autofill client. The ID is guaranteed to be
* unique at any given time. */
@property(nonatomic, copy) NSString* autofillID;
- (void)setIsVisibleToAutofill:(BOOL)visibility;
@end

#if FLUTTER_RUNTIME_MODE == FLUTTER_RUNTIME_MODE_DEBUG
FLUTTER_DARWIN_EXPORT
#endif
@interface FlutterTextInputView
: UIView <FlutterTextInputClient, FlutterTextAutofillClient, UIScribbleInteractionDelegate>

- (instancetype)init NS_UNAVAILABLE;
+ (instancetype)new NS_UNAVAILABLE;
- (instancetype)initWithCoder:(NSCoder*)aDecoder NS_UNAVAILABLE;
- (instancetype)initWithFrame:(CGRect)frame NS_UNAVAILABLE;
- (instancetype)initWithOwner:(FlutterTextInputPlugin*)textInputPlugin NS_DESIGNATED_INITIALIZER;
@end

// A FlutterTextInputView that masquerades as a UITextField, and forwards
// selectors it can't respond to to a shared UITextField instance.
//
// Relevant API docs claim that password autofill supports any custom view
// that adopts the UITextInput protocol, automatic strong password seems to
// currently only support UITextFields, and password saving only supports
// UITextFields and UITextViews, as of iOS 13.5.
@interface FlutterSecureTextInputView : FlutterTextInputView
@end

#endif // SHELL_PLATFORM_IOS_FRAMEWORK_SOURCE_FLUTTERTEXTINPUTCLIENT_H_
Loading