diff options
Diffstat (limited to 'chrome/browser/cocoa')
109 files changed, 936 insertions, 348 deletions
diff --git a/chrome/browser/cocoa/accelerators_cocoa.h b/chrome/browser/cocoa/accelerators_cocoa.h index b8eaac8..e43c550 100644 --- a/chrome/browser/cocoa/accelerators_cocoa.h +++ b/chrome/browser/cocoa/accelerators_cocoa.h @@ -11,7 +11,7 @@ #include "app/menus/accelerator_cocoa.h" // This class maintains a map of command_ids to AcceleratorCocoa objects (see -// chrome/app/chrome_dll_resource.h). Currently, this only lists the commands +// chrome/app/chrome_command_ids.h). Currently, this only lists the commands // that are used in the Wrench menu. // // It is recommended that this class be used as a singleton so that the key map diff --git a/chrome/browser/cocoa/accelerators_cocoa.mm b/chrome/browser/cocoa/accelerators_cocoa.mm index 86b4bd5..4b1eb5d 100644 --- a/chrome/browser/cocoa/accelerators_cocoa.mm +++ b/chrome/browser/cocoa/accelerators_cocoa.mm @@ -6,7 +6,7 @@ #import <Cocoa/Cocoa.h> -#include "chrome/app/chrome_dll_resource.h" +#include "chrome/app/chrome_command_ids.h" namespace { diff --git a/chrome/browser/cocoa/accelerators_cocoa_unittest.mm b/chrome/browser/cocoa/accelerators_cocoa_unittest.mm index b829351..3f0e307 100644 --- a/chrome/browser/cocoa/accelerators_cocoa_unittest.mm +++ b/chrome/browser/cocoa/accelerators_cocoa_unittest.mm @@ -6,7 +6,7 @@ #include "app/menus/accelerator_cocoa.h" #include "base/singleton.h" -#include "chrome/app/chrome_dll_resource.h" +#include "chrome/app/chrome_command_ids.h" #import "chrome/browser/cocoa/accelerators_cocoa.h" #include "testing/gtest/include/gtest/gtest.h" #include "testing/gtest_mac.h" diff --git a/chrome/browser/cocoa/applescript/window_applescript.mm b/chrome/browser/cocoa/applescript/window_applescript.mm index c51e9d8..07401d3 100644 --- a/chrome/browser/cocoa/applescript/window_applescript.mm +++ b/chrome/browser/cocoa/applescript/window_applescript.mm @@ -11,6 +11,7 @@ #import "chrome/browser/app_controller_mac.h" #include "chrome/browser/browser.h" #include "chrome/browser/browser_list.h" +#include "chrome/browser/browser_navigator.h" #include "chrome/browser/browser_window.h" #import "chrome/browser/chrome_browser_application_mac.h" #include "chrome/browser/cocoa/applescript/constants_applescript.h" @@ -185,13 +186,15 @@ // Set how long it takes a tab to be created. base::TimeTicks newTabStartTime = base::TimeTicks::Now(); - Browser::AddTabWithURLParams params(GURL(chrome::kChromeUINewTabURL), - PageTransition::TYPED); - params.index = index; - TabContents* contents = browser_->AddTabWithURL(¶ms); - contents->set_new_tab_start_time(newTabStartTime); - - [aTab setTabContent:contents]; + browser::NavigateParams params(browser_, + GURL(chrome::kChromeUINewTabURL), + PageTransition::TYPED); + params.disposition = NEW_FOREGROUND_TAB; + params.tabstrip_index = index; + browser::Navigate(¶ms); + params.target_contents->set_new_tab_start_time(newTabStartTime); + + [aTab setTabContent:params.target_contents]; } - (void)removeFromTabsAtIndex:(int)index { diff --git a/chrome/browser/cocoa/base_bubble_controller.h b/chrome/browser/cocoa/base_bubble_controller.h index fc63f0f..7cc2c5b 100644 --- a/chrome/browser/cocoa/base_bubble_controller.h +++ b/chrome/browser/cocoa/base_bubble_controller.h @@ -5,6 +5,11 @@ #import <Cocoa/Cocoa.h> #import "base/cocoa_protocols_mac.h" +#include "base/scoped_ptr.h" + +namespace BaseBubbleControllerInternal { +class Bridge; +} @class InfoBubbleView; @@ -24,6 +29,8 @@ NSWindow* parentWindow_; // weak NSPoint anchor_; IBOutlet InfoBubbleView* bubble_; // to set arrow position + // Bridge that listens for notifications. + scoped_ptr<BaseBubbleControllerInternal::Bridge> base_bridge_; } @property (nonatomic, readonly) NSWindow* parentWindow; diff --git a/chrome/browser/cocoa/base_bubble_controller.mm b/chrome/browser/cocoa/base_bubble_controller.mm index a67bc64..e9804c5 100644 --- a/chrome/browser/cocoa/base_bubble_controller.mm +++ b/chrome/browser/cocoa/base_bubble_controller.mm @@ -10,12 +10,41 @@ #include "base/scoped_nsobject.h" #include "base/string_util.h" #import "chrome/browser/cocoa/info_bubble_view.h" +#include "chrome/common/notification_observer.h" +#include "chrome/common/notification_registrar.h" +#include "chrome/common/notification_service.h" +#include "chrome/common/notification_type.h" #include "grit/generated_resources.h" @interface BaseBubbleController (Private) - (void)updateOriginFromAnchor; @end +namespace BaseBubbleControllerInternal { + +// This bridge listens for notifications so that the bubble closes when a user +// switches tabs (including by opening a new one). +class Bridge : public NotificationObserver { + public: + explicit Bridge(BaseBubbleController* controller) : controller_(controller) { + registrar_.Add(this, NotificationType::TAB_CONTENTS_HIDDEN, + NotificationService::AllSources()); + } + + // NotificationObserver: + virtual void Observe(NotificationType type, + const NotificationSource& source, + const NotificationDetails& details) { + [controller_ close]; + } + + private: + BaseBubbleController* controller_; // Weak, owns this. + NotificationRegistrar registrar_; +}; + +} // namespace BaseBubbleControllerInternal + @implementation BaseBubbleController @synthesize parentWindow = parentWindow_; @@ -62,6 +91,7 @@ if ((self = [super initWithWindow:theWindow])) { parentWindow_ = parentWindow; anchor_ = anchoredAt; + DCHECK(![[self window] delegate]); [theWindow setDelegate:self]; @@ -88,6 +118,8 @@ DCHECK(bubble_); DCHECK_EQ(self, [[self window] delegate]); + base_bridge_.reset(new BaseBubbleControllerInternal::Bridge(self)); + [bubble_ setBubbleType:info_bubble::kWhiteInfoBubble]; [bubble_ setArrowLocation:info_bubble::kTopRight]; } @@ -158,7 +190,7 @@ info_bubble::kBubbleArrowWidth / 2.0, 0); offsets = [[parentWindow_ contentView] convertSize:offsets toView:nil]; if ([bubble_ arrowLocation] == info_bubble::kTopRight) { - origin.x -= NSWidth([window frame]) + offsets.width; + origin.x -= NSWidth([window frame]) - offsets.width; } else { origin.x -= offsets.width; } diff --git a/chrome/browser/cocoa/base_view.h b/chrome/browser/cocoa/base_view.h index c3d49fd..bece608 100644 --- a/chrome/browser/cocoa/base_view.h +++ b/chrome/browser/cocoa/base_view.h @@ -35,4 +35,11 @@ @end +// A notification that a view may issue when it receives first responder status. +// The name is |kViewDidBecomeFirstResponder|, the object is the view, and the +// NSSelectionDirection is wrapped in an NSNumber under the key +// |kSelectionDirection|. +extern NSString* kViewDidBecomeFirstResponder; +extern NSString* kSelectionDirection; + #endif // CHROME_BROWSER_COCOA_BASE_VIEW_H_ diff --git a/chrome/browser/cocoa/base_view.mm b/chrome/browser/cocoa/base_view.mm index 4c9f999..433733e 100644 --- a/chrome/browser/cocoa/base_view.mm +++ b/chrome/browser/cocoa/base_view.mm @@ -4,6 +4,10 @@ #include "chrome/browser/cocoa/base_view.h" +NSString* kViewDidBecomeFirstResponder = + @"Chromium.kViewDidBecomeFirstResponder"; +NSString* kSelectionDirection = @"Chromium.kSelectionDirection"; + @implementation BaseView - (id)initWithFrame:(NSRect)frame { diff --git a/chrome/browser/cocoa/bookmarks/bookmark_bar_controller.h b/chrome/browser/cocoa/bookmarks/bookmark_bar_controller.h index 70f2ea6..6d0a0f6 100644 --- a/chrome/browser/cocoa/bookmarks/bookmark_bar_controller.h +++ b/chrome/browser/cocoa/bookmarks/bookmark_bar_controller.h @@ -13,6 +13,7 @@ #include "base/scoped_nsobject.h" #include "base/scoped_ptr.h" #include "chrome/browser/cocoa/bookmarks/bookmark_bar_bridge.h" +#import "chrome/browser/cocoa/bookmarks/bookmark_bar_constants.h" #import "chrome/browser/cocoa/bookmarks/bookmark_bar_state.h" #import "chrome/browser/cocoa/bookmarks/bookmark_bar_toolbar_view.h" #import "chrome/browser/cocoa/bookmarks/bookmark_button.h" @@ -43,14 +44,33 @@ namespace bookmarks { // Used as a maximum width for buttons on the bar. const CGFloat kDefaultBookmarkWidth = 150.0; -// TODO(jrg): http://crbug.com/36276 to get final sizes. +// Horizontal frame inset for buttons in the bookmark bar. +const CGFloat kBookmarkHorizontalPadding = 1.0; + +// Vertical frame inset for buttons in the bookmark bar. +const CGFloat kBookmarkVerticalPadding = 2.0; + // Used as a min/max width for buttons on menus (not on the bar). const CGFloat kBookmarkMenuButtonMinimumWidth = 100.0; const CGFloat kBookmarkMenuButtonMaximumWidth = 485.0; -const CGFloat kBookmarkVerticalPadding = 2.0; -const CGFloat kBookmarkHorizontalPadding = 1.0; +// Horizontal separation between a menu button and both edges of its menu. const CGFloat kBookmarkSubMenuHorizontalPadding = 5.0; + +// TODO(mrossetti): Add constant (kBookmarkVerticalSeparation) for the gap +// between buttons in a folder menu. Right now we're using +// kBookmarkVerticalPadding, which is dual purpose and wrong. +// http://crbug.com/59057 + +// Convenience constant giving the vertical distance from the top extent of one +// folder button to the next button. +const CGFloat kBookmarkButtonVerticalSpan = + kBookmarkButtonHeight + kBookmarkVerticalPadding; + +// The minimum separation between a folder menu and the edge of the screen. +// If the menu gets closer to the edge of the screen (either right or left) +// then it is pops up in the opposite direction. +// (See -[BookmarkBarFolderController childFolderWindowLeftForWidth:]). const CGFloat kBookmarkHorizontalScreenPadding = 8.0; // Our NSScrollView is supposed to be just barely big enough to fit its diff --git a/chrome/browser/cocoa/bookmarks/bookmark_bar_controller.mm b/chrome/browser/cocoa/bookmarks/bookmark_bar_controller.mm index 63cc171..03e867e 100644 --- a/chrome/browser/cocoa/bookmarks/bookmark_bar_controller.mm +++ b/chrome/browser/cocoa/bookmarks/bookmark_bar_controller.mm @@ -15,7 +15,6 @@ #include "chrome/browser/browser_list.h" #import "chrome/browser/cocoa/background_gradient_view.h" #import "chrome/browser/cocoa/bookmarks/bookmark_bar_bridge.h" -#import "chrome/browser/cocoa/bookmarks/bookmark_bar_constants.h" #import "chrome/browser/cocoa/bookmarks/bookmark_bar_folder_controller.h" #import "chrome/browser/cocoa/bookmarks/bookmark_bar_folder_window.h" #import "chrome/browser/cocoa/bookmarks/bookmark_bar_toolbar_view.h" diff --git a/chrome/browser/cocoa/bookmarks/bookmark_bar_folder_controller.mm b/chrome/browser/cocoa/bookmarks/bookmark_bar_folder_controller.mm index ca1514c..6eaca1a 100644 --- a/chrome/browser/cocoa/bookmarks/bookmark_bar_folder_controller.mm +++ b/chrome/browser/cocoa/bookmarks/bookmark_bar_folder_controller.mm @@ -27,13 +27,11 @@ const NSTimeInterval kBookmarkBarFolderScrollInterval = 0.1; // Amount to scroll by per timer fire. We scroll rather slowly; to // accomodate we do several at a time. const CGFloat kBookmarkBarFolderScrollAmount = - 3 * (bookmarks::kBookmarkButtonHeight + - bookmarks::kBookmarkVerticalPadding); + 3 * bookmarks::kBookmarkButtonVerticalSpan; // Amount to scroll for each scroll wheel delta. const CGFloat kBookmarkBarFolderScrollWheelAmount = - 1 * (bookmarks::kBookmarkButtonHeight + - bookmarks::kBookmarkVerticalPadding); + 1 * bookmarks::kBookmarkButtonVerticalSpan; // When constraining a scrolling bookmark bar folder window to the // screen, shrink the "constrain" by this much vertically. Currently @@ -387,8 +385,7 @@ const CGFloat kScrollWindowVerticalMargin = 0.0; } - (int)windowHeightForButtonCount:(int)buttonCount { - return (buttonCount * (bookmarks::kBookmarkButtonHeight + - bookmarks::kBookmarkVerticalPadding)) + + return (buttonCount * bookmarks::kBookmarkButtonVerticalSpan) + bookmarks::kBookmarkVerticalPadding; } @@ -475,8 +472,7 @@ const CGFloat kScrollWindowVerticalMargin = 0.0; // http://crbug.com/35966 NSRect buttonsOuterFrame = NSMakeRect( bookmarks::kBookmarkSubMenuHorizontalPadding, - (height - - (bookmarks::kBookmarkButtonHeight + bookmarks::kBookmarkVerticalPadding)), + (height - bookmarks::kBookmarkButtonVerticalSpan), bookmarks::kDefaultBookmarkWidth, bookmarks::kBookmarkButtonHeight); @@ -498,8 +494,7 @@ const CGFloat kScrollWindowVerticalMargin = 0.0; frame:buttonsOuterFrame]; [buttons_ addObject:button]; [mainView_ addSubview:button]; - buttonsOuterFrame.origin.y -= (bookmarks::kBookmarkButtonHeight + - bookmarks::kBookmarkVerticalPadding); + buttonsOuterFrame.origin.y -= bookmarks::kBookmarkButtonVerticalSpan; } } @@ -886,8 +881,6 @@ static BOOL ValueInRangeInclusive(CGFloat low, CGFloat value, CGFloat high) { // bookmark_bar_controller.mm, but vertical instead of horizontal. // Generalize to be axis independent then share code. // http://crbug.com/35966 -// Get UI review on "middle half" ness. -// http://crbug.com/36276 - (BookmarkButton*)buttonForDroppingOnAtPoint:(NSPoint)point { for (BookmarkButton* button in buttons_.get()) { // No early break -- makes no assumption about button ordering. @@ -1252,8 +1245,11 @@ static BOOL ValueInRangeInclusive(CGFloat low, CGFloat value, CGFloat high) { - (void)addButtonForNode:(const BookmarkNode*)node atIndex:(NSInteger)buttonIndex { - // Propose the frame for the new button. - NSRect newButtonFrame = NSMakeRect(0, 0, 500, 500); // Placeholder values. + // Propose the frame for the new button. By default, this will be set to the + // topmost button's frame (and there will always be one) offset upward in + // anticipation of insertion. + NSRect newButtonFrame = [[buttons_ objectAtIndex:0] frame]; + newButtonFrame.origin.y += bookmarks::kBookmarkButtonVerticalSpan; // When adding a button to an empty folder we must remove the 'empty' // placeholder button. This can be detected by checking for a parent // child count of 1. @@ -1277,8 +1273,7 @@ static BOOL ValueInRangeInclusive(CGFloat low, CGFloat value, CGFloat high) { // which is where the new button will be located. newButtonFrame = [button frame]; NSRect buttonFrame = [button frame]; - buttonFrame.origin.y += bookmarks::kBookmarkBarHeight + - bookmarks::kBookmarkVerticalPadding; + buttonFrame.origin.y += bookmarks::kBookmarkButtonVerticalSpan; [button setFrame:buttonFrame]; } [[button cell] mouseExited:nil]; // De-highlight. @@ -1352,8 +1347,7 @@ static BOOL ValueInRangeInclusive(CGFloat low, CGFloat value, CGFloat high) { for (NSInteger i = fromIndex; i < toIndex; ++i) { BookmarkButton* button = [buttons_ objectAtIndex:i]; NSRect frame = [button frame]; - frame.origin.y += bookmarks::kBookmarkBarHeight + - bookmarks::kBookmarkVerticalPadding; + frame.origin.y += bookmarks::kBookmarkButtonVerticalSpan; [button setFrameOrigin:frame.origin]; } } else { @@ -1362,8 +1356,7 @@ static BOOL ValueInRangeInclusive(CGFloat low, CGFloat value, CGFloat high) { for (NSInteger i = fromIndex - 1; i >= toIndex; --i) { BookmarkButton* button = [buttons_ objectAtIndex:i]; NSRect buttonFrame = [button frame]; - buttonFrame.origin.y -= bookmarks::kBookmarkBarHeight + - bookmarks::kBookmarkVerticalPadding; + buttonFrame.origin.y -= bookmarks::kBookmarkButtonVerticalSpan; [button setFrameOrigin:buttonFrame.origin]; } } @@ -1408,8 +1401,7 @@ static BOOL ValueInRangeInclusive(CGFloat low, CGFloat value, CGFloat high) { for (NSInteger i = 0; i < buttonIndex; ++i) { BookmarkButton* button = [buttons_ objectAtIndex:i]; NSRect buttonFrame = [button frame]; - buttonFrame.origin.y -= bookmarks::kBookmarkButtonHeight + - bookmarks::kBookmarkVerticalPadding; + buttonFrame.origin.y -= bookmarks::kBookmarkButtonVerticalSpan; [button setFrame:buttonFrame]; } // Search for and adjust submenus, if necessary. diff --git a/chrome/browser/cocoa/bookmarks/bookmark_bar_folder_controller_unittest.mm b/chrome/browser/cocoa/bookmarks/bookmark_bar_folder_controller_unittest.mm index 293aff1..ee9ccb8 100644 --- a/chrome/browser/cocoa/bookmarks/bookmark_bar_folder_controller_unittest.mm +++ b/chrome/browser/cocoa/bookmarks/bookmark_bar_folder_controller_unittest.mm @@ -24,12 +24,32 @@ // Add a redirect to make testing easier. @interface BookmarkBarFolderController(MakeTestingEasier) - (IBAction)openBookmarkFolderFromButton:(id)sender; +- (void)validateMenuSpacing; @end @implementation BookmarkBarFolderController(MakeTestingEasier) - (IBAction)openBookmarkFolderFromButton:(id)sender { [[self folderTarget] openBookmarkFolderFromButton:sender]; } + +// Utility function to verify that the buttons in this folder are all +// evenly spaced in a progressive manner. +- (void)validateMenuSpacing { + BOOL firstButton = YES; + CGFloat lastVerticalOffset = 0.0; + for (BookmarkButton* button in [self buttons]) { + if (firstButton) { + firstButton = NO; + lastVerticalOffset = [button frame].origin.y; + } else { + CGFloat nextVerticalOffset = [button frame].origin.y; + EXPECT_CGFLOAT_EQ(lastVerticalOffset - + bookmarks::kBookmarkButtonVerticalSpan, + nextVerticalOffset); + lastVerticalOffset = nextVerticalOffset; + } + } +} @end // Don't use a high window level when running unit tests -- it'll @@ -709,6 +729,9 @@ TEST_F(BookmarkBarFolderControllerMenuTest, DragMoveBarBookmarkToFolder) { expectedToWindowFrame.size.height += diff; EXPECT_NSRECT_EQ(expectedToWindowFrame, newToWindowFrame); + // Check button spacing. + [folderController validateMenuSpacing]; + // Move the button back to the bar at the beginning. draggedButton = [folderController buttonWithTitleEqualTo:@"1b"]; ASSERT_TRUE(draggedButton); @@ -836,6 +859,10 @@ TEST_F(BookmarkBarFolderControllerMenuTest, DragMoveBarBookmarkToSubfolder) { "4f2f1b 4f2f2b 4f2f3b 5b ] 4f3f:[ 4f3f1b 4f3f2b 4f3f3b ] ] "); EXPECT_EQ(expected_string, model_test_utils::ModelStringFromNode(root)); + // Check button spacing. + [folderController validateMenuSpacing]; + [subfolderController validateMenuSpacing]; + // Check the window layouts. The folder window should not have changed, // but the subfolder window should have shifted vertically and grown. NSRect newToWindowFrame = [toWindow frame]; @@ -893,6 +920,9 @@ TEST_F(BookmarkBarFolderControllerMenuTest, DragMoveWithinFolder) { // The folder window should not have changed. NSRect newToWindowFrame = [toWindow frame]; EXPECT_NSRECT_EQ(oldToWindowFrame, newToWindowFrame); + + // Check button spacing. + [folderController validateMenuSpacing]; } TEST_F(BookmarkBarFolderControllerMenuTest, DragParentOntoChild) { @@ -927,6 +957,9 @@ TEST_F(BookmarkBarFolderControllerMenuTest, DragParentOntoChild) { copy:NO]; // The model should not have changed. EXPECT_EQ(model_string, model_test_utils::ModelStringFromNode(root)); + + // Check button spacing. + [folderController validateMenuSpacing]; } TEST_F(BookmarkBarFolderControllerMenuTest, DragMoveChildToParent) { @@ -973,6 +1006,8 @@ TEST_F(BookmarkBarFolderControllerMenuTest, DragMoveChildToParent) { "4f2f1b 4f2f2b ] 4f3f:[ 4f3f1b 4f3f2b 4f3f3b ] ] 5b "); EXPECT_EQ(expected_string, model_test_utils::ModelStringFromNode(root)); + // Check button spacing. + [folderController validateMenuSpacing]; // The window should not have gone away. EXPECT_TRUE([bar_ folderController]); // The subfolder should have gone away. @@ -1077,6 +1112,9 @@ TEST_F(BookmarkBarFolderControllerMenuTest, MoveRemoveAddButtons) { EXPECT_NSEQ(@"2f2b", [[buttons objectAtIndex:1] title]); EXPECT_NSEQ(@"2f3b", [[buttons objectAtIndex:2] title]); EXPECT_EQ(oldDisplayedButtons, [buttons count]); + + // Check button spacing. + [folder validateMenuSpacing]; } TEST_F(BookmarkBarFolderControllerMenuTest, ControllerForNode) { @@ -1199,6 +1237,9 @@ TEST_F(BookmarkBarFolderControllerMenuTest, MenuSizingAndScrollArrows) { // Check the size. It should have reduced. EXPECT_GT(menuWidth, NSWidth([folderMenu frame])); EXPECT_GT(buttonWidth, NSWidth([button frame])); + + // Check button spacing. + [folderController validateMenuSpacing]; } // See http://crbug.com/46101 @@ -1324,6 +1365,9 @@ TEST_F(BookmarkBarFolderControllerMenuTest, DragBookmarkData) { "2f3b ] 3b 4b "); actual = model_test_utils::ModelStringFromNode(root); EXPECT_EQ(expectedA, actual); + + // Check button spacing. + [folderController validateMenuSpacing]; } TEST_F(BookmarkBarFolderControllerMenuTest, DragBookmarkDataToTrash) { @@ -1363,6 +1407,9 @@ TEST_F(BookmarkBarFolderControllerMenuTest, DragBookmarkDataToTrash) { "2f3b ] 3b 4b "); actual = model_test_utils::ModelStringFromNode(root); EXPECT_EQ(expected, actual); + + // Check button spacing. + [folderController validateMenuSpacing]; } TEST_F(BookmarkBarFolderControllerMenuTest, AddURLs) { @@ -1405,6 +1452,9 @@ TEST_F(BookmarkBarFolderControllerMenuTest, AddURLs) { "2f2f3b ] 2f3b ] 3b 4b "); actual = model_test_utils::ModelStringFromNode(root); EXPECT_EQ(expected, actual); + + // Check button spacing. + [folderController validateMenuSpacing]; } TEST_F(BookmarkBarFolderControllerMenuTest, DropPositionIndicator) { diff --git a/chrome/browser/cocoa/bookmarks/bookmark_menu_bridge_unittest.mm b/chrome/browser/cocoa/bookmarks/bookmark_menu_bridge_unittest.mm index 4be2067..c2f9026 100644 --- a/chrome/browser/cocoa/bookmarks/bookmark_menu_bridge_unittest.mm +++ b/chrome/browser/cocoa/bookmarks/bookmark_menu_bridge_unittest.mm @@ -8,7 +8,7 @@ #include "base/string16.h" #include "base/string_util.h" #include "base/utf_string_conversions.h" -#include "chrome/app/chrome_dll_resource.h" +#include "chrome/app/chrome_command_ids.h" #include "chrome/browser/bookmarks/bookmark_model.h" #include "chrome/browser/browser.h" #include "chrome/browser/cocoa/bookmarks/bookmark_menu_bridge.h" diff --git a/chrome/browser/cocoa/bookmarks/bookmark_menu_cocoa_controller.mm b/chrome/browser/cocoa/bookmarks/bookmark_menu_cocoa_controller.mm index 534ae66..439bb2c 100644 --- a/chrome/browser/cocoa/bookmarks/bookmark_menu_cocoa_controller.mm +++ b/chrome/browser/cocoa/bookmarks/bookmark_menu_cocoa_controller.mm @@ -7,7 +7,7 @@ #include "app/text_elider.h" #include "base/sys_string_conversions.h" #include "base/utf_string_conversions.h" -#include "chrome/app/chrome_dll_resource.h" // IDC_BOOKMARK_MENU +#include "chrome/app/chrome_command_ids.h" // IDC_BOOKMARK_MENU #import "chrome/browser/app_controller_mac.h" #include "chrome/browser/bookmarks/bookmark_model.h" #include "chrome/browser/browser.h" diff --git a/chrome/browser/cocoa/browser_window_cocoa.h b/chrome/browser/cocoa/browser_window_cocoa.h index 9747178..9a46f7d 100644 --- a/chrome/browser/cocoa/browser_window_cocoa.h +++ b/chrome/browser/cocoa/browser_window_cocoa.h @@ -6,6 +6,7 @@ #define CHROME_BROWSER_COCOA_BROWSER_WINDOW_COCOA_H_ #pragma once +#include "base/scoped_nsobject.h" #include "base/task.h" #include "chrome/browser/browser_window.h" #include "chrome/browser/bookmarks/bookmark_model.h" @@ -134,6 +135,7 @@ class BrowserWindowCocoa : public BrowserWindow, Browser* browser_; // weak, owned by controller BrowserWindowController* controller_; // weak, owns us ScopedRunnableMethodFactory<Browser> confirm_close_factory_; + scoped_nsobject<NSString> pending_window_title_; }; #endif // CHROME_BROWSER_COCOA_BROWSER_WINDOW_COCOA_H_ diff --git a/chrome/browser/cocoa/browser_window_cocoa.mm b/chrome/browser/cocoa/browser_window_cocoa.mm index 2203240..5e21af0 100644 --- a/chrome/browser/cocoa/browser_window_cocoa.mm +++ b/chrome/browser/cocoa/browser_window_cocoa.mm @@ -9,7 +9,7 @@ #include "base/logging.h" #include "base/message_loop.h" #include "base/sys_string_conversions.h" -#include "chrome/app/chrome_dll_resource.h" +#include "chrome/app/chrome_command_ids.h" #include "chrome/browser/bookmarks/bookmark_utils.h" #include "chrome/browser/browser.h" #include "chrome/browser/browser_list.h" @@ -151,7 +151,24 @@ void BrowserWindowCocoa::UpdateTitleBar() { NSString* newTitle = base::SysUTF16ToNSString(browser_->GetWindowTitleForCurrentTab()); - [window() setTitle:newTitle]; + // Work around Cocoa bug: if a window changes title during the tracking of the + // Window menu it doesn't display well and the constant re-sorting of the list + // makes it difficult for the user to pick the desired window. Delay window + // title updates until the default run-loop mode. + + if (pending_window_title_.get()) + [[NSRunLoop currentRunLoop] + cancelPerformSelector:@selector(setTitle:) + target:window() + argument:pending_window_title_.get()]; + + pending_window_title_.reset([newTitle copy]); + [[NSRunLoop currentRunLoop] + performSelector:@selector(setTitle:) + target:window() + argument:newTitle + order:0 + modes:[NSArray arrayWithObject:NSDefaultRunLoopMode]]; } void BrowserWindowCocoa::ShelfVisibilityChanged() { diff --git a/chrome/browser/cocoa/browser_window_controller.h b/chrome/browser/cocoa/browser_window_controller.h index efa49ab..39bd9c4 100644 --- a/chrome/browser/cocoa/browser_window_controller.h +++ b/chrome/browser/cocoa/browser_window_controller.h @@ -217,7 +217,7 @@ class TabContents; // Executes the command in the context of the current browser. // |command| is an integer value containing one of the constants defined in the -// "chrome/app/chrome_dll_resource.h" file. +// "chrome/app/chrome_command_ids.h" file. - (void)executeCommand:(int)command; // Delegate method for the status bubble to query its base frame. diff --git a/chrome/browser/cocoa/browser_window_controller.mm b/chrome/browser/cocoa/browser_window_controller.mm index dc9f400..0e39267 100644 --- a/chrome/browser/cocoa/browser_window_controller.mm +++ b/chrome/browser/cocoa/browser_window_controller.mm @@ -13,7 +13,7 @@ #include "base/nsimage_cache_mac.h" #import "base/scoped_nsobject.h" #include "base/sys_string_conversions.h" -#include "chrome/app/chrome_dll_resource.h" // IDC_* +#include "chrome/app/chrome_command_ids.h" // IDC_* #include "chrome/browser/bookmarks/bookmark_editor.h" #include "chrome/browser/browser.h" #include "chrome/browser/browser_list.h" @@ -1887,6 +1887,9 @@ willAnimateFromState:(bookmarks::VisualState)oldState if (statusBubble_) statusBubble_->SwitchParentWindow(destWindow); + // Move the title over. + [destWindow setTitle:[window title]]; + // The window needs to be onscreen before we can set its first responder. [destWindow makeKeyAndOrderFront:self]; [focusTracker restoreFocusInWindow:destWindow]; diff --git a/chrome/browser/cocoa/browser_window_controller_unittest.mm b/chrome/browser/cocoa/browser_window_controller_unittest.mm index a6fda62..4e3a5ac 100644 --- a/chrome/browser/cocoa/browser_window_controller_unittest.mm +++ b/chrome/browser/cocoa/browser_window_controller_unittest.mm @@ -5,7 +5,7 @@ #include "app/l10n_util_mac.h" #include "base/scoped_nsobject.h" #include "base/scoped_ptr.h" -#include "chrome/app/chrome_dll_resource.h" +#include "chrome/app/chrome_command_ids.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/browser_window.h" #include "chrome/browser/cocoa/browser_test_helper.h" diff --git a/chrome/browser/cocoa/chrome_browser_window_unittest.mm b/chrome/browser/cocoa/chrome_browser_window_unittest.mm index 2b82f79..fc39ccd 100644 --- a/chrome/browser/cocoa/chrome_browser_window_unittest.mm +++ b/chrome/browser/cocoa/chrome_browser_window_unittest.mm @@ -4,6 +4,7 @@ #import <Cocoa/Cocoa.h> +#include "base/debug/debugger.h" #import "chrome/browser/cocoa/chrome_browser_window.h" #import "chrome/browser/cocoa/cocoa_test_helper.h" #include "testing/gtest/include/gtest/gtest.h" @@ -22,7 +23,7 @@ class ChromeBrowserWindowTest : public CocoaTest { styleMask:mask backing:NSBackingStoreBuffered defer:NO]; - if (DebugUtil::BeingDebugged()) { + if (base::debug::BeingDebugged()) { [window_ orderFront:nil]; } else { [window_ orderBack:nil]; diff --git a/chrome/browser/cocoa/chrome_event_processing_window_unittest.mm b/chrome/browser/cocoa/chrome_event_processing_window_unittest.mm index 1b54dcb..ebcd3f3 100644 --- a/chrome/browser/cocoa/chrome_event_processing_window_unittest.mm +++ b/chrome/browser/cocoa/chrome_event_processing_window_unittest.mm @@ -2,9 +2,9 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. - +#include "base/debug/debugger.h" #include "base/scoped_nsobject.h" -#include "chrome/app/chrome_dll_resource.h" +#include "chrome/app/chrome_command_ids.h" #import "chrome/browser/cocoa/chrome_event_processing_window.h" #import "chrome/browser/cocoa/browser_window_controller.h" #import "chrome/browser/cocoa/browser_frame_view.h" @@ -38,7 +38,7 @@ class ChromeEventProcessingWindowTest : public CocoaTest { styleMask:mask backing:NSBackingStoreBuffered defer:NO]; - if (DebugUtil::BeingDebugged()) { + if (base::debug::BeingDebugged()) { [window_ orderFront:nil]; } else { [window_ orderBack:nil]; diff --git a/chrome/browser/cocoa/cocoa_test_helper.mm b/chrome/browser/cocoa/cocoa_test_helper.mm index 136412b..885a88a 100644 --- a/chrome/browser/cocoa/cocoa_test_helper.mm +++ b/chrome/browser/cocoa/cocoa_test_helper.mm @@ -4,6 +4,7 @@ #import "chrome/browser/cocoa/cocoa_test_helper.h" +#include "base/debug/debugger.h" #include "base/logging.h" #include "base/test/test_timeouts.h" #import "chrome/browser/chrome_browser_application_mac.h" @@ -49,9 +50,19 @@ CocoaTest::CocoaTest() : called_tear_down_(false), test_window_(nil) { BootstrapCocoa(); + // Set the duration of AppKit-evaluated animations (such as frame changes) // to zero for testing purposes. That way they take effect immediately. [[NSAnimationContext currentContext] setDuration:0.0]; + + // The above does not affect window-resize time, such as for an + // attached sheet dropping in. Set that duration for the current + // process (this is not persisted). Empirically, the value of 0.0 + // is ignored. + NSDictionary* dict = + [NSDictionary dictionaryWithObject:@"0.01" forKey:@"NSWindowResizeTime"]; + [[NSUserDefaults standardUserDefaults] registerDefaults:dict]; + // Collect the list of windows that were open when the test started so // that we don't wait for them to close in TearDown. Has to be done // after BootstrapCocoa is called. @@ -184,7 +195,7 @@ std::set<NSWindow*> CocoaTest::WindowsLeft() { CocoaTestHelperWindow* CocoaTest::test_window() { if (!test_window_) { test_window_ = [[CocoaTestHelperWindow alloc] init]; - if (DebugUtil::BeingDebugged()) { + if (base::debug::BeingDebugged()) { [test_window_ orderFront:nil]; } else { [test_window_ orderBack:nil]; diff --git a/chrome/browser/cocoa/confirm_quit_panel_controller.h b/chrome/browser/cocoa/confirm_quit_panel_controller.h new file mode 100644 index 0000000..c518222 --- /dev/null +++ b/chrome/browser/cocoa/confirm_quit_panel_controller.h @@ -0,0 +1,24 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#import <Cocoa/Cocoa.h> + +#include "base/cocoa_protocols_mac.h" + +// The ConfirmQuitPanelController manages the black HUD window that tells users +// to "Hold Cmd+Q to Quit". +@interface ConfirmQuitPanelController : NSWindowController<NSWindowDelegate> { +} + +// Designated initializer. Loads window from NIB but does not show it. +- (id)init; + +// Shows the window. +- (void)showWindow:(id)sender; + +// If the user did not confirm quit, send this message to give the user +// instructions on how to quit. +- (void)dismissPanel; + +@end diff --git a/chrome/browser/cocoa/confirm_quit_panel_controller.mm b/chrome/browser/cocoa/confirm_quit_panel_controller.mm new file mode 100644 index 0000000..5b624dd --- /dev/null +++ b/chrome/browser/cocoa/confirm_quit_panel_controller.mm @@ -0,0 +1,69 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#import <Cocoa/Cocoa.h> +#import <QuartzCore/QuartzCore.h> + +#include "base/logging.h" +#include "base/mac_util.h" +#include "base/scoped_nsobject.h" +#import "chrome/browser/cocoa/confirm_quit_panel_controller.h" + +@interface ConfirmQuitPanelController (Private) +- (void)animateFadeOut; +@end + +@implementation ConfirmQuitPanelController + +- (id)init { + NSString* nibPath = + [mac_util::MainAppBundle() pathForResource:@"ConfirmQuitPanel" + ofType:@"nib"]; + if ((self = [super initWithWindowNibPath:nibPath owner:self])) { + } + return self; +} + +- (void)awakeFromNib { + DCHECK([self window]); + DCHECK_EQ(self, [[self window] delegate]); +} + +- (void)windowWillClose:(NSNotification*)notif { + // Release all animations because CAAnimation retains its delegate (self), + // which will cause a retain cycle. Break it! + [[self window] setAnimations:[NSDictionary dictionary]]; + [self autorelease]; +} + +- (void)showWindow:(id)sender { + [[self window] center]; + [[self window] setAlphaValue:1.0]; + [super showWindow:sender]; +} + +- (void)dismissPanel { + [self performSelector:@selector(animateFadeOut) + withObject:nil + afterDelay:1.0]; +} + +- (void)animateFadeOut { + NSWindow* window = [self window]; + scoped_nsobject<CAAnimation> animation( + [[window animationForKey:@"alphaValue"] copy]); + [animation setDelegate:self]; + [animation setDuration:0.2]; + NSMutableDictionary* dictionary = + [NSMutableDictionary dictionaryWithDictionary:[window animations]]; + [dictionary setObject:animation forKey:@"alphaValue"]; + [window setAnimations:dictionary]; + [[window animator] setAlphaValue:0.0]; +} + +- (void)animationDidStop:(CAAnimation*)theAnimation finished:(BOOL)flag { + [self close]; +} + +@end diff --git a/chrome/browser/cocoa/confirm_quit_panel_controller_unittest.mm b/chrome/browser/cocoa/confirm_quit_panel_controller_unittest.mm new file mode 100644 index 0000000..fddf164 --- /dev/null +++ b/chrome/browser/cocoa/confirm_quit_panel_controller_unittest.mm @@ -0,0 +1,26 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/cocoa/confirm_quit_panel_controller.h" + +#import "chrome/browser/cocoa/cocoa_test_helper.h" + +namespace { + +class ConfirmQuitPanelControllerTest : public CocoaTest { + public: + ConfirmQuitPanelControllerTest() : controller_(nil) { + } + + ConfirmQuitPanelController* controller_; // Weak, owns self. +}; + + +TEST_F(ConfirmQuitPanelControllerTest, ShowAndDismiss) { + controller_ = [[ConfirmQuitPanelController alloc] init]; + [controller_ showWindow:nil]; + [controller_ dismissPanel]; // Releases self. +} + +} // namespace diff --git a/chrome/browser/cocoa/constrained_html_delegate_mac.mm b/chrome/browser/cocoa/constrained_html_delegate_mac.mm index 22d4558..efb228a 100644 --- a/chrome/browser/cocoa/constrained_html_delegate_mac.mm +++ b/chrome/browser/cocoa/constrained_html_delegate_mac.mm @@ -29,7 +29,7 @@ class ConstrainedHtmlDelegateMac : // your delegate in this method." if (is_sheet_open()) [NSApp endSheet:sheet()]; - + html_delegate_->OnDialogClosed(""); delete this; } diff --git a/chrome/browser/cocoa/content_setting_bubble_cocoa.mm b/chrome/browser/cocoa/content_setting_bubble_cocoa.mm index f5e7e93..dda55f5 100644 --- a/chrome/browser/cocoa/content_setting_bubble_cocoa.mm +++ b/chrome/browser/cocoa/content_setting_bubble_cocoa.mm @@ -437,6 +437,8 @@ NSTextField* LabelWithFrame(NSString* text, const NSRect& frame) { } - (void)awakeFromNib { + [super awakeFromNib]; + [[self bubble] setBubbleType:info_bubble::kWhiteInfoBubble]; [[self bubble] setArrowLocation:info_bubble::kTopRight]; diff --git a/chrome/browser/cocoa/content_setting_bubble_cocoa_unittest.mm b/chrome/browser/cocoa/content_setting_bubble_cocoa_unittest.mm index c42520d..3485782 100644 --- a/chrome/browser/cocoa/content_setting_bubble_cocoa_unittest.mm +++ b/chrome/browser/cocoa/content_setting_bubble_cocoa_unittest.mm @@ -6,6 +6,7 @@ #import <Cocoa/Cocoa.h> +#include "base/debug/debugger.h" #include "base/scoped_nsobject.h" #import "chrome/browser/cocoa/cocoa_test_helper.h" #include "chrome/browser/content_setting_bubble_model.h" @@ -42,7 +43,7 @@ TEST_F(ContentSettingBubbleControllerTest, Init) { backing:NSBackingStoreBuffered defer:NO]); [parent setReleasedWhenClosed:NO]; - if (DebugUtil::BeingDebugged()) + if (base::debug::BeingDebugged()) [parent.get() orderFront:nil]; else [parent.get() orderBack:nil]; diff --git a/chrome/browser/cocoa/cookie_details.h b/chrome/browser/cocoa/cookie_details.h index 5298ad8..614c87c 100644 --- a/chrome/browser/cocoa/cookie_details.h +++ b/chrome/browser/cocoa/cookie_details.h @@ -83,9 +83,8 @@ enum CocoaCookieDetailsType { // kCocoaCookieDetailsTypeTreeAppCache nodes. scoped_nsobject<NSString> created_; - // Only set for types kCocoaCookieDetailsTypeCookie, - // kCocoaCookieDetailsTypePromptDatabase, and - // kCocoaCookieDetailsTypeTreeIndexedDB nodes. + // Only set for types kCocoaCookieDetailsTypeCookie, and + // kCocoaCookieDetailsTypePromptDatabase nodes. scoped_nsobject<NSString> name_; // Only set for type kCocoaCookieDetailsTypeTreeLocalStorage, diff --git a/chrome/browser/cocoa/cookie_details.mm b/chrome/browser/cocoa/cookie_details.mm index 4c483d1..b60e005 100644 --- a/chrome/browser/cocoa/cookie_details.mm +++ b/chrome/browser/cocoa/cookie_details.mm @@ -248,7 +248,6 @@ lastModified_.reset([base::SysWideToNSString( base::TimeFormatFriendlyDateAndTime( indexedDBInfo->last_modified)) retain]); - name_.reset([base::SysUTF8ToNSString(indexedDBInfo->database_name) retain]); } return self; } diff --git a/chrome/browser/cocoa/cookie_details_unittest.mm b/chrome/browser/cocoa/cookie_details_unittest.mm index 897d92a..305c0f9 100644 --- a/chrome/browser/cocoa/cookie_details_unittest.mm +++ b/chrome/browser/cocoa/cookie_details_unittest.mm @@ -145,7 +145,6 @@ TEST_F(CookiesDetailsTest, CreateForTreeIndexedDB) { unsigned short port = 80; std::string database_identifier("id"); std::string origin("moose.org"); - std::string name("name"); FilePath file_path(FILE_PATH_LITERAL("/")); int64 size = 1234; base::Time last_modified = base::Time::Now(); @@ -154,7 +153,6 @@ TEST_F(CookiesDetailsTest, CreateForTreeIndexedDB) { port, database_identifier, origin, - name, file_path, size, last_modified); diff --git a/chrome/browser/cocoa/dev_tools_controller.mm b/chrome/browser/cocoa/dev_tools_controller.mm index 3dee715..c9cf4e1 100644 --- a/chrome/browser/cocoa/dev_tools_controller.mm +++ b/chrome/browser/cocoa/dev_tools_controller.mm @@ -92,11 +92,11 @@ const int kMinWebHeight = 50; } // Make sure |splitOffset| isn't too large or too small. + splitOffset = std::max(static_cast<CGFloat>(kMinWebHeight), splitOffset); splitOffset = std::min(splitOffset, NSHeight([splitView_ frame]) - kMinWebHeight); DCHECK_GE(splitOffset, 0) << "kMinWebHeight needs to be smaller than " << "smallest available tab contents space."; - splitOffset = std::max(static_cast<CGFloat>(0), splitOffset); [self resizeDevToolsToNewHeight:splitOffset]; } else { diff --git a/chrome/browser/cocoa/download/download_item_cell.mm b/chrome/browser/cocoa/download/download_item_cell.mm index c286669..2f5d856 100644 --- a/chrome/browser/cocoa/download/download_item_cell.mm +++ b/chrome/browser/cocoa/download/download_item_cell.mm @@ -235,7 +235,7 @@ NSGradient* BackgroundTheme::GetNSGradient(int id) const { - (void)setStateFromDownload:(BaseDownloadItemModel*)downloadModel { // Set the name of the download. - downloadPath_ = downloadModel->download()->GetFileName(); + downloadPath_ = downloadModel->download()->GetFileNameToReportUser(); std::wstring statusText = downloadModel->GetStatusText(); if (statusText.empty()) { diff --git a/chrome/browser/cocoa/download/download_item_controller.mm b/chrome/browser/cocoa/download/download_item_controller.mm index d061e93..c210a3b 100644 --- a/chrome/browser/cocoa/download/download_item_controller.mm +++ b/chrome/browser/cocoa/download/download_item_controller.mm @@ -181,8 +181,8 @@ class DownloadShelfContextMenuMac : public DownloadShelfContextMenu { // This basic fixup copies Windows DownloadItemView::DownloadItemView(). // Extract the file extension (if any). - FilePath filepath(downloadModel->download()->original_name()); - FilePath::StringType extension = filepath.Extension(); + FilePath filename(downloadModel->download()->target_name()); + FilePath::StringType extension = filename.Extension(); // Remove leading '.' from the extension if (extension.length() > 0) @@ -197,15 +197,14 @@ class DownloadShelfContextMenuMac : public DownloadShelfContextMenu { } // Rebuild the filename.extension. - std::wstring rootname = - UTF8ToWide(filepath.BaseName().RemoveExtension().value()); + std::wstring rootname = UTF8ToWide(filename.RemoveExtension().value()); ElideString(rootname, kFileNameMaxLength - extension.length(), &rootname); - std::string filename = WideToUTF8(rootname); + std::string new_filename = WideToUTF8(rootname); if (extension.length()) - filename += std::string(".") + extension; + new_filename += std::string(".") + extension; dangerousWarning = l10n_util::GetNSStringFWithFixup( - IDS_PROMPT_DANGEROUS_DOWNLOAD, UTF8ToUTF16(filename)); + IDS_PROMPT_DANGEROUS_DOWNLOAD, UTF8ToUTF16(new_filename)); confirmButtonTitle = l10n_util::GetNSStringWithFixup(IDS_SAVE_DOWNLOAD); } [dangerousDownloadLabel_ setStringValue:dangerousWarning]; @@ -268,7 +267,7 @@ class DownloadShelfContextMenuMac : public DownloadShelfContextMenu { - (void)updateToolTip { string16 elidedFilename = gfx::ElideFilename( - [self download]->GetFileName(), + [self download]->GetFileNameToReportUser(), gfx::Font(), kToolTipMaxWidth); [progressView_ setToolTip:base::SysUTF16ToNSString(elidedFilename)]; } diff --git a/chrome/browser/cocoa/download/download_item_mac.h b/chrome/browser/cocoa/download/download_item_mac.h index d5f013e..1a27549 100644 --- a/chrome/browser/cocoa/download/download_item_mac.h +++ b/chrome/browser/cocoa/download/download_item_mac.h @@ -55,7 +55,7 @@ class DownloadItemMac : DownloadItem::Observer { CancelableRequestConsumerT<int, 0> icon_consumer_; // Stores the last known name where the file will be saved. - FilePath lastFilePath_; + FilePath lastFileName_; DISALLOW_COPY_AND_ASSIGN(DownloadItemMac); }; diff --git a/chrome/browser/cocoa/download/download_item_mac.mm b/chrome/browser/cocoa/download/download_item_mac.mm index b647655..0f8c5b7 100644 --- a/chrome/browser/cocoa/download/download_item_mac.mm +++ b/chrome/browser/cocoa/download/download_item_mac.mm @@ -34,12 +34,12 @@ void DownloadItemMac::OnDownloadUpdated(DownloadItem* download) { [item_controller_ clearDangerousMode]; } - if (download->full_path() != lastFilePath_) { - // Turns out the file path is "unconfirmed %d.download" for dangerous + if (download->GetUserVerifiedFileName() != lastFileName_) { + // Turns out the file path is "unconfirmed %d.crdownload" for dangerous // downloads. When the download is confirmed, the file is renamed on // another thread, so reload the icon if the download filename changes. LoadIcon(); - lastFilePath_ = download->full_path(); + lastFileName_ = download->GetUserVerifiedFileName(); [item_controller_ updateToolTip]; } @@ -72,7 +72,7 @@ void DownloadItemMac::LoadIcon() { } // We may already have this particular image cached. - FilePath file = download_model_->download()->full_path(); + FilePath file = download_model_->download()->GetUserVerifiedFileName(); SkBitmap* icon_bitmap = icon_manager->LookupIcon(file, IconLoader::SMALL); if (icon_bitmap) { NSImage* icon = gfx::SkBitmapToNSImage(*icon_bitmap); diff --git a/chrome/browser/cocoa/encoding_menu_controller_delegate_mac.mm b/chrome/browser/cocoa/encoding_menu_controller_delegate_mac.mm index bb7d67b..afba4b0 100644 --- a/chrome/browser/cocoa/encoding_menu_controller_delegate_mac.mm +++ b/chrome/browser/cocoa/encoding_menu_controller_delegate_mac.mm @@ -8,7 +8,7 @@ #include "base/string16.h" #include "base/sys_string_conversions.h" -#include "chrome/app/chrome_dll_resource.h" +#include "chrome/app/chrome_command_ids.h" #include "chrome/browser/browser.h" #include "chrome/browser/encoding_menu_controller.h" #include "chrome/browser/profile.h" diff --git a/chrome/browser/cocoa/extension_install_prompt.mm b/chrome/browser/cocoa/extension_install_prompt.mm index cb33136..3306806 100644 --- a/chrome/browser/cocoa/extension_install_prompt.mm +++ b/chrome/browser/cocoa/extension_install_prompt.mm @@ -20,7 +20,10 @@ class Profile; void ExtensionInstallUI::ShowExtensionInstallUIPromptImpl( - Profile* profile, Delegate* delegate, Extension* extension, SkBitmap* icon, + Profile* profile, + Delegate* delegate, + const Extension* extension, + SkBitmap* icon, ExtensionInstallUI::PromptType type) { NSAlert* alert = [[[NSAlert alloc] init] autorelease]; diff --git a/chrome/browser/cocoa/extension_installed_bubble_bridge.h b/chrome/browser/cocoa/extension_installed_bubble_bridge.h index 999fd0a..d878d70 100644 --- a/chrome/browser/cocoa/extension_installed_bubble_bridge.h +++ b/chrome/browser/cocoa/extension_installed_bubble_bridge.h @@ -20,7 +20,7 @@ namespace ExtensionInstalledBubbleCocoa { // This function is called by the ExtensionInstallUI when an extension has been // installed. void ShowExtensionInstalledBubble(gfx::NativeWindow window, - Extension* extension, + const Extension* extension, Browser* browser, SkBitmap icon); } diff --git a/chrome/browser/cocoa/extension_installed_bubble_bridge.mm b/chrome/browser/cocoa/extension_installed_bubble_bridge.mm index e43b956..9c15e97 100644 --- a/chrome/browser/cocoa/extension_installed_bubble_bridge.mm +++ b/chrome/browser/cocoa/extension_installed_bubble_bridge.mm @@ -12,7 +12,7 @@ void ExtensionInstalledBubbleCocoa::ShowExtensionInstalledBubble( gfx::NativeWindow window, - Extension* extension, + const Extension* extension, Browser* browser, SkBitmap icon) { // The controller is deallocated when the window is closed, so no need to diff --git a/chrome/browser/cocoa/extension_installed_bubble_controller.h b/chrome/browser/cocoa/extension_installed_bubble_controller.h index de2998a..e5f50a3 100644 --- a/chrome/browser/cocoa/extension_installed_bubble_controller.h +++ b/chrome/browser/cocoa/extension_installed_bubble_controller.h @@ -47,7 +47,7 @@ typedef enum { NSWindowController<NSWindowDelegate> { @private NSWindow* parentWindow_; // weak - Extension* extension_; // weak + const Extension* extension_; // weak Browser* browser_; // weak scoped_nsobject<NSImage> icon_; @@ -72,13 +72,13 @@ typedef enum { IBOutlet NSTextField* extensionInstalledInfoMsg_; } -@property (nonatomic, readonly) Extension* extension; +@property (nonatomic, readonly) const Extension* extension; @property (nonatomic) BOOL pageActionRemoved; // Initialize the window, and then create observers to wait for the extension // to complete loading, or the browser window to close. - (id)initWithParentWindow:(NSWindow*)parentWindow - extension:(Extension*)extension + extension:(const Extension*)extension browser:(Browser*)browser icon:(SkBitmap)icon; @@ -89,6 +89,10 @@ typedef enum { // the extensionObserver when the extension has completed loading. - (void)showWindow:(id)sender; +// Clears our weak pointer to the Extension. This callback is triggered by +// the extensionObserver when the extension is unloaded. +- (void)extensionUnloaded:(id)sender; + @end @interface ExtensionInstalledBubbleController(ExposedForTesting) diff --git a/chrome/browser/cocoa/extension_installed_bubble_controller.mm b/chrome/browser/cocoa/extension_installed_bubble_controller.mm index 00cd535..b1263fd 100644 --- a/chrome/browser/cocoa/extension_installed_bubble_controller.mm +++ b/chrome/browser/cocoa/extension_installed_bubble_controller.mm @@ -31,10 +31,12 @@ class ExtensionLoadedNotificationObserver : public NotificationObserver { public: ExtensionLoadedNotificationObserver( - ExtensionInstalledBubbleController* controller) + ExtensionInstalledBubbleController* controller, Profile* profile) : controller_(controller) { registrar_.Add(this, NotificationType::EXTENSION_LOADED, - NotificationService::AllSources()); + Source<Profile>(profile)); + registrar_.Add(this, NotificationType::EXTENSION_UNLOADED, + Source<Profile>(profile)); } private: @@ -44,12 +46,19 @@ class ExtensionLoadedNotificationObserver : public NotificationObserver { const NotificationSource& source, const NotificationDetails& details) { if (type == NotificationType::EXTENSION_LOADED) { - Extension* extension = Details<Extension>(details).ptr(); + const Extension* extension = Details<const Extension>(details).ptr(); if (extension == [controller_ extension]) { [controller_ performSelectorOnMainThread:@selector(showWindow:) withObject:controller_ waitUntilDone:NO]; } + } else if (type == NotificationType::EXTENSION_UNLOADED) { + const Extension* extension = Details<const Extension>(details).ptr(); + if (extension == [controller_ extension]) { + [controller_ performSelectorOnMainThread:@selector(extensionUnloaded:) + withObject:controller_ + waitUntilDone:NO]; + } } else { NOTREACHED() << "Received unexpected notification."; } @@ -65,7 +74,7 @@ class ExtensionLoadedNotificationObserver : public NotificationObserver { @synthesize pageActionRemoved = pageActionRemoved_; // Exposed for unit test. - (id)initWithParentWindow:(NSWindow*)parentWindow - extension:(Extension*)extension + extension:(const Extension*)extension browser:(Browser*)browser icon:(SkBitmap)icon { NSString* nibPath = @@ -91,7 +100,8 @@ class ExtensionLoadedNotificationObserver : public NotificationObserver { } // Start showing window only after extension has fully loaded. - extensionObserver_.reset(new ExtensionLoadedNotificationObserver(self)); + extensionObserver_.reset(new ExtensionLoadedNotificationObserver( + self, browser->profile())); } return self; } @@ -140,8 +150,7 @@ class ExtensionLoadedNotificationObserver : public NotificationObserver { // Extracted to a function here so that it can be overwritten for unit // testing. - (void)removePageActionPreviewIfNecessary { - DCHECK(extension_); - if (!extension_->page_action() || pageActionRemoved_) + if (!extension_ || !extension_->page_action() || pageActionRemoved_) return; pageActionRemoved_ = YES; @@ -329,4 +338,8 @@ class ExtensionLoadedNotificationObserver : public NotificationObserver { return [extensionInstalledInfoMsg_ frame]; } +- (void)extensionUnloaded:(id)sender { + extension_ = NULL; +} + @end diff --git a/chrome/browser/cocoa/extension_installed_bubble_controller_unittest.mm b/chrome/browser/cocoa/extension_installed_bubble_controller_unittest.mm index adcc426..ad68c85 100644 --- a/chrome/browser/cocoa/extension_installed_bubble_controller_unittest.mm +++ b/chrome/browser/cocoa/extension_installed_bubble_controller_unittest.mm @@ -75,7 +75,8 @@ class ExtensionInstalledBubbleControllerTest : public CocoaTest { // Create a skeletal framework of either page action or browser action // type. This extension only needs to have a type and a name to initialize // the ExtensionInstalledBubble for unit testing. - Extension* CreateExtension(extension_installed_bubble::ExtensionType type) { + scoped_refptr<Extension> CreateExtension( + extension_installed_bubble::ExtensionType type) { FilePath path; PathService::Get(chrome::DIR_TEST_DATA, &path); path = path.AppendASCII("extensions").AppendASCII("dummy"); @@ -98,10 +99,9 @@ class ExtensionInstalledBubbleControllerTest : public CocoaTest { extension_input_value.Set(keys::kBrowserAction, browser_action); } - Extension* extension = new Extension(path); std::string error; - extension->InitFromValue(extension_input_value, false, &error); - return extension; + return Extension::Create( + path, Extension::INVALID, extension_input_value, false, &error); } // Allows us to create the window and browser for testing. @@ -114,7 +114,7 @@ class ExtensionInstalledBubbleControllerTest : public CocoaTest { Browser* browser_; // weak, owned by BrowserTestHelper. // Skeleton extension to be tested; reinitialized for each test. - scoped_ptr<Extension> extension_; + scoped_refptr<Extension> extension_; // The icon_ to be loaded into the bubble window. SkBitmap icon_; @@ -122,8 +122,7 @@ class ExtensionInstalledBubbleControllerTest : public CocoaTest { // Confirm that window sizes are set correctly for a page action extension. TEST_F(ExtensionInstalledBubbleControllerTest, PageActionTest) { - extension_.reset( - CreateExtension(extension_installed_bubble::kPageAction)); + extension_ = CreateExtension(extension_installed_bubble::kPageAction); ExtensionInstalledBubbleControllerForTest* controller = [[ExtensionInstalledBubbleControllerForTest alloc] initWithParentWindow:window_ @@ -166,8 +165,7 @@ TEST_F(ExtensionInstalledBubbleControllerTest, PageActionTest) { } TEST_F(ExtensionInstalledBubbleControllerTest, BrowserActionTest) { - extension_.reset( - CreateExtension(extension_installed_bubble::kBrowserAction)); + extension_ = CreateExtension(extension_installed_bubble::kBrowserAction); ExtensionInstalledBubbleControllerForTest* controller = [[ExtensionInstalledBubbleControllerForTest alloc] initWithParentWindow:window_ diff --git a/chrome/browser/cocoa/extensions/browser_action_button.h b/chrome/browser/cocoa/extensions/browser_action_button.h index 606b033..1205c80 100644 --- a/chrome/browser/cocoa/extensions/browser_action_button.h +++ b/chrome/browser/cocoa/extensions/browser_action_button.h @@ -42,7 +42,7 @@ extern NSString* const kBrowserActionButtonDragEndNotification; scoped_nsobject<NSViewAnimation> moveAnimation_; // The extension for this button. Weak. - Extension* extension_; + const Extension* extension_; // The ID of the active tab. int tabId_; @@ -57,7 +57,7 @@ extern NSString* const kBrowserActionButtonDragEndNotification; } - (id)initWithFrame:(NSRect)frame - extension:(Extension*)extension + extension:(const Extension*)extension profile:(Profile*)profile tabId:(int)tabId; @@ -76,7 +76,7 @@ extern NSString* const kBrowserActionButtonDragEndNotification; - (NSImage*)compositedImage; @property(readonly, nonatomic) BOOL isBeingDragged; -@property(readonly, nonatomic) Extension* extension; +@property(readonly, nonatomic) const Extension* extension; @property(readwrite, nonatomic) int tabId; @end diff --git a/chrome/browser/cocoa/extensions/browser_action_button.mm b/chrome/browser/cocoa/extensions/browser_action_button.mm index 70f15ee..0cdaee5 100644 --- a/chrome/browser/cocoa/extensions/browser_action_button.mm +++ b/chrome/browser/cocoa/extensions/browser_action_button.mm @@ -45,7 +45,8 @@ const CGFloat kShadowOffset = 2.0; class ExtensionImageTrackerBridge : public NotificationObserver, public ImageLoadingTracker::Observer { public: - ExtensionImageTrackerBridge(BrowserActionButton* owner, Extension* extension) + ExtensionImageTrackerBridge(BrowserActionButton* owner, + const Extension* extension) : owner_(owner), tracker_(this) { // The Browser Action API does not allow the default icon path to be @@ -113,7 +114,7 @@ class ExtensionImageTrackerBridge : public NotificationObserver, } - (id)initWithFrame:(NSRect)frame - extension:(Extension*)extension + extension:(const Extension*)extension profile:(Profile*)profile tabId:(int)tabId { if ((self = [super initWithFrame:frame])) { diff --git a/chrome/browser/cocoa/extensions/browser_actions_controller.h b/chrome/browser/cocoa/extensions/browser_actions_controller.h index 21b0b95..8f039ce 100644 --- a/chrome/browser/cocoa/extensions/browser_actions_controller.h +++ b/chrome/browser/cocoa/extensions/browser_actions_controller.h @@ -88,7 +88,7 @@ extern NSString* const kBrowserActionVisibilityChangedNotification; - (void)resizeContainerAndAnimate:(BOOL)animate; // Returns the NSView for the action button associated with an extension. -- (NSView*)browserActionViewForExtension:(Extension*)extension; +- (NSView*)browserActionViewForExtension:(const Extension*)extension; // Returns the saved width determined by the number of shown Browser Actions // preference property. If no preference is found, then the width for the @@ -98,7 +98,7 @@ extern NSString* const kBrowserActionVisibilityChangedNotification; // Returns where the popup arrow should point to for a given Browser Action. If // it is passed an extension that is not a Browser Action, then it will return // NSZeroPoint. -- (NSPoint)popupPointForBrowserAction:(Extension*)extension; +- (NSPoint)popupPointForBrowserAction:(const Extension*)extension; // Returns whether the chevron button is currently hidden or in the process of // being hidden (fading out). Will return NO if it is not hidden or is in the diff --git a/chrome/browser/cocoa/extensions/browser_actions_controller.mm b/chrome/browser/cocoa/extensions/browser_actions_controller.mm index e5a58ad..456ceba 100644 --- a/chrome/browser/cocoa/extensions/browser_actions_controller.mm +++ b/chrome/browser/cocoa/extensions/browser_actions_controller.mm @@ -70,13 +70,13 @@ const CGFloat kBrowserActionBubbleYOffset = 3.0; // Creates and then adds the given extension's action button to the container // at the given index within the container. It does not affect the toolbar model // object since it is called when the toolbar model changes. -- (void)createActionButtonForExtension:(Extension*)extension +- (void)createActionButtonForExtension:(const Extension*)extension withIndex:(NSUInteger)index; // Removes an action button for the given extension from the container. This // method also does not affect the underlying toolbar model since it is called // when the toolbar model changes. -- (void)removeActionButtonForExtension:(Extension*)extension; +- (void)removeActionButtonForExtension:(const Extension*)extension; // Useful in the case of a Browser Action being added/removed from the middle of // the container, this method repositions each button according to the current @@ -90,7 +90,7 @@ const CGFloat kBrowserActionBubbleYOffset = 3.0; // Returns the existing button with the given extension backing it; nil if it // cannot be found or the extension's ID is invalid. -- (BrowserActionButton*)buttonForExtension:(Extension*)extension; +- (BrowserActionButton*)buttonForExtension:(const Extension*)extension; // Returns the preferred width of the container given the number of visible // buttons |buttonCount|. @@ -141,7 +141,7 @@ const CGFloat kBrowserActionBubbleYOffset = 3.0; // Returns whether the given extension should be displayed. Only displays // incognito-enabled extensions in incognito mode. Otherwise returns YES. -- (BOOL)shouldDisplayBrowserAction:(Extension*)extension; +- (BOOL)shouldDisplayBrowserAction:(const Extension*)extension; // The reason |frame| is specified in these chevron functions is because the // container may be animating and the end frame of the animation should be @@ -203,12 +203,12 @@ class ExtensionsServiceObserverBridge : public NotificationObserver, } // ExtensionToolbarModel::Observer implementation. - void BrowserActionAdded(Extension* extension, int index) { + void BrowserActionAdded(const Extension* extension, int index) { [owner_ createActionButtonForExtension:extension withIndex:index]; [owner_ resizeContainerAndAnimate:NO]; } - void BrowserActionRemoved(Extension* extension) { + void BrowserActionRemoved(const Extension* extension) { [owner_ removeActionButtonForExtension:extension]; [owner_ resizeContainerAndAnimate:NO]; } @@ -342,7 +342,7 @@ class ExtensionsServiceObserverBridge : public NotificationObserver, } } -- (NSView*)browserActionViewForExtension:(Extension*)extension { +- (NSView*)browserActionViewForExtension:(const Extension*)extension { for (BrowserActionButton* button in [buttons_ allValues]) { if ([button extension] == extension) return button; @@ -374,7 +374,7 @@ class ExtensionsServiceObserverBridge : public NotificationObserver, return [self containerWidthWithButtonCount:savedButtonCount]; } -- (NSPoint)popupPointForBrowserAction:(Extension*)extension { +- (NSPoint)popupPointForBrowserAction:(const Extension*)extension { if (!extension->browser_action()) return NSZeroPoint; @@ -446,7 +446,7 @@ class ExtensionsServiceObserverBridge : public NotificationObserver, [containerView_ resizeToWidth:width animate:NO]; } -- (void)createActionButtonForExtension:(Extension*)extension +- (void)createActionButtonForExtension:(const Extension*)extension withIndex:(NSUInteger)index { if (!extension->browser_action()) return; @@ -491,7 +491,7 @@ class ExtensionsServiceObserverBridge : public NotificationObserver, [containerView_ setNeedsDisplay:YES]; } -- (void)removeActionButtonForExtension:(Extension*)extension { +- (void)removeActionButtonForExtension:(const Extension*)extension { if (!extension->browser_action()) return; @@ -555,7 +555,7 @@ class ExtensionsServiceObserverBridge : public NotificationObserver, } } -- (BrowserActionButton*)buttonForExtension:(Extension*)extension { +- (BrowserActionButton*)buttonForExtension:(const Extension*)extension { NSString* extensionId = base::SysUTF8ToNSString(extension->id()); DCHECK(extensionId); if (!extensionId) @@ -744,7 +744,7 @@ class ExtensionsServiceObserverBridge : public NotificationObserver, } } -- (BOOL)shouldDisplayBrowserAction:(Extension*)extension { +- (BOOL)shouldDisplayBrowserAction:(const Extension*)extension { // Only display incognito-enabled extensions while in incognito mode. return (!profile_->IsOffTheRecord() || profile_->GetExtensionsService()->IsIncognitoEnabled(extension)); @@ -854,7 +854,7 @@ class ExtensionsServiceObserverBridge : public NotificationObserver, if (profile_->IsOffTheRecord()) index = toolbarModel_->IncognitoIndexToOriginal(index); if (index < toolbarModel_->size()) { - Extension* extension = toolbarModel_->GetExtensionByIndex(index); + const Extension* extension = toolbarModel_->GetExtensionByIndex(index); return [buttons_ objectForKey:base::SysUTF8ToNSString(extension->id())]; } return nil; diff --git a/chrome/browser/cocoa/extensions/extension_action_context_menu.h b/chrome/browser/cocoa/extensions/extension_action_context_menu.h index 3c9e216..80e8398 100644 --- a/chrome/browser/cocoa/extensions/extension_action_context_menu.h +++ b/chrome/browser/cocoa/extensions/extension_action_context_menu.h @@ -28,7 +28,7 @@ class DevmodeObserver; @interface ExtensionActionContextMenu : NSMenu { @private // The extension that this menu belongs to. Weak. - Extension* extension_; + const Extension* extension_; // The extension action this menu belongs to. Weak. ExtensionAction* action_; @@ -48,7 +48,7 @@ class DevmodeObserver; } // Initializes and returns a context menu for the given extension and profile. -- (id)initWithExtension:(Extension*)extension +- (id)initWithExtension:(const Extension*)extension profile:(Profile*)profile extensionAction:(ExtensionAction*)action; diff --git a/chrome/browser/cocoa/extensions/extension_action_context_menu.mm b/chrome/browser/cocoa/extensions/extension_action_context_menu.mm index 81aa61e..36ff520 100644 --- a/chrome/browser/cocoa/extensions/extension_action_context_menu.mm +++ b/chrome/browser/cocoa/extensions/extension_action_context_menu.mm @@ -36,7 +36,7 @@ // Also acts as the extension's UI delegate in order to display the dialog. class AsyncUninstaller : public ExtensionInstallUI::Delegate { public: - AsyncUninstaller(Extension* extension, Profile* profile) + AsyncUninstaller(const Extension* extension, Profile* profile) : extension_(extension), profile_(profile) { install_ui_.reset(new ExtensionInstallUI(profile)); @@ -55,7 +55,7 @@ class AsyncUninstaller : public ExtensionInstallUI::Delegate { private: // The extension that we're loading the icon for. Weak. - Extension* extension_; + const Extension* extension_; // The current profile. Weak. Profile* profile_; @@ -125,7 +125,7 @@ int CurrentTabId() { } // namespace -- (id)initWithExtension:(Extension*)extension +- (id)initWithExtension:(const Extension*)extension profile:(Profile*)profile extensionAction:(ExtensionAction*)action{ if ((self = [super initWithTitle:@""])) { diff --git a/chrome/browser/cocoa/extensions/extension_infobar_controller.mm b/chrome/browser/cocoa/extensions/extension_infobar_controller.mm index 1bb1a5f..a2a38f2 100644 --- a/chrome/browser/cocoa/extensions/extension_infobar_controller.mm +++ b/chrome/browser/cocoa/extensions/extension_infobar_controller.mm @@ -65,7 +65,7 @@ class InfobarBridge : public ExtensionInfoBarDelegate::DelegateObserver, // Load the Extension's icon image. void LoadIcon() { - Extension* extension = delegate_->extension_host()->extension(); + const Extension* extension = delegate_->extension_host()->extension(); ExtensionResource icon_resource = extension->GetIconResource( Extension::EXTENSION_ICON_BITTY, ExtensionIconSet::MATCH_EXACTLY); if (!icon_resource.relative_path().empty()) { diff --git a/chrome/browser/cocoa/extensions/extension_install_prompt_controller.h b/chrome/browser/cocoa/extensions/extension_install_prompt_controller.h index 0fb4d4e..8a6a4ce 100644 --- a/chrome/browser/cocoa/extensions/extension_install_prompt_controller.h +++ b/chrome/browser/cocoa/extensions/extension_install_prompt_controller.h @@ -49,7 +49,7 @@ class Profile; - (id)initWithParentWindow:(NSWindow*)window profile:(Profile*)profile - extension:(Extension*)extension + extension:(const Extension*)extension delegate:(ExtensionInstallUI::Delegate*)delegate icon:(SkBitmap*)bitmap warnings:(const std::vector<string16>&)warnings; diff --git a/chrome/browser/cocoa/extensions/extension_install_prompt_controller.mm b/chrome/browser/cocoa/extensions/extension_install_prompt_controller.mm index 9ba758b..10f4f81 100644 --- a/chrome/browser/cocoa/extensions/extension_install_prompt_controller.mm +++ b/chrome/browser/cocoa/extensions/extension_install_prompt_controller.mm @@ -58,7 +58,7 @@ void OffsetControlVertically(NSControl* control, CGFloat amount) { - (id)initWithParentWindow:(NSWindow*)window profile:(Profile*)profile - extension:(Extension*)extension + extension:(const Extension*)extension delegate:(ExtensionInstallUI::Delegate*)delegate icon:(SkBitmap*)icon warnings:(const std::vector<string16>&)warnings { @@ -185,7 +185,10 @@ void OffsetControlVertically(NSControl* control, CGFloat amount) { void ExtensionInstallUI::ShowExtensionInstallUIPrompt2Impl( - Profile* profile, Delegate* delegate, Extension* extension, SkBitmap* icon, + Profile* profile, + Delegate* delegate, + const Extension* extension, + SkBitmap* icon, const std::vector<string16>& warnings) { Browser* browser = BrowserList::GetLastActiveWithProfile(profile); if (!browser) { diff --git a/chrome/browser/cocoa/extensions/extension_install_prompt_controller_unittest.mm b/chrome/browser/cocoa/extensions/extension_install_prompt_controller_unittest.mm index f596851..12eadff 100644 --- a/chrome/browser/cocoa/extensions/extension_install_prompt_controller_unittest.mm +++ b/chrome/browser/cocoa/extensions/extension_install_prompt_controller_unittest.mm @@ -60,19 +60,18 @@ public: return; } - scoped_ptr<Extension> extension(new Extension(path.DirName())); - if (!extension->InitFromValue(*value, false, &error)) { + extension_ = Extension::Create( + path.DirName(), Extension::INVALID, *value, false, &error); + if (!extension_.get()) { LOG(ERROR) << error; return; } - - extension_.reset(extension.release()); } BrowserTestHelper helper_; FilePath test_data_dir_; SkBitmap icon_; - scoped_ptr<Extension> extension_; + scoped_refptr<Extension> extension_; }; diff --git a/chrome/browser/cocoa/first_run_bubble_controller_unittest.mm b/chrome/browser/cocoa/first_run_bubble_controller_unittest.mm index a6009a6..094b1f6 100644 --- a/chrome/browser/cocoa/first_run_bubble_controller_unittest.mm +++ b/chrome/browser/cocoa/first_run_bubble_controller_unittest.mm @@ -6,6 +6,7 @@ #import <Cocoa/Cocoa.h> +#include "base/debug/debugger.h" #include "base/scoped_nsobject.h" #include "chrome/browser/cocoa/browser_test_helper.h" #import "chrome/browser/cocoa/cocoa_test_helper.h" @@ -26,7 +27,7 @@ TEST_F(FirstRunBubbleControllerTest, Init) { backing:NSBackingStoreBuffered defer:NO]); [parent setReleasedWhenClosed:NO]; - if (DebugUtil::BeingDebugged()) + if (base::debug::BeingDebugged()) [parent.get() orderFront:nil]; else [parent.get() orderBack:nil]; diff --git a/chrome/browser/cocoa/first_run_dialog.mm b/chrome/browser/cocoa/first_run_dialog.mm index 7f72bb4..5b97bde 100644 --- a/chrome/browser/cocoa/first_run_dialog.mm +++ b/chrome/browser/cocoa/first_run_dialog.mm @@ -77,7 +77,7 @@ void FirstRunShowBridge::ShowDialog() { // -[NSApplication runModalForWindow:] we will hang <http://crbug.com/54248>. // Therefore the main MessageLoop is run so things work. - scoped_refptr<FirstRunShowBridge> bridge = new FirstRunShowBridge(self); + scoped_refptr<FirstRunShowBridge> bridge(new FirstRunShowBridge(self)); MessageLoop::current()->PostTask( FROM_HERE, NewRunnableMethod(bridge.get(), diff --git a/chrome/browser/cocoa/framed_browser_window_unittest.mm b/chrome/browser/cocoa/framed_browser_window_unittest.mm index ae9c329..5638561 100644 --- a/chrome/browser/cocoa/framed_browser_window_unittest.mm +++ b/chrome/browser/cocoa/framed_browser_window_unittest.mm @@ -4,8 +4,9 @@ #import <Cocoa/Cocoa.h> +#include "base/debug/debugger.h" #include "base/scoped_nsobject.h" -#include "chrome/app/chrome_dll_resource.h" +#include "chrome/app/chrome_command_ids.h" #import "chrome/browser/cocoa/browser_window_controller.h" #import "chrome/browser/cocoa/browser_frame_view.h" #import "chrome/browser/cocoa/cocoa_test_helper.h" @@ -27,7 +28,7 @@ class FramedBrowserWindowTest : public CocoaTest { styleMask:mask backing:NSBackingStoreBuffered defer:NO]; - if (DebugUtil::BeingDebugged()) { + if (base::debug::BeingDebugged()) { [window_ orderFront:nil]; } else { [window_ orderBack:nil]; diff --git a/chrome/browser/cocoa/fullscreen_window.mm b/chrome/browser/cocoa/fullscreen_window.mm index d0fb304..47582b2 100644 --- a/chrome/browser/cocoa/fullscreen_window.mm +++ b/chrome/browser/cocoa/fullscreen_window.mm @@ -26,12 +26,27 @@ defer:YES screen:screen])) { [self setReleasedWhenClosed:NO]; + // Borderless windows don't usually show up in the Windows menu so whine at + // Cocoa until it complies. See -dealloc and -setTitle: as well. + [NSApp addWindowsItem:self title:@"" filename:NO]; } return self; } +- (void)dealloc { + // Paranoia; doesn't seem to be necessary but it doesn't hurt. + [NSApp removeWindowsItem:self]; + + [super dealloc]; +} + +- (void)setTitle:(NSString *)title { + [NSApp changeWindowsItem:self title:title filename:NO]; + [super setTitle:title]; +} + // According to -// http://www.cocoabuilder.com/archive/message/cocoa/2006/6/19/165953, +// http://www.cocoabuilder.com/archive/message/cocoa/2006/6/19/165953 , // NSBorderlessWindowMask windows cannot become key or main. // In our case, however, we don't want that behavior, so we override // canBecomeKeyWindow and canBecomeMainWindow. diff --git a/chrome/browser/cocoa/gradient_button_cell.mm b/chrome/browser/cocoa/gradient_button_cell.mm index f6ac577..8b99fa5 100644 --- a/chrome/browser/cocoa/gradient_button_cell.mm +++ b/chrome/browser/cocoa/gradient_button_cell.mm @@ -448,7 +448,7 @@ static const NSTimeInterval kAnimationContinuousCycleDuration = 0.4; active ? BrowserThemeProvider::COLOR_TOOLBAR_BUTTON_STROKE : BrowserThemeProvider::COLOR_TOOLBAR_BUTTON_STROKE_INACTIVE, true) : [NSColor colorWithCalibratedWhite:0.0 - alpha:0.6 * outerStrokeAlphaMult_]; + alpha:0.3 * outerStrokeAlphaMult_]; } [strokeColor setStroke]; diff --git a/chrome/browser/cocoa/history_menu_bridge.mm b/chrome/browser/cocoa/history_menu_bridge.mm index 844ca38..0b975ec 100644 --- a/chrome/browser/cocoa/history_menu_bridge.mm +++ b/chrome/browser/cocoa/history_menu_bridge.mm @@ -11,7 +11,7 @@ #include "base/string_number_conversions.h" #include "base/string_util.h" #include "base/sys_string_conversions.h" -#include "chrome/app/chrome_dll_resource.h" // IDC_HISTORY_MENU +#include "chrome/app/chrome_command_ids.h" // IDC_HISTORY_MENU #import "chrome/browser/app_controller_mac.h" #import "chrome/browser/cocoa/history_menu_cocoa_controller.h" #include "chrome/browser/history/page_usage_data.h" diff --git a/chrome/browser/cocoa/history_menu_bridge_unittest.mm b/chrome/browser/cocoa/history_menu_bridge_unittest.mm index a3fd2b6..399f510 100644 --- a/chrome/browser/cocoa/history_menu_bridge_unittest.mm +++ b/chrome/browser/cocoa/history_menu_bridge_unittest.mm @@ -9,7 +9,7 @@ #include "base/string_util.h" #include "base/sys_string_conversions.h" #include "base/utf_string_conversions.h" -#include "chrome/app/chrome_dll_resource.h" +#include "chrome/app/chrome_command_ids.h" #include "chrome/browser/browser.h" #include "chrome/browser/cancelable_request.h" #include "chrome/browser/cocoa/browser_test_helper.h" diff --git a/chrome/browser/cocoa/history_menu_cocoa_controller.mm b/chrome/browser/cocoa/history_menu_cocoa_controller.mm index 1b6241e..cf6cb18 100644 --- a/chrome/browser/cocoa/history_menu_cocoa_controller.mm +++ b/chrome/browser/cocoa/history_menu_cocoa_controller.mm @@ -5,7 +5,7 @@ #import "chrome/browser/cocoa/history_menu_cocoa_controller.h" #include "base/scoped_vector.h" -#include "chrome/app/chrome_dll_resource.h" // IDC_HISTORY_MENU +#include "chrome/app/chrome_command_ids.h" // IDC_HISTORY_MENU #import "chrome/browser/app_controller_mac.h" #include "chrome/browser/browser.h" #include "chrome/browser/browser_process.h" diff --git a/chrome/browser/cocoa/history_menu_cocoa_controller_unittest.mm b/chrome/browser/cocoa/history_menu_cocoa_controller_unittest.mm index a57e12b..605e2ba 100644 --- a/chrome/browser/cocoa/history_menu_cocoa_controller_unittest.mm +++ b/chrome/browser/cocoa/history_menu_cocoa_controller_unittest.mm @@ -6,7 +6,7 @@ #include "base/scoped_ptr.h" #include "base/string_util.h" #include "base/sys_string_conversions.h" -#include "chrome/app/chrome_dll_resource.h" +#include "chrome/app/chrome_command_ids.h" #include "chrome/browser/browser.h" #include "chrome/browser/cocoa/browser_test_helper.h" #include "chrome/browser/cocoa/cocoa_test_helper.h" diff --git a/chrome/browser/cocoa/html_dialog_window_controller.mm b/chrome/browser/cocoa/html_dialog_window_controller.mm index b959798..aed0d83 100644 --- a/chrome/browser/cocoa/html_dialog_window_controller.mm +++ b/chrome/browser/cocoa/html_dialog_window_controller.mm @@ -44,6 +44,7 @@ public: virtual std::string GetDialogArgs() const; virtual void OnDialogClosed(const std::string& json_retval); virtual void OnCloseContents(TabContents* source, bool* out_close_dialog) { } + virtual bool ShouldShowDialogTitle() const { return true; } // HtmlDialogTabContentsDelegate declarations. virtual void MoveContents(TabContents* source, const gfx::Rect& pos); diff --git a/chrome/browser/cocoa/html_dialog_window_controller_unittest.mm b/chrome/browser/cocoa/html_dialog_window_controller_unittest.mm index b6eae68..c8cdfb7 100644 --- a/chrome/browser/cocoa/html_dialog_window_controller_unittest.mm +++ b/chrome/browser/cocoa/html_dialog_window_controller_unittest.mm @@ -35,6 +35,7 @@ public: MOCK_METHOD1(OnDialogClosed, void(const std::string& json_retval)); MOCK_METHOD2(OnCloseContents, void(TabContents* source, bool* out_close_dialog)); + MOCK_CONST_METHOD0(ShouldShowDialogTitle, bool()); }; class HtmlDialogWindowControllerTest : public BrowserWithTestWindowTest { diff --git a/chrome/browser/cocoa/import_progress_dialog.mm b/chrome/browser/cocoa/import_progress_dialog.mm index 109365b..f40ae5f 100644 --- a/chrome/browser/cocoa/import_progress_dialog.mm +++ b/chrome/browser/cocoa/import_progress_dialog.mm @@ -154,7 +154,7 @@ NSString* keyForImportItem(importer::ImportItem item) { @end void StartImportingWithUI(gfx::NativeWindow parent_window, - int16 items, + uint16 items, ImporterHost* coordinator, const importer::ProfileInfo& source_profile, Profile* target_profile, diff --git a/chrome/browser/cocoa/import_settings_dialog.mm b/chrome/browser/cocoa/import_settings_dialog.mm index a11244a..d18dec8 100644 --- a/chrome/browser/cocoa/import_settings_dialog.mm +++ b/chrome/browser/cocoa/import_settings_dialog.mm @@ -174,9 +174,7 @@ bool importSettingsDialogVisible = false; const importer::ProfileInfo& sourceProfile = importerList_.get()->GetSourceProfileInfoAt([self sourceBrowserIndex]); uint16 items = sourceProfile.services_supported; - // ProfileInfo.services_supported is a uint16 while the call to - // StartImportingWithUI requires an int16. - int16 servicesToImport = static_cast<int16>(items & [self servicesToImport]); + uint16 servicesToImport = items & [self servicesToImport]; if (servicesToImport) { if (profile_) { ImporterHost* importerHost = new ExternalProcessImporterHost; diff --git a/chrome/browser/cocoa/keystone_glue.mm b/chrome/browser/cocoa/keystone_glue.mm index a0162a3..4ba9b21 100644 --- a/chrome/browser/cocoa/keystone_glue.mm +++ b/chrome/browser/cocoa/keystone_glue.mm @@ -13,8 +13,12 @@ #import "app/l10n_util_mac.h" #include "base/logging.h" #include "base/mac_util.h" +#include "base/mac/scoped_nsautorelease_pool.h" #include "base/sys_string_conversions.h" #import "base/worker_pool_mac.h" +#include "base/ref_counted.h" +#include "base/task.h" +#include "base/worker_pool.h" #include "chrome/browser/cocoa/authorization_util.h" #include "chrome/common/chrome_constants.h" #include "grit/chromium_strings.h" @@ -89,6 +93,51 @@ NSString* SystemBrandFilePath() { return [kBrandSystemFile stringByStandardizingPath]; } +// Adaptor for scheduling an Objective-C method call on a |WorkerPool| +// thread. +// TODO(shess): Move this into workerpool_mac.h? +class PerformBridge : public base::RefCountedThreadSafe<PerformBridge> { + public: + + // Call |sel| on |target| with |arg| in a WorkerPool thread. + // |target| and |arg| are retained, |arg| may be |nil|. + static void PostPerform(id target, SEL sel, id arg) { + DCHECK(target); + DCHECK(sel); + + scoped_refptr<PerformBridge> op = new PerformBridge(target, sel, arg); + WorkerPool::PostTask( + FROM_HERE, NewRunnableMethod(op.get(), &PerformBridge::Run), true); + } + + // Convenience for the no-argument case. + static void PostPerform(id target, SEL sel) { + PostPerform(target, sel, nil); + } + + private: + // Allow RefCountedThreadSafe<> to delete. + friend class base::RefCountedThreadSafe<PerformBridge>; + + PerformBridge(id target, SEL sel, id arg) + : target_([target retain]), + sel_(sel), + arg_([arg retain]) { + } + + ~PerformBridge() {} + + // Happens on a WorkerPool thread. + void Run() { + base::mac::ScopedNSAutoreleasePool pool; + [target_ performSelector:sel_ withObject:arg_]; + } + + scoped_nsobject<id> target_; + SEL sel_; + scoped_nsobject<id> arg_; +}; + } // namespace @interface KSRegistration : NSObject @@ -147,7 +196,7 @@ NSString* SystemBrandFilePath() { // -determineUpdateStatusAsync is called on the main thread to initiate the // operation. It performs initial set-up work that must be done on the main // thread and arranges for -determineUpdateStatus to be called on a work queue -// thread managed by NSOperationQueue. +// thread managed by WorkerPool. // -determineUpdateStatus then reads the Info.plist, gets the version from the // CFBundleShortVersionString key, and performs // -determineUpdateStatusForVersion: on the main thread. @@ -562,17 +611,10 @@ NSString* const kBrandKey = @"KSBrandID"; - (void)determineUpdateStatusAsync { DCHECK([NSThread isMainThread]); - SEL selector = @selector(determineUpdateStatus); - NSInvocationOperation* operation = - [[[NSInvocationOperation alloc] initWithTarget:self - selector:selector - object:nil] autorelease]; - - NSOperationQueue* operationQueue = [WorkerPoolObjC sharedOperationQueue]; - [operationQueue addOperation:operation]; + PerformBridge::PostPerform(self, @selector(determineUpdateStatus)); } -// Runs on a thread managed by NSOperationQueue. +// Runs on a thread managed by WorkerPool. - (void)determineUpdateStatus { DCHECK(![NSThread isMainThread]); @@ -849,7 +891,7 @@ NSString* const kBrandKey = @"KSBrandID"; - (void)changePermissionsForPromotionAsync { // NSBundle is not documented as being thread-safe. Do NSBundle operations - // on the main thread before jumping over to a NSOperationQueue-managed + // on the main thread before jumping over to a WorkerPool-managed // thread to run the tool. DCHECK([NSThread isMainThread]); @@ -858,13 +900,7 @@ NSString* const kBrandKey = @"KSBrandID"; [mac_util::MainAppBundle() pathForResource:@"keystone_promote_postflight" ofType:@"sh"]; - NSInvocationOperation* operation = - [[[NSInvocationOperation alloc] initWithTarget:self - selector:selector - object:toolPath] autorelease]; - - NSOperationQueue* operationQueue = [WorkerPoolObjC sharedOperationQueue]; - [operationQueue addOperation:operation]; + PerformBridge::PostPerform(self, selector, toolPath); } - (void)changePermissionsForPromotionWithTool:(NSString*)toolPath { diff --git a/chrome/browser/cocoa/location_bar/autocomplete_text_field_editor.mm b/chrome/browser/cocoa/location_bar/autocomplete_text_field_editor.mm index 4904e50..aa5d391 100644 --- a/chrome/browser/cocoa/location_bar/autocomplete_text_field_editor.mm +++ b/chrome/browser/cocoa/location_bar/autocomplete_text_field_editor.mm @@ -8,7 +8,7 @@ #include "base/string_util.h" #include "grit/generated_resources.h" #include "base/sys_string_conversions.h" -#include "chrome/app/chrome_dll_resource.h" // IDC_* +#include "chrome/app/chrome_command_ids.h" // IDC_* #include "chrome/browser/browser_list.h" #import "chrome/browser/cocoa/browser_window_controller.h" #import "chrome/browser/cocoa/location_bar/autocomplete_text_field.h" diff --git a/chrome/browser/cocoa/location_bar/autocomplete_text_field_editor_unittest.mm b/chrome/browser/cocoa/location_bar/autocomplete_text_field_editor_unittest.mm index fc21da0..21ad21a 100644 --- a/chrome/browser/cocoa/location_bar/autocomplete_text_field_editor_unittest.mm +++ b/chrome/browser/cocoa/location_bar/autocomplete_text_field_editor_unittest.mm @@ -7,7 +7,7 @@ #include "base/scoped_nsobject.h" #include "base/scoped_ptr.h" #include "base/string_util.h" -#include "chrome/app/chrome_dll_resource.h" // IDC_* +#include "chrome/app/chrome_command_ids.h" // IDC_* #import "chrome/browser/cocoa/cocoa_test_helper.h" #import "chrome/browser/cocoa/location_bar/autocomplete_text_field_unittest_helper.h" #import "chrome/browser/cocoa/test_event_utils.h" diff --git a/chrome/browser/cocoa/location_bar/ev_bubble_decoration.h b/chrome/browser/cocoa/location_bar/ev_bubble_decoration.h index ae06586..bbb29fc 100644 --- a/chrome/browser/cocoa/location_bar/ev_bubble_decoration.h +++ b/chrome/browser/cocoa/location_bar/ev_bubble_decoration.h @@ -29,6 +29,10 @@ class EVBubbleDecoration : public BubbleDecoration { // fits, else it will set an elided version. void SetFullLabel(NSString* full_label); + // Get the point where the page info bubble should point within the + // decoration's frame, in the cell's coordinates. + NSPoint GetBubblePointInFrame(NSRect frame); + // Implement |LocationBarDecoration|. virtual CGFloat GetWidthForSpace(CGFloat width); virtual bool IsDraggable(); diff --git a/chrome/browser/cocoa/location_bar/ev_bubble_decoration.mm b/chrome/browser/cocoa/location_bar/ev_bubble_decoration.mm index 1f54500..40220e4 100644 --- a/chrome/browser/cocoa/location_bar/ev_bubble_decoration.mm +++ b/chrome/browser/cocoa/location_bar/ev_bubble_decoration.mm @@ -28,6 +28,10 @@ const CGFloat kMinElidedBubbleWidth = 150.0; // |kMinElidedBubbleWidth|. const float kMaxBubbleFraction = 0.5; +// The info-bubble point should look like it points to the bottom of the lock +// icon. Determined with Pixie.app. +const CGFloat kPageInfoBubblePointYOffset = 6.0; + // TODO(shess): This is ugly, find a better way. Using it right now // so that I can crib from gtk and still be able to see that I'm using // the same values easily. @@ -61,6 +65,12 @@ void EVBubbleDecoration::SetFullLabel(NSString* label) { SetLabel(full_label_); } +NSPoint EVBubbleDecoration::GetBubblePointInFrame(NSRect frame) { + NSRect image_rect = GetImageRectInFrame(frame); + return NSMakePoint(NSMidX(image_rect), + NSMaxY(image_rect) - kPageInfoBubblePointYOffset); +} + CGFloat EVBubbleDecoration::GetWidthForSpace(CGFloat width) { // Limit with to not take up too much of the available width, but // also don't let it shrink too much. diff --git a/chrome/browser/cocoa/location_bar/location_bar_view_mac.h b/chrome/browser/cocoa/location_bar/location_bar_view_mac.h index 583925d..687cb1a 100644 --- a/chrome/browser/cocoa/location_bar/location_bar_view_mac.h +++ b/chrome/browser/cocoa/location_bar/location_bar_view_mac.h @@ -94,6 +94,9 @@ class LocationBarViewMac : public AutocompleteEditController, // Get the point in the security icon at which the page info bubble aims. NSPoint GetPageInfoBubblePoint() const; + // Get the point in the omnibox at which the first run bubble aims. + NSPoint GetFirstRunBubblePoint() const; + // Updates the location bar. Resets the bar's permanent text and // security style, and if |should_restore_state| is true, restores // saved state from the tab (for tab switching). @@ -130,6 +133,7 @@ class LocationBarViewMac : public AutocompleteEditController, virtual void OnAutocompleteLosingFocus(gfx::NativeView unused); virtual void OnAutocompleteWillAccept(); virtual bool OnCommitSuggestedText(const std::wstring& typed_text); + virtual void OnSetSuggestedSearchText(const string16& suggested_text); virtual void OnPopupBoundsChanged(const gfx::Rect& bounds); virtual void OnAutocompleteAccept(const GURL& url, WindowOpenDisposition disposition, diff --git a/chrome/browser/cocoa/location_bar/location_bar_view_mac.mm b/chrome/browser/cocoa/location_bar/location_bar_view_mac.mm index e20a50f..f469b80 100644 --- a/chrome/browser/cocoa/location_bar/location_bar_view_mac.mm +++ b/chrome/browser/cocoa/location_bar/location_bar_view_mac.mm @@ -11,7 +11,7 @@ #include "base/string_util.h" #include "base/sys_string_conversions.h" #include "base/utf_string_conversions.h" -#include "chrome/app/chrome_dll_resource.h" +#include "chrome/app/chrome_command_ids.h" #include "chrome/browser/alternate_nav_url_fetcher.h" #import "chrome/browser/app_controller_mac.h" #import "chrome/browser/autocomplete/autocomplete_edit_view_mac.h" @@ -56,6 +56,13 @@ #include "skia/ext/skia_utils_mac.h" #include "third_party/skia/include/core/SkBitmap.h" +namespace { + +// Vertical space between the bottom edge of the location_bar and the first run +// bubble arrow point. +const static int kFirstRunBubbleYOffset = 1; + +} // TODO(shess): This code is mostly copied from the gtk // implementation. Make sure it's all appropriate and flesh it out. @@ -117,9 +124,15 @@ void LocationBarViewMac::ShowFirstRunBubbleInternal( if (!field_ || ![field_ window]) return; - // The bubble needs to be just below the Omnibox and slightly to the right - // of the left omnibox icon, so shift x and y co-ordinates. - const NSPoint kOffset = NSMakePoint(1, 4); + // The first run bubble's left edge should line up with the left edge of the + // omnibox. This is different from other bubbles, which line up at a point + // set by their top arrow. Because the BaseBubbleController adjusts the + // window origin left to account for the arrow spacing, the first run bubble + // moves the window origin right by this spacing, so that the + // BaseBubbleController will move it back to the correct position. + const NSPoint kOffset = NSMakePoint( + info_bubble::kBubbleArrowXOffset + info_bubble::kBubbleArrowWidth/2.0, + kFirstRunBubbleYOffset); [FirstRunBubbleController showForView:field_ offset:kOffset profile:profile_]; } @@ -238,6 +251,11 @@ bool LocationBarViewMac::OnCommitSuggestedText(const std::wstring& typed_text) { return false; } +void LocationBarViewMac::OnSetSuggestedSearchText( + const string16& suggested_text) { + SetSuggestedText(suggested_text); +} + void LocationBarViewMac::OnPopupBoundsChanged(const gfx::Rect& bounds) { InstantController* instant = browser_->instant(); if (instant) @@ -474,10 +492,19 @@ NSPoint LocationBarViewMac::GetBookmarkBubblePoint() const { NSPoint LocationBarViewMac::GetPageInfoBubblePoint() const { AutocompleteTextFieldCell* cell = [field_ cell]; - const NSRect frame = [cell frameForDecoration:location_icon_decoration_.get() - inFrame:[field_ bounds]]; - const NSPoint point = location_icon_decoration_->GetBubblePointInFrame(frame); - return [field_ convertPoint:point toView:nil]; + if (ev_bubble_decoration_->IsVisible()) { + const NSRect frame = [cell frameForDecoration:ev_bubble_decoration_.get() + inFrame:[field_ bounds]]; + const NSPoint point = ev_bubble_decoration_->GetBubblePointInFrame(frame); + return [field_ convertPoint:point toView:nil]; + } else { + const NSRect frame = + [cell frameForDecoration:location_icon_decoration_.get() + inFrame:[field_ bounds]]; + const NSPoint point = + location_icon_decoration_->GetBubblePointInFrame(frame); + return [field_ convertPoint:point toView:nil]; + } } NSImage* LocationBarViewMac::GetKeywordImage(const std::wstring& keyword) { diff --git a/chrome/browser/cocoa/location_bar/location_icon_decoration.mm b/chrome/browser/cocoa/location_bar/location_icon_decoration.mm index f967af2..9649789 100644 --- a/chrome/browser/cocoa/location_bar/location_icon_decoration.mm +++ b/chrome/browser/cocoa/location_bar/location_icon_decoration.mm @@ -11,10 +11,8 @@ #include "chrome/browser/tab_contents/tab_contents.h" #import "third_party/mozilla/NSPasteboard+Utils.h" -// The info-bubble point should look like it points to the point -// between the star's lower tips. The popup should be where the -// Omnibox popup ends up (2px below field). Determined via Pixie.app -// magnification. +// The info-bubble point should look like it points to the bottom of the lock +// icon. Determined with Pixie.app. const CGFloat kBubblePointYOffset = 2.0; LocationIconDecoration::LocationIconDecoration(LocationBarViewMac* owner) diff --git a/chrome/browser/cocoa/location_bar/page_action_decoration.mm b/chrome/browser/cocoa/location_bar/page_action_decoration.mm index 572a65a..79636b2 100644 --- a/chrome/browser/cocoa/location_bar/page_action_decoration.mm +++ b/chrome/browser/cocoa/location_bar/page_action_decoration.mm @@ -39,8 +39,8 @@ PageActionDecoration::PageActionDecoration( current_tab_id_(-1), preview_enabled_(false) { DCHECK(profile); - Extension* extension = profile->GetExtensionsService()->GetExtensionById( - page_action->extension_id(), false); + const Extension* extension = profile->GetExtensionsService()-> + GetExtensionById(page_action->extension_id(), false); DCHECK(extension); // Load all the icons declared in the manifest. This is the contents of the @@ -219,7 +219,7 @@ NSMenu* PageActionDecoration::GetMenu() { ExtensionsService* service = profile_->GetExtensionsService(); if (!service) return nil; - Extension* extension = service->GetExtensionById( + const Extension* extension = service->GetExtensionById( page_action_->extension_id(), false); DCHECK(extension); if (!extension) diff --git a/chrome/browser/cocoa/location_bar/star_decoration.mm b/chrome/browser/cocoa/location_bar/star_decoration.mm index adedd16..0d91929 100644 --- a/chrome/browser/cocoa/location_bar/star_decoration.mm +++ b/chrome/browser/cocoa/location_bar/star_decoration.mm @@ -5,7 +5,7 @@ #import "chrome/browser/cocoa/location_bar/star_decoration.h" #include "app/l10n_util_mac.h" -#include "chrome/app/chrome_dll_resource.h" +#include "chrome/app/chrome_command_ids.h" #import "chrome/browser/autocomplete/autocomplete_edit_view_mac.h" #include "chrome/browser/command_updater.h" #include "grit/generated_resources.h" diff --git a/chrome/browser/cocoa/notifications/balloon_controller.h b/chrome/browser/cocoa/notifications/balloon_controller.h index 8199265..03f8e4f 100644 --- a/chrome/browser/cocoa/notifications/balloon_controller.h +++ b/chrome/browser/cocoa/notifications/balloon_controller.h @@ -8,13 +8,15 @@ #import <Cocoa/Cocoa.h> -#include "base/scoped_nsobject.h" #include "base/cocoa_protocols_mac.h" -#import "chrome/browser/cocoa/hover_image_button.h" -#import "chrome/browser/cocoa/notifications/balloon_view.h" -#import "chrome/browser/cocoa/notifications/balloon_view_host_mac.h" -#include "chrome/browser/notifications/balloon.h" +#include "base/scoped_nsobject.h" +#include "base/scoped_ptr.h" +class Balloon; +@class BalloonContentViewCocoa; +@class BalloonShelfViewCocoa; +class BalloonViewHost; +@class HoverImageButton; @class MenuController; class NotificationOptionsMenuModel; @@ -50,6 +52,9 @@ class NotificationOptionsMenuModel; // The host for the renderer of the HTML contents. scoped_ptr<BalloonViewHost> htmlContents_; + + // The psn of the front application process. + ProcessSerialNumber frontProcessNum_; } // Initialize with a balloon object containing the notification data. @@ -81,6 +86,9 @@ class NotificationOptionsMenuModel; // The BalloonHost - (BalloonViewHost*)getHost; + +// Handle the event if it is for the balloon. +- (BOOL)handleEvent:(NSEvent*)event; @end @interface BalloonController (UnitTesting) diff --git a/chrome/browser/cocoa/notifications/balloon_controller.mm b/chrome/browser/cocoa/notifications/balloon_controller.mm index 55ee041..3f8a8b0 100644 --- a/chrome/browser/cocoa/notifications/balloon_controller.mm +++ b/chrome/browser/cocoa/notifications/balloon_controller.mm @@ -11,7 +11,9 @@ #include "base/nsimage_cache_mac.h" #import "base/scoped_nsobject.h" #include "base/utf_string_conversions.h" +#import "chrome/browser/cocoa/hover_image_button.h" #import "chrome/browser/cocoa/menu_controller.h" +#import "chrome/browser/cocoa/notifications/balloon_view.h" #include "chrome/browser/cocoa/notifications/balloon_view_host_mac.h" #include "chrome/browser/notifications/balloon.h" #include "chrome/browser/notifications/desktop_notification_service.h" @@ -110,12 +112,45 @@ const int kRightMargin = 2; assumeInside:NO]; } +- (BOOL)handleEvent:(NSEvent*)event { + BOOL eventHandled = NO; + if ([event type] == NSLeftMouseDown) { + NSPoint mouse = [shelf_ convertPoint:[event locationInWindow] + fromView:nil]; + if (NSPointInRect(mouse, [closeButton_ frame])) { + [closeButton_ mouseDown:event]; + + // Bring back the front process that is deactivated when we click the + // close button. + if (frontProcessNum_.highLongOfPSN || frontProcessNum_.lowLongOfPSN) { + SetFrontProcessWithOptions(&frontProcessNum_, + kSetFrontProcessFrontWindowOnly); + frontProcessNum_.highLongOfPSN = 0; + frontProcessNum_.lowLongOfPSN = 0; + } + + eventHandled = YES; + } else if (NSPointInRect(mouse, [optionsButton_ frame])) { + [optionsButton_ mouseDown:event]; + eventHandled = YES; + } + } + return eventHandled; +} + - (void) mouseEntered:(NSEvent*)event { [[closeButton_ cell] setHighlighted:YES]; + + // Remember the current front process so that we can bring it back later. + if (!frontProcessNum_.highLongOfPSN && !frontProcessNum_.lowLongOfPSN) + GetFrontProcess(&frontProcessNum_); } - (void) mouseExited:(NSEvent*)event { [[closeButton_ cell] setHighlighted:NO]; + + frontProcessNum_.highLongOfPSN = 0; + frontProcessNum_.lowLongOfPSN = 0; } - (IBAction)optionsButtonPressed:(id)sender { @@ -143,7 +178,8 @@ const int kRightMargin = 2; } - (void)closeBalloon:(bool)byUser { - DCHECK(balloon_); + if (!balloon_) + return; [self close]; if (htmlContents_.get()) htmlContents_->Shutdown(); diff --git a/chrome/browser/cocoa/notifications/balloon_view.h b/chrome/browser/cocoa/notifications/balloon_view.h index 5164360..819df68 100644 --- a/chrome/browser/cocoa/notifications/balloon_view.h +++ b/chrome/browser/cocoa/notifications/balloon_view.h @@ -8,8 +8,6 @@ #import <Cocoa/Cocoa.h> -#include "base/scoped_nsobject.h" - @interface BalloonWindow : NSWindow { } @end diff --git a/chrome/browser/cocoa/notifications/balloon_view.mm b/chrome/browser/cocoa/notifications/balloon_view.mm index 3a5d13e..0c2e83e 100644 --- a/chrome/browser/cocoa/notifications/balloon_view.mm +++ b/chrome/browser/cocoa/notifications/balloon_view.mm @@ -8,6 +8,7 @@ #include "base/basictypes.h" #include "base/scoped_nsobject.h" +#import "chrome/browser/cocoa/notifications/balloon_controller.h" #import "third_party/GTM/AppKit/GTMNSBezierPath+RoundRect.h" namespace { @@ -36,6 +37,16 @@ const int kRoundedCornerSize = 6; - (BOOL)canBecomeMainWindow { return NO; } + +- (void)sendEvent:(NSEvent*)event { + // We do not want to bring chrome window to foreground when we click on close + // or option button. To do this, we have to intercept the event. + BalloonController* delegate = + static_cast<BalloonController*>([self delegate]); + if (![delegate handleEvent:event]) { + [super sendEvent:event]; + } +} @end @implementation BalloonShelfViewCocoa diff --git a/chrome/browser/cocoa/notifications/balloon_view_bridge.h b/chrome/browser/cocoa/notifications/balloon_view_bridge.h index 01adcd8..985fcde 100644 --- a/chrome/browser/cocoa/notifications/balloon_view_bridge.h +++ b/chrome/browser/cocoa/notifications/balloon_view_bridge.h @@ -6,10 +6,13 @@ #define CHROME_BROWSER_COCOA_NOTIFICATIONS_BALLOON_VIEW_BRIDGE_H_ #pragma once -#include "base/scoped_nsobject.h" -#import "chrome/browser/cocoa/notifications/balloon_controller.h" #include "chrome/browser/notifications/balloon.h" -#include "gfx/size.h" + +@class BalloonController; +class BalloonHost; +namespace gfx { +class Size; +} // Bridges from the cross-platform BalloonView interface to the Cocoa // controller which will draw the view on screen. diff --git a/chrome/browser/cocoa/notifications/balloon_view_bridge.mm b/chrome/browser/cocoa/notifications/balloon_view_bridge.mm index 7f6aa7c..c0b8b1f 100644 --- a/chrome/browser/cocoa/notifications/balloon_view_bridge.mm +++ b/chrome/browser/cocoa/notifications/balloon_view_bridge.mm @@ -4,6 +4,10 @@ #include "chrome/browser/cocoa/notifications/balloon_view_bridge.h" +#include "chrome/browser/cocoa/notifications/balloon_controller.h" +#import "chrome/browser/cocoa/notifications/balloon_view_host_mac.h" +#include "gfx/size.h" + #import <Cocoa/Cocoa.h> BalloonViewBridge::BalloonViewBridge() : diff --git a/chrome/browser/cocoa/notifications/balloon_view_host_mac.h b/chrome/browser/cocoa/notifications/balloon_view_host_mac.h index 286d5b1..3ef85b2 100644 --- a/chrome/browser/cocoa/notifications/balloon_view_host_mac.h +++ b/chrome/browser/cocoa/notifications/balloon_view_host_mac.h @@ -7,7 +7,9 @@ #pragma once #include "chrome/browser/notifications/balloon_host.h" -#import "chrome/browser/renderer_host/render_widget_host_view_mac.h" + +class RenderWidgetHostView; +class RenderWidgetHostViewMac; // BalloonViewHost class is a delegate to the renderer host for the HTML // notification. When initialized it creates a new RenderViewHost and loads @@ -17,23 +19,17 @@ class BalloonViewHost : public BalloonHost { public: explicit BalloonViewHost(Balloon* balloon); - ~BalloonViewHost() { - Shutdown(); - } + ~BalloonViewHost(); // Changes the size of the balloon. void UpdateActualSize(const gfx::Size& new_size); // Accessors. - gfx::NativeView native_view() const { - return render_widget_host_view_->native_view(); - } + gfx::NativeView native_view() const; protected: virtual void InitRenderWidgetHostView(); - virtual RenderWidgetHostView* render_widget_host_view() const { - return render_widget_host_view_; - } + virtual RenderWidgetHostView* render_widget_host_view() const; private: // The Mac-specific widget host view. This is owned by its native view, diff --git a/chrome/browser/cocoa/notifications/balloon_view_host_mac.mm b/chrome/browser/cocoa/notifications/balloon_view_host_mac.mm index 3b3aa35..67b75b3 100644 --- a/chrome/browser/cocoa/notifications/balloon_view_host_mac.mm +++ b/chrome/browser/cocoa/notifications/balloon_view_host_mac.mm @@ -4,15 +4,17 @@ #include "chrome/browser/cocoa/notifications/balloon_view_host_mac.h" -#include "chrome/browser/notifications/balloon.h" #include "chrome/browser/renderer_host/render_view_host.h" -#include "chrome/browser/renderer_host/render_widget_host_view.h" #include "chrome/browser/renderer_host/render_widget_host_view_mac.h" BalloonViewHost::BalloonViewHost(Balloon* balloon) : BalloonHost(balloon) { } +BalloonViewHost::~BalloonViewHost() { + Shutdown(); +} + void BalloonViewHost::UpdateActualSize(const gfx::Size& new_size) { NSView* view = render_widget_host_view_->native_view(); NSRect frame = [view frame]; @@ -23,8 +25,15 @@ void BalloonViewHost::UpdateActualSize(const gfx::Size& new_size) { [view setNeedsDisplay:YES]; } +gfx::NativeView BalloonViewHost::native_view() const { + return render_widget_host_view_->native_view(); +} + void BalloonViewHost::InitRenderWidgetHostView() { DCHECK(render_view_host_); render_widget_host_view_ = new RenderWidgetHostViewMac(render_view_host_); } +RenderWidgetHostView* BalloonViewHost::render_widget_host_view() const { + return render_widget_host_view_; +} diff --git a/chrome/browser/cocoa/page_info_bubble_controller.mm b/chrome/browser/cocoa/page_info_bubble_controller.mm index a2cc34f..c2c2d36 100644 --- a/chrome/browser/cocoa/page_info_bubble_controller.mm +++ b/chrome/browser/cocoa/page_info_bubble_controller.mm @@ -6,7 +6,9 @@ #include "app/l10n_util.h" #include "app/l10n_util_mac.h" +#include "base/message_loop.h" #include "base/sys_string_conversions.h" +#include "base/task.h" #include "chrome/browser/browser_list.h" #include "chrome/browser/cert_store.h" #include "chrome/browser/certificate_viewer.h" @@ -26,9 +28,9 @@ - (PageInfoModel*)model; - (NSButton*)certificateButtonWithFrame:(NSRect)frame; - (void)configureTextFieldAsLabel:(NSTextField*)textField; -- (CGFloat)addTitleViewForInfo:(const PageInfoModel::SectionInfo&)info - toSubviews:(NSMutableArray*)subviews - atPoint:(NSPoint)point; +- (CGFloat)addHeadlineViewForInfo:(const PageInfoModel::SectionInfo&)info + toSubviews:(NSMutableArray*)subviews + atPoint:(NSPoint)point; - (CGFloat)addDescriptionViewForInfo:(const PageInfoModel::SectionInfo&)info toSubviews:(NSMutableArray*)subviews atPoint:(NSPoint)point; @@ -45,6 +47,19 @@ parentWindow:(NSWindow*)parent; @end +// This simple NSView subclass is used as the single subview of the page info +// bubble's window's contentView. Drawing is flipped so that layout of the +// sections is easier. Apple recommends flipping the coordinate origin when +// doing a lot of text layout because it's more natural. +@interface PageInfoContentView : NSView { +} +@end +@implementation PageInfoContentView +- (BOOL)isFlipped { + return YES; +} +@end + namespace { // The width of the window, in view coordinates. The height will be determined @@ -57,8 +72,8 @@ const NSInteger kVerticalSpacing = 10; // Padding along on the X-axis between the window frame and content. const NSInteger kFramePadding = 20; -// Spacing between the title and description text views. -const NSInteger kTitleSpacing = 2; +// Spacing between the optional headline and description text views. +const NSInteger kHeadlineSpacing = 2; // Spacing between the image and the text. const NSInteger kImageSpacing = 10; @@ -75,20 +90,33 @@ const CGFloat kTextXPosition = kTextXPositionNoImage + kImageSize + const CGFloat kTextWidth = kWindowWidth - (kImageSize + kImageSpacing + kFramePadding * 2); - // Bridge that listens for change notifications from the model. class PageInfoModelBubbleBridge : public PageInfoModel::PageInfoModelObserver { public: - PageInfoModelBubbleBridge() : controller_(nil) {} + PageInfoModelBubbleBridge() + : controller_(nil), + ALLOW_THIS_IN_INITIALIZER_LIST(task_factory_(this)) { + } // PageInfoModelObserver implementation. virtual void ModelChanged() { + // Check to see if a layout has already been scheduled. + if (!task_factory_.empty()) + return; + // Delay performing layout by a second so that all the animations from // InfoBubbleWindow and origin updates from BaseBubbleController finish, so // that we don't all race trying to change the frame's origin. - [controller_ performSelector:@selector(performLayout) - withObject:nil - afterDelay:1.0]; + // + // Using ScopedRunnableMethodFactory is superior here to |-performSelector:| + // because it will not retain its target; if the child outlives its parent, + // zombies get left behind (http://crbug.com/59619). This will also cancel + // the scheduled Tasks if the controller (and thus this bridge) get + // destroyed before the message can be delivered. + MessageLoop::current()->PostDelayedTask(FROM_HERE, + task_factory_.NewRunnableMethod( + &PageInfoModelBubbleBridge::PerformLayout), + 1000 /* milliseconds */); } // Sets the controller. @@ -97,7 +125,14 @@ class PageInfoModelBubbleBridge : public PageInfoModel::PageInfoModelObserver { } private: + void PerformLayout() { + [controller_ performLayout]; + } + PageInfoBubbleController* controller_; // weak + + // Factory that vends RunnableMethod tasks for scheduling layout. + ScopedRunnableMethodFactory<PageInfoModelBubbleBridge> task_factory_; }; } // namespace @@ -173,28 +208,33 @@ void ShowPageInfoBubble(gfx::NativeWindow parent, // not using HTTPS. - (void)performLayout { // |offset| is the Y position that should be drawn at next. - CGFloat offset = kVerticalSpacing; + CGFloat offset = kFramePadding; // Keep the new subviews in an array that gets replaced at the end. NSMutableArray* subviews = [NSMutableArray array]; - // First item, drawn at the bottom of the window, is the help center link. - offset += [self addHelpButtonToSubviews:subviews atOffset:offset]; - offset += kVerticalSpacing; - offset += [self addSeparatorToSubviews:subviews atOffset:offset]; - - // Build the window from bottom-up because Cocoa's coordinate origin is the - // lower left. - for (int i = model_->GetSectionCount() - 1; i >= 0; --i) { + // The subviews will be attached to the PageInfoContentView, which has a + // flipped origin. This allows the code to build top-to-bottom. + const int sectionCount = model_->GetSectionCount(); + for (int i = 0; i < sectionCount; ++i) { PageInfoModel::SectionInfo info = model_->GetSectionInfo(i); // Only certain sections have images. This affects the X position. BOOL hasImage = model_->GetIconImage(info.icon_id) != nil; CGFloat xPosition = (hasImage ? kTextXPosition : kTextXPositionNoImage); - if (info.type == PageInfoModel::SECTION_INFO_IDENTITY) { - offset += [self addCertificateButtonToSubviews:subviews - atOffset:offset]; + // Insert the image subview for sections that are appropriate. + CGFloat imageBaseline = offset + kImageSize; + if (hasImage) { + [self addImageViewForInfo:info toSubviews:subviews atOffset:offset]; + } + + // Add the title. + if (!info.headline.empty()) { + offset += [self addHeadlineViewForInfo:info + toSubviews:subviews + atPoint:NSMakePoint(xPosition, offset)]; + offset += kHeadlineSpacing; } // Create the description of the state. @@ -202,31 +242,37 @@ void ShowPageInfoBubble(gfx::NativeWindow parent, toSubviews:subviews atPoint:NSMakePoint(xPosition, offset)]; - // Add the title. - offset += kTitleSpacing; - offset += [self addTitleViewForInfo:info - toSubviews:subviews - atPoint:NSMakePoint(xPosition, offset)]; - - // Insert the image subview for sections that are appropriate. - if (hasImage) { - [self addImageViewForInfo:info toSubviews:subviews atOffset:offset]; + if (info.type == PageInfoModel::SECTION_INFO_IDENTITY && certID_) { + offset += kVerticalSpacing; + offset += [self addCertificateButtonToSubviews:subviews atOffset:offset]; } + // If at this point the description and optional headline and button are + // not as tall as the image, adjust the offset by the difference. + CGFloat imageBaselineDelta = imageBaseline - offset; + if (imageBaselineDelta > 0) + offset += imageBaselineDelta; + // Add the separators. - if (i != 0) { - offset += kVerticalSpacing; - offset += [self addSeparatorToSubviews:subviews atOffset:offset]; - } + offset += kVerticalSpacing; + offset += [self addSeparatorToSubviews:subviews atOffset:offset]; } - // Replace the window's content. - [[[self window] contentView] setSubviews:subviews]; + // The last item at the bottom of the window is the help center link. + offset += [self addHelpButtonToSubviews:subviews atOffset:offset]; + offset += kVerticalSpacing; - offset += kFramePadding; + // Create the dummy view that uses flipped coordinates. + NSRect contentFrame = NSMakeRect(0, 0, kWindowWidth, offset); + scoped_nsobject<PageInfoContentView> contentView( + [[PageInfoContentView alloc] initWithFrame:contentFrame]); + [contentView setSubviews:subviews]; - NSRect windowFrame = NSMakeRect(0, 0, kWindowWidth, 0); - windowFrame.size.height += offset; + // Replace the window's content. + [[[self window] contentView] setSubviews: + [NSArray arrayWithObject:contentView]]; + + NSRect windowFrame = NSMakeRect(0, 0, kWindowWidth, offset); windowFrame.size = [[[self window] contentView] convertSize:windowFrame.size toView:nil]; // Adjust the origin by the difference in height. @@ -273,21 +319,21 @@ void ShowPageInfoBubble(gfx::NativeWindow parent, // Adds the title text field at the given x,y position, and returns the y // position for the next element. -- (CGFloat)addTitleViewForInfo:(const PageInfoModel::SectionInfo&)info - toSubviews:(NSMutableArray*)subviews - atPoint:(NSPoint)point { +- (CGFloat)addHeadlineViewForInfo:(const PageInfoModel::SectionInfo&)info + toSubviews:(NSMutableArray*)subviews + atPoint:(NSPoint)point { NSRect frame = NSMakeRect(point.x, point.y, kTextWidth, kImageSpacing); - scoped_nsobject<NSTextField> titleField( + scoped_nsobject<NSTextField> textField( [[NSTextField alloc] initWithFrame:frame]); - [self configureTextFieldAsLabel:titleField.get()]; - [titleField setStringValue:base::SysUTF16ToNSString(info.title)]; + [self configureTextFieldAsLabel:textField.get()]; + [textField setStringValue:base::SysUTF16ToNSString(info.headline)]; NSFont* font = [NSFont boldSystemFontOfSize:[NSFont smallSystemFontSize]]; - [titleField setFont:font]; + [textField setFont:font]; frame.size.height += [GTMUILocalizerAndLayoutTweaker sizeToFitFixedWidthTextField: - titleField]; - [titleField setFrame:frame]; - [subviews addObject:titleField.get()]; + textField]; + [textField setFrame:frame]; + [subviews addObject:textField.get()]; return NSHeight(frame); } @@ -315,6 +361,9 @@ void ShowPageInfoBubble(gfx::NativeWindow parent, // Returns the y position for the next element. - (CGFloat)addCertificateButtonToSubviews:(NSMutableArray*)subviews atOffset:(CGFloat)offset { + // The certificate button should only be added if there is SSL information. + DCHECK(certID_); + // Create the certificate button. The frame will be fixed up by GTM, so // use arbitrary values. NSRect frame = NSMakeRect(kTextXPosition, offset, 100, 14); @@ -323,19 +372,17 @@ void ShowPageInfoBubble(gfx::NativeWindow parent, [GTMUILocalizerAndLayoutTweaker sizeToFitView:certButton]; // By default, assume that we don't have certificate information to show. - [certButton setEnabled:NO]; - if (certID_) { - scoped_refptr<net::X509Certificate> cert; - CertStore::GetSharedInstance()->RetrieveCert(certID_, &cert); - - // Don't bother showing certificates if there isn't one. Gears runs - // with no OS root certificate. - if (cert.get() && cert->os_cert_handle()) { - [certButton setEnabled:YES]; - } + scoped_refptr<net::X509Certificate> cert; + CertStore::GetSharedInstance()->RetrieveCert(certID_, &cert); + + // Don't bother showing certificates if there isn't one. Gears runs + // with no OS root certificate. + if (!cert.get() || !cert->os_cert_handle()) { + // This should only ever happen in unit tests. + [certButton setEnabled:NO]; } - return NSHeight(frame) + kVerticalSpacing; + return NSHeight([certButton frame]); } // Adds the state image at a pre-determined x position and the given y. This @@ -344,7 +391,7 @@ void ShowPageInfoBubble(gfx::NativeWindow parent, - (void)addImageViewForInfo:(const PageInfoModel::SectionInfo&)info toSubviews:(NSMutableArray*)subviews atOffset:(CGFloat)offset { - NSRect frame = NSMakeRect(kFramePadding, offset - kImageSize, kImageSize, + NSRect frame = NSMakeRect(kFramePadding, offset, kImageSize, kImageSize); scoped_nsobject<NSImageView> imageView( [[NSImageView alloc] initWithFrame:frame]); diff --git a/chrome/browser/cocoa/page_info_bubble_controller_unittest.mm b/chrome/browser/cocoa/page_info_bubble_controller_unittest.mm index eb7c177..3354577 100644 --- a/chrome/browser/cocoa/page_info_bubble_controller_unittest.mm +++ b/chrome/browser/cocoa/page_info_bubble_controller_unittest.mm @@ -22,11 +22,11 @@ class FakeModel : public PageInfoModel { FakeModel() : PageInfoModel() {} void AddSection(SectionStateIcon icon_id, - const string16& title, + const string16& headline, const string16& description, SectionInfoType type) { sections_.push_back(SectionInfo( - icon_id, title, string16(), description, type)); + icon_id, headline, description, type)); } }; @@ -67,7 +67,13 @@ class PageInfoBubbleControllerTest : public CocoaTest { int link_count = 1; ++spacer_count; - for (NSView* view in [[window_ contentView] subviews]) { + // The window's only immediate child is an invisible view that has a flipped + // coordinate origin. It is into this that all views get placed. + NSArray* windowSubviews = [[window_ contentView] subviews]; + EXPECT_EQ(1U, [windowSubviews count]); + NSArray* subviews = [[windowSubviews lastObject] subviews]; + + for (NSView* view in subviews) { if ([view isKindOfClass:[NSTextField class]]) { --text_count; } else if ([view isKindOfClass:[NSImageView class]]) { @@ -113,28 +119,28 @@ class PageInfoBubbleControllerTest : public CocoaTest { TEST_F(PageInfoBubbleControllerTest, NoHistoryNoSecurity) { model_->AddSection(PageInfoModel::ICON_STATE_ERROR, - l10n_util::GetStringUTF16(IDS_PAGE_INFO_SECURITY_TAB_IDENTITY_TITLE), + string16(), l10n_util::GetStringUTF16(IDS_PAGE_INFO_SECURITY_TAB_UNKNOWN_PARTY), PageInfoModel::SECTION_INFO_IDENTITY); model_->AddSection(PageInfoModel::ICON_STATE_ERROR, - l10n_util::GetStringUTF16(IDS_PAGE_INFO_SECURITY_TAB_CONNECTION_TITLE), + string16(), l10n_util::GetStringFUTF16( IDS_PAGE_INFO_SECURITY_TAB_NOT_ENCRYPTED_CONNECTION_TEXT, ASCIIToUTF16("google.com")), PageInfoModel::SECTION_INFO_CONNECTION); CreateBubble(); - CheckWindow(/*text=*/4, /*image=*/2, /*spacer=*/1, /*button=*/1); + CheckWindow(/*text=*/2, /*image=*/2, /*spacer=*/1, /*button=*/0); } TEST_F(PageInfoBubbleControllerTest, HistoryNoSecurity) { model_->AddSection(PageInfoModel::ICON_STATE_ERROR, - l10n_util::GetStringUTF16(IDS_PAGE_INFO_SECURITY_TAB_IDENTITY_TITLE), + string16(), l10n_util::GetStringUTF16(IDS_PAGE_INFO_SECURITY_TAB_UNKNOWN_PARTY), PageInfoModel::SECTION_INFO_IDENTITY); model_->AddSection(PageInfoModel::ICON_STATE_ERROR, - l10n_util::GetStringUTF16(IDS_PAGE_INFO_SECURITY_TAB_CONNECTION_TITLE), + string16(), l10n_util::GetStringFUTF16( IDS_PAGE_INFO_SECURITY_TAB_NOT_ENCRYPTED_CONNECTION_TEXT, ASCIIToUTF16("google.com")), @@ -145,21 +151,20 @@ TEST_F(PageInfoBubbleControllerTest, HistoryNoSecurity) { CreateBubble(); model_->AddSection(PageInfoModel::ICON_STATE_ERROR, - l10n_util::GetStringUTF16( - IDS_PAGE_INFO_SECURITY_TAB_PERSONAL_HISTORY_TITLE), + l10n_util::GetStringUTF16(IDS_PAGE_INFO_SITE_INFO_TITLE), l10n_util::GetStringUTF16( IDS_PAGE_INFO_SECURITY_TAB_FIRST_VISITED_TODAY), PageInfoModel::SECTION_INFO_FIRST_VISIT); [controller_ performLayout]; - CheckWindow(/*text=*/6, /*image=*/3, /*spacer=*/2, /*button=*/1); + CheckWindow(/*text=*/4, /*image=*/3, /*spacer=*/2, /*button=*/0); } TEST_F(PageInfoBubbleControllerTest, NoHistoryMixedSecurity) { model_->AddSection(PageInfoModel::ICON_STATE_OK, - l10n_util::GetStringUTF16(IDS_PAGE_INFO_SECURITY_TAB_IDENTITY_TITLE), + string16(), l10n_util::GetStringFUTF16( IDS_PAGE_INFO_SECURITY_TAB_SECURE_IDENTITY, ASCIIToUTF16("Goat Security Systems")), @@ -177,17 +182,20 @@ TEST_F(PageInfoBubbleControllerTest, NoHistoryMixedSecurity) { IDS_PAGE_INFO_SECURITY_TAB_ENCRYPTED_INSECURE_CONTENT_WARNING)); model_->AddSection(PageInfoModel::ICON_STATE_OK, - l10n_util::GetStringUTF16(IDS_PAGE_INFO_SECURITY_TAB_CONNECTION_TITLE), + string16(), description, PageInfoModel::SECTION_INFO_CONNECTION); + CreateBubble(); + [controller_ setCertID:1]; + [controller_ performLayout]; - NSArray* subviews = [[window_ contentView] subviews]; - CheckWindow(/*text=*/4, /*image=*/2, /*spacer=*/1, /*button=*/1); + CheckWindow(/*text=*/2, /*image=*/2, /*spacer=*/1, /*button=*/1); // Look for the over-sized box. NSString* targetDesc = base::SysUTF16ToNSString(description); + NSArray* subviews = [[window_ contentView] subviews]; for (NSView* subview in subviews) { if ([subview isKindOfClass:[NSTextField class]]) { NSTextField* desc = static_cast<NSTextField*>(subview); diff --git a/chrome/browser/cocoa/page_info_window_mac.mm b/chrome/browser/cocoa/page_info_window_mac.mm deleted file mode 100644 index 15b3e7f..0000000 --- a/chrome/browser/cocoa/page_info_window_mac.mm +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/page_info_window.h" - -#include "base/logging.h" - -// TODO(finnur): Delete this file. http://crbug.com/59030 - -namespace browser { - -void ShowPageInfo(gfx::NativeWindow parent, - Profile* profile, - const GURL& url, - const NavigationEntry::SSLStatus& ssl, - bool show_history) { - NOTREACHED(); -} - -} // namespace browser diff --git a/chrome/browser/cocoa/reload_button.h b/chrome/browser/cocoa/reload_button.h index 493da1c..edb6e9c 100644 --- a/chrome/browser/cocoa/reload_button.h +++ b/chrome/browser/cocoa/reload_button.h @@ -20,9 +20,8 @@ BOOL isMouseInside_; scoped_nsobject<NSTrackingArea> trackingArea_; - // Set when reload mode is requested, but not forced, and the mouse - // is hovering. - BOOL pendingReloadMode_; + // Timer used when setting reload mode while the mouse is hovered. + scoped_nsobject<NSTimer> pendingReloadTimer_; } // Returns YES if the mouse is currently inside the bounds. @@ -32,13 +31,14 @@ // |isLoading|. If |force|, always sets the indicated mode. If // |!force|, and the mouse is over the button, defer the transition // from stop button to reload button until the mouse has left the -// button. This prevents an inadvertent click _just_ as the state -// changes. +// button, or until |pendingReloadTimer_| fires. This prevents an +// inadvertent click _just_ as the state changes. - (void)setIsLoading:(BOOL)isLoading force:(BOOL)force; @end @interface ReloadButton (PrivateTestingMethods) ++ (void)setPendingReloadTimeout:(NSTimeInterval)seconds; - (NSTrackingArea*)trackingArea; @end diff --git a/chrome/browser/cocoa/reload_button.mm b/chrome/browser/cocoa/reload_button.mm index c1379ed..9975db7 100644 --- a/chrome/browser/cocoa/reload_button.mm +++ b/chrome/browser/cocoa/reload_button.mm @@ -7,7 +7,7 @@ #include "app/l10n_util.h" #include "app/l10n_util_mac.h" #include "base/nsimage_cache_mac.h" -#include "chrome/app/chrome_dll_resource.h" +#include "chrome/app/chrome_command_ids.h" #import "chrome/browser/cocoa/gradient_button_cell.h" #import "chrome/browser/cocoa/view_id_util.h" #include "grit/generated_resources.h" @@ -17,6 +17,9 @@ namespace { NSString* const kReloadImageName = @"reload_Template.pdf"; NSString* const kStopImageName = @"stop_Template.pdf"; +// Constant matches Windows. +NSTimeInterval kPendingReloadTimeout = 1.35; + } // namespace @implementation ReloadButton @@ -58,17 +61,17 @@ NSString* const kStopImageName = @"stop_Template.pdf"; } - (void)setIsLoading:(BOOL)isLoading force:(BOOL)force { - pendingReloadMode_ = NO; - // Can always transition to stop mode. Only transition to reload // mode if forced or if the mouse isn't hovering. Otherwise, note // that reload mode is desired and disable the button. if (isLoading) { + pendingReloadTimer_.reset(); [self setImage:nsimage_cache::ImageNamed(kStopImageName)]; [self setTag:IDC_STOP]; [self setToolTip:l10n_util::GetNSStringWithFixup(IDS_TOOLTIP_STOP)]; [self setEnabled:YES]; } else if (force || ![self isMouseInside]) { + pendingReloadTimer_.reset(); [self setImage:nsimage_cache::ImageNamed(kReloadImageName)]; [self setTag:IDC_RELOAD]; [self setToolTip:l10n_util::GetNSStringWithFixup(IDS_TOOLTIP_RELOAD)]; @@ -81,26 +84,34 @@ NSString* const kStopImageName = @"stop_Template.pdf"; if ([cell respondsToSelector:@selector(setMouseInside:animate:)]) [cell setMouseInside:[self isMouseInside] animate:NO]; [self setEnabled:YES]; - } else if ([self tag] == IDC_STOP) { - pendingReloadMode_ = YES; + } else if ([self tag] == IDC_STOP && !pendingReloadTimer_) { [self setEnabled:NO]; + pendingReloadTimer_.reset( + [[NSTimer scheduledTimerWithTimeInterval:kPendingReloadTimeout + target:self + selector:@selector(forceReloadState) + userInfo:nil + repeats:NO] retain]); } } +- (void)forceReloadState { + [self setIsLoading:NO force:YES]; +} + - (BOOL)sendAction:(SEL)theAction to:(id)theTarget { if ([self tag] == IDC_STOP) { - // The stop command won't be valid after the attempt to change - // back to reload. But it "worked", so short-circuit it. - const BOOL ret = - pendingReloadMode_ ? YES : [super sendAction:theAction to:theTarget]; + // When the timer is started, the button is disabled, so this + // should not be possible. + DCHECK(!pendingReloadTimer_.get()); // When the stop is processed, immediately change to reload mode, // even though the IPC still has to bounce off the renderer and // back before the regular |-setIsLoaded:force:| will be called. // [This is how views and gtk do it.] + const BOOL ret = [super sendAction:theAction to:theTarget]; if (ret) - [self setIsLoading:NO force:YES]; - + [self forceReloadState]; return ret; } @@ -115,12 +126,12 @@ NSString* const kStopImageName = @"stop_Template.pdf"; isMouseInside_ = NO; // Reload mode was requested during the hover. - if (pendingReloadMode_) - [self setIsLoading:NO force:YES]; + if (pendingReloadTimer_) + [self forceReloadState]; } - (BOOL)isMouseInside { - return trackingArea_ && isMouseInside_; + return isMouseInside_; } - (ViewID)viewID { @@ -131,6 +142,10 @@ NSString* const kStopImageName = @"stop_Template.pdf"; @implementation ReloadButton (Testing) ++ (void)setPendingReloadTimeout:(NSTimeInterval)seconds { + kPendingReloadTimeout = seconds; +} + - (NSTrackingArea*)trackingArea { return trackingArea_; } diff --git a/chrome/browser/cocoa/reload_button_unittest.mm b/chrome/browser/cocoa/reload_button_unittest.mm index c2c9e84..19fde82 100644 --- a/chrome/browser/cocoa/reload_button_unittest.mm +++ b/chrome/browser/cocoa/reload_button_unittest.mm @@ -7,7 +7,7 @@ #import "chrome/browser/cocoa/reload_button.h" #include "base/scoped_nsobject.h" -#include "chrome/app/chrome_dll_resource.h" +#include "chrome/app/chrome_command_ids.h" #import "chrome/browser/cocoa/cocoa_test_helper.h" #import "chrome/browser/cocoa/test_event_utils.h" #include "testing/gtest/include/gtest/gtest.h" @@ -109,7 +109,7 @@ TEST_F(ReloadButtonTest, SetIsLoadingForce) { // Test that without force, stop mode is set immediately, but reload // is affected by the hover status. -TEST_F(ReloadButtonTest, SetIsLoadingNoForce) { +TEST_F(ReloadButtonTest, SetIsLoadingNoForceUnHover) { EXPECT_FALSE([button_ isMouseInside]); EXPECT_EQ([button_ tag], IDC_RELOAD); @@ -142,6 +142,54 @@ TEST_F(ReloadButtonTest, SetIsLoadingNoForce) { EXPECT_EQ([button_ tag], IDC_RELOAD); } +// Test that without force, stop mode is set immediately, and reload +// will be set after a timeout. +// TODO(shess): Reenable, http://crbug.com/61485 +TEST_F(ReloadButtonTest, DISABLED_SetIsLoadingNoForceTimeout) { + // When the event loop first spins, some delayed tracking-area setup + // is done, which causes -mouseExited: to be called. Spin it at + // least once, and dequeue any pending events. + // TODO(shess): It would be more reasonable to have an MockNSTimer + // factory for the class to use, which this code could fire + // directly. + while ([NSApp nextEventMatchingMask:NSAnyEventMask + untilDate:nil + inMode:NSDefaultRunLoopMode + dequeue:YES]) { + } + + const NSTimeInterval kShortTimeout = 0.1; + [ReloadButton setPendingReloadTimeout:kShortTimeout]; + + EXPECT_FALSE([button_ isMouseInside]); + EXPECT_EQ(IDC_RELOAD, [button_ tag]); + + // Move the mouse into the button and press it. + [button_ mouseEntered:nil]; + EXPECT_TRUE([button_ isMouseInside]); + [button_ setIsLoading:YES force:NO]; + EXPECT_EQ(IDC_STOP, [button_ tag]); + + // Does not change to reload immediately when the mouse is hovered. + EXPECT_TRUE([button_ isMouseInside]); + [button_ setIsLoading:NO force:NO]; + EXPECT_TRUE([button_ isMouseInside]); + EXPECT_EQ(IDC_STOP, [button_ tag]); + EXPECT_TRUE([button_ isMouseInside]); + + // Spin event loop until the timeout passes. + NSDate* pastTimeout = [NSDate dateWithTimeIntervalSinceNow:2 * kShortTimeout]; + [NSApp nextEventMatchingMask:NSAnyEventMask + untilDate:pastTimeout + inMode:NSDefaultRunLoopMode + dequeue:NO]; + + // Mouse is still hovered, button is in reload mode. If the mouse + // is no longer hovered, see comment at top of function. + EXPECT_TRUE([button_ isMouseInside]); + EXPECT_EQ(IDC_RELOAD, [button_ tag]); +} + // Test that pressing stop after reload mode has been requested // doesn't forward the stop message. TEST_F(ReloadButtonTest, StopAfterReloadSet) { diff --git a/chrome/browser/cocoa/sad_tab_controller_unittest.mm b/chrome/browser/cocoa/sad_tab_controller_unittest.mm index c125f87..7797397 100644 --- a/chrome/browser/cocoa/sad_tab_controller_unittest.mm +++ b/chrome/browser/cocoa/sad_tab_controller_unittest.mm @@ -2,6 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include "base/debug/debugger.h" #include "base/scoped_nsobject.h" #import "chrome/browser/cocoa/cocoa_test_helper.h" #import "chrome/browser/cocoa/sad_tab_controller.h" @@ -35,7 +36,7 @@ class SadTabControllerTest : public RenderViewHostTestHarness { // from CocoaTest, so do a bootstrap and create test window. CocoaTest::BootstrapCocoa(); test_window_ = [[CocoaTestHelperWindow alloc] init]; - if (DebugUtil::BeingDebugged()) { + if (base::debug::BeingDebugged()) { [test_window_ orderFront:nil]; } else { [test_window_ orderBack:nil]; diff --git a/chrome/browser/cocoa/search_engine_dialog_controller.h b/chrome/browser/cocoa/search_engine_dialog_controller.h index a410614..0cc06f2 100644 --- a/chrome/browser/cocoa/search_engine_dialog_controller.h +++ b/chrome/browser/cocoa/search_engine_dialog_controller.h @@ -6,6 +6,7 @@ #include <vector> +#import "base/ref_counted.h" #import "base/scoped_nsobject.h" #include "base/scoped_ptr.h" @@ -27,7 +28,7 @@ class TemplateURLModel; TemplateURLModel* searchEnginesModel_; // Bridge to the C++ world. - scoped_ptr<SearchEngineDialogControllerBridge> bridge_; + scoped_refptr<SearchEngineDialogControllerBridge> bridge_; // Offered search engine choices. std::vector<const TemplateURL*> choices_; diff --git a/chrome/browser/cocoa/search_engine_dialog_controller.mm b/chrome/browser/cocoa/search_engine_dialog_controller.mm index 044bb58..0888050 100644 --- a/chrome/browser/cocoa/search_engine_dialog_controller.mm +++ b/chrome/browser/cocoa/search_engine_dialog_controller.mm @@ -40,7 +40,9 @@ const int kLogoLabelHeight = 25; - (IBAction)searchEngineSelected:(id)sender; @end -class SearchEngineDialogControllerBridge : public TemplateURLModelObserver { +class SearchEngineDialogControllerBridge : + public base::RefCounted<SearchEngineDialogControllerBridge>, + public TemplateURLModelObserver { public: SearchEngineDialogControllerBridge(SearchEngineDialogController* controller); @@ -71,7 +73,7 @@ void SearchEngineDialogControllerBridge::OnTemplateURLModelChanged() { ofType:@"nib"]; self = [super initWithWindowNibPath:nibpath owner:self]; if (self != nil) { - bridge_.reset(new SearchEngineDialogControllerBridge(self)); + bridge_ = new SearchEngineDialogControllerBridge(self); } return self; } @@ -85,11 +87,15 @@ void SearchEngineDialogControllerBridge::OnTemplateURLModelChanged() { searchEnginesModel_->AddObserver(bridge_.get()); if (searchEnginesModel_->loaded()) { - [self onTemplateURLModelChanged]; + MessageLoop::current()->PostTask( + FROM_HERE, + NewRunnableMethod( + bridge_.get(), + &SearchEngineDialogControllerBridge::OnTemplateURLModelChanged)); } else { searchEnginesModel_->Load(); - MessageLoop::current()->Run(); } + MessageLoop::current()->Run(); } - (void)onTemplateURLModelChanged { diff --git a/chrome/browser/cocoa/shell_dialogs_mac.mm b/chrome/browser/cocoa/shell_dialogs_mac.mm index bb1ad05..46f5ea2 100644 --- a/chrome/browser/cocoa/shell_dialogs_mac.mm +++ b/chrome/browser/cocoa/shell_dialogs_mac.mm @@ -13,6 +13,7 @@ #include "app/l10n_util_mac.h" #import "base/cocoa_protocols_mac.h" +#include "base/file_util.h" #include "base/logging.h" #include "base/mac_util.h" #include "base/mac/scoped_cftyperef.h" @@ -165,8 +166,13 @@ void SelectFileDialogImpl::SelectFile( NSString* default_dir = nil; NSString* default_filename = nil; if (!default_path.empty()) { - default_dir = base::SysUTF8ToNSString(default_path.DirName().value()); - default_filename = base::SysUTF8ToNSString(default_path.BaseName().value()); + if (file_util::DirectoryExists(default_path)) { + default_dir = base::SysUTF8ToNSString(default_path.value()); + } else { + default_dir = base::SysUTF8ToNSString(default_path.DirName().value()); + default_filename = + base::SysUTF8ToNSString(default_path.BaseName().value()); + } } NSMutableArray* allowed_file_types = nil; diff --git a/chrome/browser/cocoa/speech_input_window_controller.mm b/chrome/browser/cocoa/speech_input_window_controller.mm index 191549f..76d1dd1 100644 --- a/chrome/browser/cocoa/speech_input_window_controller.mm +++ b/chrome/browser/cocoa/speech_input_window_controller.mm @@ -42,6 +42,8 @@ const int kBubbleHorizontalMargin = 5; // Space on either sides of controls. } - (void)awakeFromNib { + [super awakeFromNib]; + NSWindow* window = [self window]; [[self bubble] setArrowLocation:info_bubble::kTopLeft]; diff --git a/chrome/browser/cocoa/status_bubble_mac.mm b/chrome/browser/cocoa/status_bubble_mac.mm index 447d263..58da593 100644 --- a/chrome/browser/cocoa/status_bubble_mac.mm +++ b/chrome/browser/cocoa/status_bubble_mac.mm @@ -152,8 +152,8 @@ void StatusBubbleMac::SetURL(const GURL& url, const string16& languages) { [font pointSize]); string16 original_url_text = net::FormatUrl(url, UTF16ToUTF8(languages)); - string16 status = WideToUTF16(gfx::ElideUrl(url, font_chr, text_width, - UTF16ToWideHack(languages))); + string16 status = gfx::ElideUrl(url, font_chr, text_width, + UTF16ToWideHack(languages)); SetText(status, true); @@ -608,8 +608,8 @@ void StatusBubbleMac::ExpandBubble() { NSFont* font = [[window_ contentView] font]; gfx::Font font_chr(base::SysNSStringToWide([font fontName]), [font pointSize]); - string16 expanded_url = WideToUTF16(gfx::ElideUrl(url_, font_chr, - max_bubble_width, UTF16ToWide(languages_))); + string16 expanded_url = gfx::ElideUrl(url_, font_chr, + max_bubble_width, UTF16ToWideHack(languages_)); // Scale width from gfx::Font in view coordinates to window coordinates. int required_width_for_string = diff --git a/chrome/browser/cocoa/tab_strip_controller.mm b/chrome/browser/cocoa/tab_strip_controller.mm index fab844b..8d06213 100644 --- a/chrome/browser/cocoa/tab_strip_controller.mm +++ b/chrome/browser/cocoa/tab_strip_controller.mm @@ -14,8 +14,9 @@ #include "base/mac_util.h" #include "base/nsimage_cache_mac.h" #include "base/sys_string_conversions.h" -#include "chrome/app/chrome_dll_resource.h" +#include "chrome/app/chrome_command_ids.h" #include "chrome/browser/browser.h" +#include "chrome/browser/browser_navigator.h" #include "chrome/browser/find_bar.h" #include "chrome/browser/find_bar_controller.h" #include "chrome/browser/metrics/user_metrics.h" @@ -1350,6 +1351,11 @@ private: TabController* tabController = [tabArray_ objectAtIndex:index]; DCHECK([tabController isKindOfClass:[TabController class]]); + + // Don't do anything if the change was already picked up by the move event. + if (tabStripModel_->IsMiniTab(modelIndex) == [tabController mini]) + return; + [tabController setMini:tabStripModel_->IsMiniTab(modelIndex)]; [tabController setPinned:tabStripModel_->IsTabPinned(modelIndex)]; [tabController setApp:tabStripModel_->IsAppTab(modelIndex)]; @@ -1697,11 +1703,12 @@ private: case NEW_FOREGROUND_TAB: { UserMetrics::RecordAction(UserMetricsAction("Tab_DropURLBetweenTabs"), browser_->profile()); - Browser::AddTabWithURLParams params(url, PageTransition::TYPED); - params.index = index; - params.add_types = + browser::NavigateParams params(browser_, url, PageTransition::TYPED); + params.disposition = disposition; + params.tabstrip_index = index; + params.tabstrip_add_types = TabStripModel::ADD_SELECTED | TabStripModel::ADD_FORCE_INDEX; - browser_->AddTabWithURL(¶ms); + browser::Navigate(¶ms); break; } case CURRENT_TAB: diff --git a/chrome/browser/cocoa/tab_view.h b/chrome/browser/cocoa/tab_view.h index 74689c7..73c6334 100644 --- a/chrome/browser/cocoa/tab_view.h +++ b/chrome/browser/cocoa/tab_view.h @@ -47,6 +47,10 @@ enum AlertState { // TODO(rohitrao): Add this button to a CoreAnimation layer so we can fade it // in and out on mouseovers. IBOutlet HoverCloseButton* closeButton_; + + // See awakeFromNib for purpose. + scoped_nsobject<HoverCloseButton> closeButtonRetainer_; + BOOL closing_; // Tracking area for close button mouseover images. diff --git a/chrome/browser/cocoa/tab_view.mm b/chrome/browser/cocoa/tab_view.mm index 7b7ed59..1550d7e 100644 --- a/chrome/browser/cocoa/tab_view.mm +++ b/chrome/browser/cocoa/tab_view.mm @@ -8,6 +8,7 @@ #import "base/mac_util.h" #include "base/mac/scoped_cftyperef.h" #include "base/nsimage_cache_mac.h" +#include "chrome/browser/accessibility/browser_accessibility_state.h" #import "chrome/browser/cocoa/tab_controller.h" #import "chrome/browser/cocoa/tab_window_controller.h" #import "chrome/browser/cocoa/themed_window.h" @@ -73,6 +74,16 @@ const CGFloat kRapidCloseDist = 2.5; - (void)awakeFromNib { [self setShowsDivider:NO]; + + // It is desirable for us to remove the close button from the cocoa hierarchy, + // so that VoiceOver does not encounter it. + // TODO(dtseng): crbug.com/59978. + // Retain in case we remove it from its superview. + closeButtonRetainer_.reset([closeButton_ retain]); + if (Singleton<BrowserAccessibilityState>::get()->IsAccessibleBrowser()) { + // The superview gives up ownership of the closeButton here. + [closeButton_ removeFromSuperview]; + } } - (void)dealloc { diff --git a/chrome/browser/cocoa/tabpose_window.mm b/chrome/browser/cocoa/tabpose_window.mm index 33fcb6a..dde7caf 100644 --- a/chrome/browser/cocoa/tabpose_window.mm +++ b/chrome/browser/cocoa/tabpose_window.mm @@ -11,7 +11,7 @@ #include "base/mac/scoped_cftyperef.h" #include "base/scoped_callback_factory.h" #include "base/sys_string_conversions.h" -#include "chrome/app/chrome_dll_resource.h" +#include "chrome/app/chrome_command_ids.h" #include "chrome/browser/browser_process.h" #import "chrome/browser/cocoa/bookmarks/bookmark_bar_constants.h" #import "chrome/browser/cocoa/browser_window_controller.h" diff --git a/chrome/browser/cocoa/task_manager_mac.mm b/chrome/browser/cocoa/task_manager_mac.mm index b4cee66..65241d2 100644 --- a/chrome/browser/cocoa/task_manager_mac.mm +++ b/chrome/browser/cocoa/task_manager_mac.mm @@ -195,6 +195,12 @@ class SortHelper { [tableView_ sizeToFit]; } +- (void)dealloc { + [tableView_ setDelegate:nil]; + [tableView_ setDataSource:nil]; + [super dealloc]; +} + // Adds a column which has the given string id as title. |isVisible| specifies // if the column is initially visible. - (NSTableColumn*)addColumnWithId:(int)columnId visible:(BOOL)isVisible { diff --git a/chrome/browser/cocoa/toolbar_controller.mm b/chrome/browser/cocoa/toolbar_controller.mm index 4405b3f..25e031b 100644 --- a/chrome/browser/cocoa/toolbar_controller.mm +++ b/chrome/browser/cocoa/toolbar_controller.mm @@ -14,7 +14,7 @@ #include "base/nsimage_cache_mac.h" #include "base/singleton.h" #include "base/sys_string_conversions.h" -#include "chrome/app/chrome_dll_resource.h" +#include "chrome/app/chrome_command_ids.h" #include "chrome/browser/autocomplete/autocomplete_edit_view.h" #include "chrome/browser/browser.h" #include "chrome/browser/browser_window.h" diff --git a/chrome/browser/cocoa/toolbar_controller_unittest.mm b/chrome/browser/cocoa/toolbar_controller_unittest.mm index 03914c6..43fbafb 100644 --- a/chrome/browser/cocoa/toolbar_controller_unittest.mm +++ b/chrome/browser/cocoa/toolbar_controller_unittest.mm @@ -5,7 +5,7 @@ #import <Cocoa/Cocoa.h> #import "base/scoped_nsobject.h" -#include "chrome/app/chrome_dll_resource.h" +#include "chrome/app/chrome_command_ids.h" #include "chrome/browser/cocoa/browser_test_helper.h" #import "chrome/browser/cocoa/cocoa_test_helper.h" #import "chrome/browser/cocoa/gradient_button_cell.h" diff --git a/chrome/browser/cocoa/translate/translate_infobar_base.mm b/chrome/browser/cocoa/translate/translate_infobar_base.mm index bdc34f0..48ce514 100644 --- a/chrome/browser/cocoa/translate/translate_infobar_base.mm +++ b/chrome/browser/cocoa/translate/translate_infobar_base.mm @@ -10,7 +10,7 @@ #include "base/mac_util.h" #include "base/metrics/histogram.h" #include "base/sys_string_conversions.h" -#include "chrome/app/chrome_dll_resource.h" +#include "chrome/app/chrome_command_ids.h" #import "chrome/browser/cocoa/hover_close_button.h" #include "chrome/browser/cocoa/infobar.h" #import "chrome/browser/cocoa/infobar_controller.h" diff --git a/chrome/browser/cocoa/translate/translate_infobar_unittest.mm b/chrome/browser/cocoa/translate/translate_infobar_unittest.mm index a389eba..fbe85b0 100644 --- a/chrome/browser/cocoa/translate/translate_infobar_unittest.mm +++ b/chrome/browser/cocoa/translate/translate_infobar_unittest.mm @@ -7,7 +7,7 @@ #import "base/scoped_nsobject.h" #import "base/string_util.h" #include "base/utf_string_conversions.h" -#import "chrome/app/chrome_dll_resource.h" // For translate menu command ids. +#import "chrome/app/chrome_command_ids.h" // For translate menu command ids. #import "chrome/browser/cocoa/browser_test_helper.h" #import "chrome/browser/cocoa/cocoa_test_helper.h" #import "chrome/browser/cocoa/infobar.h" diff --git a/chrome/browser/cocoa/web_drag_source.mm b/chrome/browser/cocoa/web_drag_source.mm index a2402da..95ab0d1 100644 --- a/chrome/browser/cocoa/web_drag_source.mm +++ b/chrome/browser/cocoa/web_drag_source.mm @@ -307,13 +307,13 @@ void PromiseWriterTask::Run() { if (downloadURL_.is_valid()) { TabContents* tabContents = [contentsView_ tabContents]; - scoped_refptr<DragDownloadFile> dragFileDownloader = new DragDownloadFile( + scoped_refptr<DragDownloadFile> dragFileDownloader(new DragDownloadFile( filePath, linked_ptr<net::FileStream>(fileStream), downloadURL_, tabContents->GetURL(), tabContents->encoding(), - tabContents); + tabContents)); // The finalizer will take care of closing and deletion. dragFileDownloader->Start( diff --git a/chrome/browser/cocoa/wrench_menu_button_cell_unittest.mm b/chrome/browser/cocoa/wrench_menu_button_cell_unittest.mm index e736fdc..b24ad50 100644 --- a/chrome/browser/cocoa/wrench_menu_button_cell_unittest.mm +++ b/chrome/browser/cocoa/wrench_menu_button_cell_unittest.mm @@ -3,7 +3,7 @@ // found in the LICENSE file. #include "base/scoped_nsobject.h" -#include "chrome/app/chrome_dll_resource.h" +#include "chrome/app/chrome_command_ids.h" #import "chrome/browser/cocoa/cocoa_test_helper.h" #import "chrome/browser/cocoa/wrench_menu_button_cell.h" #include "testing/gtest/include/gtest/gtest.h" diff --git a/chrome/browser/cocoa/wrench_menu_controller.mm b/chrome/browser/cocoa/wrench_menu_controller.mm index 5b0a92a..7cecb71 100644 --- a/chrome/browser/cocoa/wrench_menu_controller.mm +++ b/chrome/browser/cocoa/wrench_menu_controller.mm @@ -7,7 +7,7 @@ #include "app/l10n_util.h" #include "app/menus/menu_model.h" #include "base/sys_string_conversions.h" -#include "chrome/app/chrome_dll_resource.h" +#include "chrome/app/chrome_command_ids.h" #include "chrome/browser/browser.h" #include "chrome/browser/browser_window.h" #import "chrome/browser/cocoa/menu_tracked_root_view.h" diff --git a/chrome/browser/cocoa/wrench_menu_controller_unittest.mm b/chrome/browser/cocoa/wrench_menu_controller_unittest.mm index 446bd80..1018666 100644 --- a/chrome/browser/cocoa/wrench_menu_controller_unittest.mm +++ b/chrome/browser/cocoa/wrench_menu_controller_unittest.mm @@ -3,7 +3,7 @@ // found in the LICENSE file. #include "base/scoped_nsobject.h" -#include "chrome/app/chrome_dll_resource.h" +#include "chrome/app/chrome_command_ids.h" #include "chrome/browser/cocoa/browser_test_helper.h" #import "chrome/browser/cocoa/cocoa_test_helper.h" #import "chrome/browser/cocoa/toolbar_controller.h" |
