Skip to content

Commit 84fa241

Browse files
committed
Fix tap highlight annoyingness
Bug: 6108346 Highlight now correctly doesn't show up unless it is a click, and no longer has any weirdness with sticking around unusually long Change-Id: I06f6eae45d970085232466f17cbbd9ebaefc4d69
1 parent f7ee988 commit 84fa241

File tree

2 files changed

+94
-18
lines changed

2 files changed

+94
-18
lines changed

core/java/android/webkit/WebViewClassic.java

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -935,7 +935,7 @@ public void onTrimMemory(int level) {
935935
private Paint mTouchCrossHairColor;
936936
private int mTouchHighlightX;
937937
private int mTouchHighlightY;
938-
private long mTouchHighlightRequested;
938+
private boolean mShowTapHighlight;
939939

940940
// Basically this proxy is used to tell the Video to update layer tree at
941941
// SetBaseLayer time and to pause when WebView paused.
@@ -5828,7 +5828,6 @@ private void handleTouchEventCommon(MotionEvent event, int action, int x, int y)
58285828
data.mSlop = viewToContentDimension(mNavSlop);
58295829
removeTouchHighlight();
58305830
if (!mBlockWebkitViewMessages) {
5831-
mTouchHighlightRequested = SystemClock.uptimeMillis();
58325831
mWebViewCore.sendMessageAtFrontOfQueue(
58335832
EventHub.HIT_TEST, data);
58345833
}
@@ -7647,6 +7646,14 @@ public boolean shouldInterceptTouchEvent(MotionEvent event) {
76477646
}
76487647
return isPressingHandle;
76497648
}
7649+
7650+
@Override
7651+
public void showTapHighlight(boolean show) {
7652+
if (mShowTapHighlight != show) {
7653+
mShowTapHighlight = show;
7654+
invalidate();
7655+
}
7656+
}
76507657
}
76517658

76527659
private void setHitTestTypeFromUrl(String url) {
@@ -7709,16 +7716,7 @@ private boolean shouldDrawHighlightRect() {
77097716
if (mFocusedNode.mHasFocus && mFocusedNode.mEditable) {
77107717
return false;
77117718
}
7712-
long delay = SystemClock.uptimeMillis() - mTouchHighlightRequested;
7713-
if (delay < ViewConfiguration.getTapTimeout()) {
7714-
Rect r = mTouchHighlightRegion.getBounds();
7715-
mWebView.postInvalidateDelayed(delay, r.left, r.top, r.right, r.bottom);
7716-
return false;
7717-
}
7718-
if (mInputDispatcher == null) {
7719-
return false;
7720-
}
7721-
return mInputDispatcher.shouldShowTapHighlight();
7719+
return mShowTapHighlight;
77227720
}
77237721

77247722

core/java/android/webkit/WebViewInputDispatcher.java

Lines changed: 84 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,8 @@ final class WebViewInputDispatcher {
9999
private boolean mPostDoNotSendTouchEventsToWebKitUntilNextGesture;
100100
private boolean mPostLongPressScheduled;
101101
private boolean mPostClickScheduled;
102+
private boolean mPostShowTapHighlightScheduled;
103+
private boolean mPostHideTapHighlightScheduled;
102104
private int mPostLastWebKitXOffset;
103105
private int mPostLastWebKitYOffset;
104106
private float mPostLastWebKitScale;
@@ -133,6 +135,7 @@ final class WebViewInputDispatcher {
133135
private static final int LONG_PRESS_TIMEOUT =
134136
ViewConfiguration.getLongPressTimeout() + TAP_TIMEOUT;
135137
private static final int DOUBLE_TAP_TIMEOUT = ViewConfiguration.getDoubleTapTimeout();
138+
private static final int PRESSED_STATE_DURATION = ViewConfiguration.getPressedStateDuration();
136139

137140
/**
138141
* Event type: Indicates a touch event type.
@@ -310,6 +313,7 @@ public boolean postPointerEvent(MotionEvent event,
310313
}
311314
unscheduleLongPressLocked();
312315
unscheduleClickLocked();
316+
hideTapCandidateLocked();
313317
return false;
314318
}
315319

@@ -349,12 +353,6 @@ private void unscheduleLongPressLocked() {
349353
}
350354
}
351355

352-
public boolean shouldShowTapHighlight() {
353-
synchronized (mLock) {
354-
return mPostLongPressScheduled || mPostClickScheduled;
355-
}
356-
}
357-
358356
private void postLongPress() {
359357
synchronized (mLock) {
360358
if (!mPostLongPressScheduled) {
@@ -385,6 +383,64 @@ private void postLongPress() {
385383
}
386384
}
387385

386+
private void hideTapCandidateLocked() {
387+
unscheduleHideTapHighlightLocked();
388+
unscheduleShowTapHighlightLocked();
389+
mUiCallbacks.showTapHighlight(false);
390+
}
391+
392+
private void showTapCandidateLocked() {
393+
unscheduleHideTapHighlightLocked();
394+
unscheduleShowTapHighlightLocked();
395+
mUiCallbacks.showTapHighlight(true);
396+
scheduleHideTapHighlightLocked();
397+
}
398+
399+
private void scheduleShowTapHighlightLocked() {
400+
unscheduleShowTapHighlightLocked();
401+
mPostShowTapHighlightScheduled = true;
402+
mUiHandler.sendEmptyMessageDelayed(UiHandler.MSG_SHOW_TAP_HIGHLIGHT,
403+
TAP_TIMEOUT);
404+
}
405+
406+
private void unscheduleShowTapHighlightLocked() {
407+
if (mPostShowTapHighlightScheduled) {
408+
mPostShowTapHighlightScheduled = false;
409+
mUiHandler.removeMessages(UiHandler.MSG_SHOW_TAP_HIGHLIGHT);
410+
}
411+
}
412+
413+
private void scheduleHideTapHighlightLocked() {
414+
unscheduleHideTapHighlightLocked();
415+
mPostHideTapHighlightScheduled = true;
416+
mUiHandler.sendEmptyMessageDelayed(UiHandler.MSG_HIDE_TAP_HIGHLIGHT,
417+
PRESSED_STATE_DURATION);
418+
}
419+
420+
private void unscheduleHideTapHighlightLocked() {
421+
if (mPostHideTapHighlightScheduled) {
422+
mPostHideTapHighlightScheduled = false;
423+
mUiHandler.removeMessages(UiHandler.MSG_HIDE_TAP_HIGHLIGHT);
424+
}
425+
}
426+
427+
private void postShowTapHighlight(boolean show) {
428+
synchronized (mLock) {
429+
if (show) {
430+
if (!mPostShowTapHighlightScheduled) {
431+
return;
432+
}
433+
mPostShowTapHighlightScheduled = false;
434+
} else {
435+
if (!mPostHideTapHighlightScheduled) {
436+
return;
437+
}
438+
mPostHideTapHighlightScheduled = false;
439+
}
440+
mUiCallbacks.showTapHighlight(show);
441+
}
442+
}
443+
388444
private void scheduleClickLocked() {
389445
unscheduleClickLocked();
390446
mPostClickScheduled = true;
@@ -404,6 +460,7 @@ private void postClick() {
404460
return;
405461
}
406462
mPostClickScheduled = false;
463+
showTapCandidateLocked();
407464

408465
MotionEvent event = mPostTouchStream.getLastEvent();
409466
if (event == null || event.getAction() != MotionEvent.ACTION_UP) {
@@ -442,6 +499,7 @@ private boolean isClickCandidateLocked(MotionEvent event) {
442499

443500
private void enqueueDoubleTapLocked(MotionEvent event) {
444501
unscheduleClickLocked();
502+
hideTapCandidateLocked();
445503
MotionEvent eventToEnqueue = MotionEvent.obtainNoHistory(event);
446504
DispatchEvent d = obtainDispatchEventLocked(eventToEnqueue, EVENT_TYPE_DOUBLE_TAP, 0,
447505
mPostLastWebKitXOffset, mPostLastWebKitYOffset, mPostLastWebKitScale);
@@ -458,6 +516,7 @@ private void checkForSlopLocked(MotionEvent event) {
458516
if ((deltaX * deltaX + deltaY * deltaY) > mTouchSlopSquared) {
459517
unscheduleLongPressLocked();
460518
mIsTapCandidate = false;
519+
hideTapCandidateLocked();
461520
}
462521
}
463522

@@ -474,14 +533,17 @@ private void updateStateTrackersLocked(DispatchEvent d, MotionEvent event) {
474533
|| event.getPointerCount() > 1) {
475534
unscheduleLongPressLocked();
476535
unscheduleClickLocked();
536+
hideTapCandidateLocked();
477537
mIsDoubleTapCandidate = false;
478538
mIsTapCandidate = false;
539+
hideTapCandidateLocked();
479540
} else if (action == MotionEvent.ACTION_DOWN) {
480541
checkForDoubleTapOnDownLocked(event);
481542
scheduleLongPressLocked();
482543
mIsTapCandidate = true;
483544
mInitialDownX = event.getX();
484545
mInitialDownY = event.getY();
546+
scheduleShowTapHighlightLocked();
485547
} else if (action == MotionEvent.ACTION_UP) {
486548
unscheduleLongPressLocked();
487549
if (isClickCandidateLocked(event)) {
@@ -490,6 +552,8 @@ private void updateStateTrackersLocked(DispatchEvent d, MotionEvent event) {
490552
} else {
491553
scheduleClickLocked();
492554
}
555+
} else {
556+
hideTapCandidateLocked();
493557
}
494558
} else if (action == MotionEvent.ACTION_MOVE) {
495559
checkForSlopLocked(event);
@@ -959,6 +1023,12 @@ public static interface UiCallbacks {
9591023
* through webkit or false otherwise.
9601024
*/
9611025
public boolean shouldInterceptTouchEvent(MotionEvent event);
1026+
1027+
/**
1028+
* Inform's the UI that it should show the tap highlight
1029+
* @param show True if it should show the highlight, false if it should hide it
1030+
*/
1031+
public void showTapHighlight(boolean show);
9621032
}
9631033

9641034
/* Implemented by {@link WebViewCore} to perform operations on the web kit thread. */
@@ -985,6 +1055,8 @@ private final class UiHandler extends Handler {
9851055
public static final int MSG_WEBKIT_TIMEOUT = 2;
9861056
public static final int MSG_LONG_PRESS = 3;
9871057
public static final int MSG_CLICK = 4;
1058+
public static final int MSG_SHOW_TAP_HIGHLIGHT = 5;
1059+
public static final int MSG_HIDE_TAP_HIGHLIGHT = 6;
9881060

9891061
public UiHandler(Looper looper) {
9901062
super(looper);
@@ -1005,6 +1077,12 @@ public void handleMessage(Message msg) {
10051077
case MSG_CLICK:
10061078
postClick();
10071079
break;
1080+
case MSG_SHOW_TAP_HIGHLIGHT:
1081+
postShowTapHighlight(true);
1082+
break;
1083+
case MSG_HIDE_TAP_HIGHLIGHT:
1084+
postShowTapHighlight(false);
1085+
break;
10081086
default:
10091087
throw new IllegalStateException("Unknown message type: " + msg.what);
10101088
}

0 commit comments

Comments
 (0)