172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved.
2c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// found in the LICENSE file.
4c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
5c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/tab_contents/tab_contents_view_gtk.h"
6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
7c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <gdk/gdk.h>
8c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <gdk/gdkkeysyms.h>
9c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <gtk/gtk.h>
10c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
1121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include <algorithm>
1221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
13c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/string_util.h"
1421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "base/utf_string_conversions.h"
15c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "build/build_config.h"
16c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/download/download_shelf.h"
17c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/renderer_host/render_widget_host_view_gtk.h"
18c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/tab_contents/render_view_context_menu_gtk.h"
19c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/tab_contents/web_drag_dest_gtk.h"
2072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "chrome/browser/ui/gtk/browser_window_gtk.h"
2172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "chrome/browser/ui/gtk/constrained_window_gtk.h"
2272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "chrome/browser/ui/gtk/gtk_expanded_container.h"
2372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "chrome/browser/ui/gtk/gtk_floating_container.h"
2472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "chrome/browser/ui/gtk/gtk_util.h"
2572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "chrome/browser/ui/gtk/sad_tab_gtk.h"
2672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "chrome/browser/ui/gtk/tab_contents_drag_source.h"
27ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "content/browser/renderer_host/render_process_host.h"
28dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/renderer_host/render_view_host.h"
29dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/renderer_host/render_view_host_factory.h"
30dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/tab_contents/interstitial_page.h"
31dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/tab_contents/tab_contents.h"
32dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/tab_contents/tab_contents_delegate.h"
33ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "content/common/notification_source.h"
34ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "content/common/notification_type.h"
3572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "ui/gfx/point.h"
3672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "ui/gfx/rect.h"
3772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "ui/gfx/size.h"
38c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "webkit/glue/webdropdata.h"
39c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
40c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing WebKit::WebDragOperation;
41c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing WebKit::WebDragOperationsMask;
42c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
43c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochnamespace {
44c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
45c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Called when the mouse leaves the widget. We notify our delegate.
46c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochgboolean OnLeaveNotify(GtkWidget* widget, GdkEventCrossing* event,
47c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                       TabContents* tab_contents) {
48c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (tab_contents->delegate())
49c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    tab_contents->delegate()->ContentsMouseEvent(
50c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        tab_contents, gfx::Point(event->x_root, event->y_root), false);
51c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return FALSE;
52c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
53c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
54c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Called when the mouse moves within the widget. We notify our delegate.
55c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochgboolean OnMouseMove(GtkWidget* widget, GdkEventMotion* event,
56c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                     TabContents* tab_contents) {
57c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (tab_contents->delegate())
58c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    tab_contents->delegate()->ContentsMouseEvent(
59c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        tab_contents, gfx::Point(event->x_root, event->y_root), true);
60c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return FALSE;
61c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
62c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
63ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// See tab_contents_view_views.cc for discussion of mouse scroll zooming.
64c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochgboolean OnMouseScroll(GtkWidget* widget, GdkEventScroll* event,
65c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                       TabContents* tab_contents) {
66c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if ((event->state & gtk_accelerator_get_default_mod_mask()) ==
67c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      GDK_CONTROL_MASK) {
68c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (event->direction == GDK_SCROLL_DOWN) {
69c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      tab_contents->delegate()->ContentsZoomChange(false);
70c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      return TRUE;
71c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    } else if (event->direction == GDK_SCROLL_UP) {
72c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      tab_contents->delegate()->ContentsZoomChange(true);
73c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      return TRUE;
74c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
75c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
76c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
77c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return FALSE;
78c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
79c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
80c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}  // namespace
81c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
82c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// static
83c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTabContentsView* TabContentsView::Create(TabContents* tab_contents) {
84c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return new TabContentsViewGtk(tab_contents);
85c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
86c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
87c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTabContentsViewGtk::TabContentsViewGtk(TabContents* tab_contents)
88c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    : TabContentsView(tab_contents),
89c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      floating_(gtk_floating_container_new()),
90c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      expanded_(gtk_expanded_container_new()),
91c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      constrained_window_(NULL) {
92c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  gtk_widget_set_name(expanded_, "chrome-tab-contents-view");
93c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  g_signal_connect(expanded_, "size-allocate",
94c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                   G_CALLBACK(OnSizeAllocateThunk), this);
95c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  g_signal_connect(expanded_, "child-size-request",
96c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                   G_CALLBACK(OnChildSizeRequestThunk), this);
97c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  g_signal_connect(floating_.get(), "set-floating-position",
98c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                   G_CALLBACK(OnSetFloatingPositionThunk), this);
99c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
100c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  gtk_container_add(GTK_CONTAINER(floating_.get()), expanded_);
101c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  gtk_widget_show(expanded_);
102c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  gtk_widget_show(floating_.get());
103c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  registrar_.Add(this, NotificationType::TAB_CONTENTS_CONNECTED,
104c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                 Source<TabContents>(tab_contents));
105c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  drag_source_.reset(new TabContentsDragSource(this));
106c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
107c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
108c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTabContentsViewGtk::~TabContentsViewGtk() {
109c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  floating_.Destroy();
110c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
111c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
112c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid TabContentsViewGtk::AttachConstrainedWindow(
113c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ConstrainedWindowGtk* constrained_window) {
114c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK(constrained_window_ == NULL);
115c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
116c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  constrained_window_ = constrained_window;
117c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  gtk_floating_container_add_floating(GTK_FLOATING_CONTAINER(floating_.get()),
118c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                      constrained_window->widget());
119c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
120c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
121c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid TabContentsViewGtk::RemoveConstrainedWindow(
122c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ConstrainedWindowGtk* constrained_window) {
123c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK(constrained_window == constrained_window_);
124c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
125c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  constrained_window_ = NULL;
126c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  gtk_container_remove(GTK_CONTAINER(floating_.get()),
127c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                       constrained_window->widget());
128c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
129c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
130c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid TabContentsViewGtk::CreateView(const gfx::Size& initial_size) {
131c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  requested_size_ = initial_size;
132c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
133c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
134c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochRenderWidgetHostView* TabContentsViewGtk::CreateViewForWidget(
135c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    RenderWidgetHost* render_widget_host) {
136c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (render_widget_host->view()) {
137c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // During testing, the view will already be set up in most cases to the
138c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // test view, so we don't want to clobber it with a real one. To verify that
139c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // this actually is happening (and somebody isn't accidentally creating the
140c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // view twice), we check for the RVH Factory, which will be set when we're
141c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // making special ones (which go along with the special views).
142c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    DCHECK(RenderViewHostFactory::has_factory());
143c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return render_widget_host->view();
144c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
145c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
146c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  RenderWidgetHostViewGtk* view =
147c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      new RenderWidgetHostViewGtk(render_widget_host);
148c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  view->InitAsChild();
149c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  gfx::NativeView content_view = view->native_view();
1503345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  g_signal_connect(content_view, "focus", G_CALLBACK(OnFocusThunk), this);
151c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  g_signal_connect(content_view, "leave-notify-event",
152c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                   G_CALLBACK(OnLeaveNotify), tab_contents());
153c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  g_signal_connect(content_view, "motion-notify-event",
154c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                   G_CALLBACK(OnMouseMove), tab_contents());
155c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  g_signal_connect(content_view, "scroll-event",
156c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                   G_CALLBACK(OnMouseScroll), tab_contents());
157c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  gtk_widget_add_events(content_view, GDK_LEAVE_NOTIFY_MASK |
158c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                        GDK_POINTER_MOTION_MASK);
159c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  InsertIntoContentArea(content_view);
160c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
161c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Renderer target DnD.
162c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  drag_dest_.reset(new WebDragDestGtk(tab_contents(), content_view));
163c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
164c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return view;
165c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
166c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
167c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochgfx::NativeView TabContentsViewGtk::GetNativeView() const {
168c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return floating_.get();
169c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
170c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
171c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochgfx::NativeView TabContentsViewGtk::GetContentNativeView() const {
172c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  RenderWidgetHostView* rwhv = tab_contents()->GetRenderWidgetHostView();
173c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!rwhv)
174c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return NULL;
175c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return rwhv->GetNativeView();
176c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
177c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
178c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochgfx::NativeWindow TabContentsViewGtk::GetTopLevelNativeWindow() const {
179c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  GtkWidget* window = gtk_widget_get_ancestor(GetNativeView(), GTK_TYPE_WINDOW);
180c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return window ? GTK_WINDOW(window) : NULL;
181c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
182c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
183c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid TabContentsViewGtk::GetContainerBounds(gfx::Rect* out) const {
184c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // This is used for positioning the download shelf arrow animation,
185c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // as well as sizing some other widgets in Windows.  In GTK the size is
186c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // managed for us, so it appears to be only used for the download shelf
187c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // animation.
188c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int x = 0;
189c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int y = 0;
190c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (expanded_->window)
191c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    gdk_window_get_origin(expanded_->window, &x, &y);
192c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  out->SetRect(x + expanded_->allocation.x, y + expanded_->allocation.y,
193c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch               requested_size_.width(), requested_size_.height());
194c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
195c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
196c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid TabContentsViewGtk::SetPageTitle(const std::wstring& title) {
197c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Set the window name to include the page title so it's easier to spot
198c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // when debugging (e.g. via xwininfo -tree).
199c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  gfx::NativeView content_view = GetContentNativeView();
200c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (content_view && content_view->window)
201c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    gdk_window_set_title(content_view->window, WideToUTF8(title).c_str());
202c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
203c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
20472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenvoid TabContentsViewGtk::OnTabCrashed(base::TerminationStatus status,
20572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                                      int error_code) {
206c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (tab_contents() != NULL && !sad_tab_.get()) {
20772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    sad_tab_.reset(new SadTabGtk(
20872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        tab_contents(),
20972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        status == base::TERMINATION_STATUS_PROCESS_WAS_KILLED ?
21072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        SadTabGtk::KILLED : SadTabGtk::CRASHED));
211c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    InsertIntoContentArea(sad_tab_->widget());
212c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    gtk_widget_show(sad_tab_->widget());
213c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
214c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
215c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
216c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid TabContentsViewGtk::SizeContents(const gfx::Size& size) {
217c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // We don't need to manually set the size of of widgets in GTK+, but we do
218c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // need to pass the sizing information on to the RWHV which will pass the
219c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // sizing information on to the renderer.
220c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  requested_size_ = size;
221c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  RenderWidgetHostView* rwhv = tab_contents()->GetRenderWidgetHostView();
222c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (rwhv)
223c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    rwhv->SetSize(size);
224c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
225c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
226c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid TabContentsViewGtk::Focus() {
227c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (tab_contents()->showing_interstitial_page()) {
228c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    tab_contents()->interstitial_page()->Focus();
2293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  } else if (!constrained_window_) {
230c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    GtkWidget* widget = GetContentNativeView();
231c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (widget)
232c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      gtk_widget_grab_focus(widget);
233c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
234c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
235c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
236c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid TabContentsViewGtk::SetInitialFocus() {
237c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (tab_contents()->FocusLocationBarByDefault())
238c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    tab_contents()->SetFocusToLocationBar(false);
239c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  else
240c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    Focus();
241c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
242c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
243c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid TabContentsViewGtk::StoreFocus() {
244c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  focus_store_.Store(GetNativeView());
245c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
246c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
247c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid TabContentsViewGtk::RestoreFocus() {
248c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (focus_store_.widget())
249c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    gtk_widget_grab_focus(focus_store_.widget());
250c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  else
251c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    SetInitialFocus();
252c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
253c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
25472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenvoid TabContentsViewGtk::GetViewBounds(gfx::Rect* out) const {
25572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  if (!floating_->window) {
25672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    out->SetRect(0, 0, requested_size_.width(), requested_size_.height());
25772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    return;
25872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  }
25972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  int x = 0, y = 0, w, h;
26072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  gdk_window_get_geometry(floating_->window, &x, &y, &w, &h, NULL);
26172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  out->SetRect(x, y, w, h);
26272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
26372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
2643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid TabContentsViewGtk::SetFocusedWidget(GtkWidget* widget) {
2653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  focus_store_.SetWidget(widget);
2663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
2673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
268c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid TabContentsViewGtk::UpdateDragCursor(WebDragOperation operation) {
269c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  drag_dest_->UpdateDragStatus(operation);
270c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
271c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
272c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid TabContentsViewGtk::GotFocus() {
273c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // This is only used in the views FocusManager stuff but it bleeds through
274c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // all subclasses. http://crbug.com/21875
275c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
276c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
277c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// This is called when we the renderer asks us to take focus back (i.e., it has
278c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// iterated past the last focusable element on the page).
279c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid TabContentsViewGtk::TakeFocus(bool reverse) {
280c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!tab_contents()->delegate()->TakeFocus(reverse)) {
281c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    gtk_widget_child_focus(GTK_WIDGET(GetTopLevelNativeWindow()),
282c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        reverse ? GTK_DIR_TAB_BACKWARD : GTK_DIR_TAB_FORWARD);
283c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
284c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
285c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
286c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid TabContentsViewGtk::Observe(NotificationType type,
287c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                 const NotificationSource& source,
288c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                 const NotificationDetails& details) {
289c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  switch (type.value) {
290c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case NotificationType::TAB_CONTENTS_CONNECTED: {
291c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      // No need to remove the SadTabGtk's widget from the container since
292c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      // the new RenderWidgetHostViewGtk instance already removed all the
293c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      // vbox's children.
294c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      sad_tab_.reset();
295c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      break;
296c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
297c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    default:
298c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      NOTREACHED() << "Got a notification we didn't register for.";
299c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      break;
300c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
301c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
302c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
303c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid TabContentsViewGtk::ShowContextMenu(const ContextMenuParams& params) {
304ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Find out the RenderWidgetHostView that corresponds to the render widget on
305ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // which this context menu is showed, so that we can retrieve the last mouse
306ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // down event on the render widget and use it as the timestamp of the
307ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // activation event to show the context menu.
308ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  RenderWidgetHostView* view = NULL;
309ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (params.custom_context.render_widget_id !=
310ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      webkit_glue::CustomContextMenuContext::kCurrentRenderWidget) {
311ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    IPC::Channel::Listener* listener =
312ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        tab_contents()->render_view_host()->process()->GetListenerByID(
313ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen            params.custom_context.render_widget_id);
314ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (!listener) {
315ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      NOTREACHED();
316ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      return;
317ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    }
318ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    view = static_cast<RenderWidgetHost*>(listener)->view();
319ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  } else {
320ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    view = tab_contents()->GetRenderWidgetHostView();
321ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
322ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  RenderWidgetHostViewGtk* view_gtk =
323ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      static_cast<RenderWidgetHostViewGtk*>(view);
324ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (!view_gtk || !view_gtk->last_mouse_down())
325ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    return;
326ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
327ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  context_menu_.reset(new RenderViewContextMenuGtk(
328ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      tab_contents(), params, view_gtk->last_mouse_down()->time));
329c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  context_menu_->Init();
330c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
331c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  gfx::Rect bounds;
332c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  GetContainerBounds(&bounds);
333c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  gfx::Point point = bounds.origin();
334c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  point.Offset(params.x, params.y);
335c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  context_menu_->Popup(point);
336c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
337c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
338513209b27ff55e2841eac0e4120199c23acce758Ben Murdochvoid TabContentsViewGtk::ShowPopupMenu(const gfx::Rect& bounds,
339513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch                                       int item_height,
340513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch                                       double item_font_size,
341513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch                                       int selected_item,
342513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch                                       const std::vector<WebMenuItem>& items,
343513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch                                       bool right_aligned) {
344513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  // We are not using external popup menus on Linux, they are rendered by
345513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  // WebKit.
346513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  NOTREACHED();
347513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch}
348513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch
349c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Render view DnD -------------------------------------------------------------
350c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
351c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid TabContentsViewGtk::StartDragging(const WebDropData& drop_data,
352c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                       WebDragOperationsMask ops,
353c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                       const SkBitmap& image,
354c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                       const gfx::Point& image_offset) {
355c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK(GetContentNativeView());
356ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
357ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  RenderWidgetHostViewGtk* view_gtk = static_cast<RenderWidgetHostViewGtk*>(
358ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      tab_contents()->GetRenderWidgetHostView());
359ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (!view_gtk || !view_gtk->last_mouse_down())
360ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    return;
361ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
362ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  drag_source_->StartDragging(drop_data, ops, view_gtk->last_mouse_down(),
363ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                              image, image_offset);
364c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
365c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
366c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// -----------------------------------------------------------------------------
367c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
368c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid TabContentsViewGtk::InsertIntoContentArea(GtkWidget* widget) {
369c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  gtk_container_add(GTK_CONTAINER(expanded_), widget);
370c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
371c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// Called when the content view gtk widget is tabbed to, or after the call to
3733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// gtk_widget_child_focus() in TakeFocus(). We return true
3743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// and grab focus if we don't have it. The call to
3753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// FocusThroughTabTraversal(bool) forwards the "move focus forward" effect to
3763345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick// webkit.
3773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickgboolean TabContentsViewGtk::OnFocus(GtkWidget* widget,
3783345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                     GtkDirectionType focus) {
3793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // If we are showing a constrained window, don't allow the native view to take
3803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // focus.
3813345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  if (constrained_window_) {
3823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    // If we return false, it will revert to the default handler, which will
3833345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    // take focus. We don't want that. But if we return true, the event will
3843345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    // stop being propagated, leaving focus wherever it is currently. That is
3853345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    // also bad. So we return false to let the default handler run, but take
3863345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    // focus first so as to trick it into thinking the view was already focused
3873345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    // and allowing the event to propagate.
3883345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    gtk_widget_grab_focus(widget);
3893345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    return FALSE;
3903345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  }
3913345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
3923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // If we already have focus, let the next widget have a shot at it. We will
3933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // reach this situation after the call to gtk_widget_child_focus() in
3943345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // TakeFocus().
3953345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  if (gtk_widget_is_focus(widget))
3963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    return FALSE;
3973345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
3983345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  gtk_widget_grab_focus(widget);
3993345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  bool reverse = focus == GTK_DIR_TAB_BACKWARD;
4003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  tab_contents()->FocusThroughTabTraversal(reverse);
4013345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  return TRUE;
4023345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
4033345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
404c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid TabContentsViewGtk::OnChildSizeRequest(GtkWidget* widget,
405c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                            GtkWidget* child,
406c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                            GtkRequisition* requisition) {
407c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (tab_contents()->delegate()) {
408c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    requisition->height +=
409c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        tab_contents()->delegate()->GetExtraRenderViewHeight();
410c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
411c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
412c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
413c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid TabContentsViewGtk::OnSizeAllocate(GtkWidget* widget,
414c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                        GtkAllocation* allocation) {
415c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int width = allocation->width;
416c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int height = allocation->height;
417c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // |delegate()| can be NULL here during browser teardown.
418c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (tab_contents()->delegate())
419c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    height += tab_contents()->delegate()->GetExtraRenderViewHeight();
420c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  gfx::Size size(width, height);
421c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  requested_size_ = size;
422c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
423c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // We manually tell our RWHV to resize the renderer content.  This avoids
424c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // spurious resizes from GTK+.
425c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  RenderWidgetHostView* rwhv = tab_contents()->GetRenderWidgetHostView();
426c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (rwhv)
427c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    rwhv->SetSize(size);
428c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (tab_contents()->interstitial_page())
429c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    tab_contents()->interstitial_page()->SetSize(size);
430c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
431c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
432c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid TabContentsViewGtk::OnSetFloatingPosition(
433c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    GtkWidget* floating_container, GtkAllocation* allocation) {
4343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  if (!constrained_window_)
4353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    return;
4363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
437c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Place each ConstrainedWindow in the center of the view.
4383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  GtkWidget* widget = constrained_window_->widget();
4393345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  DCHECK(widget->parent == floating_.get());
440c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
4413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  GtkRequisition requisition;
4423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  gtk_widget_size_request(widget, &requisition);
443c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
4443345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  GValue value = { 0, };
4453345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  g_value_init(&value, G_TYPE_INT);
446c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
4473345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  int child_x = std::max((allocation->width - requisition.width) / 2, 0);
4483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  g_value_set_int(&value, child_x);
4493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  gtk_container_child_set_property(GTK_CONTAINER(floating_container),
4503345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                   widget, "x", &value);
451c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
4523345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  int child_y = std::max((allocation->height - requisition.height) / 2, 0);
4533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  g_value_set_int(&value, child_y);
4543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  gtk_container_child_set_property(GTK_CONTAINER(floating_container),
4553345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                   widget, "y", &value);
4563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  g_value_unset(&value);
457c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
458