Index: chrome/browser/ui/cocoa/infobars/infobar_controller.mm |
=================================================================== |
--- chrome/browser/ui/cocoa/infobars/infobar_controller.mm (revision 102604) |
+++ chrome/browser/ui/cocoa/infobars/infobar_controller.mm (working copy) |
@@ -34,10 +34,6 @@ |
// Sets |label_| based on |labelPlaceholder_|, sets |labelPlaceholder_| to nil. |
- (void)initializeLabel; |
-// Asks the container controller to remove the infobar for this delegate. This |
-// call will trigger a notification that starts the infobar animating closed. |
-- (void)removeSelf; |
- |
// Performs final cleanup after an animation is finished or stopped, including |
// notifying the InfoBarDelegate that the infobar was closed and removing the |
// infobar from its container, if necessary. |
@@ -105,6 +101,10 @@ |
return YES; |
} |
+- (BOOL)owned { |
+ return !!owner_; |
+} |
+ |
// Called when someone clicks on the ok button. |
- (void)ok:(id)sender { |
// Subclasses must override this method if they do not hide the ok button. |
@@ -119,12 +119,17 @@ |
// Called when someone clicks on the close button. |
- (void)dismiss:(id)sender { |
- if (delegate_) |
- delegate_->InfoBarDismissed(); |
- |
+ if (![self owned]) |
+ return; |
+ delegate_->InfoBarDismissed(); |
[self removeSelf]; |
} |
+- (void)removeSelf { |
+ DCHECK(owner_); |
+ owner_->infobar_tab_helper()->RemoveInfoBar(delegate_); |
+} |
+ |
- (AnimatableView*)animatableView { |
return static_cast<AnimatableView*>([self view]); |
} |
@@ -165,10 +170,6 @@ |
// currently-running animations, so do not set |infoBarClosing_| until after |
// starting the animation. |
infoBarClosing_ = YES; |
- |
- // The owner called this method to close the infobar, so there will |
- // be no need to forward future remove events to the owner. |
- owner_ = NULL; |
} |
- (void)addAdditionalControls { |
@@ -176,7 +177,7 @@ |
} |
- (void)infobarWillClose { |
- // Default implementation does nothing. |
+ owner_ = NULL; |
} |
- (void)removeButtons { |
@@ -190,6 +191,20 @@ |
[label_.get() setFrame:labelFrame]; |
} |
+- (void)disablePopUpMenu:(NSMenu*)menu { |
+ // Remove the menu if visible. |
+ [menu cancelTracking]; |
+ |
+ // If the menu is re-opened, prevent queries to update items. |
+ [menu setDelegate:nil]; |
+ |
+ // Prevent target/action messages to the controller. |
+ for (NSMenuItem* item in [menu itemArray]) { |
+ [item setEnabled:NO]; |
+ [item setTarget:nil]; |
+ } |
+} |
+ |
@end |
@implementation InfoBarController (PrivateMethods) |
@@ -208,16 +223,6 @@ |
[label_.get() setDelegate:self]; |
} |
-- (void)removeSelf { |
- // TODO(rohitrao): This method can be called even if the infobar has already |
- // been removed and |delegate_| is NULL. Is there a way to rewrite the code |
- // so that inner event loops don't cause us to try and remove the infobar |
- // twice? http://crbug.com/54253 |
- if (owner_) |
- owner_->infobar_tab_helper()->RemoveInfoBar(delegate_); |
- owner_ = NULL; |
-} |
- |
- (void)cleanUpAfterAnimation:(BOOL)finished { |
// Don't need to do any cleanup if the bar was animating open. |
if (!infoBarClosing_) |
@@ -298,20 +303,12 @@ |
// is called by the InfobarTextField on its delegate (the |
// LinkInfoBarController). |
- (void)linkClicked { |
+ if (![self owned]) |
+ return; |
WindowOpenDisposition disposition = |
event_utils::WindowOpenDispositionFromNSEvent([NSApp currentEvent]); |
- if (delegate_ && |
- delegate_->AsLinkInfoBarDelegate()->LinkClicked(disposition)) { |
- // Call |-removeSelf| on the outermost runloop to force a delay. As shown in |
- // <http://crbug.com/87201>, the second click event can be delivered after |
- // the animation finishes (and this gets released and deallocated), which |
- // leads to zombie messaging. Unfortunately, the order between the animation |
- // finishing and the click event being delivered is nondeterministic, so |
- // this hack is the best that can be done. |
- [self performSelector:@selector(removeSelf) |
- withObject:nil |
- afterDelay:0.0]; |
- } |
+ if (delegate_->AsLinkInfoBarDelegate()->LinkClicked(disposition)) |
+ [self removeSelf]; |
} |
@end |
@@ -324,13 +321,17 @@ |
// Called when someone clicks on the "OK" button. |
- (IBAction)ok:(id)sender { |
- if (delegate_ && delegate_->AsConfirmInfoBarDelegate()->Accept()) |
+ if (![self owned]) |
+ return; |
+ if (delegate_->AsConfirmInfoBarDelegate()->Accept()) |
[self removeSelf]; |
} |
// Called when someone clicks on the "Cancel" button. |
- (IBAction)cancel:(id)sender { |
- if (delegate_ && delegate_->AsConfirmInfoBarDelegate()->Cancel()) |
+ if (![self owned]) |
+ return; |
+ if (delegate_->AsConfirmInfoBarDelegate()->Cancel()) |
[self removeSelf]; |
} |
@@ -429,10 +430,11 @@ |
// is called by the InfobarTextField on its delegate (the |
// LinkInfoBarController). |
- (void)linkClicked { |
+ if (![self owned]) |
+ return; |
WindowOpenDisposition disposition = |
event_utils::WindowOpenDispositionFromNSEvent([NSApp currentEvent]); |
- if (delegate_ && |
- delegate_->AsConfirmInfoBarDelegate()->LinkClicked(disposition)) |
+ if (delegate_->AsConfirmInfoBarDelegate()->LinkClicked(disposition)) |
[self removeSelf]; |
} |