Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2533)

Unified Diff: chrome/browser/ui/cocoa/infobars/infobar_controller.mm

Issue 7981045: Make infobars ignore button clicks when closing. (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 9 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/browser/ui/cocoa/infobars/infobar_controller.mm
===================================================================
--- chrome/browser/ui/cocoa/infobars/infobar_controller.mm (revision 103307)
+++ 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)isOwned {
+ 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 isOwned])
+ 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 isOwned])
+ 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 isOwned])
+ 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 isOwned])
+ 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 isOwned])
+ return;
WindowOpenDisposition disposition =
event_utils::WindowOpenDispositionFromNSEvent([NSApp currentEvent]);
- if (delegate_ &&
- delegate_->AsConfirmInfoBarDelegate()->LinkClicked(disposition))
+ if (delegate_->AsConfirmInfoBarDelegate()->LinkClicked(disposition))
[self removeSelf];
}
« no previous file with comments | « chrome/browser/ui/cocoa/infobars/infobar_controller.h ('k') | chrome/browser/ui/cocoa/infobars/infobar_controller_unittest.mm » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698