Commit 4a6dca0f authored by wutao's avatar wutao Committed by Commit Bot

assistant: Scroll container when focus changes

Currently UiElementContainerView does not auto scroll when the focus in the
AssistantCardElementView changes, e.g. during Tab traversing.
This patch surfaces the OnFocusChangedInPage event from WebContentsImpl
to NavigableContentsObserver, so that the UiElementContainerView can do
scroll accordinglly.
In this patch, if the bounds of the focused node is clipped by the
container, it will scroll the node to the center of the container.

Bug: 966806
Test: manual
Change-Id: I974db35731b85fdcb957d9898ae921a12dbd7607
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1885253
Commit-Queue: Tao Wu <wutao@chromium.org>
Reviewed-by: default avatarCamille Lamy <clamy@chromium.org>
Reviewed-by: default avatarXiaohui Chen <xiaohuic@chromium.org>
Reviewed-by: default avatarKen Rockot <rockot@google.com>
Reviewed-by: default avatarSam McNally <sammc@chromium.org>
Reviewed-by: default avatarXiyuan Xia <xiyuan@chromium.org>
Cr-Commit-Position: refs/heads/master@{#713180}
parent 6e231975
...@@ -298,6 +298,9 @@ class SearchResultAnswerCardView::AnswerCardResultView ...@@ -298,6 +298,9 @@ class SearchResultAnswerCardView::AnswerCardResultView
base::RecordAction(base::UserMetricsAction("SearchAnswer_OpenedUrl")); base::RecordAction(base::UserMetricsAction("SearchAnswer_OpenedUrl"));
} }
void FocusedNodeChanged(bool is_editable_node,
const gfx::Rect& node_bounds_in_screen) override {}
SearchResultContainerView* const container_; // Not owned. SearchResultContainerView* const container_; // Not owned.
AppListViewDelegate* const view_delegate_; // Not owned. AppListViewDelegate* const view_delegate_; // Not owned.
mojo::Remote<content::mojom::NavigableContentsFactory> contents_factory_; mojo::Remote<content::mojom::NavigableContentsFactory> contents_factory_;
......
...@@ -155,6 +155,19 @@ void AssistantCardElementView::DidSuppressNavigation( ...@@ -155,6 +155,19 @@ void AssistantCardElementView::DidSuppressNavigation(
delegate_->OpenUrlFromView(url); delegate_->OpenUrlFromView(url);
} }
void AssistantCardElementView::FocusedNodeChanged(
bool is_editable_node,
const gfx::Rect& node_bounds_in_screen) {
// TODO(b/143985066): Card has element with empty bounds, e.g. the line break.
if (node_bounds_in_screen.IsEmpty())
return;
gfx::Point origin = node_bounds_in_screen.origin();
ConvertPointFromScreen(this, &origin);
gfx::Rect focused_rect_in_local(origin, node_bounds_in_screen.size());
ScrollRectToVisible(focused_rect_in_local);
}
void AssistantCardElementView::InitLayout( void AssistantCardElementView::InitLayout(
const AssistantCardElement* card_element) { const AssistantCardElement* card_element) {
SetFocusBehavior(FocusBehavior::ALWAYS); SetFocusBehavior(FocusBehavior::ALWAYS);
......
...@@ -39,6 +39,8 @@ class COMPONENT_EXPORT(ASSISTANT_UI) AssistantCardElementView ...@@ -39,6 +39,8 @@ class COMPONENT_EXPORT(ASSISTANT_UI) AssistantCardElementView
void DidSuppressNavigation(const GURL& url, void DidSuppressNavigation(const GURL& url,
WindowOpenDisposition disposition, WindowOpenDisposition disposition,
bool from_user_gesture) override; bool from_user_gesture) override;
void FocusedNodeChanged(bool is_editable_node,
const gfx::Rect& node_bounds_in_screen) override;
// Returns a reference to the native view associated with the underlying web // Returns a reference to the native view associated with the underlying web
// contents. When animating AssistantCardElementView, we should animate the // contents. When animating AssistantCardElementView, we should animate the
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
#include "base/macros.h" #include "base/macros.h"
#include "base/optional.h" #include "base/optional.h"
#include "content/public/browser/focused_node_details.h"
#include "content/public/browser/navigation_handle.h" #include "content/public/browser/navigation_handle.h"
#include "content/public/browser/render_view_host.h" #include "content/public/browser/render_view_host.h"
#include "content/public/browser/render_widget_host.h" #include "content/public/browser/render_widget_host.h"
...@@ -197,6 +198,11 @@ class NavigableContentsDelegateImpl : public content::NavigableContentsDelegate, ...@@ -197,6 +198,11 @@ class NavigableContentsDelegateImpl : public content::NavigableContentsDelegate,
client_->UpdateCanGoBack(can_go_back); client_->UpdateCanGoBack(can_go_back);
} }
void OnFocusChangedInPage(FocusedNodeDetails* details) override {
client_->FocusedNodeChanged(details->is_editable_node,
details->node_bounds_in_screen);
}
std::unique_ptr<WebContents> web_contents_; std::unique_ptr<WebContents> web_contents_;
mojom::NavigableContentsClient* const client_; mojom::NavigableContentsClient* const client_;
......
...@@ -106,6 +106,13 @@ void NavigableContents::UpdateContentAXTree(const ui::AXTreeID& id) { ...@@ -106,6 +106,13 @@ void NavigableContents::UpdateContentAXTree(const ui::AXTreeID& id) {
view_->NotifyAccessibilityTreeChange(); view_->NotifyAccessibilityTreeChange();
} }
void NavigableContents::FocusedNodeChanged(
bool is_editable_node,
const gfx::Rect& node_bounds_in_screen) {
for (auto& observer : observers_)
observer.FocusedNodeChanged(is_editable_node, node_bounds_in_screen);
}
void NavigableContents::OnEmbedTokenReceived( void NavigableContents::OnEmbedTokenReceived(
const base::UnguessableToken& token) { const base::UnguessableToken& token) {
DCHECK(view_); DCHECK(view_);
......
...@@ -85,6 +85,8 @@ class COMPONENT_EXPORT(CONTENT_SERVICE_CPP) NavigableContents ...@@ -85,6 +85,8 @@ class COMPONENT_EXPORT(CONTENT_SERVICE_CPP) NavigableContents
bool from_user_gesture) override; bool from_user_gesture) override;
void UpdateCanGoBack(bool can_go_back) override; void UpdateCanGoBack(bool can_go_back) override;
void UpdateContentAXTree(const ui::AXTreeID& id) override; void UpdateContentAXTree(const ui::AXTreeID& id) override;
void FocusedNodeChanged(bool is_editable_node,
const gfx::Rect& node_bounds_in_screen) override;
void OnEmbedTokenReceived(const base::UnguessableToken& token); void OnEmbedTokenReceived(const base::UnguessableToken& token);
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#include "base/observer_list_types.h" #include "base/observer_list_types.h"
#include "net/http/http_response_headers.h" #include "net/http/http_response_headers.h"
#include "ui/base/window_open_disposition.h" #include "ui/base/window_open_disposition.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/geometry/size.h" #include "ui/gfx/geometry/size.h"
#include "url/gurl.h" #include "url/gurl.h"
...@@ -28,6 +29,8 @@ class COMPONENT_EXPORT(CONTENT_SERVICE_CPP) NavigableContentsObserver ...@@ -28,6 +29,8 @@ class COMPONENT_EXPORT(CONTENT_SERVICE_CPP) NavigableContentsObserver
WindowOpenDisposition disposition, WindowOpenDisposition disposition,
bool from_user_gesture) {} bool from_user_gesture) {}
virtual void UpdateCanGoBack(bool can_go_back) {} virtual void UpdateCanGoBack(bool can_go_back) {}
virtual void FocusedNodeChanged(bool is_editable_node,
const gfx::Rect& node_bounds_in_screen) {}
}; };
} // namespace content } // namespace content
......
...@@ -86,4 +86,8 @@ interface NavigableContentsClient { ...@@ -86,4 +86,8 @@ interface NavigableContentsClient {
// Informs the client of the ID of the content area's accessibility tree // Informs the client of the ID of the content area's accessibility tree
// whenever it changes. // whenever it changes.
UpdateContentAXTree(ax.mojom.AXTreeID id); UpdateContentAXTree(ax.mojom.AXTreeID id);
// Informs the client that the focused DOM node has changed.
FocusedNodeChanged(bool is_editable_node,
gfx.mojom.Rect node_bounds_in_screen);
}; };
...@@ -45,6 +45,8 @@ class TestNavigableContentsClient : public mojom::NavigableContentsClient { ...@@ -45,6 +45,8 @@ class TestNavigableContentsClient : public mojom::NavigableContentsClient {
bool from_user_gesture) override {} bool from_user_gesture) override {}
void UpdateCanGoBack(bool can_go_back) override {} void UpdateCanGoBack(bool can_go_back) override {}
void UpdateContentAXTree(const ui::AXTreeID& id) override {} void UpdateContentAXTree(const ui::AXTreeID& id) override {}
void FocusedNodeChanged(bool is_editable_node,
const gfx::Rect& node_bounds_in_screen) override {}
DISALLOW_COPY_AND_ASSIGN(TestNavigableContentsClient); DISALLOW_COPY_AND_ASSIGN(TestNavigableContentsClient);
}; };
......
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