Bug 1331154 - 7. Update the tab strip after tabs are moved in the tabs tray. r?sebastian
The tabs tray is drawn on top of the tab strip, not instead of it, so the tab
strip needs to be updated after tabs are moved in the tabs tray before the tab
strip becomes user-visible again.
This introduces a slight change in behavior: *if* a move (of a tab matching the
privacy state of the tab strip) occurs while the tabs panel is open, the tab
strip will be scrolled to the currently selected tab when the tabs panel is
closed - previously the tab strip maintained its old scroll position if a tab
wasn't closed or added while the tabs panel was open.
MozReview-Commit-ID: Ipy5huthNYB
--- a/mobile/android/base/java/org/mozilla/gecko/BrowserApp.java
+++ b/mobile/android/base/java/org/mozilla/gecko/BrowserApp.java
@@ -2208,30 +2208,36 @@ public class BrowserApp extends GeckoApp
showTabs(panel);
}
});
}
} else {
if (mDoorHangerPopup != null) {
mDoorHangerPopup.disable();
}
+ if (mTabStrip != null) {
+ mTabStrip.tabStripIsCovered(true);
+ }
mTabsPanel.show(panel);
// Hide potentially visible "find in page" bar (Bug 1177338)
mFindInPageBar.hide();
for (final BrowserAppDelegate delegate : delegates) {
delegate.onTabsTrayShown(this, mTabsPanel);
}
}
}
@Override
public void hideTabs() {
mTabsPanel.hide();
+ if (mTabStrip != null) {
+ mTabStrip.tabStripIsCovered(false);
+ }
if (mDoorHangerPopup != null) {
mDoorHangerPopup.enable();
}
for (final BrowserAppDelegate delegate : delegates) {
delegate.onTabsTrayHidden(this, mTabsPanel);
}
}
@@ -4170,16 +4176,20 @@ public class BrowserApp extends GeckoApp
// Only slide the urlbar out if it was hidden when the action mode started
// Don't animate hiding it so that there's no flash as we switch back to url mode
mDynamicToolbar.setTemporarilyVisible(false, VisibilityTransition.IMMEDIATE);
}
public static interface TabStripInterface {
public void refresh();
+ /** Called to let the tab strip know it is now, or is now no longer, being hidden by
+ * something being drawn over it.
+ */
+ void tabStripIsCovered(boolean covered);
void setOnTabChangedListener(OnTabAddedOrRemovedListener listener);
interface OnTabAddedOrRemovedListener {
void onTabChanged();
}
}
@Override
protected void recordStartupActionTelemetry(final String passedURL, final String action) {
--- a/mobile/android/base/java/org/mozilla/gecko/Tabs.java
+++ b/mobile/android/base/java/org/mozilla/gecko/Tabs.java
@@ -672,16 +672,17 @@ public class Tabs implements BundleEvent
STOP,
FAVICON,
THUMBNAIL,
TITLE,
SELECTED,
UNSELECTED,
ADDED,
RESTORED,
+ MOVED,
LOCATION_CHANGE,
MENU_UPDATED,
PAGE_SHOW,
LINK_FEED,
SECURITY_CHANGE,
DESKTOP_MODE_CHANGE,
RECORDING_CHANGE,
BOOKMARK_ADDED,
@@ -1152,16 +1153,18 @@ public class Tabs implements BundleEvent
// other threads from possibly choosing to start iterating mOrder in between when we
// might mOrder.clear() and then mOrder.addAll(newTabsArray) if we were to repopulate
// mOrder in place.)
mOrder = new CopyOnWriteArrayList<>(newTabsList);
}
queuePersistAllTabs();
+ notifyListeners(mOrder.get(toPosition), TabEvents.MOVED);
+
final GeckoBundle data = new GeckoBundle();
data.putInt("fromTabId", fromTabId);
data.putInt("fromPosition", fromPosition);
data.putInt("toTabId", toTabId);
data.putInt("toPosition", toPosition);
EventDispatcher.getInstance().dispatch("Tab:Move", data);
}
}
--- a/mobile/android/base/java/org/mozilla/gecko/tabs/TabStrip.java
+++ b/mobile/android/base/java/org/mozilla/gecko/tabs/TabStrip.java
@@ -4,16 +4,17 @@
* You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.gecko.tabs;
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.StateListDrawable;
import android.graphics.Rect;
+import android.support.annotation.UiThread;
import android.support.v4.content.ContextCompat;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.TouchDelegate;
import android.view.View;
import android.view.ViewTreeObserver;
import org.mozilla.gecko.BrowserApp.TabStripInterface;
@@ -28,16 +29,20 @@ public class TabStrip extends ThemedLine
private static final String LOGTAG = "GeckoTabStrip";
private final TabStripView tabStripView;
private final ThemedImageButton addTabButton;
private final TabsListener tabsListener;
private OnTabAddedOrRemovedListener tabChangedListener;
+ // True when the tab strip isn't visible to the user due to something being drawn over it.
+ private boolean tabStripIsCovered;
+ private boolean tabsNeedUpdating;
+
public TabStrip(Context context) {
this(context, null);
}
public TabStrip(Context context, AttributeSet attrs) {
super(context, attrs);
setOrientation(HORIZONTAL);
@@ -135,25 +140,43 @@ public class TabStrip extends ThemedLine
case UNSELECTED:
// We just need to update the style for the unselected tab...
case TITLE:
case FAVICON:
case RECORDING_CHANGE:
case AUDIO_PLAYING_CHANGE:
tabStripView.updateTab(tab);
break;
+
+ case MOVED:
+ if (tabStripIsCovered && tab.isPrivate() == tabStripView.isPrivate()) {
+ // One of our tabs got moved while we're visible but covered; be sure to
+ // update the tabs list before the user can see us again.
+ tabsNeedUpdating = true;
+ }
+ break;
}
}
}
@Override
public void refresh() {
tabStripView.refresh();
}
+ @UiThread
+ @Override
+ public void tabStripIsCovered(boolean covered) {
+ tabStripIsCovered = covered;
+ if (!tabStripIsCovered && tabsNeedUpdating) {
+ tabStripView.refreshTabs();
+ tabsNeedUpdating = false;
+ }
+ }
+
@Override
public void onLightweightThemeChanged() {
final Drawable drawable = getTheme().getDrawable(this);
if (drawable == null) {
return;
}
final StateListDrawable stateList = new StateListDrawable();
--- a/mobile/android/base/java/org/mozilla/gecko/tabs/TabStripView.java
+++ b/mobile/android/base/java/org/mozilla/gecko/tabs/TabStripView.java
@@ -133,16 +133,20 @@ public class TabStripView extends Recycl
}
}
/* package */ void updateTab(Tab tab) {
adapter.notifyTabChanged(tab);
}
+ /* package */ boolean isPrivate() {
+ return isPrivate;
+ }
+
@Override
public boolean onItemMove(int fromPosition, int toPosition) {
return adapter.moveTab(fromPosition, toPosition);
}
public int getPositionForSelectedTab() {
return adapter.getPositionForTab(Tabs.getInstance().getSelectedTab());
}