1ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved.
2ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Use of this source code is governed by a BSD-style license that can be
3ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// found in the LICENSE file.
4ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
5ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/ui/views/tab_contents/tab_contents_view_touch.h"
6ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
7ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/string_util.h"
8ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "build/build_config.h"
9ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/download/download_shelf.h"
10ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/renderer_host/render_widget_host_view_views.h"
11ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/ui/views/sad_tab_view.h"
12ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/ui/views/tab_contents/render_view_context_menu_views.h"
13ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "content/browser/renderer_host/render_view_host.h"
14ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "content/browser/renderer_host/render_view_host_factory.h"
15ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "content/browser/tab_contents/interstitial_page.h"
16ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "content/browser/tab_contents/tab_contents.h"
17ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "content/browser/tab_contents/tab_contents_delegate.h"
18ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "ui/gfx/canvas_skia_paint.h"
19ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "ui/gfx/point.h"
20ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "ui/gfx/rect.h"
21ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "ui/gfx/size.h"
22ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "views/controls/native/native_view_host.h"
23ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "views/focus/focus_manager.h"
24ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "views/focus/view_storage.h"
25ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "views/layout/fill_layout.h"
26ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "views/screen.h"
27ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "views/widget/widget.h"
28ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
29ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenusing WebKit::WebDragOperation;
30ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenusing WebKit::WebDragOperationsMask;
31ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenusing WebKit::WebInputEvent;
32ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
33ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// static
34ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenTabContentsView* TabContentsView::Create(TabContents* tab_contents) {
35ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  return new TabContentsViewTouch(tab_contents);
36ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
37ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
38ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenTabContentsViewTouch::TabContentsViewTouch(TabContents* tab_contents)
39ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    : TabContentsView(tab_contents),
40ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      sad_tab_(NULL),
41ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      ignore_next_char_event_(false) {
42ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  last_focused_view_storage_id_ =
43ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      views::ViewStorage::GetInstance()->CreateStorageID();
44ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  SetLayoutManager(new views::FillLayout());
45ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
46ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
47ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenTabContentsViewTouch::~TabContentsViewTouch() {
48ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Make sure to remove any stored view we may still have in the ViewStorage.
49ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  //
50ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // It is possible the view went away before us, so we only do this if the
51ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // view is registered.
52ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  views::ViewStorage* view_storage = views::ViewStorage::GetInstance();
53ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (view_storage->RetrieveView(last_focused_view_storage_id_) != NULL)
54ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    view_storage->RemoveView(last_focused_view_storage_id_);
55ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
56ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
57ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid TabContentsViewTouch::AttachConstrainedWindow(
58ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ConstrainedWindowGtk* constrained_window) {
59ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // TODO(anicolao): reimplement all dialogs as WebUI
60ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  NOTIMPLEMENTED();
61ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
62ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
63ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid TabContentsViewTouch::RemoveConstrainedWindow(
64ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ConstrainedWindowGtk* constrained_window) {
65ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // TODO(anicolao): reimplement all dialogs as WebUI
66ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  NOTIMPLEMENTED();
67ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
68ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
69ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid TabContentsViewTouch::CreateView(const gfx::Size& initial_size) {
70ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  SetBoundsRect(gfx::Rect(bounds().origin(), initial_size));
71ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
72ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
73ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenRenderWidgetHostView* TabContentsViewTouch::CreateViewForWidget(
74ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    RenderWidgetHost* render_widget_host) {
75ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (render_widget_host->view()) {
76ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // During testing, the view will already be set up in most cases to the
77ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // test view, so we don't want to clobber it with a real one. To verify that
78ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // this actually is happening (and somebody isn't accidentally creating the
79ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // view twice), we check for the RVH Factory, which will be set when we're
80ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // making special ones (which go along with the special views).
81ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    DCHECK(RenderViewHostFactory::has_factory());
82ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    return render_widget_host->view();
83ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
84ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
85ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // If we were showing sad tab, remove it now.
86ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (sad_tab_ != NULL) {
87ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    RemoveChildView(sad_tab_.get());
88ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    sad_tab_.reset();
89ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
90ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
91ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  RenderWidgetHostViewViews* view =
92ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      new RenderWidgetHostViewViews(render_widget_host);
93ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  AddChildView(view);
94ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  view->Show();
95ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  view->InitAsChild();
96ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
97ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // TODO(anicolao): implement drag'n'drop hooks if needed
98ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
99ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  return view;
100ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
101ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
102ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsengfx::NativeView TabContentsViewTouch::GetNativeView() const {
103ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  return GetWidget()->GetNativeView();
104ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
105ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
106ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsengfx::NativeView TabContentsViewTouch::GetContentNativeView() const {
107ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  RenderWidgetHostView* rwhv = tab_contents()->GetRenderWidgetHostView();
108ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (!rwhv)
109ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    return NULL;
110ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  return rwhv->GetNativeView();
111ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
112ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
113ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsengfx::NativeWindow TabContentsViewTouch::GetTopLevelNativeWindow() const {
114ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  GtkWidget* window = gtk_widget_get_ancestor(GetNativeView(), GTK_TYPE_WINDOW);
115ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  return window ? GTK_WINDOW(window) : NULL;
116ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
117ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
118ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid TabContentsViewTouch::GetContainerBounds(gfx::Rect* out) const {
119ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  *out = bounds();
120ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
121ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
122ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid TabContentsViewTouch::StartDragging(const WebDropData& drop_data,
123ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                         WebDragOperationsMask ops,
124ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                         const SkBitmap& image,
125ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                         const gfx::Point& image_offset) {
126ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // TODO(anicolao): implement dragging
127ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
128ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
129ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid TabContentsViewTouch::SetPageTitle(const std::wstring& title) {
130ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // TODO(anicolao): figure out if there's anything useful to do here
131ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
132ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
133ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid TabContentsViewTouch::OnTabCrashed(base::TerminationStatus status,
134ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                        int /* error_code */) {
135ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (sad_tab_ != NULL)
136ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    return;
137ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
138ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  sad_tab_.reset(new SadTabView(
139ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      tab_contents(),
140ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      status == base::TERMINATION_STATUS_PROCESS_WAS_KILLED ?
141ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          SadTabView::KILLED : SadTabView::CRASHED));
142ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  RemoveAllChildViews(true);
143ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  AddChildView(sad_tab_.get());
144ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  Layout();
145ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
146ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
147ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid TabContentsViewTouch::SizeContents(const gfx::Size& size) {
148ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  WasSized(size);
149ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
150ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // We need to send this immediately.
151ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  RenderWidgetHostView* rwhv = tab_contents()->GetRenderWidgetHostView();
152ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (rwhv)
153ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    rwhv->SetSize(size);
154ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
155ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
156ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid TabContentsViewTouch::Focus() {
157ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (tab_contents()->interstitial_page()) {
158ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    tab_contents()->interstitial_page()->Focus();
159ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    return;
160ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
161ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
162ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (tab_contents()->is_crashed() && sad_tab_ != NULL) {
163ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    sad_tab_->RequestFocus();
164ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    return;
165ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
166ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
167ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  RenderWidgetHostView* rwhv = tab_contents()->GetRenderWidgetHostView();
168ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (rwhv)
169ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    rwhv->Focus();
170ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
171ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
172ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid TabContentsViewTouch::SetInitialFocus() {
173ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (tab_contents()->FocusLocationBarByDefault())
174ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    tab_contents()->SetFocusToLocationBar(false);
175ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  else
176ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    Focus();
177ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
178ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
179ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid TabContentsViewTouch::StoreFocus() {
180ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  views::ViewStorage* view_storage = views::ViewStorage::GetInstance();
181ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
182ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (view_storage->RetrieveView(last_focused_view_storage_id_) != NULL)
183ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    view_storage->RemoveView(last_focused_view_storage_id_);
184ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
185ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  views::FocusManager* focus_manager =
186ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      views::FocusManager::GetFocusManagerForNativeView(GetNativeView());
187ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (focus_manager) {
188ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // |focus_manager| can be NULL if the tab has been detached but still
189ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // exists.
190ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    views::View* focused_view = focus_manager->GetFocusedView();
191ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (focused_view)
192ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      view_storage->StoreView(last_focused_view_storage_id_, focused_view);
193ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
194ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
195ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
196ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid TabContentsViewTouch::RestoreFocus() {
197ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  views::ViewStorage* view_storage = views::ViewStorage::GetInstance();
198ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  views::View* last_focused_view =
199ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      view_storage->RetrieveView(last_focused_view_storage_id_);
200ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (!last_focused_view) {
201ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    SetInitialFocus();
202ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  } else {
203ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    views::FocusManager* focus_manager =
204ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        views::FocusManager::GetFocusManagerForNativeView(GetNativeView());
205ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
206ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // If you hit this DCHECK, please report it to Jay (jcampan).
207ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    DCHECK(focus_manager != NULL) << "No focus manager when restoring focus.";
208ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
209ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (last_focused_view->IsFocusableInRootView() && focus_manager &&
210ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        focus_manager->ContainsView(last_focused_view)) {
211ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      last_focused_view->RequestFocus();
212ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    } else {
213ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      // The focused view may not belong to the same window hierarchy (e.g.
214ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      // if the location bar was focused and the tab is dragged out), or it may
215ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      // no longer be focusable (e.g. if the location bar was focused and then
216ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      // we switched to fullscreen mode).  In that case we default to the
217ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      // default focus.
218ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      SetInitialFocus();
219ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    }
220ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    view_storage->RemoveView(last_focused_view_storage_id_);
221ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
222ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
223ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
224ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid TabContentsViewTouch::GetViewBounds(gfx::Rect* out) const {
225ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  out->SetRect(x(), y(), width(), height());
226ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
227ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
228ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid TabContentsViewTouch::OnBoundsChanged(const gfx::Rect& previous_bounds) {
229ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (IsVisibleInRootView())
230ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    WasSized(size());
231ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
232ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
233ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid TabContentsViewTouch::OnPaint(gfx::Canvas* canvas) {
234ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
235ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
236ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid TabContentsViewTouch::UpdateDragCursor(WebDragOperation operation) {
237ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  NOTIMPLEMENTED();
238ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // It's not even clear a drag cursor will make sense for touch.
239ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // TODO(anicolao): implement dragging
240ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
241ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
242ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid TabContentsViewTouch::GotFocus() {
243ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (tab_contents()->delegate())
244ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    tab_contents()->delegate()->TabContentsFocused(tab_contents());
245ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
246ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
247ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid TabContentsViewTouch::TakeFocus(bool reverse) {
248ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (tab_contents()->delegate() &&
249ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      !tab_contents()->delegate()->TakeFocus(reverse)) {
250ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
251ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    views::FocusManager* focus_manager =
252ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        views::FocusManager::GetFocusManagerForNativeView(GetNativeView());
253ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
254ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // We may not have a focus manager if the tab has been switched before this
255ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // message arrived.
256ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (focus_manager)
257ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      focus_manager->AdvanceFocus(reverse);
258ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
259ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
260ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
261ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid TabContentsViewTouch::VisibilityChanged(views::View *, bool is_visible) {
262ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (is_visible) {
263ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    WasShown();
264ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  } else {
265ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    WasHidden();
266ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
267ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
268ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
269ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid TabContentsViewTouch::ShowContextMenu(const ContextMenuParams& params) {
270ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Allow delegates to handle the context menu operation first.
271ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (tab_contents()->delegate() &&
272ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      tab_contents()->delegate()->HandleContextMenu(params))
273ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    return;
274ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
275ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  context_menu_.reset(new RenderViewContextMenuViews(tab_contents(), params));
276ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  context_menu_->Init();
277ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
278ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  gfx::Point screen_point(params.x, params.y);
279ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  RenderWidgetHostViewViews* rwhv = static_cast<RenderWidgetHostViewViews*>
280ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      (tab_contents()->GetRenderWidgetHostView());
281ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (rwhv) {
282ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    views::View::ConvertPointToScreen(rwhv, &screen_point);
283ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
284ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
285ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Enable recursive tasks on the message loop so we can get updates while
286ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // the context menu is being displayed.
287ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  bool old_state = MessageLoop::current()->NestableTasksAllowed();
288ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  MessageLoop::current()->SetNestableTasksAllowed(true);
289ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  context_menu_->RunMenuAt(screen_point.x(), screen_point.y());
290ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  MessageLoop::current()->SetNestableTasksAllowed(old_state);
291ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
292ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
293ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid TabContentsViewTouch::ShowPopupMenu(const gfx::Rect& bounds,
294ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                         int item_height,
295ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                         double item_font_size,
296ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                         int selected_item,
297ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                         const std::vector<WebMenuItem>& items,
298ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                         bool right_aligned) {
299ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // External popup menus are only used on Mac.
300ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  NOTREACHED();
301ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
302ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
303ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid TabContentsViewTouch::WasHidden() {
304ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  tab_contents()->HideContents();
305ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
306ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
307ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid TabContentsViewTouch::WasShown() {
308ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  tab_contents()->ShowContents();
309ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
310ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
311ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid TabContentsViewTouch::WasSized(const gfx::Size& size) {
312ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // We have to check that the RenderWidgetHostView is the proper size.
313ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // It can be wrong in cases where the renderer has died and the host
314ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // view needed to be recreated.
315ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  bool needs_resize = size != size_;
316ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
317ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (needs_resize) {
318ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    size_ = size;
319ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (tab_contents()->interstitial_page())
320ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      tab_contents()->interstitial_page()->SetSize(size);
321ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
322ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
323ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  RenderWidgetHostView* rwhv = tab_contents()->GetRenderWidgetHostView();
324ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (rwhv && rwhv->GetViewBounds().size() != size)
325ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    rwhv->SetSize(size);
326ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
327ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (needs_resize)
328ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    SetFloatingPosition(size);
329ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
330ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
331ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid TabContentsViewTouch::SetFloatingPosition(const gfx::Size& size) {
332ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // TODO(anicolao): rework this once we have WebUI views for dialogs
333ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  SetBounds(x(), y(), size.width(), size.height());
334ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
335