1 // Copyright (c) 2013 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.
5 #include "ui/wm/core/cursor_manager.h"
7 #include "base/logging.h"
8 #include "ui/aura/client/cursor_client_observer.h"
9 #include "ui/wm/core/native_cursor_manager.h"
10 #include "ui/wm/core/native_cursor_manager_delegate.h"
16 // Represents the cursor state which is composed of cursor type, visibility, and
17 // mouse events enable state. When mouse events are disabled, the cursor is
22 : cursor_(ui::kCursorNone
),
24 cursor_set_(ui::CURSOR_SET_NORMAL
),
25 mouse_events_enabled_(true),
26 visible_on_mouse_events_enabled_(true) {
29 gfx::NativeCursor
cursor() const { return cursor_
; }
30 void set_cursor(gfx::NativeCursor cursor
) { cursor_
= cursor
; }
32 bool visible() const { return visible_
; }
33 void SetVisible(bool visible
) {
34 if (mouse_events_enabled_
)
36 // Ignores the call when mouse events disabled.
39 ui::CursorSetType
cursor_set() const { return cursor_set_
; }
40 void set_cursor_set(ui::CursorSetType cursor_set
) {
41 cursor_set_
= cursor_set
;
44 bool mouse_events_enabled() const { return mouse_events_enabled_
; }
45 void SetMouseEventsEnabled(bool enabled
) {
46 if (mouse_events_enabled_
== enabled
)
48 mouse_events_enabled_
= enabled
;
50 // Restores the visibility when mouse events are enabled.
52 visible_
= visible_on_mouse_events_enabled_
;
54 visible_on_mouse_events_enabled_
= visible_
;
60 gfx::NativeCursor cursor_
;
62 ui::CursorSetType cursor_set_
;
63 bool mouse_events_enabled_
;
65 // The visibility to set when mouse events are enabled.
66 bool visible_on_mouse_events_enabled_
;
68 DISALLOW_COPY_AND_ASSIGN(CursorState
);
71 } // namespace internal
73 CursorManager::CursorManager(scoped_ptr
<NativeCursorManager
> delegate
)
74 : delegate_(delegate
.Pass()),
75 cursor_lock_count_(0),
76 current_state_(new internal::CursorState
),
77 state_on_unlock_(new internal::CursorState
) {
80 CursorManager::~CursorManager() {
83 void CursorManager::SetCursor(gfx::NativeCursor cursor
) {
84 state_on_unlock_
->set_cursor(cursor
);
85 if (cursor_lock_count_
== 0 &&
86 GetCursor() != state_on_unlock_
->cursor()) {
87 delegate_
->SetCursor(state_on_unlock_
->cursor(), this);
91 gfx::NativeCursor
CursorManager::GetCursor() const {
92 return current_state_
->cursor();
95 void CursorManager::ShowCursor() {
96 state_on_unlock_
->SetVisible(true);
97 if (cursor_lock_count_
== 0 &&
98 IsCursorVisible() != state_on_unlock_
->visible()) {
99 delegate_
->SetVisibility(state_on_unlock_
->visible(), this);
100 FOR_EACH_OBSERVER(aura::client::CursorClientObserver
, observers_
,
101 OnCursorVisibilityChanged(true));
105 void CursorManager::HideCursor() {
106 state_on_unlock_
->SetVisible(false);
107 if (cursor_lock_count_
== 0 &&
108 IsCursorVisible() != state_on_unlock_
->visible()) {
109 delegate_
->SetVisibility(state_on_unlock_
->visible(), this);
110 FOR_EACH_OBSERVER(aura::client::CursorClientObserver
, observers_
,
111 OnCursorVisibilityChanged(false));
115 bool CursorManager::IsCursorVisible() const {
116 return current_state_
->visible();
119 void CursorManager::SetCursorSet(ui::CursorSetType cursor_set
) {
120 state_on_unlock_
->set_cursor_set(cursor_set
);
121 if (GetCursorSet() != state_on_unlock_
->cursor_set())
122 delegate_
->SetCursorSet(state_on_unlock_
->cursor_set(), this);
125 ui::CursorSetType
CursorManager::GetCursorSet() const {
126 return current_state_
->cursor_set();
129 void CursorManager::EnableMouseEvents() {
130 state_on_unlock_
->SetMouseEventsEnabled(true);
131 if (cursor_lock_count_
== 0 &&
132 IsMouseEventsEnabled() != state_on_unlock_
->mouse_events_enabled()) {
133 delegate_
->SetMouseEventsEnabled(state_on_unlock_
->mouse_events_enabled(),
138 void CursorManager::DisableMouseEvents() {
139 state_on_unlock_
->SetMouseEventsEnabled(false);
140 if (cursor_lock_count_
== 0 &&
141 IsMouseEventsEnabled() != state_on_unlock_
->mouse_events_enabled()) {
142 delegate_
->SetMouseEventsEnabled(state_on_unlock_
->mouse_events_enabled(),
147 bool CursorManager::IsMouseEventsEnabled() const {
148 return current_state_
->mouse_events_enabled();
151 void CursorManager::SetDisplay(const gfx::Display
& display
) {
152 delegate_
->SetDisplay(display
, this);
155 void CursorManager::LockCursor() {
156 cursor_lock_count_
++;
159 void CursorManager::UnlockCursor() {
160 cursor_lock_count_
--;
161 DCHECK_GE(cursor_lock_count_
, 0);
162 if (cursor_lock_count_
> 0)
165 if (GetCursor() != state_on_unlock_
->cursor()) {
166 delegate_
->SetCursor(state_on_unlock_
->cursor(), this);
168 if (IsMouseEventsEnabled() != state_on_unlock_
->mouse_events_enabled()) {
169 delegate_
->SetMouseEventsEnabled(state_on_unlock_
->mouse_events_enabled(),
172 if (IsCursorVisible() != state_on_unlock_
->visible()) {
173 delegate_
->SetVisibility(state_on_unlock_
->visible(),
178 bool CursorManager::IsCursorLocked() const {
179 return cursor_lock_count_
> 0;
182 void CursorManager::AddObserver(
183 aura::client::CursorClientObserver
* observer
) {
184 observers_
.AddObserver(observer
);
187 void CursorManager::RemoveObserver(
188 aura::client::CursorClientObserver
* observer
) {
189 observers_
.RemoveObserver(observer
);
192 bool CursorManager::ShouldHideCursorOnKeyEvent(
193 const ui::KeyEvent
& event
) const {
197 void CursorManager::CommitCursor(gfx::NativeCursor cursor
) {
198 current_state_
->set_cursor(cursor
);
201 void CursorManager::CommitVisibility(bool visible
) {
202 // TODO(tdanderson): Find a better place for this so we don't
203 // notify the observers more than is necessary.
204 FOR_EACH_OBSERVER(aura::client::CursorClientObserver
, observers_
,
205 OnCursorVisibilityChanged(visible
));
206 current_state_
->SetVisible(visible
);
209 void CursorManager::CommitCursorSet(ui::CursorSetType cursor_set
) {
210 current_state_
->set_cursor_set(cursor_set
);
213 void CursorManager::CommitMouseEventsEnabled(bool enabled
) {
214 current_state_
->SetMouseEventsEnabled(enabled
);