From 408afd16d459a1be75186e835ed2582e99d4f8d1 Mon Sep 17 00:00:00 2001 From: Marshall Greenblatt Date: Fri, 23 Jun 2017 15:06:37 -0400 Subject: [PATCH] Fix OSR PDF mouse wheel scrolling (issue #2078) --- .../osr/render_widget_host_view_osr.cc | 151 ++++++++++++++---- .../browser/osr/render_widget_host_view_osr.h | 9 +- 2 files changed, 128 insertions(+), 32 deletions(-) diff --git a/libcef/browser/osr/render_widget_host_view_osr.cc b/libcef/browser/osr/render_widget_host_view_osr.cc index aa9709a01..04de703ec 100644 --- a/libcef/browser/osr/render_widget_host_view_osr.cc +++ b/libcef/browser/osr/render_widget_host_view_osr.cc @@ -362,7 +362,6 @@ CefRenderWidgetHostViewOSR::CefRenderWidgetHostViewOSR( CefRenderWidgetHostViewOSR* parent_host_view, bool is_guest_view_hack) : background_color_(background_color), - scale_factor_(kDefaultScaleFactor), frame_rate_threshold_ms_(0), #if !defined(OS_MACOSX) compositor_widget_(gfx::kNullAcceleratedWidget), @@ -382,6 +381,8 @@ CefRenderWidgetHostViewOSR::CefRenderWidgetHostViewOSR( DCHECK(render_widget_host_); DCHECK(!render_widget_host_->GetView()); + current_device_scale_factor_ = kDefaultScaleFactor; + if (parent_host_view_) { browser_impl_ = parent_host_view_->browser_impl(); DCHECK(browser_impl_); @@ -776,8 +777,14 @@ void CefRenderWidgetHostViewOSR::Destroy() { popup_host_view_->CancelWidget(); if (child_host_view_) child_host_view_->CancelWidget(); - for (auto guest_host_view : guest_host_views_) - guest_host_view->CancelWidget(); + if (!guest_host_views_.empty()) { + // Guest RWHVs will be destroyed when the associated RWHVGuest is + // destroyed. This parent RWHV may be destroyed first, so disassociate + // the guest RWHVs here without destroying them. + for (auto guest_host_view : guest_host_views_) + guest_host_view->parent_host_view_ = nullptr; + guest_host_views_.clear(); + } Hide(); } } @@ -803,7 +810,8 @@ gfx::Size CefRenderWidgetHostViewOSR::GetRequestedRendererSize() const { } gfx::Size CefRenderWidgetHostViewOSR::GetPhysicalBackingSize() const { - return gfx::ConvertSizeToPixel(scale_factor_, GetRequestedRendererSize()); + return gfx::ConvertSizeToPixel(current_device_scale_factor_, + GetRequestedRendererSize()); } void CefRenderWidgetHostViewOSR::CopyFromSurface( @@ -943,20 +951,45 @@ void CefRenderWidgetHostViewOSR::SetNeedsBeginFrames(bool enabled) { } } +void CefRenderWidgetHostViewOSR::ProcessMouseEvent( + const blink::WebMouseEvent& event, + const ui::LatencyInfo& latency) { + render_widget_host_->ForwardMouseEventWithLatencyInfo(event, latency); +} + +void CefRenderWidgetHostViewOSR::ProcessMouseWheelEvent( + const blink::WebMouseWheelEvent& event, + const ui::LatencyInfo& latency) { + render_widget_host_->ForwardWheelEventWithLatencyInfo(event, latency); +} + +void CefRenderWidgetHostViewOSR::ProcessTouchEvent( + const blink::WebTouchEvent& event, + const ui::LatencyInfo& latency) { + render_widget_host_->ForwardTouchEventWithLatencyInfo(event, latency); +} + +void CefRenderWidgetHostViewOSR::ProcessGestureEvent( + const blink::WebGestureEvent& event, + const ui::LatencyInfo& latency) { + render_widget_host_->ForwardGestureEventWithLatencyInfo(event, latency); +} + bool CefRenderWidgetHostViewOSR::TransformPointToLocalCoordSpace( const gfx::Point& point, const cc::SurfaceId& original_surface, gfx::Point* transformed_point) { // Transformations use physical pixels rather than DIP, so conversion // is necessary. - gfx::Point point_in_pixels = gfx::ConvertPointToPixel(scale_factor_, point); + gfx::Point point_in_pixels = + gfx::ConvertPointToPixel(current_device_scale_factor_, point); if (!GetDelegatedFrameHost()->TransformPointToLocalCoordSpace( point_in_pixels, original_surface, transformed_point)) { return false; } *transformed_point = - gfx::ConvertPointToDIP(scale_factor_, *transformed_point); + gfx::ConvertPointToDIP(current_device_scale_factor_, *transformed_point); return true; } @@ -1156,23 +1189,48 @@ void CefRenderWidgetHostViewOSR::SendMouseEvent( browser_impl_->CancelContextMenu(); } - if (popup_host_view_ && - popup_host_view_->popup_position_.Contains( - event.PositionInWidget().x, event.PositionInWidget().y)) { - blink::WebMouseEvent popup_event(event); - popup_event.SetPositionInWidget( - event.PositionInWidget().x - popup_host_view_->popup_position_.x(), - event.PositionInWidget().y - popup_host_view_->popup_position_.y()); - popup_event.SetPositionInScreen(popup_event.PositionInWidget().x, - popup_event.PositionInWidget().y); + if (popup_host_view_) { + if (popup_host_view_->popup_position_.Contains( + event.PositionInWidget().x, event.PositionInWidget().y)) { + blink::WebMouseEvent popup_event(event); + popup_event.SetPositionInWidget( + event.PositionInWidget().x - popup_host_view_->popup_position_.x(), + event.PositionInWidget().y - popup_host_view_->popup_position_.y()); + popup_event.SetPositionInScreen(popup_event.PositionInWidget().x, + popup_event.PositionInWidget().y); - popup_host_view_->SendMouseEvent(popup_event); - return; + popup_host_view_->SendMouseEvent(popup_event); + return; + } + } else if (!guest_host_views_.empty()) { + for (auto guest_host_view : guest_host_views_) { + if (!guest_host_view->render_widget_host_ || + !guest_host_view->render_widget_host_->GetView()) { + continue; + } + const gfx::Rect& guest_bounds = + guest_host_view->render_widget_host_->GetView()->GetViewBounds(); + if (guest_bounds.Contains(event.PositionInWidget().x, + event.PositionInWidget().y)) { + blink::WebMouseEvent guest_event(event); + guest_event.SetPositionInWidget( + event.PositionInWidget().x - guest_bounds.x(), + event.PositionInWidget().y - guest_bounds.y()); + guest_event.SetPositionInScreen(guest_event.PositionInWidget().x, + guest_event.PositionInWidget().y); + + guest_host_view->SendMouseEvent(guest_event); + return; + } + } } } - if (!render_widget_host_) - return; - render_widget_host_->ForwardMouseEvent(event); + + if (render_widget_host_ && render_widget_host_->GetView()) { + // Direct routing requires that mouse events go directly to the View. + render_widget_host_->GetView()->ProcessMouseEvent( + event, ui::LatencyInfo(ui::SourceEventType::OTHER)); + } } void CefRenderWidgetHostViewOSR::SendMouseWheelEvent( @@ -1203,11 +1261,35 @@ void CefRenderWidgetHostViewOSR::SendMouseWheelEvent( base::Bind(&CefRenderWidgetHostViewOSR::CancelWidget, popup_host_view_->weak_ptr_factory_.GetWeakPtr())); } + } else if (!guest_host_views_.empty()) { + for (auto guest_host_view : guest_host_views_) { + if (!guest_host_view->render_widget_host_ || + !guest_host_view->render_widget_host_->GetView()) { + continue; + } + const gfx::Rect& guest_bounds = + guest_host_view->render_widget_host_->GetView()->GetViewBounds(); + if (guest_bounds.Contains(event.PositionInWidget().x, + event.PositionInWidget().y)) { + blink::WebMouseWheelEvent guest_event(event); + guest_event.SetPositionInWidget( + event.PositionInWidget().x - guest_bounds.x(), + event.PositionInWidget().y - guest_bounds.y()); + guest_event.SetPositionInScreen(guest_event.PositionInWidget().x, + guest_event.PositionInWidget().y); + + guest_host_view->SendMouseWheelEvent(guest_event); + return; + } + } } } - if (!render_widget_host_) - return; - render_widget_host_->ForwardWheelEvent(event); + + if (render_widget_host_ && render_widget_host_->GetView()) { + // Direct routing requires that mouse events go directly to the View. + render_widget_host_->GetView()->ProcessMouseWheelEvent( + event, ui::LatencyInfo(ui::SourceEventType::WHEEL)); + } } void CefRenderWidgetHostViewOSR::SendFocusEvent(bool focus) { @@ -1349,7 +1431,7 @@ void CefRenderWidgetHostViewOSR::SetDeviceScaleFactor() { } } - scale_factor_ = new_scale_factor; + current_device_scale_factor_ = new_scale_factor; if (render_widget_host_ && render_widget_host_->delegate()) render_widget_host_->delegate()->UpdateDeviceScaleFactor(new_scale_factor); @@ -1368,9 +1450,10 @@ void CefRenderWidgetHostViewOSR::SetDeviceScaleFactor() { void CefRenderWidgetHostViewOSR::ResizeRootLayer() { SetFrameRate(); - const float orgScaleFactor = scale_factor_; + const float orgScaleFactor = current_device_scale_factor_; SetDeviceScaleFactor(); - const bool scaleFactorDidChange = (orgScaleFactor != scale_factor_); + const bool scaleFactorDidChange = + (orgScaleFactor != current_device_scale_factor_); gfx::Size size; if (!IsPopupWidget()) @@ -1382,10 +1465,11 @@ void CefRenderWidgetHostViewOSR::ResizeRootLayer() { return; const gfx::Size& size_in_pixels = - gfx::ConvertSizeToPixel(scale_factor_, size); + gfx::ConvertSizeToPixel(current_device_scale_factor_, size); GetRootLayer()->SetBounds(gfx::Rect(size)); - GetCompositor()->SetScaleAndSize(scale_factor_, size_in_pixels); + GetCompositor()->SetScaleAndSize(current_device_scale_factor_, + size_in_pixels); PlatformResizeCompositorWidget(size_in_pixels); } @@ -1451,8 +1535,13 @@ void CefRenderWidgetHostViewOSR::CancelWidget() { if (render_widget_host_ && !is_destroyed_) { is_destroyed_ = true; + + // Don't delete the RWHI manually while owned by a scoped_ptr in RVHI. This + // matches a CHECK() in RenderWidgetHostImpl::Destroy(). + const bool also_delete = !render_widget_host_->owner_delegate(); + // Results in a call to Destroy(). - render_widget_host_->ShutdownAndDestroyWidget(true); + render_widget_host_->ShutdownAndDestroyWidget(also_delete); } } @@ -1489,8 +1578,8 @@ void CefRenderWidgetHostViewOSR::RegisterGuestViewFrameSwappedCallback( void CefRenderWidgetHostViewOSR::OnGuestViewFrameSwapped( content::RenderWidgetHostViewGuest* guest_host_view) { - InvalidateInternal( - gfx::ConvertRectToPixel(scale_factor_, guest_host_view->GetViewBounds())); + InvalidateInternal(gfx::ConvertRectToPixel(current_device_scale_factor_, + guest_host_view->GetViewBounds())); RegisterGuestViewFrameSwappedCallback(guest_host_view); } diff --git a/libcef/browser/osr/render_widget_host_view_osr.h b/libcef/browser/osr/render_widget_host_view_osr.h index 320ca746e..7d92c8295 100644 --- a/libcef/browser/osr/render_widget_host_view_osr.h +++ b/libcef/browser/osr/render_widget_host_view_osr.h @@ -177,6 +177,14 @@ class CefRenderWidgetHostViewOSR : public content::RenderWidgetHostViewBase, void SetNeedsBeginFrames(bool enabled) override; + void ProcessMouseEvent(const blink::WebMouseEvent& event, + const ui::LatencyInfo& latency) override; + void ProcessMouseWheelEvent(const blink::WebMouseWheelEvent& event, + const ui::LatencyInfo& latency) override; + void ProcessTouchEvent(const blink::WebTouchEvent& event, + const ui::LatencyInfo& latency) override; + void ProcessGestureEvent(const blink::WebGestureEvent& event, + const ui::LatencyInfo& latency) override; bool TransformPointToLocalCoordSpace(const gfx::Point& point, const cc::SurfaceId& original_surface, gfx::Point* transformed_point) override; @@ -307,7 +315,6 @@ class CefRenderWidgetHostViewOSR : public content::RenderWidgetHostViewBase, // The background color of the web content. SkColor background_color_; - float scale_factor_; int frame_rate_threshold_ms_; #if !defined(OS_MACOSX)