summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorderat@chromium.org <derat@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-10-29 21:58:54 +0000
committerderat@chromium.org <derat@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-10-29 21:58:54 +0000
commite2204a709c504b616790f21cd1cea87897f1966f (patch)
tree2dbb4f85fe3c4f82b70847701e91b88979ffc555
parentb6d6a783565289eb8a4dc635cad370b5db73c6d0 (diff)
downloadchromium_src-e2204a709c504b616790f21cd1cea87897f1966f.zip
chromium_src-e2204a709c504b616790f21cd1cea87897f1966f.tar.gz
chromium_src-e2204a709c504b616790f21cd1cea87897f1966f.tar.bz2
chromeos: Pref for treating top-row keys as function keys.
Add a "Treat top-row keys as function keys" keyboard setting that can be set to prevent top-row key events from either internal or external keyboards from being rewritten as media key (e.g. back, forward, brightness, etc.) events. BUG=303798 Review URL: https://codereview.chromium.org/48363005 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@231649 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/app/chromeos_strings.grdp8
-rw-r--r--chrome/browser/chromeos/preferences.cc7
-rw-r--r--chrome/browser/resources/options/chromeos/keyboard_overlay.css7
-rw-r--r--chrome/browser/resources/options/chromeos/keyboard_overlay.html12
-rw-r--r--chrome/browser/resources/options/options.html1
-rw-r--r--chrome/browser/ui/ash/event_rewriter.cc68
-rw-r--r--chrome/browser/ui/ash/event_rewriter.h19
-rw-r--r--chrome/browser/ui/ash/event_rewriter_unittest.cc32
-rw-r--r--chrome/browser/ui/webui/options/chromeos/keyboard_handler.cc6
-rw-r--r--chrome/common/pref_names.cc7
-rw-r--r--chrome/common/pref_names.h1
11 files changed, 120 insertions, 48 deletions
diff --git a/chrome/app/chromeos_strings.grdp b/chrome/app/chromeos_strings.grdp
index 7fea1bd..cc8c5e1 100644
--- a/chrome/app/chromeos_strings.grdp
+++ b/chrome/app/chromeos_strings.grdp
@@ -2369,6 +2369,14 @@ Press any key to continue exploring.
desc="The dropdown list item for 'Customize modifier keys' overlay">
Escape
</message>
+ <message name="IDS_OPTIONS_SETTINGS_LANGUAGES_SEND_FUNCTION_KEYS"
+ desc="The checkbox label for a setting to interpret the top-row keys as function keys instead.">
+ Treat top-row keys as function keys
+ </message>
+ <message name="IDS_OPTIONS_SETTINGS_LANGUAGES_SEND_FUNCTION_KEYS_DESCRIPTION"
+ desc="A label describing how to use the top-row keys' original actions when the treat-as-function-keys setting is enabled.">
+ Hold the Search key to switch the behavior of the top-row keys.
+ </message>
<message name="IDS_OPTIONS_SETTINGS_CHANGE_LANGUAGE_AND_INPUT_SETTINGS"
desc="The link to open 'Language and input settings' window.">
Change language and input settings
diff --git a/chrome/browser/chromeos/preferences.cc b/chrome/browser/chromeos/preferences.cc
index b3e6262..c014ff7 100644
--- a/chrome/browser/chromeos/preferences.cc
+++ b/chrome/browser/chromeos/preferences.cc
@@ -244,6 +244,13 @@ void Preferences::RegisterProfilePrefs(
prefs::kLanguageRemapDiamondKeyTo,
input_method::kControlKey,
user_prefs::PrefRegistrySyncable::SYNCABLE_PRIORITY_PREF);
+ // The following pref isn't synced since the user may desire a different value
+ // depending on whether an external keyboard is attached to a particular
+ // device.
+ registry->RegisterBooleanPref(
+ prefs::kLanguageSendFunctionKeys,
+ false,
+ user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
// We don't sync the following keyboard prefs since they are not user-
// configurable.
registry->RegisterBooleanPref(
diff --git a/chrome/browser/resources/options/chromeos/keyboard_overlay.css b/chrome/browser/resources/options/chromeos/keyboard_overlay.css
new file mode 100644
index 0000000..316e07a
--- /dev/null
+++ b/chrome/browser/resources/options/chromeos/keyboard_overlay.css
@@ -0,0 +1,7 @@
+/* Copyright 2013 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. */
+
+#send-function-keys-description {
+ color: gray;
+}
diff --git a/chrome/browser/resources/options/chromeos/keyboard_overlay.html b/chrome/browser/resources/options/chromeos/keyboard_overlay.html
index 36c29f9..039c52e 100644
--- a/chrome/browser/resources/options/chromeos/keyboard_overlay.html
+++ b/chrome/browser/resources/options/chromeos/keyboard_overlay.html
@@ -72,6 +72,18 @@
</td>
</tr>
</table>
+ <div class="settings-row">
+ <div class="checkbox">
+ <label>
+ <input id="send-function-keys" type="checkbox"
+ pref="settings.language.send_function_keys" dialog-pref>
+ <span i18n-content="sendFunctionKeys"></span>
+ </label>
+ </div>
+ <label id="send-function-keys-description" for="send-function-keys"
+ i18n-content="sendFunctionKeysDescription">
+ </label>
+ </div>
</div>
<div class="content-area">
<button id="languages-and-input-settings" class="link-button"
diff --git a/chrome/browser/resources/options/options.html b/chrome/browser/resources/options/options.html
index f96f5f8..a2c84c2 100644
--- a/chrome/browser/resources/options/options.html
+++ b/chrome/browser/resources/options/options.html
@@ -52,6 +52,7 @@
<link rel="stylesheet" href="chromeos/display_options.css">
<link rel="stylesheet" href="chromeos/display_overscan.css">
<link rel="stylesheet" href="chromeos/internet_detail.css">
+<link rel="stylesheet" href="chromeos/keyboard_overlay.css">
<link rel="stylesheet" href="chromeos/pointer_overlay.css">
<link rel="stylesheet" href="factory_reset_overlay.css">
</if>
diff --git a/chrome/browser/ui/ash/event_rewriter.cc b/chrome/browser/ui/ash/event_rewriter.cc
index c28df4f4..f294653 100644
--- a/chrome/browser/ui/ash/event_rewriter.cc
+++ b/chrome/browser/ui/ash/event_rewriter.cc
@@ -136,39 +136,18 @@ bool IsMod3UsedByCurrentInputMethod() {
manager->GetCurrentInputMethod().id() == kCaMultixLayoutId;
}
-// Returns true if the target for |event| would prefer to receive raw function
-// keys instead of having them rewritten into back, forward, brightness, volume,
-// etc. Web apps (v2 apps) can request this behavior via a permission so users
-// can use unmodified top-row keypresses to send function keys for things like
-// ssh and remote desktop.
-bool TopRowKeysAreFunctionKeys(ui::KeyEvent* event) {
- aura::Window* target = static_cast<aura::Window*>(event->target());
- if (!target)
- return false;
- aura::Window* top_level = views::corewm::GetToplevelWindow(target);
- return top_level &&
- ash::wm::GetWindowState(top_level)->top_row_keys_are_function_keys();
-}
-
#endif // defined(OS_CHROMEOS)
-const PrefService* GetPrefService() {
- Profile* profile = ProfileManager::GetDefaultProfile();
- if (profile)
- return profile->GetPrefs();
- return NULL;
-}
-
} // namespace
EventRewriter::EventRewriter()
: last_device_id_(kBadDeviceId),
#if defined(OS_CHROMEOS)
- xkeyboard_(NULL),
- keyboard_driven_event_rewritter_(
+ xkeyboard_for_testing_(NULL),
+ keyboard_driven_event_rewriter_(
new chromeos::KeyboardDrivenEventRewriter),
#endif
- pref_service_(NULL) {
+ pref_service_for_testing_(NULL) {
// The ash shell isn't instantiated for our unit tests.
if (ash::Shell::HasInstance()) {
ash::Shell::GetPrimaryRootWindow()->GetDispatcher()->
@@ -309,6 +288,21 @@ KeyCode EventRewriter::NativeKeySymToNativeKeycode(KeySym keysym) {
return keycode;
}
+bool EventRewriter::TopRowKeysAreFunctionKeys(ui::KeyEvent* event) const {
+ const PrefService* prefs = GetPrefService();
+ if (prefs &&
+ prefs->FindPreference(prefs::kLanguageSendFunctionKeys) &&
+ prefs->GetBoolean(prefs::kLanguageSendFunctionKeys))
+ return true;
+
+ aura::Window* target = static_cast<aura::Window*>(event->target());
+ if (!target)
+ return false;
+ aura::Window* top_level = views::corewm::GetToplevelWindow(target);
+ return top_level &&
+ ash::wm::GetWindowState(top_level)->top_row_keys_are_function_keys();
+}
+
bool EventRewriter::RewriteWithKeyboardRemappingsByKeySym(
const KeyboardRemapping* remappings,
size_t num_remappings,
@@ -369,7 +363,14 @@ bool EventRewriter::RewriteWithKeyboardRemappingsByKeyCode(
return false;
}
-#endif
+#endif // defined(OS_CHROMEOS)
+
+const PrefService* EventRewriter::GetPrefService() const {
+ if (pref_service_for_testing_)
+ return pref_service_for_testing_;
+ Profile* profile = ProfileManager::GetDefaultProfile();
+ return profile ? profile->GetPrefs() : NULL;
+}
void EventRewriter::Rewrite(ui::KeyEvent* event) {
#if defined(OS_CHROMEOS)
@@ -381,7 +382,7 @@ void EventRewriter::Rewrite(ui::KeyEvent* event) {
// Keyboard driven rewriting needs to happen before RewriteExtendedKeys
// to handle Ctrl+Alt+Shift+(Up | Down) so that they are not translated
// to Home/End.
- keyboard_driven_event_rewritter_->RewriteIfKeyboardDrivenOnLoginScreen(event);
+ keyboard_driven_event_rewriter_->RewriteIfKeyboardDrivenOnLoginScreen(event);
#endif
RewriteModifiers(event);
RewriteNumPadKeys(event);
@@ -418,8 +419,7 @@ void EventRewriter::GetRemappedModifierMasks(
return;
}
- const PrefService* pref_service =
- pref_service_ ? pref_service_ : GetPrefService();
+ const PrefService* pref_service = GetPrefService();
if (!pref_service)
return;
@@ -472,6 +472,7 @@ void EventRewriter::GetRemappedModifierMasks(
}
bool EventRewriter::RewriteModifiers(ui::KeyEvent* event) {
+#if defined(OS_CHROMEOS)
// Do nothing if we have just logged in as guest but have not restarted chrome
// process yet (so we are still on the login screen). In this situations we
// have no user profile so can not do anything useful.
@@ -479,17 +480,14 @@ bool EventRewriter::RewriteModifiers(ui::KeyEvent* event) {
// restart chrome process. In future this is to be changed.
// TODO(glotov): remove the following condition when we do not restart chrome
// when user logs in as guest.
-#if defined(OS_CHROMEOS)
if (chromeos::UserManager::Get()->IsLoggedInAsGuest() &&
chromeos::LoginDisplayHostImpl::default_host())
return false;
-#endif // defined(OS_CHROMEOS)
- const PrefService* pref_service =
- pref_service_ ? pref_service_ : GetPrefService();
+
+ const PrefService* pref_service = GetPrefService();
if (!pref_service)
return false;
-#if defined(OS_CHROMEOS)
DCHECK_EQ(chromeos::input_method::kControlKey,
kModifierRemappingCtrl->remap_to);
@@ -571,8 +569,8 @@ bool EventRewriter::RewriteModifiers(ui::KeyEvent* event) {
if ((event->type() == ui::ET_KEY_PRESSED) &&
(event->key_code() != ui::VKEY_CAPITAL) &&
(remapped_keycode == ui::VKEY_CAPITAL)) {
- chromeos::input_method::XKeyboard* xkeyboard = xkeyboard_ ?
- xkeyboard_ :
+ chromeos::input_method::XKeyboard* xkeyboard = xkeyboard_for_testing_ ?
+ xkeyboard_for_testing_ :
chromeos::input_method::InputMethodManager::Get()->GetXKeyboard();
xkeyboard->SetCapsLockEnabled(!xkeyboard->CapsLockIsEnabled());
}
diff --git a/chrome/browser/ui/ash/event_rewriter.h b/chrome/browser/ui/ash/event_rewriter.h
index 431eddf6..68ef918 100644
--- a/chrome/browser/ui/ash/event_rewriter.h
+++ b/chrome/browser/ui/ash/event_rewriter.h
@@ -65,11 +65,11 @@ class EventRewriter : public ash::EventRewriterDelegate,
last_device_id_ = device_id;
}
void set_pref_service_for_testing(const PrefService* pref_service) {
- pref_service_ = pref_service;
+ pref_service_for_testing_ = pref_service;
}
#if defined(OS_CHROMEOS)
void set_xkeyboard_for_testing(chromeos::input_method::XKeyboard* xkeyboard) {
- xkeyboard_ = xkeyboard;
+ xkeyboard_for_testing_ = xkeyboard;
}
#endif
@@ -115,6 +115,12 @@ class EventRewriter : public ash::EventRewriterDelegate,
unsigned int output_native_mods;
};
+ // Returns true if the target for |event| would prefer to receive raw function
+ // keys instead of having them rewritten into back, forward, brightness,
+ // volume, etc. or if the user has specified that they desire top-row keys to
+ // be treated as function keys globally.
+ bool TopRowKeysAreFunctionKeys(ui::KeyEvent* event) const;
+
// Given a set of KeyboardRemapping structs, it finds a matching struct
// if possible, and updates the remapped event values. Returns true if a
// remapping was found and remapped values were updated.
@@ -146,6 +152,9 @@ class EventRewriter : public ash::EventRewriterDelegate,
unsigned int* remapped_mods);
#endif
+ // Returns the PrefService that should be used.
+ const PrefService* GetPrefService() const;
+
// Rewrites the |event| by applying all RewriteXXX functions as needed.
void Rewrite(ui::KeyEvent* event);
@@ -214,13 +223,13 @@ class EventRewriter : public ash::EventRewriterDelegate,
// A mapping from X11 KeySym keys to KeyCode values.
base::hash_map<unsigned long, unsigned long> keysym_to_keycode_map_;
- chromeos::input_method::XKeyboard* xkeyboard_; // for testing.
+ chromeos::input_method::XKeyboard* xkeyboard_for_testing_;
scoped_ptr<chromeos::KeyboardDrivenEventRewriter>
- keyboard_driven_event_rewritter_;
+ keyboard_driven_event_rewriter_;
#endif
- const PrefService* pref_service_; // for testing.
+ const PrefService* pref_service_for_testing_;
DISALLOW_COPY_AND_ASSIGN(EventRewriter);
};
diff --git a/chrome/browser/ui/ash/event_rewriter_unittest.cc b/chrome/browser/ui/ash/event_rewriter_unittest.cc
index 4009c93..4bbfb9e 100644
--- a/chrome/browser/ui/ash/event_rewriter_unittest.cc
+++ b/chrome/browser/ui/ash/event_rewriter_unittest.cc
@@ -2332,13 +2332,19 @@ TEST_F(EventRewriterTest, TestRewriteKeyEventSentByXSendEvent) {
// Tests of event rewriting that depend on the Ash window manager.
class EventRewriterAshTest : public ash::test::AshTestBase {
public:
- EventRewriterAshTest() {}
+ EventRewriterAshTest() {
+ chromeos::Preferences::RegisterProfilePrefs(prefs_.registry());
+ rewriter_.set_pref_service_for_testing(&prefs_);
+ }
virtual ~EventRewriterAshTest() {}
bool RewriteFunctionKeys(ui::KeyEvent* event) {
return rewriter_.RewriteFunctionKeys(event);
}
+ protected:
+ TestingPrefServiceSyncable prefs_;
+
private:
EventRewriter rewriter_;
@@ -2361,13 +2367,25 @@ TEST_F(EventRewriterAshTest, TopRowKeysAreFunctionKeys) {
// Simulate an apps v2 window that has requested top row keys as function
// keys. The event should not be rewritten.
window_state->set_top_row_keys_are_function_keys(true);
- EXPECT_FALSE(RewriteFunctionKeys(&press_f1));
- EXPECT_EQ(ui::VKEY_F1, press_f1.key_code());
-
- // For a regular window, F1 is rewritten to the back key.
+ ASSERT_FALSE(RewriteFunctionKeys(&press_f1));
+ ASSERT_EQ(ui::VKEY_F1, press_f1.key_code());
+
+ // The event should also not be rewritten if the send-function-keys pref is
+ // additionally set, for both apps v2 and regular windows.
+ BooleanPrefMember send_function_keys_pref;
+ send_function_keys_pref.Init(prefs::kLanguageSendFunctionKeys, &prefs_);
+ send_function_keys_pref.SetValue(true);
+ ASSERT_FALSE(RewriteFunctionKeys(&press_f1));
+ ASSERT_EQ(ui::VKEY_F1, press_f1.key_code());
window_state->set_top_row_keys_are_function_keys(false);
- EXPECT_TRUE(RewriteFunctionKeys(&press_f1));
- EXPECT_EQ(ui::VKEY_BROWSER_BACK, press_f1.key_code());
+ ASSERT_FALSE(RewriteFunctionKeys(&press_f1));
+ ASSERT_EQ(ui::VKEY_F1, press_f1.key_code());
+
+ // If the pref isn't set when an event is sent to a regular window, F1 is
+ // rewritten to the back key.
+ send_function_keys_pref.SetValue(false);
+ ASSERT_TRUE(RewriteFunctionKeys(&press_f1));
+ ASSERT_EQ(ui::VKEY_BROWSER_BACK, press_f1.key_code());
}
#endif // OS_CHROMEOS
diff --git a/chrome/browser/ui/webui/options/chromeos/keyboard_handler.cc b/chrome/browser/ui/webui/options/chromeos/keyboard_handler.cc
index 9c95cc2..6aa795c9 100644
--- a/chrome/browser/ui/webui/options/chromeos/keyboard_handler.cc
+++ b/chrome/browser/ui/webui/options/chromeos/keyboard_handler.cc
@@ -69,6 +69,12 @@ void KeyboardHandler::GetLocalizedValues(DictionaryValue* localized_strings) {
localized_strings->SetString("remapDiamondKeyToContent",
l10n_util::GetStringUTF16(
IDS_OPTIONS_SETTINGS_LANGUAGES_KEY_DIAMOND_KEY_LABEL));
+ localized_strings->SetString("sendFunctionKeys",
+ l10n_util::GetStringUTF16(
+ IDS_OPTIONS_SETTINGS_LANGUAGES_SEND_FUNCTION_KEYS));
+ localized_strings->SetString("sendFunctionKeysDescription",
+ l10n_util::GetStringUTF16(
+ IDS_OPTIONS_SETTINGS_LANGUAGES_SEND_FUNCTION_KEYS_DESCRIPTION));
localized_strings->SetString("changeLanguageAndInputSettings",
l10n_util::GetStringUTF16(
IDS_OPTIONS_SETTINGS_CHANGE_LANGUAGE_AND_INPUT_SETTINGS));
diff --git a/chrome/common/pref_names.cc b/chrome/common/pref_names.cc
index ff6499a..88beefd 100644
--- a/chrome/common/pref_names.cc
+++ b/chrome/common/pref_names.cc
@@ -637,7 +637,7 @@ const char kLanguagePreloadEngines[] = "settings.language.preload_engines";
const char kLanguageEnabledExtensionImes[] =
"settings.language.enabled_extension_imes";
-// A integer prefs which determine how we remap modifier keys (e.g. swap Alt and
+// Integer prefs which determine how we remap modifier keys (e.g. swap Alt and
// Control.) Possible values for these prefs are 0-4. See ModifierKey enum in
// src/chrome/browser/chromeos/input_method/xkeyboard.h
const char kLanguageRemapSearchKeyTo[] =
@@ -653,6 +653,11 @@ const char kLanguageRemapCapsLockKeyTo[] =
const char kLanguageRemapDiamondKeyTo[] =
"settings.language.remap_diamond_key_to";
+// A boolean pref that causes top-row keys to be interpreted as function keys
+// instead of as media keys.
+const char kLanguageSendFunctionKeys[] =
+ "settings.language.send_function_keys";
+
// A boolean pref which determines whether key repeat is enabled.
const char kLanguageXkbAutoRepeatEnabled[] =
"settings.language.xkb_auto_repeat_enabled_r2";
diff --git a/chrome/common/pref_names.h b/chrome/common/pref_names.h
index dc57f9f..665b429 100644
--- a/chrome/common/pref_names.h
+++ b/chrome/common/pref_names.h
@@ -218,6 +218,7 @@ extern const char kLanguageRemapSearchKeyTo[];
extern const char kLanguageRemapControlKeyTo[];
extern const char kLanguageRemapAltKeyTo[];
extern const char kLanguageRemapDiamondKeyTo[];
+extern const char kLanguageSendFunctionKeys[];
extern const char kLanguageXkbAutoRepeatEnabled[];
extern const char kLanguageXkbAutoRepeatDelay[];
extern const char kLanguageXkbAutoRepeatInterval[];