Skip to content

Commit 41f73bd

Browse files
committed
Always do a HIT_TEST
Bug: 6490959 The issue here is that if the page calls preventDefault on a touchstart handler WebViewClassic will not do a HIT_TEST as it doesn't get the ACTION_DOWN. This means that the mouse is in the wrong position when the click ultimately fires. This changes it so that WebViewInputDispatcher will always do a HIT_TEST at the start of a touch stream, which ensures that the mouse is positioned correctly. Change-Id: I1aaca7692e2c7aeedeb21fa3592cd4cb3223ea25
1 parent 2411c33 commit 41f73bd

File tree

3 files changed

+27
-39
lines changed

3 files changed

+27
-39
lines changed

core/java/android/webkit/WebViewClassic.java

Lines changed: 4 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1719,6 +1719,10 @@ public void setOverScrollMode(int mode) {
17191719
mZoomManager.updateDefaultZoomDensity(density);
17201720
}
17211721

1722+
/* package */ int getScaledNavSlop() {
1723+
return viewToContentDimension(mNavSlop);
1724+
}
1725+
17221726
/* package */ boolean onSavePassword(String schemePlusHost, String username,
17231727
String password, final Message resumeMsg) {
17241728
boolean rVal = false;
@@ -4339,10 +4343,6 @@ public void onDraw(Canvas canvas) {
43394343
}
43404344

43414345
private void removeTouchHighlight() {
4342-
if (mWebViewCore != null) {
4343-
mWebViewCore.removeMessages(EventHub.HIT_TEST);
4344-
}
4345-
mPrivateHandler.removeMessages(HIT_TEST_RESULT);
43464346
setTouchHighlightRects(null);
43474347
}
43484348

@@ -5834,7 +5834,6 @@ private void handleTouchEventCommon(MotionEvent event, int action, int x, int y)
58345834
switch (action) {
58355835
case MotionEvent.ACTION_DOWN: {
58365836
mConfirmMove = false;
5837-
mInitialHitTestResult = null;
58385837
if (!mEditTextScroller.isFinished()) {
58395838
mEditTextScroller.abortAnimation();
58405839
}
@@ -5856,23 +5855,6 @@ private void handleTouchEventCommon(MotionEvent event, int action, int x, int y)
58565855
}
58575856
} else { // the normal case
58585857
mTouchMode = TOUCH_INIT_MODE;
5859-
// TODO: Have WebViewInputDispatch handle this
5860-
TouchHighlightData data = new TouchHighlightData();
5861-
data.mX = contentX;
5862-
data.mY = contentY;
5863-
data.mNativeLayerRect = new Rect();
5864-
if (mNativeClass != 0) {
5865-
data.mNativeLayer = nativeScrollableLayer(mNativeClass,
5866-
contentX, contentY, data.mNativeLayerRect, null);
5867-
} else {
5868-
data.mNativeLayer = 0;
5869-
}
5870-
data.mSlop = viewToContentDimension(mNavSlop);
5871-
removeTouchHighlight();
5872-
if (!mBlockWebkitViewMessages && mWebViewCore != null) {
5873-
mWebViewCore.sendMessageAtFrontOfQueue(
5874-
EventHub.HIT_TEST, data);
5875-
}
58765858
if (mLogEvent && eventTime - mLastTouchUpTime < 1000) {
58775859
EventLog.writeEvent(EventLogTags.BROWSER_DOUBLE_TAP_DURATION,
58785860
(eventTime - mLastTouchUpTime), eventTime);

core/java/android/webkit/WebViewCore.java

Lines changed: 9 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1143,8 +1143,6 @@ public class EventHub implements WebViewInputDispatcher.WebKitCallbacks {
11431143
static final int ADD_PACKAGE_NAME = 185;
11441144
static final int REMOVE_PACKAGE_NAME = 186;
11451145

1146-
static final int HIT_TEST = 187;
1147-
11481146
// accessibility support
11491147
static final int MODIFY_SELECTION = 190;
11501148

@@ -1648,18 +1646,6 @@ public void handleMessage(Message msg) {
16481646
(Set<String>) msg.obj);
16491647
break;
16501648

1651-
case HIT_TEST:
1652-
TouchHighlightData d = (TouchHighlightData) msg.obj;
1653-
if (d.mNativeLayer != 0) {
1654-
nativeScrollLayer(mNativeClass,
1655-
d.mNativeLayer, d.mNativeLayerRect);
1656-
}
1657-
WebKitHitTest hit = performHitTest(d.mX, d.mY, d.mSlop, true);
1658-
mWebViewClassic.mPrivateHandler.obtainMessage(
1659-
WebViewClassic.HIT_TEST_RESULT, hit)
1660-
.sendToTarget();
1661-
break;
1662-
16631649
case SET_USE_MOCK_DEVICE_ORIENTATION:
16641650
setUseMockDeviceOrientation();
16651651
break;
@@ -1788,6 +1774,15 @@ public boolean dispatchWebKitEvent(MotionEvent event, int eventType, int flags)
17881774
return false;
17891775
}
17901776
switch (eventType) {
1777+
case WebViewInputDispatcher.EVENT_TYPE_HIT_TEST:
1778+
int x = Math.round(event.getX());
1779+
int y = Math.round(event.getY());
1780+
WebKitHitTest hit = performHitTest(x, y,
1781+
mWebViewClassic.getScaledNavSlop(), true);
1782+
mWebViewClassic.mPrivateHandler.obtainMessage(
1783+
WebViewClassic.HIT_TEST_RESULT, hit).sendToTarget();
1784+
return false;
1785+
17911786
case WebViewInputDispatcher.EVENT_TYPE_CLICK:
17921787
return nativeMouseClick(mNativeClass);
17931788

core/java/android/webkit/WebViewInputDispatcher.java

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,11 @@ final class WebViewInputDispatcher {
203203
*/
204204
public static final int EVENT_TYPE_DOUBLE_TAP = 5;
205205

206+
/**
207+
* Event type: Indicates that a hit test should be performed
208+
*/
209+
public static final int EVENT_TYPE_HIT_TEST = 6;
210+
206211
/**
207212
* Flag: This event is private to this queue. Do not forward it.
208213
*/
@@ -499,13 +504,17 @@ private boolean isClickCandidateLocked(MotionEvent event) {
499504
}
500505

501506
private void enqueueDoubleTapLocked(MotionEvent event) {
502-
unscheduleClickLocked();
503-
hideTapCandidateLocked();
504507
MotionEvent eventToEnqueue = MotionEvent.obtainNoHistory(event);
505508
DispatchEvent d = obtainDispatchEventLocked(eventToEnqueue, EVENT_TYPE_DOUBLE_TAP, 0,
506509
mPostLastWebKitXOffset, mPostLastWebKitYOffset, mPostLastWebKitScale);
507510
enqueueEventLocked(d);
508-
mIsDoubleTapCandidate = false;
511+
}
512+
513+
private void enqueueHitTestLocked(MotionEvent event) {
514+
MotionEvent eventToEnqueue = MotionEvent.obtainNoHistory(event);
515+
DispatchEvent d = obtainDispatchEventLocked(eventToEnqueue, EVENT_TYPE_HIT_TEST, 0,
516+
mPostLastWebKitXOffset, mPostLastWebKitYOffset, mPostLastWebKitScale);
517+
enqueueEventLocked(d);
509518
}
510519

511520
private void checkForSlopLocked(MotionEvent event) {
@@ -545,6 +554,7 @@ private void updateStateTrackersLocked(DispatchEvent d, MotionEvent event) {
545554
mInitialDownX = event.getX();
546555
mInitialDownY = event.getY();
547556
scheduleShowTapHighlightLocked();
557+
enqueueHitTestLocked(event);
548558
} else if (action == MotionEvent.ACTION_UP) {
549559
unscheduleLongPressLocked();
550560
if (isClickCandidateLocked(event)) {
@@ -824,6 +834,7 @@ private boolean shouldSkipWebKit(int eventType) {
824834
case EVENT_TYPE_CLICK:
825835
case EVENT_TYPE_HOVER:
826836
case EVENT_TYPE_SCROLL:
837+
case EVENT_TYPE_HIT_TEST:
827838
return false;
828839
case EVENT_TYPE_TOUCH:
829840
return !mPostSendTouchEventsToWebKit

0 commit comments

Comments
 (0)