diff options
| -rw-r--r-- | chrome/browser/disposition_utils.cc | 30 | ||||
| -rw-r--r-- | chrome/browser/disposition_utils.h | 24 | ||||
| -rw-r--r-- | chrome/browser/dom_ui/app_launcher_handler.cc | 114 | ||||
| -rw-r--r-- | chrome/browser/dom_ui/generic_handler.cc | 40 | ||||
| -rw-r--r-- | chrome/browser/resources/ntp/apps.js | 30 | ||||
| -rw-r--r-- | chrome/browser/resources/shared/js/util.js | 3 | ||||
| -rw-r--r-- | chrome/browser/ui/cocoa/event_utils.mm | 11 | ||||
| -rw-r--r-- | chrome/browser/ui/gtk/gtk_util.cc | 15 | ||||
| -rw-r--r-- | chrome/browser/ui/views/event_utils.cc | 18 | ||||
| -rw-r--r-- | chrome/chrome_browser.gypi | 2 |
10 files changed, 185 insertions, 102 deletions
diff --git a/chrome/browser/disposition_utils.cc b/chrome/browser/disposition_utils.cc new file mode 100644 index 0000000..326a323 --- /dev/null +++ b/chrome/browser/disposition_utils.cc @@ -0,0 +1,30 @@ +// Copyright (c) 2011 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/disposition_utils.h" + +#include "build/build_config.h" + +namespace disposition_utils { + +WindowOpenDisposition DispositionFromClick(bool middle_button, + bool alt_key, + bool ctrl_key, + bool meta_key, + bool shift_key) { + // MacOS uses meta key (Command key) to spawn new tabs. +#if defined(OS_MACOSX) + if (middle_button || meta_key) +#else + if (middle_button || ctrl_key) +#endif + return shift_key ? NEW_FOREGROUND_TAB : NEW_BACKGROUND_TAB; + if (shift_key) + return NEW_WINDOW; + if (alt_key) + return SAVE_TO_DISK; + return CURRENT_TAB; +} + +} diff --git a/chrome/browser/disposition_utils.h b/chrome/browser/disposition_utils.h new file mode 100644 index 0000000..eb847f9 --- /dev/null +++ b/chrome/browser/disposition_utils.h @@ -0,0 +1,24 @@ +// Copyright (c) 2011 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_DISPOSITION_UTILS_H_ +#define CHROME_BROWSER_DISPOSITION_UTILS_H_ +#pragma once + +#include "webkit/glue/window_open_disposition.h" + +namespace disposition_utils { + +// Translates event flags from a click on a link into the user's desired +// window disposition. For example, a middle click would mean to open +// a background tab. +WindowOpenDisposition DispositionFromClick(bool middle_button, + bool alt_key, + bool ctrl_key, + bool meta_key, + bool shift_key); + +} + +#endif // CHROME_BROWSER_DISPOSITION_UTILS_H_ diff --git a/chrome/browser/dom_ui/app_launcher_handler.cc b/chrome/browser/dom_ui/app_launcher_handler.cc index e7cc713..1355f92 100644 --- a/chrome/browser/dom_ui/app_launcher_handler.cc +++ b/chrome/browser/dom_ui/app_launcher_handler.cc @@ -13,6 +13,7 @@ #include "base/string_util.h" #include "base/utf_string_conversions.h" #include "base/values.h" +#include "chrome/browser/disposition_utils.h" #include "chrome/browser/dom_ui/shown_sections_handler.h" #include "chrome/browser/extensions/default_apps.h" #include "chrome/browser/extensions/extension_prefs.h" @@ -34,6 +35,7 @@ #include "grit/generated_resources.h" #include "ui/base/animation/animation.h" #include "ui/gfx/rect.h" +#include "webkit/glue/window_open_disposition.h" namespace { @@ -42,18 +44,6 @@ namespace { const char* kLaunchAppPingURL = "record-app-launch"; const char* kLaunchWebStorePingURL = "record-webstore-launch"; -// This extracts an int from a ListValue at the given |index|. -bool ExtractInt(const ListValue* list, size_t index, int* out_int) { - std::string string_value; - - if (list->GetString(index, &string_value)) { - base::StringToInt(string_value, out_int); - return true; - } - - return false; -} - std::string GetIconURL(const Extension* extension, Extension::Icons icon, const std::string& default_val) { GURL url = extension->GetIconURL(icon, ExtensionIconSet::MATCH_EXACTLY); @@ -271,23 +261,31 @@ void AppLauncherHandler::HandleGetApps(const ListValue* args) { void AppLauncherHandler::HandleLaunchApp(const ListValue* args) { std::string extension_id; - int left = 0; - int top = 0; - int width = 0; - int height = 0; - - if (!args->GetString(0, &extension_id) || - !ExtractInt(args, 1, &left) || - !ExtractInt(args, 2, &top) || - !ExtractInt(args, 3, &width) || - !ExtractInt(args, 4, &height)) { - NOTREACHED(); - return; - } + double left; + double top; + double width; + double height; + bool alt_key; + bool ctrl_key; + bool meta_key; + bool shift_key; + double button; + + CHECK(args->GetString(0, &extension_id)); + CHECK(args->GetDouble(1, &left)); + CHECK(args->GetDouble(2, &top)); + CHECK(args->GetDouble(3, &width)); + CHECK(args->GetDouble(4, &height)); + CHECK(args->GetBoolean(5, &alt_key)); + CHECK(args->GetBoolean(6, &ctrl_key)); + CHECK(args->GetBoolean(7, &meta_key)); + CHECK(args->GetBoolean(8, &shift_key)); + CHECK(args->GetDouble(9, &button)); // The rect we get from the client is relative to the browser client viewport. // Offset the rect by the tab contents bounds. - gfx::Rect rect(left, top, width, height); + gfx::Rect rect(static_cast<int>(left), static_cast<int>(top), + static_cast<int>(width), static_cast<int>(height)); gfx::Rect tab_contents_bounds; web_ui_->tab_contents()->GetContainerBounds(&tab_contents_bounds); rect.Offset(tab_contents_bounds.origin()); @@ -297,24 +295,40 @@ void AppLauncherHandler::HandleLaunchApp(const ListValue* args) { DCHECK(extension); Profile* profile = extensions_service_->profile(); - // To give a more "launchy" experience when using the NTP launcher, we close - // it automatically. - Browser* browser = BrowserList::GetLastActive(); - TabContents* old_contents = NULL; - if (browser) - old_contents = browser->GetSelectedTabContents(); - - // Look at preference to find the right launch container. If no preference - // is set, launch as a regular tab. - extension_misc::LaunchContainer launch_container = - extensions_service_->extension_prefs()->GetLaunchContainer( - extension, ExtensionPrefs::LAUNCH_DEFAULT); - - TabContents* new_contents = Browser::OpenApplication( - profile, extension, launch_container, old_contents); - - if (new_contents != old_contents && browser->tab_count() > 1) - browser->CloseTabContents(old_contents); + // If the user pressed special keys when clicking, override the saved + // preference for launch container. + bool middle_button = (button == 1.0); + WindowOpenDisposition disposition = + disposition_utils::DispositionFromClick(middle_button, alt_key, + ctrl_key, meta_key, shift_key); + if (disposition == NEW_FOREGROUND_TAB || disposition == NEW_BACKGROUND_TAB) { + // TODO(jamescook): Proper support for background tabs. + Browser::OpenApplication( + profile, extension, extension_misc::LAUNCH_TAB, NULL); + } else if (disposition == NEW_WINDOW) { + // Force a new window open. + Browser::OpenApplication( + profile, extension, extension_misc::LAUNCH_WINDOW, NULL); + } else { + // Look at preference to find the right launch container. If no preference + // is set, launch as a regular tab. + extension_misc::LaunchContainer launch_container = + extensions_service_->extension_prefs()->GetLaunchContainer( + extension, ExtensionPrefs::LAUNCH_REGULAR); + + // To give a more "launchy" experience when using the NTP launcher, we close + // it automatically. + Browser* browser = BrowserList::GetLastActive(); + TabContents* old_contents = NULL; + if (browser) + old_contents = browser->GetSelectedTabContents(); + + TabContents* new_contents = Browser::OpenApplication( + profile, extension, launch_container, old_contents); + + if (new_contents != old_contents && browser->tab_count() > 1) + browser->CloseTabContents(old_contents); + } if (extension_id != extension_misc::kWebStoreAppId) { RecordAppLaunch(promo_active_); @@ -324,12 +338,9 @@ void AppLauncherHandler::HandleLaunchApp(const ListValue* args) { void AppLauncherHandler::HandleSetLaunchType(const ListValue* args) { std::string extension_id; - int launch_type; - if (!args->GetString(0, &extension_id) || - !ExtractInt(args, 1, &launch_type)) { - NOTREACHED(); - return; - } + double launch_type; + CHECK(args->GetString(0, &extension_id)); + CHECK(args->GetDouble(1, &launch_type)); const Extension* extension = extensions_service_->GetExtensionById(extension_id, false); @@ -337,7 +348,8 @@ void AppLauncherHandler::HandleSetLaunchType(const ListValue* args) { extensions_service_->extension_prefs()->SetLaunchType( extension_id, - static_cast<ExtensionPrefs::LaunchType>(launch_type)); + static_cast<ExtensionPrefs::LaunchType>( + static_cast<int>(launch_type))); } void AppLauncherHandler::HandleUninstallApp(const ListValue* args) { diff --git a/chrome/browser/dom_ui/generic_handler.cc b/chrome/browser/dom_ui/generic_handler.cc index d6682cc..d293cfb 100644 --- a/chrome/browser/dom_ui/generic_handler.cc +++ b/chrome/browser/dom_ui/generic_handler.cc @@ -6,6 +6,7 @@ #include "base/logging.h" #include "base/values.h" +#include "chrome/browser/disposition_utils.h" #include "chrome/browser/tab_contents/tab_contents.h" #include "googleurl/src/gurl.h" @@ -22,28 +23,25 @@ void GenericHandler::RegisterMessages() { void GenericHandler::HandleNavigateToUrl(const ListValue* args) { std::string url_string; + double button; + bool alt_key; + bool ctrl_key; + bool meta_key; + bool shift_key; + CHECK(args->GetString(0, &url_string)); - std::string button_string; - CHECK(args->GetString(1, &button_string)); - CHECK(button_string == "0" || button_string == "1"); - std::string ctrl_string; - CHECK(args->GetString(2, &ctrl_string)); - std::string shift_string; - CHECK(args->GetString(3, &shift_string)); - std::string alt_string; - CHECK(args->GetString(4, &alt_string)); - - // TODO(estade): This logic is replicated in 4 places throughout chrome. - // It would be nice to centralize it. - WindowOpenDisposition disposition; - if (button_string == "1" || ctrl_string == "true") { - disposition = shift_string == "true" ? - NEW_FOREGROUND_TAB : NEW_BACKGROUND_TAB; - } else if (shift_string == "true") { - disposition = NEW_WINDOW; - } else { - disposition = alt_string == "true" ? SAVE_TO_DISK : CURRENT_TAB; - } + CHECK(args->GetDouble(1, &button)); + CHECK(args->GetBoolean(2, &alt_key)); + CHECK(args->GetBoolean(3, &ctrl_key)); + CHECK(args->GetBoolean(4, &meta_key)); + CHECK(args->GetBoolean(5, &shift_key)); + + CHECK(button == 0.0 || button == 1.0); + bool middle_button = (button == 1.0); + + WindowOpenDisposition disposition = + disposition_utils::DispositionFromClick(middle_button, alt_key, ctrl_key, + meta_key, shift_key); web_ui_->tab_contents()->OpenURL( GURL(url_string), GURL(), disposition, PageTransition::LINK); diff --git a/chrome/browser/resources/ntp/apps.js b/chrome/browser/resources/ntp/apps.js index a64dddc..3f50d760 100644 --- a/chrome/browser/resources/ntp/apps.js +++ b/chrome/browser/resources/ntp/apps.js @@ -132,7 +132,14 @@ var apps = (function() { return div; } - function launchApp(appId) { + /** + * Launches an application. + * @param {string} appId Application to launch. + * @param {MouseEvent} opt_mouseEvent Mouse event from the click that + * triggered the launch, used to detect modifier keys that change + * the tab's disposition. + */ + function launchApp(appId, opt_mouseEvent) { var appsSection = $('apps'); var expanded = !appsSection.classList.contains('collapsed'); var element = document.querySelector( @@ -162,9 +169,19 @@ var apps = (function() { left = rect.left; } - chrome.send('launchApp', [appId, - String(left), String(top), - String(width), String(height)]); + if (opt_mouseEvent) { + // Launch came from a click. + chrome.send('launchApp', [appId, left, top, width, height, + opt_mouseEvent.altKey, opt_mouseEvent.ctrlKey, + opt_mouseEvent.metaKey, opt_mouseEvent.shiftKey, + opt_mouseEvent.button]); + } else { + // Launch came from 'command' event from elsewhere in UI. + chrome.send('launchApp', [appId, left, top, width, height, + false /* altKey */, false /* ctrlKey */, + false /* metaKey */, false /* shiftKey */, + 0 /* button */]); + } } /** @@ -173,7 +190,7 @@ var apps = (function() { function handleClick(e) { var appId = e.currentTarget.getAttribute('app-id'); if (!appDragAndDrop.isDragging()) - launchApp(appId); + launchApp(appId, e); return false; } @@ -258,7 +275,8 @@ var apps = (function() { case 'apps-launch-type-fullscreen': case 'apps-launch-type-window': chrome.send('setLaunchType', - [currentApp['id'], e.command.getAttribute('launch-type')]); + [currentApp['id'], + Number(e.command.getAttribute('launch-type'))]); break; } }); diff --git a/chrome/browser/resources/shared/js/util.js b/chrome/browser/resources/shared/js/util.js index a74badd..63b3a8c 100644 --- a/chrome/browser/resources/shared/js/util.js +++ b/chrome/browser/resources/shared/js/util.js @@ -129,8 +129,7 @@ function handleLinkClickOrMouseUp(e) { ((e.button == 0 && e.type == 'click') || (e.button == 1 && e.type == 'mouseup'))) { chrome.send('navigateToUrl', - [el.href, String(e.button), String(e.ctrlKey), String(e.shiftKey), - String(e.altKey)]); + [el.href, e.button, e.altKey, e.ctrlKey, e.metaKey, e.shiftKey]); e.preventDefault(); } } diff --git a/chrome/browser/ui/cocoa/event_utils.mm b/chrome/browser/ui/cocoa/event_utils.mm index ec475b5..d471398 100644 --- a/chrome/browser/ui/cocoa/event_utils.mm +++ b/chrome/browser/ui/cocoa/event_utils.mm @@ -4,6 +4,8 @@ #import "chrome/browser/ui/cocoa/event_utils.h" +#include "chrome/browser/disposition_utils.h" + namespace event_utils { WindowOpenDisposition WindowOpenDispositionFromNSEvent(NSEvent* event) { @@ -13,9 +15,12 @@ WindowOpenDisposition WindowOpenDispositionFromNSEvent(NSEvent* event) { WindowOpenDisposition WindowOpenDispositionFromNSEventWithFlags( NSEvent* event, NSUInteger flags) { - if ([event buttonNumber] == 2 || flags & NSCommandKeyMask) - return flags & NSShiftKeyMask ? NEW_FOREGROUND_TAB : NEW_BACKGROUND_TAB; - return flags & NSShiftKeyMask ? NEW_WINDOW : CURRENT_TAB; + return disposition_utils::DispositionFromClick( + [event buttonNumber] == 2, + flags & NSAlternateKeyMask, + flags & NSControlKeyMask, + flags & NSCommandKeyMask, + flags & NSShiftKeyMask); } } // namespace event_utils diff --git a/chrome/browser/ui/gtk/gtk_util.cc b/chrome/browser/ui/gtk/gtk_util.cc index 16ee8d1..92e1aec 100644 --- a/chrome/browser/ui/gtk/gtk_util.cc +++ b/chrome/browser/ui/gtk/gtk_util.cc @@ -23,6 +23,7 @@ #include "chrome/browser/autocomplete/autocomplete_match.h" #include "chrome/browser/browser_list.h" #include "chrome/browser/browser_window.h" +#include "chrome/browser/disposition_utils.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/renderer_host/render_view_host.h" #include "chrome/browser/tab_contents/tab_contents.h" @@ -150,14 +151,12 @@ GtkWidget* GetBrowserWindowFocusedWidget(BrowserWindow* window) { namespace event_utils { WindowOpenDisposition DispositionFromEventFlags(guint event_flags) { - if ((event_flags & GDK_BUTTON2_MASK) || (event_flags & GDK_CONTROL_MASK)) { - return (event_flags & GDK_SHIFT_MASK) ? - NEW_FOREGROUND_TAB : NEW_BACKGROUND_TAB; - } - - if (event_flags & GDK_SHIFT_MASK) - return NEW_WINDOW; - return false /*event.IsAltDown()*/ ? SAVE_TO_DISK : CURRENT_TAB; + return disposition_utils::DispositionFromClick( + event_flags & GDK_BUTTON2_MASK, + event_flags & GDK_MOD1_MASK, + event_flags & GDK_CONTROL_MASK, + event_flags & GDK_META_MASK, + event_flags & GDK_SHIFT_MASK); } } // namespace event_utils diff --git a/chrome/browser/ui/views/event_utils.cc b/chrome/browser/ui/views/event_utils.cc index 8c59c51..6e13947 100644 --- a/chrome/browser/ui/views/event_utils.cc +++ b/chrome/browser/ui/views/event_utils.cc @@ -4,6 +4,7 @@ #include "chrome/browser/ui/views/event_utils.h" +#include "chrome/browser/disposition_utils.h" #include "views/events/event.h" using views::Event; @@ -11,17 +12,12 @@ using views::Event; namespace event_utils { WindowOpenDisposition DispositionFromEventFlags(int event_flags) { - if (((event_flags & ui::EF_MIDDLE_BUTTON_DOWN) == - ui::EF_MIDDLE_BUTTON_DOWN) || - ((event_flags & ui::EF_CONTROL_DOWN) == - ui::EF_CONTROL_DOWN)) { - return ((event_flags & ui::EF_SHIFT_DOWN) == ui::EF_SHIFT_DOWN) ? - NEW_FOREGROUND_TAB : NEW_BACKGROUND_TAB; - } - - if ((event_flags & ui::EF_SHIFT_DOWN) == ui::EF_SHIFT_DOWN) - return NEW_WINDOW; - return false /*event.IsAltDown()*/ ? SAVE_TO_DISK : CURRENT_TAB; + return disposition_utils::DispositionFromClick( + (event_flags & ui::EF_MIDDLE_BUTTON_DOWN) != 0, + (event_flags & ui::EF_ALT_DOWN) != 0, + (event_flags & ui::EF_CONTROL_DOWN) != 0, + false /* meta_key */, + (event_flags & ui::EF_SHIFT_DOWN) != 0); } bool IsPossibleDispositionEvent(const views::MouseEvent& event) { diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi index 43a92bc..310f0b7 100644 --- a/chrome/chrome_browser.gypi +++ b/chrome/chrome_browser.gypi @@ -853,6 +853,8 @@ 'browser/diagnostics/recon_diagnostics.h', 'browser/diagnostics/sqlite_diagnostics.cc', 'browser/diagnostics/sqlite_diagnostics.h', + 'browser/disposition_utils.cc', + 'browser/disposition_utils.h', 'browser/dom_operation_notification_details.h', 'browser/dom_ui/app_launcher_handler.cc', 'browser/dom_ui/app_launcher_handler.h', |
