Chromium Code Reviews| Index: ui/views/controls/scroll_view.cc |
| diff --git a/ui/views/controls/scroll_view.cc b/ui/views/controls/scroll_view.cc |
| index cf212b7c8bd3c99d10b268ab234d9acf05508a54..35f7f1b651e64c9c64878a5786022c26bce96be5 100644 |
| --- a/ui/views/controls/scroll_view.cc |
| +++ b/ui/views/controls/scroll_view.cc |
| @@ -243,12 +243,14 @@ void ScrollView::ClipHeightTo(int min_height, int max_height) { |
| max_height_ = max_height; |
| } |
| -int ScrollView::GetScrollBarWidth() const { |
| - return vert_sb_ ? vert_sb_->GetLayoutSize() : 0; |
| +int ScrollView::GetScrollBarLayoutWidth() const { |
| + return vert_sb_ && !vert_sb_->OverlapsContent() ? vert_sb_->GetThickness() |
| + : 0; |
| } |
| -int ScrollView::GetScrollBarHeight() const { |
| - return horiz_sb_ ? horiz_sb_->GetLayoutSize() : 0; |
| +int ScrollView::GetScrollBarLayoutHeight() const { |
| + return horiz_sb_ && !horiz_sb_->OverlapsContent() ? horiz_sb_->GetThickness() |
| + : 0; |
| } |
| void ScrollView::SetHorizontalScrollBar(ScrollBar* horiz_sb) { |
| @@ -302,6 +304,14 @@ int ScrollView::GetHeightForWidth(int width) const { |
| } |
| void ScrollView::Layout() { |
| +#if defined(OS_MACOSX) |
| + // On Mac, scrollbars may update their style one at a time, so they may |
| + // temporarily be of different types. Refuse to lay out at this point. |
| + if (horiz_sb_->OverlapsContent() != vert_sb_->OverlapsContent()) |
|
Evan Stade
2016/12/13 00:51:52
Sadrul, do you mind this change that I had to make
|
| + return; |
| +#endif |
| + DCHECK_EQ(horiz_sb_->OverlapsContent(), vert_sb_->OverlapsContent()); |
| + |
| if (focus_ring_) |
| focus_ring_->Layout(); |
| @@ -310,7 +320,7 @@ void ScrollView::Layout() { |
| int content_width = available_rect.width(); |
| int content_height = contents_->GetHeightForWidth(content_width); |
| if (content_height > height()) { |
| - content_width = std::max(content_width - GetScrollBarWidth(), 0); |
| + content_width = std::max(content_width - GetScrollBarLayoutWidth(), 0); |
| content_height = contents_->GetHeightForWidth(content_width); |
| } |
| contents_->SetSize(gfx::Size(content_width, content_height)); |
| @@ -342,9 +352,9 @@ void ScrollView::Layout() { |
| gfx::Size viewport_size = viewport_bounds.size(); |
| // Assumes a vertical scrollbar since most of the current views are designed |
| // for this. |
| - int horiz_sb_height = GetScrollBarHeight(); |
| - int vert_sb_width = GetScrollBarWidth(); |
| - viewport_bounds.set_width(viewport_bounds.width() - vert_sb_width); |
| + const int horiz_sb_layout_height = GetScrollBarLayoutHeight(); |
| + const int vert_sb_layout_width = GetScrollBarLayoutWidth(); |
| + viewport_bounds.set_width(viewport_bounds.width() - vert_sb_layout_width); |
| // Update the bounds right now so the inner views can fit in it. |
| contents_viewport_->SetBoundsRect(viewport_bounds); |
| @@ -363,7 +373,9 @@ void ScrollView::Layout() { |
| &horiz_sb_required, |
| &vert_sb_required); |
| } |
| - bool corner_view_required = horiz_sb_required && vert_sb_required; |
| + // Overlay scrollbars don't need a corner view. |
| + bool corner_view_required = |
| + horiz_sb_required && vert_sb_required && !vert_sb_->OverlapsContent(); |
| // Take action. |
| SetControlVisibility(horiz_sb_, horiz_sb_required); |
| SetControlVisibility(vert_sb_, vert_sb_required); |
| @@ -372,37 +384,45 @@ void ScrollView::Layout() { |
| // Non-default. |
| if (horiz_sb_required) { |
| viewport_bounds.set_height( |
| - std::max(0, viewport_bounds.height() - horiz_sb_height)); |
| + std::max(0, viewport_bounds.height() - horiz_sb_layout_height)); |
| should_layout_contents = true; |
| } |
| // Default. |
| if (!vert_sb_required) { |
| - viewport_bounds.set_width(viewport_bounds.width() + vert_sb_width); |
| + viewport_bounds.set_width(viewport_bounds.width() + vert_sb_layout_width); |
| should_layout_contents = true; |
| } |
| - int height_offset = horiz_sb_required ? |
| - horiz_sb_->GetContentOverlapSize() : 0; |
| - int width_offset = vert_sb_required ? |
| - vert_sb_->GetContentOverlapSize() : 0; |
| - |
| if (horiz_sb_required) { |
| - horiz_sb_->SetBounds(contents_x, |
| - viewport_bounds.bottom() - height_offset, |
| - viewport_bounds.right() - contents_x - width_offset, |
| - horiz_sb_height + height_offset); |
| + gfx::Rect horiz_sb_bounds(contents_x, viewport_bounds.bottom(), |
| + viewport_bounds.right() - contents_x, |
| + horiz_sb_layout_height); |
| + if (horiz_sb_->OverlapsContent()) { |
| + horiz_sb_bounds.Inset( |
| + gfx::Insets(-horiz_sb_->GetThickness(), 0, 0, |
| + vert_sb_required ? vert_sb_->GetThickness() : 0)); |
| + } |
| + |
| + horiz_sb_->SetBoundsRect(horiz_sb_bounds); |
| } |
| if (vert_sb_required) { |
| - int width_offset = vert_sb_->GetContentOverlapSize(); |
| - vert_sb_->SetBounds(viewport_bounds.right() - width_offset, |
| - contents_y, |
| - vert_sb_width + width_offset, |
| - viewport_bounds.bottom() - contents_y - height_offset); |
| + gfx::Rect vert_sb_bounds(viewport_bounds.right(), contents_y, |
| + vert_sb_layout_width, |
| + viewport_bounds.bottom() - contents_y); |
| + if (vert_sb_->OverlapsContent()) { |
| + // In the overlay scrollbar case, the scrollbar only covers the viewport |
| + // (and not the header). |
| + vert_sb_bounds.Inset( |
| + gfx::Insets(header_height, -vert_sb_->GetThickness(), |
| + horiz_sb_required ? horiz_sb_->GetThickness() : 0, 0)); |
| + } |
| + |
| + vert_sb_->SetBoundsRect(vert_sb_bounds); |
| } |
| if (corner_view_required) { |
| // Show the resize corner. |
| corner_view_->SetBounds(vert_sb_->bounds().x(), horiz_sb_->bounds().y(), |
| - vert_sb_width, horiz_sb_height); |
| + vert_sb_layout_width, horiz_sb_layout_height); |
| } |
| // Update to the real client size with the visible scrollbars. |
| @@ -619,10 +639,12 @@ void ScrollView::ComputeScrollBarsVisibility(const gfx::Size& vp_size, |
| content_size.height() <= vp_size.height()) { |
| *horiz_is_shown = false; |
| *vert_is_shown = false; |
| - } else if (content_size.width() <= vp_size.width() - GetScrollBarWidth()) { |
| + } else if (content_size.width() <= |
| + vp_size.width() - GetScrollBarLayoutWidth()) { |
| *horiz_is_shown = false; |
| *vert_is_shown = true; |
| - } else if (content_size.height() <= vp_size.height() - GetScrollBarHeight()) { |
| + } else if (content_size.height() <= |
| + vp_size.height() - GetScrollBarLayoutHeight()) { |
| *horiz_is_shown = true; |
| *vert_is_shown = false; |
| } else { |