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/message_loop.h" | 10 #include "base/message_loop/message_loop.h" |
(...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
243 } | 243 } |
244 | 244 |
245 //////////////////////////////////////////////////////////////////////////////// | 245 //////////////////////////////////////////////////////////////////////////////// |
246 // RootView, ui::EventProcessor overrides: | 246 // RootView, ui::EventProcessor overrides: |
247 | 247 |
248 ui::EventTarget* RootView::GetRootTarget() { | 248 ui::EventTarget* RootView::GetRootTarget() { |
249 return this; | 249 return this; |
250 } | 250 } |
251 | 251 |
252 ui::EventDispatchDetails RootView::OnEventFromSource(ui::Event* event) { | 252 ui::EventDispatchDetails RootView::OnEventFromSource(ui::Event* event) { |
253 // TODO(tdanderson): Replace the calls to Dispatch*Event() with calls to | |
254 // EventProcessor::OnEventFromSource() once the code for | |
255 // that event type has been refactored, and then | |
256 // eventually remove this function altogether. See | |
257 // crbug.com/348083. | |
258 | |
259 if (event->IsKeyEvent()) | 253 if (event->IsKeyEvent()) |
260 return EventProcessor::OnEventFromSource(event); | 254 return EventProcessor::OnEventFromSource(event); |
261 | 255 |
262 if (event->IsScrollEvent()) | 256 if (event->IsScrollEvent()) |
263 return EventProcessor::OnEventFromSource(event); | 257 return EventProcessor::OnEventFromSource(event); |
264 | 258 |
265 if (event->IsGestureEvent()) { | 259 if (event->IsGestureEvent()) { |
| 260 // TODO(tdanderson): Once DispatchGestureEvent() has been removed, move |
| 261 // all of this logic into an override of a new |
| 262 // virtual method |
| 263 // EventProcessor::OnEventProcessingStarted() (which |
| 264 // returns false if no processing should take place). |
| 265 // Also move the implementation of |
| 266 // PrepareEventForDispatch() into this new method. |
| 267 // Then RootView::OnEventFromSource() can be removed. |
266 ui::GestureEvent* gesture_event = event->AsGestureEvent(); | 268 ui::GestureEvent* gesture_event = event->AsGestureEvent(); |
267 | 269 |
268 // Do not dispatch ui::ET_GESTURE_BEGIN events. | 270 // Do not dispatch ui::ET_GESTURE_BEGIN events. |
269 if (gesture_event->type() == ui::ET_GESTURE_BEGIN) | 271 if (gesture_event->type() == ui::ET_GESTURE_BEGIN) |
270 return DispatchDetails(); | 272 return DispatchDetails(); |
271 | 273 |
272 // Ignore ui::ET_GESTURE_END events which do not correspond to the | 274 // Ignore ui::ET_GESTURE_END events which do not correspond to the |
273 // removal of the final touch point. | 275 // removal of the final touch point. |
274 if (gesture_event->type() == ui::ET_GESTURE_END && | 276 if (gesture_event->type() == ui::ET_GESTURE_END && |
275 gesture_event->details().touch_points() > 1) { | 277 gesture_event->details().touch_points() > 1) { |
(...skipping 361 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
637 View::DragInfo* RootView::GetDragInfo() { | 639 View::DragInfo* RootView::GetDragInfo() { |
638 return &drag_info_; | 640 return &drag_info_; |
639 } | 641 } |
640 | 642 |
641 //////////////////////////////////////////////////////////////////////////////// | 643 //////////////////////////////////////////////////////////////////////////////// |
642 // RootView, private: | 644 // RootView, private: |
643 | 645 |
644 // Input ----------------------------------------------------------------------- | 646 // Input ----------------------------------------------------------------------- |
645 | 647 |
646 void RootView::DispatchGestureEvent(ui::GestureEvent* event) { | 648 void RootView::DispatchGestureEvent(ui::GestureEvent* event) { |
647 if (gesture_handler_) { | 649 bool gesture_handler_set_before_dispatch = !!gesture_handler_; |
648 if (gesture_handler_->enabled()) { | 650 View* target = |
649 // |gesture_handler_| can be deleted during processing. In particular, it | |
650 // will be set to NULL if the view is deleted or removed from the tree as | |
651 // a result of an event dispatch. | |
652 ui::GestureEvent handler_event(*event, | |
653 static_cast<View*>(this), | |
654 gesture_handler_); | |
655 ui::EventDispatchDetails dispatch_details = | |
656 DispatchEvent(gesture_handler_, &handler_event); | |
657 if (dispatch_details.dispatcher_destroyed) | |
658 return; | |
659 | |
660 if (handler_event.stopped_propagation()) | |
661 event->StopPropagation(); | |
662 else if (handler_event.handled()) | |
663 event->SetHandled(); | |
664 } else { | |
665 // Disabled views are permitted to be targets of gesture events, but | |
666 // gesture events should never actually be dispatched to them. | |
667 event->SetHandled(); | |
668 } | |
669 | |
670 if (event->type() == ui::ET_GESTURE_END) { | |
671 DCHECK_EQ(1, event->details().touch_points()); | |
672 // In case a drag was in progress, reset all the handlers. Otherwise, just | |
673 // reset the gesture handler. | |
674 if (gesture_handler_ == mouse_pressed_handler_) | |
675 SetMouseHandler(NULL); | |
676 else | |
677 gesture_handler_ = NULL; | |
678 } | |
679 | |
680 if (event->handled()) | |
681 return; | |
682 | |
683 if (event->type() == ui::ET_GESTURE_SCROLL_BEGIN) { | |
684 // Some view started processing gesture events, however it does not | |
685 // process scroll-gesture events. In such case, we allow the event to | |
686 // bubble up. |gesture_handler_| is changed to its nearest ancestor | |
687 // that handles scroll-gesture events. | |
688 gesture_handler_ = static_cast<View*>( | |
689 targeter()->FindNextBestTarget(gesture_handler_, event)); | |
690 while (gesture_handler_ && gesture_handler_ != this) { | |
691 ui::GestureEvent gesture_event(*event, | |
692 static_cast<View*>(this), | |
693 gesture_handler_); | |
694 ui::EventDispatchDetails dispatch_details = | |
695 DispatchEvent(gesture_handler_, &gesture_event); | |
696 if (gesture_event.stopped_propagation()) { | |
697 event->StopPropagation(); | |
698 return; | |
699 } else if (gesture_event.handled()) { | |
700 event->SetHandled(); | |
701 return; | |
702 } else if (dispatch_details.dispatcher_destroyed || | |
703 dispatch_details.target_destroyed) { | |
704 return; | |
705 } | |
706 gesture_handler_ = static_cast<View*>( | |
707 targeter()->FindNextBestTarget(gesture_handler_, event)); | |
708 } | |
709 gesture_handler_ = NULL; | |
710 } | |
711 | |
712 return; | |
713 } | |
714 | |
715 // Walk up the tree until we find a view that wants the gesture event. | |
716 gesture_handler_ = | |
717 static_cast<View*>(targeter()->FindTargetForEvent(this, event)); | 651 static_cast<View*>(targeter()->FindTargetForEvent(this, event)); |
718 while (gesture_handler_ && gesture_handler_ != this) { | 652 while (target && target != this) { |
719 // Disabled views are permitted to be targets of gesture events, but | 653 // Create and dispatch a copy of |event|. |
720 // gesture events should never actually be dispatched to them. | 654 ui::GestureEvent event_copy(*event, static_cast<View*>(this), target); |
721 if (!gesture_handler_->enabled()) { | |
722 event->SetHandled(); | |
723 | |
724 // Last ui::ET_GESTURE_END should not set the gesture_handler_. | |
725 if (event->type() == ui::ET_GESTURE_END) { | |
726 DCHECK_EQ(1, event->details().touch_points()); | |
727 gesture_handler_ = NULL; | |
728 } | |
729 | |
730 return; | |
731 } | |
732 | |
733 // See if this view wants to handle the Gesture. | |
734 ui::GestureEvent gesture_event(*event, | |
735 static_cast<View*>(this), | |
736 gesture_handler_); | |
737 ui::EventDispatchDetails dispatch_details = | 655 ui::EventDispatchDetails dispatch_details = |
738 DispatchEvent(gesture_handler_, &gesture_event); | 656 DispatchEvent(target, &event_copy); |
739 if (dispatch_details.dispatcher_destroyed) | 657 if (dispatch_details.dispatcher_destroyed) |
740 return; | 658 return; |
741 | 659 |
742 // The view could have removed itself from the tree when handling | 660 if (event_copy.stopped_propagation()) |
743 // OnGestureEvent(). So handle as per OnMousePressed. NB: we | 661 event->StopPropagation(); |
744 // assume that the RootView itself cannot be so removed. | 662 else if (event_copy.handled()) |
745 if (!gesture_handler_) | 663 event->SetHandled(); |
| 664 |
| 665 // If the event was handled by the previous dispatch or if the target |
| 666 // was destroyed, do not allow any further processing of |event|. |
| 667 if (event->handled() || dispatch_details.target_destroyed) |
746 return; | 668 return; |
747 | 669 |
748 if (gesture_event.handled()) { | 670 // The event was not handled by |target|, so continue processing by |
749 if (gesture_event.stopped_propagation()) | 671 // re-targeting the event. |
750 event->StopPropagation(); | 672 target = static_cast<View*>(targeter()->FindNextBestTarget(target, event)); |
751 else | |
752 event->SetHandled(); | |
753 // Last ui::ET_GESTURE_END should not set the gesture_handler_. | |
754 if (gesture_event.type() == ui::ET_GESTURE_END) { | |
755 DCHECK_EQ(1, event->details().touch_points()); | |
756 gesture_handler_ = NULL; | |
757 } | |
758 return; | |
759 } | |
760 | |
761 // The gesture event wasn't processed. Go up the view hierarchy and | |
762 // dispatch the gesture event. | |
763 gesture_handler_ = static_cast<View*>( | |
764 targeter()->FindNextBestTarget(gesture_handler_, event)); | |
765 } | 673 } |
766 | 674 |
767 gesture_handler_ = NULL; | 675 // |event| was not handled, so if |gesture_handler_| was not set by the |
| 676 // dispatch of a previous gesture event, then no default gesture handler |
| 677 // should be set prior to the next gesture event being received. |
| 678 // TODO(tdanderson): Move this into a new virtual function |
| 679 // EventProcessor::OnEventProcessingFinished(), to be called |
| 680 // at the end of EventProcessor::OnEventFromSource(). |
| 681 if (!gesture_handler_set_before_dispatch) |
| 682 gesture_handler_ = NULL; |
768 } | 683 } |
769 | 684 |
770 void RootView::UpdateCursor(const ui::MouseEvent& event) { | 685 void RootView::UpdateCursor(const ui::MouseEvent& event) { |
771 if (!(event.flags() & ui::EF_IS_NON_CLIENT)) { | 686 if (!(event.flags() & ui::EF_IS_NON_CLIENT)) { |
772 View* v = GetEventHandlerForPoint(event.location()); | 687 View* v = GetEventHandlerForPoint(event.location()); |
773 ui::MouseEvent me(event, static_cast<View*>(this), v); | 688 ui::MouseEvent me(event, static_cast<View*>(this), v); |
774 widget_->SetCursor(v->GetCursor(me)); | 689 widget_->SetCursor(v->GetCursor(me)); |
775 } | 690 } |
776 } | 691 } |
777 | 692 |
(...skipping 23 matching lines...) Expand all Loading... |
801 } | 716 } |
802 } | 717 } |
803 } | 718 } |
804 | 719 |
805 bool RootView::CanDispatchToTarget(ui::EventTarget* target) { | 720 bool RootView::CanDispatchToTarget(ui::EventTarget* target) { |
806 return event_dispatch_target_ == target; | 721 return event_dispatch_target_ == target; |
807 } | 722 } |
808 | 723 |
809 ui::EventDispatchDetails RootView::PreDispatchEvent(ui::EventTarget* target, | 724 ui::EventDispatchDetails RootView::PreDispatchEvent(ui::EventTarget* target, |
810 ui::Event* event) { | 725 ui::Event* event) { |
| 726 View* view = static_cast<View*>(target); |
| 727 if (event->IsGestureEvent()) { |
| 728 // Update |gesture_handler_| to indicate which View is currently handling |
| 729 // gesture events. |
| 730 gesture_handler_ = view; |
| 731 |
| 732 // Disabled views are permitted to be targets of gesture events, but |
| 733 // gesture events should never actually be dispatched to them. Prevent |
| 734 // dispatch by marking the event as handled. |
| 735 if (!view->enabled()) |
| 736 event->SetHandled(); |
| 737 } |
| 738 |
811 old_dispatch_target_ = event_dispatch_target_; | 739 old_dispatch_target_ = event_dispatch_target_; |
812 event_dispatch_target_ = static_cast<View*>(target); | 740 event_dispatch_target_ = view; |
813 return DispatchDetails(); | 741 return DispatchDetails(); |
814 } | 742 } |
815 | 743 |
816 ui::EventDispatchDetails RootView::PostDispatchEvent(ui::EventTarget* target, | 744 ui::EventDispatchDetails RootView::PostDispatchEvent(ui::EventTarget* target, |
817 const ui::Event& event) { | 745 const ui::Event& event) { |
| 746 // The GESTURE_END event corresponding to the removal of the final touch |
| 747 // point marks the end of a gesture sequence, so reset |gesture_handler_| |
| 748 // to NULL. |
| 749 if (event.type() == ui::ET_GESTURE_END) { |
| 750 // In case a drag was in progress, reset all the handlers. Otherwise, just |
| 751 // reset the gesture handler. |
| 752 if (gesture_handler_ && gesture_handler_ == mouse_pressed_handler_) |
| 753 SetMouseHandler(NULL); |
| 754 else |
| 755 gesture_handler_ = NULL; |
| 756 } |
| 757 |
818 DispatchDetails details; | 758 DispatchDetails details; |
819 if (target != event_dispatch_target_) | 759 if (target != event_dispatch_target_) |
820 details.target_destroyed = true; | 760 details.target_destroyed = true; |
821 | 761 |
822 event_dispatch_target_ = old_dispatch_target_; | 762 event_dispatch_target_ = old_dispatch_target_; |
823 old_dispatch_target_ = NULL; | 763 old_dispatch_target_ = NULL; |
824 | 764 |
825 #ifndef NDEBUG | 765 #ifndef NDEBUG |
826 DCHECK(!event_dispatch_target_ || Contains(event_dispatch_target_)); | 766 DCHECK(!event_dispatch_target_ || Contains(event_dispatch_target_)); |
827 #endif | 767 #endif |
828 | 768 |
829 return details; | 769 return details; |
830 } | 770 } |
831 | 771 |
832 } // namespace internal | 772 } // namespace internal |
833 } // namespace views | 773 } // namespace views |
OLD | NEW |