diff options
20 files changed, 267 insertions, 145 deletions
diff --git a/chrome/browser/autocomplete/autocomplete_edit_view_mac.mm b/chrome/browser/autocomplete/autocomplete_edit_view_mac.mm index 9ba16ef..5843584 100644 --- a/chrome/browser/autocomplete/autocomplete_edit_view_mac.mm +++ b/chrome/browser/autocomplete/autocomplete_edit_view_mac.mm @@ -15,8 +15,8 @@ #include "chrome/browser/autocomplete/autocomplete_popup_view_mac.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/cocoa/autocomplete_text_field.h" +#include "chrome/browser/cocoa/event_utils.h" #include "chrome/browser/tab_contents/tab_contents.h" -#import "chrome/common/cocoa_utils.h" // Focus-handling between |field_| and |model_| is a bit subtle. // Other platforms detect change of focus, which is inconvenient @@ -692,8 +692,8 @@ std::wstring AutocompleteEditViewMac::GetClipboardText(Clipboard* clipboard) { NSEvent* event = [NSApp currentEvent]; if (cmd == @selector(insertNewline:) || (cmd == @selector(noop:) && [event keyCode] == kVK_Return)) { - WindowOpenDisposition disposition = event_utils::DispositionFromEventFlags( - [event modifierFlags]); + WindowOpenDisposition disposition = + event_utils::WindowOpenDispositionFromNSEvent(event); edit_view_->AcceptInput(disposition, false); return YES; } @@ -704,8 +704,8 @@ std::wstring AutocompleteEditViewMac::GetClipboardText(Clipboard* clipboard) { // is safe to tell it twice. if (cmd == @selector(insertLineBreak:)) { edit_view_->OnControlKeyChanged(true); - WindowOpenDisposition disposition = event_utils::DispositionFromEventFlags( - [[NSApp currentEvent] modifierFlags]); + WindowOpenDisposition disposition = + event_utils::WindowOpenDispositionFromNSEvent([NSApp currentEvent]); edit_view_->AcceptInput(disposition, false); return YES; } diff --git a/chrome/browser/autocomplete/autocomplete_popup_view_mac.mm b/chrome/browser/autocomplete/autocomplete_popup_view_mac.mm index 1d54c9e..c545ee4 100644 --- a/chrome/browser/autocomplete/autocomplete_popup_view_mac.mm +++ b/chrome/browser/autocomplete/autocomplete_popup_view_mac.mm @@ -8,8 +8,8 @@ #include "chrome/browser/autocomplete/autocomplete_edit.h" #include "chrome/browser/autocomplete/autocomplete_edit_view_mac.h" #include "chrome/browser/autocomplete/autocomplete_popup_model.h" +#include "chrome/browser/cocoa/event_utils.h" #include "chrome/browser/cocoa/nsimage_cache.h" -#import "chrome/common/cocoa_utils.h" namespace { @@ -268,9 +268,9 @@ void AutocompletePopupViewMac::CreatePopupIfNeeded() { // We need the popup to follow window resize. NSNotificationCenter *nc = [NSNotificationCenter defaultCenter]; - [nc addObserver:matrix_target_ - selector:@selector(windowDidResize:) - name:NSWindowDidResizeNotification + [nc addObserver:matrix_target_ + selector:@selector(windowDidResize:) + name:NSWindowDidResizeNotification object:[field_ window]]; } } @@ -287,7 +287,7 @@ void AutocompletePopupViewMac::UpdatePopupAppearance() { NSNotificationCenter *nc = [NSNotificationCenter defaultCenter]; [nc removeObserver:matrix_target_ - name:NSWindowDidResizeNotification + name:NSWindowDidResizeNotification object:[field_ window]]; popup_.reset(nil); @@ -380,8 +380,8 @@ void AutocompletePopupViewMac::AcceptInput() { PaintUpdatesNow(); } else { model_->SetSelectedLine(selectedRow, false); - WindowOpenDisposition disposition = event_utils::DispositionFromEventFlags( - [[NSApp currentEvent] modifierFlags]); + WindowOpenDisposition disposition = + event_utils::WindowOpenDispositionFromNSEvent([NSApp currentEvent]); edit_view_->AcceptInput(disposition, false); } } diff --git a/chrome/browser/browser.cc b/chrome/browser/browser.cc index d72c24a..4d54c4d 100644 --- a/chrome/browser/browser.cc +++ b/chrome/browser/browser.cc @@ -580,7 +580,7 @@ TabContents* Browser::AddTabWithURL( } else { // We're in an app window or a popup window. Find an existing browser to // open this URL in, creating one if none exists. - Browser* b = GetOrCreateTabbedBrowser(); + Browser* b = GetOrCreateTabbedBrowser(profile_); contents = b->AddTabWithURL(url, referrer, transition, foreground, index, force_index, instance); b->window()->Show(); @@ -832,7 +832,7 @@ void Browser::NewTab() { if (type() == TYPE_NORMAL) { AddBlankTab(true); } else { - Browser* b = GetOrCreateTabbedBrowser(); + Browser* b = GetOrCreateTabbedBrowser(profile_); b->AddBlankTab(true); b->window()->Show(); // The call to AddBlankTab above did not set the focus to the tab as its @@ -1779,7 +1779,7 @@ void Browser::AddNewContents(TabContents* source, if (tabstrip_model_.count() > 0 && disposition != NEW_WINDOW && disposition != NEW_POPUP && type_ != TYPE_NORMAL) { - Browser* b = GetOrCreateTabbedBrowser(); + Browser* b = GetOrCreateTabbedBrowser(profile_); DCHECK(b); PageTransition::Type transition = PageTransition::LINK; // If we were called from an "installed webapp" we want to emulate the code @@ -2585,11 +2585,12 @@ bool Browser::CanCloseWithInProgressDownloads() { /////////////////////////////////////////////////////////////////////////////// // Browser, Assorted utility functions (private): -Browser* Browser::GetOrCreateTabbedBrowser() { +// static +Browser* Browser::GetOrCreateTabbedBrowser(Profile* profile) { Browser* browser = BrowserList::FindBrowserWithType( - profile_, TYPE_NORMAL); + profile, TYPE_NORMAL); if (!browser) - browser = Browser::Create(profile_); + browser = Browser::Create(profile); return browser; } @@ -2637,7 +2638,7 @@ void Browser::OpenURLAtIndex(TabContents* source, return; } - Browser* b = GetOrCreateTabbedBrowser(); + Browser* b = GetOrCreateTabbedBrowser(profile_); DCHECK(b); // If we have just created a new browser window, make sure we select the diff --git a/chrome/browser/browser.h b/chrome/browser/browser.h index b2addca..0ea7629 100644 --- a/chrome/browser/browser.h +++ b/chrome/browser/browser.h @@ -403,6 +403,9 @@ class Browser : public TabStripModelDelegate, static Browser* GetBrowserForController( const NavigationController* controller, int* index); + // Retrieve the last active tabbed browser with a profile matching |profile|. + // Creates a new Browser if none are available. + static Browser* GetOrCreateTabbedBrowser(Profile* profile); // Helper function to create a new popup window. static void BuildPopupWindowHelper(TabContents* source, @@ -613,10 +616,6 @@ class Browser : public TabStripModelDelegate, // Assorted utility functions /////////////////////////////////////////////// - // Retrieve the last active tabbed browser with the same profile as the - // receiving Browser. Creates a new Browser if none are available. - Browser* GetOrCreateTabbedBrowser(); - // The low-level function that other OpenURL...() functions call. This // determines the appropriate SiteInstance to pass to AddTabWithURL(), focuses // the newly created tab as needed, and does other miscellaneous housekeeping. diff --git a/chrome/browser/cocoa/bookmark_bar_controller.mm b/chrome/browser/cocoa/bookmark_bar_controller.mm index 5d25b67..1f64cf4 100644 --- a/chrome/browser/cocoa/bookmark_bar_controller.mm +++ b/chrome/browser/cocoa/bookmark_bar_controller.mm @@ -14,14 +14,25 @@ #import "chrome/browser/cocoa/bookmark_editor_controller.h" #import "chrome/browser/cocoa/bookmark_name_folder_controller.h" #import "chrome/browser/cocoa/bookmark_menu_cocoa_controller.h" +#import "chrome/browser/cocoa/event_utils.h" #import "chrome/browser/cocoa/view_resizer.h" #include "chrome/browser/cocoa/nsimage_cache.h" #include "chrome/browser/profile.h" -#import "chrome/common/cocoa_utils.h" #include "chrome/common/pref_names.h" #include "chrome/common/pref_service.h" #include "skia/ext/skia_utils_mac.h" +// Specialization of NSButton that responds to middle-clicks. By default, +// NSButton ignores them. +@interface BookmarkButton : NSButton +@end + +@implementation BookmarkButton +- (void)otherMouseUp:(NSEvent*) event { + [self performClick:self]; +} +@end + @interface BookmarkBarController(Private) - (void)applyContentAreaOffset:(BOOL)apply immediately:(BOOL)immediately; - (void)showBookmarkBar:(BOOL)enable immediately:(BOOL)immediately; @@ -40,7 +51,8 @@ const int kBookmarkBarHeight = 30; const CGFloat kDefaultBookmarkWidth = 150.0; const CGFloat kBookmarkVerticalPadding = 2.0; const CGFloat kBookmarkHorizontalPadding = 1.0; -}; + +} // namespace @implementation BookmarkBarController @@ -186,9 +198,9 @@ const CGFloat kBookmarkHorizontalPadding = 1.0; - (IBAction)openBookmark:(id)sender { BookmarkNode* node = [self nodeFromButton:sender]; - WindowOpenDisposition disposition = event_utils::DispositionFromEventFlags( - [[NSApp currentEvent] modifierFlags]); - [urlDelegate_ openBookmarkURL:node->GetURL() disposition:disposition]; + [urlDelegate_ openBookmarkURL:node->GetURL() + disposition:event_utils::WindowOpenDispositionFromNSEvent( + [NSApp currentEvent])]; } // Given a NSMenuItem tag, return the appropriate bookmark node id. @@ -501,8 +513,8 @@ const CGFloat kBookmarkHorizontalPadding = 1.0; - (IBAction)openBookmarkMenuItem:(id)sender { int64 tag = [self nodeIdFromMenuTag:[sender tag]]; const BookmarkNode* node = bookmarkModel_->GetNodeByID(tag); - WindowOpenDisposition disposition = event_utils::DispositionFromEventFlags( - [[NSApp currentEvent] modifierFlags]); + WindowOpenDisposition disposition = + event_utils::WindowOpenDispositionFromNSEvent([NSApp currentEvent]); [urlDelegate_ openBookmarkURL:node->GetURL() disposition:disposition]; } @@ -523,7 +535,7 @@ const CGFloat kBookmarkHorizontalPadding = 1.0; NSCell* cell = [self cellForBookmarkNode:child]; NSRect frame = [self frameForBookmarkButtonFromCell:cell xOffset:&x_offset]; - NSButton* button = [[[NSButton alloc] initWithFrame:frame] + NSButton* button = [[[BookmarkButton alloc] initWithFrame:frame] autorelease]; DCHECK(button); [buttons_ addObject:button]; diff --git a/chrome/browser/cocoa/bookmark_bar_controller_unittest.mm b/chrome/browser/cocoa/bookmark_bar_controller_unittest.mm index 161f12a..d72caa3 100644 --- a/chrome/browser/cocoa/bookmark_bar_controller_unittest.mm +++ b/chrome/browser/cocoa/bookmark_bar_controller_unittest.mm @@ -9,6 +9,7 @@ #import "chrome/browser/cocoa/bookmark_bar_controller.h" #include "chrome/browser/cocoa/browser_test_helper.h" #import "chrome/browser/cocoa/cocoa_test_helper.h" +#include "chrome/browser/cocoa/test_event_utils.h" #import "chrome/browser/cocoa/view_resizer_pong.h" #include "testing/gtest/include/gtest/gtest.h" @@ -503,6 +504,25 @@ TEST_F(BookmarkBarControllerTest, Display) { [[bar_ view] display]; } +// Test that middle clicking on a bookmark button results in an open action. +TEST_F(BookmarkBarControllerTest, MiddleClick) { + BookmarkModel* model = helper_.profile()->GetBookmarkModel(); + GURL gurl1("http://www.google.com/"); + std::wstring title1(L"x"); + model->SetURLStarred(gurl1, title1, true); + + EXPECT_EQ(1U, [[bar_ buttons] count]); + NSButton* first = [[bar_ buttons] objectAtIndex:0]; + EXPECT_TRUE(first); + + scoped_nsobject<BookmarkURLOpenerPong> pong([[BookmarkURLOpenerPong alloc] + init]); + [bar_ setUrlDelegate:pong.get()]; + [first otherMouseUp:test_event_utils::MakeMouseEvent(NSOtherMouseUp, 0)]; + EXPECT_EQ(pong.get()->urls_.size(), 1U); + [bar_ setUrlDelegate:nil]; +} + // Cannot test these methods since they simply call a single static // method, BookmarkEditor::Show(), which is impossible to mock. // editBookmark:, addPage: diff --git a/chrome/browser/cocoa/bookmark_menu_cocoa_controller.mm b/chrome/browser/cocoa/bookmark_menu_cocoa_controller.mm index 7d3df67..d3acf3a 100644 --- a/chrome/browser/cocoa/bookmark_menu_cocoa_controller.mm +++ b/chrome/browser/cocoa/bookmark_menu_cocoa_controller.mm @@ -8,9 +8,9 @@ #include "chrome/browser/browser.h" #import "chrome/browser/cocoa/bookmark_menu_bridge.h" #import "chrome/browser/cocoa/bookmark_menu_cocoa_controller.h" +#include "chrome/browser/cocoa/event_utils.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/tab_contents/tab_contents.h" -#import "chrome/common/cocoa_utils.h" #include "webkit/glue/window_open_disposition.h" namespace { @@ -50,21 +50,12 @@ const NSUInteger kMaximumMenuPixelsWide = 300; // Open the URL of the given BookmarkNode in the current tab. - (void)openURLForNode:(const BookmarkNode*)node { - Browser* browser = BrowserList::GetLastActive(); - - if (!browser) { // No windows open? - Browser::OpenEmptyWindow(bridge_->GetDefaultProfile()); - browser = BrowserList::GetLastActive(); - } - DCHECK(browser); - TabContents* tab_contents = browser->GetSelectedTabContents(); - DCHECK(tab_contents); - - // A TabContents is a PageNavigator, so we can OpenURL() on it. - WindowOpenDisposition disposition = event_utils::DispositionFromEventFlags( - [[NSApp currentEvent] modifierFlags]); - tab_contents->OpenURL(node->GetURL(), GURL(), disposition, - PageTransition::AUTO_BOOKMARK); + Browser* browser = + Browser::GetOrCreateTabbedBrowser(bridge_->GetDefaultProfile()); + WindowOpenDisposition disposition = + event_utils::WindowOpenDispositionFromNSEvent([NSApp currentEvent]); + browser->OpenURL(node->GetURL(), GURL(), disposition, + PageTransition::AUTO_BOOKMARK); } - (IBAction)openBookmarkMenuItem:(id)sender { diff --git a/chrome/browser/cocoa/browser_window_controller.mm b/chrome/browser/cocoa/browser_window_controller.mm index 70b0284..5918cc4 100644 --- a/chrome/browser/cocoa/browser_window_controller.mm +++ b/chrome/browser/cocoa/browser_window_controller.mm @@ -871,10 +871,7 @@ willPositionSheet:(NSWindow*)sheet // Called by the bookmark bar to open a URL. - (void)openBookmarkURL:(const GURL&)url disposition:(WindowOpenDisposition)disposition { - TabContents* tab_contents = browser_->GetSelectedTabContents(); - DCHECK(tab_contents); - tab_contents->OpenURL(url, GURL(), disposition, - PageTransition::AUTO_BOOKMARK); + browser_->OpenURL(url, GURL(), disposition, PageTransition::AUTO_BOOKMARK); } - (NSInteger)numberOfTabs { diff --git a/chrome/browser/cocoa/event_utils.h b/chrome/browser/cocoa/event_utils.h new file mode 100644 index 0000000..7d0f87b --- /dev/null +++ b/chrome/browser/cocoa/event_utils.h @@ -0,0 +1,21 @@ +// Copyright (c) 2009 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. + +#ifndef CHROME_BROWSER_COCOA_EVENT_UTILS_H_ +#define CHROME_BROWSER_COCOA_EVENT_UTILS_H_ + +#import <Cocoa/Cocoa.h> + +#include "webkit/glue/window_open_disposition.h" + +namespace event_utils { + +// Retrieves the WindowOpenDisposition used to open a link from a user gesture +// represented by |event|. For example, a Cmd+Click would mean open the +// associated link in a background tab. +WindowOpenDisposition WindowOpenDispositionFromNSEvent(NSEvent* event); + +} // namespace event_utils + +#endif // CHROME_BROWSER_COCOA_EVENT_UTILS_H_ diff --git a/chrome/browser/cocoa/event_utils.mm b/chrome/browser/cocoa/event_utils.mm new file mode 100644 index 0000000..a528d6c --- /dev/null +++ b/chrome/browser/cocoa/event_utils.mm @@ -0,0 +1,16 @@ +// Copyright (c) 2009 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 "chrome/browser/cocoa/event_utils.h" + +namespace event_utils { + +WindowOpenDisposition WindowOpenDispositionFromNSEvent(NSEvent* event) { + NSUInteger modifiers = [event modifierFlags]; + if ([event buttonNumber] == 2 || modifiers & NSCommandKeyMask) + return modifiers & NSShiftKeyMask ? NEW_FOREGROUND_TAB : NEW_BACKGROUND_TAB; + return modifiers & NSShiftKeyMask ? NEW_WINDOW : CURRENT_TAB; +} + +} // namespace event_utils diff --git a/chrome/browser/cocoa/event_utils_unittest.mm b/chrome/browser/cocoa/event_utils_unittest.mm new file mode 100644 index 0000000..c9d3642 --- /dev/null +++ b/chrome/browser/cocoa/event_utils_unittest.mm @@ -0,0 +1,62 @@ +// Copyright (c) 2009 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 <objc/objc-class.h> + +#import "chrome/browser/cocoa/cocoa_test_helper.h" +#include "chrome/browser/cocoa/event_utils.h" +#include "chrome/browser/cocoa/test_event_utils.h" +#include "testing/gtest/include/gtest/gtest.h" + +// We provide a donor class with a specially modified |modifierFlags| +// implementation that we swap with NSEvent's. This is because we can't create a +// NSEvent that represents a middle click with modifiers. +@interface TestEvent : NSObject +@end +@implementation TestEvent +- (NSUInteger)modifierFlags { return NSShiftKeyMask; } +@end + +namespace { + +class EventUtilsTest : public testing::Test { + private: + CocoaTestHelper cocoa_helper_; // Inits Cocoa, creates window, etc... +}; + +TEST_F(EventUtilsTest, TestWindowOpenDispositionFromNSEvent) { + // Left Click = same tab. + NSEvent* me = test_event_utils::MakeMouseEvent(NSLeftMouseUp, 0); + EXPECT_EQ(CURRENT_TAB, event_utils::WindowOpenDispositionFromNSEvent(me)); + + // Middle Click = new background tab. + me = test_event_utils::MakeMouseEvent(NSOtherMouseUp, 0); + EXPECT_EQ(NEW_BACKGROUND_TAB, + event_utils::WindowOpenDispositionFromNSEvent(me)); + + // Shift+Middle Click = new foreground tab. + { + ScopedClassSwizzler swizzler([NSEvent class], [TestEvent class], + @selector(modifierFlags)); + me = test_event_utils::MakeMouseEvent(NSOtherMouseUp, NSShiftKeyMask); + EXPECT_EQ(NEW_FOREGROUND_TAB, + event_utils::WindowOpenDispositionFromNSEvent(me)); + } + + // Cmd+Left Click = new background tab. + me = test_event_utils::MakeMouseEvent(NSLeftMouseUp, NSCommandKeyMask); + EXPECT_EQ(NEW_BACKGROUND_TAB, + event_utils::WindowOpenDispositionFromNSEvent(me)); + + // Cmd+Shift+Left Click = new foreground tab. + me = test_event_utils::MakeMouseEvent(NSLeftMouseUp, NSCommandKeyMask | NSShiftKeyMask); + EXPECT_EQ(NEW_FOREGROUND_TAB, + event_utils::WindowOpenDispositionFromNSEvent(me)); + + // Shift+Left Click = new window + me = test_event_utils::MakeMouseEvent(NSLeftMouseUp, NSShiftKeyMask); + EXPECT_EQ(NEW_WINDOW, event_utils::WindowOpenDispositionFromNSEvent(me)); +} + +} // namespace diff --git a/chrome/browser/cocoa/history_menu_cocoa_controller.mm b/chrome/browser/cocoa/history_menu_cocoa_controller.mm index b6523ab..89dd2f8 100644 --- a/chrome/browser/cocoa/history_menu_cocoa_controller.mm +++ b/chrome/browser/cocoa/history_menu_cocoa_controller.mm @@ -7,10 +7,10 @@ #import "chrome/browser/cocoa/history_menu_cocoa_controller.h" #include "chrome/browser/browser_list.h" #include "chrome/browser/browser_process.h" +#include "chrome/browser/cocoa/event_utils.h" #include "chrome/browser/history/history.h" #include "chrome/browser/history/history_types.h" #include "chrome/browser/tab_contents/tab_contents.h" -#import "chrome/common/cocoa_utils.h" #include "webkit/glue/window_open_disposition.h" @implementation HistoryMenuCocoaController @@ -25,21 +25,11 @@ // Open the URL of the given history item in the current tab. - (void)openURLForItem:(HistoryMenuBridge::HistoryItem&)node { - Browser* browser = BrowserList::GetLastActive(); - - if (!browser) { // No windows open? - Browser::OpenEmptyWindow(bridge_->profile()); - browser = BrowserList::GetLastActive(); - } - DCHECK(browser); - TabContents* tab_contents = browser->GetSelectedTabContents(); - DCHECK(tab_contents); - - // A TabContents is a PageNavigator, so we can OpenURL() on it. - WindowOpenDisposition disposition = event_utils::DispositionFromEventFlags( - [[NSApp currentEvent] modifierFlags]); - tab_contents->OpenURL(node.url, GURL(), disposition, - PageTransition::AUTO_BOOKMARK); + Browser* browser = Browser::GetOrCreateTabbedBrowser(bridge_->profile()); + WindowOpenDisposition disposition = + event_utils::WindowOpenDispositionFromNSEvent([NSApp currentEvent]); + browser->OpenURL(node.url, GURL(), disposition, + PageTransition::AUTO_BOOKMARK); } - (HistoryMenuBridge::HistoryItem)itemForTag:(NSInteger)tag { diff --git a/chrome/browser/cocoa/infobar_controller.mm b/chrome/browser/cocoa/infobar_controller.mm index ea496de..8e4affe 100644 --- a/chrome/browser/cocoa/infobar_controller.mm +++ b/chrome/browser/cocoa/infobar_controller.mm @@ -7,11 +7,11 @@ #include "base/logging.h" // for NOTREACHED() #include "base/mac_util.h" #include "base/sys_string_conversions.h" +#include "chrome/browser/cocoa/event_utils.h" #include "chrome/browser/cocoa/infobar.h" #import "chrome/browser/cocoa/infobar_container_controller.h" #import "chrome/browser/cocoa/infobar_controller.h" #include "chrome/browser/tab_contents/tab_contents.h" -#import "chrome/common/cocoa_utils.h" #include "skia/ext/skia_utils_mac.h" #include "webkit/glue/window_open_disposition.h" @@ -177,8 +177,8 @@ // is called by the InfobarTextField on its delegate (the // LinkInfoBarController). - (void)linkClicked { - WindowOpenDisposition disposition = event_utils::DispositionFromEventFlags( - [[NSApp currentEvent] modifierFlags]); + WindowOpenDisposition disposition = + event_utils::WindowOpenDispositionFromNSEvent([NSApp currentEvent]); if (delegate_->AsLinkInfoBarDelegate()->LinkClicked(disposition)) [self closeInfoBar]; } diff --git a/chrome/browser/cocoa/location_bar_view_mac.mm b/chrome/browser/cocoa/location_bar_view_mac.mm index bdb7c1b..1e0dbff 100644 --- a/chrome/browser/cocoa/location_bar_view_mac.mm +++ b/chrome/browser/cocoa/location_bar_view_mac.mm @@ -9,8 +9,8 @@ #include "chrome/browser/alternate_nav_url_fetcher.h" #import "chrome/browser/app_controller_mac.h" #import "chrome/browser/autocomplete/autocomplete_edit_view_mac.h" +#include "chrome/browser/cocoa/event_utils.h" #include "chrome/browser/command_updater.h" -#import "chrome/common/cocoa_utils.h" #include "third_party/skia/include/core/SkBitmap.h" // TODO(shess): This code is mostly copied from the gtk @@ -49,8 +49,8 @@ PageTransition::Type LocationBarViewMac::GetPageTransition() const { } void LocationBarViewMac::AcceptInput() { - WindowOpenDisposition disposition = event_utils::DispositionFromEventFlags( - [[NSApp currentEvent] modifierFlags]); + WindowOpenDisposition disposition = + event_utils::WindowOpenDispositionFromNSEvent([NSApp currentEvent]); AcceptInputWithDisposition(disposition); } diff --git a/chrome/browser/cocoa/test_event_utils.h b/chrome/browser/cocoa/test_event_utils.h new file mode 100644 index 0000000..c6e8f0a --- /dev/null +++ b/chrome/browser/cocoa/test_event_utils.h @@ -0,0 +1,35 @@ +// Copyright (c) 2009 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. + +#ifndef CHROME_BROWSER_COCOA_TEST_EVENT_UTILS_H_ +#define CHROME_BROWSER_COCOA_TEST_EVENT_UTILS_H_ + +#import <objc/objc-class.h> + +#include "base/logging.h" + +// Within a given scope, replace the selector |selector| on |target| with that +// from |source|. +class ScopedClassSwizzler { + public: + ScopedClassSwizzler(Class target, Class source, SEL selector); + ~ScopedClassSwizzler(); + + private: + Method old_selector_impl_; + Method new_selector_impl_; + + DISALLOW_COPY_AND_ASSIGN(ScopedClassSwizzler); +}; + +namespace test_event_utils { + +// Create a synthetic mouse event for testing. Currently this is very basic, +// flesh out as needed. +NSEvent* MakeMouseEvent(NSEventType type, NSUInteger modifiers); + +} // namespace test_event_utils + +#endif // CHROME_BROWSER_COCOA_TEST_EVENT_UTILS_H_ + diff --git a/chrome/browser/cocoa/test_event_utils.mm b/chrome/browser/cocoa/test_event_utils.mm new file mode 100644 index 0000000..f3b202d --- /dev/null +++ b/chrome/browser/cocoa/test_event_utils.mm @@ -0,0 +1,45 @@ +// Copyright (c) 2009 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 "chrome/browser/cocoa/test_event_utils.h" + +ScopedClassSwizzler::ScopedClassSwizzler(Class target, Class source, + SEL selector) { + old_selector_impl_ = class_getInstanceMethod(target, selector); + new_selector_impl_ = class_getInstanceMethod(source, selector); + method_exchangeImplementations(old_selector_impl_, new_selector_impl_); +} + +ScopedClassSwizzler::~ScopedClassSwizzler() { + method_exchangeImplementations(old_selector_impl_, new_selector_impl_); +} + +namespace test_event_utils { + +NSEvent* MakeMouseEvent(NSEventType type, NSUInteger modifiers) { + if (type == NSOtherMouseUp) { + // To synthesize middle clicks we need to create a CGEvent with the + // "center" button flags so that our resulting NSEvent will have the + // appropriate buttonNumber field. NSEvent provides no way to create a + // mouse event with a buttonNumber directly. + CGPoint location = { 0, 0 }; + CGEventRef event = CGEventCreateMouseEvent(NULL, kCGEventOtherMouseUp, + location, + kCGMouseButtonCenter); + return [NSEvent eventWithCGEvent:event]; + } + return [NSEvent mouseEventWithType:type + location:NSMakePoint(0, 0) + modifierFlags:modifiers + timestamp:0 + windowNumber:0 + context:nil + eventNumber:0 + clickCount:1 + pressure:1.0]; +} + +} // namespace test_event_utils diff --git a/chrome/chrome.gyp b/chrome/chrome.gyp index 1a6ba7d..a28eb1d 100644 --- a/chrome/chrome.gyp +++ b/chrome/chrome.gyp @@ -433,8 +433,6 @@ 'common/chrome_switches.h', 'common/classfactory.cc', 'common/classfactory.h', - 'common/cocoa_utils.mm', - 'common/cocoa_utils.h', 'common/common_glue.cc', 'common/common_param_traits.cc', 'common/common_param_traits.h', @@ -866,6 +864,8 @@ 'browser/cocoa/download_util_mac.mm', 'browser/cocoa/encoding_menu_controller_delegate_mac.h', 'browser/cocoa/encoding_menu_controller_delegate_mac.mm', + 'browser/cocoa/event_utils.h', + 'browser/cocoa/event_utils.mm', 'browser/cocoa/find_bar_bridge.h', 'browser/cocoa/find_bar_bridge.mm', 'browser/cocoa/find_bar_cocoa_controller.h', @@ -3819,6 +3819,7 @@ 'browser/cocoa/download_shelf_mac_unittest.mm', 'browser/cocoa/download_shelf_view_unittest.mm', 'browser/cocoa/download_util_mac_unittest.mm', + 'browser/cocoa/event_utils_unittest.mm', 'browser/cocoa/find_bar_bridge_unittest.mm', 'browser/cocoa/find_bar_cocoa_controller_unittest.mm', 'browser/cocoa/find_bar_view_unittest.mm', @@ -3844,6 +3845,8 @@ 'browser/cocoa/tab_strip_controller_unittest.mm', 'browser/cocoa/tab_strip_view_unittest.mm', 'browser/cocoa/tab_view_unittest.mm', + 'browser/cocoa/test_event_utils.h', + 'browser/cocoa/test_event_utils.mm', 'browser/cocoa/throbber_view_unittest.mm', 'browser/cocoa/toolbar_button_cell_unittest.mm', 'browser/cocoa/toolbar_controller_unittest.mm', @@ -3972,7 +3975,6 @@ 'common/bzip2_unittest.cc', 'common/child_process_logging_mac_unittest.mm', 'common/chrome_plugin_unittest.cc', - 'common/cocoa_utils_unittest.mm', 'common/common_param_traits_unittest.cc', 'common/extensions/extension_unittest.cc', 'common/extensions/url_pattern_unittest.cc', diff --git a/chrome/common/cocoa_utils.h b/chrome/common/cocoa_utils.h deleted file mode 100644 index 4607f987..0000000 --- a/chrome/common/cocoa_utils.h +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright (c) 2009 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. - -#ifndef CHROME_COMMON_COCOA_UTIL_H_ -#define CHROME_COMMON_COCOA_UTIL_H_ - -#import <Cocoa/Cocoa.h> -#include "webkit/glue/window_open_disposition.h" - -namespace event_utils { - -// Translates modifier flags from an NSEvent into a WindowOpenDisposition. For -// example, holding down Cmd (Apple) will cause pages to be opened in a new -// foreground tab. Pass this the result of -[NSEvent modifierFlags]. -WindowOpenDisposition DispositionFromEventFlags(NSUInteger modifiers); - -} // namespace event_utils - -#endif // CHROME_COMMON_COCOA_UTIL_H_ diff --git a/chrome/common/cocoa_utils.mm b/chrome/common/cocoa_utils.mm deleted file mode 100644 index 3472178..0000000 --- a/chrome/common/cocoa_utils.mm +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright (c) 2009 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 "chrome/common/cocoa_utils.h" - -namespace event_utils { - -// Translates modifier flags from an NSEvent into a WindowOpenDisposition. For -// example, holding down Cmd (Apple) will cause pages to be opened in a new -// foreground tab. Pass this the result of -[NSEvent modifierFlags]. -WindowOpenDisposition DispositionFromEventFlags(NSUInteger modifiers) { - if (modifiers & NSCommandKeyMask) { - return (modifiers & NSShiftKeyMask) ? - NEW_BACKGROUND_TAB : NEW_FOREGROUND_TAB; - } - - if (modifiers & NSShiftKeyMask) - return NEW_WINDOW; - // TODO: Browser::OpenURLAtIndex does not support SAVE_TO_DISK, so we can't - // offer to download the page. See DCHECK() and TODOs there. - return (false /* modifiers & NSAlternateKeyMask */) ? - SAVE_TO_DISK : CURRENT_TAB; -} - -} // namespace event_utils diff --git a/chrome/common/cocoa_utils_unittest.mm b/chrome/common/cocoa_utils_unittest.mm deleted file mode 100644 index e9ce0ae..0000000 --- a/chrome/common/cocoa_utils_unittest.mm +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright (c) 2009 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 "chrome/common/cocoa_utils.h" -#include "testing/gtest/include/gtest/gtest.h" - -TEST(CocoaUtilsTest, DispositionFromEventFlagsTest) { - ASSERT_EQ(NEW_FOREGROUND_TAB, - event_utils::DispositionFromEventFlags(NSCommandKeyMask)); - ASSERT_EQ(NEW_BACKGROUND_TAB, - event_utils::DispositionFromEventFlags(NSCommandKeyMask | - NSShiftKeyMask)); - ASSERT_EQ(NEW_WINDOW, - event_utils::DispositionFromEventFlags(NSShiftKeyMask)); - // The SAVE_TO_DISK disposition is not currently supported, so we use - // CURRENT_TAB instead. - ASSERT_EQ(CURRENT_TAB, - event_utils::DispositionFromEventFlags(NSAlternateKeyMask)); - ASSERT_EQ(CURRENT_TAB, event_utils::DispositionFromEventFlags(0)); - ASSERT_EQ(CURRENT_TAB, - event_utils::DispositionFromEventFlags(NSControlKeyMask)); -} |