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 
     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