| Index: ui/events/ozone/evdev/touch_event_converter_evdev.cc
|
| diff --git a/ui/events/ozone/evdev/touch_event_converter_evdev.cc b/ui/events/ozone/evdev/touch_event_converter_evdev.cc
|
| index 88b04aa1cfef8991d174175f9bab678efa60fa5c..36fe49bd97f0d678ce38cfbfc4be8fd124df8636 100644
|
| --- a/ui/events/ozone/evdev/touch_event_converter_evdev.cc
|
| +++ b/ui/events/ozone/evdev/touch_event_converter_evdev.cc
|
| @@ -129,6 +129,7 @@ TouchEventConverterEvdev::~TouchEventConverterEvdev() {
|
|
|
| void TouchEventConverterEvdev::Initialize(const EventDeviceInfo& info) {
|
| has_mt_ = info.HasMultitouch();
|
| + has_pen_ = info.HasKeyEvent(BTN_TOOL_PEN);
|
|
|
| if (has_mt_) {
|
| pressure_min_ = info.GetAbsMinimum(ABS_MT_PRESSURE);
|
| @@ -139,6 +140,7 @@ void TouchEventConverterEvdev::Initialize(const EventDeviceInfo& info) {
|
| y_num_tuxels_ = info.GetAbsMaximum(ABS_MT_POSITION_Y) - y_min_tuxels_ + 1;
|
| touch_points_ =
|
| std::min<int>(info.GetAbsMaximum(ABS_MT_SLOT) + 1, kNumTouchEvdevSlots);
|
| + major_max_ = info.GetAbsMaximum(ABS_MT_TOUCH_MAJOR);
|
| current_slot_ = info.GetAbsValue(ABS_MT_SLOT);
|
| } else {
|
| pressure_min_ = info.GetAbsMinimum(ABS_PRESSURE);
|
| @@ -148,6 +150,7 @@ void TouchEventConverterEvdev::Initialize(const EventDeviceInfo& info) {
|
| y_min_tuxels_ = info.GetAbsMinimum(ABS_Y);
|
| y_num_tuxels_ = info.GetAbsMaximum(ABS_Y) - y_min_tuxels_ + 1;
|
| touch_points_ = 1;
|
| + major_max_ = 0;
|
| current_slot_ = 0;
|
| }
|
|
|
| @@ -188,12 +191,14 @@ void TouchEventConverterEvdev::Initialize(const EventDeviceInfo& info) {
|
| events_[i].altered = true;
|
|
|
| // Optional bits.
|
| - events_[i].radius_x =
|
| - info.GetAbsMtSlotValueWithDefault(ABS_MT_TOUCH_MAJOR, i, 0) / 2.0f;
|
| + int touch_major =
|
| + info.GetAbsMtSlotValueWithDefault(ABS_MT_TOUCH_MAJOR, i, 0);
|
| + events_[i].radius_x = touch_major / 2.0f;
|
| events_[i].radius_y =
|
| info.GetAbsMtSlotValueWithDefault(ABS_MT_TOUCH_MINOR, i, 0) / 2.0f;
|
| events_[i].pressure = ScalePressure(
|
| info.GetAbsMtSlotValueWithDefault(ABS_MT_PRESSURE, i, 0));
|
| + events_[i].cancelled = (major_max_ > 0 && touch_major == major_max_);
|
| }
|
| } else {
|
| // TODO(spang): Add key state to EventDeviceInfo to allow initial contact.
|
| @@ -207,6 +212,7 @@ void TouchEventConverterEvdev::Initialize(const EventDeviceInfo& info) {
|
| events_[0].radius_y = 0;
|
| events_[0].pressure = 0;
|
| events_[0].tool_code = 0;
|
| + events_[0].cancelled = false;
|
| }
|
| }
|
|
|
| @@ -227,6 +233,10 @@ bool TouchEventConverterEvdev::HasTouchscreen() const {
|
| return true;
|
| }
|
|
|
| +bool TouchEventConverterEvdev::HasPen() const {
|
| + return has_pen_;
|
| +}
|
| +
|
| gfx::Size TouchEventConverterEvdev::GetTouchscreenSize() const {
|
| return gfx::Size(x_num_tuxels_, y_num_tuxels_);
|
| }
|
| @@ -236,12 +246,14 @@ int TouchEventConverterEvdev::GetTouchPoints() const {
|
| }
|
|
|
| void TouchEventConverterEvdev::OnEnabled() {
|
| - ReportEvents(EventTimeForNow());
|
| }
|
|
|
| void TouchEventConverterEvdev::OnDisabled() {
|
| ReleaseTouches();
|
| ReleaseButtons();
|
| + if (enable_palm_suppression_callback_) {
|
| + enable_palm_suppression_callback_.Run(false);
|
| + }
|
| }
|
|
|
| void TouchEventConverterEvdev::OnFileCanReadWithoutBlocking(int fd) {
|
| @@ -260,11 +272,6 @@ void TouchEventConverterEvdev::OnFileCanReadWithoutBlocking(int fd) {
|
| return;
|
| }
|
|
|
| - if (!enabled_) {
|
| - dropped_events_ = true;
|
| - return;
|
| - }
|
| -
|
| for (unsigned i = 0; i < read_size / sizeof(*inputs); i++) {
|
| if (!has_mt_) {
|
| // Emulate the device as an MT device with only 1 slot by inserting extra
|
| @@ -284,6 +291,11 @@ void TouchEventConverterEvdev::SetTouchEventLoggingEnabled(bool enabled) {
|
| touch_logging_enabled_ = enabled;
|
| }
|
|
|
| +void TouchEventConverterEvdev::SetPalmSuppressionCallback(
|
| + const base::Callback<void(bool)>& callback) {
|
| + enable_palm_suppression_callback_ = callback;
|
| +}
|
| +
|
| void TouchEventConverterEvdev::ProcessMultitouchEvent(
|
| const input_event& input) {
|
| if (touch_logging_enabled_)
|
| @@ -357,6 +369,7 @@ void TouchEventConverterEvdev::ProcessKey(const input_event& input) {
|
| } else {
|
| events_[current_slot_].tool_code = 0;
|
| }
|
| + events_[current_slot_].altered = true;
|
| break;
|
| default:
|
| NOTIMPLEMENTED() << "invalid code for EV_KEY: " << input.code;
|
| @@ -370,6 +383,11 @@ void TouchEventConverterEvdev::ProcessAbs(const input_event& input) {
|
| // we can scale the ellipse correctly. However on the Pixel we get
|
| // neither minor nor orientation, so this is all we can do.
|
| events_[current_slot_].radius_x = input.value / 2.0f;
|
| +
|
| + // The MT protocol cannot communicate cancelled touches, so some kernel
|
| + // drivers will identify palms by setting touch major to max.
|
| + if (major_max_ > 0 && input.value == major_max_)
|
| + events_[current_slot_].cancelled = true;
|
| break;
|
| case ABS_MT_TOUCH_MINOR:
|
| events_[current_slot_].radius_y = input.value / 2.0f;
|
| @@ -419,14 +437,11 @@ void TouchEventConverterEvdev::ProcessSyn(const input_event& input) {
|
|
|
| EventType TouchEventConverterEvdev::GetEventTypeForTouch(
|
| const InProgressTouchEvdev& touch) {
|
| - if (touch.cancelled)
|
| + if (touch.was_cancelled)
|
| return ET_UNKNOWN;
|
|
|
| - if (touch_noise_finder_ && touch_noise_finder_->SlotHasNoise(touch.slot)) {
|
| - if (touch.touching && !touch.was_touching)
|
| - return ET_UNKNOWN;
|
| - return ET_TOUCH_CANCELLED;
|
| - }
|
| + if (touch.cancelled)
|
| + return touch.was_touching ? ET_TOUCH_CANCELLED : ET_UNKNOWN;
|
|
|
| if (touch.touching)
|
| return touch.was_touching ? ET_TOUCH_MOVED : ET_TOUCH_PRESSED;
|
| @@ -480,17 +495,21 @@ void TouchEventConverterEvdev::ReportEvents(base::TimeTicks timestamp) {
|
| if (!event->altered)
|
| continue;
|
|
|
| + if (enable_palm_suppression_callback_)
|
| + enable_palm_suppression_callback_.Run(event->tool_code > 0);
|
| +
|
| + if (touch_noise_finder_ && touch_noise_finder_->SlotHasNoise(event->slot))
|
| + event->cancelled = true;
|
| +
|
| if (event->tool_code > 0) {
|
| ReportStylusEvent(*event, timestamp);
|
| } else {
|
| EventType event_type = GetEventTypeForTouch(*event);
|
| - if (event_type == ET_UNKNOWN || event_type == ET_TOUCH_CANCELLED)
|
| - event->cancelled = true;
|
| -
|
| if (event_type != ET_UNKNOWN)
|
| ReportTouchEvent(*event, event_type, timestamp);
|
| }
|
|
|
| + event->was_cancelled = event->cancelled;
|
| event->was_touching = event->touching;
|
| event->altered = false;
|
| event->btn_left.changed = false;
|
| @@ -509,13 +528,17 @@ void TouchEventConverterEvdev::UpdateTrackingId(int slot, int tracking_id) {
|
| event->touching = (tracking_id >= 0);
|
| event->altered = true;
|
|
|
| - if (tracking_id >= 0)
|
| - event->cancelled = false;
|
| + if (tracking_id >= 0) {
|
| + event->was_cancelled = false;
|
| + event->cancelled = !enabled_;
|
| + }
|
| }
|
|
|
| void TouchEventConverterEvdev::ReleaseTouches() {
|
| - for (size_t slot = 0; slot < events_.size(); slot++)
|
| - UpdateTrackingId(slot, kTrackingIdForUnusedSlot);
|
| + for (size_t slot = 0; slot < events_.size(); slot++) {
|
| + events_[slot].cancelled = true;
|
| + events_[slot].altered = true;
|
| + }
|
|
|
| ReportEvents(EventTimeForNow());
|
| }
|
|
|