1 // Copyright (c) 2012 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_ROOT_WINDOW_H_ 6 #define UI_AURA_ROOT_WINDOW_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 "ui/aura/aura_export.h" 17 #include "ui/aura/client/capture_delegate.h" 18 #include "ui/aura/window_tree_host.h" 19 #include "ui/aura/window_tree_host_delegate.h" 20 #include "ui/base/cursor/cursor.h" 21 #include "ui/compositor/compositor.h" 22 #include "ui/compositor/layer_animation_observer.h" 23 #include "ui/events/event_constants.h" 24 #include "ui/events/event_processor.h" 25 #include "ui/events/event_targeter.h" 26 #include "ui/events/gestures/gesture_recognizer.h" 27 #include "ui/events/gestures/gesture_types.h" 28 #include "ui/gfx/native_widget_types.h" 29 #include "ui/gfx/point.h" 30 #include "ui/gfx/transform.h" 31 32 namespace gfx { 33 class Size; 34 class Transform; 35 } 36 37 namespace ui { 38 class GestureEvent; 39 class GestureRecognizer; 40 class KeyEvent; 41 class LayerAnimationSequence; 42 class MouseEvent; 43 class ScrollEvent; 44 class TouchEvent; 45 class ViewProp; 46 } 47 48 namespace aura { 49 class RootWindow; 50 class RootWindowHost; 51 class RootWindowObserver; 52 class RootWindowTransformer; 53 class TestScreen; 54 class WindowTargeter; 55 56 // RootWindow is responsible for hosting a set of windows. 57 class AURA_EXPORT RootWindow : public ui::EventProcessor, 58 public ui::GestureEventHelper, 59 public ui::LayerAnimationObserver, 60 public aura::client::CaptureDelegate, 61 public aura::RootWindowHostDelegate { 62 public: 63 struct AURA_EXPORT CreateParams { 64 // CreateParams with initial_bounds and default host in pixel. 65 explicit CreateParams(const gfx::Rect& initial_bounds); 66 ~CreateParams() {} 67 68 gfx::Rect initial_bounds; 69 70 // A host to use in place of the default one that RootWindow will create. 71 // NULL by default. 72 RootWindowHost* host; 73 }; 74 75 explicit RootWindow(const CreateParams& params); 76 virtual ~RootWindow(); 77 78 // Returns the RootWindowHost for the specified accelerated widget, or NULL 79 // if there is none associated. 80 static RootWindow* GetForAcceleratedWidget(gfx::AcceleratedWidget widget); 81 82 Window* window() { 83 return const_cast<Window*>(const_cast<const RootWindow*>(this)->window()); 84 } 85 const Window* window() const { return window_.get(); } 86 RootWindowHost* host() { 87 return const_cast<RootWindowHost*>( 88 const_cast<const RootWindow*>(this)->host()); 89 } 90 const RootWindowHost* host() const { return host_.get(); } 91 ui::Compositor* compositor() { return compositor_.get(); } 92 gfx::NativeCursor last_cursor() const { return last_cursor_; } 93 Window* mouse_pressed_handler() { return mouse_pressed_handler_; } 94 Window* mouse_moved_handler() { return mouse_moved_handler_; } 95 96 // Initializes the root window. 97 void Init(); 98 99 // Stop listening events in preparation for shutdown. 100 void PrepareForShutdown(); 101 102 // Repost event for re-processing. Used when exiting context menus. 103 // We only support the ET_MOUSE_PRESSED and ET_GESTURE_TAP_DOWN event 104 // types (although the latter is currently a no-op). 105 void RepostEvent(const ui::LocatedEvent& event); 106 107 RootWindowHostDelegate* AsRootWindowHostDelegate(); 108 109 // Gets/sets the size of the host window. 110 void SetHostSize(const gfx::Size& size_in_pixel); 111 112 // Sets the bounds of the host window. 113 void SetHostBounds(const gfx::Rect& size_in_pizel); 114 115 // Sets the currently-displayed cursor. If the cursor was previously hidden 116 // via ShowCursor(false), it will remain hidden until ShowCursor(true) is 117 // called, at which point the cursor that was last set via SetCursor() will be 118 // used. 119 void SetCursor(gfx::NativeCursor cursor); 120 121 // Invoked when the cursor's visibility has changed. 122 void OnCursorVisibilityChanged(bool visible); 123 124 // Invoked when the mouse events get enabled or disabled. 125 void OnMouseEventsEnableStateChanged(bool enabled); 126 127 // Moves the cursor to the specified location relative to the root window. 128 void MoveCursorTo(const gfx::Point& location); 129 130 // Moves the cursor to the |host_location| given in host coordinates. 131 void MoveCursorToHostLocation(const gfx::Point& host_location); 132 133 // Draw the damage_rect. 134 void ScheduleRedrawRect(const gfx::Rect& damage_rect); 135 136 // Returns a target window for the given gesture event. 137 Window* GetGestureTarget(ui::GestureEvent* event); 138 139 // Handles a gesture event. Returns true if handled. Unlike the other 140 // event-dispatching function (e.g. for touch/mouse/keyboard events), gesture 141 // events are dispatched from GestureRecognizer instead of RootWindowHost. 142 void DispatchGestureEvent(ui::GestureEvent* event); 143 144 // Invoked when |window| is being destroyed. 145 void OnWindowDestroying(Window* window); 146 147 // Invoked when |window|'s bounds have changed. |contained_mouse| indicates if 148 // the bounds before change contained the |last_moust_location()|. 149 void OnWindowBoundsChanged(Window* window, bool contained_mouse); 150 151 // Dispatches OnMouseExited to the |window| which is hiding if nessessary. 152 void DispatchMouseExitToHidingWindow(Window* window); 153 154 // Dispatches a ui::ET_MOUSE_EXITED event at |point|. 155 void DispatchMouseExitAtPoint(const gfx::Point& point); 156 157 // Invoked when |window|'s visibility has changed. 158 void OnWindowVisibilityChanged(Window* window, bool is_visible); 159 160 // Invoked when |window|'s tranfrom has changed. |contained_mouse| 161 // indicates if the bounds before change contained the 162 // |last_moust_location()|. 163 void OnWindowTransformed(Window* window, bool contained_mouse); 164 165 // Invoked when the keyboard mapping (in X11 terms: the mapping between 166 // keycodes and keysyms) has changed. 167 void OnKeyboardMappingChanged(); 168 169 // The system windowing system has sent a request that we close our window. 170 void OnRootWindowHostCloseRequested(); 171 172 // Add/remove observer. There is no need to remove the observer if 173 // the root window is being deleted. In particular, you SHOULD NOT remove 174 // in |WindowObserver::OnWindowDestroying| of the observer observing 175 // the root window because it is too late to remove it. 176 void AddRootWindowObserver(RootWindowObserver* observer); 177 void RemoveRootWindowObserver(RootWindowObserver* observer); 178 179 // Converts |point| from the root window's coordinate system to the 180 // host window's. 181 void ConvertPointToHost(gfx::Point* point) const; 182 183 // Converts |point| from the host window's coordinate system to the 184 // root window's. 185 void ConvertPointFromHost(gfx::Point* point) const; 186 187 // Gesture Recognition ------------------------------------------------------- 188 189 // When a touch event is dispatched to a Window, it may want to process the 190 // touch event asynchronously. In such cases, the window should consume the 191 // event during the event dispatch. Once the event is properly processed, the 192 // window should let the RootWindow know about the result of the event 193 // processing, so that gesture events can be properly created and dispatched. 194 void ProcessedTouchEvent(ui::TouchEvent* event, 195 Window* window, 196 ui::EventResult result); 197 198 // These methods are used to defer the processing of mouse/touch events 199 // related to resize. A client (typically a RenderWidgetHostViewAura) can call 200 // HoldPointerMoves when an resize is initiated and then ReleasePointerMoves 201 // once the resize is completed. 202 // 203 // More than one hold can be invoked and each hold must be cancelled by a 204 // release before we resume normal operation. 205 void HoldPointerMoves(); 206 void ReleasePointerMoves(); 207 208 // Gets the last location seen in a mouse event in this root window's 209 // coordinates. This may return a point outside the root window's bounds. 210 gfx::Point GetLastMouseLocationInRoot() const; 211 212 void SetRootWindowTransformer(scoped_ptr<RootWindowTransformer> transformer); 213 gfx::Transform GetRootTransform() const; 214 215 void SetTransform(const gfx::Transform& transform); 216 217 private: 218 FRIEND_TEST_ALL_PREFIXES(RootWindowTest, KeepTranslatedEventInRoot); 219 220 friend class Window; 221 friend class TestScreen; 222 223 // The parameter for OnWindowHidden() to specify why window is hidden. 224 enum WindowHiddenReason { 225 WINDOW_DESTROYED, // Window is destroyed. 226 WINDOW_HIDDEN, // Window is hidden. 227 WINDOW_MOVING, // Window is temporarily marked as hidden due to move 228 // across root windows. 229 }; 230 231 // Updates the event with the appropriate transform for the device scale 232 // factor. The RootWindowHostDelegate dispatches events in the physical pixel 233 // coordinate. But the event processing from RootWindow onwards happen in 234 // device-independent pixel coordinate. So it is necessary to update the event 235 // received from the host. 236 void TransformEventForDeviceScaleFactor(ui::LocatedEvent* event); 237 238 // Moves the cursor to the specified location. This method is internally used 239 // by MoveCursorTo() and MoveCursorToHostLocation(). 240 void MoveCursorToInternal(const gfx::Point& root_location, 241 const gfx::Point& host_location); 242 243 // Dispatches the specified event type (intended for enter/exit) to the 244 // |mouse_moved_handler_|. 245 ui::EventDispatchDetails DispatchMouseEnterOrExit( 246 const ui::MouseEvent& event, 247 ui::EventType type) WARN_UNUSED_RESULT; 248 ui::EventDispatchDetails ProcessGestures( 249 ui::GestureRecognizer::Gestures* gestures) WARN_UNUSED_RESULT; 250 251 // Called when a Window is attached or detached from the RootWindow. 252 void OnWindowAddedToRootWindow(Window* window); 253 void OnWindowRemovedFromRootWindow(Window* window, Window* new_root); 254 255 // Called when a window becomes invisible, either by being removed 256 // from root window hierarchy, via SetVisible(false) or being destroyed. 257 // |reason| specifies what triggered the hiding. 258 void OnWindowHidden(Window* invisible, WindowHiddenReason reason); 259 260 // Cleans up the state of gestures for all windows in |window| (including 261 // |window| itself). This includes cancelling active touch points. 262 void CleanupGestureState(Window* window); 263 264 // Updates the root window's size using |host_size|, current 265 // transform and insets. 266 void UpdateRootWindowSize(const gfx::Size& host_size); 267 268 // Overridden from aura::client::CaptureDelegate: 269 virtual void UpdateCapture(Window* old_capture, Window* new_capture) OVERRIDE; 270 virtual void OnOtherRootGotCapture() OVERRIDE; 271 virtual void SetNativeCapture() OVERRIDE; 272 virtual void ReleaseNativeCapture() OVERRIDE; 273 274 // Overridden from ui::EventProcessor: 275 virtual ui::EventTarget* GetRootTarget() OVERRIDE; 276 virtual void PrepareEventForDispatch(ui::Event* event) OVERRIDE; 277 278 // Overridden from ui::EventDispatcherDelegate. 279 virtual bool CanDispatchToTarget(ui::EventTarget* target) OVERRIDE; 280 virtual ui::EventDispatchDetails PreDispatchEvent(ui::EventTarget* target, 281 ui::Event* event) OVERRIDE; 282 virtual ui::EventDispatchDetails PostDispatchEvent( 283 ui::EventTarget* target, const ui::Event& event) OVERRIDE; 284 285 // Overridden from ui::GestureEventHelper. 286 virtual bool CanDispatchToConsumer(ui::GestureConsumer* consumer) OVERRIDE; 287 virtual void DispatchPostponedGestureEvent(ui::GestureEvent* event) OVERRIDE; 288 virtual void DispatchCancelTouchEvent(ui::TouchEvent* event) OVERRIDE; 289 290 // Overridden from ui::LayerAnimationObserver: 291 virtual void OnLayerAnimationEnded( 292 ui::LayerAnimationSequence* animation) OVERRIDE; 293 virtual void OnLayerAnimationScheduled( 294 ui::LayerAnimationSequence* animation) OVERRIDE; 295 virtual void OnLayerAnimationAborted( 296 ui::LayerAnimationSequence* animation) OVERRIDE; 297 298 // Overridden from aura::RootWindowHostDelegate: 299 virtual bool OnHostKeyEvent(ui::KeyEvent* event) OVERRIDE; 300 virtual bool OnHostMouseEvent(ui::MouseEvent* event) OVERRIDE; 301 virtual bool OnHostScrollEvent(ui::ScrollEvent* event) OVERRIDE; 302 virtual bool OnHostTouchEvent(ui::TouchEvent* event) OVERRIDE; 303 virtual void OnHostCancelMode() OVERRIDE; 304 virtual void OnHostActivated() OVERRIDE; 305 virtual void OnHostLostWindowCapture() OVERRIDE; 306 virtual void OnHostLostMouseGrab() OVERRIDE; 307 virtual void OnHostPaint(const gfx::Rect& damage_rect) OVERRIDE; 308 virtual void OnHostMoved(const gfx::Point& origin) OVERRIDE; 309 virtual void OnHostResized(const gfx::Size& size) OVERRIDE; 310 virtual float GetDeviceScaleFactor() OVERRIDE; 311 virtual RootWindow* AsRootWindow() OVERRIDE; 312 virtual const RootWindow* AsRootWindow() const OVERRIDE; 313 virtual ui::EventProcessor* GetEventProcessor() OVERRIDE; 314 315 ui::EventDispatchDetails OnHostMouseEventImpl(ui::MouseEvent* event) 316 WARN_UNUSED_RESULT; 317 318 // We hold and aggregate mouse drags and touch moves as a way of throttling 319 // resizes when HoldMouseMoves() is called. The following methods are used to 320 // dispatch held and newly incoming mouse and touch events, typically when an 321 // event other than one of these needs dispatching or a matching 322 // ReleaseMouseMoves()/ReleaseTouchMoves() is called. NOTE: because these 323 // methods dispatch events from RootWindowHost the coordinates are in terms of 324 // the root. 325 ui::EventDispatchDetails DispatchMouseEventImpl(ui::MouseEvent* event) 326 WARN_UNUSED_RESULT; 327 ui::EventDispatchDetails DispatchMouseEventRepost(ui::MouseEvent* event) 328 WARN_UNUSED_RESULT; 329 ui::EventDispatchDetails DispatchMouseEventToTarget(ui::MouseEvent* event, 330 Window* target) 331 WARN_UNUSED_RESULT; 332 ui::EventDispatchDetails DispatchTouchEventImpl(ui::TouchEvent* event) 333 WARN_UNUSED_RESULT; 334 ui::EventDispatchDetails DispatchHeldEvents() WARN_UNUSED_RESULT; 335 // Creates and dispatches synthesized mouse move event using the 336 // current mouse location. 337 ui::EventDispatchDetails SynthesizeMouseMoveEvent() WARN_UNUSED_RESULT; 338 339 void SynthesizeMouseMoveEventAsync(); 340 341 // Posts a task to send synthesized mouse move event if there 342 // is no a pending task. 343 void PostMouseMoveEventAfterWindowChange(); 344 345 gfx::Transform GetInverseRootTransform() const; 346 347 void PreDispatchLocatedEvent(Window* target, ui::LocatedEvent* event); 348 349 // TODO(beng): evaluate the ideal ownership model. 350 scoped_ptr<Window> window_; 351 352 scoped_ptr<ui::Compositor> compositor_; 353 354 scoped_ptr<RootWindowHost> host_; 355 356 // Touch ids that are currently down. 357 uint32 touch_ids_down_; 358 359 // Last cursor set. Used for testing. 360 gfx::NativeCursor last_cursor_; 361 362 ObserverList<RootWindowObserver> observers_; 363 364 Window* mouse_pressed_handler_; 365 Window* mouse_moved_handler_; 366 Window* event_dispatch_target_; 367 Window* old_dispatch_target_; 368 369 bool synthesize_mouse_move_; 370 bool waiting_on_compositing_end_; 371 bool draw_on_compositing_end_; 372 373 bool defer_draw_scheduling_; 374 375 // How many move holds are outstanding. We try to defer dispatching 376 // touch/mouse moves while the count is > 0. 377 int move_hold_count_; 378 scoped_ptr<ui::LocatedEvent> held_move_event_; 379 380 // Allowing for reposting of events. Used when exiting context menus. 381 scoped_ptr<ui::LocatedEvent> held_repostable_event_; 382 383 // Set when dispatching a held event. 384 bool dispatching_held_event_; 385 386 scoped_ptr<ui::ViewProp> prop_; 387 388 scoped_ptr<RootWindowTransformer> transformer_; 389 390 // Used to schedule reposting an event. 391 base::WeakPtrFactory<RootWindow> repost_event_factory_; 392 393 // Used to schedule DispatchHeldEvents() when |move_hold_count_| goes to 0. 394 base::WeakPtrFactory<RootWindow> held_event_factory_; 395 396 DISALLOW_COPY_AND_ASSIGN(RootWindow); 397 }; 398 399 } // namespace aura 400 401 #endif // UI_AURA_ROOT_WINDOW_H_ 402