Roll src/third_party/WebKit c1a6e5d:a81080d (svn 192591:192595)
[chromium-blink-merge.git] / ui / aura / window_tree_host.cc
blobe0ea779a6183023799fe0f8391836f24ad823e9f
1 // Copyright (c) 2013 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.
5 #include "ui/aura/window_tree_host.h"
7 #include "base/thread_task_runner_handle.h"
8 #include "base/trace_event/trace_event.h"
9 #include "ui/aura/client/capture_client.h"
10 #include "ui/aura/client/cursor_client.h"
11 #include "ui/aura/env.h"
12 #include "ui/aura/window.h"
13 #include "ui/aura/window_event_dispatcher.h"
14 #include "ui/aura/window_targeter.h"
15 #include "ui/aura/window_tree_host_observer.h"
16 #include "ui/base/view_prop.h"
17 #include "ui/compositor/dip_util.h"
18 #include "ui/compositor/layer.h"
19 #include "ui/gfx/display.h"
20 #include "ui/gfx/geometry/insets.h"
21 #include "ui/gfx/geometry/point.h"
22 #include "ui/gfx/geometry/point3_f.h"
23 #include "ui/gfx/geometry/point_conversions.h"
24 #include "ui/gfx/geometry/size_conversions.h"
25 #include "ui/gfx/screen.h"
27 namespace aura {
29 const char kWindowTreeHostForAcceleratedWidget[] =
30 "__AURA_WINDOW_TREE_HOST_ACCELERATED_WIDGET__";
32 float GetDeviceScaleFactorFromDisplay(Window* window) {
33 gfx::Display display = gfx::Screen::GetScreenFor(window)->
34 GetDisplayNearestWindow(window);
35 DCHECK(display.is_valid());
36 return display.device_scale_factor();
39 ////////////////////////////////////////////////////////////////////////////////
40 // WindowTreeHost, public:
42 WindowTreeHost::~WindowTreeHost() {
43 DCHECK(!compositor_) << "compositor must be destroyed before root window";
46 #if defined(OS_ANDROID)
47 // static
48 WindowTreeHost* WindowTreeHost::Create(const gfx::Rect& bounds) {
49 // This is only hit for tests and ash, right now these aren't an issue so
50 // adding the CHECK.
51 // TODO(sky): decide if we want a factory.
52 CHECK(false);
53 return NULL;
55 #endif
57 // static
58 WindowTreeHost* WindowTreeHost::GetForAcceleratedWidget(
59 gfx::AcceleratedWidget widget) {
60 return reinterpret_cast<WindowTreeHost*>(
61 ui::ViewProp::GetValue(widget, kWindowTreeHostForAcceleratedWidget));
64 void WindowTreeHost::InitHost() {
65 InitCompositor();
66 UpdateRootWindowSize(GetBounds().size());
67 Env::GetInstance()->NotifyHostInitialized(this);
68 window()->Show();
71 void WindowTreeHost::InitCompositor() {
72 compositor_->SetScaleAndSize(GetDeviceScaleFactorFromDisplay(window()),
73 GetBounds().size());
74 compositor_->SetRootLayer(window()->layer());
77 void WindowTreeHost::AddObserver(WindowTreeHostObserver* observer) {
78 observers_.AddObserver(observer);
81 void WindowTreeHost::RemoveObserver(WindowTreeHostObserver* observer) {
82 observers_.RemoveObserver(observer);
85 ui::EventProcessor* WindowTreeHost::event_processor() {
86 return dispatcher();
89 gfx::Transform WindowTreeHost::GetRootTransform() const {
90 float scale = ui::GetDeviceScaleFactor(window()->layer());
91 gfx::Transform transform;
92 transform.Scale(scale, scale);
93 transform *= window()->layer()->transform();
94 return transform;
97 void WindowTreeHost::SetRootTransform(const gfx::Transform& transform) {
98 window()->SetTransform(transform);
99 UpdateRootWindowSize(GetBounds().size());
102 gfx::Transform WindowTreeHost::GetInverseRootTransform() const {
103 gfx::Transform invert;
104 gfx::Transform transform = GetRootTransform();
105 if (!transform.GetInverse(&invert))
106 return transform;
107 return invert;
110 void WindowTreeHost::UpdateRootWindowSize(const gfx::Size& host_size) {
111 gfx::Rect bounds(host_size);
112 gfx::RectF new_bounds(ui::ConvertRectToDIP(window()->layer(), bounds));
113 window()->layer()->transform().TransformRect(&new_bounds);
114 window()->SetBounds(gfx::Rect(gfx::ToFlooredSize(new_bounds.size())));
117 void WindowTreeHost::ConvertPointToNativeScreen(gfx::Point* point) const {
118 ConvertPointToHost(point);
119 gfx::Point location = GetLocationOnNativeScreen();
120 point->Offset(location.x(), location.y());
123 void WindowTreeHost::ConvertPointFromNativeScreen(gfx::Point* point) const {
124 gfx::Point location = GetLocationOnNativeScreen();
125 point->Offset(-location.x(), -location.y());
126 ConvertPointFromHost(point);
129 void WindowTreeHost::ConvertPointToHost(gfx::Point* point) const {
130 gfx::Point3F point_3f(*point);
131 GetRootTransform().TransformPoint(&point_3f);
132 *point = gfx::ToFlooredPoint(point_3f.AsPointF());
135 void WindowTreeHost::ConvertPointFromHost(gfx::Point* point) const {
136 gfx::Point3F point_3f(*point);
137 GetInverseRootTransform().TransformPoint(&point_3f);
138 *point = gfx::ToFlooredPoint(point_3f.AsPointF());
141 void WindowTreeHost::SetCursor(gfx::NativeCursor cursor) {
142 last_cursor_ = cursor;
143 // A lot of code seems to depend on NULL cursors actually showing an arrow,
144 // so just pass everything along to the host.
145 SetCursorNative(cursor);
148 void WindowTreeHost::OnCursorVisibilityChanged(bool show) {
149 // Clear any existing mouse hover effects when the cursor becomes invisible.
150 // Note we do not need to dispatch a mouse enter when the cursor becomes
151 // visible because that can only happen in response to a mouse event, which
152 // will trigger its own mouse enter.
153 if (!show) {
154 ui::EventDispatchDetails details = dispatcher()->DispatchMouseExitAtPoint(
155 nullptr, dispatcher()->GetLastMouseLocationInRoot());
156 if (details.dispatcher_destroyed)
157 return;
160 OnCursorVisibilityChangedNative(show);
163 void WindowTreeHost::MoveCursorTo(const gfx::Point& location_in_dip) {
164 gfx::Point host_location(location_in_dip);
165 ConvertPointToHost(&host_location);
166 MoveCursorToInternal(location_in_dip, host_location);
169 void WindowTreeHost::MoveCursorToHostLocation(const gfx::Point& host_location) {
170 gfx::Point root_location(host_location);
171 ConvertPointFromHost(&root_location);
172 MoveCursorToInternal(root_location, host_location);
175 ////////////////////////////////////////////////////////////////////////////////
176 // WindowTreeHost, protected:
178 WindowTreeHost::WindowTreeHost()
179 : window_(new Window(NULL)),
180 last_cursor_(ui::kCursorNull) {
183 void WindowTreeHost::DestroyCompositor() {
184 compositor_.reset();
187 void WindowTreeHost::DestroyDispatcher() {
188 delete window_;
189 window_ = NULL;
190 dispatcher_.reset();
192 // TODO(beng): this comment is no longer quite valid since this function
193 // isn't called from WED, and WED isn't a subclass of Window. So it seems
194 // like we could just rely on ~Window now.
195 // Destroy child windows while we're still valid. This is also done by
196 // ~Window, but by that time any calls to virtual methods overriden here (such
197 // as GetRootWindow()) result in Window's implementation. By destroying here
198 // we ensure GetRootWindow() still returns this.
199 //window()->RemoveOrDestroyChildren();
202 void WindowTreeHost::CreateCompositor(
203 gfx::AcceleratedWidget accelerated_widget) {
204 DCHECK(Env::GetInstance());
205 ui::ContextFactory* context_factory = Env::GetInstance()->context_factory();
206 DCHECK(context_factory);
207 compositor_.reset(
208 new ui::Compositor(GetAcceleratedWidget(),
209 context_factory,
210 base::ThreadTaskRunnerHandle::Get()));
211 // TODO(beng): I think this setup should probably all move to a "accelerated
212 // widget available" function.
213 if (!dispatcher()) {
214 window()->Init(WINDOW_LAYER_NOT_DRAWN);
215 window()->set_host(this);
216 window()->SetName("RootWindow");
217 window()->SetEventTargeter(
218 scoped_ptr<ui::EventTargeter>(new WindowTargeter()));
219 prop_.reset(new ui::ViewProp(GetAcceleratedWidget(),
220 kWindowTreeHostForAcceleratedWidget,
221 this));
222 dispatcher_.reset(new WindowEventDispatcher(this));
226 void WindowTreeHost::OnHostMoved(const gfx::Point& new_location) {
227 TRACE_EVENT1("ui", "WindowTreeHost::OnHostMoved",
228 "origin", new_location.ToString());
230 FOR_EACH_OBSERVER(WindowTreeHostObserver, observers_,
231 OnHostMoved(this, new_location));
234 void WindowTreeHost::OnHostResized(const gfx::Size& new_size) {
235 // The compositor should have the same size as the native root window host.
236 // Get the latest scale from display because it might have been changed.
237 compositor_->SetScaleAndSize(GetDeviceScaleFactorFromDisplay(window()),
238 new_size);
240 gfx::Size layer_size = GetBounds().size();
241 // The layer, and the observers should be notified of the
242 // transformed size of the root window.
243 UpdateRootWindowSize(layer_size);
244 FOR_EACH_OBSERVER(WindowTreeHostObserver, observers_, OnHostResized(this));
247 void WindowTreeHost::OnHostCloseRequested() {
248 FOR_EACH_OBSERVER(WindowTreeHostObserver, observers_,
249 OnHostCloseRequested(this));
252 void WindowTreeHost::OnHostActivated() {
253 Env::GetInstance()->NotifyHostActivated(this);
256 void WindowTreeHost::OnHostLostWindowCapture() {
257 Window* capture_window = client::GetCaptureWindow(window());
258 if (capture_window && capture_window->GetRootWindow() == window())
259 capture_window->ReleaseCapture();
262 ////////////////////////////////////////////////////////////////////////////////
263 // WindowTreeHost, private:
265 void WindowTreeHost::MoveCursorToInternal(const gfx::Point& root_location,
266 const gfx::Point& host_location) {
267 last_cursor_request_position_in_host_ = host_location;
268 MoveCursorToNative(host_location);
269 client::CursorClient* cursor_client = client::GetCursorClient(window());
270 if (cursor_client) {
271 const gfx::Display& display =
272 gfx::Screen::GetScreenFor(window())->GetDisplayNearestWindow(window());
273 cursor_client->SetDisplay(display);
275 dispatcher()->OnCursorMovedToRootLocation(root_location);
278 } // namespace aura