Chromium Code Reviews| Index: services/ui/ws/display.cc |
| diff --git a/services/ui/ws/display.cc b/services/ui/ws/display.cc |
| index becd40ed97784b72dbada881f97b3c6838de21e2..1848b4b29ddd5c52d70df9ce7f940ae74ebe391b 100644 |
| --- a/services/ui/ws/display.cc |
| +++ b/services/ui/ws/display.cc |
| @@ -36,9 +36,42 @@ |
| namespace ui { |
| namespace ws { |
| +class Display::CursorState { |
| + public: |
| + CursorState() |
| + : cursor_data_(ui::CursorData(ui::CursorType::kNull)), visible_(true) {} |
| + CursorState(const CursorState& rhs) = default; |
| + ~CursorState() {} |
| + |
| + const base::Optional<ui::CursorData>& global_override_cursor() const { |
| + return global_override_cursor_; |
| + } |
| + void SetGlobalOverrideCursor(const base::Optional<ui::CursorData>& cursor) { |
| + global_override_cursor_ = cursor; |
| + } |
| + |
| + const ui::CursorData& cursor_data() const { return cursor_data_; } |
| + void SetCursorData(const ui::CursorData& data) { cursor_data_ = data; } |
| + |
| + bool visible() const { return visible_; } |
| + void set_visible(bool visible) { visible_ = visible; } |
| + |
| + private: |
| + // An optional cursor set by the window manager which overrides per-window |
| + // requests. |
| + base::Optional<ui::CursorData> global_override_cursor_; |
| + |
| + // The last cursor set. Used to track whether we need to change the cursor. |
| + ui::CursorData cursor_data_; |
| + |
| + // Whether the cursor is visible. |
| + bool visible_; |
| +}; |
| + |
| Display::Display(WindowServer* window_server) |
| : window_server_(window_server), |
| - last_cursor_(ui::CursorData(ui::CursorType::kNull)) { |
| + current_state_(base::MakeUnique<CursorState>()), |
| + state_on_unlock_(base::MakeUnique<CursorState>()) { |
| window_server_->window_manager_window_tree_factory_set()->AddObserver(this); |
| window_server_->user_id_tracker()->AddObserver(this); |
| } |
| @@ -199,9 +232,54 @@ void Display::RemoveWindowManagerDisplayRoot( |
| } |
| void Display::UpdateNativeCursor(const ui::CursorData& cursor) { |
| - if (!last_cursor_.IsSameAs(cursor)) { |
| - platform_display_->SetCursor(cursor); |
| - last_cursor_ = cursor; |
| + if (!state_on_unlock_->cursor_data().IsSameAs(cursor)) |
| + state_on_unlock_->SetCursorData(cursor); |
| + |
| + if (cursor_lock_count_ == 0 && |
| + !current_state_->cursor_data().IsSameAs(cursor)) { |
| + current_state_->SetCursorData(cursor); |
| + SetPlatformCursor(); |
| + } |
| +} |
| + |
| +void Display::LockCursor() { |
| + cursor_lock_count_++; |
| +} |
| + |
| +void Display::UnlockCursor() { |
| + cursor_lock_count_--; |
|
sky
2017/05/12 13:40:01
Having each Display track this state is rather dup
Elliot Glaysher
2017/05/12 23:02:44
Created CursorState class, which is owned by windo
|
| + DCHECK_GE(cursor_lock_count_, 0); |
| + if (cursor_lock_count_ > 0) |
| + return; |
| + |
| + *current_state_ = *state_on_unlock_; |
| + SetPlatformCursor(); |
| +} |
| + |
| +void Display::ShowCursor() { |
| + state_on_unlock_->set_visible(true); |
| + if (cursor_lock_count_ == 0 && |
| + current_state_->visible() != state_on_unlock_->visible()) { |
| + current_state_->set_visible(true); |
| + SetPlatformCursor(); |
| + } |
| +} |
| + |
| +void Display::HideCursor() { |
| + state_on_unlock_->set_visible(false); |
| + if (cursor_lock_count_ == 0 && |
| + current_state_->visible() != state_on_unlock_->visible()) { |
| + platform_display_->SetCursor(ui::CursorData(ui::CursorType::kNone)); |
| + current_state_->set_visible(false); |
| + } |
| +} |
| + |
| +void Display::SetGlobalOverrideCursor( |
| + const base::Optional<ui::CursorData>& cursor) { |
| + state_on_unlock_->SetGlobalOverrideCursor(cursor); |
| + if (cursor_lock_count_ == 0) { |
| + current_state_->SetGlobalOverrideCursor(cursor); |
| + SetPlatformCursor(); |
| } |
| } |
| @@ -273,6 +351,19 @@ void Display::CreateRootWindow(const gfx::Size& size) { |
| focus_controller_->AddObserver(this); |
| } |
| +void Display::SetPlatformCursor() { |
| + if (current_state_->visible()) { |
| + if (current_state_->global_override_cursor().has_value()) { |
| + platform_display_->SetCursor( |
| + current_state_->global_override_cursor().value()); |
| + } else { |
| + platform_display_->SetCursor(current_state_->cursor_data()); |
| + } |
| + } else { |
| + platform_display_->SetCursor(ui::CursorData(ui::CursorType::kNone)); |
| + } |
| +} |
| + |
| ServerWindow* Display::GetRootWindow() { |
| return root_.get(); |
| } |