Bug 960146. r=kats,wesj

This commit is contained in:
Kartikaya Gupta 2014-02-20 09:36:48 -05:00
parent 5dd9b2f2bf
commit c9f3c78ff5
4 changed files with 33 additions and 66 deletions

View File

@ -887,7 +887,7 @@ public class GeckoLayerClient implements LayerView.Listener, PanZoomTarget
* You must hold the monitor while calling this.
*/
@Override
public void onSubdocumentScrollBy(float dx, float dy) {
public void scrollMarginsBy(float dx, float dy) {
ImmutableViewportMetrics newMarginsMetrics =
mMarginsAnimator.scrollBy(mViewportMetrics, dx, dy);
mViewportMetrics = mViewportMetrics.setMarginsFrom(newMarginsMetrics);

View File

@ -128,6 +128,8 @@ class JavaPanZoomController
private boolean mMediumPress;
/* Used to change the scrollY direction */
private boolean mNegateWheelScrollY;
/* Whether the current event has been default-prevented. */
private boolean mDefaultPrevented;
// Handler to be notified when overscroll occurs
private Overscroll mOverscroll;
@ -343,7 +345,9 @@ class JavaPanZoomController
return mTouchEventHandler.handleEvent(event);
}
boolean handleEvent(MotionEvent event) {
boolean handleEvent(MotionEvent event, boolean defaultPrevented) {
mDefaultPrevented = defaultPrevented;
switch (event.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN: return handleTouchStart(event);
case MotionEvent.ACTION_MOVE: return handleTouchMove(event);
@ -401,17 +405,6 @@ class JavaPanZoomController
}
}
/** This function must be called on the UI thread. */
public void preventedTouchFinished() {
checkMainThread();
if (mState == PanZoomState.WAITING_LISTENERS) {
// if we enter here, we just finished a block of events whose default actions
// were prevented by touch listeners. Now there are no touch points left, so
// we need to reset our state and re-bounce because we might be in overscroll
bounce();
}
}
/** This must be called on the UI thread. */
@Override
public void pageRectUpdated() {
@ -524,16 +517,18 @@ class JavaPanZoomController
case FLING:
case AUTONAV:
case BOUNCE:
case WAITING_LISTENERS:
// should never happen
Log.e(LOGTAG, "Received impossible touch end while in " + mState);
// fall through
case ANIMATED_ZOOM:
case NOTHING:
// may happen if user double-taps and drags without lifting after the
// second tap. ignore if this happens.
return false;
case WAITING_LISTENERS:
if (!mDefaultPrevented) {
// should never happen
Log.e(LOGTAG, "Received impossible touch end while in " + mState);
}
// fall through
case TOUCHING:
// the switch into TOUCHING might have happened while the page was
// snapping back after overscroll. we need to finish the snap if that
@ -562,16 +557,6 @@ class JavaPanZoomController
private boolean handleTouchCancel(MotionEvent event) {
cancelTouch();
if (mState == PanZoomState.WAITING_LISTENERS) {
// we might get a cancel event from the TouchEventHandler while in the
// WAITING_LISTENERS state if the touch listeners prevent-default the
// block of events. at this point being in WAITING_LISTENERS is equivalent
// to being in NOTHING with the exception of possibly being in overscroll.
// so here we don't want to do anything right now; the overscroll will be
// corrected in preventedTouchFinished().
return false;
}
// ensure we snap back if we're overscrolled
bounce();
return false;
@ -827,9 +812,9 @@ class JavaPanZoomController
if (FloatUtils.fuzzyEquals(displacement.x, 0.0f) && FloatUtils.fuzzyEquals(displacement.y, 0.0f)) {
return;
}
if (mSubscroller.scrollBy(displacement)) {
if (mDefaultPrevented || mSubscroller.scrollBy(displacement)) {
synchronized (mTarget.getLock()) {
mTarget.onSubdocumentScrollBy(displacement.x, displacement.y);
mTarget.scrollMarginsBy(displacement.x, displacement.y);
}
} else {
synchronized (mTarget.getLock()) {

View File

@ -19,7 +19,7 @@ public interface PanZoomTarget {
public void setAnimationTarget(ImmutableViewportMetrics viewport);
public void setViewportMetrics(ImmutableViewportMetrics viewport);
public void scrollBy(float dx, float dy);
public void onSubdocumentScrollBy(float dx, float dy);
public void scrollMarginsBy(float dx, float dy);
public void panZoomStopped();
/** This triggers an (asynchronous) viewport update/redraw. */
public void forceRedraw(DisplayPortMetrics displayPort);

View File

@ -74,11 +74,11 @@ final class TouchEventHandler implements Tabs.OnTabsChangedListener {
// default-prevented or not (or we time out waiting for that).
private boolean mHoldInQueue;
// true if we should dispatch incoming events to the gesture detector and the pan/zoom
// controller. if this is false, then the current block of events has been
// default-prevented, and we should not dispatch these events (although we'll still send
// them to gecko listeners).
private boolean mDispatchEvents;
// false if the current event block has been default-prevented. In this case,
// we still pass the event to both Gecko and the pan/zoom controller, but the
// latter will not use it to scroll content. It may still use the events for
// other things, such as making the dynamic toolbar visible.
private boolean mAllowDefaultAction;
// this next variable requires some explanation. strap yourself in.
//
@ -128,7 +128,7 @@ final class TouchEventHandler implements Tabs.OnTabsChangedListener {
mGestureDetector = new GestureDetector(context, mPanZoomController);
mScaleGestureDetector = new SimpleScaleGestureDetector(mPanZoomController);
mListenerTimeoutProcessor = new ListenerTimeoutProcessor();
mDispatchEvents = true;
mAllowDefaultAction = true;
mGestureDetector.setOnDoubleTapListener(mPanZoomController);
@ -145,10 +145,10 @@ final class TouchEventHandler implements Tabs.OnTabsChangedListener {
// this is the start of a new block of events! whee!
mHoldInQueue = mWaitForTouchListeners;
// Set mDispatchEvents to true so that we are guaranteed to either queue these
// events or dispatch them. The only time we should not do either is once we've
// heard back from content to preventDefault this block.
mDispatchEvents = true;
// Set mAllowDefaultAction to true so that in the event we dispatch events, the
// PanZoomController doesn't treat them as if they've been prevent-defaulted
// when they haven't.
mAllowDefaultAction = true;
if (mHoldInQueue) {
// if the new block we are starting is the current block (i.e. there are no
// other blocks waiting in the queue, then we should let the pan/zoom controller
@ -170,17 +170,12 @@ final class TouchEventHandler implements Tabs.OnTabsChangedListener {
mView.postDelayed(mListenerTimeoutProcessor, EVENT_LISTENER_TIMEOUT);
}
// if we need to hold the events, add it to the queue. if we need to dispatch
// it directly, do that. it is possible that both mHoldInQueue and mDispatchEvents
// are false, in which case we are processing a block of events that we know
// has been default-prevented. in that case we don't keep the events as we don't
// need them (but we still pass them to the gecko listener).
// if we need to hold the events, add it to the queue, otherwise dispatch
// it directly.
if (mHoldInQueue) {
mEventQueue.add(MotionEvent.obtain(event));
} else if (mDispatchEvents) {
dispatchEvent(event);
} else if (touchFinished(event)) {
mPanZoomController.preventedTouchFinished();
} else {
dispatchEvent(event, mAllowDefaultAction);
}
return false;
@ -224,7 +219,7 @@ final class TouchEventHandler implements Tabs.OnTabsChangedListener {
/**
* Dispatch the event to the gesture detectors and the pan/zoom controller.
*/
private void dispatchEvent(MotionEvent event) {
private void dispatchEvent(MotionEvent event, boolean allowDefaultAction) {
if (mGestureDetector.onTouchEvent(event)) {
return;
}
@ -232,7 +227,7 @@ final class TouchEventHandler implements Tabs.OnTabsChangedListener {
if (mScaleGestureDetector.isInProgress()) {
return;
}
mPanZoomController.handleEvent(event);
mPanZoomController.handleEvent(event, !allowDefaultAction);
}
/**
@ -240,13 +235,6 @@ final class TouchEventHandler implements Tabs.OnTabsChangedListener {
* whether it has been default-prevented or not.
*/
private void processEventBlock(boolean allowDefaultAction) {
if (!allowDefaultAction) {
// if the block has been default-prevented, cancel whatever stuff we had in
// progress in the gesture detector and pan zoom controller
long now = SystemClock.uptimeMillis();
dispatchEvent(MotionEvent.obtain(now, now, MotionEvent.ACTION_CANCEL, 0, 0, 0));
}
if (mEventQueue.isEmpty()) {
Log.e(LOGTAG, "Unexpected empty event queue in processEventBlock!", new Exception());
return;
@ -263,13 +251,7 @@ final class TouchEventHandler implements Tabs.OnTabsChangedListener {
// that has already been dispatched.
if (event != null) {
// for each event we process, only dispatch it if the block hasn't been
// default-prevented.
if (allowDefaultAction) {
dispatchEvent(event);
} else if (touchFinished(event)) {
mPanZoomController.preventedTouchFinished();
}
dispatchEvent(event, allowDefaultAction);
}
if (mEventQueue.isEmpty()) {
// we have processed the backlog of events, and are all caught up.
@ -278,7 +260,7 @@ final class TouchEventHandler implements Tabs.OnTabsChangedListener {
// remaining events in this block (which is still ongoing) without
// having to put them in the queue.
mHoldInQueue = false;
mDispatchEvents = allowDefaultAction;
mAllowDefaultAction = allowDefaultAction;
break;
}
event = mEventQueue.peek();