Commit 3ff59f65 authored by Bo Liu's avatar Bo Liu Committed by Commit Bot

Fix input offset under browser control

Copies ContentView from components and EventOffsetHandler from chrome.
These together will call EventForwarder.setCurrentTouchEventOffsets at
the right times to correctly offset user input under browser controls

Change-Id: I29a418457c4daf2306e7ce13e8311a489b1ca958
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1796046Reviewed-by: default avatarScott Violet <sky@chromium.org>
Commit-Queue: Bo <boliu@chromium.org>
Cr-Commit-Position: refs/heads/master@{#695823}
parent a8bef4d0
......@@ -115,6 +115,11 @@ int BrowserControllerImpl::GetTopControlsHeight() {
#endif
}
bool BrowserControllerImpl::DoBrowserControlsShrinkRendererSize(
const content::WebContents* web_contents) {
return true;
}
void BrowserControllerImpl::DidFirstVisuallyNonEmptyPaint() {
for (auto& observer : observers_)
observer.FirstContentfulPaint();
......
......@@ -62,6 +62,8 @@ class BrowserControllerImpl : public BrowserController,
void DidNavigateMainFramePostCommit(
content::WebContents* web_contents) override;
int GetTopControlsHeight() override;
bool DoBrowserControlsShrinkRendererSize(
const content::WebContents* web_contents) override;
// content::WebContentsObserver implementation:
void DidFirstVisuallyNonEmptyPaint() override;
......
......@@ -9,7 +9,9 @@ android_library("java") {
java_files = [
"org/chromium/weblayer_private/BrowserControllerImpl.java",
"org/chromium/weblayer_private/BrowserObserverProxy.java",
"org/chromium/weblayer_private/ContentView.java",
"org/chromium/weblayer_private/ContentViewRenderView.java",
"org/chromium/weblayer_private/EventOffsetHandler.java",
"org/chromium/weblayer_private/NavigationControllerImpl.java",
"org/chromium/weblayer_private/NavigationImpl.java",
"org/chromium/weblayer_private/ProfileImpl.java",
......@@ -20,7 +22,6 @@ android_library("java") {
deps = [
":client_java",
"//base:base_java",
"//components/embedder_support/android:content_view_java",
"//content/public/android:content_java",
"//ui/android:ui_java",
]
......
......@@ -13,7 +13,6 @@ import android.view.ViewGroup.LayoutParams;
import android.widget.FrameLayout;
import org.chromium.base.annotations.JNINamespace;
import org.chromium.components.embedder_support.view.ContentView;
import org.chromium.content_public.browser.ViewEventSink;
import org.chromium.content_public.browser.WebContents;
import org.chromium.ui.base.ActivityWindowAndroid;
......@@ -72,8 +71,11 @@ public final class BrowserControllerImpl extends IBrowserController.Stub {
mNativeBrowserController = nativeCreateBrowserController(profile.getNativeProfile());
mWebContents = nativeGetWebContents(mNativeBrowserController);
mContentView = ContentView.createContentView(context, mWebContents);
ViewAndroidDelegate viewAndroidDelegate = new ViewAndroidDelegate(mContentViewRenderView) {
mTopControlsContainerView =
new TopControlsContainerView(context, mWebContents, mContentViewRenderView);
mContentView = ContentView.createContentView(
context, mWebContents, mTopControlsContainerView.getEventOffsetHandler());
ViewAndroidDelegate viewAndroidDelegate = new ViewAndroidDelegate(mContentView) {
@Override
public void onTopControlsChanged(int topControlsOffsetY, int topContentOffsetY) {
mTopControlsContainerView.onTopControlsChanged(
......@@ -89,8 +91,6 @@ public final class BrowserControllerImpl extends IBrowserController.Stub {
new FrameLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT,
FrameLayout.LayoutParams.UNSPECIFIED_GRAVITY));
mTopControlsContainerView =
new TopControlsContainerView(context, mWebContents, mContentViewRenderView);
nativeSetTopControlsContainerView(
mNativeBrowserController, mTopControlsContainerView.getNativeHandle());
mContentView.addView(mTopControlsContainerView,
......
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.weblayer_private;
import android.view.DragEvent;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import org.chromium.ui.base.SPenSupport;
/**
* A class to update motion event offset while dragging. This is needed to compensate the change
* caused by top control.
* TODO: Note this class is copied from src/chrome and should be shared.
*/
public class EventOffsetHandler {
/**
* A delegate for EventOffsetHandler.
*/
interface EventOffsetHandlerDelegate {
float getTop();
void setCurrentTouchEventOffsets(float top);
}
private final EventOffsetHandlerDelegate mDelegate;
public EventOffsetHandler(EventOffsetHandlerDelegate delegate) {
mDelegate = delegate;
}
/**
* Call this before handling onDispatchDragEvent.
* @param action Drag event action.
*/
public void onPreDispatchDragEvent(int action) {
setTouchEventOffsets(-mDelegate.getTop());
}
/**
* Call this after handling onDispatchDragEvent.
* @param action Drag event action.
*/
public void onPostDispatchDragEvent(int action) {
if (action == DragEvent.ACTION_DRAG_EXITED || action == DragEvent.ACTION_DRAG_ENDED
|| action == DragEvent.ACTION_DROP) {
setTouchEventOffsets(0.f);
}
}
/** See {@link ViewGroup#onInterceptTouchEvent(MotionEvent)}. */
public void onInterceptTouchEvent(MotionEvent e) {
setContentViewMotionEventOffsets(e, false);
}
/** See {@link View#onTouchEvent(MotionEvent)}. */
public void onTouchEvent(MotionEvent e) {
setContentViewMotionEventOffsets(e, true);
}
/** See {@link ViewGroup#onInterceptHoverEvent(MotionEvent)}. */
public void onInterceptHoverEvent(MotionEvent e) {
setContentViewMotionEventOffsets(e, true);
}
private void setContentViewMotionEventOffsets(MotionEvent e, boolean canClear) {
int actionMasked = SPenSupport.convertSPenEventAction(e.getActionMasked());
if (actionMasked == MotionEvent.ACTION_DOWN
|| actionMasked == MotionEvent.ACTION_HOVER_ENTER
|| actionMasked == MotionEvent.ACTION_HOVER_MOVE) {
setTouchEventOffsets(-mDelegate.getTop());
} else if (canClear
&& (actionMasked == MotionEvent.ACTION_UP
|| actionMasked == MotionEvent.ACTION_CANCEL
|| actionMasked == MotionEvent.ACTION_HOVER_EXIT)) {
setTouchEventOffsets(0.f);
}
}
private void setTouchEventOffsets(float y) {
mDelegate.setCurrentTouchEventOffsets(y);
}
}
......@@ -41,6 +41,9 @@ class TopControlsContainerView extends FrameLayout {
private View mView;
private ContentViewRenderView mContentViewRenderView;
private WebContents mWebContents;
private EventOffsetHandler mEventOffsetHandler;
private int mTopContentOffset;
// True if scrolling.
private boolean mInTopControlsScroll;
......@@ -54,6 +57,19 @@ class TopControlsContainerView extends FrameLayout {
Context context, WebContents webContents, ContentViewRenderView contentViewRenderView) {
super(context);
mContentViewRenderView = contentViewRenderView;
mWebContents = webContents;
mEventOffsetHandler =
new EventOffsetHandler(new EventOffsetHandler.EventOffsetHandlerDelegate() {
@Override
public float getTop() {
return mTopContentOffset;
}
@Override
public void setCurrentTouchEventOffsets(float top) {
mWebContents.getEventForwarder().setCurrentTouchEventOffsets(0, top);
}
});
mNativeTopControlsContainerView = nativeCreateTopControlsContainerView(
webContents, contentViewRenderView.getNativeHandle());
}
......@@ -67,6 +83,10 @@ class TopControlsContainerView extends FrameLayout {
return mNativeTopControlsContainerView;
}
public EventOffsetHandler getEventOffsetHandler() {
return mEventOffsetHandler;
}
/**
* Sets the view from the client.
*/
......@@ -105,8 +125,7 @@ class TopControlsContainerView extends FrameLayout {
return;
}
if (!mInTopControlsScroll) prepareForTopControlsScroll();
nativeSetTopControlsOffset(
mNativeTopControlsContainerView, topControlsOffsetY, topContentOffsetY);
setTopControlsOffset(topControlsOffsetY, topContentOffsetY);
}
@SuppressLint("NewApi") // Used on O+, invalidateChildInParent used for previous versions.
......@@ -172,10 +191,16 @@ class TopControlsContainerView extends FrameLayout {
private void finishTopControlsScroll(int topContentOffsetY) {
mInTopControlsScroll = false;
nativeSetTopControlsOffset(mNativeTopControlsContainerView, 0, topContentOffsetY);
setTopControlsOffset(0, topContentOffsetY);
mContentViewRenderView.postOnAnimation(() -> showTopControls());
}
private void setTopControlsOffset(int topControlsOffsetY, int topContentOffsetY) {
mTopContentOffset = topContentOffsetY;
nativeSetTopControlsOffset(
mNativeTopControlsContainerView, topControlsOffsetY, topContentOffsetY);
}
private void prepareForTopControlsScroll() {
mInTopControlsScroll = true;
mContentViewRenderView.postOnAnimation(() -> hideTopControls());
......
......@@ -24,7 +24,7 @@
android:launchMode="singleTask"
android:theme="@android:style/Theme.Holo.Light.NoActionBar"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize"
android:windowSoftInputMode="adjustResize">
android:windowSoftInputMode="stateUnspecified">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment