| 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_gtk.h" | 5 #include "chrome/browser/renderer_host/render_widget_host_view_gtk.h" |
| 6 | 6 |
| 7 // If this gets included after the gtk headers, then a bunch of compiler | 7 // If this gets included after the gtk headers, then a bunch of compiler |
| 8 // errors happen because of a "#define Status int" in Xlib.h, which interacts | 8 // errors happen because of a "#define Status int" in Xlib.h, which interacts |
| 9 // badly with URLRequestStatus::Status. | 9 // badly with URLRequestStatus::Status. |
| 10 #include "chrome/common/render_messages.h" | 10 #include "chrome/common/render_messages.h" |
| (...skipping 11 matching lines...) Expand all Loading... |
| 22 #include "app/x11_util.h" | 22 #include "app/x11_util.h" |
| 23 #include "base/command_line.h" | 23 #include "base/command_line.h" |
| 24 #include "base/logging.h" | 24 #include "base/logging.h" |
| 25 #include "base/message_loop.h" | 25 #include "base/message_loop.h" |
| 26 #include "base/metrics/histogram.h" | 26 #include "base/metrics/histogram.h" |
| 27 #include "base/string_number_conversions.h" | 27 #include "base/string_number_conversions.h" |
| 28 #include "base/time.h" | 28 #include "base/time.h" |
| 29 #include "base/utf_string_conversions.h" | 29 #include "base/utf_string_conversions.h" |
| 30 #include "chrome/browser/gtk/gtk_util.h" | 30 #include "chrome/browser/gtk/gtk_util.h" |
| 31 #include "chrome/browser/renderer_host/backing_store_x.h" | 31 #include "chrome/browser/renderer_host/backing_store_x.h" |
| 32 #include "chrome/browser/renderer_host/gpu_view_host.h" | |
| 33 #include "chrome/browser/renderer_host/gtk_im_context_wrapper.h" | 32 #include "chrome/browser/renderer_host/gtk_im_context_wrapper.h" |
| 34 #include "chrome/browser/renderer_host/gtk_key_bindings_handler.h" | 33 #include "chrome/browser/renderer_host/gtk_key_bindings_handler.h" |
| 35 #include "chrome/browser/renderer_host/render_view_host.h" | 34 #include "chrome/browser/renderer_host/render_view_host.h" |
| 36 #include "chrome/browser/renderer_host/render_view_host_delegate.h" | 35 #include "chrome/browser/renderer_host/render_view_host_delegate.h" |
| 37 #include "chrome/browser/renderer_host/render_widget_host.h" | 36 #include "chrome/browser/renderer_host/render_widget_host.h" |
| 38 #include "chrome/browser/renderer_host/video_layer_x.h" | |
| 39 #include "chrome/common/chrome_switches.h" | 37 #include "chrome/common/chrome_switches.h" |
| 40 #include "chrome/common/native_web_keyboard_event.h" | 38 #include "chrome/common/native_web_keyboard_event.h" |
| 41 #include "gfx/gtk_preserve_window.h" | 39 #include "gfx/gtk_preserve_window.h" |
| 42 #include "third_party/WebKit/WebKit/chromium/public/gtk/WebInputEventFactory.h" | 40 #include "third_party/WebKit/WebKit/chromium/public/gtk/WebInputEventFactory.h" |
| 43 #include "webkit/glue/plugins/webplugin.h" | 41 #include "webkit/glue/plugins/webplugin.h" |
| 44 #include "webkit/glue/webaccessibility.h" | 42 #include "webkit/glue/webaccessibility.h" |
| 45 #include "webkit/glue/webcursor_gtk_data.h" | 43 #include "webkit/glue/webcursor_gtk_data.h" |
| 46 | 44 |
| 47 #if defined(OS_CHROMEOS) | 45 #if defined(OS_CHROMEOS) |
| 48 #include "views/widget/tooltip_window_gtk.h" | 46 #include "views/widget/tooltip_window_gtk.h" |
| (...skipping 418 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 467 }; | 465 }; |
| 468 | 466 |
| 469 // static | 467 // static |
| 470 RenderWidgetHostView* RenderWidgetHostView::CreateViewForWidget( | 468 RenderWidgetHostView* RenderWidgetHostView::CreateViewForWidget( |
| 471 RenderWidgetHost* widget) { | 469 RenderWidgetHost* widget) { |
| 472 return new RenderWidgetHostViewGtk(widget); | 470 return new RenderWidgetHostViewGtk(widget); |
| 473 } | 471 } |
| 474 | 472 |
| 475 RenderWidgetHostViewGtk::RenderWidgetHostViewGtk(RenderWidgetHost* widget_host) | 473 RenderWidgetHostViewGtk::RenderWidgetHostViewGtk(RenderWidgetHost* widget_host) |
| 476 : host_(widget_host), | 474 : host_(widget_host), |
| 477 enable_gpu_rendering_(false), | |
| 478 about_to_validate_and_paint_(false), | 475 about_to_validate_and_paint_(false), |
| 479 is_hidden_(false), | 476 is_hidden_(false), |
| 480 is_loading_(false), | 477 is_loading_(false), |
| 481 is_showing_context_menu_(false), | 478 is_showing_context_menu_(false), |
| 482 visually_deemphasized_(false), | 479 visually_deemphasized_(false), |
| 483 parent_host_view_(NULL), | 480 parent_host_view_(NULL), |
| 484 parent_(NULL), | 481 parent_(NULL), |
| 485 is_popup_first_mouse_release_(true), | 482 is_popup_first_mouse_release_(true), |
| 486 was_focused_before_grab_(false), | 483 was_focused_before_grab_(false), |
| 487 do_x_grab_(false), | 484 do_x_grab_(false), |
| 488 dragged_at_horizontal_edge_(0), | 485 dragged_at_horizontal_edge_(0), |
| 489 dragged_at_vertical_edge_(0) { | 486 dragged_at_vertical_edge_(0) { |
| 490 host_->set_view(this); | 487 host_->set_view(this); |
| 491 | |
| 492 // Enable experimental out-of-process GPU rendering. | |
| 493 CommandLine* command_line = CommandLine::ForCurrentProcess(); | |
| 494 enable_gpu_rendering_ = | |
| 495 command_line->HasSwitch(switches::kEnableGPURendering); | |
| 496 } | 488 } |
| 497 | 489 |
| 498 RenderWidgetHostViewGtk::~RenderWidgetHostViewGtk() { | 490 RenderWidgetHostViewGtk::~RenderWidgetHostViewGtk() { |
| 499 view_.Destroy(); | 491 view_.Destroy(); |
| 500 } | 492 } |
| 501 | 493 |
| 502 void RenderWidgetHostViewGtk::InitAsChild() { | 494 void RenderWidgetHostViewGtk::InitAsChild() { |
| 503 view_.Own(RenderWidgetHostViewGtkWidget::CreateNewWidget(this)); | 495 view_.Own(RenderWidgetHostViewGtkWidget::CreateNewWidget(this)); |
| 504 // |im_context_| must be created after creating |view_| widget. | 496 // |im_context_| must be created after creating |view_| widget. |
| 505 im_context_.reset(new GtkIMContextWrapper(this)); | 497 im_context_.reset(new GtkIMContextWrapper(this)); |
| (...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 745 bool RenderWidgetHostViewGtk::NeedsInputGrab() { | 737 bool RenderWidgetHostViewGtk::NeedsInputGrab() { |
| 746 return popup_type_ == WebKit::WebPopupTypeSelect; | 738 return popup_type_ == WebKit::WebPopupTypeSelect; |
| 747 } | 739 } |
| 748 | 740 |
| 749 bool RenderWidgetHostViewGtk::IsPopup() { | 741 bool RenderWidgetHostViewGtk::IsPopup() { |
| 750 return popup_type_ != WebKit::WebPopupTypeNone; | 742 return popup_type_ != WebKit::WebPopupTypeNone; |
| 751 } | 743 } |
| 752 | 744 |
| 753 BackingStore* RenderWidgetHostViewGtk::AllocBackingStore( | 745 BackingStore* RenderWidgetHostViewGtk::AllocBackingStore( |
| 754 const gfx::Size& size) { | 746 const gfx::Size& size) { |
| 755 if (enable_gpu_rendering_) { | |
| 756 // Use a special GPU accelerated backing store. | |
| 757 if (!gpu_view_host_.get()) { | |
| 758 // Here we lazily make the GpuViewHost. This must be allocated when we | |
| 759 // have a native view realized, which happens sometime after creation | |
| 760 // when our owner puts us in the parent window. | |
| 761 DCHECK(GetNativeView()); | |
| 762 XID window_xid = x11_util::GetX11WindowFromGtkWidget(GetNativeView()); | |
| 763 gpu_view_host_.reset(new GpuViewHost(host_, window_xid)); | |
| 764 } | |
| 765 return gpu_view_host_->CreateBackingStore(size); | |
| 766 } | |
| 767 | |
| 768 return new BackingStoreX(host_, size, | 747 return new BackingStoreX(host_, size, |
| 769 x11_util::GetVisualFromGtkWidget(view_.get()), | 748 x11_util::GetVisualFromGtkWidget(view_.get()), |
| 770 gtk_widget_get_visual(view_.get())->depth); | 749 gtk_widget_get_visual(view_.get())->depth); |
| 771 } | 750 } |
| 772 | 751 |
| 773 VideoLayer* RenderWidgetHostViewGtk::AllocVideoLayer(const gfx::Size& size) { | |
| 774 if (enable_gpu_rendering_) { | |
| 775 // TODO(scherkus): is it possible for a video layer to be allocated before a | |
| 776 // backing store? | |
| 777 DCHECK(gpu_view_host_.get()) | |
| 778 << "AllocVideoLayer() called before AllocBackingStore()"; | |
| 779 return gpu_view_host_->CreateVideoLayer(size); | |
| 780 } | |
| 781 | |
| 782 return new VideoLayerX(host_, size, | |
| 783 x11_util::GetVisualFromGtkWidget(view_.get()), | |
| 784 gtk_widget_get_visual(view_.get())->depth); | |
| 785 } | |
| 786 | |
| 787 void RenderWidgetHostViewGtk::SetBackground(const SkBitmap& background) { | 752 void RenderWidgetHostViewGtk::SetBackground(const SkBitmap& background) { |
| 788 RenderWidgetHostView::SetBackground(background); | 753 RenderWidgetHostView::SetBackground(background); |
| 789 host_->Send(new ViewMsg_SetBackground(host_->routing_id(), background)); | 754 host_->Send(new ViewMsg_SetBackground(host_->routing_id(), background)); |
| 790 } | 755 } |
| 791 | 756 |
| 792 void RenderWidgetHostViewGtk::ModifyEventForEdgeDragging( | 757 void RenderWidgetHostViewGtk::ModifyEventForEdgeDragging( |
| 793 GtkWidget* widget, GdkEventMotion* event) { | 758 GtkWidget* widget, GdkEventMotion* event) { |
| 794 // If the widget is aligned with an edge of the monitor its on and the user | 759 // If the widget is aligned with an edge of the monitor its on and the user |
| 795 // attempts to drag past that edge we track the number of times it has | 760 // attempts to drag past that edge we track the number of times it has |
| 796 // occurred, so that we can force the widget to scroll when it otherwise | 761 // occurred, so that we can force the widget to scroll when it otherwise |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 835 event->y += new_dragged_at_vertical_edge; | 800 event->y += new_dragged_at_vertical_edge; |
| 836 } else { | 801 } else { |
| 837 // Clear whenever we get a non-drag mouse move. | 802 // Clear whenever we get a non-drag mouse move. |
| 838 drag_monitor_size.SetSize(0, 0); | 803 drag_monitor_size.SetSize(0, 0); |
| 839 } | 804 } |
| 840 dragged_at_horizontal_edge_ = new_dragged_at_horizontal_edge; | 805 dragged_at_horizontal_edge_ = new_dragged_at_horizontal_edge; |
| 841 dragged_at_vertical_edge_ = new_dragged_at_vertical_edge; | 806 dragged_at_vertical_edge_ = new_dragged_at_vertical_edge; |
| 842 } | 807 } |
| 843 | 808 |
| 844 void RenderWidgetHostViewGtk::Paint(const gfx::Rect& damage_rect) { | 809 void RenderWidgetHostViewGtk::Paint(const gfx::Rect& damage_rect) { |
| 845 if (enable_gpu_rendering_) { | |
| 846 // When we're proxying painting, we don't actually display the web page | |
| 847 // ourselves. | |
| 848 if (gpu_view_host_.get()) | |
| 849 gpu_view_host_->OnWindowPainted(); | |
| 850 | |
| 851 // Erase the background. This will prevent a flash of black when resizing | |
| 852 // or exposing the window. White is usually better than black. | |
| 853 return; | |
| 854 } | |
| 855 | |
| 856 // If the GPU process is rendering directly into the View, | 810 // If the GPU process is rendering directly into the View, |
| 857 // call the compositor directly. | 811 // call the compositor directly. |
| 858 RenderWidgetHost* render_widget_host = GetRenderWidgetHost(); | 812 RenderWidgetHost* render_widget_host = GetRenderWidgetHost(); |
| 859 if (render_widget_host->is_gpu_rendering_active()) { | 813 if (render_widget_host->is_gpu_rendering_active()) { |
| 860 host_->ScheduleComposite(); | 814 host_->ScheduleComposite(); |
| 861 return; | 815 return; |
| 862 } | 816 } |
| 863 | 817 |
| 864 GdkWindow* window = view_.get()->window; | 818 GdkWindow* window = view_.get()->window; |
| 865 DCHECK(!about_to_validate_and_paint_); | 819 DCHECK(!about_to_validate_and_paint_); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 877 if (backing_store) { | 831 if (backing_store) { |
| 878 // Only render the widget if it is attached to a window; there's a short | 832 // Only render the widget if it is attached to a window; there's a short |
| 879 // period where this object isn't attached to a window but hasn't been | 833 // period where this object isn't attached to a window but hasn't been |
| 880 // Destroy()ed yet and it receives paint messages... | 834 // Destroy()ed yet and it receives paint messages... |
| 881 if (window) { | 835 if (window) { |
| 882 if (!visually_deemphasized_) { | 836 if (!visually_deemphasized_) { |
| 883 // In the common case, use XCopyArea. We don't draw more than once, so | 837 // In the common case, use XCopyArea. We don't draw more than once, so |
| 884 // we don't need to double buffer. | 838 // we don't need to double buffer. |
| 885 backing_store->XShowRect( | 839 backing_store->XShowRect( |
| 886 paint_rect, x11_util::GetX11WindowFromGtkWidget(view_.get())); | 840 paint_rect, x11_util::GetX11WindowFromGtkWidget(view_.get())); |
| 887 | |
| 888 // Paint the video layer using XCopyArea. | |
| 889 // TODO(scherkus): implement VideoLayerX::CairoShow() for grey | |
| 890 // blending. | |
| 891 VideoLayerX* video_layer = static_cast<VideoLayerX*>( | |
| 892 host_->video_layer()); | |
| 893 if (video_layer) | |
| 894 video_layer->XShow(x11_util::GetX11WindowFromGtkWidget(view_.get())); | |
| 895 } else { | 841 } else { |
| 896 // If the grey blend is showing, we make two drawing calls. Use double | 842 // If the grey blend is showing, we make two drawing calls. Use double |
| 897 // buffering to prevent flicker. Use CairoShowRect because XShowRect | 843 // buffering to prevent flicker. Use CairoShowRect because XShowRect |
| 898 // shortcuts GDK's double buffering. We won't be able to draw outside | 844 // shortcuts GDK's double buffering. We won't be able to draw outside |
| 899 // of |damage_rect|, so invalidate the difference between |paint_rect| | 845 // of |damage_rect|, so invalidate the difference between |paint_rect| |
| 900 // and |damage_rect|. | 846 // and |damage_rect|. |
| 901 if (paint_rect != damage_rect) { | 847 if (paint_rect != damage_rect) { |
| 902 GdkRectangle extra_gdk_rect = | 848 GdkRectangle extra_gdk_rect = |
| 903 paint_rect.Subtract(damage_rect).ToGdkRectangle(); | 849 paint_rect.Subtract(damage_rect).ToGdkRectangle(); |
| 904 gdk_window_invalidate_rect(window, &extra_gdk_rect, false); | 850 gdk_window_invalidate_rect(window, &extra_gdk_rect, false); |
| (...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1116 } | 1062 } |
| 1117 | 1063 |
| 1118 // static | 1064 // static |
| 1119 RenderWidgetHostView* | 1065 RenderWidgetHostView* |
| 1120 RenderWidgetHostView::GetRenderWidgetHostViewFromNativeView( | 1066 RenderWidgetHostView::GetRenderWidgetHostViewFromNativeView( |
| 1121 gfx::NativeView widget) { | 1067 gfx::NativeView widget) { |
| 1122 gpointer user_data = g_object_get_data(G_OBJECT(widget), | 1068 gpointer user_data = g_object_get_data(G_OBJECT(widget), |
| 1123 kRenderWidgetHostViewKey); | 1069 kRenderWidgetHostViewKey); |
| 1124 return reinterpret_cast<RenderWidgetHostView*>(user_data); | 1070 return reinterpret_cast<RenderWidgetHostView*>(user_data); |
| 1125 } | 1071 } |
| OLD | NEW |