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

Side by Side Diff: ui/views/widget/root_view.cc

Issue 12207092: views: Dispatch key, touch, scroll and gesture events using the EventDispatch interface. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: tot-merge-before-land Created 7 years, 10 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 | Annotate | Revision Log
« no previous file with comments | « ui/views/widget/root_view.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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/views/widget/root_view.h" 5 #include "ui/views/widget/root_view.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "base/message_loop.h" 10 #include "base/message_loop.h"
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
64 last_click_handler_(NULL), 64 last_click_handler_(NULL),
65 explicit_mouse_handler_(false), 65 explicit_mouse_handler_(false),
66 last_mouse_event_flags_(0), 66 last_mouse_event_flags_(0),
67 last_mouse_event_x_(-1), 67 last_mouse_event_x_(-1),
68 last_mouse_event_y_(-1), 68 last_mouse_event_y_(-1),
69 touch_pressed_handler_(NULL), 69 touch_pressed_handler_(NULL),
70 gesture_handler_(NULL), 70 gesture_handler_(NULL),
71 scroll_gesture_handler_(NULL), 71 scroll_gesture_handler_(NULL),
72 ALLOW_THIS_IN_INITIALIZER_LIST(focus_search_(this, false, false)), 72 ALLOW_THIS_IN_INITIALIZER_LIST(focus_search_(this, false, false)),
73 focus_traversable_parent_(NULL), 73 focus_traversable_parent_(NULL),
74 focus_traversable_parent_view_(NULL) { 74 focus_traversable_parent_view_(NULL),
75 event_dispatch_target_(NULL) {
75 } 76 }
76 77
77 RootView::~RootView() { 78 RootView::~RootView() {
78 // If we have children remove them explicitly so to make sure a remove 79 // If we have children remove them explicitly so to make sure a remove
79 // notification is sent for each one of them. 80 // notification is sent for each one of them.
80 if (has_children()) 81 if (has_children())
81 RemoveAllChildViews(true); 82 RemoveAllChildViews(true);
82 } 83 }
83 84
84 // Tree operations ------------------------------------------------------------- 85 // Tree operations -------------------------------------------------------------
(...skipping 20 matching lines...) Expand all
105 } 106 }
106 107
107 void RootView::NotifyNativeViewHierarchyChanged(bool attached, 108 void RootView::NotifyNativeViewHierarchyChanged(bool attached,
108 gfx::NativeView native_view) { 109 gfx::NativeView native_view) {
109 PropagateNativeViewHierarchyChanged(attached, native_view, this); 110 PropagateNativeViewHierarchyChanged(attached, native_view, this);
110 } 111 }
111 112
112 // Input ----------------------------------------------------------------------- 113 // Input -----------------------------------------------------------------------
113 114
114 void RootView::DispatchKeyEvent(ui::KeyEvent* event) { 115 void RootView::DispatchKeyEvent(ui::KeyEvent* event) {
115 bool consumed = false;
116
117 View* v = NULL; 116 View* v = NULL;
118 if (GetFocusManager()) // NULL in unittests. 117 if (GetFocusManager()) // NULL in unittests.
119 v = GetFocusManager()->GetFocusedView(); 118 v = GetFocusManager()->GetFocusedView();
120 // Special case to handle right-click context menus triggered by the 119 // Special case to handle right-click context menus triggered by the
121 // keyboard. 120 // keyboard.
122 if (v && v->enabled() && ((event->key_code() == ui::VKEY_APPS) || 121 if (v && v->enabled() && ((event->key_code() == ui::VKEY_APPS) ||
123 (event->key_code() == ui::VKEY_F10 && event->IsShiftDown()))) { 122 (event->key_code() == ui::VKEY_F10 && event->IsShiftDown()))) {
124 v->ShowContextMenu(v->GetKeyboardContextMenuLocation(), false); 123 v->ShowContextMenu(v->GetKeyboardContextMenuLocation(), false);
125 event->StopPropagation(); 124 event->StopPropagation();
126 return; 125 return;
127 } 126 }
128 for (; v && v != this && !consumed; v = v->parent()) {
129 consumed = (event->type() == ui::ET_KEY_PRESSED) ?
130 v->OnKeyPressed(*event) : v->OnKeyReleased(*event);
131 }
132 127
133 if (consumed) 128 for (; v && v != this && !event->handled(); v = v->parent())
134 event->StopPropagation(); 129 DispatchEventToTarget(v, event);
135 } 130 }
136 131
137 void RootView::DispatchScrollEvent(ui::ScrollEvent* event) { 132 void RootView::DispatchScrollEvent(ui::ScrollEvent* event) {
138 for (View* v = GetEventHandlerForPoint(event->location()); 133 for (View* v = GetEventHandlerForPoint(event->location());
139 v && v != this && !event->stopped_propagation(); v = v->parent()) { 134 v && v != this && !event->stopped_propagation(); v = v->parent()) {
140 v->OnScrollEvent(event); 135 DispatchEventToTarget(v, event);
141 } 136 }
142 137
143 if (event->handled() || event->type() != ui::ET_SCROLL) 138 if (event->handled() || event->type() != ui::ET_SCROLL)
144 return; 139 return;
145 140
146 // Convert unprocessed scroll events into mouse-wheel events. Note that 141 // Convert unprocessed scroll events into mouse-wheel events. Note that
147 // wheel events are normally sent to the focused view. However, if the focused 142 // wheel events are normally sent to the focused view. However, if the focused
148 // view does not process these wheel events, then dispatch them to the view 143 // view does not process these wheel events, then dispatch them to the view
149 // under the cursor. 144 // under the cursor.
150 ui::MouseWheelEvent wheel(*event); 145 ui::MouseWheelEvent wheel(*event);
(...skipping 19 matching lines...) Expand all
170 // view and target that view with all touches with the same id until the 165 // view and target that view with all touches with the same id until the
171 // release (or keep it if captured). 166 // release (or keep it if captured).
172 167
173 // If touch_pressed_handler_ is non null, we are currently processing 168 // If touch_pressed_handler_ is non null, we are currently processing
174 // a touch down on the screen situation. In that case we send the 169 // a touch down on the screen situation. In that case we send the
175 // event to touch_pressed_handler_ 170 // event to touch_pressed_handler_
176 171
177 if (touch_pressed_handler_) { 172 if (touch_pressed_handler_) {
178 ui::TouchEvent touch_event(*event, static_cast<View*>(this), 173 ui::TouchEvent touch_event(*event, static_cast<View*>(this),
179 touch_pressed_handler_); 174 touch_pressed_handler_);
180 touch_pressed_handler_->ProcessTouchEvent(&touch_event); 175 DispatchEventToTarget(touch_pressed_handler_, &touch_event);
181 if (touch_event.handled()) 176 if (touch_event.handled())
182 event->SetHandled(); 177 event->SetHandled();
183 if (touch_event.stopped_propagation()) 178 if (touch_event.stopped_propagation())
184 event->StopPropagation(); 179 event->StopPropagation();
185 return; 180 return;
186 } 181 }
187 182
188 // Walk up the tree until we find a view that wants the touch event. 183 // Walk up the tree until we find a view that wants the touch event.
189 for (touch_pressed_handler_ = GetEventHandlerForPoint(event->location()); 184 for (touch_pressed_handler_ = GetEventHandlerForPoint(event->location());
190 touch_pressed_handler_ && (touch_pressed_handler_ != this); 185 touch_pressed_handler_ && (touch_pressed_handler_ != this);
191 touch_pressed_handler_ = touch_pressed_handler_->parent()) { 186 touch_pressed_handler_ = touch_pressed_handler_->parent()) {
192 if (!touch_pressed_handler_->enabled()) { 187 if (!touch_pressed_handler_->enabled()) {
193 // Disabled views eat events but are treated as not handled. 188 // Disabled views eat events but are treated as not handled.
194 break; 189 break;
195 } 190 }
196 191
197 // See if this view wants to handle the touch 192 // See if this view wants to handle the touch
198 ui::TouchEvent touch_event(*event, static_cast<View*>(this), 193 ui::TouchEvent touch_event(*event, static_cast<View*>(this),
199 touch_pressed_handler_); 194 touch_pressed_handler_);
200 touch_pressed_handler_->ProcessTouchEvent(&touch_event); 195 DispatchEventToTarget(touch_pressed_handler_, &touch_event);
201 if (touch_event.handled()) 196 if (touch_event.handled())
202 event->SetHandled(); 197 event->SetHandled();
203 if (touch_event.stopped_propagation()) 198 if (touch_event.stopped_propagation())
204 event->StopPropagation(); 199 event->StopPropagation();
205 200
206 // The view could have removed itself from the tree when handling 201 // The view could have removed itself from the tree when handling
207 // OnTouchEvent(). So handle as per OnMousePressed. NB: we 202 // OnTouchEvent(). So handle as per OnMousePressed. NB: we
208 // assume that the RootView itself cannot be so removed. 203 // assume that the RootView itself cannot be so removed.
209 if (!touch_pressed_handler_) 204 if (!touch_pressed_handler_)
210 break; 205 break;
(...skipping 18 matching lines...) Expand all
229 } 224 }
230 225
231 void RootView::DispatchGestureEvent(ui::GestureEvent* event) { 226 void RootView::DispatchGestureEvent(ui::GestureEvent* event) {
232 if (gesture_handler_) { 227 if (gesture_handler_) {
233 // |gesture_handler_| (or |scroll_gesture_handler_|) can be deleted during 228 // |gesture_handler_| (or |scroll_gesture_handler_|) can be deleted during
234 // processing. 229 // processing.
235 View* handler = scroll_gesture_handler_ && 230 View* handler = scroll_gesture_handler_ &&
236 (event->IsScrollGestureEvent() || event->IsFlingScrollEvent()) ? 231 (event->IsScrollGestureEvent() || event->IsFlingScrollEvent()) ?
237 scroll_gesture_handler_ : gesture_handler_; 232 scroll_gesture_handler_ : gesture_handler_;
238 ui::GestureEvent handler_event(*event, static_cast<View*>(this), handler); 233 ui::GestureEvent handler_event(*event, static_cast<View*>(this), handler);
239 handler->ProcessGestureEvent(&handler_event); 234 DispatchEventToTarget(handler, &handler_event);
240 235
241 if (event->type() == ui::ET_GESTURE_END && 236 if (event->type() == ui::ET_GESTURE_END &&
242 event->details().touch_points() <= 1) { 237 event->details().touch_points() <= 1) {
243 // In case a drag was in progress, reset all the handlers. Otherwise, just 238 // In case a drag was in progress, reset all the handlers. Otherwise, just
244 // reset the gesture handler. 239 // reset the gesture handler.
245 if (gesture_handler_ == mouse_pressed_handler_) 240 if (gesture_handler_ == mouse_pressed_handler_)
246 SetMouseHandler(NULL); 241 SetMouseHandler(NULL);
247 else 242 else
248 gesture_handler_ = NULL; 243 gesture_handler_ = NULL;
249 } 244 }
(...skipping 16 matching lines...) Expand all
266 !scroll_gesture_handler_) { 261 !scroll_gesture_handler_) {
267 // Some view started processing gesture events, however it does not 262 // Some view started processing gesture events, however it does not
268 // process scroll-gesture events. In such case, we allow the event to 263 // process scroll-gesture events. In such case, we allow the event to
269 // bubble up, and install a different scroll-gesture handler different 264 // bubble up, and install a different scroll-gesture handler different
270 // from the default gesture handler. 265 // from the default gesture handler.
271 for (scroll_gesture_handler_ = gesture_handler_->parent(); 266 for (scroll_gesture_handler_ = gesture_handler_->parent();
272 scroll_gesture_handler_ && scroll_gesture_handler_ != this; 267 scroll_gesture_handler_ && scroll_gesture_handler_ != this;
273 scroll_gesture_handler_ = scroll_gesture_handler_->parent()) { 268 scroll_gesture_handler_ = scroll_gesture_handler_->parent()) {
274 ui::GestureEvent gesture_event(*event, static_cast<View*>(this), 269 ui::GestureEvent gesture_event(*event, static_cast<View*>(this),
275 scroll_gesture_handler_); 270 scroll_gesture_handler_);
276 scroll_gesture_handler_->ProcessGestureEvent(&gesture_event); 271 DispatchEventToTarget(scroll_gesture_handler_, &gesture_event);
277 if (gesture_event.stopped_propagation()) { 272 if (gesture_event.stopped_propagation()) {
278 event->StopPropagation(); 273 event->StopPropagation();
279 return; 274 return;
280 } else if (gesture_event.handled()) { 275 } else if (gesture_event.handled()) {
281 event->SetHandled(); 276 event->SetHandled();
282 return; 277 return;
283 } 278 }
284 } 279 }
285 scroll_gesture_handler_ = NULL; 280 scroll_gesture_handler_ = NULL;
286 } 281 }
(...skipping 17 matching lines...) Expand all
304 gesture_handler_ && (gesture_handler_ != this); 299 gesture_handler_ && (gesture_handler_ != this);
305 gesture_handler_ = gesture_handler_->parent()) { 300 gesture_handler_ = gesture_handler_->parent()) {
306 if (!gesture_handler_->enabled()) { 301 if (!gesture_handler_->enabled()) {
307 // Disabled views eat events but are treated as not handled. 302 // Disabled views eat events but are treated as not handled.
308 return; 303 return;
309 } 304 }
310 305
311 // See if this view wants to handle the Gesture. 306 // See if this view wants to handle the Gesture.
312 ui::GestureEvent gesture_event(*event, static_cast<View*>(this), 307 ui::GestureEvent gesture_event(*event, static_cast<View*>(this),
313 gesture_handler_); 308 gesture_handler_);
314 gesture_handler_->ProcessGestureEvent(&gesture_event); 309 DispatchEventToTarget(gesture_handler_, &gesture_event);
315 310
316 // The view could have removed itself from the tree when handling 311 // The view could have removed itself from the tree when handling
317 // OnGestureEvent(). So handle as per OnMousePressed. NB: we 312 // OnGestureEvent(). So handle as per OnMousePressed. NB: we
318 // assume that the RootView itself cannot be so removed. 313 // assume that the RootView itself cannot be so removed.
319 if (!gesture_handler_) 314 if (!gesture_handler_)
320 return; 315 return;
321 316
322 if (gesture_event.handled()) { 317 if (gesture_event.handled()) {
323 if (gesture_event.type() == ui::ET_GESTURE_SCROLL_BEGIN) 318 if (gesture_event.type() == ui::ET_GESTURE_SCROLL_BEGIN)
324 scroll_gesture_handler_ = gesture_handler_; 319 scroll_gesture_handler_ = gesture_handler_;
(...skipping 300 matching lines...) Expand 10 before | Expand all | Expand 10 after
625 if (!explicit_mouse_handler_ && mouse_pressed_handler_ == child) 620 if (!explicit_mouse_handler_ && mouse_pressed_handler_ == child)
626 mouse_pressed_handler_ = NULL; 621 mouse_pressed_handler_ = NULL;
627 if (mouse_move_handler_ == child) 622 if (mouse_move_handler_ == child)
628 mouse_move_handler_ = NULL; 623 mouse_move_handler_ = NULL;
629 if (touch_pressed_handler_ == child) 624 if (touch_pressed_handler_ == child)
630 touch_pressed_handler_ = NULL; 625 touch_pressed_handler_ = NULL;
631 if (gesture_handler_ == child) 626 if (gesture_handler_ == child)
632 gesture_handler_ = NULL; 627 gesture_handler_ = NULL;
633 if (scroll_gesture_handler_ == child) 628 if (scroll_gesture_handler_ == child)
634 scroll_gesture_handler_ = NULL; 629 scroll_gesture_handler_ = NULL;
630 if (event_dispatch_target_ == child)
631 event_dispatch_target_ = NULL;
635 } 632 }
636 } 633 }
637 634
638 void RootView::OnPaint(gfx::Canvas* canvas) { 635 void RootView::OnPaint(gfx::Canvas* canvas) {
639 if (!layer() || !layer()->fills_bounds_opaquely()) 636 if (!layer() || !layer()->fills_bounds_opaquely())
640 canvas->DrawColor(SK_ColorBLACK, SkXfermode::kClear_Mode); 637 canvas->DrawColor(SK_ColorBLACK, SkXfermode::kClear_Mode);
641 638
642 // TODO (pkotwicz): Remove this once we switch over to Aura desktop. 639 // TODO (pkotwicz): Remove this once we switch over to Aura desktop.
643 // This is needed so that we can set the background behind the RWHV when the 640 // This is needed so that we can set the background behind the RWHV when the
644 // RWHV is not visible. Not needed once there is a view between the RootView 641 // RWHV is not visible. Not needed once there is a view between the RootView
(...skipping 21 matching lines...) Expand all
666 widget_->SetCursor(v->GetCursor(me)); 663 widget_->SetCursor(v->GetCursor(me));
667 } 664 }
668 } 665 }
669 666
670 void RootView::SetMouseLocationAndFlags(const ui::MouseEvent& event) { 667 void RootView::SetMouseLocationAndFlags(const ui::MouseEvent& event) {
671 last_mouse_event_flags_ = event.flags(); 668 last_mouse_event_flags_ = event.flags();
672 last_mouse_event_x_ = event.x(); 669 last_mouse_event_x_ = event.x();
673 last_mouse_event_y_ = event.y(); 670 last_mouse_event_y_ = event.y();
674 } 671 }
675 672
673 void RootView::DispatchEventToTarget(View* target, ui::Event* event) {
674 View* old_target = event_dispatch_target_;
675 event_dispatch_target_ = target;
676 if (DispatchEvent(target, event))
677 event_dispatch_target_ = old_target;
678 }
679
680 bool RootView::CanDispatchToTarget(ui::EventTarget* target) {
681 return event_dispatch_target_ == target;
682 }
683
676 } // namespace internal 684 } // namespace internal
677 } // namespace views 685 } // namespace views
OLDNEW
« no previous file with comments | « ui/views/widget/root_view.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698