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; | |
sadrul
2014/08/29 21:43:54
Instead of setting gesture_handler_ here, can we s
tdanderson
2014/08/29 21:58:07
We need to set it in PreDispatchEvent() otherwise
sadrul
2014/09/02 14:36:01
Should we use |RV::event_dispatch_target_| to dete
tdanderson
2014/09/02 17:26:35
I like this idea in theory, but for it to work pro
| |
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 if the event will not be re-targeted further. | |
749 if (event.type() == ui::ET_GESTURE_END && | |
750 (!allow_gesture_event_retargeting_ || event.handled())) { | |
sadrul
2014/08/29 21:43:54
This seems wrong. Shouldn't we always reset gestur
tdanderson
2014/08/29 21:58:07
We shouldn't reset |gesture_handler_| to NULL unti
sadrul
2014/09/02 14:36:01
Do we need GESTURE_END to bubble up? (i.e. shouldn
tdanderson
2014/09/02 17:26:35
Yes, this makes sense. I will put up a separate CL
tdanderson
2014/09/02 20:29:06
https://codereview.chromium.org/533793002/ has lan
| |
751 // In case a drag was in progress, reset all the handlers. Otherwise, just | |
752 // reset the gesture handler. | |
753 if (gesture_handler_ == mouse_pressed_handler_) | |
754 SetMouseHandler(NULL); | |
755 else | |
756 gesture_handler_ = NULL; | |
757 } | |
758 | |
818 DispatchDetails details; | 759 DispatchDetails details; |
819 if (target != event_dispatch_target_) | 760 if (target != event_dispatch_target_) |
820 details.target_destroyed = true; | 761 details.target_destroyed = true; |
821 | 762 |
822 event_dispatch_target_ = old_dispatch_target_; | 763 event_dispatch_target_ = old_dispatch_target_; |
823 old_dispatch_target_ = NULL; | 764 old_dispatch_target_ = NULL; |
824 | 765 |
825 #ifndef NDEBUG | 766 #ifndef NDEBUG |
826 DCHECK(!event_dispatch_target_ || Contains(event_dispatch_target_)); | 767 DCHECK(!event_dispatch_target_ || Contains(event_dispatch_target_)); |
827 #endif | 768 #endif |
828 | 769 |
829 return details; | 770 return details; |
830 } | 771 } |
831 | 772 |
832 } // namespace internal | 773 } // namespace internal |
833 } // namespace views | 774 } // namespace views |
OLD | NEW |