blob: f0475e0d46b3d4827e02ed3bc9c707c3265d1458 [file] [log] [blame]
[email protected]1aad3322012-06-06 06:37:091// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
[email protected]4b8003c2012-07-26 00:54:195#include "ash/wm/cursor_manager.h"
[email protected]1aad3322012-06-06 06:37:096
[email protected]60c26202012-10-12 18:55:237#include "ash/shell.h"
[email protected]151ffdff2012-09-11 20:18:358#include "ash/wm/image_cursors.h"
[email protected]1aad3322012-06-06 06:37:099#include "base/logging.h"
[email protected]166ccde2012-12-19 16:43:5310#include "ui/aura/env.h"
[email protected]60c26202012-10-12 18:55:2311#include "ui/aura/root_window.h"
[email protected]151ffdff2012-09-11 20:18:3512#include "ui/base/cursor/cursor.h"
[email protected]1aad3322012-06-06 06:37:0913
[email protected]60c26202012-10-12 18:55:2314namespace {
15
[email protected]166ccde2012-12-19 16:43:5316// The coordinate of the cursor used when the mouse events are disabled.
17const int kDisabledCursorLocationX = -10000;
18const int kDisabledCursorLocationY = -10000;
19
[email protected]60c26202012-10-12 18:55:2320void SetCursorOnAllRootWindows(gfx::NativeCursor cursor) {
21 ash::Shell::RootWindowList root_windows =
22 ash::Shell::GetInstance()->GetAllRootWindows();
23 for (ash::Shell::RootWindowList::iterator iter = root_windows.begin();
24 iter != root_windows.end(); ++iter)
25 (*iter)->SetCursor(cursor);
26}
27
28void NotifyCursorVisibilityChange(bool visible) {
29 ash::Shell::RootWindowList root_windows =
30 ash::Shell::GetInstance()->GetAllRootWindows();
31 for (ash::Shell::RootWindowList::iterator iter = root_windows.begin();
32 iter != root_windows.end(); ++iter)
33 (*iter)->OnCursorVisibilityChanged(visible);
34}
35
[email protected]166ccde2012-12-19 16:43:5336void NotifyMouseEventsEnableStateChange(bool enabled) {
37 ash::Shell::RootWindowList root_windows =
38 ash::Shell::GetInstance()->GetAllRootWindows();
39 for (ash::Shell::RootWindowList::iterator iter = root_windows.begin();
40 iter != root_windows.end(); ++iter)
41 (*iter)->OnMouseEventsEnableStateChanged(enabled);
42}
43
[email protected]60c26202012-10-12 18:55:2344} // namespace
45
[email protected]4b8003c2012-07-26 00:54:1946namespace ash {
[email protected]166ccde2012-12-19 16:43:5347namespace internal {
48
49// Represents the cursor state which is composed of cursor type, visibility, and
50// mouse events enable state. When mouse events are disabled, the cursor is
51// always invisible.
52class CursorState {
53 public:
54 CursorState()
55 : cursor_(ui::kCursorNone),
56 visible_(true),
57 mouse_events_enabled_(true),
58 visible_on_mouse_events_enabled_(true) {
59 }
60
61 gfx::NativeCursor cursor() const { return cursor_; }
62 void set_cursor(gfx::NativeCursor cursor) { cursor_ = cursor; }
63
64 bool visible() const { return visible_; }
65 void SetVisible(bool visible) {
66 if (mouse_events_enabled_)
67 visible_ = visible;
68 // Ignores the call when mouse events disabled.
69 }
70
71 bool mouse_events_enabled() const { return mouse_events_enabled_; }
72 void SetMouseEventsEnabled(bool enabled) {
73 mouse_events_enabled_ = enabled;
74
75 // Restores the visibility when mouse events are enabled.
76 if (enabled) {
77 visible_ = visible_on_mouse_events_enabled_;
78 } else {
79 visible_on_mouse_events_enabled_ = visible_;
80 visible_ = false;
81 }
82 }
83
84
85 private:
86 gfx::NativeCursor cursor_;
87 bool visible_;
88 bool mouse_events_enabled_;
89
90 // The visibility to set when mouse events are enabled.
91 bool visible_on_mouse_events_enabled_;
92
93 DISALLOW_COPY_AND_ASSIGN(CursorState);
94};
95
96} // namespace internal
[email protected]1aad3322012-06-06 06:37:0997
98CursorManager::CursorManager()
[email protected]60c26202012-10-12 18:55:2399 : cursor_lock_count_(0),
[email protected]166ccde2012-12-19 16:43:53100 current_state_(new internal::CursorState),
101 state_on_unlock_(new internal::CursorState),
[email protected]151ffdff2012-09-11 20:18:35102 image_cursors_(new ImageCursors) {
[email protected]1aad3322012-06-06 06:37:09103}
104
105CursorManager::~CursorManager() {
106}
107
[email protected]1aad3322012-06-06 06:37:09108void CursorManager::SetCursor(gfx::NativeCursor cursor) {
[email protected]166ccde2012-12-19 16:43:53109 state_on_unlock_->set_cursor(cursor);
110 if (cursor_lock_count_ == 0 &&
111 GetCurrentCursor() != state_on_unlock_->cursor()) {
112 SetCursorInternal(state_on_unlock_->cursor());
[email protected]1aad3322012-06-06 06:37:09113 }
114}
115
[email protected]166ccde2012-12-19 16:43:53116void CursorManager::ShowCursor() {
117 state_on_unlock_->SetVisible(true);
118 if (cursor_lock_count_ == 0 &&
119 IsCursorVisible() != state_on_unlock_->visible()) {
120 SetCursorVisibility(state_on_unlock_->visible());
121 }
122}
123
124void CursorManager::HideCursor() {
125 state_on_unlock_->SetVisible(false);
126 if (cursor_lock_count_ == 0 &&
127 IsCursorVisible() != state_on_unlock_->visible()) {
128 SetCursorVisibility(state_on_unlock_->visible());
[email protected]60c26202012-10-12 18:55:23129 }
[email protected]1aad3322012-06-06 06:37:09130}
131
[email protected]4b8003c2012-07-26 00:54:19132bool CursorManager::IsCursorVisible() const {
[email protected]166ccde2012-12-19 16:43:53133 return current_state_->visible();
134}
135
136void CursorManager::EnableMouseEvents() {
137 state_on_unlock_->SetMouseEventsEnabled(true);
138 if (cursor_lock_count_ == 0 &&
139 IsMouseEventsEnabled() != state_on_unlock_->mouse_events_enabled()) {
140 SetMouseEventsEnabled(state_on_unlock_->mouse_events_enabled());
141 }
142}
143
144void CursorManager::DisableMouseEvents() {
145 state_on_unlock_->SetMouseEventsEnabled(false);
146 if (cursor_lock_count_ == 0 &&
147 IsMouseEventsEnabled() != state_on_unlock_->mouse_events_enabled()) {
148 SetMouseEventsEnabled(state_on_unlock_->mouse_events_enabled());
149 }
150}
151
152bool CursorManager::IsMouseEventsEnabled() const {
153 return current_state_->mouse_events_enabled();
[email protected]4b8003c2012-07-26 00:54:19154}
155
[email protected]151ffdff2012-09-11 20:18:35156void CursorManager::SetDeviceScaleFactor(float device_scale_factor) {
[email protected]2216f232012-10-22 23:45:05157 if (image_cursors_->SetDeviceScaleFactor(device_scale_factor))
[email protected]166ccde2012-12-19 16:43:53158 SetCursorInternal(GetCurrentCursor());
[email protected]151ffdff2012-09-11 20:18:35159}
160
[email protected]60c26202012-10-12 18:55:23161void CursorManager::LockCursor() {
162 cursor_lock_count_++;
163}
164
165void CursorManager::UnlockCursor() {
166 cursor_lock_count_--;
167 DCHECK_GE(cursor_lock_count_, 0);
168 if (cursor_lock_count_ > 0)
169 return;
170
[email protected]166ccde2012-12-19 16:43:53171 if (GetCurrentCursor() != state_on_unlock_->cursor())
172 SetCursorInternal(state_on_unlock_->cursor());
173 if (IsMouseEventsEnabled() != state_on_unlock_->mouse_events_enabled())
174 SetMouseEventsEnabled(state_on_unlock_->mouse_events_enabled());
175 if (IsCursorVisible() != state_on_unlock_->visible())
176 SetCursorVisibility(state_on_unlock_->visible());
[email protected]60c26202012-10-12 18:55:23177}
178
[email protected]151ffdff2012-09-11 20:18:35179void CursorManager::SetCursorInternal(gfx::NativeCursor cursor) {
[email protected]166ccde2012-12-19 16:43:53180 gfx::NativeCursor new_cursor = cursor;
181 image_cursors_->SetPlatformCursor(&new_cursor);
182 new_cursor.set_device_scale_factor(image_cursors_->GetDeviceScaleFactor());
183 current_state_->set_cursor(new_cursor);
[email protected]60c26202012-10-12 18:55:23184
[email protected]166ccde2012-12-19 16:43:53185 if (IsCursorVisible())
186 SetCursorOnAllRootWindows(GetCurrentCursor());
[email protected]60c26202012-10-12 18:55:23187}
188
[email protected]166ccde2012-12-19 16:43:53189void CursorManager::SetCursorVisibility(bool visible) {
190 current_state_->SetVisible(visible);
[email protected]60c26202012-10-12 18:55:23191
[email protected]166ccde2012-12-19 16:43:53192 if (visible) {
193 SetCursorInternal(GetCurrentCursor());
[email protected]60c26202012-10-12 18:55:23194 } else {
195 gfx::NativeCursor invisible_cursor(ui::kCursorNone);
196 image_cursors_->SetPlatformCursor(&invisible_cursor);
197 SetCursorOnAllRootWindows(invisible_cursor);
198 }
199
[email protected]166ccde2012-12-19 16:43:53200 NotifyCursorVisibilityChange(visible);
201}
202
203void CursorManager::SetMouseEventsEnabled(bool enabled) {
204 current_state_->SetMouseEventsEnabled(enabled);
205
206 if (enabled) {
207 aura::Env::GetInstance()->set_last_mouse_location(
208 disabled_cursor_location_);
209 } else {
210 disabled_cursor_location_ = aura::Env::GetInstance()->last_mouse_location();
211 aura::Env::GetInstance()->set_last_mouse_location(
212 gfx::Point(kDisabledCursorLocationX, kDisabledCursorLocationY));
213 }
214
215 SetCursorVisibility(current_state_->visible());
216 NotifyMouseEventsEnableStateChange(enabled);
217}
218
219gfx::NativeCursor CursorManager::GetCurrentCursor() const {
220 return current_state_->cursor();
[email protected]151ffdff2012-09-11 20:18:35221}
222
[email protected]4b8003c2012-07-26 00:54:19223} // namespace ash