Bug 1366352 - Ensure anchor is always set before trying to show tabs tray menu r=nechen
authorAndrzej Hunt <ahunt@mozilla.com>
Fri, 19 May 2017 12:16:12 -0700
changeset 409721 66a8c78c4c24b87025099ff9b476579cc2334ac8
parent 409720 c2d00a8b897b7c48bc8526d0a754eb3570bac684
child 409722 80286a18d5d639924669fe1cfe0c3874611cd07c
push id7391
push usermtabara@mozilla.com
push dateMon, 12 Jun 2017 13:08:53 +0000
treeherdermozilla-beta@2191d7f87e2e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersnechen
bugs1366352
milestone55.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 1366352 - Ensure anchor is always set before trying to show tabs tray menu r=nechen MozReview-Commit-ID: 18KLMDlJUQe
mobile/android/base/java/org/mozilla/gecko/tabs/TabsPanel.java
--- a/mobile/android/base/java/org/mozilla/gecko/tabs/TabsPanel.java
+++ b/mobile/android/base/java/org/mozilla/gecko/tabs/TabsPanel.java
@@ -183,16 +183,21 @@ public class TabsPanel extends LinearLay
             public void onClick(View view) {
                 mActivity.onBackPressed();
             }
         });
     }
 
     public void showMenu() {
         final Menu menu = mPopupMenu.getMenu();
+        // Ensure we update the anchor here to absolutely guarantee there's an anchor
+        // We do set this during prepareToShow(), however only via a UI-thread callback. There are no
+        // guarantees that that callback will complete before a user clicks on the menu button, so
+        // we need to ensure we've set an anchor here.
+        mPopupMenu.setAnchor(mMenuButton);
 
         // Each panel has a "+" shortcut button, so don't show it for that panel.
         menu.findItem(R.id.new_tab).setVisible(mCurrentPanel != Panel.NORMAL_TABS);
         menu.findItem(R.id.new_private_tab).setVisible(mCurrentPanel != Panel.PRIVATE_TABS
                 && Restrictions.isAllowed(mContext, Restrictable.PRIVATE_BROWSING));
 
         // Only show "Clear * tabs" for current panel.
         menu.findItem(R.id.close_all_tabs).setVisible(mCurrentPanel == Panel.NORMAL_TABS);
@@ -379,22 +384,26 @@ public class TabsPanel extends LinearLay
             default:
                 throw new IllegalArgumentException("Unknown panel type " + panelToShow);
         }
         mPanel.show();
 
         mAddTab.setVisibility(View.VISIBLE);
 
         mMenuButton.setEnabled(true);
-        // If mPopupMenu is visible then setAnchor redisplays the menu on its new anchor - but we
-        // may have just been inflated, so give mMenuButton a chance to get its true measurements
-        // before mPopupMenu.setAnchor reads them to determine its offset from the anchor.
-        ThreadUtils.postToUiThread(new Runnable() {
+        mMenuButton.addOnLayoutChangeListener(new OnLayoutChangeListener() {
             @Override
-            public void run() {
+            public void onLayoutChange(View v, int left, int top, int right, int bottom,
+                                       int oldLeft,
+                                       int oldTop, int oldRight, int oldBottom) {
+                // We also set the anchor in showMenu(), but we need to update it in case the menu
+                // is already showing.
+                // If mPopupMenu is visible then setAnchor redisplays the menu on its new anchor - but we
+                // may have just been inflated, so give mMenuButton a chance to get its true measurements
+                // before mPopupMenu.setAnchor reads them to determine its offset from the anchor.
                 mPopupMenu.setAnchor(mMenuButton);
             }
         });
     }
 
     public void hide() {
         mHeaderVisible = false;