[go: nahoru, domu]

blob: e0844d87ef6ed8c760e0451f4a169afe1b433f15 [file] [log] [blame]
// Copyright 2016 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "ui/events/blink/web_input_event_traits.h"
#include "base/check_op.h"
#include "base/notreached.h"
#include "base/strings/stringprintf.h"
#include "third_party/blink/public/common/input/web_gesture_event.h"
#include "third_party/blink/public/common/input/web_keyboard_event.h"
#include "third_party/blink/public/common/input/web_mouse_wheel_event.h"
#include "third_party/blink/public/common/input/web_pointer_event.h"
#include "third_party/blink/public/common/input/web_touch_event.h"
using base::StringAppendF;
using blink::WebGestureEvent;
using blink::WebInputEvent;
using blink::WebKeyboardEvent;
using blink::WebMouseEvent;
using blink::WebMouseWheelEvent;
using blink::WebPointerEvent;
using blink::WebTouchEvent;
using blink::WebTouchPoint;
namespace ui {
namespace {
void ApppendEventDetails(const WebKeyboardEvent& event, std::string* result) {
StringAppendF(result,
"{\n WinCode: %d\n NativeCode: %d\n IsSystem: %d\n"
" Text: %s\n UnmodifiedText: %s\n}",
event.windows_key_code, event.native_key_code,
event.is_system_key, reinterpret_cast<const char*>(event.text),
reinterpret_cast<const char*>(event.unmodified_text));
}
void ApppendEventDetails(const WebMouseEvent& event, std::string* result) {
StringAppendF(result,
"{\n Button: %d\n Pos: (%f, %f)\n"
" GlobalPos: (%f, %f)\n Movement: (%d, %d)\n Clicks: %d\n}",
static_cast<int>(event.button), event.PositionInWidget().x(),
event.PositionInWidget().y(), event.PositionInScreen().x(),
event.PositionInScreen().y(), event.movement_x,
event.movement_y, event.click_count);
}
void ApppendEventDetails(const WebMouseWheelEvent& event, std::string* result) {
StringAppendF(result,
"{\n Delta: (%f, %f)\n WheelTicks: (%f, %f)\n Accel: (%f, %f)\n"
" DeltaUnits: %d\n Phase: (%d, %d)",
event.delta_x, event.delta_y, event.wheel_ticks_x,
event.wheel_ticks_y, event.acceleration_ratio_x,
event.acceleration_ratio_y, static_cast<int>(event.delta_units),
event.phase, event.momentum_phase);
}
void ApppendEventDetails(const WebGestureEvent& event, std::string* result) {
StringAppendF(
result,
"{\n Pos: (%f, %f)\n GlobalPos: (%f, %f)\n SourceDevice: %d\n"
" RawData: (%f, %f, %f, %f)\n}",
event.PositionInWidget().x(), event.PositionInWidget().y(),
event.PositionInScreen().x(), event.PositionInScreen().y(),
static_cast<int>(event.SourceDevice()), event.data.scroll_update.delta_x,
event.data.scroll_update.delta_y, event.data.scroll_update.velocity_x,
event.data.scroll_update.velocity_y);
}
void ApppendTouchPointDetails(const WebTouchPoint& point, std::string* result) {
StringAppendF(result,
" (ID: %d, State: %d, ScreenPos: (%f, %f), Pos: (%f, %f),"
" Radius: (%f, %f), Rot: %f, Force: %f,"
" Tilt: (%d, %d), Twist: %d, TangentialPressure: %f),\n",
point.id, static_cast<int>(point.state),
point.PositionInScreen().x(), point.PositionInScreen().y(),
point.PositionInWidget().x(), point.PositionInWidget().y(),
point.radius_x, point.radius_y, point.rotation_angle,
point.force, point.tilt_x, point.tilt_y, point.twist,
point.tangential_pressure);
}
void ApppendEventDetails(const WebTouchEvent& event, std::string* result) {
StringAppendF(result,
"{\n Touches: %u, DispatchType: %d, CausesScrolling: %d,"
" Hovering: %d, uniqueTouchEventId: %u\n[\n",
event.touches_length, static_cast<int>(event.dispatch_type),
event.moved_beyond_slop_region, event.hovering,
event.unique_touch_event_id);
for (unsigned i = 0; i < event.touches_length; ++i)
ApppendTouchPointDetails(event.touches[i], result);
result->append(" ]\n}");
}
void ApppendEventDetails(const WebPointerEvent& event, std::string* result) {
StringAppendF(
result,
"{\n Id: %d\n Button: %d\n Pos: (%f, %f)\n"
" GlobalPos: (%f, %f)\n Movement: (%d, %d)\n width: %f\n height: "
"%f\n Pressure: %f\n TangentialPressure: %f\n Rotation: %f\n Tilt: "
"(%d, %d)\n}",
event.id, static_cast<int>(event.button), event.PositionInWidget().x(),
event.PositionInWidget().y(), event.PositionInScreen().x(),
event.PositionInScreen().y(), event.movement_x, event.movement_y,
event.width, event.height, event.force, event.tangential_pressure,
event.rotation_angle, event.tilt_x, event.tilt_y);
}
template <typename EventType>
std::string Execute(const WebInputEvent& event) {
std::string result = base::StringPrintf(
"%s (Time: %lf, Modifiers: %d)\n",
WebInputEvent::GetName(event.GetType()),
event.TimeStamp().since_origin().InSecondsF(), event.GetModifiers());
ApppendEventDetails(static_cast<const EventType&>(event), &result);
return result;
}
} // namespace
std::string WebInputEventTraits::ToString(const WebInputEvent& event) {
const WebInputEvent::Type type = event.GetType();
if (WebInputEvent::IsPointerEventType(type)) {
return Execute<WebPointerEvent>(event);
}
if (WebInputEvent::IsMouseEventType(type)) {
return Execute<WebMouseEvent>(event);
}
if (type == WebInputEvent::Type::kMouseWheel) {
return Execute<WebMouseWheelEvent>(event);
}
if (WebInputEvent::IsKeyboardEventType(type)) {
return Execute<WebKeyboardEvent>(event);
}
if (WebInputEvent::IsTouchEventType(type)) {
return Execute<WebTouchEvent>(event);
}
CHECK(WebInputEvent::IsGestureEventType(type));
return Execute<WebGestureEvent>(event);
}
bool WebInputEventTraits::ShouldBlockEventStream(const WebInputEvent& event) {
switch (event.GetType()) {
case WebInputEvent::Type::kContextMenu:
case WebInputEvent::Type::kGestureScrollEnd:
case WebInputEvent::Type::kGestureShowPress:
case WebInputEvent::Type::kGestureTapUnconfirmed:
case WebInputEvent::Type::kGestureTapDown:
case WebInputEvent::Type::kGestureTapCancel:
case WebInputEvent::Type::kGesturePinchBegin:
case WebInputEvent::Type::kGesturePinchUpdate:
case WebInputEvent::Type::kGesturePinchEnd:
return false;
case WebInputEvent::Type::kGestureScrollBegin:
return true;
// TouchCancel and TouchScrollStarted should always be non-blocking.
case WebInputEvent::Type::kTouchCancel:
case WebInputEvent::Type::kTouchScrollStarted:
DCHECK_NE(WebInputEvent::DispatchType::kBlocking,
static_cast<const WebTouchEvent&>(event).dispatch_type);
return false;
// Touch start and touch end indicate whether they are non-blocking
// (aka uncancelable) on the event.
case WebInputEvent::Type::kTouchStart:
case WebInputEvent::Type::kTouchEnd:
return static_cast<const WebTouchEvent&>(event).dispatch_type ==
WebInputEvent::DispatchType::kBlocking;
case WebInputEvent::Type::kTouchMove:
// Non-blocking touch moves can be ack'd right away.
return static_cast<const WebTouchEvent&>(event).dispatch_type ==
WebInputEvent::DispatchType::kBlocking;
case WebInputEvent::Type::kMouseWheel:
return static_cast<const WebMouseWheelEvent&>(event).dispatch_type ==
WebInputEvent::DispatchType::kBlocking;
default:
return true;
}
}
uint32_t WebInputEventTraits::GetUniqueTouchEventId(
const WebInputEvent& event) {
if (WebInputEvent::IsTouchEventType(event.GetType())) {
return static_cast<const WebTouchEvent&>(event).unique_touch_event_id;
}
return 0U;
}
// static
LatencyInfo WebInputEventTraits::CreateLatencyInfoForWebGestureEvent(
const WebGestureEvent& event) {
SourceEventType source_event_type = SourceEventType::UNKNOWN;
if (event.SourceDevice() == blink::WebGestureDevice::kTouchpad) {
source_event_type = SourceEventType::WHEEL;
if (event.GetType() >= blink::WebInputEvent::Type::kGesturePinchTypeFirst &&
event.GetType() <= blink::WebInputEvent::Type::kGesturePinchTypeLast) {
source_event_type = SourceEventType::TOUCHPAD;
}
} else if (event.SourceDevice() == blink::WebGestureDevice::kTouchscreen) {
blink::WebGestureEvent::InertialPhaseState inertial_phase_state =
blink::WebGestureEvent::InertialPhaseState::kUnknownMomentum;
switch (event.GetType()) {
case blink::WebInputEvent::Type::kGestureScrollBegin:
inertial_phase_state = event.data.scroll_begin.inertial_phase;
break;
case blink::WebInputEvent::Type::kGestureScrollUpdate:
inertial_phase_state = event.data.scroll_update.inertial_phase;
break;
case blink::WebInputEvent::Type::kGestureScrollEnd:
inertial_phase_state = event.data.scroll_end.inertial_phase;
break;
default:
break;
}
bool is_in_inertial_phase =
inertial_phase_state ==
blink::WebGestureEvent::InertialPhaseState::kMomentum;
source_event_type = is_in_inertial_phase ? SourceEventType::INERTIAL
: SourceEventType::TOUCH;
}
LatencyInfo latency_info(source_event_type);
return latency_info;
}
} // namespace ui