1f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Copyright (c) 2013 The Chromium Authors. All rights reserved.
2f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// found in the LICENSE file.
4f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
5f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "ui/aura/window_tree_host.h"
6f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
7a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "base/debug/trace_event.h"
81320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/thread_task_runner_handle.h"
9a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ui/aura/client/capture_client.h"
105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ui/aura/client/cursor_client.h"
115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ui/aura/env.h"
125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ui/aura/window.h"
13a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ui/aura/window_event_dispatcher.h"
14a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ui/aura/window_targeter.h"
15a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ui/aura/window_tree_host_observer.h"
16a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ui/base/view_prop.h"
175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ui/compositor/dip_util.h"
185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ui/compositor/layer.h"
195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ui/gfx/display.h"
205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ui/gfx/insets.h"
21f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "ui/gfx/point.h"
225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ui/gfx/point3_f.h"
235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ui/gfx/point_conversions.h"
245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ui/gfx/screen.h"
255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ui/gfx/size_conversions.h"
26f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
27f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)namespace aura {
28f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
29a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)const char kWindowTreeHostForAcceleratedWidget[] =
30a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    "__AURA_WINDOW_TREE_HOST_ACCELERATED_WIDGET__";
31a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)float GetDeviceScaleFactorFromDisplay(Window* window) {
335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  gfx::Display display = gfx::Screen::GetScreenFor(window)->
345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      GetDisplayNearestWindow(window);
355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(display.is_valid());
365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return display.device_scale_factor();
375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
39f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)////////////////////////////////////////////////////////////////////////////////
405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// WindowTreeHost, public:
415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)WindowTreeHost::~WindowTreeHost() {
435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(!compositor_) << "compositor must be destroyed before root window";
445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
46a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#if defined(OS_ANDROID)
47a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// static
48a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)WindowTreeHost* WindowTreeHost::Create(const gfx::Rect& bounds) {
49a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // This is only hit for tests and ash, right now these aren't an issue so
50a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // adding the CHECK.
51a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // TODO(sky): decide if we want a factory.
52a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  CHECK(false);
53a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return NULL;
54a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
55a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#endif
56a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
57a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// static
58a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)WindowTreeHost* WindowTreeHost::GetForAcceleratedWidget(
59a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    gfx::AcceleratedWidget widget) {
60a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return reinterpret_cast<WindowTreeHost*>(
61a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      ui::ViewProp::GetValue(widget, kWindowTreeHostForAcceleratedWidget));
62a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
63a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void WindowTreeHost::InitHost() {
655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  InitCompositor();
665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  UpdateRootWindowSize(GetBounds().size());
67a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  Env::GetInstance()->NotifyHostInitialized(this);
685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  window()->Show();
695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void WindowTreeHost::InitCompositor() {
725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  compositor_->SetScaleAndSize(GetDeviceScaleFactorFromDisplay(window()),
735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                               GetBounds().size());
745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  compositor_->SetRootLayer(window()->layer());
755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
77a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void WindowTreeHost::AddObserver(WindowTreeHostObserver* observer) {
78a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  observers_.AddObserver(observer);
79a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
80a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
81a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void WindowTreeHost::RemoveObserver(WindowTreeHostObserver* observer) {
82a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  observers_.RemoveObserver(observer);
835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
85a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)ui::EventProcessor* WindowTreeHost::event_processor() {
86a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return dispatcher();
875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)gfx::Transform WindowTreeHost::GetRootTransform() const {
905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  float scale = ui::GetDeviceScaleFactor(window()->layer());
915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  gfx::Transform transform;
925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  transform.Scale(scale, scale);
93a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  transform *= window()->layer()->transform();
945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return transform;
955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
97a02191e04bc25c4935f804f2c080ae28663d096dBen Murdochvoid WindowTreeHost::SetRootTransform(const gfx::Transform& transform) {
98a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  window()->SetTransform(transform);
99a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  UpdateRootWindowSize(GetBounds().size());
1005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
101f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
1025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)gfx::Transform WindowTreeHost::GetInverseRootTransform() const {
103a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  gfx::Transform invert;
104a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  gfx::Transform transform = GetRootTransform();
105a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  if (!transform.GetInverse(&invert))
106a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    return transform;
107a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  return invert;
108f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
109f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
1105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void WindowTreeHost::UpdateRootWindowSize(const gfx::Size& host_size) {
111a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  gfx::Rect bounds(host_size);
112a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  gfx::RectF new_bounds(ui::ConvertRectToDIP(window()->layer(), bounds));
1130529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  window()->layer()->transform().TransformRect(&new_bounds);
114a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  window()->SetBounds(gfx::Rect(gfx::ToFlooredSize(new_bounds.size())));
1155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void WindowTreeHost::ConvertPointToNativeScreen(gfx::Point* point) const {
1185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ConvertPointToHost(point);
119f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  gfx::Point location = GetLocationOnNativeScreen();
120f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  point->Offset(location.x(), location.y());
121f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
122f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
1235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void WindowTreeHost::ConvertPointFromNativeScreen(gfx::Point* point) const {
124f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  gfx::Point location = GetLocationOnNativeScreen();
125f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  point->Offset(-location.x(), -location.y());
1265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ConvertPointFromHost(point);
1275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void WindowTreeHost::ConvertPointToHost(gfx::Point* point) const {
1305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  gfx::Point3F point_3f(*point);
1315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  GetRootTransform().TransformPoint(&point_3f);
1325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  *point = gfx::ToFlooredPoint(point_3f.AsPointF());
1335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void WindowTreeHost::ConvertPointFromHost(gfx::Point* point) const {
1365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  gfx::Point3F point_3f(*point);
1375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  GetInverseRootTransform().TransformPoint(&point_3f);
1385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  *point = gfx::ToFlooredPoint(point_3f.AsPointF());
1395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void WindowTreeHost::SetCursor(gfx::NativeCursor cursor) {
1425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  last_cursor_ = cursor;
1435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // A lot of code seems to depend on NULL cursors actually showing an arrow,
1445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // so just pass everything along to the host.
1455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  SetCursorNative(cursor);
1465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void WindowTreeHost::OnCursorVisibilityChanged(bool show) {
1495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Clear any existing mouse hover effects when the cursor becomes invisible.
1505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Note we do not need to dispatch a mouse enter when the cursor becomes
1515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // visible because that can only happen in response to a mouse event, which
1525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // will trigger its own mouse enter.
1535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (!show) {
154116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    ui::EventDispatchDetails details = dispatcher()->DispatchMouseExitAtPoint(
155a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        dispatcher()->GetLastMouseLocationInRoot());
156116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    if (details.dispatcher_destroyed)
157116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      return;
1585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
1595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  OnCursorVisibilityChangedNative(show);
1615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void WindowTreeHost::MoveCursorTo(const gfx::Point& location_in_dip) {
1645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  gfx::Point host_location(location_in_dip);
1655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ConvertPointToHost(&host_location);
1665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  MoveCursorToInternal(location_in_dip, host_location);
1675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void WindowTreeHost::MoveCursorToHostLocation(const gfx::Point& host_location) {
1705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  gfx::Point root_location(host_location);
1715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  ConvertPointFromHost(&root_location);
1725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  MoveCursorToInternal(root_location, host_location);
173f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
174f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
175f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)////////////////////////////////////////////////////////////////////////////////
1765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// WindowTreeHost, protected:
1775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)WindowTreeHost::WindowTreeHost()
179a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    : window_(new Window(NULL)),
1805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      last_cursor_(ui::kCursorNull) {
1815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void WindowTreeHost::DestroyCompositor() {
1845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  compositor_.reset();
1855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
186f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
187a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void WindowTreeHost::DestroyDispatcher() {
188a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  delete window_;
189a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  window_ = NULL;
190a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  dispatcher_.reset();
191a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
192a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // TODO(beng): this comment is no longer quite valid since this function
193a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // isn't called from WED, and WED isn't a subclass of Window. So it seems
194a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // like we could just rely on ~Window now.
195a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Destroy child windows while we're still valid. This is also done by
196a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // ~Window, but by that time any calls to virtual methods overriden here (such
197a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // as GetRootWindow()) result in Window's implementation. By destroying here
198a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // we ensure GetRootWindow() still returns this.
199a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  //window()->RemoveOrDestroyChildren();
200a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
201a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
2025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void WindowTreeHost::CreateCompositor(
2035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    gfx::AcceleratedWidget accelerated_widget) {
204cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DCHECK(Env::GetInstance());
205cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  ui::ContextFactory* context_factory = Env::GetInstance()->context_factory();
206cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DCHECK(context_factory);
207cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  compositor_.reset(
2085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      new ui::Compositor(GetAcceleratedWidget(),
2095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                         context_factory,
2101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                         base::ThreadTaskRunnerHandle::Get()));
211a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // TODO(beng): I think this setup should probably all move to a "accelerated
212a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // widget available" function.
213a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (!dispatcher()) {
214a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    window()->Init(WINDOW_LAYER_NOT_DRAWN);
215a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    window()->set_host(this);
216a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    window()->SetName("RootWindow");
217a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    window()->SetEventTargeter(
218a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        scoped_ptr<ui::EventTargeter>(new WindowTargeter()));
219a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    prop_.reset(new ui::ViewProp(GetAcceleratedWidget(),
220a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                 kWindowTreeHostForAcceleratedWidget,
221a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                 this));
222a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    dispatcher_.reset(new WindowEventDispatcher(this));
223a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
224a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
225a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
226a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void WindowTreeHost::OnHostMoved(const gfx::Point& new_location) {
227a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  TRACE_EVENT1("ui", "WindowTreeHost::OnHostMoved",
228a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)               "origin", new_location.ToString());
229a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
230a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  FOR_EACH_OBSERVER(WindowTreeHostObserver, observers_,
231a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                    OnHostMoved(this, new_location));
232f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
233f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
234a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void WindowTreeHost::OnHostResized(const gfx::Size& new_size) {
2355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // The compositor should have the same size as the native root window host.
2365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Get the latest scale from display because it might have been changed.
2375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  compositor_->SetScaleAndSize(GetDeviceScaleFactorFromDisplay(window()),
2385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                               new_size);
2395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
2405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  gfx::Size layer_size = GetBounds().size();
2415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // The layer, and the observers should be notified of the
2425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // transformed size of the root window.
2435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  UpdateRootWindowSize(layer_size);
244a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  FOR_EACH_OBSERVER(WindowTreeHostObserver, observers_, OnHostResized(this));
245a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
246a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
247a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void WindowTreeHost::OnHostCloseRequested() {
248a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  FOR_EACH_OBSERVER(WindowTreeHostObserver, observers_,
249a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                    OnHostCloseRequested(this));
250a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
251a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
252a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void WindowTreeHost::OnHostActivated() {
253a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  Env::GetInstance()->NotifyHostActivated(this);
2545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
2555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
256a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void WindowTreeHost::OnHostLostWindowCapture() {
257a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  Window* capture_window = client::GetCaptureWindow(window());
258a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (capture_window && capture_window->GetRootWindow() == window())
259a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    capture_window->ReleaseCapture();
260a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
261a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
262a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)////////////////////////////////////////////////////////////////////////////////
263a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// WindowTreeHost, private:
264a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
2655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void WindowTreeHost::MoveCursorToInternal(const gfx::Point& root_location,
2665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                          const gfx::Point& host_location) {
2675c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  last_cursor_request_position_in_host_ = host_location;
2685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  MoveCursorToNative(host_location);
2695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  client::CursorClient* cursor_client = client::GetCursorClient(window());
2705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (cursor_client) {
2715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const gfx::Display& display =
2725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        gfx::Screen::GetScreenFor(window())->GetDisplayNearestWindow(window());
2735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    cursor_client->SetDisplay(display);
2745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
275a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  dispatcher()->OnCursorMovedToRootLocation(root_location);
2765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
2775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
278f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}  // namespace aura
279