blob: 91f1161cf3119212832bad4a42171fa5d14b20b1 [file] [log] [blame]
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00001// 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
5#include "ash/wm/ash_native_cursor_manager.h"
6
Torne (Richard Coles)5d1f7b12014-02-21 12:16:55 +00007#include "ash/display/cursor_window_controller.h"
Ben Murdoch7dbb3d52013-07-17 14:55:54 +01008#include "ash/display/display_controller.h"
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00009#include "ash/shell.h"
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000010#include "base/logging.h"
11#include "ui/aura/env.h"
Torne (Richard Coles)a1401312014-03-18 10:20:56 +000012#include "ui/aura/window_event_dispatcher.h"
Torne (Richard Coles)23730a62014-03-21 14:25:57 +000013#include "ui/aura/window_tree_host.h"
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000014#include "ui/base/cursor/cursor.h"
Bo Liu5c02ac12014-05-01 10:37:37 -070015#include "ui/base/cursor/image_cursors.h"
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000016
Torne (Richard Coles)90dce4d2013-05-29 14:40:03 +010017namespace ash {
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000018namespace {
19
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000020void SetCursorOnAllRootWindows(gfx::NativeCursor cursor) {
Torne (Richard Coles)f2477e02013-11-28 11:55:43 +000021 aura::Window::Windows root_windows =
Torne (Richard Coles)90dce4d2013-05-29 14:40:03 +010022 Shell::GetInstance()->GetAllRootWindows();
Torne (Richard Coles)f2477e02013-11-28 11:55:43 +000023 for (aura::Window::Windows::iterator iter = root_windows.begin();
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000024 iter != root_windows.end(); ++iter)
Torne (Richard Coles)a1401312014-03-18 10:20:56 +000025 (*iter)->GetHost()->SetCursor(cursor);
Torne (Richard Coles)90dce4d2013-05-29 14:40:03 +010026#if defined(OS_CHROMEOS)
Ben Murdoch7dbb3d52013-07-17 14:55:54 +010027 Shell::GetInstance()->display_controller()->
Torne (Richard Coles)5d1f7b12014-02-21 12:16:55 +000028 cursor_window_controller()->SetCursor(cursor);
Torne (Richard Coles)90dce4d2013-05-29 14:40:03 +010029#endif
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000030}
31
32void NotifyCursorVisibilityChange(bool visible) {
Torne (Richard Coles)f2477e02013-11-28 11:55:43 +000033 aura::Window::Windows root_windows =
Torne (Richard Coles)90dce4d2013-05-29 14:40:03 +010034 Shell::GetInstance()->GetAllRootWindows();
Torne (Richard Coles)f2477e02013-11-28 11:55:43 +000035 for (aura::Window::Windows::iterator iter = root_windows.begin();
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000036 iter != root_windows.end(); ++iter)
Torne (Richard Coles)a1401312014-03-18 10:20:56 +000037 (*iter)->GetHost()->OnCursorVisibilityChanged(visible);
Torne (Richard Coles)90dce4d2013-05-29 14:40:03 +010038#if defined(OS_CHROMEOS)
Torne (Richard Coles)5d1f7b12014-02-21 12:16:55 +000039 Shell::GetInstance()->display_controller()->cursor_window_controller()->
40 SetVisibility(visible);
Torne (Richard Coles)90dce4d2013-05-29 14:40:03 +010041#endif
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000042}
43
44void NotifyMouseEventsEnableStateChange(bool enabled) {
Torne (Richard Coles)f2477e02013-11-28 11:55:43 +000045 aura::Window::Windows root_windows =
Torne (Richard Coles)90dce4d2013-05-29 14:40:03 +010046 Shell::GetInstance()->GetAllRootWindows();
Torne (Richard Coles)f2477e02013-11-28 11:55:43 +000047 for (aura::Window::Windows::iterator iter = root_windows.begin();
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000048 iter != root_windows.end(); ++iter)
Torne (Richard Coles)a1401312014-03-18 10:20:56 +000049 (*iter)->GetHost()->dispatcher()->OnMouseEventsEnableStateChanged(enabled);
Torne (Richard Coles)90dce4d2013-05-29 14:40:03 +010050 // Mirror window never process events.
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000051}
52
53} // namespace
54
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000055AshNativeCursorManager::AshNativeCursorManager()
Torne (Richard Coles)5d1f7b12014-02-21 12:16:55 +000056 : native_cursor_enabled_(true),
Bo Liu5c02ac12014-05-01 10:37:37 -070057 image_cursors_(new ui::ImageCursors) {
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000058}
59
60AshNativeCursorManager::~AshNativeCursorManager() {
61}
62
Torne (Richard Coles)5d1f7b12014-02-21 12:16:55 +000063
64void AshNativeCursorManager::SetNativeCursorEnabled(bool enabled) {
65 native_cursor_enabled_ = enabled;
66
Torne (Richard Coles)a1401312014-03-18 10:20:56 +000067 ::wm::CursorManager* cursor_manager =
Torne (Richard Coles)5d1f7b12014-02-21 12:16:55 +000068 Shell::GetInstance()->cursor_manager();
69 SetCursor(cursor_manager->GetCursor(), cursor_manager);
70}
71
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000072void AshNativeCursorManager::SetDisplay(
73 const gfx::Display& display,
Torne (Richard Coles)a1401312014-03-18 10:20:56 +000074 ::wm::NativeCursorManagerDelegate* delegate) {
Bo Liu5c02ac12014-05-01 10:37:37 -070075 DCHECK(display.is_valid());
76 // Use the platform's device scale factor instead of the display's, which
77 // might have been adjusted for the UI scale.
78 const float scale_factor = Shell::GetInstance()->display_manager()->
79 GetDisplayInfo(display.id()).device_scale_factor();
80 if (image_cursors_->SetDisplay(display, scale_factor))
Torne (Richard Coles)5d1f7b12014-02-21 12:16:55 +000081 SetCursor(delegate->GetCursor(), delegate);
82#if defined(OS_CHROMEOS)
83 Shell::GetInstance()->display_controller()->cursor_window_controller()->
84 SetDisplay(display);
85#endif
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000086}
87
88void AshNativeCursorManager::SetCursor(
89 gfx::NativeCursor cursor,
Torne (Richard Coles)a1401312014-03-18 10:20:56 +000090 ::wm::NativeCursorManagerDelegate* delegate) {
Torne (Richard Coles)5d1f7b12014-02-21 12:16:55 +000091 if (native_cursor_enabled_) {
Bo Liu5c02ac12014-05-01 10:37:37 -070092 image_cursors_->SetPlatformCursor(&cursor);
Torne (Richard Coles)5d1f7b12014-02-21 12:16:55 +000093 } else {
94 gfx::NativeCursor invisible_cursor(ui::kCursorNone);
95 image_cursors_->SetPlatformCursor(&invisible_cursor);
Bo Liu5c02ac12014-05-01 10:37:37 -070096 if (cursor == ui::kCursorCustom) {
97 cursor = invisible_cursor;
Torne (Richard Coles)5d1f7b12014-02-21 12:16:55 +000098 } else {
Bo Liu5c02ac12014-05-01 10:37:37 -070099 cursor.SetPlatformCursor(invisible_cursor.platform());
Torne (Richard Coles)5d1f7b12014-02-21 12:16:55 +0000100 }
101 }
Bo Liu5c02ac12014-05-01 10:37:37 -0700102 cursor.set_device_scale_factor(image_cursors_->GetScale());
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000103
Bo Liu5c02ac12014-05-01 10:37:37 -0700104 delegate->CommitCursor(cursor);
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000105
Torne (Richard Coles)5d1f7b12014-02-21 12:16:55 +0000106 if (delegate->IsCursorVisible())
Bo Liu5c02ac12014-05-01 10:37:37 -0700107 SetCursorOnAllRootWindows(cursor);
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000108}
109
Torne (Richard Coles)424c4d72013-08-30 15:14:49 +0100110void AshNativeCursorManager::SetCursorSet(
111 ui::CursorSetType cursor_set,
Torne (Richard Coles)a1401312014-03-18 10:20:56 +0000112 ::wm::NativeCursorManagerDelegate* delegate) {
Torne (Richard Coles)424c4d72013-08-30 15:14:49 +0100113 image_cursors_->SetCursorSet(cursor_set);
114 delegate->CommitCursorSet(cursor_set);
115
116 // Sets the cursor to reflect the scale change immediately.
Torne (Richard Coles)5d1f7b12014-02-21 12:16:55 +0000117 if (delegate->IsCursorVisible())
118 SetCursor(delegate->GetCursor(), delegate);
119
120#if defined(OS_CHROMEOS)
121 Shell::GetInstance()->display_controller()->cursor_window_controller()->
122 SetCursorSet(cursor_set);
123#endif
Torne (Richard Coles)424c4d72013-08-30 15:14:49 +0100124}
125
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000126void AshNativeCursorManager::SetVisibility(
127 bool visible,
Torne (Richard Coles)a1401312014-03-18 10:20:56 +0000128 ::wm::NativeCursorManagerDelegate* delegate) {
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000129 delegate->CommitVisibility(visible);
130
131 if (visible) {
Torne (Richard Coles)5d1f7b12014-02-21 12:16:55 +0000132 SetCursor(delegate->GetCursor(), delegate);
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000133 } else {
134 gfx::NativeCursor invisible_cursor(ui::kCursorNone);
135 image_cursors_->SetPlatformCursor(&invisible_cursor);
136 SetCursorOnAllRootWindows(invisible_cursor);
137 }
138
139 NotifyCursorVisibilityChange(visible);
140}
141
142void AshNativeCursorManager::SetMouseEventsEnabled(
143 bool enabled,
Torne (Richard Coles)a1401312014-03-18 10:20:56 +0000144 ::wm::NativeCursorManagerDelegate* delegate) {
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000145 delegate->CommitMouseEventsEnabled(enabled);
146
147 if (enabled) {
148 aura::Env::GetInstance()->set_last_mouse_location(
149 disabled_cursor_location_);
150 } else {
151 disabled_cursor_location_ = aura::Env::GetInstance()->last_mouse_location();
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000152 }
153
Torne (Richard Coles)5d1f7b12014-02-21 12:16:55 +0000154 SetVisibility(delegate->IsCursorVisible(), delegate);
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000155 NotifyMouseEventsEnableStateChange(enabled);
156}
157
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000158} // namespace ash