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

Side by Side Diff: ash/sticky_keys/sticky_keys_controller.cc

Issue 137373003: Show overlay displaying the state of all sticky keys when it is enabled. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: update constant Created 6 years, 11 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 | Annotate | Revision Log
« no previous file with comments | « ash/sticky_keys/sticky_keys_controller.h ('k') | ash/sticky_keys/sticky_keys_overlay.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 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/sticky_keys/sticky_keys_controller.h" 5 #include "ash/sticky_keys/sticky_keys_controller.h"
6 6
7 #if defined(USE_X11) 7 #if defined(USE_X11)
8 #include <X11/extensions/XInput2.h> 8 #include <X11/extensions/XInput2.h>
9 #include <X11/Xlib.h> 9 #include <X11/Xlib.h>
10 #undef RootWindow 10 #undef RootWindow
11 #endif 11 #endif
12 12
13 #include "ash/sticky_keys/sticky_keys_overlay.h"
13 #include "base/basictypes.h" 14 #include "base/basictypes.h"
14 #include "base/debug/stack_trace.h" 15 #include "base/debug/stack_trace.h"
15 #include "ui/aura/root_window.h" 16 #include "ui/aura/root_window.h"
16 #include "ui/aura/window.h" 17 #include "ui/aura/window.h"
17 #include "ui/aura/window_tracker.h" 18 #include "ui/aura/window_tracker.h"
18 #include "ui/events/event.h" 19 #include "ui/events/event.h"
19 #include "ui/events/keycodes/keyboard_code_conversion.h" 20 #include "ui/events/keycodes/keyboard_code_conversion.h"
20 21
21 namespace ash { 22 namespace ash {
22 23
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
82 DCHECK(target); 83 DCHECK(target);
83 target->GetDispatcher()->AsWindowTreeHostDelegate() 84 target->GetDispatcher()->AsWindowTreeHostDelegate()
84 ->OnHostScrollEvent(event); 85 ->OnHostScrollEvent(event);
85 } 86 }
86 87
87 } // namespace 88 } // namespace
88 89
89 /////////////////////////////////////////////////////////////////////////////// 90 ///////////////////////////////////////////////////////////////////////////////
90 // StickyKeys 91 // StickyKeys
91 StickyKeysController::StickyKeysController() 92 StickyKeysController::StickyKeysController()
92 : enabled_(false), 93 : enabled_(false) {
93 shift_sticky_key_(
94 new StickyKeysHandler(ui::EF_SHIFT_DOWN,
95 new StickyKeysHandlerDelegateImpl())),
96 alt_sticky_key_(
97 new StickyKeysHandler(ui::EF_ALT_DOWN,
98 new StickyKeysHandlerDelegateImpl())),
99 ctrl_sticky_key_(
100 new StickyKeysHandler(ui::EF_CONTROL_DOWN,
101 new StickyKeysHandlerDelegateImpl())) {
102 } 94 }
103 95
104 StickyKeysController::~StickyKeysController() { 96 StickyKeysController::~StickyKeysController() {
105 } 97 }
106 98
107 void StickyKeysController::Enable(bool enabled) { 99 void StickyKeysController::Enable(bool enabled) {
108 if (enabled_ != enabled) { 100 if (enabled_ != enabled) {
109 enabled_ = enabled; 101 enabled_ = enabled;
110 102
111 // Reset key handlers when activating sticky keys to ensure all 103 // Reset key handlers when activating sticky keys to ensure all
112 // the handlers' states are reset. 104 // the handlers' states are reset.
113 if (enabled_) { 105 if (enabled_) {
114 shift_sticky_key_.reset( 106 shift_sticky_key_.reset(
115 new StickyKeysHandler(ui::EF_SHIFT_DOWN, 107 new StickyKeysHandler(ui::EF_SHIFT_DOWN,
116 new StickyKeysHandlerDelegateImpl())); 108 new StickyKeysHandlerDelegateImpl()));
117 alt_sticky_key_.reset( 109 alt_sticky_key_.reset(
118 new StickyKeysHandler(ui::EF_ALT_DOWN, 110 new StickyKeysHandler(ui::EF_ALT_DOWN,
119 new StickyKeysHandlerDelegateImpl())); 111 new StickyKeysHandlerDelegateImpl()));
120 ctrl_sticky_key_.reset( 112 ctrl_sticky_key_.reset(
121 new StickyKeysHandler(ui::EF_CONTROL_DOWN, 113 new StickyKeysHandler(ui::EF_CONTROL_DOWN,
122 new StickyKeysHandlerDelegateImpl())); 114 new StickyKeysHandlerDelegateImpl()));
115
116 overlay_.reset(new StickyKeysOverlay());
117 } else if (overlay_.get()) {
118 overlay_->Show(false);
123 } 119 }
124 } 120 }
125 } 121 }
126 122
127 bool StickyKeysController::HandleKeyEvent(ui::KeyEvent* event) { 123 bool StickyKeysController::HandleKeyEvent(ui::KeyEvent* event) {
128 return shift_sticky_key_->HandleKeyEvent(event) || 124 return shift_sticky_key_->HandleKeyEvent(event) ||
129 alt_sticky_key_->HandleKeyEvent(event) || 125 alt_sticky_key_->HandleKeyEvent(event) ||
130 ctrl_sticky_key_->HandleKeyEvent(event); 126 ctrl_sticky_key_->HandleKeyEvent(event);
131 } 127 }
132 128
133 bool StickyKeysController::HandleMouseEvent(ui::MouseEvent* event) { 129 bool StickyKeysController::HandleMouseEvent(ui::MouseEvent* event) {
134 return shift_sticky_key_->HandleMouseEvent(event) || 130 return shift_sticky_key_->HandleMouseEvent(event) ||
135 alt_sticky_key_->HandleMouseEvent(event) || 131 alt_sticky_key_->HandleMouseEvent(event) ||
136 ctrl_sticky_key_->HandleMouseEvent(event); 132 ctrl_sticky_key_->HandleMouseEvent(event);
137 } 133 }
138 134
139 bool StickyKeysController::HandleScrollEvent(ui::ScrollEvent* event) { 135 bool StickyKeysController::HandleScrollEvent(ui::ScrollEvent* event) {
140 return shift_sticky_key_->HandleScrollEvent(event) || 136 return shift_sticky_key_->HandleScrollEvent(event) ||
141 alt_sticky_key_->HandleScrollEvent(event) || 137 alt_sticky_key_->HandleScrollEvent(event) ||
142 ctrl_sticky_key_->HandleScrollEvent(event); 138 ctrl_sticky_key_->HandleScrollEvent(event);
143 } 139 }
144 140
145 void StickyKeysController::OnKeyEvent(ui::KeyEvent* event) { 141 void StickyKeysController::OnKeyEvent(ui::KeyEvent* event) {
146 // Do not consume a translated key event which is generated by an IME. 142 // Do not consume a translated key event which is generated by an IME.
147 if (event->type() == ui::ET_TRANSLATED_KEY_PRESS || 143 if (event->type() == ui::ET_TRANSLATED_KEY_PRESS ||
148 event->type() == ui::ET_TRANSLATED_KEY_RELEASE) { 144 event->type() == ui::ET_TRANSLATED_KEY_RELEASE) {
149 return; 145 return;
150 } 146 }
151 147
152 if (enabled_ && HandleKeyEvent(event)) 148 if (enabled_) {
153 event->StopPropagation(); 149 if (HandleKeyEvent(event))
150 event->StopPropagation();
151 UpdateOverlay();
152 }
154 } 153 }
155 154
156 void StickyKeysController::OnMouseEvent(ui::MouseEvent* event) { 155 void StickyKeysController::OnMouseEvent(ui::MouseEvent* event) {
157 if (enabled_ && HandleMouseEvent(event)) 156 if (enabled_) {
158 event->StopPropagation(); 157 if (HandleMouseEvent(event))
158 event->StopPropagation();
159 UpdateOverlay();
160 }
159 } 161 }
160 162
161 void StickyKeysController::OnScrollEvent(ui::ScrollEvent* event) { 163 void StickyKeysController::OnScrollEvent(ui::ScrollEvent* event) {
162 if (enabled_ && HandleScrollEvent(event)) 164 if (enabled_) {
163 event->StopPropagation(); 165 if (HandleScrollEvent(event))
166 event->StopPropagation();
167 UpdateOverlay();
168 }
169 }
170
171 void StickyKeysController::UpdateOverlay() {
172 overlay_->SetModifierKeyState(
173 ui::EF_SHIFT_DOWN, shift_sticky_key_->current_state());
174 overlay_->SetModifierKeyState(
175 ui::EF_CONTROL_DOWN, ctrl_sticky_key_->current_state());
176 overlay_->SetModifierKeyState(
177 ui::EF_ALT_DOWN, alt_sticky_key_->current_state());
178
179 bool key_in_use =
180 shift_sticky_key_->current_state() != STICKY_KEY_STATE_DISABLED ||
181 alt_sticky_key_->current_state() != STICKY_KEY_STATE_DISABLED ||
182 ctrl_sticky_key_->current_state() != STICKY_KEY_STATE_DISABLED;
183
184 overlay_->Show(enabled_ && key_in_use);
185 }
186
187 StickyKeysOverlay* StickyKeysController::GetOverlayForTest() {
188 return overlay_.get();
164 } 189 }
165 190
166 /////////////////////////////////////////////////////////////////////////////// 191 ///////////////////////////////////////////////////////////////////////////////
167 // StickyKeysHandler 192 // StickyKeysHandler
168 StickyKeysHandler::StickyKeysHandler(ui::EventFlags target_modifier_flag, 193 StickyKeysHandler::StickyKeysHandler(ui::EventFlags modifier_flag,
169 StickyKeysHandlerDelegate* delegate) 194 StickyKeysHandlerDelegate* delegate)
170 : modifier_flag_(target_modifier_flag), 195 : modifier_flag_(modifier_flag),
171 current_state_(DISABLED), 196 current_state_(STICKY_KEY_STATE_DISABLED),
172 event_from_myself_(false), 197 event_from_myself_(false),
173 preparing_to_enable_(false), 198 preparing_to_enable_(false),
174 scroll_delta_(0), 199 scroll_delta_(0),
175 delegate_(delegate) { 200 delegate_(delegate) {
176 } 201 }
177 202
178 StickyKeysHandler::~StickyKeysHandler() { 203 StickyKeysHandler::~StickyKeysHandler() {
179 } 204 }
180 205
181 StickyKeysHandler::StickyKeysHandlerDelegate::StickyKeysHandlerDelegate() { 206 StickyKeysHandler::StickyKeysHandlerDelegate::StickyKeysHandlerDelegate() {
182 } 207 }
183 208
184 StickyKeysHandler::StickyKeysHandlerDelegate::~StickyKeysHandlerDelegate() { 209 StickyKeysHandler::StickyKeysHandlerDelegate::~StickyKeysHandlerDelegate() {
185 } 210 }
186 211
187 bool StickyKeysHandler::HandleKeyEvent(ui::KeyEvent* event) { 212 bool StickyKeysHandler::HandleKeyEvent(ui::KeyEvent* event) {
188 if (event_from_myself_) 213 if (event_from_myself_)
189 return false; // Do not handle self-generated key event. 214 return false; // Do not handle self-generated key event.
190 switch (current_state_) { 215 switch (current_state_) {
191 case DISABLED: 216 case STICKY_KEY_STATE_DISABLED:
192 return HandleDisabledState(event); 217 return HandleDisabledState(event);
193 case ENABLED: 218 case STICKY_KEY_STATE_ENABLED:
194 return HandleEnabledState(event); 219 return HandleEnabledState(event);
195 case LOCKED: 220 case STICKY_KEY_STATE_LOCKED:
196 return HandleLockedState(event); 221 return HandleLockedState(event);
197 } 222 }
198 NOTREACHED(); 223 NOTREACHED();
199 return false; 224 return false;
200 } 225 }
201 226
202 bool StickyKeysHandler::HandleMouseEvent(ui::MouseEvent* event) { 227 bool StickyKeysHandler::HandleMouseEvent(ui::MouseEvent* event) {
203 if (ShouldModifyMouseEvent(event)) 228 if (ShouldModifyMouseEvent(event))
204 preparing_to_enable_ = false; 229 preparing_to_enable_ = false;
205 230
206 if (event_from_myself_ || current_state_ == DISABLED 231 if (event_from_myself_ || current_state_ == STICKY_KEY_STATE_DISABLED
207 || !ShouldModifyMouseEvent(event)) { 232 || !ShouldModifyMouseEvent(event)) {
208 return false; 233 return false;
209 } 234 }
210 DCHECK(current_state_ == ENABLED || current_state_ == LOCKED); 235 DCHECK(current_state_ == STICKY_KEY_STATE_ENABLED ||
236 current_state_ == STICKY_KEY_STATE_LOCKED);
211 237
212 AppendModifier(event); 238 AppendModifier(event);
213 // Only disable on the mouse released event in normal, non-locked mode. 239 // Only disable on the mouse released event in normal, non-locked mode.
214 if (current_state_ == ENABLED && event->type() != ui::ET_MOUSE_PRESSED) { 240 if (current_state_ == STICKY_KEY_STATE_ENABLED &&
215 current_state_ = DISABLED; 241 event->type() != ui::ET_MOUSE_PRESSED) {
242 current_state_ = STICKY_KEY_STATE_DISABLED;
216 DispatchEventAndReleaseModifier(event); 243 DispatchEventAndReleaseModifier(event);
217 return true; 244 return true;
218 } 245 }
219 246
220 return false; 247 return false;
221 } 248 }
222 249
223 bool StickyKeysHandler::HandleScrollEvent(ui::ScrollEvent* event) { 250 bool StickyKeysHandler::HandleScrollEvent(ui::ScrollEvent* event) {
224 preparing_to_enable_ = false; 251 preparing_to_enable_ = false;
225 if (event_from_myself_ || current_state_ == DISABLED) 252 if (event_from_myself_ || current_state_ == STICKY_KEY_STATE_DISABLED)
226 return false; 253 return false;
227 DCHECK(current_state_ == ENABLED || current_state_ == LOCKED); 254 DCHECK(current_state_ == STICKY_KEY_STATE_ENABLED ||
255 current_state_ == STICKY_KEY_STATE_LOCKED);
228 256
229 // We detect a direction change if the current |scroll_delta_| is assigned 257 // We detect a direction change if the current |scroll_delta_| is assigned
230 // and the offset of the current scroll event has the opposing sign. 258 // and the offset of the current scroll event has the opposing sign.
231 bool direction_changed = false; 259 bool direction_changed = false;
232 if (current_state_ == ENABLED && event->type() == ui::ET_SCROLL) { 260 if (current_state_ == STICKY_KEY_STATE_ENABLED &&
261 event->type() == ui::ET_SCROLL) {
233 int offset = event->y_offset(); 262 int offset = event->y_offset();
234 if (scroll_delta_) 263 if (scroll_delta_)
235 direction_changed = offset * scroll_delta_ <= 0; 264 direction_changed = offset * scroll_delta_ <= 0;
236 scroll_delta_ = offset; 265 scroll_delta_ = offset;
237 } 266 }
238 267
239 if (!direction_changed) 268 if (!direction_changed)
240 AppendModifier(event); 269 AppendModifier(event);
241 270
242 // We want to modify all the scroll events in the scroll sequence, which ends 271 // We want to modify all the scroll events in the scroll sequence, which ends
243 // with a fling start event. We also stop when the scroll sequence changes 272 // with a fling start event. We also stop when the scroll sequence changes
244 // direction. 273 // direction.
245 if (current_state_ == ENABLED && 274 if (current_state_ == STICKY_KEY_STATE_ENABLED &&
246 (event->type() == ui::ET_SCROLL_FLING_START || direction_changed)) { 275 (event->type() == ui::ET_SCROLL_FLING_START || direction_changed)) {
247 current_state_ = DISABLED; 276 current_state_ = STICKY_KEY_STATE_DISABLED;
248 scroll_delta_ = 0; 277 scroll_delta_ = 0;
249 DispatchEventAndReleaseModifier(event); 278 DispatchEventAndReleaseModifier(event);
250 return true; 279 return true;
251 } 280 }
252 281
253 return false; 282 return false;
254 } 283 }
255 284
256 StickyKeysHandler::KeyEventType 285 StickyKeysHandler::KeyEventType
257 StickyKeysHandler::TranslateKeyEvent(ui::KeyEvent* event) { 286 StickyKeysHandler::TranslateKeyEvent(ui::KeyEvent* event) {
(...skipping 22 matching lines...) Expand all
280 return event->type() == ui::ET_KEY_PRESSED ? 309 return event->type() == ui::ET_KEY_PRESSED ?
281 OTHER_MODIFIER_DOWN : OTHER_MODIFIER_UP; 310 OTHER_MODIFIER_DOWN : OTHER_MODIFIER_UP;
282 } 311 }
283 312
284 bool StickyKeysHandler::HandleDisabledState(ui::KeyEvent* event) { 313 bool StickyKeysHandler::HandleDisabledState(ui::KeyEvent* event) {
285 switch (TranslateKeyEvent(event)) { 314 switch (TranslateKeyEvent(event)) {
286 case TARGET_MODIFIER_UP: 315 case TARGET_MODIFIER_UP:
287 if (preparing_to_enable_) { 316 if (preparing_to_enable_) {
288 preparing_to_enable_ = false; 317 preparing_to_enable_ = false;
289 scroll_delta_ = 0; 318 scroll_delta_ = 0;
290 current_state_ = ENABLED; 319 current_state_ = STICKY_KEY_STATE_ENABLED;
291 modifier_up_event_.reset(new ui::KeyEvent(*event)); 320 modifier_up_event_.reset(new ui::KeyEvent(*event));
292 return true; 321 return true;
293 } 322 }
294 return false; 323 return false;
295 case TARGET_MODIFIER_DOWN: 324 case TARGET_MODIFIER_DOWN:
296 preparing_to_enable_ = true; 325 preparing_to_enable_ = true;
297 return false; 326 return false;
298 case NORMAL_KEY_DOWN: 327 case NORMAL_KEY_DOWN:
299 preparing_to_enable_ = false; 328 preparing_to_enable_ = false;
300 return false; 329 return false;
301 case NORMAL_KEY_UP: 330 case NORMAL_KEY_UP:
302 case OTHER_MODIFIER_DOWN: 331 case OTHER_MODIFIER_DOWN:
303 case OTHER_MODIFIER_UP: 332 case OTHER_MODIFIER_UP:
304 return false; 333 return false;
305 } 334 }
306 NOTREACHED(); 335 NOTREACHED();
307 return false; 336 return false;
308 } 337 }
309 338
310 bool StickyKeysHandler::HandleEnabledState(ui::KeyEvent* event) { 339 bool StickyKeysHandler::HandleEnabledState(ui::KeyEvent* event) {
311 switch (TranslateKeyEvent(event)) { 340 switch (TranslateKeyEvent(event)) {
312 case NORMAL_KEY_UP: 341 case NORMAL_KEY_UP:
313 case TARGET_MODIFIER_DOWN: 342 case TARGET_MODIFIER_DOWN:
314 return true; 343 return true;
315 case TARGET_MODIFIER_UP: 344 case TARGET_MODIFIER_UP:
316 current_state_ = LOCKED; 345 current_state_ = STICKY_KEY_STATE_LOCKED;
317 modifier_up_event_.reset(); 346 modifier_up_event_.reset();
318 return true; 347 return true;
319 case NORMAL_KEY_DOWN: { 348 case NORMAL_KEY_DOWN: {
320 current_state_ = DISABLED; 349 current_state_ = STICKY_KEY_STATE_DISABLED;
321 AppendModifier(event); 350 AppendModifier(event);
322 DispatchEventAndReleaseModifier(event); 351 DispatchEventAndReleaseModifier(event);
323 return true; 352 return true;
324 } 353 }
325 case OTHER_MODIFIER_DOWN: 354 case OTHER_MODIFIER_DOWN:
326 case OTHER_MODIFIER_UP: 355 case OTHER_MODIFIER_UP:
327 return false; 356 return false;
328 } 357 }
329 NOTREACHED(); 358 NOTREACHED();
330 return false; 359 return false;
331 } 360 }
332 361
333 bool StickyKeysHandler::HandleLockedState(ui::KeyEvent* event) { 362 bool StickyKeysHandler::HandleLockedState(ui::KeyEvent* event) {
334 switch (TranslateKeyEvent(event)) { 363 switch (TranslateKeyEvent(event)) {
335 case TARGET_MODIFIER_DOWN: 364 case TARGET_MODIFIER_DOWN:
336 return true; 365 return true;
337 case TARGET_MODIFIER_UP: 366 case TARGET_MODIFIER_UP:
338 current_state_ = DISABLED; 367 current_state_ = STICKY_KEY_STATE_DISABLED;
339 return false; 368 return false;
340 case NORMAL_KEY_DOWN: 369 case NORMAL_KEY_DOWN:
341 case NORMAL_KEY_UP: 370 case NORMAL_KEY_UP:
342 AppendModifier(event); 371 AppendModifier(event);
343 return false; 372 return false;
344 case OTHER_MODIFIER_DOWN: 373 case OTHER_MODIFIER_DOWN:
345 case OTHER_MODIFIER_UP: 374 case OTHER_MODIFIER_UP:
346 return false; 375 return false;
347 } 376 }
348 NOTREACHED(); 377 NOTREACHED();
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
437 &xievent->mods.effective)); 466 &xievent->mods.effective));
438 } 467 }
439 } 468 }
440 #elif defined(USE_OZONE) 469 #elif defined(USE_OZONE)
441 NOTIMPLEMENTED() << "Modifier key is not handled"; 470 NOTIMPLEMENTED() << "Modifier key is not handled";
442 #endif 471 #endif
443 event->set_flags(event->flags() | modifier_flag_); 472 event->set_flags(event->flags() | modifier_flag_);
444 } 473 }
445 474
446 } // namespace ash 475 } // namespace ash
OLDNEW
« no previous file with comments | « ash/sticky_keys/sticky_keys_controller.h ('k') | ash/sticky_keys/sticky_keys_overlay.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698