Index: ash/shelf/shelf_tooltip_manager.cc |
diff --git a/ash/shelf/shelf_tooltip_manager.cc b/ash/shelf/shelf_tooltip_manager.cc |
index 5e25fb2aae0391ef29d2e9cd7169290bacb22e59..92621dadeecba91b6dcf2506955993194bd9c9b4 100644 |
--- a/ash/shelf/shelf_tooltip_manager.cc |
+++ b/ash/shelf/shelf_tooltip_manager.cc |
@@ -24,6 +24,7 @@ |
namespace ash { |
namespace { |
+ |
const int kTooltipTopBottomMargin = 3; |
const int kTooltipLeftRightMargin = 10; |
const int kTooltipAppearanceDelay = 1000; // msec |
@@ -48,70 +49,72 @@ class ShelfTooltipManager::ShelfTooltipBubble |
public: |
ShelfTooltipBubble(views::View* anchor, |
views::BubbleBorder::Arrow arrow, |
- const base::string16& text); |
+ const base::string16& text) |
+ : views::BubbleDelegateView(anchor, arrow) { |
+ gfx::Insets insets = |
+ gfx::Insets(kArrowOffsetTopBottom, kArrowOffsetLeftRight); |
+ // Adjust the anchor location for asymmetrical borders of shelf item. |
+ if (anchor->border()) |
+ insets += anchor->border()->GetInsets(); |
+ |
+ set_anchor_view_insets(insets); |
+ set_close_on_esc(false); |
+ set_close_on_deactivate(false); |
+ set_can_activate(false); |
+ set_accept_events(false); |
+ set_margins(gfx::Insets(kTooltipTopBottomMargin, kTooltipLeftRightMargin)); |
+ set_shadow(views::BubbleBorder::SMALL_SHADOW); |
+ SetLayoutManager(new views::FillLayout()); |
+ // The anchor may not have the widget in tests. |
+ if (anchor->GetWidget() && anchor->GetWidget()->GetNativeWindow()) { |
+ set_parent_window(ash::Shell::GetContainer( |
+ anchor->GetWidget()->GetNativeWindow()->GetRootWindow(), |
+ ash::kShellWindowId_SettingBubbleContainer)); |
+ } |
+ views::Label* label = new views::Label(text); |
+ label->SetHorizontalAlignment(gfx::ALIGN_LEFT); |
+ label->SetEnabledColor(kTooltipTextColor); |
+ AddChildView(label); |
+ views::BubbleDelegateView::CreateBubble(this); |
+ SizeToContents(); |
+ } |
private: |
// views::View overrides: |
- gfx::Size GetPreferredSize() const override; |
+ gfx::Size GetPreferredSize() const override { |
+ const gfx::Size size = views::BubbleDelegateView::GetPreferredSize(); |
+ return gfx::Size(std::min(size.width(), kTooltipMaxWidth), |
+ std::max(size.height(), kTooltipMinHeight)); |
+ } |
DISALLOW_COPY_AND_ASSIGN(ShelfTooltipBubble); |
}; |
-ShelfTooltipManager::ShelfTooltipBubble::ShelfTooltipBubble( |
- views::View* anchor, |
- views::BubbleBorder::Arrow arrow, |
- const base::string16& text) |
- : views::BubbleDelegateView(anchor, arrow) { |
- gfx::Insets insets = gfx::Insets(kArrowOffsetTopBottom, |
- kArrowOffsetLeftRight); |
- // Adjust the anchor location for asymmetrical borders of shelf item. |
- if (anchor->border()) |
- insets += anchor->border()->GetInsets(); |
- |
- set_anchor_view_insets(insets); |
- set_close_on_esc(false); |
- set_close_on_deactivate(false); |
- set_can_activate(false); |
- set_accept_events(false); |
- set_margins(gfx::Insets(kTooltipTopBottomMargin, kTooltipLeftRightMargin)); |
- set_shadow(views::BubbleBorder::SMALL_SHADOW); |
- SetLayoutManager(new views::FillLayout()); |
- // The anchor may not have the widget in tests. |
- if (anchor->GetWidget() && anchor->GetWidget()->GetNativeWindow()) { |
- set_parent_window(ash::Shell::GetContainer( |
- anchor->GetWidget()->GetNativeWindow()->GetRootWindow(), |
- ash::kShellWindowId_SettingBubbleContainer)); |
- } |
- views::Label* label = new views::Label(text); |
- label->SetHorizontalAlignment(gfx::ALIGN_LEFT); |
- label->SetEnabledColor(kTooltipTextColor); |
- AddChildView(label); |
- views::BubbleDelegateView::CreateBubble(this); |
- SizeToContents(); |
-} |
- |
-gfx::Size ShelfTooltipManager::ShelfTooltipBubble::GetPreferredSize() const { |
- const gfx::Size size = views::BubbleDelegateView::GetPreferredSize(); |
- return gfx::Size(std::min(size.width(), kTooltipMaxWidth), |
- std::max(size.height(), kTooltipMinHeight)); |
-} |
- |
ShelfTooltipManager::ShelfTooltipManager(ShelfView* shelf_view) |
: timer_delay_(kTooltipAppearanceDelay), |
shelf_view_(shelf_view), |
+ root_window_(nullptr), |
shelf_layout_manager_(nullptr), |
bubble_(nullptr), |
weak_factory_(this) {} |
ShelfTooltipManager::~ShelfTooltipManager() { |
WillDeleteShelf(); |
+ if (root_window_) { |
+ root_window_->RemoveObserver(this); |
+ root_window_->RemovePreTargetHandler(this); |
+ root_window_ = nullptr; |
+ } |
} |
void ShelfTooltipManager::Init() { |
shelf_layout_manager_ = shelf_view_->shelf()->shelf_layout_manager(); |
shelf_layout_manager_->AddObserver(this); |
- // TODO(msw): Capture events outside the shelf to close tooltips? |
- shelf_view_->GetWidget()->GetNativeWindow()->AddPreTargetHandler(this); |
+ |
+ // TODO(msw): Observe events outside the shelf in mash, to close tooltips. |
+ root_window_ = shelf_view_->GetWidget()->GetNativeWindow()->GetRootWindow(); |
+ root_window_->AddPreTargetHandler(this); |
+ root_window_->AddObserver(this); |
} |
void ShelfTooltipManager::Close() { |
@@ -164,30 +167,36 @@ void ShelfTooltipManager::ShowTooltipWithDelay(views::View* view) { |
} |
void ShelfTooltipManager::OnEvent(ui::Event* event) { |
- // Close the tooltip on mouse press or exit, and on most non-mouse events. |
if (event->type() == ui::ET_MOUSE_PRESSED || |
- event->type() == ui::ET_MOUSE_EXITED || !event->IsMouseEvent()) { |
+ event->type() == ui::ET_MOUSE_EXITED || !event->IsMouseEvent() || |
+ event->target() != shelf_view_->GetWidget()->GetNativeWindow()) { |
if (!event->IsKeyEvent()) |
Close(); |
return; |
} |
gfx::Point point = static_cast<ui::LocatedEvent*>(event)->location(); |
+ aura::Window::ConvertPointToTarget( |
+ static_cast<aura::Window*>(event->target()), |
+ shelf_view_->GetWidget()->GetNativeWindow(), &point); |
views::View::ConvertPointFromWidget(shelf_view_, &point); |
- if (IsVisible() && shelf_view_->ShouldHideTooltip(point)) { |
- Close(); |
- return; |
- } |
- |
views::View* view = shelf_view_->GetTooltipHandlerForPoint(point); |
const bool should_show = shelf_view_->ShouldShowTooltipForView(view); |
- if (IsVisible() && bubble_->GetAnchorView() != view && should_show) |
+ |
+ timer_.Stop(); |
+ if (IsVisible() && should_show && bubble_->GetAnchorView() != view) |
ShowTooltip(view); |
+ else if (!IsVisible() && should_show && event->type() == ui::ET_MOUSE_MOVED) |
+ ShowTooltipWithDelay(view); |
+ else if (IsVisible() && shelf_view_->ShouldHideTooltip(point)) |
+ Close(); |
+} |
- if (!IsVisible() && event->type() == ui::ET_MOUSE_MOVED) { |
- timer_.Stop(); |
- if (should_show) |
- ShowTooltipWithDelay(view); |
+void ShelfTooltipManager::OnWindowDestroying(aura::Window* window) { |
+ if (window == root_window_) { |
+ root_window_->RemoveObserver(this); |
+ root_window_->RemovePreTargetHandler(this); |
+ root_window_ = nullptr; |
} |
} |
@@ -195,10 +204,6 @@ void ShelfTooltipManager::WillDeleteShelf() { |
if (shelf_layout_manager_) |
shelf_layout_manager_->RemoveObserver(this); |
shelf_layout_manager_ = nullptr; |
- |
- views::Widget* widget = shelf_view_ ? shelf_view_->GetWidget() : nullptr; |
- if (widget && widget->GetNativeWindow()) |
- widget->GetNativeWindow()->RemovePreTargetHandler(this); |
shelf_view_ = nullptr; |
} |