| OLD | NEW |
| 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/tab_contents/tab_contents_view_gtk.h" | 5 #include "chrome/browser/tab_contents/tab_contents_view_gtk.h" |
| 6 | 6 |
| 7 #include <gdk/gdk.h> | 7 #include <gdk/gdk.h> |
| 8 #include <gtk/gtk.h> | 8 #include <gtk/gtk.h> |
| 9 | 9 |
| 10 #include "base/string_util.h" | 10 #include "base/string_util.h" |
| 11 #include "base/gfx/point.h" | 11 #include "base/gfx/point.h" |
| 12 #include "base/gfx/rect.h" | 12 #include "base/gfx/rect.h" |
| 13 #include "base/gfx/size.h" | 13 #include "base/gfx/size.h" |
| 14 #include "build/build_config.h" | 14 #include "build/build_config.h" |
| 15 #include "chrome/browser/download/download_shelf.h" | 15 #include "chrome/browser/download/download_shelf.h" |
| 16 #include "chrome/browser/gtk/blocked_popup_container_view_gtk.h" |
| 16 #include "chrome/browser/gtk/browser_window_gtk.h" | 17 #include "chrome/browser/gtk/browser_window_gtk.h" |
| 18 #include "chrome/browser/gtk/gtk_floating_container.h" |
| 17 #include "chrome/browser/gtk/sad_tab_gtk.h" | 19 #include "chrome/browser/gtk/sad_tab_gtk.h" |
| 18 #include "chrome/browser/renderer_host/render_view_host.h" | 20 #include "chrome/browser/renderer_host/render_view_host.h" |
| 19 #include "chrome/browser/renderer_host/render_view_host_factory.h" | 21 #include "chrome/browser/renderer_host/render_view_host_factory.h" |
| 20 #include "chrome/browser/renderer_host/render_widget_host_view_gtk.h" | 22 #include "chrome/browser/renderer_host/render_widget_host_view_gtk.h" |
| 21 #include "chrome/browser/tab_contents/interstitial_page.h" | 23 #include "chrome/browser/tab_contents/interstitial_page.h" |
| 22 #include "chrome/browser/tab_contents/render_view_context_menu_gtk.h" | 24 #include "chrome/browser/tab_contents/render_view_context_menu_gtk.h" |
| 23 #include "chrome/browser/tab_contents/tab_contents.h" | 25 #include "chrome/browser/tab_contents/tab_contents.h" |
| 24 #include "chrome/browser/tab_contents/tab_contents_delegate.h" | 26 #include "chrome/browser/tab_contents/tab_contents_delegate.h" |
| 25 #include "chrome/common/gtk_util.h" | 27 #include "chrome/common/gtk_util.h" |
| 26 #include "chrome/common/notification_source.h" | 28 #include "chrome/common/notification_source.h" |
| 27 #include "chrome/common/notification_type.h" | 29 #include "chrome/common/notification_type.h" |
| 28 | 30 |
| 29 namespace { | 31 namespace { |
| 30 | 32 |
| 33 // TODO(erg): I have no idea how to progromatically figure out how wide the |
| 34 // vertical scrollbar is. Hack it with a hardcoded value for now. |
| 35 const int kScrollbarWidthHack = 25; |
| 36 |
| 31 // Called when the content view gtk widget is tabbed to, or after the call to | 37 // Called when the content view gtk widget is tabbed to, or after the call to |
| 32 // gtk_widget_child_focus() in TakeFocus(). We return true | 38 // gtk_widget_child_focus() in TakeFocus(). We return true |
| 33 // and grab focus if we don't have it. The call to | 39 // and grab focus if we don't have it. The call to |
| 34 // FocusThroughTabTraversal(bool) forwards the "move focus forward" effect to | 40 // FocusThroughTabTraversal(bool) forwards the "move focus forward" effect to |
| 35 // webkit. | 41 // webkit. |
| 36 gboolean OnFocus(GtkWidget* widget, GtkDirectionType focus, | 42 gboolean OnFocus(GtkWidget* widget, GtkDirectionType focus, |
| 37 TabContents* tab_contents) { | 43 TabContents* tab_contents) { |
| 38 // If we already have focus, let the next widget have a shot at it. We will | 44 // If we already have focus, let the next widget have a shot at it. We will |
| 39 // reach this situation after the call to gtk_widget_child_focus() in | 45 // reach this situation after the call to gtk_widget_child_focus() in |
| 40 // TakeFocus(). | 46 // TakeFocus(). |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 92 | 98 |
| 93 } // namespace | 99 } // namespace |
| 94 | 100 |
| 95 // static | 101 // static |
| 96 TabContentsView* TabContentsView::Create(TabContents* tab_contents) { | 102 TabContentsView* TabContentsView::Create(TabContents* tab_contents) { |
| 97 return new TabContentsViewGtk(tab_contents); | 103 return new TabContentsViewGtk(tab_contents); |
| 98 } | 104 } |
| 99 | 105 |
| 100 TabContentsViewGtk::TabContentsViewGtk(TabContents* tab_contents) | 106 TabContentsViewGtk::TabContentsViewGtk(TabContents* tab_contents) |
| 101 : TabContentsView(tab_contents), | 107 : TabContentsView(tab_contents), |
| 102 fixed_(gtk_fixed_new()) { | 108 floating_(gtk_floating_container_new()), |
| 103 g_signal_connect(fixed_.get(), "size-allocate", | 109 fixed_(gtk_fixed_new()), |
| 110 popup_view_(NULL) { |
| 111 g_signal_connect(fixed_, "size-allocate", |
| 104 G_CALLBACK(OnSizeAllocate), this); | 112 G_CALLBACK(OnSizeAllocate), this); |
| 105 gtk_widget_show(fixed_.get()); | 113 g_signal_connect(floating_.get(), "set-floating-position", |
| 114 G_CALLBACK(OnSetFloatingPosition), this); |
| 115 |
| 116 gtk_container_add(GTK_CONTAINER(floating_.get()), fixed_); |
| 117 gtk_widget_show(fixed_); |
| 118 gtk_widget_show(floating_.get()); |
| 106 registrar_.Add(this, NotificationType::TAB_CONTENTS_CONNECTED, | 119 registrar_.Add(this, NotificationType::TAB_CONTENTS_CONNECTED, |
| 107 Source<TabContents>(tab_contents)); | 120 Source<TabContents>(tab_contents)); |
| 108 } | 121 } |
| 109 | 122 |
| 110 TabContentsViewGtk::~TabContentsViewGtk() { | 123 TabContentsViewGtk::~TabContentsViewGtk() { |
| 111 fixed_.Destroy(); | 124 floating_.Destroy(); |
| 125 } |
| 126 |
| 127 void TabContentsViewGtk::AttachBlockedPopupView( |
| 128 BlockedPopupContainerViewGtk* popup_view) { |
| 129 DCHECK(popup_view_ == NULL); |
| 130 popup_view_ = popup_view; |
| 131 gtk_floating_container_add_floating(GTK_FLOATING_CONTAINER(floating_.get()), |
| 132 popup_view->widget()); |
| 133 } |
| 134 |
| 135 void TabContentsViewGtk::RemoveBlockedPopupView( |
| 136 BlockedPopupContainerViewGtk* popup_view) { |
| 137 DCHECK(popup_view_ == popup_view); |
| 138 gtk_container_remove(GTK_CONTAINER(floating_.get()), popup_view->widget()); |
| 139 popup_view_ = NULL; |
| 112 } | 140 } |
| 113 | 141 |
| 114 void TabContentsViewGtk::CreateView() { | 142 void TabContentsViewGtk::CreateView() { |
| 115 // Windows uses this to do initialization, but we do all our initialization | 143 // Windows uses this to do initialization, but we do all our initialization |
| 116 // in the constructor. | 144 // in the constructor. |
| 117 } | 145 } |
| 118 | 146 |
| 119 RenderWidgetHostView* TabContentsViewGtk::CreateViewForWidget( | 147 RenderWidgetHostView* TabContentsViewGtk::CreateViewForWidget( |
| 120 RenderWidgetHost* render_widget_host) { | 148 RenderWidgetHost* render_widget_host) { |
| 121 if (render_widget_host->view()) { | 149 if (render_widget_host->view()) { |
| (...skipping 21 matching lines...) Expand all Loading... |
| 143 gtk_widget_add_events(content_view, GDK_LEAVE_NOTIFY_MASK | | 171 gtk_widget_add_events(content_view, GDK_LEAVE_NOTIFY_MASK | |
| 144 GDK_POINTER_MOTION_MASK); | 172 GDK_POINTER_MOTION_MASK); |
| 145 g_signal_connect(content_view, "button-press-event", | 173 g_signal_connect(content_view, "button-press-event", |
| 146 G_CALLBACK(OnMouseDown), this); | 174 G_CALLBACK(OnMouseDown), this); |
| 147 | 175 |
| 148 InsertIntoContentArea(content_view); | 176 InsertIntoContentArea(content_view); |
| 149 return view; | 177 return view; |
| 150 } | 178 } |
| 151 | 179 |
| 152 gfx::NativeView TabContentsViewGtk::GetNativeView() const { | 180 gfx::NativeView TabContentsViewGtk::GetNativeView() const { |
| 153 return fixed_.get(); | 181 return floating_.get(); |
| 154 } | 182 } |
| 155 | 183 |
| 156 gfx::NativeView TabContentsViewGtk::GetContentNativeView() const { | 184 gfx::NativeView TabContentsViewGtk::GetContentNativeView() const { |
| 157 if (!tab_contents()->render_widget_host_view()) | 185 if (!tab_contents()->render_widget_host_view()) |
| 158 return NULL; | 186 return NULL; |
| 159 return tab_contents()->render_widget_host_view()->GetNativeView(); | 187 return tab_contents()->render_widget_host_view()->GetNativeView(); |
| 160 } | 188 } |
| 161 | 189 |
| 162 | 190 |
| 163 gfx::NativeWindow TabContentsViewGtk::GetTopLevelNativeWindow() const { | 191 gfx::NativeWindow TabContentsViewGtk::GetTopLevelNativeWindow() const { |
| 164 GtkWidget* window = gtk_widget_get_ancestor(GetNativeView(), GTK_TYPE_WINDOW); | 192 GtkWidget* window = gtk_widget_get_ancestor(GetNativeView(), GTK_TYPE_WINDOW); |
| 165 return window ? GTK_WINDOW(window) : NULL; | 193 return window ? GTK_WINDOW(window) : NULL; |
| 166 } | 194 } |
| 167 | 195 |
| 168 void TabContentsViewGtk::GetContainerBounds(gfx::Rect* out) const { | 196 void TabContentsViewGtk::GetContainerBounds(gfx::Rect* out) const { |
| 169 // This is used for positioning the download shelf arrow animation, | 197 // This is used for positioning the download shelf arrow animation, |
| 170 // as well as sizing some other widgets in Windows. In GTK the size is | 198 // as well as sizing some other widgets in Windows. In GTK the size is |
| 171 // managed for us, so it appears to be only used for the download shelf | 199 // managed for us, so it appears to be only used for the download shelf |
| 172 // animation. | 200 // animation. |
| 173 int x = 0; | 201 int x = 0; |
| 174 int y = 0; | 202 int y = 0; |
| 175 if (fixed_.get()->window) | 203 if (fixed_->window) |
| 176 gdk_window_get_origin(fixed_.get()->window, &x, &y); | 204 gdk_window_get_origin(fixed_->window, &x, &y); |
| 177 out->SetRect(x + fixed_.get()->allocation.x, y + fixed_.get()->allocation.y, | 205 out->SetRect(x + fixed_->allocation.x, y + fixed_->allocation.y, |
| 178 fixed_.get()->allocation.width, fixed_.get()->allocation.height); | 206 fixed_->allocation.width, fixed_->allocation.height); |
| 179 } | 207 } |
| 180 | 208 |
| 181 void TabContentsViewGtk::OnContentsDestroy() { | 209 void TabContentsViewGtk::OnContentsDestroy() { |
| 182 // TODO(estade): Windows uses this function cancel pending drag-n-drop drags. | 210 // TODO(estade): Windows uses this function cancel pending drag-n-drop drags. |
| 183 // We don't have drags yet, so do nothing for now. | 211 // We don't have drags yet, so do nothing for now. |
| 184 } | 212 } |
| 185 | 213 |
| 186 void TabContentsViewGtk::SetPageTitle(const std::wstring& title) { | 214 void TabContentsViewGtk::SetPageTitle(const std::wstring& title) { |
| 187 // Set the window name to include the page title so it's easier to spot | 215 // Set the window name to include the page title so it's easier to spot |
| 188 // when debugging (e.g. via xwininfo -tree). | 216 // when debugging (e.g. via xwininfo -tree). |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 292 | 320 |
| 293 // Until we have d'n'd implemented, just immediately pretend we're | 321 // Until we have d'n'd implemented, just immediately pretend we're |
| 294 // already done with the drag and drop so we don't get stuck | 322 // already done with the drag and drop so we don't get stuck |
| 295 // thinking we're in mid-drag. | 323 // thinking we're in mid-drag. |
| 296 // TODO(port): remove me when the above NOTIMPLEMENTED is fixed. | 324 // TODO(port): remove me when the above NOTIMPLEMENTED is fixed. |
| 297 if (tab_contents()->render_view_host()) | 325 if (tab_contents()->render_view_host()) |
| 298 tab_contents()->render_view_host()->DragSourceSystemDragEnded(); | 326 tab_contents()->render_view_host()->DragSourceSystemDragEnded(); |
| 299 } | 327 } |
| 300 | 328 |
| 301 void TabContentsViewGtk::InsertIntoContentArea(GtkWidget* widget) { | 329 void TabContentsViewGtk::InsertIntoContentArea(GtkWidget* widget) { |
| 302 gtk_fixed_put(GTK_FIXED(fixed_.get()), widget, 0, 0); | 330 gtk_fixed_put(GTK_FIXED(fixed_), widget, 0, 0); |
| 303 } | 331 } |
| 304 | 332 |
| 305 gboolean TabContentsViewGtk::OnMouseDown(GtkWidget* widget, | 333 gboolean TabContentsViewGtk::OnMouseDown(GtkWidget* widget, |
| 306 GdkEventButton* event, TabContentsViewGtk* view) { | 334 GdkEventButton* event, TabContentsViewGtk* view) { |
| 307 view->last_mouse_down_time_ = event->time; | 335 view->last_mouse_down_time_ = event->time; |
| 308 return FALSE; | 336 return FALSE; |
| 309 } | 337 } |
| 310 | 338 |
| 311 gboolean TabContentsViewGtk::OnSizeAllocate(GtkWidget* widget, | 339 gboolean TabContentsViewGtk::OnSizeAllocate(GtkWidget* widget, |
| 312 GtkAllocation* allocation, | 340 GtkAllocation* allocation, |
| 313 TabContentsViewGtk* view) { | 341 TabContentsViewGtk* view) { |
| 314 int width = allocation->width; | 342 int width = allocation->width; |
| 315 int height = allocation->height; | 343 int height = allocation->height; |
| 316 // |delegate()| can be NULL here during browser teardown. | 344 // |delegate()| can be NULL here during browser teardown. |
| 317 if (view->tab_contents()->delegate()) | 345 if (view->tab_contents()->delegate()) |
| 318 height += view->tab_contents()->delegate()->GetExtraRenderViewHeight(); | 346 height += view->tab_contents()->delegate()->GetExtraRenderViewHeight(); |
| 319 gfx::Size size(width, height); | 347 gfx::Size size(width, height); |
| 320 gtk_container_foreach(GTK_CONTAINER(widget), SetSizeRequest, &size); | 348 gtk_container_foreach(GTK_CONTAINER(widget), SetSizeRequest, &size); |
| 321 | 349 |
| 322 return FALSE; | 350 return FALSE; |
| 323 } | 351 } |
| 352 |
| 353 // static |
| 354 void TabContentsViewGtk::OnSetFloatingPosition( |
| 355 GtkFloatingContainer* floating_container, GtkAllocation* allocation, |
| 356 TabContentsViewGtk* tab_contents_view) { |
| 357 if (tab_contents_view->popup_view_) { |
| 358 GtkWidget* widget = tab_contents_view->popup_view_->widget(); |
| 359 |
| 360 // Look at the size request of the status bubble and tell the |
| 361 // GtkFloatingContainer where we want it positioned. |
| 362 GtkRequisition requisition; |
| 363 gtk_widget_size_request(widget, &requisition); |
| 364 |
| 365 GValue value = { 0, }; |
| 366 g_value_init(&value, G_TYPE_INT); |
| 367 |
| 368 int child_x = std::max( |
| 369 allocation->x + allocation->width - requisition.width - |
| 370 kScrollbarWidthHack, 0); |
| 371 g_value_set_int(&value, child_x); |
| 372 gtk_container_child_set_property(GTK_CONTAINER(floating_container), |
| 373 widget, "x", &value); |
| 374 |
| 375 int child_y = std::max( |
| 376 allocation->y + allocation->height - requisition.height, 0); |
| 377 g_value_set_int(&value, child_y); |
| 378 gtk_container_child_set_property(GTK_CONTAINER(floating_container), |
| 379 widget, "y", &value); |
| 380 g_value_unset(&value); |
| 381 } |
| 382 } |
| OLD | NEW |