| OLD | NEW |
| 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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/renderer_host/render_widget_host_view_views.h" | 5 #include "chrome/browser/renderer_host/render_widget_host_view_views.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <string> | 8 #include <string> |
| 9 | 9 |
| 10 #include "app/keyboard_code_conversion_gtk.h" | 10 #include "app/keyboard_code_conversion_gtk.h" |
| 11 #include "app/l10n_util.h" | 11 #include "app/l10n_util.h" |
| 12 #include "app/x11_util.h" | 12 #include "app/x11_util.h" |
| 13 #include "base/command_line.h" | 13 #include "base/command_line.h" |
| 14 #include "base/logging.h" | 14 #include "base/logging.h" |
| 15 #include "base/message_loop.h" | 15 #include "base/message_loop.h" |
| 16 #include "base/metrics/histogram.h" | 16 #include "base/metrics/histogram.h" |
| 17 #include "base/string_number_conversions.h" | 17 #include "base/string_number_conversions.h" |
| 18 #include "base/task.h" | 18 #include "base/task.h" |
| 19 #include "base/time.h" | 19 #include "base/time.h" |
| 20 #include "chrome/browser/renderer_host/backing_store_x.h" | 20 #include "chrome/browser/renderer_host/backing_store_x.h" |
| 21 #include "chrome/browser/renderer_host/render_widget_host.h" | 21 #include "chrome/browser/renderer_host/render_widget_host.h" |
| 22 #include "chrome/common/chrome_switches.h" | 22 #include "chrome/common/chrome_switches.h" |
| 23 #include "chrome/common/native_web_keyboard_event.h" | 23 #include "chrome/common/native_web_keyboard_event.h" |
| 24 #include "chrome/common/render_messages.h" | 24 #include "chrome/common/render_messages.h" |
| 25 #include "gfx/canvas.h" |
| 25 #include "third_party/WebKit/WebKit/chromium/public/gtk/WebInputEventFactory.h" | 26 #include "third_party/WebKit/WebKit/chromium/public/gtk/WebInputEventFactory.h" |
| 26 #include "third_party/WebKit/WebKit/chromium/public/WebInputEvent.h" | 27 #include "third_party/WebKit/WebKit/chromium/public/WebInputEvent.h" |
| 27 #include "views/event.h" | 28 #include "views/event.h" |
| 28 #include "views/widget/widget.h" | 29 #include "views/widget/widget.h" |
| 29 | 30 |
| 30 static const int kMaxWindowWidth = 4000; | 31 static const int kMaxWindowWidth = 4000; |
| 31 static const int kMaxWindowHeight = 4000; | 32 static const int kMaxWindowHeight = 4000; |
| 32 static const char* kRenderWidgetHostViewKey = "__RENDER_WIDGET_HOST_VIEW__"; | 33 static const char* kRenderWidgetHostViewKey = "__RENDER_WIDGET_HOST_VIEW__"; |
| 33 | 34 |
| 34 using WebKit::WebInputEventFactory; | 35 using WebKit::WebInputEventFactory; |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 130 GetRenderWidgetHost()->WasHidden(); | 131 GetRenderWidgetHost()->WasHidden(); |
| 131 } | 132 } |
| 132 | 133 |
| 133 void RenderWidgetHostViewViews::SetSize(const gfx::Size& size) { | 134 void RenderWidgetHostViewViews::SetSize(const gfx::Size& size) { |
| 134 // This is called when webkit has sent us a Move message. | 135 // This is called when webkit has sent us a Move message. |
| 135 int width = std::min(size.width(), kMaxWindowWidth); | 136 int width = std::min(size.width(), kMaxWindowWidth); |
| 136 int height = std::min(size.height(), kMaxWindowHeight); | 137 int height = std::min(size.height(), kMaxWindowHeight); |
| 137 if (requested_size_.width() != width || | 138 if (requested_size_.width() != width || |
| 138 requested_size_.height() != height) { | 139 requested_size_.height() != height) { |
| 139 requested_size_ = gfx::Size(width, height); | 140 requested_size_ = gfx::Size(width, height); |
| 140 SetBounds(x(), y(), requested_size_.width(), requested_size_.height()); | 141 SetBounds(gfx::Rect(x(), y(), width, height)); |
| 141 host_->WasResized(); | 142 host_->WasResized(); |
| 142 } | 143 } |
| 143 } | 144 } |
| 144 | 145 |
| 145 void RenderWidgetHostViewViews::MovePluginWindows( | 146 void RenderWidgetHostViewViews::MovePluginWindows( |
| 146 const std::vector<webkit_glue::WebPluginGeometry>& moves) { | 147 const std::vector<webkit_glue::WebPluginGeometry>& moves) { |
| 147 // TODO(anicolao): NIY | 148 // TODO(anicolao): NIY |
| 148 NOTIMPLEMENTED(); | 149 NOTIMPLEMENTED(); |
| 149 } | 150 } |
| 150 | 151 |
| (...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 272 } | 273 } |
| 273 | 274 |
| 274 BackingStore* RenderWidgetHostViewViews::AllocBackingStore( | 275 BackingStore* RenderWidgetHostViewViews::AllocBackingStore( |
| 275 const gfx::Size& size) { | 276 const gfx::Size& size) { |
| 276 return new BackingStoreX(host_, size, | 277 return new BackingStoreX(host_, size, |
| 277 x11_util::GetVisualFromGtkWidget(native_view()), | 278 x11_util::GetVisualFromGtkWidget(native_view()), |
| 278 gtk_widget_get_visual(native_view())->depth); | 279 gtk_widget_get_visual(native_view())->depth); |
| 279 } | 280 } |
| 280 | 281 |
| 281 gfx::NativeView RenderWidgetHostViewViews::native_view() const { | 282 gfx::NativeView RenderWidgetHostViewViews::native_view() const { |
| 282 return GetWidget()->GetNativeView(); | 283 if (GetWidget()) |
| 284 return GetWidget()->GetNativeView(); |
| 285 return NULL; |
| 283 } | 286 } |
| 284 | 287 |
| 285 void RenderWidgetHostViewViews::SetBackground(const SkBitmap& background) { | 288 void RenderWidgetHostViewViews::SetBackground(const SkBitmap& background) { |
| 286 RenderWidgetHostView::SetBackground(background); | 289 RenderWidgetHostView::SetBackground(background); |
| 287 host_->Send(new ViewMsg_SetBackground(host_->routing_id(), background)); | 290 host_->Send(new ViewMsg_SetBackground(host_->routing_id(), background)); |
| 288 } | 291 } |
| 289 | 292 |
| 290 void RenderWidgetHostViewViews::Paint(gfx::Canvas* canvas) { | 293 void RenderWidgetHostViewViews::Paint(gfx::Canvas* canvas) { |
| 294 if (is_hidden_) { |
| 295 return; |
| 296 } |
| 297 |
| 298 // Paint a "hole" in the canvas so that the render of the web page is on |
| 299 // top of whatever else has already been painted in the views hierarchy. |
| 300 // Later views might still get to paint on top. |
| 301 canvas->FillRectInt(SK_ColorBLACK, 0, 0, kMaxWindowWidth, kMaxWindowHeight, |
| 302 SkXfermode::kClear_Mode); |
| 303 |
| 291 // Don't do any painting if the GPU process is rendering directly | 304 // Don't do any painting if the GPU process is rendering directly |
| 292 // into the View. | 305 // into the View. |
| 293 RenderWidgetHost* render_widget_host = GetRenderWidgetHost(); | 306 RenderWidgetHost* render_widget_host = GetRenderWidgetHost(); |
| 294 if (render_widget_host->is_gpu_rendering_active()) { | 307 if (render_widget_host->is_gpu_rendering_active()) { |
| 295 return; | 308 return; |
| 296 } | 309 } |
| 297 | 310 |
| 298 GdkWindow* window = native_view()->window; | 311 GdkWindow* window = native_view()->window; |
| 299 DCHECK(!about_to_validate_and_paint_); | 312 DCHECK(!about_to_validate_and_paint_); |
| 300 | 313 |
| 301 // TODO(anicolao): get the damage somehow | 314 // TODO(anicolao): get the damage somehow |
| 302 // invalid_rect_ = damage_rect; | 315 // invalid_rect_ = damage_rect; |
| 303 invalid_rect_ = bounds(); | 316 invalid_rect_ = bounds(); |
| 317 gfx::Point origin; |
| 318 ConvertPointToWidget(this, &origin); |
| 319 |
| 304 about_to_validate_and_paint_ = true; | 320 about_to_validate_and_paint_ = true; |
| 305 BackingStoreX* backing_store = static_cast<BackingStoreX*>( | 321 BackingStoreX* backing_store = static_cast<BackingStoreX*>( |
| 306 host_->GetBackingStore(true)); | 322 host_->GetBackingStore(true)); |
| 307 // Calling GetBackingStore maybe have changed |invalid_rect_|... | 323 // Calling GetBackingStore maybe have changed |invalid_rect_|... |
| 308 about_to_validate_and_paint_ = false; | 324 about_to_validate_and_paint_ = false; |
| 309 | 325 |
| 310 gfx::Rect paint_rect = gfx::Rect(0, 0, kMaxWindowWidth, kMaxWindowHeight); | 326 gfx::Rect paint_rect = gfx::Rect(0, 0, kMaxWindowWidth, kMaxWindowHeight); |
| 311 paint_rect = paint_rect.Intersect(invalid_rect_); | 327 paint_rect = paint_rect.Intersect(invalid_rect_); |
| 312 | 328 |
| 313 if (backing_store) { | 329 if (backing_store) { |
| 314 // Only render the widget if it is attached to a window; there's a short | 330 // Only render the widget if it is attached to a window; there's a short |
| 315 // period where this object isn't attached to a window but hasn't been | 331 // period where this object isn't attached to a window but hasn't been |
| 316 // Destroy()ed yet and it receives paint messages... | 332 // Destroy()ed yet and it receives paint messages... |
| 317 if (window) { | 333 if (window) { |
| 318 if (!visually_deemphasized_) { | 334 if (!visually_deemphasized_) { |
| 319 // In the common case, use XCopyArea. We don't draw more than once, so | 335 // In the common case, use XCopyArea. We don't draw more than once, so |
| 320 // we don't need to double buffer. | 336 // we don't need to double buffer. |
| 321 backing_store->XShowRect( | 337 backing_store->XShowRect(origin, |
| 322 paint_rect, x11_util::GetX11WindowFromGtkWidget(native_view())); | 338 paint_rect, x11_util::GetX11WindowFromGtkWidget(native_view())); |
| 323 } else { | 339 } else { |
| 324 // If the grey blend is showing, we make two drawing calls. Use double | 340 // If the grey blend is showing, we make two drawing calls. Use double |
| 325 // buffering to prevent flicker. Use CairoShowRect because XShowRect | 341 // buffering to prevent flicker. Use CairoShowRect because XShowRect |
| 326 // shortcuts GDK's double buffering. | 342 // shortcuts GDK's double buffering. |
| 327 GdkRectangle rect = { paint_rect.x(), paint_rect.y(), | 343 GdkRectangle rect = { paint_rect.x(), paint_rect.y(), |
| 328 paint_rect.width(), paint_rect.height() }; | 344 paint_rect.width(), paint_rect.height() }; |
| 329 gdk_window_begin_paint_rect(window, &rect); | 345 gdk_window_begin_paint_rect(window, &rect); |
| 330 | 346 |
| 331 backing_store->CairoShowRect(paint_rect, GDK_DRAWABLE(window)); | 347 backing_store->CairoShowRect(paint_rect, GDK_DRAWABLE(window)); |
| (...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 493 } | 509 } |
| 494 #endif | 510 #endif |
| 495 | 511 |
| 496 ShowCurrentCursor(); | 512 ShowCurrentCursor(); |
| 497 GetRenderWidgetHost()->GotFocus(); | 513 GetRenderWidgetHost()->GotFocus(); |
| 498 } | 514 } |
| 499 | 515 |
| 500 void RenderWidgetHostViewViews::WillLoseFocus() { | 516 void RenderWidgetHostViewViews::WillLoseFocus() { |
| 501 // If we are showing a context menu, maintain the illusion that webkit has | 517 // If we are showing a context menu, maintain the illusion that webkit has |
| 502 // focus. | 518 // focus. |
| 503 if (!is_showing_context_menu_) | 519 if (!is_showing_context_menu_ && !is_hidden_) |
| 504 GetRenderWidgetHost()->Blur(); | 520 GetRenderWidgetHost()->Blur(); |
| 505 } | 521 } |
| 506 | 522 |
| 507 | 523 |
| 508 void RenderWidgetHostViewViews::ShowCurrentCursor() { | 524 void RenderWidgetHostViewViews::ShowCurrentCursor() { |
| 509 // The widget may not have a window. If that's the case, abort mission. This | 525 // The widget may not have a window. If that's the case, abort mission. This |
| 510 // is the same issue as that explained above in Paint(). | 526 // is the same issue as that explained above in Paint(). |
| 511 if (!native_view()->window) | 527 if (!native_view() || !native_view()->window) |
| 512 return; | 528 return; |
| 513 | 529 |
| 514 // TODO(anicolao): change to set cursors without GTK | 530 // TODO(anicolao): change to set cursors without GTK |
| 515 } | 531 } |
| 516 | 532 |
| 517 void RenderWidgetHostViewViews::CreatePluginContainer( | 533 void RenderWidgetHostViewViews::CreatePluginContainer( |
| 518 gfx::PluginWindowHandle id) { | 534 gfx::PluginWindowHandle id) { |
| 519 // TODO(anicolao): plugin_container_manager_.CreatePluginContainer(id); | 535 // TODO(anicolao): plugin_container_manager_.CreatePluginContainer(id); |
| 520 } | 536 } |
| 521 | 537 |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 576 } | 592 } |
| 577 | 593 |
| 578 // static | 594 // static |
| 579 RenderWidgetHostView* | 595 RenderWidgetHostView* |
| 580 RenderWidgetHostView::GetRenderWidgetHostViewFromNativeView( | 596 RenderWidgetHostView::GetRenderWidgetHostViewFromNativeView( |
| 581 gfx::NativeView widget) { | 597 gfx::NativeView widget) { |
| 582 gpointer user_data = g_object_get_data(G_OBJECT(widget), | 598 gpointer user_data = g_object_get_data(G_OBJECT(widget), |
| 583 kRenderWidgetHostViewKey); | 599 kRenderWidgetHostViewKey); |
| 584 return reinterpret_cast<RenderWidgetHostView*>(user_data); | 600 return reinterpret_cast<RenderWidgetHostView*>(user_data); |
| 585 } | 601 } |
| OLD | NEW |