This source file includes following definitions.
- CreateWebContentsView
- IsScrollEndEffectEnabled
- ShouldNavigateForward
- ShouldNavigateBack
- ToRenderWidgetHostViewAura
- forward_events_
- stop_forwarding_events
- web_contents_window
- OnScrollEvent
- OnGestureEvent
- contents_
- Observe
- window
- PrepareDragForFileContents
- PrepareDragForDownload
- PrepareDragData
- PrepareDropData
- ConvertFromWeb
- ConvertToWeb
- ConvertAuraEventFlagsToWebInputEventModifiers
- parent_
- WindowObserver
- OnWindowAdded
- OnWillRemoveWindow
- OnWindowVisibilityChanged
- OnWindowParentChanged
- OnWindowBoundsChanged
- OnWindowAddedToRootWindow
- OnWindowRemovingFromRootWindow
- OnHostMoved
- SendScreenRects
- UpdateConstrainedWindows
- touch_editable_
- SetupOverlayWindowForTesting
- SetTouchEditableForTest
- SizeChangedCommon
- EndDrag
- InstallOverscrollControllerDelegate
- PrepareOverscrollWindow
- PrepareContentWindowForOverscroll
- ResetOverscrollTransform
- CompleteOverscrollNavigation
- GetWindowToAnimateForOverscroll
- GetTranslationForOverscroll
- PrepareOverscrollNavigationOverlay
- UpdateOverscrollWindowBrightness
- AttachTouchEditableToRenderView
- OverscrollUpdateForWebContentsDelegate
- GetNativeView
- GetContentNativeView
- GetTopLevelNativeWindow
- GetContainerBounds
- OnTabCrashed
- SizeContents
- Focus
- SetInitialFocus
- StoreFocus
- RestoreFocus
- GetDropData
- GetViewBounds
- CreateView
- CreateViewForWidget
- CreateViewForPopupWidget
- SetPageTitle
- RenderViewCreated
- RenderViewSwappedIn
- SetOverscrollControllerEnabled
- ShowContextMenu
- StartDragging
- UpdateDragCursor
- GotFocus
- TakeFocus
- GetVisibleBounds
- OnOverscrollUpdate
- OnOverscrollComplete
- OnOverscrollModeChange
- OnImplicitAnimationsCompleted
- GetMinimumSize
- GetMaximumSize
- OnBoundsChanged
- GetCursor
- GetNonClientComponent
- ShouldDescendIntoChildForEventHandling
- CanFocus
- OnCaptureLost
- OnPaint
- OnDeviceScaleFactorChanged
- OnWindowDestroying
- OnWindowDestroyed
- OnWindowTargetVisibilityChanged
- HasHitTestMask
- GetHitTestMask
- OnKeyEvent
- OnMouseEvent
- OnDragEntered
- OnDragUpdated
- OnDragExited
- OnPerformDrop
#include "content/browser/web_contents/web_contents_view_aura.h"
#include "base/auto_reset.h"
#include "base/command_line.h"
#include "base/file_util.h"
#include "base/metrics/histogram.h"
#include "base/strings/utf_string_conversions.h"
#include "content/browser/download/drag_download_util.h"
#include "content/browser/frame_host/interstitial_page_impl.h"
#include "content/browser/frame_host/navigation_entry_impl.h"
#include "content/browser/renderer_host/dip_util.h"
#include "content/browser/renderer_host/overscroll_controller.h"
#include "content/browser/renderer_host/render_view_host_factory.h"
#include "content/browser/renderer_host/render_view_host_impl.h"
#include "content/browser/renderer_host/render_widget_host_impl.h"
#include "content/browser/renderer_host/render_widget_host_view_aura.h"
#include "content/browser/web_contents/aura/gesture_nav_simple.h"
#include "content/browser/web_contents/aura/image_window_delegate.h"
#include "content/browser/web_contents/aura/overscroll_navigation_overlay.h"
#include "content/browser/web_contents/aura/shadow_layer_delegate.h"
#include "content/browser/web_contents/aura/window_slider.h"
#include "content/browser/web_contents/touch_editable_impl_aura.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/public/browser/content_browser_client.h"
#include "content/public/browser/notification_observer.h"
#include "content/public/browser/notification_registrar.h"
#include "content/public/browser/notification_source.h"
#include "content/public/browser/notification_types.h"
#include "content/public/browser/overscroll_configuration.h"
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/render_widget_host.h"
#include "content/public/browser/render_widget_host_view.h"
#include "content/public/browser/web_contents_delegate.h"
#include "content/public/browser/web_contents_observer.h"
#include "content/public/browser/web_contents_view_delegate.h"
#include "content/public/browser/web_drag_dest_delegate.h"
#include "content/public/common/content_client.h"
#include "content/public/common/content_switches.h"
#include "content/public/common/drop_data.h"
#include "net/base/net_util.h"
#include "third_party/WebKit/public/web/WebInputEvent.h"
#include "ui/aura/client/aura_constants.h"
#include "ui/aura/client/window_tree_client.h"
#include "ui/aura/env.h"
#include "ui/aura/window.h"
#include "ui/aura/window_observer.h"
#include "ui/aura/window_tree_host.h"
#include "ui/aura/window_tree_host_observer.h"
#include "ui/base/clipboard/clipboard.h"
#include "ui/base/clipboard/custom_data_helper.h"
#include "ui/base/dragdrop/drag_drop_types.h"
#include "ui/base/dragdrop/drag_utils.h"
#include "ui/base/dragdrop/drop_target_event.h"
#include "ui/base/dragdrop/os_exchange_data.h"
#include "ui/base/hit_test.h"
#include "ui/compositor/layer.h"
#include "ui/compositor/scoped_layer_animation_settings.h"
#include "ui/events/event.h"
#include "ui/events/event_utils.h"
#include "ui/gfx/canvas.h"
#include "ui/gfx/image/image.h"
#include "ui/gfx/image/image_png_rep.h"
#include "ui/gfx/image/image_skia.h"
#include "ui/gfx/screen.h"
#include "ui/wm/public/drag_drop_client.h"
#include "ui/wm/public/drag_drop_delegate.h"
namespace content {
WebContentsViewPort* CreateWebContentsView(
WebContentsImpl* web_contents,
WebContentsViewDelegate* delegate,
RenderViewHostDelegateView** render_view_host_delegate_view) {
WebContentsViewAura* rv = new WebContentsViewAura(web_contents, delegate);
*render_view_host_delegate_view = rv;
return rv;
}
namespace {
bool IsScrollEndEffectEnabled() {
return CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
switches::kScrollEndEffect) == "1";
}
bool ShouldNavigateForward(const NavigationController& controller,
OverscrollMode mode) {
return mode == (base::i18n::IsRTL() ? OVERSCROLL_EAST : OVERSCROLL_WEST) &&
controller.CanGoForward();
}
bool ShouldNavigateBack(const NavigationController& controller,
OverscrollMode mode) {
return mode == (base::i18n::IsRTL() ? OVERSCROLL_WEST : OVERSCROLL_EAST) &&
controller.CanGoBack();
}
RenderWidgetHostViewAura* ToRenderWidgetHostViewAura(
RenderWidgetHostView* view) {
if (!view || RenderViewHostFactory::has_factory())
return NULL;
RenderProcessHostImpl* process = static_cast<RenderProcessHostImpl*>(
view->GetRenderWidgetHost()->GetProcess());
if (process->IsGuest())
return NULL;
return static_cast<RenderWidgetHostViewAura*>(view);
}
class OverscrollWindowDelegate : public ImageWindowDelegate {
public:
OverscrollWindowDelegate(WebContentsImpl* web_contents,
OverscrollMode overscroll_mode)
: web_contents_(web_contents),
forward_events_(true) {
const NavigationControllerImpl& controller = web_contents->GetController();
const NavigationEntryImpl* entry = NULL;
if (ShouldNavigateForward(controller, overscroll_mode)) {
entry = NavigationEntryImpl::FromNavigationEntry(
controller.GetEntryAtOffset(1));
} else if (ShouldNavigateBack(controller, overscroll_mode)) {
entry = NavigationEntryImpl::FromNavigationEntry(
controller.GetEntryAtOffset(-1));
}
gfx::Image image;
if (entry && entry->screenshot().get()) {
std::vector<gfx::ImagePNGRep> image_reps;
image_reps.push_back(gfx::ImagePNGRep(entry->screenshot(),
ui::GetImageScale(
ui::GetScaleFactorForNativeView(web_contents_window()))));
image = gfx::Image(image_reps);
}
SetImage(image);
}
void stop_forwarding_events() { forward_events_ = false; }
private:
virtual ~OverscrollWindowDelegate() {}
aura::Window* web_contents_window() {
return web_contents_->GetView()->GetContentNativeView();
}
virtual void OnScrollEvent(ui::ScrollEvent* event) OVERRIDE {
if (forward_events_ && web_contents_window())
web_contents_window()->delegate()->OnScrollEvent(event);
}
virtual void OnGestureEvent(ui::GestureEvent* event) OVERRIDE {
if (forward_events_ && web_contents_window())
web_contents_window()->delegate()->OnGestureEvent(event);
}
WebContents* web_contents_;
bool forward_events_;
DISALLOW_COPY_AND_ASSIGN(OverscrollWindowDelegate);
};
class WebDragSourceAura : public NotificationObserver {
public:
WebDragSourceAura(aura::Window* window, WebContentsImpl* contents)
: window_(window),
contents_(contents) {
registrar_.Add(this,
NOTIFICATION_WEB_CONTENTS_DISCONNECTED,
Source<WebContents>(contents));
}
virtual ~WebDragSourceAura() {
}
virtual void Observe(int type,
const NotificationSource& source,
const NotificationDetails& details) OVERRIDE {
if (type != NOTIFICATION_WEB_CONTENTS_DISCONNECTED)
return;
aura::client::DragDropClient* dnd_client =
aura::client::GetDragDropClient(window_->GetRootWindow());
if (dnd_client && dnd_client->IsDragDropInProgress())
dnd_client->DragCancel();
window_ = NULL;
contents_ = NULL;
}
aura::Window* window() const { return window_; }
private:
aura::Window* window_;
WebContentsImpl* contents_;
NotificationRegistrar registrar_;
DISALLOW_COPY_AND_ASSIGN(WebDragSourceAura);
};
#if (!defined(OS_CHROMEOS) && defined(USE_X11)) || defined(OS_WIN)
void PrepareDragForFileContents(const DropData& drop_data,
ui::OSExchangeData::Provider* provider) {
base::FilePath file_name =
base::FilePath::FromUTF16Unsafe(drop_data.file_description_filename);
if (file_name.BaseName().RemoveExtension().empty()) {
const base::FilePath::StringType extension = file_name.Extension();
file_name = net::GenerateFileName(drop_data.url, "", "", "", "", "")
.ReplaceExtension(extension);
}
provider->SetFileContents(file_name, drop_data.file_contents);
}
#endif
#if defined(OS_WIN)
void PrepareDragForDownload(
const DropData& drop_data,
ui::OSExchangeData::Provider* provider,
WebContentsImpl* web_contents) {
const GURL& page_url = web_contents->GetLastCommittedURL();
const std::string& page_encoding = web_contents->GetEncoding();
base::string16 mime_type;
base::FilePath file_name;
GURL download_url;
if (!ParseDownloadMetadata(drop_data.download_metadata,
&mime_type,
&file_name,
&download_url))
return;
std::string default_name =
GetContentClient()->browser()->GetDefaultDownloadName();
base::FilePath generated_download_file_name =
net::GenerateFileName(download_url,
std::string(),
std::string(),
base::UTF16ToUTF8(file_name.value()),
base::UTF16ToUTF8(mime_type),
default_name);
base::ThreadRestrictions::ScopedAllowIO allow_file_operations;
base::FilePath temp_dir_path;
if (!base::CreateNewTempDirectory(FILE_PATH_LITERAL("chrome_drag"),
&temp_dir_path))
return;
base::FilePath download_path =
temp_dir_path.Append(generated_download_file_name);
base::DeleteFileAfterReboot(download_path);
base::DeleteFileAfterReboot(temp_dir_path);
scoped_refptr<DragDownloadFile> download_file =
new DragDownloadFile(
download_path,
base::File(),
download_url,
Referrer(page_url, drop_data.referrer_policy),
page_encoding,
web_contents);
ui::OSExchangeData::DownloadFileInfo file_download(base::FilePath(),
download_file.get());
provider->SetDownloadFileInfo(file_download);
}
#endif
void PrepareDragData(const DropData& drop_data,
ui::OSExchangeData::Provider* provider,
WebContentsImpl* web_contents) {
provider->MarkOriginatedFromRenderer();
#if defined(OS_WIN)
if (!drop_data.download_metadata.empty())
PrepareDragForDownload(drop_data, provider, web_contents);
#endif
#if (!defined(OS_CHROMEOS) && defined(USE_X11)) || defined(OS_WIN)
if (!drop_data.file_contents.empty())
PrepareDragForFileContents(drop_data, provider);
#endif
if (!drop_data.text.string().empty())
provider->SetString(drop_data.text.string());
if (drop_data.url.is_valid())
provider->SetURL(drop_data.url, drop_data.url_title);
if (!drop_data.html.string().empty())
provider->SetHtml(drop_data.html.string(), drop_data.html_base_url);
if (!drop_data.filenames.empty())
provider->SetFilenames(drop_data.filenames);
if (!drop_data.custom_data.empty()) {
Pickle pickle;
ui::WriteCustomDataToPickle(drop_data.custom_data, &pickle);
provider->SetPickledData(ui::Clipboard::GetWebCustomDataFormatType(),
pickle);
}
}
void PrepareDropData(DropData* drop_data, const ui::OSExchangeData& data) {
drop_data->did_originate_from_renderer = data.DidOriginateFromRenderer();
base::string16 plain_text;
data.GetString(&plain_text);
if (!plain_text.empty())
drop_data->text = base::NullableString16(plain_text, false);
GURL url;
base::string16 url_title;
data.GetURLAndTitle(
ui::OSExchangeData::DO_NOT_CONVERT_FILENAMES, &url, &url_title);
if (url.is_valid()) {
drop_data->url = url;
drop_data->url_title = url_title;
}
base::string16 html;
GURL html_base_url;
data.GetHtml(&html, &html_base_url);
if (!html.empty())
drop_data->html = base::NullableString16(html, false);
if (html_base_url.is_valid())
drop_data->html_base_url = html_base_url;
data.GetFilenames(&drop_data->filenames);
Pickle pickle;
if (data.GetPickledData(ui::Clipboard::GetWebCustomDataFormatType(), &pickle))
ui::ReadCustomDataIntoMap(
pickle.data(), pickle.size(), &drop_data->custom_data);
}
int ConvertFromWeb(blink::WebDragOperationsMask ops) {
int drag_op = ui::DragDropTypes::DRAG_NONE;
if (ops & blink::WebDragOperationCopy)
drag_op |= ui::DragDropTypes::DRAG_COPY;
if (ops & blink::WebDragOperationMove)
drag_op |= ui::DragDropTypes::DRAG_MOVE;
if (ops & blink::WebDragOperationLink)
drag_op |= ui::DragDropTypes::DRAG_LINK;
return drag_op;
}
blink::WebDragOperationsMask ConvertToWeb(int drag_op) {
int web_drag_op = blink::WebDragOperationNone;
if (drag_op & ui::DragDropTypes::DRAG_COPY)
web_drag_op |= blink::WebDragOperationCopy;
if (drag_op & ui::DragDropTypes::DRAG_MOVE)
web_drag_op |= blink::WebDragOperationMove;
if (drag_op & ui::DragDropTypes::DRAG_LINK)
web_drag_op |= blink::WebDragOperationLink;
return (blink::WebDragOperationsMask) web_drag_op;
}
int ConvertAuraEventFlagsToWebInputEventModifiers(int aura_event_flags) {
int web_input_event_modifiers = 0;
if (aura_event_flags & ui::EF_SHIFT_DOWN)
web_input_event_modifiers |= blink::WebInputEvent::ShiftKey;
if (aura_event_flags & ui::EF_CONTROL_DOWN)
web_input_event_modifiers |= blink::WebInputEvent::ControlKey;
if (aura_event_flags & ui::EF_ALT_DOWN)
web_input_event_modifiers |= blink::WebInputEvent::AltKey;
if (aura_event_flags & ui::EF_COMMAND_DOWN)
web_input_event_modifiers |= blink::WebInputEvent::MetaKey;
return web_input_event_modifiers;
}
}
class WebContentsViewAura::WindowObserver
: public aura::WindowObserver, public aura::WindowTreeHostObserver {
public:
explicit WindowObserver(WebContentsViewAura* view)
: view_(view),
parent_(NULL) {
view_->window_->AddObserver(this);
#if defined(OS_WIN)
if (view_->window_->GetRootWindow())
view_->window_->GetRootWindow()->AddObserver(this);
#endif
}
virtual ~WindowObserver() {
view_->window_->RemoveObserver(this);
if (view_->window_->GetHost())
view_->window_->GetHost()->RemoveObserver(this);
if (parent_)
parent_->RemoveObserver(this);
#if defined(OS_WIN)
if (parent_) {
const aura::Window::Windows& children = parent_->children();
for (size_t i = 0; i < children.size(); ++i)
children[i]->RemoveObserver(this);
}
aura::Window* root_window = view_->window_->GetRootWindow();
if (root_window) {
root_window->RemoveObserver(this);
const aura::Window::Windows& root_children = root_window->children();
for (size_t i = 0; i < root_children.size(); ++i)
root_children[i]->RemoveObserver(this);
}
#endif
}
#if defined(OS_WIN)
virtual void OnWindowAdded(aura::Window* new_window) OVERRIDE {
if (new_window != view_->window_) {
if (new_window != parent_) {
if (new_window->parent() == parent_ ||
new_window->parent() == view_->window_->GetRootWindow()) {
new_window->AddObserver(this);
}
}
}
if (new_window->parent() == parent_) {
UpdateConstrainedWindows(NULL);
}
}
virtual void OnWillRemoveWindow(aura::Window* window) OVERRIDE {
if (window == view_->window_)
return;
window->RemoveObserver(this);
UpdateConstrainedWindows(window);
}
virtual void OnWindowVisibilityChanged(aura::Window* window,
bool visible) OVERRIDE {
if (window == view_->window_ ||
window->parent() == parent_ ||
window->parent() == view_->window_->GetRootWindow()) {
UpdateConstrainedWindows(NULL);
}
}
#endif
virtual void OnWindowParentChanged(aura::Window* window,
aura::Window* parent) OVERRIDE {
if (window != view_->window_)
return;
if (parent_)
parent_->RemoveObserver(this);
#if defined(OS_WIN)
if (parent_) {
const aura::Window::Windows& children = parent_->children();
for (size_t i = 0; i < children.size(); ++i)
children[i]->RemoveObserver(this);
RenderWidgetHostViewAura* view = ToRenderWidgetHostViewAura(
view_->web_contents_->GetRenderWidgetHostView());
if (view)
view->UpdateConstrainedWindowRects(std::vector<gfx::Rect>());
}
if (parent && parent == window->GetRootWindow())
parent->RemoveObserver(this);
if (window->GetRootWindow() &&
parent != window->GetRootWindow() &&
!window->GetRootWindow()->HasObserver(this)) {
window->GetRootWindow()->AddObserver(this);
}
#endif
parent_ = parent;
if (parent) {
parent->AddObserver(this);
#if defined(OS_WIN)
if (parent != window->GetRootWindow()) {
const aura::Window::Windows& children = parent->children();
for (size_t i = 0; i < children.size(); ++i) {
if (children[i] != view_->window_)
children[i]->AddObserver(this);
}
}
#endif
}
}
virtual void OnWindowBoundsChanged(aura::Window* window,
const gfx::Rect& old_bounds,
const gfx::Rect& new_bounds) OVERRIDE {
if (window == parent_ || window == view_->window_) {
SendScreenRects();
if (view_->touch_editable_)
view_->touch_editable_->UpdateEditingController();
#if defined(OS_WIN)
} else {
UpdateConstrainedWindows(NULL);
#endif
}
}
virtual void OnWindowAddedToRootWindow(aura::Window* window) OVERRIDE {
if (window == view_->window_) {
window->GetHost()->AddObserver(this);
#if defined(OS_WIN)
if (!window->GetRootWindow()->HasObserver(this))
window->GetRootWindow()->AddObserver(this);
#endif
}
}
virtual void OnWindowRemovingFromRootWindow(aura::Window* window,
aura::Window* new_root) OVERRIDE {
if (window == view_->window_) {
window->GetHost()->RemoveObserver(this);
#if defined(OS_WIN)
window->GetRootWindow()->RemoveObserver(this);
const aura::Window::Windows& root_children =
window->GetRootWindow()->children();
for (size_t i = 0; i < root_children.size(); ++i) {
if (root_children[i] != view_->window_ && root_children[i] != parent_)
root_children[i]->RemoveObserver(this);
}
#endif
}
}
virtual void OnHostMoved(const aura::WindowTreeHost* host,
const gfx::Point& new_origin) OVERRIDE {
TRACE_EVENT1("ui",
"WebContentsViewAura::WindowObserver::OnHostMoved",
"new_origin", new_origin.ToString());
SendScreenRects();
}
private:
void SendScreenRects() {
RenderWidgetHostImpl::From(view_->web_contents_->GetRenderViewHost())->
SendScreenRects();
}
#if defined(OS_WIN)
void UpdateConstrainedWindows(aura::Window* exclude) {
RenderWidgetHostViewAura* view = ToRenderWidgetHostViewAura(
view_->web_contents_->GetRenderWidgetHostView());
if (!view)
return;
std::vector<gfx::Rect> constrained_windows;
if (parent_) {
const aura::Window::Windows& children = parent_->children();
for (size_t i = 0; i < children.size(); ++i) {
if (children[i] != view_->window_ &&
children[i] != exclude &&
children[i]->IsVisible()) {
constrained_windows.push_back(children[i]->GetBoundsInRootWindow());
}
}
}
aura::Window* root_window = view_->window_->GetRootWindow();
const aura::Window::Windows& root_children = root_window->children();
if (root_window) {
for (size_t i = 0; i < root_children.size(); ++i) {
if (root_children[i]->IsVisible() &&
!root_children[i]->Contains(view_->window_.get())) {
constrained_windows.push_back(
root_children[i]->GetBoundsInRootWindow());
}
}
}
view->UpdateConstrainedWindowRects(constrained_windows);
}
#endif
WebContentsViewAura* view_;
aura::Window* parent_;
DISALLOW_COPY_AND_ASSIGN(WindowObserver);
};
WebContentsViewAura::WebContentsViewAura(
WebContentsImpl* web_contents,
WebContentsViewDelegate* delegate)
: web_contents_(web_contents),
delegate_(delegate),
current_drag_op_(blink::WebDragOperationNone),
drag_dest_delegate_(NULL),
current_rvh_for_drag_(NULL),
overscroll_change_brightness_(false),
current_overscroll_gesture_(OVERSCROLL_NONE),
completed_overscroll_gesture_(OVERSCROLL_NONE),
touch_editable_(TouchEditableImplAura::Create()) {
}
WebContentsViewAura::~WebContentsViewAura() {
if (!window_)
return;
window_observer_.reset();
window_.reset();
}
void WebContentsViewAura::SetupOverlayWindowForTesting() {
if (navigation_overlay_)
navigation_overlay_->SetupForTesting();
}
void WebContentsViewAura::SetTouchEditableForTest(
TouchEditableImplAura* touch_editable) {
touch_editable_.reset(touch_editable);
AttachTouchEditableToRenderView();
}
void WebContentsViewAura::SizeChangedCommon(const gfx::Size& size) {
if (web_contents_->GetInterstitialPage())
web_contents_->GetInterstitialPage()->SetSize(size);
RenderWidgetHostView* rwhv =
web_contents_->GetRenderWidgetHostView();
if (rwhv)
rwhv->SetSize(size);
}
void WebContentsViewAura::EndDrag(blink::WebDragOperationsMask ops) {
aura::Window* root_window = GetNativeView()->GetRootWindow();
gfx::Point screen_loc =
gfx::Screen::GetScreenFor(GetNativeView())->GetCursorScreenPoint();
gfx::Point client_loc = screen_loc;
RenderViewHost* rvh = web_contents_->GetRenderViewHost();
aura::Window* window = rvh->GetView()->GetNativeView();
aura::Window::ConvertPointToTarget(root_window, window, &client_loc);
if (!web_contents_)
return;
web_contents_->DragSourceEndedAt(client_loc.x(), client_loc.y(),
screen_loc.x(), screen_loc.y(), ops);
}
void WebContentsViewAura::InstallOverscrollControllerDelegate(
RenderWidgetHostImpl* host) {
const std::string value = CommandLine::ForCurrentProcess()->
GetSwitchValueASCII(switches::kOverscrollHistoryNavigation);
if (value == "0") {
navigation_overlay_.reset();
return;
}
if (value == "2") {
navigation_overlay_.reset();
if (!gesture_nav_simple_)
gesture_nav_simple_.reset(new GestureNavSimple(web_contents_));
host->overscroll_controller()->set_delegate(gesture_nav_simple_.get());
return;
}
host->overscroll_controller()->set_delegate(this);
if (!navigation_overlay_)
navigation_overlay_.reset(new OverscrollNavigationOverlay(web_contents_));
}
void WebContentsViewAura::PrepareOverscrollWindow() {
if (overscroll_window_) {
base::AutoReset<OverscrollMode> reset_state(¤t_overscroll_gesture_,
current_overscroll_gesture_);
scoped_ptr<aura::Window> reset_window(overscroll_window_.release());
}
OverscrollWindowDelegate* overscroll_delegate = new OverscrollWindowDelegate(
web_contents_,
current_overscroll_gesture_);
overscroll_window_.reset(new aura::Window(overscroll_delegate));
overscroll_window_->SetType(ui::wm::WINDOW_TYPE_CONTROL);
overscroll_window_->SetTransparent(true);
overscroll_window_->Init(aura::WINDOW_LAYER_TEXTURED);
overscroll_window_->layer()->SetMasksToBounds(false);
overscroll_window_->SetName("OverscrollOverlay");
overscroll_change_brightness_ = overscroll_delegate->has_image();
window_->AddChild(overscroll_window_.get());
gfx::Rect bounds = gfx::Rect(window_->bounds().size());
if (ShouldNavigateForward(web_contents_->GetController(),
current_overscroll_gesture_)) {
bounds.Offset(base::i18n::IsRTL() ? -bounds.width() : bounds.width(), 0);
}
aura::Window* animate_window = GetWindowToAnimateForOverscroll();
if (animate_window == overscroll_window_)
window_->StackChildAbove(overscroll_window_.get(), GetContentNativeView());
else
window_->StackChildBelow(overscroll_window_.get(), GetContentNativeView());
UpdateOverscrollWindowBrightness(0.f);
overscroll_window_->SetBounds(bounds);
overscroll_window_->Show();
overscroll_shadow_.reset(new ShadowLayerDelegate(animate_window->layer()));
}
void WebContentsViewAura::PrepareContentWindowForOverscroll() {
StopObservingImplicitAnimations();
aura::Window* content = GetContentNativeView();
content->layer()->GetAnimator()->AbortAllAnimations();
content->SetTransform(gfx::Transform());
content->layer()->SetLayerBrightness(0.f);
}
void WebContentsViewAura::ResetOverscrollTransform() {
if (!web_contents_->GetRenderWidgetHostView())
return;
aura::Window* target = GetWindowToAnimateForOverscroll();
if (!target)
return;
{
ui::ScopedLayerAnimationSettings settings(target->layer()->GetAnimator());
settings.SetPreemptionStrategy(
ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
settings.SetTweenType(gfx::Tween::EASE_OUT);
settings.AddObserver(this);
target->SetTransform(gfx::Transform());
}
{
ui::ScopedLayerAnimationSettings settings(target->layer()->GetAnimator());
settings.SetPreemptionStrategy(
ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
settings.SetTweenType(gfx::Tween::EASE_OUT);
UpdateOverscrollWindowBrightness(0.f);
}
}
void WebContentsViewAura::CompleteOverscrollNavigation(OverscrollMode mode) {
if (!web_contents_->GetRenderWidgetHostView())
return;
if (current_overscroll_gesture_ == OVERSCROLL_NONE)
return;
UMA_HISTOGRAM_ENUMERATION("Overscroll.Navigated",
current_overscroll_gesture_, OVERSCROLL_COUNT);
OverscrollWindowDelegate* delegate = static_cast<OverscrollWindowDelegate*>(
overscroll_window_->delegate());
delegate->stop_forwarding_events();
completed_overscroll_gesture_ = mode;
aura::Window* target = GetWindowToAnimateForOverscroll();
ui::ScopedLayerAnimationSettings settings(target->layer()->GetAnimator());
settings.SetPreemptionStrategy(
ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
settings.SetTweenType(gfx::Tween::EASE_OUT);
settings.AddObserver(this);
gfx::Transform transform;
int content_width =
web_contents_->GetRenderWidgetHostView()->GetViewBounds().width();
int translate_x = mode == OVERSCROLL_WEST ? -content_width : content_width;
transform.Translate(translate_x, 0);
target->SetTransform(transform);
UpdateOverscrollWindowBrightness(translate_x);
}
aura::Window* WebContentsViewAura::GetWindowToAnimateForOverscroll() {
if (current_overscroll_gesture_ == OVERSCROLL_NONE)
return NULL;
return ShouldNavigateForward(web_contents_->GetController(),
current_overscroll_gesture_) ?
overscroll_window_.get() : GetContentNativeView();
}
gfx::Vector2d WebContentsViewAura::GetTranslationForOverscroll(int delta_x,
int delta_y) {
if (current_overscroll_gesture_ == OVERSCROLL_NORTH ||
current_overscroll_gesture_ == OVERSCROLL_SOUTH) {
return gfx::Vector2d(0, delta_y);
}
const NavigationControllerImpl& controller = web_contents_->GetController();
const gfx::Rect& bounds = GetViewBounds();
if (ShouldNavigateForward(controller, current_overscroll_gesture_))
return gfx::Vector2d(std::max(-bounds.width(), delta_x), 0);
else if (ShouldNavigateBack(controller, current_overscroll_gesture_))
return gfx::Vector2d(std::min(bounds.width(), delta_x), 0);
return gfx::Vector2d();
}
void WebContentsViewAura::PrepareOverscrollNavigationOverlay() {
OverscrollWindowDelegate* delegate = static_cast<OverscrollWindowDelegate*>(
overscroll_window_->delegate());
overscroll_window_->SchedulePaintInRect(
gfx::Rect(overscroll_window_->bounds().size()));
overscroll_window_->SetBounds(gfx::Rect(window_->bounds().size()));
overscroll_window_->SetTransform(gfx::Transform());
navigation_overlay_->SetOverlayWindow(overscroll_window_.Pass(),
delegate);
navigation_overlay_->StartObserving();
}
void WebContentsViewAura::UpdateOverscrollWindowBrightness(float delta_x) {
if (!overscroll_change_brightness_)
return;
const float kBrightnessMin = -.1f;
const float kBrightnessMax = -.01f;
float ratio = fabs(delta_x) / GetViewBounds().width();
ratio = std::min(1.f, ratio);
if (base::i18n::IsRTL())
ratio = 1.f - ratio;
float brightness = current_overscroll_gesture_ == OVERSCROLL_WEST ?
kBrightnessMin + ratio * (kBrightnessMax - kBrightnessMin) :
kBrightnessMax - ratio * (kBrightnessMax - kBrightnessMin);
brightness = std::max(kBrightnessMin, brightness);
brightness = std::min(kBrightnessMax, brightness);
aura::Window* window = GetWindowToAnimateForOverscroll();
window->layer()->SetLayerBrightness(brightness);
}
void WebContentsViewAura::AttachTouchEditableToRenderView() {
if (!touch_editable_)
return;
RenderWidgetHostViewAura* rwhva = ToRenderWidgetHostViewAura(
web_contents_->GetRenderWidgetHostView());
touch_editable_->AttachToView(rwhva);
}
void WebContentsViewAura::OverscrollUpdateForWebContentsDelegate(int delta_y) {
if (web_contents_->GetDelegate() && IsScrollEndEffectEnabled())
web_contents_->GetDelegate()->OverscrollUpdate(delta_y);
}
gfx::NativeView WebContentsViewAura::GetNativeView() const {
return window_.get();
}
gfx::NativeView WebContentsViewAura::GetContentNativeView() const {
RenderWidgetHostView* rwhv = web_contents_->GetRenderWidgetHostView();
return rwhv ? rwhv->GetNativeView() : NULL;
}
gfx::NativeWindow WebContentsViewAura::GetTopLevelNativeWindow() const {
return window_->GetToplevelWindow();
}
void WebContentsViewAura::GetContainerBounds(gfx::Rect *out) const {
*out = window_->GetBoundsInScreen();
}
void WebContentsViewAura::OnTabCrashed(base::TerminationStatus status,
int error_code) {
}
void WebContentsViewAura::SizeContents(const gfx::Size& size) {
gfx::Rect bounds = window_->bounds();
if (bounds.size() != size) {
bounds.set_size(size);
window_->SetBounds(bounds);
} else {
SizeChangedCommon(size);
}
}
void WebContentsViewAura::Focus() {
if (web_contents_->GetInterstitialPage()) {
web_contents_->GetInterstitialPage()->Focus();
return;
}
if (delegate_.get() && delegate_->Focus())
return;
RenderWidgetHostView* rwhv = web_contents_->GetRenderWidgetHostView();
if (rwhv)
rwhv->Focus();
}
void WebContentsViewAura::SetInitialFocus() {
if (web_contents_->FocusLocationBarByDefault())
web_contents_->SetFocusToLocationBar(false);
else
Focus();
}
void WebContentsViewAura::StoreFocus() {
if (delegate_)
delegate_->StoreFocus();
}
void WebContentsViewAura::RestoreFocus() {
if (delegate_)
delegate_->RestoreFocus();
}
DropData* WebContentsViewAura::GetDropData() const {
return current_drop_data_.get();
}
gfx::Rect WebContentsViewAura::GetViewBounds() const {
return window_->GetBoundsInScreen();
}
void WebContentsViewAura::CreateView(
const gfx::Size& initial_size, gfx::NativeView context) {
aura::Env::CreateInstance();
window_.reset(new aura::Window(this));
window_->set_owned_by_parent(false);
window_->SetType(ui::wm::WINDOW_TYPE_CONTROL);
window_->SetTransparent(false);
window_->Init(aura::WINDOW_LAYER_NOT_DRAWN);
aura::Window* root_window = context ? context->GetRootWindow() : NULL;
if (root_window) {
if (root_window) {
aura::client::ParentWindowWithContext(
window_.get(), root_window, root_window->GetBoundsInScreen());
}
}
window_->layer()->SetMasksToBounds(true);
window_->SetName("WebContentsViewAura");
if (!web_contents_->GetRenderProcessHost()->IsGuest())
window_observer_.reset(new WindowObserver(this));
if (delegate_)
drag_dest_delegate_ = delegate_->GetDragDestDelegate();
}
RenderWidgetHostView* WebContentsViewAura::CreateViewForWidget(
RenderWidgetHost* render_widget_host) {
if (render_widget_host->GetView()) {
DCHECK(RenderViewHostFactory::has_factory());
return render_widget_host->GetView();
}
RenderWidgetHostView* view =
RenderWidgetHostView::CreateViewForWidget(render_widget_host);
view->InitAsChild(NULL);
GetNativeView()->AddChild(view->GetNativeView());
if (navigation_overlay_.get() && navigation_overlay_->has_window()) {
navigation_overlay_->StartObserving();
}
RenderWidgetHostImpl* host_impl =
RenderWidgetHostImpl::From(render_widget_host);
if (!host_impl->is_hidden())
view->Show();
aura::client::SetDragDropDelegate(view->GetNativeView(), this);
if (host_impl->overscroll_controller() &&
(!web_contents_->GetDelegate() ||
web_contents_->GetDelegate()->CanOverscrollContent())) {
InstallOverscrollControllerDelegate(host_impl);
}
AttachTouchEditableToRenderView();
return view;
}
RenderWidgetHostView* WebContentsViewAura::CreateViewForPopupWidget(
RenderWidgetHost* render_widget_host) {
return RenderWidgetHostViewPort::CreateViewForWidget(render_widget_host);
}
void WebContentsViewAura::SetPageTitle(const base::string16& title) {
window_->set_title(title);
}
void WebContentsViewAura::RenderViewCreated(RenderViewHost* host) {
}
void WebContentsViewAura::RenderViewSwappedIn(RenderViewHost* host) {
if (navigation_overlay_.get() && navigation_overlay_->has_window())
navigation_overlay_->StartObserving();
AttachTouchEditableToRenderView();
}
void WebContentsViewAura::SetOverscrollControllerEnabled(bool enabled) {
RenderViewHostImpl* host = static_cast<RenderViewHostImpl*>(
web_contents_->GetRenderViewHost());
if (host) {
host->SetOverscrollControllerEnabled(enabled);
if (enabled)
InstallOverscrollControllerDelegate(host);
}
if (!enabled)
navigation_overlay_.reset();
else if (!navigation_overlay_)
navigation_overlay_.reset(new OverscrollNavigationOverlay(web_contents_));
}
void WebContentsViewAura::ShowContextMenu(RenderFrameHost* render_frame_host,
const ContextMenuParams& params) {
if (touch_editable_) {
touch_editable_->EndTouchEditing(false);
}
if (delegate_) {
delegate_->ShowContextMenu(render_frame_host, params);
}
}
void WebContentsViewAura::StartDragging(
const DropData& drop_data,
blink::WebDragOperationsMask operations,
const gfx::ImageSkia& image,
const gfx::Vector2d& image_offset,
const DragEventSourceInfo& event_info) {
aura::Window* root_window = GetNativeView()->GetRootWindow();
if (!aura::client::GetDragDropClient(root_window)) {
web_contents_->SystemDragEnded();
return;
}
if (touch_editable_)
touch_editable_->EndTouchEditing(false);
ui::OSExchangeData::Provider* provider = ui::OSExchangeData::CreateProvider();
PrepareDragData(drop_data, provider, web_contents_);
ui::OSExchangeData data(provider);
if (!image.isNull()) {
drag_utils::SetDragImageOnDataObject(image,
gfx::Size(image.width(), image.height()), image_offset, &data);
}
scoped_ptr<WebDragSourceAura> drag_source(
new WebDragSourceAura(GetNativeView(), web_contents_));
int result_op = 0;
{
gfx::NativeView content_native_view = GetContentNativeView();
base::MessageLoop::ScopedNestableTaskAllower allow(
base::MessageLoop::current());
result_op = aura::client::GetDragDropClient(root_window)
->StartDragAndDrop(data,
root_window,
content_native_view,
event_info.event_location,
ConvertFromWeb(operations),
event_info.event_source);
}
if (!drag_source->window()) {
return;
}
EndDrag(ConvertToWeb(result_op));
web_contents_->SystemDragEnded();
}
void WebContentsViewAura::UpdateDragCursor(blink::WebDragOperation operation) {
current_drag_op_ = operation;
}
void WebContentsViewAura::GotFocus() {
if (web_contents_->GetDelegate())
web_contents_->GetDelegate()->WebContentsFocused(web_contents_);
}
void WebContentsViewAura::TakeFocus(bool reverse) {
if (web_contents_->GetDelegate() &&
!web_contents_->GetDelegate()->TakeFocus(web_contents_, reverse) &&
delegate_.get()) {
delegate_->TakeFocus(reverse);
}
}
gfx::Rect WebContentsViewAura::GetVisibleBounds() const {
RenderWidgetHostView* rwhv = web_contents_->GetRenderWidgetHostView();
if (!rwhv || !rwhv->IsShowing())
return gfx::Rect();
return rwhv->GetViewBounds();
}
void WebContentsViewAura::OnOverscrollUpdate(float delta_x, float delta_y) {
if (current_overscroll_gesture_ == OVERSCROLL_NONE)
return;
aura::Window* target = GetWindowToAnimateForOverscroll();
ui::ScopedLayerAnimationSettings settings(target->layer()->GetAnimator());
settings.SetPreemptionStrategy(ui::LayerAnimator::IMMEDIATELY_SET_NEW_TARGET);
gfx::Vector2d translate = GetTranslationForOverscroll(delta_x, delta_y);
gfx::Transform transform;
if (current_overscroll_gesture_ != OVERSCROLL_NORTH &&
current_overscroll_gesture_ != OVERSCROLL_SOUTH) {
transform.Translate(translate.x(), translate.y());
target->SetTransform(transform);
UpdateOverscrollWindowBrightness(delta_x);
}
OverscrollUpdateForWebContentsDelegate(translate.y());
}
void WebContentsViewAura::OnOverscrollComplete(OverscrollMode mode) {
UMA_HISTOGRAM_ENUMERATION("Overscroll.Completed", mode, OVERSCROLL_COUNT);
OverscrollUpdateForWebContentsDelegate(0);
NavigationControllerImpl& controller = web_contents_->GetController();
if (ShouldNavigateForward(controller, mode) ||
ShouldNavigateBack(controller, mode)) {
CompleteOverscrollNavigation(mode);
return;
}
ResetOverscrollTransform();
}
void WebContentsViewAura::OnOverscrollModeChange(OverscrollMode old_mode,
OverscrollMode new_mode) {
ResetOverscrollTransform();
if (new_mode != OVERSCROLL_NONE && touch_editable_)
touch_editable_->OverscrollStarted();
if (new_mode == OVERSCROLL_NONE ||
!GetContentNativeView() ||
((new_mode == OVERSCROLL_EAST || new_mode == OVERSCROLL_WEST) &&
navigation_overlay_.get() && navigation_overlay_->has_window())) {
current_overscroll_gesture_ = OVERSCROLL_NONE;
OverscrollUpdateForWebContentsDelegate(0);
} else {
aura::Window* target = GetWindowToAnimateForOverscroll();
if (target) {
StopObservingImplicitAnimations();
target->layer()->GetAnimator()->AbortAllAnimations();
}
PrepareContentWindowForOverscroll();
current_overscroll_gesture_ = new_mode;
if (current_overscroll_gesture_ == OVERSCROLL_EAST ||
current_overscroll_gesture_ == OVERSCROLL_WEST)
PrepareOverscrollWindow();
UMA_HISTOGRAM_ENUMERATION("Overscroll.Started", new_mode, OVERSCROLL_COUNT);
}
completed_overscroll_gesture_ = OVERSCROLL_NONE;
}
void WebContentsViewAura::OnImplicitAnimationsCompleted() {
overscroll_shadow_.reset();
if (ShouldNavigateForward(web_contents_->GetController(),
completed_overscroll_gesture_)) {
PrepareOverscrollNavigationOverlay();
web_contents_->GetController().GoForward();
} else if (ShouldNavigateBack(web_contents_->GetController(),
completed_overscroll_gesture_)) {
PrepareOverscrollNavigationOverlay();
web_contents_->GetController().GoBack();
} else {
if (touch_editable_)
touch_editable_->OverscrollCompleted();
}
aura::Window* content = GetContentNativeView();
if (content) {
content->SetTransform(gfx::Transform());
content->layer()->SetLayerBrightness(0.f);
}
current_overscroll_gesture_ = OVERSCROLL_NONE;
completed_overscroll_gesture_ = OVERSCROLL_NONE;
overscroll_window_.reset();
}
gfx::Size WebContentsViewAura::GetMinimumSize() const {
return gfx::Size();
}
gfx::Size WebContentsViewAura::GetMaximumSize() const {
return gfx::Size();
}
void WebContentsViewAura::OnBoundsChanged(const gfx::Rect& old_bounds,
const gfx::Rect& new_bounds) {
SizeChangedCommon(new_bounds.size());
if (delegate_)
delegate_->SizeChanged(new_bounds.size());
for (size_t i = 0; i < window_->children().size(); i++) {
if (window_->children()[i]->GetProperty(
aura::client::kConstrainedWindowKey)) {
gfx::Rect bounds = window_->children()[i]->bounds();
bounds.set_origin(
gfx::Point((new_bounds.width() - bounds.width()) / 2,
(new_bounds.height() - bounds.height()) / 2));
window_->children()[i]->SetBounds(bounds);
}
}
}
gfx::NativeCursor WebContentsViewAura::GetCursor(const gfx::Point& point) {
return gfx::kNullCursor;
}
int WebContentsViewAura::GetNonClientComponent(const gfx::Point& point) const {
return HTCLIENT;
}
bool WebContentsViewAura::ShouldDescendIntoChildForEventHandling(
aura::Window* child,
const gfx::Point& location) {
return true;
}
bool WebContentsViewAura::CanFocus() {
RenderWidgetHostViewAura* view = ToRenderWidgetHostViewAura(
web_contents_->GetRenderWidgetHostView());
if (view != NULL && !view->IsClosing())
return true;
return false;
}
void WebContentsViewAura::OnCaptureLost() {
}
void WebContentsViewAura::OnPaint(gfx::Canvas* canvas) {
}
void WebContentsViewAura::OnDeviceScaleFactorChanged(
float device_scale_factor) {
}
void WebContentsViewAura::OnWindowDestroying(aura::Window* window) {
navigation_overlay_.reset();
overscroll_window_.reset();
}
void WebContentsViewAura::OnWindowDestroyed(aura::Window* window) {
}
void WebContentsViewAura::OnWindowTargetVisibilityChanged(bool visible) {
if (visible)
web_contents_->WasShown();
else
web_contents_->WasHidden();
}
bool WebContentsViewAura::HasHitTestMask() const {
return false;
}
void WebContentsViewAura::GetHitTestMask(gfx::Path* mask) const {
}
void WebContentsViewAura::OnKeyEvent(ui::KeyEvent* event) {
}
void WebContentsViewAura::OnMouseEvent(ui::MouseEvent* event) {
if (!web_contents_->GetDelegate())
return;
switch (event->type()) {
case ui::ET_MOUSE_PRESSED:
web_contents_->GetDelegate()->ActivateContents(web_contents_);
break;
case ui::ET_MOUSE_MOVED:
case ui::ET_MOUSE_EXITED:
web_contents_->GetDelegate()->ContentsMouseEvent(
web_contents_,
gfx::Screen::GetScreenFor(GetNativeView())->GetCursorScreenPoint(),
event->type() == ui::ET_MOUSE_MOVED);
break;
default:
break;
}
}
void WebContentsViewAura::OnDragEntered(const ui::DropTargetEvent& event) {
if (drag_dest_delegate_)
drag_dest_delegate_->DragInitialize(web_contents_);
current_drop_data_.reset(new DropData());
PrepareDropData(current_drop_data_.get(), event.data());
blink::WebDragOperationsMask op = ConvertToWeb(event.source_operations());
gfx::Point screen_pt =
gfx::Screen::GetScreenFor(GetNativeView())->GetCursorScreenPoint();
current_rvh_for_drag_ = web_contents_->GetRenderViewHost();
web_contents_->GetRenderViewHost()->DragTargetDragEnter(
*current_drop_data_.get(), event.location(), screen_pt, op,
ConvertAuraEventFlagsToWebInputEventModifiers(event.flags()));
if (drag_dest_delegate_) {
drag_dest_delegate_->OnReceiveDragData(event.data());
drag_dest_delegate_->OnDragEnter();
}
}
int WebContentsViewAura::OnDragUpdated(const ui::DropTargetEvent& event) {
DCHECK(current_rvh_for_drag_);
if (current_rvh_for_drag_ != web_contents_->GetRenderViewHost())
OnDragEntered(event);
blink::WebDragOperationsMask op = ConvertToWeb(event.source_operations());
gfx::Point screen_pt =
gfx::Screen::GetScreenFor(GetNativeView())->GetCursorScreenPoint();
web_contents_->GetRenderViewHost()->DragTargetDragOver(
event.location(), screen_pt, op,
ConvertAuraEventFlagsToWebInputEventModifiers(event.flags()));
if (drag_dest_delegate_)
drag_dest_delegate_->OnDragOver();
return ConvertFromWeb(current_drag_op_);
}
void WebContentsViewAura::OnDragExited() {
DCHECK(current_rvh_for_drag_);
if (current_rvh_for_drag_ != web_contents_->GetRenderViewHost())
return;
web_contents_->GetRenderViewHost()->DragTargetDragLeave();
if (drag_dest_delegate_)
drag_dest_delegate_->OnDragLeave();
current_drop_data_.reset();
}
int WebContentsViewAura::OnPerformDrop(const ui::DropTargetEvent& event) {
DCHECK(current_rvh_for_drag_);
if (current_rvh_for_drag_ != web_contents_->GetRenderViewHost())
OnDragEntered(event);
web_contents_->GetRenderViewHost()->DragTargetDrop(
event.location(),
gfx::Screen::GetScreenFor(GetNativeView())->GetCursorScreenPoint(),
ConvertAuraEventFlagsToWebInputEventModifiers(event.flags()));
if (drag_dest_delegate_)
drag_dest_delegate_->OnDrop();
current_drop_data_.reset();
return ConvertFromWeb(current_drag_op_);
}
}