Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 "base/logging.h" | 7 #include "base/logging.h" |
| 8 #include "base/strings/string_number_conversions.h" | 8 #include "base/strings/string_number_conversions.h" |
| 9 #include "base/time/default_tick_clock.h" | |
| 9 #include "ui/aura/client/cursor_client.h" | 10 #include "ui/aura/client/cursor_client.h" |
| 10 #include "ui/aura/window.h" | 11 #include "ui/aura/window.h" |
| 11 #include "ui/aura/window_event_dispatcher.h" | 12 #include "ui/aura/window_event_dispatcher.h" |
| 12 #include "ui/aura/window_tree_host.h" | 13 #include "ui/aura/window_tree_host.h" |
| 13 #include "ui/events/event.h" | 14 #include "ui/events/event.h" |
| 14 #include "ui/events/event_processor.h" | 15 #include "ui/events/event_processor.h" |
| 15 #include "ui/events/event_utils.h" | 16 #include "ui/events/event_utils.h" |
| 16 #include "ui/gfx/geometry/rect.h" | 17 #include "ui/gfx/geometry/rect.h" |
| 17 | 18 |
| 18 #define VLOG_STATE() if (VLOG_IS_ON(0)) VlogState(__func__) | 19 #define VLOG_STATE() if (VLOG_IS_ON(0)) VlogState(__func__) |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 29 const ui::KeyboardCode kChromeOSSearchKey = ui::VKEY_LWIN; | 30 const ui::KeyboardCode kChromeOSSearchKey = ui::VKEY_LWIN; |
| 30 } // namespace | 31 } // namespace |
| 31 | 32 |
| 32 TouchExplorationController::TouchExplorationController( | 33 TouchExplorationController::TouchExplorationController( |
| 33 aura::Window* root_window, | 34 aura::Window* root_window, |
| 34 TouchExplorationControllerDelegate* delegate) | 35 TouchExplorationControllerDelegate* delegate) |
| 35 : root_window_(root_window), | 36 : root_window_(root_window), |
| 36 delegate_(delegate), | 37 delegate_(delegate), |
| 37 state_(NO_FINGERS_DOWN), | 38 state_(NO_FINGERS_DOWN), |
| 38 event_handler_for_testing_(NULL), | 39 event_handler_for_testing_(NULL), |
| 39 gesture_provider_(this), | |
| 40 prev_state_(NO_FINGERS_DOWN), | 40 prev_state_(NO_FINGERS_DOWN), |
| 41 VLOG_on_(true), | 41 VLOG_on_(true), |
| 42 tick_clock_(NULL) { | 42 tick_clock_(NULL) { |
| 43 CHECK(root_window); | 43 CHECK(root_window); |
| 44 root_window->GetHost()->GetEventSource()->AddEventRewriter(this); | 44 root_window->GetHost()->GetEventSource()->AddEventRewriter(this); |
| 45 InitializeSwipeGestureMaps(); | |
| 46 gesture_provider_.reset(new GestureProviderAura(this)); | |
| 45 } | 47 } |
| 46 | 48 |
| 47 TouchExplorationController::~TouchExplorationController() { | 49 TouchExplorationController::~TouchExplorationController() { |
| 48 root_window_->GetHost()->GetEventSource()->RemoveEventRewriter(this); | 50 root_window_->GetHost()->GetEventSource()->RemoveEventRewriter(this); |
| 49 } | 51 } |
| 50 | 52 |
| 51 ui::EventRewriteStatus TouchExplorationController::RewriteEvent( | 53 ui::EventRewriteStatus TouchExplorationController::RewriteEvent( |
| 52 const ui::Event& event, | 54 const ui::Event& event, |
| 53 scoped_ptr<ui::Event>* rewritten_event) { | 55 scoped_ptr<ui::Event>* rewritten_event) { |
| 54 if (!event.IsTouchEvent()) { | 56 if (!event.IsTouchEvent()) { |
| 57 if (event.IsKeyEvent()) { | |
| 58 const ui::KeyEvent& key_event = static_cast<const ui::KeyEvent&>(event); | |
| 59 VLOG(0) << "\nKeyboard event: " << key_event.name() | |
| 60 << "\n Key code: " << key_event.key_code() | |
| 61 << ", Flags: " << key_event.flags() | |
| 62 << ", Is char: " << key_event.is_char(); | |
| 63 } | |
| 55 return ui::EVENT_REWRITE_CONTINUE; | 64 return ui::EVENT_REWRITE_CONTINUE; |
| 56 } | 65 } |
| 57 const ui::TouchEvent& touch_event = static_cast<const ui::TouchEvent&>(event); | 66 const ui::TouchEvent& touch_event = static_cast<const ui::TouchEvent&>(event); |
| 58 | 67 |
| 59 // If the tap timer should have fired by now but hasn't, run it now and | 68 // If the tap timer should have fired by now but hasn't, run it now and |
| 60 // stop the timer. This is important so that behavior is consistent with | 69 // stop the timer. This is important so that behavior is consistent with |
| 61 // the timestamps of the events, and not dependent on the granularity of | 70 // the timestamps of the events, and not dependent on the granularity of |
| 62 // the timer. | 71 // the timer. |
| 63 if (tap_timer_.IsRunning() && | 72 if (tap_timer_.IsRunning() && |
| 64 touch_event.time_stamp() - initial_press_->time_stamp() > | 73 touch_event.time_stamp() - initial_press_->time_stamp() > |
| 65 gesture_detector_config_.double_tap_timeout) { | 74 gesture_detector_config_.double_tap_timeout) { |
| 66 tap_timer_.Stop(); | 75 tap_timer_.Stop(); |
| 67 OnTapTimerFired(); | 76 OnTapTimerFired(); |
| 68 // Note: this may change the state. We should now continue and process | 77 // Note: this may change the state. We should now continue and process |
| 69 // this event under this new state. | 78 // this event under this new state. |
| 70 } | 79 } |
| 71 | 80 |
| 72 const ui::EventType type = touch_event.type(); | 81 const ui::EventType type = touch_event.type(); |
| 73 const gfx::PointF& location = touch_event.location_f(); | 82 const gfx::PointF& location = touch_event.location_f(); |
| 74 const int touch_id = touch_event.touch_id(); | 83 const int touch_id = touch_event.touch_id(); |
| 75 | 84 |
| 76 // Always update touch ids and touch locations, so we can use those | 85 // Always update touch ids and touch locations, so we can use those |
| 77 // no matter what state we're in. | 86 // no matter what state we're in. |
| 78 if (type == ui::ET_TOUCH_PRESSED) { | 87 if (type == ui::ET_TOUCH_PRESSED) { |
| 79 current_touch_ids_.push_back(touch_id); | 88 current_touch_ids_.push_back(touch_id); |
| 80 touch_locations_.insert(std::pair<int, gfx::PointF>(touch_id, location)); | 89 touch_locations_.insert(std::pair<int, gfx::PointF>(touch_id, location)); |
| 81 } else if (type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) { | 90 } else if (type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) { |
| 82 // In order to avoid accidentally double tapping when moving off the edge of | 91 // In order to avoid accidentally double tapping when moving off the edge |
| 83 // the screen, the state will be rewritten to NoFingersDown. | 92 // of the screen, the state will be rewritten to NoFingersDown. |
| 84 TouchEvent touch_event = static_cast<const TouchEvent&>(event); | 93 TouchEvent touch_event = static_cast<const TouchEvent&>(event); |
| 85 if (FindEdgesWithinBounds(touch_event.location(), kLeavingScreenEdge) != | 94 if (FindEdgesWithinBounds(touch_event.location(), kLeavingScreenEdge) != |
| 86 NO_EDGE) { | 95 NO_EDGE) { |
| 87 if (current_touch_ids_.size() == 0) { | 96 if (current_touch_ids_.size() == 0) { |
| 88 ResetToNoFingersDown(); | 97 ResetToNoFingersDown(); |
| 89 } | 98 } |
| 90 } | 99 } |
| 91 | 100 |
| 92 std::vector<int>::iterator it = std::find( | 101 std::vector<int>::iterator it = std::find( |
| 93 current_touch_ids_.begin(), current_touch_ids_.end(), touch_id); | 102 current_touch_ids_.begin(), current_touch_ids_.end(), touch_id); |
| 94 | 103 |
| 95 // Can happen if touch exploration is enabled while fingers were down. | 104 // Can happen if touch exploration is enabled while fingers were down. |
| 96 if (it == current_touch_ids_.end()) | 105 if (it == current_touch_ids_.end()) |
| 97 return ui::EVENT_REWRITE_CONTINUE; | 106 return ui::EVENT_REWRITE_CONTINUE; |
| 98 | 107 |
| 99 current_touch_ids_.erase(it); | 108 current_touch_ids_.erase(it); |
| 100 touch_locations_.erase(touch_id); | 109 touch_locations_.erase(touch_id); |
| 101 } else if (type == ui::ET_TOUCH_MOVED) { | 110 } else if (type == ui::ET_TOUCH_MOVED) { |
| 102 std::vector<int>::iterator it = std::find( | 111 std::vector<int>::iterator it = std::find( |
| 103 current_touch_ids_.begin(), current_touch_ids_.end(), touch_id); | 112 current_touch_ids_.begin(), current_touch_ids_.end(), touch_id); |
| 104 | 113 |
| 105 // Can happen if touch exploration is enabled while fingers were down. | 114 // Can happen if touch exploration is enabled while fingers were down. |
| 106 if (it == current_touch_ids_.end()) | 115 if (it == current_touch_ids_.end()) |
| 107 return ui::EVENT_REWRITE_CONTINUE; | 116 return ui::EVENT_REWRITE_CONTINUE; |
| 108 | 117 |
| 109 touch_locations_[*it] = location; | 118 touch_locations_[*it] = location; |
| 119 } else { | |
| 120 NOTREACHED() << "Unexpected event type received: " << event.name(); | |
| 121 return ui::EVENT_REWRITE_CONTINUE; | |
| 110 } | 122 } |
| 111 VLOG_STATE(); | 123 VLOG_STATE(); |
| 112 VLOG_EVENT(touch_event); | 124 VLOG_EVENT(touch_event); |
| 125 | |
| 126 // If the user is in a gesture state, or if there is a possiblity that the | |
| 127 // user will enter it in the future, we send the event to the gesture | |
| 128 // provider so it can keep track of the state of the fingers. | |
| 129 // TODO(lisayin, evy): Add the two finger hold state when that's completed. | |
| 130 if (state_ == NO_FINGERS_DOWN || | |
| 131 state_ == SINGLE_TAP_PRESSED || | |
| 132 state_ == GESTURE_IN_PROGRESS || | |
| 133 state_ == SLIDE_GESTURE) { | |
| 134 gesture_provider_->OnTouchEvent(touch_event); | |
| 135 gesture_provider_->OnTouchEventAck(false); | |
| 136 ProcessGestureEvents(); | |
| 137 } | |
| 138 | |
| 113 // The rest of the processing depends on what state we're in. | 139 // The rest of the processing depends on what state we're in. |
| 114 switch(state_) { | 140 switch (state_) { |
| 115 case NO_FINGERS_DOWN: | 141 case NO_FINGERS_DOWN: |
| 116 return InNoFingersDown(touch_event, rewritten_event); | 142 return InNoFingersDown(touch_event, rewritten_event); |
| 117 case SINGLE_TAP_PRESSED: | 143 case SINGLE_TAP_PRESSED: |
| 118 return InSingleTapPressed(touch_event, rewritten_event); | 144 return InSingleTapPressed(touch_event, rewritten_event); |
| 119 case SINGLE_TAP_RELEASED: | 145 case SINGLE_TAP_RELEASED: |
| 120 case TOUCH_EXPLORE_RELEASED: | 146 case TOUCH_EXPLORE_RELEASED: |
| 121 return InSingleTapOrTouchExploreReleased(touch_event, rewritten_event); | 147 return InSingleTapOrTouchExploreReleased(touch_event, rewritten_event); |
| 122 case DOUBLE_TAP_PENDING: | 148 case DOUBLE_TAP_PENDING: |
| 123 return InDoubleTapPending(touch_event, rewritten_event); | 149 return InDoubleTapPending(touch_event, rewritten_event); |
| 124 case TOUCH_RELEASE_PENDING: | 150 case TOUCH_RELEASE_PENDING: |
| 125 return InTouchReleasePending(touch_event, rewritten_event); | 151 return InTouchReleasePending(touch_event, rewritten_event); |
| 126 case TOUCH_EXPLORATION: | 152 case TOUCH_EXPLORATION: |
| 127 return InTouchExploration(touch_event, rewritten_event); | 153 return InTouchExploration(touch_event, rewritten_event); |
| 128 case GESTURE_IN_PROGRESS: | 154 case GESTURE_IN_PROGRESS: |
| 129 return InGestureInProgress(touch_event, rewritten_event); | 155 return InGestureInProgress(touch_event, rewritten_event); |
| 130 case TOUCH_EXPLORE_SECOND_PRESS: | 156 case TOUCH_EXPLORE_SECOND_PRESS: |
| 131 return InTouchExploreSecondPress(touch_event, rewritten_event); | 157 return InTouchExploreSecondPress(touch_event, rewritten_event); |
| 158 case ONE_FINGER_PASSTHROUGH: | |
| 159 return InOneFingerPassthrough(touch_event, rewritten_event); | |
| 160 case WAIT_FOR_NO_FINGERS: | |
| 161 return InWaitForNoFingers(touch_event, rewritten_event); | |
| 132 case SLIDE_GESTURE: | 162 case SLIDE_GESTURE: |
| 133 return InSlideGesture(touch_event, rewritten_event); | 163 return InSlideGesture(touch_event, rewritten_event); |
| 134 case ONE_FINGER_PASSTHROUGH: | |
| 135 return InOneFingerPassthrough(touch_event, rewritten_event); | |
| 136 case WAIT_FOR_ONE_FINGER: | |
| 137 return InWaitForOneFinger(touch_event, rewritten_event); | |
| 138 } | 164 } |
| 139 NOTREACHED(); | 165 NOTREACHED(); |
| 140 return ui::EVENT_REWRITE_CONTINUE; | 166 return ui::EVENT_REWRITE_CONTINUE; |
| 141 } | 167 } |
| 142 | 168 |
| 143 ui::EventRewriteStatus TouchExplorationController::NextDispatchEvent( | 169 ui::EventRewriteStatus TouchExplorationController::NextDispatchEvent( |
| 144 const ui::Event& last_event, scoped_ptr<ui::Event>* new_event) { | 170 const ui::Event& last_event, scoped_ptr<ui::Event>* new_event) { |
| 145 NOTREACHED(); | 171 NOTREACHED(); |
| 146 return ui::EVENT_REWRITE_CONTINUE; | 172 return ui::EVENT_REWRITE_CONTINUE; |
| 147 } | 173 } |
| 148 | 174 |
| 149 ui::EventRewriteStatus TouchExplorationController::InNoFingersDown( | 175 ui::EventRewriteStatus TouchExplorationController::InNoFingersDown( |
| 150 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event) { | 176 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event) { |
| 151 const ui::EventType type = event.type(); | 177 const ui::EventType type = event.type(); |
| 152 if (type == ui::ET_TOUCH_PRESSED) { | 178 if (type == ui::ET_TOUCH_PRESSED) { |
| 153 initial_press_.reset(new TouchEvent(event)); | 179 initial_press_.reset(new TouchEvent(event)); |
| 154 last_unused_finger_event_.reset(new TouchEvent(event)); | 180 last_unused_finger_event_.reset(new TouchEvent(event)); |
| 155 StartTapTimer(); | 181 StartTapTimer(); |
| 156 gesture_provider_.OnTouchEvent(event); | |
| 157 gesture_provider_.OnTouchEventAck(false); | |
| 158 ProcessGestureEvents(); | |
| 159 state_ = SINGLE_TAP_PRESSED; | 182 state_ = SINGLE_TAP_PRESSED; |
| 160 VLOG_STATE(); | 183 VLOG_STATE(); |
| 161 return ui::EVENT_REWRITE_DISCARD; | 184 return ui::EVENT_REWRITE_DISCARD; |
| 162 } | 185 } |
| 163 NOTREACHED() << "Unexpected event type received: " << event.name(); | 186 NOTREACHED() << "Unexpected event type received: " << event.name(); |
| 164 return ui::EVENT_REWRITE_CONTINUE; | 187 return ui::EVENT_REWRITE_CONTINUE; |
| 165 } | 188 } |
| 166 | 189 |
| 167 ui::EventRewriteStatus TouchExplorationController::InSingleTapPressed( | 190 ui::EventRewriteStatus TouchExplorationController::InSingleTapPressed( |
| 168 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event) { | 191 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event) { |
| 169 const ui::EventType type = event.type(); | 192 const ui::EventType type = event.type(); |
| 170 | 193 |
| 171 if (type == ui::ET_TOUCH_PRESSED) { | 194 if (type == ui::ET_TOUCH_PRESSED) { |
| 172 // TODO (evy, lisayin) : add support for multifinger swipes. | 195 // This is the start of a multifinger gesture. |
| 173 // For now, we wait for there to be only one finger down again. | 196 state_ = GESTURE_IN_PROGRESS; |
| 174 state_ = WAIT_FOR_ONE_FINGER; | 197 VLOG_STATE(); |
| 175 return EVENT_REWRITE_DISCARD; | 198 return InGestureInProgress(event, rewritten_event); |
| 176 } else if (type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) { | 199 } else if (type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) { |
| 177 if (current_touch_ids_.size() == 0 && | 200 if (current_touch_ids_.size() == 0 && |
| 178 event.touch_id() == initial_press_->touch_id()) { | 201 event.touch_id() == initial_press_->touch_id()) { |
| 179 state_ = SINGLE_TAP_RELEASED; | 202 state_ = SINGLE_TAP_RELEASED; |
| 180 VLOG_STATE(); | 203 VLOG_STATE(); |
| 181 } else if (current_touch_ids_.size() == 0) { | 204 } else if (current_touch_ids_.size() == 0) { |
| 182 ResetToNoFingersDown(); | 205 ResetToNoFingersDown(); |
| 183 } | 206 } |
| 184 return EVENT_REWRITE_DISCARD; | 207 return EVENT_REWRITE_DISCARD; |
| 185 } else if (type == ui::ET_TOUCH_MOVED) { | 208 } else if (type == ui::ET_TOUCH_MOVED) { |
| (...skipping 26 matching lines...) Expand all Loading... | |
| 212 if (velocity > gesture_detector_config_.minimum_swipe_velocity) { | 235 if (velocity > gesture_detector_config_.minimum_swipe_velocity) { |
| 213 state_ = GESTURE_IN_PROGRESS; | 236 state_ = GESTURE_IN_PROGRESS; |
| 214 VLOG_STATE(); | 237 VLOG_STATE(); |
| 215 return InGestureInProgress(event, rewritten_event); | 238 return InGestureInProgress(event, rewritten_event); |
| 216 } | 239 } |
| 217 EnterTouchToMouseMode(); | 240 EnterTouchToMouseMode(); |
| 218 state_ = TOUCH_EXPLORATION; | 241 state_ = TOUCH_EXPLORATION; |
| 219 VLOG_STATE(); | 242 VLOG_STATE(); |
| 220 return InTouchExploration(event, rewritten_event); | 243 return InTouchExploration(event, rewritten_event); |
| 221 } | 244 } |
| 222 NOTREACHED() << "Unexpected event type received: " << event.name(); | 245 NOTREACHED(); |
| 223 return ui::EVENT_REWRITE_CONTINUE; | 246 return ui::EVENT_REWRITE_CONTINUE; |
| 224 } | 247 } |
| 225 | 248 |
| 226 ui::EventRewriteStatus | 249 ui::EventRewriteStatus |
| 227 TouchExplorationController::InSingleTapOrTouchExploreReleased( | 250 TouchExplorationController::InSingleTapOrTouchExploreReleased( |
| 228 const ui::TouchEvent& event, | 251 const ui::TouchEvent& event, |
| 229 scoped_ptr<ui::Event>* rewritten_event) { | 252 scoped_ptr<ui::Event>* rewritten_event) { |
| 230 const ui::EventType type = event.type(); | 253 const ui::EventType type = event.type(); |
| 231 // If there is more than one finger down, then discard to wait until only one | 254 // If there is more than one finger down, then discard to wait until no |
| 232 // finger is or no fingers are down. | 255 // fingers are down. |
| 233 if (current_touch_ids_.size() > 1) { | 256 if (current_touch_ids_.size() > 1) { |
| 234 state_ = WAIT_FOR_ONE_FINGER; | 257 state_ = WAIT_FOR_NO_FINGERS; |
| 258 VLOG_STATE(); | |
| 235 return ui::EVENT_REWRITE_DISCARD; | 259 return ui::EVENT_REWRITE_DISCARD; |
| 236 } | 260 } |
| 237 if (type == ui::ET_TOUCH_PRESSED) { | 261 if (type == ui::ET_TOUCH_PRESSED) { |
| 238 // If there is no touch exploration yet, we can't send a click, so discard. | 262 // If there is no touch exploration yet, we can't send a click, so discard. |
| 239 if (!last_touch_exploration_) { | 263 if (!last_touch_exploration_) { |
| 240 tap_timer_.Stop(); | 264 tap_timer_.Stop(); |
| 241 return ui::EVENT_REWRITE_DISCARD; | 265 return ui::EVENT_REWRITE_DISCARD; |
| 242 } | 266 } |
| 243 // This is the second tap in a double-tap (or double tap-hold). | 267 // This is the second tap in a double-tap (or double tap-hold). |
| 244 // We set the tap timer. If it fires before the user lifts their finger, | 268 // We set the tap timer. If it fires before the user lifts their finger, |
| 245 // one-finger passthrough begins. Otherwise, there is a touch press and | 269 // one-finger passthrough begins. Otherwise, there is a touch press and |
| 246 // release at the location of the last touch exploration. | 270 // release at the location of the last touch exploration. |
| 247 state_ = DOUBLE_TAP_PENDING; | 271 state_ = DOUBLE_TAP_PENDING; |
| 248 VLOG_STATE(); | 272 VLOG_STATE(); |
| 273 // The old tap timer (from the initial click) is stopped if it is still | |
| 274 // going, and the new one is set. | |
| 275 tap_timer_.Stop(); | |
| 249 StartTapTimer(); | 276 StartTapTimer(); |
| 250 // This will update as the finger moves before a possible passthrough, and | 277 // This will update as the finger moves before a possible passthrough, and |
| 251 // will determine the offset. | 278 // will determine the offset. |
| 252 last_unused_finger_event_.reset(new ui::TouchEvent(event)); | 279 last_unused_finger_event_.reset(new ui::TouchEvent(event)); |
| 253 return ui::EVENT_REWRITE_DISCARD; | 280 return ui::EVENT_REWRITE_DISCARD; |
| 254 } else if (type == ui::ET_TOUCH_RELEASED && !last_touch_exploration_) { | 281 } else if (type == ui::ET_TOUCH_RELEASED && !last_touch_exploration_) { |
| 255 // If the previous press was discarded, we need to also handle its | 282 // If the previous press was discarded, we need to also handle its |
| 256 // release. | 283 // release. |
| 257 if (current_touch_ids_.size() == 0) { | 284 if (current_touch_ids_.size() == 0) { |
| 258 ResetToNoFingersDown(); | 285 ResetToNoFingersDown(); |
| 259 } | 286 } |
| 260 return ui::EVENT_REWRITE_DISCARD; | 287 return ui::EVENT_REWRITE_DISCARD; |
| 261 } else if (type == ui::ET_TOUCH_MOVED) { | 288 } else if (type == ui::ET_TOUCH_MOVED) { |
| 262 return ui::EVENT_REWRITE_DISCARD; | 289 return ui::EVENT_REWRITE_DISCARD; |
| 263 } | 290 } |
| 264 NOTREACHED() << "Unexpected event type received: " << event.name(); | 291 NOTREACHED(); |
| 265 return ui::EVENT_REWRITE_CONTINUE; | 292 return ui::EVENT_REWRITE_CONTINUE; |
| 266 } | 293 } |
| 267 | 294 |
| 268 ui::EventRewriteStatus TouchExplorationController::InDoubleTapPending( | 295 ui::EventRewriteStatus TouchExplorationController::InDoubleTapPending( |
| 269 const ui::TouchEvent& event, | 296 const ui::TouchEvent& event, |
| 270 scoped_ptr<ui::Event>* rewritten_event) { | 297 scoped_ptr<ui::Event>* rewritten_event) { |
| 271 const ui::EventType type = event.type(); | 298 const ui::EventType type = event.type(); |
| 272 if (type == ui::ET_TOUCH_PRESSED) { | 299 if (type == ui::ET_TOUCH_PRESSED) { |
| 273 return ui::EVENT_REWRITE_DISCARD; | 300 return ui::EVENT_REWRITE_DISCARD; |
| 274 } else if (type == ui::ET_TOUCH_MOVED) { | 301 } else if (type == ui::ET_TOUCH_MOVED) { |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 293 | 320 |
| 294 rewritten_event->reset( | 321 rewritten_event->reset( |
| 295 new ui::TouchEvent(ui::ET_TOUCH_RELEASED, | 322 new ui::TouchEvent(ui::ET_TOUCH_RELEASED, |
| 296 last_touch_exploration_->location(), | 323 last_touch_exploration_->location(), |
| 297 initial_press_->touch_id(), | 324 initial_press_->touch_id(), |
| 298 event.time_stamp())); | 325 event.time_stamp())); |
| 299 (*rewritten_event)->set_flags(event.flags()); | 326 (*rewritten_event)->set_flags(event.flags()); |
| 300 ResetToNoFingersDown(); | 327 ResetToNoFingersDown(); |
| 301 return ui::EVENT_REWRITE_REWRITTEN; | 328 return ui::EVENT_REWRITE_REWRITTEN; |
| 302 } | 329 } |
| 303 NOTREACHED() << "Unexpected event type received: " << event.name(); | 330 NOTREACHED(); |
| 304 return ui::EVENT_REWRITE_CONTINUE; | 331 return ui::EVENT_REWRITE_CONTINUE; |
| 305 } | 332 } |
| 306 | 333 |
| 307 ui::EventRewriteStatus TouchExplorationController::InTouchReleasePending( | 334 ui::EventRewriteStatus TouchExplorationController::InTouchReleasePending( |
| 308 const ui::TouchEvent& event, | 335 const ui::TouchEvent& event, |
| 309 scoped_ptr<ui::Event>* rewritten_event) { | 336 scoped_ptr<ui::Event>* rewritten_event) { |
| 310 const ui::EventType type = event.type(); | 337 const ui::EventType type = event.type(); |
| 311 if (type == ui::ET_TOUCH_PRESSED || type == ui::ET_TOUCH_MOVED) { | 338 if (type == ui::ET_TOUCH_PRESSED || type == ui::ET_TOUCH_MOVED) { |
| 312 return ui::EVENT_REWRITE_DISCARD; | 339 return ui::EVENT_REWRITE_DISCARD; |
| 313 } else if (type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) { | 340 } else if (type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) { |
| 314 if (current_touch_ids_.size() != 0) | 341 if (current_touch_ids_.size() != 0) |
| 315 return EVENT_REWRITE_DISCARD; | 342 return EVENT_REWRITE_DISCARD; |
| 316 | 343 |
| 317 rewritten_event->reset( | 344 rewritten_event->reset( |
| 318 new ui::TouchEvent(ui::ET_TOUCH_RELEASED, | 345 new ui::TouchEvent(ui::ET_TOUCH_RELEASED, |
| 319 last_touch_exploration_->location(), | 346 last_touch_exploration_->location(), |
| 320 initial_press_->touch_id(), | 347 initial_press_->touch_id(), |
| 321 event.time_stamp())); | 348 event.time_stamp())); |
| 322 (*rewritten_event)->set_flags(event.flags()); | 349 (*rewritten_event)->set_flags(event.flags()); |
| 323 ResetToNoFingersDown(); | 350 ResetToNoFingersDown(); |
| 324 return ui::EVENT_REWRITE_REWRITTEN; | 351 return ui::EVENT_REWRITE_REWRITTEN; |
| 325 } | 352 } |
| 326 NOTREACHED() << "Unexpected event type received: " << event.name(); | 353 NOTREACHED(); |
| 327 return ui::EVENT_REWRITE_CONTINUE; | 354 return ui::EVENT_REWRITE_CONTINUE; |
| 328 } | 355 } |
| 329 | 356 |
| 330 ui::EventRewriteStatus TouchExplorationController::InTouchExploration( | 357 ui::EventRewriteStatus TouchExplorationController::InTouchExploration( |
| 331 const ui::TouchEvent& event, | 358 const ui::TouchEvent& event, |
| 332 scoped_ptr<ui::Event>* rewritten_event) { | 359 scoped_ptr<ui::Event>* rewritten_event) { |
| 333 const ui::EventType type = event.type(); | 360 const ui::EventType type = event.type(); |
| 334 if (type == ui::ET_TOUCH_PRESSED) { | 361 if (type == ui::ET_TOUCH_PRESSED) { |
| 335 // Handle split-tap. | 362 // Handle split-tap. |
| 336 initial_press_.reset(new TouchEvent(event)); | 363 initial_press_.reset(new TouchEvent(event)); |
| 337 if (tap_timer_.IsRunning()) | 364 tap_timer_.Stop(); |
| 338 tap_timer_.Stop(); | |
| 339 rewritten_event->reset( | 365 rewritten_event->reset( |
| 340 new ui::TouchEvent(ui::ET_TOUCH_PRESSED, | 366 new ui::TouchEvent(ui::ET_TOUCH_PRESSED, |
| 341 last_touch_exploration_->location(), | 367 last_touch_exploration_->location(), |
| 342 event.touch_id(), | 368 event.touch_id(), |
| 343 event.time_stamp())); | 369 event.time_stamp())); |
| 344 (*rewritten_event)->set_flags(event.flags()); | 370 (*rewritten_event)->set_flags(event.flags()); |
| 345 state_ = TOUCH_EXPLORE_SECOND_PRESS; | 371 state_ = TOUCH_EXPLORE_SECOND_PRESS; |
| 346 VLOG_STATE(); | 372 VLOG_STATE(); |
| 347 return ui::EVENT_REWRITE_REWRITTEN; | 373 return ui::EVENT_REWRITE_REWRITTEN; |
| 348 } else if (type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) { | 374 } else if (type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) { |
| 349 initial_press_.reset(new TouchEvent(event)); | 375 initial_press_.reset(new TouchEvent(event)); |
| 350 StartTapTimer(); | 376 StartTapTimer(); |
| 351 state_ = TOUCH_EXPLORE_RELEASED; | 377 state_ = TOUCH_EXPLORE_RELEASED; |
| 352 VLOG_STATE(); | 378 VLOG_STATE(); |
| 353 } else if (type != ui::ET_TOUCH_MOVED) { | 379 } else if (type != ui::ET_TOUCH_MOVED) { |
| 354 NOTREACHED() << "Unexpected event type received: " << event.name(); | 380 NOTREACHED(); |
| 355 return ui::EVENT_REWRITE_CONTINUE; | 381 return ui::EVENT_REWRITE_CONTINUE; |
| 356 } | 382 } |
| 357 | 383 |
| 358 // Rewrite as a mouse-move event. | 384 // Rewrite as a mouse-move event. |
| 359 *rewritten_event = CreateMouseMoveEvent(event.location(), event.flags()); | 385 *rewritten_event = CreateMouseMoveEvent(event.location(), event.flags()); |
| 360 last_touch_exploration_.reset(new TouchEvent(event)); | 386 last_touch_exploration_.reset(new TouchEvent(event)); |
| 361 return ui::EVENT_REWRITE_REWRITTEN; | 387 return ui::EVENT_REWRITE_REWRITTEN; |
| 362 } | 388 } |
| 363 | 389 |
| 364 ui::EventRewriteStatus TouchExplorationController::InGestureInProgress( | 390 ui::EventRewriteStatus TouchExplorationController::InGestureInProgress( |
| 365 const ui::TouchEvent& event, | 391 const ui::TouchEvent& event, |
| 366 scoped_ptr<ui::Event>* rewritten_event) { | 392 scoped_ptr<ui::Event>* rewritten_event) { |
| 367 ui::EventType type = event.type(); | 393 // The events were sent to the gesture provider in RewriteEvent already. |
| 368 // If additional fingers are added before a swipe gesture has been | 394 // If no gesture is registered before the tap timer times out, the state |
| 369 // registered, then the state will no longer be GESTURE_IN_PROGRESS. | 395 // will change to wait for no fingers down and this function will stop |
| 370 if (type == ui::ET_TOUCH_PRESSED || | 396 // being called. |
| 371 event.touch_id() != initial_press_->touch_id()) { | 397 if (current_touch_ids_.size() == 0) { |
| 372 if (tap_timer_.IsRunning()) | 398 ResetToNoFingersDown(); |
| 373 tap_timer_.Stop(); | |
| 374 // Discard any pending gestures. | |
| 375 delete gesture_provider_.GetAndResetPendingGestures(); | |
| 376 state_ = WAIT_FOR_ONE_FINGER; | |
| 377 return EVENT_REWRITE_DISCARD; | |
| 378 } | 399 } |
| 379 | |
| 380 // There should not be more than one finger down. | |
| 381 DCHECK(current_touch_ids_.size() <= 1); | |
| 382 if (type == ui::ET_TOUCH_MOVED) { | |
| 383 gesture_provider_.OnTouchEvent(event); | |
| 384 gesture_provider_.OnTouchEventAck(false); | |
| 385 } | |
| 386 if (type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) { | |
| 387 gesture_provider_.OnTouchEvent(event); | |
| 388 gesture_provider_.OnTouchEventAck(false); | |
| 389 if (current_touch_ids_.size() == 0) { | |
| 390 ResetToNoFingersDown(); | |
| 391 } | |
| 392 } | |
| 393 ProcessGestureEvents(); | |
| 394 return ui::EVENT_REWRITE_DISCARD; | 400 return ui::EVENT_REWRITE_DISCARD; |
| 395 } | 401 } |
| 396 | 402 |
| 397 ui::EventRewriteStatus TouchExplorationController::InOneFingerPassthrough( | 403 ui::EventRewriteStatus TouchExplorationController::InOneFingerPassthrough( |
| 398 const ui::TouchEvent& event, | 404 const ui::TouchEvent& event, |
| 399 scoped_ptr<ui::Event>* rewritten_event) { | 405 scoped_ptr<ui::Event>* rewritten_event) { |
| 400 ui::EventType type = event.type(); | |
| 401 | |
| 402 if (!(type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED || | |
| 403 type == ui::ET_TOUCH_MOVED || type == ui::ET_TOUCH_PRESSED)) { | |
| 404 NOTREACHED() << "Unexpected event type received: " << event.name(); | |
| 405 return ui::EVENT_REWRITE_CONTINUE; | |
| 406 } | |
| 407 if (event.touch_id() != initial_press_->touch_id()) { | 406 if (event.touch_id() != initial_press_->touch_id()) { |
| 408 if (current_touch_ids_.size() == 0) { | 407 if (current_touch_ids_.size() == 0) { |
| 409 ResetToNoFingersDown(); | 408 ResetToNoFingersDown(); |
| 410 } | 409 } |
| 411 return ui::EVENT_REWRITE_DISCARD; | 410 return ui::EVENT_REWRITE_DISCARD; |
| 412 } | 411 } |
| 413 rewritten_event->reset( | 412 rewritten_event->reset( |
| 414 new ui::TouchEvent(event.type(), | 413 new ui::TouchEvent(event.type(), |
| 415 event.location() - passthrough_offset_, | 414 event.location() - passthrough_offset_, |
| 416 event.touch_id(), | 415 event.touch_id(), |
| 417 event.time_stamp())); | 416 event.time_stamp())); |
| 418 | 417 |
| 419 (*rewritten_event)->set_flags(event.flags()); | 418 (*rewritten_event)->set_flags(event.flags()); |
| 420 if (current_touch_ids_.size() == 0) { | 419 if (current_touch_ids_.size() == 0) { |
| 421 ResetToNoFingersDown(); | 420 ResetToNoFingersDown(); |
| 422 } | 421 } |
| 423 | |
| 424 return ui::EVENT_REWRITE_REWRITTEN; | 422 return ui::EVENT_REWRITE_REWRITTEN; |
| 425 } | 423 } |
| 426 | 424 |
| 427 ui::EventRewriteStatus TouchExplorationController::InTouchExploreSecondPress( | 425 ui::EventRewriteStatus TouchExplorationController::InTouchExploreSecondPress( |
| 428 const ui::TouchEvent& event, | 426 const ui::TouchEvent& event, |
| 429 scoped_ptr<ui::Event>* rewritten_event) { | 427 scoped_ptr<ui::Event>* rewritten_event) { |
| 430 ui::EventType type = event.type(); | 428 ui::EventType type = event.type(); |
| 431 gfx::PointF location = event.location_f(); | 429 gfx::PointF location = event.location_f(); |
| 432 if (type == ui::ET_TOUCH_PRESSED) { | 430 if (type == ui::ET_TOUCH_PRESSED) { |
| 433 return ui::EVENT_REWRITE_DISCARD; | 431 return ui::EVENT_REWRITE_DISCARD; |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 455 new ui::TouchEvent(ui::ET_TOUCH_RELEASED, | 453 new ui::TouchEvent(ui::ET_TOUCH_RELEASED, |
| 456 last_touch_exploration_->location(), | 454 last_touch_exploration_->location(), |
| 457 initial_press_->touch_id(), | 455 initial_press_->touch_id(), |
| 458 event.time_stamp())); | 456 event.time_stamp())); |
| 459 (*rewritten_event)->set_flags(event.flags()); | 457 (*rewritten_event)->set_flags(event.flags()); |
| 460 state_ = TOUCH_EXPLORATION; | 458 state_ = TOUCH_EXPLORATION; |
| 461 EnterTouchToMouseMode(); | 459 EnterTouchToMouseMode(); |
| 462 VLOG_STATE(); | 460 VLOG_STATE(); |
| 463 return ui::EVENT_REWRITE_REWRITTEN; | 461 return ui::EVENT_REWRITE_REWRITTEN; |
| 464 } | 462 } |
| 465 NOTREACHED() << "Unexpected event type received: " << event.name(); | 463 NOTREACHED(); |
| 466 return ui::EVENT_REWRITE_CONTINUE; | 464 return ui::EVENT_REWRITE_CONTINUE; |
| 467 } | 465 } |
| 468 | 466 |
| 469 ui::EventRewriteStatus TouchExplorationController::InWaitForOneFinger( | 467 ui::EventRewriteStatus TouchExplorationController::InWaitForNoFingers( |
| 470 const ui::TouchEvent& event, | 468 const ui::TouchEvent& event, |
| 471 scoped_ptr<ui::Event>* rewritten_event) { | 469 scoped_ptr<ui::Event>* rewritten_event) { |
| 472 ui::EventType type = event.type(); | 470 if (current_touch_ids_.size() == 0) |
| 473 if (!(type == ui::ET_TOUCH_PRESSED || type == ui::ET_TOUCH_MOVED || | 471 ResetToNoFingersDown(); |
| 474 type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED)) { | |
| 475 NOTREACHED() << "Unexpected event type received: " << event.name(); | |
| 476 return ui::EVENT_REWRITE_CONTINUE; | |
| 477 } | |
| 478 if (current_touch_ids_.size() == 1) { | |
| 479 EnterTouchToMouseMode(); | |
| 480 state_ = TOUCH_EXPLORATION; | |
| 481 VLOG_STATE(); | |
| 482 *rewritten_event = CreateMouseMoveEvent(event.location(), event.flags()); | |
| 483 last_touch_exploration_.reset(new TouchEvent(event)); | |
| 484 return ui::EVENT_REWRITE_REWRITTEN; | |
| 485 } | |
| 486 return EVENT_REWRITE_DISCARD; | 472 return EVENT_REWRITE_DISCARD; |
| 487 } | 473 } |
| 488 | 474 |
| 489 void TouchExplorationController::PlaySoundForTimer() { | 475 void TouchExplorationController::PlaySoundForTimer() { |
| 490 delegate_->PlayVolumeAdjustSound(); | 476 delegate_->PlayVolumeAdjustSound(); |
| 491 } | 477 } |
| 492 | 478 |
| 493 ui::EventRewriteStatus TouchExplorationController::InSlideGesture( | 479 ui::EventRewriteStatus TouchExplorationController::InSlideGesture( |
| 494 const ui::TouchEvent& event, | 480 const ui::TouchEvent& event, |
| 495 scoped_ptr<ui::Event>* rewritten_event) { | 481 scoped_ptr<ui::Event>* rewritten_event) { |
| 496 // The timer should not fire when sliding. | 482 // The timer should not fire when sliding. |
| 497 if (tap_timer_.IsRunning()) | 483 tap_timer_.Stop(); |
| 498 tap_timer_.Stop(); | |
| 499 | 484 |
| 500 ui::EventType type = event.type(); | 485 ui::EventType type = event.type(); |
| 501 // If additional fingers are added before a swipe gesture has been registered, | 486 // If additional fingers are added before a swipe gesture has been registered, |
| 502 // then wait until all fingers have been lifted. | 487 // then wait until all fingers have been lifted. |
| 503 if (type == ui::ET_TOUCH_PRESSED || | 488 if (type == ui::ET_TOUCH_PRESSED || |
| 504 event.touch_id() != initial_press_->touch_id()) { | 489 event.touch_id() != initial_press_->touch_id()) { |
| 505 if (sound_timer_.IsRunning()) | 490 if (sound_timer_.IsRunning()) |
| 506 sound_timer_.Stop(); | 491 sound_timer_.Stop(); |
| 507 // Discard any pending gestures. | 492 state_ = WAIT_FOR_NO_FINGERS; |
| 508 delete gesture_provider_.GetAndResetPendingGestures(); | 493 VLOG_STATE(); |
| 509 state_ = WAIT_FOR_ONE_FINGER; | |
| 510 return EVENT_REWRITE_DISCARD; | 494 return EVENT_REWRITE_DISCARD; |
| 511 } | 495 } |
| 512 | 496 |
| 497 // There should not be more than one finger down. | |
| 498 DCHECK(current_touch_ids_.size() <= 1); | |
| 499 | |
| 500 | |
| 513 // Allows user to return to the edge to adjust the sound if they have left the | 501 // Allows user to return to the edge to adjust the sound if they have left the |
| 514 // boundaries. | 502 // boundaries. |
| 515 int edge = FindEdgesWithinBounds(event.location(), kSlopDistanceFromEdge); | 503 int edge = FindEdgesWithinBounds(event.location(), kSlopDistanceFromEdge); |
| 516 if (!(edge & RIGHT_EDGE) && (type != ui::ET_TOUCH_RELEASED)) { | 504 if (!(edge & RIGHT_EDGE) && (type != ui::ET_TOUCH_RELEASED)) { |
| 517 if (sound_timer_.IsRunning()) { | 505 if (sound_timer_.IsRunning()) { |
| 518 sound_timer_.Stop(); | 506 sound_timer_.Stop(); |
| 519 } | 507 } |
| 520 return EVENT_REWRITE_DISCARD; | 508 return EVENT_REWRITE_DISCARD; |
| 521 } | 509 } |
| 522 | 510 |
| 523 // This can occur if the user leaves the screen edge and then returns to it to | 511 // This can occur if the user leaves the screen edge and then returns to it to |
| 524 // continue adjusting the sound. | 512 // continue adjusting the sound. |
| 525 if (!sound_timer_.IsRunning()) { | 513 if (!sound_timer_.IsRunning()) { |
| 526 sound_timer_.Start(FROM_HERE, | 514 sound_timer_.Start(FROM_HERE, |
| 527 kSoundDelay, | 515 kSoundDelay, |
| 528 this, | 516 this, |
| 529 &ui::TouchExplorationController::PlaySoundForTimer); | 517 &ui::TouchExplorationController::PlaySoundForTimer); |
| 530 delegate_->PlayVolumeAdjustSound(); | 518 delegate_->PlayVolumeAdjustSound(); |
| 531 } | 519 } |
| 532 | 520 |
| 533 // There should not be more than one finger down. | 521 if (current_touch_ids_.size() == 0) { |
| 534 DCHECK(current_touch_ids_.size() <= 1); | 522 ResetToNoFingersDown(); |
| 535 if (type == ui::ET_TOUCH_MOVED) { | |
| 536 gesture_provider_.OnTouchEvent(event); | |
| 537 gesture_provider_.OnTouchEventAck(false); | |
| 538 } | |
| 539 if (type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) { | |
| 540 gesture_provider_.OnTouchEvent(event); | |
| 541 gesture_provider_.OnTouchEventAck(false); | |
| 542 delete gesture_provider_.GetAndResetPendingGestures(); | |
| 543 if (current_touch_ids_.size() == 0) { | |
| 544 ResetToNoFingersDown(); | |
| 545 } | |
| 546 return ui::EVENT_REWRITE_DISCARD; | |
| 547 } | 523 } |
| 548 | 524 |
| 549 ProcessGestureEvents(); | |
| 550 return ui::EVENT_REWRITE_DISCARD; | 525 return ui::EVENT_REWRITE_DISCARD; |
| 551 } | 526 } |
| 552 | 527 |
| 553 base::TimeDelta TouchExplorationController::Now() { | 528 base::TimeDelta TouchExplorationController::Now() { |
| 554 if (tick_clock_) { | 529 if (tick_clock_) { |
| 555 // This is the same as what EventTimeForNow() does, but here we do it | 530 // This is the same as what EventTimeForNow() does, but here we do it |
| 556 // with a clock that can be replaced with a simulated clock for tests. | 531 // with a clock that can be replaced with a simulated clock for tests. |
| 557 return base::TimeDelta::FromInternalValue( | 532 return base::TimeDelta::FromInternalValue( |
| 558 tick_clock_->NowTicks().ToInternalValue()); | 533 tick_clock_->NowTicks().ToInternalValue()); |
| 559 } | 534 } |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 583 last_touch_exploration_->location(); | 558 last_touch_exploration_->location(); |
| 584 scoped_ptr<ui::TouchEvent> passthrough_press( | 559 scoped_ptr<ui::TouchEvent> passthrough_press( |
| 585 new ui::TouchEvent(ui::ET_TOUCH_PRESSED, | 560 new ui::TouchEvent(ui::ET_TOUCH_PRESSED, |
| 586 last_touch_exploration_->location(), | 561 last_touch_exploration_->location(), |
| 587 last_unused_finger_event_->touch_id(), | 562 last_unused_finger_event_->touch_id(), |
| 588 Now())); | 563 Now())); |
| 589 DispatchEvent(passthrough_press.get()); | 564 DispatchEvent(passthrough_press.get()); |
| 590 return; | 565 return; |
| 591 } | 566 } |
| 592 case SINGLE_TAP_PRESSED: | 567 case SINGLE_TAP_PRESSED: |
| 593 case GESTURE_IN_PROGRESS: | |
| 594 // Discard any pending gestures. | |
| 595 delete gesture_provider_.GetAndResetPendingGestures(); | |
| 596 EnterTouchToMouseMode(); | 568 EnterTouchToMouseMode(); |
| 597 state_ = TOUCH_EXPLORATION; | 569 state_ = TOUCH_EXPLORATION; |
| 570 break; | |
| 571 case GESTURE_IN_PROGRESS: | |
| 572 // If only one finger is down, go into touch exploration. | |
| 573 if (current_touch_ids_.size() == 1) { | |
| 574 EnterTouchToMouseMode(); | |
| 575 state_ = TOUCH_EXPLORATION; | |
| 576 VLOG_STATE(); | |
| 577 return; | |
|
lisayin
2014/08/06 22:43:29
This should be a break so that the mouse moves can
evy
2014/08/06 22:59:14
Done.
| |
| 578 } | |
| 579 // Otherwise wait for all fingers to be lifted. | |
| 580 state_ = WAIT_FOR_NO_FINGERS; | |
| 598 VLOG_STATE(); | 581 VLOG_STATE(); |
| 599 break; | 582 return; |
| 600 default: | 583 default: |
| 601 return; | 584 return; |
| 602 } | 585 } |
| 603 scoped_ptr<ui::Event> mouse_move = | 586 scoped_ptr<ui::Event> mouse_move = |
| 604 CreateMouseMoveEvent(initial_press_->location(), initial_press_->flags()); | 587 CreateMouseMoveEvent(initial_press_->location(), initial_press_->flags()); |
| 605 DispatchEvent(mouse_move.get()); | 588 DispatchEvent(mouse_move.get()); |
| 606 last_touch_exploration_.reset(new TouchEvent(*initial_press_)); | 589 last_touch_exploration_.reset(new TouchEvent(*initial_press_)); |
| 607 } | 590 } |
| 608 | 591 |
| 609 void TouchExplorationController::DispatchEvent(ui::Event* event) { | 592 void TouchExplorationController::DispatchEvent(ui::Event* event) { |
| 610 if (event_handler_for_testing_) { | 593 if (event_handler_for_testing_) { |
| 611 event_handler_for_testing_->OnEvent(event); | 594 event_handler_for_testing_->OnEvent(event); |
| 612 return; | 595 return; |
| 613 } | 596 } |
| 614 ui::EventDispatchDetails result ALLOW_UNUSED = | 597 ui::EventDispatchDetails result ALLOW_UNUSED = |
| 615 root_window_->GetHost()->dispatcher()->OnEventFromSource(event); | 598 root_window_->GetHost()->dispatcher()->OnEventFromSource(event); |
| 616 } | 599 } |
| 617 | 600 |
| 618 void TouchExplorationController::OnGestureEvent( | 601 // This is an override. We're using other more specific functions for possible |
| 619 ui::GestureEvent* gesture) { | 602 // processed gesture events. |
| 620 CHECK(gesture->IsGestureEvent()); | 603 void TouchExplorationController::OnGestureEvent(ui::GestureEvent* gesture) { |
| 621 ui::EventType type = gesture->type(); | |
| 622 if (VLOG_on_) | |
| 623 VLOG(0) << " \n Gesture Triggered: " << gesture->name(); | |
| 624 if (type == ui::ET_GESTURE_SWIPE && state_ != SLIDE_GESTURE) { | |
| 625 if (VLOG_on_) | |
| 626 VLOG(0) << "Swipe!"; | |
| 627 delete gesture_provider_.GetAndResetPendingGestures(); | |
| 628 OnSwipeEvent(gesture); | |
| 629 return; | |
| 630 } | |
| 631 } | 604 } |
| 632 | 605 |
| 633 void TouchExplorationController::ProcessGestureEvents() { | 606 void TouchExplorationController::ProcessGestureEvents() { |
| 634 scoped_ptr<ScopedVector<ui::GestureEvent> > gestures( | 607 scoped_ptr<ScopedVector<ui::GestureEvent> > gestures( |
| 635 gesture_provider_.GetAndResetPendingGestures()); | 608 gesture_provider_->GetAndResetPendingGestures()); |
| 636 if (gestures) { | 609 if (gestures) { |
| 637 for (ScopedVector<GestureEvent>::iterator i = gestures->begin(); | 610 for (ScopedVector<GestureEvent>::iterator i = gestures->begin(); |
| 638 i != gestures->end(); | 611 i != gestures->end(); |
| 639 ++i) { | 612 ++i) { |
| 640 if (state_ == SLIDE_GESTURE) | 613 if ((*i)->type() == ui::ET_GESTURE_SWIPE && |
| 614 state_ == GESTURE_IN_PROGRESS) { | |
| 615 OnSwipeEvent(*i); | |
| 616 // The tap timer to leave gesture state is ended, and we now wait for | |
| 617 // all | |
| 618 // fingers to be released. | |
|
lisayin
2014/08/06 22:43:29
nit: move this line to the line with // all
evy
2014/08/06 22:59:14
Done.
| |
| 619 tap_timer_.Stop(); | |
| 620 state_ = WAIT_FOR_NO_FINGERS; | |
| 621 VLOG_STATE(); | |
| 622 return; | |
| 623 } | |
| 624 if (state_ == SLIDE_GESTURE && (*i)->IsScrollGestureEvent()) { | |
| 641 SideSlideControl(*i); | 625 SideSlideControl(*i); |
| 642 else | 626 return; |
| 643 OnGestureEvent(*i); | 627 } |
| 644 } | 628 } |
| 645 } | 629 } |
| 646 } | 630 } |
| 647 | 631 |
| 648 void TouchExplorationController::SideSlideControl(ui::GestureEvent* gesture) { | 632 void TouchExplorationController::SideSlideControl(ui::GestureEvent* gesture) { |
| 649 ui::EventType type = gesture->type(); | 633 ui::EventType type = gesture->type(); |
| 650 if (!gesture->IsScrollGestureEvent()) | 634 CHECK(gesture->IsGestureEvent()); |
| 651 return; | 635 CHECK(gesture->IsScrollGestureEvent()); |
| 652 | 636 |
| 653 if (type == ET_GESTURE_SCROLL_BEGIN) { | 637 if (type == ET_GESTURE_SCROLL_BEGIN) { |
| 654 delegate_->PlayVolumeAdjustSound(); | 638 delegate_->PlayVolumeAdjustSound(); |
| 655 } | 639 } |
| 656 | 640 |
| 657 if (type == ET_GESTURE_SCROLL_END) { | 641 if (type == ET_GESTURE_SCROLL_END) { |
| 658 if (sound_timer_.IsRunning()) | 642 if (sound_timer_.IsRunning()) |
| 659 sound_timer_.Stop(); | 643 sound_timer_.Stop(); |
| 660 delegate_->PlayVolumeAdjustSound(); | 644 delegate_->PlayVolumeAdjustSound(); |
| 661 } | 645 } |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 686 float ratio = (location.y() - kMaxDistanceFromEdge) / volume_adjust_height; | 670 float ratio = (location.y() - kMaxDistanceFromEdge) / volume_adjust_height; |
| 687 float volume = 100 - 100 * ratio; | 671 float volume = 100 - 100 * ratio; |
| 688 if (VLOG_on_) { | 672 if (VLOG_on_) { |
| 689 VLOG(0) << "\n Volume = " << volume | 673 VLOG(0) << "\n Volume = " << volume |
| 690 << "\n Location = " << location.ToString() | 674 << "\n Location = " << location.ToString() |
| 691 << "\n Bounds = " << root_window_->bounds().right(); | 675 << "\n Bounds = " << root_window_->bounds().right(); |
| 692 } | 676 } |
| 693 delegate_->SetOutputLevel(int(volume)); | 677 delegate_->SetOutputLevel(int(volume)); |
| 694 } | 678 } |
| 695 | 679 |
| 696 | |
| 697 void TouchExplorationController::OnSwipeEvent(ui::GestureEvent* swipe_gesture) { | 680 void TouchExplorationController::OnSwipeEvent(ui::GestureEvent* swipe_gesture) { |
| 698 // A swipe gesture contains details for the direction in which the swipe | 681 // A swipe gesture contains details for the direction in which the swipe |
| 699 // occurred. | 682 // occurred. TODO(evy) : Research which swipe results users most want and |
| 683 // remap these swipes to the best events. Hopefully in the near future | |
| 684 // there will also be a menu for users to pick custom mappings. | |
| 685 CHECK(swipe_gesture->IsGestureEvent()); | |
| 700 GestureEventDetails event_details = swipe_gesture->details(); | 686 GestureEventDetails event_details = swipe_gesture->details(); |
| 701 if (event_details.swipe_left()) { | 687 int num_fingers = event_details.touch_points(); |
| 702 DispatchShiftSearchKeyEvent(ui::VKEY_LEFT); | 688 if(VLOG_on_) |
| 689 VLOG(0) << "\nSwipe with " << num_fingers << " fingers."; | |
| 690 | |
| 691 if (num_fingers > 4) | |
| 703 return; | 692 return; |
| 704 } else if (event_details.swipe_right()) { | 693 |
| 705 DispatchShiftSearchKeyEvent(ui::VKEY_RIGHT); | 694 if (event_details.swipe_left()) |
| 706 return; | 695 left_swipe_gestures_[num_fingers].Run(); |
| 707 } else if (event_details.swipe_up()) { | 696 else if (event_details.swipe_right()) |
| 708 DispatchShiftSearchKeyEvent(ui::VKEY_UP); | 697 right_swipe_gestures_[num_fingers].Run(); |
| 709 return; | 698 else if (event_details.swipe_up()) |
| 710 } else if (event_details.swipe_down()) { | 699 up_swipe_gestures_[num_fingers].Run(); |
| 711 DispatchShiftSearchKeyEvent(ui::VKEY_DOWN); | 700 else if (event_details.swipe_down()) |
| 712 return; | 701 down_swipe_gestures_[num_fingers].Run(); |
| 713 } | |
| 714 } | 702 } |
| 715 | 703 |
| 716 int TouchExplorationController::FindEdgesWithinBounds(gfx::Point point, | 704 int TouchExplorationController::FindEdgesWithinBounds(gfx::Point point, |
| 717 float bounds) { | 705 float bounds) { |
| 718 // Since GetBoundsInScreen is in DIPs but point is not, then point needs to be | 706 // Since GetBoundsInScreen is in DIPs but point is not, then point needs to be |
| 719 // converted. | 707 // converted. |
| 720 root_window_->GetHost()->ConvertPointFromNativeScreen(&point); | 708 root_window_->GetHost()->ConvertPointFromNativeScreen(&point); |
| 721 gfx::Rect window = root_window_->GetBoundsInScreen(); | 709 gfx::Rect window = root_window_->GetBoundsInScreen(); |
| 722 | 710 |
| 723 float left_edge_limit = window.x() + bounds; | 711 float left_edge_limit = window.x() + bounds; |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 735 if (point.x() > right_edge_limit) | 723 if (point.x() > right_edge_limit) |
| 736 result |= RIGHT_EDGE; | 724 result |= RIGHT_EDGE; |
| 737 if (point.y() < top_edge_limit) | 725 if (point.y() < top_edge_limit) |
| 738 result |= TOP_EDGE; | 726 result |= TOP_EDGE; |
| 739 if (point.y() > bottom_edge_limit) | 727 if (point.y() > bottom_edge_limit) |
| 740 result |= BOTTOM_EDGE; | 728 result |= BOTTOM_EDGE; |
| 741 return result; | 729 return result; |
| 742 } | 730 } |
| 743 | 731 |
| 744 void TouchExplorationController::DispatchShiftSearchKeyEvent( | 732 void TouchExplorationController::DispatchShiftSearchKeyEvent( |
| 745 const ui::KeyboardCode direction) { | 733 const ui::KeyboardCode third_key) { |
| 746 // In order to activate the shortcut shift+search+<arrow key> | 734 // In order to activate the shortcut shift+search+<key> |
| 747 // three KeyPressed events must be dispatched in succession along | 735 // three KeyPressed events must be dispatched in succession along |
| 748 // with three KeyReleased events. | 736 // with three KeyReleased events. |
| 749 ui::KeyEvent shift_down = ui::KeyEvent( | 737 |
| 738 ui::KeyEvent shift_down( | |
| 750 ui::ET_KEY_PRESSED, ui::VKEY_SHIFT, ui::EF_SHIFT_DOWN); | 739 ui::ET_KEY_PRESSED, ui::VKEY_SHIFT, ui::EF_SHIFT_DOWN); |
| 751 ui::KeyEvent search_down = ui::KeyEvent( | 740 ui::KeyEvent search_down( |
| 752 ui::ET_KEY_PRESSED, kChromeOSSearchKey, ui::EF_SHIFT_DOWN); | 741 ui::ET_KEY_PRESSED, kChromeOSSearchKey, ui::EF_SHIFT_DOWN); |
| 753 ui::KeyEvent direction_down = | 742 ui::KeyEvent third_key_down(ui::ET_KEY_PRESSED, third_key, ui::EF_SHIFT_DOWN); |
| 754 ui::KeyEvent(ui::ET_KEY_PRESSED, direction, ui::EF_SHIFT_DOWN); | |
| 755 | 743 |
| 756 ui::KeyEvent direction_up = | 744 ui::KeyEvent third_key_up(ui::ET_KEY_RELEASED, third_key, ui::EF_SHIFT_DOWN); |
| 757 ui::KeyEvent(ui::ET_KEY_RELEASED, direction, ui::EF_SHIFT_DOWN); | 745 ui::KeyEvent search_up( |
| 758 ui::KeyEvent search_up = ui::KeyEvent( | |
| 759 ui::ET_KEY_RELEASED, kChromeOSSearchKey, ui::EF_SHIFT_DOWN); | 746 ui::ET_KEY_RELEASED, kChromeOSSearchKey, ui::EF_SHIFT_DOWN); |
| 760 ui::KeyEvent shift_up = | 747 ui ::KeyEvent shift_up(ui::ET_KEY_RELEASED, ui::VKEY_SHIFT, ui::EF_NONE); |
| 761 ui::KeyEvent(ui::ET_KEY_RELEASED, ui::VKEY_SHIFT, ui::EF_NONE); | |
| 762 | 748 |
| 763 DispatchEvent(&shift_down); | 749 DispatchEvent(&shift_down); |
| 764 DispatchEvent(&search_down); | 750 DispatchEvent(&search_down); |
| 765 DispatchEvent(&direction_down); | 751 DispatchEvent(&third_key_down); |
| 766 DispatchEvent(&direction_up); | 752 DispatchEvent(&third_key_up); |
| 767 DispatchEvent(&search_up); | 753 DispatchEvent(&search_up); |
| 768 DispatchEvent(&shift_up); | 754 DispatchEvent(&shift_up); |
| 769 } | 755 } |
| 770 | 756 |
| 757 void TouchExplorationController::DispatchKeyWithFlags( | |
| 758 const ui::KeyboardCode key, | |
| 759 int flags) { | |
| 760 ui::KeyEvent key_down(ui::ET_KEY_PRESSED, key, flags); | |
| 761 ui::KeyEvent key_up(ui::ET_KEY_RELEASED, key, flags); | |
| 762 DispatchEvent(&key_down); | |
| 763 DispatchEvent(&key_up); | |
| 764 if(VLOG_on_) { | |
| 765 VLOG(0) << "\nKey down: key code : " << key_down.key_code() | |
| 766 << ", flags: " << key_down.flags() | |
| 767 << "\nKey up: key code : " << key_up.key_code() | |
| 768 << ", flags: " << key_up.flags(); | |
| 769 } | |
| 770 } | |
| 771 | |
| 771 scoped_ptr<ui::Event> TouchExplorationController::CreateMouseMoveEvent( | 772 scoped_ptr<ui::Event> TouchExplorationController::CreateMouseMoveEvent( |
| 772 const gfx::PointF& location, | 773 const gfx::PointF& location, |
| 773 int flags) { | 774 int flags) { |
| 774 // The "synthesized" flag should be set on all events that don't have a | 775 // The "synthesized" flag should be set on all events that don't have a |
| 775 // backing native event. | 776 // backing native event. |
| 776 flags |= ui::EF_IS_SYNTHESIZED; | 777 flags |= ui::EF_IS_SYNTHESIZED; |
| 777 | 778 |
| 778 // This flag is used to identify mouse move events that were generated from | 779 // This flag is used to identify mouse move events that were generated from |
| 779 // touch exploration in Chrome code. | 780 // touch exploration in Chrome code. |
| 780 flags |= ui::EF_TOUCH_ACCESSIBILITY; | 781 flags |= ui::EF_TOUCH_ACCESSIBILITY; |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 797 void TouchExplorationController::EnterTouchToMouseMode() { | 798 void TouchExplorationController::EnterTouchToMouseMode() { |
| 798 aura::client::CursorClient* cursor_client = | 799 aura::client::CursorClient* cursor_client = |
| 799 aura::client::GetCursorClient(root_window_); | 800 aura::client::GetCursorClient(root_window_); |
| 800 if (cursor_client && !cursor_client->IsMouseEventsEnabled()) | 801 if (cursor_client && !cursor_client->IsMouseEventsEnabled()) |
| 801 cursor_client->EnableMouseEvents(); | 802 cursor_client->EnableMouseEvents(); |
| 802 if (cursor_client && cursor_client->IsCursorVisible()) | 803 if (cursor_client && cursor_client->IsCursorVisible()) |
| 803 cursor_client->HideCursor(); | 804 cursor_client->HideCursor(); |
| 804 } | 805 } |
| 805 | 806 |
| 806 void TouchExplorationController::ResetToNoFingersDown() { | 807 void TouchExplorationController::ResetToNoFingersDown() { |
| 807 ProcessGestureEvents(); | 808 gesture_provider_.reset(new GestureProviderAura(this)); |
| 808 if (sound_timer_.IsRunning()) | 809 if (sound_timer_.IsRunning()) |
| 809 sound_timer_.Stop(); | 810 sound_timer_.Stop(); |
| 810 state_ = NO_FINGERS_DOWN; | 811 state_ = NO_FINGERS_DOWN; |
| 811 VLOG_STATE(); | 812 VLOG_STATE(); |
| 812 if (tap_timer_.IsRunning()) | 813 tap_timer_.Stop(); |
| 813 tap_timer_.Stop(); | |
| 814 } | 814 } |
| 815 | 815 |
| 816 void TouchExplorationController::VlogState(const char* function_name) { | 816 void TouchExplorationController::VlogState(const char* function_name) { |
| 817 if (!VLOG_on_) | 817 if (!VLOG_on_) |
| 818 return; | 818 return; |
| 819 if (prev_state_ == state_) | 819 if (prev_state_ == state_) |
| 820 return; | 820 return; |
| 821 prev_state_ = state_; | 821 prev_state_ = state_; |
| 822 const char* state_string = EnumStateToString(state_); | 822 const char* state_string = EnumStateToString(state_); |
| 823 VLOG(0) << "\n Function name: " << function_name | 823 VLOG(0) << "\n Function name: " << function_name |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 836 return; | 836 return; |
| 837 } | 837 } |
| 838 // The above statement prevents events of the same type and id from being | 838 // The above statement prevents events of the same type and id from being |
| 839 // printed in a row. However, if two fingers are down, they would both be | 839 // printed in a row. However, if two fingers are down, they would both be |
| 840 // moving and alternating printing move events unless we check for this. | 840 // moving and alternating printing move events unless we check for this. |
| 841 if (prev_event_ != NULL && | 841 if (prev_event_ != NULL && |
| 842 prev_event_->type() == ET_TOUCH_MOVED && | 842 prev_event_->type() == ET_TOUCH_MOVED && |
| 843 touch_event.type() == ET_TOUCH_MOVED){ | 843 touch_event.type() == ET_TOUCH_MOVED){ |
| 844 return; | 844 return; |
| 845 } | 845 } |
| 846 | |
| 846 const std::string& type = touch_event.name(); | 847 const std::string& type = touch_event.name(); |
| 847 const gfx::PointF& location = touch_event.location_f(); | 848 const gfx::PointF& location = touch_event.location_f(); |
| 848 const int touch_id = touch_event.touch_id(); | 849 const int touch_id = touch_event.touch_id(); |
| 849 | 850 |
| 850 VLOG(0) << "\n Function name: " << function_name | 851 VLOG(0) << "\n Function name: " << function_name |
| 851 << "\n Event Type: " << type | 852 << "\n Event Type: " << type |
| 852 << "\n Location: " << location.ToString() | 853 << "\n Location: " << location.ToString() |
| 853 << "\n Touch ID: " << touch_id; | 854 << "\n Touch ID: " << touch_id; |
| 854 prev_event_.reset(new TouchEvent(touch_event)); | 855 prev_event_.reset(new TouchEvent(touch_event)); |
| 855 } | 856 } |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 867 case DOUBLE_TAP_PENDING: | 868 case DOUBLE_TAP_PENDING: |
| 868 return "DOUBLE_TAP_PENDING"; | 869 return "DOUBLE_TAP_PENDING"; |
| 869 case TOUCH_RELEASE_PENDING: | 870 case TOUCH_RELEASE_PENDING: |
| 870 return "TOUCH_RELEASE_PENDING"; | 871 return "TOUCH_RELEASE_PENDING"; |
| 871 case TOUCH_EXPLORATION: | 872 case TOUCH_EXPLORATION: |
| 872 return "TOUCH_EXPLORATION"; | 873 return "TOUCH_EXPLORATION"; |
| 873 case GESTURE_IN_PROGRESS: | 874 case GESTURE_IN_PROGRESS: |
| 874 return "GESTURE_IN_PROGRESS"; | 875 return "GESTURE_IN_PROGRESS"; |
| 875 case TOUCH_EXPLORE_SECOND_PRESS: | 876 case TOUCH_EXPLORE_SECOND_PRESS: |
| 876 return "TOUCH_EXPLORE_SECOND_PRESS"; | 877 return "TOUCH_EXPLORE_SECOND_PRESS"; |
| 878 case ONE_FINGER_PASSTHROUGH: | |
| 879 return "ONE_FINGER_PASSTHROUGH"; | |
| 880 case WAIT_FOR_NO_FINGERS: | |
| 881 return "WAIT_FOR_NO_FINGERS"; | |
| 877 case SLIDE_GESTURE: | 882 case SLIDE_GESTURE: |
| 878 return "SLIDE_GESTURE"; | 883 return "SLIDE_GESTURE"; |
| 879 case ONE_FINGER_PASSTHROUGH: | |
| 880 return "ONE_FINGER_PASSTHROUGH"; | |
| 881 case WAIT_FOR_ONE_FINGER: | |
| 882 return "WAIT_FOR_ONE_FINGER"; | |
| 883 } | 884 } |
| 884 return "Not a state"; | 885 return "Not a state"; |
| 885 } | 886 } |
| 886 | 887 |
| 888 void TouchExplorationController::InitializeSwipeGestureMaps() { | |
| 889 // Gestures with one finger are used for navigation. | |
| 890 left_swipe_gestures_[1] = | |
| 891 base::Bind(&TouchExplorationController::DispatchShiftSearchKeyEvent, | |
| 892 base::Unretained(this), | |
| 893 ui::VKEY_LEFT); | |
| 894 right_swipe_gestures_[1] = | |
| 895 base::Bind(&TouchExplorationController::DispatchShiftSearchKeyEvent, | |
| 896 base::Unretained(this), | |
| 897 ui::VKEY_RIGHT); | |
| 898 up_swipe_gestures_[1] = | |
| 899 base::Bind(&TouchExplorationController::DispatchShiftSearchKeyEvent, | |
| 900 base::Unretained(this), | |
| 901 ui::VKEY_UP); | |
| 902 down_swipe_gestures_[1] = | |
| 903 base::Bind(&TouchExplorationController::DispatchShiftSearchKeyEvent, | |
| 904 base::Unretained(this), | |
| 905 ui::VKEY_DOWN); | |
| 906 | |
| 907 // Gestures with two fingers. | |
| 908 left_swipe_gestures_[2] = | |
| 909 base::Bind(&TouchExplorationController::DispatchKeyWithFlags, | |
| 910 base::Unretained(this), | |
| 911 ui::VKEY_BROWSER_BACK, | |
| 912 ui::EF_NONE); | |
| 913 right_swipe_gestures_[2] = | |
| 914 base::Bind(&TouchExplorationController::DispatchKeyWithFlags, | |
| 915 base::Unretained(this), | |
| 916 ui::VKEY_BROWSER_FORWARD, | |
| 917 ui::EF_NONE); | |
| 918 // Jump to top. | |
| 919 up_swipe_gestures_[2] = | |
| 920 base::Bind(&TouchExplorationController::DispatchShiftSearchKeyEvent, | |
| 921 base::Unretained(this), | |
| 922 ui::VKEY_A); | |
| 923 // Read from here. | |
| 924 down_swipe_gestures_[2] = | |
| 925 base::Bind(&TouchExplorationController::DispatchShiftSearchKeyEvent, | |
| 926 base::Unretained(this), | |
| 927 ui::VKEY_R); | |
| 928 | |
| 929 // Gestures with three fingers switch tabs left/right and scroll up/down. | |
| 930 left_swipe_gestures_[3] = | |
| 931 base::Bind(&TouchExplorationController::DispatchKeyWithFlags, | |
| 932 base::Unretained(this), | |
| 933 ui::VKEY_TAB, | |
| 934 ui::EF_CONTROL_DOWN | ui::EF_SHIFT_DOWN); | |
| 935 right_swipe_gestures_[3] = | |
| 936 base::Bind(&TouchExplorationController::DispatchKeyWithFlags, | |
| 937 base::Unretained(this), | |
| 938 ui::VKEY_TAB, | |
| 939 ui::EF_CONTROL_DOWN); | |
| 940 up_swipe_gestures_[3] = | |
| 941 base::Bind(&TouchExplorationController::DispatchKeyWithFlags, | |
| 942 base::Unretained(this), | |
| 943 ui::VKEY_NEXT, | |
| 944 ui::EF_NONE); | |
| 945 down_swipe_gestures_[3] = | |
| 946 base::Bind(&TouchExplorationController::DispatchKeyWithFlags, | |
| 947 base::Unretained(this), | |
| 948 ui::VKEY_PRIOR, | |
| 949 ui::EF_NONE); | |
| 950 | |
| 951 // Gestures with four fingers should probably eventually be used for rare | |
| 952 // needs that are hard to access through menus. | |
| 953 // Note that brightness levels are here because they can be important for low | |
| 954 // vision users. However, none of these mappings are permanent. | |
| 955 left_swipe_gestures_[4] = | |
| 956 base::Bind(&TouchExplorationController::DispatchKeyWithFlags, | |
| 957 base::Unretained(this), | |
| 958 ui::VKEY_BRIGHTNESS_DOWN, | |
| 959 ui::EF_NONE); | |
| 960 right_swipe_gestures_[4] = | |
| 961 base::Bind(&TouchExplorationController::DispatchKeyWithFlags, | |
| 962 base::Unretained(this), | |
| 963 VKEY_BRIGHTNESS_UP, | |
| 964 ui::EF_NONE); | |
| 965 up_swipe_gestures_[4] = | |
| 966 base::Bind(&TouchExplorationController::DispatchKeyWithFlags, | |
| 967 base::Unretained(this), | |
| 968 VKEY_BROWSER_HOME, | |
| 969 ui::EF_NONE); | |
| 970 down_swipe_gestures_[4] = | |
| 971 base::Bind(&TouchExplorationController::DispatchKeyWithFlags, | |
| 972 base::Unretained(this), | |
| 973 VKEY_BROWSER_REFRESH, | |
| 974 ui::EF_NONE); | |
| 975 | |
| 976 } | |
| 977 | |
| 887 } // namespace ui | 978 } // namespace ui |
| OLD | NEW |