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 #include "ui/aura/root_window.h"
      6 
      7 #include <vector>
      8 
      9 #include "base/auto_reset.h"
     10 #include "base/bind.h"
     11 #include "base/command_line.h"
     12 #include "base/debug/trace_event.h"
     13 #include "base/logging.h"
     14 #include "base/message_loop/message_loop.h"
     15 #include "ui/aura/client/activation_client.h"
     16 #include "ui/aura/client/capture_client.h"
     17 #include "ui/aura/client/cursor_client.h"
     18 #include "ui/aura/client/event_client.h"
     19 #include "ui/aura/client/focus_client.h"
     20 #include "ui/aura/client/screen_position_client.h"
     21 #include "ui/aura/env.h"
     22 #include "ui/aura/root_window_host.h"
     23 #include "ui/aura/root_window_observer.h"
     24 #include "ui/aura/root_window_transformer.h"
     25 #include "ui/aura/window.h"
     26 #include "ui/aura/window_delegate.h"
     27 #include "ui/aura/window_tracker.h"
     28 #include "ui/base/events/event.h"
     29 #include "ui/base/gestures/gesture_recognizer.h"
     30 #include "ui/base/gestures/gesture_types.h"
     31 #include "ui/base/hit_test.h"
     32 #include "ui/base/view_prop.h"
     33 #include "ui/compositor/compositor.h"
     34 #include "ui/compositor/dip_util.h"
     35 #include "ui/compositor/layer.h"
     36 #include "ui/compositor/layer_animator.h"
     37 #include "ui/gfx/display.h"
     38 #include "ui/gfx/point3_f.h"
     39 #include "ui/gfx/point_conversions.h"
     40 #include "ui/gfx/screen.h"
     41 #include "ui/gfx/size_conversions.h"
     42 
     43 using std::vector;
     44 
     45 namespace aura {
     46 
     47 namespace {
     48 
     49 const char kRootWindowForAcceleratedWidget[] =
     50     "__AURA_ROOT_WINDOW_ACCELERATED_WIDGET__";
     51 
     52 // Returns true if |target| has a non-client (frame) component at |location|,
     53 // in window coordinates.
     54 bool IsNonClientLocation(Window* target, const gfx::Point& location) {
     55   if (!target->delegate())
     56     return false;
     57   int hit_test_code = target->delegate()->GetNonClientComponent(location);
     58   return hit_test_code != HTCLIENT && hit_test_code != HTNOWHERE;
     59 }
     60 
     61 float GetDeviceScaleFactorFromDisplay(Window* window) {
     62   return gfx::Screen::GetScreenFor(window)->
     63       GetDisplayNearestWindow(window).device_scale_factor();
     64 }
     65 
     66 Window* ConsumerToWindow(ui::GestureConsumer* consumer) {
     67   return consumer && !consumer->ignores_events() ?
     68       static_cast<Window*>(consumer) : NULL;
     69 }
     70 
     71 void SetLastMouseLocation(const RootWindow* root_window,
     72                           const gfx::Point& location_in_root) {
     73   client::ScreenPositionClient* client =
     74       client::GetScreenPositionClient(root_window);
     75   if (client) {
     76     gfx::Point location_in_screen = location_in_root;
     77     client->ConvertPointToScreen(root_window, &location_in_screen);
     78     Env::GetInstance()->set_last_mouse_location(location_in_screen);
     79   } else {
     80     Env::GetInstance()->set_last_mouse_location(location_in_root);
     81   }
     82 }
     83 
     84 RootWindowHost* CreateHost(RootWindow* root_window,
     85                            const RootWindow::CreateParams& params) {
     86   RootWindowHost* host = params.host ?
     87       params.host : RootWindowHost::Create(params.initial_bounds);
     88   host->SetDelegate(root_window);
     89   return host;
     90 }
     91 
     92 class SimpleRootWindowTransformer : public RootWindowTransformer {
     93  public:
     94   SimpleRootWindowTransformer(const RootWindow* root_window,
     95                               const gfx::Transform& transform)
     96       : root_window_(root_window),
     97         transform_(transform) {
     98   }
     99 
    100   // RootWindowTransformer overrides:
    101   virtual gfx::Transform GetTransform() const OVERRIDE {
    102     return transform_;
    103   }
    104 
    105   virtual gfx::Transform GetInverseTransform() const OVERRIDE {
    106     gfx::Transform invert;
    107     if (!transform_.GetInverse(&invert))
    108       return transform_;
    109     return invert;
    110   }
    111 
    112   virtual gfx::Rect GetRootWindowBounds(
    113       const gfx::Size& host_size) const OVERRIDE {
    114     gfx::Rect bounds(host_size);
    115     gfx::RectF new_bounds(ui::ConvertRectToDIP(root_window_->layer(), bounds));
    116     transform_.TransformRect(&new_bounds);
    117     return gfx::Rect(gfx::ToFlooredSize(new_bounds.size()));
    118   }
    119 
    120   virtual gfx::Insets GetHostInsets() const OVERRIDE {
    121     return gfx::Insets();
    122   }
    123 
    124  private:
    125   virtual ~SimpleRootWindowTransformer() {}
    126 
    127   const RootWindow* root_window_;
    128   const gfx::Transform transform_;
    129 
    130   DISALLOW_COPY_AND_ASSIGN(SimpleRootWindowTransformer);
    131 };
    132 
    133 }  // namespace
    134 
    135 RootWindow::CreateParams::CreateParams(const gfx::Rect& a_initial_bounds)
    136     : initial_bounds(a_initial_bounds),
    137       host(NULL) {
    138 }
    139 
    140 ////////////////////////////////////////////////////////////////////////////////
    141 // RootWindow, public:
    142 
    143 RootWindow::RootWindow(const CreateParams& params)
    144     : Window(NULL),
    145       host_(CreateHost(this, params)),
    146       schedule_paint_factory_(this),
    147       event_factory_(this),
    148       touch_ids_down_(0),
    149       last_cursor_(ui::kCursorNull),
    150       mouse_pressed_handler_(NULL),
    151       mouse_moved_handler_(NULL),
    152       mouse_event_dispatch_target_(NULL),
    153       event_dispatch_target_(NULL),
    154       gesture_recognizer_(ui::GestureRecognizer::Create(this)),
    155       synthesize_mouse_move_(false),
    156       waiting_on_compositing_end_(false),
    157       draw_on_compositing_end_(false),
    158       defer_draw_scheduling_(false),
    159       move_hold_count_(0),
    160       held_event_factory_(this),
    161       repostable_event_factory_(this) {
    162   SetName("RootWindow");
    163 
    164   compositor_.reset(new ui::Compositor(this, host_->GetAcceleratedWidget()));
    165   DCHECK(compositor_.get());
    166   compositor_->AddObserver(this);
    167 
    168   prop_.reset(new ui::ViewProp(host_->GetAcceleratedWidget(),
    169                                kRootWindowForAcceleratedWidget,
    170                                this));
    171 }
    172 
    173 RootWindow::~RootWindow() {
    174   compositor_->RemoveObserver(this);
    175   // Make sure to destroy the compositor before terminating so that state is
    176   // cleared and we don't hit asserts.
    177   compositor_.reset();
    178 
    179   // Tear down in reverse.  Frees any references held by the host.
    180   host_.reset(NULL);
    181 
    182   // An observer may have been added by an animation on the RootWindow.
    183   layer()->GetAnimator()->RemoveObserver(this);
    184 }
    185 
    186 // static
    187 RootWindow* RootWindow::GetForAcceleratedWidget(
    188     gfx::AcceleratedWidget widget) {
    189   return reinterpret_cast<RootWindow*>(
    190       ui::ViewProp::GetValue(widget, kRootWindowForAcceleratedWidget));
    191 }
    192 
    193 void RootWindow::Init() {
    194   compositor()->SetScaleAndSize(GetDeviceScaleFactorFromDisplay(this),
    195                                 host_->GetBounds().size());
    196   Window::Init(ui::LAYER_NOT_DRAWN);
    197   compositor()->SetRootLayer(layer());
    198   transformer_.reset(new SimpleRootWindowTransformer(this, gfx::Transform()));
    199   UpdateRootWindowSize(GetHostSize());
    200   Env::GetInstance()->NotifyRootWindowInitialized(this);
    201   Show();
    202 }
    203 
    204 void RootWindow::ShowRootWindow() {
    205   host_->Show();
    206 }
    207 
    208 void RootWindow::HideRootWindow() {
    209   host_->Hide();
    210 }
    211 
    212 void RootWindow::PrepareForShutdown() {
    213   host_->PrepareForShutdown();
    214   // discard synthesize event request as well.
    215   synthesize_mouse_move_ = false;
    216 }
    217 
    218 void RootWindow::RepostEvent(const ui::LocatedEvent& event) {
    219   // We allow for only one outstanding repostable event. This is used
    220   // in exiting context menus.  A dropped repost request is allowed.
    221   if (event.type() == ui::ET_MOUSE_PRESSED) {
    222     held_repostable_event_.reset(
    223         new ui::MouseEvent(
    224             static_cast<const ui::MouseEvent&>(event),
    225             static_cast<aura::Window*>(event.target()),
    226             static_cast<aura::Window*>(this)));
    227     base::MessageLoop::current()->PostTask(
    228         FROM_HERE,
    229         base::Bind(&RootWindow::DispatchHeldEvents,
    230                    repostable_event_factory_.GetWeakPtr()));
    231   } else {
    232     DCHECK(event.type() == ui::ET_GESTURE_TAP_DOWN);
    233     held_repostable_event_.reset();
    234     // TODO(sschmitz): add similar code for gesture events.
    235   }
    236 }
    237 
    238 RootWindowHostDelegate* RootWindow::AsRootWindowHostDelegate() {
    239   return this;
    240 }
    241 
    242 void RootWindow::SetHostSize(const gfx::Size& size_in_pixel) {
    243   DispatchHeldEvents();
    244   gfx::Rect bounds = host_->GetBounds();
    245   bounds.set_size(size_in_pixel);
    246   host_->SetBounds(bounds);
    247 
    248   // Requery the location to constrain it within the new root window size.
    249   gfx::Point point;
    250   if (host_->QueryMouseLocation(&point))
    251     SetLastMouseLocation(this, ui::ConvertPointToDIP(layer(), point));
    252 
    253   synthesize_mouse_move_ = false;
    254 }
    255 
    256 gfx::Size RootWindow::GetHostSize() const {
    257   return host_->GetBounds().size();
    258 }
    259 
    260 void RootWindow::SetHostBounds(const gfx::Rect& bounds_in_pixel) {
    261   DCHECK(!bounds_in_pixel.IsEmpty());
    262   DispatchHeldEvents();
    263   host_->SetBounds(bounds_in_pixel);
    264   synthesize_mouse_move_ = false;
    265 }
    266 
    267 gfx::Point RootWindow::GetHostOrigin() const {
    268   return host_->GetBounds().origin();
    269 }
    270 
    271 void RootWindow::SetCursor(gfx::NativeCursor cursor) {
    272   last_cursor_ = cursor;
    273   // A lot of code seems to depend on NULL cursors actually showing an arrow,
    274   // so just pass everything along to the host.
    275   host_->SetCursor(cursor);
    276 }
    277 
    278 void RootWindow::OnCursorVisibilityChanged(bool show) {
    279   host_->OnCursorVisibilityChanged(show);
    280 }
    281 
    282 void RootWindow::OnMouseEventsEnableStateChanged(bool enabled) {
    283   // Send entered / exited so that visual state can be updated to match
    284   // mouse events state.
    285   PostMouseMoveEventAfterWindowChange();
    286   // TODO(mazda): Add code to disable mouse events when |enabled| == false.
    287 }
    288 
    289 void RootWindow::MoveCursorTo(const gfx::Point& location_in_dip) {
    290   gfx::Point host_location(location_in_dip);
    291   ConvertPointToHost(&host_location);
    292   MoveCursorToInternal(location_in_dip, host_location);
    293 }
    294 
    295 void RootWindow::MoveCursorToHostLocation(const gfx::Point& host_location) {
    296   gfx::Point root_location(host_location);
    297   ConvertPointFromHost(&root_location);
    298   MoveCursorToInternal(root_location, host_location);
    299 }
    300 
    301 bool RootWindow::ConfineCursorToWindow() {
    302   // We would like to be able to confine the cursor to that window. However,
    303   // currently, we do not have such functionality in X. So we just confine
    304   // to the root window. This is ok because this option is currently only
    305   // being used in fullscreen mode, so root_window bounds = window bounds.
    306   return host_->ConfineCursorToRootWindow();
    307 }
    308 
    309 void RootWindow::Draw() {
    310   defer_draw_scheduling_ = false;
    311   if (waiting_on_compositing_end_) {
    312     draw_on_compositing_end_ = true;
    313     return;
    314   }
    315   waiting_on_compositing_end_ = true;
    316 
    317   TRACE_EVENT_ASYNC_BEGIN0("ui", "RootWindow::Draw",
    318                            compositor_->last_started_frame() + 1);
    319 
    320   compositor_->Draw();
    321 }
    322 
    323 void RootWindow::ScheduleFullRedraw() {
    324   compositor_->ScheduleFullRedraw();
    325 }
    326 
    327 void RootWindow::ScheduleRedrawRect(const gfx::Rect& damage_rect) {
    328   compositor_->ScheduleRedrawRect(damage_rect);
    329 }
    330 
    331 Window* RootWindow::GetGestureTarget(ui::GestureEvent* event) {
    332   Window* target = client::GetCaptureWindow(this);
    333   if (!target) {
    334     target = ConsumerToWindow(
    335         gesture_recognizer_->GetTargetForGestureEvent(event));
    336   }
    337 
    338   return target;
    339 }
    340 
    341 bool RootWindow::DispatchGestureEvent(ui::GestureEvent* event) {
    342   DispatchHeldEvents();
    343 
    344   Window* target = GetGestureTarget(event);
    345   if (target) {
    346     event->ConvertLocationToTarget(static_cast<Window*>(this), target);
    347     ProcessEvent(target, event);
    348     return event->handled();
    349   }
    350 
    351   return false;
    352 }
    353 
    354 void RootWindow::OnWindowDestroying(Window* window) {
    355   DispatchMouseExitToHidingWindow(window);
    356   OnWindowHidden(window, WINDOW_DESTROYED);
    357 
    358   if (window->IsVisible() &&
    359       window->ContainsPointInRoot(GetLastMouseLocationInRoot())) {
    360     PostMouseMoveEventAfterWindowChange();
    361   }
    362 }
    363 
    364 void RootWindow::OnWindowBoundsChanged(Window* window,
    365                                        bool contained_mouse_point) {
    366   if (contained_mouse_point ||
    367       (window->IsVisible() &&
    368        window->ContainsPointInRoot(GetLastMouseLocationInRoot()))) {
    369     PostMouseMoveEventAfterWindowChange();
    370   }
    371 }
    372 
    373 void RootWindow::DispatchMouseExitToHidingWindow(Window* window) {
    374   // The mouse capture is intentionally ignored. Think that a mouse enters
    375   // to a window, the window sets the capture, the mouse exits the window,
    376   // and then it releases the capture. In that case OnMouseExited won't
    377   // be called. So it is natural not to emit OnMouseExited even though
    378   // |window| is the capture window.
    379   gfx::Point last_mouse_location = GetLastMouseLocationInRoot();
    380   if (window->Contains(mouse_moved_handler_) &&
    381       window->ContainsPointInRoot(last_mouse_location)) {
    382     ui::MouseEvent event(ui::ET_MOUSE_EXITED,
    383                          last_mouse_location,
    384                          last_mouse_location,
    385                          ui::EF_NONE);
    386     DispatchMouseEnterOrExit(event, ui::ET_MOUSE_EXITED);
    387   }
    388 }
    389 
    390 void RootWindow::OnWindowVisibilityChanged(Window* window, bool is_visible) {
    391   if (!is_visible)
    392     OnWindowHidden(window, WINDOW_HIDDEN);
    393 
    394   if (window->ContainsPointInRoot(GetLastMouseLocationInRoot()))
    395     PostMouseMoveEventAfterWindowChange();
    396 }
    397 
    398 void RootWindow::OnWindowTransformed(Window* window, bool contained_mouse) {
    399   if (contained_mouse ||
    400       (window->IsVisible() &&
    401        window->ContainsPointInRoot(GetLastMouseLocationInRoot()))) {
    402     PostMouseMoveEventAfterWindowChange();
    403   }
    404 }
    405 
    406 void RootWindow::OnKeyboardMappingChanged() {
    407   FOR_EACH_OBSERVER(RootWindowObserver, observers_,
    408                     OnKeyboardMappingChanged(this));
    409 }
    410 
    411 void RootWindow::OnRootWindowHostCloseRequested() {
    412   FOR_EACH_OBSERVER(RootWindowObserver, observers_,
    413                     OnRootWindowHostCloseRequested(this));
    414 }
    415 
    416 void RootWindow::AddRootWindowObserver(RootWindowObserver* observer) {
    417   observers_.AddObserver(observer);
    418 }
    419 
    420 void RootWindow::RemoveRootWindowObserver(RootWindowObserver* observer) {
    421   observers_.RemoveObserver(observer);
    422 }
    423 
    424 void RootWindow::PostNativeEvent(const base::NativeEvent& native_event) {
    425 #if !defined(OS_MACOSX)
    426   host_->PostNativeEvent(native_event);
    427 #endif
    428 }
    429 
    430 void RootWindow::ConvertPointToNativeScreen(gfx::Point* point) const {
    431   ConvertPointToHost(point);
    432   gfx::Point location = host_->GetLocationOnNativeScreen();
    433   point->Offset(location.x(), location.y());
    434 }
    435 
    436 void RootWindow::ConvertPointFromNativeScreen(gfx::Point* point) const {
    437   gfx::Point location = host_->GetLocationOnNativeScreen();
    438   point->Offset(-location.x(), -location.y());
    439   ConvertPointFromHost(point);
    440 }
    441 
    442 void RootWindow::ConvertPointToHost(gfx::Point* point) const {
    443   gfx::Point3F point_3f(*point);
    444   GetRootTransform().TransformPoint(point_3f);
    445   *point = gfx::ToFlooredPoint(point_3f.AsPointF());
    446 }
    447 
    448 void RootWindow::ConvertPointFromHost(gfx::Point* point) const {
    449   gfx::Point3F point_3f(*point);
    450   GetInverseRootTransform().TransformPoint(point_3f);
    451   *point = gfx::ToFlooredPoint(point_3f.AsPointF());
    452 }
    453 
    454 void RootWindow::ProcessedTouchEvent(ui::TouchEvent* event,
    455                                      Window* window,
    456                                      ui::EventResult result) {
    457   scoped_ptr<ui::GestureRecognizer::Gestures> gestures;
    458   gestures.reset(gesture_recognizer_->ProcessTouchEventForGesture(
    459       *event, result, window));
    460   ProcessGestures(gestures.get());
    461 }
    462 
    463 void RootWindow::SetGestureRecognizerForTesting(ui::GestureRecognizer* gr) {
    464   gesture_recognizer_.reset(gr);
    465 }
    466 
    467 gfx::AcceleratedWidget RootWindow::GetAcceleratedWidget() {
    468   return host_->GetAcceleratedWidget();
    469 }
    470 
    471 void RootWindow::ToggleFullScreen() {
    472   host_->ToggleFullScreen();
    473 }
    474 
    475 void RootWindow::HoldPointerMoves() {
    476   if (!move_hold_count_)
    477     held_event_factory_.InvalidateWeakPtrs();
    478   ++move_hold_count_;
    479   TRACE_EVENT_ASYNC_BEGIN0("ui", "RootWindow::HoldPointerMoves", this);
    480 }
    481 
    482 void RootWindow::ReleasePointerMoves() {
    483   --move_hold_count_;
    484   DCHECK_GE(move_hold_count_, 0);
    485   if (!move_hold_count_ && held_move_event_) {
    486     // We don't want to call DispatchHeldEvents directly, because this might be
    487     // called from a deep stack while another event, in which case dispatching
    488     // another one may not be safe/expected.  Instead we post a task, that we
    489     // may cancel if HoldPointerMoves is called again before it executes.
    490     base::MessageLoop::current()->PostTask(
    491         FROM_HERE,
    492         base::Bind(&RootWindow::DispatchHeldEvents,
    493                    held_event_factory_.GetWeakPtr()));
    494   }
    495   TRACE_EVENT_ASYNC_END0("ui", "RootWindow::HoldPointerMoves", this);
    496 }
    497 
    498 void RootWindow::SetFocusWhenShown(bool focused) {
    499   host_->SetFocusWhenShown(focused);
    500 }
    501 
    502 bool RootWindow::CopyAreaToSkCanvas(const gfx::Rect& source_bounds,
    503                                     const gfx::Point& dest_offset,
    504                                     SkCanvas* canvas) {
    505   DCHECK(canvas);
    506   DCHECK(bounds().Contains(source_bounds));
    507   gfx::Rect source_pixels = ui::ConvertRectToPixel(layer(), source_bounds);
    508   return host_->CopyAreaToSkCanvas(source_pixels, dest_offset, canvas);
    509 }
    510 
    511 gfx::Point RootWindow::GetLastMouseLocationInRoot() const {
    512   gfx::Point location = Env::GetInstance()->last_mouse_location();
    513   client::ScreenPositionClient* client = client::GetScreenPositionClient(this);
    514   if (client)
    515     client->ConvertPointFromScreen(this, &location);
    516   return location;
    517 }
    518 
    519 ////////////////////////////////////////////////////////////////////////////////
    520 // RootWindow, Window overrides:
    521 
    522 RootWindow* RootWindow::GetRootWindow() {
    523   return this;
    524 }
    525 
    526 const RootWindow* RootWindow::GetRootWindow() const {
    527   return this;
    528 }
    529 
    530 void RootWindow::SetTransform(const gfx::Transform& transform) {
    531   scoped_ptr<RootWindowTransformer> transformer(
    532       new SimpleRootWindowTransformer(this, transform));
    533   SetRootWindowTransformer(transformer.Pass());
    534 }
    535 
    536 void RootWindow::SetRootWindowTransformer(
    537     scoped_ptr<RootWindowTransformer> transformer) {
    538   transformer_ = transformer.Pass();
    539   host_->SetInsets(transformer_->GetHostInsets());
    540   Window::SetTransform(transformer_->GetTransform());
    541   // If the layer is not animating, then we need to update the root window
    542   // size immediately.
    543   if (!layer()->GetAnimator()->is_animating())
    544     UpdateRootWindowSize(GetHostSize());
    545 }
    546 
    547 gfx::Transform RootWindow::GetRootTransform() const {
    548   float scale = ui::GetDeviceScaleFactor(layer());
    549   gfx::Transform transform;
    550   transform.Scale(scale, scale);
    551   transform *= transformer_->GetTransform();
    552   return transform;
    553 }
    554 
    555 ////////////////////////////////////////////////////////////////////////////////
    556 // RootWindow, ui::EventTarget implementation:
    557 
    558 ui::EventTarget* RootWindow::GetParentTarget() {
    559   return client::GetEventClient(this) ?
    560       client::GetEventClient(this)->GetToplevelEventTarget() :
    561           Env::GetInstance();
    562 }
    563 
    564 ////////////////////////////////////////////////////////////////////////////////
    565 // RootWindow, ui::CompositorDelegate implementation:
    566 
    567 void RootWindow::ScheduleDraw() {
    568   DCHECK(!ui::Compositor::WasInitializedWithThread());
    569   if (!defer_draw_scheduling_) {
    570     defer_draw_scheduling_ = true;
    571     base::MessageLoop::current()->PostTask(
    572         FROM_HERE,
    573         base::Bind(&RootWindow::Draw, schedule_paint_factory_.GetWeakPtr()));
    574   }
    575 }
    576 
    577 ////////////////////////////////////////////////////////////////////////////////
    578 // RootWindow, ui::CompositorObserver implementation:
    579 
    580 void RootWindow::OnCompositingDidCommit(ui::Compositor*) {
    581 }
    582 
    583 void RootWindow::OnCompositingStarted(ui::Compositor*,
    584                                       base::TimeTicks start_time) {
    585 }
    586 
    587 void RootWindow::OnCompositingEnded(ui::Compositor*) {
    588   TRACE_EVENT_ASYNC_END0("ui", "RootWindow::Draw",
    589                          compositor_->last_ended_frame());
    590   waiting_on_compositing_end_ = false;
    591   if (draw_on_compositing_end_) {
    592     draw_on_compositing_end_ = false;
    593 
    594     // Call ScheduleDraw() instead of Draw() in order to allow other
    595     // ui::CompositorObservers to be notified before starting another
    596     // draw cycle.
    597     ScheduleDraw();
    598   }
    599 }
    600 
    601 void RootWindow::OnCompositingAborted(ui::Compositor*) {
    602 }
    603 
    604 void RootWindow::OnCompositingLockStateChanged(ui::Compositor*) {
    605 }
    606 
    607 void RootWindow::OnUpdateVSyncParameters(ui::Compositor* compositor,
    608                                          base::TimeTicks timebase,
    609                                          base::TimeDelta interval) {
    610 }
    611 
    612 ////////////////////////////////////////////////////////////////////////////////
    613 // RootWindow, ui::LayerDelegate implementation:
    614 
    615 void RootWindow::OnDeviceScaleFactorChanged(
    616     float device_scale_factor) {
    617   const bool cursor_is_in_bounds =
    618       GetBoundsInScreen().Contains(Env::GetInstance()->last_mouse_location());
    619   bool cursor_visible = false;
    620   client::CursorClient* cursor_client = client::GetCursorClient(this);
    621   if (cursor_is_in_bounds && cursor_client) {
    622     cursor_visible = cursor_client->IsCursorVisible();
    623     if (cursor_visible)
    624       cursor_client->HideCursor();
    625   }
    626   host_->OnDeviceScaleFactorChanged(device_scale_factor);
    627   Window::OnDeviceScaleFactorChanged(device_scale_factor);
    628   // Update the device scale factor of the cursor client only when the last
    629   // mouse location is on this root window.
    630   if (cursor_is_in_bounds) {
    631     if (cursor_client) {
    632       const gfx::Display& display =
    633           gfx::Screen::GetScreenFor(this)->GetDisplayNearestWindow(this);
    634       cursor_client->SetDisplay(display);
    635     }
    636   }
    637   if (cursor_is_in_bounds && cursor_client && cursor_visible)
    638     cursor_client->ShowCursor();
    639 }
    640 
    641 ////////////////////////////////////////////////////////////////////////////////
    642 // RootWindow, overridden from aura::Window:
    643 
    644 bool RootWindow::CanFocus() const {
    645   return IsVisible();
    646 }
    647 
    648 bool RootWindow::CanReceiveEvents() const {
    649   return IsVisible();
    650 }
    651 
    652 ////////////////////////////////////////////////////////////////////////////////
    653 // RootWindow, overridden from aura::client::CaptureDelegate:
    654 
    655 void RootWindow::UpdateCapture(Window* old_capture,
    656                                Window* new_capture) {
    657   if (old_capture && old_capture->GetRootWindow() == this &&
    658       old_capture->delegate()) {
    659     // Send a capture changed event with bogus location data.
    660     ui::MouseEvent event(ui::ET_MOUSE_CAPTURE_CHANGED, gfx::Point(),
    661                          gfx::Point(), 0);
    662 
    663     ProcessEvent(old_capture, &event);
    664 
    665     old_capture->delegate()->OnCaptureLost();
    666   }
    667 
    668   // Reset the mouse_moved_handler_ if the mouse_moved_handler_ belongs
    669   // to another root window when losing the capture.
    670   if (mouse_moved_handler_ && old_capture &&
    671       old_capture->Contains(mouse_moved_handler_) &&
    672       old_capture->GetRootWindow() != this) {
    673     mouse_moved_handler_ = NULL;
    674   }
    675 
    676   if (new_capture) {
    677     // Make all subsequent mouse events and touch go to the capture window. We
    678     // shouldn't need to send an event here as OnCaptureLost should take care of
    679     // that.
    680     if (mouse_moved_handler_ || Env::GetInstance()->is_mouse_button_down())
    681       mouse_moved_handler_ = new_capture;
    682   } else {
    683     // Make sure mouse_moved_handler gets updated.
    684     SynthesizeMouseMoveEvent();
    685   }
    686   mouse_pressed_handler_ = NULL;
    687 }
    688 
    689 void RootWindow::SetNativeCapture() {
    690   host_->SetCapture();
    691 }
    692 
    693 void RootWindow::ReleaseNativeCapture() {
    694   host_->ReleaseCapture();
    695 }
    696 
    697 bool RootWindow::QueryMouseLocationForTest(gfx::Point* point) const {
    698   return host_->QueryMouseLocation(point);
    699 }
    700 
    701 void RootWindow::ClearMouseHandlers() {
    702   mouse_pressed_handler_ = NULL;
    703   mouse_moved_handler_ = NULL;
    704   mouse_event_dispatch_target_ = NULL;
    705 }
    706 
    707 ////////////////////////////////////////////////////////////////////////////////
    708 // RootWindow, private:
    709 
    710 void RootWindow::TransformEventForDeviceScaleFactor(ui::LocatedEvent* event) {
    711   event->UpdateForRootTransform(GetInverseRootTransform());
    712 }
    713 
    714 void RootWindow::MoveCursorToInternal(const gfx::Point& root_location,
    715                                       const gfx::Point& host_location) {
    716   host_->MoveCursorTo(host_location);
    717   SetLastMouseLocation(this, root_location);
    718   client::CursorClient* cursor_client = client::GetCursorClient(this);
    719   if (cursor_client) {
    720     const gfx::Display& display =
    721         gfx::Screen::GetScreenFor(this)->GetDisplayNearestWindow(this);
    722     cursor_client->SetDisplay(display);
    723   }
    724   synthesize_mouse_move_ = false;
    725 }
    726 
    727 void RootWindow::HandleMouseMoved(const ui::MouseEvent& event, Window* target) {
    728   if (target == mouse_moved_handler_)
    729     return;
    730 
    731   DispatchMouseEnterOrExit(event, ui::ET_MOUSE_EXITED);
    732 
    733   if (mouse_event_dispatch_target_ != target) {
    734     mouse_moved_handler_ = NULL;
    735     return;
    736   }
    737 
    738   mouse_moved_handler_ = target;
    739 
    740   DispatchMouseEnterOrExit(event, ui::ET_MOUSE_ENTERED);
    741 }
    742 
    743 void RootWindow::DispatchMouseEnterOrExit(const ui::MouseEvent& event,
    744                                           ui::EventType type) {
    745   if (!mouse_moved_handler_ || !mouse_moved_handler_->delegate())
    746     return;
    747 
    748   ui::MouseEvent translated_event(event,
    749                                   static_cast<Window*>(this),
    750                                   mouse_moved_handler_,
    751                                   type,
    752                                   event.flags() | ui::EF_IS_SYNTHESIZED);
    753   ProcessEvent(mouse_moved_handler_, &translated_event);
    754 }
    755 
    756 void RootWindow::ProcessEvent(Window* target, ui::Event* event) {
    757   Window* old_target = event_dispatch_target_;
    758   event_dispatch_target_ = target;
    759   if (DispatchEvent(target, event))
    760     event_dispatch_target_ = old_target;
    761 }
    762 
    763 bool RootWindow::ProcessGestures(ui::GestureRecognizer::Gestures* gestures) {
    764   if (!gestures || gestures->empty())
    765     return false;
    766 
    767   Window* target = GetGestureTarget(gestures->get().at(0));
    768   Window* old_target = event_dispatch_target_;
    769   event_dispatch_target_ = target;
    770 
    771   bool handled = false;
    772   for (size_t i = 0; i < gestures->size(); ++i) {
    773     ui::GestureEvent* event = gestures->get().at(i);
    774     event->ConvertLocationToTarget(static_cast<Window*>(this), target);
    775     if (!DispatchEvent(target, event))
    776       return false;  // |this| has been destroyed.
    777     if (event->handled())
    778       handled = true;
    779     if (event_dispatch_target_ != target)  // |target| has been destroyed.
    780       break;
    781   }
    782   event_dispatch_target_ = old_target;
    783   return handled;
    784 }
    785 
    786 void RootWindow::OnWindowRemovedFromRootWindow(Window* detached,
    787                                                RootWindow* new_root) {
    788   DCHECK(aura::client::GetCaptureWindow(this) != this);
    789 
    790   DispatchMouseExitToHidingWindow(detached);
    791   OnWindowHidden(detached, new_root ? WINDOW_MOVING : WINDOW_HIDDEN);
    792 
    793   if (detached->IsVisible() &&
    794       detached->ContainsPointInRoot(GetLastMouseLocationInRoot())) {
    795     PostMouseMoveEventAfterWindowChange();
    796   }
    797 }
    798 
    799 void RootWindow::OnWindowHidden(Window* invisible, WindowHiddenReason reason) {
    800   // TODO(beng): This should be removed once FocusController is turned on.
    801   if (client::GetFocusClient(this)) {
    802     client::GetFocusClient(this)->OnWindowHiddenInRootWindow(
    803         invisible, this, reason == WINDOW_DESTROYED);
    804   }
    805 
    806   // Do not clear the capture, and the |event_dispatch_target_| if the
    807   // window is moving across root windows, because the target itself
    808   // is actually still visible and clearing them stops further event
    809   // processing, which can cause unexpected behaviors. See
    810   // crbug.com/157583
    811   if (reason != WINDOW_MOVING) {
    812     Window* capture_window = aura::client::GetCaptureWindow(this);
    813     // If the ancestor of the capture window is hidden,
    814     // release the capture.
    815     if (invisible->Contains(capture_window) && invisible != this)
    816       capture_window->ReleaseCapture();
    817 
    818     if (invisible->Contains(event_dispatch_target_))
    819       event_dispatch_target_ = NULL;
    820   }
    821 
    822   // If the ancestor of any event handler windows are invisible, release the
    823   // pointer to those windows.
    824   if (invisible->Contains(mouse_pressed_handler_))
    825     mouse_pressed_handler_ = NULL;
    826   if (invisible->Contains(mouse_moved_handler_))
    827     mouse_moved_handler_ = NULL;
    828   if (invisible->Contains(mouse_event_dispatch_target_))
    829     mouse_event_dispatch_target_ = NULL;
    830 
    831   CleanupGestureRecognizerState(invisible);
    832 }
    833 
    834 void RootWindow::CleanupGestureRecognizerState(Window* window) {
    835   gesture_recognizer_->CleanupStateForConsumer(window);
    836   Windows windows = window->children();
    837   for (Windows::const_iterator iter = windows.begin();
    838       iter != windows.end();
    839       ++iter) {
    840     CleanupGestureRecognizerState(*iter);
    841   }
    842 }
    843 
    844 void RootWindow::UpdateRootWindowSize(const gfx::Size& host_size) {
    845   SetBounds(transformer_->GetRootWindowBounds(host_size));
    846 }
    847 
    848 void RootWindow::OnWindowAddedToRootWindow(Window* attached) {
    849   if (attached->IsVisible() &&
    850       attached->ContainsPointInRoot(GetLastMouseLocationInRoot()))
    851     PostMouseMoveEventAfterWindowChange();
    852 }
    853 
    854 bool RootWindow::CanDispatchToTarget(ui::EventTarget* target) {
    855   return event_dispatch_target_ == target;
    856 }
    857 
    858 bool RootWindow::DispatchLongPressGestureEvent(ui::GestureEvent* event) {
    859   return DispatchGestureEvent(event);
    860 }
    861 
    862 bool RootWindow::DispatchCancelTouchEvent(ui::TouchEvent* event) {
    863   return OnHostTouchEvent(event);
    864 }
    865 
    866 void RootWindow::OnLayerAnimationEnded(
    867     ui::LayerAnimationSequence* animation) {
    868   UpdateRootWindowSize(GetHostSize());
    869 }
    870 
    871 void RootWindow::OnLayerAnimationScheduled(
    872     ui::LayerAnimationSequence* animation) {
    873 }
    874 
    875 void RootWindow::OnLayerAnimationAborted(
    876     ui::LayerAnimationSequence* animation) {
    877 }
    878 
    879 ////////////////////////////////////////////////////////////////////////////////
    880 // RootWindow, RootWindowHostDelegate implementation:
    881 
    882 bool RootWindow::OnHostKeyEvent(ui::KeyEvent* event) {
    883   DispatchHeldEvents();
    884   if (event->key_code() == ui::VKEY_UNKNOWN)
    885     return false;
    886   client::EventClient* client = client::GetEventClient(GetRootWindow());
    887   Window* focused_window = client::GetFocusClient(this)->GetFocusedWindow();
    888   if (client && !client->CanProcessEventsWithinSubtree(focused_window)) {
    889     client::GetFocusClient(this)->FocusWindow(NULL);
    890     return false;
    891   }
    892   ProcessEvent(focused_window ? focused_window : this, event);
    893   return event->handled();
    894 }
    895 
    896 bool RootWindow::OnHostMouseEvent(ui::MouseEvent* event) {
    897   if (event->type() == ui::ET_MOUSE_DRAGGED ||
    898       (event->flags() & ui::EF_IS_SYNTHESIZED)) {
    899     if (move_hold_count_) {
    900       Window* null_window = static_cast<Window*>(NULL);
    901       held_move_event_.reset(
    902           new ui::MouseEvent(*event, null_window, null_window));
    903       return true;
    904     } else {
    905       // We may have a held event for a period between the time move_hold_count_
    906       // fell to 0 and the DispatchHeldEvents executes. Since we're going to
    907       // dispatch the new event directly below, we can reset the old one.
    908       held_move_event_.reset();
    909     }
    910   }
    911   DispatchHeldEvents();
    912   return DispatchMouseEventImpl(event);
    913 }
    914 
    915 bool RootWindow::OnHostScrollEvent(ui::ScrollEvent* event) {
    916   DispatchHeldEvents();
    917 
    918   TransformEventForDeviceScaleFactor(event);
    919   SetLastMouseLocation(this, event->location());
    920   synthesize_mouse_move_ = false;
    921 
    922   Window* target = mouse_pressed_handler_ ?
    923       mouse_pressed_handler_ : client::GetCaptureWindow(this);
    924 
    925   if (!target)
    926     target = GetEventHandlerForPoint(event->location());
    927 
    928   if (!target)
    929     target = this;
    930 
    931   event->ConvertLocationToTarget(static_cast<Window*>(this), target);
    932   int flags = event->flags();
    933   if (IsNonClientLocation(target, event->location()))
    934     flags |= ui::EF_IS_NON_CLIENT;
    935   event->set_flags(flags);
    936 
    937   ProcessEvent(target, event);
    938   return event->handled();
    939 }
    940 
    941 bool RootWindow::OnHostTouchEvent(ui::TouchEvent* event) {
    942   if ((event->type() == ui::ET_TOUCH_MOVED)) {
    943     if (move_hold_count_) {
    944       Window* null_window = static_cast<Window*>(NULL);
    945       held_move_event_.reset(
    946           new ui::TouchEvent(*event, null_window, null_window));
    947       return true;
    948     } else {
    949       // We may have a held event for a period between the time move_hold_count_
    950       // fell to 0 and the DispatchHeldEvents executes. Since we're going to
    951       // dispatch the new event directly below, we can reset the old one.
    952       held_move_event_.reset();
    953     }
    954   }
    955   DispatchHeldEvents();
    956   return DispatchTouchEventImpl(event);
    957 }
    958 
    959 void RootWindow::OnHostCancelMode() {
    960   ui::CancelModeEvent event;
    961   Window* focused_window = client::GetFocusClient(this)->GetFocusedWindow();
    962   ProcessEvent(focused_window ? focused_window : this, &event);
    963 }
    964 
    965 void RootWindow::OnHostActivated() {
    966   Env::GetInstance()->RootWindowActivated(this);
    967 }
    968 
    969 void RootWindow::OnHostLostWindowCapture() {
    970   Window* capture_window = client::GetCaptureWindow(this);
    971   if (capture_window && capture_window->GetRootWindow() == this)
    972     capture_window->ReleaseCapture();
    973 }
    974 
    975 void RootWindow::OnHostLostMouseGrab() {
    976   ClearMouseHandlers();
    977 }
    978 
    979 void RootWindow::OnHostPaint(const gfx::Rect& damage_rect) {
    980   compositor_->ScheduleRedrawRect(damage_rect);
    981 }
    982 
    983 void RootWindow::OnHostMoved(const gfx::Point& origin) {
    984   FOR_EACH_OBSERVER(RootWindowObserver, observers_,
    985                     OnRootWindowHostMoved(this, origin));
    986 }
    987 
    988 void RootWindow::OnHostResized(const gfx::Size& size) {
    989   DispatchHeldEvents();
    990   // The compositor should have the same size as the native root window host.
    991   // Get the latest scale from display because it might have been changed.
    992   compositor_->SetScaleAndSize(GetDeviceScaleFactorFromDisplay(this), size);
    993 
    994   // The layer, and the observers should be notified of the
    995   // transformed size of the root window.
    996   UpdateRootWindowSize(size);
    997   FOR_EACH_OBSERVER(RootWindowObserver, observers_,
    998                     OnRootWindowHostResized(this));
    999 }
   1000 
   1001 float RootWindow::GetDeviceScaleFactor() {
   1002   return compositor()->device_scale_factor();
   1003 }
   1004 
   1005 RootWindow* RootWindow::AsRootWindow() {
   1006   return this;
   1007 }
   1008 
   1009 ////////////////////////////////////////////////////////////////////////////////
   1010 // RootWindow, private:
   1011 
   1012 bool RootWindow::DispatchMouseEventImpl(ui::MouseEvent* event) {
   1013   TransformEventForDeviceScaleFactor(event);
   1014   Window* target = mouse_pressed_handler_ ?
   1015       mouse_pressed_handler_ : client::GetCaptureWindow(this);
   1016   if (!target)
   1017     target = GetEventHandlerForPoint(event->location());
   1018   return DispatchMouseEventToTarget(event, target);
   1019 }
   1020 
   1021 bool RootWindow::DispatchMouseEventRepost(ui::MouseEvent* event) {
   1022   if (event->type() != ui::ET_MOUSE_PRESSED)
   1023     return false;
   1024   mouse_pressed_handler_ = NULL;
   1025   Window* target = GetEventHandlerForPoint(event->location());
   1026   return DispatchMouseEventToTarget(event, target);
   1027 }
   1028 
   1029 bool RootWindow::DispatchMouseEventToTarget(ui::MouseEvent* event,
   1030                                             Window* target) {
   1031   client::CursorClient* cursor_client = client::GetCursorClient(this);
   1032   if (cursor_client &&
   1033       !cursor_client->IsMouseEventsEnabled() &&
   1034       (event->flags() & ui::EF_IS_SYNTHESIZED))
   1035     return false;
   1036 
   1037   static const int kMouseButtonFlagMask =
   1038       ui::EF_LEFT_MOUSE_BUTTON |
   1039       ui::EF_MIDDLE_MOUSE_BUTTON |
   1040       ui::EF_RIGHT_MOUSE_BUTTON;
   1041   base::AutoReset<Window*> reset(&mouse_event_dispatch_target_, target);
   1042   SetLastMouseLocation(this, event->location());
   1043   synthesize_mouse_move_ = false;
   1044   switch (event->type()) {
   1045     case ui::ET_MOUSE_EXITED:
   1046       if (!target) {
   1047         DispatchMouseEnterOrExit(*event, ui::ET_MOUSE_EXITED);
   1048         mouse_moved_handler_ = NULL;
   1049       }
   1050       break;
   1051     case ui::ET_MOUSE_MOVED:
   1052       mouse_event_dispatch_target_ = target;
   1053       HandleMouseMoved(*event, target);
   1054       if (mouse_event_dispatch_target_ != target)
   1055         return false;
   1056       break;
   1057     case ui::ET_MOUSE_PRESSED:
   1058       // Don't set the mouse pressed handler for non client mouse down events.
   1059       // These are only sent by Windows and are not always followed with non
   1060       // client mouse up events which causes subsequent mouse events to be
   1061       // sent to the wrong target.
   1062       if (!(event->flags() & ui::EF_IS_NON_CLIENT) && !mouse_pressed_handler_)
   1063         mouse_pressed_handler_ = target;
   1064       Env::GetInstance()->set_mouse_button_flags(
   1065           event->flags() & kMouseButtonFlagMask);
   1066       break;
   1067     case ui::ET_MOUSE_RELEASED:
   1068       mouse_pressed_handler_ = NULL;
   1069       Env::GetInstance()->set_mouse_button_flags(event->flags() &
   1070           kMouseButtonFlagMask & ~event->changed_button_flags());
   1071       break;
   1072     default:
   1073       break;
   1074   }
   1075   if (target) {
   1076     event->ConvertLocationToTarget(static_cast<Window*>(this), target);
   1077     if (IsNonClientLocation(target, event->location()))
   1078       event->set_flags(event->flags() | ui::EF_IS_NON_CLIENT);
   1079     ProcessEvent(target, event);
   1080     return event->handled();
   1081   }
   1082   return false;
   1083 }
   1084 
   1085 bool RootWindow::DispatchTouchEventImpl(ui::TouchEvent* event) {
   1086   switch (event->type()) {
   1087     case ui::ET_TOUCH_PRESSED:
   1088       touch_ids_down_ |= (1 << event->touch_id());
   1089       Env::GetInstance()->set_touch_down(touch_ids_down_ != 0);
   1090       break;
   1091 
   1092       // Handle ET_TOUCH_CANCELLED only if it has a native event.
   1093     case ui::ET_TOUCH_CANCELLED:
   1094       if (!event->HasNativeEvent())
   1095         break;
   1096       // fallthrough
   1097     case ui::ET_TOUCH_RELEASED:
   1098       touch_ids_down_ = (touch_ids_down_ | (1 << event->touch_id())) ^
   1099             (1 << event->touch_id());
   1100       Env::GetInstance()->set_touch_down(touch_ids_down_ != 0);
   1101       break;
   1102 
   1103     default:
   1104       break;
   1105   }
   1106   TransformEventForDeviceScaleFactor(event);
   1107   bool handled = false;
   1108   Window* target = client::GetCaptureWindow(this);
   1109   if (!target) {
   1110     target = ConsumerToWindow(
   1111         gesture_recognizer_->GetTouchLockedTarget(event));
   1112     if (!target) {
   1113       target = ConsumerToWindow(
   1114           gesture_recognizer_->GetTargetForLocation(event->location()));
   1115     }
   1116   }
   1117 
   1118   // The gesture recognizer processes touch events in the system coordinates. So
   1119   // keep a copy of the touch event here before possibly converting the event to
   1120   // a window's local coordinate system.
   1121   ui::TouchEvent event_for_gr(*event);
   1122 
   1123   ui::EventResult result = ui::ER_UNHANDLED;
   1124   if (!target && !bounds().Contains(event->location())) {
   1125     // If the initial touch is outside the root window, target the root.
   1126     target = this;
   1127     ProcessEvent(target ? target : NULL, event);
   1128     result = event->result();
   1129   } else {
   1130     // We only come here when the first contact was within the root window.
   1131     if (!target) {
   1132       target = GetEventHandlerForPoint(event->location());
   1133       if (!target)
   1134         return false;
   1135     }
   1136 
   1137     event->ConvertLocationToTarget(static_cast<Window*>(this), target);
   1138     ProcessEvent(target, event);
   1139     handled = event->handled();
   1140     result = event->result();
   1141   }
   1142 
   1143   // Get the list of GestureEvents from GestureRecognizer.
   1144   scoped_ptr<ui::GestureRecognizer::Gestures> gestures;
   1145   gestures.reset(gesture_recognizer_->ProcessTouchEventForGesture(
   1146       event_for_gr, result, target));
   1147 
   1148   return ProcessGestures(gestures.get()) ? true : handled;
   1149 }
   1150 
   1151 void RootWindow::DispatchHeldEvents() {
   1152   if (held_repostable_event_) {
   1153     if (held_repostable_event_->type() == ui::ET_MOUSE_PRESSED) {
   1154       ui::MouseEvent mouse_event(
   1155           static_cast<const ui::MouseEvent&>(*held_repostable_event_.get()));
   1156       held_repostable_event_.reset(); // must be reset before dispatch
   1157       DispatchMouseEventRepost(&mouse_event);
   1158     } else {
   1159       DCHECK(held_repostable_event_->type() == ui::ET_GESTURE_TAP_DOWN);
   1160       // TODO(sschmitz): add similar code for gesture events
   1161     }
   1162     held_repostable_event_.reset();
   1163   }
   1164   if (held_move_event_ && held_move_event_->IsMouseEvent()) {
   1165     // If a mouse move has been synthesized, the target location is suspect,
   1166     // so drop the held event.
   1167     if (!synthesize_mouse_move_)
   1168       DispatchMouseEventImpl(
   1169           static_cast<ui::MouseEvent*>(held_move_event_.get()));
   1170     held_move_event_.reset();
   1171   } else if (held_move_event_ && held_move_event_->IsTouchEvent()) {
   1172     DispatchTouchEventImpl(
   1173         static_cast<ui::TouchEvent*>(held_move_event_.get()));
   1174     held_move_event_.reset();
   1175   }
   1176 }
   1177 
   1178 void RootWindow::PostMouseMoveEventAfterWindowChange() {
   1179   if (synthesize_mouse_move_)
   1180     return;
   1181   synthesize_mouse_move_ = true;
   1182   base::MessageLoop::current()->PostTask(
   1183       FROM_HERE,
   1184       base::Bind(&RootWindow::SynthesizeMouseMoveEvent,
   1185                  event_factory_.GetWeakPtr()));
   1186 }
   1187 
   1188 void RootWindow::SynthesizeMouseMoveEvent() {
   1189   if (!synthesize_mouse_move_)
   1190     return;
   1191   synthesize_mouse_move_ = false;
   1192   gfx::Point root_mouse_location = GetLastMouseLocationInRoot();
   1193   if (!bounds().Contains(root_mouse_location))
   1194     return;
   1195   gfx::Point host_mouse_location = root_mouse_location;
   1196   ConvertPointToHost(&host_mouse_location);
   1197 
   1198   ui::MouseEvent event(ui::ET_MOUSE_MOVED,
   1199                        host_mouse_location,
   1200                        host_mouse_location,
   1201                        ui::EF_IS_SYNTHESIZED);
   1202   OnHostMouseEvent(&event);
   1203 }
   1204 
   1205 gfx::Transform RootWindow::GetInverseRootTransform() const {
   1206   float scale = ui::GetDeviceScaleFactor(layer());
   1207   gfx::Transform transform;
   1208   transform.Scale(1.0f / scale, 1.0f / scale);
   1209   return transformer_->GetInverseTransform() * transform;
   1210 }
   1211 
   1212 }  // namespace aura
   1213