Home | History | Annotate | Download | only in core
      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.
      4 
      5 #include "ui/wm/core/cursor_manager.h"
      6 
      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"
     11 
     12 namespace wm {
     13 
     14 namespace internal {
     15 
     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
     18 // always invisible.
     19 class CursorState {
     20  public:
     21   CursorState()
     22       : cursor_(ui::kCursorNone),
     23         visible_(true),
     24         cursor_set_(ui::CURSOR_SET_NORMAL),
     25         mouse_events_enabled_(true),
     26         visible_on_mouse_events_enabled_(true) {
     27   }
     28 
     29   gfx::NativeCursor cursor() const { return cursor_; }
     30   void set_cursor(gfx::NativeCursor cursor) { cursor_ = cursor; }
     31 
     32   bool visible() const { return visible_; }
     33   void SetVisible(bool visible) {
     34     if (mouse_events_enabled_)
     35       visible_ = visible;
     36     // Ignores the call when mouse events disabled.
     37   }
     38 
     39   ui::CursorSetType cursor_set() const { return cursor_set_; }
     40   void set_cursor_set(ui::CursorSetType cursor_set) {
     41     cursor_set_ = cursor_set;
     42   }
     43 
     44   bool mouse_events_enabled() const { return mouse_events_enabled_; }
     45   void SetMouseEventsEnabled(bool enabled) {
     46     if (mouse_events_enabled_ == enabled)
     47       return;
     48     mouse_events_enabled_ = enabled;
     49 
     50     // Restores the visibility when mouse events are enabled.
     51     if (enabled) {
     52       visible_ = visible_on_mouse_events_enabled_;
     53     } else {
     54       visible_on_mouse_events_enabled_ = visible_;
     55       visible_ = false;
     56     }
     57   }
     58 
     59  private:
     60   gfx::NativeCursor cursor_;
     61   bool visible_;
     62   ui::CursorSetType cursor_set_;
     63   bool mouse_events_enabled_;
     64 
     65   // The visibility to set when mouse events are enabled.
     66   bool visible_on_mouse_events_enabled_;
     67 
     68   DISALLOW_COPY_AND_ASSIGN(CursorState);
     69 };
     70 
     71 }  // namespace internal
     72 
     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) {
     78 }
     79 
     80 CursorManager::~CursorManager() {
     81 }
     82 
     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);
     88   }
     89 }
     90 
     91 gfx::NativeCursor CursorManager::GetCursor() const {
     92   return current_state_->cursor();
     93 }
     94 
     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));
    102   }
    103 }
    104 
    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));
    112   }
    113 }
    114 
    115 bool CursorManager::IsCursorVisible() const {
    116   return current_state_->visible();
    117 }
    118 
    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);
    123 }
    124 
    125 ui::CursorSetType CursorManager::GetCursorSet() const {
    126   return current_state_->cursor_set();
    127 }
    128 
    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(),
    134                                      this);
    135   }
    136 }
    137 
    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(),
    143                                      this);
    144   }
    145 }
    146 
    147 bool CursorManager::IsMouseEventsEnabled() const {
    148   return current_state_->mouse_events_enabled();
    149 }
    150 
    151 void CursorManager::SetDisplay(const gfx::Display& display) {
    152   delegate_->SetDisplay(display, this);
    153 }
    154 
    155 void CursorManager::LockCursor() {
    156   cursor_lock_count_++;
    157 }
    158 
    159 void CursorManager::UnlockCursor() {
    160   cursor_lock_count_--;
    161   DCHECK_GE(cursor_lock_count_, 0);
    162   if (cursor_lock_count_ > 0)
    163     return;
    164 
    165   if (GetCursor() != state_on_unlock_->cursor()) {
    166     delegate_->SetCursor(state_on_unlock_->cursor(), this);
    167   }
    168   if (IsMouseEventsEnabled() != state_on_unlock_->mouse_events_enabled()) {
    169     delegate_->SetMouseEventsEnabled(state_on_unlock_->mouse_events_enabled(),
    170                                      this);
    171   }
    172   if (IsCursorVisible() != state_on_unlock_->visible()) {
    173     delegate_->SetVisibility(state_on_unlock_->visible(),
    174                              this);
    175   }
    176 }
    177 
    178 bool CursorManager::IsCursorLocked() const {
    179   return cursor_lock_count_ > 0;
    180 }
    181 
    182 void CursorManager::AddObserver(
    183     aura::client::CursorClientObserver* observer) {
    184   observers_.AddObserver(observer);
    185 }
    186 
    187 void CursorManager::RemoveObserver(
    188     aura::client::CursorClientObserver* observer) {
    189   observers_.RemoveObserver(observer);
    190 }
    191 
    192 bool CursorManager::ShouldHideCursorOnKeyEvent(
    193     const ui::KeyEvent& event) const {
    194   return false;
    195 }
    196 
    197 void CursorManager::CommitCursor(gfx::NativeCursor cursor) {
    198   current_state_->set_cursor(cursor);
    199 }
    200 
    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);
    207 }
    208 
    209 void CursorManager::CommitCursorSet(ui::CursorSetType cursor_set) {
    210   current_state_->set_cursor_set(cursor_set);
    211 }
    212 
    213 void CursorManager::CommitMouseEventsEnabled(bool enabled) {
    214   current_state_->SetMouseEventsEnabled(enabled);
    215 }
    216 
    217 }  // namespace wm
    218