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 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 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 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 56 AshNativeCursorManager::AshNativeCursorManager() 57 : native_cursor_enabled_(true), 58 image_cursors_(new ui::ImageCursors) { 59 } 60 61 AshNativeCursorManager::~AshNativeCursorManager() { 62 } 63 64 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 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 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 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 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 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