| OLD | NEW |
| (Empty) |
| 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 | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #ifndef UI_AURA_WINDOW_EVENT_DISPATCHER_H_ | |
| 6 #define UI_AURA_WINDOW_EVENT_DISPATCHER_H_ | |
| 7 | |
| 8 #include <vector> | |
| 9 | |
| 10 #include "base/basictypes.h" | |
| 11 #include "base/gtest_prod_util.h" | |
| 12 #include "base/memory/ref_counted.h" | |
| 13 #include "base/memory/scoped_ptr.h" | |
| 14 #include "base/memory/weak_ptr.h" | |
| 15 #include "base/message_loop/message_loop.h" | |
| 16 #include "base/scoped_observer.h" | |
| 17 #include "ui/aura/aura_export.h" | |
| 18 #include "ui/aura/client/capture_delegate.h" | |
| 19 #include "ui/aura/env_observer.h" | |
| 20 #include "ui/aura/window_observer.h" | |
| 21 #include "ui/base/cursor/cursor.h" | |
| 22 #include "ui/events/event_constants.h" | |
| 23 #include "ui/events/event_processor.h" | |
| 24 #include "ui/events/event_targeter.h" | |
| 25 #include "ui/events/gestures/gesture_recognizer.h" | |
| 26 #include "ui/events/gestures/gesture_types.h" | |
| 27 #include "ui/gfx/native_widget_types.h" | |
| 28 #include "ui/gfx/point.h" | |
| 29 | |
| 30 namespace gfx { | |
| 31 class Size; | |
| 32 class Transform; | |
| 33 } | |
| 34 | |
| 35 namespace ui { | |
| 36 class GestureEvent; | |
| 37 class GestureRecognizer; | |
| 38 class KeyEvent; | |
| 39 class MouseEvent; | |
| 40 class ScrollEvent; | |
| 41 class TouchEvent; | |
| 42 } | |
| 43 | |
| 44 namespace aura { | |
| 45 class TestScreen; | |
| 46 class WindowTargeter; | |
| 47 class WindowTreeHost; | |
| 48 | |
| 49 namespace test { | |
| 50 class WindowEventDispatcherTestApi; | |
| 51 } | |
| 52 | |
| 53 // WindowEventDispatcher orchestrates event dispatch within a window tree | |
| 54 // owned by WindowTreeHost. WTH also owns the WED. | |
| 55 // TODO(beng): In progress, remove functionality not directly related to | |
| 56 // event dispatch. | |
| 57 class AURA_EXPORT WindowEventDispatcher : public ui::EventProcessor, | |
| 58 public ui::GestureEventHelper, | |
| 59 public client::CaptureDelegate, | |
| 60 public WindowObserver, | |
| 61 public EnvObserver { | |
| 62 public: | |
| 63 explicit WindowEventDispatcher(WindowTreeHost* host); | |
| 64 virtual ~WindowEventDispatcher(); | |
| 65 | |
| 66 Window* mouse_pressed_handler() { return mouse_pressed_handler_; } | |
| 67 Window* mouse_moved_handler() { return mouse_moved_handler_; } | |
| 68 | |
| 69 // Repost event for re-processing. Used when exiting context menus. | |
| 70 // We only support the ET_MOUSE_PRESSED and ET_GESTURE_TAP_DOWN event | |
| 71 // types (although the latter is currently a no-op). | |
| 72 void RepostEvent(const ui::LocatedEvent& event); | |
| 73 | |
| 74 // Invoked when the mouse events get enabled or disabled. | |
| 75 void OnMouseEventsEnableStateChanged(bool enabled); | |
| 76 | |
| 77 void DispatchCancelModeEvent(); | |
| 78 | |
| 79 // Dispatches a ui::ET_MOUSE_EXITED event at |point|. | |
| 80 // TODO(beng): needed only for WTH::OnCursorVisibilityChanged(). | |
| 81 ui::EventDispatchDetails DispatchMouseExitAtPoint( | |
| 82 const gfx::Point& point) WARN_UNUSED_RESULT; | |
| 83 | |
| 84 // Gesture Recognition ------------------------------------------------------- | |
| 85 | |
| 86 // When a touch event is dispatched to a Window, it may want to process the | |
| 87 // touch event asynchronously. In such cases, the window should consume the | |
| 88 // event during the event dispatch. Once the event is properly processed, the | |
| 89 // window should let the WindowEventDispatcher know about the result of the | |
| 90 // event processing, so that gesture events can be properly created and | |
| 91 // dispatched. |event|'s location should be in the dispatcher's coordinate | |
| 92 // space, in DIPs. | |
| 93 void ProcessedTouchEvent(ui::TouchEvent* event, | |
| 94 Window* window, | |
| 95 ui::EventResult result); | |
| 96 | |
| 97 // These methods are used to defer the processing of mouse/touch events | |
| 98 // related to resize. A client (typically a RenderWidgetHostViewAura) can call | |
| 99 // HoldPointerMoves when an resize is initiated and then ReleasePointerMoves | |
| 100 // once the resize is completed. | |
| 101 // | |
| 102 // More than one hold can be invoked and each hold must be cancelled by a | |
| 103 // release before we resume normal operation. | |
| 104 void HoldPointerMoves(); | |
| 105 void ReleasePointerMoves(); | |
| 106 | |
| 107 // Gets the last location seen in a mouse event in this root window's | |
| 108 // coordinates. This may return a point outside the root window's bounds. | |
| 109 gfx::Point GetLastMouseLocationInRoot() const; | |
| 110 | |
| 111 void OnHostLostMouseGrab(); | |
| 112 void OnCursorMovedToRootLocation(const gfx::Point& root_location); | |
| 113 | |
| 114 // TODO(beng): This is only needed because this cleanup needs to happen after | |
| 115 // all other observers are notified of OnWindowDestroying() but | |
| 116 // before OnWindowDestroyed() is sent (i.e. while the window | |
| 117 // hierarchy is still intact). This didn't seem worth adding a | |
| 118 // generic notification for as only this class needs to implement | |
| 119 // it. I would however like to find a way to do this via an | |
| 120 // observer. | |
| 121 void OnPostNotifiedWindowDestroying(Window* window); | |
| 122 | |
| 123 private: | |
| 124 FRIEND_TEST_ALL_PREFIXES(WindowEventDispatcherTest, | |
| 125 KeepTranslatedEventInRoot); | |
| 126 | |
| 127 friend class test::WindowEventDispatcherTestApi; | |
| 128 friend class Window; | |
| 129 friend class TestScreen; | |
| 130 | |
| 131 // The parameter for OnWindowHidden() to specify why window is hidden. | |
| 132 enum WindowHiddenReason { | |
| 133 WINDOW_DESTROYED, // Window is destroyed. | |
| 134 WINDOW_HIDDEN, // Window is hidden. | |
| 135 WINDOW_MOVING, // Window is temporarily marked as hidden due to move | |
| 136 // across root windows. | |
| 137 }; | |
| 138 | |
| 139 Window* window(); | |
| 140 const Window* window() const; | |
| 141 | |
| 142 // Updates the event with the appropriate transform for the device scale | |
| 143 // factor. The WindowEventDispatcher dispatches events in the physical pixel | |
| 144 // coordinate. But the event processing from WindowEventDispatcher onwards | |
| 145 // happen in device-independent pixel coordinate. So it is necessary to update | |
| 146 // the event received from the host. | |
| 147 void TransformEventForDeviceScaleFactor(ui::LocatedEvent* event); | |
| 148 | |
| 149 // Dispatches OnMouseExited to the |window| which is hiding if necessary. | |
| 150 void DispatchMouseExitToHidingWindow(Window* window); | |
| 151 | |
| 152 // Dispatches the specified event type (intended for enter/exit) to the | |
| 153 // |mouse_moved_handler_|. | |
| 154 ui::EventDispatchDetails DispatchMouseEnterOrExit( | |
| 155 const ui::MouseEvent& event, | |
| 156 ui::EventType type) WARN_UNUSED_RESULT; | |
| 157 ui::EventDispatchDetails ProcessGestures( | |
| 158 ui::GestureRecognizer::Gestures* gestures) WARN_UNUSED_RESULT; | |
| 159 | |
| 160 // Called when a window becomes invisible, either by being removed | |
| 161 // from root window hierarchy, via SetVisible(false) or being destroyed. | |
| 162 // |reason| specifies what triggered the hiding. Note that becoming invisible | |
| 163 // will cause a window to lose capture and some windows may destroy themselves | |
| 164 // on capture (like DragDropTracker). | |
| 165 void OnWindowHidden(Window* invisible, WindowHiddenReason reason); | |
| 166 | |
| 167 // Returns a target window for the given gesture event. | |
| 168 Window* GetGestureTarget(ui::GestureEvent* event); | |
| 169 | |
| 170 // Overridden from aura::client::CaptureDelegate: | |
| 171 virtual void UpdateCapture(Window* old_capture, Window* new_capture) override; | |
| 172 virtual void OnOtherRootGotCapture() override; | |
| 173 virtual void SetNativeCapture() override; | |
| 174 virtual void ReleaseNativeCapture() override; | |
| 175 | |
| 176 // Overridden from ui::EventProcessor: | |
| 177 virtual ui::EventTarget* GetRootTarget() override; | |
| 178 virtual void OnEventProcessingStarted(ui::Event* event) override; | |
| 179 | |
| 180 // Overridden from ui::EventDispatcherDelegate. | |
| 181 virtual bool CanDispatchToTarget(ui::EventTarget* target) override; | |
| 182 virtual ui::EventDispatchDetails PreDispatchEvent(ui::EventTarget* target, | |
| 183 ui::Event* event) override; | |
| 184 virtual ui::EventDispatchDetails PostDispatchEvent( | |
| 185 ui::EventTarget* target, const ui::Event& event) override; | |
| 186 | |
| 187 // Overridden from ui::GestureEventHelper. | |
| 188 virtual bool CanDispatchToConsumer(ui::GestureConsumer* consumer) override; | |
| 189 virtual void DispatchGestureEvent(ui::GestureEvent* event) override; | |
| 190 virtual void DispatchCancelTouchEvent(ui::TouchEvent* event) override; | |
| 191 | |
| 192 // Overridden from WindowObserver: | |
| 193 virtual void OnWindowDestroying(Window* window) override; | |
| 194 virtual void OnWindowDestroyed(Window* window) override; | |
| 195 virtual void OnWindowAddedToRootWindow(Window* window) override; | |
| 196 virtual void OnWindowRemovingFromRootWindow(Window* window, | |
| 197 Window* new_root) override; | |
| 198 virtual void OnWindowVisibilityChanging(Window* window, | |
| 199 bool visible) override; | |
| 200 virtual void OnWindowVisibilityChanged(Window* window, bool visible) override; | |
| 201 virtual void OnWindowBoundsChanged(Window* window, | |
| 202 const gfx::Rect& old_bounds, | |
| 203 const gfx::Rect& new_bounds) override; | |
| 204 virtual void OnWindowTransforming(Window* window) override; | |
| 205 virtual void OnWindowTransformed(Window* window) override; | |
| 206 | |
| 207 // Overridden from EnvObserver: | |
| 208 virtual void OnWindowInitialized(Window* window) override; | |
| 209 | |
| 210 // We hold and aggregate mouse drags and touch moves as a way of throttling | |
| 211 // resizes when HoldMouseMoves() is called. The following methods are used to | |
| 212 // dispatch held and newly incoming mouse and touch events, typically when an | |
| 213 // event other than one of these needs dispatching or a matching | |
| 214 // ReleaseMouseMoves()/ReleaseTouchMoves() is called. NOTE: because these | |
| 215 // methods dispatch events from WindowTreeHost the coordinates are in terms of | |
| 216 // the root. | |
| 217 ui::EventDispatchDetails DispatchHeldEvents() WARN_UNUSED_RESULT; | |
| 218 | |
| 219 // Posts a task to send synthesized mouse move event if there is no a pending | |
| 220 // task. | |
| 221 void PostSynthesizeMouseMove(); | |
| 222 | |
| 223 // Creates and dispatches synthesized mouse move event using the current mouse | |
| 224 // location. | |
| 225 ui::EventDispatchDetails SynthesizeMouseMoveEvent() WARN_UNUSED_RESULT; | |
| 226 | |
| 227 // Calls SynthesizeMouseMove() if |window| is currently visible and contains | |
| 228 // the mouse cursor. | |
| 229 void SynthesizeMouseMoveAfterChangeToWindow(Window* window); | |
| 230 | |
| 231 void PreDispatchLocatedEvent(Window* target, ui::LocatedEvent* event); | |
| 232 void PreDispatchMouseEvent(Window* target, ui::MouseEvent* event); | |
| 233 void PreDispatchTouchEvent(Window* target, ui::TouchEvent* event); | |
| 234 | |
| 235 WindowTreeHost* host_; | |
| 236 | |
| 237 // Touch ids that are currently down. | |
| 238 uint32 touch_ids_down_; | |
| 239 | |
| 240 Window* mouse_pressed_handler_; | |
| 241 Window* mouse_moved_handler_; | |
| 242 Window* event_dispatch_target_; | |
| 243 Window* old_dispatch_target_; | |
| 244 | |
| 245 bool synthesize_mouse_move_; | |
| 246 | |
| 247 // How many move holds are outstanding. We try to defer dispatching | |
| 248 // touch/mouse moves while the count is > 0. | |
| 249 int move_hold_count_; | |
| 250 // The location of |held_move_event_| is in |window_|'s coordinate. | |
| 251 scoped_ptr<ui::LocatedEvent> held_move_event_; | |
| 252 | |
| 253 // Allowing for reposting of events. Used when exiting context menus. | |
| 254 scoped_ptr<ui::LocatedEvent> held_repostable_event_; | |
| 255 | |
| 256 // Set when dispatching a held event. | |
| 257 bool dispatching_held_event_; | |
| 258 | |
| 259 ScopedObserver<aura::Window, aura::WindowObserver> observer_manager_; | |
| 260 | |
| 261 // Used to schedule reposting an event. | |
| 262 base::WeakPtrFactory<WindowEventDispatcher> repost_event_factory_; | |
| 263 | |
| 264 // Used to schedule DispatchHeldEvents() when |move_hold_count_| goes to 0. | |
| 265 base::WeakPtrFactory<WindowEventDispatcher> held_event_factory_; | |
| 266 | |
| 267 DISALLOW_COPY_AND_ASSIGN(WindowEventDispatcher); | |
| 268 }; | |
| 269 | |
| 270 } // namespace aura | |
| 271 | |
| 272 #endif // UI_AURA_WINDOW_EVENT_DISPATCHER_H_ | |
| OLD | NEW |