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

Side by Side Diff: ui/chromeos/touch_exploration_controller.cc

Issue 2007863004: Fix the double-tap to click gesture in touch accessibility mode. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Add TODO for second display Created 4 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 "ui/chromeos/touch_exploration_controller.h" 5 #include "ui/chromeos/touch_exploration_controller.h"
6 6
7 #include <utility> 7 #include <utility>
8 8
9 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "base/strings/string_number_conversions.h" 10 #include "base/strings/string_number_conversions.h"
(...skipping 19 matching lines...) Expand all
30 const int kSoundDelayInMS = 150; 30 const int kSoundDelayInMS = 150;
31 31
32 } // namespace 32 } // namespace
33 33
34 TouchExplorationController::TouchExplorationController( 34 TouchExplorationController::TouchExplorationController(
35 aura::Window* root_window, 35 aura::Window* root_window,
36 TouchExplorationControllerDelegate* delegate) 36 TouchExplorationControllerDelegate* delegate)
37 : root_window_(root_window), 37 : root_window_(root_window),
38 delegate_(delegate), 38 delegate_(delegate),
39 state_(NO_FINGERS_DOWN), 39 state_(NO_FINGERS_DOWN),
40 anchor_point_state_(ANCHOR_POINT_NONE),
40 gesture_provider_(new GestureProviderAura(this, this)), 41 gesture_provider_(new GestureProviderAura(this, this)),
41 prev_state_(NO_FINGERS_DOWN), 42 prev_state_(NO_FINGERS_DOWN),
42 VLOG_on_(true), 43 VLOG_on_(true),
43 tick_clock_(NULL) { 44 tick_clock_(NULL) {
44 DCHECK(root_window); 45 DCHECK(root_window);
45 root_window->GetHost()->GetEventSource()->AddEventRewriter(this); 46 root_window->GetHost()->GetEventSource()->AddEventRewriter(this);
46 } 47 }
47 48
48 TouchExplorationController::~TouchExplorationController() { 49 TouchExplorationController::~TouchExplorationController() {
49 root_window_->GetHost()->GetEventSource()->RemoveEventRewriter(this); 50 root_window_->GetHost()->GetEventSource()->RemoveEventRewriter(this);
50 } 51 }
51 52
53 void TouchExplorationController::SetTouchAccessibilityAnchorPoint(
54 const gfx::Point& anchor_point) {
55 gfx::Point native_point = anchor_point;
56 root_window_->GetHost()->ConvertPointToNativeScreen(&native_point);
57
58 anchor_point_ = gfx::PointF(native_point.x(), native_point.y());
59 anchor_point_state_ = ANCHOR_POINT_EXPLICITLY_SET;
60 }
61
52 ui::EventRewriteStatus TouchExplorationController::RewriteEvent( 62 ui::EventRewriteStatus TouchExplorationController::RewriteEvent(
53 const ui::Event& event, 63 const ui::Event& event,
54 std::unique_ptr<ui::Event>* rewritten_event) { 64 std::unique_ptr<ui::Event>* rewritten_event) {
55 if (!event.IsTouchEvent()) { 65 if (!event.IsTouchEvent()) {
56 if (event.IsKeyEvent()) { 66 if (event.IsKeyEvent()) {
57 const ui::KeyEvent& key_event = static_cast<const ui::KeyEvent&>(event); 67 const ui::KeyEvent& key_event = static_cast<const ui::KeyEvent&>(event);
58 VLOG(0) << "\nKeyboard event: " << key_event.name() 68 VLOG(0) << "\nKeyboard event: " << key_event.name()
59 << "\n Key code: " << key_event.key_code() 69 << "\n Key code: " << key_event.key_code()
60 << ", Flags: " << key_event.flags() 70 << ", Flags: " << key_event.flags()
61 << ", Is char: " << key_event.is_char(); 71 << ", Is char: " << key_event.is_char();
(...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after
288 SET_STATE(SLIDE_GESTURE); 298 SET_STATE(SLIDE_GESTURE);
289 return InSlideGesture(event, rewritten_event); 299 return InSlideGesture(event, rewritten_event);
290 } 300 }
291 301
292 // If the user moves fast enough from the initial touch location, start 302 // If the user moves fast enough from the initial touch location, start
293 // gesture detection. Otherwise, jump to the touch exploration mode early. 303 // gesture detection. Otherwise, jump to the touch exploration mode early.
294 if (velocity > gesture_detector_config_.minimum_swipe_velocity) { 304 if (velocity > gesture_detector_config_.minimum_swipe_velocity) {
295 SET_STATE(GESTURE_IN_PROGRESS); 305 SET_STATE(GESTURE_IN_PROGRESS);
296 return InGestureInProgress(event, rewritten_event); 306 return InGestureInProgress(event, rewritten_event);
297 } 307 }
308 anchor_point_state_ = ANCHOR_POINT_FROM_TOUCH_EXPLORATION;
298 EnterTouchToMouseMode(); 309 EnterTouchToMouseMode();
299 SET_STATE(TOUCH_EXPLORATION); 310 SET_STATE(TOUCH_EXPLORATION);
300 return InTouchExploration(event, rewritten_event); 311 return InTouchExploration(event, rewritten_event);
301 } 312 }
302 NOTREACHED(); 313 NOTREACHED();
303 return ui::EVENT_REWRITE_CONTINUE; 314 return ui::EVENT_REWRITE_CONTINUE;
304 } 315 }
305 316
306 ui::EventRewriteStatus 317 ui::EventRewriteStatus
307 TouchExplorationController::InSingleTapOrTouchExploreReleased( 318 TouchExplorationController::InSingleTapOrTouchExploreReleased(
308 const ui::TouchEvent& event, 319 const ui::TouchEvent& event,
309 std::unique_ptr<ui::Event>* rewritten_event) { 320 std::unique_ptr<ui::Event>* rewritten_event) {
310 const ui::EventType type = event.type(); 321 const ui::EventType type = event.type();
311 // If there is more than one finger down, then discard to wait until no 322 // If there is more than one finger down, then discard to wait until no
312 // fingers are down. 323 // fingers are down.
313 if (current_touch_ids_.size() > 1) { 324 if (current_touch_ids_.size() > 1) {
314 SET_STATE(WAIT_FOR_NO_FINGERS); 325 SET_STATE(WAIT_FOR_NO_FINGERS);
315 return ui::EVENT_REWRITE_DISCARD; 326 return ui::EVENT_REWRITE_DISCARD;
316 } 327 }
317 if (type == ui::ET_TOUCH_PRESSED) { 328 if (type == ui::ET_TOUCH_PRESSED) {
318 // If there is no touch exploration yet, we can't send a click, so discard. 329 // If there is no anchor point for synthesized events because the
319 if (!last_touch_exploration_) { 330 // user hasn't touch-explored or focused anything yet, we can't
331 // send a click, so discard.
332 if (anchor_point_state_ == ANCHOR_POINT_NONE) {
320 tap_timer_.Stop(); 333 tap_timer_.Stop();
321 return ui::EVENT_REWRITE_DISCARD; 334 return ui::EVENT_REWRITE_DISCARD;
322 } 335 }
323 // This is the second tap in a double-tap (or double tap-hold). 336 // This is the second tap in a double-tap (or double tap-hold).
324 // We set the tap timer. If it fires before the user lifts their finger, 337 // We set the tap timer. If it fires before the user lifts their finger,
325 // one-finger passthrough begins. Otherwise, there is a touch press and 338 // one-finger passthrough begins. Otherwise, there is a touch press and
326 // release at the location of the last touch exploration. 339 // release at the location of the last touch exploration.
327 SET_STATE(DOUBLE_TAP_PENDING); 340 SET_STATE(DOUBLE_TAP_PENDING);
328 // The old tap timer (from the initial click) is stopped if it is still 341 // The old tap timer (from the initial click) is stopped if it is still
329 // going, and the new one is set. 342 // going, and the new one is set.
330 tap_timer_.Stop(); 343 tap_timer_.Stop();
331 StartTapTimer(); 344 StartTapTimer();
332 // This will update as the finger moves before a possible passthrough, and 345 // This will update as the finger moves before a possible passthrough, and
333 // will determine the offset. 346 // will determine the offset.
334 last_unused_finger_event_.reset(new ui::TouchEvent(event)); 347 last_unused_finger_event_.reset(new ui::TouchEvent(event));
335 return ui::EVENT_REWRITE_DISCARD; 348 return ui::EVENT_REWRITE_DISCARD;
336 } else if (type == ui::ET_TOUCH_RELEASED && !last_touch_exploration_) { 349 } else if (type == ui::ET_TOUCH_RELEASED &&
350 anchor_point_state_ == ANCHOR_POINT_NONE) {
337 // If the previous press was discarded, we need to also handle its 351 // If the previous press was discarded, we need to also handle its
338 // release. 352 // release.
339 if (current_touch_ids_.size() == 0) { 353 if (current_touch_ids_.size() == 0) {
340 SET_STATE(NO_FINGERS_DOWN); 354 SET_STATE(NO_FINGERS_DOWN);
341 } 355 }
342 return ui::EVENT_REWRITE_DISCARD; 356 return ui::EVENT_REWRITE_DISCARD;
343 } else if (type == ui::ET_TOUCH_MOVED) { 357 } else if (type == ui::ET_TOUCH_MOVED) {
344 return ui::EVENT_REWRITE_DISCARD; 358 return ui::EVENT_REWRITE_DISCARD;
345 } 359 }
346 NOTREACHED(); 360 NOTREACHED();
(...skipping 12 matching lines...) Expand all
359 float delta = (event.location() - initial_press_->location()).Length(); 373 float delta = (event.location() - initial_press_->location()).Length();
360 if (delta > gesture_detector_config_.touch_slop) { 374 if (delta > gesture_detector_config_.touch_slop) {
361 tap_timer_.Stop(); 375 tap_timer_.Stop();
362 OnTapTimerFired(); 376 OnTapTimerFired();
363 } 377 }
364 return EVENT_REWRITE_DISCARD; 378 return EVENT_REWRITE_DISCARD;
365 } else if (type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) { 379 } else if (type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) {
366 if (current_touch_ids_.size() != 0) 380 if (current_touch_ids_.size() != 0)
367 return EVENT_REWRITE_DISCARD; 381 return EVENT_REWRITE_DISCARD;
368 382
369 std::unique_ptr<ui::TouchEvent> touch_press; 383 SendSimulatedClick();
370 touch_press.reset(new ui::TouchEvent(ui::ET_TOUCH_PRESSED, gfx::Point(),
371 initial_press_->touch_id(),
372 event.time_stamp()));
373 touch_press->set_location_f(last_touch_exploration_->location_f());
374 touch_press->set_root_location_f(last_touch_exploration_->location_f());
375 DispatchEvent(touch_press.get());
376 384
377 std::unique_ptr<ui::TouchEvent> new_event(
378 new ui::TouchEvent(ui::ET_TOUCH_RELEASED, gfx::Point(),
379 initial_press_->touch_id(), event.time_stamp()));
380 new_event->set_location_f(last_touch_exploration_->location_f());
381 new_event->set_root_location_f(last_touch_exploration_->location_f());
382 new_event->set_flags(event.flags());
383 *rewritten_event = std::move(new_event);
384 SET_STATE(NO_FINGERS_DOWN); 385 SET_STATE(NO_FINGERS_DOWN);
385 return ui::EVENT_REWRITE_REWRITTEN; 386 return ui::EVENT_REWRITE_DISCARD;
386 } 387 }
387 NOTREACHED(); 388 NOTREACHED();
388 return ui::EVENT_REWRITE_CONTINUE; 389 return ui::EVENT_REWRITE_CONTINUE;
389 } 390 }
390 391
391 ui::EventRewriteStatus TouchExplorationController::InTouchReleasePending( 392 ui::EventRewriteStatus TouchExplorationController::InTouchReleasePending(
392 const ui::TouchEvent& event, 393 const ui::TouchEvent& event,
393 std::unique_ptr<ui::Event>* rewritten_event) { 394 std::unique_ptr<ui::Event>* rewritten_event) {
394 const ui::EventType type = event.type(); 395 const ui::EventType type = event.type();
395 if (type == ui::ET_TOUCH_PRESSED || type == ui::ET_TOUCH_MOVED) { 396 if (type == ui::ET_TOUCH_PRESSED || type == ui::ET_TOUCH_MOVED) {
396 return ui::EVENT_REWRITE_DISCARD; 397 return ui::EVENT_REWRITE_DISCARD;
397 } else if (type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) { 398 } else if (type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) {
398 if (current_touch_ids_.size() != 0) 399 if (current_touch_ids_.size() != 0)
399 return EVENT_REWRITE_DISCARD; 400 return EVENT_REWRITE_DISCARD;
400 401
401 std::unique_ptr<ui::TouchEvent> new_event( 402 SendSimulatedClick();
402 new ui::TouchEvent(ui::ET_TOUCH_RELEASED, gfx::Point(),
403 initial_press_->touch_id(), event.time_stamp()));
404 new_event->set_location_f(last_touch_exploration_->location_f());
405 new_event->set_root_location_f(last_touch_exploration_->location_f());
406 new_event->set_flags(event.flags());
407 *rewritten_event = std::move(new_event);
408 SET_STATE(NO_FINGERS_DOWN); 403 SET_STATE(NO_FINGERS_DOWN);
409 return ui::EVENT_REWRITE_REWRITTEN; 404 return ui::EVENT_REWRITE_DISCARD;
410 } 405 }
411 NOTREACHED(); 406 NOTREACHED();
412 return ui::EVENT_REWRITE_CONTINUE; 407 return ui::EVENT_REWRITE_CONTINUE;
413 } 408 }
414 409
415 ui::EventRewriteStatus TouchExplorationController::InTouchExploration( 410 ui::EventRewriteStatus TouchExplorationController::InTouchExploration(
416 const ui::TouchEvent& event, 411 const ui::TouchEvent& event,
417 std::unique_ptr<ui::Event>* rewritten_event) { 412 std::unique_ptr<ui::Event>* rewritten_event) {
418 const ui::EventType type = event.type(); 413 const ui::EventType type = event.type();
419 if (type == ui::ET_TOUCH_PRESSED) { 414 if (type == ui::ET_TOUCH_PRESSED) {
420 // Handle split-tap. 415 // Enter split-tap mode.
421 initial_press_.reset(new TouchEvent(event)); 416 initial_press_.reset(new TouchEvent(event));
422 tap_timer_.Stop(); 417 tap_timer_.Stop();
423 std::unique_ptr<ui::TouchEvent> new_event(
424 new ui::TouchEvent(ui::ET_TOUCH_PRESSED, gfx::Point(), event.touch_id(),
425 event.time_stamp()));
426 new_event->set_location_f(last_touch_exploration_->location_f());
427 new_event->set_root_location_f(last_touch_exploration_->location_f());
428 new_event->set_flags(event.flags());
429 *rewritten_event = std::move(new_event);
430 SET_STATE(TOUCH_EXPLORE_SECOND_PRESS); 418 SET_STATE(TOUCH_EXPLORE_SECOND_PRESS);
431 return ui::EVENT_REWRITE_REWRITTEN; 419 return ui::EVENT_REWRITE_DISCARD;
432 } else if (type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) { 420 } else if (type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) {
433 initial_press_.reset(new TouchEvent(event)); 421 initial_press_.reset(new TouchEvent(event));
434 StartTapTimer(); 422 StartTapTimer();
435 SET_STATE(TOUCH_EXPLORE_RELEASED); 423 SET_STATE(TOUCH_EXPLORE_RELEASED);
436 } else if (type != ui::ET_TOUCH_MOVED) { 424 } else if (type != ui::ET_TOUCH_MOVED) {
437 NOTREACHED(); 425 NOTREACHED();
438 return ui::EVENT_REWRITE_CONTINUE; 426 return ui::EVENT_REWRITE_CONTINUE;
439 } 427 }
440 428
441 // Rewrite as a mouse-move event. 429 // Rewrite as a mouse-move event.
442 *rewritten_event = CreateMouseMoveEvent(event.location_f(), event.flags()); 430 *rewritten_event = CreateMouseMoveEvent(event.location_f(), event.flags());
443 last_touch_exploration_.reset(new TouchEvent(event)); 431 last_touch_exploration_.reset(new TouchEvent(event));
432 if (anchor_point_state_ != ANCHOR_POINT_EXPLICITLY_SET)
433 anchor_point_ = last_touch_exploration_->location_f();
434
444 return ui::EVENT_REWRITE_REWRITTEN; 435 return ui::EVENT_REWRITE_REWRITTEN;
445 } 436 }
446 437
447 ui::EventRewriteStatus TouchExplorationController::InGestureInProgress( 438 ui::EventRewriteStatus TouchExplorationController::InGestureInProgress(
448 const ui::TouchEvent& event, 439 const ui::TouchEvent& event,
449 std::unique_ptr<ui::Event>* rewritten_event) { 440 std::unique_ptr<ui::Event>* rewritten_event) {
450 // The events were sent to the gesture provider in RewriteEvent already. 441 // The events were sent to the gesture provider in RewriteEvent already.
451 // If no gesture is registered before the tap timer times out, the state 442 // If no gesture is registered before the tap timer times out, the state
452 // will change to "wait for no fingers down" or "touch exploration" depending 443 // will change to "wait for no fingers down" or "touch exploration" depending
453 // on the number of fingers down, and this function will stop being called. 444 // on the number of fingers down, and this function will stop being called.
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
518 ui::EventType type = event.type(); 509 ui::EventType type = event.type();
519 gfx::PointF location = event.location_f(); 510 gfx::PointF location = event.location_f();
520 if (type == ui::ET_TOUCH_PRESSED) { 511 if (type == ui::ET_TOUCH_PRESSED) {
521 // A third finger being pressed means that a split tap can no longer go 512 // A third finger being pressed means that a split tap can no longer go
522 // through. The user enters the wait state, Since there has already been 513 // through. The user enters the wait state, Since there has already been
523 // a press dispatched when split tap began, the touch needs to be 514 // a press dispatched when split tap began, the touch needs to be
524 // cancelled. 515 // cancelled.
525 std::unique_ptr<ui::TouchEvent> new_event( 516 std::unique_ptr<ui::TouchEvent> new_event(
526 new ui::TouchEvent(ui::ET_TOUCH_CANCELLED, gfx::Point(), 517 new ui::TouchEvent(ui::ET_TOUCH_CANCELLED, gfx::Point(),
527 initial_press_->touch_id(), event.time_stamp())); 518 initial_press_->touch_id(), event.time_stamp()));
528 new_event->set_location_f(last_touch_exploration_->location_f()); 519 // TODO(dmazzoni): fix for multiple displays. http://crbug.com/616793
529 new_event->set_root_location_f(last_touch_exploration_->location_f()); 520 new_event->set_location_f(anchor_point_);
521 new_event->set_root_location_f(anchor_point_);
530 new_event->set_flags(event.flags()); 522 new_event->set_flags(event.flags());
531 *rewritten_event = std::move(new_event); 523 *rewritten_event = std::move(new_event);
532 SET_STATE(WAIT_FOR_NO_FINGERS); 524 SET_STATE(WAIT_FOR_NO_FINGERS);
533 return ui::EVENT_REWRITE_REWRITTEN; 525 return ui::EVENT_REWRITE_REWRITTEN;
534 } else if (type == ui::ET_TOUCH_MOVED) { 526 } else if (type == ui::ET_TOUCH_MOVED) {
535 // If the fingers have moved too far from their original locations, 527 // If the fingers have moved too far from their original locations,
536 // the user can no longer split tap. 528 // the user can no longer split tap.
537 ui::TouchEvent* original_touch; 529 ui::TouchEvent* original_touch;
538 if (event.touch_id() == last_touch_exploration_->touch_id()) { 530 if (event.touch_id() == last_touch_exploration_->touch_id()) {
539 original_touch = last_touch_exploration_.get(); 531 original_touch = last_touch_exploration_.get();
540 } else if (event.touch_id() == initial_press_->touch_id()) { 532 } else if (event.touch_id() == initial_press_->touch_id()) {
541 original_touch = initial_press_.get(); 533 original_touch = initial_press_.get();
542 } else { 534 } else {
543 NOTREACHED(); 535 NOTREACHED();
544 SET_STATE(WAIT_FOR_NO_FINGERS); 536 SET_STATE(WAIT_FOR_NO_FINGERS);
545 return ui::EVENT_REWRITE_DISCARD; 537 return ui::EVENT_REWRITE_DISCARD;
546 } 538 }
547 // Check the distance between the current finger location and the original 539 // Check the distance between the current finger location and the original
548 // location. The slop for this is a bit more generous since keeping two 540 // location. The slop for this is a bit more generous since keeping two
549 // fingers in place is a bit harder. If the user has left the slop, the 541 // fingers in place is a bit harder. If the user has left the slop, the
550 // split tap press (which was previous dispatched) is lifted with a touch 542 // user enters the wait state.
551 // cancelled, and the user enters the wait state.
552 if ((event.location_f() - original_touch->location_f()).Length() > 543 if ((event.location_f() - original_touch->location_f()).Length() >
553 GetSplitTapTouchSlop()) { 544 GetSplitTapTouchSlop()) {
554 std::unique_ptr<ui::TouchEvent> new_event(
555 new ui::TouchEvent(ui::ET_TOUCH_CANCELLED, gfx::Point(),
556 initial_press_->touch_id(), event.time_stamp()));
557 new_event->set_location_f(last_touch_exploration_->location_f());
558 new_event->set_root_location_f(last_touch_exploration_->location_f());
559 new_event->set_flags(event.flags());
560 *rewritten_event = std::move(new_event);
561 SET_STATE(WAIT_FOR_NO_FINGERS); 545 SET_STATE(WAIT_FOR_NO_FINGERS);
562 return ui::EVENT_REWRITE_REWRITTEN;
563 } 546 }
564 return ui::EVENT_REWRITE_DISCARD; 547 return ui::EVENT_REWRITE_DISCARD;
565 } else if (type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) { 548 } else if (type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) {
566 // If the touch exploration finger is lifted, there is no option to return 549 // If the touch exploration finger is lifted, there is no option to return
567 // to touch explore anymore. The remaining finger acts as a pending 550 // to touch explore anymore. The remaining finger acts as a pending
568 // tap or long tap for the last touch explore location. 551 // tap or long tap for the last touch explore location.
569 if (event.touch_id() == last_touch_exploration_->touch_id()) { 552 if (event.touch_id() == last_touch_exploration_->touch_id()) {
570 SET_STATE(TOUCH_RELEASE_PENDING); 553 SET_STATE(TOUCH_RELEASE_PENDING);
571 return EVENT_REWRITE_DISCARD; 554 return EVENT_REWRITE_DISCARD;
572 } 555 }
573 556
574 // Continue to release the touch only if the touch explore finger is the 557 // Continue to release the touch only if the touch explore finger is the
575 // only finger remaining. 558 // only finger remaining.
576 if (current_touch_ids_.size() != 1) 559 if (current_touch_ids_.size() != 1)
577 return EVENT_REWRITE_DISCARD; 560 return EVENT_REWRITE_DISCARD;
578 561
579 // Rewrite at location of last touch exploration. 562 SendSimulatedClick();
580 std::unique_ptr<ui::TouchEvent> new_event( 563
581 new ui::TouchEvent(ui::ET_TOUCH_RELEASED, gfx::Point(),
582 initial_press_->touch_id(), event.time_stamp()));
583 new_event->set_location_f(last_touch_exploration_->location_f());
584 new_event->set_root_location_f(last_touch_exploration_->location_f());
585 new_event->set_flags(event.flags());
586 *rewritten_event = std::move(new_event);
587 SET_STATE(TOUCH_EXPLORATION); 564 SET_STATE(TOUCH_EXPLORATION);
588 EnterTouchToMouseMode(); 565 EnterTouchToMouseMode();
589 return ui::EVENT_REWRITE_REWRITTEN; 566 return ui::EVENT_REWRITE_DISCARD;
590 } 567 }
591 NOTREACHED(); 568 NOTREACHED();
592 return ui::EVENT_REWRITE_CONTINUE; 569 return ui::EVENT_REWRITE_CONTINUE;
593 } 570 }
594 571
595 ui::EventRewriteStatus TouchExplorationController::InWaitForNoFingers( 572 ui::EventRewriteStatus TouchExplorationController::InWaitForNoFingers(
596 const ui::TouchEvent& event, 573 const ui::TouchEvent& event,
597 std::unique_ptr<ui::Event>* rewritten_event) { 574 std::unique_ptr<ui::Event>* rewritten_event) {
598 if (current_touch_ids_.size() == 0) 575 if (current_touch_ids_.size() == 0)
599 SET_STATE(NO_FINGERS_DOWN); 576 SET_STATE(NO_FINGERS_DOWN);
600 return EVENT_REWRITE_DISCARD; 577 return EVENT_REWRITE_DISCARD;
601 } 578 }
602 579
603 void TouchExplorationController::PlaySoundForTimer() { 580 void TouchExplorationController::PlaySoundForTimer() {
604 delegate_->PlayVolumeAdjustEarcon(); 581 delegate_->PlayVolumeAdjustEarcon();
605 } 582 }
606 583
584 void TouchExplorationController::SendSimulatedClick() {
585 // If we got an anchor point from ChromeVox, send a double-tap gesture
586 // and let ChromeVox handle the click.
587 if (anchor_point_state_ == ANCHOR_POINT_EXPLICITLY_SET) {
588 delegate_->HandleAccessibilityGesture(ui::AX_GESTURE_CLICK);
589 return;
590 }
591
592 // If we don't have an anchor point, we can't send a simulated click.
593 if (anchor_point_state_ == ANCHOR_POINT_NONE)
594 return;
595
596 // Otherwise send a simulated press/release at the anchor point.
597 std::unique_ptr<ui::TouchEvent> touch_press;
598 touch_press.reset(new ui::TouchEvent(ui::ET_TOUCH_PRESSED, gfx::Point(),
599 initial_press_->touch_id(), Now()));
600 touch_press->set_location_f(anchor_point_);
601 touch_press->set_root_location_f(anchor_point_);
602 DispatchEvent(touch_press.get());
603
604 std::unique_ptr<ui::TouchEvent> touch_release;
605 touch_release.reset(new ui::TouchEvent(ui::ET_TOUCH_RELEASED, gfx::Point(),
606 initial_press_->touch_id(), Now()));
607 touch_release->set_location_f(anchor_point_);
608 touch_release->set_root_location_f(anchor_point_);
609 DispatchEvent(touch_release.get());
610 }
611
607 ui::EventRewriteStatus TouchExplorationController::InSlideGesture( 612 ui::EventRewriteStatus TouchExplorationController::InSlideGesture(
608 const ui::TouchEvent& event, 613 const ui::TouchEvent& event,
609 std::unique_ptr<ui::Event>* rewritten_event) { 614 std::unique_ptr<ui::Event>* rewritten_event) {
610 // The timer should not fire when sliding. 615 // The timer should not fire when sliding.
611 tap_timer_.Stop(); 616 tap_timer_.Stop();
612 617
613 ui::EventType type = event.type(); 618 ui::EventType type = event.type();
614 // If additional fingers are added before a swipe gesture has been registered, 619 // If additional fingers are added before a swipe gesture has been registered,
615 // then wait until all fingers have been lifted. 620 // then wait until all fingers have been lifted.
616 if (type == ui::ET_TOUCH_PRESSED || 621 if (type == ui::ET_TOUCH_PRESSED ||
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
706 } 711 }
707 712
708 void TouchExplorationController::OnTapTimerFired() { 713 void TouchExplorationController::OnTapTimerFired() {
709 switch (state_) { 714 switch (state_) {
710 case SINGLE_TAP_RELEASED: 715 case SINGLE_TAP_RELEASED:
711 SET_STATE(NO_FINGERS_DOWN); 716 SET_STATE(NO_FINGERS_DOWN);
712 break; 717 break;
713 case TOUCH_EXPLORE_RELEASED: 718 case TOUCH_EXPLORE_RELEASED:
714 SET_STATE(NO_FINGERS_DOWN); 719 SET_STATE(NO_FINGERS_DOWN);
715 last_touch_exploration_.reset(new TouchEvent(*initial_press_)); 720 last_touch_exploration_.reset(new TouchEvent(*initial_press_));
721 anchor_point_ = last_touch_exploration_->location_f();
722 anchor_point_state_ = ANCHOR_POINT_FROM_TOUCH_EXPLORATION;
716 return; 723 return;
717 case DOUBLE_TAP_PENDING: { 724 case DOUBLE_TAP_PENDING: {
718 SET_STATE(ONE_FINGER_PASSTHROUGH); 725 SET_STATE(ONE_FINGER_PASSTHROUGH);
719 passthrough_offset_ = last_unused_finger_event_->location_f() - 726 passthrough_offset_ =
720 last_touch_exploration_->location_f(); 727 last_unused_finger_event_->location_f() - anchor_point_;
721 std::unique_ptr<ui::TouchEvent> passthrough_press( 728 std::unique_ptr<ui::TouchEvent> passthrough_press(
722 new ui::TouchEvent(ui::ET_TOUCH_PRESSED, gfx::Point(), 729 new ui::TouchEvent(ui::ET_TOUCH_PRESSED, gfx::Point(),
723 last_unused_finger_event_->touch_id(), Now())); 730 last_unused_finger_event_->touch_id(), Now()));
724 passthrough_press->set_location_f(last_touch_exploration_->location_f()); 731 passthrough_press->set_location_f(anchor_point_);
725 passthrough_press->set_root_location_f( 732 passthrough_press->set_root_location_f(anchor_point_);
726 last_touch_exploration_->location_f());
727 DispatchEvent(passthrough_press.get()); 733 DispatchEvent(passthrough_press.get());
728 return; 734 return;
729 } 735 }
730 case SINGLE_TAP_PRESSED: 736 case SINGLE_TAP_PRESSED:
731 if (passthrough_timer_.IsRunning()) 737 if (passthrough_timer_.IsRunning())
732 return; 738 return;
733 case GESTURE_IN_PROGRESS: 739 case GESTURE_IN_PROGRESS:
734 // If only one finger is down, go into touch exploration. 740 // If only one finger is down, go into touch exploration.
735 if (current_touch_ids_.size() == 1) { 741 if (current_touch_ids_.size() == 1) {
742 anchor_point_state_ = ANCHOR_POINT_FROM_TOUCH_EXPLORATION;
736 EnterTouchToMouseMode(); 743 EnterTouchToMouseMode();
737 SET_STATE(TOUCH_EXPLORATION); 744 SET_STATE(TOUCH_EXPLORATION);
738 break; 745 break;
739 } 746 }
740 // Otherwise wait for all fingers to be lifted. 747 // Otherwise wait for all fingers to be lifted.
741 SET_STATE(WAIT_FOR_NO_FINGERS); 748 SET_STATE(WAIT_FOR_NO_FINGERS);
742 return; 749 return;
743 case TWO_FINGER_TAP: 750 case TWO_FINGER_TAP:
744 SET_STATE(WAIT_FOR_NO_FINGERS); 751 SET_STATE(WAIT_FOR_NO_FINGERS);
745 break; 752 break;
746 default: 753 default:
747 return; 754 return;
748 } 755 }
749 EnterTouchToMouseMode(); 756 EnterTouchToMouseMode();
750 std::unique_ptr<ui::Event> mouse_move = CreateMouseMoveEvent( 757 std::unique_ptr<ui::Event> mouse_move = CreateMouseMoveEvent(
751 initial_press_->location_f(), initial_press_->flags()); 758 initial_press_->location_f(), initial_press_->flags());
752 DispatchEvent(mouse_move.get()); 759 DispatchEvent(mouse_move.get());
753 last_touch_exploration_.reset(new TouchEvent(*initial_press_)); 760 last_touch_exploration_.reset(new TouchEvent(*initial_press_));
761 anchor_point_ = last_touch_exploration_->location_f();
762 anchor_point_state_ = ANCHOR_POINT_FROM_TOUCH_EXPLORATION;
754 } 763 }
755 764
756 void TouchExplorationController::OnPassthroughTimerFired() { 765 void TouchExplorationController::OnPassthroughTimerFired() {
757 // The passthrough timer will only fire if if the user has held a finger in 766 // The passthrough timer will only fire if if the user has held a finger in
758 // one of the passthrough corners for the duration of the passthrough timeout. 767 // one of the passthrough corners for the duration of the passthrough timeout.
759 768
760 // Check that initial press isn't null. Also a check that if the initial 769 // Check that initial press isn't null. Also a check that if the initial
761 // corner press was released, then it should not be in corner passthrough. 770 // corner press was released, then it should not be in corner passthrough.
762 if (!initial_press_ || 771 if (!initial_press_ ||
763 touch_locations_.find(initial_press_->touch_id()) != 772 touch_locations_.find(initial_press_->touch_id()) !=
764 touch_locations_.end()) { 773 touch_locations_.end()) {
765 LOG(ERROR) << "No initial press or the initial press has been released.";
766 } 774 }
767 775
768 gfx::Point location = 776 gfx::Point location =
769 ToRoundedPoint(touch_locations_[initial_press_->touch_id()]); 777 ToRoundedPoint(touch_locations_[initial_press_->touch_id()]);
770 int corner = FindEdgesWithinBounds(location, kSlopDistanceFromEdge); 778 int corner = FindEdgesWithinBounds(location, kSlopDistanceFromEdge);
771 if (corner != BOTTOM_LEFT_CORNER && corner != BOTTOM_RIGHT_CORNER) 779 if (corner != BOTTOM_LEFT_CORNER && corner != BOTTOM_RIGHT_CORNER)
772 return; 780 return;
773 781
774 if (sound_timer_.IsRunning()) 782 if (sound_timer_.IsRunning())
775 sound_timer_.Stop(); 783 sound_timer_.Stop();
(...skipping 366 matching lines...) Expand 10 before | Expand all | Expand 10 after
1142 return "TWO_FINGER_TAP"; 1150 return "TWO_FINGER_TAP";
1143 } 1151 }
1144 return "Not a state"; 1152 return "Not a state";
1145 } 1153 }
1146 1154
1147 float TouchExplorationController::GetSplitTapTouchSlop() { 1155 float TouchExplorationController::GetSplitTapTouchSlop() {
1148 return gesture_detector_config_.touch_slop * 3; 1156 return gesture_detector_config_.touch_slop * 3;
1149 } 1157 }
1150 1158
1151 } // namespace ui 1159 } // namespace ui
OLDNEW
« no previous file with comments | « ui/chromeos/touch_exploration_controller.h ('k') | ui/chromeos/touch_exploration_controller_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698