Chromium Code Reviews| 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 e0c9d2d2fa6a656c34ad10f7a2f0ab12df913874..044f66e00e18144d95d5409c898e85c2ff21a143 100644 |
| --- a/ui/events/ozone/evdev/touch_event_converter_evdev.cc |
| +++ b/ui/events/ozone/evdev/touch_event_converter_evdev.cc |
| @@ -126,6 +126,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); |
| @@ -136,6 +137,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); |
| @@ -145,6 +147,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; |
| } |
| @@ -185,12 +188,14 @@ void TouchEventConverterEvdev::Initialize(const EventDeviceInfo& info) { |
| events_[i].altered = true; |
| // Optional bits. |
| - events_[i].radius_x = |
| + int touch_major = |
| info.GetAbsMtSlotValueWithDefault(ABS_MT_TOUCH_MAJOR, i, 0) / 2.0f; |
| + 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].will_cancel = (major_max_ > 0 && touch_major == major_max_); |
| } |
| } else { |
| // TODO(spang): Add key state to EventDeviceInfo to allow initial contact. |
| @@ -204,6 +209,7 @@ void TouchEventConverterEvdev::Initialize(const EventDeviceInfo& info) { |
| events_[0].radius_y = 0; |
| events_[0].pressure = 0; |
| events_[0].tool_code = 0; |
| + events_[0].will_cancel = false; |
| } |
| } |
| @@ -224,6 +230,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_); |
| } |
| @@ -233,12 +243,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) { |
| @@ -257,11 +269,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 |
| @@ -281,6 +288,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_) |
| @@ -352,6 +364,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; |
| @@ -365,6 +378,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_].will_cancel = true; |
| break; |
| case ABS_MT_TOUCH_MINOR: |
| events_[current_slot_].radius_y = input.value / 2.0f; |
| @@ -417,6 +435,12 @@ EventType TouchEventConverterEvdev::GetEventTypeForTouch( |
| if (touch.cancelled) |
| return ET_UNKNOWN; |
| + if (touch.will_cancel) { |
| + if (touch.touching && !touch.was_touching) |
| + return ET_UNKNOWN; |
| + return ET_TOUCH_CANCELLED; |
| + } |
| + |
| if (touch_noise_finder_ && touch_noise_finder_->SlotHasNoise(touch.slot)) { |
|
spang
2016/08/26 00:58:34
Can we move this earlier and just set |will_cancel
denniskempin
2016/08/26 21:56:02
Done. I have moved it to ReportTouches, since this
|
| if (touch.touching && !touch.was_touching) |
| return ET_UNKNOWN; |
| @@ -475,6 +499,10 @@ 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 (event->tool_code > 0) { |
| ReportStylusEvent(*event, timestamp); |
| } else { |
| @@ -504,13 +532,15 @@ void TouchEventConverterEvdev::UpdateTrackingId(int slot, int tracking_id) { |
| event->touching = (tracking_id >= 0); |
| event->altered = true; |
| - if (tracking_id >= 0) |
| + if (tracking_id >= 0) { |
| event->cancelled = false; |
| + event->will_cancel = !enabled_; |
| + } |
| } |
| void TouchEventConverterEvdev::ReleaseTouches() { |
| for (size_t slot = 0; slot < events_.size(); slot++) |
| - UpdateTrackingId(slot, kTrackingIdForUnusedSlot); |
| + events_[slot].will_cancel = true; |
| ReportEvents(EventTimeForNow()); |
| } |