diff options
author | ben@chromium.org <ben@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-08-19 03:52:11 +0000 |
---|---|---|
committer | ben@chromium.org <ben@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-08-19 03:52:11 +0000 |
commit | 1a6b30a619cba771cb9c4ed4da9c3778634567ad (patch) | |
tree | 4ced69ac8eb511a6f9bc7949348551ee62b57989 /chrome | |
parent | a8815b3277284778247545728bc41a077ff55b43 (diff) | |
download | chromium_src-1a6b30a619cba771cb9c4ed4da9c3778634567ad.zip chromium_src-1a6b30a619cba771cb9c4ed4da9c3778634567ad.tar.gz chromium_src-1a6b30a619cba771cb9c4ed4da9c3778634567ad.tar.bz2 |
This changelist represents the necessary merger of two others:
http://codereview.chromium.org/172082
Create new event_utils.h file for Cocoa-specific event to WindowOpenDisposition
cracking.
Hook this up to BookmarkBarController so that clicks to bookmark items use the
oracle function to determine where the bookmark should be opened.
BUG=17301
TEST=Cmd+Click etc on bookmark items should work. See bug and unit test
attached.
http://codereview.chromium.org/174021
Convert users of the "get last active browser, get selected tab contents, open
url" pattern to just call OpenURL on Browser directly.
Makes GetOrCreateTabbedBrowser public on Browser, and makes it static so it can
be called with a provided profile.
BUG=none
TEST=Try opening links from the bookmark/history menus on mac, with and without
an existing window open, with an active incognito window, etc. The links should
all open in the last active non-incognito window, or create a new non-incognito
window if none is open.
Review URL: http://codereview.chromium.org/173044
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@23693 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
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)); -} |