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

Side by Side Diff: ui/events/keycodes/platform_key_map_win.cc

Issue 1776673007: [Windows] Produce correct DomKey for NumPad when combined with Shift/NumLock (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: wez's review 2 Created 4 years, 9 months 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) 2016 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2016 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 "ui/events/keycodes/platform_key_map_win.h" 5 #include "ui/events/keycodes/platform_key_map_win.h"
6 6
7 #include <utility> 7 #include <utility>
8 8
9 #include "base/lazy_instance.h" 9 #include "base/lazy_instance.h"
10 #include "base/logging.h" 10 #include "base/logging.h"
11 #include "base/macros.h" 11 #include "base/macros.h"
12 #include "base/threading/thread_local_storage.h" 12 #include "base/threading/thread_local_storage.h"
13 13
14 #include "ui/events/event_constants.h" 14 #include "ui/events/event_constants.h"
15 #include "ui/events/event_utils.h"
15 #include "ui/events/keycodes/dom/dom_code.h" 16 #include "ui/events/keycodes/dom/dom_code.h"
17 #include "ui/events/keycodes/dom/keycode_converter.h"
18 #include "ui/events/keycodes/keyboard_code_conversion.h"
16 19
17 namespace ui { 20 namespace ui {
18 21
19 namespace { 22 namespace {
20 23
21 struct DomCodeEntry { 24 struct DomCodeEntry {
22 DomCode dom_code; 25 DomCode dom_code;
23 int scan_code; 26 int scan_code;
24 }; 27 };
25 #define USB_KEYMAP_DECLARATION const DomCodeEntry supported_dom_code_list[] = 28 #define USB_KEYMAP_DECLARATION const DomCodeEntry supported_dom_code_list[] =
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
80 if (flags & EF_NUM_LOCK_ON) 83 if (flags & EF_NUM_LOCK_ON)
81 keyboard_state[VK_NUMLOCK] |= 0x01; 84 keyboard_state[VK_NUMLOCK] |= 0x01;
82 85
83 if (flags & EF_CAPS_LOCK_ON) 86 if (flags & EF_CAPS_LOCK_ON)
84 keyboard_state[VK_CAPITAL] |= 0x01; 87 keyboard_state[VK_CAPITAL] |= 0x01;
85 88
86 if (flags & EF_SCROLL_LOCK_ON) 89 if (flags & EF_SCROLL_LOCK_ON)
87 keyboard_state[VK_SCROLL] |= 0x01; 90 keyboard_state[VK_SCROLL] |= 0x01;
88 } 91 }
89 92
93 DomKey NumPadKeyCodeToDomKey(KeyboardCode key_code) {
94 switch (key_code) {
95 case VKEY_NUMPAD0:
96 return DomKey::Constant<'0'>::Character;
97 case VKEY_NUMPAD1:
98 return DomKey::Constant<'1'>::Character;
99 case VKEY_NUMPAD2:
100 return DomKey::Constant<'2'>::Character;
101 case VKEY_NUMPAD3:
102 return DomKey::Constant<'3'>::Character;
103 case VKEY_NUMPAD4:
104 return DomKey::Constant<'4'>::Character;
105 case VKEY_NUMPAD5:
106 return DomKey::Constant<'5'>::Character;
107 case VKEY_NUMPAD6:
108 return DomKey::Constant<'6'>::Character;
109 case VKEY_NUMPAD7:
110 return DomKey::Constant<'7'>::Character;
111 case VKEY_NUMPAD8:
112 return DomKey::Constant<'8'>::Character;
113 case VKEY_NUMPAD9:
114 return DomKey::Constant<'9'>::Character;
115 case VKEY_CLEAR:
116 return DomKey::CLEAR;
117 case VKEY_PRIOR:
118 return DomKey::PAGE_UP;
119 case VKEY_NEXT:
120 return DomKey::PAGE_DOWN;
121 case VKEY_END:
122 return DomKey::END;
123 case VKEY_HOME:
124 return DomKey::HOME;
125 case VKEY_LEFT:
126 return DomKey::ARROW_LEFT;
127 case VKEY_UP:
128 return DomKey::ARROW_UP;
129 case VKEY_RIGHT:
130 return DomKey::ARROW_RIGHT;
131 case VKEY_DOWN:
132 return DomKey::ARROW_DOWN;
133 case VKEY_INSERT:
134 return DomKey::INSERT;
135 case VKEY_DELETE:
136 return DomKey::DEL;
137 default:
138 return DomKey::NONE;
139 }
140 }
141
90 void CleanupKeyMapTls(void* data) { 142 void CleanupKeyMapTls(void* data) {
91 PlatformKeyMap* key_map = reinterpret_cast<PlatformKeyMap*>(data); 143 PlatformKeyMap* key_map = reinterpret_cast<PlatformKeyMap*>(data);
92 delete key_map; 144 delete key_map;
93 } 145 }
94 146
95 struct PlatformKeyMapInstanceTlsTraits 147 struct PlatformKeyMapInstanceTlsTraits
96 : public base::DefaultLazyInstanceTraits<base::ThreadLocalStorage::Slot> { 148 : public base::DefaultLazyInstanceTraits<base::ThreadLocalStorage::Slot> {
97 static base::ThreadLocalStorage::Slot* New(void* instance) { 149 static base::ThreadLocalStorage::Slot* New(void* instance) {
98 // Use placement new to initialize our instance in our preallocated space. 150 // Use placement new to initialize our instance in our preallocated space.
99 // TODO(chongz): Use std::default_delete instead of providing own function. 151 // TODO(chongz): Use std::default_delete instead of providing own function.
100 return new (instance) base::ThreadLocalStorage::Slot(CleanupKeyMapTls); 152 return new (instance) base::ThreadLocalStorage::Slot(CleanupKeyMapTls);
101 } 153 }
102 }; 154 };
103 155
104 base::LazyInstance<base::ThreadLocalStorage::Slot, 156 base::LazyInstance<base::ThreadLocalStorage::Slot,
105 PlatformKeyMapInstanceTlsTraits> 157 PlatformKeyMapInstanceTlsTraits>
106 g_platform_key_map_tls_lazy = LAZY_INSTANCE_INITIALIZER; 158 g_platform_key_map_tls_lazy = LAZY_INSTANCE_INITIALIZER;
107 159
108 } // anonymous namespace 160 } // anonymous namespace
109 161
110 PlatformKeyMap::PlatformKeyMap() {} 162 PlatformKeyMap::PlatformKeyMap() {}
111 163
112 PlatformKeyMap::PlatformKeyMap(HKL layout) { 164 PlatformKeyMap::PlatformKeyMap(HKL layout) {
113 UpdateLayout(layout); 165 UpdateLayout(layout);
114 } 166 }
115 167
116 PlatformKeyMap::~PlatformKeyMap() {} 168 PlatformKeyMap::~PlatformKeyMap() {}
117 169
118 DomKey PlatformKeyMap::DomCodeAndFlagsToDomKey(DomCode code, int flags) const { 170 DomKey PlatformKeyMap::DomKeyFromNativeImpl(DomCode code,
171 KeyboardCode key_code,
172 int flags) const {
173 if (KeycodeConverter::DomCodeToLocation(code) == DomKeyLocation::NUMPAD) {
174 // Derived the DOM Key value from |key_code| instead of |code|, to address
175 // Windows Numlock/Shift interaction - see crbug.com/594552.
176 return NumPadKeyCodeToDomKey(key_code);
177 }
178
119 const int flags_to_try[] = { 179 const int flags_to_try[] = {
120 // Trying to match Firefox's behavior and UIEvents DomKey guidelines. 180 // Trying to match Firefox's behavior and UIEvents DomKey guidelines.
121 // If the combination doesn't produce a printable character, the key value 181 // If the combination doesn't produce a printable character, the key value
122 // should be the key with no modifiers except for Shift and AltGr. 182 // should be the key with no modifiers except for Shift and AltGr.
123 // See https://w3c.github.io/uievents/#keys-guidelines 183 // See https://w3c.github.io/uievents/#keys-guidelines
124 flags, 184 flags,
125 flags & (EF_SHIFT_DOWN | EF_ALTGR_DOWN | EF_CAPS_LOCK_ON), 185 flags & (EF_SHIFT_DOWN | EF_ALTGR_DOWN | EF_CAPS_LOCK_ON),
126 flags & (EF_SHIFT_DOWN | EF_CAPS_LOCK_ON), 186 flags & (EF_SHIFT_DOWN | EF_CAPS_LOCK_ON),
127 EF_NONE, 187 EF_NONE,
128 }; 188 };
129 189
130 DomKey key = DomKey::NONE; 190 DomKey key = DomKey::NONE;
131 for (auto try_flags : flags_to_try) { 191 for (auto try_flags : flags_to_try) {
132 const auto& it = code_to_key_.find(std::make_pair(static_cast<int>(code), 192 const auto& it = code_to_key_.find(std::make_pair(static_cast<int>(code),
133 try_flags)); 193 try_flags));
134 if (it != code_to_key_.end()) { 194 if (it != code_to_key_.end()) {
135 key = it->second; 195 key = it->second;
136 if (key != DomKey::NONE) 196 if (key != DomKey::NONE)
137 break; 197 break;
138 } 198 }
139 } 199 }
140 return key; 200 return key;
141 } 201 }
142 202
143 // static 203 // static
144 DomKey PlatformKeyMap::DomCodeAndFlagsToDomKeyStatic(DomCode code, int flags) { 204 DomKey PlatformKeyMap::DomKeyFromNative(const base::NativeEvent& native_event) {
145 // Use TLS because KeyboardLayout is per thread. 205 // Use TLS because KeyboardLayout is per thread.
146 // However currently PlatformKeyMap will only be used by the host application, 206 // However currently PlatformKeyMap will only be used by the host application,
147 // which is just one process and one thread. 207 // which is just one process and one thread.
148 base::ThreadLocalStorage::Slot* platform_key_map_tls = 208 base::ThreadLocalStorage::Slot* platform_key_map_tls =
149 g_platform_key_map_tls_lazy.Pointer(); 209 g_platform_key_map_tls_lazy.Pointer();
150 PlatformKeyMap* platform_key_map = 210 PlatformKeyMap* platform_key_map =
151 reinterpret_cast<PlatformKeyMap*>(platform_key_map_tls->Get()); 211 reinterpret_cast<PlatformKeyMap*>(platform_key_map_tls->Get());
152 if (!platform_key_map) { 212 if (!platform_key_map) {
153 platform_key_map = new PlatformKeyMap(); 213 platform_key_map = new PlatformKeyMap();
154 platform_key_map_tls->Set(platform_key_map); 214 platform_key_map_tls->Set(platform_key_map);
155 } 215 }
156 216
157 HKL current_layout = ::GetKeyboardLayout(0); 217 HKL current_layout = ::GetKeyboardLayout(0);
158 platform_key_map->UpdateLayout(current_layout); 218 platform_key_map->UpdateLayout(current_layout);
159 return platform_key_map->DomCodeAndFlagsToDomKey(code, flags); 219 return platform_key_map->DomKeyFromNativeImpl(
220 CodeFromNative(native_event), KeyboardCodeFromNative(native_event),
221 EventFlagsFromNative(native_event));
160 } 222 }
161 223
162 void PlatformKeyMap::UpdateLayout(HKL layout) { 224 void PlatformKeyMap::UpdateLayout(HKL layout) {
163 if (layout == keyboard_layout_) 225 if (layout == keyboard_layout_)
164 return; 226 return;
165 227
166 BYTE keyboard_state_to_restore[256]; 228 BYTE keyboard_state_to_restore[256];
167 if (!::GetKeyboardState(keyboard_state_to_restore)) 229 if (!::GetKeyboardState(keyboard_state_to_restore))
168 return; 230 return;
169 231
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
210 } 272 }
211 } else { 273 } else {
212 // TODO(chongz): Handle rv <= -2 and rv >= 2. 274 // TODO(chongz): Handle rv <= -2 and rv >= 2.
213 } 275 }
214 } 276 }
215 } 277 }
216 ::SetKeyboardState(keyboard_state_to_restore); 278 ::SetKeyboardState(keyboard_state_to_restore);
217 } 279 }
218 280
219 } // namespace ui 281 } // namespace ui
OLDNEW
« no previous file with comments | « ui/events/keycodes/platform_key_map_win.h ('k') | ui/events/keycodes/platform_key_map_win_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698