Bug 1442176 - 2. Add pinned-to-screen flag in GeckoSession; r=snorp r=droeh

Add a flag for whether the session should be pinned to the screen. The
app would check the flag and prevent scrolling of the session when it's
pinned.

Differential Revision: https://phabricator.services.mozilla.com/D5190
This commit is contained in:
Jim Chen 2018-09-17 17:47:21 -04:00
parent e87c3096e6
commit 1499711f6e
5 changed files with 67 additions and 1 deletions

View File

@ -49,6 +49,7 @@ class GeckoViewContent extends GeckoViewContentModule {
addEventListener("pageshow", this, options);
addEventListener("focusin", this, options);
addEventListener("focusout", this, options);
addEventListener("mozcaretstatechanged", this, options);
XPCOMUtils.defineLazyGetter(this, "_autoFill", () =>
new GeckoViewAutoFill(this.eventDispatcher));
@ -236,6 +237,7 @@ class GeckoViewContent extends GeckoViewContentModule {
}
}
// eslint-disable-next-line complexity
handleEvent(aEvent) {
debug `handleEvent: ${aEvent.type}`;
@ -336,6 +338,14 @@ class GeckoViewContent extends GeckoViewContentModule {
this._autoFill.scanDocument(aEvent.target);
}
break;
case "mozcaretstatechanged":
if (aEvent.reason === "presscaret" || aEvent.reason === "releasecaret") {
this.eventDispatcher.sendRequest({
type: "GeckoView:PinOnScreen",
pinned: aEvent.reason === "presscaret",
});
}
break;
}
}

View File

@ -475,6 +475,16 @@ public class LayerSession {
mOverscroll.setDistance(y, OverscrollEdgeEffect.AXIS_Y);
}
protected void setShouldPinOnScreen(final boolean pinned) {
if (DEBUG) {
ThreadUtils.assertOnUiThread();
}
if (mToolbar != null) {
mToolbar.setPinned(pinned, DynamicToolbarAnimator.PinReason.CARET_DRAG);
}
}
/* package */ void onMetricsChanged(final float scrollX, final float scrollY,
final float zoom) {
if (DEBUG) {

View File

@ -59,4 +59,17 @@ public class GeckoDisplay {
session.onScreenOriginChanged(left, top);
}
}
/**
* Return whether the display should be pinned on the screen. When pinned, the display
* should not be moved on the screen due to animation, scrolling, etc. A common reason
* for the display being pinned is when the user is dragging a selection caret inside
* the display; normal user interaction would be disrupted in that case if the display
* was moved on screen.
*
* @return True if display should be pinned on the screen.
*/
public boolean shouldPinOnScreen() {
return session.getDisplay() == this && session.shouldPinOnScreen();
}
}

View File

@ -101,6 +101,8 @@ public final class GeckoSession extends LayerSession
private String mId = UUID.randomUUID().toString().replace("-", "");
/* package */ String getId() { return mId; }
private boolean mShouldPinOnScreen;
/* package */ static abstract class CallbackResult<T> extends GeckoResult<T>
implements EventCallback {
@Override
@ -813,6 +815,7 @@ public final class GeckoSession extends LayerSession
private class Listener implements BundleEventListener {
/* package */ void registerListeners() {
getEventDispatcher().registerUiThreadListener(this,
"GeckoView:PinOnScreen",
"GeckoView:Prompt",
null);
}
@ -824,7 +827,9 @@ public final class GeckoSession extends LayerSession
Log.d(LOGTAG, "handleMessage: event = " + event);
}
if ("GeckoView:Prompt".equals(event)) {
if ("GeckoView:PinOnScreen".equals(event)) {
GeckoSession.this.setShouldPinOnScreen(message.getBoolean("pinned"));
} else if ("GeckoView:Prompt".equals(event)) {
handlePromptEvent(GeckoSession.this, message, callback);
}
}
@ -1992,6 +1997,17 @@ public final class GeckoSession extends LayerSession
}
}
@Override
protected void setShouldPinOnScreen(final boolean pinned) {
super.setShouldPinOnScreen(pinned);
mShouldPinOnScreen = pinned;
}
/* package */ boolean shouldPinOnScreen() {
ThreadUtils.assertOnUiThread();
return mShouldPinOnScreen;
}
public EventDispatcher getEventDispatcher() {
return mEventDispatcher;
}

View File

@ -159,6 +159,10 @@ public class GeckoView extends FrameLayout {
mDisplay.screenOriginChanged(mOrigin[0], mOrigin[1]);
}
}
public boolean shouldPinOnScreen() {
return mDisplay != null ? mDisplay.shouldPinOnScreen() : false;
}
}
public GeckoView(final Context context) {
@ -212,6 +216,19 @@ public class GeckoView extends FrameLayout {
}
}
/**
* Return whether the view should be pinned on the screen. When pinned, the view
* should not be moved on the screen due to animation, scrolling, etc. A common reason
* for the view being pinned is when the user is dragging a selection caret inside
* the view; normal user interaction would be disrupted in that case if the view
* was moved on screen.
*
* @return True if view should be pinned on the screen.
*/
public boolean shouldPinOnScreen() {
return mDisplay.shouldPinOnScreen();
}
/* package */ void setActive(final boolean active) {
if (mSession != null) {
mSession.setActive(active);