1 // 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.
5 #include "ash/wm/ash_native_cursor_manager.h"
7 #include "ash/display/cursor_window_controller.h"
8 #include "ash/display/window_tree_host_manager.h"
10 #include "base/logging.h"
11 #include "ui/aura/env.h"
12 #include "ui/aura/window_event_dispatcher.h"
13 #include "ui/aura/window_tree_host.h"
14 #include "ui/base/cursor/cursor.h"
15 #include "ui/base/cursor/image_cursors.h"
16 #include "ui/base/layout.h"
21 void SetCursorOnAllRootWindows(gfx::NativeCursor cursor
) {
22 aura::Window::Windows root_windows
=
23 Shell::GetInstance()->GetAllRootWindows();
24 for (aura::Window::Windows::iterator iter
= root_windows
.begin();
25 iter
!= root_windows
.end(); ++iter
)
26 (*iter
)->GetHost()->SetCursor(cursor
);
27 #if defined(OS_CHROMEOS)
29 ->window_tree_host_manager()
30 ->cursor_window_controller()
35 void NotifyCursorVisibilityChange(bool visible
) {
36 aura::Window::Windows root_windows
=
37 Shell::GetInstance()->GetAllRootWindows();
38 for (aura::Window::Windows::iterator iter
= root_windows
.begin();
39 iter
!= root_windows
.end(); ++iter
)
40 (*iter
)->GetHost()->OnCursorVisibilityChanged(visible
);
41 #if defined(OS_CHROMEOS)
43 ->window_tree_host_manager()
44 ->cursor_window_controller()
45 ->SetVisibility(visible
);
49 void NotifyMouseEventsEnableStateChange(bool enabled
) {
50 aura::Window::Windows root_windows
=
51 Shell::GetInstance()->GetAllRootWindows();
52 for (aura::Window::Windows::iterator iter
= root_windows
.begin();
53 iter
!= root_windows
.end(); ++iter
)
54 (*iter
)->GetHost()->dispatcher()->OnMouseEventsEnableStateChanged(enabled
);
55 // Mirror window never process events.
60 AshNativeCursorManager::AshNativeCursorManager()
61 : native_cursor_enabled_(true),
62 image_cursors_(new ui::ImageCursors
) {
65 AshNativeCursorManager::~AshNativeCursorManager() {
69 void AshNativeCursorManager::SetNativeCursorEnabled(bool enabled
) {
70 native_cursor_enabled_
= enabled
;
72 ::wm::CursorManager
* cursor_manager
=
73 Shell::GetInstance()->cursor_manager();
74 SetCursor(cursor_manager
->GetCursor(), cursor_manager
);
77 void AshNativeCursorManager::SetDisplay(
78 const gfx::Display
& display
,
79 ::wm::NativeCursorManagerDelegate
* delegate
) {
80 DCHECK(display
.is_valid());
81 // Use the platform's device scale factor instead of the display's, which
82 // might have been adjusted for the UI scale.
83 const float original_scale
= Shell::GetInstance()->display_manager()->
84 GetDisplayInfo(display
.id()).device_scale_factor();
85 #if defined(OS_CHROMEOS)
86 // And use the nearest resource scale factor.
87 const float cursor_scale
= ui::GetScaleForScaleFactor(
88 ui::GetSupportedScaleFactor(original_scale
));
90 // TODO(oshima): crbug.com/143619
91 const float cursor_scale
= original_scale
;
93 if (image_cursors_
->SetDisplay(display
, cursor_scale
))
94 SetCursor(delegate
->GetCursor(), delegate
);
95 #if defined(OS_CHROMEOS)
97 ->window_tree_host_manager()
98 ->cursor_window_controller()
99 ->SetDisplay(display
);
103 void AshNativeCursorManager::SetCursor(
104 gfx::NativeCursor cursor
,
105 ::wm::NativeCursorManagerDelegate
* delegate
) {
106 if (native_cursor_enabled_
) {
107 image_cursors_
->SetPlatformCursor(&cursor
);
109 gfx::NativeCursor
invisible_cursor(ui::kCursorNone
);
110 image_cursors_
->SetPlatformCursor(&invisible_cursor
);
111 if (cursor
== ui::kCursorCustom
) {
112 // Fall back to the default pointer cursor for now. (crbug.com/476078)
113 // TODO(oshima): support custom cursor.
114 cursor
= ui::kCursorPointer
;
116 cursor
.SetPlatformCursor(invisible_cursor
.platform());
119 cursor
.set_device_scale_factor(image_cursors_
->GetScale());
121 delegate
->CommitCursor(cursor
);
123 if (delegate
->IsCursorVisible())
124 SetCursorOnAllRootWindows(cursor
);
127 void AshNativeCursorManager::SetCursorSet(
128 ui::CursorSetType cursor_set
,
129 ::wm::NativeCursorManagerDelegate
* delegate
) {
130 image_cursors_
->SetCursorSet(cursor_set
);
131 delegate
->CommitCursorSet(cursor_set
);
133 // Sets the cursor to reflect the scale change immediately.
134 if (delegate
->IsCursorVisible())
135 SetCursor(delegate
->GetCursor(), delegate
);
137 #if defined(OS_CHROMEOS)
139 ->window_tree_host_manager()
140 ->cursor_window_controller()
141 ->SetCursorSet(cursor_set
);
145 void AshNativeCursorManager::SetVisibility(
147 ::wm::NativeCursorManagerDelegate
* delegate
) {
148 delegate
->CommitVisibility(visible
);
151 SetCursor(delegate
->GetCursor(), delegate
);
153 gfx::NativeCursor
invisible_cursor(ui::kCursorNone
);
154 image_cursors_
->SetPlatformCursor(&invisible_cursor
);
155 SetCursorOnAllRootWindows(invisible_cursor
);
158 NotifyCursorVisibilityChange(visible
);
161 void AshNativeCursorManager::SetMouseEventsEnabled(
163 ::wm::NativeCursorManagerDelegate
* delegate
) {
164 delegate
->CommitMouseEventsEnabled(enabled
);
167 aura::Env::GetInstance()->set_last_mouse_location(
168 disabled_cursor_location_
);
170 disabled_cursor_location_
= aura::Env::GetInstance()->last_mouse_location();
173 SetVisibility(delegate
->IsCursorVisible(), delegate
);
174 NotifyMouseEventsEnableStateChange(enabled
);