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 17 namespace ash { 18 namespace { 19 20 void SetCursorOnAllRootWindows(gfx::NativeCursor cursor) { 21 aura::Window::Windows root_windows = 22 Shell::GetInstance()->GetAllRootWindows(); 23 for (aura::Window::Windows::iterator iter = root_windows.begin(); 24 iter != root_windows.end(); ++iter) 25 (*iter)->GetHost()->SetCursor(cursor); 26 #if defined(OS_CHROMEOS) 27 Shell::GetInstance()->display_controller()-> 28 cursor_window_controller()->SetCursor(cursor); 29 #endif 30 } 31 32 void NotifyCursorVisibilityChange(bool visible) { 33 aura::Window::Windows root_windows = 34 Shell::GetInstance()->GetAllRootWindows(); 35 for (aura::Window::Windows::iterator iter = root_windows.begin(); 36 iter != root_windows.end(); ++iter) 37 (*iter)->GetHost()->OnCursorVisibilityChanged(visible); 38 #if defined(OS_CHROMEOS) 39 Shell::GetInstance()->display_controller()->cursor_window_controller()-> 40 SetVisibility(visible); 41 #endif 42 } 43 44 void NotifyMouseEventsEnableStateChange(bool enabled) { 45 aura::Window::Windows root_windows = 46 Shell::GetInstance()->GetAllRootWindows(); 47 for (aura::Window::Windows::iterator iter = root_windows.begin(); 48 iter != root_windows.end(); ++iter) 49 (*iter)->GetHost()->dispatcher()->OnMouseEventsEnableStateChanged(enabled); 50 // Mirror window never process events. 51 } 52 53 } // namespace 54 55 AshNativeCursorManager::AshNativeCursorManager() 56 : native_cursor_enabled_(true), 57 image_cursors_(new ui::ImageCursors) { 58 } 59 60 AshNativeCursorManager::~AshNativeCursorManager() { 61 } 62 63 64 void AshNativeCursorManager::SetNativeCursorEnabled(bool enabled) { 65 native_cursor_enabled_ = enabled; 66 67 ::wm::CursorManager* cursor_manager = 68 Shell::GetInstance()->cursor_manager(); 69 SetCursor(cursor_manager->GetCursor(), cursor_manager); 70 } 71 72 void AshNativeCursorManager::SetDisplay( 73 const gfx::Display& display, 74 ::wm::NativeCursorManagerDelegate* delegate) { 75 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)) 81 SetCursor(delegate->GetCursor(), delegate); 82 #if defined(OS_CHROMEOS) 83 Shell::GetInstance()->display_controller()->cursor_window_controller()-> 84 SetDisplay(display); 85 #endif 86 } 87 88 void AshNativeCursorManager::SetCursor( 89 gfx::NativeCursor cursor, 90 ::wm::NativeCursorManagerDelegate* delegate) { 91 if (native_cursor_enabled_) { 92 image_cursors_->SetPlatformCursor(&cursor); 93 } else { 94 gfx::NativeCursor invisible_cursor(ui::kCursorNone); 95 image_cursors_->SetPlatformCursor(&invisible_cursor); 96 if (cursor == ui::kCursorCustom) { 97 cursor = invisible_cursor; 98 } else { 99 cursor.SetPlatformCursor(invisible_cursor.platform()); 100 } 101 } 102 cursor.set_device_scale_factor(image_cursors_->GetScale()); 103 104 delegate->CommitCursor(cursor); 105 106 if (delegate->IsCursorVisible()) 107 SetCursorOnAllRootWindows(cursor); 108 } 109 110 void AshNativeCursorManager::SetCursorSet( 111 ui::CursorSetType cursor_set, 112 ::wm::NativeCursorManagerDelegate* delegate) { 113 image_cursors_->SetCursorSet(cursor_set); 114 delegate->CommitCursorSet(cursor_set); 115 116 // Sets the cursor to reflect the scale change immediately. 117 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 124 } 125 126 void AshNativeCursorManager::SetVisibility( 127 bool visible, 128 ::wm::NativeCursorManagerDelegate* delegate) { 129 delegate->CommitVisibility(visible); 130 131 if (visible) { 132 SetCursor(delegate->GetCursor(), delegate); 133 } 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 142 void AshNativeCursorManager::SetMouseEventsEnabled( 143 bool enabled, 144 ::wm::NativeCursorManagerDelegate* delegate) { 145 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(); 152 } 153 154 SetVisibility(delegate->IsCursorVisible(), delegate); 155 NotifyMouseEventsEnableStateChange(enabled); 156 } 157 158 } // namespace ash 159