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 143458 6c4b716fe1898ff347380dbe935754f8d6bae6cc
parent 143457 962211a2b765b4306a65c44d22df6a30283a8c7f
child 143459 ef686945229b4ce2c3560d266bd29a39e975761a
push id25130
push userlrocha@mozilla.com
push dateWed, 21 Aug 2013 09:41:27 +0000
treeherdermozilla-central@b2486721572e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerslucasr
bugs895828
milestone25.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
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);
+    }
 }