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

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: 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/keycodes/dom/dom_code.h" 15 #include "ui/events/keycodes/dom/dom_code.h"
16 #include "ui/events/keycodes/keyboard_code_conversion.h"
16 17
17 namespace ui { 18 namespace ui {
18 19
19 namespace { 20 namespace {
20 21
21 struct DomCodeEntry { 22 struct DomCodeEntry {
22 DomCode dom_code; 23 DomCode dom_code;
23 int scan_code; 24 int scan_code;
24 }; 25 };
25 #define USB_KEYMAP_DECLARATION const DomCodeEntry supported_dom_code_list[] = 26 #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) 81 if (flags & EF_NUM_LOCK_ON)
81 keyboard_state[VK_NUMLOCK] |= 0x01; 82 keyboard_state[VK_NUMLOCK] |= 0x01;
82 83
83 if (flags & EF_CAPS_LOCK_ON) 84 if (flags & EF_CAPS_LOCK_ON)
84 keyboard_state[VK_CAPITAL] |= 0x01; 85 keyboard_state[VK_CAPITAL] |= 0x01;
85 86
86 if (flags & EF_SCROLL_LOCK_ON) 87 if (flags & EF_SCROLL_LOCK_ON)
87 keyboard_state[VK_SCROLL] |= 0x01; 88 keyboard_state[VK_SCROLL] |= 0x01;
88 } 89 }
89 90
91 DomKey NonPrintableNumPadKeyCodeToDomKey(KeyboardCode key_code) {
92 switch (key_code) {
93 case VKEY_CLEAR:
94 return DomKey::CLEAR;
95 case VKEY_PRIOR:
96 return DomKey::PAGE_UP;
97 case VKEY_NEXT:
98 return DomKey::PAGE_DOWN;
99 case VKEY_END:
100 return DomKey::END;
101 case VKEY_HOME:
102 return DomKey::HOME;
103 case VKEY_LEFT:
104 return DomKey::ARROW_LEFT;
105 case VKEY_UP:
106 return DomKey::ARROW_UP;
107 case VKEY_RIGHT:
108 return DomKey::ARROW_RIGHT;
109 case VKEY_DOWN:
110 return DomKey::ARROW_DOWN;
111 case VKEY_INSERT:
112 return DomKey::INSERT;
113 case VKEY_DELETE:
114 return DomKey::DEL;
115 default:
116 return DomKey::NONE;
117 }
118 }
119
90 void CleanupKeyMapTls(void* data) { 120 void CleanupKeyMapTls(void* data) {
91 PlatformKeyMap* key_map = reinterpret_cast<PlatformKeyMap*>(data); 121 PlatformKeyMap* key_map = reinterpret_cast<PlatformKeyMap*>(data);
92 delete key_map; 122 delete key_map;
93 } 123 }
94 124
95 struct PlatformKeyMapInstanceTlsTraits 125 struct PlatformKeyMapInstanceTlsTraits
96 : public base::DefaultLazyInstanceTraits<base::ThreadLocalStorage::Slot> { 126 : public base::DefaultLazyInstanceTraits<base::ThreadLocalStorage::Slot> {
97 static base::ThreadLocalStorage::Slot* New(void* instance) { 127 static base::ThreadLocalStorage::Slot* New(void* instance) {
98 // Use placement new to initialize our instance in our preallocated space. 128 // Use placement new to initialize our instance in our preallocated space.
99 // TODO(chongz): Use std::default_delete instead of providing own function. 129 // TODO(chongz): Use std::default_delete instead of providing own function.
100 return new (instance) base::ThreadLocalStorage::Slot(CleanupKeyMapTls); 130 return new (instance) base::ThreadLocalStorage::Slot(CleanupKeyMapTls);
101 } 131 }
102 }; 132 };
103 133
104 base::LazyInstance<base::ThreadLocalStorage::Slot, 134 base::LazyInstance<base::ThreadLocalStorage::Slot,
105 PlatformKeyMapInstanceTlsTraits> 135 PlatformKeyMapInstanceTlsTraits>
106 g_platform_key_map_tls_lazy = LAZY_INSTANCE_INITIALIZER; 136 g_platform_key_map_tls_lazy = LAZY_INSTANCE_INITIALIZER;
107 137
108 } // anonymous namespace 138 } // anonymous namespace
109 139
110 PlatformKeyMap::PlatformKeyMap() {} 140 PlatformKeyMap::PlatformKeyMap() {}
111 141
112 PlatformKeyMap::PlatformKeyMap(HKL layout) { 142 PlatformKeyMap::PlatformKeyMap(HKL layout) {
113 UpdateLayout(layout); 143 UpdateLayout(layout);
114 } 144 }
115 145
116 PlatformKeyMap::~PlatformKeyMap() {} 146 PlatformKeyMap::~PlatformKeyMap() {}
117 147
118 DomKey PlatformKeyMap::DomCodeAndFlagsToDomKey(DomCode code, int flags) const { 148 DomKey PlatformKeyMap::DomCodeAndFlagsToDomKey(DomCode code,
149 KeyboardCode key_code,
150 int flags) const {
151 // Try printable key map first.
119 const int flags_to_try[] = { 152 const int flags_to_try[] = {
120 // Trying to match Firefox's behavior and UIEvents DomKey guidelines. 153 // Trying to match Firefox's behavior and UIEvents DomKey guidelines.
121 // If the combination doesn't produce a printable character, the key value 154 // 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. 155 // should be the key with no modifiers except for Shift and AltGr.
123 // See https://w3c.github.io/uievents/#keys-guidelines 156 // See https://w3c.github.io/uievents/#keys-guidelines
124 flags, 157 flags,
125 flags & (EF_SHIFT_DOWN | EF_ALTGR_DOWN | EF_CAPS_LOCK_ON), 158 flags & (EF_SHIFT_DOWN | EF_ALTGR_DOWN | EF_CAPS_LOCK_ON),
126 flags & (EF_SHIFT_DOWN | EF_CAPS_LOCK_ON), 159 flags & (EF_SHIFT_DOWN | EF_CAPS_LOCK_ON),
127 EF_NONE, 160 EF_NONE,
128 }; 161 };
129 162
130 DomKey key = DomKey::NONE; 163 DomKey key = DomKey::NONE;
131 for (auto try_flags : flags_to_try) { 164 for (auto try_flags : flags_to_try) {
132 const auto& it = code_to_key_.find(std::make_pair(static_cast<int>(code), 165 const auto& it = code_to_key_.find(std::make_pair(static_cast<int>(code),
133 try_flags)); 166 try_flags));
134 if (it != code_to_key_.end()) { 167 if (it != code_to_key_.end()) {
135 key = it->second; 168 key = it->second;
136 if (key != DomKey::NONE) 169 if (key != DomKey::NONE)
137 break; 170 break;
138 } 171 }
139 } 172 }
173
174 // Handle non-printable key produced by NumPad.
175 if (key == DomKey::NONE) {
Wez 2016/03/16 21:03:06 IMO it would be cleaner & easier to understand thi
176 // Have to use KeyboardCode instead of DomCode because NumLockOn+Shift+4
177 // will generate keydown event with EF_SHIFT_DOWN modifier set to false, so
178 // we have no way to know whether Shift is down.
179 key = NonPrintableNumPadKeyCodeToDomKey(key_code);
180 }
181
182 // Use US layout for other non-printable key.
dtapuska 2016/03/10 20:51:44 This is a bit odd that this is done here; because
chongz 2016/03/10 21:03:32 Yes it will simplify the tests, otherwise I will n
Wez 2016/03/16 21:03:06 Sorry, I didn't get the logic here; are you sugges
183 if (key == DomKey::NONE) {
184 KeyboardCode dummy_key_code;
185 DomCodeToUsLayoutDomKey(code, flags, &key, &dummy_key_code);
186 }
187
140 return key; 188 return key;
141 } 189 }
142 190
143 // static 191 // static
144 DomKey PlatformKeyMap::DomCodeAndFlagsToDomKeyStatic(DomCode code, int flags) { 192 DomKey PlatformKeyMap::DomCodeAndFlagsToDomKeyStatic(DomCode code,
193 KeyboardCode key_code,
194 int flags) {
145 // Use TLS because KeyboardLayout is per thread. 195 // Use TLS because KeyboardLayout is per thread.
146 // However currently PlatformKeyMap will only be used by the host application, 196 // However currently PlatformKeyMap will only be used by the host application,
147 // which is just one process and one thread. 197 // which is just one process and one thread.
148 base::ThreadLocalStorage::Slot* platform_key_map_tls = 198 base::ThreadLocalStorage::Slot* platform_key_map_tls =
149 g_platform_key_map_tls_lazy.Pointer(); 199 g_platform_key_map_tls_lazy.Pointer();
150 PlatformKeyMap* platform_key_map = 200 PlatformKeyMap* platform_key_map =
151 reinterpret_cast<PlatformKeyMap*>(platform_key_map_tls->Get()); 201 reinterpret_cast<PlatformKeyMap*>(platform_key_map_tls->Get());
152 if (!platform_key_map) { 202 if (!platform_key_map) {
153 platform_key_map = new PlatformKeyMap(); 203 platform_key_map = new PlatformKeyMap();
154 platform_key_map_tls->Set(platform_key_map); 204 platform_key_map_tls->Set(platform_key_map);
155 } 205 }
156 206
157 HKL current_layout = ::GetKeyboardLayout(0); 207 HKL current_layout = ::GetKeyboardLayout(0);
158 platform_key_map->UpdateLayout(current_layout); 208 platform_key_map->UpdateLayout(current_layout);
159 return platform_key_map->DomCodeAndFlagsToDomKey(code, flags); 209 return platform_key_map->DomCodeAndFlagsToDomKey(code, key_code, flags);
160 } 210 }
161 211
162 void PlatformKeyMap::UpdateLayout(HKL layout) { 212 void PlatformKeyMap::UpdateLayout(HKL layout) {
163 if (layout == keyboard_layout_) 213 if (layout == keyboard_layout_)
164 return; 214 return;
165 215
166 BYTE keyboard_state_to_restore[256]; 216 BYTE keyboard_state_to_restore[256];
167 if (!::GetKeyboardState(keyboard_state_to_restore)) 217 if (!::GetKeyboardState(keyboard_state_to_restore))
168 return; 218 return;
169 219
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
210 } 260 }
211 } else { 261 } else {
212 // TODO(chongz): Handle rv <= -2 and rv >= 2. 262 // TODO(chongz): Handle rv <= -2 and rv >= 2.
213 } 263 }
214 } 264 }
215 } 265 }
216 ::SetKeyboardState(keyboard_state_to_restore); 266 ::SetKeyboardState(keyboard_state_to_restore);
217 } 267 }
218 268
219 } // namespace ui 269 } // namespace ui
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698