This source file includes following definitions.
- SetUseTransparentWindows
- params_
- IsCommandIdChecked
- IsCommandIdEnabled
- GetAcceleratorForCommandId
- ExecuteCommand
- contents_view_
- SetAddressBarURL
- SetWebContents
- SetWindowTitle
- EnableUIControl
- ShowWebViewContextMenu
- OnWebContentsFocused
- InitShellWindow
- InitAccelerators
- ContentsChanged
- HandleKeyEvent
- ButtonPressed
- CanResize
- CanMaximize
- GetWindowTitle
- WindowClosing
- GetContentsView
- GetMinimumSize
- ViewHierarchyChanged
- AcceleratorPressed
- PlatformInitialize
- PlatformExit
- PlatformCleanUp
- PlatformEnableUIControl
- PlatformSetAddressBarURL
- PlatformSetIsLoading
- PlatformCreateWindow
- PlatformSetContents
- PlatformResizeSubViews
- Close
- PlatformSetTitle
- PlatformHandleContextMenu
- PlatformWebContentsFocused
#include "content/shell/browser/shell.h"
#include "base/command_line.h"
#include "base/strings/utf_string_conversions.h"
#include "content/public/browser/render_widget_host_view.h"
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_contents_view.h"
#include "content/public/common/context_menu_params.h"
#include "content/shell/browser/shell_platform_data_aura.h"
#include "ui/aura/client/screen_position_client.h"
#include "ui/aura/env.h"
#include "ui/aura/window.h"
#include "ui/aura/window_event_dispatcher.h"
#include "ui/base/clipboard/clipboard.h"
#include "ui/base/models/simple_menu_model.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/events/event.h"
#include "ui/gfx/screen.h"
#include "ui/views/background.h"
#include "ui/views/controls/button/label_button.h"
#include "ui/views/controls/button/menu_button.h"
#include "ui/views/controls/button/menu_button_listener.h"
#include "ui/views/controls/menu/menu_item_view.h"
#include "ui/views/controls/menu/menu_runner.h"
#include "ui/views/controls/textfield/textfield.h"
#include "ui/views/controls/textfield/textfield_controller.h"
#include "ui/views/controls/webview/webview.h"
#include "ui/views/layout/fill_layout.h"
#include "ui/views/layout/grid_layout.h"
#include "ui/views/test/desktop_test_views_delegate.h"
#include "ui/views/view.h"
#include "ui/views/widget/widget.h"
#include "ui/views/widget/widget_delegate.h"
#if defined(OS_CHROMEOS)
#include "chromeos/dbus/dbus_thread_manager.h"
#include "ui/aura/test/test_screen.h"
#include "ui/wm/test/wm_test_helper.h"
#else
#include "ui/views/widget/desktop_aura/desktop_screen.h"
#endif
#if defined(OS_WIN)
#include <fcntl.h>
#include <io.h>
#endif
namespace content {
namespace {
class ShellViewsDelegateAura : public views::DesktopTestViewsDelegate {
public:
ShellViewsDelegateAura() : use_transparent_windows_(false) {
}
virtual ~ShellViewsDelegateAura() {
}
void SetUseTransparentWindows(bool transparent) {
use_transparent_windows_ = transparent;
}
private:
bool use_transparent_windows_;
DISALLOW_COPY_AND_ASSIGN(ShellViewsDelegateAura);
};
class ContextMenuModel : public ui::SimpleMenuModel,
public ui::SimpleMenuModel::Delegate {
public:
explicit ContextMenuModel(
Shell* shell, const content::ContextMenuParams& params)
: ui::SimpleMenuModel(this),
shell_(shell),
params_(params) {
AddItem(COMMAND_OPEN_DEVTOOLS, base::ASCIIToUTF16("Inspect Element"));
}
virtual bool IsCommandIdChecked(int command_id) const OVERRIDE {
return false;
}
virtual bool IsCommandIdEnabled(int command_id) const OVERRIDE {
return true;
}
virtual bool GetAcceleratorForCommandId(
int command_id,
ui::Accelerator* accelerator) OVERRIDE { return false; }
virtual void ExecuteCommand(int command_id, int event_flags) OVERRIDE {
switch (command_id) {
case COMMAND_OPEN_DEVTOOLS:
shell_->ShowDevToolsForElementAt(params_.x, params_.y);
break;
};
}
private:
enum CommandID {
COMMAND_OPEN_DEVTOOLS
};
Shell* shell_;
content::ContextMenuParams params_;
DISALLOW_COPY_AND_ASSIGN(ContextMenuModel);
};
class ShellWindowDelegateView : public views::WidgetDelegateView,
public views::TextfieldController,
public views::ButtonListener {
public:
enum UIControl {
BACK_BUTTON,
FORWARD_BUTTON,
STOP_BUTTON
};
ShellWindowDelegateView(Shell* shell)
: shell_(shell),
toolbar_view_(new View),
contents_view_(new View) {
}
virtual ~ShellWindowDelegateView() {}
void SetAddressBarURL(const GURL& url) {
url_entry_->SetText(base::ASCIIToUTF16(url.spec()));
}
void SetWebContents(WebContents* web_contents, const gfx::Size& size) {
contents_view_->SetLayoutManager(new views::FillLayout());
web_view_ = new views::WebView(web_contents->GetBrowserContext());
web_view_->SetWebContents(web_contents);
web_view_->SetPreferredSize(size);
web_contents->GetView()->Focus();
contents_view_->AddChildView(web_view_);
Layout();
gfx::Rect bounds = GetWidget()->GetWindowBoundsInScreen();
bounds.set_size(GetWidget()->GetRootView()->GetPreferredSize());
GetWidget()->SetBounds(bounds);
#if defined(OS_CHROMEOS)
GetWidget()->GetNativeWindow()->GetHost()->SetBounds(bounds);
#endif
}
void SetWindowTitle(const base::string16& title) { title_ = title; }
void EnableUIControl(UIControl control, bool is_enabled) {
if (control == BACK_BUTTON) {
back_button_->SetState(is_enabled ? views::CustomButton::STATE_NORMAL
: views::CustomButton::STATE_DISABLED);
} else if (control == FORWARD_BUTTON) {
forward_button_->SetState(is_enabled ? views::CustomButton::STATE_NORMAL
: views::CustomButton::STATE_DISABLED);
} else if (control == STOP_BUTTON) {
stop_button_->SetState(is_enabled ? views::CustomButton::STATE_NORMAL
: views::CustomButton::STATE_DISABLED);
}
}
void ShowWebViewContextMenu(const content::ContextMenuParams& params) {
gfx::Point screen_point(params.x, params.y);
aura::Window* web_contents_window =
shell_->web_contents()->GetView()->GetNativeView();
aura::Window* root_window = web_contents_window->GetRootWindow();
aura::client::ScreenPositionClient* screen_position_client =
aura::client::GetScreenPositionClient(root_window);
if (screen_position_client) {
screen_position_client->ConvertPointToScreen(web_contents_window,
&screen_point);
}
context_menu_model_.reset(new ContextMenuModel(shell_, params));
context_menu_runner_.reset(
new views::MenuRunner(context_menu_model_.get()));
if (context_menu_runner_->RunMenuAt(web_view_->GetWidget(),
NULL, gfx::Rect(screen_point, gfx::Size()),
views::MenuItemView::TOPRIGHT, ui::MENU_SOURCE_NONE,
views::MenuRunner::CONTEXT_MENU) ==
views::MenuRunner::MENU_DELETED)
return;
}
void OnWebContentsFocused(content::WebContents* web_contents) {
if (web_view_->GetWebContents() == web_contents)
web_view_->OnWebContentsFocused(web_contents);
}
private:
void InitShellWindow() {
set_background(views::Background::CreateStandardPanelBackground());
views::GridLayout* layout = new views::GridLayout(this);
SetLayoutManager(layout);
views::ColumnSet* column_set = layout->AddColumnSet(0);
column_set->AddPaddingColumn(0, 2);
column_set->AddColumn(views::GridLayout::FILL, views::GridLayout::FILL, 1,
views::GridLayout::USE_PREF, 0, 0);
column_set->AddPaddingColumn(0, 2);
layout->AddPaddingRow(0, 2);
{
layout->StartRow(0, 0);
views::GridLayout* toolbar_layout = new views::GridLayout(toolbar_view_);
toolbar_view_->SetLayoutManager(toolbar_layout);
views::ColumnSet* toolbar_column_set =
toolbar_layout->AddColumnSet(0);
back_button_ = new views::LabelButton(this, base::ASCIIToUTF16("Back"));
back_button_->SetStyle(views::Button::STYLE_BUTTON);
gfx::Size back_button_size = back_button_->GetPreferredSize();
toolbar_column_set->AddColumn(views::GridLayout::CENTER,
views::GridLayout::CENTER, 0,
views::GridLayout::FIXED,
back_button_size.width(),
back_button_size.width() / 2);
forward_button_ =
new views::LabelButton(this, base::ASCIIToUTF16("Forward"));
forward_button_->SetStyle(views::Button::STYLE_BUTTON);
gfx::Size forward_button_size = forward_button_->GetPreferredSize();
toolbar_column_set->AddColumn(views::GridLayout::CENTER,
views::GridLayout::CENTER, 0,
views::GridLayout::FIXED,
forward_button_size.width(),
forward_button_size.width() / 2);
refresh_button_ =
new views::LabelButton(this, base::ASCIIToUTF16("Refresh"));
refresh_button_->SetStyle(views::Button::STYLE_BUTTON);
gfx::Size refresh_button_size = refresh_button_->GetPreferredSize();
toolbar_column_set->AddColumn(views::GridLayout::CENTER,
views::GridLayout::CENTER, 0,
views::GridLayout::FIXED,
refresh_button_size.width(),
refresh_button_size.width() / 2);
stop_button_ = new views::LabelButton(this, base::ASCIIToUTF16("Stop"));
stop_button_->SetStyle(views::Button::STYLE_BUTTON);
gfx::Size stop_button_size = stop_button_->GetPreferredSize();
toolbar_column_set->AddColumn(views::GridLayout::CENTER,
views::GridLayout::CENTER, 0,
views::GridLayout::FIXED,
stop_button_size.width(),
stop_button_size.width() / 2);
toolbar_column_set->AddPaddingColumn(0, 2);
url_entry_ = new views::Textfield();
url_entry_->set_controller(this);
toolbar_column_set->AddColumn(views::GridLayout::FILL,
views::GridLayout::FILL, 1,
views::GridLayout::USE_PREF, 0, 0);
toolbar_column_set->AddPaddingColumn(0, 2);
toolbar_layout->StartRow(0, 0);
toolbar_layout->AddView(back_button_);
toolbar_layout->AddView(forward_button_);
toolbar_layout->AddView(refresh_button_);
toolbar_layout->AddView(stop_button_);
toolbar_layout->AddView(url_entry_);
layout->AddView(toolbar_view_);
}
layout->AddPaddingRow(0, 5);
{
layout->StartRow(1, 0);
layout->AddView(contents_view_);
}
layout->AddPaddingRow(0, 5);
InitAccelerators();
}
void InitAccelerators() {
static const ui::KeyboardCode keys[] = { ui::VKEY_F5,
ui::VKEY_BROWSER_BACK,
ui::VKEY_BROWSER_FORWARD };
for (size_t i = 0; i < arraysize(keys); ++i) {
GetFocusManager()->RegisterAccelerator(
ui::Accelerator(keys[i], ui::EF_NONE),
ui::AcceleratorManager::kNormalPriority,
this);
}
}
virtual void ContentsChanged(views::Textfield* sender,
const base::string16& new_contents) OVERRIDE {
}
virtual bool HandleKeyEvent(views::Textfield* sender,
const ui::KeyEvent& key_event) OVERRIDE {
if (sender == url_entry_ && key_event.key_code() == ui::VKEY_RETURN) {
std::string text = base::UTF16ToUTF8(url_entry_->text());
GURL url(text);
if (!url.has_scheme()) {
url = GURL(std::string("http://") + std::string(text));
url_entry_->SetText(base::ASCIIToUTF16(url.spec()));
}
shell_->LoadURL(url);
return true;
}
return false;
}
virtual void ButtonPressed(views::Button* sender,
const ui::Event& event) OVERRIDE {
if (sender == back_button_)
shell_->GoBackOrForward(-1);
else if (sender == forward_button_)
shell_->GoBackOrForward(1);
else if (sender == refresh_button_)
shell_->Reload();
else if (sender == stop_button_)
shell_->Stop();
}
virtual bool CanResize() const OVERRIDE { return true; }
virtual bool CanMaximize() const OVERRIDE { return true; }
virtual base::string16 GetWindowTitle() const OVERRIDE {
return title_;
}
virtual void WindowClosing() OVERRIDE {
if (shell_) {
delete shell_;
shell_ = NULL;
}
}
virtual View* GetContentsView() OVERRIDE { return this; }
virtual gfx::Size GetMinimumSize() OVERRIDE {
return gfx::Size();
}
virtual void ViewHierarchyChanged(
const ViewHierarchyChangedDetails& details) OVERRIDE {
if (details.is_add && details.child == this) {
InitShellWindow();
}
}
virtual bool AcceleratorPressed(const ui::Accelerator& accelerator) OVERRIDE {
switch (accelerator.key_code()) {
case ui::VKEY_F5:
shell_->Reload();
return true;
case ui::VKEY_BROWSER_BACK:
shell_->GoBackOrForward(-1);
return true;
case ui::VKEY_BROWSER_FORWARD:
shell_->GoBackOrForward(1);
return true;
default:
return views::WidgetDelegateView::AcceleratorPressed(accelerator);
}
}
private:
Shell* shell_;
base::string16 title_;
View* toolbar_view_;
views::LabelButton* back_button_;
views::LabelButton* forward_button_;
views::LabelButton* refresh_button_;
views::LabelButton* stop_button_;
views::Textfield* url_entry_;
scoped_ptr<ContextMenuModel> context_menu_model_;
scoped_ptr<views::MenuRunner> context_menu_runner_;
View* contents_view_;
views::WebView* web_view_;
DISALLOW_COPY_AND_ASSIGN(ShellWindowDelegateView);
};
}
#if defined(OS_CHROMEOS)
wm::WMTestHelper* Shell::wm_test_helper_ = NULL;
#endif
views::ViewsDelegate* Shell::views_delegate_ = NULL;
void Shell::PlatformInitialize(const gfx::Size& default_window_size) {
#if defined(OS_WIN)
_setmode(_fileno(stdout), _O_BINARY);
_setmode(_fileno(stderr), _O_BINARY);
#endif
#if defined(OS_CHROMEOS)
chromeos::DBusThreadManager::Initialize();
gfx::Screen::SetScreenInstance(
gfx::SCREEN_TYPE_NATIVE, aura::TestScreen::Create());
wm_test_helper_ = new wm::WMTestHelper(default_window_size);
#else
gfx::Screen::SetScreenInstance(
gfx::SCREEN_TYPE_NATIVE, views::CreateDesktopScreen());
#endif
views_delegate_ = new ShellViewsDelegateAura();
}
void Shell::PlatformExit() {
#if defined(OS_CHROMEOS)
delete wm_test_helper_;
#endif
delete views_delegate_;
views_delegate_ = NULL;
delete platform_;
platform_ = NULL;
#if defined(OS_CHROMEOS)
chromeos::DBusThreadManager::Shutdown();
#endif
aura::Env::DeleteInstance();
}
void Shell::PlatformCleanUp() {
}
void Shell::PlatformEnableUIControl(UIControl control, bool is_enabled) {
if (headless_)
return;
ShellWindowDelegateView* delegate_view =
static_cast<ShellWindowDelegateView*>(window_widget_->widget_delegate());
if (control == BACK_BUTTON) {
delegate_view->EnableUIControl(ShellWindowDelegateView::BACK_BUTTON,
is_enabled);
} else if (control == FORWARD_BUTTON) {
delegate_view->EnableUIControl(ShellWindowDelegateView::FORWARD_BUTTON,
is_enabled);
} else if (control == STOP_BUTTON) {
delegate_view->EnableUIControl(ShellWindowDelegateView::STOP_BUTTON,
is_enabled);
}
}
void Shell::PlatformSetAddressBarURL(const GURL& url) {
if (headless_)
return;
ShellWindowDelegateView* delegate_view =
static_cast<ShellWindowDelegateView*>(window_widget_->widget_delegate());
delegate_view->SetAddressBarURL(url);
}
void Shell::PlatformSetIsLoading(bool loading) {
}
void Shell::PlatformCreateWindow(int width, int height) {
if (headless_) {
content_size_ = gfx::Size(width, height);
if (!platform_)
platform_ = new ShellPlatformDataAura(content_size_);
else
platform_->ResizeWindow(content_size_);
return;
}
#if defined(OS_CHROMEOS)
window_widget_ = views::Widget::CreateWindowWithContextAndBounds(
new ShellWindowDelegateView(this),
wm_test_helper_->GetDefaultParent(NULL, NULL, gfx::Rect()),
gfx::Rect(0, 0, width, height));
#else
window_widget_ = new views::Widget;
views::Widget::InitParams params;
params.bounds = gfx::Rect(0, 0, width, height);
params.delegate = new ShellWindowDelegateView(this);
params.top_level = true;
params.remove_standard_frame = true;
window_widget_->Init(params);
#endif
content_size_ = gfx::Size(width, height);
window_ = window_widget_->GetNativeWindow();
window_->GetHost()->Show();
window_widget_->Show();
}
void Shell::PlatformSetContents() {
if (headless_) {
CHECK(platform_);
aura::Window* content = web_contents_->GetView()->GetNativeView();
aura::Window* parent = platform_->host()->window();
if (!parent->Contains(content)) {
parent->AddChild(content);
content->Show();
}
content->SetBounds(gfx::Rect(content_size_));
RenderWidgetHostView* host_view = web_contents_->GetRenderWidgetHostView();
if (host_view)
host_view->SetSize(content_size_);
} else {
views::WidgetDelegate* widget_delegate = window_widget_->widget_delegate();
ShellWindowDelegateView* delegate_view =
static_cast<ShellWindowDelegateView*>(widget_delegate);
delegate_view->SetWebContents(web_contents_.get(), content_size_);
}
}
void Shell::PlatformResizeSubViews() {
}
void Shell::Close() {
if (headless_)
delete this;
else
window_widget_->CloseNow();
}
void Shell::PlatformSetTitle(const base::string16& title) {
if (headless_)
return;
ShellWindowDelegateView* delegate_view =
static_cast<ShellWindowDelegateView*>(window_widget_->widget_delegate());
delegate_view->SetWindowTitle(title);
window_widget_->UpdateWindowTitle();
}
bool Shell::PlatformHandleContextMenu(
const content::ContextMenuParams& params) {
if (headless_)
return true;
ShellWindowDelegateView* delegate_view =
static_cast<ShellWindowDelegateView*>(window_widget_->widget_delegate());
delegate_view->ShowWebViewContextMenu(params);
return true;
}
void Shell::PlatformWebContentsFocused(WebContents* contents) {
if (headless_)
return;
ShellWindowDelegateView* delegate_view =
static_cast<ShellWindowDelegateView*>(window_widget_->widget_delegate());
delegate_view->OnWebContentsFocused(contents);
}
}