dispatchBubbleUp method
Dispatches msg by walking UP the element tree from startElement to
the root, calling handleUpdate on each StatefulElement's state.
This mirrors Flutter's pointer-event bubbling: the deepest hit element's ancestors get to handle the event, and the first one that produces a Cmd wins.
When visited is provided, elements already in the set are skipped
and newly visited elements are added. This prevents a
GestureDetector from processing the same event multiple times when
several child render objects bubble up to the same ancestor.
Use this for HitTestMouseMsg dispatch so that a GestureDetector (which is a StatefulWidget without its own render object) receives the event even though only its child's render object was hit.
Implementation
Cmd? dispatchBubbleUp(
Element startElement,
Msg msg, {
Set<Element>? visited,
}) {
Element? current = startElement;
Cmd? bubbleCmd;
while (current != null) {
if (current is StatefulElement) {
if (visited != null) {
if (!visited.add(current)) {
// Already dispatched to this element — skip.
current = current.parent;
continue;
}
}
current.rebuild();
final cmd = current.state.handleUpdate(msg);
if (cmd != null) {
bubbleCmd = cmd;
break;
}
}
current = current.parent;
}
_flushDirtyBuilds();
final mountInit = _owner.drainMountInitCmds();
return _coalesceCommands([
if (bubbleCmd != null) bubbleCmd,
if (mountInit != null) mountInit,
]);
}