blob: 2b1de0853b38b3c1ed562aff6064f09a1ea8d940 [file] [log] [blame]
// Copyright 2017 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/mus/client_surface_embedder.h"
#include "ui/aura/window.h"
#include "ui/compositor/layer.h"
#include "ui/compositor/layer_owner.h"
#include "ui/gfx/geometry/dip_util.h"
namespace aura {
namespace {
// Returns the target visibility respecting the window hierarchy. It returns
// true only when the target visibility of the window and all its ancestors are
// true. This can check if the window is going to be drawn without the effect
// of LayerAnimator.
bool GetTargetVisibility(aura::Window* window) {
if (!window)
return false;
while (window && window->TargetVisibility())
window = window->parent();
return window == nullptr;
}
} // namespace
ClientSurfaceEmbedder::ClientSurfaceEmbedder(Window* window)
: window_(window),
surface_layer_owner_(std::make_unique<ui::LayerOwner>(
std::make_unique<ui::Layer>(ui::LAYER_SOLID_COLOR))) {
surface_layer_owner_->layer()->set_name("ClientSurfaceEmbedder");
surface_layer_owner_->layer()->SetMasksToBounds(true);
// The frame provided by the parent window->layer() needs to show through
// the surface layer.
surface_layer_owner_->layer()->SetFillsBoundsOpaquely(false);
surface_layer_owner_->layer()->SetVisible(GetTargetVisibility(window_));
window_->layer()->Add(surface_layer_owner_->layer());
// Window's layer may contain content from this client (the embedder), e.g.
// this is the case with window decorations provided by Window Manager.
// This content should appear underneath the content of the embedded client.
window_->layer()->StackAtTop(surface_layer_owner_->layer());
window_->AddObserver(this);
}
ClientSurfaceEmbedder::~ClientSurfaceEmbedder() {
window_->RemoveObserver(this);
}
void ClientSurfaceEmbedder::SetSurfaceId(const viz::SurfaceId& surface_id) {
// Set the background to transparent to avoid a flash of color before the
// client surface is rendered. See https://crbug.com/930199
const gfx::Size size = window_->bounds().size();
surface_layer_owner_->layer()->SetBounds(gfx::Rect(size));
surface_layer_owner_->layer()->SetShowSurface(
surface_id, size, SK_ColorTRANSPARENT,
cc::DeadlinePolicy::UseDefaultDeadline(),
false /* stretch_content_to_fill_bounds */);
window_->layer()->StackAtTop(surface_layer_owner_->layer());
}
viz::SurfaceId ClientSurfaceEmbedder::GetSurfaceId() const {
const viz::SurfaceId* id = surface_layer_owner_->layer()->GetSurfaceId();
return id ? *id : viz::SurfaceId();
}
void ClientSurfaceEmbedder::OnWindowVisibilityChanged(Window* window,
bool visible) {
if (window->Contains(window_))
surface_layer_owner_->layer()->SetVisible(GetTargetVisibility(window_));
}
} // namespace aura