Commit caee00de authored by jdduke@chromium.org's avatar jdduke@chromium.org

Use a minimum touch size for selection handle hit testing

Certain Android devices, as well as stylus and mouse inputs, may report zero
for the touch size. These sizes are used when constructing the rect for touch
handle insersection tests.  However, gfx::RectBase will always report false when
performing the intersection test if either rect is empty.  Add an appropriate
epsilon minimum touch size when forming the touch bounding box rect.

BUG=402795

Review URL: https://codereview.chromium.org/462163002

Cr-Commit-Position: refs/heads/master@{#289501}
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@289501 0039d316-1c4b-4281-b951-d872f2087c98
parent 6d493a45
...@@ -17,11 +17,15 @@ const double kFadeDurationMs = 200; ...@@ -17,11 +17,15 @@ const double kFadeDurationMs = 200;
// when the handle is moving rapidly while the fade is active. // when the handle is moving rapidly while the fade is active.
const double kFadeDistanceSquared = 20.f * 20.f; const double kFadeDistanceSquared = 20.f * 20.f;
// Avoid using an empty touch rect, as it may fail the intersection test event
// if it lies within the other rect's bounds.
const float kMinTouchMajorForHitTesting = 1.f;
// The maximum touch size to use when computing whether a touch point is // The maximum touch size to use when computing whether a touch point is
// targetting a touch handle. This is necessary for devices that misreport // targetting a touch handle. This is necessary for devices that misreport
// touch radii, preventing inappropriately largely touch sizes from completely // touch radii, preventing inappropriately largely touch sizes from completely
// breaking handle dragging behavior. // breaking handle dragging behavior.
const float kMaxTouchMajorForHitTesting = 48.f; const float kMaxTouchMajorForHitTesting = 36.f;
} // namespace } // namespace
...@@ -120,8 +124,9 @@ bool TouchHandle::WillHandleTouchEvent(const ui::MotionEvent& event) { ...@@ -120,8 +124,9 @@ bool TouchHandle::WillHandleTouchEvent(const ui::MotionEvent& event) {
case ui::MotionEvent::ACTION_DOWN: { case ui::MotionEvent::ACTION_DOWN: {
if (!is_visible_) if (!is_visible_)
return false; return false;
const float touch_size = const float touch_size = std::max(
std::min(event.GetTouchMajor(), kMaxTouchMajorForHitTesting); kMinTouchMajorForHitTesting,
std::min(kMaxTouchMajorForHitTesting, event.GetTouchMajor()));
const gfx::RectF touch_rect(event.GetX() - touch_size * .5f, const gfx::RectF touch_rect(event.GetX() - touch_size * .5f,
event.GetY() - touch_size * .5f, event.GetY() - touch_size * .5f,
touch_size, touch_size,
......
...@@ -424,6 +424,15 @@ TEST_F(TouchHandleTest, DragTargettingUsesTouchSize) { ...@@ -424,6 +424,15 @@ TEST_F(TouchHandleTest, DragTargettingUsesTouchSize) {
event.SetTouchMajor(kTouchSize * 2.f); event.SetTouchMajor(kTouchSize * 2.f);
EXPECT_TRUE(handle.WillHandleTouchEvent(event)); EXPECT_TRUE(handle.WillHandleTouchEvent(event));
EXPECT_TRUE(IsDragging()); EXPECT_TRUE(IsDragging());
// Ensure a touch size of 0 can still register a hit.
event = MockMotionEvent(MockMotionEvent::ACTION_DOWN,
event_time,
kDefaultDrawableSize / 2.f,
kDefaultDrawableSize / 2.f);
event.SetTouchMajor(0);
EXPECT_TRUE(handle.WillHandleTouchEvent(event));
EXPECT_TRUE(IsDragging());
} }
TEST_F(TouchHandleTest, Tap) { TEST_F(TouchHandleTest, Tap) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment