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

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

Issue 1953613002: Make touch accessibility gestures work with ChromeVox Next (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebase Created 4 years, 7 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"
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
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:
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698