0

Refactors RenderWidgetHostViewBase and moves common code to

//components/input.

This CL introduces a new common class RenderWidgetHostViewCommon which
implements several methods of the RenderWidgetHostViewInput interface
that are going to be common for both browser and Viz's input handling.
This is going to be useful to minizime code duplication when
implementing RenderWidgetHostViewInput interface on VizCompositorThread.

Design Doc:
https://docs.google.com/document/d/1Z7zA77GX0qeov3chL96wzbN41ucAjZenSZgdMp6voRs/edit?resourcekey=0-VZIpFx5rHVed-PN78jpIAA&tab=t.0#heading=h.h400rreu42ij

Bug: b/358566970
Change-Id: I3378950d7c975c6a96c9e145068569b28df5ca9f
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5842228
Reviewed-by: Jonathan Ross <jonross@chromium.org>
Commit-Queue: Aman Verma <amanvr@google.com>
Cr-Commit-Position: refs/heads/main@{#1355774}
This commit is contained in:
Aman Verma
2024-09-16 10:55:07 +00:00
committed by Chromium LUCI CQ
parent 66600355b7
commit a207000ff7
7 changed files with 436 additions and 445 deletions

@@ -96,38 +96,10 @@ void RenderWidgetHostViewBase::SetContentBackgroundColor(SkColor color) {
UpdateBackgroundColor();
}
void RenderWidgetHostViewBase::NotifyObserversAboutShutdown() {
// Note: RenderWidgetHostInputEventRouter is an observer, and uses the
// following notification to remove this view from its surface owners map.
for (auto& observer : observers_)
observer.OnRenderWidgetHostViewInputDestroyed(this);
// All observers are required to disconnect after they are notified.
CHECK(observers_.empty());
}
MouseWheelPhaseHandler* RenderWidgetHostViewBase::GetMouseWheelPhaseHandler() {
return nullptr;
}
void RenderWidgetHostViewBase::StopFlingingIfNecessary(
const blink::WebGestureEvent& event,
blink::mojom::InputEventResultState ack_result) {
// Reset view_stopped_flinging_for_test_ at the beginning of the scroll
// sequence.
if (event.GetType() == blink::WebInputEvent::Type::kGestureScrollBegin)
view_stopped_flinging_for_test_ = false;
bool processed = blink::mojom::InputEventResultState::kConsumed == ack_result;
if (!processed &&
event.GetType() == blink::WebInputEvent::Type::kGestureScrollUpdate &&
event.data.scroll_update.inertial_phase ==
blink::WebGestureEvent::InertialPhaseState::kMomentum &&
event.SourceDevice() != blink::WebGestureDevice::kSyntheticAutoscroll) {
StopFling();
view_stopped_flinging_for_test_ = true;
}
}
void RenderWidgetHostViewBase::UpdateIntrinsicSizingInfo(
blink::mojom::IntrinsicSizingInfoPtr sizing_info) {}
@@ -154,13 +126,6 @@ void RenderWidgetHostViewBase::SelectionBoundsChanged(
#endif
}
int RenderWidgetHostViewBase::GetMouseWheelMinimumGranularity() const {
// Most platforms can specify the floating-point delta in the wheel event so
// they don't have a minimum granularity. Android is currently the only
// platform that overrides this.
return 0;
}
RenderWidgetHostViewBase* RenderWidgetHostViewBase::GetRootView() {
return this;
}
@@ -186,10 +151,6 @@ ui::TextInputClient* RenderWidgetHostViewBase::GetTextInputClient() {
return nullptr;
}
viz::FrameSinkId RenderWidgetHostViewBase::GetRootFrameSinkId() {
return viz::FrameSinkId();
}
bool RenderWidgetHostViewBase::IsSurfaceAvailableForCopy() {
return false;
}
@@ -365,6 +326,11 @@ bool RenderWidgetHostViewBase::IsPointerLocked() {
return false;
}
const viz::DisplayHitTestQueryMap&
RenderWidgetHostViewBase::GetDisplayHitTestQuery() const {
return GetHostFrameSinkManager()->GetDisplayHitTestQuery();
}
bool RenderWidgetHostViewBase::
GetIsPointerLockedUnadjustedMovementForTesting() {
return false;
@@ -398,80 +364,6 @@ RenderWidgetHostViewBase::GetKeyboardLayoutMap() {
return base::flat_map<std::string, std::string>();
}
blink::mojom::InputEventResultState RenderWidgetHostViewBase::FilterInputEvent(
const blink::WebInputEvent& input_event) {
// By default, input events are simply forwarded to the renderer.
return blink::mojom::InputEventResultState::kNotConsumed;
}
void RenderWidgetHostViewBase::WheelEventAck(
const blink::WebMouseWheelEvent& event,
blink::mojom::InputEventResultState ack_result) {}
void RenderWidgetHostViewBase::GestureEventAck(
const blink::WebGestureEvent& event,
blink::mojom::InputEventResultSource ack_source,
blink::mojom::InputEventResultState ack_result) {}
void RenderWidgetHostViewBase::ChildDidAckGestureEvent(
const blink::WebGestureEvent& event,
blink::mojom::InputEventResultState ack_result) {}
void RenderWidgetHostViewBase::ForwardTouchpadZoomEventIfNecessary(
const blink::WebGestureEvent& event,
blink::mojom::InputEventResultState ack_result) {
if (!event.IsTouchpadZoomEvent())
return;
if (!event.NeedsWheelEvent())
return;
switch (event.GetType()) {
case blink::WebInputEvent::Type::kGesturePinchBegin:
// Don't send the begin event until we get the first unconsumed update, so
// that we elide pinch gesture steams consisting of only a begin and end.
pending_touchpad_pinch_begin_ = event;
pending_touchpad_pinch_begin_->SetNeedsWheelEvent(false);
break;
case blink::WebInputEvent::Type::kGesturePinchUpdate:
if (ack_result != blink::mojom::InputEventResultState::kConsumed &&
!event.data.pinch_update.zoom_disabled) {
if (pending_touchpad_pinch_begin_) {
host()->ForwardGestureEvent(*pending_touchpad_pinch_begin_);
pending_touchpad_pinch_begin_.reset();
}
// Now that the synthetic wheel event has gone unconsumed, we have the
// pinch event actually change the page scale.
blink::WebGestureEvent pinch_event(event);
pinch_event.SetNeedsWheelEvent(false);
host()->ForwardGestureEvent(pinch_event);
}
break;
case blink::WebInputEvent::Type::kGesturePinchEnd:
if (pending_touchpad_pinch_begin_) {
pending_touchpad_pinch_begin_.reset();
} else {
blink::WebGestureEvent pinch_end_event(event);
pinch_end_event.SetNeedsWheelEvent(false);
host()->ForwardGestureEvent(pinch_end_event);
}
break;
case blink::WebInputEvent::Type::kGestureDoubleTap:
if (ack_result != blink::mojom::InputEventResultState::kConsumed) {
blink::WebGestureEvent double_tap(event);
double_tap.SetNeedsWheelEvent(false);
// TODO(mcnee): Support double-tap zoom gesture for OOPIFs. For now,
// we naively send this to the main frame. If this is over an OOPIF,
// then the iframe element will incorrectly be used for the scale
// calculation rather than the element in the OOPIF.
// https://crbug.com/758348
host()->ForwardGestureEvent(double_tap);
}
break;
default:
NOTREACHED_IN_MIGRATION();
}
}
bool RenderWidgetHostViewBase::HasFallbackSurface() const {
NOTREACHED_IN_MIGRATION();
return false;
@@ -514,12 +406,6 @@ bool RenderWidgetHostViewBase::RequestRepaintForTesting() {
return false;
}
void RenderWidgetHostViewBase::ProcessAckedTouchEvent(
const input::TouchEventWithLatencyInfo& touch,
blink::mojom::InputEventResultState ack_result) {
DUMP_WILL_BE_NOTREACHED();
}
// Send system cursor size to the renderer via UpdateScreenInfo().
void RenderWidgetHostViewBase::UpdateSystemCursorSize(
const gfx::Size& cursor_size) {
@@ -694,11 +580,6 @@ input::RenderInputRouter* RenderWidgetHostViewBase::GetViewRenderInputRouter() {
return host()->GetRenderInputRouter();
}
input::RenderWidgetHostViewInput*
RenderWidgetHostViewBase::GetParentViewInput() {
return nullptr;
}
void RenderWidgetHostViewBase::SetScaleOverrideForCapture(float scale) {
DVLOG(1) << __func__ << ": override=" << scale;
scale_override_for_capture_ = scale;
@@ -741,18 +622,6 @@ void RenderWidgetHostViewBase::SetInsets(const gfx::Insets& insets) {
NOTIMPLEMENTED_LOG_ONCE();
}
void RenderWidgetHostViewBase::DisplayCursor(const ui::Cursor& cursor) {
return;
}
input::CursorManager* RenderWidgetHostViewBase::GetCursorManager() {
return nullptr;
}
void RenderWidgetHostViewBase::TransformPointToRootSurface(gfx::PointF* point) {
return;
}
const viz::LocalSurfaceId&
RenderWidgetHostViewBase::IncrementSurfaceIdForNavigation() {
NOTREACHED();
@@ -769,16 +638,6 @@ void RenderWidgetHostViewBase::OnFrameTokenChangedForView(
host()->DidProcessFrame(frame_token, activation_time);
}
bool RenderWidgetHostViewBase::ScreenRectIsUnstableFor(
const blink::WebInputEvent& event) {
return false;
}
bool RenderWidgetHostViewBase::ScreenRectIsUnstableForIOv2For(
const blink::WebInputEvent& event) {
return false;
}
void RenderWidgetHostViewBase::ProcessMouseEvent(
const blink::WebMouseEvent& event,
const ui::LatencyInfo& latency) {
@@ -846,19 +705,6 @@ gfx::PointF RenderWidgetHostViewBase::TransformPointToRootCoordSpaceF(
return point;
}
gfx::PointF RenderWidgetHostViewBase::TransformRootPointToViewCoordSpace(
const gfx::PointF& point) {
return point;
}
bool RenderWidgetHostViewBase::TransformPointToCoordSpaceForView(
const gfx::PointF& point,
input::RenderWidgetHostViewInput* target_view,
gfx::PointF* transformed_point) {
NOTREACHED_IN_MIGRATION();
return true;
}
bool RenderWidgetHostViewBase::IsRenderWidgetHostViewChildFrame() {
return false;
}
@@ -920,29 +766,6 @@ TextInputManager* RenderWidgetHostViewBase::GetTextInputManager() {
return text_input_manager_;
}
void RenderWidgetHostViewBase::StopFling() {
if (!host())
return;
host()->StopFling();
// In case of scroll bubbling tells the child's fling controller which is in
// charge of generating GSUs to stop flinging.
if (host()->delegate() && host()->delegate()->GetInputEventRouter()) {
host()->delegate()->GetInputEventRouter()->StopFling();
}
}
void RenderWidgetHostViewBase::AddObserver(
input::RenderWidgetHostViewInputObserver* observer) {
observers_.AddObserver(observer);
}
void RenderWidgetHostViewBase::RemoveObserver(
input::RenderWidgetHostViewInputObserver* observer) {
observers_.RemoveObserver(observer);
}
TouchSelectionControllerClientManager*
RenderWidgetHostViewBase::GetTouchSelectionControllerClientManager() {
return nullptr;
@@ -992,139 +815,6 @@ void RenderWidgetHostViewBase::SetTooltipObserverForTesting(
tooltip_observer_for_testing_ = observer;
}
// TODO(wjmaclean): Would it simplify this function if we re-implemented it
// using GetTransformToViewCoordSpace()?
bool RenderWidgetHostViewBase::TransformPointToTargetCoordSpace(
input::RenderWidgetHostViewInput* original_view,
input::RenderWidgetHostViewInput* target_view,
const gfx::PointF& point,
gfx::PointF* transformed_point) const {
CHECK(original_view);
CHECK(target_view);
viz::FrameSinkId root_frame_sink_id = original_view->GetRootFrameSinkId();
if (!root_frame_sink_id.is_valid())
return false;
const auto& display_hit_test_query_map =
GetHostFrameSinkManager()->GetDisplayHitTestQuery();
const auto iter = display_hit_test_query_map.find(root_frame_sink_id);
if (iter == display_hit_test_query_map.end())
return false;
viz::HitTestQuery* query = iter->second.get();
std::vector<viz::FrameSinkId> target_ancestors;
target_ancestors.push_back(target_view->GetFrameSinkId());
input::RenderWidgetHostViewInput* cur_view = target_view;
while (cur_view->GetParentViewInput()) {
cur_view = cur_view->GetParentViewInput();
if (!cur_view)
return false;
target_ancestors.push_back(cur_view->GetFrameSinkId());
}
if (target_ancestors.back() != root_frame_sink_id)
target_ancestors.push_back(root_frame_sink_id);
float device_scale_factor = original_view->GetDeviceScaleFactor();
CHECK_GT(device_scale_factor, 0.0f);
// TODO(crbug.com/41460959): Optimize so that |point_in_pixels| doesn't need
// to be in the coordinate space of the root surface in HitTestQuery.
gfx::Transform transform_root_to_original;
query->GetTransformToTarget(original_view->GetFrameSinkId(),
&transform_root_to_original);
const std::optional<gfx::PointF> point_in_pixels =
transform_root_to_original.InverseMapPoint(
gfx::ConvertPointToPixels(point, device_scale_factor));
if (!point_in_pixels.has_value())
return false;
gfx::PointF transformed_point_in_physical_pixels;
if (!query->TransformLocationForTarget(
target_ancestors, *point_in_pixels,
&transformed_point_in_physical_pixels)) {
return false;
}
*transformed_point = gfx::ConvertPointToDips(
transformed_point_in_physical_pixels, device_scale_factor);
return true;
}
bool RenderWidgetHostViewBase::GetTransformToViewCoordSpace(
input::RenderWidgetHostViewInput* target_view,
gfx::Transform* transform) {
CHECK(transform);
if (target_view == this) {
transform->MakeIdentity();
return true;
}
viz::FrameSinkId root_frame_sink_id = GetRootFrameSinkId();
if (!root_frame_sink_id.is_valid())
return false;
const auto& display_hit_test_query_map =
GetHostFrameSinkManager()->GetDisplayHitTestQuery();
const auto iter = display_hit_test_query_map.find(root_frame_sink_id);
if (iter == display_hit_test_query_map.end())
return false;
viz::HitTestQuery* query = iter->second.get();
gfx::Transform transform_this_to_root;
if (GetFrameSinkId() != root_frame_sink_id) {
gfx::Transform transform_root_to_this;
if (!query->GetTransformToTarget(GetFrameSinkId(), &transform_root_to_this))
return false;
if (!transform_root_to_this.GetInverse(&transform_this_to_root))
return false;
}
gfx::Transform transform_root_to_target;
if (!query->GetTransformToTarget(target_view->GetFrameSinkId(),
&transform_root_to_target)) {
return false;
}
// TODO(wjmaclean): In TransformPointToTargetCoordSpace the device scale
// factor is taken from the original view ... does that matter? Presumably
// all the views have the same dsf.
float device_scale_factor = GetDeviceScaleFactor();
gfx::Transform transform_to_pixel;
transform_to_pixel.Scale(device_scale_factor, device_scale_factor);
gfx::Transform transform_from_pixel;
transform_from_pixel.Scale(1.f / device_scale_factor,
1.f / device_scale_factor);
// Note: gfx::Transform includes optimizations to early-out for scale = 1 or
// concatenating an identity matrix, so we don't add those checks here.
transform->MakeIdentity();
transform->PostConcat(transform_to_pixel);
transform->PostConcat(transform_this_to_root);
transform->PostConcat(transform_root_to_target);
transform->PostConcat(transform_from_pixel);
return true;
}
bool RenderWidgetHostViewBase::TransformPointToLocalCoordSpace(
const gfx::PointF& point,
const viz::SurfaceId& original_surface,
gfx::PointF* transformed_point) {
viz::FrameSinkId original_frame_sink_id = original_surface.frame_sink_id();
viz::FrameSinkId target_frame_sink_id = GetFrameSinkId();
if (!original_frame_sink_id.is_valid() || !target_frame_sink_id.is_valid())
return false;
if (original_frame_sink_id == target_frame_sink_id)
return true;
if (!host() || !host()->delegate())
return false;
auto* router = host()->delegate()->GetInputEventRouter();
if (!router)
return false;
*transformed_point = point;
return TransformPointToTargetCoordSpace(
router->FindViewFromFrameSinkId(original_frame_sink_id),
router->FindViewFromFrameSinkId(target_frame_sink_id), point,
transformed_point);
}
ui::Compositor* RenderWidgetHostViewBase::GetCompositor() {
return nullptr;
}

@@ -58,17 +58,11 @@ class WebMouseEvent;
class WebMouseWheelEvent;
}
namespace input {
class CursorManager;
class RenderWidgetHostViewInputObserver;
} // namespace input
namespace ui {
class Compositor;
class Cursor;
class LatencyInfo;
enum class DomCode : uint32_t;
struct DidOverscrollParams;
} // namespace ui
namespace content {
@@ -149,59 +143,9 @@ class CONTENT_EXPORT RenderWidgetHostViewBase
const ui::LatencyInfo& latency) override;
void ProcessGestureEvent(const blink::WebGestureEvent& event,
const ui::LatencyInfo& latency) override;
void ProcessAckedTouchEvent(
const input::TouchEventWithLatencyInfo& touch,
blink::mojom::InputEventResultState ack_result) override;
void DidOverscroll(const ui::DidOverscrollParams& params) override {}
void DidStopFlinging() override {}
RenderWidgetHostViewBase* GetRootView() override;
viz::FrameSinkId GetRootFrameSinkId() override;
void NotifyHitTestRegionUpdated(
const viz::AggregatedHitTestRegion& region) override {}
bool ScreenRectIsUnstableFor(const blink::WebInputEvent& event) override;
bool ScreenRectIsUnstableForIOv2For(
const blink::WebInputEvent& event) override;
void PreProcessTouchEvent(const blink::WebTouchEvent& event) override {}
void PreProcessMouseEvent(const blink::WebMouseEvent& event) override {}
gfx::PointF TransformRootPointToViewCoordSpace(
const gfx::PointF& point) override;
bool TransformPointToLocalCoordSpace(const gfx::PointF& point,
const viz::SurfaceId& original_surface,
gfx::PointF* transformed_point) override;
bool TransformPointToCoordSpaceForView(
const gfx::PointF& point,
input::RenderWidgetHostViewInput* target_view,
gfx::PointF* transformed_point) override;
bool GetTransformToViewCoordSpace(
input::RenderWidgetHostViewInput* target_view,
gfx::Transform* transform) override;
void TransformPointToRootSurface(gfx::PointF* point) override;
input::RenderWidgetHostViewInput* GetParentViewInput() override;
blink::mojom::InputEventResultState FilterInputEvent(
const blink::WebInputEvent& input_event) override;
void GestureEventAck(const blink::WebGestureEvent& event,
blink::mojom::InputEventResultSource ack_source,
blink::mojom::InputEventResultState ack_result) override;
void WheelEventAck(const blink::WebMouseWheelEvent& event,
blink::mojom::InputEventResultState ack_result) override;
void ChildDidAckGestureEvent(
const blink::WebGestureEvent& event,
blink::mojom::InputEventResultState ack_result) override;
void SetLastPointerType(ui::EventPointerType last_pointer_type) override {}
void DisplayCursor(const ui::Cursor& cursor) override;
input::CursorManager* GetCursorManager() override;
void UpdateTooltipUnderCursor(const std::u16string& tooltip_text) override {}
void UpdateTooltip(const std::u16string& tooltip_text) override {}
int GetMouseWheelMinimumGranularity() const override;
void OnStartStylusWriting() override {}
void OnEditElementFocusedForStylusWriting(
const gfx::Rect& focused_edit_bounds,
const gfx::Rect& caret_bounds) override {}
void OnEditElementFocusClearedForStylusWriting() override {}
void OnAutoscrollStart() override;
void AddObserver(input::RenderWidgetHostViewInputObserver* observer) override;
void RemoveObserver(
input::RenderWidgetHostViewInputObserver* observer) override;
const viz::DisplayHitTestQueryMap& GetDisplayHitTestQuery() const override;
float GetDeviceScaleFactor() const final;
bool IsPointerLocked() override;
@@ -497,8 +441,6 @@ class CONTENT_EXPORT RenderWidgetHostViewBase
// |text_input_manager_|.
TextInputManager* GetTextInputManager();
void StopFling();
virtual void DidNavigate();
// Called when the RenderWidgetHostImpl establishes a connection to the
@@ -546,20 +488,12 @@ class CONTENT_EXPORT RenderWidgetHostViewBase
explicit RenderWidgetHostViewBase(RenderWidgetHost* host);
~RenderWidgetHostViewBase() override;
void NotifyObserversAboutShutdown();
bool is_frame_sink_id_owner() const { return is_frame_sink_id_owner_; }
virtual MouseWheelPhaseHandler* GetMouseWheelPhaseHandler();
// RenderWidgetHostViewInput implementations.
void UpdateFrameSinkIdRegistration() override;
void StopFlingingIfNecessary(
const blink::WebGestureEvent& event,
blink::mojom::InputEventResultState ack_result) override;
void ForwardTouchpadZoomEventIfNecessary(
const blink::WebGestureEvent& event,
blink::mojom::InputEventResultState ack_result) override;
// Applies background color without notifying the RenderWidget about
// opaqueness changes. This allows us to, when navigating to a new page,
@@ -684,31 +618,10 @@ class CONTENT_EXPORT RenderWidgetHostViewBase
// LocalSurfaceId.
virtual void OnSynchronizedDisplayPropertiesChanged(bool rotation = false) {}
// Transforms |point| from |original_view| coord space to |target_view| coord
// space. Result is stored in |transformed_point|. Returns true if the
// transform is successful, false otherwise.
bool TransformPointToTargetCoordSpace(
input::RenderWidgetHostViewInput* original_view,
input::RenderWidgetHostViewInput* target_view,
const gfx::PointF& point,
gfx::PointF* transformed_point) const;
// Helper function to return whether the current background color is fully
// opaque.
bool IsBackgroundColorOpaque();
bool view_stopped_flinging_for_test() const {
return view_stopped_flinging_for_test_;
}
base::ObserverList<input::RenderWidgetHostViewInputObserver>::Unchecked
observers_;
std::optional<blink::WebGestureEvent> pending_touchpad_pinch_begin_;
// True when StopFlingingIfNecessary() calls StopFling().
bool view_stopped_flinging_for_test_ = false;
bool is_evicted_ = false;
bool is_frame_sink_id_owner_ = false;