Home | History | Annotate | Download | only in wm
      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