Commit e49b2555 authored by Mike Wasserman's avatar Mike Wasserman Committed by Commit Bot

Fix the system tray bubble placement.

The system tray bubble's shadow should not overlap the shelf.
This regressed in https://chromium-review.googlesource.com/c/1386432

Add a flag to apply shadow insets before calculating coordinates.
This should restore the previous behavior for tray bubbles.

Bug: 919645
Test: Tray/volume/etc. bubbles placed correctly for all shelf positions.
Change-Id: I3592e73fc67b32dead470e25e14e450fadc08aba
Reviewed-on: https://chromium-review.googlesource.com/c/1457434
Commit-Queue: Manu Cornet <manucornet@chromium.org>
Reviewed-by: default avatarManu Cornet <manucornet@chromium.org>
Reviewed-by: default avatarTetsui Ohkubo <tetsui@chromium.org>
Cr-Commit-Position: refs/heads/master@{#629917}
parent 04bc4119
...@@ -217,6 +217,7 @@ TrayBubbleView::TrayBubbleView(const InitParams& init_params) ...@@ -217,6 +217,7 @@ TrayBubbleView::TrayBubbleView(const InitParams& init_params)
bubble_border_->set_use_theme_background_color(!init_params.bg_color); bubble_border_->set_use_theme_background_color(!init_params.bg_color);
if (init_params.corner_radius) if (init_params.corner_radius)
bubble_border_->SetCornerRadius(init_params.corner_radius.value()); bubble_border_->SetCornerRadius(init_params.corner_radius.value());
bubble_border_->set_avoid_shadow_overlap(true);
set_parent_window(params_.parent_window); set_parent_window(params_.parent_window);
SetCanActivate(false); SetCanActivate(false);
set_notify_enter_exit_on_child(true); set_notify_enter_exit_on_child(true);
......
...@@ -91,19 +91,23 @@ gfx::Rect BubbleBorder::GetBounds(const gfx::Rect& anchor_rect, ...@@ -91,19 +91,23 @@ gfx::Rect BubbleBorder::GetBounds(const gfx::Rect& anchor_rect,
// In MD, there are no arrows, so positioning logic is significantly simpler. // In MD, there are no arrows, so positioning logic is significantly simpler.
if (has_arrow(arrow_)) { if (has_arrow(arrow_)) {
gfx::Rect contents_bounds(contents_size); gfx::Rect contents_bounds(contents_size);
// Apply the border part of the inset before calculating coordinates because // Always apply the border part of the inset before calculating coordinates,
// the border should align with the anchor's border. For the purposes of // that ensures the bubble's border is aligned with the anchor's border.
// positioning, the border is rounded up to a dip, which may mean we have // For the purposes of positioning, the border is rounded up to a dip, which
// misalignment in scale factors greater than 1. Borders with custom shadow // may cause misalignment in scale factors greater than 1.
// elevations do not draw the 1px border.
// TODO(estade): when it becomes possible to provide px bounds instead of // TODO(estade): when it becomes possible to provide px bounds instead of
// dip bounds, fix this. // dip bounds, fix this.
// Borders with custom shadow elevations do not draw the 1px border.
const gfx::Insets border_insets = const gfx::Insets border_insets =
shadow_ == NO_ASSETS || md_shadow_elevation_.has_value() shadow_ == NO_ASSETS || md_shadow_elevation_.has_value()
? gfx::Insets() ? gfx::Insets()
: gfx::Insets(kBorderThicknessDip); : gfx::Insets(kBorderThicknessDip);
const gfx::Insets shadow_insets = GetInsets() - border_insets; const gfx::Insets shadow_insets = GetInsets() - border_insets;
contents_bounds.Inset(-border_insets); contents_bounds.Inset(-border_insets);
// If |avoid_shadow_overlap_| is true, the shadow part of the inset is also
// applied now, to ensure that the shadow itself doesn't overlap the anchor.
if (avoid_shadow_overlap_)
contents_bounds.Inset(-shadow_insets);
switch (arrow_) { switch (arrow_) {
case TOP_LEFT: case TOP_LEFT:
contents_bounds += anchor_rect.bottom_left() - contents_bounds.origin(); contents_bounds += anchor_rect.bottom_left() - contents_bounds.origin();
...@@ -156,7 +160,8 @@ gfx::Rect BubbleBorder::GetBounds(const gfx::Rect& anchor_rect, ...@@ -156,7 +160,8 @@ gfx::Rect BubbleBorder::GetBounds(const gfx::Rect& anchor_rect,
// used to position the bubble origin according to |anchor_rect|. // used to position the bubble origin according to |anchor_rect|.
DCHECK((shadow_ != NO_ASSETS && shadow_ != NO_SHADOW) || DCHECK((shadow_ != NO_ASSETS && shadow_ != NO_SHADOW) ||
shadow_insets.IsEmpty()); shadow_insets.IsEmpty());
contents_bounds.Inset(-shadow_insets); if (!avoid_shadow_overlap_)
contents_bounds.Inset(-shadow_insets);
// |arrow_offset_| is used to adjust bubbles that would normally be // |arrow_offset_| is used to adjust bubbles that would normally be
// partially offscreen. // partially offscreen.
if (is_arrow_on_horizontal(arrow_)) if (is_arrow_on_horizontal(arrow_))
......
...@@ -182,6 +182,9 @@ class VIEWS_EXPORT BubbleBorder : public Border { ...@@ -182,6 +182,9 @@ class VIEWS_EXPORT BubbleBorder : public Border {
md_shadow_color_ = shadow_color; md_shadow_color_ = shadow_color;
} }
// Set a flag to avoid the bubble's shadow overlapping the anchor.
void set_avoid_shadow_overlap(bool value) { avoid_shadow_overlap_ = value; }
// Get the desired widget bounds (in screen coordinates) given the anchor rect // Get the desired widget bounds (in screen coordinates) given the anchor rect
// and bubble content size; calculated from shadow and arrow image dimensions. // and bubble content size; calculated from shadow and arrow image dimensions.
virtual gfx::Rect GetBounds(const gfx::Rect& anchor_rect, virtual gfx::Rect GetBounds(const gfx::Rect& anchor_rect,
...@@ -245,6 +248,7 @@ class VIEWS_EXPORT BubbleBorder : public Border { ...@@ -245,6 +248,7 @@ class VIEWS_EXPORT BubbleBorder : public Border {
SkColor md_shadow_color_ = SK_ColorBLACK; SkColor md_shadow_color_ = SK_ColorBLACK;
SkColor background_color_; SkColor background_color_;
bool use_theme_background_color_; bool use_theme_background_color_;
bool avoid_shadow_overlap_ = false;
DISALLOW_COPY_AND_ASSIGN(BubbleBorder); DISALLOW_COPY_AND_ASSIGN(BubbleBorder);
}; };
......
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