| 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 |