[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/775734
Reviewed-by: Robert Liao <robliao@chromium.org>
Commit-Queue: Yuwei Huang <yuweih@chromium.org>
Cr-Commit-Position: refs/heads/master@{#517256}diff --git a/chrome/browser/ui/views/fullscreen_control/fullscreen_control_host.cc b/chrome/browser/ui/views/fullscreen_control/fullscreen_control_host.cc
index a01f68d2..94fda584 100644
--- a/chrome/browser/ui/views/fullscreen_control/fullscreen_control_host.cc
+++ b/chrome/browser/ui/views/fullscreen_control/fullscreen_control_host.cc
@@ -37,46 +37,28 @@
// +----------------------------+
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 @@
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 @@
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);
+ }
+}
diff --git a/chrome/browser/ui/views/fullscreen_control/fullscreen_control_host.h b/chrome/browser/ui/views/fullscreen_control/fullscreen_control_host.h
index 9368aba..9778193 100644
--- a/chrome/browser/ui/views/fullscreen_control/fullscreen_control_host.h
+++ b/chrome/browser/ui/views/fullscreen_control/fullscreen_control_host.h
@@ -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 FullscreenControlView;
namespace ui {
-class LocatedEvent;
class GestureEvent;
class MouseEvent;
class TouchEvent;
@@ -52,15 +52,16 @@
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);
};
diff --git a/chrome/browser/ui/views/fullscreen_control/fullscreen_control_popup.cc b/chrome/browser/ui/views/fullscreen_control/fullscreen_control_popup.cc
index 16e4d14a..c1fb9d5a 100644
--- a/chrome/browser/ui/views/fullscreen_control/fullscreen_control_popup.cc
+++ b/chrome/browser/ui/views/fullscreen_control/fullscreen_control_popup.cc
@@ -39,10 +39,13 @@
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 @@
// to prevent potential flickering.
AnimationProgressed(animation_.get());
popup_->Show();
+
+ OnVisibilityChanged();
}
void FullscreenControlPopup::Hide(bool animated) {
@@ -113,6 +118,7 @@
// 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 @@
parent_bounds_in_screen_.y() + y_offset);
return {origin, control_view_->GetPreferredSize()};
}
+
+void FullscreenControlPopup::OnVisibilityChanged() {
+ on_visibility_changed_.Run();
+}
diff --git a/chrome/browser/ui/views/fullscreen_control/fullscreen_control_popup.h b/chrome/browser/ui/views/fullscreen_control/fullscreen_control_popup.h
index b1e1c8c..9973087 100644
--- a/chrome/browser/ui/views/fullscreen_control/fullscreen_control_popup.h
+++ b/chrome/browser/ui/views/fullscreen_control/fullscreen_control_popup.h
@@ -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 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 @@
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 @@
// 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);
};
diff --git a/chrome/browser/ui/views/fullscreen_control/fullscreen_control_popup_unittest.cc b/chrome/browser/ui/views/fullscreen_control/fullscreen_control_popup_unittest.cc
index b4dc15f2..9ccb7c8 100644
--- a/chrome/browser/ui/views/fullscreen_control/fullscreen_control_popup_unittest.cc
+++ b/chrome/browser/ui/views/fullscreen_control/fullscreen_control_popup_unittest.cc
@@ -29,7 +29,8 @@
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());
}