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/root_window_host_delegate.h" 19 #include "ui/aura/window.h" 20 #include "ui/base/cursor/cursor.h" 21 #include "ui/base/events/event_constants.h" 22 #include "ui/base/events/event_dispatcher.h" 23 #include "ui/base/gestures/gesture_recognizer.h" 24 #include "ui/base/gestures/gesture_types.h" 25 #include "ui/compositor/compositor.h" 26 #include "ui/compositor/compositor_observer.h" 27 #include "ui/compositor/layer_animation_observer.h" 28 #include "ui/gfx/native_widget_types.h" 29 #include "ui/gfx/point.h" 30 #include "ui/gfx/transform.h" 31 32 class SkCanvas; 33 34 namespace gfx { 35 class Size; 36 class Transform; 37 } 38 39 namespace ui { 40 class GestureEvent; 41 class GestureRecognizer; 42 class KeyEvent; 43 class LayerAnimationSequence; 44 class MouseEvent; 45 class ScrollEvent; 46 class TouchEvent; 47 class ViewProp; 48 } 49 50 namespace aura { 51 class TestScreen; 52 class RootWindow; 53 class RootWindowHost; 54 class RootWindowObserver; 55 class RootWindowTransformer; 56 57 // RootWindow is responsible for hosting a set of windows. 58 class AURA_EXPORT RootWindow : public ui::CompositorDelegate, 59 public ui::CompositorObserver, 60 public Window, 61 public ui::EventDispatcherDelegate, 62 public ui::GestureEventHelper, 63 public ui::LayerAnimationObserver, 64 public aura::client::CaptureDelegate, 65 public aura::RootWindowHostDelegate { 66 public: 67 struct AURA_EXPORT CreateParams { 68 // CreateParams with initial_bounds and default host in pixel. 69 explicit CreateParams(const gfx::Rect& initial_bounds); 70 ~CreateParams() {} 71 72 gfx::Rect initial_bounds; 73 74 // A host to use in place of the default one that RootWindow will create. 75 // NULL by default. 76 RootWindowHost* host; 77 }; 78 79 explicit RootWindow(const CreateParams& params); 80 virtual ~RootWindow(); 81 82 // Returns the RootWindowHost for the specified accelerated widget, or NULL 83 // if there is none associated. 84 static RootWindow* GetForAcceleratedWidget(gfx::AcceleratedWidget widget); 85 86 ui::Compositor* compositor() { return compositor_.get(); } 87 gfx::NativeCursor last_cursor() const { return last_cursor_; } 88 Window* mouse_pressed_handler() { return mouse_pressed_handler_; } 89 90 // Initializes the root window. 91 void Init(); 92 93 // Shows the root window host. 94 void ShowRootWindow(); 95 96 // Hides the root window host. 97 void HideRootWindow(); 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 void RepostEvent(const ui::LocatedEvent& event); 104 105 RootWindowHostDelegate* AsRootWindowHostDelegate(); 106 107 // Gets/sets the size of the host window. 108 void SetHostSize(const gfx::Size& size_in_pixel); 109 gfx::Size GetHostSize() const; 110 111 // Sets the bounds of the host window. 112 void SetHostBounds(const gfx::Rect& size_in_pizel); 113 114 // Returns where the RootWindow is on screen. 115 gfx::Point GetHostOrigin() const; 116 117 // Sets the currently-displayed cursor. If the cursor was previously hidden 118 // via ShowCursor(false), it will remain hidden until ShowCursor(true) is 119 // called, at which point the cursor that was last set via SetCursor() will be 120 // used. 121 void SetCursor(gfx::NativeCursor cursor); 122 123 // Invoked when the cursor's visibility has changed. 124 void OnCursorVisibilityChanged(bool visible); 125 126 // Invoked when the mouse events get enabled or disabled. 127 void OnMouseEventsEnableStateChanged(bool enabled); 128 129 // Moves the cursor to the specified location relative to the root window. 130 virtual void MoveCursorTo(const gfx::Point& location) OVERRIDE; 131 132 // Moves the cursor to the |host_location| given in host coordinates. 133 void MoveCursorToHostLocation(const gfx::Point& host_location); 134 135 // Clips the cursor movement to the root_window. 136 bool ConfineCursorToWindow(); 137 138 // Draws the necessary set of windows. 139 void Draw(); 140 141 // Draw the whole screen. 142 void ScheduleFullRedraw(); 143 144 // Draw the damage_rect. 145 void ScheduleRedrawRect(const gfx::Rect& damage_rect); 146 147 // Returns a target window for the given gesture event. 148 Window* GetGestureTarget(ui::GestureEvent* event); 149 150 // Handles a gesture event. Returns true if handled. Unlike the other 151 // event-dispatching function (e.g. for touch/mouse/keyboard events), gesture 152 // events are dispatched from GestureRecognizer instead of RootWindowHost. 153 bool DispatchGestureEvent(ui::GestureEvent* event); 154 155 // Invoked when |window| is being destroyed. 156 void OnWindowDestroying(Window* window); 157 158 // Invoked when |window|'s bounds have changed. |contained_mouse| indicates if 159 // the bounds before change contained the |last_moust_location()|. 160 void OnWindowBoundsChanged(Window* window, bool contained_mouse); 161 162 // Dispatches OnMouseExited to the |window| which is hiding if nessessary. 163 void DispatchMouseExitToHidingWindow(Window* window); 164 165 // Invoked when |window|'s visibility has changed. 166 void OnWindowVisibilityChanged(Window* window, bool is_visible); 167 168 // Invoked when |window|'s tranfrom has changed. |contained_mouse| 169 // indicates if the bounds before change contained the 170 // |last_moust_location()|. 171 void OnWindowTransformed(Window* window, bool contained_mouse); 172 173 // Invoked when the keyboard mapping (in X11 terms: the mapping between 174 // keycodes and keysyms) has changed. 175 void OnKeyboardMappingChanged(); 176 177 // The system windowing system has sent a request that we close our window. 178 void OnRootWindowHostCloseRequested(); 179 180 // Add/remove observer. There is no need to remove the observer if 181 // the root window is being deleted. In particular, you SHOULD NOT remove 182 // in |WindowObserver::OnWindowDestroying| of the observer observing 183 // the root window because it is too late to remove it. 184 void AddRootWindowObserver(RootWindowObserver* observer); 185 void RemoveRootWindowObserver(RootWindowObserver* observer); 186 187 // Posts |native_event| to the platform's event queue. 188 void PostNativeEvent(const base::NativeEvent& native_event); 189 190 // Converts |point| from the root window's coordinate system to native 191 // screen's. 192 void ConvertPointToNativeScreen(gfx::Point* point) const; 193 194 // Converts |point| from native screen coordinate system to the root window's. 195 void ConvertPointFromNativeScreen(gfx::Point* point) const; 196 197 // Converts |point| from the root window's coordinate system to the 198 // host window's. 199 void ConvertPointToHost(gfx::Point* point) const; 200 201 // Converts |point| from the host window's coordinate system to the 202 // root window's. 203 void ConvertPointFromHost(gfx::Point* point) const; 204 205 // Gesture Recognition ------------------------------------------------------- 206 207 // When a touch event is dispatched to a Window, it may want to process the 208 // touch event asynchronously. In such cases, the window should consume the 209 // event during the event dispatch. Once the event is properly processed, the 210 // window should let the RootWindow know about the result of the event 211 // processing, so that gesture events can be properly created and dispatched. 212 void ProcessedTouchEvent(ui::TouchEvent* event, 213 Window* window, 214 ui::EventResult result); 215 216 ui::GestureRecognizer* gesture_recognizer() const { 217 return gesture_recognizer_.get(); 218 } 219 220 // Provided only for testing: 221 void SetGestureRecognizerForTesting(ui::GestureRecognizer* gr); 222 223 // Returns the accelerated widget from the RootWindowHost. 224 gfx::AcceleratedWidget GetAcceleratedWidget(); 225 226 // Toggles the host's full screen state. 227 void ToggleFullScreen(); 228 229 // These methods are used to defer the processing of mouse/touch events 230 // related to resize. A client (typically a RenderWidgetHostViewAura) can call 231 // HoldPointerMoves when an resize is initiated and then ReleasePointerMoves 232 // once the resize is completed. 233 // 234 // More than one hold can be invoked and each hold must be cancelled by a 235 // release before we resume normal operation. 236 void HoldPointerMoves(); 237 void ReleasePointerMoves(); 238 239 // Sets if the window should be focused when shown. 240 void SetFocusWhenShown(bool focus_when_shown); 241 242 // Copies |source_bounds| from the root window (as displayed on the host 243 // machine) to |canvas| at offset |dest_offset|. 244 bool CopyAreaToSkCanvas(const gfx::Rect& source_bounds, 245 const gfx::Point& dest_offset, 246 SkCanvas* canvas); 247 248 // Gets the last location seen in a mouse event in this root window's 249 // coordinates. This may return a point outside the root window's bounds. 250 gfx::Point GetLastMouseLocationInRoot() const; 251 252 // Overridden from Window: 253 virtual RootWindow* GetRootWindow() OVERRIDE; 254 virtual const RootWindow* GetRootWindow() const OVERRIDE; 255 virtual void SetTransform(const gfx::Transform& transform) OVERRIDE; 256 257 // Overridden from ui::EventTarget: 258 virtual ui::EventTarget* GetParentTarget() OVERRIDE; 259 260 // Overridden from ui::CompositorDelegate: 261 virtual void ScheduleDraw() OVERRIDE; 262 263 // Overridden from ui::CompositorObserver: 264 virtual void OnCompositingDidCommit(ui::Compositor*) OVERRIDE; 265 virtual void OnCompositingStarted(ui::Compositor*, 266 base::TimeTicks start_time) OVERRIDE; 267 virtual void OnCompositingEnded(ui::Compositor*) OVERRIDE; 268 virtual void OnCompositingAborted(ui::Compositor*) OVERRIDE; 269 virtual void OnCompositingLockStateChanged(ui::Compositor*) OVERRIDE; 270 virtual void OnUpdateVSyncParameters(ui::Compositor* compositor, 271 base::TimeTicks timebase, 272 base::TimeDelta interval) OVERRIDE; 273 274 // Overridden from ui::LayerDelegate: 275 virtual void OnDeviceScaleFactorChanged(float device_scale_factor) OVERRIDE; 276 277 // Overridden from Window: 278 virtual bool CanFocus() const OVERRIDE; 279 virtual bool CanReceiveEvents() const OVERRIDE; 280 281 // Overridden from aura::client::CaptureDelegate: 282 virtual void UpdateCapture(Window* old_capture, Window* new_capture) OVERRIDE; 283 virtual void SetNativeCapture() OVERRIDE; 284 virtual void ReleaseNativeCapture() OVERRIDE; 285 286 // Exposes RootWindowHost::QueryMouseLocation() for test purposes. 287 bool QueryMouseLocationForTest(gfx::Point* point) const; 288 289 // Clears internal mouse state (such as mouse ups should be sent to the same 290 // window that ate mouse downs). 291 void ClearMouseHandlers(); 292 293 void SetRootWindowTransformer(scoped_ptr<RootWindowTransformer> transformer); 294 gfx::Transform GetRootTransform() const; 295 296 private: 297 FRIEND_TEST_ALL_PREFIXES(RootWindowTest, KeepTranslatedEventInRoot); 298 299 friend class Window; 300 friend class TestScreen; 301 302 // The parameter for OnWindowHidden() to specify why window is hidden. 303 enum WindowHiddenReason { 304 WINDOW_DESTROYED, // Window is destroyed. 305 WINDOW_HIDDEN, // Window is hidden. 306 WINDOW_MOVING, // Window is temporarily marked as hidden due to move 307 // across root windows. 308 }; 309 310 // Updates the event with the appropriate transform for the device scale 311 // factor. The RootWindowHostDelegate dispatches events in the physical pixel 312 // coordinate. But the event processing from RootWindow onwards happen in 313 // device-independent pixel coordinate. So it is necessary to update the event 314 // received from the host. 315 void TransformEventForDeviceScaleFactor(ui::LocatedEvent* event); 316 317 // Moves the cursor to the specified location. This method is internally used 318 // by MoveCursorTo() and MoveCursorToHostLocation(). 319 void MoveCursorToInternal(const gfx::Point& root_location, 320 const gfx::Point& host_location); 321 322 // Called whenever the mouse moves, tracks the current |mouse_moved_handler_|, 323 // sending exited and entered events as its value changes. 324 void HandleMouseMoved(const ui::MouseEvent& event, Window* target); 325 326 // Dispatches the specified event type (intended for enter/exit) to the 327 // |mouse_moved_handler_|. 328 void DispatchMouseEnterOrExit(const ui::MouseEvent& event, 329 ui::EventType type); 330 331 void ProcessEvent(Window* target, ui::Event* event); 332 333 bool ProcessGestures(ui::GestureRecognizer::Gestures* gestures); 334 335 // Called when a Window is attached or detached from the RootWindow. 336 void OnWindowAddedToRootWindow(Window* window); 337 void OnWindowRemovedFromRootWindow(Window* window, RootWindow* new_root); 338 339 // Called when a window becomes invisible, either by being removed 340 // from root window hierarchy, via SetVisible(false) or being destroyed. 341 // |reason| specifies what triggered the hiding. 342 void OnWindowHidden(Window* invisible, WindowHiddenReason reason); 343 344 // Cleans up the gesture recognizer for all windows in |window| (including 345 // |window| itself). 346 void CleanupGestureRecognizerState(Window* window); 347 348 // Updates the root window's size using |host_size|, current 349 // transform and insets. 350 void UpdateRootWindowSize(const gfx::Size& host_size); 351 352 // Overridden from ui::EventDispatcherDelegate. 353 virtual bool CanDispatchToTarget(EventTarget* target) OVERRIDE; 354 355 // Overridden from ui::GestureEventHelper. 356 virtual bool DispatchLongPressGestureEvent(ui::GestureEvent* event) OVERRIDE; 357 virtual bool DispatchCancelTouchEvent(ui::TouchEvent* event) OVERRIDE; 358 359 // Overridden from ui::LayerAnimationObserver: 360 virtual void OnLayerAnimationEnded( 361 ui::LayerAnimationSequence* animation) OVERRIDE; 362 virtual void OnLayerAnimationScheduled( 363 ui::LayerAnimationSequence* animation) OVERRIDE; 364 virtual void OnLayerAnimationAborted( 365 ui::LayerAnimationSequence* animation) OVERRIDE; 366 367 // Overridden from aura::RootWindowHostDelegate: 368 virtual bool OnHostKeyEvent(ui::KeyEvent* event) OVERRIDE; 369 virtual bool OnHostMouseEvent(ui::MouseEvent* event) OVERRIDE; 370 virtual bool OnHostScrollEvent(ui::ScrollEvent* event) OVERRIDE; 371 virtual bool OnHostTouchEvent(ui::TouchEvent* event) OVERRIDE; 372 virtual void OnHostCancelMode() OVERRIDE; 373 virtual void OnHostActivated() OVERRIDE; 374 virtual void OnHostLostWindowCapture() OVERRIDE; 375 virtual void OnHostLostMouseGrab() OVERRIDE; 376 virtual void OnHostPaint(const gfx::Rect& damage_rect) OVERRIDE; 377 virtual void OnHostMoved(const gfx::Point& origin) OVERRIDE; 378 virtual void OnHostResized(const gfx::Size& size) OVERRIDE; 379 virtual float GetDeviceScaleFactor() OVERRIDE; 380 virtual RootWindow* AsRootWindow() OVERRIDE; 381 382 // We hold and aggregate mouse drags and touch moves as a way of throttling 383 // resizes when HoldMouseMoves() is called. The following methods are used to 384 // dispatch held and newly incoming mouse and touch events, typically when an 385 // event other than one of these needs dispatching or a matching 386 // ReleaseMouseMoves()/ReleaseTouchMoves() is called. NOTE: because these 387 // methods dispatch events from RootWindowHost the coordinates are in terms of 388 // the root. 389 bool DispatchMouseEventImpl(ui::MouseEvent* event); 390 bool DispatchMouseEventRepost(ui::MouseEvent* event); 391 bool DispatchMouseEventToTarget(ui::MouseEvent* event, Window* target); 392 bool DispatchTouchEventImpl(ui::TouchEvent* event); 393 void DispatchHeldEvents(); 394 395 // Parses the switch describing the initial size for the host window and 396 // returns bounds for the window. 397 gfx::Rect GetInitialHostWindowBounds() const; 398 399 // Posts a task to send synthesized mouse move event if there 400 // is no a pending task. 401 void PostMouseMoveEventAfterWindowChange(); 402 403 // Creates and dispatches synthesized mouse move event using the 404 // current mouse location. 405 void SynthesizeMouseMoveEvent(); 406 407 gfx::Transform GetInverseRootTransform() const; 408 409 scoped_ptr<ui::Compositor> compositor_; 410 411 scoped_ptr<RootWindowHost> host_; 412 413 // Used to schedule painting. 414 base::WeakPtrFactory<RootWindow> schedule_paint_factory_; 415 416 // Use to post mouse move event. 417 base::WeakPtrFactory<RootWindow> event_factory_; 418 419 // Touch ids that are currently down. 420 uint32 touch_ids_down_; 421 422 // Last cursor set. Used for testing. 423 gfx::NativeCursor last_cursor_; 424 425 ObserverList<RootWindowObserver> observers_; 426 427 Window* mouse_pressed_handler_; 428 Window* mouse_moved_handler_; 429 Window* mouse_event_dispatch_target_; 430 Window* event_dispatch_target_; 431 432 // The gesture_recognizer_ for this. 433 scoped_ptr<ui::GestureRecognizer> gesture_recognizer_; 434 435 bool synthesize_mouse_move_; 436 bool waiting_on_compositing_end_; 437 bool draw_on_compositing_end_; 438 439 bool defer_draw_scheduling_; 440 441 // How many move holds are outstanding. We try to defer dispatching 442 // touch/mouse moves while the count is > 0. 443 int move_hold_count_; 444 // Used to schedule DispatchHeldEvents() when |move_hold_count_| goes to 0. 445 base::WeakPtrFactory<RootWindow> held_event_factory_; 446 scoped_ptr<ui::LocatedEvent> held_move_event_; 447 448 // Allowing for reposting of events. Used when exiting context menus. 449 scoped_ptr<ui::LocatedEvent> held_repostable_event_; 450 base::WeakPtrFactory<RootWindow> repostable_event_factory_; 451 452 scoped_ptr<ui::ViewProp> prop_; 453 454 scoped_ptr<RootWindowTransformer> transformer_; 455 456 DISALLOW_COPY_AND_ASSIGN(RootWindow); 457 }; 458 459 } // namespace aura 460 461 #endif // UI_AURA_ROOT_WINDOW_H_ 462