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

Side by Side Diff: athena/wm/bezel_controller.cc

Issue 694883002: Do not allow split view to be engaged by a bezel gesture (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 years, 1 month 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
« no previous file with comments | « athena/wm/bezel_controller.h ('k') | athena/wm/split_view_controller.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "athena/wm/bezel_controller.h"
6
7 #include "ui/aura/window.h"
8 #include "ui/events/event_handler.h"
9 #include "ui/gfx/display.h"
10 #include "ui/gfx/geometry/point_conversions.h"
11 #include "ui/gfx/screen.h"
12 #include "ui/wm/core/coordinate_conversion.h"
13
14 namespace athena {
15 namespace {
16
17 // Using bezel swipes, the first touch that is registered is usually within
18 // 5-10 pixels from the edge, but sometimes as far as 29 pixels away.
19 // So setting this width fairly high for now.
20 const float kBezelWidth = 20.0f;
21
22 const float kScrollDeltaNone = 0;
23
24 bool ShouldProcessGesture(ui::EventType event_type) {
25 return event_type == ui::ET_GESTURE_SCROLL_UPDATE ||
26 event_type == ui::ET_GESTURE_SCROLL_BEGIN ||
27 event_type == ui::ET_GESTURE_BEGIN ||
28 event_type == ui::ET_GESTURE_END;
29 }
30
31 gfx::Display GetDisplay(aura::Window* window) {
32 gfx::Screen* screen = gfx::Screen::GetScreenFor(window);
33 return screen->GetDisplayNearestWindow(window);
34 }
35
36 float GetDistance(const gfx::PointF& location,
37 aura::Window* window,
38 BezelController::Bezel bezel) {
39 DCHECK(bezel == BezelController::BEZEL_LEFT ||
40 bezel == BezelController::BEZEL_RIGHT);
41 // Convert location from window coordinates to screen coordinates.
42 gfx::Point point_in_screen(gfx::ToRoundedPoint(location));
43 wm::ConvertPointToScreen(window, &point_in_screen);
44 return bezel == BezelController::BEZEL_LEFT
45 ? point_in_screen.x()
46 : point_in_screen.x() - GetDisplay(window).bounds().width();
47 }
48
49 // Returns the bezel corresponding to the |location| in |window| or BEZEL_NONE
50 // if the location is outside of the bezel area.
51 // Only implemented for LEFT and RIGHT bezels.
52 BezelController::Bezel GetBezel(const gfx::PointF& location,
53 aura::Window* window) {
54 int screen_width = GetDisplay(window).bounds().width();
55 gfx::Point point_in_screen(gfx::ToRoundedPoint(location));
56 wm::ConvertPointToScreen(window, &point_in_screen);
57 if (point_in_screen.x() < kBezelWidth)
58 return BezelController::BEZEL_LEFT;
59 if (point_in_screen.x() > screen_width - kBezelWidth)
60 return BezelController::BEZEL_RIGHT;
61 return BezelController::BEZEL_NONE;
62 }
63
64 } // namespace
65
66 BezelController::BezelController(aura::Window* container)
67 : container_(container),
68 state_(NONE),
69 scroll_bezel_(BEZEL_NONE),
70 scroll_target_(nullptr),
71 left_right_delegate_(nullptr) {
72 }
73
74 void BezelController::SetState(BezelController::State state) {
75 // Use SetState(State, float) if |state| is one of the BEZEL_SCROLLING states.
76 DCHECK_NE(state, BEZEL_SCROLLING_TWO_FINGERS);
77 DCHECK_NE(state, BEZEL_SCROLLING_ONE_FINGER);
78 SetState(state, kScrollDeltaNone);
79 }
80
81 void BezelController::SetState(BezelController::State state,
82 float scroll_delta) {
83 if (!left_right_delegate_ || state == state_)
84 return;
85
86 State old_state = state_;
87 state_ = state;
88
89 if (state == NONE) {
90 scroll_bezel_ = BEZEL_NONE;
91 scroll_target_ = nullptr;
92 }
93
94 if (state == BEZEL_SCROLLING_TWO_FINGERS) {
95 left_right_delegate_->BezelScrollBegin(scroll_bezel_, scroll_delta);
96 } else if (old_state == BEZEL_SCROLLING_TWO_FINGERS) {
97 // If BezelScrollEnd() hides |scroll_target_|, ET_GESTURE_END is dispatched
98 // and we get a reentrant call to SetState().
99 left_right_delegate_->BezelScrollEnd(0.0f);
100 }
101 }
102
103 void BezelController::OnGestureEvent(ui::GestureEvent* event) {
104 // TODO(mfomitchev): Currently we aren't retargetting or consuming any of the
105 // touch events. This means that content can prevent the generation of gesture
106 // events and two-finger scroll won't work. Possible solution to this problem
107 // is hosting our own gesture recognizer or retargetting touch events at the
108 // bezel.
109
110 if (!left_right_delegate_)
111 return;
112
113 ui::EventType type = event->type();
114 if (!ShouldProcessGesture(type))
115 return;
116
117 const ui::GestureEventDetails& event_details = event->details();
118 int num_touch_points = event_details.touch_points();
119 if (num_touch_points == 1 && type == ui::ET_GESTURE_BEGIN) {
120 // Reset the state when the first finger touches and starts a gesture.
121 // Normally, the state gets reset when the last finger is lifted and we
122 // receive ET_GESTURE_END. However ET_GESTURE_END doesn't always get
123 // dispatched. (E.g. if the gesture target was hidden or deleted).
124 // Since we can't rely on receiving ET_GESTURE_END when the last finger is
125 // lifted, we also reset the state on ET_GESTURE_BEGIN when the first
126 // finger touches the screen.
127 SetState(NONE);
128 }
129
130 if (scroll_target_ && event->target() != scroll_target_)
131 return;
132
133 const gfx::PointF& event_location = event->location_f();
134 float scroll_delta = kScrollDeltaNone;
135 aura::Window* target_window = static_cast<aura::Window*>(event->target());
136 if (scroll_bezel_ != BEZEL_NONE)
137 scroll_delta = GetDistance(event_location, target_window, scroll_bezel_);
138
139 if (type == ui::ET_GESTURE_BEGIN) {
140 if (num_touch_points > 2) {
141 SetState(IGNORE_CURRENT_SCROLL);
142 return;
143 }
144 BezelController::Bezel event_bezel =
145 GetBezel(event->location_f(), target_window);
146 switch (state_) {
147 case NONE:
148 scroll_bezel_ = event_bezel;
149 scroll_target_ = event->target();
150 if (event_bezel != BEZEL_LEFT && event_bezel != BEZEL_RIGHT)
151 SetState(IGNORE_CURRENT_SCROLL);
152 else
153 SetState(BEZEL_GESTURE_STARTED);
154 break;
155 case IGNORE_CURRENT_SCROLL:
156 break;
157 case BEZEL_GESTURE_STARTED:
158 case BEZEL_SCROLLING_ONE_FINGER:
159 DCHECK_EQ(num_touch_points, 2);
160 DCHECK(scroll_target_);
161 DCHECK_NE(scroll_bezel_, BEZEL_NONE);
162
163 if (event_bezel != scroll_bezel_) {
164 SetState(IGNORE_CURRENT_SCROLL);
165 return;
166 }
167 if (state_ == BEZEL_SCROLLING_ONE_FINGER)
168 SetState(BEZEL_SCROLLING_TWO_FINGERS);
169 break;
170 case BEZEL_SCROLLING_TWO_FINGERS:
171 // Should've exited above
172 NOTREACHED();
173 break;
174 }
175 } else if (type == ui::ET_GESTURE_END) {
176 if (state_ == NONE)
177 return;
178
179 CHECK(scroll_target_);
180 if (num_touch_points == 1) {
181 SetState(NONE);
182 } else {
183 SetState(IGNORE_CURRENT_SCROLL);
184 }
185 } else if (type == ui::ET_GESTURE_SCROLL_BEGIN) {
186 DCHECK(state_ == IGNORE_CURRENT_SCROLL || state_ == BEZEL_GESTURE_STARTED);
187 if (state_ != BEZEL_GESTURE_STARTED)
188 return;
189
190 if (num_touch_points == 1) {
191 SetState(BEZEL_SCROLLING_ONE_FINGER, scroll_delta);
192 return;
193 }
194
195 DCHECK_EQ(num_touch_points, 2);
196 SetState(BEZEL_SCROLLING_TWO_FINGERS, scroll_delta);
197 if (left_right_delegate_->BezelCanScroll())
198 event->SetHandled();
199 } else if (type == ui::ET_GESTURE_SCROLL_UPDATE) {
200 if (state_ != BEZEL_SCROLLING_TWO_FINGERS)
201 return;
202
203 left_right_delegate_->BezelScrollUpdate(scroll_delta);
204 if (left_right_delegate_->BezelCanScroll())
205 event->SetHandled();
206 }
207 }
208
209 } // namespace athena
OLDNEW
« no previous file with comments | « athena/wm/bezel_controller.h ('k') | athena/wm/split_view_controller.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698