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 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
115 prop_.reset(new ui::ViewProp(host_->GetAcceleratedWidget(), | 115 prop_.reset(new ui::ViewProp(host_->GetAcceleratedWidget(), |
116 kRootWindowForAcceleratedWidget, | 116 kRootWindowForAcceleratedWidget, |
117 this)); | 117 this)); |
118 ui::GestureRecognizer::Get()->AddGestureEventHelper(this); | 118 ui::GestureRecognizer::Get()->AddGestureEventHelper(this); |
119 } | 119 } |
120 | 120 |
121 RootWindow::~RootWindow() { | 121 RootWindow::~RootWindow() { |
122 TRACE_EVENT0("shutdown", "RootWindow::Destructor"); | 122 TRACE_EVENT0("shutdown", "RootWindow::Destructor"); |
123 | 123 |
124 ui::GestureRecognizer::Get()->RemoveGestureEventHelper(this); | 124 ui::GestureRecognizer::Get()->RemoveGestureEventHelper(this); |
| 125 STLDeleteValues(&gesture_event_queues_); |
125 | 126 |
126 // An observer may have been added by an animation on the RootWindow. | 127 // An observer may have been added by an animation on the RootWindow. |
127 window()->layer()->GetAnimator()->RemoveObserver(this); | 128 window()->layer()->GetAnimator()->RemoveObserver(this); |
128 | 129 |
129 // Destroy child windows while we're still valid. This is also done by | 130 // Destroy child windows while we're still valid. This is also done by |
130 // ~Window, but by that time any calls to virtual methods overriden here (such | 131 // ~Window, but by that time any calls to virtual methods overriden here (such |
131 // as GetRootWindow()) result in Window's implementation. By destroying here | 132 // as GetRootWindow()) result in Window's implementation. By destroying here |
132 // we ensure GetRootWindow() still returns this. | 133 // we ensure GetRootWindow() still returns this. |
133 window()->RemoveOrDestroyChildren(); | 134 window()->RemoveOrDestroyChildren(); |
134 | 135 |
(...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
346 observers_.AddObserver(observer); | 347 observers_.AddObserver(observer); |
347 } | 348 } |
348 | 349 |
349 void RootWindow::RemoveRootWindowObserver(RootWindowObserver* observer) { | 350 void RootWindow::RemoveRootWindowObserver(RootWindowObserver* observer) { |
350 observers_.RemoveObserver(observer); | 351 observers_.RemoveObserver(observer); |
351 } | 352 } |
352 | 353 |
353 void RootWindow::ProcessedTouchEvent(ui::TouchEvent* event, | 354 void RootWindow::ProcessedTouchEvent(ui::TouchEvent* event, |
354 Window* window, | 355 Window* window, |
355 ui::EventResult result) { | 356 ui::EventResult result) { |
356 scoped_ptr<ui::GestureRecognizer::Gestures> gestures; | 357 gesture_event_queues_[window]->OnTouchEventAck(*event, result); |
357 gestures.reset(ui::GestureRecognizer::Get()-> | |
358 ProcessTouchEventForGesture(*event, result, window)); | |
359 DispatchDetails details = ProcessGestures(gestures.get()); | |
360 if (details.dispatcher_destroyed) | |
361 return; | |
362 } | 358 } |
363 | 359 |
364 void RootWindow::HoldPointerMoves() { | 360 void RootWindow::HoldPointerMoves() { |
365 if (!move_hold_count_) | 361 if (!move_hold_count_) |
366 held_event_factory_.InvalidateWeakPtrs(); | 362 held_event_factory_.InvalidateWeakPtrs(); |
367 ++move_hold_count_; | 363 ++move_hold_count_; |
368 TRACE_EVENT_ASYNC_BEGIN0("ui", "RootWindow::HoldPointerMoves", this); | 364 TRACE_EVENT_ASYNC_BEGIN0("ui", "RootWindow::HoldPointerMoves", this); |
369 } | 365 } |
370 | 366 |
371 void RootWindow::ReleasePointerMoves() { | 367 void RootWindow::ReleasePointerMoves() { |
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
490 mouse_pressed_handler_ = NULL; | 486 mouse_pressed_handler_ = NULL; |
491 if (invisible->Contains(mouse_moved_handler_)) | 487 if (invisible->Contains(mouse_moved_handler_)) |
492 mouse_moved_handler_ = NULL; | 488 mouse_moved_handler_ = NULL; |
493 | 489 |
494 CleanupGestureState(invisible); | 490 CleanupGestureState(invisible); |
495 } | 491 } |
496 | 492 |
497 void RootWindow::CleanupGestureState(Window* window) { | 493 void RootWindow::CleanupGestureState(Window* window) { |
498 ui::GestureRecognizer::Get()->CancelActiveTouches(window); | 494 ui::GestureRecognizer::Get()->CancelActiveTouches(window); |
499 ui::GestureRecognizer::Get()->CleanupStateForConsumer(window); | 495 ui::GestureRecognizer::Get()->CleanupStateForConsumer(window); |
| 496 gesture_event_queues_.erase(window); |
500 const Window::Windows& windows = window->children(); | 497 const Window::Windows& windows = window->children(); |
501 for (Window::Windows::const_iterator iter = windows.begin(); | 498 for (Window::Windows::const_iterator iter = windows.begin(); |
502 iter != windows.end(); | 499 iter != windows.end(); |
503 ++iter) { | 500 ++iter) { |
504 CleanupGestureState(*iter); | 501 CleanupGestureState(*iter); |
505 } | 502 } |
506 } | 503 } |
507 | 504 |
508 //////////////////////////////////////////////////////////////////////////////// | 505 //////////////////////////////////////////////////////////////////////////////// |
509 // RootWindow, aura::client::CaptureDelegate implementation: | 506 // RootWindow, aura::client::CaptureDelegate implementation: |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
610 } | 607 } |
611 | 608 |
612 //////////////////////////////////////////////////////////////////////////////// | 609 //////////////////////////////////////////////////////////////////////////////// |
613 // RootWindow, ui::GestureEventHelper implementation: | 610 // RootWindow, ui::GestureEventHelper implementation: |
614 | 611 |
615 bool RootWindow::CanDispatchToConsumer(ui::GestureConsumer* consumer) { | 612 bool RootWindow::CanDispatchToConsumer(ui::GestureConsumer* consumer) { |
616 Window* consumer_window = ConsumerToWindow(consumer);; | 613 Window* consumer_window = ConsumerToWindow(consumer);; |
617 return (consumer_window && consumer_window->GetRootWindow() == window()); | 614 return (consumer_window && consumer_window->GetRootWindow() == window()); |
618 } | 615 } |
619 | 616 |
620 void RootWindow::DispatchPostponedGestureEvent(ui::GestureEvent* event) { | |
621 DispatchGestureEvent(event); | |
622 } | |
623 | |
624 void RootWindow::DispatchCancelTouchEvent(ui::TouchEvent* event) { | 617 void RootWindow::DispatchCancelTouchEvent(ui::TouchEvent* event) { |
625 OnHostTouchEvent(event); | 618 OnHostTouchEvent(event); |
626 } | 619 } |
627 | 620 |
628 //////////////////////////////////////////////////////////////////////////////// | 621 //////////////////////////////////////////////////////////////////////////////// |
629 // RootWindow, ui::LayerAnimationObserver implementation: | 622 // RootWindow, ui::LayerAnimationObserver implementation: |
630 | 623 |
631 void RootWindow::OnLayerAnimationEnded( | 624 void RootWindow::OnLayerAnimationEnded( |
632 ui::LayerAnimationSequence* animation) { | 625 ui::LayerAnimationSequence* animation) { |
633 host()->UpdateRootWindowSize(host_->GetBounds().size()); | 626 host()->UpdateRootWindowSize(host_->GetBounds().size()); |
(...skipping 22 matching lines...) Expand all Loading... |
656 return event->handled() || details.dispatcher_destroyed; | 649 return event->handled() || details.dispatcher_destroyed; |
657 } | 650 } |
658 | 651 |
659 bool RootWindow::OnHostScrollEvent(ui::ScrollEvent* event) { | 652 bool RootWindow::OnHostScrollEvent(ui::ScrollEvent* event) { |
660 DispatchDetails details = OnEventFromSource(event); | 653 DispatchDetails details = OnEventFromSource(event); |
661 if (details.dispatcher_destroyed) | 654 if (details.dispatcher_destroyed) |
662 event->SetHandled(); | 655 event->SetHandled(); |
663 return event->handled(); | 656 return event->handled(); |
664 } | 657 } |
665 | 658 |
| 659 void RootWindow::OnTouchEventForGestures( |
| 660 ui::TouchEvent* event, |
| 661 ui::TouchPointState::RequiresAck requires_ack) { |
| 662 Window* target = GetTouchEventTarget(event); |
| 663 if (target) |
| 664 event->ConvertLocationToTarget(target, window()); |
| 665 if (!gesture_event_queues_[target]) |
| 666 gesture_event_queues_[target] = new ui::GestureEventQueue(this); |
| 667 ui::GestureEventQueue* gesture_event_queue = gesture_event_queues_[target]; |
| 668 gesture_event_queue->OnTouchEvent(*event); |
| 669 // Get the list of GestureEvents from GestureRecognizer. |
| 670 scoped_ptr<ui::GestureRecognizer::Gestures> gestures; |
| 671 gestures.reset( |
| 672 ui::GestureRecognizer::Get()->ProcessTouchEventForGesture( |
| 673 *event, target, gesture_event_queue)); |
| 674 for (ui::GestureRecognizer::Gestures::iterator it = gestures->begin(); |
| 675 it != gestures->end(); |
| 676 ++it) { |
| 677 gesture_event_queue->QueueGestureEvent(*it, requires_ack); |
| 678 } |
| 679 gestures->weak_clear(); |
| 680 } |
| 681 |
666 bool RootWindow::OnHostTouchEvent(ui::TouchEvent* event) { | 682 bool RootWindow::OnHostTouchEvent(ui::TouchEvent* event) { |
| 683 TransformEventForDeviceScaleFactor(event); |
| 684 |
| 685 Window* target = GetTouchEventTarget(event); |
| 686 |
| 687 if (target) |
| 688 event->ConvertLocationToTarget(window(), target); |
| 689 |
667 if ((event->type() == ui::ET_TOUCH_MOVED)) { | 690 if ((event->type() == ui::ET_TOUCH_MOVED)) { |
668 if (move_hold_count_) { | 691 if (move_hold_count_) { |
669 Window* null_window = static_cast<Window*>(NULL); | 692 Window* null_window = static_cast<Window*>(NULL); |
670 held_move_event_.reset( | 693 held_move_event_.reset( |
671 new ui::TouchEvent(*event, null_window, null_window)); | 694 new ui::TouchEvent(*event, null_window, null_window)); |
672 return true; | 695 return true; |
673 } else { | 696 } else { |
674 // We may have a held event for a period between the time move_hold_count_ | 697 // 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 | 698 // 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. | 699 // dispatch the new event directly below, we can reset the old one. |
677 held_move_event_.reset(); | 700 held_move_event_.reset(); |
678 } | 701 } |
679 } | 702 } |
680 DispatchDetails details = DispatchHeldEvents(); | 703 DispatchDetails details = DispatchHeldEvents(); |
681 if (details.dispatcher_destroyed) | 704 if (details.dispatcher_destroyed) |
682 return false; | 705 return false; |
683 details = DispatchTouchEventImpl(event); | 706 details = DispatchTouchEventImpl(event, target); |
| 707 if (event->result() == ui::ER_UNHANDLED) |
| 708 OnTouchEventForGestures(event, ui::TouchPointState::NO_ACK); |
684 if (details.dispatcher_destroyed) | 709 if (details.dispatcher_destroyed) |
685 return true; | 710 return true; |
686 return event->handled(); | 711 return event->handled(); |
687 } | 712 } |
688 | 713 |
689 void RootWindow::OnHostCancelMode() { | 714 void RootWindow::OnHostCancelMode() { |
690 ui::CancelModeEvent event; | 715 ui::CancelModeEvent event; |
691 Window* focused_window = client::GetFocusClient(window())->GetFocusedWindow(); | 716 Window* focused_window = client::GetFocusClient(window())->GetFocusedWindow(); |
692 DispatchDetails details = | 717 DispatchDetails details = |
693 DispatchEvent(focused_window ? focused_window : window(), &event); | 718 DispatchEvent(focused_window ? focused_window : window(), &event); |
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
871 if (target) { | 896 if (target) { |
872 event->ConvertLocationToTarget(window(), target); | 897 event->ConvertLocationToTarget(window(), target); |
873 if (IsNonClientLocation(target, event->location())) | 898 if (IsNonClientLocation(target, event->location())) |
874 event->set_flags(event->flags() | ui::EF_IS_NON_CLIENT); | 899 event->set_flags(event->flags() | ui::EF_IS_NON_CLIENT); |
875 return DispatchEvent(target, event); | 900 return DispatchEvent(target, event); |
876 } | 901 } |
877 return DispatchDetails(); | 902 return DispatchDetails(); |
878 } | 903 } |
879 | 904 |
880 ui::EventDispatchDetails RootWindow::DispatchTouchEventImpl( | 905 ui::EventDispatchDetails RootWindow::DispatchTouchEventImpl( |
881 ui::TouchEvent* event) { | 906 ui::TouchEvent* event, Window* target) { |
| 907 if (!target) |
| 908 return DispatchDetails(); |
| 909 |
882 switch (event->type()) { | 910 switch (event->type()) { |
883 case ui::ET_TOUCH_PRESSED: | 911 case ui::ET_TOUCH_PRESSED: |
884 touch_ids_down_ |= (1 << event->touch_id()); | 912 touch_ids_down_ |= (1 << event->touch_id()); |
885 Env::GetInstance()->set_touch_down(touch_ids_down_ != 0); | 913 Env::GetInstance()->set_touch_down(touch_ids_down_ != 0); |
886 break; | 914 break; |
887 | 915 |
888 // Handle ET_TOUCH_CANCELLED only if it has a native event. | 916 // Handle ET_TOUCH_CANCELLED only if it has a native event. |
889 case ui::ET_TOUCH_CANCELLED: | 917 case ui::ET_TOUCH_CANCELLED: |
890 if (!event->HasNativeEvent()) | 918 if (!event->HasNativeEvent()) |
891 break; | 919 break; |
892 // fallthrough | 920 // fallthrough |
893 case ui::ET_TOUCH_RELEASED: | 921 case ui::ET_TOUCH_RELEASED: |
894 touch_ids_down_ = (touch_ids_down_ | (1 << event->touch_id())) ^ | 922 touch_ids_down_ = (touch_ids_down_ | (1 << event->touch_id())) ^ |
895 (1 << event->touch_id()); | 923 (1 << event->touch_id()); |
896 Env::GetInstance()->set_touch_down(touch_ids_down_ != 0); | 924 Env::GetInstance()->set_touch_down(touch_ids_down_ != 0); |
897 break; | 925 break; |
898 | 926 |
899 default: | 927 default: |
900 break; | 928 break; |
901 } | 929 } |
902 TransformEventForDeviceScaleFactor(event); | 930 DispatchDetails details = DispatchEvent(target, event); |
903 Window* target = client::GetCaptureWindow(window()); | 931 return details; |
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 } | 932 } |
948 | 933 |
949 ui::EventDispatchDetails RootWindow::DispatchHeldEvents() { | 934 ui::EventDispatchDetails RootWindow::DispatchHeldEvents() { |
950 if (!held_repostable_event_ && !held_move_event_) | 935 if (!held_repostable_event_ && !held_move_event_) |
951 return DispatchDetails(); | 936 return DispatchDetails(); |
952 | 937 |
953 CHECK(!dispatching_held_event_); | 938 CHECK(!dispatching_held_event_); |
954 dispatching_held_event_ = true; | 939 dispatching_held_event_ = true; |
955 | 940 |
956 DispatchDetails dispatch_details; | 941 DispatchDetails dispatch_details; |
(...skipping 13 matching lines...) Expand all Loading... |
970 if (held_move_event_ && held_move_event_->IsMouseEvent()) { | 955 if (held_move_event_ && held_move_event_->IsMouseEvent()) { |
971 // If a mouse move has been synthesized, the target location is suspect, | 956 // If a mouse move has been synthesized, the target location is suspect, |
972 // so drop the held event. | 957 // so drop the held event. |
973 if (!synthesize_mouse_move_) { | 958 if (!synthesize_mouse_move_) { |
974 dispatch_details = DispatchMouseEventImpl( | 959 dispatch_details = DispatchMouseEventImpl( |
975 static_cast<ui::MouseEvent*>(held_move_event_.get())); | 960 static_cast<ui::MouseEvent*>(held_move_event_.get())); |
976 } | 961 } |
977 if (!dispatch_details.dispatcher_destroyed) | 962 if (!dispatch_details.dispatcher_destroyed) |
978 held_move_event_.reset(); | 963 held_move_event_.reset(); |
979 } else if (held_move_event_ && held_move_event_->IsTouchEvent()) { | 964 } else if (held_move_event_ && held_move_event_->IsTouchEvent()) { |
| 965 ui::TouchEvent* touch_event = |
| 966 static_cast<ui::TouchEvent*>(held_move_event_.get()); |
980 dispatch_details = DispatchTouchEventImpl( | 967 dispatch_details = DispatchTouchEventImpl( |
981 static_cast<ui::TouchEvent*>(held_move_event_.get())); | 968 touch_event, GetTouchEventTarget(touch_event)); |
982 if (!dispatch_details.dispatcher_destroyed) | 969 if (!dispatch_details.dispatcher_destroyed) |
983 held_move_event_.reset(); | 970 held_move_event_.reset(); |
984 } | 971 } |
985 | 972 |
986 if (!dispatch_details.dispatcher_destroyed) | 973 if (!dispatch_details.dispatcher_destroyed) |
987 dispatching_held_event_ = false; | 974 dispatching_held_event_ = false; |
988 return dispatch_details; | 975 return dispatch_details; |
989 } | 976 } |
990 | 977 |
991 void RootWindow::PostMouseMoveEventAfterWindowChange() { | 978 void RootWindow::PostMouseMoveEventAfterWindowChange() { |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1029 if (IsNonClientLocation(target, event->location())) | 1016 if (IsNonClientLocation(target, event->location())) |
1030 flags |= ui::EF_IS_NON_CLIENT; | 1017 flags |= ui::EF_IS_NON_CLIENT; |
1031 event->set_flags(flags); | 1018 event->set_flags(flags); |
1032 | 1019 |
1033 if (!dispatching_held_event_) { | 1020 if (!dispatching_held_event_) { |
1034 SetLastMouseLocation(window(), event->location()); | 1021 SetLastMouseLocation(window(), event->location()); |
1035 synthesize_mouse_move_ = false; | 1022 synthesize_mouse_move_ = false; |
1036 } | 1023 } |
1037 } | 1024 } |
1038 | 1025 |
| 1026 Window* RootWindow::GetTouchEventTarget(ui::TouchEvent* event) { |
| 1027 Window* target = client::GetCaptureWindow(window()); |
| 1028 if (!target) { |
| 1029 target = ConsumerToWindow( |
| 1030 ui::GestureRecognizer::Get()->GetTouchLockedTarget(*event)); |
| 1031 if (!target) { |
| 1032 target = ConsumerToWindow(ui::GestureRecognizer::Get()-> |
| 1033 GetTargetForLocation(event->location())); |
| 1034 } |
| 1035 } |
| 1036 |
| 1037 if (!target && !window()->bounds().Contains(event->location())) { |
| 1038 // If the initial touch is outside the root window, target the root. |
| 1039 target = window(); |
| 1040 if (!target) |
| 1041 target = this->window(); |
| 1042 } else { |
| 1043 // We only come here when the first contact was within the root window. |
| 1044 if (!target) |
| 1045 target = window()->GetEventHandlerForPoint(event->location()); |
| 1046 } |
| 1047 return target; |
| 1048 } |
| 1049 |
1039 } // namespace aura | 1050 } // namespace aura |
OLD | NEW |