blob: 221674758152db16ee27c5bd48aa00fc6090bbdf [file] [log] [blame]
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "ui/aura/local/window_port_local.h"
#include "components/viz/service/frame_sinks/frame_sink_manager_impl.h"
#include "ui/aura/client/cursor_client.h"
#include "ui/aura/env.h"
#include "ui/aura/local/layer_tree_frame_sink_local.h"
#include "ui/aura/window.h"
#include "ui/aura/window_delegate.h"
#include "ui/base/layout.h"
#include "ui/display/display.h"
#include "ui/display/screen.h"
namespace aura {
namespace {
class ScopedCursorHider {
public:
explicit ScopedCursorHider(Window* window)
: window_(window), hid_cursor_(false) {
if (!window_->IsRootWindow())
return;
const bool cursor_is_in_bounds = window_->GetBoundsInScreen().Contains(
Env::GetInstance()->last_mouse_location());
client::CursorClient* cursor_client = client::GetCursorClient(window_);
if (cursor_is_in_bounds && cursor_client &&
cursor_client->IsCursorVisible()) {
cursor_client->HideCursor();
hid_cursor_ = true;
}
}
~ScopedCursorHider() {
if (!window_->IsRootWindow())
return;
// Update the device scale factor of the cursor client only when the last
// mouse location is on this root window.
if (hid_cursor_) {
client::CursorClient* cursor_client = client::GetCursorClient(window_);
if (cursor_client) {
const display::Display& display =
display::Screen::GetScreen()->GetDisplayNearestWindow(window_);
cursor_client->SetDisplay(display);
cursor_client->ShowCursor();
}
}
}
private:
Window* window_;
bool hid_cursor_;
DISALLOW_COPY_AND_ASSIGN(ScopedCursorHider);
};
} // namespace
WindowPortLocal::WindowPortLocal(Window* window)
: window_(window), weak_factory_(this) {}
WindowPortLocal::~WindowPortLocal() {}
void WindowPortLocal::OnPreInit(Window* window) {}
void WindowPortLocal::OnDeviceScaleFactorChanged(
float old_device_scale_factor,
float new_device_scale_factor) {
if (last_device_scale_factor_ != new_device_scale_factor &&
local_surface_id_.is_valid()) {
last_device_scale_factor_ = new_device_scale_factor;
local_surface_id_ = local_surface_id_allocator_.GenerateId();
if (frame_sink_)
frame_sink_->SetLocalSurfaceId(local_surface_id_);
}
ScopedCursorHider hider(window_);
if (window_->delegate()) {
window_->delegate()->OnDeviceScaleFactorChanged(old_device_scale_factor,
new_device_scale_factor);
}
}
void WindowPortLocal::OnWillAddChild(Window* child) {}
void WindowPortLocal::OnWillRemoveChild(Window* child) {}
void WindowPortLocal::OnWillMoveChild(size_t current_index, size_t dest_index) {
}
void WindowPortLocal::OnVisibilityChanged(bool visible) {}
void WindowPortLocal::OnDidChangeBounds(const gfx::Rect& old_bounds,
const gfx::Rect& new_bounds) {
if (last_size_ != new_bounds.size() && local_surface_id_.is_valid()) {
last_size_ = new_bounds.size();
local_surface_id_ = local_surface_id_allocator_.GenerateId();
if (frame_sink_)
frame_sink_->SetLocalSurfaceId(local_surface_id_);
}
}
void WindowPortLocal::OnDidChangeTransform(
const gfx::Transform& old_transform,
const gfx::Transform& new_transform) {}
std::unique_ptr<ui::PropertyData> WindowPortLocal::OnWillChangeProperty(
const void* key) {
return nullptr;
}
void WindowPortLocal::OnPropertyChanged(
const void* key,
int64_t old_value,
std::unique_ptr<ui::PropertyData> data) {}
std::unique_ptr<cc::LayerTreeFrameSink>
WindowPortLocal::CreateLayerTreeFrameSink() {
DCHECK(!frame_sink_id_.is_valid());
auto* context_factory_private =
aura::Env::GetInstance()->context_factory_private();
frame_sink_id_ = context_factory_private->AllocateFrameSinkId();
auto frame_sink = std::make_unique<LayerTreeFrameSinkLocal>(
frame_sink_id_, context_factory_private->GetHostFrameSinkManager(),
window_->GetName());
frame_sink->SetSurfaceChangedCallback(base::Bind(
&WindowPortLocal::OnSurfaceChanged, weak_factory_.GetWeakPtr()));
frame_sink_ = frame_sink->GetWeakPtr();
AllocateLocalSurfaceId();
if (window_->GetRootWindow())
window_->layer()->GetCompositor()->AddFrameSink(frame_sink_id_);
return std::move(frame_sink);
}
viz::SurfaceId WindowPortLocal::GetSurfaceId() const {
return viz::SurfaceId(frame_sink_id_, local_surface_id_);
}
void WindowPortLocal::AllocateLocalSurfaceId() {
last_device_scale_factor_ = ui::GetScaleFactorForNativeView(window_);
last_size_ = window_->bounds().size();
local_surface_id_ = local_surface_id_allocator_.GenerateId();
if (frame_sink_)
frame_sink_->SetLocalSurfaceId(local_surface_id_);
}
const viz::LocalSurfaceId& WindowPortLocal::GetLocalSurfaceId() {
if (!local_surface_id_.is_valid())
AllocateLocalSurfaceId();
return local_surface_id_;
}
viz::FrameSinkId WindowPortLocal::GetFrameSinkId() const {
return frame_sink_id_;
}
void WindowPortLocal::OnWindowAddedToRootWindow() {
if (frame_sink_id_.is_valid())
window_->layer()->GetCompositor()->AddFrameSink(frame_sink_id_);
}
void WindowPortLocal::OnWillRemoveWindowFromRootWindow() {
if (frame_sink_id_.is_valid())
window_->layer()->GetCompositor()->RemoveFrameSink(frame_sink_id_);
}
void WindowPortLocal::OnEventTargetingPolicyChanged() {}
void WindowPortLocal::OnSurfaceChanged(const viz::SurfaceInfo& surface_info) {
DCHECK_EQ(surface_info.id().frame_sink_id(), frame_sink_id_);
DCHECK_EQ(surface_info.id().local_surface_id(), local_surface_id_);
scoped_refptr<viz::SurfaceReferenceFactory> reference_factory =
aura::Env::GetInstance()
->context_factory_private()
->GetFrameSinkManager()
->surface_manager()
->reference_factory();
window_->layer()->SetShowPrimarySurface(
surface_info.id(), window_->bounds().size(), reference_factory);
window_->layer()->SetFallbackSurfaceId(surface_info.id());
}
bool WindowPortLocal::ShouldRestackTransientChildren() {
return true;
}
} // namespace aura