Bug 1225936 - Support scroll events in APZ on Fennec r=kats,jchen

This commit is contained in:
Randall Barker 2016-02-11 16:34:58 -08:00
parent cb722f4d52
commit 0b32350888
5 changed files with 145 additions and 2 deletions

View File

@ -5,8 +5,10 @@
package org.mozilla.gecko.gfx;
import org.mozilla.gecko.GeckoAppShell;
import org.mozilla.gecko.GeckoEvent;
import org.mozilla.gecko.GeckoThread;
import org.mozilla.gecko.PrefsHelper;
import org.mozilla.gecko.annotation.WrapForJNI;
import org.mozilla.gecko.mozglue.JNIObject;
import org.mozilla.gecko.util.ThreadUtils;
@ -14,6 +16,7 @@ import org.mozilla.gecko.util.ThreadUtils;
import org.json.JSONObject;
import android.graphics.PointF;
import android.util.TypedValue;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
@ -23,6 +26,10 @@ class NativePanZoomController extends JNIObject implements PanZoomController {
private final LayerView mView;
private boolean mDestroyed;
private Overscroll mOverscroll;
boolean mNegateWheelScroll;
private float mPointerScrollFactor;
private final PrefsHelper.PrefHandler mPrefsObserver;
private static final float MAX_SCROLL = 0.075f * GeckoAppShell.getDpi();
@WrapForJNI
private native boolean handleMotionEvent(
@ -30,6 +37,12 @@ class NativePanZoomController extends JNIObject implements PanZoomController {
int pointerId[], float x[], float y[], float orientation[], float pressure[],
float toolMajor[], float toolMinor[]);
@WrapForJNI
private native boolean handleScrollEvent(
long time, int metaState,
float x, float y,
float hScroll, float vScroll);
private boolean handleMotionEvent(MotionEvent event, boolean keepInViewCoordinates) {
if (mDestroyed) {
return false;
@ -78,9 +91,50 @@ class NativePanZoomController extends JNIObject implements PanZoomController {
toolMajor, toolMinor);
}
private boolean handleScrollEvent(MotionEvent event) {
if (mDestroyed) {
return false;
}
final int count = event.getPointerCount();
if (count <= 0) {
return false;
}
final MotionEvent.PointerCoords coords = new MotionEvent.PointerCoords();
event.getPointerCoords(0, coords);
final float x = coords.x;
final float y = coords.y;
final float flipFactor = mNegateWheelScroll ? -1.0f : 1.0f;
final float hScroll = event.getAxisValue(MotionEvent.AXIS_HSCROLL) * flipFactor * mPointerScrollFactor;
final float vScroll = event.getAxisValue(MotionEvent.AXIS_VSCROLL) * flipFactor * mPointerScrollFactor;
return handleScrollEvent(event.getEventTime(), event.getMetaState(), x, y, hScroll, vScroll);
}
NativePanZoomController(PanZoomTarget target, View view) {
mTarget = target;
mView = (LayerView) view;
String[] prefs = { "ui.scrolling.negate_wheel_scroll" };
mPrefsObserver = new PrefsHelper.PrefHandlerBase() {
@Override public void prefValue(String pref, boolean value) {
if (pref.equals("ui.scrolling.negate_wheel_scroll")) {
mNegateWheelScroll = value;
}
}
};
PrefsHelper.addObserver(prefs, mPrefsObserver);
TypedValue outValue = new TypedValue();
if (view.getContext().getTheme().resolveAttribute(android.R.attr.listPreferredItemHeight, outValue, true)) {
mPointerScrollFactor = outValue.getDimension(view.getContext().getResources().getDisplayMetrics());
} else {
mPointerScrollFactor = MAX_SCROLL;
}
}
@Override
@ -90,8 +144,12 @@ class NativePanZoomController extends JNIObject implements PanZoomController {
@Override
public boolean onMotionEvent(MotionEvent event) {
// FIXME implement this
return false;
final int action = event.getActionMasked();
if (action == MotionEvent.ACTION_SCROLL) {
return handleScrollEvent(event);
} else {
return false;
}
}
@Override

View File

@ -298,6 +298,10 @@ public:
mozilla::jni::NativeStub<NativePanZoomController::HandleMotionEvent_t, Impl>
::template Wrap<&Impl::HandleMotionEvent>),
mozilla::jni::MakeNativeMethod<NativePanZoomController::HandleScrollEvent_t>(
mozilla::jni::NativeStub<NativePanZoomController::HandleScrollEvent_t, Impl>
::template Wrap<&Impl::HandleScrollEvent>),
mozilla::jni::MakeNativeMethod<NativePanZoomController::AbortAnimation_t>(
mozilla::jni::NativeStub<NativePanZoomController::AbortAnimation_t, Impl>
::template Wrap<&Impl::AbortAnimation>),

View File

@ -1517,6 +1517,9 @@ constexpr char NativePanZoomController::DisposeNative_t::signature[];
constexpr char NativePanZoomController::HandleMotionEvent_t::name[];
constexpr char NativePanZoomController::HandleMotionEvent_t::signature[];
constexpr char NativePanZoomController::HandleScrollEvent_t::name[];
constexpr char NativePanZoomController::HandleScrollEvent_t::signature[];
constexpr char NativePanZoomController::AbortAnimation_t::name[];
constexpr char NativePanZoomController::AbortAnimation_t::signature[];

View File

@ -3588,6 +3588,25 @@ public:
mozilla::jni::ExceptionMode::ABORT;
};
struct HandleScrollEvent_t {
typedef NativePanZoomController Owner;
typedef bool ReturnType;
typedef bool SetterType;
typedef mozilla::jni::Args<
int64_t,
int32_t,
float,
float,
float,
float> Args;
static constexpr char name[] = "handleScrollEvent";
static constexpr char signature[] =
"(JIFFFF)Z";
static const bool isStatic = false;
static const mozilla::jni::ExceptionMode exceptionMode =
mozilla::jni::ExceptionMode::ABORT;
};
struct AbortAnimation_t {
typedef NativePanZoomController Owner;
typedef void ReturnType;

View File

@ -521,6 +521,65 @@ public:
APZCTreeManager::SetLongTapEnabled(aIsLongpressEnabled);
}
bool HandleScrollEvent(int64_t aTime, int32_t aMetaState,
float aX, float aY,
float aHScroll, float aVScroll)
{
MOZ_ASSERT(AndroidBridge::IsJavaUiThread());
MutexAutoLock lock(mWindowLock);
if (!mWindow) {
// We already shut down.
return false;
}
RefPtr<APZCTreeManager> controller = mWindow->mAPZC;
if (!controller) {
return false;
}
ScreenIntPoint offset = ViewAs<ScreenPixel>(mWindow->WidgetToScreenOffset(), PixelCastJustification::LayoutDeviceIsScreenForBounds);
ScreenPoint origin = ScreenPoint(aX, aY) - offset;
ScrollWheelInput input(aTime, TimeStamp(), GetModifiers(aMetaState),
ScrollWheelInput::SCROLLMODE_SMOOTH,
ScrollWheelInput::SCROLLDELTA_PIXEL,
origin,
aHScroll, aVScroll,
false);
ScrollableLayerGuid guid;
uint64_t blockId;
nsEventStatus status = controller->ReceiveInputEvent(input, &guid, &blockId);
if (status == nsEventStatus_eConsumeNoDefault) {
return true;
}
NativePanZoomController::GlobalRef npzc = mNPZC;
nsAppShell::PostEvent([npzc, input, guid, blockId, status] {
MOZ_ASSERT(NS_IsMainThread());
JNIEnv* const env = jni::GetGeckoThreadEnv();
NPZCSupport* npzcSupport = GetNative(
NativePanZoomController::LocalRef(env, npzc));
if (!npzcSupport || !npzcSupport->mWindow) {
// We already shut down.
env->ExceptionClear();
return;
}
nsWindow* const window = npzcSupport->mWindow;
window->UserActivity();
WidgetWheelEvent wheelEvent = input.ToWidgetWheelEvent(window);
window->ProcessUntransformedAPZEvent(&wheelEvent, guid,
blockId, status);
});
return true;
}
bool HandleMotionEvent(const NativePanZoomController::LocalRef& aInstance,
int32_t aAction, int32_t aActionIndex,
int64_t aTime, int32_t aMetaState,