summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--base/gfx/point.cc6
-rw-r--r--base/gfx/point.h1
-rw-r--r--chrome/browser/views/find_bar_win.cc4
-rw-r--r--chrome/browser/views/fullscreen_exit_bubble.cc63
-rw-r--r--chrome/browser/views/fullscreen_exit_bubble.h18
5 files changed, 66 insertions, 26 deletions
diff --git a/base/gfx/point.cc b/base/gfx/point.cc
index cbe687b..8fb958e 100644
--- a/base/gfx/point.cc
+++ b/base/gfx/point.cc
@@ -20,6 +20,12 @@ Point::Point(int x, int y) : x_(x), y_(y) {
Point::Point(const POINT& point) : x_(point.x), y_(point.y) {
}
+Point& Point::operator=(const POINT& point) {
+ x_ = point.x;
+ y_ = point.y;
+ return *this;
+}
+
POINT Point::ToPOINT() const {
POINT p;
p.x = x_;
diff --git a/base/gfx/point.h b/base/gfx/point.h
index e930889..377efb1 100644
--- a/base/gfx/point.h
+++ b/base/gfx/point.h
@@ -26,6 +26,7 @@ class Point {
Point(int x, int y);
#if defined(OS_WIN)
explicit Point(const POINT& point);
+ Point& operator=(const POINT& point);
#elif defined(OS_MACOSX)
explicit Point(const CGPoint& point);
#endif
diff --git a/chrome/browser/views/find_bar_win.cc b/chrome/browser/views/find_bar_win.cc
index d85c2ef..69d2417 100644
--- a/chrome/browser/views/find_bar_win.cc
+++ b/chrome/browser/views/find_bar_win.cc
@@ -367,12 +367,12 @@ bool FindBarWin::GetFindBarWindowInfo(gfx::Point* position,
if (!find_bar_controller_ ||
!::IsWindow(GetNativeView()) ||
!::GetWindowRect(GetNativeView(), &window_rect)) {
- *position = gfx::Point(0, 0);
+ *position = gfx::Point();
*fully_visible = false;
return false;
}
- *position = gfx::Point(window_rect.TopLeft().x, window_rect.TopLeft().y);
+ *position = window_rect.TopLeft();
*fully_visible = IsVisible() && !IsAnimating();
return true;
}
diff --git a/chrome/browser/views/fullscreen_exit_bubble.cc b/chrome/browser/views/fullscreen_exit_bubble.cc
index 2525cfb..4146bbb 100644
--- a/chrome/browser/views/fullscreen_exit_bubble.cc
+++ b/chrome/browser/views/fullscreen_exit_bubble.cc
@@ -117,6 +117,7 @@ class FullscreenExitBubble::FullscreenExitPopup : public views::WidgetWin {
const double FullscreenExitBubble::kOpacity = 0.7;
const int FullscreenExitBubble::kInitialDelayMs = 2300;
+const int FullscreenExitBubble::kIdleTimeMs = 2300;
const int FullscreenExitBubble::kPositionCheckHz = 10;
const int FullscreenExitBubble::kSlideInRegionHeightPx = 4;
const int FullscreenExitBubble::kSlideInDurationMs = 350;
@@ -147,9 +148,16 @@ FullscreenExitBubble::FullscreenExitBubble(
popup_->SetContentsView(view_);
popup_->Show(); // This does not activate the popup.
- // Start the initial delay timer.
+ // Start the initial delay timer and begin watching the mouse.
initial_delay_.Start(base::TimeDelta::FromMilliseconds(kInitialDelayMs), this,
- &FullscreenExitBubble::AfterInitialDelay);
+ &FullscreenExitBubble::CheckMousePosition);
+ POINT cursor_pos;
+ GetCursorPos(&cursor_pos);
+ last_mouse_pos_ = cursor_pos;
+ views::View::ConvertPointToView(NULL, root_view_, &last_mouse_pos_);
+ mouse_position_checker_.Start(
+ base::TimeDelta::FromMilliseconds(1000 / kPositionCheckHz), this,
+ &FullscreenExitBubble::CheckMousePosition);
}
FullscreenExitBubble::~FullscreenExitBubble() {
@@ -186,14 +194,6 @@ void FullscreenExitBubble::AnimationEnded(
AnimationProgressed(animation);
}
-void FullscreenExitBubble::AfterInitialDelay() {
- // Check the mouse position immediately and every 50 ms afterwards.
- CheckMousePosition();
- mouse_position_checker_.Start(
- base::TimeDelta::FromMilliseconds(1000 / kPositionCheckHz), this,
- &FullscreenExitBubble::CheckMousePosition);
-}
-
void FullscreenExitBubble::CheckMousePosition() {
// Desired behavior:
//
@@ -203,29 +203,52 @@ void FullscreenExitBubble::CheckMousePosition() {
// | | Slide-out region
// : :
//
- // * If the mouse is in the slide-in region, we show the popup.
- // * If the mouse is in the slide-out region, we hide the popup.
- // * If the mouse is in the neutral region, we do nothing, except if the popup
- // is currently sliding out, in which case we show it again. This
- // facilitates users correcting us if they try to mouse horizontally towards
- // the popup and unintentionally drop too low.
+ // * If the mouse is offscreen or in the slide-out region, we hide the popup.
+ // * If the mouse goes idle, we hide the popup.
+ // * If the mouse is in the slide-in-region and not idle, we show the popup.
+ // * If the mouse is in the neutral region and not idle, and the popup is
+ // currently sliding out, we show it again. This facilitates users
+ // correcting us if they try to mouse horizontally towards the popup and
+ // unintentionally drop too low.
+ // * Otherwise, we do nothing, because the mouse is in the neutral region and
+ // either the popup is hidden or the mouse is not idle, so we don't want to
+ // change anything's state.
POINT cursor_pos;
GetCursorPos(&cursor_pos);
gfx::Point transformed_pos(cursor_pos);
views::View::ConvertPointToView(NULL, root_view_, &transformed_pos);
- gfx::Rect trigger_rect(GetPopupRect(true));
+
+ // Check to see whether the mouse is idle.
+ if (transformed_pos != last_mouse_pos_) {
+ // The mouse moved; reset the idle timer.
+ idle_timeout_.Stop(); // If the timer isn't running, this is a no-op.
+ idle_timeout_.Start(base::TimeDelta::FromMilliseconds(kIdleTimeMs), this,
+ &FullscreenExitBubble::CheckMousePosition);
+ }
+ last_mouse_pos_ = transformed_pos;
+
if (!root_view_->HitTest(transformed_pos) ||
- (cursor_pos.y >= trigger_rect.bottom())) {
- size_animation_->SetSlideDuration(kSlideOutDurationMs);
- size_animation_->Hide();
+ (cursor_pos.y >= GetPopupRect(true).bottom()) ||
+ !idle_timeout_.IsRunning()) {
+ // The cursor is offscreen, in the slide-out region, or idle.
+ Hide();
} else if ((cursor_pos.y < kSlideInRegionHeightPx) ||
(size_animation_->GetCurrentValue() != 0)) {
+ // The cursor is not idle, and either it's in the slide-in region or it's in
+ // the neutral region and we're sliding out.
size_animation_->SetSlideDuration(kSlideInDurationMs);
size_animation_->Show();
}
}
+void FullscreenExitBubble::Hide() {
+ if (!initial_delay_.IsRunning()) {
+ size_animation_->SetSlideDuration(kSlideOutDurationMs);
+ size_animation_->Hide();
+ }
+}
+
gfx::Rect FullscreenExitBubble::GetPopupRect(
bool ignore_animation_state) const {
gfx::Size size(view_->GetPreferredSize());
diff --git a/chrome/browser/views/fullscreen_exit_bubble.h b/chrome/browser/views/fullscreen_exit_bubble.h
index b5e6b1e..7e354bd 100644
--- a/chrome/browser/views/fullscreen_exit_bubble.h
+++ b/chrome/browser/views/fullscreen_exit_bubble.h
@@ -29,6 +29,7 @@ class FullscreenExitBubble : public views::LinkController,
static const double kOpacity; // Opacity of the bubble, 0.0 - 1.0
static const int kInitialDelayMs; // Initial time bubble remains onscreen
+ static const int kIdleTimeMs; // Time before mouse idle triggers hide
static const int kPositionCheckHz; // How fast to check the mouse position
static const int kSlideInRegionHeightPx;
// Height of region triggering slide-in
@@ -42,13 +43,14 @@ class FullscreenExitBubble : public views::LinkController,
virtual void AnimationProgressed(const Animation* animation);
virtual void AnimationEnded(const Animation* animation);
- // Called after the initial delay to start checking the mouse position.
- void AfterInitialDelay();
-
// Called repeatedly to get the current mouse position and animate the bubble
// on or off the screen as appropriate.
void CheckMousePosition();
+ // Hides the bubble. This is a separate function so it can be called by a
+ // timer.
+ void Hide();
+
// Returns the current desirable rect for the popup window. If
// |ignore_animation_state| is true this returns the rect assuming the popup
// is fully onscreen.
@@ -71,15 +73,23 @@ class FullscreenExitBubble : public views::LinkController,
// Animation controlling sliding into/out of the top of the screen.
scoped_ptr<SlideAnimation> size_animation_;
- // Timer to delay before starting the mouse checking/bubble hiding code.
+ // Timer to delay before allowing the bubble to hide after it's initially
+ // shown.
base::OneShotTimer<FullscreenExitBubble> initial_delay_;
+ // Timer to see how long the mouse has been idle.
+ base::OneShotTimer<FullscreenExitBubble> idle_timeout_;
+
// Timer to poll the current mouse position. We can't just listen for mouse
// events without putting a non-empty HWND onscreen (or hooking Windows, which
// has other problems), so instead we run a low-frequency poller to see if the
// user has moved in or out of our show/hide regions.
base::RepeatingTimer<FullscreenExitBubble> mouse_position_checker_;
+ // The most recently seen mouse position, in screen coordinates. Used to see
+ // if the mouse has moved since our last check.
+ gfx::Point last_mouse_pos_;
+
DISALLOW_COPY_AND_ASSIGN(FullscreenExitBubble);
};