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