| Index: ui/views/bubble/bubble_frame_view.cc
|
| diff --git a/ui/views/bubble/bubble_frame_view.cc b/ui/views/bubble/bubble_frame_view.cc
|
| index 9ae1f8d5862799a76d3239555054824cbd076af1..55010e4c79ff7f52a5ffbc9d74d08389f14aa744 100644
|
| --- a/ui/views/bubble/bubble_frame_view.cc
|
| +++ b/ui/views/bubble/bubble_frame_view.cc
|
| @@ -74,17 +74,22 @@ gfx::Size BubbleFrameView::GetPreferredSize() {
|
|
|
| gfx::Rect BubbleFrameView::GetUpdatedWindowBounds(const gfx::Rect& anchor_rect,
|
| gfx::Size client_size,
|
| - bool try_mirroring_arrow) {
|
| + bool try_fit_bubble) {
|
| // Give the contents a margin.
|
| client_size.Enlarge(content_margins_.width(), content_margins_.height());
|
|
|
| - if (try_mirroring_arrow) {
|
| - // Try to mirror the anchoring if the bubble does not fit on the screen.
|
| - MirrorArrowIfOffScreen(true, anchor_rect, client_size);
|
| - MirrorArrowIfOffScreen(false, anchor_rect, client_size);
|
| + if (try_fit_bubble &&
|
| + BubbleBorder::has_arrow(bubble_border_->arrow_location())) {
|
| + if (!bubble_border_->center_arrow()) {
|
| + // Try to mirror the anchoring if the bubble does not fit on the screen.
|
| + MirrorArrowIfOffScreen(true, anchor_rect, client_size);
|
| + MirrorArrowIfOffScreen(false, anchor_rect, client_size);
|
| + }
|
| +
|
| + OffsetArrowIfOffScreen(anchor_rect, client_size);
|
| }
|
|
|
| - // Calculate the bounds with the arrow in its updated location.
|
| + // Calculate the bounds with the arrow in its updated location and offset.
|
| return bubble_border_->GetBounds(anchor_rect, client_size);
|
| }
|
|
|
| @@ -124,4 +129,47 @@ void BubbleFrameView::MirrorArrowIfOffScreen(
|
| }
|
| }
|
|
|
| +void BubbleFrameView::OffsetArrowIfOffScreen(const gfx::Rect& anchor_rect,
|
| + const gfx::Size& client_size) {
|
| + BubbleBorder::ArrowLocation arrow = bubble_border()->arrow_location();
|
| + DCHECK(BubbleBorder::has_arrow(arrow));
|
| +
|
| + // Get desired bubble bounds without adjustment.
|
| + const int old_adjust = bubble_border_->relative_arrow_offset();
|
| + bubble_border_->set_relative_arrow_offset(0);
|
| + gfx::Rect window_bounds(bubble_border_->GetBounds(anchor_rect, client_size));
|
| +
|
| + gfx::Rect monitor_rect(GetMonitorBounds(anchor_rect));
|
| + if (monitor_rect.IsEmpty() || monitor_rect.Contains(window_bounds))
|
| + return;
|
| +
|
| + // Calculate off screen adjustment
|
| + const bool is_horizontal = BubbleBorder::is_arrow_on_horizontal(arrow);
|
| + int offscreen_adjust = 0;
|
| + if (is_horizontal) {
|
| + if (window_bounds.x() < monitor_rect.x())
|
| + offscreen_adjust = monitor_rect.x() - window_bounds.x();
|
| + else if (window_bounds.right() > monitor_rect.right())
|
| + offscreen_adjust = monitor_rect.right() - window_bounds.right();
|
| + } else {
|
| + if (window_bounds.y() < monitor_rect.y())
|
| + offscreen_adjust = monitor_rect.y() - window_bounds.y();
|
| + else if (window_bounds.bottom() > monitor_rect.bottom())
|
| + offscreen_adjust = monitor_rect.bottom() - window_bounds.bottom();
|
| + }
|
| +
|
| + if ((is_horizontal && BubbleBorder::is_arrow_on_left(arrow)) ||
|
| + (!is_horizontal && BubbleBorder::is_arrow_on_top(arrow))) {
|
| + // For left and top arrow, arrow moves closer to starting edge for positive
|
| + // adjustment (i.e. negative arrow offset adjustment). Similarly, negative
|
| + // adjustment (bubble right edge offscreen) means arrow should move further
|
| + // from starting edge (i.e. positive arrow offset adjustment).
|
| + offscreen_adjust = -offscreen_adjust;
|
| + }
|
| +
|
| + bubble_border_->set_relative_arrow_offset(offscreen_adjust);
|
| + if (old_adjust != offscreen_adjust)
|
| + SchedulePaint();
|
| +}
|
| +
|
| } // namespace views
|
|
|