blob: e04a77b22ea0fb7bca2623fc7a737d362fd2427d [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 "cc/surfaces/surface_reference_factory.h"
#include "ui/aura/window.h"
namespace aura {
namespace {
// TODO(mfomitchev, samans): Remove these stub classes once the SurfaceReference
// work is complete.
class StubSurfaceReferenceFactory : public cc::SurfaceReferenceFactory {
public:
StubSurfaceReferenceFactory() = default;
// cc::SurfaceReferenceFactory:
base::Closure CreateReference(
cc::SurfaceReferenceOwner* owner,
const cc::SurfaceId& surface_id) const override {
return base::Closure();
}
protected:
~StubSurfaceReferenceFactory() override = default;
DISALLOW_COPY_AND_ASSIGN(StubSurfaceReferenceFactory);
};
} // namespace
ClientSurfaceEmbedder::ClientSurfaceEmbedder(
Window* window,
const gfx::Insets& client_area_insets)
: window_(window), client_area_insets_(client_area_insets) {
surface_layer_ = base::MakeUnique<ui::Layer>(ui::LAYER_TEXTURED);
surface_layer_->SetMasksToBounds(true);
// The frame provided by the parent window->layer() needs to show through
// the surface layer.
surface_layer_->SetFillsBoundsOpaquely(false);
window_->layer()->Add(surface_layer_.get());
// 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_.get());
}
ClientSurfaceEmbedder::~ClientSurfaceEmbedder() = default;
void ClientSurfaceEmbedder::SetPrimarySurfaceInfo(
const cc::SurfaceInfo& surface_info) {
surface_layer_->SetShowPrimarySurface(
surface_info, make_scoped_refptr(new StubSurfaceReferenceFactory));
surface_layer_->SetBounds(gfx::Rect(window_->bounds().size()));
}
void ClientSurfaceEmbedder::SetFallbackSurfaceInfo(
const cc::SurfaceInfo& surface_info) {
surface_layer_->SetFallbackSurface(surface_info);
UpdateSizeAndGutters();
}
void ClientSurfaceEmbedder::UpdateSizeAndGutters() {
surface_layer_->SetBounds(gfx::Rect(window_->bounds().size()));
// TODO(fsamuel): Fix this for high DPI.
gfx::Size fallback_surface_size(
surface_layer_->GetFallbackSurfaceInfo()
? surface_layer_->GetFallbackSurfaceInfo()->size_in_pixels()
: gfx::Size());
gfx::Rect window_bounds(window_->bounds());
if (fallback_surface_size.width() < window_bounds.width()) {
right_gutter_ = base::MakeUnique<ui::Layer>(ui::LAYER_SOLID_COLOR);
// TODO(fsamuel): Use the embedded client's background color.
right_gutter_->SetColor(SK_ColorWHITE);
int width = window_bounds.width() - fallback_surface_size.width();
// The right gutter also includes the bottom-right corner, if necessary.
int height = window_bounds.height() - client_area_insets_.height();
right_gutter_->SetBounds(
gfx::Rect(client_area_insets_.left() + fallback_surface_size.width(),
client_area_insets_.top(), width, height));
window_->layer()->Add(right_gutter_.get());
} else {
right_gutter_.reset();
}
// Only create a bottom gutter if a fallback surface is available. Otherwise,
// the right gutter will fill the whole window until a fallback is available.
if (!fallback_surface_size.IsEmpty() &&
fallback_surface_size.height() < window_bounds.height()) {
bottom_gutter_ = base::MakeUnique<ui::Layer>(ui::LAYER_SOLID_COLOR);
// TODO(fsamuel): Use the embedded client's background color.
bottom_gutter_->SetColor(SK_ColorWHITE);
int width = fallback_surface_size.width();
int height = window_bounds.height() - fallback_surface_size.height();
bottom_gutter_->SetBounds(
gfx::Rect(0, fallback_surface_size.height(), width, height));
window_->layer()->Add(bottom_gutter_.get());
} else {
bottom_gutter_.reset();
}
window_->layer()->StackAtTop(surface_layer_.get());
}
} // namespace aura