blob: d8d8c38d21072af1be8f5efd3f12550a04cb8e21 [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 "mash/simple_wm/simple_wm.h"
#include "base/strings/utf_string_conversions.h"
#include "ui/aura/client/aura_constants.h"
#include "ui/display/screen_base.h"
#include "ui/gfx/canvas.h"
#include "ui/gfx/geometry/mojo/geometry.mojom.h"
#include "ui/views/controls/label.h"
#include "ui/views/mus/aura_init.h"
#include "ui/views/mus/mus_client.h"
#include "ui/views/widget/native_widget_aura.h"
#include "ui/views/widget/widget.h"
#include "ui/views/widget/widget_delegate.h"
#include "ui/wm/core/default_activation_client.h"
namespace simple_wm {
namespace {
const int kNonClientTopHeight = 24;
const int kNonClientSize = 5;
} // namespace
class SimpleWM::FrameView : public views::WidgetDelegateView,
public aura::WindowObserver {
public:
explicit FrameView(aura::Window* client_window)
: client_window_(client_window) {
client_window_->AddObserver(this);
}
~FrameView() override {}
private:
// views::WidgetDelegateView:
base::string16 GetWindowTitle() const override {
base::string16* title =
client_window_->GetProperty(aura::client::kTitleKey);
if (!title)
return base::UTF8ToUTF16("(Window)");
return *title;
}
void Layout() override {
// Client offsets are applied automatically by the window service.
gfx::Rect parent_bounds = GetWidget()->GetNativeWindow()->bounds();
parent_bounds.set_origin(gfx::Point());
client_window_->SetBounds(parent_bounds);
}
// aura::WindowObserver:
void OnWindowPropertyChanged(aura::Window* window, const void* key,
intptr_t old) override {
if (key == aura::client::kTitleKey)
GetWidget()->UpdateWindowTitle();
}
aura::Window* client_window_;
DISALLOW_COPY_AND_ASSIGN(FrameView);
};
SimpleWM::SimpleWM() {}
SimpleWM::~SimpleWM() {
// WindowTreeHost uses state from WindowTreeClient, so destroy it first.
window_tree_host_.reset();
// WindowTreeClient destruction may callback to us.
window_tree_client_.reset();
gpu_service_.reset();
display::Screen::SetScreenInstance(nullptr);
}
void SimpleWM::OnStart() {
CHECK(!started_);
started_ = true;
screen_ = base::MakeUnique<display::ScreenBase>();
display::Screen::SetScreenInstance(screen_.get());
aura_init_ = base::MakeUnique<views::AuraInit>(
context()->connector(), context()->identity(), "views_mus_resources.pak",
std::string(), nullptr, views::AuraInit::Mode::AURA_MUS_WINDOW_MANAGER);
gpu_service_ = ui::GpuService::Create(context()->connector(), nullptr);
compositor_context_factory_ =
base::MakeUnique<aura::MusContextFactory>(gpu_service_.get());
aura::Env::GetInstance()->set_context_factory(
compositor_context_factory_.get());
window_tree_client_ = base::MakeUnique<aura::WindowTreeClient>(
context()->connector(), this, this);
aura::Env::GetInstance()->SetWindowTreeClient(window_tree_client_.get());
window_tree_client_->ConnectAsWindowManager();
}
bool SimpleWM::OnConnect(
const service_manager::ServiceInfo& remote_info,
service_manager::InterfaceRegistry* registry) {
return true;
}
void SimpleWM::OnEmbed(
std::unique_ptr<aura::WindowTreeHostMus> window_tree_host) {
// WindowTreeClients configured as the window manager should never get
// OnEmbed().
NOTREACHED();
}
void SimpleWM::OnLostConnection(aura::WindowTreeClient* client) {
window_tree_host_.reset();
window_tree_client_.reset();
}
void SimpleWM::OnEmbedRootDestroyed(aura::WindowTreeHostMus* window_tree_host) {
// WindowTreeClients configured as the window manager should never get
// OnEmbedRootDestroyed().
NOTREACHED();
}
void SimpleWM::OnPointerEventObserved(const ui::PointerEvent& event,
aura::Window* target) {
// Don't care.
}
aura::client::CaptureClient* SimpleWM::GetCaptureClient() {
return wm_state_.capture_controller();
}
aura::PropertyConverter* SimpleWM::GetPropertyConverter() {
return &property_converter_;
}
void SimpleWM::SetWindowManagerClient(
aura::WindowManagerClient* client) {
window_manager_client_ = client;
}
bool SimpleWM::OnWmSetBounds(aura::Window* window, gfx::Rect* bounds) {
FrameView* frame_view = GetFrameViewForClientWindow(window);
frame_view->GetWidget()->SetBounds(*bounds);
return true;
}
bool SimpleWM::OnWmSetProperty(
aura::Window* window,
const std::string& name,
std::unique_ptr<std::vector<uint8_t>>* new_data) {
return true;
}
aura::Window* SimpleWM::OnWmCreateTopLevelWindow(
ui::mojom::WindowType window_type,
std::map<std::string, std::vector<uint8_t>>* properties) {
aura::Window* client_window = new aura::Window(nullptr);
SetWindowType(client_window, window_type);
client_window->Init(ui::LAYER_NOT_DRAWN);
views::Widget* frame_widget = new views::Widget;
views::NativeWidgetAura* frame_native_widget =
new views::NativeWidgetAura(frame_widget, true);
views::Widget::InitParams params(views::Widget::InitParams::TYPE_WINDOW);
FrameView* frame_view = new FrameView(client_window);
params.delegate = frame_view;
params.native_widget = frame_native_widget;
params.parent = root_;
params.bounds = gfx::Rect(10, 10, 500, 500);
frame_widget->Init(params);
frame_widget->Show();
frame_widget->GetNativeWindow()->AddChild(client_window);
client_window_to_frame_view_[client_window] = frame_view;
// TODO(beng): probably need to observe client_window from now on so we can
// clean up this map.
return client_window;
}
void SimpleWM::OnWmClientJankinessChanged(
const std::set<aura::Window*>& client_windows,
bool janky) {
// Don't care.
}
void SimpleWM::OnWmWillCreateDisplay(const display::Display& display) {
screen_->display_list().AddDisplay(display,
display::DisplayList::Type::PRIMARY);
}
void SimpleWM::OnWmNewDisplay(
std::unique_ptr<aura::WindowTreeHostMus> window_tree_host,
const display::Display& display) {
// Only handles a single root.
DCHECK(!root_);
window_tree_host_ = std::move(window_tree_host);
root_ = window_tree_host_->window();
DCHECK(window_manager_client_);
window_manager_client_->AddActivationParent(root_);
ui::mojom::FrameDecorationValuesPtr frame_decoration_values =
ui::mojom::FrameDecorationValues::New();
frame_decoration_values->normal_client_area_insets.Set(
kNonClientTopHeight, kNonClientSize, kNonClientSize, kNonClientSize);
frame_decoration_values->max_title_bar_button_width = 0;
window_manager_client_->SetFrameDecorationValues(
std::move(frame_decoration_values));
new wm::DefaultActivationClient(root_);
aura::client::SetFocusClient(root_, &focus_client_);
}
void SimpleWM::OnWmDisplayRemoved(
aura::WindowTreeHostMus* window_tree_host) {
DCHECK_EQ(window_tree_host, window_tree_host_.get());
root_ = nullptr;
window_tree_host_.reset();
}
void SimpleWM::OnWmDisplayModified(const display::Display& display) {}
void SimpleWM::OnWmPerformMoveLoop(
aura::Window* window,
ui::mojom::MoveLoopSource source,
const gfx::Point& cursor_location,
const base::Callback<void(bool)>& on_done) {
// Don't care.
}
void SimpleWM::OnWmCancelMoveLoop(aura::Window* window) {}
void SimpleWM::OnWmSetClientArea(
aura::Window* window,
const gfx::Insets& insets,
const std::vector<gfx::Rect>& additional_client_areas) {}
SimpleWM::FrameView* SimpleWM::GetFrameViewForClientWindow(
aura::Window* client_window) {
auto it = client_window_to_frame_view_.find(client_window);
return it != client_window_to_frame_view_.end() ? it->second : nullptr;
}
} // namespace simple_wm