Commit 2c5146f5 authored by erg@chromium.org's avatar erg@chromium.org

GTK: Always relayout the tab strip when the tab strip bounds change.

TabStripGtk::OnSizeAllocate() could fail to call Layout() or schedule Layout()
to be called in the future (and was reusing the code to resize the internal
tabs when a single tab was closed). The views implementation of the tabstrip
didn't use that path and would always relayout the entire tabstrip on bounds
changes.

BUG=79094
TEST=Create a window with more than 20 tabs in it. Very slowly shrink the window, one pixel at a time. The min/max/close buttons shouldn't overlap with the new tab button.


Review URL: http://codereview.chromium.org/8568026

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@110451 0039d316-1c4b-4281-b951-d872f2087c98
parent 5c4d804b
......@@ -55,6 +55,10 @@ const int kNewTabButtonVOffset = 5;
// is started.
const int kResizeTabsTimeMs = 300;
// A very short time just to make sure we don't clump up our Layout() calls
// during slow window resizes.
const int kLayoutAfterSizeAllocateMs = 10;
// The range outside of the tabstrip where the pointer must enter/leave to
// start/stop the resize animation.
const int kTabStripAnimationVSlop = 40;
......@@ -706,6 +710,7 @@ TabStripGtk::TabStripGtk(TabStripModel* model, BrowserWindowGtk* window)
window_(window),
theme_service_(GtkThemeService::GetFrom(model->profile())),
weak_factory_(this),
layout_factory_(this),
added_as_message_loop_observer_(false),
hover_tab_selector_(model) {
}
......@@ -1556,6 +1561,7 @@ int TabStripGtk::tab_start_x() const {
bool TabStripGtk::ResizeLayoutTabs() {
weak_factory_.InvalidateWeakPtrs();
layout_factory_.InvalidateWeakPtrs();
// It is critically important that this is unhooked here, otherwise we will
// keep spying on messages forever.
......@@ -1623,7 +1629,6 @@ void TabStripGtk::ReStack() {
active_tab->Raise();
}
void TabStripGtk::AddMessageLoopObserver() {
if (!added_as_message_loop_observer_) {
MessageLoopForUI::current()->AddObserver(this);
......@@ -2081,10 +2086,16 @@ void TabStripGtk::OnSizeAllocate(GtkWidget* widget, GtkAllocation* allocation) {
return;
// When there is only one tab, Layout() so we don't animate it. With more
// tabs, do ResizeLayoutTabs(). In RTL(), we will also need to manually
// Layout() when ResizeLayoutTabs() is a no-op.
if ((GetTabCount() == 1) || (!ResizeLayoutTabs() && base::i18n::IsRTL()))
// tabs, we should always attempt a resize unless we already have one coming
// up in our message loop.
if (GetTabCount() == 1) {
Layout();
} else if (!layout_factory_.HasWeakPtrs()) {
MessageLoop::current()->PostDelayedTask(
FROM_HERE,
base::Bind(&TabStripGtk::Layout, layout_factory_.GetWeakPtr()),
kLayoutAfterSizeAllocateMs);
}
}
gboolean TabStripGtk::OnDragMotion(GtkWidget* widget, GdkDragContext* context,
......
......@@ -483,6 +483,9 @@ class TabStripGtk : public TabStripModelObserver,
// ResizeLayoutTabsNow method.
base::WeakPtrFactory<TabStripGtk> weak_factory_;
// A different factory for calls to Layout().
base::WeakPtrFactory<TabStripGtk> layout_factory_;
// True if the tabstrip has already been added as a MessageLoop observer.
bool added_as_message_loop_observer_;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment