Index: content/public/android/java/src/org/chromium/content/browser/ContentViewCore.java |
diff --git a/content/public/android/java/src/org/chromium/content/browser/ContentViewCore.java b/content/public/android/java/src/org/chromium/content/browser/ContentViewCore.java |
index 3493dfef590fc0fe5740ccf545029b8efa968368..20869a81bb8731eec438eec1227f0c18f1fda800 100644 |
--- a/content/public/android/java/src/org/chromium/content/browser/ContentViewCore.java |
+++ b/content/public/android/java/src/org/chromium/content/browser/ContentViewCore.java |
@@ -360,6 +360,11 @@ public class ContentViewCore |
// ResultReceiver in the InputMethodService (IME app) gets gc'ed. |
private ShowKeyboardResultReceiver mShowKeyboardResultReceiver; |
+ // Whether this ContentViewCore has view focus. |
+ private boolean mHasViewFocus; |
+ // Whether this ContentViewCore has window focus. |
+ private boolean mHasWindowFocus; |
+ |
// The list of observers that are notified when ContentViewCore changes its WindowAndroid. |
private final ObserverList<WindowAndroidChangedObserver> mWindowAndroidChangedObservers; |
@@ -552,7 +557,7 @@ public class ContentViewCore |
InternalAccessDelegate internalDispatcher, WebContents webContents, |
WindowAndroid windowAndroid) { |
mViewAndroidDelegate = viewDelegate; |
- setContainerView(viewDelegate.getContainerView()); |
+ setContainerView(viewDelegate.getContainerView(), false); |
aelias_OOO_until_Jul13
2017/04/03 21:57:56
Could you try just moving this to the end of the c
mthiesse
2017/04/05 14:11:23
Done.
|
long windowNativePointer = windowAndroid.getNativePointer(); |
assert windowNativePointer != 0; |
@@ -580,6 +585,9 @@ public class ContentViewCore |
mShouldRequestUnbufferedDispatch = Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP |
&& ContentFeatureList.isEnabled(ContentFeatureList.REQUEST_UNBUFFERED_DISPATCH); |
+ |
+ onFocusChangedInternal(getRealWindowFocusedState(), mContainerView.hasFocus(), |
+ false /* hideKeyboardOnBlur */); |
} |
/** |
@@ -639,12 +647,12 @@ public class ContentViewCore |
} |
/** |
- * Sets a new container view for this {@link ContentViewCore}. |
+ * Replaces the container view for this {@link ContentViewCore}. This ContentViewCore must |
+ * already have been initialized. |
* |
- * <p>WARNING: This method can also be used to replace the existing container view, |
- * but you should only do it if you have a very good reason to. Replacing the |
- * container view has been designed to support fullscreen in the Webview so it |
- * might not be appropriate for other use cases. |
+ * <p>WARNING: You should only use this method if you have a very good reason to. Replacing the |
+ * container view has been designed to support fullscreen in the Webview so it might not be |
+ * appropriate for other use cases. |
* |
* <p>This method only performs a small part of replacing the container view and |
* embedders are responsible for: |
@@ -656,7 +664,15 @@ public class ContentViewCore |
* <li>etc.</li> |
* </ul> |
*/ |
- public void setContainerView(ViewGroup containerView) { |
+ public void replaceContainerView(ViewGroup containerView) { |
+ assert mContainerView != null; |
+ setContainerView(containerView, true); |
+ } |
+ |
+ /** |
+ * Sets the container view for this {@link ContentViewCore}. |
+ */ |
+ private void setContainerView(ViewGroup containerView, boolean initialized) { |
try { |
TraceEvent.begin("ContentViewCore.setContainerView"); |
if (mContainerView != null) { |
@@ -675,11 +691,28 @@ public class ContentViewCore |
if (mJoystickZoomProvider != null) { |
mJoystickZoomProvider.setContainerView(containerView); |
} |
+ if (initialized) { |
+ onFocusChangedInternal(getRealWindowFocusedState(), mContainerView.hasFocus(), |
+ false /* hideKeyboardOnBlur */); |
+ } |
} finally { |
TraceEvent.end("ContentViewCore.setContainerView"); |
} |
} |
+ /** |
+ * Note: We don't use View#hasWindowFocus() because it returns incorrect values when the View |
+ * doesn't have View focus. |
+ * @return Whether the containerView actually has Window focus. |
+ */ |
+ private boolean getRealWindowFocusedState() { |
+ int[] states = mContainerView.getDrawableState(); |
+ for (int state : states) { |
+ if ((state & android.R.attr.state_window_focused) != 0) return true; |
+ } |
+ return false; |
+ } |
+ |
@CalledByNative |
private void onNativeContentViewCoreDestroyed(long nativeContentViewCore) { |
assert nativeContentViewCore == mNativeContentViewCore; |
@@ -1327,24 +1360,44 @@ public class ContentViewCore |
/** |
* @see View#onWindowFocusChanged(boolean) |
+ * |
+ * This function must only be called after this ContentViewCore has been initialized. |
*/ |
public void onWindowFocusChanged(boolean hasWindowFocus) { |
+ if (mHasWindowFocus == hasWindowFocus) return; |
mImeAdapter.onWindowFocusChanged(hasWindowFocus); |
if (!hasWindowFocus) resetGestureDetection(); |
mSelectionPopupController.onWindowFocusChanged(hasWindowFocus); |
for (mGestureStateListenersIterator.rewind(); mGestureStateListenersIterator.hasNext();) { |
mGestureStateListenersIterator.next().onWindowFocusChanged(hasWindowFocus); |
} |
+ onFocusChangedInternal(hasWindowFocus, mHasViewFocus, true /* hideKeyboardOnBlur */); |
+ } |
+ |
+ /** |
+ * Called when the View focus for this ContentViewCore changes. |
+ * |
+ * This function must only be called after this ContentViewCore has been initialized. |
+ */ |
+ public void onFocusChanged(boolean hasViewFocus, boolean hideKeyboardOnBlur) { |
+ if (mHasViewFocus == hasViewFocus) return; |
+ mImeAdapter.onViewFocusChanged(hasViewFocus, hideKeyboardOnBlur); |
+ onFocusChangedInternal(mHasWindowFocus, hasViewFocus, hideKeyboardOnBlur); |
} |
- public void onFocusChanged(boolean gainFocus, boolean hideKeyboardOnBlur) { |
- mImeAdapter.onViewFocusChanged(gainFocus, hideKeyboardOnBlur); |
+ private void onFocusChangedInternal( |
+ boolean hasWindowFocus, boolean hasViewFocus, boolean hideKeyboardOnBlur) { |
+ boolean hadInputFocus = mHasWindowFocus && mHasViewFocus; |
+ boolean hasInputFocus = hasWindowFocus && hasViewFocus; |
+ mHasWindowFocus = hasWindowFocus; |
+ mHasViewFocus = hasViewFocus; |
+ if (hasInputFocus == hadInputFocus) return; |
if (mJoystickScrollProvider != null) { |
- mJoystickScrollProvider.setEnabled(gainFocus && !isFocusedNodeEditable()); |
+ mJoystickScrollProvider.setEnabled(hasInputFocus && !isFocusedNodeEditable()); |
} |
- if (gainFocus) { |
+ if (hasInputFocus) { |
restoreSelectionPopupsIfNecessary(); |
} else { |
cancelRequestToScrollFocusedEditableNodeIntoView(); |
@@ -1359,7 +1412,7 @@ public class ContentViewCore |
clearSelection(); |
} |
} |
- if (mNativeContentViewCore != 0) nativeSetFocus(mNativeContentViewCore, gainFocus); |
+ if (mNativeContentViewCore != 0) nativeSetFocus(mNativeContentViewCore, hasInputFocus); |
} |
/** |