Bug 895828: Unfocus the URL bar when the soft keyboard is hidden. r=lucasr
authorMichael Comella <michael.l.comella@gmail.com>
Fri, 26 Jul 2013 11:15:10 -0700
changeset 151442 6c4b716fe1898ff347380dbe935754f8d6bae6cc
parent 151441 962211a2b765b4306a65c44d22df6a30283a8c7f
child 151443 ef686945229b4ce2c3560d266bd29a39e975761a
push idunknown
push userunknown
push dateunknown
reviewerslucasr
bugs895828
milestone25.0a1
Bug 895828: Unfocus the URL bar when the soft keyboard is hidden. r=lucasr
mobile/android/base/BrowserToolbar.java
mobile/android/base/home/HomeListView.java
mobile/android/base/home/HomePager.java
--- a/mobile/android/base/BrowserToolbar.java
+++ b/mobile/android/base/BrowserToolbar.java
@@ -139,16 +139,17 @@ public class BrowserToolbar extends Geck
     private boolean mShowReader;
 
     private boolean mDelayRestartInput;
     // The previous autocomplete result returned to us
     private String mAutoCompleteResult = "";
     // The user typed part of the autocomplete result
     private String mAutoCompletePrefix = null;
 
+    private boolean mIsEditing;
     private boolean mAnimatingEntry;
 
     private AlphaAnimation mLockFadeIn;
     private TranslateAnimation mTitleSlideLeft;
     private TranslateAnimation mTitleSlideRight;
 
     private int mUrlBarViewOffset;
     private int mDefaultForwardMargin;
@@ -182,16 +183,17 @@ public class BrowserToolbar extends Geck
         mActivity = (BrowserApp) context;
 
         // Inflate the content.
         LayoutInflater.from(context).inflate(R.layout.browser_toolbar, this);
 
         Tabs.registerOnTabsChangedListener(this);
         mSwitchingTabs = true;
 
+        mIsEditing = false;
         mAnimatingEntry = false;
         mShowUrl = false;
 
         // listen to the title bar pref.
         mPrefObserverId = PrefsHelper.getPref(PREF_TITLEBAR_MODE, new PrefsHelper.PrefHandlerBase() {
             @Override
             public void prefValue(String pref, String str) {
                 int value = Integer.parseInt(str);
@@ -352,16 +354,21 @@ public class BrowserToolbar extends Geck
                     if (!hasCompositionString(content)) {
                         if (mCommitListener != null) {
                             mCommitListener.onCommit();
                         }
                         return true;
                     }
                 }
 
+                if (keyCode == KeyEvent.KEYCODE_BACK) {
+                    clearFocus();
+                    return true;
+                }
+
                 return false;
             }
         });
 
         mUrlEditText.setOnKeyListener(new View.OnKeyListener() {
             @Override
             public boolean onKey(View v, int keyCode, KeyEvent event) {
                 if (keyCode == KeyEvent.KEYCODE_ENTER || GamepadUtils.isActionKey(event)) {
@@ -381,17 +388,22 @@ public class BrowserToolbar extends Geck
 
                 return false;
             }
         });
 
         mUrlEditText.setOnFocusChangeListener(new View.OnFocusChangeListener() {
             @Override
             public void onFocusChange(View v, boolean hasFocus) {
-                if (v == null || hasFocus) {
+                if (v == null) {
+                    return;
+                }
+
+                setSelected(hasFocus);
+                if (hasFocus) {
                     return;
                 }
 
                 InputMethodManager imm = (InputMethodManager) mActivity.getSystemService(Context.INPUT_METHOD_SERVICE);
                 try {
                     imm.hideSoftInputFromWindow(v.getWindowToken(), 0);
                 } catch (NullPointerException e) {
                     Log.e(LOGTAG, "InputMethodManagerService, why are you throwing"
@@ -1243,41 +1255,45 @@ public class BrowserToolbar extends Geck
                 if (showEditContainer) {
                     ViewHelper.setAlpha(mGo, 1.0f);
                     showSoftInput();
                 }
             }
         });
     }
 
+    /**
+     * Returns whether or not the URL bar is in editing mode (url bar is expanded, hiding the new
+     * tab button). Note that selection state is independent of editing mode.
+     */
     public boolean isEditing() {
-        return isSelected();
+        return mIsEditing;
     }
 
     public void startEditing(String url, PropertyAnimator animator) {
         if (isEditing()) {
             return;
         }
 
         mUrlEditText.setText(url != null ? url : "");
+        mIsEditing = true;
 
         // This animation doesn't make much sense in a sidebar UI
         if (HardwareUtils.isTablet()) {
-            setSelected(true);
             showUrlEditContainer();
             return;
         }
 
         if (mAnimatingEntry)
             return;
 
         final int entryTranslation = getUrlBarEntryTranslation();
         final int curveTranslation = getUrlBarCurveTranslation();
 
-        // Keep the entry highlighted during the animation
+        // Highlight the toolbar from the start of the animation.
         setSelected(true);
 
         // Hide page actions/stop buttons immediately
         ViewHelper.setAlpha(mPageActionLayout, 0);
         ViewHelper.setAlpha(mStop, 0);
 
         // Slide the right side elements of the toolbar
 
@@ -1345,19 +1361,19 @@ public class BrowserToolbar extends Geck
         return url;
     }
 
     private String stopEditing() {
         final String url = mUrlEditText.getText().toString();
         if (!isEditing()) {
             return url;
         }
+        mIsEditing = false;
 
         if (HardwareUtils.isTablet()) {
-            setSelected(false);
             hideUrlEditContainer();
             updateTabCountAndAnimate(Tabs.getInstance().getDisplayCount());
             return url;
         }
 
         final PropertyAnimator contentAnimator = new PropertyAnimator(250);
         contentAnimator.setUseHardwareLayer(false);
 
@@ -1393,18 +1409,16 @@ public class BrowserToolbar extends Geck
 
         contentAnimator.addPropertyAnimationListener(new PropertyAnimator.PropertyAnimationListener() {
             @Override
             public void onPropertyAnimationStart() {
             }
 
             @Override
             public void onPropertyAnimationEnd() {
-                // Turn off selected state on the entry
-                setSelected(false);
                 setShadowVisibility(true);
 
                 PropertyAnimator buttonsAnimator = new PropertyAnimator(300);
 
                 // Fade toolbar buttons (page actions, stop) after the entry
                 // is schrunk back to its original size.
                 buttonsAnimator.attach(mPageActionLayout,
                                        PropertyAnimator.Property.ALPHA,
--- a/mobile/android/base/home/HomeListView.java
+++ b/mobile/android/base/home/HomeListView.java
@@ -51,26 +51,16 @@ public class HomeListView extends ListVi
     @Override
     public void onDetachedFromWindow() {
         super.onDetachedFromWindow();
 
         mUrlOpenListener = null;
     }
 
     @Override
-    public boolean onInterceptTouchEvent(MotionEvent event) {
-        if (event.getActionMasked() == MotionEvent.ACTION_DOWN) {
-            // take focus away from awesome bar to hide the keyboard
-            requestFocus();
-        }
-
-        return false;
-    }
-
-    @Override
     public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
         Object item = parent.getItemAtPosition(position);
 
         // HomeListView could hold headers too. Add a context menu info only for its children.
         if (item instanceof Cursor) {
             Cursor cursor = (Cursor) item;
             mContextMenuInfo = new HomeContextMenuInfo(view, position, id, cursor);
             return showContextMenuForChild(HomeListView.this);
--- a/mobile/android/base/home/HomePager.java
+++ b/mobile/android/base/home/HomePager.java
@@ -11,16 +11,17 @@ import org.mozilla.gecko.animation.ViewH
 
 import android.content.Context;
 import android.os.Bundle;
 import android.support.v4.app.Fragment;
 import android.support.v4.app.FragmentManager;
 import android.support.v4.app.FragmentStatePagerAdapter;
 import android.support.v4.view.ViewPager;
 import android.util.AttributeSet;
+import android.view.MotionEvent;
 import android.view.ViewGroup;
 
 import java.util.ArrayList;
 import java.util.EnumMap;
 import java.util.EnumSet;
 
 public class HomePager extends ViewPager {
     // Subpage fragment tag
@@ -174,9 +175,23 @@ public class HomePager extends ViewPager
 
         @Override
         public void destroyItem(ViewGroup container, int position, Object object) {
             super.destroyItem(container, position, object);
 
             mPages.remove(mTabs.get(position).page);
         }
     }
+
+    @Override
+    public boolean onInterceptTouchEvent(MotionEvent event) {
+        if (event.getActionMasked() == MotionEvent.ACTION_DOWN) {
+            // XXX: When an adapter is empty (e.g. Reading List), there are no elements focusable
+            // in touch mode so instead of requestFocus() we use requestFocusFromTouch(). However,
+            // now we may be focusing an object whose focused state is potentially visible to the
+            // user but should not be (e.g. the background), so we clear the focus.
+            requestFocusFromTouch();
+            clearFocus();
+        }
+
+        return super.onInterceptTouchEvent(event);
+    }
 }