// 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