Commit 68bd9289 authored by derat@chromium.org's avatar derat@chromium.org

app_shell: Add support for mouse cursors.

Move ImageCursors from ash/wm/ to ui/base/cursors/ and add a
NativeCursorManager implementation for
ShellDesktopController to use.

BUG=364290
TEST=cursor is visible when running app_shell on a Chrome OS
     device and changes after mousing over a link

Review URL: https://codereview.chromium.org/258893002

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@266694 0039d316-1c4b-4281-b951-d872f2087c98
parent 2f264fc0
......@@ -5,14 +5,21 @@
#include "apps/shell/browser/shell_desktop_controller.h"
#include "apps/shell/browser/shell_app_window.h"
#include "ui/aura/client/cursor_client.h"
#include "ui/aura/env.h"
#include "ui/aura/layout_manager.h"
#include "ui/aura/test/test_screen.h"
#include "ui/aura/window.h"
#include "ui/aura/window_event_dispatcher.h"
#include "ui/aura/window_tree_host.h"
#include "ui/base/cursor/cursor.h"
#include "ui/base/cursor/image_cursors.h"
#include "ui/base/ime/input_method_initializer.h"
#include "ui/gfx/native_widget_types.h"
#include "ui/gfx/screen.h"
#include "ui/wm/core/cursor_manager.h"
#include "ui/wm/core/native_cursor_manager.h"
#include "ui/wm/core/native_cursor_manager_delegate.h"
#include "ui/wm/core/user_activity_detector.h"
#include "ui/wm/test/wm_test_helper.h"
......@@ -59,6 +66,77 @@ class FillLayout : public aura::LayoutManager {
DISALLOW_COPY_AND_ASSIGN(FillLayout);
};
// A class that bridges the gap between CursorManager and Aura. It borrows
// heavily from AshNativeCursorManager.
class ShellNativeCursorManager : public wm::NativeCursorManager {
public:
explicit ShellNativeCursorManager(aura::WindowTreeHost* host)
: host_(host),
image_cursors_(new ui::ImageCursors) {}
virtual ~ShellNativeCursorManager() {}
// wm::NativeCursorManager overrides.
virtual void SetDisplay(
const gfx::Display& display,
wm::NativeCursorManagerDelegate* delegate) OVERRIDE {
if (image_cursors_->SetDisplay(display, display.device_scale_factor()))
SetCursor(delegate->GetCursor(), delegate);
}
virtual void SetCursor(
gfx::NativeCursor cursor,
wm::NativeCursorManagerDelegate* delegate) OVERRIDE {
image_cursors_->SetPlatformCursor(&cursor);
cursor.set_device_scale_factor(image_cursors_->GetScale());
delegate->CommitCursor(cursor);
if (delegate->IsCursorVisible())
ApplyCursor(cursor);
}
virtual void SetVisibility(
bool visible,
wm::NativeCursorManagerDelegate* delegate) OVERRIDE {
delegate->CommitVisibility(visible);
if (visible) {
SetCursor(delegate->GetCursor(), delegate);
} else {
gfx::NativeCursor invisible_cursor(ui::kCursorNone);
image_cursors_->SetPlatformCursor(&invisible_cursor);
ApplyCursor(invisible_cursor);
}
}
virtual void SetCursorSet(
ui::CursorSetType cursor_set,
wm::NativeCursorManagerDelegate* delegate) OVERRIDE {
image_cursors_->SetCursorSet(cursor_set);
delegate->CommitCursorSet(cursor_set);
if (delegate->IsCursorVisible())
SetCursor(delegate->GetCursor(), delegate);
}
virtual void SetMouseEventsEnabled(
bool enabled,
wm::NativeCursorManagerDelegate* delegate) OVERRIDE {
delegate->CommitMouseEventsEnabled(enabled);
SetVisibility(delegate->IsCursorVisible(), delegate);
}
private:
// Sets |cursor| as the active cursor within Aura.
void ApplyCursor(gfx::NativeCursor cursor) {
host_->SetCursor(cursor);
}
aura::WindowTreeHost* host_; // Not owned.
scoped_ptr<ui::ImageCursors> image_cursors_;
DISALLOW_COPY_AND_ASSIGN(ShellNativeCursorManager);
};
ShellDesktopController* g_instance = NULL;
} // namespace
......@@ -72,6 +150,15 @@ ShellDesktopController::ShellDesktopController() {
#endif
CreateRootWindow();
cursor_manager_.reset(
new wm::CursorManager(scoped_ptr<wm::NativeCursorManager>(
new ShellNativeCursorManager(GetWindowTreeHost()))));
cursor_manager_->SetDisplay(
gfx::Screen::GetNativeScreen()->GetPrimaryDisplay());
cursor_manager_->SetCursor(ui::kCursorPointer);
aura::client::SetCursorClient(
GetWindowTreeHost()->window(), cursor_manager_.get());
user_activity_detector_.reset(new wm::UserActivityDetector);
GetWindowTreeHost()->event_processor()->GetRootTarget()->AddPreTargetHandler(
user_activity_detector_.get());
......
......@@ -31,6 +31,7 @@ class UserActivityPowerManagerNotifier;
#endif
namespace wm {
class CursorManager;
class UserActivityDetector;
class WMTestHelper;
}
......@@ -90,6 +91,8 @@ class ShellDesktopController
scoped_ptr<aura::TestScreen> test_screen_;
scoped_ptr<wm::CursorManager> cursor_manager_;
scoped_ptr<wm::UserActivityDetector> user_activity_detector_;
#if defined(OS_CHROMEOS)
scoped_ptr<ui::UserActivityPowerManagerNotifier> user_activity_notifier_;
......
......@@ -566,8 +566,6 @@
'wm/gestures/shelf_gesture_handler.h',
'wm/gestures/tray_gesture_handler.cc',
'wm/gestures/tray_gesture_handler.h',
'wm/image_cursors.cc',
'wm/image_cursors.h',
'wm/immersive_fullscreen_controller.cc',
'wm/immersive_fullscreen_controller.h',
'wm/immersive_revealed_lock.cc',
......
......@@ -10,7 +10,7 @@
#include "ui/gfx/display.h"
namespace ash {
namespace test{
namespace test {
class MirrorWindowTestApi;
}
......
......@@ -7,7 +7,7 @@
#include "ash/shell.h"
#include "ash/test/shell_test_api.h"
#include "ash/wm/ash_native_cursor_manager.h"
#include "ash/wm/image_cursors.h"
#include "ui/base/cursor/image_cursors.h"
#include "ui/gfx/display.h"
#include "ui/wm/core/cursor_manager.h"
......
......@@ -7,12 +7,12 @@
#include "ash/display/cursor_window_controller.h"
#include "ash/display/display_controller.h"
#include "ash/shell.h"
#include "ash/wm/image_cursors.h"
#include "base/logging.h"
#include "ui/aura/env.h"
#include "ui/aura/window_event_dispatcher.h"
#include "ui/aura/window_tree_host.h"
#include "ui/base/cursor/cursor.h"
#include "ui/base/cursor/image_cursors.h"
namespace ash {
namespace {
......@@ -54,7 +54,7 @@ void NotifyMouseEventsEnableStateChange(bool enabled) {
AshNativeCursorManager::AshNativeCursorManager()
: native_cursor_enabled_(true),
image_cursors_(new ImageCursors) {
image_cursors_(new ui::ImageCursors) {
}
AshNativeCursorManager::~AshNativeCursorManager() {
......@@ -72,7 +72,12 @@ void AshNativeCursorManager::SetNativeCursorEnabled(bool enabled) {
void AshNativeCursorManager::SetDisplay(
const gfx::Display& display,
::wm::NativeCursorManagerDelegate* delegate) {
if (image_cursors_->SetDisplay(display))
DCHECK(display.is_valid());
// Use the platform's device scale factor instead of the display's, which
// might have been adjusted for the UI scale.
const float scale_factor = Shell::GetInstance()->display_manager()->
GetDisplayInfo(display.id()).device_scale_factor();
if (image_cursors_->SetDisplay(display, scale_factor))
SetCursor(delegate->GetCursor(), delegate);
#if defined(OS_CHROMEOS)
Shell::GetInstance()->display_controller()->cursor_window_controller()->
......@@ -83,24 +88,23 @@ void AshNativeCursorManager::SetDisplay(
void AshNativeCursorManager::SetCursor(
gfx::NativeCursor cursor,
::wm::NativeCursorManagerDelegate* delegate) {
gfx::NativeCursor new_cursor = cursor;
if (native_cursor_enabled_) {
image_cursors_->SetPlatformCursor(&new_cursor);
image_cursors_->SetPlatformCursor(&cursor);
} else {
gfx::NativeCursor invisible_cursor(ui::kCursorNone);
image_cursors_->SetPlatformCursor(&invisible_cursor);
if (new_cursor == ui::kCursorCustom) {
new_cursor = invisible_cursor;
if (cursor == ui::kCursorCustom) {
cursor = invisible_cursor;
} else {
new_cursor.SetPlatformCursor(invisible_cursor.platform());
cursor.SetPlatformCursor(invisible_cursor.platform());
}
}
new_cursor.set_device_scale_factor(image_cursors_->GetScale());
cursor.set_device_scale_factor(image_cursors_->GetScale());
delegate->CommitCursor(new_cursor);
delegate->CommitCursor(cursor);
if (delegate->IsCursorVisible())
SetCursorOnAllRootWindows(new_cursor);
SetCursorOnAllRootWindows(cursor);
}
void AshNativeCursorManager::SetCursorSet(
......
......@@ -15,14 +15,16 @@
#include "ui/wm/core/native_cursor_manager.h"
#include "ui/wm/core/native_cursor_manager_delegate.h"
namespace ui {
class ImageCursors;
}
namespace ash {
namespace test {
class CursorManagerTestApi;
}
class ImageCursors;
// This does the ash-specific setting of cursor details like cursor
// visibility. It communicates back with the CursorManager through the
// NativeCursorManagerDelegate interface, which receives messages about what
......@@ -64,7 +66,7 @@ class ASH_EXPORT AshNativeCursorManager
bool native_cursor_enabled_;
scoped_ptr<ImageCursors> image_cursors_;
scoped_ptr<ui::ImageCursors> image_cursors_;
DISALLOW_COPY_AND_ASSIGN(AshNativeCursorManager);
};
......
......@@ -9,12 +9,12 @@
#include "ash/shell.h"
#include "ash/test/ash_test_base.h"
#include "ash/test/cursor_manager_test_api.h"
#include "ash/wm/image_cursors.h"
#include "ui/aura/test/aura_test_utils.h"
#include "ui/aura/test/test_window_delegate.h"
#include "ui/aura/test/test_windows.h"
#include "ui/aura/window.h"
#include "ui/aura/window_event_dispatcher.h"
#include "ui/base/cursor/image_cursors.h"
#include "ui/gfx/screen.h"
#if defined(OS_WIN)
......
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "ash/wm/image_cursors.h"
#include "ui/base/cursor/image_cursors.h"
#include <float.h>
#include "ash/display/display_info.h"
#include "ash/display/display_manager.h"
#include "ash/shell.h"
#include "base/logging.h"
#include "base/strings/string16.h"
#include "ui/base/cursor/cursor.h"
......@@ -17,49 +14,53 @@
#include "ui/gfx/display.h"
#include "ui/gfx/point.h"
namespace ash {
namespace ui {
namespace {
const int kImageCursorIds[] = {
ui::kCursorNull,
ui::kCursorPointer,
ui::kCursorNoDrop,
ui::kCursorNotAllowed,
ui::kCursorCopy,
ui::kCursorHand,
ui::kCursorMove,
ui::kCursorNorthEastResize,
ui::kCursorSouthWestResize,
ui::kCursorSouthEastResize,
ui::kCursorNorthWestResize,
ui::kCursorNorthResize,
ui::kCursorSouthResize,
ui::kCursorEastResize,
ui::kCursorWestResize,
ui::kCursorIBeam,
ui::kCursorAlias,
ui::kCursorCell,
ui::kCursorContextMenu,
ui::kCursorCross,
ui::kCursorHelp,
ui::kCursorVerticalText,
ui::kCursorZoomIn,
ui::kCursorZoomOut,
ui::kCursorRowResize,
ui::kCursorColumnResize,
ui::kCursorEastWestResize,
ui::kCursorNorthSouthResize,
ui::kCursorNorthEastSouthWestResize,
ui::kCursorNorthWestSouthEastResize,
ui::kCursorGrab,
ui::kCursorGrabbing,
kCursorNull,
kCursorPointer,
kCursorNoDrop,
kCursorNotAllowed,
kCursorCopy,
kCursorHand,
kCursorMove,
kCursorNorthEastResize,
kCursorSouthWestResize,
kCursorSouthEastResize,
kCursorNorthWestResize,
kCursorNorthResize,
kCursorSouthResize,
kCursorEastResize,
kCursorWestResize,
kCursorIBeam,
kCursorAlias,
kCursorCell,
kCursorContextMenu,
kCursorCross,
kCursorHelp,
kCursorVerticalText,
kCursorZoomIn,
kCursorZoomOut,
kCursorRowResize,
kCursorColumnResize,
kCursorEastWestResize,
kCursorNorthSouthResize,
kCursorNorthEastSouthWestResize,
kCursorNorthWestSouthEastResize,
kCursorGrab,
kCursorGrabbing,
};
const int kAnimatedCursorIds[] = {
ui::kCursorWait,
ui::kCursorProgress
kCursorWait,
kCursorProgress
};
ImageCursors::ImageCursors() : cursor_set_(ui::CURSOR_SET_NORMAL) {
} // namespace
ImageCursors::ImageCursors() : cursor_set_(CURSOR_SET_NORMAL) {
}
ImageCursors::~ImageCursors() {
......@@ -85,15 +86,10 @@ gfx::Display::Rotation ImageCursors::GetRotation() const {
return cursor_loader_->rotation();
}
bool ImageCursors::SetDisplay(const gfx::Display& display) {
DCHECK(display.is_valid());
// Use the platform's device scale factor instead of display's
// that might have been adjusted for UI scale.
float scale_factor = Shell::GetInstance()->display_manager()->
GetDisplayInfo(display.id()).device_scale_factor();
bool ImageCursors::SetDisplay(const gfx::Display& display,
float scale_factor) {
if (!cursor_loader_) {
cursor_loader_.reset(ui::CursorLoader::Create());
cursor_loader_.reset(CursorLoader::Create());
} else if (cursor_loader_->rotation() == display.rotation() &&
cursor_loader_->scale() == scale_factor) {
return false;
......@@ -113,31 +109,31 @@ void ImageCursors::ReloadCursors() {
for (size_t i = 0; i < arraysize(kImageCursorIds); ++i) {
int resource_id = -1;
gfx::Point hot_point;
bool success = ui::GetCursorDataFor(cursor_set_,
kImageCursorIds[i],
device_scale_factor,
&resource_id,
&hot_point);
bool success = GetCursorDataFor(cursor_set_,
kImageCursorIds[i],
device_scale_factor,
&resource_id,
&hot_point);
DCHECK(success);
cursor_loader_->LoadImageCursor(kImageCursorIds[i], resource_id, hot_point);
}
for (size_t i = 0; i < arraysize(kAnimatedCursorIds); ++i) {
int resource_id = -1;
gfx::Point hot_point;
bool success = ui::GetAnimatedCursorDataFor(cursor_set_,
kAnimatedCursorIds[i],
device_scale_factor,
&resource_id,
&hot_point);
bool success = GetAnimatedCursorDataFor(cursor_set_,
kAnimatedCursorIds[i],
device_scale_factor,
&resource_id,
&hot_point);
DCHECK(success);
cursor_loader_->LoadAnimatedCursor(kAnimatedCursorIds[i],
resource_id,
hot_point,
ui::kAnimatedCursorFrameDelayMs);
kAnimatedCursorFrameDelayMs);
}
}
void ImageCursors::SetCursorSet(ui::CursorSetType cursor_set) {
void ImageCursors::SetCursorSet(CursorSetType cursor_set) {
if (cursor_set_ == cursor_set)
return;
......@@ -151,4 +147,4 @@ void ImageCursors::SetPlatformCursor(gfx::NativeCursor* cursor) {
cursor_loader_->SetPlatformCursor(cursor);
}
} // namespace ash
} // namespace ui
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef ASH_WM_IMAGE_CURSORS_H_
#define ASH_WM_IMAGE_CURSORS_H_
#ifndef UI_BASE_CURSOR_IMAGE_CURSORS_H_
#define UI_BASE_CURSOR_IMAGE_CURSORS_H_
#include "ash/ash_export.h"
#include "base/memory/scoped_ptr.h"
#include "base/strings/string16.h"
#include "ui/base/cursor/cursor.h"
#include "ui/base/ui_base_export.h"
#include "ui/gfx/display.h"
#include "ui/gfx/native_widget_types.h"
namespace ui {
class CursorLoader;
}
namespace ash {
class CursorLoader;
// A utility class that provides cursors for NativeCursors for which we have
// image resources.
class ASH_EXPORT ImageCursors {
class UI_BASE_EXPORT ImageCursors {
public:
ImageCursors();
~ImageCursors();
......@@ -29,14 +27,12 @@ class ASH_EXPORT ImageCursors {
float GetScale() const;
gfx::Display::Rotation GetRotation() const;
// Sets the display the cursors are loaded for. The device scale factor
// determines the size of the image to load, and the rotation of the display
// determines if the image and its host point has to be retated.
// Returns true if the cursor image is reloaded.
bool SetDisplay(const gfx::Display& display);
// Sets the display the cursors are loaded for. |scale_factor| determines the
// size of the image to load. Returns true if the cursor image is reloaded.
bool SetDisplay(const gfx::Display& display, float scale_factor);
// Sets the type of the mouse cursor icon.
void SetCursorSet(ui::CursorSetType cursor_set);
void SetCursorSet(CursorSetType cursor_set);
// Sets the platform cursor based on the native type of |cursor|.
void SetPlatformCursor(gfx::NativeCursor* cursor);
......@@ -45,12 +41,12 @@ class ASH_EXPORT ImageCursors {
// Reloads the all loaded cursors in the cursor loader.
void ReloadCursors();
scoped_ptr<ui::CursorLoader> cursor_loader_;
ui::CursorSetType cursor_set_;
scoped_ptr<CursorLoader> cursor_loader_;
CursorSetType cursor_set_;
DISALLOW_COPY_AND_ASSIGN(ImageCursors);
};
} // namespace ash
} // namespace ui
#endif // ASH_WM_IMAGE_CURSORS_H_
#endif // UI_BASE_CURSOR_IMAGE_CURSORS_H_
......@@ -132,6 +132,8 @@
'cursor/cursor_x11.cc',
'cursor/cursors_aura.cc',
'cursor/cursors_aura.h',
'cursor/image_cursors.cc',
'cursor/image_cursors.h',
'cursor/ozone/bitmap_cursor_factory_ozone.cc',
'cursor/ozone/bitmap_cursor_factory_ozone.h',
'cursor/ozone/cursor_factory_ozone.cc',
......@@ -474,6 +476,8 @@
'../../third_party/mozilla/mozilla.gyp:mozilla',
],
'sources!': [
'cursor/image_cursors.cc',
'cursor/image_cursors.h',
'dragdrop/drag_utils.cc',
'dragdrop/drag_utils.h',
],
......@@ -512,6 +516,8 @@
}],
['OS=="android"', {
'sources!': [
'cursor/image_cursors.cc',
'cursor/image_cursors.h',
'default_theme_provider.cc',
'dragdrop/drag_utils.cc',
'dragdrop/drag_utils.h',
......
......@@ -6,6 +6,7 @@
#define UI_WM_CORE_NATIVE_CURSOR_MANAGER_H_
#include "base/strings/string16.h"
#include "ui/base/cursor/cursor.h"
#include "ui/wm/core/native_cursor_manager_delegate.h"
#include "ui/wm/wm_export.h"
......@@ -26,33 +27,33 @@ class WM_EXPORT NativeCursorManager {
// A request to set the screen DPI. Can cause changes in the current cursor.
virtual void SetDisplay(
const gfx::Display& display,
wm::NativeCursorManagerDelegate* delegate) = 0;
NativeCursorManagerDelegate* delegate) = 0;
// A request to set the cursor to |cursor|. At minimum, implementer should
// call NativeCursorManagerDelegate::CommitCursor() with whatever cursor is
// actually used.
virtual void SetCursor(
gfx::NativeCursor cursor,
wm::NativeCursorManagerDelegate* delegate) = 0;
NativeCursorManagerDelegate* delegate) = 0;
// A request to set the visibility of the cursor. At minimum, implementer
// should call NativeCursorManagerDelegate::CommitVisibility() with whatever
// the visibility is.
virtual void SetVisibility(
bool visible,
wm::NativeCursorManagerDelegate* delegate) = 0;
NativeCursorManagerDelegate* delegate) = 0;
// A request to set the cursor set.
virtual void SetCursorSet(
ui::CursorSetType cursor_set,
wm::NativeCursorManagerDelegate* delegate) = 0;
NativeCursorManagerDelegate* delegate) = 0;
// A request to set whether mouse events are disabled. At minimum,
// implementer should call NativeCursorManagerDelegate::
// CommitMouseEventsEnabled() with whether mouse events are actually enabled.
virtual void SetMouseEventsEnabled(
bool enabled,
wm::NativeCursorManagerDelegate* delegate) = 0;
NativeCursorManagerDelegate* delegate) = 0;
};
} // namespace wm
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment