Index: ash/wm/cursor_manager.cc |
diff --git a/ash/wm/cursor_manager.cc b/ash/wm/cursor_manager.cc |
index b25105172d2e9011cadedc603ee297e5479a770a..f0475e0d46b3d4827e02ed3bc9c707c3265d1458 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(¤t_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 |