Commit dcee7502 authored by Henrique Ferreiro's avatar Henrique Ferreiro Committed by Commit Bot

Fix loading of animated cursors on Ozone/Wayland

Animated cursor assets were not being loaded because GetCursorDataFor
was used for all cursors, instead of using GetAnimatedCursorDataFor when
the cursor was animated.

With this CL, both set of cursors are merged so they can be retrieved
with a single call.

To ease these changes, ImageCursor, which was a very thin layer over
CursorLoader, was merged into the latter. This change has the benefit of
unifying the cursor loading code path of Ash with the one of the other
Aura platforms and changing Ash on Linux to use the Chromium assets
instead of the platform cursors, as when running on Chrome OS devices.

The only behavior change with respect to ImageCursors is that the cached
cursors will be removed on display changes, instead of reloaded.

Bug: 1135515
Change-Id: Iedf84290bf3792c3ce06cfad0be1b5c0e2d96946
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2440760
Commit-Queue: Henrique Ferreiro <hferreiro@igalia.com>
Reviewed-by: default avatarScott Violet <sky@chromium.org>
Cr-Commit-Position: refs/heads/master@{#815678}
parent 704cdba1
......@@ -12,7 +12,7 @@
#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/cursor/cursor_loader.h"
#include "ui/base/cursor/mojom/cursor_type.mojom-shared.h"
#include "ui/base/layout.h"
#include "ui/wm/core/native_cursor_manager_delegate.h"
......@@ -55,7 +55,9 @@ void NotifyMouseEventsEnableStateChange(bool enabled) {
} // namespace
NativeCursorManagerAsh::NativeCursorManagerAsh()
: native_cursor_enabled_(true), image_cursors_(new ui::ImageCursors) {}
: native_cursor_enabled_(true),
cursor_loader_(ui::CursorLoader::Create(/*use_platform_cursors=*/false)) {
}
NativeCursorManagerAsh::~NativeCursorManagerAsh() = default;
......@@ -67,11 +69,11 @@ void NativeCursorManagerAsh::SetNativeCursorEnabled(bool enabled) {
}
float NativeCursorManagerAsh::GetScale() const {
return image_cursors_->GetScale();
return cursor_loader_->scale();
}
display::Display::Rotation NativeCursorManagerAsh::GetRotation() const {
return image_cursors_->GetRotation();
return cursor_loader_->rotation();
}
void NativeCursorManagerAsh::SetDisplay(
......@@ -84,7 +86,7 @@ void NativeCursorManagerAsh::SetDisplay(
const float cursor_scale =
ui::GetScaleForScaleFactor(ui::GetSupportedScaleFactor(original_scale));
if (image_cursors_->SetDisplay(display, cursor_scale))
if (cursor_loader_->SetDisplayData(display.panel_rotation(), cursor_scale))
SetCursor(delegate->GetCursor(), delegate);
Shell::Get()
......@@ -97,13 +99,13 @@ void NativeCursorManagerAsh::SetCursor(
gfx::NativeCursor cursor,
::wm::NativeCursorManagerDelegate* delegate) {
if (native_cursor_enabled_) {
image_cursors_->SetPlatformCursor(&cursor);
cursor_loader_->SetPlatformCursor(&cursor);
} else {
gfx::NativeCursor invisible_cursor(ui::mojom::CursorType::kNone);
image_cursors_->SetPlatformCursor(&invisible_cursor);
cursor_loader_->SetPlatformCursor(&invisible_cursor);
cursor.SetPlatformCursor(invisible_cursor.platform());
}
cursor.set_image_scale_factor(image_cursors_->GetScale());
cursor.set_image_scale_factor(cursor_loader_->scale());
delegate->CommitCursor(cursor);
......@@ -114,7 +116,7 @@ void NativeCursorManagerAsh::SetCursor(
void NativeCursorManagerAsh::SetCursorSize(
ui::CursorSize cursor_size,
::wm::NativeCursorManagerDelegate* delegate) {
image_cursors_->SetCursorSize(cursor_size);
cursor_loader_->set_size(cursor_size);
delegate->CommitCursorSize(cursor_size);
// Sets the cursor to reflect the scale change immediately.
......@@ -136,7 +138,7 @@ void NativeCursorManagerAsh::SetVisibility(
SetCursor(delegate->GetCursor(), delegate);
} else {
gfx::NativeCursor invisible_cursor(ui::mojom::CursorType::kNone);
image_cursors_->SetPlatformCursor(&invisible_cursor);
cursor_loader_->SetPlatformCursor(&invisible_cursor);
SetCursorOnAllRootWindows(invisible_cursor);
}
......
......@@ -11,7 +11,7 @@
#include "ui/wm/core/native_cursor_manager.h"
namespace ui {
class ImageCursors;
class CursorLoader;
}
namespace ash {
......@@ -56,7 +56,7 @@ class ASH_EXPORT NativeCursorManagerAsh : public ::wm::NativeCursorManager {
bool native_cursor_enabled_;
std::unique_ptr<ui::ImageCursors> image_cursors_;
std::unique_ptr<ui::CursorLoader> cursor_loader_;
DISALLOW_COPY_AND_ASSIGN(NativeCursorManagerAsh);
};
......
......@@ -17,7 +17,7 @@
#include "ui/aura/window.h"
#include "ui/aura/window_tree_host.h"
#include "ui/base/cursor/cursor.h"
#include "ui/base/cursor/image_cursors.h"
#include "ui/base/cursor/cursor_loader.h"
#include "ui/base/cursor/mojom/cursor_type.mojom-shared.h"
#include "ui/base/ime/init/input_method_factory.h"
#include "ui/base/ime/input_method.h"
......@@ -57,21 +57,21 @@ class ShellNativeCursorManager : public wm::NativeCursorManager {
public:
explicit ShellNativeCursorManager(
ShellDesktopControllerAura* desktop_controller)
: desktop_controller_(desktop_controller),
image_cursors_(new ui::ImageCursors) {}
: desktop_controller_(desktop_controller) {}
~ShellNativeCursorManager() override {}
// wm::NativeCursorManager overrides.
void SetDisplay(const display::Display& display,
wm::NativeCursorManagerDelegate* delegate) override {
if (image_cursors_->SetDisplay(display, display.device_scale_factor()))
if (cursor_loader_->SetDisplayData(display.panel_rotation(),
display.device_scale_factor()))
SetCursor(delegate->GetCursor(), delegate);
}
void SetCursor(gfx::NativeCursor cursor,
wm::NativeCursorManagerDelegate* delegate) override {
image_cursors_->SetPlatformCursor(&cursor);
cursor.set_image_scale_factor(image_cursors_->GetScale());
cursor_loader_->SetPlatformCursor(&cursor);
cursor.set_image_scale_factor(cursor_loader_->scale());
delegate->CommitCursor(cursor);
if (delegate->IsCursorVisible())
......@@ -86,14 +86,14 @@ class ShellNativeCursorManager : public wm::NativeCursorManager {
SetCursor(delegate->GetCursor(), delegate);
} else {
gfx::NativeCursor invisible_cursor(ui::mojom::CursorType::kNone);
image_cursors_->SetPlatformCursor(&invisible_cursor);
cursor_loader_->SetPlatformCursor(&invisible_cursor);
SetCursorOnAllRootWindows(invisible_cursor);
}
}
void SetCursorSize(ui::CursorSize cursor_size,
wm::NativeCursorManagerDelegate* delegate) override {
image_cursors_->SetCursorSize(cursor_size);
cursor_loader_->set_size(cursor_size);
delegate->CommitCursorSize(cursor_size);
if (delegate->IsCursorVisible())
SetCursor(delegate->GetCursor(), delegate);
......@@ -115,7 +115,8 @@ class ShellNativeCursorManager : public wm::NativeCursorManager {
ShellDesktopControllerAura* desktop_controller_; // Not owned.
std::unique_ptr<ui::ImageCursors> image_cursors_;
std::unique_ptr<ui::CursorLoader> cursor_loader_ =
ui::CursorLoader::Create(/*use_platform_cursors=*/false);
DISALLOW_COPY_AND_ASSIGN(ShellNativeCursorManager);
};
......
......@@ -55,8 +55,6 @@ if (use_aura) {
"cursor_util.h",
"cursors_aura.cc",
"cursors_aura.h",
"image_cursors.cc",
"image_cursors.h",
]
defines = [ "IS_UI_BASE_CURSOR_IMPL" ]
public_deps = [
......
......@@ -46,6 +46,7 @@ class COMPONENT_EXPORT(UI_BASE_CURSOR_BASE) CursorFactory {
// cursors are referenced counted and have an initial refcount of 1.
// Therefore, each CreateAnimatedCursor call must be matched with a call to
// UnrefImageCursor.
// |frame_delay_ms| is the delay between frames in millisecond.
virtual PlatformCursor CreateAnimatedCursor(
const std::vector<SkBitmap>& bitmaps,
const gfx::Point& hotspot,
......
......@@ -5,71 +5,70 @@
#ifndef UI_BASE_CURSOR_CURSOR_LOADER_H_
#define UI_BASE_CURSOR_CURSOR_LOADER_H_
#include <memory>
#include "base/component_export.h"
#include "base/macros.h"
#include "ui/base/cursor/cursor_size.h"
#include "ui/base/cursor/mojom/cursor_type.mojom-forward.h"
#include "ui/display/display.h"
#include "ui/gfx/native_widget_types.h"
namespace gfx {
class Point;
}
namespace ui {
class COMPONENT_EXPORT(UI_BASE_CURSOR) CursorLoader {
public:
CursorLoader() : scale_(1.f), rotation_(display::Display::ROTATE_0) {}
virtual ~CursorLoader() {}
CursorLoader() = default;
CursorLoader(const CursorLoader&) = delete;
CursorLoader& operator=(const CursorLoader&) = delete;
virtual ~CursorLoader() = default;
// Returns the rotation and scale of the currently loaded cursor.
display::Display::Rotation rotation() const { return rotation_; }
float scale() const { return scale_; }
// Sets the rotation and scale the cursors are loaded for.
// Returns true if the cursor image was reloaded.
bool SetDisplayData(display::Display::Rotation rotation, float scale) {
if (rotation_ == rotation && scale_ == scale)
return false;
void set_rotation(display::Display::Rotation rotation) {
rotation_ = rotation;
scale_ = scale;
UnloadAll();
return true;
}
// Returns the current scale of the mouse cursor icon.
float scale() const {
return scale_;
}
// Returns the size of the currently loaded cursor.
CursorSize size() { return size_; }
// Sets the scale of the mouse cursor icon.
void set_scale(const float scale) {
scale_ = scale;
}
// Sets the size of the mouse cursor icon.
void set_size(CursorSize size) {
if (size_ == size)
return;
// Creates a cursor from an image resource and puts it in the cursor map.
virtual void LoadImageCursor(mojom::CursorType id,
int resource_id,
const gfx::Point& hot) = 0;
// Creates an animated cursor from an image resource and puts it in the
// cursor map. The image is assumed to be a concatenation of animation frames
// from left to right. Also, each frame is assumed to be square
// (width == height).
// |frame_delay_ms| is the delay between frames in millisecond.
virtual void LoadAnimatedCursor(mojom::CursorType id,
int resource_id,
const gfx::Point& hot,
int frame_delay_ms) = 0;
// Unloads all the cursors.
virtual void UnloadAll() = 0;
size_ = size;
UnloadAll();
}
// Sets the platform cursor based on the native type of |cursor|.
virtual void SetPlatformCursor(gfx::NativeCursor* cursor) = 0;
// Creates a CursorLoader.
static CursorLoader* Create();
static std::unique_ptr<CursorLoader> Create(bool use_platform_cursors = true);
protected:
// Resets the cursor cache.
virtual void UnloadAll() = 0;
private:
// The current scale of the mouse cursor icon.
float scale_;
float scale_ = 1.0f;
// The current rotation of the mouse cursor icon.
display::Display::Rotation rotation_;
display::Display::Rotation rotation_ = display::Display::ROTATE_0;
DISALLOW_COPY_AND_ASSIGN(CursorLoader);
// The preferred size of the mouse cursor icon.
CursorSize size_ = CursorSize::kNormal;
};
} // namespace ui
......
......@@ -6,45 +6,31 @@
#include <vector>
#include "base/ranges/algorithm.h"
#include "ui/base/cursor/cursor_factory.h"
#include "ui/base/cursor/cursor_size.h"
#include "ui/base/cursor/cursor_util.h"
#include "ui/base/cursor/cursors_aura.h"
#include "ui/base/cursor/mojom/cursor_type.mojom-shared.h"
#include "ui/gfx/geometry/point.h"
namespace ui {
CursorLoaderOzone::CursorLoaderOzone() {
factory_ = CursorFactory::GetInstance();
}
CursorLoaderOzone::~CursorLoaderOzone() {
UnloadAll();
}
namespace {
void CursorLoaderOzone::LoadImageCursor(mojom::CursorType id,
int resource_id,
const gfx::Point& hot) {
SkBitmap bitmap;
gfx::Point hotspot = hot;
constexpr mojom::CursorType kAnimatedCursorTypes[] = {
mojom::CursorType::kWait, mojom::CursorType::kProgress};
GetImageCursorBitmap(resource_id, scale(), rotation(), &hotspot, &bitmap);
image_cursors_[id] = factory_->CreateImageCursor(bitmap, hotspot);
}
const int kAnimatedCursorFrameDelayMs = 25;
void CursorLoaderOzone::LoadAnimatedCursor(mojom::CursorType id,
int resource_id,
const gfx::Point& hot,
int frame_delay_ms) {
std::vector<SkBitmap> bitmaps;
gfx::Point hotspot = hot;
} // namespace
GetAnimatedCursorBitmaps(
resource_id, scale(), rotation(), &hotspot, &bitmaps);
CursorLoaderOzone::CursorLoaderOzone(bool use_platform_cursors)
: use_platform_cursors_(use_platform_cursors),
factory_(CursorFactory::GetInstance()) {}
image_cursors_[id] =
factory_->CreateAnimatedCursor(bitmaps, hotspot, frame_delay_ms);
CursorLoaderOzone::~CursorLoaderOzone() {
UnloadAll();
}
void CursorLoaderOzone::UnloadAll() {
......@@ -63,43 +49,61 @@ void CursorLoaderOzone::SetPlatformCursor(gfx::NativeCursor* cursor) {
cursor->SetPlatformCursor(CursorFromType(cursor->type()));
}
void CursorLoaderOzone::LoadImageCursor(mojom::CursorType type,
int resource_id,
const gfx::Point& hot) {
gfx::Point hotspot = hot;
if (base::ranges::count(kAnimatedCursorTypes, type) == 0) {
SkBitmap bitmap;
GetImageCursorBitmap(resource_id, scale(), rotation(), &hotspot, &bitmap);
image_cursors_[type] = factory_->CreateImageCursor(bitmap, hotspot);
} else {
std::vector<SkBitmap> bitmaps;
GetAnimatedCursorBitmaps(resource_id, scale(), rotation(), &hotspot,
&bitmaps);
image_cursors_[type] = factory_->CreateAnimatedCursor(
bitmaps, hotspot, kAnimatedCursorFrameDelayMs);
}
}
PlatformCursor CursorLoaderOzone::CursorFromType(mojom::CursorType type) {
// An image cursor is loaded for this type.
if (image_cursors_.count(type))
return image_cursors_[type];
// Check if there's a default platform cursor available.
base::Optional<PlatformCursor> default_cursor =
factory_->GetDefaultCursor(type);
if (default_cursor)
return *default_cursor;
if (use_platform_cursors_) {
base::Optional<PlatformCursor> default_cursor =
factory_->GetDefaultCursor(type);
if (default_cursor)
return *default_cursor;
}
// Loads the default Aura cursor bitmap for the cursor type. Falls back on
// pointer cursor if this fails.
PlatformCursor platform = CreateFallbackCursor(type);
PlatformCursor platform = LoadCursorFromAsset(type);
if (!platform && type != mojom::CursorType::kPointer) {
platform = CursorFromType(mojom::CursorType::kPointer);
factory_->RefImageCursor(platform);
image_cursors_[type] = platform;
}
DCHECK(platform) << "Failed to load a fallback bitmap for cursor " << type;
DCHECK(platform) << "Failed to load a bitmap for the pointer cursor.";
return platform;
}
// Gets default Aura cursor bitmap/hotspot and creates a PlatformCursor with it.
PlatformCursor CursorLoaderOzone::CreateFallbackCursor(mojom::CursorType type) {
PlatformCursor CursorLoaderOzone::LoadCursorFromAsset(mojom::CursorType type) {
int resource_id;
gfx::Point point;
if (ui::GetCursorDataFor(ui::CursorSize::kNormal, type, scale(), &resource_id,
&point)) {
LoadImageCursor(type, resource_id, point);
gfx::Point hotspot;
if (GetCursorDataFor(size(), type, scale(), &resource_id, &hotspot)) {
LoadImageCursor(type, resource_id, hotspot);
return image_cursors_[type];
}
return nullptr;
}
CursorLoader* CursorLoader::Create() {
return new CursorLoaderOzone();
std::unique_ptr<CursorLoader> CursorLoader::Create(bool use_platform_cursors) {
return std::make_unique<CursorLoaderOzone>(use_platform_cursors);
}
} // namespace ui
......@@ -13,28 +13,35 @@
#include "ui/base/cursor/cursor_loader.h"
#include "ui/base/cursor/mojom/cursor_type.mojom-forward.h"
namespace gfx {
class Point;
}
namespace ui {
class CursorFactory;
class COMPONENT_EXPORT(UI_BASE_CURSOR) CursorLoaderOzone : public CursorLoader {
public:
CursorLoaderOzone();
explicit CursorLoaderOzone(bool use_platform_cursors);
~CursorLoaderOzone() override;
// CursorLoader overrides:
void LoadImageCursor(mojom::CursorType id,
int resource_id,
const gfx::Point& hot) override;
void LoadAnimatedCursor(mojom::CursorType id,
int resource_id,
const gfx::Point& hot,
int frame_delay_ms) override;
void UnloadAll() override;
void SetPlatformCursor(gfx::NativeCursor* cursor) override;
private:
// CursorLoader overrides:
void UnloadAll() override;
void LoadImageCursor(mojom::CursorType id,
int resource_id,
const gfx::Point& hot);
PlatformCursor CursorFromType(mojom::CursorType type);
PlatformCursor CreateFallbackCursor(mojom::CursorType type);
PlatformCursor LoadCursorFromAsset(mojom::CursorType type);
// Whether to use cursors provided by the underlying platform (e.g. X11
// cursors). If false or in the case of a failure, Chromium assets will be
// used instead.
const bool use_platform_cursors_;
// Pointers are owned by ResourceBundle and must not be freed here.
std::map<mojom::CursorType, PlatformCursor> image_cursors_;
......
......@@ -122,8 +122,8 @@ const wchar_t* GetCursorId(gfx::NativeCursor native_cursor) {
} // namespace
CursorLoader* CursorLoader::Create() {
return new CursorLoaderWin;
std::unique_ptr<CursorLoader> CursorLoader::Create(bool use_platform_cursors) {
return std::make_unique<CursorLoaderWin>();
}
CursorLoaderWin::CursorLoaderWin() {
......@@ -132,19 +132,6 @@ CursorLoaderWin::CursorLoaderWin() {
CursorLoaderWin::~CursorLoaderWin() {
}
void CursorLoaderWin::LoadImageCursor(mojom::CursorType id,
int resource_id,
const gfx::Point& hot) {
// NOTIMPLEMENTED();
}
void CursorLoaderWin::LoadAnimatedCursor(mojom::CursorType id,
int resource_id,
const gfx::Point& hot,
int frame_delay_ms) {
// NOTIMPLEMENTED();
}
void CursorLoaderWin::UnloadAll() {
// NOTIMPLEMENTED();
}
......
......@@ -18,13 +18,6 @@ class COMPONENT_EXPORT(UI_BASE_CURSOR) CursorLoaderWin : public CursorLoader {
~CursorLoaderWin() override;
// Overridden from CursorLoader:
void LoadImageCursor(mojom::CursorType id,
int resource_id,
const gfx::Point& hot) override;
void LoadAnimatedCursor(mojom::CursorType id,
int resource_id,
const gfx::Point& hot,
int frame_delay_ms) override;
void UnloadAll() override;
void SetPlatformCursor(gfx::NativeCursor* cursor) override;
......
......@@ -133,6 +133,9 @@ void GetAnimatedCursorBitmaps(int resource_id,
ResourceBundle::GetSharedInstance().GetImageSkiaNamed(resource_id);
const gfx::ImageSkiaRep& image_rep = image->GetRepresentation(scale);
SkBitmap bitmap = image_rep.GetBitmap();
// The image is assumed to be a concatenation of animation frames from left to
// right. Also, each frame is assumed to be square (width == height).
int frame_width = bitmap.height();
int frame_height = frame_width;
int total_width = bitmap.width();
......
......@@ -42,8 +42,6 @@ struct CursorSizeData {
const CursorSize id;
const CursorData* cursors;
const int length;
const CursorData* animated_cursors;
const int animated_length;
};
const CursorData kNormalCursors[] = {
......@@ -127,6 +125,8 @@ const CursorData kNormalCursors[] = {
{24, 23}},
{mojom::CursorType::kGrab, IDR_AURA_CURSOR_GRAB, {8, 5}, {16, 10}},
{mojom::CursorType::kGrabbing, IDR_AURA_CURSOR_GRABBING, {9, 9}, {18, 18}},
{mojom::CursorType::kWait, IDR_AURA_CURSOR_THROBBER, {7, 7}, {14, 14}},
{mojom::CursorType::kProgress, IDR_AURA_CURSOR_THROBBER, {7, 7}, {14, 14}},
};
const CursorData kLargeCursors[] = {
......@@ -233,20 +233,12 @@ const CursorData kLargeCursors[] = {
IDR_AURA_CURSOR_BIG_GRABBING,
{20, 12},
{40, 24}},
};
const CursorData kAnimatedCursors[] = {
{mojom::CursorType::kWait, IDR_AURA_CURSOR_THROBBER, {7, 7}, {14, 14}},
{mojom::CursorType::kProgress, IDR_AURA_CURSOR_THROBBER, {7, 7}, {14, 14}},
// TODO(https://crbug.com/336867): create IDR_AURA_CURSOR_BIG_THROBBER.
};
const CursorSizeData kCursorSizes[] = {
{CursorSize::kNormal, kNormalCursors, base::size(kNormalCursors),
kAnimatedCursors, base::size(kAnimatedCursors)},
{CursorSize::kLarge, kLargeCursors, base::size(kLargeCursors),
// TODO(yoshiki): Replace animated cursors with big assets.
// crbug.com/247254
kAnimatedCursors, base::size(kAnimatedCursors)},
{CursorSize::kNormal, kNormalCursors, base::size(kNormalCursors)},
{CursorSize::kLarge, kLargeCursors, base::size(kLargeCursors)},
};
const CursorSizeData* GetCursorSizeByType(CursorSize cursor_size) {
......@@ -302,25 +294,6 @@ bool GetCursorDataFor(CursorSize cursor_size,
resource_id, point);
}
bool GetAnimatedCursorDataFor(CursorSize cursor_size,
mojom::CursorType id,
float scale_factor,
int* resource_id,
gfx::Point* point) {
const CursorSizeData* cursor_set = GetCursorSizeByType(cursor_size);
if (cursor_set &&
SearchTable(cursor_set->animated_cursors, cursor_set->animated_length, id,
scale_factor, resource_id, point)) {
return true;
}
// Falls back to the default cursor set.
cursor_set = GetCursorSizeByType(ui::CursorSize::kNormal);
DCHECK(cursor_set);
return SearchTable(cursor_set->animated_cursors, cursor_set->animated_length,
id, scale_factor, resource_id, point);
}
SkBitmap GetDefaultBitmap(const Cursor& cursor) {
#if defined(OS_WIN)
Cursor cursor_copy = cursor;
......
......@@ -18,8 +18,6 @@ namespace ui {
class Cursor;
enum class CursorSize;
const int kAnimatedCursorFrameDelayMs = 25;
// Returns data about |id|, where id is a cursor constant like
// ui::mojom::CursorType::kHelp. The IDR will be placed in |resource_id| and
// the hotspots for the different DPIs will be placed in |hot_1x| and
......@@ -31,14 +29,6 @@ bool GetCursorDataFor(CursorSize cursor_size,
int* resource_id,
gfx::Point* point);
// Like above, but for animated cursors.
COMPONENT_EXPORT(UI_BASE_CURSOR)
bool GetAnimatedCursorDataFor(CursorSize cursor_size,
mojom::CursorType id,
float scale_factor,
int* resource_id,
gfx::Point* point);
SkBitmap GetDefaultBitmap(const Cursor& cursor);
gfx::Point GetDefaultHotspot(const Cursor& cursor);
......
// 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 "ui/base/cursor/image_cursors.h"
#include "base/check.h"
#include "ui/base/cursor/cursor_loader.h"
#include "ui/base/cursor/cursors_aura.h"
#include "ui/base/cursor/mojom/cursor_type.mojom-shared.h"
#include "ui/gfx/geometry/point.h"
namespace ui {
namespace {
constexpr mojom::CursorType kImageCursorIds[] = {
mojom::CursorType::kNull,
mojom::CursorType::kPointer,
mojom::CursorType::kNoDrop,
mojom::CursorType::kNotAllowed,
mojom::CursorType::kCopy,
mojom::CursorType::kHand,
mojom::CursorType::kMove,
mojom::CursorType::kNorthEastResize,
mojom::CursorType::kSouthWestResize,
mojom::CursorType::kSouthEastResize,
mojom::CursorType::kNorthWestResize,
mojom::CursorType::kNorthResize,
mojom::CursorType::kSouthResize,
mojom::CursorType::kEastResize,
mojom::CursorType::kWestResize,
mojom::CursorType::kIBeam,
mojom::CursorType::kAlias,
mojom::CursorType::kCell,
mojom::CursorType::kContextMenu,
mojom::CursorType::kCross,
mojom::CursorType::kHelp,
mojom::CursorType::kVerticalText,
mojom::CursorType::kZoomIn,
mojom::CursorType::kZoomOut,
mojom::CursorType::kRowResize,
mojom::CursorType::kColumnResize,
mojom::CursorType::kEastWestResize,
mojom::CursorType::kNorthSouthResize,
mojom::CursorType::kNorthEastSouthWestResize,
mojom::CursorType::kNorthWestSouthEastResize,
mojom::CursorType::kGrab,
mojom::CursorType::kGrabbing,
};
constexpr mojom::CursorType kAnimatedCursorIds[] = {
mojom::CursorType::kWait, mojom::CursorType::kProgress};
} // namespace
ImageCursors::ImageCursors()
: cursor_loader_(CursorLoader::Create()),
cursor_size_(CursorSize::kNormal) {}
ImageCursors::~ImageCursors() = default;
float ImageCursors::GetScale() const {
return cursor_loader_->scale();
}
display::Display::Rotation ImageCursors::GetRotation() const {
return cursor_loader_->rotation();
}
bool ImageCursors::SetDisplay(const display::Display& display,
float scale_factor) {
if (cursor_loader_->rotation() == display.panel_rotation() &&
cursor_loader_->scale() == scale_factor)
return false;
cursor_loader_->set_rotation(display.panel_rotation());
cursor_loader_->set_scale(scale_factor);
ReloadCursors();
return true;
}
void ImageCursors::ReloadCursors() {
float device_scale_factor = cursor_loader_->scale();
cursor_loader_->UnloadAll();
for (auto cursor_id : kImageCursorIds) {
int resource_id = -1;
gfx::Point hot_point;
bool success = GetCursorDataFor(
cursor_size_, cursor_id, device_scale_factor, &resource_id, &hot_point);
DCHECK(success);
cursor_loader_->LoadImageCursor(cursor_id, resource_id, hot_point);
}
for (auto cursor_id : kAnimatedCursorIds) {
int resource_id = -1;
gfx::Point hot_point;
bool success = GetAnimatedCursorDataFor(
cursor_size_, cursor_id, device_scale_factor, &resource_id, &hot_point);
DCHECK(success);
cursor_loader_->LoadAnimatedCursor(cursor_id, resource_id, hot_point,
kAnimatedCursorFrameDelayMs);
}
}
void ImageCursors::SetCursorSize(CursorSize cursor_size) {
if (cursor_size_ == cursor_size)
return;
cursor_size_ = cursor_size;
ReloadCursors();
}
void ImageCursors::SetPlatformCursor(gfx::NativeCursor* cursor) {
cursor_loader_->SetPlatformCursor(cursor);
}
} // namespace ui
// 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 UI_BASE_CURSOR_IMAGE_CURSORS_H_
#define UI_BASE_CURSOR_IMAGE_CURSORS_H_
#include <memory>
#include "base/component_export.h"
#include "ui/base/cursor/cursor_size.h"
#include "ui/display/display.h"
#include "ui/gfx/native_widget_types.h"
namespace ui {
class CursorLoader;
// A utility class that provides cursors for NativeCursors for which we have
// image resources.
class COMPONENT_EXPORT(UI_BASE_CURSOR) ImageCursors {
public:
ImageCursors();
ImageCursors(const ImageCursors&) = delete;
ImageCursors& operator=(const ImageCursors&) = delete;
~ImageCursors();
// Returns the scale and rotation of the currently loaded cursor.
float GetScale() const;
display::Display::Rotation GetRotation() const;
// 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 display::Display& display, float scale_factor);
// Sets the size of the mouse cursor icon.
void SetCursorSize(CursorSize cursor_size);
// Sets the platform cursor based on the native type of |cursor|.
void SetPlatformCursor(gfx::NativeCursor* cursor);
private:
// Reloads the all loaded cursors in the cursor loader.
void ReloadCursors();
std::unique_ptr<CursorLoader> cursor_loader_;
CursorSize cursor_size_;
};
} // namespace ui
#endif // UI_BASE_CURSOR_IMAGE_CURSORS_H_
......@@ -14,8 +14,14 @@
namespace views {
DesktopNativeCursorManager::DesktopNativeCursorManager()
: cursor_loader_(ui::CursorLoader::Create()) {}
DesktopNativeCursorManager::DesktopNativeCursorManager() {
#if BUILDFLAG(IS_LACROS)
const bool use_platform_cursors = false;
#else
const bool use_platform_cursors = true;
#endif
cursor_loader_ = ui::CursorLoader::Create(use_platform_cursors);
}
DesktopNativeCursorManager::~DesktopNativeCursorManager() = default;
......@@ -37,9 +43,8 @@ void DesktopNativeCursorManager::RemoveHost(aura::WindowTreeHost* host) {
void DesktopNativeCursorManager::SetDisplay(
const display::Display& display,
wm::NativeCursorManagerDelegate* delegate) {
cursor_loader_->UnloadAll();
cursor_loader_->set_rotation(display.rotation());
cursor_loader_->set_scale(display.device_scale_factor());
cursor_loader_->SetDisplayData(display.rotation(),
display.device_scale_factor());
SetCursor(delegate->GetCursor(), delegate);
}
......
......@@ -523,9 +523,6 @@ void DesktopNativeWidgetAura::InitNativeWidget(Widget::InitParams params) {
if (!cursor_manager_) {
cursor_manager_ = new wm::CursorManager(
std::unique_ptr<wm::NativeCursorManager>(native_cursor_manager_));
cursor_manager_->SetDisplay(
display::Screen::GetScreen()->GetDisplayNearestWindow(
host_->window()));
}
native_cursor_manager_->AddHost(host());
aura::client::SetCursorClient(host_->window(), cursor_manager_);
......
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