Index: chrome/browser/ui/cocoa/bubble_anchor_helper_views.mm |
diff --git a/chrome/browser/ui/cocoa/bubble_anchor_helper_views.mm b/chrome/browser/ui/cocoa/bubble_anchor_helper_views.mm |
index fae302ed9a08ee6ed24f19e951e183453b4b5c3e..df326be92d8bc2fcbec3455f90efd9b3c9d98a52 100644 |
--- a/chrome/browser/ui/cocoa/bubble_anchor_helper_views.mm |
+++ b/chrome/browser/ui/cocoa/bubble_anchor_helper_views.mm |
@@ -7,6 +7,11 @@ |
#import <Cocoa/Cocoa.h> |
#import "base/mac/scoped_nsobject.h" |
+#import "chrome/browser/ui/cocoa/browser_window_controller.h" |
+#import "chrome/browser/ui/cocoa/location_bar/location_bar_decoration.h" |
+#import "chrome/browser/ui/cocoa/location_bar/location_bar_view_mac.h" |
+#import "chrome/browser/ui/cocoa/location_bar/manage_passwords_decoration.h" |
+#include "ui/gfx/mac/coordinate_conversion.h" |
tapted
2017/05/18 03:40:38
remove?
spqchan
2017/05/19 01:47:28
Done.
|
#include "ui/views/bubble/bubble_dialog_delegate.h" |
#include "ui/views/widget/widget_observer.h" |
@@ -17,7 +22,8 @@ namespace { |
// Widget closes. |
class BubbleAnchorHelper : public views::WidgetObserver { |
public: |
- explicit BubbleAnchorHelper(views::BubbleDialogDelegateView* bubble); |
+ BubbleAnchorHelper(views::BubbleDialogDelegateView* bubble, |
+ LocationBarDecoration* decoration); |
private: |
// Observe |name| on the bubble parent window with a block to call ReAnchor(). |
@@ -40,21 +46,41 @@ class BubbleAnchorHelper : public views::WidgetObserver { |
CGFloat horizontal_offset_; // Offset from the left or right. |
CGFloat vertical_offset_; // Offset from the top. |
+ // The omnibox decoration that |bubble_| is anchored to. |
+ // Weak. The lifetime is tied to the controller of the bubble's parent |
+ // window, which owns a LocationBarViewMac that directly owns |decoration_|. |
+ LocationBarDecoration* decoration_; |
+ |
DISALLOW_COPY_AND_ASSIGN(BubbleAnchorHelper); |
}; |
} // namespace |
-void KeepBubbleAnchored(views::BubbleDialogDelegateView* bubble) { |
- new BubbleAnchorHelper(bubble); |
+LocationBarDecoration* GetManagePasswordDecoration( |
+ views::BubbleDialogDelegateView* bubble) { |
+ BrowserWindowController* window_controller = [BrowserWindowController |
+ browserWindowControllerForWindow:[bubble->parent_window() window]]; |
+ LocationBarViewMac* location_bar = [window_controller locationBarBridge]; |
+ return location_bar ? location_bar->manage_passwords_decoration() : nullptr; |
+} |
+ |
+void KeepBubbleAnchored(views::BubbleDialogDelegateView* bubble, |
+ LocationBarDecoration* decoration) { |
+ new BubbleAnchorHelper(bubble, decoration); |
} |
-BubbleAnchorHelper::BubbleAnchorHelper(views::BubbleDialogDelegateView* bubble) |
- : observer_tokens_([[NSMutableArray alloc] init]), bubble_(bubble) { |
+BubbleAnchorHelper::BubbleAnchorHelper(views::BubbleDialogDelegateView* bubble, |
+ LocationBarDecoration* decoration) |
+ : observer_tokens_([[NSMutableArray alloc] init]), |
+ bubble_(bubble), |
+ decoration_(decoration) { |
DCHECK(bubble->GetWidget()); |
DCHECK(bubble->parent_window()); |
bubble->GetWidget()->AddObserver(this); |
+ if (decoration_) |
+ decoration_->SetActive(true); |
+ |
NSRect parent_frame = [[bubble->parent_window() window] frame]; |
NSRect bubble_frame = [bubble->GetWidget()->GetNativeWindow() frame]; |
@@ -102,6 +128,10 @@ void BubbleAnchorHelper::ReAnchor() { |
} |
void BubbleAnchorHelper::OnWidgetDestroying(views::Widget* widget) { |
+ // NativeWidgetMac guarantees that a child's OnWidgetDestroying() is invoked |
+ // before the parent NSWindow has closed. |
+ if (decoration_) |
+ decoration_->SetActive(false); |
widget->RemoveObserver(this); |
for (id token in observer_tokens_.get()) |
[[NSNotificationCenter defaultCenter] removeObserver:token]; |