| Flutter macOS Embedder |

Instance Methods | Properties | List of all members
FlutterTextInputPlugin Class Reference

`#import <FlutterTextInputPlugin.h>`

Inheritance diagram for FlutterTextInputPlugin:

## Instance Methods
(instancetype) | - initWithViewController:
(BOOL) | - isFirstResponder
(BOOL) | - handleKeyEvent:
(void) | - handleMethodCall:result:
(NSRect) | - firstRectForCharacterRange:actualRange:
(NSDictionary *) | - editingState

## Properties
FlutterTextField * | client
NSTextInputContext * | textInputContext
NSString * | customRunLoopMode

## Detailed Description

A plugin to handle text input.

Responsible for bridging the native macOS text input system with the Flutter framework text editing classes, via system channels.

This is not an FlutterPlugin since it needs access to FlutterViewController internals, so needs to be managed differently.

When accessibility is on, accessibility bridge creates a NSTextField, i.e. FlutterTextField, for every text field in the Flutter. This plugin acts as a field editor for those NSTextField[s].

Definition at line 27 of file FlutterTextInputPlugin.h.

## Method Documentation

## ◆ editingState

- (NSDictionary*) editingState |  |  |

Provided by category FlutterTextInputPlugin(TestMethods).

Referenced by FlutterInputPluginTestObjc::testClearClientDuringComposing, and FlutterInputPluginTestObjc::testEmptyCompositionRange.

## ◆ firstRectForCharacterRange:actualRange:

- (NSRect) firstRectForCharacterRange: |  | (NSRange) | range
actualRange: |  | (NSRangePointer) | actualRange

Provided by category FlutterTextInputPlugin(TestMethods).

## ◆ handleKeyEvent:

- (BOOL) handleKeyEvent: |  | (NSEvent*) | event |

Handles key down events received from the view controller, responding YES if the event was handled.

Note, the Apple docs suggest that clients should override essentially all the mouse and keyboard event-handling methods of NSResponder. However, experimentation indicates that only key events are processed by the native layer; Flutter processes mouse events. Additionally, processing both keyUp and keyDown results in duplicate processing of the same keys.

Definition at line 605 of file FlutterTextInputPlugin.mm.

605 :(NSEvent*)event {
606 if (event.type == NSEventTypeKeyUp ||
607 (event.type == NSEventTypeFlagsChanged && event.modifierFlags < _previouslyPressedFlags)) {
608 return NO;
609 }
610 _previouslyPressedFlags = event.modifierFlags;
611 if (!_shown) {
612 return NO;
613 }
614
615 _eventProducedOutput = NO;
616 BOOL res = [_textInputContext handleEvent:event];
617 // NSTextInputContext#handleEvent returns YES if the context handles the event. One of the reasons
618 // the event is handled is because it's a key equivalent. But a key equivalent might produce a
619 // text command (indicated by calling doCommandBySelector) or might not (for example, Cmd+Q). In
620 // the latter case, this command somehow has not been executed yet and Flutter must dispatch it to
621 // the next responder. See https://github.com/flutter/flutter/issues/106354 .
622 // The event is also not redispatched if there is IME composition active, because it might be
623 // handled by the IME. See https://github.com/flutter/flutter/issues/134699
624
625 // both NSEventModifierFlagNumericPad and NSEventModifierFlagFunction are set for arrow keys.
626 bool is_navigation = event.modifierFlags & NSEventModifierFlagFunction &&
627 event.modifierFlags & NSEventModifierFlagNumericPad;
628 bool is_navigation_in_ime = is_navigation && self.hasMarkedText;
629
630 if (event.isKeyEquivalent && !is_navigation_in_ime && !_eventProducedOutput) {
631 return NO;
632 }
633 return res;
634 }

## ◆ handleMethodCall:result:

- (void) handleMethodCall: |  | (FlutterMethodCall *) | call
result: |  | (FlutterResult) | result

Provided by category FlutterTextInputPlugin(TestMethods).

Referenced by flutter::testing::TEST(), FlutterInputPluginTestObjc::testClearClientDuringComposing, and FlutterInputPluginTestObjc::testEmptyCompositionRange.

## ◆ initWithViewController:

- (instancetype) initWithViewController: |  | (FlutterViewController*) | viewController |

Initializes a text input plugin that coordinates key event handling with |viewController|.

Definition at line 342 of file FlutterTextInputPlugin.mm.

342 :(FlutterViewController*)viewController {
343 // The view needs an empty frame otherwise it is visible on dark background.
344 // https://github.com/flutter/flutter/issues/118504
345 self = [super initWithFrame:NSZeroRect];
346 self.clipsToBounds = YES;
347 if (self != nil) {
348 _flutterViewController = viewController;
349 _channel = [FlutterMethodChannel methodChannelWithName:kTextInputChannel
350 binaryMessenger:viewController.engine.binaryMessenger
351 codec:[FlutterJSONMethodCodec sharedInstance]];
352 _shown = FALSE;
353 // NSTextView does not support _weak reference, so this class has to
354 // use __unsafe_unretained and manage the reference by itself.
355 //
356 // Since the dealloc removes the handler, the pointer should
357 // be valid if the handler is ever called.
358 __unsafe_unretained FlutterTextInputPlugin* unsafeSelf = self;
359 [_channel setMethodCallHandler:^(FlutterMethodCall* call, FlutterResult result) {
360 [unsafeSelf handleMethodCall:call result:result];
361 }];
362 _textInputContext = [[NSTextInputContext alloc] initWithClient:unsafeSelf];
363 _previouslyPressedFlags = 0;
364
365 // Initialize with the zero matrix which is not
366 // an affine transform.
367 _editableTransform = CATransform3D();
368 _caretRect = CGRectNull;
369 }
370 return self;
371 }

References _caretRect, _editableTransform, and FlutterMethodChannel::methodChannelWithName:binaryMessenger:codec:.

## ◆ isFirstResponder

- (BOOL) isFirstResponder |  |  |

Whether this plugin is the first responder of this NSWindow.

When accessibility is on, this plugin is set as the first responder to act as the field editor for FlutterTextFields.

Returns false if accessibility is off.

Definition at line 373 of file FlutterTextInputPlugin.mm.

373 {
374 if (!self.flutterViewController.viewLoaded) {
375 return false;
376 }
377 return [self.flutterViewController.view.window firstResponder] == self;
378 }

## Property Documentation

## ◆ client

- (FlutterTextField*) client
| read write nonatomic weak

The NSTextField that currently has this plugin as its field editor.

Must be nil if accessibility is off.

Definition at line 34 of file FlutterTextInputPlugin.h.

Referenced by FlutterTextField::startEditing, and FlutterTextField::updateString:withSelection:.

## ◆ customRunLoopMode

- (NSString*) customRunLoopMode
| read write nonatomic assign

Provided by category FlutterTextInputPlugin(TestMethods).

Definition at line 71 of file FlutterTextInputPlugin.h.

## ◆ textInputContext

- (NSTextInputContext*) textInputContext
| read write nonatomic assign

Provided by category FlutterTextInputPlugin(TestMethods).

Definition at line 70 of file FlutterTextInputPlugin.h.

The documentation for this class was generated from the following files:

- shell/platform/darwin/macos/framework/Source/FlutterTextInputPlugin.h
- shell/platform/darwin/macos/framework/Source/FlutterTextInputPlugin.mm

FlutterViewController
Definition: FlutterViewController.h:73
FlutterMethodChannel
Definition: FlutterChannels.h:220
FlutterTextInputPlugin
Definition: FlutterTextInputPlugin.h:27
+[FlutterMethodChannel methodChannelWithName:binaryMessenger:codec:]
instancetype methodChannelWithName:binaryMessenger:codec:(NSString *name,[binaryMessenger] NSObject< FlutterBinaryMessenger > *messenger,[codec] NSObject< FlutterMethodCodec > *codec)
FlutterJSONMethodCodec
Definition: FlutterCodecs.h:455
_editableTransform
CATransform3D _editableTransform
Definition: FlutterTextInputPlugin.mm:325
_caretRect
CGRect _caretRect
Definition: FlutterTextInputPlugin.mm:339