Commit 9c4c2fb3 authored by David Black's avatar David Black Committed by Commit Bot

Fix hover state when using ProactiveSuggestionsRichView.

The proactive suggestions entry point times out after a fixed interval.
When the entry point is hovered over, timeout is paused.

ProactiveSuggestionsRichView is not currently pausing timeout on hover
because the embedded web contents consume the events causing mouse
enter/exit to not be received by the embedding view.

To fix this, we'll use an EventMonitor on our views native window to
make sure we get the events we need to detect hover state.

Bug: b:145056104
Change-Id: I2588fe119addfe9577963d4c29baf566e9168336
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1938448Reviewed-by: default avatarTao Wu <wutao@chromium.org>
Commit-Queue: David Black <dmblack@google.com>
Cr-Commit-Position: refs/heads/master@{#721083}
parent aaf7e6c8
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#include "base/base64.h" #include "base/base64.h"
#include "chromeos/services/assistant/public/features.h" #include "chromeos/services/assistant/public/features.h"
#include "ui/aura/window.h" #include "ui/aura/window.h"
#include "ui/views/event_monitor.h"
#include "ui/views/layout/fill_layout.h" #include "ui/views/layout/fill_layout.h"
#include "ui/views/widget/widget.h" #include "ui/views/widget/widget.h"
...@@ -126,6 +127,50 @@ void ProactiveSuggestionsRichView::InitLayout() { ...@@ -126,6 +127,50 @@ void ProactiveSuggestionsRichView::InitLayout() {
contents_->Navigate(GURL(kDataUriPrefix + encoded_html)); contents_->Navigate(GURL(kDataUriPrefix + encoded_html));
} }
void ProactiveSuggestionsRichView::AddedToWidget() {
// Our embedded web contents will consume events that would otherwise reach
// our view so we need to use an EventMonitor to still receive them.
event_monitor_ = views::EventMonitor::CreateWindowMonitor(
this, GetWidget()->GetNativeWindow(),
{ui::ET_GESTURE_TAP, ui::ET_GESTURE_TAP_CANCEL, ui::ET_GESTURE_TAP_DOWN,
ui::ET_MOUSE_ENTERED, ui::ET_MOUSE_MOVED, ui::ET_MOUSE_EXITED});
}
void ProactiveSuggestionsRichView::OnMouseEntered(const ui::MouseEvent& event) {
// Our embedded web contents is expected to consume events that would
// otherwise reach our view. We instead handle these events in OnEvent().
NOTREACHED();
}
void ProactiveSuggestionsRichView::OnMouseExited(const ui::MouseEvent& event) {
// Our embedded web contents is expected to consume events that would
// otherwise reach our view. We instead handle these events in OnEvent().
NOTREACHED();
}
void ProactiveSuggestionsRichView::OnGestureEvent(ui::GestureEvent* event) {
// Our embedded web contents is expected to consume events that would
// otherwise reach our view. We instead handle these events in OnEvent().
NOTREACHED();
}
void ProactiveSuggestionsRichView::OnEvent(const ui::Event& event) {
switch (event.type()) {
case ui::ET_GESTURE_TAP:
case ui::ET_GESTURE_TAP_CANCEL:
case ui::ET_MOUSE_EXITED:
delegate()->OnProactiveSuggestionsViewHoverChanged(/*is_hovering=*/false);
break;
case ui::ET_GESTURE_TAP_DOWN:
case ui::ET_MOUSE_ENTERED:
delegate()->OnProactiveSuggestionsViewHoverChanged(/*is_hovering=*/true);
break;
default:
NOTREACHED();
break;
}
}
void ProactiveSuggestionsRichView::ShowWhenReady() { void ProactiveSuggestionsRichView::ShowWhenReady() {
// If no children have yet been added to the layout, the embedded web contents // If no children have yet been added to the layout, the embedded web contents
// has not yet finished loading. In this case, we'll set a flag and delay // has not yet finished loading. In this case, we'll set a flag and delay
......
...@@ -11,6 +11,11 @@ ...@@ -11,6 +11,11 @@
#include "mojo/public/cpp/bindings/remote.h" #include "mojo/public/cpp/bindings/remote.h"
#include "services/content/public/cpp/navigable_contents.h" #include "services/content/public/cpp/navigable_contents.h"
#include "services/content/public/cpp/navigable_contents_view.h" #include "services/content/public/cpp/navigable_contents_view.h"
#include "ui/events/event_observer.h"
namespace views {
class EventMonitor;
} // namespace views
namespace ash { namespace ash {
...@@ -19,6 +24,7 @@ class AssistantViewDelegate; ...@@ -19,6 +24,7 @@ class AssistantViewDelegate;
// Rich entry point for the proactive suggestions feature. // Rich entry point for the proactive suggestions feature.
class COMPONENT_EXPORT(ASSISTANT_UI) ProactiveSuggestionsRichView class COMPONENT_EXPORT(ASSISTANT_UI) ProactiveSuggestionsRichView
: public ProactiveSuggestionsView, : public ProactiveSuggestionsView,
public ui::EventObserver,
public content::NavigableContentsObserver { public content::NavigableContentsObserver {
public: public:
explicit ProactiveSuggestionsRichView(AssistantViewDelegate* delegate); explicit ProactiveSuggestionsRichView(AssistantViewDelegate* delegate);
...@@ -30,9 +36,17 @@ class COMPONENT_EXPORT(ASSISTANT_UI) ProactiveSuggestionsRichView ...@@ -30,9 +36,17 @@ class COMPONENT_EXPORT(ASSISTANT_UI) ProactiveSuggestionsRichView
// ProactiveSuggestionsView: // ProactiveSuggestionsView:
const char* GetClassName() const override; const char* GetClassName() const override;
void InitLayout() override; void InitLayout() override;
void AddedToWidget() override;
void ShowWhenReady() override; void ShowWhenReady() override;
void Hide() override; void Hide() override;
void Close() override; void Close() override;
void OnMouseEntered(const ui::MouseEvent& event) override;
void OnMouseExited(const ui::MouseEvent& event) override;
void OnGestureEvent(ui::GestureEvent* event) override;
// ui::EventObserver:
using views::View::OnEvent; // Suppress clang warning.
void OnEvent(const ui::Event& event) override;
// content::NavigableContentsObserver: // content::NavigableContentsObserver:
void DidAutoResizeView(const gfx::Size& new_size) override; void DidAutoResizeView(const gfx::Size& new_size) override;
...@@ -44,6 +58,7 @@ class COMPONENT_EXPORT(ASSISTANT_UI) ProactiveSuggestionsRichView ...@@ -44,6 +58,7 @@ class COMPONENT_EXPORT(ASSISTANT_UI) ProactiveSuggestionsRichView
private: private:
mojo::Remote<content::mojom::NavigableContentsFactory> contents_factory_; mojo::Remote<content::mojom::NavigableContentsFactory> contents_factory_;
std::unique_ptr<content::NavigableContents> contents_; std::unique_ptr<content::NavigableContents> contents_;
std::unique_ptr<views::EventMonitor> event_monitor_;
// Because the web contents that this view embeds loads asynchronously, it // Because the web contents that this view embeds loads asynchronously, it
// may cause UI jank if we show our widget before loading has stopped. To // may cause UI jank if we show our widget before loading has stopped. To
......
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