summaryrefslogtreecommitdiffstats
path: root/chrome/browser
diff options
context:
space:
mode:
authorasvitkine@chromium.org <asvitkine@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-09-01 05:15:52 +0000
committerasvitkine@chromium.org <asvitkine@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-09-01 05:15:52 +0000
commit0fa17dab3c9bc209404313e16594f1eb056ef4a7 (patch)
tree31d1c8343c1578dd10d0d7223ff1c9a601dca919 /chrome/browser
parente27c985875ed6efd260cc42ba6b53f0f3124b7e1 (diff)
downloadchromium_src-0fa17dab3c9bc209404313e16594f1eb056ef4a7.zip
chromium_src-0fa17dab3c9bc209404313e16594f1eb056ef4a7.tar.gz
chromium_src-0fa17dab3c9bc209404313e16594f1eb056ef4a7.tar.bz2
[Mac] Better fix for MenuController ZombieObjectCrash.
Use a |chrome_application_mac::ScopedSendingEvent| to block window close events for the duration of the context menu. In addition, instead of retaining the controller for the duration of the menu being open, close the menu and unset the menu's delegate when the controller is destroyed. BUG=90412 TEST=Using test.close.html from the bug report, open a context menu and wait for the tab to close. When it does, the context menu should be closed and no crash should happen. Also, monitor crash reports to make sure these crashes disappear. Review URL: http://codereview.chromium.org/7812026 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@99130 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser')
-rw-r--r--chrome/browser/tab_contents/render_view_context_menu_mac.mm8
-rw-r--r--chrome/browser/ui/cocoa/menu_controller.h1
-rw-r--r--chrome/browser/ui/cocoa/menu_controller.mm20
3 files changed, 21 insertions, 8 deletions
diff --git a/chrome/browser/tab_contents/render_view_context_menu_mac.mm b/chrome/browser/tab_contents/render_view_context_menu_mac.mm
index 351b511..f7c52be 100644
--- a/chrome/browser/tab_contents/render_view_context_menu_mac.mm
+++ b/chrome/browser/tab_contents/render_view_context_menu_mac.mm
@@ -11,6 +11,7 @@
#include "chrome/app/chrome_command_ids.h"
#import "chrome/browser/ui/cocoa/browser_window_controller.h"
#import "chrome/browser/ui/cocoa/menu_controller.h"
+#import "content/common/chrome_application_mac.h"
#include "grit/generated_resources.h"
// Obj-C bridge class that is the target of all items in the context menu.
@@ -53,6 +54,13 @@ void RenderViewContextMenuMac::PlatformInit() {
// Make sure events can be pumped while the menu is up.
MessageLoop::ScopedNestableTaskAllower allow(MessageLoop::current());
+ // One of the events that could be pumped is |window.close()|.
+ // User-initiated event-tracking loops protect against this by
+ // setting flags in -[CrApplication sendEvent:], but since
+ // web-content menus are initiated by IPC message the setup has to
+ // be done manually.
+ chrome_application_mac::ScopedSendingEvent sendingEventScoper;
+
// Show the menu.
[NSMenu popUpContextMenu:[menuController_ menu]
withEvent:clickEvent
diff --git a/chrome/browser/ui/cocoa/menu_controller.h b/chrome/browser/ui/cocoa/menu_controller.h
index e5a980c..9b20e885 100644
--- a/chrome/browser/ui/cocoa/menu_controller.h
+++ b/chrome/browser/ui/cocoa/menu_controller.h
@@ -26,6 +26,7 @@ class MenuModel;
ui::MenuModel* model_; // weak
scoped_nsobject<NSMenu> menu_;
BOOL useWithPopUpButtonCell_; // If YES, 0th item is blank
+ BOOL isMenuOpen_;
}
@property(nonatomic, assign) ui::MenuModel* model;
diff --git a/chrome/browser/ui/cocoa/menu_controller.mm b/chrome/browser/ui/cocoa/menu_controller.mm
index db931a6..e02b776 100644
--- a/chrome/browser/ui/cocoa/menu_controller.mm
+++ b/chrome/browser/ui/cocoa/menu_controller.mm
@@ -39,6 +39,16 @@
}
- (void)dealloc {
+ [menu_ setDelegate:nil];
+
+ // Close the menu if it is still open. This could happen if a tab gets closed
+ // while its context menu is still open.
+ if (isMenuOpen_) {
+ [menu_ cancelTracking];
+ model_->MenuClosed();
+ isMenuOpen_ = NO;
+ }
+
model_ = NULL;
[super dealloc];
}
@@ -190,19 +200,13 @@
}
- (void)menuWillOpen:(NSMenu*)menu {
- // Retain the controller, which is the menu's delegate, since it needs to be
- // alive for the duration of the menu being open, even if all other owners
- // release it.
- [self retain];
-
+ isMenuOpen_ = YES;
model_->MenuWillShow();
}
- (void)menuDidClose:(NSMenu*)menu {
model_->MenuClosed();
-
- // Release the controller which was retained by -menuWillOpen:.
- [self release];
+ isMenuOpen_ = NO;
}
@end