Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(130)

Side by Side Diff: ash/accelerators/accelerator_controller.cc

Issue 1414483011: Deprecate Shift+Alt to switch IME and use Ctrl+Shift+Space instead. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: ensure no line breaks in the middle of shortcuts texts Created 5 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "ash/accelerators/accelerator_controller.h" 5 #include "ash/accelerators/accelerator_controller.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <cmath> 8 #include <cmath>
9 #include <string> 9 #include <string>
10 10
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
49 #include "ash/wm/overview/window_selector_controller.h" 49 #include "ash/wm/overview/window_selector_controller.h"
50 #include "ash/wm/power_button_controller.h" 50 #include "ash/wm/power_button_controller.h"
51 #include "ash/wm/window_cycle_controller.h" 51 #include "ash/wm/window_cycle_controller.h"
52 #include "ash/wm/window_state.h" 52 #include "ash/wm/window_state.h"
53 #include "ash/wm/window_util.h" 53 #include "ash/wm/window_util.h"
54 #include "ash/wm/wm_event.h" 54 #include "ash/wm/wm_event.h"
55 #include "base/bind.h" 55 #include "base/bind.h"
56 #include "base/command_line.h" 56 #include "base/command_line.h"
57 #include "base/metrics/histogram_macros.h" 57 #include "base/metrics/histogram_macros.h"
58 #include "base/metrics/user_metrics.h" 58 #include "base/metrics/user_metrics.h"
59 #include "base/strings/utf_string_conversions.h"
59 #include "ui/aura/env.h" 60 #include "ui/aura/env.h"
60 #include "ui/base/accelerators/accelerator.h" 61 #include "ui/base/accelerators/accelerator.h"
61 #include "ui/base/accelerators/accelerator_manager.h" 62 #include "ui/base/accelerators/accelerator_manager.h"
62 #include "ui/base/l10n/l10n_util.h" 63 #include "ui/base/l10n/l10n_util.h"
63 #include "ui/base/resource/resource_bundle.h" 64 #include "ui/base/resource/resource_bundle.h"
64 #include "ui/compositor/layer.h" 65 #include "ui/compositor/layer.h"
65 #include "ui/compositor/layer_animation_sequence.h" 66 #include "ui/compositor/layer_animation_sequence.h"
66 #include "ui/compositor/layer_animator.h" 67 #include "ui/compositor/layer_animator.h"
67 #include "ui/events/event.h" 68 #include "ui/events/event.h"
68 #include "ui/events/keycodes/keyboard_codes.h" 69 #include "ui/events/keycodes/keyboard_codes.h"
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
108 109
109 ui::Accelerator CreateAccelerator(ui::KeyboardCode keycode, 110 ui::Accelerator CreateAccelerator(ui::KeyboardCode keycode,
110 int modifiers, 111 int modifiers,
111 bool trigger_on_press) { 112 bool trigger_on_press) {
112 ui::Accelerator accelerator(keycode, modifiers); 113 ui::Accelerator accelerator(keycode, modifiers);
113 accelerator.set_type(trigger_on_press ? ui::ET_KEY_PRESSED 114 accelerator.set_type(trigger_on_press ? ui::ET_KEY_PRESSED
114 : ui::ET_KEY_RELEASED); 115 : ui::ET_KEY_RELEASED);
115 return accelerator; 116 return accelerator;
116 } 117 }
117 118
119 // Ensures that there are no word breaks at the "+"s in the shortcut texts such
oshima 2015/11/09 19:49:28 what if the shortcut contains "+" key itself?
afakhry 2015/11/10 00:56:47 The "+" will just be appended and prepended with t
120 // as "Ctrl+Shift+Space".
121 void EnsureNoWordBreaks(base::string16* shortcut_text) {
122 std::vector<base::string16> keys =
123 base::SplitString(*shortcut_text, base::ASCIIToUTF16("+"),
124 base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
125
126 if (keys.size() < 2U)
127 return;
128
129 // The plus sign surrounded by the word joiner to guarantee an non-breaking
130 // shortcut.
131 const base::string16 non_breaking_plus =
132 base::UTF8ToUTF16("\xe2\x81\xa0+\xe2\x81\xa0");
133 shortcut_text->clear();
134 for (size_t i = 0; i < keys.size() - 1; ++i) {
135 *shortcut_text += keys[i];
136 *shortcut_text += non_breaking_plus;
137 }
138
139 *shortcut_text += keys[keys.size() - 1];
140 }
141
142 // Gets the notification message after it formats it in such a way that there
143 // are no line breaks in the middle of the shortcut texts.
144 base::string16 GetNotificationText(int message_id,
145 int old_shortcut_id,
146 int new_shortcut_id) {
147 base::string16 old_shortcut = l10n_util::GetStringUTF16(old_shortcut_id);
148 base::string16 new_shortcut = l10n_util::GetStringUTF16(new_shortcut_id);
149 EnsureNoWordBreaks(&old_shortcut);
150 EnsureNoWordBreaks(&new_shortcut);
151
152 return l10n_util::GetStringFUTF16(message_id, new_shortcut, old_shortcut);
153 }
154
118 void ShowDeprecatedAcceleratorNotification(const char* const notification_id, 155 void ShowDeprecatedAcceleratorNotification(const char* const notification_id,
119 int message_id) { 156 int message_id,
120 const base::string16 message = l10n_util::GetStringUTF16(message_id); 157 int old_shortcut_id,
158 int new_shortcut_id) {
159 const base::string16 message =
160 GetNotificationText(message_id, old_shortcut_id, new_shortcut_id);
121 scoped_ptr<message_center::Notification> notification( 161 scoped_ptr<message_center::Notification> notification(
122 new message_center::Notification( 162 new message_center::Notification(
123 message_center::NOTIFICATION_TYPE_SIMPLE, notification_id, 163 message_center::NOTIFICATION_TYPE_SIMPLE, notification_id,
124 base::string16(), message, 164 base::string16(), message,
125 Shell::GetInstance()->delegate()->GetDeprecatedAcceleratorImage(), 165 Shell::GetInstance()->delegate()->GetDeprecatedAcceleratorImage(),
126 base::string16(), GURL(), 166 base::string16(), GURL(),
127 message_center::NotifierId( 167 message_center::NotifierId(
128 message_center::NotifierId::SYSTEM_COMPONENT, 168 message_center::NotifierId::SYSTEM_COMPONENT,
129 system_notifier::kNotifierDeprecatedAccelerator), 169 system_notifier::kNotifierDeprecatedAccelerator),
130 message_center::RichNotificationData(), 170 message_center::RichNotificationData(),
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
246 Shell::GetInstance()->new_window_delegate()->NewTab(); 286 Shell::GetInstance()->new_window_delegate()->NewTab();
247 } 287 }
248 288
249 void HandleNewWindow() { 289 void HandleNewWindow() {
250 base::RecordAction(base::UserMetricsAction("Accel_New_Window")); 290 base::RecordAction(base::UserMetricsAction("Accel_New_Window"));
251 Shell::GetInstance()->new_window_delegate()->NewWindow( 291 Shell::GetInstance()->new_window_delegate()->NewWindow(
252 false /* is_incognito */); 292 false /* is_incognito */);
253 } 293 }
254 294
255 bool CanHandleNextIme(ImeControlDelegate* ime_control_delegate, 295 bool CanHandleNextIme(ImeControlDelegate* ime_control_delegate,
256 const ui::Accelerator& previous_accelerator) { 296 const ui::Accelerator& previous_accelerator,
257 // We only allow next IME to be triggered if the previous is accelerator key 297 bool current_accelerator_is_deprecated) {
258 // is ONLY either Shift, Alt, Enter or Space. 298 if (current_accelerator_is_deprecated) {
259 // The first two cases to avoid conflicting accelerators that contain 299 // We only allow next IME to be triggered if the previous is accelerator key
260 // Alt+Shift (like Alt+Shift+Tab or Alt+Shift+S) to trigger next IME when the 300 // is ONLY either Shift, Alt, Enter or Space.
261 // wrong order of key sequences is pressed. crbug.com/527154. 301 // The first six cases below are to avoid conflicting accelerators that
262 // The latter two cases are needed for CJK IME users who tend to press Enter 302 // contain Alt+Shift (like Alt+Shift+Tab or Alt+Shift+S) to trigger next IME
263 // (or Space) and Shift+Alt almost at the same time to commit an IME string 303 // when the wrong order of key sequences is pressed. crbug.com/527154.
264 // and then switch from the IME to the English layout. This allows these users 304 // The latter two cases are needed for CJK IME users who tend to press Enter
265 // to trigger NEXT_IME even if they press Shift+Alt before releasing Enter. 305 // (or Space) and Shift+Alt almost at the same time to commit an IME string
266 // crbug.com/139556. 306 // and then switch from the IME to the English layout. This allows these
267 // TODO(nona|mazda): Fix crbug.com/139556 in a cleaner way. 307 // users to trigger NEXT_IME even if they press Shift+Alt before releasing
268 const ui::KeyboardCode previous_key_code = previous_accelerator.key_code(); 308 // Enter. crbug.com/139556.
269 switch (previous_key_code) { 309 // TODO(nona|mazda): Fix crbug.com/139556 in a cleaner way.
270 case ui::VKEY_SHIFT: 310 const ui::KeyboardCode previous_key_code = previous_accelerator.key_code();
271 case ui::VKEY_LSHIFT: 311 switch (previous_key_code) {
272 case ui::VKEY_RSHIFT: 312 case ui::VKEY_SHIFT:
273 case ui::VKEY_MENU: 313 case ui::VKEY_LSHIFT:
274 case ui::VKEY_LMENU: 314 case ui::VKEY_RSHIFT:
275 case ui::VKEY_RMENU: 315 case ui::VKEY_MENU:
276 case ui::VKEY_RETURN: 316 case ui::VKEY_LMENU:
277 case ui::VKEY_SPACE: 317 case ui::VKEY_RMENU:
278 return ime_control_delegate && ime_control_delegate->CanCycleIme(); 318 case ui::VKEY_RETURN:
319 case ui::VKEY_SPACE:
320 break;
279 321
280 default: 322 default:
281 return false; 323 return false;
324 }
282 } 325 }
326
327 return ime_control_delegate && ime_control_delegate->CanCycleIme();
283 } 328 }
284 329
285 void HandleNextIme(ImeControlDelegate* ime_control_delegate) { 330 void HandleNextIme(ImeControlDelegate* ime_control_delegate) {
286 base::RecordAction(UserMetricsAction("Accel_Next_Ime")); 331 base::RecordAction(UserMetricsAction("Accel_Next_Ime"));
287 ime_control_delegate->HandleNextIme(); 332 ime_control_delegate->HandleNextIme();
288 } 333 }
289 334
290 void HandleOpenFeedbackPage() { 335 void HandleOpenFeedbackPage() {
291 base::RecordAction(UserMetricsAction("Accel_Open_Feedback_Page")); 336 base::RecordAction(UserMetricsAction("Accel_Open_Feedback_Page"));
292 ash::Shell::GetInstance()->new_window_delegate()->OpenFeedbackPage(); 337 ash::Shell::GetInstance()->new_window_delegate()->OpenFeedbackPage();
(...skipping 532 matching lines...) Expand 10 before | Expand all | Expand 10 after
825 if (itr != actions_with_deprecations_.end()) { 870 if (itr != actions_with_deprecations_.end()) {
826 const DeprecatedAcceleratorData* data = itr->second; 871 const DeprecatedAcceleratorData* data = itr->second;
827 if (deprecated_accelerators_.count(accelerator)) { 872 if (deprecated_accelerators_.count(accelerator)) {
828 // This accelerator has been deprecated and should be treated according 873 // This accelerator has been deprecated and should be treated according
829 // to its |DeprecatedAcceleratorData|. 874 // to its |DeprecatedAcceleratorData|.
830 875
831 // Record UMA stats. 876 // Record UMA stats.
832 RecordUmaHistogram(data->uma_histogram_name, DEPRECATED_USED); 877 RecordUmaHistogram(data->uma_histogram_name, DEPRECATED_USED);
833 878
834 // We always display the notification as long as this entry exists. 879 // We always display the notification as long as this entry exists.
835 ShowDeprecatedAcceleratorNotification(data->uma_histogram_name, 880 ShowDeprecatedAcceleratorNotification(
836 data->notification_message_id); 881 data->uma_histogram_name, data->notification_message_id,
882 data->old_shortcut_id, data->new_shortcut_id);
837 883
838 if (!data->deprecated_enabled) 884 if (!data->deprecated_enabled)
839 return false; 885 return false;
840 } else { 886 } else {
841 // This is a new accelerator replacing the old deprecated one. 887 // This is a new accelerator replacing the old deprecated one.
842 // Record UMA stats and proceed normally. 888 // Record UMA stats and proceed normally.
843 RecordUmaHistogram(data->uma_histogram_name, NEW_USED); 889 RecordUmaHistogram(data->uma_histogram_name, NEW_USED);
844 } 890 }
845 } 891 }
846 892
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
906 CreateAccelerator(accelerators[i].keycode, accelerators[i].modifiers, 952 CreateAccelerator(accelerators[i].keycode, accelerators[i].modifiers,
907 accelerators[i].trigger_on_press); 953 accelerators[i].trigger_on_press);
908 Register(accelerator, this); 954 Register(accelerator, this);
909 accelerators_.insert( 955 accelerators_.insert(
910 std::make_pair(accelerator, accelerators[i].action)); 956 std::make_pair(accelerator, accelerators[i].action));
911 } 957 }
912 } 958 }
913 959
914 void AcceleratorController::RegisterDeprecatedAccelerators() { 960 void AcceleratorController::RegisterDeprecatedAccelerators() {
915 #if defined(OS_CHROMEOS) 961 #if defined(OS_CHROMEOS)
962 for (size_t i = 0; i < kDeprecatedAcceleratorsDataLength; ++i) {
963 const DeprecatedAcceleratorData* data = &kDeprecatedAcceleratorsData[i];
964 actions_with_deprecations_[data->action] = data;
965 }
966
916 for (size_t i = 0; i < kDeprecatedAcceleratorsLength; ++i) { 967 for (size_t i = 0; i < kDeprecatedAcceleratorsLength; ++i) {
917 const DeprecatedAcceleratorData* data = &kDeprecatedAccelerators[i]; 968 const AcceleratorData& accelerator_data = kDeprecatedAccelerators[i];
918 const AcceleratorAction action = data->deprecated_accelerator.action;
919 const ui::Accelerator deprecated_accelerator = 969 const ui::Accelerator deprecated_accelerator =
920 CreateAccelerator(data->deprecated_accelerator.keycode, 970 CreateAccelerator(accelerator_data.keycode, accelerator_data.modifiers,
921 data->deprecated_accelerator.modifiers, 971 accelerator_data.trigger_on_press);
922 data->deprecated_accelerator.trigger_on_press);
923 972
924 Register(deprecated_accelerator, this); 973 Register(deprecated_accelerator, this);
925 actions_with_deprecations_[action] = data; 974 accelerators_[deprecated_accelerator] = accelerator_data.action;
926 accelerators_[deprecated_accelerator] = action;
927 deprecated_accelerators_.insert(deprecated_accelerator); 975 deprecated_accelerators_.insert(deprecated_accelerator);
928 } 976 }
929 #endif // defined(OS_CHROMEOS) 977 #endif // defined(OS_CHROMEOS)
930 } 978 }
931 979
932 bool AcceleratorController::CanPerformAction( 980 bool AcceleratorController::CanPerformAction(
933 AcceleratorAction action, 981 AcceleratorAction action,
934 const ui::Accelerator& accelerator) { 982 const ui::Accelerator& accelerator) {
935 if (nonrepeatable_actions_.find(action) != nonrepeatable_actions_.end() && 983 if (nonrepeatable_actions_.find(action) != nonrepeatable_actions_.end() &&
936 accelerator.IsRepeat()) { 984 accelerator.IsRepeat()) {
(...skipping 20 matching lines...) Expand all
957 case DEBUG_TOGGLE_ROOT_WINDOW_FULL_SCREEN: 1005 case DEBUG_TOGGLE_ROOT_WINDOW_FULL_SCREEN:
958 case DEBUG_TOGGLE_SHOW_DEBUG_BORDERS: 1006 case DEBUG_TOGGLE_SHOW_DEBUG_BORDERS:
959 case DEBUG_TOGGLE_SHOW_FPS_COUNTER: 1007 case DEBUG_TOGGLE_SHOW_FPS_COUNTER:
960 case DEBUG_TOGGLE_SHOW_PAINT_RECTS: 1008 case DEBUG_TOGGLE_SHOW_PAINT_RECTS:
961 return debug::DebugAcceleratorsEnabled(); 1009 return debug::DebugAcceleratorsEnabled();
962 case MAGNIFY_SCREEN_ZOOM_IN: 1010 case MAGNIFY_SCREEN_ZOOM_IN:
963 case MAGNIFY_SCREEN_ZOOM_OUT: 1011 case MAGNIFY_SCREEN_ZOOM_OUT:
964 return CanHandleMagnifyScreen(); 1012 return CanHandleMagnifyScreen();
965 case NEW_INCOGNITO_WINDOW: 1013 case NEW_INCOGNITO_WINDOW:
966 return CanHandleNewIncognitoWindow(); 1014 return CanHandleNewIncognitoWindow();
967 case NEXT_IME: 1015 case NEXT_IME: {
968 return CanHandleNextIme(ime_control_delegate_.get(), 1016 #if defined(OS_CHROMEOS)
969 previous_accelerator); 1017 bool accelerator_is_deprecated =
1018 (deprecated_accelerators_.count(accelerator) != 0);
1019 #else
1020 // On non-chromeos, the NEXT_IME deprecated accelerators are always used.
1021 bool accelerator_is_deprecated = true;
1022 #endif // defined(OS_CHROMEOS)
1023
1024 return CanHandleNextIme(ime_control_delegate_.get(), previous_accelerator,
1025 accelerator_is_deprecated);
1026 }
970 case PREVIOUS_IME: 1027 case PREVIOUS_IME:
971 return CanHandlePreviousIme(ime_control_delegate_.get()); 1028 return CanHandlePreviousIme(ime_control_delegate_.get());
972 case SCALE_UI_RESET: 1029 case SCALE_UI_RESET:
973 case SCALE_UI_UP: 1030 case SCALE_UI_UP:
974 case SCALE_UI_DOWN: 1031 case SCALE_UI_DOWN:
975 return accelerators::IsInternalDisplayZoomEnabled(); 1032 return accelerators::IsInternalDisplayZoomEnabled();
976 case SHOW_MESSAGE_CENTER_BUBBLE: 1033 case SHOW_MESSAGE_CENTER_BUBBLE:
977 return CanHandleShowMessageCenterBubble(); 1034 return CanHandleShowMessageCenterBubble();
978 case SWITCH_IME: 1035 case SWITCH_IME:
979 return CanHandleSwitchIme(ime_control_delegate_.get(), accelerator); 1036 return CanHandleSwitchIme(ime_control_delegate_.get(), accelerator);
(...skipping 412 matching lines...) Expand 10 before | Expand all | Expand 10 after
1392 } 1449 }
1393 1450
1394 void AcceleratorController::SetKeyboardBrightnessControlDelegate( 1451 void AcceleratorController::SetKeyboardBrightnessControlDelegate(
1395 scoped_ptr<KeyboardBrightnessControlDelegate> 1452 scoped_ptr<KeyboardBrightnessControlDelegate>
1396 keyboard_brightness_control_delegate) { 1453 keyboard_brightness_control_delegate) {
1397 keyboard_brightness_control_delegate_ = 1454 keyboard_brightness_control_delegate_ =
1398 keyboard_brightness_control_delegate.Pass(); 1455 keyboard_brightness_control_delegate.Pass();
1399 } 1456 }
1400 1457
1401 } // namespace ash 1458 } // namespace ash
OLDNEW
« no previous file with comments | « ash/accelerators/accelerator_controller.h ('k') | ash/accelerators/accelerator_controller_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698