summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjrg@chromium.org <jrg@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-06-18 02:19:16 +0000
committerjrg@chromium.org <jrg@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-06-18 02:19:16 +0000
commit8ecf35ac037b7847c280fcbe402c53250db0d53a (patch)
treea3786e63cc2bf461f3a56e1240cb356a68dad3fd
parenta29928fc2e031c55c5f90869d2492a22fa68adc3 (diff)
downloadchromium_src-8ecf35ac037b7847c280fcbe402c53250db0d53a.zip
chromium_src-8ecf35ac037b7847c280fcbe402c53250db0d53a.tar.gz
chromium_src-8ecf35ac037b7847c280fcbe402c53250db0d53a.tar.bz2
When deleting bookmark buttons, make sure all delayed messages
(e.g. for hover-open) are cancelled. TEST=Add 100 bookmarks to the bar. Open overflow menu. Use context menu to delete them. Repeat 100 times. Make sure no crashing. BUG=http://crbug.com/46175 Review URL: http://codereview.chromium.org/2799015 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@50201 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/browser/cocoa/bookmark_bar_controller_unittest.mm51
-rw-r--r--chrome/browser/cocoa/bookmark_bar_folder_controller.mm5
2 files changed, 56 insertions, 0 deletions
diff --git a/chrome/browser/cocoa/bookmark_bar_controller_unittest.mm b/chrome/browser/cocoa/bookmark_bar_controller_unittest.mm
index f26484b..616753e 100644
--- a/chrome/browser/cocoa/bookmark_bar_controller_unittest.mm
+++ b/chrome/browser/cocoa/bookmark_bar_controller_unittest.mm
@@ -7,6 +7,7 @@
#include "app/theme_provider.h"
#include "base/basictypes.h"
#include "base/scoped_nsobject.h"
+#include "base/string_util.h"
#include "base/sys_string_conversions.h"
#import "chrome/browser/cocoa/bookmark_bar_constants.h"
#import "chrome/browser/cocoa/bookmark_bar_controller.h"
@@ -584,6 +585,56 @@ TEST_F(BookmarkBarControllerTest, OffTheSideButtonHidden) {
}
}
+// http://crbug.com/46175 is a crash when deleting bookmarks from the
+// off-the-side menu while it is open. This test tries to bang hard
+// in this area to reproduce the crash.
+TEST_F(BookmarkBarControllerTest, DeleteFromOffTheSideWhileItIsOpen) {
+ BookmarkModel* model = helper_.profile()->GetBookmarkModel();
+ [bar_ setIgnoreAnimations:YES];
+ [bar_ loaded:model];
+
+ // Add a lot of bookmarks (per the bug).
+ const BookmarkNode* parent = model->GetBookmarkBarNode();
+ for (int i = 0; i < 100; i++) {
+ std::ostringstream title;
+ title << "super duper wide title " << i;
+ model->AddURL(parent, parent->GetChildCount(),
+ ASCIIToWide(title.str().c_str()),
+ GURL("http://superfriends.hall-of-justice.edu"));
+ }
+ EXPECT_FALSE([bar_ offTheSideButtonIsHidden]);
+
+ // Open "off the side" menu.
+ NSButton* offTheSideButton = [bar_ offTheSideButton];
+ [bar_ openBookmarkFolderFromButton:offTheSideButton];
+ BookmarkBarFolderController* bbfc = [bar_ folderController];
+ EXPECT_TRUE(bbfc);
+ [bbfc setIgnoreAnimations:YES];
+
+ // Start deleting items; try and delete randomish ones in case it
+ // makes a difference.
+ int indices[] = { 2, 4, 5, 1, 7, 9, 2, 0, 10, 9 };
+ while (parent->GetChildCount()) {
+ for (unsigned int i = 0; i < arraysize(indices); i++) {
+ if (indices[i] < parent->GetChildCount()) {
+ // First we mouse-enter the button to make things harder.
+ NSArray* buttons = [bbfc buttons];
+ for (BookmarkButton* button in buttons) {
+ if ([button bookmarkNode] == parent->GetChild(indices[i])) {
+ [bbfc mouseEnteredButton:button event:nil];
+ break;
+ }
+ }
+ // Then we remove the node. This triggers the button to get
+ // deleted.
+ model->Remove(parent, indices[i]);
+ // Force visual update which is otherwise delayed.
+ [[bbfc window] displayIfNeeded];
+ }
+ }
+ }
+}
+
// Test whether |-dragShouldLockBarVisibility| returns NO iff the bar is
// detached.
TEST_F(BookmarkBarControllerTest, TestDragShouldLockBarVisibility) {
diff --git a/chrome/browser/cocoa/bookmark_bar_folder_controller.mm b/chrome/browser/cocoa/bookmark_bar_folder_controller.mm
index 752ab4b..1d4fa9f 100644
--- a/chrome/browser/cocoa/bookmark_bar_folder_controller.mm
+++ b/chrome/browser/cocoa/bookmark_bar_folder_controller.mm
@@ -1267,6 +1267,11 @@ static BOOL ValueInRangeInclusive(CGFloat low, CGFloat value, CGFloat high) {
NSPoint poofPoint = NSMakePoint(NSMidX(poofFrame), NSMidY(poofFrame));
poofPoint = [oldButton convertPoint:poofPoint toView:nil];
poofPoint = [[oldButton window] convertBaseToScreen:poofPoint];
+
+ // If a hover-open is pending, cancel it.
+ if (oldButton == buttonThatMouseIsIn_)
+ [NSObject cancelPreviousPerformRequestsWithTarget:self];
+
[oldButton removeFromSuperview];
if (animate && !ignoreAnimations_)
NSShowAnimationEffect(NSAnimationEffectDisappearingItemDefault, poofPoint,