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 <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" |
11 #include "base/time/default_tick_clock.h" | 11 #include "base/time/default_tick_clock.h" |
12 #include "ui/accessibility/ax_enums.h" | |
12 #include "ui/aura/client/cursor_client.h" | 13 #include "ui/aura/client/cursor_client.h" |
13 #include "ui/aura/window.h" | 14 #include "ui/aura/window.h" |
14 #include "ui/aura/window_event_dispatcher.h" | 15 #include "ui/aura/window_event_dispatcher.h" |
15 #include "ui/aura/window_tree_host.h" | 16 #include "ui/aura/window_tree_host.h" |
16 #include "ui/events/event.h" | 17 #include "ui/events/event.h" |
17 #include "ui/events/event_processor.h" | 18 #include "ui/events/event_processor.h" |
18 #include "ui/events/event_utils.h" | 19 #include "ui/events/event_utils.h" |
19 #include "ui/gfx/geometry/rect.h" | 20 #include "ui/gfx/geometry/rect.h" |
20 | 21 |
21 #define SET_STATE(state) SetState(state, __func__) | 22 #define SET_STATE(state) SetState(state, __func__) |
22 #define VLOG_EVENT(event) if (VLOG_IS_ON(0)) VlogEvent(event, __func__) | 23 #define VLOG_EVENT(event) if (VLOG_IS_ON(0)) VlogEvent(event, __func__) |
23 | 24 |
24 namespace ui { | 25 namespace ui { |
25 | 26 |
26 namespace { | 27 namespace { |
27 | 28 |
28 // Delay between adjustment sounds. | 29 // Delay between adjustment sounds. |
29 const int kSoundDelayInMS = 150; | 30 const int kSoundDelayInMS = 150; |
30 | 31 |
31 // In ChromeOS, VKEY_LWIN is synonymous for the search key. | |
32 const ui::KeyboardCode kChromeOSSearchKey = ui::VKEY_LWIN; | |
33 | |
34 } // namespace | 32 } // namespace |
35 | 33 |
36 TouchExplorationController::TouchExplorationController( | 34 TouchExplorationController::TouchExplorationController( |
37 aura::Window* root_window, | 35 aura::Window* root_window, |
38 TouchExplorationControllerDelegate* delegate) | 36 TouchExplorationControllerDelegate* delegate) |
39 : root_window_(root_window), | 37 : root_window_(root_window), |
40 delegate_(delegate), | 38 delegate_(delegate), |
41 state_(NO_FINGERS_DOWN), | 39 state_(NO_FINGERS_DOWN), |
42 gesture_provider_(new GestureProviderAura(this, this)), | 40 gesture_provider_(new GestureProviderAura(this, this)), |
43 prev_state_(NO_FINGERS_DOWN), | 41 prev_state_(NO_FINGERS_DOWN), |
44 VLOG_on_(true), | 42 VLOG_on_(true), |
45 tick_clock_(NULL) { | 43 tick_clock_(NULL) { |
46 DCHECK(root_window); | 44 DCHECK(root_window); |
47 root_window->GetHost()->GetEventSource()->AddEventRewriter(this); | 45 root_window->GetHost()->GetEventSource()->AddEventRewriter(this); |
48 InitializeSwipeGestureMaps(); | |
49 } | 46 } |
50 | 47 |
51 TouchExplorationController::~TouchExplorationController() { | 48 TouchExplorationController::~TouchExplorationController() { |
52 root_window_->GetHost()->GetEventSource()->RemoveEventRewriter(this); | 49 root_window_->GetHost()->GetEventSource()->RemoveEventRewriter(this); |
53 } | 50 } |
54 | 51 |
55 ui::EventRewriteStatus TouchExplorationController::RewriteEvent( | 52 ui::EventRewriteStatus TouchExplorationController::RewriteEvent( |
56 const ui::Event& event, | 53 const ui::Event& event, |
57 std::unique_ptr<ui::Event>* rewritten_event) { | 54 std::unique_ptr<ui::Event>* rewritten_event) { |
58 if (!event.IsTouchEvent()) { | 55 if (!event.IsTouchEvent()) { |
(...skipping 807 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
866 void TouchExplorationController::OnSwipeEvent(ui::GestureEvent* swipe_gesture) { | 863 void TouchExplorationController::OnSwipeEvent(ui::GestureEvent* swipe_gesture) { |
867 // A swipe gesture contains details for the direction in which the swipe | 864 // A swipe gesture contains details for the direction in which the swipe |
868 // occurred. TODO(evy) : Research which swipe results users most want and | 865 // occurred. TODO(evy) : Research which swipe results users most want and |
869 // remap these swipes to the best events. Hopefully in the near future | 866 // remap these swipes to the best events. Hopefully in the near future |
870 // there will also be a menu for users to pick custom mappings. | 867 // there will also be a menu for users to pick custom mappings. |
871 GestureEventDetails event_details = swipe_gesture->details(); | 868 GestureEventDetails event_details = swipe_gesture->details(); |
872 int num_fingers = event_details.touch_points(); | 869 int num_fingers = event_details.touch_points(); |
873 if (VLOG_on_) | 870 if (VLOG_on_) |
874 VLOG(0) << "\nSwipe with " << num_fingers << " fingers."; | 871 VLOG(0) << "\nSwipe with " << num_fingers << " fingers."; |
875 | 872 |
876 if (num_fingers > 4) | 873 ui::AXGesture gesture = ui::AX_GESTURE_NONE; |
877 return; | 874 if (event_details.swipe_left()) { |
875 switch (num_fingers) { | |
876 case 1: | |
877 gesture = ui::AX_GESTURE_SWIPE_LEFT_1; | |
878 break; | |
879 case 2: | |
880 gesture = ui::AX_GESTURE_SWIPE_LEFT_2; | |
881 break; | |
882 case 3: | |
883 gesture = ui::AX_GESTURE_SWIPE_LEFT_3; | |
884 break; | |
885 case 4: | |
886 gesture = ui::AX_GESTURE_SWIPE_LEFT_4; | |
887 break; | |
888 default: | |
oshima
2016/05/06 19:43:50
qq: this (5 fingers or more) can happen?
dmazzoni
2016/05/09 18:07:08
Yes, it can, we just don't intend to map 5 finger
| |
889 break; | |
890 } | |
891 } else if (event_details.swipe_up()) { | |
892 switch (num_fingers) { | |
893 case 1: | |
894 gesture = ui::AX_GESTURE_SWIPE_UP_1; | |
895 break; | |
896 case 2: | |
897 gesture = ui::AX_GESTURE_SWIPE_UP_2; | |
898 break; | |
899 case 3: | |
900 gesture = ui::AX_GESTURE_SWIPE_UP_3; | |
901 break; | |
902 case 4: | |
903 gesture = ui::AX_GESTURE_SWIPE_UP_4; | |
904 break; | |
905 default: | |
906 break; | |
907 } | |
908 } else if (event_details.swipe_right()) { | |
909 switch (num_fingers) { | |
910 case 1: | |
911 gesture = ui::AX_GESTURE_SWIPE_RIGHT_1; | |
912 break; | |
913 case 2: | |
914 gesture = ui::AX_GESTURE_SWIPE_RIGHT_2; | |
915 break; | |
916 case 3: | |
917 gesture = ui::AX_GESTURE_SWIPE_RIGHT_3; | |
918 break; | |
919 case 4: | |
920 gesture = ui::AX_GESTURE_SWIPE_RIGHT_4; | |
921 break; | |
922 default: | |
923 break; | |
924 } | |
925 } else if (event_details.swipe_down()) { | |
926 switch (num_fingers) { | |
927 case 1: | |
928 gesture = ui::AX_GESTURE_SWIPE_DOWN_1; | |
929 break; | |
930 case 2: | |
931 gesture = ui::AX_GESTURE_SWIPE_DOWN_2; | |
932 break; | |
933 case 3: | |
934 gesture = ui::AX_GESTURE_SWIPE_DOWN_3; | |
935 break; | |
936 case 4: | |
937 gesture = ui::AX_GESTURE_SWIPE_DOWN_4; | |
938 break; | |
939 default: | |
940 break; | |
941 } | |
942 } | |
878 | 943 |
879 if (event_details.swipe_left() && | 944 if (gesture != ui::AX_GESTURE_NONE) |
880 !left_swipe_gestures_[num_fingers].is_null()) { | 945 delegate_->HandleAccessibilityGesture(gesture); |
881 left_swipe_gestures_[num_fingers].Run(); | |
882 } else if (event_details.swipe_right() && | |
883 !right_swipe_gestures_[num_fingers].is_null()) { | |
884 right_swipe_gestures_[num_fingers].Run(); | |
885 } else if (event_details.swipe_up() && | |
886 !up_swipe_gestures_[num_fingers].is_null()) { | |
887 up_swipe_gestures_[num_fingers].Run(); | |
888 } else if (event_details.swipe_down() && | |
889 !down_swipe_gestures_[num_fingers].is_null()) { | |
890 down_swipe_gestures_[num_fingers].Run(); | |
891 } | |
892 } | 946 } |
893 | 947 |
894 int TouchExplorationController::FindEdgesWithinBounds(gfx::Point point, | 948 int TouchExplorationController::FindEdgesWithinBounds(gfx::Point point, |
895 float bounds) { | 949 float bounds) { |
896 // Since GetBoundsInScreen is in DIPs but point is not, then point needs to be | 950 // Since GetBoundsInScreen is in DIPs but point is not, then point needs to be |
897 // converted. | 951 // converted. |
898 root_window_->GetHost()->ConvertPointFromNativeScreen(&point); | 952 root_window_->GetHost()->ConvertPointFromNativeScreen(&point); |
899 gfx::Rect window = root_window_->GetBoundsInScreen(); | 953 gfx::Rect window = root_window_->GetBoundsInScreen(); |
900 | 954 |
901 float left_edge_limit = window.x() + bounds; | 955 float left_edge_limit = window.x() + bounds; |
(...skipping 10 matching lines...) Expand all Loading... | |
912 result |= LEFT_EDGE; | 966 result |= LEFT_EDGE; |
913 if (point.x() > right_edge_limit) | 967 if (point.x() > right_edge_limit) |
914 result |= RIGHT_EDGE; | 968 result |= RIGHT_EDGE; |
915 if (point.y() < top_edge_limit) | 969 if (point.y() < top_edge_limit) |
916 result |= TOP_EDGE; | 970 result |= TOP_EDGE; |
917 if (point.y() > bottom_edge_limit) | 971 if (point.y() > bottom_edge_limit) |
918 result |= BOTTOM_EDGE; | 972 result |= BOTTOM_EDGE; |
919 return result; | 973 return result; |
920 } | 974 } |
921 | 975 |
922 void TouchExplorationController::DispatchShiftSearchKeyEvent( | |
923 const ui::KeyboardCode third_key) { | |
924 // In order to activate the shortcut shift+search+<arrow key> | |
925 // three KeyPressed events must be dispatched in succession along | |
926 // with three KeyReleased events. | |
927 | |
928 ui::KeyEvent shift_down( | |
929 ui::ET_KEY_PRESSED, ui::VKEY_SHIFT, ui::EF_SHIFT_DOWN); | |
930 ui::KeyEvent search_down( | |
931 ui::ET_KEY_PRESSED, kChromeOSSearchKey, ui::EF_SHIFT_DOWN); | |
932 ui::KeyEvent third_key_down(ui::ET_KEY_PRESSED, third_key, ui::EF_SHIFT_DOWN); | |
933 | |
934 ui::KeyEvent third_key_up(ui::ET_KEY_RELEASED, third_key, ui::EF_SHIFT_DOWN); | |
935 ui::KeyEvent search_up( | |
936 ui::ET_KEY_RELEASED, kChromeOSSearchKey, ui::EF_SHIFT_DOWN); | |
937 ui ::KeyEvent shift_up(ui::ET_KEY_RELEASED, ui::VKEY_SHIFT, ui::EF_NONE); | |
938 | |
939 DispatchEvent(&shift_down); | |
940 DispatchEvent(&search_down); | |
941 DispatchEvent(&third_key_down); | |
942 DispatchEvent(&third_key_up); | |
943 DispatchEvent(&search_up); | |
944 DispatchEvent(&shift_up); | |
945 } | |
946 | |
947 base::Closure TouchExplorationController::BindShiftSearchKeyEvent( | |
948 const ui::KeyboardCode third_key) { | |
949 return base::Bind(&TouchExplorationController::DispatchShiftSearchKeyEvent, | |
950 base::Unretained(this), | |
951 third_key); | |
952 } | |
953 | |
954 void TouchExplorationController::DispatchKeyWithFlags( | 976 void TouchExplorationController::DispatchKeyWithFlags( |
955 const ui::KeyboardCode key, | 977 const ui::KeyboardCode key, |
956 int flags) { | 978 int flags) { |
957 ui::KeyEvent key_down(ui::ET_KEY_PRESSED, key, flags); | 979 ui::KeyEvent key_down(ui::ET_KEY_PRESSED, key, flags); |
958 ui::KeyEvent key_up(ui::ET_KEY_RELEASED, key, flags); | 980 ui::KeyEvent key_up(ui::ET_KEY_RELEASED, key, flags); |
959 DispatchEvent(&key_down); | 981 DispatchEvent(&key_down); |
960 DispatchEvent(&key_up); | 982 DispatchEvent(&key_up); |
961 if (VLOG_on_) { | 983 if (VLOG_on_) { |
962 VLOG(0) << "\nKey down: key code : " << key_down.key_code() | 984 VLOG(0) << "\nKey down: key code : " << key_down.key_code() |
963 << ", flags: " << key_down.flags() | 985 << ", flags: " << key_down.flags() |
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1115 case ONE_FINGER_PASSTHROUGH: | 1137 case ONE_FINGER_PASSTHROUGH: |
1116 return "ONE_FINGER_PASSTHROUGH"; | 1138 return "ONE_FINGER_PASSTHROUGH"; |
1117 case WAIT_FOR_NO_FINGERS: | 1139 case WAIT_FOR_NO_FINGERS: |
1118 return "WAIT_FOR_NO_FINGERS"; | 1140 return "WAIT_FOR_NO_FINGERS"; |
1119 case TWO_FINGER_TAP: | 1141 case TWO_FINGER_TAP: |
1120 return "TWO_FINGER_TAP"; | 1142 return "TWO_FINGER_TAP"; |
1121 } | 1143 } |
1122 return "Not a state"; | 1144 return "Not a state"; |
1123 } | 1145 } |
1124 | 1146 |
1125 // TODO(evy, lisayin) : Just call abstracted methods on the delegate (e.g. | |
1126 // Swipe(Direction direction, int num_fingers)), and add the DispatchXYZ | |
1127 // methods to the delegate. Avoid the middle step of dispatching keys at all, | |
1128 // and simply have ChromeVox/ChromeOS complete the required action. | |
1129 | |
1130 void TouchExplorationController::InitializeSwipeGestureMaps() { | |
1131 // Gestures with one finger are used for navigation. | |
1132 left_swipe_gestures_[1] = BindShiftSearchKeyEvent(ui::VKEY_LEFT); | |
1133 right_swipe_gestures_[1] = BindShiftSearchKeyEvent(ui::VKEY_RIGHT); | |
1134 up_swipe_gestures_[1] = BindShiftSearchKeyEvent(ui::VKEY_UP); | |
1135 down_swipe_gestures_[1] = BindShiftSearchKeyEvent(ui::VKEY_DOWN); | |
1136 | |
1137 // Gestures with two fingers. | |
1138 left_swipe_gestures_[2] = | |
1139 BindKeyEventWithFlags(ui::VKEY_BROWSER_BACK, ui::EF_NONE); | |
1140 right_swipe_gestures_[2] = | |
1141 BindKeyEventWithFlags(ui::VKEY_BROWSER_FORWARD, ui::EF_NONE); | |
1142 // Jump to top. | |
1143 up_swipe_gestures_[2] = BindShiftSearchKeyEvent(ui::VKEY_A); | |
1144 // Read from here. | |
1145 down_swipe_gestures_[2] = BindShiftSearchKeyEvent(ui::VKEY_R); | |
1146 | |
1147 // Gestures with three fingers switch tabs left/right and scroll up/down. | |
1148 left_swipe_gestures_[3] = BindKeyEventWithFlags( | |
1149 ui::VKEY_TAB, ui::EF_CONTROL_DOWN | ui::EF_SHIFT_DOWN); | |
1150 right_swipe_gestures_[3] = | |
1151 BindKeyEventWithFlags(ui::VKEY_TAB, ui::EF_CONTROL_DOWN); | |
1152 up_swipe_gestures_[3] = BindKeyEventWithFlags(ui::VKEY_NEXT, ui::EF_NONE); | |
1153 down_swipe_gestures_[3] = BindKeyEventWithFlags(ui::VKEY_PRIOR, ui::EF_NONE); | |
1154 | |
1155 // Gestures with four fingers should probably eventually be used for rare | |
1156 // needs that are hard to access through menus. | |
1157 // Note that brightness levels are here because they can be important for low | |
1158 // vision users. However, none of these mappings are permanent. | |
1159 left_swipe_gestures_[4] = | |
1160 BindKeyEventWithFlags(ui::VKEY_BRIGHTNESS_DOWN, ui::EF_NONE); | |
1161 right_swipe_gestures_[4] = | |
1162 BindKeyEventWithFlags(VKEY_BRIGHTNESS_UP, ui::EF_NONE); | |
1163 up_swipe_gestures_[4] = BindKeyEventWithFlags(VKEY_BROWSER_HOME, ui::EF_NONE); | |
1164 down_swipe_gestures_[4] = | |
1165 BindKeyEventWithFlags(VKEY_BROWSER_REFRESH, ui::EF_NONE); | |
1166 } | |
1167 | |
1168 float TouchExplorationController::GetSplitTapTouchSlop() { | 1147 float TouchExplorationController::GetSplitTapTouchSlop() { |
1169 return gesture_detector_config_.touch_slop * 3; | 1148 return gesture_detector_config_.touch_slop * 3; |
1170 } | 1149 } |
1171 | 1150 |
1172 } // namespace ui | 1151 } // namespace ui |
OLD | NEW |