| 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 26 matching lines...) Expand all Loading... |
| 259 DispatchMouseExitAtPoint(this->window(), last_mouse_location); | 247 DispatchMouseExitAtPoint(this->window(), last_mouse_location); |
| 260 if (details.dispatcher_destroyed) | 248 if (details.dispatcher_destroyed) |
| 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 env_controller_->UpdateStateForMouseEvent(window(), event); |
| 270 !(event.flags() & ui::EF_IS_SYNTHESIZED)) { | |
| 271 SetLastMouseLocation(window(), event.root_location()); | |
| 272 } | |
| 273 | |
| 274 if (!mouse_moved_handler_ || !mouse_moved_handler_->delegate() || | 258 if (!mouse_moved_handler_ || !mouse_moved_handler_->delegate() || |
| 275 !window()->Contains(mouse_moved_handler_)) | 259 !window()->Contains(mouse_moved_handler_)) |
| 276 return DispatchDetails(); | 260 return DispatchDetails(); |
| 277 | 261 |
| 278 // |event| may be an event in the process of being dispatched to a target (in | 262 // |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 | 263 // 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 | 264 // 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 | 265 // event's target will be NULL, and the event will be in the root-window's |
| 282 // coordinate system. | 266 // coordinate system. |
| 283 if (!target) | 267 if (!target) |
| (...skipping 460 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 744 Window* target, | 728 Window* target, |
| 745 ui::LocatedEvent* event) { | 729 ui::LocatedEvent* event) { |
| 746 int flags = event->flags(); | 730 int flags = event->flags(); |
| 747 if (IsNonClientLocation(target, event->location())) | 731 if (IsNonClientLocation(target, event->location())) |
| 748 flags |= ui::EF_IS_NON_CLIENT; | 732 flags |= ui::EF_IS_NON_CLIENT; |
| 749 event->set_flags(flags); | 733 event->set_flags(flags); |
| 750 | 734 |
| 751 if (!is_dispatched_held_event(*event) && | 735 if (!is_dispatched_held_event(*event) && |
| 752 (event->IsMouseEvent() || event->IsScrollEvent()) && | 736 (event->IsMouseEvent() || event->IsScrollEvent()) && |
| 753 !(event->flags() & ui::EF_IS_SYNTHESIZED)) { | 737 !(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; | 738 synthesize_mouse_move_ = false; |
| 757 } | 739 } |
| 758 | 740 |
| 759 return DispatchDetails(); | 741 return DispatchDetails(); |
| 760 } | 742 } |
| 761 | 743 |
| 762 DispatchDetails WindowEventDispatcher::PreDispatchMouseEvent( | 744 DispatchDetails WindowEventDispatcher::PreDispatchMouseEvent( |
| 763 Window* target, | 745 Window* target, |
| 764 ui::MouseEvent* event) { | 746 ui::MouseEvent* event) { |
| 765 client::CursorClient* cursor_client = client::GetCursorClient(window()); | 747 client::CursorClient* cursor_client = client::GetCursorClient(window()); |
| 766 // We allow synthesized mouse exit events through even if mouse events are | 748 // 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 | 749 // disabled. This ensures that hover state, etc on controls like buttons is |
| 768 // cleared. | 750 // cleared. |
| 769 if (cursor_client && | 751 if (cursor_client && |
| 770 !cursor_client->IsMouseEventsEnabled() && | 752 !cursor_client->IsMouseEventsEnabled() && |
| 771 (event->flags() & ui::EF_IS_SYNTHESIZED) && | 753 (event->flags() & ui::EF_IS_SYNTHESIZED) && |
| 772 (event->type() != ui::ET_MOUSE_EXITED)) { | 754 (event->type() != ui::ET_MOUSE_EXITED)) { |
| 773 event->SetHandled(); | 755 event->SetHandled(); |
| 774 return DispatchDetails(); | 756 return DispatchDetails(); |
| 775 } | 757 } |
| 776 | 758 |
| 759 env_controller_->UpdateStateForMouseEvent(window(), *event); |
| 760 |
| 777 if (IsEventCandidateForHold(*event) && !dispatching_held_event_) { | 761 if (IsEventCandidateForHold(*event) && !dispatching_held_event_) { |
| 778 if (move_hold_count_) { | 762 if (move_hold_count_) { |
| 779 if (!(event->flags() & ui::EF_IS_SYNTHESIZED) && | |
| 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())); | 763 held_move_event_.reset(new ui::MouseEvent(*event, target, window())); |
| 784 event->SetHandled(); | 764 event->SetHandled(); |
| 785 return DispatchDetails(); | 765 return DispatchDetails(); |
| 786 } else { | 766 } else { |
| 787 // We may have a held event for a period between the time move_hold_count_ | 767 // 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 | 768 // 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. | 769 // dispatch the new event directly below, we can reset the old one. |
| 790 held_move_event_.reset(); | 770 held_move_event_.reset(); |
| 791 } | 771 } |
| 792 } | 772 } |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 844 } | 824 } |
| 845 } | 825 } |
| 846 break; | 826 break; |
| 847 case ui::ET_MOUSE_PRESSED: | 827 case ui::ET_MOUSE_PRESSED: |
| 848 // Don't set the mouse pressed handler for non client mouse down events. | 828 // 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 | 829 // 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 | 830 // client mouse up events which causes subsequent mouse events to be |
| 851 // sent to the wrong target. | 831 // sent to the wrong target. |
| 852 if (!(event->flags() & ui::EF_IS_NON_CLIENT) && !mouse_pressed_handler_) | 832 if (!(event->flags() & ui::EF_IS_NON_CLIENT) && !mouse_pressed_handler_) |
| 853 mouse_pressed_handler_ = target; | 833 mouse_pressed_handler_ = target; |
| 854 Env::GetInstance()->set_mouse_button_flags(event->button_flags()); | |
| 855 break; | 834 break; |
| 856 case ui::ET_MOUSE_RELEASED: | 835 case ui::ET_MOUSE_RELEASED: |
| 857 mouse_pressed_handler_ = NULL; | 836 mouse_pressed_handler_ = NULL; |
| 858 Env::GetInstance()->set_mouse_button_flags( | |
| 859 event->button_flags() & ~event->changed_button_flags()); | |
| 860 break; | 837 break; |
| 861 default: | 838 default: |
| 862 break; | 839 break; |
| 863 } | 840 } |
| 864 | 841 |
| 865 return PreDispatchLocatedEvent(target, event); | 842 return PreDispatchLocatedEvent(target, event); |
| 866 } | 843 } |
| 867 | 844 |
| 868 DispatchDetails WindowEventDispatcher::PreDispatchTouchEvent( | 845 DispatchDetails WindowEventDispatcher::PreDispatchTouchEvent( |
| 869 Window* target, | 846 Window* target, |
| 870 ui::TouchEvent* event) { | 847 ui::TouchEvent* event) { |
| 871 switch (event->type()) { | 848 if (event->type() == ui::ET_TOUCH_MOVED && move_hold_count_ && |
| 872 case ui::ET_TOUCH_PRESSED: | 849 !dispatching_held_event_) { |
| 873 touch_ids_down_ |= (1 << event->touch_id()); | 850 held_move_event_.reset(new ui::TouchEvent(*event, target, window())); |
| 874 Env::GetInstance()->set_touch_down(touch_ids_down_ != 0); | 851 event->SetHandled(); |
| 875 break; | 852 return DispatchDetails(); |
| 853 } |
| 876 | 854 |
| 877 // Handle ET_TOUCH_CANCELLED only if it has a native event. | 855 env_controller_->UpdateStateForTouchEvent(*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())); | |
| 891 event->SetHandled(); | |
| 892 return DispatchDetails(); | |
| 893 } | |
| 894 break; | |
| 895 | |
| 896 default: | |
| 897 NOTREACHED(); | |
| 898 break; | |
| 899 } | |
| 900 | 856 |
| 901 ui::TouchEvent orig_event(*event, target, window()); | 857 ui::TouchEvent orig_event(*event, target, window()); |
| 902 if (!ui::GestureRecognizer::Get()->ProcessTouchEventPreDispatch(&orig_event, | 858 if (!ui::GestureRecognizer::Get()->ProcessTouchEventPreDispatch(&orig_event, |
| 903 target)) { | 859 target)) { |
| 904 // The event is invalid - ignore it. | 860 // The event is invalid - ignore it. |
| 905 event->StopPropagation(); | 861 event->StopPropagation(); |
| 906 event->DisableSynchronousHandling(); | 862 event->DisableSynchronousHandling(); |
| 907 return DispatchDetails(); | 863 return DispatchDetails(); |
| 908 } | 864 } |
| 909 | 865 |
| 910 // This flag is set depending on the gestures recognized in the call above, | 866 // This flag is set depending on the gestures recognized in the call above, |
| 911 // and needs to propagate with the forwarded event. | 867 // and needs to propagate with the forwarded event. |
| 912 event->set_may_cause_scrolling(orig_event.may_cause_scrolling()); | 868 event->set_may_cause_scrolling(orig_event.may_cause_scrolling()); |
| 913 | 869 |
| 914 return PreDispatchLocatedEvent(target, event); | 870 return PreDispatchLocatedEvent(target, event); |
| 915 } | 871 } |
| 916 | 872 |
| 917 } // namespace aura | 873 } // namespace aura |
| OLD | NEW |