| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 |
| OLD | NEW |