diff options
author | tdanderson@google.com <tdanderson@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-05-06 20:16:00 +0000 |
---|---|---|
committer | tdanderson@google.com <tdanderson@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-05-06 20:16:00 +0000 |
commit | a01746e1507b0b2256eebced9c7d892b8712a654 (patch) | |
tree | bf46dd6b4c4bb54b2bdfc5f4195e17abbc018e3f /ash | |
parent | 8136b62262f65e6053cbf2d0ee45a9fc9a43c051 (diff) | |
download | chromium_src-a01746e1507b0b2256eebced9c7d892b8712a654.zip chromium_src-a01746e1507b0b2256eebced9c7d892b8712a654.tar.gz chromium_src-a01746e1507b0b2256eebced9c7d892b8712a654.tar.bz2 |
Notify all visible renderers when the visibility of the mouse cursor changes
Blink side patch:
https://codereview.chromium.org/14047016/
The ultimate goal of both patches is to disallow new hover
effects from being invoked in web contents when the mouse
cursor is not visible to the user (i.e., while touch
scrolling). The job of this patch is to communicate the
cursor visibility state to all visible renderers using
the new IPC InputMsg_CursorVisibilityChange whenever the
visibility state changes.
Added the new observer type CursorClientObserver.
Subscribers (instances of RenderWidgetHostViewAura) are
notified whenever the cursor visibility changes, at which
point the IPC is sent to the renderer.
I have also removed the code in ash_native_cursor_manager.cc
that sets the mouse cursor location to the bogus value
of (-10000,-10000) when mouse events are disabled; afaik
this was originally added as a way to prevent unwanted
hover effects in web contents but it does not work in all
cases and causes other problems (see crbug.com/174358).
BUG=153784,174358
R=jamesr@chromium.org, kenrb@chromium.org, oshima@chromium.org, sky@chromium.org
Review URL: https://codereview.chromium.org/14047015
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@198519 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ash')
-rw-r--r-- | ash/wm/ash_native_cursor_manager.cc | 6 | ||||
-rw-r--r-- | ash/wm/window_manager_unittest.cc | 84 |
2 files changed, 84 insertions, 6 deletions
diff --git a/ash/wm/ash_native_cursor_manager.cc b/ash/wm/ash_native_cursor_manager.cc index be9c6b7..dd72af1 100644 --- a/ash/wm/ash_native_cursor_manager.cc +++ b/ash/wm/ash_native_cursor_manager.cc @@ -13,10 +13,6 @@ namespace { -// The coordinate of the cursor used when the mouse events are disabled. -const int kDisabledCursorLocationX = -10000; -const int kDisabledCursorLocationY = -10000; - void SetCursorOnAllRootWindows(gfx::NativeCursor cursor) { ash::Shell::RootWindowList root_windows = ash::Shell::GetInstance()->GetAllRootWindows(); @@ -99,8 +95,6 @@ void AshNativeCursorManager::SetMouseEventsEnabled( disabled_cursor_location_); } else { disabled_cursor_location_ = aura::Env::GetInstance()->last_mouse_location(); - aura::Env::GetInstance()->set_last_mouse_location( - gfx::Point(kDisabledCursorLocationX, kDisabledCursorLocationY)); } SetVisibility(delegate->GetCurrentVisibility(), delegate); diff --git a/ash/wm/window_manager_unittest.cc b/ash/wm/window_manager_unittest.cc index e12c9db..936b29a 100644 --- a/ash/wm/window_manager_unittest.cc +++ b/ash/wm/window_manager_unittest.cc @@ -11,6 +11,7 @@ #include "ash/wm/window_util.h" #include "ui/aura/client/activation_client.h" #include "ui/aura/client/activation_delegate.h" +#include "ui/aura/client/cursor_client_observer.h" #include "ui/aura/client/focus_client.h" #include "ui/aura/env.h" #include "ui/aura/root_window.h" @@ -30,6 +31,28 @@ namespace { +class TestingCursorClientObserver : public aura::client::CursorClientObserver { + public: + TestingCursorClientObserver() + : cursor_visibility_(false), + did_visibility_change_(false) {} + void reset() { cursor_visibility_ = did_visibility_change_ = false; } + bool is_cursor_visible() const { return cursor_visibility_; } + bool did_visibility_change() const { return did_visibility_change_; } + + // Overridden from aura::client::CursorClientObserver: + virtual void OnCursorVisibilityChanged(bool is_visible) OVERRIDE { + cursor_visibility_ = is_visible; + did_visibility_change_ = true; + } + + private: + bool cursor_visibility_; + bool did_visibility_change_; + + DISALLOW_COPY_AND_ASSIGN(TestingCursorClientObserver); +}; + base::TimeDelta getTime() { return ui::EventTimeForNow(); } @@ -753,4 +776,65 @@ TEST_F(WindowManagerTest, UpdateCursorVisibilityOnKeyEvent) { EXPECT_TRUE(cursor_manager->IsMouseEventsEnabled()); } +TEST_F(WindowManagerTest, TestCursorClientObserver) { + aura::test::EventGenerator& generator = GetEventGenerator(); + views::corewm::CursorManager* cursor_manager = + ash::Shell::GetInstance()->cursor_manager(); + + scoped_ptr<aura::Window> w1(CreateTestWindowInShell( + SK_ColorWHITE, -1, gfx::Rect(0, 0, 100, 100))); + wm::ActivateWindow(w1.get()); + + // Add two observers. Both should have OnCursorVisibilityChanged() + // invoked when an event changes the visibility of the cursor. + TestingCursorClientObserver observer_a; + TestingCursorClientObserver observer_b; + cursor_manager->AddObserver(&observer_a); + cursor_manager->AddObserver(&observer_b); + + // Initial state before any events have been sent. + observer_a.reset(); + observer_b.reset(); + EXPECT_FALSE(observer_a.did_visibility_change()); + EXPECT_FALSE(observer_b.did_visibility_change()); + EXPECT_FALSE(observer_a.is_cursor_visible()); + EXPECT_FALSE(observer_b.is_cursor_visible()); + + // Keypress should hide the cursor. + generator.PressKey(ui::VKEY_A, ui::EF_NONE); + EXPECT_TRUE(observer_a.did_visibility_change()); + EXPECT_TRUE(observer_b.did_visibility_change()); + EXPECT_FALSE(observer_a.is_cursor_visible()); + EXPECT_FALSE(observer_b.is_cursor_visible()); + + // Mouse move should show the cursor. + observer_a.reset(); + observer_b.reset(); + generator.MoveMouseTo(50, 50); + EXPECT_TRUE(observer_a.did_visibility_change()); + EXPECT_TRUE(observer_b.did_visibility_change()); + EXPECT_TRUE(observer_a.is_cursor_visible()); + EXPECT_TRUE(observer_b.is_cursor_visible()); + + // Remove observer_b. Its OnCursorVisibilityChanged() should + // not be invoked past this point. + cursor_manager->RemoveObserver(&observer_b); + + // Gesture tap should hide the cursor. + observer_a.reset(); + observer_b.reset(); + generator.GestureTapAt(gfx::Point(25, 25)); + EXPECT_TRUE(observer_a.did_visibility_change()); + EXPECT_FALSE(observer_b.did_visibility_change()); + EXPECT_FALSE(observer_a.is_cursor_visible()); + + // Mouse move should show the cursor. + observer_a.reset(); + observer_b.reset(); + generator.MoveMouseTo(50, 50); + EXPECT_TRUE(observer_a.did_visibility_change()); + EXPECT_FALSE(observer_b.did_visibility_change()); + EXPECT_TRUE(observer_a.is_cursor_visible()); +} + } // namespace ash |