OLD | NEW |
---|---|
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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/window_event_dispatcher.h" | 5 #include "ui/aura/window_event_dispatcher.h" |
6 | 6 |
7 #include <stddef.h> | 7 #include <stddef.h> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/logging.h" | 10 #include "base/logging.h" |
11 #include "base/threading/thread_task_runner_handle.h" | 11 #include "base/threading/thread_task_runner_handle.h" |
12 #include "base/trace_event/trace_event.h" | 12 #include "base/trace_event/trace_event.h" |
13 #include "build/build_config.h" | 13 #include "build/build_config.h" |
14 #include "ui/aura/client/capture_client.h" | 14 #include "ui/aura/client/capture_client.h" |
15 #include "ui/aura/client/cursor_client.h" | 15 #include "ui/aura/client/cursor_client.h" |
16 #include "ui/aura/client/event_client.h" | 16 #include "ui/aura/client/event_client.h" |
17 #include "ui/aura/client/focus_client.h" | 17 #include "ui/aura/client/focus_client.h" |
18 #include "ui/aura/client/screen_position_client.h" | 18 #include "ui/aura/client/screen_position_client.h" |
19 #include "ui/aura/env.h" | 19 #include "ui/aura/env.h" |
20 #include "ui/aura/env_input_state_controller.h" | |
20 #include "ui/aura/window.h" | 21 #include "ui/aura/window.h" |
21 #include "ui/aura/window_delegate.h" | 22 #include "ui/aura/window_delegate.h" |
22 #include "ui/aura/window_targeter.h" | 23 #include "ui/aura/window_targeter.h" |
23 #include "ui/aura/window_tracker.h" | 24 #include "ui/aura/window_tracker.h" |
24 #include "ui/aura/window_tree_host.h" | 25 #include "ui/aura/window_tree_host.h" |
25 #include "ui/base/hit_test.h" | 26 #include "ui/base/hit_test.h" |
26 #include "ui/compositor/dip_util.h" | 27 #include "ui/compositor/dip_util.h" |
27 #include "ui/events/event.h" | 28 #include "ui/events/event.h" |
28 #include "ui/events/event_utils.h" | 29 #include "ui/events/event_utils.h" |
29 #include "ui/events/gestures/gesture_recognizer.h" | 30 #include "ui/events/gestures/gesture_recognizer.h" |
(...skipping 11 matching lines...) Expand all Loading... | |
41 if (!target->delegate()) | 42 if (!target->delegate()) |
42 return false; | 43 return false; |
43 int hit_test_code = target->delegate()->GetNonClientComponent(location); | 44 int hit_test_code = target->delegate()->GetNonClientComponent(location); |
44 return hit_test_code != HTCLIENT && hit_test_code != HTNOWHERE; | 45 return hit_test_code != HTCLIENT && hit_test_code != HTNOWHERE; |
45 } | 46 } |
46 | 47 |
47 Window* ConsumerToWindow(ui::GestureConsumer* consumer) { | 48 Window* ConsumerToWindow(ui::GestureConsumer* consumer) { |
48 return consumer ? static_cast<Window*>(consumer) : NULL; | 49 return consumer ? static_cast<Window*>(consumer) : NULL; |
49 } | 50 } |
50 | 51 |
51 void SetLastMouseLocation(const Window* root_window, | |
52 const gfx::Point& location_in_root) { | |
53 client::ScreenPositionClient* client = | |
54 client::GetScreenPositionClient(root_window); | |
55 if (client) { | |
56 gfx::Point location_in_screen = location_in_root; | |
57 client->ConvertPointToScreen(root_window, &location_in_screen); | |
58 Env::GetInstance()->set_last_mouse_location(location_in_screen); | |
59 } else { | |
60 Env::GetInstance()->set_last_mouse_location(location_in_root); | |
61 } | |
62 } | |
63 | |
64 bool IsEventCandidateForHold(const ui::Event& event) { | 52 bool IsEventCandidateForHold(const ui::Event& event) { |
65 if (event.type() == ui::ET_TOUCH_MOVED) | 53 if (event.type() == ui::ET_TOUCH_MOVED) |
66 return true; | 54 return true; |
67 if (event.type() == ui::ET_MOUSE_DRAGGED) | 55 if (event.type() == ui::ET_MOUSE_DRAGGED) |
68 return true; | 56 return true; |
69 if (event.IsMouseEvent() && (event.flags() & ui::EF_IS_SYNTHESIZED)) | 57 if (event.IsMouseEvent() && (event.flags() & ui::EF_IS_SYNTHESIZED)) |
70 return true; | 58 return true; |
71 return false; | 59 return false; |
72 } | 60 } |
73 | 61 |
74 } // namespace | 62 } // namespace |
75 | 63 |
76 //////////////////////////////////////////////////////////////////////////////// | 64 //////////////////////////////////////////////////////////////////////////////// |
77 // WindowEventDispatcher, public: | 65 // WindowEventDispatcher, public: |
78 | 66 |
79 WindowEventDispatcher::WindowEventDispatcher(WindowTreeHost* host) | 67 WindowEventDispatcher::WindowEventDispatcher(WindowTreeHost* host) |
80 : host_(host), | 68 : host_(host), |
81 touch_ids_down_(0), | |
82 mouse_pressed_handler_(NULL), | 69 mouse_pressed_handler_(NULL), |
83 mouse_moved_handler_(NULL), | 70 mouse_moved_handler_(NULL), |
84 event_dispatch_target_(NULL), | 71 event_dispatch_target_(NULL), |
85 old_dispatch_target_(NULL), | 72 old_dispatch_target_(NULL), |
86 synthesize_mouse_move_(false), | 73 synthesize_mouse_move_(false), |
87 move_hold_count_(0), | 74 move_hold_count_(0), |
88 dispatching_held_event_(nullptr), | 75 dispatching_held_event_(nullptr), |
89 observer_manager_(this), | 76 observer_manager_(this), |
90 transform_events_(true), | 77 transform_events_(true), |
78 env_controller_(new EnvInputStateController), | |
91 repost_event_factory_(this), | 79 repost_event_factory_(this), |
92 held_event_factory_(this) { | 80 held_event_factory_(this) { |
93 ui::GestureRecognizer::Get()->AddGestureEventHelper(this); | 81 ui::GestureRecognizer::Get()->AddGestureEventHelper(this); |
94 Env::GetInstance()->AddObserver(this); | 82 Env::GetInstance()->AddObserver(this); |
95 } | 83 } |
96 | 84 |
97 WindowEventDispatcher::~WindowEventDispatcher() { | 85 WindowEventDispatcher::~WindowEventDispatcher() { |
98 TRACE_EVENT0("shutdown", "WindowEventDispatcher::Destructor"); | 86 TRACE_EVENT0("shutdown", "WindowEventDispatcher::Destructor"); |
99 Env::GetInstance()->RemoveObserver(this); | 87 Env::GetInstance()->RemoveObserver(this); |
100 ui::GestureRecognizer::Get()->RemoveGestureEventHelper(this); | 88 ui::GestureRecognizer::Get()->RemoveGestureEventHelper(this); |
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
212 return location; | 200 return location; |
213 } | 201 } |
214 | 202 |
215 void WindowEventDispatcher::OnHostLostMouseGrab() { | 203 void WindowEventDispatcher::OnHostLostMouseGrab() { |
216 mouse_pressed_handler_ = NULL; | 204 mouse_pressed_handler_ = NULL; |
217 mouse_moved_handler_ = NULL; | 205 mouse_moved_handler_ = NULL; |
218 } | 206 } |
219 | 207 |
220 void WindowEventDispatcher::OnCursorMovedToRootLocation( | 208 void WindowEventDispatcher::OnCursorMovedToRootLocation( |
221 const gfx::Point& root_location) { | 209 const gfx::Point& root_location) { |
222 SetLastMouseLocation(window(), root_location); | 210 env_controller_->SetLastMouseLocation(window(), root_location); |
223 | 211 |
224 // Synthesize a mouse move in case the cursor's location in root coordinates | 212 // Synthesize a mouse move in case the cursor's location in root coordinates |
225 // changed but its position in WindowTreeHost coordinates did not. | 213 // changed but its position in WindowTreeHost coordinates did not. |
226 PostSynthesizeMouseMove(); | 214 PostSynthesizeMouseMove(); |
227 } | 215 } |
228 | 216 |
229 void WindowEventDispatcher::OnPostNotifiedWindowDestroying(Window* window) { | 217 void WindowEventDispatcher::OnPostNotifiedWindowDestroying(Window* window) { |
230 OnWindowHidden(window, WINDOW_DESTROYED); | 218 OnWindowHidden(window, WINDOW_DESTROYED); |
231 } | 219 } |
232 | 220 |
(...skipping 28 matching lines...) Expand all Loading... | |
261 return; | 249 return; |
262 } | 250 } |
263 } | 251 } |
264 | 252 |
265 ui::EventDispatchDetails WindowEventDispatcher::DispatchMouseEnterOrExit( | 253 ui::EventDispatchDetails WindowEventDispatcher::DispatchMouseEnterOrExit( |
266 Window* target, | 254 Window* target, |
267 const ui::MouseEvent& event, | 255 const ui::MouseEvent& event, |
268 ui::EventType type) { | 256 ui::EventType type) { |
269 if (event.type() != ui::ET_MOUSE_CAPTURE_CHANGED && | 257 if (event.type() != ui::ET_MOUSE_CAPTURE_CHANGED && |
270 !(event.flags() & ui::EF_IS_SYNTHESIZED)) { | 258 !(event.flags() & ui::EF_IS_SYNTHESIZED)) { |
271 SetLastMouseLocation(window(), event.root_location()); | 259 env_controller_->SetLastMouseLocation(window(), event.root_location()); |
272 } | 260 } |
273 | 261 |
274 if (!mouse_moved_handler_ || !mouse_moved_handler_->delegate() || | 262 if (!mouse_moved_handler_ || !mouse_moved_handler_->delegate() || |
275 !window()->Contains(mouse_moved_handler_)) | 263 !window()->Contains(mouse_moved_handler_)) |
276 return DispatchDetails(); | 264 return DispatchDetails(); |
277 | 265 |
278 // |event| may be an event in the process of being dispatched to a target (in | 266 // |event| may be an event in the process of being dispatched to a target (in |
279 // which case its locations will be in the event's target's coordinate | 267 // which case its locations will be in the event's target's coordinate |
280 // system), or a synthetic event created in root-window (in which case, the | 268 // system), or a synthetic event created in root-window (in which case, the |
281 // event's target will be NULL, and the event will be in the root-window's | 269 // event's target will be NULL, and the event will be in the root-window's |
(...skipping 462 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
744 Window* target, | 732 Window* target, |
745 ui::LocatedEvent* event) { | 733 ui::LocatedEvent* event) { |
746 int flags = event->flags(); | 734 int flags = event->flags(); |
747 if (IsNonClientLocation(target, event->location())) | 735 if (IsNonClientLocation(target, event->location())) |
748 flags |= ui::EF_IS_NON_CLIENT; | 736 flags |= ui::EF_IS_NON_CLIENT; |
749 event->set_flags(flags); | 737 event->set_flags(flags); |
750 | 738 |
751 if (!is_dispatched_held_event(*event) && | 739 if (!is_dispatched_held_event(*event) && |
752 (event->IsMouseEvent() || event->IsScrollEvent()) && | 740 (event->IsMouseEvent() || event->IsScrollEvent()) && |
753 !(event->flags() & ui::EF_IS_SYNTHESIZED)) { | 741 !(event->flags() & ui::EF_IS_SYNTHESIZED)) { |
754 if (event->type() != ui::ET_MOUSE_CAPTURE_CHANGED) | |
755 SetLastMouseLocation(window(), event->root_location()); | |
756 synthesize_mouse_move_ = false; | 742 synthesize_mouse_move_ = false; |
757 } | 743 } |
758 | 744 |
759 return DispatchDetails(); | 745 return DispatchDetails(); |
760 } | 746 } |
761 | 747 |
762 DispatchDetails WindowEventDispatcher::PreDispatchMouseEvent( | 748 DispatchDetails WindowEventDispatcher::PreDispatchMouseEvent( |
763 Window* target, | 749 Window* target, |
764 ui::MouseEvent* event) { | 750 ui::MouseEvent* event) { |
765 client::CursorClient* cursor_client = client::GetCursorClient(window()); | 751 client::CursorClient* cursor_client = client::GetCursorClient(window()); |
766 // We allow synthesized mouse exit events through even if mouse events are | 752 // We allow synthesized mouse exit events through even if mouse events are |
767 // disabled. This ensures that hover state, etc on controls like buttons is | 753 // disabled. This ensures that hover state, etc on controls like buttons is |
768 // cleared. | 754 // cleared. |
769 if (cursor_client && | 755 if (cursor_client && |
770 !cursor_client->IsMouseEventsEnabled() && | 756 !cursor_client->IsMouseEventsEnabled() && |
771 (event->flags() & ui::EF_IS_SYNTHESIZED) && | 757 (event->flags() & ui::EF_IS_SYNTHESIZED) && |
772 (event->type() != ui::ET_MOUSE_EXITED)) { | 758 (event->type() != ui::ET_MOUSE_EXITED)) { |
773 event->SetHandled(); | 759 event->SetHandled(); |
774 return DispatchDetails(); | 760 return DispatchDetails(); |
775 } | 761 } |
776 | 762 |
777 if (IsEventCandidateForHold(*event) && !dispatching_held_event_) { | 763 if (IsEventCandidateForHold(*event) && !dispatching_held_event_) { |
778 if (move_hold_count_) { | 764 if (move_hold_count_) { |
779 if (!(event->flags() & ui::EF_IS_SYNTHESIZED) && | |
Mark Dittmer
2016/06/08 15:31:30
I do not yet understand why this is the case, but
sadrul
2016/06/08 17:07:27
Perhaps we can move the call to |env_controller_->
Mark Dittmer
2016/06/09 15:17:10
Not sure I quite understand. Are you advocating th
sadrul
2016/06/09 15:21:40
Yeah. The rest of the early returns seem to be rel
Mark Dittmer
2016/06/10 18:03:32
Looks like no luck (see recent upload). WindowEven
| |
780 event->type() != ui::ET_MOUSE_CAPTURE_CHANGED) { | |
781 SetLastMouseLocation(window(), event->root_location()); | |
782 } | |
783 held_move_event_.reset(new ui::MouseEvent(*event, target, window())); | 765 held_move_event_.reset(new ui::MouseEvent(*event, target, window())); |
784 event->SetHandled(); | 766 event->SetHandled(); |
785 return DispatchDetails(); | 767 return DispatchDetails(); |
786 } else { | 768 } else { |
787 // We may have a held event for a period between the time move_hold_count_ | 769 // We may have a held event for a period between the time move_hold_count_ |
788 // fell to 0 and the DispatchHeldEvents executes. Since we're going to | 770 // fell to 0 and the DispatchHeldEvents executes. Since we're going to |
789 // dispatch the new event directly below, we can reset the old one. | 771 // dispatch the new event directly below, we can reset the old one. |
790 held_move_event_.reset(); | 772 held_move_event_.reset(); |
791 } | 773 } |
792 } | 774 } |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
844 } | 826 } |
845 } | 827 } |
846 break; | 828 break; |
847 case ui::ET_MOUSE_PRESSED: | 829 case ui::ET_MOUSE_PRESSED: |
848 // Don't set the mouse pressed handler for non client mouse down events. | 830 // Don't set the mouse pressed handler for non client mouse down events. |
849 // These are only sent by Windows and are not always followed with non | 831 // These are only sent by Windows and are not always followed with non |
850 // client mouse up events which causes subsequent mouse events to be | 832 // client mouse up events which causes subsequent mouse events to be |
851 // sent to the wrong target. | 833 // sent to the wrong target. |
852 if (!(event->flags() & ui::EF_IS_NON_CLIENT) && !mouse_pressed_handler_) | 834 if (!(event->flags() & ui::EF_IS_NON_CLIENT) && !mouse_pressed_handler_) |
853 mouse_pressed_handler_ = target; | 835 mouse_pressed_handler_ = target; |
854 Env::GetInstance()->set_mouse_button_flags(event->button_flags()); | |
855 break; | 836 break; |
856 case ui::ET_MOUSE_RELEASED: | 837 case ui::ET_MOUSE_RELEASED: |
857 mouse_pressed_handler_ = NULL; | 838 mouse_pressed_handler_ = NULL; |
858 Env::GetInstance()->set_mouse_button_flags( | |
859 event->button_flags() & ~event->changed_button_flags()); | |
860 break; | 839 break; |
861 default: | 840 default: |
862 break; | 841 break; |
863 } | 842 } |
864 | 843 |
844 env_controller_->UpdateStateForMouseEvent(window(), event); | |
845 | |
865 return PreDispatchLocatedEvent(target, event); | 846 return PreDispatchLocatedEvent(target, event); |
866 } | 847 } |
867 | 848 |
868 DispatchDetails WindowEventDispatcher::PreDispatchTouchEvent( | 849 DispatchDetails WindowEventDispatcher::PreDispatchTouchEvent( |
869 Window* target, | 850 Window* target, |
870 ui::TouchEvent* event) { | 851 ui::TouchEvent* event) { |
871 switch (event->type()) { | 852 if (event->type() == ui::ET_TOUCH_MOVED && move_hold_count_ && |
872 case ui::ET_TOUCH_PRESSED: | 853 !dispatching_held_event_) { |
873 touch_ids_down_ |= (1 << event->touch_id()); | |
874 Env::GetInstance()->set_touch_down(touch_ids_down_ != 0); | |
875 break; | |
876 | |
877 // Handle ET_TOUCH_CANCELLED only if it has a native event. | |
878 case ui::ET_TOUCH_CANCELLED: | |
879 if (!event->HasNativeEvent()) | |
880 break; | |
881 // fallthrough | |
882 case ui::ET_TOUCH_RELEASED: | |
883 touch_ids_down_ = (touch_ids_down_ | (1 << event->touch_id())) ^ | |
884 (1 << event->touch_id()); | |
885 Env::GetInstance()->set_touch_down(touch_ids_down_ != 0); | |
886 break; | |
887 | |
888 case ui::ET_TOUCH_MOVED: | |
889 if (move_hold_count_ && !dispatching_held_event_) { | |
890 held_move_event_.reset(new ui::TouchEvent(*event, target, window())); | 854 held_move_event_.reset(new ui::TouchEvent(*event, target, window())); |
891 event->SetHandled(); | 855 event->SetHandled(); |
892 return DispatchDetails(); | 856 return DispatchDetails(); |
893 } | 857 } |
894 break; | |
895 | 858 |
896 default: | 859 env_controller_->UpdateStateForTouchEvent(event); |
897 NOTREACHED(); | |
898 break; | |
899 } | |
900 | 860 |
901 ui::TouchEvent orig_event(*event, target, window()); | 861 ui::TouchEvent orig_event(*event, target, window()); |
902 if (!ui::GestureRecognizer::Get()->ProcessTouchEventPreDispatch(&orig_event, | 862 if (!ui::GestureRecognizer::Get()->ProcessTouchEventPreDispatch(&orig_event, |
903 target)) { | 863 target)) { |
904 // The event is invalid - ignore it. | 864 // The event is invalid - ignore it. |
905 event->StopPropagation(); | 865 event->StopPropagation(); |
906 event->DisableSynchronousHandling(); | 866 event->DisableSynchronousHandling(); |
907 return DispatchDetails(); | 867 return DispatchDetails(); |
908 } | 868 } |
909 | 869 |
910 // This flag is set depending on the gestures recognized in the call above, | 870 // This flag is set depending on the gestures recognized in the call above, |
911 // and needs to propagate with the forwarded event. | 871 // and needs to propagate with the forwarded event. |
912 event->set_may_cause_scrolling(orig_event.may_cause_scrolling()); | 872 event->set_may_cause_scrolling(orig_event.may_cause_scrolling()); |
913 | 873 |
914 return PreDispatchLocatedEvent(target, event); | 874 return PreDispatchLocatedEvent(target, event); |
915 } | 875 } |
916 | 876 |
917 } // namespace aura | 877 } // namespace aura |
OLD | NEW |