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