Commit 2bbad6bf authored by Yuwei Huang's avatar Yuwei Huang Committed by Commit Bot

[Fullscreen Control] Fixing the touch behavior

* Fix the issue of |input_entry_method_| not being reset to NOT_ACTIVE
  when the popup is hidden.
* Use ET_GESTURE_LONG_PRESS instead of ET_GESTURE_LONG_TAP so that
  animation is triggered before the tap is released.
* Add auto timeout to the popup when it is triggered by touch.
* Hide the popup when it is triggered by touch and the user touches
  outside of the popup.

Bug: 758456
Change-Id: Id2cb6642a4e9129a096c5025d5695aeacf304717
Reviewed-on: https://chromium-review.googlesource.com/775734Reviewed-by: default avatarRobert Liao <robliao@chromium.org>
Commit-Queue: Yuwei Huang <yuweih@chromium.org>
Cr-Commit-Position: refs/heads/master@{#517256}
parent 0ba80d49
......@@ -37,46 +37,28 @@ constexpr float kExitHeightScaleFactor = 1.5f;
// +----------------------------+
constexpr float kShowFullscreenExitControlHeight = 3.f;
// Time to wait to hide the popup when it is triggered by touch input.
constexpr int kTouchPopupTimeoutMs = 3000;
} // namespace
FullscreenControlHost::FullscreenControlHost(BrowserView* browser_view,
views::View* host_view)
: browser_view_(browser_view),
fullscreen_control_popup_(browser_view->GetBubbleParentView(),
base::Bind(&BrowserView::ExitFullscreen,
base::Unretained(browser_view))) {}
fullscreen_control_popup_(
browser_view->GetBubbleParentView(),
base::Bind(&BrowserView::ExitFullscreen,
base::Unretained(browser_view)),
base::Bind(&FullscreenControlHost::OnVisibilityChanged,
base::Unretained(this))) {}
FullscreenControlHost::~FullscreenControlHost() = default;
void FullscreenControlHost::OnMouseEvent(ui::MouseEvent* event) {
if (event->type() == ui::ET_MOUSE_MOVED)
HandleFullScreenControlVisibility(event, InputEntryMethod::MOUSE);
}
void FullscreenControlHost::OnTouchEvent(ui::TouchEvent* event) {
if (event->type() == ui::ET_TOUCH_MOVED)
HandleFullScreenControlVisibility(event, InputEntryMethod::TOUCH);
}
void FullscreenControlHost::OnGestureEvent(ui::GestureEvent* event) {
if (event->type() == ui::ET_GESTURE_LONG_TAP)
HandleFullScreenControlVisibility(event, InputEntryMethod::TOUCH);
}
void FullscreenControlHost::Hide(bool animate) {
fullscreen_control_popup_.Hide(animate);
}
bool FullscreenControlHost::IsVisible() const {
return fullscreen_control_popup_.IsVisible();
}
void FullscreenControlHost::HandleFullScreenControlVisibility(
const ui::LocatedEvent* event,
InputEntryMethod input_entry_method) {
if (fullscreen_control_popup_.IsAnimating() ||
if (event->type() != ui::ET_MOUSE_MOVED ||
fullscreen_control_popup_.IsAnimating() ||
(input_entry_method_ != InputEntryMethod::NOT_ACTIVE &&
input_entry_method_ != input_entry_method)) {
input_entry_method_ != InputEntryMethod::MOUSE)) {
return;
}
......@@ -88,16 +70,43 @@ void FullscreenControlHost::HandleFullScreenControlVisibility(
if (event->y() >= y_limit)
Hide(true);
} else {
if (event->y() <= kShowFullscreenExitControlHeight ||
event->type() == ui::ET_GESTURE_LONG_TAP) {
ShowForInputEntryMethod(input_entry_method);
}
if (event->y() <= kShowFullscreenExitControlHeight)
ShowForInputEntryMethod(InputEntryMethod::MOUSE);
}
} else if (IsVisible()) {
Hide(true);
}
}
void FullscreenControlHost::OnTouchEvent(ui::TouchEvent* event) {
// Hide the popup if the popup is showing and the user touches outside of the
// popup.
if (event->type() == ui::ET_TOUCH_PRESSED && IsVisible() &&
!fullscreen_control_popup_.IsAnimating() &&
input_entry_method_ == InputEntryMethod::TOUCH) {
Hide(true);
}
}
void FullscreenControlHost::OnGestureEvent(ui::GestureEvent* event) {
if (event->type() == ui::ET_GESTURE_LONG_PRESS &&
browser_view_->IsFullscreen() && !IsVisible()) {
ShowForInputEntryMethod(InputEntryMethod::TOUCH);
touch_timeout_timer_.Start(
FROM_HERE, base::TimeDelta::FromMilliseconds(kTouchPopupTimeoutMs),
base::Bind(&FullscreenControlHost::OnTouchPopupTimeout,
base::Unretained(this)));
}
}
void FullscreenControlHost::Hide(bool animate) {
fullscreen_control_popup_.Hide(animate);
}
bool FullscreenControlHost::IsVisible() const {
return fullscreen_control_popup_.IsVisible();
}
void FullscreenControlHost::ShowForInputEntryMethod(
InputEntryMethod input_entry_method) {
input_entry_method_ = input_entry_method;
......@@ -106,3 +115,15 @@ void FullscreenControlHost::ShowForInputEntryMethod(
bubble->HideImmediately();
fullscreen_control_popup_.Show(browser_view_->GetClientAreaBoundsInScreen());
}
void FullscreenControlHost::OnVisibilityChanged() {
if (!IsVisible())
input_entry_method_ = InputEntryMethod::NOT_ACTIVE;
}
void FullscreenControlHost::OnTouchPopupTimeout() {
if (IsVisible() && !fullscreen_control_popup_.IsAnimating() &&
input_entry_method_ == InputEntryMethod::TOUCH) {
Hide(true);
}
}
......@@ -6,6 +6,7 @@
#define CHROME_BROWSER_UI_VIEWS_FULLSCREEN_CONTROL_FULLSCREEN_CONTROL_HOST_H_
#include "base/macros.h"
#include "base/timer/timer.h"
#include "chrome/browser/ui/views/fullscreen_control/fullscreen_control_popup.h"
#include "ui/events/event_handler.h"
......@@ -13,7 +14,6 @@ class BrowserView;
class FullscreenControlView;
namespace ui {
class LocatedEvent;
class GestureEvent;
class MouseEvent;
class TouchEvent;
......@@ -52,15 +52,16 @@ class FullscreenControlHost : public ui::EventHandler {
TOUCH, // A touch event caused the view to show.
};
void HandleFullScreenControlVisibility(const ui::LocatedEvent* event,
InputEntryMethod input_entry_method);
void ShowForInputEntryMethod(InputEntryMethod input_entry_method);
void OnVisibilityChanged();
void OnTouchPopupTimeout();
InputEntryMethod input_entry_method_ = InputEntryMethod::NOT_ACTIVE;
BrowserView* const browser_view_;
FullscreenControlPopup fullscreen_control_popup_;
base::OneShotTimer touch_timeout_timer_;
DISALLOW_COPY_AND_ASSIGN(FullscreenControlHost);
};
......
......@@ -39,10 +39,13 @@ std::unique_ptr<views::Widget> CreatePopupWidget(gfx::NativeView parent_view,
FullscreenControlPopup::FullscreenControlPopup(
gfx::NativeView parent_view,
const base::RepeatingClosure& on_button_pressed)
const base::RepeatingClosure& on_button_pressed,
const base::RepeatingClosure& on_visibility_changed)
: control_view_(new FullscreenControlView(on_button_pressed)),
popup_(CreatePopupWidget(parent_view, control_view_)),
animation_(std::make_unique<gfx::SlideAnimation>(this)) {
animation_(std::make_unique<gfx::SlideAnimation>(this)),
on_visibility_changed_(on_visibility_changed) {
DCHECK(on_visibility_changed_);
animation_->Reset(0);
}
......@@ -61,6 +64,8 @@ void FullscreenControlPopup::Show(const gfx::Rect& parent_bounds_in_screen) {
// to prevent potential flickering.
AnimationProgressed(animation_.get());
popup_->Show();
OnVisibilityChanged();
}
void FullscreenControlPopup::Hide(bool animated) {
......@@ -113,6 +118,7 @@ void FullscreenControlPopup::AnimationEnded(const gfx::Animation* animation) {
// It's the end of the reversed animation. Just hide the popup in this case.
parent_bounds_in_screen_ = gfx::Rect();
popup_->Hide();
OnVisibilityChanged();
return;
}
AnimationProgressed(animation);
......@@ -127,3 +133,7 @@ gfx::Rect FullscreenControlPopup::CalculateBounds(int y_offset) const {
parent_bounds_in_screen_.y() + y_offset);
return {origin, control_view_->GetPreferredSize()};
}
void FullscreenControlPopup::OnVisibilityChanged() {
on_visibility_changed_.Run();
}
......@@ -7,7 +7,7 @@
#include <memory>
#include "base/callback_forward.h"
#include "base/callback.h"
#include "base/macros.h"
#include "ui/gfx/animation/animation_delegate.h"
#include "ui/gfx/animation/slide_animation.h"
......@@ -25,7 +25,8 @@ class FullscreenControlView;
class FullscreenControlPopup : public gfx::AnimationDelegate {
public:
FullscreenControlPopup(gfx::NativeView parent_view,
const base::RepeatingClosure& on_button_pressed);
const base::RepeatingClosure& on_button_pressed,
const base::RepeatingClosure& on_visibility_changed);
~FullscreenControlPopup() override;
// Shows the indicator with an animation that drops it off the top of
......@@ -61,6 +62,8 @@ class FullscreenControlPopup : public gfx::AnimationDelegate {
gfx::Rect CalculateBounds(int y_offset) const;
void OnVisibilityChanged();
FullscreenControlView* const control_view_;
const std::unique_ptr<views::Widget> popup_;
const std::unique_ptr<gfx::SlideAnimation> animation_;
......@@ -68,6 +71,8 @@ class FullscreenControlPopup : public gfx::AnimationDelegate {
// The bounds is empty when the popup is not showing.
gfx::Rect parent_bounds_in_screen_;
const base::RepeatingClosure on_visibility_changed_;
DISALLOW_COPY_AND_ASSIGN(FullscreenControlPopup);
};
......
......@@ -29,7 +29,8 @@ class FullscreenControlPopupTest : public views::test::WidgetTest {
parent_widget_->SetBounds(gfx::Rect(100, 100, 640, 480));
parent_widget_->Show();
popup_ = std::make_unique<FullscreenControlPopup>(
parent_widget_->GetNativeView(), base::BindRepeating(&base::DoNothing));
parent_widget_->GetNativeView(), base::BindRepeating(&base::DoNothing),
base::BindRepeating(&base::DoNothing));
animation_api_ = std::make_unique<gfx::AnimationTestApi>(
popup_->GetAnimationForTesting());
}
......
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