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/aura/root_window.h" | 5 #include "ui/aura/root_window.h" |
6 | 6 |
7 #include <vector> | 7 #include <vector> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/command_line.h" | 10 #include "base/command_line.h" |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
73 RootWindowHost* CreateHost(RootWindow* root_window, | 73 RootWindowHost* CreateHost(RootWindow* root_window, |
74 const RootWindow::CreateParams& params) { | 74 const RootWindow::CreateParams& params) { |
75 RootWindowHost* host = params.host ? | 75 RootWindowHost* host = params.host ? |
76 params.host : RootWindowHost::Create(params.initial_bounds); | 76 params.host : RootWindowHost::Create(params.initial_bounds); |
77 host->set_delegate(root_window); | 77 host->set_delegate(root_window); |
78 return host; | 78 return host; |
79 } | 79 } |
80 | 80 |
81 bool IsUsingEventProcessorForDispatch(const ui::Event& event) { | 81 bool IsUsingEventProcessorForDispatch(const ui::Event& event) { |
82 return event.IsKeyEvent() || | 82 return event.IsKeyEvent() || |
83 event.IsScrollEvent(); | 83 event.IsScrollEvent() || |
| 84 event.IsTouchEvent(); |
| 85 } |
| 86 |
| 87 bool IsEventCandidateForHold(const ui::Event& event) { |
| 88 if (event.type() == ui::ET_TOUCH_MOVED) |
| 89 return true; |
| 90 if (event.type() == ui::ET_MOUSE_DRAGGED) |
| 91 return true; |
| 92 if (event.IsMouseEvent() && (event.flags() & ui::EF_IS_SYNTHESIZED)) |
| 93 return true; |
| 94 return false; |
84 } | 95 } |
85 | 96 |
86 } // namespace | 97 } // namespace |
87 | 98 |
88 RootWindow::CreateParams::CreateParams(const gfx::Rect& a_initial_bounds) | 99 RootWindow::CreateParams::CreateParams(const gfx::Rect& a_initial_bounds) |
89 : initial_bounds(a_initial_bounds), | 100 : initial_bounds(a_initial_bounds), |
90 host(NULL) { | 101 host(NULL) { |
91 } | 102 } |
92 | 103 |
93 //////////////////////////////////////////////////////////////////////////////// | 104 //////////////////////////////////////////////////////////////////////////////// |
(...skipping 480 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
574 //////////////////////////////////////////////////////////////////////////////// | 585 //////////////////////////////////////////////////////////////////////////////// |
575 // RootWindow, ui::EventDispatcherDelegate implementation: | 586 // RootWindow, ui::EventDispatcherDelegate implementation: |
576 | 587 |
577 bool RootWindow::CanDispatchToTarget(ui::EventTarget* target) { | 588 bool RootWindow::CanDispatchToTarget(ui::EventTarget* target) { |
578 return event_dispatch_target_ == target; | 589 return event_dispatch_target_ == target; |
579 } | 590 } |
580 | 591 |
581 ui::EventDispatchDetails RootWindow::PreDispatchEvent(ui::EventTarget* target, | 592 ui::EventDispatchDetails RootWindow::PreDispatchEvent(ui::EventTarget* target, |
582 ui::Event* event) { | 593 ui::Event* event) { |
583 if (!dispatching_held_event_ && IsUsingEventProcessorForDispatch(*event)) { | 594 if (!dispatching_held_event_ && IsUsingEventProcessorForDispatch(*event)) { |
584 DispatchDetails details = DispatchHeldEvents(); | 595 if (!move_hold_count_ || !IsEventCandidateForHold(*event)) { |
585 if (details.dispatcher_destroyed || details.target_destroyed) | 596 if (IsEventCandidateForHold(*event)) |
586 return details; | 597 held_move_event_.reset(); |
| 598 DispatchDetails details = DispatchHeldEvents(); |
| 599 if (details.dispatcher_destroyed || details.target_destroyed) |
| 600 return details; |
| 601 } |
587 | 602 |
588 Window* target_window = static_cast<Window*>(target); | 603 Window* target_window = static_cast<Window*>(target); |
589 if (event->IsScrollEvent()) { | 604 if (event->IsScrollEvent()) { |
590 PreDispatchLocatedEvent(target_window, | 605 PreDispatchLocatedEvent(target_window, |
591 static_cast<ui::ScrollEvent*>(event)); | 606 static_cast<ui::ScrollEvent*>(event)); |
| 607 } else if (event->IsTouchEvent()) { |
| 608 PreDispatchTouchEvent(target_window, static_cast<ui::TouchEvent*>(event)); |
592 } | 609 } |
593 } | 610 } |
594 old_dispatch_target_ = event_dispatch_target_; | 611 old_dispatch_target_ = event_dispatch_target_; |
595 event_dispatch_target_ = static_cast<Window*>(target); | 612 event_dispatch_target_ = static_cast<Window*>(target); |
596 return DispatchDetails(); | 613 return DispatchDetails(); |
597 } | 614 } |
598 | 615 |
599 ui::EventDispatchDetails RootWindow::PostDispatchEvent(ui::EventTarget* target, | 616 ui::EventDispatchDetails RootWindow::PostDispatchEvent(ui::EventTarget* target, |
600 const ui::Event& event) { | 617 const ui::Event& event) { |
601 DispatchDetails details; | 618 DispatchDetails details; |
602 if (target != event_dispatch_target_) | 619 if (target != event_dispatch_target_) |
603 details.target_destroyed = true; | 620 details.target_destroyed = true; |
604 event_dispatch_target_ = old_dispatch_target_; | 621 event_dispatch_target_ = old_dispatch_target_; |
605 old_dispatch_target_ = NULL; | 622 old_dispatch_target_ = NULL; |
606 #ifndef NDEBUG | 623 #ifndef NDEBUG |
607 DCHECK(!event_dispatch_target_ || window()->Contains(event_dispatch_target_)); | 624 DCHECK(!event_dispatch_target_ || window()->Contains(event_dispatch_target_)); |
608 #endif | 625 #endif |
| 626 |
| 627 if (event.IsTouchEvent() && !details.target_destroyed) { |
| 628 ui::TouchEvent orig_event(static_cast<const ui::TouchEvent&>(event), |
| 629 static_cast<Window*>(event.target()), window()); |
| 630 // Get the list of GestureEvents from GestureRecognizer. |
| 631 scoped_ptr<ui::GestureRecognizer::Gestures> gestures; |
| 632 gestures.reset(ui::GestureRecognizer::Get()-> |
| 633 ProcessTouchEventForGesture(orig_event, event.result(), |
| 634 static_cast<Window*>(target))); |
| 635 return ProcessGestures(gestures.get()); |
| 636 } |
| 637 |
609 return details; | 638 return details; |
610 } | 639 } |
611 | 640 |
612 //////////////////////////////////////////////////////////////////////////////// | 641 //////////////////////////////////////////////////////////////////////////////// |
613 // RootWindow, ui::GestureEventHelper implementation: | 642 // RootWindow, ui::GestureEventHelper implementation: |
614 | 643 |
615 bool RootWindow::CanDispatchToConsumer(ui::GestureConsumer* consumer) { | 644 bool RootWindow::CanDispatchToConsumer(ui::GestureConsumer* consumer) { |
616 Window* consumer_window = ConsumerToWindow(consumer);; | 645 Window* consumer_window = ConsumerToWindow(consumer);; |
617 return (consumer_window && consumer_window->GetRootWindow() == window()); | 646 return (consumer_window && consumer_window->GetRootWindow() == window()); |
618 } | 647 } |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
657 } | 686 } |
658 | 687 |
659 bool RootWindow::OnHostScrollEvent(ui::ScrollEvent* event) { | 688 bool RootWindow::OnHostScrollEvent(ui::ScrollEvent* event) { |
660 DispatchDetails details = OnEventFromSource(event); | 689 DispatchDetails details = OnEventFromSource(event); |
661 if (details.dispatcher_destroyed) | 690 if (details.dispatcher_destroyed) |
662 event->SetHandled(); | 691 event->SetHandled(); |
663 return event->handled(); | 692 return event->handled(); |
664 } | 693 } |
665 | 694 |
666 bool RootWindow::OnHostTouchEvent(ui::TouchEvent* event) { | 695 bool RootWindow::OnHostTouchEvent(ui::TouchEvent* event) { |
667 if ((event->type() == ui::ET_TOUCH_MOVED)) { | 696 DispatchDetails details = OnEventFromSource(event); |
668 if (move_hold_count_) { | |
669 Window* null_window = static_cast<Window*>(NULL); | |
670 held_move_event_.reset( | |
671 new ui::TouchEvent(*event, null_window, null_window)); | |
672 return true; | |
673 } else { | |
674 // We may have a held event for a period between the time move_hold_count_ | |
675 // fell to 0 and the DispatchHeldEvents executes. Since we're going to | |
676 // dispatch the new event directly below, we can reset the old one. | |
677 held_move_event_.reset(); | |
678 } | |
679 } | |
680 DispatchDetails details = DispatchHeldEvents(); | |
681 if (details.dispatcher_destroyed) | 697 if (details.dispatcher_destroyed) |
682 return false; | 698 event->SetHandled(); |
683 details = DispatchTouchEventImpl(event); | |
684 if (details.dispatcher_destroyed) | |
685 return true; | |
686 return event->handled(); | 699 return event->handled(); |
687 } | 700 } |
688 | 701 |
689 void RootWindow::OnHostCancelMode() { | 702 void RootWindow::OnHostCancelMode() { |
690 ui::CancelModeEvent event; | 703 ui::CancelModeEvent event; |
691 Window* focused_window = client::GetFocusClient(window())->GetFocusedWindow(); | 704 Window* focused_window = client::GetFocusClient(window())->GetFocusedWindow(); |
692 DispatchDetails details = | 705 DispatchDetails details = |
693 DispatchEvent(focused_window ? focused_window : window(), &event); | 706 DispatchEvent(focused_window ? focused_window : window(), &event); |
694 if (details.dispatcher_destroyed) | 707 if (details.dispatcher_destroyed) |
695 return; | 708 return; |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
739 | 752 |
740 ui::EventProcessor* RootWindow::GetEventProcessor() { | 753 ui::EventProcessor* RootWindow::GetEventProcessor() { |
741 return this; | 754 return this; |
742 } | 755 } |
743 | 756 |
744 //////////////////////////////////////////////////////////////////////////////// | 757 //////////////////////////////////////////////////////////////////////////////// |
745 // RootWindow, private: | 758 // RootWindow, private: |
746 | 759 |
747 ui::EventDispatchDetails RootWindow::OnHostMouseEventImpl( | 760 ui::EventDispatchDetails RootWindow::OnHostMouseEventImpl( |
748 ui::MouseEvent* event) { | 761 ui::MouseEvent* event) { |
749 if (event->type() == ui::ET_MOUSE_DRAGGED || | 762 if (IsEventCandidateForHold(*event)) { |
750 (event->flags() & ui::EF_IS_SYNTHESIZED)) { | |
751 if (move_hold_count_) { | 763 if (move_hold_count_) { |
752 Window* null_window = static_cast<Window*>(NULL); | 764 Window* null_window = static_cast<Window*>(NULL); |
753 held_move_event_.reset( | 765 held_move_event_.reset( |
754 new ui::MouseEvent(*event, null_window, null_window)); | 766 new ui::MouseEvent(*event, null_window, null_window)); |
755 event->SetHandled(); | 767 event->SetHandled(); |
756 return DispatchDetails(); | 768 return DispatchDetails(); |
757 } else { | 769 } else { |
758 // We may have a held event for a period between the time move_hold_count_ | 770 // We may have a held event for a period between the time move_hold_count_ |
759 // fell to 0 and the DispatchHeldEvents executes. Since we're going to | 771 // fell to 0 and the DispatchHeldEvents executes. Since we're going to |
760 // dispatch the new event directly below, we can reset the old one. | 772 // dispatch the new event directly below, we can reset the old one. |
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
870 } | 882 } |
871 if (target) { | 883 if (target) { |
872 event->ConvertLocationToTarget(window(), target); | 884 event->ConvertLocationToTarget(window(), target); |
873 if (IsNonClientLocation(target, event->location())) | 885 if (IsNonClientLocation(target, event->location())) |
874 event->set_flags(event->flags() | ui::EF_IS_NON_CLIENT); | 886 event->set_flags(event->flags() | ui::EF_IS_NON_CLIENT); |
875 return DispatchEvent(target, event); | 887 return DispatchEvent(target, event); |
876 } | 888 } |
877 return DispatchDetails(); | 889 return DispatchDetails(); |
878 } | 890 } |
879 | 891 |
880 ui::EventDispatchDetails RootWindow::DispatchTouchEventImpl( | |
881 ui::TouchEvent* event) { | |
882 switch (event->type()) { | |
883 case ui::ET_TOUCH_PRESSED: | |
884 touch_ids_down_ |= (1 << event->touch_id()); | |
885 Env::GetInstance()->set_touch_down(touch_ids_down_ != 0); | |
886 break; | |
887 | |
888 // Handle ET_TOUCH_CANCELLED only if it has a native event. | |
889 case ui::ET_TOUCH_CANCELLED: | |
890 if (!event->HasNativeEvent()) | |
891 break; | |
892 // fallthrough | |
893 case ui::ET_TOUCH_RELEASED: | |
894 touch_ids_down_ = (touch_ids_down_ | (1 << event->touch_id())) ^ | |
895 (1 << event->touch_id()); | |
896 Env::GetInstance()->set_touch_down(touch_ids_down_ != 0); | |
897 break; | |
898 | |
899 default: | |
900 break; | |
901 } | |
902 TransformEventForDeviceScaleFactor(event); | |
903 Window* target = client::GetCaptureWindow(window()); | |
904 if (!target) { | |
905 target = ConsumerToWindow( | |
906 ui::GestureRecognizer::Get()->GetTouchLockedTarget(*event)); | |
907 if (!target) { | |
908 target = ConsumerToWindow(ui::GestureRecognizer::Get()-> | |
909 GetTargetForLocation(event->location())); | |
910 } | |
911 } | |
912 | |
913 // The gesture recognizer processes touch events in the system coordinates. So | |
914 // keep a copy of the touch event here before possibly converting the event to | |
915 // a window's local coordinate system. | |
916 ui::TouchEvent event_for_gr(*event); | |
917 | |
918 ui::EventResult result = ui::ER_UNHANDLED; | |
919 if (!target && !window()->bounds().Contains(event->location())) { | |
920 // If the initial touch is outside the root window, target the root. | |
921 target = window(); | |
922 DispatchDetails details = DispatchEvent(target ? target : NULL, event); | |
923 if (details.dispatcher_destroyed) | |
924 return details; | |
925 result = event->result(); | |
926 } else { | |
927 // We only come here when the first contact was within the root window. | |
928 if (!target) { | |
929 target = window()->GetEventHandlerForPoint(event->location()); | |
930 if (!target) | |
931 return DispatchDetails(); | |
932 } | |
933 | |
934 event->ConvertLocationToTarget(window(), target); | |
935 DispatchDetails details = DispatchEvent(target, event); | |
936 if (details.dispatcher_destroyed) | |
937 return details; | |
938 result = event->result(); | |
939 } | |
940 | |
941 // Get the list of GestureEvents from GestureRecognizer. | |
942 scoped_ptr<ui::GestureRecognizer::Gestures> gestures; | |
943 gestures.reset(ui::GestureRecognizer::Get()-> | |
944 ProcessTouchEventForGesture(event_for_gr, result, target)); | |
945 | |
946 return ProcessGestures(gestures.get()); | |
947 } | |
948 | |
949 ui::EventDispatchDetails RootWindow::DispatchHeldEvents() { | 892 ui::EventDispatchDetails RootWindow::DispatchHeldEvents() { |
950 if (!held_repostable_event_ && !held_move_event_) | 893 if (!held_repostable_event_ && !held_move_event_) |
951 return DispatchDetails(); | 894 return DispatchDetails(); |
952 | 895 |
953 CHECK(!dispatching_held_event_); | 896 CHECK(!dispatching_held_event_); |
954 dispatching_held_event_ = true; | 897 dispatching_held_event_ = true; |
955 | 898 |
956 DispatchDetails dispatch_details; | 899 DispatchDetails dispatch_details; |
957 if (held_repostable_event_) { | 900 if (held_repostable_event_) { |
958 if (held_repostable_event_->type() == ui::ET_MOUSE_PRESSED) { | 901 if (held_repostable_event_->type() == ui::ET_MOUSE_PRESSED) { |
(...skipping 11 matching lines...) Expand all Loading... |
970 if (held_move_event_ && held_move_event_->IsMouseEvent()) { | 913 if (held_move_event_ && held_move_event_->IsMouseEvent()) { |
971 // If a mouse move has been synthesized, the target location is suspect, | 914 // If a mouse move has been synthesized, the target location is suspect, |
972 // so drop the held event. | 915 // so drop the held event. |
973 if (!synthesize_mouse_move_) { | 916 if (!synthesize_mouse_move_) { |
974 dispatch_details = DispatchMouseEventImpl( | 917 dispatch_details = DispatchMouseEventImpl( |
975 static_cast<ui::MouseEvent*>(held_move_event_.get())); | 918 static_cast<ui::MouseEvent*>(held_move_event_.get())); |
976 } | 919 } |
977 if (!dispatch_details.dispatcher_destroyed) | 920 if (!dispatch_details.dispatcher_destroyed) |
978 held_move_event_.reset(); | 921 held_move_event_.reset(); |
979 } else if (held_move_event_ && held_move_event_->IsTouchEvent()) { | 922 } else if (held_move_event_ && held_move_event_->IsTouchEvent()) { |
980 dispatch_details = DispatchTouchEventImpl( | 923 dispatch_details = OnEventFromSource( |
981 static_cast<ui::TouchEvent*>(held_move_event_.get())); | 924 static_cast<ui::TouchEvent*>(held_move_event_.get())); |
982 if (!dispatch_details.dispatcher_destroyed) | 925 if (!dispatch_details.dispatcher_destroyed) |
983 held_move_event_.reset(); | 926 held_move_event_.reset(); |
984 } | 927 } |
985 | 928 |
986 if (!dispatch_details.dispatcher_destroyed) | 929 if (!dispatch_details.dispatcher_destroyed) |
987 dispatching_held_event_ = false; | 930 dispatching_held_event_ = false; |
988 return dispatch_details; | 931 return dispatch_details; |
989 } | 932 } |
990 | 933 |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1029 if (IsNonClientLocation(target, event->location())) | 972 if (IsNonClientLocation(target, event->location())) |
1030 flags |= ui::EF_IS_NON_CLIENT; | 973 flags |= ui::EF_IS_NON_CLIENT; |
1031 event->set_flags(flags); | 974 event->set_flags(flags); |
1032 | 975 |
1033 if (!dispatching_held_event_) { | 976 if (!dispatching_held_event_) { |
1034 SetLastMouseLocation(window(), event->location()); | 977 SetLastMouseLocation(window(), event->location()); |
1035 synthesize_mouse_move_ = false; | 978 synthesize_mouse_move_ = false; |
1036 } | 979 } |
1037 } | 980 } |
1038 | 981 |
| 982 void RootWindow::PreDispatchTouchEvent(Window* target, |
| 983 ui::TouchEvent* event) { |
| 984 switch (event->type()) { |
| 985 case ui::ET_TOUCH_PRESSED: |
| 986 touch_ids_down_ |= (1 << event->touch_id()); |
| 987 Env::GetInstance()->set_touch_down(touch_ids_down_ != 0); |
| 988 break; |
| 989 |
| 990 // Handle ET_TOUCH_CANCELLED only if it has a native event. |
| 991 case ui::ET_TOUCH_CANCELLED: |
| 992 if (!event->HasNativeEvent()) |
| 993 break; |
| 994 // fallthrough |
| 995 case ui::ET_TOUCH_RELEASED: |
| 996 touch_ids_down_ = (touch_ids_down_ | (1 << event->touch_id())) ^ |
| 997 (1 << event->touch_id()); |
| 998 Env::GetInstance()->set_touch_down(touch_ids_down_ != 0); |
| 999 break; |
| 1000 |
| 1001 case ui::ET_TOUCH_MOVED: |
| 1002 if (move_hold_count_) { |
| 1003 held_move_event_.reset(new ui::TouchEvent(*event)); |
| 1004 event->SetHandled(); |
| 1005 return; |
| 1006 } |
| 1007 break; |
| 1008 |
| 1009 default: |
| 1010 NOTREACHED(); |
| 1011 break; |
| 1012 } |
| 1013 PreDispatchLocatedEvent(target, event); |
| 1014 } |
| 1015 |
1039 } // namespace aura | 1016 } // namespace aura |
OLD | NEW |