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