| 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 <gdk/gdkkeysyms.h> | 8 #include <gdk/gdkkeysyms.h> |
| 9 #include <gtk/gtk.h> | 9 #include <gtk/gtk.h> |
| 10 | 10 |
| 11 #include "app/gtk_dnd_util.h" | 11 #include "app/gtk_dnd_util.h" |
| 12 #include "base/gfx/point.h" | 12 #include "base/gfx/point.h" |
| 13 #include "base/gfx/rect.h" | 13 #include "base/gfx/rect.h" |
| 14 #include "base/gfx/size.h" | 14 #include "base/gfx/size.h" |
| 15 #include "base/pickle.h" | 15 #include "base/pickle.h" |
| 16 #include "base/string_util.h" | 16 #include "base/string_util.h" |
| 17 #include "build/build_config.h" | 17 #include "build/build_config.h" |
| 18 #include "chrome/browser/download/download_shelf.h" | 18 #include "chrome/browser/download/download_shelf.h" |
| 19 #include "chrome/browser/gtk/blocked_popup_container_view_gtk.h" | 19 #include "chrome/browser/gtk/blocked_popup_container_view_gtk.h" |
| 20 #include "chrome/browser/gtk/browser_window_gtk.h" | 20 #include "chrome/browser/gtk/browser_window_gtk.h" |
| 21 #include "chrome/browser/gtk/constrained_window_gtk.h" | 21 #include "chrome/browser/gtk/constrained_window_gtk.h" |
| 22 #include "chrome/browser/gtk/gtk_expanded_container.h" | |
| 23 #include "chrome/browser/gtk/gtk_floating_container.h" | 22 #include "chrome/browser/gtk/gtk_floating_container.h" |
| 24 #include "chrome/browser/gtk/gtk_theme_provider.h" | 23 #include "chrome/browser/gtk/gtk_theme_provider.h" |
| 25 #include "chrome/browser/gtk/sad_tab_gtk.h" | 24 #include "chrome/browser/gtk/sad_tab_gtk.h" |
| 26 #include "chrome/browser/gtk/tab_contents_drag_source.h" | 25 #include "chrome/browser/gtk/tab_contents_drag_source.h" |
| 27 #include "chrome/browser/renderer_host/render_view_host.h" | 26 #include "chrome/browser/renderer_host/render_view_host.h" |
| 28 #include "chrome/browser/renderer_host/render_view_host_factory.h" | 27 #include "chrome/browser/renderer_host/render_view_host_factory.h" |
| 29 #include "chrome/browser/renderer_host/render_widget_host_view_gtk.h" | 28 #include "chrome/browser/renderer_host/render_widget_host_view_gtk.h" |
| 30 #include "chrome/browser/tab_contents/interstitial_page.h" | 29 #include "chrome/browser/tab_contents/interstitial_page.h" |
| 31 #include "chrome/browser/tab_contents/render_view_context_menu_gtk.h" | 30 #include "chrome/browser/tab_contents/render_view_context_menu_gtk.h" |
| 32 #include "chrome/browser/tab_contents/tab_contents.h" | 31 #include "chrome/browser/tab_contents/tab_contents.h" |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 94 return TRUE; | 93 return TRUE; |
| 95 } else if (event->direction == GDK_SCROLL_UP) { | 94 } else if (event->direction == GDK_SCROLL_UP) { |
| 96 tab_contents->delegate()->ContentsZoomChange(true); | 95 tab_contents->delegate()->ContentsZoomChange(true); |
| 97 return TRUE; | 96 return TRUE; |
| 98 } | 97 } |
| 99 } | 98 } |
| 100 | 99 |
| 101 return FALSE; | 100 return FALSE; |
| 102 } | 101 } |
| 103 | 102 |
| 103 // Used with gtk_container_foreach to change the sizes of the children of |
| 104 // |fixed_|. |
| 105 void SetSizeRequest(GtkWidget* widget, gpointer userdata) { |
| 106 gfx::Size* size = static_cast<gfx::Size*>(userdata); |
| 107 if (widget->allocation.width != size->width() || |
| 108 widget->allocation.height != size->height()) { |
| 109 gtk_widget_set_size_request(widget, size->width(), size->height()); |
| 110 } |
| 111 } |
| 112 |
| 104 } // namespace | 113 } // namespace |
| 105 | 114 |
| 106 // static | 115 // static |
| 107 TabContentsView* TabContentsView::Create(TabContents* tab_contents) { | 116 TabContentsView* TabContentsView::Create(TabContents* tab_contents) { |
| 108 return new TabContentsViewGtk(tab_contents); | 117 return new TabContentsViewGtk(tab_contents); |
| 109 } | 118 } |
| 110 | 119 |
| 111 TabContentsViewGtk::TabContentsViewGtk(TabContents* tab_contents) | 120 TabContentsViewGtk::TabContentsViewGtk(TabContents* tab_contents) |
| 112 : TabContentsView(tab_contents), | 121 : TabContentsView(tab_contents), |
| 113 floating_(gtk_floating_container_new()), | 122 floating_(gtk_floating_container_new()), |
| 114 expanded_(gtk_expanded_container_new()), | 123 fixed_(gtk_fixed_new()), |
| 115 popup_view_(NULL) { | 124 popup_view_(NULL) { |
| 116 gtk_widget_set_name(expanded_, "chrome-tab-contents-view"); | 125 gtk_widget_set_name(fixed_, "chrome-tab-contents-view"); |
| 117 g_signal_connect(expanded_, "size-allocate", | 126 g_signal_connect(fixed_, "size-allocate", |
| 118 G_CALLBACK(OnSizeAllocate), this); | 127 G_CALLBACK(OnSizeAllocate), this); |
| 119 g_signal_connect(expanded_, "child-size-request", | |
| 120 G_CALLBACK(OnChildSizeRequest), this); | |
| 121 g_signal_connect(floating_.get(), "set-floating-position", | 128 g_signal_connect(floating_.get(), "set-floating-position", |
| 122 G_CALLBACK(OnSetFloatingPosition), this); | 129 G_CALLBACK(OnSetFloatingPosition), this); |
| 123 | 130 |
| 124 gtk_container_add(GTK_CONTAINER(floating_.get()), expanded_); | 131 gtk_container_add(GTK_CONTAINER(floating_.get()), fixed_); |
| 125 gtk_widget_show(expanded_); | 132 gtk_widget_show(fixed_); |
| 126 gtk_widget_show(floating_.get()); | 133 gtk_widget_show(floating_.get()); |
| 127 registrar_.Add(this, NotificationType::TAB_CONTENTS_CONNECTED, | 134 registrar_.Add(this, NotificationType::TAB_CONTENTS_CONNECTED, |
| 128 Source<TabContents>(tab_contents)); | 135 Source<TabContents>(tab_contents)); |
| 129 drag_source_.reset(new TabContentsDragSource(this)); | 136 drag_source_.reset(new TabContentsDragSource(this)); |
| 130 } | 137 } |
| 131 | 138 |
| 132 TabContentsViewGtk::~TabContentsViewGtk() { | 139 TabContentsViewGtk::~TabContentsViewGtk() { |
| 133 floating_.Destroy(); | 140 floating_.Destroy(); |
| 134 } | 141 } |
| 135 | 142 |
| (...skipping 29 matching lines...) Expand all Loading... |
| 165 constrained_window); | 172 constrained_window); |
| 166 DCHECK(item != constrained_windows_.end()); | 173 DCHECK(item != constrained_windows_.end()); |
| 167 | 174 |
| 168 gtk_container_remove(GTK_CONTAINER(floating_.get()), | 175 gtk_container_remove(GTK_CONTAINER(floating_.get()), |
| 169 constrained_window->widget()); | 176 constrained_window->widget()); |
| 170 constrained_windows_.erase(item); | 177 constrained_windows_.erase(item); |
| 171 } | 178 } |
| 172 | 179 |
| 173 void TabContentsViewGtk::CreateView(const gfx::Size& initial_size) { | 180 void TabContentsViewGtk::CreateView(const gfx::Size& initial_size) { |
| 174 requested_size_ = initial_size; | 181 requested_size_ = initial_size; |
| 182 gtk_widget_set_size_request(fixed_, requested_size_.width(), |
| 183 requested_size_.height()); |
| 175 } | 184 } |
| 176 | 185 |
| 177 RenderWidgetHostView* TabContentsViewGtk::CreateViewForWidget( | 186 RenderWidgetHostView* TabContentsViewGtk::CreateViewForWidget( |
| 178 RenderWidgetHost* render_widget_host) { | 187 RenderWidgetHost* render_widget_host) { |
| 179 if (render_widget_host->view()) { | 188 if (render_widget_host->view()) { |
| 180 // During testing, the view will already be set up in most cases to the | 189 // During testing, the view will already be set up in most cases to the |
| 181 // test view, so we don't want to clobber it with a real one. To verify that | 190 // test view, so we don't want to clobber it with a real one. To verify that |
| 182 // this actually is happening (and somebody isn't accidentally creating the | 191 // this actually is happening (and somebody isn't accidentally creating the |
| 183 // view twice), we check for the RVH Factory, which will be set when we're | 192 // view twice), we check for the RVH Factory, which will be set when we're |
| 184 // making special ones (which go along with the special views). | 193 // making special ones (which go along with the special views). |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 225 return window ? GTK_WINDOW(window) : NULL; | 234 return window ? GTK_WINDOW(window) : NULL; |
| 226 } | 235 } |
| 227 | 236 |
| 228 void TabContentsViewGtk::GetContainerBounds(gfx::Rect* out) const { | 237 void TabContentsViewGtk::GetContainerBounds(gfx::Rect* out) const { |
| 229 // This is used for positioning the download shelf arrow animation, | 238 // This is used for positioning the download shelf arrow animation, |
| 230 // as well as sizing some other widgets in Windows. In GTK the size is | 239 // as well as sizing some other widgets in Windows. In GTK the size is |
| 231 // managed for us, so it appears to be only used for the download shelf | 240 // managed for us, so it appears to be only used for the download shelf |
| 232 // animation. | 241 // animation. |
| 233 int x = 0; | 242 int x = 0; |
| 234 int y = 0; | 243 int y = 0; |
| 235 if (expanded_->window) | 244 if (fixed_->window) |
| 236 gdk_window_get_origin(expanded_->window, &x, &y); | 245 gdk_window_get_origin(fixed_->window, &x, &y); |
| 237 out->SetRect(x + expanded_->allocation.x, y + expanded_->allocation.y, | 246 out->SetRect(x + fixed_->allocation.x, y + fixed_->allocation.y, |
| 238 requested_size_.width(), requested_size_.height()); | 247 requested_size_.width(), requested_size_.height()); |
| 239 } | 248 } |
| 240 | 249 |
| 241 void TabContentsViewGtk::SetPageTitle(const std::wstring& title) { | 250 void TabContentsViewGtk::SetPageTitle(const std::wstring& title) { |
| 242 // Set the window name to include the page title so it's easier to spot | 251 // Set the window name to include the page title so it's easier to spot |
| 243 // when debugging (e.g. via xwininfo -tree). | 252 // when debugging (e.g. via xwininfo -tree). |
| 244 gfx::NativeView content_view = GetContentNativeView(); | 253 gfx::NativeView content_view = GetContentNativeView(); |
| 245 if (content_view && content_view->window) | 254 if (content_view && content_view->window) |
| 246 gdk_window_set_title(content_view->window, WideToUTF8(title).c_str()); | 255 gdk_window_set_title(content_view->window, WideToUTF8(title).c_str()); |
| 247 } | 256 } |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 344 WebDragOperationsMask ops) { | 353 WebDragOperationsMask ops) { |
| 345 DCHECK(GetContentNativeView()); | 354 DCHECK(GetContentNativeView()); |
| 346 | 355 |
| 347 drag_source_->StartDragging(drop_data, &last_mouse_down_); | 356 drag_source_->StartDragging(drop_data, &last_mouse_down_); |
| 348 // TODO(snej): Make use of the WebDragOperationsMask somehow | 357 // TODO(snej): Make use of the WebDragOperationsMask somehow |
| 349 } | 358 } |
| 350 | 359 |
| 351 // ----------------------------------------------------------------------------- | 360 // ----------------------------------------------------------------------------- |
| 352 | 361 |
| 353 void TabContentsViewGtk::InsertIntoContentArea(GtkWidget* widget) { | 362 void TabContentsViewGtk::InsertIntoContentArea(GtkWidget* widget) { |
| 354 gtk_container_add(GTK_CONTAINER(expanded_), widget); | 363 gtk_fixed_put(GTK_FIXED(fixed_), widget, 0, 0); |
| 355 } | 364 } |
| 356 | 365 |
| 357 gboolean TabContentsViewGtk::OnMouseDown(GtkWidget* widget, | 366 gboolean TabContentsViewGtk::OnMouseDown(GtkWidget* widget, |
| 358 GdkEventButton* event, TabContentsViewGtk* view) { | 367 GdkEventButton* event, TabContentsViewGtk* view) { |
| 359 view->last_mouse_down_ = *event; | 368 view->last_mouse_down_ = *event; |
| 360 return FALSE; | 369 return FALSE; |
| 361 } | 370 } |
| 362 | 371 |
| 363 void TabContentsViewGtk::OnChildSizeRequest(GtkWidget* widget, | 372 gboolean TabContentsViewGtk::OnSizeAllocate(GtkWidget* widget, |
| 364 GtkWidget* child, | 373 GtkAllocation* allocation, |
| 365 GtkRequisition* requisition, | |
| 366 TabContentsViewGtk* view) { | 374 TabContentsViewGtk* view) { |
| 367 if (view->tab_contents()->delegate()) { | |
| 368 requisition->height += | |
| 369 view->tab_contents()->delegate()->GetExtraRenderViewHeight(); | |
| 370 } | |
| 371 } | |
| 372 | |
| 373 void TabContentsViewGtk::OnSizeAllocate(GtkWidget* widget, | |
| 374 GtkAllocation* allocation, | |
| 375 TabContentsViewGtk* view) { | |
| 376 int width = allocation->width; | 375 int width = allocation->width; |
| 377 int height = allocation->height; | 376 int height = allocation->height; |
| 378 // |delegate()| can be NULL here during browser teardown. | 377 // |delegate()| can be NULL here during browser teardown. |
| 379 if (view->tab_contents()->delegate()) | 378 if (view->tab_contents()->delegate()) |
| 380 height += view->tab_contents()->delegate()->GetExtraRenderViewHeight(); | 379 height += view->tab_contents()->delegate()->GetExtraRenderViewHeight(); |
| 381 gfx::Size size(width, height); | 380 gfx::Size size(width, height); |
| 382 view->requested_size_ = size; | 381 view->requested_size_ = size; |
| 382 gtk_container_foreach(GTK_CONTAINER(widget), SetSizeRequest, &size); |
| 383 | 383 |
| 384 // We manually tell our RWHV to resize the renderer content. This avoids | 384 // We manually tell our RWHV to resize the renderer content. This avoids |
| 385 // spurious resizes from GTK+. | 385 // spurious resizes from GTK+. |
| 386 if (view->tab_contents()->render_widget_host_view()) | 386 if (view->tab_contents()->render_widget_host_view()) |
| 387 view->tab_contents()->render_widget_host_view()->SetSize(size); | 387 view->tab_contents()->render_widget_host_view()->SetSize(size); |
| 388 if (view->tab_contents()->interstitial_page()) | 388 if (view->tab_contents()->interstitial_page()) |
| 389 view->tab_contents()->interstitial_page()->SetSize(size); | 389 view->tab_contents()->interstitial_page()->SetSize(size); |
| 390 |
| 391 return FALSE; |
| 390 } | 392 } |
| 391 | 393 |
| 392 // static | 394 // static |
| 393 void TabContentsViewGtk::OnSetFloatingPosition( | 395 void TabContentsViewGtk::OnSetFloatingPosition( |
| 394 GtkFloatingContainer* floating_container, GtkAllocation* allocation, | 396 GtkFloatingContainer* floating_container, GtkAllocation* allocation, |
| 395 TabContentsViewGtk* tab_contents_view) { | 397 TabContentsViewGtk* tab_contents_view) { |
| 396 if (tab_contents_view->popup_view_) { | 398 if (tab_contents_view->popup_view_) { |
| 397 GtkWidget* widget = tab_contents_view->popup_view_->widget(); | 399 GtkWidget* widget = tab_contents_view->popup_view_->widget(); |
| 398 | 400 |
| 399 // Look at the size request of the status bubble and tell the | 401 // Look at the size request of the status bubble and tell the |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 441 gtk_container_child_set_property(GTK_CONTAINER(floating_container), | 443 gtk_container_child_set_property(GTK_CONTAINER(floating_container), |
| 442 widget, "x", &value); | 444 widget, "x", &value); |
| 443 | 445 |
| 444 int child_y = std::max(half_view_height - (requisition.height / 2), 0); | 446 int child_y = std::max(half_view_height - (requisition.height / 2), 0); |
| 445 g_value_set_int(&value, child_y); | 447 g_value_set_int(&value, child_y); |
| 446 gtk_container_child_set_property(GTK_CONTAINER(floating_container), | 448 gtk_container_child_set_property(GTK_CONTAINER(floating_container), |
| 447 widget, "y", &value); | 449 widget, "y", &value); |
| 448 g_value_unset(&value); | 450 g_value_unset(&value); |
| 449 } | 451 } |
| 450 } | 452 } |
| OLD | NEW |