in lib/ui/window/pointer_data_packet_converter.cc [44:257]
void PointerDataPacketConverter::ConvertPointerData(
PointerData pointer_data,
std::vector<PointerData>& converted_pointers) {
if (pointer_data.signal_kind == PointerData::SignalKind::kNone) {
switch (pointer_data.change) {
case PointerData::Change::kCancel: {
// Android's three finger gesture will send a cancel event
// to a non-existing pointer. Drops the cancel if pointer
// is not previously added.
// https://github.com/flutter/flutter/issues/20517
auto iter = states_.find(pointer_data.device);
if (iter != states_.end()) {
PointerState state = iter->second;
FML_DCHECK(state.is_down);
UpdatePointerIdentifier(pointer_data, state, false);
if (LocationNeedsUpdate(pointer_data, state)) {
// Synthesizes a move event if the location does not match.
PointerData synthesized_move_event = pointer_data;
synthesized_move_event.change = PointerData::Change::kMove;
synthesized_move_event.synthesized = 1;
UpdateDeltaAndState(synthesized_move_event, state);
converted_pointers.push_back(synthesized_move_event);
}
state.is_down = false;
states_[pointer_data.device] = state;
converted_pointers.push_back(pointer_data);
}
break;
}
case PointerData::Change::kAdd: {
FML_DCHECK(states_.find(pointer_data.device) == states_.end());
EnsurePointerState(pointer_data);
converted_pointers.push_back(pointer_data);
break;
}
case PointerData::Change::kRemove: {
// Makes sure we have an existing pointer
auto iter = states_.find(pointer_data.device);
FML_DCHECK(iter != states_.end());
PointerState state = iter->second;
if (state.is_down) {
// Synthesizes cancel event if the pointer is down.
PointerData synthesized_cancel_event = pointer_data;
synthesized_cancel_event.change = PointerData::Change::kCancel;
synthesized_cancel_event.synthesized = 1;
UpdatePointerIdentifier(synthesized_cancel_event, state, false);
state.is_down = false;
states_[synthesized_cancel_event.device] = state;
converted_pointers.push_back(synthesized_cancel_event);
}
if (LocationNeedsUpdate(pointer_data, state)) {
// Synthesizes a hover event if the location does not match.
PointerData synthesized_hover_event = pointer_data;
synthesized_hover_event.change = PointerData::Change::kHover;
synthesized_hover_event.synthesized = 1;
UpdateDeltaAndState(synthesized_hover_event, state);
converted_pointers.push_back(synthesized_hover_event);
}
states_.erase(pointer_data.device);
converted_pointers.push_back(pointer_data);
break;
}
case PointerData::Change::kHover: {
auto iter = states_.find(pointer_data.device);
PointerState state;
if (iter == states_.end()) {
// Synthesizes add event if the pointer is not previously added.
PointerData synthesized_add_event = pointer_data;
synthesized_add_event.change = PointerData::Change::kAdd;
synthesized_add_event.synthesized = 1;
synthesized_add_event.buttons = 0;
state = EnsurePointerState(synthesized_add_event);
converted_pointers.push_back(synthesized_add_event);
} else {
state = iter->second;
}
FML_DCHECK(!state.is_down);
state.buttons = pointer_data.buttons;
if (LocationNeedsUpdate(pointer_data, state)) {
UpdateDeltaAndState(pointer_data, state);
converted_pointers.push_back(pointer_data);
}
break;
}
case PointerData::Change::kDown: {
auto iter = states_.find(pointer_data.device);
PointerState state;
if (iter == states_.end()) {
// Synthesizes a add event if the pointer is not previously added.
PointerData synthesized_add_event = pointer_data;
synthesized_add_event.change = PointerData::Change::kAdd;
synthesized_add_event.synthesized = 1;
synthesized_add_event.buttons = 0;
state = EnsurePointerState(synthesized_add_event);
converted_pointers.push_back(synthesized_add_event);
} else {
state = iter->second;
}
FML_DCHECK(!state.is_down);
if (LocationNeedsUpdate(pointer_data, state)) {
// Synthesizes a hover event if the location does not match.
PointerData synthesized_hover_event = pointer_data;
synthesized_hover_event.change = PointerData::Change::kHover;
synthesized_hover_event.synthesized = 1;
synthesized_hover_event.buttons = 0;
UpdateDeltaAndState(synthesized_hover_event, state);
converted_pointers.push_back(synthesized_hover_event);
}
UpdatePointerIdentifier(pointer_data, state, true);
state.is_down = true;
state.buttons = pointer_data.buttons;
states_[pointer_data.device] = state;
converted_pointers.push_back(pointer_data);
break;
}
case PointerData::Change::kMove: {
// Makes sure we have an existing pointer in down state
auto iter = states_.find(pointer_data.device);
FML_DCHECK(iter != states_.end());
PointerState state = iter->second;
FML_DCHECK(state.is_down);
UpdatePointerIdentifier(pointer_data, state, false);
UpdateDeltaAndState(pointer_data, state);
state.buttons = pointer_data.buttons;
converted_pointers.push_back(pointer_data);
break;
}
case PointerData::Change::kUp: {
// Makes sure we have an existing pointer in down state
auto iter = states_.find(pointer_data.device);
FML_DCHECK(iter != states_.end());
PointerState state = iter->second;
FML_DCHECK(state.is_down);
UpdatePointerIdentifier(pointer_data, state, false);
if (LocationNeedsUpdate(pointer_data, state)) {
// Synthesizes a move event if the location does not match.
PointerData synthesized_move_event = pointer_data;
synthesized_move_event.change = PointerData::Change::kMove;
synthesized_move_event.buttons = state.buttons;
synthesized_move_event.synthesized = 1;
UpdateDeltaAndState(synthesized_move_event, state);
converted_pointers.push_back(synthesized_move_event);
}
state.is_down = false;
state.buttons = pointer_data.buttons;
states_[pointer_data.device] = state;
converted_pointers.push_back(pointer_data);
break;
}
default: {
converted_pointers.push_back(pointer_data);
break;
}
}
} else {
switch (pointer_data.signal_kind) {
case PointerData::SignalKind::kScroll: {
// Makes sure we have an existing pointer
auto iter = states_.find(pointer_data.device);
FML_DCHECK(iter != states_.end());
PointerState state = iter->second;
if (LocationNeedsUpdate(pointer_data, state)) {
if (state.is_down) {
// Synthesizes a move event if the pointer is down.
PointerData synthesized_move_event = pointer_data;
synthesized_move_event.signal_kind = PointerData::SignalKind::kNone;
synthesized_move_event.change = PointerData::Change::kMove;
synthesized_move_event.buttons = state.buttons;
synthesized_move_event.synthesized = 1;
UpdateDeltaAndState(synthesized_move_event, state);
converted_pointers.push_back(synthesized_move_event);
} else {
// Synthesizes a hover event if the pointer is up.
PointerData synthesized_hover_event = pointer_data;
synthesized_hover_event.signal_kind =
PointerData::SignalKind::kNone;
synthesized_hover_event.change = PointerData::Change::kHover;
synthesized_hover_event.buttons = 0;
synthesized_hover_event.synthesized = 1;
UpdateDeltaAndState(synthesized_hover_event, state);
converted_pointers.push_back(synthesized_hover_event);
}
}
converted_pointers.push_back(pointer_data);
break;
}
default: {
// Ignores unknown signal kind.
break;
}
}
}
}