Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / ui / aura / window_event_dispatcher.h
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.
92   void ProcessedTouchEvent(ui::TouchEvent* event,
93                            Window* window,
94                            ui::EventResult result);
95
96   // These methods are used to defer the processing of mouse/touch events
97   // related to resize. A client (typically a RenderWidgetHostViewAura) can call
98   // HoldPointerMoves when an resize is initiated and then ReleasePointerMoves
99   // once the resize is completed.
100   //
101   // More than one hold can be invoked and each hold must be cancelled by a
102   // release before we resume normal operation.
103   void HoldPointerMoves();
104   void ReleasePointerMoves();
105
106   // Gets the last location seen in a mouse event in this root window's
107   // coordinates. This may return a point outside the root window's bounds.
108   gfx::Point GetLastMouseLocationInRoot() const;
109
110   void OnHostLostMouseGrab();
111   void OnCursorMovedToRootLocation(const gfx::Point& root_location);
112
113   // TODO(beng): This is only needed because this cleanup needs to happen after
114   //             all other observers are notified of OnWindowDestroying() but
115   //             before OnWindowDestroyed() is sent (i.e. while the window
116   //             hierarchy is still intact). This didn't seem worth adding a
117   //             generic notification for as only this class needs to implement
118   //             it. I would however like to find a way to do this via an
119   //             observer.
120   void OnPostNotifiedWindowDestroying(Window* window);
121
122  private:
123   FRIEND_TEST_ALL_PREFIXES(WindowEventDispatcherTest,
124                            KeepTranslatedEventInRoot);
125
126   friend class test::WindowEventDispatcherTestApi;
127   friend class Window;
128   friend class TestScreen;
129
130   // The parameter for OnWindowHidden() to specify why window is hidden.
131   enum WindowHiddenReason {
132     WINDOW_DESTROYED,  // Window is destroyed.
133     WINDOW_HIDDEN,     // Window is hidden.
134     WINDOW_MOVING,     // Window is temporarily marked as hidden due to move
135                        // across root windows.
136   };
137
138   Window* window();
139   const Window* window() const;
140
141   // Updates the event with the appropriate transform for the device scale
142   // factor. The WindowEventDispatcher dispatches events in the physical pixel
143   // coordinate. But the event processing from WindowEventDispatcher onwards
144   // happen in device-independent pixel coordinate. So it is necessary to update
145   // the event received from the host.
146   void TransformEventForDeviceScaleFactor(ui::LocatedEvent* event);
147
148   // Dispatches OnMouseExited to the |window| which is hiding if necessary.
149   void DispatchMouseExitToHidingWindow(Window* window);
150
151   // Dispatches the specified event type (intended for enter/exit) to the
152   // |mouse_moved_handler_|.
153   ui::EventDispatchDetails DispatchMouseEnterOrExit(
154       const ui::MouseEvent& event,
155       ui::EventType type) WARN_UNUSED_RESULT;
156   ui::EventDispatchDetails ProcessGestures(
157       ui::GestureRecognizer::Gestures* gestures) WARN_UNUSED_RESULT;
158
159   // Called when a window becomes invisible, either by being removed
160   // from root window hierarchy, via SetVisible(false) or being destroyed.
161   // |reason| specifies what triggered the hiding. Note that becoming invisible
162   // will cause a window to lose capture and some windows may destroy themselves
163   // on capture (like DragDropTracker).
164   void OnWindowHidden(Window* invisible, WindowHiddenReason reason);
165
166   // Returns a target window for the given gesture event.
167   Window* GetGestureTarget(ui::GestureEvent* event);
168
169   // Overridden from aura::client::CaptureDelegate:
170   virtual void UpdateCapture(Window* old_capture, Window* new_capture) OVERRIDE;
171   virtual void OnOtherRootGotCapture() OVERRIDE;
172   virtual void SetNativeCapture() OVERRIDE;
173   virtual void ReleaseNativeCapture() OVERRIDE;
174
175   // Overridden from ui::EventProcessor:
176   virtual ui::EventTarget* GetRootTarget() OVERRIDE;
177   virtual void PrepareEventForDispatch(ui::Event* event) OVERRIDE;
178
179   // Overridden from ui::EventDispatcherDelegate.
180   virtual bool CanDispatchToTarget(ui::EventTarget* target) OVERRIDE;
181   virtual ui::EventDispatchDetails PreDispatchEvent(ui::EventTarget* target,
182                                                     ui::Event* event) OVERRIDE;
183   virtual ui::EventDispatchDetails PostDispatchEvent(
184       ui::EventTarget* target, const ui::Event& event) OVERRIDE;
185
186   // Overridden from ui::GestureEventHelper.
187   virtual bool CanDispatchToConsumer(ui::GestureConsumer* consumer) OVERRIDE;
188   virtual void DispatchGestureEvent(ui::GestureEvent* event) OVERRIDE;
189   virtual void DispatchCancelTouchEvent(ui::TouchEvent* event) OVERRIDE;
190
191   // Overridden from WindowObserver:
192   virtual void OnWindowDestroying(Window* window) OVERRIDE;
193   virtual void OnWindowDestroyed(Window* window) OVERRIDE;
194   virtual void OnWindowAddedToRootWindow(Window* window) OVERRIDE;
195   virtual void OnWindowRemovingFromRootWindow(Window* window,
196                                               Window* new_root) OVERRIDE;
197   virtual void OnWindowVisibilityChanging(Window* window,
198                                           bool visible) OVERRIDE;
199   virtual void OnWindowVisibilityChanged(Window* window, bool visible) OVERRIDE;
200   virtual void OnWindowBoundsChanged(Window* window,
201                                      const gfx::Rect& old_bounds,
202                                      const gfx::Rect& new_bounds) OVERRIDE;
203   virtual void OnWindowTransforming(Window* window) OVERRIDE;
204   virtual void OnWindowTransformed(Window* window) OVERRIDE;
205
206   // Overridden from EnvObserver:
207   virtual void OnWindowInitialized(Window* window) OVERRIDE;
208
209   // We hold and aggregate mouse drags and touch moves as a way of throttling
210   // resizes when HoldMouseMoves() is called. The following methods are used to
211   // dispatch held and newly incoming mouse and touch events, typically when an
212   // event other than one of these needs dispatching or a matching
213   // ReleaseMouseMoves()/ReleaseTouchMoves() is called.  NOTE: because these
214   // methods dispatch events from WindowTreeHost the coordinates are in terms of
215   // the root.
216   ui::EventDispatchDetails DispatchHeldEvents() WARN_UNUSED_RESULT;
217
218   // Posts a task to send synthesized mouse move event if there is no a pending
219   // task.
220   void PostSynthesizeMouseMove();
221
222   // Creates and dispatches synthesized mouse move event using the current mouse
223   // location.
224   ui::EventDispatchDetails SynthesizeMouseMoveEvent() WARN_UNUSED_RESULT;
225
226   // Calls SynthesizeMouseMove() if |window| is currently visible and contains
227   // the mouse cursor.
228   void SynthesizeMouseMoveAfterChangeToWindow(Window* window);
229
230   void PreDispatchLocatedEvent(Window* target, ui::LocatedEvent* event);
231   void PreDispatchMouseEvent(Window* target, ui::MouseEvent* event);
232   void PreDispatchTouchEvent(Window* target, ui::TouchEvent* event);
233
234   WindowTreeHost* host_;
235
236   // Touch ids that are currently down.
237   uint32 touch_ids_down_;
238
239   Window* mouse_pressed_handler_;
240   Window* mouse_moved_handler_;
241   Window* event_dispatch_target_;
242   Window* old_dispatch_target_;
243
244   bool synthesize_mouse_move_;
245
246   // How many move holds are outstanding. We try to defer dispatching
247   // touch/mouse moves while the count is > 0.
248   int move_hold_count_;
249   // The location of |held_move_event_| is in |window_|'s coordinate.
250   scoped_ptr<ui::LocatedEvent> held_move_event_;
251
252   // Allowing for reposting of events. Used when exiting context menus.
253   scoped_ptr<ui::LocatedEvent> held_repostable_event_;
254
255   // Set when dispatching a held event.
256   bool dispatching_held_event_;
257
258   ScopedObserver<aura::Window, aura::WindowObserver> observer_manager_;
259
260   // Used to schedule reposting an event.
261   base::WeakPtrFactory<WindowEventDispatcher> repost_event_factory_;
262
263   // Used to schedule DispatchHeldEvents() when |move_hold_count_| goes to 0.
264   base::WeakPtrFactory<WindowEventDispatcher> held_event_factory_;
265
266   DISALLOW_COPY_AND_ASSIGN(WindowEventDispatcher);
267 };
268
269 }  // namespace aura
270
271 #endif  // UI_AURA_WINDOW_EVENT_DISPATCHER_H_