// Copyright 2013 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 "content/shell/browser/shell.h"
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_contents_view.h"
#include "content/shell/browser/shell_aura.h"
#include "ui/aura/client/aura_constants.h"
#include "ui/aura/client/default_activation_client.h"
#include "ui/aura/client/default_capture_client.h"
#include "ui/aura/env.h"
#include "ui/aura/layout_manager.h"
#include "ui/aura/root_window.h"
#include "ui/aura/test/test_focus_client.h"
#include "ui/aura/test/test_screen.h"
#include "ui/aura/test/test_window_tree_client.h"
#include "ui/aura/window.h"
#include "ui/base/ime/input_method.h"
#include "ui/base/ime/input_method_delegate.h"
#include "ui/base/ime/input_method_factory.h"
#include "ui/gfx/screen.h"
namespace content {
namespace {
class FillLayout : public aura::LayoutManager {
public:
explicit FillLayout(aura::RootWindow* root)
: root_(root) {
}
virtual ~FillLayout() {}
private:
// aura::LayoutManager:
virtual void OnWindowResized() OVERRIDE {
}
virtual void OnWindowAddedToLayout(aura::Window* child) OVERRIDE {
child->SetBounds(gfx::Rect(root_->host()->GetBounds().size()));
}
virtual void OnWillRemoveWindowFromLayout(aura::Window* child) OVERRIDE {
}
virtual void OnWindowRemovedFromLayout(aura::Window* child) OVERRIDE {
}
virtual void OnChildWindowVisibilityChanged(aura::Window* child,
bool visible) OVERRIDE {
}
virtual void SetChildBounds(aura::Window* child,
const gfx::Rect& requested_bounds) OVERRIDE {
SetChildBoundsDirect(child, requested_bounds);
}
aura::RootWindow* root_;
DISALLOW_COPY_AND_ASSIGN(FillLayout);
};
class MinimalInputEventFilter : public ui::internal::InputMethodDelegate,
public ui::EventHandler {
public:
explicit MinimalInputEventFilter(aura::RootWindow* root)
: root_(root),
input_method_(ui::CreateInputMethod(this,
gfx::kNullAcceleratedWidget)) {
input_method_->Init(true);
root_->window()->AddPreTargetHandler(this);
root_->window()->SetProperty(aura::client::kRootWindowInputMethodKey,
input_method_.get());
}
virtual ~MinimalInputEventFilter() {
root_->window()->RemovePreTargetHandler(this);
root_->window()->SetProperty(aura::client::kRootWindowInputMethodKey,
static_cast<ui::InputMethod*>(NULL));
}
private:
// ui::EventHandler:
virtual void OnKeyEvent(ui::KeyEvent* event) OVERRIDE {
const ui::EventType type = event->type();
if (type == ui::ET_TRANSLATED_KEY_PRESS ||
type == ui::ET_TRANSLATED_KEY_RELEASE) {
// The |event| is already handled by this object, change the type of the
// event to ui::ET_KEY_* and pass it to the next filter.
static_cast<ui::TranslatedKeyEvent*>(event)->ConvertToKeyEvent();
} else {
if (input_method_->DispatchKeyEvent(*event))
event->StopPropagation();
}
}
// ui::InputMethodDelegate:
virtual bool DispatchKeyEventPostIME(
const base::NativeEvent& event) OVERRIDE {
ui::TranslatedKeyEvent aura_event(event, false /* is_char */);
return root_->AsRootWindowHostDelegate()->OnHostKeyEvent(
&aura_event);
}
virtual bool DispatchFabricatedKeyEventPostIME(ui::EventType type,
ui::KeyboardCode key_code,
int flags) OVERRIDE {
ui::TranslatedKeyEvent aura_event(type == ui::ET_KEY_PRESSED, key_code,
flags);
return root_->AsRootWindowHostDelegate()->OnHostKeyEvent(
&aura_event);
}
aura::RootWindow* root_;
scoped_ptr<ui::InputMethod> input_method_;
DISALLOW_COPY_AND_ASSIGN(MinimalInputEventFilter);
};
}
ShellAuraPlatformData* Shell::platform_ = NULL;
ShellAuraPlatformData::ShellAuraPlatformData() {
aura::TestScreen* screen = aura::TestScreen::Create();
gfx::Screen::SetScreenInstance(gfx::SCREEN_TYPE_NATIVE, screen);
root_window_.reset(screen->CreateRootWindowForPrimaryDisplay());
root_window_->host()->Show();
root_window_->window()->SetLayoutManager(new FillLayout(root_window_.get()));
focus_client_.reset(new aura::test::TestFocusClient());
aura::client::SetFocusClient(root_window_->window(), focus_client_.get());
activation_client_.reset(
new aura::client::DefaultActivationClient(root_window_->window()));
capture_client_.reset(
new aura::client::DefaultCaptureClient(root_window_->window()));
window_tree_client_.reset(
new aura::test::TestWindowTreeClient(root_window_->window()));
ime_filter_.reset(new MinimalInputEventFilter(root_window_.get()));
}
ShellAuraPlatformData::~ShellAuraPlatformData() {
}
void ShellAuraPlatformData::ResizeWindow(int width, int height) {
root_window_->SetHostSize(gfx::Size(width, height));
}
// static
void Shell::PlatformInitialize(const gfx::Size& default_window_size) {
CHECK(!platform_);
aura::Env::CreateInstance();
platform_ = new ShellAuraPlatformData();
}
void Shell::PlatformExit() {
CHECK(platform_);
delete platform_;
platform_ = NULL;
aura::Env::DeleteInstance();
}
void Shell::PlatformCleanUp() {
}
void Shell::PlatformEnableUIControl(UIControl control, bool is_enabled) {
}
void Shell::PlatformSetAddressBarURL(const GURL& url) {
}
void Shell::PlatformSetIsLoading(bool loading) {
}
void Shell::PlatformCreateWindow(int width, int height) {
CHECK(platform_);
platform_->ResizeWindow(width, height);
}
void Shell::PlatformSetContents() {
CHECK(platform_);
aura::Window* content = web_contents_->GetView()->GetNativeView();
aura::Window* parent = platform_->window()->window();
if (parent->Contains(content))
return;
parent->AddChild(content);
content->Show();
}
void Shell::PlatformResizeSubViews() {
}
void Shell::Close() {
web_contents_.reset();
}
void Shell::PlatformSetTitle(const base::string16& title) {
}
} // namespace content