summaryrefslogtreecommitdiffstats
path: root/ash
diff options
context:
space:
mode:
authormazda@chromium.org <mazda@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-12-19 16:43:53 +0000
committermazda@chromium.org <mazda@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-12-19 16:43:53 +0000
commit166ccde782c9603bfda23edd922d467a47f08cef (patch)
treefb2881a992d43b954927071812d78e77bb5ffccc /ash
parentf5e8479e80f090dd1a95e701bb1f38de6718523b (diff)
downloadchromium_src-166ccde782c9603bfda23edd922d467a47f08cef.zip
chromium_src-166ccde782c9603bfda23edd922d467a47f08cef.tar.gz
chromium_src-166ccde782c9603bfda23edd922d467a47f08cef.tar.bz2
Make the cursor have separate mode for disabled mouse events and invisible.
This CL adds the following APIs. * CursorClient::DisableMouseEvents: Makes mouse events stop being sent and hides the cursor if it is visible. (For now, DisableMouseEvents just clears the hover state and doesn't prevent mouse events from being generated, though). * CursorClient::EnableMouseEvents: Makes mouse events start being sent and shows the cursor if it was hidden with DisableMouseEvents. * CursorClient::HideCursor: Makes the cursor invisible. This changes only the cursor visibility and mouse events keep being sent even when the cursor is invisible. * CursorClient::ShowCursor: Makes the cursor visible. This does not take effect When mouse events are disabled. This CL just replaces the old usages of CursorClient::ShowCursor with the new APIs to retain existing behavior. I'll make another CL that uses these APIs in appropriate places. BUG=153703 TEST=CursorManagerTest.EnableDisableMouseEvents, CursorManagerTest.ShowAndEnable Review URL: https://chromiumcodereview.appspot.com/11412315 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@173933 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ash')
-rw-r--r--ash/display/mouse_cursor_event_filter_unittest.cc9
-rw-r--r--ash/magnifier/magnification_controller.cc4
-rw-r--r--ash/shell.cc2
-rw-r--r--ash/test/ash_test_base.cc2
-rw-r--r--ash/test/cursor_manager_test_api.cc6
-rw-r--r--ash/test/cursor_manager_test_api.h4
-rw-r--r--ash/tooltips/tooltip_controller_unittest.cc4
-rw-r--r--ash/wm/cursor_manager.cc182
-rw-r--r--ash/wm/cursor_manager.h40
-rw-r--r--ash/wm/cursor_manager_unittest.cc231
-rw-r--r--ash/wm/session_state_controller_impl.cc4
-rw-r--r--ash/wm/session_state_controller_impl2.cc6
-rw-r--r--ash/wm/window_manager_unittest.cc4
13 files changed, 405 insertions, 93 deletions
diff --git a/ash/display/mouse_cursor_event_filter_unittest.cc b/ash/display/mouse_cursor_event_filter_unittest.cc
index c9af25d..231a929 100644
--- a/ash/display/mouse_cursor_event_filter_unittest.cc
+++ b/ash/display/mouse_cursor_event_filter_unittest.cc
@@ -121,8 +121,7 @@ TEST_F(MouseCursorEventFilterTest, MAYBE_WarpMouseDifferentSizeDisplays) {
display_controller()->default_display_layout().position);
Shell::RootWindowList root_windows = Shell::GetAllRootWindows();
- aura::Env::GetInstance()->SetLastMouseLocation(*root_windows[1],
- gfx::Point(123, 123));
+ aura::Env::GetInstance()->set_last_mouse_location(gfx::Point(623, 123));
// Touch the left edge of the secondary root window. Pointer should NOT warp
// because 1px left of (0, 500) is outside the primary root window.
@@ -162,8 +161,7 @@ TEST_F(MouseCursorEventFilterTest, MAYBE_WarpMouseDifferentScaleDisplays) {
display_controller()->default_display_layout().position);
Shell::RootWindowList root_windows = Shell::GetAllRootWindows();
- aura::Env::GetInstance()->SetLastMouseLocation(*root_windows[1],
- gfx::Point(400, 123));
+ aura::Env::GetInstance()->set_last_mouse_location(gfx::Point(900, 123));
// This emulates the dragging back to the 2nd display, which has
// higher scale factor, by having 2nd display's root as target
@@ -199,8 +197,7 @@ TEST_F(MouseCursorEventFilterTest, MAYBE_SetMouseWarpModeFlag) {
Shell::GetInstance()->mouse_cursor_filter();
Shell::RootWindowList root_windows = Shell::GetAllRootWindows();
- aura::Env::GetInstance()->SetLastMouseLocation(*root_windows[0],
- gfx::Point(1, 1));
+ aura::Env::GetInstance()->set_last_mouse_location(gfx::Point(1, 1));
event_filter->set_mouse_warp_mode(MouseCursorEventFilter::WARP_NONE);
bool is_warped = event_filter->WarpMouseCursorIfNecessary(root_windows[0],
diff --git a/ash/magnifier/magnification_controller.cc b/ash/magnifier/magnification_controller.cc
index b7fd98d..9ee22de 100644
--- a/ash/magnifier/magnification_controller.cc
+++ b/ash/magnifier/magnification_controller.cc
@@ -343,7 +343,7 @@ void MagnificationControllerImpl::AfterAnimationMoveCursorTo(
// animation.
if (!cursor_client->IsCursorVisible())
return;
- cursor_client->ShowCursor(false);
+ cursor_client->DisableMouseEvents();
}
move_cursor_after_animation_ = true;
position_after_animation_ = location;
@@ -393,7 +393,7 @@ void MagnificationControllerImpl::OnImplicitAnimationsCompleted() {
aura::client::CursorClient* cursor_client =
aura::client::GetCursorClient(root_window_);
if (cursor_client)
- cursor_client->ShowCursor(true);
+ cursor_client->EnableMouseEvents();
}
is_on_animation_ = false;
diff --git a/ash/shell.cc b/ash/shell.cc
index 7e95abf..e99fd4e 100644
--- a/ash/shell.cc
+++ b/ash/shell.cc
@@ -564,7 +564,7 @@ void Shell::Init() {
user_wallpaper_delegate_->InitializeWallpaper();
if (initially_hide_cursor_)
- cursor_manager_.ShowCursor(false);
+ cursor_manager_.DisableMouseEvents();
cursor_manager_.SetCursor(ui::kCursorPointer);
// Cursor might have been hidden by somethign other than chrome.
diff --git a/ash/test/ash_test_base.cc b/ash/test/ash_test_base.cc
index f308e69..b9da0d7 100644
--- a/ash/test/ash_test_base.cc
+++ b/ash/test/ash_test_base.cc
@@ -65,7 +65,7 @@ void AshTestBase::SetUp() {
// Move the mouse cursor to far away so that native events doesn't
// interfere test expectations.
Shell::GetPrimaryRootWindow()->MoveCursorTo(gfx::Point(-1000, -1000));
- Shell::GetInstance()->cursor_manager()->ShowCursor(true);
+ Shell::GetInstance()->cursor_manager()->EnableMouseEvents();
}
void AshTestBase::TearDown() {
diff --git a/ash/test/cursor_manager_test_api.cc b/ash/test/cursor_manager_test_api.cc
index e992f9c..bd24b0d 100644
--- a/ash/test/cursor_manager_test_api.cc
+++ b/ash/test/cursor_manager_test_api.cc
@@ -17,11 +17,11 @@ CursorManagerTestApi::CursorManagerTestApi(CursorManager* cursor_manager)
CursorManagerTestApi::~CursorManagerTestApi() {
}
-gfx::NativeCursor CursorManagerTestApi::GetCurrentCursor() {
- return cursor_manager_->current_cursor_;
+gfx::NativeCursor CursorManagerTestApi::GetCurrentCursor() const {
+ return cursor_manager_->GetCurrentCursor();
}
-float CursorManagerTestApi::GetDeviceScaleFactor() {
+float CursorManagerTestApi::GetDeviceScaleFactor() const {
return cursor_manager_->image_cursors_->GetDeviceScaleFactor();
}
diff --git a/ash/test/cursor_manager_test_api.h b/ash/test/cursor_manager_test_api.h
index 5cb25ad..73a6e4c 100644
--- a/ash/test/cursor_manager_test_api.h
+++ b/ash/test/cursor_manager_test_api.h
@@ -20,8 +20,8 @@ class CursorManagerTestApi {
explicit CursorManagerTestApi(CursorManager* cursor_manager);
~CursorManagerTestApi();
- gfx::NativeCursor GetCurrentCursor();
- float GetDeviceScaleFactor();
+ gfx::NativeCursor GetCurrentCursor() const;
+ float GetDeviceScaleFactor() const;
private:
CursorManager* cursor_manager_;
diff --git a/ash/tooltips/tooltip_controller_unittest.cc b/ash/tooltips/tooltip_controller_unittest.cc
index a4b2be3..4426654 100644
--- a/ash/tooltips/tooltip_controller_unittest.cc
+++ b/ash/tooltips/tooltip_controller_unittest.cc
@@ -267,12 +267,12 @@ TEST_F(TooltipControllerTest, HideTooltipWhenCursorHidden) {
EXPECT_TRUE(IsTooltipVisible());
// Hide the cursor and check again.
- ash::Shell::GetInstance()->cursor_manager()->ShowCursor(false);
+ ash::Shell::GetInstance()->cursor_manager()->DisableMouseEvents();
FireTooltipTimer();
EXPECT_FALSE(IsTooltipVisible());
// Show the cursor and re-check.
- ash::Shell::GetInstance()->cursor_manager()->ShowCursor(true);
+ ash::Shell::GetInstance()->cursor_manager()->EnableMouseEvents();
FireTooltipTimer();
EXPECT_TRUE(IsTooltipVisible());
}
diff --git a/ash/wm/cursor_manager.cc b/ash/wm/cursor_manager.cc
index b251051..f0475e0 100644
--- a/ash/wm/cursor_manager.cc
+++ b/ash/wm/cursor_manager.cc
@@ -7,11 +7,16 @@
#include "ash/shell.h"
#include "ash/wm/image_cursors.h"
#include "base/logging.h"
+#include "ui/aura/env.h"
#include "ui/aura/root_window.h"
#include "ui/base/cursor/cursor.h"
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();
@@ -28,18 +33,72 @@ void NotifyCursorVisibilityChange(bool visible) {
(*iter)->OnCursorVisibilityChanged(visible);
}
+void NotifyMouseEventsEnableStateChange(bool enabled) {
+ ash::Shell::RootWindowList root_windows =
+ ash::Shell::GetInstance()->GetAllRootWindows();
+ for (ash::Shell::RootWindowList::iterator iter = root_windows.begin();
+ iter != root_windows.end(); ++iter)
+ (*iter)->OnMouseEventsEnableStateChanged(enabled);
+}
+
} // namespace
namespace ash {
+namespace internal {
+
+// Represents the cursor state which is composed of cursor type, visibility, and
+// mouse events enable state. When mouse events are disabled, the cursor is
+// always invisible.
+class CursorState {
+ public:
+ CursorState()
+ : cursor_(ui::kCursorNone),
+ visible_(true),
+ mouse_events_enabled_(true),
+ visible_on_mouse_events_enabled_(true) {
+ }
+
+ gfx::NativeCursor cursor() const { return cursor_; }
+ void set_cursor(gfx::NativeCursor cursor) { cursor_ = cursor; }
+
+ bool visible() const { return visible_; }
+ void SetVisible(bool visible) {
+ if (mouse_events_enabled_)
+ visible_ = visible;
+ // Ignores the call when mouse events disabled.
+ }
+
+ bool mouse_events_enabled() const { return mouse_events_enabled_; }
+ void SetMouseEventsEnabled(bool enabled) {
+ mouse_events_enabled_ = enabled;
+
+ // Restores the visibility when mouse events are enabled.
+ if (enabled) {
+ visible_ = visible_on_mouse_events_enabled_;
+ } else {
+ visible_on_mouse_events_enabled_ = visible_;
+ visible_ = false;
+ }
+ }
+
+
+ private:
+ gfx::NativeCursor cursor_;
+ bool visible_;
+ bool mouse_events_enabled_;
+
+ // The visibility to set when mouse events are enabled.
+ bool visible_on_mouse_events_enabled_;
+
+ DISALLOW_COPY_AND_ASSIGN(CursorState);
+};
+
+} // namespace internal
CursorManager::CursorManager()
: cursor_lock_count_(0),
- did_cursor_change_(false),
- cursor_to_set_on_unlock_(0),
- did_visibility_change_(false),
- show_on_unlock_(true),
- cursor_visible_(true),
- current_cursor_(ui::kCursorNone),
+ current_state_(new internal::CursorState),
+ state_on_unlock_(new internal::CursorState),
image_cursors_(new ImageCursors) {
}
@@ -47,30 +106,56 @@ CursorManager::~CursorManager() {
}
void CursorManager::SetCursor(gfx::NativeCursor cursor) {
- if (cursor_lock_count_ == 0) {
- SetCursorInternal(cursor);
- } else {
- cursor_to_set_on_unlock_ = cursor;
- did_cursor_change_ = true;
+ state_on_unlock_->set_cursor(cursor);
+ if (cursor_lock_count_ == 0 &&
+ GetCurrentCursor() != state_on_unlock_->cursor()) {
+ SetCursorInternal(state_on_unlock_->cursor());
}
}
-void CursorManager::ShowCursor(bool show) {
- if (cursor_lock_count_ == 0) {
- ShowCursorInternal(show);
- } else {
- show_on_unlock_ = show;
- did_visibility_change_ = true;
+void CursorManager::ShowCursor() {
+ state_on_unlock_->SetVisible(true);
+ if (cursor_lock_count_ == 0 &&
+ IsCursorVisible() != state_on_unlock_->visible()) {
+ SetCursorVisibility(state_on_unlock_->visible());
+ }
+}
+
+void CursorManager::HideCursor() {
+ state_on_unlock_->SetVisible(false);
+ if (cursor_lock_count_ == 0 &&
+ IsCursorVisible() != state_on_unlock_->visible()) {
+ SetCursorVisibility(state_on_unlock_->visible());
}
}
bool CursorManager::IsCursorVisible() const {
- return cursor_visible_;
+ return current_state_->visible();
+}
+
+void CursorManager::EnableMouseEvents() {
+ state_on_unlock_->SetMouseEventsEnabled(true);
+ if (cursor_lock_count_ == 0 &&
+ IsMouseEventsEnabled() != state_on_unlock_->mouse_events_enabled()) {
+ SetMouseEventsEnabled(state_on_unlock_->mouse_events_enabled());
+ }
+}
+
+void CursorManager::DisableMouseEvents() {
+ state_on_unlock_->SetMouseEventsEnabled(false);
+ if (cursor_lock_count_ == 0 &&
+ IsMouseEventsEnabled() != state_on_unlock_->mouse_events_enabled()) {
+ SetMouseEventsEnabled(state_on_unlock_->mouse_events_enabled());
+ }
+}
+
+bool CursorManager::IsMouseEventsEnabled() const {
+ return current_state_->mouse_events_enabled();
}
void CursorManager::SetDeviceScaleFactor(float device_scale_factor) {
if (image_cursors_->SetDeviceScaleFactor(device_scale_factor))
- SetCursorInternal(current_cursor_);
+ SetCursorInternal(GetCurrentCursor());
}
void CursorManager::LockCursor() {
@@ -83,41 +168,56 @@ void CursorManager::UnlockCursor() {
if (cursor_lock_count_ > 0)
return;
- if (did_cursor_change_)
- SetCursorInternal(cursor_to_set_on_unlock_);
- did_cursor_change_ = false;
- cursor_to_set_on_unlock_ = gfx::kNullCursor;
-
- if (did_visibility_change_)
- ShowCursorInternal(show_on_unlock_);
- did_visibility_change_ = false;
+ if (GetCurrentCursor() != state_on_unlock_->cursor())
+ SetCursorInternal(state_on_unlock_->cursor());
+ if (IsMouseEventsEnabled() != state_on_unlock_->mouse_events_enabled())
+ SetMouseEventsEnabled(state_on_unlock_->mouse_events_enabled());
+ if (IsCursorVisible() != state_on_unlock_->visible())
+ SetCursorVisibility(state_on_unlock_->visible());
}
void CursorManager::SetCursorInternal(gfx::NativeCursor cursor) {
- current_cursor_ = cursor;
- image_cursors_->SetPlatformCursor(&current_cursor_);
- current_cursor_.set_device_scale_factor(
- image_cursors_->GetDeviceScaleFactor());
+ gfx::NativeCursor new_cursor = cursor;
+ image_cursors_->SetPlatformCursor(&new_cursor);
+ new_cursor.set_device_scale_factor(image_cursors_->GetDeviceScaleFactor());
+ current_state_->set_cursor(new_cursor);
- if (cursor_visible_)
- SetCursorOnAllRootWindows(current_cursor_);
+ if (IsCursorVisible())
+ SetCursorOnAllRootWindows(GetCurrentCursor());
}
-void CursorManager::ShowCursorInternal(bool show) {
- if (cursor_visible_ == show)
- return;
-
- cursor_visible_ = show;
+void CursorManager::SetCursorVisibility(bool visible) {
+ current_state_->SetVisible(visible);
- if (show) {
- SetCursorInternal(current_cursor_);
+ if (visible) {
+ SetCursorInternal(GetCurrentCursor());
} else {
gfx::NativeCursor invisible_cursor(ui::kCursorNone);
image_cursors_->SetPlatformCursor(&invisible_cursor);
SetCursorOnAllRootWindows(invisible_cursor);
}
- NotifyCursorVisibilityChange(show);
+ NotifyCursorVisibilityChange(visible);
+}
+
+void CursorManager::SetMouseEventsEnabled(bool enabled) {
+ current_state_->SetMouseEventsEnabled(enabled);
+
+ if (enabled) {
+ aura::Env::GetInstance()->set_last_mouse_location(
+ disabled_cursor_location_);
+ } else {
+ disabled_cursor_location_ = aura::Env::GetInstance()->last_mouse_location();
+ aura::Env::GetInstance()->set_last_mouse_location(
+ gfx::Point(kDisabledCursorLocationX, kDisabledCursorLocationY));
+ }
+
+ SetCursorVisibility(current_state_->visible());
+ NotifyMouseEventsEnableStateChange(enabled);
+}
+
+gfx::NativeCursor CursorManager::GetCurrentCursor() const {
+ return current_state_->cursor();
}
} // namespace ash
diff --git a/ash/wm/cursor_manager.h b/ash/wm/cursor_manager.h
index 2eb2c68..774e450 100644
--- a/ash/wm/cursor_manager.h
+++ b/ash/wm/cursor_manager.h
@@ -11,9 +11,14 @@
#include "base/memory/scoped_ptr.h"
#include "ui/aura/client/cursor_client.h"
#include "ui/gfx/native_widget_types.h"
+#include "ui/gfx/point.h"
namespace ash {
+namespace internal {
+class CursorState;
+}
+
namespace test {
class CursorManagerTestApi;
}
@@ -32,8 +37,12 @@ class ASH_EXPORT CursorManager : public aura::client::CursorClient {
// Overridden from aura::client::CursorClient:
virtual void SetCursor(gfx::NativeCursor) OVERRIDE;
- virtual void ShowCursor(bool show) OVERRIDE;
+ virtual void ShowCursor() OVERRIDE;
+ virtual void HideCursor() OVERRIDE;
virtual bool IsCursorVisible() const OVERRIDE;
+ virtual void EnableMouseEvents() OVERRIDE;
+ virtual void DisableMouseEvents() OVERRIDE;
+ virtual bool IsMouseEventsEnabled() const OVERRIDE;
virtual void SetDeviceScaleFactor(float device_scale_factor) OVERRIDE;
virtual void LockCursor() OVERRIDE;
virtual void UnlockCursor() OVERRIDE;
@@ -42,31 +51,24 @@ class ASH_EXPORT CursorManager : public aura::client::CursorClient {
friend class test::CursorManagerTestApi;
void SetCursorInternal(gfx::NativeCursor cursor);
- void ShowCursorInternal(bool show);
+ void SetCursorVisibility(bool visible);
+ void SetMouseEventsEnabled(bool enabled);
+
+ // Returns the current cursor.
+ gfx::NativeCursor GetCurrentCursor() const;
// Number of times LockCursor() has been invoked without a corresponding
// UnlockCursor().
int cursor_lock_count_;
- // Set to true if SetCursor() is invoked while |cursor_lock_count_| == 0.
- bool did_cursor_change_;
-
- // Cursor to set once |cursor_lock_count_| is set to 0. Only valid if
- // |did_cursor_change_| is true.
- gfx::NativeCursor cursor_to_set_on_unlock_;
-
- // Set to true if ShowCursor() is invoked while |cursor_lock_count_| == 0.
- bool did_visibility_change_;
-
- // The visibility to set once |cursor_lock_count_| is set to 0. Only valid if
- // |did_visibility_change_| is true.
- bool show_on_unlock_;
+ // The cursor location where the cursor was disabled.
+ gfx::Point disabled_cursor_location_;
- // Is cursor visible?
- bool cursor_visible_;
+ // The current state of the cursor.
+ scoped_ptr<internal::CursorState> current_state_;
- // The cursor currently set.
- gfx::NativeCursor current_cursor_;
+ // The cursor state to restore when the cursor is unlocked.
+ scoped_ptr<internal::CursorState> state_on_unlock_;
scoped_ptr<ImageCursors> image_cursors_;
diff --git a/ash/wm/cursor_manager_unittest.cc b/ash/wm/cursor_manager_unittest.cc
index 7d82864..e31f3e0 100644
--- a/ash/wm/cursor_manager_unittest.cc
+++ b/ash/wm/cursor_manager_unittest.cc
@@ -8,10 +8,39 @@
#include "ash/test/ash_test_base.h"
#include "ash/test/cursor_manager_test_api.h"
#include "ash/wm/image_cursors.h"
+#include "ui/aura/root_window.h"
+#include "ui/aura/test/test_window_delegate.h"
+#include "ui/aura/test/test_windows.h"
+#include "ui/aura/window.h"
namespace ash {
namespace test {
+namespace {
+
+// A delegate for recording a mouse event location.
+class MouseEventLocationDelegate : public aura::test::TestWindowDelegate {
+ public:
+ MouseEventLocationDelegate() {}
+ virtual ~MouseEventLocationDelegate() {}
+
+ const gfx::Point& mouse_event_location() const {
+ return mouse_event_location_;
+ }
+
+ virtual void OnMouseEvent(ui::MouseEvent* event) OVERRIDE {
+ mouse_event_location_ = event->location();
+ event->SetHandled();
+ }
+
+ private:
+ gfx::Point mouse_event_location_;
+
+ DISALLOW_COPY_AND_ASSIGN(MouseEventLocationDelegate);
+};
+
+} // namespace
+
typedef test::AshTestBase CursorManagerTest;
TEST_F(CursorManagerTest, LockCursor) {
@@ -56,16 +85,16 @@ TEST_F(CursorManagerTest, SetCursor) {
EXPECT_TRUE(test_api.GetCurrentCursor().platform());
}
-TEST_F(CursorManagerTest, ShowCursor) {
+TEST_F(CursorManagerTest, ShowHideCursor) {
CursorManager* cursor_manager = Shell::GetInstance()->cursor_manager();
CursorManagerTestApi test_api(cursor_manager);
cursor_manager->SetCursor(ui::kCursorCopy);
EXPECT_EQ(ui::kCursorCopy, test_api.GetCurrentCursor().native_type());
- cursor_manager->ShowCursor(true);
+ cursor_manager->ShowCursor();
EXPECT_TRUE(cursor_manager->IsCursorVisible());
- cursor_manager->ShowCursor(false);
+ cursor_manager->HideCursor();
EXPECT_FALSE(cursor_manager->IsCursorVisible());
// The current cursor does not change even when the cursor is not shown.
EXPECT_EQ(ui::kCursorCopy, test_api.GetCurrentCursor().native_type());
@@ -73,14 +102,14 @@ TEST_F(CursorManagerTest, ShowCursor) {
// Check if cursor visibility is locked.
cursor_manager->LockCursor();
EXPECT_FALSE(cursor_manager->IsCursorVisible());
- cursor_manager->ShowCursor(true);
+ cursor_manager->ShowCursor();
EXPECT_FALSE(cursor_manager->IsCursorVisible());
cursor_manager->UnlockCursor();
EXPECT_TRUE(cursor_manager->IsCursorVisible());
cursor_manager->LockCursor();
EXPECT_TRUE(cursor_manager->IsCursorVisible());
- cursor_manager->ShowCursor(false);
+ cursor_manager->HideCursor();
EXPECT_TRUE(cursor_manager->IsCursorVisible());
cursor_manager->UnlockCursor();
EXPECT_FALSE(cursor_manager->IsCursorVisible());
@@ -88,21 +117,21 @@ TEST_F(CursorManagerTest, ShowCursor) {
// Checks setting visiblity while cursor is locked does not affect the
// subsequent uses of UnlockCursor.
cursor_manager->LockCursor();
- cursor_manager->ShowCursor(false);
+ cursor_manager->HideCursor();
cursor_manager->UnlockCursor();
EXPECT_FALSE(cursor_manager->IsCursorVisible());
- cursor_manager->ShowCursor(true);
+ cursor_manager->ShowCursor();
cursor_manager->LockCursor();
cursor_manager->UnlockCursor();
EXPECT_TRUE(cursor_manager->IsCursorVisible());
cursor_manager->LockCursor();
- cursor_manager->ShowCursor(true);
+ cursor_manager->ShowCursor();
cursor_manager->UnlockCursor();
EXPECT_TRUE(cursor_manager->IsCursorVisible());
- cursor_manager->ShowCursor(false);
+ cursor_manager->HideCursor();
cursor_manager->LockCursor();
cursor_manager->UnlockCursor();
EXPECT_FALSE(cursor_manager->IsCursorVisible());
@@ -118,5 +147,189 @@ TEST_F(CursorManagerTest, SetDeviceScaleFactor) {
EXPECT_EQ(1.0f, test_api.GetDeviceScaleFactor());
}
+// Verifies that LockCursor/UnlockCursor work correctly with
+// EnableMouseEvents and DisableMouseEvents
+TEST_F(CursorManagerTest, EnableDisableMouseEvents) {
+ CursorManager* cursor_manager = Shell::GetInstance()->cursor_manager();
+ CursorManagerTestApi test_api(cursor_manager);
+
+ cursor_manager->SetCursor(ui::kCursorCopy);
+ EXPECT_EQ(ui::kCursorCopy, test_api.GetCurrentCursor().native_type());
+
+ cursor_manager->EnableMouseEvents();
+ EXPECT_TRUE(cursor_manager->IsMouseEventsEnabled());
+ cursor_manager->DisableMouseEvents();
+ EXPECT_FALSE(cursor_manager->IsMouseEventsEnabled());
+ // The current cursor does not change even when the cursor is not shown.
+ EXPECT_EQ(ui::kCursorCopy, test_api.GetCurrentCursor().native_type());
+
+ // Check if cursor enable state is locked.
+ cursor_manager->LockCursor();
+ EXPECT_FALSE(cursor_manager->IsMouseEventsEnabled());
+ cursor_manager->EnableMouseEvents();
+ EXPECT_FALSE(cursor_manager->IsMouseEventsEnabled());
+ cursor_manager->UnlockCursor();
+ EXPECT_TRUE(cursor_manager->IsMouseEventsEnabled());
+
+ cursor_manager->LockCursor();
+ EXPECT_TRUE(cursor_manager->IsMouseEventsEnabled());
+ cursor_manager->DisableMouseEvents();
+ EXPECT_TRUE(cursor_manager->IsMouseEventsEnabled());
+ cursor_manager->UnlockCursor();
+ EXPECT_FALSE(cursor_manager->IsMouseEventsEnabled());
+
+ // Checks enabling cursor while cursor is locked does not affect the
+ // subsequent uses of UnlockCursor.
+ cursor_manager->LockCursor();
+ cursor_manager->DisableMouseEvents();
+ cursor_manager->UnlockCursor();
+ EXPECT_FALSE(cursor_manager->IsMouseEventsEnabled());
+
+ cursor_manager->EnableMouseEvents();
+ cursor_manager->LockCursor();
+ cursor_manager->UnlockCursor();
+ EXPECT_TRUE(cursor_manager->IsMouseEventsEnabled());
+
+ cursor_manager->LockCursor();
+ cursor_manager->EnableMouseEvents();
+ cursor_manager->UnlockCursor();
+ EXPECT_TRUE(cursor_manager->IsMouseEventsEnabled());
+
+ cursor_manager->DisableMouseEvents();
+ cursor_manager->LockCursor();
+ cursor_manager->UnlockCursor();
+ EXPECT_FALSE(cursor_manager->IsMouseEventsEnabled());
+}
+
+TEST_F(CursorManagerTest, IsMouseEventsEnabled) {
+ CursorManager* cursor_manager = Shell::GetInstance()->cursor_manager();
+ cursor_manager->EnableMouseEvents();
+ EXPECT_TRUE(cursor_manager->IsMouseEventsEnabled());
+ cursor_manager->DisableMouseEvents();
+ EXPECT_FALSE(cursor_manager->IsMouseEventsEnabled());
+}
+
+// Verifies that the mouse events enable state changes correctly when
+// ShowCursor/HideCursor and EnableMouseEvents/DisableMouseEvents are used
+// together.
+TEST_F(CursorManagerTest, ShowAndEnable) {
+ CursorManager* cursor_manager = Shell::GetInstance()->cursor_manager();
+
+ // Changing the visibility of the cursor does not affect the enable state.
+ cursor_manager->EnableMouseEvents();
+ cursor_manager->ShowCursor();
+ EXPECT_TRUE(cursor_manager->IsCursorVisible());
+ EXPECT_TRUE(cursor_manager->IsMouseEventsEnabled());
+ cursor_manager->HideCursor();
+ EXPECT_FALSE(cursor_manager->IsCursorVisible());
+ EXPECT_TRUE(cursor_manager->IsMouseEventsEnabled());
+ cursor_manager->ShowCursor();
+ EXPECT_TRUE(cursor_manager->IsCursorVisible());
+ EXPECT_TRUE(cursor_manager->IsMouseEventsEnabled());
+
+ // When mouse events are disabled, it also gets invisible.
+ EXPECT_TRUE(cursor_manager->IsCursorVisible());
+ cursor_manager->DisableMouseEvents();
+ EXPECT_FALSE(cursor_manager->IsCursorVisible());
+ EXPECT_FALSE(cursor_manager->IsMouseEventsEnabled());
+
+ // When mouse events are enabled, it restores the visibility state.
+ cursor_manager->EnableMouseEvents();
+ EXPECT_TRUE(cursor_manager->IsCursorVisible());
+ EXPECT_TRUE(cursor_manager->IsMouseEventsEnabled());
+
+ cursor_manager->ShowCursor();
+ cursor_manager->DisableMouseEvents();
+ EXPECT_FALSE(cursor_manager->IsCursorVisible());
+ EXPECT_FALSE(cursor_manager->IsMouseEventsEnabled());
+ cursor_manager->EnableMouseEvents();
+ EXPECT_TRUE(cursor_manager->IsCursorVisible());
+ EXPECT_TRUE(cursor_manager->IsMouseEventsEnabled());
+
+ cursor_manager->HideCursor();
+ cursor_manager->DisableMouseEvents();
+ EXPECT_FALSE(cursor_manager->IsCursorVisible());
+ EXPECT_FALSE(cursor_manager->IsMouseEventsEnabled());
+ cursor_manager->EnableMouseEvents();
+ EXPECT_FALSE(cursor_manager->IsCursorVisible());
+ EXPECT_TRUE(cursor_manager->IsMouseEventsEnabled());
+
+ // When mouse events are disabled, ShowCursor is ignored.
+ cursor_manager->DisableMouseEvents();
+ EXPECT_FALSE(cursor_manager->IsCursorVisible());
+ EXPECT_FALSE(cursor_manager->IsMouseEventsEnabled());
+ cursor_manager->ShowCursor();
+ EXPECT_FALSE(cursor_manager->IsCursorVisible());
+ EXPECT_FALSE(cursor_manager->IsMouseEventsEnabled());
+ cursor_manager->DisableMouseEvents();
+ EXPECT_FALSE(cursor_manager->IsCursorVisible());
+ EXPECT_FALSE(cursor_manager->IsMouseEventsEnabled());
+}
+
+#if defined(OS_WIN)
+// Temporarily disabled for windows. See crbug.com/112222.
+#define MAYBE_DisabledMouseEventsLocation DISABLED_DisabledMouseEventsLocation
+#else
+#define MAYBE_DisabledMouseEventsLocation DisabledMouseEventsLocation
+#endif // defined(OS_WIN)
+
+// Verifies that RootWindow generates a mouse event located outside of a window
+// when mouse events are disabled.
+TEST_F(CursorManagerTest, MAYBE_DisabledMouseEventsLocation) {
+ scoped_ptr<MouseEventLocationDelegate> delegate(
+ new MouseEventLocationDelegate());
+ const int kWindowWidth = 123;
+ const int kWindowHeight = 45;
+ gfx::Rect bounds(100, 200, kWindowWidth, kWindowHeight);
+ scoped_ptr<aura::Window> window(aura::test::CreateTestWindowWithDelegate(
+ delegate.get(), 1, bounds, Shell::GetInstance()->GetPrimaryRootWindow()));
+
+ CursorManager* cursor_manager = Shell::GetInstance()->cursor_manager();
+ cursor_manager->EnableMouseEvents();
+ // Send a mouse event to window.
+ gfx::Point point(101, 201);
+ gfx::Point local_point;
+ ui::MouseEvent event(ui::ET_MOUSE_MOVED, point, point, 0);
+ aura::RootWindow* root_window = window->GetRootWindow();
+ root_window->AsRootWindowHostDelegate()->OnHostMouseEvent(&event);
+
+ // Location was in window.
+ local_point = delegate->mouse_event_location();
+ aura::Window::ConvertPointToTarget(window.get(), root_window, &local_point);
+ EXPECT_TRUE(window->bounds().Contains(local_point));
+
+ // Location is now out of window.
+ cursor_manager->DisableMouseEvents();
+ RunAllPendingInMessageLoop();
+ local_point = delegate->mouse_event_location();
+ aura::Window::ConvertPointToTarget(window.get(), root_window, &local_point);
+ EXPECT_FALSE(window->bounds().Contains(local_point));
+
+ // Location is back in window.
+ cursor_manager->EnableMouseEvents();
+ RunAllPendingInMessageLoop();
+ local_point = delegate->mouse_event_location();
+ aura::Window::ConvertPointToTarget(window.get(), root_window, &local_point);
+ EXPECT_TRUE(window->bounds().Contains(local_point));
+}
+
+#if defined(OS_WIN)
+// Disable on Win because RootWindow::MoveCursorTo is not implemented.
+#define MAYBE_DisabledQueryMouseLocation DISABLED_DisabledQueryMouseLocation
+#else
+#define MAYBE_DisabledQueryMouseLocation DisabledQueryMouseLocation
+#endif // defined(OS_WIN)
+
+TEST_F(CursorManagerTest, MAYBE_DisabledQueryMouseLocation) {
+ aura::RootWindow* root_window = Shell::GetInstance()->GetPrimaryRootWindow();
+ root_window->MoveCursorTo(gfx::Point(10, 10));
+ gfx::Point mouse_location;
+ EXPECT_TRUE(root_window->QueryMouseLocationForTest(&mouse_location));
+ EXPECT_EQ("10,10", mouse_location.ToString());
+ Shell::GetInstance()->cursor_manager()->DisableMouseEvents();
+ EXPECT_FALSE(root_window->QueryMouseLocationForTest(&mouse_location));
+ EXPECT_EQ("0,0", mouse_location.ToString());
+}
+
} // namespace test
} // namespace ash
diff --git a/ash/wm/session_state_controller_impl.cc b/ash/wm/session_state_controller_impl.cc
index 69cd036..b31b29b6 100644
--- a/ash/wm/session_state_controller_impl.cc
+++ b/ash/wm/session_state_controller_impl.cc
@@ -52,7 +52,7 @@ void SessionStateControllerImpl::OnAppTerminating() {
shutting_down_ = true;
Shell* shell = ash::Shell::GetInstance();
shell->env_filter()->set_cursor_hidden_by_filter(false);
- shell->cursor_manager()->ShowCursor(false);
+ shell->cursor_manager()->DisableMouseEvents();
animator_->StartAnimation(
internal::SessionStateAnimator::kAllContainersMask,
internal::SessionStateAnimator::ANIMATION_HIDE_IMMEDIATELY,
@@ -219,7 +219,7 @@ void SessionStateControllerImpl::RequestShutdownImpl() {
Shell* shell = ash::Shell::GetInstance();
shell->env_filter()->set_cursor_hidden_by_filter(false);
- shell->cursor_manager()->ShowCursor(false);
+ shell->cursor_manager()->DisableMouseEvents();
if (login_status_ != user::LOGGED_IN_NONE) {
// Hide the other containers before starting the animation.
diff --git a/ash/wm/session_state_controller_impl2.cc b/ash/wm/session_state_controller_impl2.cc
index 7629284..1c50712 100644
--- a/ash/wm/session_state_controller_impl2.cc
+++ b/ash/wm/session_state_controller_impl2.cc
@@ -171,7 +171,7 @@ void SessionStateControllerImpl2::OnAppTerminating() {
shutting_down_ = true;
Shell* shell = ash::Shell::GetInstance();
shell->env_filter()->set_cursor_hidden_by_filter(false);
- shell->cursor_manager()->ShowCursor(false);
+ shell->cursor_manager()->DisableMouseEvents();
animator_->StartAnimation(
internal::SessionStateAnimator::kAllContainersMask,
internal::SessionStateAnimator::ANIMATION_HIDE_IMMEDIATELY,
@@ -279,7 +279,7 @@ void SessionStateControllerImpl2::RequestShutdownImpl() {
Shell* shell = ash::Shell::GetInstance();
shell->env_filter()->set_cursor_hidden_by_filter(false);
- shell->cursor_manager()->ShowCursor(false);
+ shell->cursor_manager()->DisableMouseEvents();
StartShutdownAnimationImpl();
}
@@ -338,7 +338,7 @@ void SessionStateControllerImpl2::OnPreShutdownAnimationTimeout() {
Shell* shell = ash::Shell::GetInstance();
shell->env_filter()->set_cursor_hidden_by_filter(false);
- shell->cursor_manager()->ShowCursor(false);
+ shell->cursor_manager()->DisableMouseEvents();
StartRealShutdownTimer(false);
}
diff --git a/ash/wm/window_manager_unittest.cc b/ash/wm/window_manager_unittest.cc
index 2328850..1f7bd1b 100644
--- a/ash/wm/window_manager_unittest.cc
+++ b/ash/wm/window_manager_unittest.cc
@@ -671,7 +671,7 @@ TEST_F(WindowManagerTest, UpdateCursorVisibility) {
// If someone else made cursor invisible keep it invisible even after it
// received mouse events.
- cursor_manager->ShowCursor(false);
+ cursor_manager->DisableMouseEvents();
root_window->AsRootWindowHostDelegate()->OnHostMouseEvent(&mouse_moved);
EXPECT_FALSE(cursor_manager->IsCursorVisible());
root_window->AsRootWindowHostDelegate()->OnHostTouchEvent(&touch_pressed2);
@@ -682,7 +682,7 @@ TEST_F(WindowManagerTest, UpdateCursorVisibility) {
EXPECT_FALSE(cursor_manager->IsCursorVisible());
// Back to normal.
- cursor_manager->ShowCursor(true);
+ cursor_manager->EnableMouseEvents();
root_window->AsRootWindowHostDelegate()->OnHostMouseEvent(&mouse_moved);
EXPECT_TRUE(cursor_manager->IsCursorVisible());
root_window->AsRootWindowHostDelegate()->OnHostTouchEvent(&touch_pressed2);