15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/gtk/tab_contents/chrome_web_contents_view_delegate_gtk.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <map>
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/lazy_instance.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/browser_shutdown.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/gtk/constrained_window_gtk.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/gtk/tab_contents/render_view_context_menu_gtk.h"
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/gtk/tab_contents/web_drag_bookmark_handler_gtk.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/tab_contents/chrome_web_contents_view_delegate.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/render_process_host.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/render_view_host.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/render_widget_host_view.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/web_contents.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/web_contents_view.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/gtk/focus_store_gtk.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/gtk/gtk_floating_container.h"
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kViewDelegateUserDataKey[] = "ChromeWebContentsViewDelegateGtk";
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ViewDelegateUserData : public base::SupportsUserData::Data {
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  explicit ViewDelegateUserData(ChromeWebContentsViewDelegateGtk* view_delegate)
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : view_delegate_(view_delegate) {}
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~ViewDelegateUserData() {}
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ChromeWebContentsViewDelegateGtk* view_delegate() { return view_delegate_; }
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ChromeWebContentsViewDelegateGtk* view_delegate_;  // unowned
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ChromeWebContentsViewDelegateGtk* ChromeWebContentsViewDelegateGtk::GetFor(
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    content::WebContents* web_contents) {
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ViewDelegateUserData* user_data = static_cast<ViewDelegateUserData*>(
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      web_contents->GetUserData(&kViewDelegateUserDataKey));
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return user_data ? user_data->view_delegate() : NULL;
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ChromeWebContentsViewDelegateGtk::ChromeWebContentsViewDelegateGtk(
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    content::WebContents* web_contents)
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : floating_(gtk_floating_container_new()),
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      web_contents_modal_dialog_(NULL),
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      web_contents_(web_contents),
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      expanded_container_(NULL),
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      focus_store_(NULL) {
552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  g_object_ref_sink(floating_.get());
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gtk_widget_set_name(floating_.get(), "chrome-tab-contents-view");
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  g_signal_connect(floating_.get(), "set-floating-position",
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   G_CALLBACK(OnSetFloatingPositionThunk), this);
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Stash this in the WebContents.
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  web_contents->SetUserData(&kViewDelegateUserDataKey,
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            new ViewDelegateUserData(this));
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ChromeWebContentsViewDelegateGtk::~ChromeWebContentsViewDelegateGtk() {
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ChromeWebContentsViewDelegateGtk::AttachWebContentsModalDialog(
692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    GtkWidget* web_contents_modal_dialog) {
702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(web_contents_modal_dialog_ == NULL);
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  web_contents_modal_dialog_ = web_contents_modal_dialog;
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gtk_floating_container_add_floating(GTK_FLOATING_CONTAINER(floating_.get()),
742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                      web_contents_modal_dialog);
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ChromeWebContentsViewDelegateGtk::RemoveWebContentsModalDialog(
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    GtkWidget* web_contents_modal_dialog) {
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(web_contents_modal_dialog == web_contents_modal_dialog_);
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  web_contents_modal_dialog_ = NULL;
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ChromeWebContentsViewDelegateGtk::Initialize(
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GtkWidget* expanded_container, ui::FocusStoreGtk* focus_store) {
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  expanded_container_ = expanded_container;
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  focus_store_ = focus_store;
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We install a chrome specific handler to intercept bookmark drags for the
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // bookmark manager/extension API.
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bookmark_handler_gtk_.reset(new WebDragBookmarkHandlerGtk);
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gtk_container_add(GTK_CONTAINER(floating_.get()), expanded_container);
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gtk_widget_show(floating_.get());
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)gfx::NativeView ChromeWebContentsViewDelegateGtk::GetNativeView() const {
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return floating_.get();
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ChromeWebContentsViewDelegateGtk::Focus() {
1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!web_contents_modal_dialog_) {
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GtkWidget* widget = web_contents_->GetView()->GetContentNativeView();
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (widget)
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      gtk_widget_grab_focus(widget);
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)gboolean ChromeWebContentsViewDelegateGtk::OnNativeViewFocusEvent(
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GtkWidget* widget,
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GtkDirectionType type,
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    gboolean* return_value) {
1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // If we are showing a web contents modal dialog, don't allow the native view
1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // to take focus.
1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (web_contents_modal_dialog_) {
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // If we return false, it will revert to the default handler, which will
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // take focus. We don't want that. But if we return true, the event will
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // stop being propagated, leaving focus wherever it is currently. That is
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // also bad. So we return false to let the default handler run, but take
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // focus first so as to trick it into thinking the view was already focused
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // and allowing the event to propagate.
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    gtk_widget_grab_focus(widget);
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *return_value = FALSE;
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return TRUE;
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Let the default WebContentsViewGtk::OnFocus() behaviour run.
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return FALSE;
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ChromeWebContentsViewDelegateGtk::ShowContextMenu(
1317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    const content::ContextMenuParams& params) {
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Find out the RenderWidgetHostView that corresponds to the render widget on
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // which this context menu is showed, so that we can retrieve the last mouse
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // down event on the render widget and use it as the timestamp of the
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // activation event to show the context menu.
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::RenderWidgetHostView* view = NULL;
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (params.custom_context.render_widget_id !=
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      content::CustomContextMenuContext::kCurrentRenderWidget) {
139eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    content::RenderWidgetHost* host = content::RenderWidgetHost::FromID(
140eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        web_contents_->GetRenderProcessHost()->GetID(),
141eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        params.custom_context.render_widget_id);
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!host) {
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NOTREACHED();
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return;
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    view = host->GetView();
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    view = web_contents_->GetRenderWidgetHostView();
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  context_menu_.reset(
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new RenderViewContextMenuGtk(web_contents_, params, view));
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  context_menu_->Init();
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Don't show empty menus.
1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (context_menu_->menu_model().GetItemCount() == 0)
1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Rect bounds;
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  web_contents_->GetView()->GetContainerBounds(&bounds);
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Point point = bounds.origin();
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  point.Offset(params.x, params.y);
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  context_menu_->Popup(point);
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)content::WebDragDestDelegate*
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ChromeWebContentsViewDelegateGtk::GetDragDestDelegate() {
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return bookmark_handler_gtk_.get();
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ChromeWebContentsViewDelegateGtk::OnSetFloatingPosition(
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GtkWidget* floating_container, GtkAllocation* allocation) {
1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!web_contents_modal_dialog_)
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Place each web contents modal dialog in the center of the view.
1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  GtkWidget* widget = web_contents_modal_dialog_;
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(gtk_widget_get_parent(widget) == floating_.get());
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GtkRequisition requisition;
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gtk_widget_size_request(widget, &requisition);
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GValue value = { 0, };
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  g_value_init(&value, G_TYPE_INT);
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int child_x = std::max((allocation->width - requisition.width) / 2, 0);
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  g_value_set_int(&value, child_x);
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gtk_container_child_set_property(GTK_CONTAINER(floating_container),
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   widget, "x", &value);
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int child_y = std::max((allocation->height - requisition.height) / 2, 0);
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  g_value_set_int(&value, child_y);
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gtk_container_child_set_property(GTK_CONTAINER(floating_container),
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   widget, "y", &value);
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  g_value_unset(&value);
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace chrome {
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)content::WebContentsViewDelegate* CreateWebContentsViewDelegate(
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    content::WebContents* web_contents) {
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return new ChromeWebContentsViewDelegateGtk(web_contents);
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace chrome
206