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 |