Flutter macOS Embedder
FlutterKeyboardManager Class Reference

#import <FlutterKeyboardManager.h>

Inheritance diagram for FlutterKeyboardManager:

Instance Methods

(nonnull instancetype) - initWithViewDelegate:
 
(void) - handleEvent:
 
(BOOL) - isDispatchingKeyEvent:
 
(void) - syncModifiersIfNeeded:timestamp:
 
(nonnull NSDictionary *) - getPressedState
 

Detailed Description

Processes keyboard events and cooperate with |TextInputPlugin|.

A keyboard event goes through a few sections, each can choose to handled the event, and only unhandled events can move to the next section:

  • Pre-filtering: Events during IME are sent to the system immediately.
  • Keyboard: Dispatch to the embedder responder and the channel responder simultaneously. After both responders have responded (asynchronously), the event is considered handled if either responder handles.
  • Text input: Events are sent to |TextInputPlugin| and are handled synchronously.
  • Next responder: Events are sent to the next responder as specified by |viewDelegate|.

Definition at line 24 of file FlutterKeyboardManager.h.

Method Documentation

◆ getPressedState

- (nonnull NSDictionary *) getPressedState

Returns the keyboard pressed state.

Returns the keyboard pressed state. The dictionary contains one entry per pressed keys, mapping from the logical key to the physical key.

Definition at line 351 of file FlutterKeyboardManager.mm.

351  {
352  // The embedder responder is the first element in _primaryResponders.
353  FlutterEmbedderKeyResponder* embedderResponder =
354  (FlutterEmbedderKeyResponder*)_primaryResponders[0];
355  return [embedderResponder getPressedState];
356 }

References FlutterEmbedderKeyResponder::getPressedState.

◆ handleEvent:

- (void) handleEvent: (nonnull NSEvent*)  event

Processes a key event.

Unhandled events will be dispatched to the text input system, and possibly the next responder afterwards.

Definition at line 173 of file FlutterKeyboardManager.mm.

173  :(nonnull NSEvent*)event {
174  // The `handleEvent` does not process the event immediately, but instead put
175  // events into a queue. Events are processed one by one by `processNextEvent`.
176 
177  // Be sure to add a handling method in propagateKeyEvent when allowing more
178  // event types here.
179  if (event.type != NSEventTypeKeyDown && event.type != NSEventTypeKeyUp &&
180  event.type != NSEventTypeFlagsChanged) {
181  return;
182  }
183 
184  [_pendingEvents addObject:event];
185  [self processNextEvent];
186 }

◆ initWithViewDelegate:

- (nonnull instancetype) initWithViewDelegate: (nonnull id<FlutterKeyboardViewDelegate>)  viewDelegate
Initial value:
{
NextResponderProvider _getNextResponder

Create a keyboard manager.

The |viewDelegate| is a weak reference, typically implemented by |FlutterViewController|.

Definition at line 116 of file FlutterKeyboardManager.mm.

116  :(nonnull id<FlutterKeyboardViewDelegate>)viewDelegate {
117  self = [super init];
118  if (self != nil) {
119  _processingEvent = FALSE;
120  _viewDelegate = viewDelegate;
121 
122  FlutterMethodChannel* keyboardChannel =
123  [FlutterMethodChannel methodChannelWithName:@"flutter/keyboard"
124  binaryMessenger:[_viewDelegate getBinaryMessenger]
125  codec:[FlutterStandardMethodCodec sharedInstance]];
126  [keyboardChannel setMethodCallHandler:^(FlutterMethodCall* call, FlutterResult result) {
127  [self handleKeyboardMethodCall:call result:result];
128  }];
129  _primaryResponders = [[NSMutableArray alloc] init];
130  [self addPrimaryResponder:[[FlutterEmbedderKeyResponder alloc]
131  initWithSendEvent:^(const FlutterKeyEvent& event,
132  FlutterKeyEventCallback callback,
133  void* userData) {
134  [_viewDelegate sendKeyEvent:event
135  callback:callback
136  userData:userData];
137  }]];
138  [self
139  addPrimaryResponder:[[FlutterChannelKeyResponder alloc]
140  initWithChannel:[FlutterBasicMessageChannel
141  messageChannelWithName:@"flutter/keyevent"
142  binaryMessenger:[_viewDelegate
143  getBinaryMessenger]
145  sharedInstance]]]];
146  _pendingEvents = [[NSMutableArray alloc] init];
147  _layoutMap = [NSMutableDictionary<NSNumber*, NSNumber*> dictionary];
148  [self buildLayout];
149  for (id<FlutterKeyPrimaryResponder> responder in _primaryResponders) {
150  responder.layoutMap = _layoutMap;
151  }
152 
153  __weak __typeof__(self) weakSelf = self;
154  [_viewDelegate subscribeToKeyboardLayoutChange:^() {
155  [weakSelf buildLayout];
156  }];
157  }
158  return self;
159 }

References <FlutterKeyPrimaryResponder>::layoutMap, FlutterBasicMessageChannel::messageChannelWithName:binaryMessenger:codec:, FlutterMethodChannel::methodChannelWithName:binaryMessenger:codec:, FlutterMethodChannel::setMethodCallHandler:, and <FlutterMessageCodec>::sharedInstance.

◆ isDispatchingKeyEvent:

- (BOOL) isDispatchingKeyEvent: (nonnull NSEvent *)  event

Returns yes if is event currently being redispatched.

In some instances (i.e. emoji shortcut) the event may be redelivered by cocoa as key equivalent to FlutterTextInput, in which case it shouldn't be processed again.

◆ syncModifiersIfNeeded:timestamp:

- (void) syncModifiersIfNeeded: (NSEventModifierFlags)  modifierFlags
timestamp: (NSTimeInterval)  timestamp 

Synthesize modifier keys events.

If needed, synthesize modifier keys up and down events by comparing their current pressing states with the given modifier flags.

Definition at line 338 of file FlutterKeyboardManager.mm.

338  :(NSEventModifierFlags)modifierFlags
339  timestamp:(NSTimeInterval)timestamp {
340  for (id<FlutterKeyPrimaryResponder> responder in _primaryResponders) {
341  [responder syncModifiersIfNeeded:modifierFlags timestamp:timestamp];
342  }
343 }

References <FlutterKeyPrimaryResponder>::syncModifiersIfNeeded:timestamp:.


The documentation for this class was generated from the following files:
+[FlutterBasicMessageChannel messageChannelWithName:binaryMessenger:codec:]
instancetype messageChannelWithName:binaryMessenger:codec:(NSString *name,[binaryMessenger] NSObject< FlutterBinaryMessenger > *messenger,[codec] NSObject< FlutterMessageCodec > *codec)
Definition: FlutterChannels.mm:82
FlutterBasicMessageChannel
Definition: FlutterChannels.h:39
FlutterMethodChannel
Definition: FlutterChannels.h:222
-[FlutterEmbedderKeyResponder getPressedState]
nonnull NSDictionary * getPressedState()
Definition: FlutterEmbedderKeyResponder.mm:796
-[FlutterMethodChannel setMethodCallHandler:]
void setMethodCallHandler:(FlutterMethodCallHandler _Nullable handler)
FlutterChannelKeyResponder
Definition: FlutterChannelKeyResponder.h:17
+[FlutterMethodChannel methodChannelWithName:binaryMessenger:codec:]
instancetype methodChannelWithName:binaryMessenger:codec:(NSString *name,[binaryMessenger] NSObject< FlutterBinaryMessenger > *messenger,[codec] NSObject< FlutterMethodCodec > *codec)
FlutterEmbedderKeyResponder
Definition: FlutterEmbedderKeyResponder.h:24
FlutterStandardMethodCodec
Definition: FlutterCodecs.h:467
+[FlutterMessageCodec-p sharedInstance]
instancetype sharedInstance()
FlutterJSONMessageCodec
Definition: FlutterCodecs.h:81