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

Side by Side Diff: chrome/browser/chromeos/events/event_rewriter.cc

Issue 255033003: Convert sticky keys to a chromeos::EventRewriter phase. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@x354034-er
Patch Set: address review comments Created 6 years, 6 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 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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 "chrome/browser/chromeos/events/event_rewriter.h" 5 #include "chrome/browser/chromeos/events/event_rewriter.h"
6 6
7 #include <vector> 7 #include <vector>
8 8
9 #include "ash/sticky_keys/sticky_keys_controller.h"
9 #include "ash/wm/window_state.h" 10 #include "ash/wm/window_state.h"
10 #include "ash/wm/window_util.h" 11 #include "ash/wm/window_util.h"
11 #include "base/command_line.h" 12 #include "base/command_line.h"
12 #include "base/logging.h" 13 #include "base/logging.h"
14 #include "base/macros.h"
13 #include "base/prefs/pref_service.h" 15 #include "base/prefs/pref_service.h"
14 #include "base/strings/string_util.h" 16 #include "base/strings/string_util.h"
15 #include "base/sys_info.h" 17 #include "base/sys_info.h"
16 #include "chrome/browser/chromeos/login/ui/login_display_host_impl.h" 18 #include "chrome/browser/chromeos/login/ui/login_display_host_impl.h"
17 #include "chrome/browser/chromeos/login/users/user_manager.h" 19 #include "chrome/browser/chromeos/login/users/user_manager.h"
18 #include "chrome/browser/profiles/profile_manager.h" 20 #include "chrome/browser/profiles/profile_manager.h"
19 #include "chrome/common/pref_names.h" 21 #include "chrome/common/pref_names.h"
20 #include "chromeos/chromeos_switches.h" 22 #include "chromeos/chromeos_switches.h"
21 #include "chromeos/ime/ime_keyboard.h" 23 #include "chromeos/ime/ime_keyboard.h"
22 #include "chromeos/ime/input_method_manager.h" 24 #include "chromeos/ime/input_method_manager.h"
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after
148 if (ui_flags & flags[i].ui) 150 if (ui_flags & flags[i].ui)
149 *x_flags |= flags[i].x; 151 *x_flags |= flags[i].x;
150 else 152 else
151 *x_flags &= ~flags[i].x; 153 *x_flags &= ~flags[i].x;
152 } 154 }
153 } 155 }
154 #endif 156 #endif
155 157
156 } // namespace 158 } // namespace
157 159
158 EventRewriter::EventRewriter() 160 EventRewriter::EventRewriter(ash::StickyKeysController* sticky_keys_controller)
159 : last_device_id_(kBadDeviceId), 161 : last_device_id_(kBadDeviceId),
160 ime_keyboard_for_testing_(NULL), 162 ime_keyboard_for_testing_(NULL),
161 pref_service_for_testing_(NULL) { 163 pref_service_for_testing_(NULL),
164 sticky_keys_controller_(sticky_keys_controller) {
162 #if defined(USE_X11) 165 #if defined(USE_X11)
163 ui::PlatformEventSource::GetInstance()->AddPlatformEventObserver(this); 166 ui::PlatformEventSource::GetInstance()->AddPlatformEventObserver(this);
164 if (base::SysInfo::IsRunningOnChromeOS()) { 167 if (base::SysInfo::IsRunningOnChromeOS()) {
165 XInputHierarchyChangedEventListener::GetInstance()->AddObserver(this); 168 XInputHierarchyChangedEventListener::GetInstance()->AddObserver(this);
166 } 169 }
167 #endif 170 #endif
168 } 171 }
169 172
170 EventRewriter::~EventRewriter() { 173 EventRewriter::~EventRewriter() {
171 #if defined(USE_X11) 174 #if defined(USE_X11)
(...skipping 18 matching lines...) Expand all
190 ui::EventRewriteStatus EventRewriter::RewriteEvent( 193 ui::EventRewriteStatus EventRewriter::RewriteEvent(
191 const ui::Event& event, 194 const ui::Event& event,
192 scoped_ptr<ui::Event>* rewritten_event) { 195 scoped_ptr<ui::Event>* rewritten_event) {
193 #if defined(USE_X11) 196 #if defined(USE_X11)
194 // Do not rewrite an event sent by ui_controls::SendKeyPress(). See 197 // Do not rewrite an event sent by ui_controls::SendKeyPress(). See
195 // crbug.com/136465. 198 // crbug.com/136465.
196 XEvent* xev = event.native_event(); 199 XEvent* xev = event.native_event();
197 if (xev && xev->xany.send_event) 200 if (xev && xev->xany.send_event)
198 return ui::EVENT_REWRITE_CONTINUE; 201 return ui::EVENT_REWRITE_CONTINUE;
199 #endif 202 #endif
200 switch (event.type()) { 203 if ((event.type() == ui::ET_KEY_PRESSED) ||
201 case ui::ET_KEY_PRESSED: 204 (event.type() == ui::ET_KEY_RELEASED)) {
202 case ui::ET_KEY_RELEASED: 205 return RewriteKeyEvent(static_cast<const ui::KeyEvent&>(event),
203 return RewriteKeyEvent(static_cast<const ui::KeyEvent&>(event), 206 rewritten_event);
207 }
208 if (event.IsMouseEvent()) {
209 return RewriteMouseEvent(static_cast<const ui::MouseEvent&>(event),
204 rewritten_event); 210 rewritten_event);
205 case ui::ET_MOUSE_PRESSED:
206 case ui::ET_MOUSE_RELEASED:
207 return RewriteMouseEvent(static_cast<const ui::MouseEvent&>(event),
208 rewritten_event);
209 case ui::ET_TOUCH_PRESSED:
210 case ui::ET_TOUCH_RELEASED:
211 return RewriteTouchEvent(static_cast<const ui::TouchEvent&>(event),
212 rewritten_event);
213 default:
214 return ui::EVENT_REWRITE_CONTINUE;
215 } 211 }
216 NOTREACHED(); 212 if ((event.type() == ui::ET_TOUCH_PRESSED) ||
213 (event.type() == ui::ET_TOUCH_RELEASED)) {
214 return RewriteTouchEvent(static_cast<const ui::TouchEvent&>(event),
215 rewritten_event);
216 }
217 if (event.IsScrollEvent()) {
218 return RewriteScrollEvent(static_cast<const ui::ScrollEvent&>(event),
219 rewritten_event);
220 }
221 return ui::EVENT_REWRITE_CONTINUE;
217 } 222 }
218 223
219 ui::EventRewriteStatus EventRewriter::NextDispatchEvent( 224 ui::EventRewriteStatus EventRewriter::NextDispatchEvent(
220 const ui::Event& last_event, 225 const ui::Event& last_event,
221 scoped_ptr<ui::Event>* new_event) { 226 scoped_ptr<ui::Event>* new_event) {
227 if (sticky_keys_controller_) {
228 // In the case of sticky keys, we know what the events obtained here are:
229 // modifier key releases that match the ones previously discarded. So, we
230 // know that they don't have to be passed through the post-sticky key
231 // rewriting phases, |RewriteExtendedKeys()| and |RewriteFunctionKeys()|,
232 // because those phases do nothing with modifier key releases.
233 return sticky_keys_controller_->NextDispatchEvent(new_event);
234 }
222 NOTREACHED(); 235 NOTREACHED();
223 return ui::EVENT_REWRITE_CONTINUE; 236 return ui::EVENT_REWRITE_CONTINUE;
224 } 237 }
225 238
226 #if defined(USE_X11) 239 #if defined(USE_X11)
227 void EventRewriter::DeviceKeyPressedOrReleased(int device_id) { 240 void EventRewriter::DeviceKeyPressedOrReleased(int device_id) {
228 if (!device_id_to_type_.count(device_id)) { 241 if (!device_id_to_type_.count(device_id)) {
229 // |device_id| is unknown. This means the device was connected before 242 // |device_id| is unknown. This means the device was connected before
230 // booting the OS. Query the name of the device and add it to the map. 243 // booting the OS. Query the name of the device and add it to the map.
231 DeviceAdded(device_id); 244 DeviceAdded(device_id);
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
328 } 341 }
329 return false; 342 return false;
330 } 343 }
331 344
332 ui::EventRewriteStatus EventRewriter::RewriteKeyEvent( 345 ui::EventRewriteStatus EventRewriter::RewriteKeyEvent(
333 const ui::KeyEvent& key_event, 346 const ui::KeyEvent& key_event,
334 scoped_ptr<ui::Event>* rewritten_event) { 347 scoped_ptr<ui::Event>* rewritten_event) {
335 MutableKeyState state = {key_event.flags(), key_event.key_code()}; 348 MutableKeyState state = {key_event.flags(), key_event.key_code()};
336 RewriteModifierKeys(key_event, &state); 349 RewriteModifierKeys(key_event, &state);
337 RewriteNumPadKeys(key_event, &state); 350 RewriteNumPadKeys(key_event, &state);
351 ui::EventRewriteStatus status = ui::EVENT_REWRITE_CONTINUE;
352 if (sticky_keys_controller_) {
353 status = sticky_keys_controller_->RewriteKeyEvent(
354 key_event, state.key_code, &state.flags);
355 if (status == ui::EVENT_REWRITE_DISCARD)
356 return ui::EVENT_REWRITE_DISCARD;
357 }
338 RewriteExtendedKeys(key_event, &state); 358 RewriteExtendedKeys(key_event, &state);
339 RewriteFunctionKeys(key_event, &state); 359 RewriteFunctionKeys(key_event, &state);
340 if ((key_event.flags() == state.flags) && 360 if ((key_event.flags() == state.flags) &&
341 (key_event.key_code() == state.key_code)) { 361 (key_event.key_code() == state.key_code) &&
362 (status == ui::EVENT_REWRITE_CONTINUE)) {
342 return ui::EVENT_REWRITE_CONTINUE; 363 return ui::EVENT_REWRITE_CONTINUE;
343 } 364 }
365 if (status == ui::EVENT_REWRITE_CONTINUE)
366 status = ui::EVENT_REWRITE_REWRITTEN;
sadrul 2014/06/16 15:07:43 Add a comment here why.
kpschoedel 2014/06/16 15:29:28 Done.
344 ui::KeyEvent* rewritten_key_event = new ui::KeyEvent(key_event); 367 ui::KeyEvent* rewritten_key_event = new ui::KeyEvent(key_event);
345 rewritten_event->reset(rewritten_key_event); 368 rewritten_event->reset(rewritten_key_event);
346 rewritten_key_event->set_flags(state.flags); 369 rewritten_key_event->set_flags(state.flags);
347 rewritten_key_event->set_key_code(state.key_code); 370 rewritten_key_event->set_key_code(state.key_code);
348 rewritten_key_event->set_character( 371 rewritten_key_event->set_character(
349 ui::GetCharacterFromKeyCode(state.key_code, state.flags)); 372 ui::GetCharacterFromKeyCode(state.key_code, state.flags));
350 rewritten_key_event->NormalizeFlags(); 373 rewritten_key_event->NormalizeFlags();
351 #if defined(USE_X11) 374 #if defined(USE_X11)
352 XEvent* xev = rewritten_key_event->native_event(); 375 XEvent* xev = rewritten_key_event->native_event();
353 if (xev) { 376 if (xev) {
354 CHECK(xev->type == KeyPress || xev->type == KeyRelease); 377 CHECK(xev->type == KeyPress || xev->type == KeyRelease);
355 XKeyEvent* xkey = &(xev->xkey); 378 XKeyEvent* xkey = &(xev->xkey);
356 UpdateX11EventMask(rewritten_key_event->flags(), &xkey->state); 379 UpdateX11EventMask(rewritten_key_event->flags(), &xkey->state);
357 xkey->keycode = 380 xkey->keycode =
358 XKeysymToKeycode(gfx::GetXDisplay(), 381 XKeysymToKeycode(gfx::GetXDisplay(),
359 ui::XKeysymForWindowsKeyCode( 382 ui::XKeysymForWindowsKeyCode(
360 state.key_code, state.flags & ui::EF_SHIFT_DOWN)); 383 state.key_code, state.flags & ui::EF_SHIFT_DOWN));
361 } 384 }
362 #endif 385 #endif
363 return ui::EVENT_REWRITE_REWRITTEN; 386 return status;
364 } 387 }
365 388
366 ui::EventRewriteStatus EventRewriter::RewriteMouseEvent( 389 ui::EventRewriteStatus EventRewriter::RewriteMouseEvent(
367 const ui::MouseEvent& mouse_event, 390 const ui::MouseEvent& mouse_event,
368 scoped_ptr<ui::Event>* rewritten_event) { 391 scoped_ptr<ui::Event>* rewritten_event) {
369 int flags = mouse_event.flags(); 392 int flags = mouse_event.flags();
370 RewriteLocatedEvent(mouse_event, &flags); 393 if ((mouse_event.type() == ui::ET_MOUSE_PRESSED) ||
371 if (mouse_event.flags() == flags) 394 (mouse_event.type() == ui::ET_MOUSE_RELEASED)) {
395 RewriteLocatedEvent(mouse_event, &flags);
396 }
397 ui::EventRewriteStatus status = ui::EVENT_REWRITE_CONTINUE;
398 if (sticky_keys_controller_)
399 status = sticky_keys_controller_->RewriteMouseEvent(mouse_event, &flags);
400 if ((mouse_event.flags() == flags) &&
401 (status == ui::EVENT_REWRITE_CONTINUE)) {
372 return ui::EVENT_REWRITE_CONTINUE; 402 return ui::EVENT_REWRITE_CONTINUE;
403 }
404 if (status == ui::EVENT_REWRITE_CONTINUE)
405 status = ui::EVENT_REWRITE_REWRITTEN;
373 ui::MouseEvent* rewritten_mouse_event = new ui::MouseEvent(mouse_event); 406 ui::MouseEvent* rewritten_mouse_event = new ui::MouseEvent(mouse_event);
374 rewritten_event->reset(rewritten_mouse_event); 407 rewritten_event->reset(rewritten_mouse_event);
375 rewritten_mouse_event->set_flags(flags); 408 rewritten_mouse_event->set_flags(flags);
376 #if defined(USE_X11) 409 #if defined(USE_X11)
377 XEvent* xev = rewritten_mouse_event->native_event(); 410 XEvent* xev = rewritten_mouse_event->native_event();
378 if (xev) { 411 if (xev) {
379 switch (xev->type) { 412 switch (xev->type) {
380 case ButtonPress: 413 case ButtonPress:
381 case ButtonRelease: { 414 case ButtonRelease: {
382 XButtonEvent* xbutton = &(xev->xbutton); 415 XButtonEvent* xbutton = &(xev->xbutton);
383 UpdateX11EventMask(rewritten_mouse_event->flags(), &xbutton->state); 416 UpdateX11EventMask(rewritten_mouse_event->flags(), &xbutton->state);
384 break; 417 break;
385 } 418 }
386 case GenericEvent: { 419 case GenericEvent: {
387 XIDeviceEvent* xievent = static_cast<XIDeviceEvent*>(xev->xcookie.data); 420 XIDeviceEvent* xievent = static_cast<XIDeviceEvent*>(xev->xcookie.data);
388 CHECK(xievent->evtype == XI_ButtonPress || 421 CHECK(xievent->evtype == XI_ButtonPress ||
389 xievent->evtype == XI_ButtonRelease); 422 xievent->evtype == XI_ButtonRelease);
390 UpdateX11EventMask( 423 UpdateX11EventMask(
391 rewritten_mouse_event->flags(), 424 rewritten_mouse_event->flags(),
392 reinterpret_cast<unsigned int*>(&xievent->mods.effective)); 425 reinterpret_cast<unsigned int*>(&xievent->mods.effective));
393 break; 426 break;
394 } 427 }
395 default: 428 default:
396 NOTREACHED(); 429 NOTREACHED();
397 } 430 }
398 } 431 }
399 #endif 432 #endif
400 return ui::EVENT_REWRITE_REWRITTEN; 433 return status;
401 } 434 }
402 435
403 ui::EventRewriteStatus EventRewriter::RewriteTouchEvent( 436 ui::EventRewriteStatus EventRewriter::RewriteTouchEvent(
404 const ui::TouchEvent& touch_event, 437 const ui::TouchEvent& touch_event,
405 scoped_ptr<ui::Event>* rewritten_event) { 438 scoped_ptr<ui::Event>* rewritten_event) {
406 int flags = touch_event.flags(); 439 int flags = touch_event.flags();
407 RewriteLocatedEvent(touch_event, &flags); 440 RewriteLocatedEvent(touch_event, &flags);
408 if (touch_event.flags() == flags) 441 if (touch_event.flags() == flags)
409 return ui::EVENT_REWRITE_CONTINUE; 442 return ui::EVENT_REWRITE_CONTINUE;
410 ui::TouchEvent* rewritten_touch_event = new ui::TouchEvent(touch_event); 443 ui::TouchEvent* rewritten_touch_event = new ui::TouchEvent(touch_event);
411 rewritten_event->reset(rewritten_touch_event); 444 rewritten_event->reset(rewritten_touch_event);
412 rewritten_touch_event->set_flags(flags); 445 rewritten_touch_event->set_flags(flags);
413 #if defined(USE_X11) 446 #if defined(USE_X11)
414 XEvent* xev = rewritten_touch_event->native_event(); 447 XEvent* xev = rewritten_touch_event->native_event();
415 if (xev) { 448 if (xev) {
416 XIDeviceEvent* xievent = static_cast<XIDeviceEvent*>(xev->xcookie.data); 449 XIDeviceEvent* xievent = static_cast<XIDeviceEvent*>(xev->xcookie.data);
417 if (xievent) { 450 if (xievent) {
418 UpdateX11EventMask( 451 UpdateX11EventMask(
419 rewritten_touch_event->flags(), 452 rewritten_touch_event->flags(),
420 reinterpret_cast<unsigned int*>(&xievent->mods.effective)); 453 reinterpret_cast<unsigned int*>(&xievent->mods.effective));
421 } 454 }
422 } 455 }
423 #endif 456 #endif
424 return ui::EVENT_REWRITE_REWRITTEN; 457 return ui::EVENT_REWRITE_REWRITTEN;
425 } 458 }
426 459
460 ui::EventRewriteStatus EventRewriter::RewriteScrollEvent(
461 const ui::ScrollEvent& scroll_event,
462 scoped_ptr<ui::Event>* rewritten_event) {
463 int flags = scroll_event.flags();
464 ui::EventRewriteStatus status = ui::EVENT_REWRITE_CONTINUE;
465 if (sticky_keys_controller_)
466 status = sticky_keys_controller_->RewriteScrollEvent(scroll_event, &flags);
467 if (status == ui::EVENT_REWRITE_CONTINUE)
468 return status;
469 ui::ScrollEvent* rewritten_scroll_event = new ui::ScrollEvent(scroll_event);
470 rewritten_event->reset(rewritten_scroll_event);
471 rewritten_scroll_event->set_flags(flags);
472 #if defined(USE_X11)
473 XEvent* xev = rewritten_scroll_event->native_event();
474 if (xev) {
475 XIDeviceEvent* xievent = static_cast<XIDeviceEvent*>(xev->xcookie.data);
476 if (xievent) {
477 UpdateX11EventMask(
478 rewritten_scroll_event->flags(),
479 reinterpret_cast<unsigned int*>(&xievent->mods.effective));
480 }
481 }
482 #endif
483 return status;
484 }
485
427 void EventRewriter::RewriteModifierKeys(const ui::KeyEvent& key_event, 486 void EventRewriter::RewriteModifierKeys(const ui::KeyEvent& key_event,
428 MutableKeyState* state) { 487 MutableKeyState* state) {
429 DCHECK(key_event.type() == ui::ET_KEY_PRESSED || 488 DCHECK(key_event.type() == ui::ET_KEY_PRESSED ||
430 key_event.type() == ui::ET_KEY_RELEASED); 489 key_event.type() == ui::ET_KEY_RELEASED);
431 490
432 // Do nothing if we have just logged in as guest but have not restarted chrome 491 // Do nothing if we have just logged in as guest but have not restarted chrome
433 // process yet (so we are still on the login screen). In this situations we 492 // process yet (so we are still on the login screen). In this situations we
434 // have no user profile so can not do anything useful. 493 // have no user profile so can not do anything useful.
435 // Note that currently, unlike other accounts, when user logs in as guest, we 494 // Note that currently, unlike other accounts, when user logs in as guest, we
436 // restart chrome process. In future this is to be changed. 495 // restart chrome process. In future this is to be changed.
(...skipping 377 matching lines...) Expand 10 before | Expand all | Expand 10 after
814 873
815 XIFreeDeviceInfo(device_info); 874 XIFreeDeviceInfo(device_info);
816 } 875 }
817 876
818 void EventRewriter::DeviceRemoved(int device_id) { 877 void EventRewriter::DeviceRemoved(int device_id) {
819 device_id_to_type_.erase(device_id); 878 device_id_to_type_.erase(device_id);
820 } 879 }
821 #endif 880 #endif
822 881
823 } // namespace chromeos 882 } // namespace chromeos
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698