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