Home | History | Annotate | Download | only in aura
      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