Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.
Closed
Show file tree
Hide file tree
Changes from 5 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
2 changes: 2 additions & 0 deletions ci/licenses_golden/licenses_flutter
Original file line number Diff line number Diff line change
Expand Up @@ -2535,6 +2535,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
37 changes: 33 additions & 4 deletions shell/platform/darwin/ios/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,33 @@ _flutter_framework_headers = [

_flutter_framework_headers_copy_dir = "$_flutter_framework_dir/Headers"

source_set("flutter_framework_source_arc") {
visibility = [ ":*" ]
cflags_objc = flutter_cflags_objc_arc
cflags_objcc = flutter_cflags_objcc_arc

defines = [ "FLUTTER_FRAMEWORK=1" ]
allow_circular_includes_from = [ ":flutter_framework_source" ]
deps = [
":flutter_framework_source",
"//flutter/fml",
"//flutter/shell/platform/common:common_cpp_input",
"//flutter/shell/platform/darwin/common:framework_shared",
"//third_party/icu",
]
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",
]

frameworks = [ "UIKit.framework" ]
}

source_set("flutter_framework_source") {
visibility = [ ":*" ]
cflags_objc = flutter_cflags_objc
Expand Down Expand Up @@ -81,9 +108,6 @@ source_set("flutter_framework_source") {
"framework/Source/FlutterSemanticsScrollView.mm",
"framework/Source/FlutterSpellCheckPlugin.h",
"framework/Source/FlutterSpellCheckPlugin.mm",
"framework/Source/FlutterTextInputDelegate.h",
"framework/Source/FlutterTextInputPlugin.h",
"framework/Source/FlutterTextInputPlugin.mm",
"framework/Source/FlutterUIPressProxy.h",
"framework/Source/FlutterUIPressProxy.mm",
"framework/Source/FlutterUndoManagerDelegate.h",
Expand Down Expand Up @@ -209,6 +233,7 @@ source_set("ios_test_flutter_mrc") {
]
deps = [
":flutter_framework_source",
":flutter_framework_source_arc",
"//flutter/common:common",
"//flutter/lib/ui:ui",
"//flutter/shell/common:common",
Expand Down Expand Up @@ -267,6 +292,7 @@ shared_library("ios_test_flutter") {
deps = [
":flutter_framework",
":flutter_framework_source",
":flutter_framework_source_arc",
":ios_gpu_configuration",
":ios_test_flutter_mrc",
"//flutter/common:common",
Expand Down Expand Up @@ -295,7 +321,10 @@ shared_library("create_flutter_framework_dylib") {

public = _flutter_framework_headers

deps = [ ":flutter_framework_source" ]
deps = [
":flutter_framework_source",
":flutter_framework_source_arc",
]

public_configs = [ "//flutter:config" ]
}
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