blob: a0b70604d0117565b7e8e0d6a6b3b09a2b7fdf59 [file] [log] [blame]
[email protected]2374d1812014-03-04 03:42:271// Copyright 2014 The Chromium Authors. All rights reserved.
[email protected]81585f32011-07-29 19:32:062// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
[email protected]fcc51c952014-02-21 21:31:265#ifndef UI_AURA_WINDOW_EVENT_DISPATCHER_H_
6#define UI_AURA_WINDOW_EVENT_DISPATCHER_H_
[email protected]81585f32011-07-29 19:32:067
avi4ca294112015-12-24 08:04:098#include <stdint.h>
9
danakj25c52c32016-04-12 21:51:0810#include <memory>
[email protected]1266ba492012-05-16 23:29:4811#include <vector>
12
[email protected]379b0d62013-03-23 17:26:3713#include "base/gtest_prod_util.h"
avi4ca294112015-12-24 08:04:0914#include "base/macros.h"
[email protected]8d8953c2012-03-23 23:19:1015#include "base/memory/ref_counted.h"
[email protected]f296be72011-10-11 15:40:0016#include "base/memory/weak_ptr.h"
[email protected]4e2d03e22013-07-18 04:19:5417#include "base/message_loop/message_loop.h"
[email protected]29cf75e2014-03-21 20:48:4518#include "base/scoped_observer.h"
[email protected]f94f0f12011-09-14 21:14:0119#include "ui/aura/aura_export.h"
[email protected]60a978b72012-06-08 00:29:1820#include "ui/aura/client/capture_delegate.h"
[email protected]29cf75e2014-03-21 20:48:4521#include "ui/aura/env_observer.h"
22#include "ui/aura/window_observer.h"
[email protected]c7839552012-04-03 21:14:3623#include "ui/base/cursor/cursor.h"
[email protected]86ccbd42013-09-18 18:11:5424#include "ui/events/event_constants.h"
[email protected]8daeb412013-12-06 23:55:5125#include "ui/events/event_processor.h"
26#include "ui/events/event_targeter.h"
[email protected]e5ae4652013-09-25 00:36:2727#include "ui/events/gestures/gesture_recognizer.h"
28#include "ui/events/gestures/gesture_types.h"
tfarina655f81d2014-12-23 02:38:5029#include "ui/gfx/geometry/point.h"
[email protected]81585f32011-07-29 19:32:0630#include "ui/gfx/native_widget_types.h"
31
32namespace gfx {
33class Size;
[email protected]0f0453e2012-10-14 18:15:3534class Transform;
[email protected]81585f32011-07-29 19:32:0635}
36
[email protected]593ddfa2011-10-20 21:51:4337namespace ui {
[email protected]2487bee42012-08-10 16:21:4438class GestureEvent;
[email protected]81675c92012-04-05 22:14:4939class GestureRecognizer;
[email protected]ca7060982012-08-08 18:05:2540class KeyEvent;
[email protected]ca7060982012-08-08 18:05:2541class MouseEvent;
42class ScrollEvent;
[email protected]8ca8d2462012-08-09 22:28:0443class TouchEvent;
[email protected]593ddfa2011-10-20 21:51:4344}
45
[email protected]81585f32011-07-29 19:32:0646namespace aura {
[email protected]778ee202013-09-25 17:56:1047class TestScreen;
[email protected]8daeb412013-12-06 23:55:5148class WindowTargeter;
[email protected]7a60cd3a2014-03-20 20:54:5749class WindowTreeHost;
[email protected]b1b155512011-08-18 22:47:5050
[email protected]6b61474752014-06-27 17:37:0751namespace test {
52class WindowEventDispatcherTestApi;
53}
54
[email protected]2374d1812014-03-04 03:42:2755// WindowEventDispatcher orchestrates event dispatch within a window tree
56// owned by WindowTreeHost. WTH also owns the WED.
57// TODO(beng): In progress, remove functionality not directly related to
58// event dispatch.
[email protected]056ce052014-02-21 05:19:3259class AURA_EXPORT WindowEventDispatcher : public ui::EventProcessor,
60 public ui::GestureEventHelper,
[email protected]29cf75e2014-03-21 20:48:4561 public client::CaptureDelegate,
62 public WindowObserver,
63 public EnvObserver {
[email protected]81585f32011-07-29 19:32:0664 public:
[email protected]2f2620332014-02-28 10:07:3865 explicit WindowEventDispatcher(WindowTreeHost* host);
dcheng5bdeb6b2014-10-27 20:58:0566 ~WindowEventDispatcher() override;
[email protected]9ed496e2011-10-18 23:47:3967
sky05111cd2015-11-16 22:41:5768 void set_transform_events(bool value) { transform_events_ = value; }
69
[email protected]9ed496e2011-10-18 23:47:3970 Window* mouse_pressed_handler() { return mouse_pressed_handler_; }
[email protected]23a2dc8d2013-08-22 15:04:2271 Window* mouse_moved_handler() { return mouse_moved_handler_; }
[email protected]a857dbe2012-05-30 22:10:1472
[email protected]5c95ee472013-03-15 16:55:2773 // Repost event for re-processing. Used when exiting context menus.
ananta57508862016-01-14 21:54:4274 // We support the ET_MOUSE_PRESSED, ET_TOUCH_PRESSED and ET_GESTURE_TAP_DOWN
75 // event types (although the latter is currently a no-op).
76 void RepostEvent(const ui::LocatedEvent* event);
[email protected]5c95ee472013-03-15 16:55:2777
[email protected]166ccde2012-12-19 16:43:5378 // Invoked when the mouse events get enabled or disabled.
79 void OnMouseEventsEnableStateChanged(bool enabled);
80
[email protected]d04aca192014-03-07 05:00:1781 void DispatchCancelModeEvent();
82
myid.shin50bcf1b2015-01-08 02:42:1783 // Dispatches a ui::ET_MOUSE_EXITED event at |point| to the |target|
84 // If the |target| is NULL, we will dispatch the event to the root-window
[email protected]29cf75e2014-03-21 20:48:4585 // TODO(beng): needed only for WTH::OnCursorVisibilityChanged().
myid.shin50bcf1b2015-01-08 02:42:1786 ui::EventDispatchDetails DispatchMouseExitAtPoint(Window* target,
87 const gfx::Point& point)
88 WARN_UNUSED_RESULT;
[email protected]450edc672013-09-20 15:29:5989
[email protected]4aeda5792012-01-26 20:38:4290 // Gesture Recognition -------------------------------------------------------
91
[email protected]9bc27552012-10-17 21:02:5192 // When a touch event is dispatched to a Window, it may want to process the
93 // touch event asynchronously. In such cases, the window should consume the
94 // event during the event dispatch. Once the event is properly processed, the
[email protected]056ce052014-02-21 05:19:3295 // window should let the WindowEventDispatcher know about the result of the
96 // event processing, so that gesture events can be properly created and
tdresserb6387c52014-09-10 20:39:4997 // dispatched. |event|'s location should be in the dispatcher's coordinate
98 // space, in DIPs.
avi4ca294112015-12-24 08:04:0999 virtual void ProcessedTouchEvent(uint32_t unique_event_id,
lanweic67620d2015-05-25 17:24:54100 Window* window,
101 ui::EventResult result);
[email protected]4aeda5792012-01-26 20:38:42102
[email protected]a1f064d2013-06-11 18:58:54103 // These methods are used to defer the processing of mouse/touch events
104 // related to resize. A client (typically a RenderWidgetHostViewAura) can call
105 // HoldPointerMoves when an resize is initiated and then ReleasePointerMoves
[email protected]308aaa32012-03-12 13:14:50106 // once the resize is completed.
107 //
108 // More than one hold can be invoked and each hold must be cancelled by a
109 // release before we resume normal operation.
[email protected]a1f064d2013-06-11 18:58:54110 void HoldPointerMoves();
111 void ReleasePointerMoves();
[email protected]308aaa32012-03-12 13:14:50112
[email protected]718b26c2012-07-24 20:53:23113 // Gets the last location seen in a mouse event in this root window's
114 // coordinates. This may return a point outside the root window's bounds.
115 gfx::Point GetLastMouseLocationInRoot() const;
116
[email protected]c1784712014-07-23 14:19:39117 void OnHostLostMouseGrab();
[email protected]d04aca192014-03-07 05:00:17118 void OnCursorMovedToRootLocation(const gfx::Point& root_location);
119
[email protected]29cf75e2014-03-21 20:48:45120 // TODO(beng): This is only needed because this cleanup needs to happen after
121 // all other observers are notified of OnWindowDestroying() but
122 // before OnWindowDestroyed() is sent (i.e. while the window
123 // hierarchy is still intact). This didn't seem worth adding a
124 // generic notification for as only this class needs to implement
125 // it. I would however like to find a way to do this via an
126 // observer.
127 void OnPostNotifiedWindowDestroying(Window* window);
128
[email protected]72eb1cf2012-01-31 23:31:11129 private:
[email protected]056ce052014-02-21 05:19:32130 FRIEND_TEST_ALL_PREFIXES(WindowEventDispatcherTest,
131 KeepTranslatedEventInRoot);
[email protected]379b0d62013-03-23 17:26:37132
[email protected]6b61474752014-06-27 17:37:07133 friend class test::WindowEventDispatcherTestApi;
[email protected]16690b02012-02-01 04:06:35134 friend class Window;
[email protected]046cd7c2013-03-08 13:52:43135 friend class TestScreen;
[email protected]16690b02012-02-01 04:06:35136
[email protected]2e98aaf72012-11-08 06:30:59137 // The parameter for OnWindowHidden() to specify why window is hidden.
138 enum WindowHiddenReason {
139 WINDOW_DESTROYED, // Window is destroyed.
140 WINDOW_HIDDEN, // Window is hidden.
141 WINDOW_MOVING, // Window is temporarily marked as hidden due to move
142 // across root windows.
143 };
144
[email protected]7a60cd3a2014-03-20 20:54:57145 Window* window();
146 const Window* window() const;
147
[email protected]49d7c1d2012-11-15 17:08:08148 // Updates the event with the appropriate transform for the device scale
[email protected]d04aca192014-03-07 05:00:17149 // factor. The WindowEventDispatcher dispatches events in the physical pixel
[email protected]056ce052014-02-21 05:19:32150 // coordinate. But the event processing from WindowEventDispatcher onwards
151 // happen in device-independent pixel coordinate. So it is necessary to update
152 // the event received from the host.
[email protected]95aa489a2013-07-08 15:30:23153 void TransformEventForDeviceScaleFactor(ui::LocatedEvent* event);
[email protected]49d7c1d2012-11-15 17:08:08154
[email protected]29cf75e2014-03-21 20:48:45155 // Dispatches OnMouseExited to the |window| which is hiding if necessary.
156 void DispatchMouseExitToHidingWindow(Window* window);
157
[email protected]fe9eec12013-01-28 21:57:33158 // Dispatches the specified event type (intended for enter/exit) to the
159 // |mouse_moved_handler_|.
myid.shin50bcf1b2015-01-08 02:42:17160 // The event's location will be converted from |target|coordinate system to
161 // |mouse_moved_handler_| coordinate system.
162 ui::EventDispatchDetails DispatchMouseEnterOrExit(Window* target,
163 const ui::MouseEvent& event,
164 ui::EventType type)
165 WARN_UNUSED_RESULT;
[email protected]ddb5ec52013-11-08 05:22:03166 ui::EventDispatchDetails ProcessGestures(
dtapuska8aba19072015-12-22 20:38:04167 Window* target,
[email protected]ddb5ec52013-11-08 05:22:03168 ui::GestureRecognizer::Gestures* gestures) WARN_UNUSED_RESULT;
[email protected]ea2a867a2011-10-26 17:41:33169
[email protected]a278e2602012-02-16 16:46:35170 // Called when a window becomes invisible, either by being removed
[email protected]052305f2012-12-05 18:53:04171 // from root window hierarchy, via SetVisible(false) or being destroyed.
[email protected]727f6a12014-02-06 01:43:58172 // |reason| specifies what triggered the hiding. Note that becoming invisible
173 // will cause a window to lose capture and some windows may destroy themselves
174 // on capture (like DragDropTracker).
[email protected]6184d10f2013-08-06 07:57:07175 void OnWindowHidden(Window* invisible, WindowHiddenReason reason);
[email protected]a278e2602012-02-16 16:46:35176
Sadrul Habib Chowdhuryd91358f2015-03-13 02:08:33177 bool is_dispatched_held_event(const ui::Event& event) const;
178
[email protected]efdb40c2013-10-18 22:24:19179 // Overridden from aura::client::CaptureDelegate:
dcheng5bdeb6b2014-10-27 20:58:05180 void UpdateCapture(Window* old_capture, Window* new_capture) override;
181 void OnOtherRootGotCapture() override;
182 void SetNativeCapture() override;
183 void ReleaseNativeCapture() override;
[email protected]efdb40c2013-10-18 22:24:19184
[email protected]8daeb412013-12-06 23:55:51185 // Overridden from ui::EventProcessor:
dcheng5bdeb6b2014-10-27 20:58:05186 ui::EventTarget* GetRootTarget() override;
187 void OnEventProcessingStarted(ui::Event* event) override;
[email protected]8daeb412013-12-06 23:55:51188
[email protected]4d8784a72012-12-06 22:45:41189 // Overridden from ui::EventDispatcherDelegate.
dcheng5bdeb6b2014-10-27 20:58:05190 bool CanDispatchToTarget(ui::EventTarget* target) override;
191 ui::EventDispatchDetails PreDispatchEvent(ui::EventTarget* target,
192 ui::Event* event) override;
193 ui::EventDispatchDetails PostDispatchEvent(ui::EventTarget* target,
194 const ui::Event& event) override;
[email protected]ab6cbed02012-09-03 13:20:04195
[email protected]81675c92012-04-05 22:14:49196 // Overridden from ui::GestureEventHelper.
dcheng5bdeb6b2014-10-27 20:58:05197 bool CanDispatchToConsumer(ui::GestureConsumer* consumer) override;
dtapuska8aba19072015-12-22 20:38:04198 void DispatchGestureEvent(ui::GestureConsumer* raw_input_consumer,
199 ui::GestureEvent* event) override;
200 void DispatchCancelTouchEvent(ui::GestureConsumer* raw_input_consumer,
201 ui::TouchEvent* event) override;
[email protected]81675c92012-04-05 22:14:49202
[email protected]29cf75e2014-03-21 20:48:45203 // Overridden from WindowObserver:
dcheng5bdeb6b2014-10-27 20:58:05204 void OnWindowDestroying(Window* window) override;
205 void OnWindowDestroyed(Window* window) override;
206 void OnWindowAddedToRootWindow(Window* window) override;
207 void OnWindowRemovingFromRootWindow(Window* window,
208 Window* new_root) override;
209 void OnWindowVisibilityChanging(Window* window, bool visible) override;
210 void OnWindowVisibilityChanged(Window* window, bool visible) override;
211 void OnWindowBoundsChanged(Window* window,
212 const gfx::Rect& old_bounds,
213 const gfx::Rect& new_bounds) override;
214 void OnWindowTransforming(Window* window) override;
215 void OnWindowTransformed(Window* window) override;
[email protected]29cf75e2014-03-21 20:48:45216
217 // Overridden from EnvObserver:
dcheng5bdeb6b2014-10-27 20:58:05218 void OnWindowInitialized(Window* window) override;
[email protected]29cf75e2014-03-21 20:48:45219
[email protected]a1f064d2013-06-11 18:58:54220 // We hold and aggregate mouse drags and touch moves as a way of throttling
221 // resizes when HoldMouseMoves() is called. The following methods are used to
222 // dispatch held and newly incoming mouse and touch events, typically when an
223 // event other than one of these needs dispatching or a matching
224 // ReleaseMouseMoves()/ReleaseTouchMoves() is called. NOTE: because these
[email protected]641dcfd2014-01-08 16:41:23225 // methods dispatch events from WindowTreeHost the coordinates are in terms of
[email protected]a1f064d2013-06-11 18:58:54226 // the root.
[email protected]ddb5ec52013-11-08 05:22:03227 ui::EventDispatchDetails DispatchHeldEvents() WARN_UNUSED_RESULT;
[email protected]29cf75e2014-03-21 20:48:45228
229 // Posts a task to send synthesized mouse move event if there is no a pending
230 // task.
[email protected]b1609ea92014-04-30 10:30:33231 void PostSynthesizeMouseMove();
[email protected]29cf75e2014-03-21 20:48:45232
[email protected]b1609ea92014-04-30 10:30:33233 // Creates and dispatches synthesized mouse move event using the current mouse
234 // location.
235 ui::EventDispatchDetails SynthesizeMouseMoveEvent() WARN_UNUSED_RESULT;
[email protected]ddb5ec52013-11-08 05:22:03236
[email protected]29cf75e2014-03-21 20:48:45237 // Calls SynthesizeMouseMove() if |window| is currently visible and contains
238 // the mouse cursor.
239 void SynthesizeMouseMoveAfterChangeToWindow(Window* window);
[email protected]539a8af2012-01-27 20:12:14240
mohsena352204882015-11-06 01:57:49241 ui::EventDispatchDetails PreDispatchLocatedEvent(Window* target,
242 ui::LocatedEvent* event);
243 ui::EventDispatchDetails PreDispatchMouseEvent(Window* target,
244 ui::MouseEvent* event);
245 ui::EventDispatchDetails PreDispatchTouchEvent(Window* target,
246 ui::TouchEvent* event);
[email protected]4c5d7c92013-12-13 17:17:39247
[email protected]2f2620332014-02-28 10:07:38248 WindowTreeHost* host_;
[email protected]8d8c7732011-08-25 22:35:13249
[email protected]23d94a602012-05-31 22:21:40250 // Touch ids that are currently down.
avi4ca294112015-12-24 08:04:09251 uint32_t touch_ids_down_;
[email protected]23d94a602012-05-31 22:21:40252
[email protected]114bfbd2011-10-18 21:20:24253 Window* mouse_pressed_handler_;
254 Window* mouse_moved_handler_;
[email protected]ab6cbed02012-09-03 13:20:04255 Window* event_dispatch_target_;
[email protected]8daeb412013-12-06 23:55:51256 Window* old_dispatch_target_;
[email protected]912b6f32012-01-19 00:48:01257
[email protected]539a8af2012-01-27 20:12:14258 bool synthesize_mouse_move_;
[email protected]308aaa32012-03-12 13:14:50259
[email protected]a1f064d2013-06-11 18:58:54260 // How many move holds are outstanding. We try to defer dispatching
261 // touch/mouse moves while the count is > 0.
262 int move_hold_count_;
[email protected]48f19de2014-01-13 18:20:38263 // The location of |held_move_event_| is in |window_|'s coordinate.
danakj25c52c32016-04-12 21:51:08264 std::unique_ptr<ui::LocatedEvent> held_move_event_;
[email protected]5c95ee472013-03-15 16:55:27265
266 // Allowing for reposting of events. Used when exiting context menus.
danakj25c52c32016-04-12 21:51:08267 std::unique_ptr<ui::LocatedEvent> held_repostable_event_;
[email protected]308aaa32012-03-12 13:14:50268
[email protected]4c5d7c92013-12-13 17:17:39269 // Set when dispatching a held event.
Sadrul Habib Chowdhury9af9ccd2015-01-15 13:05:28270 ui::LocatedEvent* dispatching_held_event_;
[email protected]4c5d7c92013-12-13 17:17:39271
[email protected]29cf75e2014-03-21 20:48:45272 ScopedObserver<aura::Window, aura::WindowObserver> observer_manager_;
273
sky05111cd2015-11-16 22:41:57274 bool transform_events_;
275
[email protected]ddb5ec52013-11-08 05:22:03276 // Used to schedule reposting an event.
[email protected]056ce052014-02-21 05:19:32277 base::WeakPtrFactory<WindowEventDispatcher> repost_event_factory_;
[email protected]07f0f2cf2013-10-09 03:43:18278
279 // Used to schedule DispatchHeldEvents() when |move_hold_count_| goes to 0.
[email protected]056ce052014-02-21 05:19:32280 base::WeakPtrFactory<WindowEventDispatcher> held_event_factory_;
[email protected]07f0f2cf2013-10-09 03:43:18281
[email protected]056ce052014-02-21 05:19:32282 DISALLOW_COPY_AND_ASSIGN(WindowEventDispatcher);
[email protected]81585f32011-07-29 19:32:06283};
284
285} // namespace aura
286
[email protected]fcc51c952014-02-21 21:31:26287#endif // UI_AURA_WINDOW_EVENT_DISPATCHER_H_