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()); |
} |