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

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

Issue 517023004: Condense RootView::DispatchGestureEvent() to a single loop (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: always reset gesture handler to NULL on gesture-end Created 6 years, 3 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
« no previous file with comments | « no previous file | 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/message_loop.h" 10 #include "base/message_loop/message_loop.h"
(...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698