• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.
4 
5 #include "ash/wm/ash_native_cursor_manager.h"
6 
7 #include "ash/display/cursor_window_controller.h"
8 #include "ash/display/display_controller.h"
9 #include "ash/shell.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"
17 
18 namespace ash {
19 namespace  {
20 
SetCursorOnAllRootWindows(gfx::NativeCursor cursor)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)
28   Shell::GetInstance()->display_controller()->
29       cursor_window_controller()->SetCursor(cursor);
30 #endif
31 }
32 
NotifyCursorVisibilityChange(bool visible)33 void NotifyCursorVisibilityChange(bool visible) {
34   aura::Window::Windows root_windows =
35       Shell::GetInstance()->GetAllRootWindows();
36   for (aura::Window::Windows::iterator iter = root_windows.begin();
37        iter != root_windows.end(); ++iter)
38     (*iter)->GetHost()->OnCursorVisibilityChanged(visible);
39 #if defined(OS_CHROMEOS)
40   Shell::GetInstance()->display_controller()->cursor_window_controller()->
41       SetVisibility(visible);
42 #endif
43 }
44 
NotifyMouseEventsEnableStateChange(bool enabled)45 void NotifyMouseEventsEnableStateChange(bool enabled) {
46   aura::Window::Windows root_windows =
47       Shell::GetInstance()->GetAllRootWindows();
48   for (aura::Window::Windows::iterator iter = root_windows.begin();
49        iter != root_windows.end(); ++iter)
50     (*iter)->GetHost()->dispatcher()->OnMouseEventsEnableStateChanged(enabled);
51   // Mirror window never process events.
52 }
53 
54 }  // namespace
55 
AshNativeCursorManager()56 AshNativeCursorManager::AshNativeCursorManager()
57     : native_cursor_enabled_(true),
58       image_cursors_(new ui::ImageCursors) {
59 }
60 
~AshNativeCursorManager()61 AshNativeCursorManager::~AshNativeCursorManager() {
62 }
63 
64 
SetNativeCursorEnabled(bool enabled)65 void AshNativeCursorManager::SetNativeCursorEnabled(bool enabled) {
66   native_cursor_enabled_ = enabled;
67 
68   ::wm::CursorManager* cursor_manager =
69       Shell::GetInstance()->cursor_manager();
70   SetCursor(cursor_manager->GetCursor(), cursor_manager);
71 }
72 
SetDisplay(const gfx::Display & display,::wm::NativeCursorManagerDelegate * delegate)73 void AshNativeCursorManager::SetDisplay(
74     const gfx::Display& display,
75     ::wm::NativeCursorManagerDelegate* delegate) {
76   DCHECK(display.is_valid());
77   // Use the platform's device scale factor instead of the display's, which
78   // might have been adjusted for the UI scale.
79   const float original_scale = Shell::GetInstance()->display_manager()->
80       GetDisplayInfo(display.id()).device_scale_factor();
81 #if defined(OS_CHROMEOS)
82   // And use the nearest resource scale factor.
83   const float cursor_scale = ui::GetScaleForScaleFactor(
84       ui::GetSupportedScaleFactor(original_scale));
85 #else
86   // TODO(oshima): crbug.com/143619
87   const float cursor_scale = original_scale;
88 #endif
89   if (image_cursors_->SetDisplay(display, cursor_scale))
90     SetCursor(delegate->GetCursor(), delegate);
91 #if defined(OS_CHROMEOS)
92   Shell::GetInstance()->display_controller()->cursor_window_controller()->
93       SetDisplay(display);
94 #endif
95 }
96 
SetCursor(gfx::NativeCursor cursor,::wm::NativeCursorManagerDelegate * delegate)97 void AshNativeCursorManager::SetCursor(
98     gfx::NativeCursor cursor,
99     ::wm::NativeCursorManagerDelegate* delegate) {
100   if (native_cursor_enabled_) {
101     image_cursors_->SetPlatformCursor(&cursor);
102   } else {
103     gfx::NativeCursor invisible_cursor(ui::kCursorNone);
104     image_cursors_->SetPlatformCursor(&invisible_cursor);
105     if (cursor == ui::kCursorCustom) {
106       cursor = invisible_cursor;
107     } else {
108       cursor.SetPlatformCursor(invisible_cursor.platform());
109     }
110   }
111   cursor.set_device_scale_factor(image_cursors_->GetScale());
112 
113   delegate->CommitCursor(cursor);
114 
115   if (delegate->IsCursorVisible())
116     SetCursorOnAllRootWindows(cursor);
117 }
118 
SetCursorSet(ui::CursorSetType cursor_set,::wm::NativeCursorManagerDelegate * delegate)119 void AshNativeCursorManager::SetCursorSet(
120     ui::CursorSetType cursor_set,
121     ::wm::NativeCursorManagerDelegate* delegate) {
122   image_cursors_->SetCursorSet(cursor_set);
123   delegate->CommitCursorSet(cursor_set);
124 
125   // Sets the cursor to reflect the scale change immediately.
126   if (delegate->IsCursorVisible())
127     SetCursor(delegate->GetCursor(), delegate);
128 
129 #if defined(OS_CHROMEOS)
130   Shell::GetInstance()->display_controller()->cursor_window_controller()->
131       SetCursorSet(cursor_set);
132 #endif
133 }
134 
SetVisibility(bool visible,::wm::NativeCursorManagerDelegate * delegate)135 void AshNativeCursorManager::SetVisibility(
136     bool visible,
137     ::wm::NativeCursorManagerDelegate* delegate) {
138   delegate->CommitVisibility(visible);
139 
140   if (visible) {
141     SetCursor(delegate->GetCursor(), delegate);
142   } else {
143     gfx::NativeCursor invisible_cursor(ui::kCursorNone);
144     image_cursors_->SetPlatformCursor(&invisible_cursor);
145     SetCursorOnAllRootWindows(invisible_cursor);
146   }
147 
148   NotifyCursorVisibilityChange(visible);
149 }
150 
SetMouseEventsEnabled(bool enabled,::wm::NativeCursorManagerDelegate * delegate)151 void AshNativeCursorManager::SetMouseEventsEnabled(
152     bool enabled,
153     ::wm::NativeCursorManagerDelegate* delegate) {
154   delegate->CommitMouseEventsEnabled(enabled);
155 
156   if (enabled) {
157     aura::Env::GetInstance()->set_last_mouse_location(
158         disabled_cursor_location_);
159   } else {
160     disabled_cursor_location_ = aura::Env::GetInstance()->last_mouse_location();
161   }
162 
163   SetVisibility(delegate->IsCursorVisible(), delegate);
164   NotifyMouseEventsEnableStateChange(enabled);
165 }
166 
167 }  // namespace ash
168