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.
5 #ifndef UI_AURA_WINDOW_EVENT_DISPATCHER_H_
6 #define UI_AURA_WINDOW_EVENT_DISPATCHER_H_
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/geometry/point.h"
28 #include "ui/gfx/native_widget_types.h"
37 class GestureRecognizer
;
50 class WindowEventDispatcherTestApi
;
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
57 class AURA_EXPORT WindowEventDispatcher
: public ui::EventProcessor
,
58 public ui::GestureEventHelper
,
59 public client::CaptureDelegate
,
60 public WindowObserver
,
63 explicit WindowEventDispatcher(WindowTreeHost
* host
);
64 ~WindowEventDispatcher() override
;
66 Window
* mouse_pressed_handler() { return mouse_pressed_handler_
; }
67 Window
* mouse_moved_handler() { return mouse_moved_handler_
; }
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
);
74 // Invoked when the mouse events get enabled or disabled.
75 void OnMouseEventsEnableStateChanged(bool enabled
);
77 void DispatchCancelModeEvent();
79 // Dispatches a ui::ET_MOUSE_EXITED event at |point| to the |target|
80 // If the |target| is NULL, we will dispatch the event to the root-window
81 // TODO(beng): needed only for WTH::OnCursorVisibilityChanged().
82 ui::EventDispatchDetails
DispatchMouseExitAtPoint(Window
* target
,
83 const gfx::Point
& point
)
86 // Gesture Recognition -------------------------------------------------------
88 // When a touch event is dispatched to a Window, it may want to process the
89 // touch event asynchronously. In such cases, the window should consume the
90 // event during the event dispatch. Once the event is properly processed, the
91 // window should let the WindowEventDispatcher know about the result of the
92 // event processing, so that gesture events can be properly created and
93 // dispatched. |event|'s location should be in the dispatcher's coordinate
95 void ProcessedTouchEvent(ui::TouchEvent
* event
,
97 ui::EventResult result
);
99 // These methods are used to defer the processing of mouse/touch events
100 // related to resize. A client (typically a RenderWidgetHostViewAura) can call
101 // HoldPointerMoves when an resize is initiated and then ReleasePointerMoves
102 // once the resize is completed.
104 // More than one hold can be invoked and each hold must be cancelled by a
105 // release before we resume normal operation.
106 void HoldPointerMoves();
107 void ReleasePointerMoves();
109 // Gets the last location seen in a mouse event in this root window's
110 // coordinates. This may return a point outside the root window's bounds.
111 gfx::Point
GetLastMouseLocationInRoot() const;
113 void OnHostLostMouseGrab();
114 void OnCursorMovedToRootLocation(const gfx::Point
& root_location
);
116 // TODO(beng): This is only needed because this cleanup needs to happen after
117 // all other observers are notified of OnWindowDestroying() but
118 // before OnWindowDestroyed() is sent (i.e. while the window
119 // hierarchy is still intact). This didn't seem worth adding a
120 // generic notification for as only this class needs to implement
121 // it. I would however like to find a way to do this via an
123 void OnPostNotifiedWindowDestroying(Window
* window
);
126 FRIEND_TEST_ALL_PREFIXES(WindowEventDispatcherTest
,
127 KeepTranslatedEventInRoot
);
129 friend class test::WindowEventDispatcherTestApi
;
131 friend class TestScreen
;
133 // The parameter for OnWindowHidden() to specify why window is hidden.
134 enum WindowHiddenReason
{
135 WINDOW_DESTROYED
, // Window is destroyed.
136 WINDOW_HIDDEN
, // Window is hidden.
137 WINDOW_MOVING
, // Window is temporarily marked as hidden due to move
138 // across root windows.
142 const Window
* window() const;
144 // Updates the event with the appropriate transform for the device scale
145 // factor. The WindowEventDispatcher dispatches events in the physical pixel
146 // coordinate. But the event processing from WindowEventDispatcher onwards
147 // happen in device-independent pixel coordinate. So it is necessary to update
148 // the event received from the host.
149 void TransformEventForDeviceScaleFactor(ui::LocatedEvent
* event
);
151 // Dispatches OnMouseExited to the |window| which is hiding if necessary.
152 void DispatchMouseExitToHidingWindow(Window
* window
);
154 // Dispatches the specified event type (intended for enter/exit) to the
155 // |mouse_moved_handler_|.
156 // The event's location will be converted from |target|coordinate system to
157 // |mouse_moved_handler_| coordinate system.
158 ui::EventDispatchDetails
DispatchMouseEnterOrExit(Window
* target
,
159 const ui::MouseEvent
& event
,
162 ui::EventDispatchDetails
ProcessGestures(
163 ui::GestureRecognizer::Gestures
* gestures
) WARN_UNUSED_RESULT
;
165 // Called when a window becomes invisible, either by being removed
166 // from root window hierarchy, via SetVisible(false) or being destroyed.
167 // |reason| specifies what triggered the hiding. Note that becoming invisible
168 // will cause a window to lose capture and some windows may destroy themselves
169 // on capture (like DragDropTracker).
170 void OnWindowHidden(Window
* invisible
, WindowHiddenReason reason
);
172 // Returns a target window for the given gesture event.
173 Window
* GetGestureTarget(ui::GestureEvent
* event
);
175 // Overridden from aura::client::CaptureDelegate:
176 void UpdateCapture(Window
* old_capture
, Window
* new_capture
) override
;
177 void OnOtherRootGotCapture() override
;
178 void SetNativeCapture() override
;
179 void ReleaseNativeCapture() override
;
181 // Overridden from ui::EventProcessor:
182 ui::EventTarget
* GetRootTarget() override
;
183 void OnEventProcessingStarted(ui::Event
* event
) override
;
185 // Overridden from ui::EventDispatcherDelegate.
186 bool CanDispatchToTarget(ui::EventTarget
* target
) override
;
187 ui::EventDispatchDetails
PreDispatchEvent(ui::EventTarget
* target
,
188 ui::Event
* event
) override
;
189 ui::EventDispatchDetails
PostDispatchEvent(ui::EventTarget
* target
,
190 const ui::Event
& event
) override
;
192 // Overridden from ui::GestureEventHelper.
193 bool CanDispatchToConsumer(ui::GestureConsumer
* consumer
) override
;
194 void DispatchGestureEvent(ui::GestureEvent
* event
) override
;
195 void DispatchCancelTouchEvent(ui::TouchEvent
* event
) override
;
197 // Overridden from WindowObserver:
198 void OnWindowDestroying(Window
* window
) override
;
199 void OnWindowDestroyed(Window
* window
) override
;
200 void OnWindowAddedToRootWindow(Window
* window
) override
;
201 void OnWindowRemovingFromRootWindow(Window
* window
,
202 Window
* new_root
) override
;
203 void OnWindowVisibilityChanging(Window
* window
, bool visible
) override
;
204 void OnWindowVisibilityChanged(Window
* window
, bool visible
) override
;
205 void OnWindowBoundsChanged(Window
* window
,
206 const gfx::Rect
& old_bounds
,
207 const gfx::Rect
& new_bounds
) override
;
208 void OnWindowTransforming(Window
* window
) override
;
209 void OnWindowTransformed(Window
* window
) override
;
211 // Overridden from EnvObserver:
212 void OnWindowInitialized(Window
* window
) override
;
214 // We hold and aggregate mouse drags and touch moves as a way of throttling
215 // resizes when HoldMouseMoves() is called. The following methods are used to
216 // dispatch held and newly incoming mouse and touch events, typically when an
217 // event other than one of these needs dispatching or a matching
218 // ReleaseMouseMoves()/ReleaseTouchMoves() is called. NOTE: because these
219 // methods dispatch events from WindowTreeHost the coordinates are in terms of
221 ui::EventDispatchDetails
DispatchHeldEvents() WARN_UNUSED_RESULT
;
223 // Posts a task to send synthesized mouse move event if there is no a pending
225 void PostSynthesizeMouseMove();
227 // Creates and dispatches synthesized mouse move event using the current mouse
229 ui::EventDispatchDetails
SynthesizeMouseMoveEvent() WARN_UNUSED_RESULT
;
231 // Calls SynthesizeMouseMove() if |window| is currently visible and contains
233 void SynthesizeMouseMoveAfterChangeToWindow(Window
* window
);
235 void PreDispatchLocatedEvent(Window
* target
, ui::LocatedEvent
* event
);
236 void PreDispatchMouseEvent(Window
* target
, ui::MouseEvent
* event
);
237 void PreDispatchTouchEvent(Window
* target
, ui::TouchEvent
* event
);
239 WindowTreeHost
* host_
;
241 // Touch ids that are currently down.
242 uint32 touch_ids_down_
;
244 Window
* mouse_pressed_handler_
;
245 Window
* mouse_moved_handler_
;
246 Window
* event_dispatch_target_
;
247 Window
* old_dispatch_target_
;
249 bool synthesize_mouse_move_
;
251 // How many move holds are outstanding. We try to defer dispatching
252 // touch/mouse moves while the count is > 0.
253 int move_hold_count_
;
254 // The location of |held_move_event_| is in |window_|'s coordinate.
255 scoped_ptr
<ui::LocatedEvent
> held_move_event_
;
257 // Allowing for reposting of events. Used when exiting context menus.
258 scoped_ptr
<ui::LocatedEvent
> held_repostable_event_
;
260 // Set when dispatching a held event.
261 bool dispatching_held_event_
;
263 ScopedObserver
<aura::Window
, aura::WindowObserver
> observer_manager_
;
265 // Used to schedule reposting an event.
266 base::WeakPtrFactory
<WindowEventDispatcher
> repost_event_factory_
;
268 // Used to schedule DispatchHeldEvents() when |move_hold_count_| goes to 0.
269 base::WeakPtrFactory
<WindowEventDispatcher
> held_event_factory_
;
271 DISALLOW_COPY_AND_ASSIGN(WindowEventDispatcher
);
276 #endif // UI_AURA_WINDOW_EVENT_DISPATCHER_H_