Index: ui/views/bubble/bubble_delegate.cc |
diff --git a/ui/views/bubble/bubble_delegate.cc b/ui/views/bubble/bubble_delegate.cc |
index 3942c9276f5521b67f289eeb29e351bf411331e0..f593a1b23e21fe762c086a2ce229c8f447b0181f 100644 |
--- a/ui/views/bubble/bubble_delegate.cc |
+++ b/ui/views/bubble/bubble_delegate.cc |
@@ -20,7 +20,7 @@ namespace views { |
namespace { |
// Create a widget to host the bubble. |
-Widget* CreateBubbleWidget(BubbleDelegateView* bubble, Widget* parent) { |
+Widget* CreateBubbleWidget(BubbleDelegateView* bubble) { |
Widget* bubble_widget = new Widget(); |
Widget::InitParams bubble_params(Widget::InitParams::TYPE_BUBBLE); |
bubble_params.delegate = bubble; |
@@ -28,7 +28,7 @@ Widget* CreateBubbleWidget(BubbleDelegateView* bubble, Widget* parent) { |
if (bubble->parent_window()) |
bubble_params.parent = bubble->parent_window(); |
else |
- bubble_params.parent_widget = parent; |
+ bubble_params.parent_widget = bubble->anchor_widget(); |
if (bubble->use_focusless()) |
bubble_params.can_activate = false; |
#if defined(OS_WIN) && !defined(USE_AURA) |
@@ -81,12 +81,12 @@ class BubbleBorderDelegate : public WidgetDelegate, |
}; |
// Create a widget to host the bubble's border. |
-Widget* CreateBorderWidget(BubbleDelegateView* bubble, Widget* parent) { |
+Widget* CreateBorderWidget(BubbleDelegateView* bubble) { |
Widget* border_widget = new Widget(); |
Widget::InitParams border_params(Widget::InitParams::TYPE_BUBBLE); |
border_params.delegate = new BubbleBorderDelegate(bubble, border_widget); |
border_params.transparent = true; |
- border_params.parent_widget = parent; |
+ border_params.parent_widget = bubble->anchor_widget(); |
border_widget->Init(border_params); |
return border_widget; |
} |
@@ -106,6 +106,8 @@ BubbleDelegateView::BubbleDelegateView() |
: close_on_esc_(true), |
close_on_deactivate_(true), |
anchor_view_(NULL), |
+ anchor_widget_(NULL), |
+ move_with_anchor_(false), |
arrow_location_(BubbleBorder::TOP_LEFT), |
color_(kBackgroundColor), |
margin_(kDefaultMargin), |
@@ -123,6 +125,8 @@ BubbleDelegateView::BubbleDelegateView( |
: close_on_esc_(true), |
close_on_deactivate_(true), |
anchor_view_(anchor_view), |
+ anchor_widget_(NULL), |
+ move_with_anchor_(false), |
arrow_location_(arrow_location), |
color_(kBackgroundColor), |
margin_(kDefaultMargin), |
@@ -139,14 +143,15 @@ BubbleDelegateView::~BubbleDelegateView() {} |
// static |
Widget* BubbleDelegateView::CreateBubble(BubbleDelegateView* bubble_delegate) { |
bubble_delegate->Init(); |
- Widget* parent = bubble_delegate->anchor_view() ? |
+ // Determine the anchor widget from the anchor view at bubble creation time. |
+ bubble_delegate->anchor_widget_ = bubble_delegate->anchor_view() ? |
bubble_delegate->anchor_view()->GetWidget() : NULL; |
- Widget* bubble_widget = CreateBubbleWidget(bubble_delegate, parent); |
+ Widget* bubble_widget = CreateBubbleWidget(bubble_delegate); |
#if defined(OS_WIN) && !defined(USE_AURA) |
// First set the contents view to initialize view bounds for widget sizing. |
bubble_widget->SetContentsView(bubble_delegate->GetContentsView()); |
- bubble_delegate->border_widget_ = CreateBorderWidget(bubble_delegate, parent); |
+ bubble_delegate->border_widget_ = CreateBorderWidget(bubble_delegate); |
#endif |
bubble_delegate->SizeToContents(); |
@@ -171,19 +176,31 @@ NonClientFrameView* BubbleDelegateView::CreateNonClientFrameView( |
return new BubbleFrameView(arrow_location(), color(), margin()); |
} |
+void BubbleDelegateView::OnWidgetClosing(Widget* widget) { |
+ if (anchor_widget() == widget) { |
+ anchor_view_ = NULL; |
+ anchor_widget_ = NULL; |
+ } |
+} |
+ |
void BubbleDelegateView::OnWidgetVisibilityChanged(Widget* widget, |
bool visible) { |
- if (widget == GetWidget()) { |
- if (visible) { |
- if (border_widget_) |
- border_widget_->Show(); |
- GetFocusManager()->SetFocusedView(GetInitiallyFocusedView()); |
- Widget* anchor_widget = anchor_view() ? anchor_view()->GetWidget() : NULL; |
- if (anchor_widget && anchor_widget->GetTopLevelWidget()) |
- anchor_widget->GetTopLevelWidget()->DisableInactiveRendering(); |
- } else if (border_widget_) { |
+ if (widget != GetWidget()) |
+ return; |
+ |
+ if (visible) { |
+ if (border_widget_) |
+ border_widget_->Show(); |
+ if (anchor_widget()) |
+ anchor_widget()->AddObserver(this); |
+ GetFocusManager()->SetFocusedView(GetInitiallyFocusedView()); |
+ if (anchor_widget() && anchor_widget()->GetTopLevelWidget()) |
+ anchor_widget()->GetTopLevelWidget()->DisableInactiveRendering(); |
+ } else { |
+ if (border_widget_) |
border_widget_->Hide(); |
- } |
+ if (anchor_widget()) |
+ anchor_widget()->RemoveObserver(this); |
} |
} |
@@ -193,6 +210,11 @@ void BubbleDelegateView::OnWidgetActivationChanged(Widget* widget, |
GetWidget()->Close(); |
} |
+void BubbleDelegateView::OnWidgetMoved(Widget* widget) { |
+ if (move_with_anchor() && anchor_widget() == widget) |
+ SizeToContents(); |
+} |
+ |
gfx::Rect BubbleDelegateView::GetAnchorRect() { |
return anchor_view() ? anchor_view()->GetScreenBounds() : gfx::Rect(); |
} |