Commit 53a6e84a authored by W. James MacLean's avatar W. James MacLean Committed by Commit Bot

Fix TouchSelectionHandle updates on Android.

This CL addresses the remaining issues with Android touch selection
handles. First, it removes the manual scaling done by the child frame
client for the device scale factor; apparently this is now handled by
the point-transform functions. Second, it makes sure the child frame's
handles update during pinch just like the main frame's handles do.

Because a child frame's handles are not locked to a surface like the
main frame's handles, there is a small amount of jitter/lag when
pinching or scrolling the main-frame, but not enough to impair
functionality.

Note this CL also resolves the issues for desktop handles not updating
after pinch as well.

Bug: 809122
Change-Id: I120386c3d7a0d87dacc655e83b07e0cfeaf4920a
Reviewed-on: https://chromium-review.googlesource.com/c/1259945
Commit-Queue: James MacLean <wjmaclean@chromium.org>
Reviewed-by: default avatarKen Buchanan <kenrb@chromium.org>
Cr-Commit-Position: refs/heads/master@{#600412}
parent 6971239a
...@@ -35,40 +35,32 @@ void TouchSelectionControllerClientChildFrame::DidStopFlinging() { ...@@ -35,40 +35,32 @@ void TouchSelectionControllerClientChildFrame::DidStopFlinging() {
manager_->DidStopFlinging(); manager_->DidStopFlinging();
} }
void TouchSelectionControllerClientChildFrame::
TransformSelectionBoundsAndUpdate() {
gfx::SelectionBound transformed_selection_start(selection_start_);
gfx::SelectionBound transformed_selection_end(selection_end_);
// TODO(wjmaclean): Get the transform between the views to lower the
// overhead here, instead of calling the transform functions four times.
transformed_selection_start.SetEdge(
rwhv_->TransformPointToRootCoordSpaceF(selection_start_.edge_top()),
rwhv_->TransformPointToRootCoordSpaceF(selection_start_.edge_bottom()));
transformed_selection_end.SetEdge(
rwhv_->TransformPointToRootCoordSpaceF(selection_end_.edge_top()),
rwhv_->TransformPointToRootCoordSpaceF(selection_end_.edge_bottom()));
manager_->UpdateClientSelectionBounds(transformed_selection_start,
transformed_selection_end, this, this);
}
void TouchSelectionControllerClientChildFrame::UpdateSelectionBoundsIfNeeded( void TouchSelectionControllerClientChildFrame::UpdateSelectionBoundsIfNeeded(
const viz::Selection<gfx::SelectionBound>& selection, const viz::Selection<gfx::SelectionBound>& selection,
float device_scale_factor) { float device_scale_factor) {
gfx::PointF start_edge_top = selection.start.edge_top(); if (selection.start != selection_start_ || selection.end != selection_end_) {
gfx::PointF start_edge_bottom = selection.start.edge_bottom(); selection_start_ = selection.start;
gfx::PointF end_edge_top = selection.end.edge_top(); selection_end_ = selection.end;
gfx::PointF end_edge_bottom = selection.end.edge_bottom();
if (IsUseZoomForDSFEnabled()) {
float viewportToDIPScale = 1.0f / device_scale_factor;
start_edge_top.Scale(viewportToDIPScale);
start_edge_bottom.Scale(viewportToDIPScale);
end_edge_top.Scale(viewportToDIPScale);
end_edge_bottom.Scale(viewportToDIPScale);
}
gfx::PointF origin = rwhv_->TransformPointToRootCoordSpaceF(gfx::PointF()); TransformSelectionBoundsAndUpdate();
start_edge_top = rwhv_->TransformPointToRootCoordSpaceF(start_edge_top);
start_edge_bottom = rwhv_->TransformPointToRootCoordSpaceF(start_edge_bottom);
end_edge_top = rwhv_->TransformPointToRootCoordSpaceF(end_edge_top);
end_edge_bottom = rwhv_->TransformPointToRootCoordSpaceF(end_edge_bottom);
viz::Selection<gfx::SelectionBound> transformed_selection(selection);
transformed_selection.start.SetEdge(start_edge_top, start_edge_bottom);
transformed_selection.end.SetEdge(end_edge_top, end_edge_bottom);
if (transformed_selection.start != selection_start_ ||
transformed_selection.end != selection_end_) {
selection_start_ = transformed_selection.start;
selection_end_ = transformed_selection.end;
view_origin_at_last_update_ = origin;
manager_->UpdateClientSelectionBounds(selection_start_, selection_end_,
this, this);
} }
} }
...@@ -77,17 +69,7 @@ void TouchSelectionControllerClientChildFrame::UpdateSelectionBoundsIfNeeded( ...@@ -77,17 +69,7 @@ void TouchSelectionControllerClientChildFrame::UpdateSelectionBoundsIfNeeded(
// sending a new compositor frame), we must manually recompute the screen // sending a new compositor frame), we must manually recompute the screen
// position if requested to do so and it has changed. // position if requested to do so and it has changed.
void TouchSelectionControllerClientChildFrame::DidScroll() { void TouchSelectionControllerClientChildFrame::DidScroll() {
gfx::PointF origin = rwhv_->TransformPointToRootCoordSpaceF(gfx::PointF()); TransformSelectionBoundsAndUpdate();
if (origin != view_origin_at_last_update_) {
gfx::Vector2dF delta = origin - view_origin_at_last_update_;
selection_start_.SetEdge(selection_start_.edge_top() + delta,
selection_start_.edge_bottom() + delta);
selection_end_.SetEdge(selection_end_.edge_top() + delta,
selection_end_.edge_bottom() + delta);
view_origin_at_last_update_ = origin;
manager_->UpdateClientSelectionBounds(selection_start_, selection_end_,
this, this);
}
} }
gfx::Point TouchSelectionControllerClientChildFrame::ConvertFromRoot( gfx::Point TouchSelectionControllerClientChildFrame::ConvertFromRoot(
......
...@@ -37,6 +37,8 @@ class CONTENT_EXPORT TouchSelectionControllerClientChildFrame ...@@ -37,6 +37,8 @@ class CONTENT_EXPORT TouchSelectionControllerClientChildFrame
float device_scale_factor); float device_scale_factor);
private: private:
void TransformSelectionBoundsAndUpdate();
// ui::TouchSelectionControllerClient: // ui::TouchSelectionControllerClient:
bool SupportsAnimation() const override; bool SupportsAnimation() const override;
void SetNeedsAnimate() override; void SetNeedsAnimate() override;
...@@ -60,11 +62,9 @@ class CONTENT_EXPORT TouchSelectionControllerClientChildFrame ...@@ -60,11 +62,9 @@ class CONTENT_EXPORT TouchSelectionControllerClientChildFrame
RenderWidgetHostViewChildFrame* rwhv_; RenderWidgetHostViewChildFrame* rwhv_;
TouchSelectionControllerClientManager* manager_; TouchSelectionControllerClientManager* manager_;
// The last selection bounds reported by the view. // The last selection bounds reported by the view, in view coordinates.
gfx::SelectionBound selection_start_; gfx::SelectionBound selection_start_;
gfx::SelectionBound selection_end_; gfx::SelectionBound selection_end_;
// Keep track of the view origin as of the last time selection was updated.
gfx::PointF view_origin_at_last_update_;
DISALLOW_COPY_AND_ASSIGN(TouchSelectionControllerClientChildFrame); DISALLOW_COPY_AND_ASSIGN(TouchSelectionControllerClientChildFrame);
}; };
......
...@@ -4,19 +4,29 @@ ...@@ -4,19 +4,29 @@
#include "content/browser/renderer_host/input/touch_selection_controller_client_manager_android.h" #include "content/browser/renderer_host/input/touch_selection_controller_client_manager_android.h"
#include "components/viz/common/hit_test/aggregated_hit_test_region.h"
#include "components/viz/common/surfaces/frame_sink_id.h"
#include "components/viz/host/host_frame_sink_manager.h"
#include "content/browser/renderer_host/render_widget_host_view_android.h" #include "content/browser/renderer_host/render_widget_host_view_android.h"
namespace content { namespace content {
TouchSelectionControllerClientManagerAndroid:: TouchSelectionControllerClientManagerAndroid::
TouchSelectionControllerClientManagerAndroid( TouchSelectionControllerClientManagerAndroid(
RenderWidgetHostViewAndroid* rwhv) RenderWidgetHostViewAndroid* rwhv,
: rwhv_(rwhv), active_client_(rwhv) { viz::HostFrameSinkManager* host_frame_sink_manager)
: rwhv_(rwhv),
host_frame_sink_manager_(host_frame_sink_manager),
active_client_(rwhv) {
DCHECK(rwhv_); DCHECK(rwhv_);
DCHECK(host_frame_sink_manager_);
} }
TouchSelectionControllerClientManagerAndroid:: TouchSelectionControllerClientManagerAndroid::
~TouchSelectionControllerClientManagerAndroid() { ~TouchSelectionControllerClientManagerAndroid() {
if (active_client_ != rwhv_)
host_frame_sink_manager_->RemoveHitTestRegionObserver(this);
for (auto& observer : observers_) for (auto& observer : observers_)
observer.OnManagerWillDestroy(this); observer.OnManagerWillDestroy(this);
} }
...@@ -39,6 +49,16 @@ void TouchSelectionControllerClientManagerAndroid::UpdateClientSelectionBounds( ...@@ -39,6 +49,16 @@ void TouchSelectionControllerClientManagerAndroid::UpdateClientSelectionBounds(
return; return;
} }
// Since the observer method does very little processing, and early-outs when
// not displaying handles, we don't bother un-installing it when an OOPIF
// client is not currently displaying handles.
if (client != active_client_) {
if (active_client_ == rwhv_) // We are switching to an OOPIF client.
host_frame_sink_manager_->AddHitTestRegionObserver(this);
else if (client == rwhv_) // We are switching to a non-OOPIF client.
host_frame_sink_manager_->RemoveHitTestRegionObserver(this);
}
active_client_ = client; active_client_ = client;
manager_selection_start_ = start; manager_selection_start_ = start;
manager_selection_end_ = end; manager_selection_end_ = end;
...@@ -118,4 +138,19 @@ void TouchSelectionControllerClientManagerAndroid::DidScroll() { ...@@ -118,4 +138,19 @@ void TouchSelectionControllerClientManagerAndroid::DidScroll() {
// Nothing needs to be done here. // Nothing needs to be done here.
} }
void TouchSelectionControllerClientManagerAndroid::
OnAggregatedHitTestRegionListUpdated(
const viz::FrameSinkId& frame_sink_id,
const std::vector<viz::AggregatedHitTestRegion>& hit_test_data) {
DCHECK(active_client_ != rwhv_);
if (!GetTouchSelectionController() ||
GetTouchSelectionController()->active_status() ==
ui::TouchSelectionController::INACTIVE) {
return;
}
active_client_->DidScroll();
}
} // namespace content } // namespace content
...@@ -7,19 +7,30 @@ ...@@ -7,19 +7,30 @@
#include "base/macros.h" #include "base/macros.h"
#include "base/observer_list.h" #include "base/observer_list.h"
#include "components/viz/host/hit_test/hit_test_region_observer.h"
#include "content/public/browser/touch_selection_controller_client_manager.h" #include "content/public/browser/touch_selection_controller_client_manager.h"
#include "ui/touch_selection/touch_selection_controller.h" #include "ui/touch_selection/touch_selection_controller.h"
namespace viz {
class HostFrameSinkManager;
class FrameSinkId;
struct AggregatedHitTestRegion;
} // namespace viz
namespace content { namespace content {
class RenderWidgetHostViewAndroid; class RenderWidgetHostViewAndroid;
class TouchSelectionControllerClientManagerAndroid class TouchSelectionControllerClientManagerAndroid
: public TouchSelectionControllerClientManager, : public TouchSelectionControllerClientManager,
public ui::TouchSelectionControllerClient { public ui::TouchSelectionControllerClient,
public viz::HitTestRegionObserver {
public: public:
explicit TouchSelectionControllerClientManagerAndroid( explicit TouchSelectionControllerClientManagerAndroid(
RenderWidgetHostViewAndroid* rwhv); RenderWidgetHostViewAndroid* rwhv,
viz::HostFrameSinkManager* frame_host_sink_manager);
~TouchSelectionControllerClientManagerAndroid() override; ~TouchSelectionControllerClientManagerAndroid() override;
// TouchSelectionControllerClientManager implementation. // TouchSelectionControllerClientManager implementation.
...@@ -47,8 +58,17 @@ class TouchSelectionControllerClientManagerAndroid ...@@ -47,8 +58,17 @@ class TouchSelectionControllerClientManagerAndroid
std::unique_ptr<ui::TouchHandleDrawable> CreateDrawable() override; std::unique_ptr<ui::TouchHandleDrawable> CreateDrawable() override;
void DidScroll() override; void DidScroll() override;
// viz::HitTestRegionObserver implementation.
void OnAggregatedHitTestRegionListUpdated(
const viz::FrameSinkId& frame_sink_id,
const std::vector<viz::AggregatedHitTestRegion>& hit_test_data) override;
private: private:
// Neither of the following pointers are owned, and both are assumed to
// outlive this object.
RenderWidgetHostViewAndroid* rwhv_; RenderWidgetHostViewAndroid* rwhv_;
viz::HostFrameSinkManager* host_frame_sink_manager_;
TouchSelectionControllerClient* active_client_; TouchSelectionControllerClient* active_client_;
gfx::SelectionBound manager_selection_start_; gfx::SelectionBound manager_selection_start_;
gfx::SelectionBound manager_selection_end_; gfx::SelectionBound manager_selection_end_;
......
...@@ -212,7 +212,8 @@ RenderWidgetHostViewAndroid::RenderWidgetHostViewAndroid( ...@@ -212,7 +212,8 @@ RenderWidgetHostViewAndroid::RenderWidgetHostViewAndroid(
host()->SetView(this); host()->SetView(this);
touch_selection_controller_client_manager_ = touch_selection_controller_client_manager_ =
std::make_unique<TouchSelectionControllerClientManagerAndroid>(this); std::make_unique<TouchSelectionControllerClientManagerAndroid>(
this, CompositorImpl::GetHostFrameSinkManager());
UpdateNativeViewTree(parent_native_view); UpdateNativeViewTree(parent_native_view);
// This RWHVA may have been created speculatively. We should give any // This RWHVA may have been created speculatively. We should give any
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment