onSend method

  1. @override
Msg? onSend(
  1. Msg msg
)
override

Called for each message before it is queued.

Return the same message to keep it, a modified message to transform it, or null to drop it.

Implementation

@override
Msg? onSend(Msg msg) {
  // Timeouts always go to the owning surface first.
  if (msg is _SequenceTimeoutMsg) {
    for (final s in _stack) {
      if (s.id == msg.surfaceId) {
        final result = s.handle(msg);
        switch (result) {
          case KeymapLayerClaim(:final msg):
            onPendingChanged?.call();
            return msg;
          case KeymapLayerDrop():
            return null;
          case KeymapLayerPass():
            return null;
        }
      }
    }
    return null;
  }

  final hadPending = isSequencePending;

  // Surface-first: top of stack → bottom.
  for (var i = _stack.length - 1; i >= 0; i--) {
    final surface = _stack[i];
    final result = surface.handle(msg);
    switch (result) {
      case KeymapLayerPass():
        if (surface.exclusive) {
          if (hadPending != isSequencePending) onPendingChanged?.call();
          return null;
        }
        continue;
      case KeymapLayerClaim(:final msg):
        if (hadPending != isSequencePending ||
            msg is KeymapSequencePrefixMsg ||
            msg is KeymapSequenceCancelledMsg ||
            msg is KeymapActionMsg) {
          onPendingChanged?.call();
        }
        return msg;
      case KeymapLayerDrop():
        if (hadPending != isSequencePending) onPendingChanged?.call();
        return null;
    }
  }

  // Base layers last.
  var current = msg;
  for (final b in _base) {
    final out = b.onSend(current);
    if (out == null) return null;
    current = out;
  }
  return current;
}