summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/disposition_utils.cc30
-rw-r--r--chrome/browser/disposition_utils.h24
-rw-r--r--chrome/browser/dom_ui/app_launcher_handler.cc114
-rw-r--r--chrome/browser/dom_ui/generic_handler.cc40
-rw-r--r--chrome/browser/resources/ntp/apps.js30
-rw-r--r--chrome/browser/resources/shared/js/util.js3
-rw-r--r--chrome/browser/ui/cocoa/event_utils.mm11
-rw-r--r--chrome/browser/ui/gtk/gtk_util.cc15
-rw-r--r--chrome/browser/ui/views/event_utils.cc18
-rw-r--r--chrome/chrome_browser.gypi2
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',