diff options
author | derat@chromium.org <derat@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-10-29 21:58:54 +0000 |
---|---|---|
committer | derat@chromium.org <derat@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-10-29 21:58:54 +0000 |
commit | e2204a709c504b616790f21cd1cea87897f1966f (patch) | |
tree | 2dbb4f85fe3c4f82b70847701e91b88979ffc555 | |
parent | b6d6a783565289eb8a4dc635cad370b5db73c6d0 (diff) | |
download | chromium_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.grdp | 8 | ||||
-rw-r--r-- | chrome/browser/chromeos/preferences.cc | 7 | ||||
-rw-r--r-- | chrome/browser/resources/options/chromeos/keyboard_overlay.css | 7 | ||||
-rw-r--r-- | chrome/browser/resources/options/chromeos/keyboard_overlay.html | 12 | ||||
-rw-r--r-- | chrome/browser/resources/options/options.html | 1 | ||||
-rw-r--r-- | chrome/browser/ui/ash/event_rewriter.cc | 68 | ||||
-rw-r--r-- | chrome/browser/ui/ash/event_rewriter.h | 19 | ||||
-rw-r--r-- | chrome/browser/ui/ash/event_rewriter_unittest.cc | 32 | ||||
-rw-r--r-- | chrome/browser/ui/webui/options/chromeos/keyboard_handler.cc | 6 | ||||
-rw-r--r-- | chrome/common/pref_names.cc | 7 | ||||
-rw-r--r-- | chrome/common/pref_names.h | 1 |
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[]; |