Bug 1404111 - Re-request focus after unhiding the layer view. r?jchen draft
authorJan Henning <jh+bugzilla@buttercookie.de>
Wed, 11 Oct 2017 21:50:38 +0200
changeset 678787 ab57243197ba50dffb9719ac41230b6e6f3e59e5
parent 678764 bf2a8d8452ebb7c614e087bed34cda8fc5a20056
child 735438 0009c1094dddca60ec08bf185553f7b71e3f6bab
push id84040
push usermozilla@buttercookie.de
push dateWed, 11 Oct 2017 20:42:07 +0000
reviewersjchen
bugs1404111
milestone58.0a1
Bug 1404111 - Re-request focus after unhiding the layer view. r?jchen MozReview-Commit-ID: HV1YUQOb6SK
mobile/android/base/java/org/mozilla/gecko/BrowserApp.java
--- a/mobile/android/base/java/org/mozilla/gecko/BrowserApp.java
+++ b/mobile/android/base/java/org/mozilla/gecko/BrowserApp.java
@@ -3018,16 +3018,35 @@ public class BrowserApp extends GeckoApp
     }
 
     private void hideWebContent() {
         // The view is set to INVISIBLE, rather than GONE, to avoid
         // the additional requestLayout() call.
         mLayerView.setVisibility(View.INVISIBLE);
     }
 
+    private void showWebContent() {
+        mLayerView.setVisibility(View.VISIBLE);
+        // On some devices, onViewDetachedFromWindow for the previously focused view now being hidden
+        // (e.g. the home pager powering about:home) may be called after the mLayerView has already
+        // gained focus, which can mess up the InputMethodManager's tracking of which view is allowed
+        // to interact with the IME (bug 1404111). To bring the InputMethodManager's internal state
+        // into sync again, we clear and re-set the focus during the next spin of the message loop.
+        ThreadUtils.postToUiThread(new Runnable() {
+            @Override
+            public void run() {
+                mLayerView.clearFocus();
+                // Currently, mLayerView automatically regains focus after calling clearFocus(), but
+                // we're explicitly requesting focus just to be on the safe side - if we've already
+                // got it back, then this will be a no-op anyway.
+                mLayerView.requestFocus();
+            }
+        });
+    }
+
     /**
      * Hide the Onboarding pager on user action, and don't show any onFinish hints.
      * @param method TelemetryContract method by which action was taken
      * @return boolean of whether pager was visible
      */
     private boolean hideFirstrunPager(TelemetryContract.Method method) {
         if (!isFirstrunVisible()) {
             return false;
@@ -3060,17 +3079,17 @@ public class BrowserApp extends GeckoApp
         if (!isHomePagerVisible() || AboutPages.isAboutHome(url)) {
             return;
         }
 
         // Prevent race in hiding web content - see declaration for more info.
         mHideWebContentOnAnimationEnd = false;
 
         // Display the previously hidden web content (which prevented screen reader access).
-        mLayerView.setVisibility(View.VISIBLE);
+        showWebContent();
         mHomeScreenContainer.setVisibility(View.GONE);
 
         if (mHomeScreen != null) {
             mHomeScreen.unload();
         }
 
         mBrowserToolbar.setNextFocusDownId(R.id.layer_view);