Use scoped_refptr for platform cursors
Platform cursors will be automatically ref-counted by migrating them to use scoped_refptr. Originally, the custom platform cursors were ref-counted manually in several places: after using a custom cursor created by CursorFactory::CreateImageCursor() and in ui::Cursor and content::WebCursor, when custom cursors were stored (Cursor::SetPlatformCursor()) and copied (copy constructors/operators). By moving to a ref-counted type, many types of bugs that happened in the past regarding WebCursor and PlatformCursor lifetimes will be prevented (e.g. removing WebCursor::operator=, and thus leaking the custom cursor resources on each assignment). Bug: 1149906 Change-Id: If0f8c8570e6bcb47b203086dc90f49b8e7253fd0 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2255605 Reviewed-by: Scott Violet <sky@chromium.org> Reviewed-by: Bret Sepulveda <bsep@chromium.org> Reviewed-by: Mitsuru Oshima <oshima@chromium.org> Commit-Queue: Henrique Ferreiro <hferreiro@igalia.com> Cr-Commit-Position: refs/heads/master@{#874510}
This commit is contained in:

committed by
Chromium LUCI CQ

parent
3c38617171
commit
070fa848c1
ash/capture_mode
components/exo
content/common/cursors
ui
base
cursor
BUILD.gncursor.cccursor.hcursor_aura.cccursor_factory.cccursor_factory.hcursor_loader.cccursor_loader.hcursor_loader_unittest.cccursors_aura.cc
ozone
platform_cursor.hwin
x
ozone
platform
platform_window
views
@ -251,12 +251,10 @@ ui::Cursor GetCursorForFullscreenOrWindowCapture(bool capture_image) {
|
||||
ui::ScaleAndRotateCursorBitmapAndHotpoint(
|
||||
device_scale_factor, display.panel_rotation(), &bitmap, &hotspot);
|
||||
auto* cursor_factory = ui::CursorFactory::GetInstance();
|
||||
ui::PlatformCursor platform_cursor =
|
||||
cursor_factory->CreateImageCursor(cursor.type(), bitmap, hotspot);
|
||||
cursor.SetPlatformCursor(platform_cursor);
|
||||
cursor.SetPlatformCursor(
|
||||
cursor_factory->CreateImageCursor(cursor.type(), bitmap, hotspot));
|
||||
cursor.set_custom_bitmap(bitmap);
|
||||
cursor.set_custom_hotspot(hotspot);
|
||||
cursor_factory->UnrefImageCursor(platform_cursor);
|
||||
|
||||
return cursor;
|
||||
}
|
||||
|
@ -766,16 +766,14 @@ void Pointer::UpdateCursor() {
|
||||
ui::ScaleAndRotateCursorBitmapAndHotpoint(scale, display.panel_rotation(),
|
||||
&bitmap, &hotspot);
|
||||
|
||||
ui::PlatformCursor platform_cursor;
|
||||
// TODO(reveman): Add interface for creating cursors from GpuMemoryBuffers
|
||||
// and use that here instead of the current bitmap API.
|
||||
// https://crbug.com/686600
|
||||
platform_cursor = ui::CursorFactory::GetInstance()->CreateImageCursor(
|
||||
cursor_.type(), bitmap, hotspot);
|
||||
cursor_.SetPlatformCursor(platform_cursor);
|
||||
cursor_.SetPlatformCursor(
|
||||
ui::CursorFactory::GetInstance()->CreateImageCursor(cursor_.type(),
|
||||
bitmap, hotspot));
|
||||
cursor_.set_custom_bitmap(bitmap);
|
||||
cursor_.set_custom_hotspot(hotspot);
|
||||
ui::CursorFactory::GetInstance()->UnrefImageCursor(platform_cursor);
|
||||
}
|
||||
|
||||
// If there is a focused surface, update its widget as the views framework
|
||||
|
@ -13,9 +13,7 @@ namespace content {
|
||||
|
||||
WebCursor::WebCursor() = default;
|
||||
|
||||
WebCursor::~WebCursor() {
|
||||
CleanupPlatformData();
|
||||
}
|
||||
WebCursor::~WebCursor() = default;
|
||||
|
||||
WebCursor::WebCursor(const ui::Cursor& cursor) {
|
||||
SetCursor(cursor);
|
||||
|
@ -17,7 +17,6 @@
|
||||
|
||||
#if defined(USE_AURA)
|
||||
#include "base/optional.h"
|
||||
|
||||
#include "ui/base/cursor/cursor.h"
|
||||
#endif
|
||||
|
||||
@ -75,7 +74,6 @@ class CONTENT_EXPORT WebCursor {
|
||||
|
||||
#if defined(USE_AURA) || defined(USE_OZONE)
|
||||
// Only used for custom cursors.
|
||||
ui::PlatformCursor platform_cursor_ = nullptr;
|
||||
float device_scale_factor_ = 1.f;
|
||||
display::Display::Rotation rotation_ = display::Display::ROTATE_0;
|
||||
#endif
|
||||
|
@ -23,11 +23,9 @@ gfx::NativeCursor WebCursor::GetNativeCursor() {
|
||||
custom_cursor_->set_custom_bitmap(bitmap);
|
||||
custom_cursor_->set_custom_hotspot(hotspot);
|
||||
custom_cursor_->set_image_scale_factor(scale);
|
||||
|
||||
DCHECK(!platform_cursor_);
|
||||
platform_cursor_ = ui::CursorFactory::GetInstance()->CreateImageCursor(
|
||||
ui::mojom::CursorType::kCustom, bitmap, hotspot);
|
||||
custom_cursor_->SetPlatformCursor(platform_cursor_);
|
||||
custom_cursor_->SetPlatformCursor(
|
||||
ui::CursorFactory::GetInstance()->CreateImageCursor(
|
||||
ui::mojom::CursorType::kCustom, bitmap, hotspot));
|
||||
}
|
||||
return *custom_cursor_;
|
||||
}
|
||||
@ -64,12 +62,6 @@ float WebCursor::GetCursorScaleFactor(SkBitmap* bitmap) {
|
||||
|
||||
void WebCursor::CopyPlatformData(const WebCursor& other) {
|
||||
custom_cursor_ = other.custom_cursor_;
|
||||
if (platform_cursor_)
|
||||
ui::CursorFactory::GetInstance()->UnrefImageCursor(platform_cursor_);
|
||||
platform_cursor_ = other.platform_cursor_;
|
||||
if (platform_cursor_)
|
||||
ui::CursorFactory::GetInstance()->RefImageCursor(platform_cursor_);
|
||||
|
||||
device_scale_factor_ = other.device_scale_factor_;
|
||||
#if defined(USE_OZONE)
|
||||
maximum_cursor_size_ = other.maximum_cursor_size_;
|
||||
@ -77,10 +69,6 @@ void WebCursor::CopyPlatformData(const WebCursor& other) {
|
||||
}
|
||||
|
||||
void WebCursor::CleanupPlatformData() {
|
||||
if (platform_cursor_) {
|
||||
ui::CursorFactory::GetInstance()->UnrefImageCursor(platform_cursor_);
|
||||
platform_cursor_ = nullptr;
|
||||
}
|
||||
custom_cursor_.reset();
|
||||
}
|
||||
|
||||
|
@ -30,8 +30,6 @@ void WebCursor::SetDisplayInfo(const display::Display& display) {
|
||||
if (maximum_cursor_size_.width() == 0 || maximum_cursor_size_.height() == 0)
|
||||
maximum_cursor_size_ = gfx::Size(kDefaultMaxSize, kDefaultMaxSize);
|
||||
CleanupPlatformData();
|
||||
// It is not necessary to recreate platform_cursor_ yet, since it will be
|
||||
// recreated on demand when GetNativeCursor is called.
|
||||
}
|
||||
|
||||
float WebCursor::GetCursorScaleFactor(SkBitmap* bitmap) {
|
||||
|
@ -211,7 +211,7 @@ void ScaleCursor(float scale, int hotspot_x, int hotspot_y) {
|
||||
webcursor.SetDisplayInfo(display);
|
||||
|
||||
HCURSOR windows_cursor_handle =
|
||||
static_cast<ui::WinCursor*>(webcursor.GetNativeCursor().platform())
|
||||
ui::WinCursor::FromPlatformCursor(webcursor.GetNativeCursor().platform())
|
||||
->hcursor();
|
||||
EXPECT_NE(nullptr, windows_cursor_handle);
|
||||
ICONINFO windows_icon_info;
|
||||
|
@ -14,6 +14,7 @@ component("cursor_base") {
|
||||
"cursor_factory.cc",
|
||||
"cursor_factory.h",
|
||||
"cursor_size.h",
|
||||
"platform_cursor.h",
|
||||
]
|
||||
defines = [ "IS_UI_BASE_CURSOR_BASE_IMPL" ]
|
||||
public_deps = [
|
||||
@ -23,10 +24,6 @@ component("cursor_base") {
|
||||
"//ui/gfx/geometry",
|
||||
]
|
||||
deps = [ "//ui/gfx:geometry_skia" ]
|
||||
|
||||
if (use_aura) {
|
||||
sources += [ "cursor_aura.cc" ]
|
||||
}
|
||||
}
|
||||
|
||||
component("theme_manager") {
|
||||
|
@ -13,39 +13,14 @@ Cursor::Cursor() = default;
|
||||
|
||||
Cursor::Cursor(mojom::CursorType type) : type_(type) {}
|
||||
|
||||
Cursor::Cursor(const Cursor& cursor)
|
||||
: type_(cursor.type_),
|
||||
platform_cursor_(cursor.platform_cursor_),
|
||||
image_scale_factor_(cursor.image_scale_factor_) {
|
||||
if (type_ == mojom::CursorType::kCustom) {
|
||||
custom_hotspot_ = cursor.custom_hotspot_;
|
||||
custom_bitmap_ = cursor.custom_bitmap_;
|
||||
RefCustomCursor();
|
||||
}
|
||||
}
|
||||
Cursor::Cursor(const Cursor& cursor) = default;
|
||||
|
||||
Cursor::~Cursor() {
|
||||
if (type_ == mojom::CursorType::kCustom)
|
||||
UnrefCustomCursor();
|
||||
}
|
||||
Cursor::~Cursor() = default;
|
||||
|
||||
void Cursor::SetPlatformCursor(const PlatformCursor& platform) {
|
||||
if (type_ == mojom::CursorType::kCustom)
|
||||
UnrefCustomCursor();
|
||||
platform_cursor_ = platform;
|
||||
if (type_ == mojom::CursorType::kCustom)
|
||||
RefCustomCursor();
|
||||
void Cursor::SetPlatformCursor(scoped_refptr<PlatformCursor> platform_cursor) {
|
||||
platform_cursor_ = platform_cursor;
|
||||
}
|
||||
|
||||
#if !defined(USE_AURA)
|
||||
void Cursor::RefCustomCursor() {
|
||||
NOTIMPLEMENTED();
|
||||
}
|
||||
void Cursor::UnrefCustomCursor() {
|
||||
NOTIMPLEMENTED();
|
||||
}
|
||||
#endif
|
||||
|
||||
bool Cursor::operator==(const Cursor& cursor) const {
|
||||
return type_ == cursor.type_ && platform_cursor_ == cursor.platform_cursor_ &&
|
||||
image_scale_factor_ == cursor.image_scale_factor_ &&
|
||||
@ -54,19 +29,4 @@ bool Cursor::operator==(const Cursor& cursor) const {
|
||||
gfx::BitmapsAreEqual(custom_bitmap_, cursor.custom_bitmap_)));
|
||||
}
|
||||
|
||||
void Cursor::operator=(const Cursor& cursor) {
|
||||
if (*this == cursor)
|
||||
return;
|
||||
if (type_ == mojom::CursorType::kCustom)
|
||||
UnrefCustomCursor();
|
||||
type_ = cursor.type_;
|
||||
platform_cursor_ = cursor.platform_cursor_;
|
||||
if (type_ == mojom::CursorType::kCustom) {
|
||||
RefCustomCursor();
|
||||
custom_hotspot_ = cursor.custom_hotspot_;
|
||||
custom_bitmap_ = cursor.custom_bitmap_;
|
||||
}
|
||||
image_scale_factor_ = cursor.image_scale_factor_;
|
||||
}
|
||||
|
||||
} // namespace ui
|
||||
|
@ -6,42 +6,26 @@
|
||||
#define UI_BASE_CURSOR_CURSOR_H_
|
||||
|
||||
#include "base/component_export.h"
|
||||
#include "build/build_config.h"
|
||||
#include "base/memory/scoped_refptr.h"
|
||||
#include "third_party/skia/include/core/SkBitmap.h"
|
||||
#include "ui/base/cursor/mojom/cursor_type.mojom-shared.h"
|
||||
#include "ui/base/cursor/platform_cursor.h"
|
||||
#include "ui/gfx/geometry/point.h"
|
||||
|
||||
#if defined(OS_WIN)
|
||||
#include "base/win/windows_types.h"
|
||||
#endif
|
||||
|
||||
namespace ui {
|
||||
|
||||
// NOTE: On Ozone platforms, the type is chosen at runtime, and is either
|
||||
// X11Cursor* or BitmapCursorOzone*.
|
||||
// On Windows, it's WinCursor*.
|
||||
using PlatformCursor = void*;
|
||||
|
||||
// Ref-counted cursor that supports both default and custom cursors.
|
||||
class COMPONENT_EXPORT(UI_BASE_CURSOR_BASE) Cursor {
|
||||
public:
|
||||
Cursor();
|
||||
|
||||
// Implicit constructor.
|
||||
Cursor(mojom::CursorType type);
|
||||
|
||||
// Allow copy.
|
||||
Cursor(const Cursor& cursor);
|
||||
|
||||
~Cursor();
|
||||
|
||||
void SetPlatformCursor(const PlatformCursor& platform);
|
||||
|
||||
void RefCustomCursor();
|
||||
void UnrefCustomCursor();
|
||||
void SetPlatformCursor(scoped_refptr<PlatformCursor> platform_cursor);
|
||||
|
||||
mojom::CursorType type() const { return type_; }
|
||||
PlatformCursor platform() const { return platform_cursor_; }
|
||||
scoped_refptr<PlatformCursor> platform() const { return platform_cursor_; }
|
||||
float image_scale_factor() const { return image_scale_factor_; }
|
||||
void set_image_scale_factor(float scale) { image_scale_factor_ = scale; }
|
||||
|
||||
@ -60,14 +44,12 @@ class COMPONENT_EXPORT(UI_BASE_CURSOR_BASE) Cursor {
|
||||
bool operator==(mojom::CursorType type) const { return type_ == type; }
|
||||
bool operator!=(mojom::CursorType type) const { return type_ != type; }
|
||||
|
||||
void operator=(const Cursor& cursor);
|
||||
|
||||
private:
|
||||
// The basic cursor type.
|
||||
mojom::CursorType type_ = mojom::CursorType::kNull;
|
||||
|
||||
// The native platform cursor.
|
||||
PlatformCursor platform_cursor_ = 0;
|
||||
scoped_refptr<PlatformCursor> platform_cursor_;
|
||||
|
||||
// The scale factor for the cursor bitmap.
|
||||
float image_scale_factor_ = 1.0f;
|
||||
|
@ -1,21 +0,0 @@
|
||||
// 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/cursor.h"
|
||||
|
||||
#include "ui/base/cursor/cursor_factory.h"
|
||||
|
||||
namespace ui {
|
||||
|
||||
void Cursor::RefCustomCursor() {
|
||||
if (platform_cursor_)
|
||||
CursorFactory::GetInstance()->RefImageCursor(platform_cursor_);
|
||||
}
|
||||
|
||||
void Cursor::UnrefCustomCursor() {
|
||||
if (platform_cursor_)
|
||||
CursorFactory::GetInstance()->UnrefImageCursor(platform_cursor_);
|
||||
}
|
||||
|
||||
} // namespace ui
|
@ -8,8 +8,10 @@
|
||||
|
||||
#include "base/check.h"
|
||||
#include "base/check_op.h"
|
||||
#include "base/memory/scoped_refptr.h"
|
||||
#include "base/notreached.h"
|
||||
#include "ui/base/cursor/mojom/cursor_type.mojom-shared.h"
|
||||
#include "ui/base/cursor/platform_cursor.h"
|
||||
|
||||
namespace ui {
|
||||
|
||||
@ -34,33 +36,27 @@ CursorFactory* CursorFactory::GetInstance() {
|
||||
return g_instance;
|
||||
}
|
||||
|
||||
PlatformCursor CursorFactory::GetDefaultCursor(mojom::CursorType type) {
|
||||
scoped_refptr<PlatformCursor> CursorFactory::GetDefaultCursor(
|
||||
mojom::CursorType type) {
|
||||
NOTIMPLEMENTED();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
PlatformCursor CursorFactory::CreateImageCursor(mojom::CursorType type,
|
||||
const SkBitmap& bitmap,
|
||||
const gfx::Point& hotspot) {
|
||||
scoped_refptr<PlatformCursor> CursorFactory::CreateImageCursor(
|
||||
mojom::CursorType type,
|
||||
const SkBitmap& bitmap,
|
||||
const gfx::Point& hotspot) {
|
||||
NOTIMPLEMENTED();
|
||||
return 0;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
PlatformCursor CursorFactory::CreateAnimatedCursor(
|
||||
scoped_refptr<PlatformCursor> CursorFactory::CreateAnimatedCursor(
|
||||
mojom::CursorType type,
|
||||
const std::vector<SkBitmap>& bitmaps,
|
||||
const gfx::Point& hotspot,
|
||||
base::TimeDelta frame_delay) {
|
||||
NOTIMPLEMENTED();
|
||||
return 0;
|
||||
}
|
||||
|
||||
void CursorFactory::RefImageCursor(PlatformCursor cursor) {
|
||||
NOTIMPLEMENTED();
|
||||
}
|
||||
|
||||
void CursorFactory::UnrefImageCursor(PlatformCursor cursor) {
|
||||
NOTIMPLEMENTED();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void CursorFactory::ObserveThemeChanges() {
|
||||
|
@ -14,6 +14,9 @@
|
||||
|
||||
class SkBitmap;
|
||||
|
||||
template <class T>
|
||||
class scoped_refptr;
|
||||
|
||||
namespace base {
|
||||
class TimeDelta;
|
||||
}
|
||||
@ -23,7 +26,7 @@ class Point;
|
||||
}
|
||||
|
||||
namespace ui {
|
||||
using PlatformCursor = void*;
|
||||
class PlatformCursor;
|
||||
|
||||
class COMPONENT_EXPORT(UI_BASE_CURSOR_BASE) CursorFactory {
|
||||
public:
|
||||
@ -33,37 +36,26 @@ class COMPONENT_EXPORT(UI_BASE_CURSOR_BASE) CursorFactory {
|
||||
// Returns the thread-local instance.
|
||||
static CursorFactory* GetInstance();
|
||||
|
||||
// Return the default cursor of the specified type. The types are listed in
|
||||
// ui/base/cursor/cursor.h. Default cursors are managed by the implementation
|
||||
// and must live indefinitely; there's no way to know when to free them.
|
||||
// When a default cursor is not available, nullptr is returned.
|
||||
virtual PlatformCursor GetDefaultCursor(mojom::CursorType type);
|
||||
// Return the default cursor of the specified type. When a default cursor is
|
||||
// not available, nullptr is returned.
|
||||
virtual scoped_refptr<PlatformCursor> GetDefaultCursor(
|
||||
mojom::CursorType type);
|
||||
|
||||
// Return an image cursor for the specified |type| with a |bitmap| and
|
||||
// |hotspot|. Image cursors are referenced counted and have an initial
|
||||
// refcount of 1. Therefore, each CreateImageCursor call must be matched with
|
||||
// a call to UnrefImageCursor.
|
||||
virtual PlatformCursor CreateImageCursor(mojom::CursorType type,
|
||||
const SkBitmap& bitmap,
|
||||
const gfx::Point& hotspot);
|
||||
// Return an image cursor for the specified `type` with a `bitmap` and
|
||||
// `hotspot`.
|
||||
virtual scoped_refptr<PlatformCursor> CreateImageCursor(
|
||||
mojom::CursorType type,
|
||||
const SkBitmap& bitmap,
|
||||
const gfx::Point& hotspot);
|
||||
|
||||
// Return a animated cursor from the specified image & hotspot. Animated
|
||||
// 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| is the delay between frames.
|
||||
virtual PlatformCursor CreateAnimatedCursor(
|
||||
// Return a animated cursor from the specified `bitmaps` and `hotspot`.
|
||||
// `frame_delay` is the delay between frames.
|
||||
virtual scoped_refptr<PlatformCursor> CreateAnimatedCursor(
|
||||
mojom::CursorType type,
|
||||
const std::vector<SkBitmap>& bitmaps,
|
||||
const gfx::Point& hotspot,
|
||||
base::TimeDelta frame_delay);
|
||||
|
||||
// Increment platform image cursor refcount.
|
||||
virtual void RefImageCursor(PlatformCursor cursor);
|
||||
|
||||
// Decrement platform image cursor refcount.
|
||||
virtual void UnrefImageCursor(PlatformCursor cursor);
|
||||
|
||||
// Called after CursorThemeManager is initialized, to be able to track
|
||||
// cursor theme and size changes.
|
||||
virtual void ObserveThemeChanges();
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include <vector>
|
||||
|
||||
#include "base/check.h"
|
||||
#include "base/memory/scoped_refptr.h"
|
||||
#include "base/time/time.h"
|
||||
#include "ui/base/cursor/cursor.h"
|
||||
#include "ui/base/cursor/cursor_factory.h"
|
||||
@ -15,6 +16,7 @@
|
||||
#include "ui/base/cursor/cursor_util.h"
|
||||
#include "ui/base/cursor/cursors_aura.h"
|
||||
#include "ui/base/cursor/mojom/cursor_type.mojom.h"
|
||||
#include "ui/base/cursor/platform_cursor.h"
|
||||
#include "ui/gfx/geometry/point.h"
|
||||
|
||||
namespace ui {
|
||||
@ -38,8 +40,6 @@ CursorLoader::~CursorLoader() {
|
||||
}
|
||||
|
||||
void CursorLoader::UnloadCursors() {
|
||||
for (const auto& image_cursor : image_cursors_)
|
||||
factory_->UnrefImageCursor(image_cursor.second);
|
||||
image_cursors_.clear();
|
||||
}
|
||||
|
||||
@ -91,7 +91,8 @@ void CursorLoader::LoadImageCursor(mojom::CursorType type,
|
||||
}
|
||||
}
|
||||
|
||||
PlatformCursor CursorLoader::CursorFromType(mojom::CursorType type) {
|
||||
scoped_refptr<PlatformCursor> CursorLoader::CursorFromType(
|
||||
mojom::CursorType type) {
|
||||
// An image cursor is loaded for this type.
|
||||
if (image_cursors_.count(type))
|
||||
return image_cursors_[type];
|
||||
@ -99,7 +100,7 @@ PlatformCursor CursorLoader::CursorFromType(mojom::CursorType type) {
|
||||
// Check if there's a default platform cursor available.
|
||||
// For the none cursor, we also need to use the platform factory to take
|
||||
// into account the different ways of creating an invisible cursor.
|
||||
PlatformCursor cursor;
|
||||
scoped_refptr<PlatformCursor> cursor;
|
||||
if (use_platform_cursors_ || type == mojom::CursorType::kNone) {
|
||||
cursor = factory_->GetDefaultCursor(type);
|
||||
if (cursor)
|
||||
@ -112,14 +113,14 @@ PlatformCursor CursorLoader::CursorFromType(mojom::CursorType type) {
|
||||
cursor = LoadCursorFromAsset(type);
|
||||
if (!cursor && type != mojom::CursorType::kPointer) {
|
||||
cursor = CursorFromType(mojom::CursorType::kPointer);
|
||||
factory_->RefImageCursor(cursor);
|
||||
image_cursors_[type] = cursor;
|
||||
}
|
||||
DCHECK(cursor) << "Failed to load a bitmap for the pointer cursor.";
|
||||
return cursor;
|
||||
}
|
||||
|
||||
PlatformCursor CursorLoader::LoadCursorFromAsset(mojom::CursorType type) {
|
||||
scoped_refptr<PlatformCursor> CursorLoader::LoadCursorFromAsset(
|
||||
mojom::CursorType type) {
|
||||
int resource_id;
|
||||
gfx::Point hotspot;
|
||||
if (GetCursorDataFor(size(), type, scale(), &resource_id, &hotspot)) {
|
||||
|
@ -9,6 +9,7 @@
|
||||
#include <memory>
|
||||
|
||||
#include "base/component_export.h"
|
||||
#include "base/memory/scoped_refptr.h"
|
||||
#include "ui/base/cursor/cursor.h"
|
||||
#include "ui/base/cursor/cursor_size.h"
|
||||
#include "ui/base/cursor/mojom/cursor_type.mojom-forward.h"
|
||||
@ -20,6 +21,7 @@ class Point;
|
||||
|
||||
namespace ui {
|
||||
class CursorFactory;
|
||||
class PlatformCursor;
|
||||
|
||||
class COMPONENT_EXPORT(UI_BASE_CURSOR) CursorLoader {
|
||||
public:
|
||||
@ -51,15 +53,15 @@ class COMPONENT_EXPORT(UI_BASE_CURSOR) CursorLoader {
|
||||
void LoadImageCursor(mojom::CursorType id,
|
||||
int resource_id,
|
||||
const gfx::Point& hot);
|
||||
PlatformCursor CursorFromType(mojom::CursorType type);
|
||||
PlatformCursor LoadCursorFromAsset(mojom::CursorType type);
|
||||
scoped_refptr<PlatformCursor> CursorFromType(mojom::CursorType type);
|
||||
scoped_refptr<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_;
|
||||
|
||||
std::map<mojom::CursorType, PlatformCursor> image_cursors_;
|
||||
std::map<mojom::CursorType, scoped_refptr<PlatformCursor>> image_cursors_;
|
||||
CursorFactory* factory_ = nullptr;
|
||||
|
||||
// The current scale of the mouse cursor icon.
|
||||
|
@ -4,10 +4,12 @@
|
||||
|
||||
#include "ui/base/cursor/cursor_loader.h"
|
||||
|
||||
#include "base/memory/scoped_refptr.h"
|
||||
#include "build/build_config.h"
|
||||
#include "testing/gtest/include/gtest/gtest.h"
|
||||
#include "ui/base/cursor/cursor.h"
|
||||
#include "ui/base/cursor/mojom/cursor_type.mojom-shared.h"
|
||||
#include "ui/base/cursor/platform_cursor.h"
|
||||
|
||||
#if defined(OS_WIN)
|
||||
#include "ui/base/cursor/win/win_cursor.h"
|
||||
@ -25,12 +27,13 @@
|
||||
#endif
|
||||
|
||||
namespace ui {
|
||||
|
||||
namespace {
|
||||
|
||||
PlatformCursor LoadInvisibleCursor() {
|
||||
using mojom::CursorType;
|
||||
|
||||
scoped_refptr<PlatformCursor> LoadInvisibleCursor() {
|
||||
CursorLoader cursor_loader;
|
||||
Cursor cursor(mojom::CursorType::kNone);
|
||||
Cursor cursor(CursorType::kNone);
|
||||
cursor_loader.SetPlatformCursor(&cursor);
|
||||
return cursor.platform();
|
||||
}
|
||||
@ -40,19 +43,20 @@ PlatformCursor LoadInvisibleCursor() {
|
||||
#if defined(OS_WIN)
|
||||
TEST(CursorLoaderTest, InvisibleCursor) {
|
||||
WinCursorFactory cursor_factory;
|
||||
auto* invisible_cursor = static_cast<WinCursor*>(LoadInvisibleCursor());
|
||||
auto invisible_cursor = LoadInvisibleCursor();
|
||||
ASSERT_NE(invisible_cursor, nullptr);
|
||||
EXPECT_EQ(invisible_cursor->hcursor(), nullptr);
|
||||
EXPECT_EQ(WinCursor::FromPlatformCursor(invisible_cursor)->hcursor(),
|
||||
nullptr);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(USE_OZONE) && !defined(USE_X11)
|
||||
TEST(CursorLoaderTest, InvisibleCursor) {
|
||||
BitmapCursorFactoryOzone cursor_factory;
|
||||
auto* invisible_cursor =
|
||||
static_cast<BitmapCursorOzone*>(LoadInvisibleCursor());
|
||||
auto invisible_cursor = LoadInvisibleCursor();
|
||||
ASSERT_NE(invisible_cursor, nullptr);
|
||||
EXPECT_EQ(invisible_cursor->type(), mojom::CursorType::kNone);
|
||||
EXPECT_EQ(BitmapCursorOzone::FromPlatformCursor(invisible_cursor)->type(),
|
||||
CursorType::kNone);
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -61,13 +65,10 @@ TEST(CursorLoaderTest, InvisibleCursor) {
|
||||
X11CursorFactory cursor_factory;
|
||||
// Building an image cursor with an invalid SkBitmap should return the
|
||||
// invisible cursor in X11.
|
||||
auto* invisible_cursor =
|
||||
auto invisible_cursor =
|
||||
cursor_factory.CreateImageCursor({}, SkBitmap(), gfx::Point());
|
||||
ASSERT_NE(invisible_cursor, nullptr);
|
||||
EXPECT_EQ(invisible_cursor, LoadInvisibleCursor());
|
||||
|
||||
// Release our refcount on the cursor
|
||||
cursor_factory.UnrefImageCursor(invisible_cursor);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -333,7 +333,7 @@ SkBitmap GetDefaultBitmap(const Cursor& cursor) {
|
||||
CursorLoader cursor_loader;
|
||||
cursor_loader.SetPlatformCursor(&cursor_copy);
|
||||
return IconUtil::CreateSkBitmapFromHICON(
|
||||
static_cast<WinCursor*>(cursor_copy.platform())->hcursor());
|
||||
WinCursor::FromPlatformCursor(cursor_copy.platform())->hcursor());
|
||||
#else
|
||||
int resource_id;
|
||||
gfx::Point hotspot;
|
||||
@ -354,7 +354,7 @@ gfx::Point GetDefaultHotspot(const Cursor& cursor) {
|
||||
CursorLoader cursor_loader;
|
||||
cursor_loader.SetPlatformCursor(&cursor_copy);
|
||||
return IconUtil::GetHotSpotFromHICON(
|
||||
static_cast<WinCursor*>(cursor_copy.platform())->hcursor());
|
||||
WinCursor::FromPlatformCursor(cursor_copy.platform())->hcursor());
|
||||
#else
|
||||
int resource_id;
|
||||
gfx::Point hotspot;
|
||||
|
@ -85,16 +85,15 @@ bool UseDefaultCursorForType(mojom::CursorType type) {
|
||||
}
|
||||
#endif // BUILDFLAG(IS_CHROMEOS_LACROS)
|
||||
|
||||
BitmapCursorOzone* ToBitmapCursorOzone(PlatformCursor cursor) {
|
||||
return static_cast<BitmapCursorOzone*>(cursor);
|
||||
}
|
||||
|
||||
PlatformCursor ToPlatformCursor(BitmapCursorOzone* cursor) {
|
||||
return static_cast<PlatformCursor>(cursor);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
// static
|
||||
scoped_refptr<BitmapCursorOzone> BitmapCursorOzone::FromPlatformCursor(
|
||||
scoped_refptr<PlatformCursor> platform_cursor) {
|
||||
return base::WrapRefCounted(
|
||||
static_cast<BitmapCursorOzone*>(platform_cursor.get()));
|
||||
}
|
||||
|
||||
BitmapCursorOzone::BitmapCursorOzone(mojom::CursorType type) : type_(type) {}
|
||||
|
||||
BitmapCursorOzone::BitmapCursorOzone(mojom::CursorType type,
|
||||
@ -148,13 +147,7 @@ BitmapCursorFactoryOzone::BitmapCursorFactoryOzone() {}
|
||||
|
||||
BitmapCursorFactoryOzone::~BitmapCursorFactoryOzone() {}
|
||||
|
||||
// static
|
||||
scoped_refptr<BitmapCursorOzone> BitmapCursorFactoryOzone::GetBitmapCursor(
|
||||
PlatformCursor platform_cursor) {
|
||||
return base::WrapRefCounted(ToBitmapCursorOzone(platform_cursor));
|
||||
}
|
||||
|
||||
PlatformCursor BitmapCursorFactoryOzone::GetDefaultCursor(
|
||||
scoped_refptr<PlatformCursor> BitmapCursorFactoryOzone::GetDefaultCursor(
|
||||
mojom::CursorType type) {
|
||||
if (!default_cursors_.count(type)) {
|
||||
if (type == mojom::CursorType::kNone
|
||||
@ -171,37 +164,24 @@ PlatformCursor BitmapCursorFactoryOzone::GetDefaultCursor(
|
||||
}
|
||||
}
|
||||
|
||||
// Returns owned default cursor for this type.
|
||||
return default_cursors_[type].get();
|
||||
return default_cursors_[type];
|
||||
}
|
||||
|
||||
PlatformCursor BitmapCursorFactoryOzone::CreateImageCursor(
|
||||
scoped_refptr<PlatformCursor> BitmapCursorFactoryOzone::CreateImageCursor(
|
||||
mojom::CursorType type,
|
||||
const SkBitmap& bitmap,
|
||||
const gfx::Point& hotspot) {
|
||||
BitmapCursorOzone* cursor = new BitmapCursorOzone(type, bitmap, hotspot);
|
||||
cursor->AddRef(); // Balanced by UnrefImageCursor.
|
||||
return ToPlatformCursor(cursor);
|
||||
return base::MakeRefCounted<BitmapCursorOzone>(type, bitmap, hotspot);
|
||||
}
|
||||
|
||||
PlatformCursor BitmapCursorFactoryOzone::CreateAnimatedCursor(
|
||||
scoped_refptr<PlatformCursor> BitmapCursorFactoryOzone::CreateAnimatedCursor(
|
||||
mojom::CursorType type,
|
||||
const std::vector<SkBitmap>& bitmaps,
|
||||
const gfx::Point& hotspot,
|
||||
base::TimeDelta frame_delay) {
|
||||
DCHECK_LT(0U, bitmaps.size());
|
||||
auto cursor = base::MakeRefCounted<BitmapCursorOzone>(type, bitmaps, hotspot,
|
||||
frame_delay);
|
||||
cursor->AddRef(); // Balanced by UnrefImageCursor.
|
||||
return ToPlatformCursor(cursor.get());
|
||||
}
|
||||
|
||||
void BitmapCursorFactoryOzone::RefImageCursor(PlatformCursor cursor) {
|
||||
ToBitmapCursorOzone(cursor)->AddRef();
|
||||
}
|
||||
|
||||
void BitmapCursorFactoryOzone::UnrefImageCursor(PlatformCursor cursor) {
|
||||
ToBitmapCursorOzone(cursor)->Release();
|
||||
return base::MakeRefCounted<BitmapCursorOzone>(type, bitmaps, hotspot,
|
||||
frame_delay);
|
||||
}
|
||||
|
||||
} // namespace ui
|
||||
|
@ -10,21 +10,24 @@
|
||||
|
||||
#include "base/component_export.h"
|
||||
#include "base/macros.h"
|
||||
#include "base/memory/ref_counted.h"
|
||||
#include "base/memory/scoped_refptr.h"
|
||||
#include "base/time/time.h"
|
||||
#include "third_party/skia/include/core/SkBitmap.h"
|
||||
#include "ui/base/cursor/cursor.h"
|
||||
#include "ui/base/cursor/cursor_factory.h"
|
||||
#include "ui/base/cursor/mojom/cursor_type.mojom-forward.h"
|
||||
#include "ui/base/cursor/platform_cursor.h"
|
||||
#include "ui/gfx/geometry/point.h"
|
||||
|
||||
namespace ui {
|
||||
|
||||
// A cursor that is an SkBitmap combined with a gfx::Point hotspot.
|
||||
class COMPONENT_EXPORT(UI_BASE_CURSOR) BitmapCursorOzone
|
||||
: public base::RefCounted<BitmapCursorOzone> {
|
||||
: public PlatformCursor {
|
||||
public:
|
||||
static scoped_refptr<BitmapCursorOzone> FromPlatformCursor(
|
||||
scoped_refptr<PlatformCursor> platform_cursor);
|
||||
|
||||
// Creates a cursor that doesn't need backing bitmaps (for example, a
|
||||
// server-side cursor for Lacros).
|
||||
explicit BitmapCursorOzone(mojom::CursorType type);
|
||||
@ -55,8 +58,8 @@ class COMPONENT_EXPORT(UI_BASE_CURSOR) BitmapCursorOzone
|
||||
void* platform_data() { return platform_data_; }
|
||||
|
||||
private:
|
||||
friend class base::RefCounted<BitmapCursorOzone>;
|
||||
~BitmapCursorOzone();
|
||||
friend class base::RefCounted<PlatformCursor>;
|
||||
~BitmapCursorOzone() override;
|
||||
|
||||
const mojom::CursorType type_;
|
||||
std::vector<SkBitmap> bitmaps_;
|
||||
@ -80,21 +83,18 @@ class COMPONENT_EXPORT(UI_BASE_CURSOR) BitmapCursorFactoryOzone
|
||||
BitmapCursorFactoryOzone();
|
||||
~BitmapCursorFactoryOzone() override;
|
||||
|
||||
// Convert PlatformCursor to BitmapCursorOzone.
|
||||
static scoped_refptr<BitmapCursorOzone> GetBitmapCursor(
|
||||
PlatformCursor platform_cursor);
|
||||
|
||||
// CursorFactory:
|
||||
PlatformCursor GetDefaultCursor(mojom::CursorType type) override;
|
||||
PlatformCursor CreateImageCursor(mojom::CursorType type,
|
||||
const SkBitmap& bitmap,
|
||||
const gfx::Point& hotspot) override;
|
||||
PlatformCursor CreateAnimatedCursor(mojom::CursorType type,
|
||||
const std::vector<SkBitmap>& bitmaps,
|
||||
const gfx::Point& hotspot,
|
||||
base::TimeDelta frame_delay) override;
|
||||
void RefImageCursor(PlatformCursor cursor) override;
|
||||
void UnrefImageCursor(PlatformCursor cursor) override;
|
||||
scoped_refptr<PlatformCursor> GetDefaultCursor(
|
||||
mojom::CursorType type) override;
|
||||
scoped_refptr<PlatformCursor> CreateImageCursor(
|
||||
mojom::CursorType type,
|
||||
const SkBitmap& bitmap,
|
||||
const gfx::Point& hotspot) override;
|
||||
scoped_refptr<PlatformCursor> CreateAnimatedCursor(
|
||||
mojom::CursorType type,
|
||||
const std::vector<SkBitmap>& bitmaps,
|
||||
const gfx::Point& hotspot,
|
||||
base::TimeDelta frame_delay) override;
|
||||
|
||||
private:
|
||||
std::map<mojom::CursorType, scoped_refptr<BitmapCursorOzone>>
|
||||
|
@ -6,8 +6,8 @@
|
||||
|
||||
#include "build/chromeos_buildflags.h"
|
||||
#include "testing/gtest/include/gtest/gtest.h"
|
||||
#include "ui/base/cursor/cursor.h"
|
||||
#include "ui/base/cursor/mojom/cursor_type.mojom-shared.h"
|
||||
#include "ui/base/cursor/platform_cursor.h"
|
||||
|
||||
namespace ui {
|
||||
|
||||
@ -16,11 +16,12 @@ using mojom::CursorType;
|
||||
TEST(BitmapCursorFactoryOzoneTest, InvisibleCursor) {
|
||||
BitmapCursorFactoryOzone cursor_factory;
|
||||
|
||||
PlatformCursor cursor = cursor_factory.GetDefaultCursor(CursorType::kNone);
|
||||
auto cursor = cursor_factory.GetDefaultCursor(CursorType::kNone);
|
||||
// The invisible cursor should be a BitmapCursorOzone of type kNone, not
|
||||
// nullptr.
|
||||
ASSERT_NE(cursor, nullptr);
|
||||
EXPECT_EQ(static_cast<BitmapCursorOzone*>(cursor)->type(), CursorType::kNone);
|
||||
EXPECT_EQ(BitmapCursorOzone::FromPlatformCursor(cursor)->type(),
|
||||
CursorType::kNone);
|
||||
}
|
||||
|
||||
#if BUILDFLAG(IS_CHROMEOS_LACROS)
|
||||
@ -28,24 +29,25 @@ TEST(BitmapCursorFactoryOzoneTest, LacrosUsesDefaultCursorsForCommonTypes) {
|
||||
BitmapCursorFactoryOzone factory;
|
||||
|
||||
// Verify some common cursor types.
|
||||
PlatformCursor cursor = factory.GetDefaultCursor(CursorType::kPointer);
|
||||
auto cursor = factory.GetDefaultCursor(CursorType::kPointer);
|
||||
EXPECT_NE(cursor, nullptr);
|
||||
EXPECT_EQ(static_cast<BitmapCursorOzone*>(cursor)->type(),
|
||||
EXPECT_EQ(BitmapCursorOzone::FromPlatformCursor(cursor)->type(),
|
||||
CursorType::kPointer);
|
||||
|
||||
cursor = factory.GetDefaultCursor(CursorType::kHand);
|
||||
EXPECT_NE(cursor, nullptr);
|
||||
EXPECT_EQ(static_cast<BitmapCursorOzone*>(cursor)->type(), CursorType::kHand);
|
||||
EXPECT_EQ(BitmapCursorOzone::FromPlatformCursor(cursor)->type(),
|
||||
CursorType::kHand);
|
||||
|
||||
cursor = factory.GetDefaultCursor(CursorType::kIBeam);
|
||||
EXPECT_NE(cursor, nullptr);
|
||||
EXPECT_EQ(static_cast<BitmapCursorOzone*>(cursor)->type(),
|
||||
EXPECT_EQ(BitmapCursorOzone::FromPlatformCursor(cursor)->type(),
|
||||
CursorType::kIBeam);
|
||||
}
|
||||
|
||||
TEST(BitmapCursorFactoryOzoneTest, LacrosCustomCursor) {
|
||||
BitmapCursorFactoryOzone factory;
|
||||
PlatformCursor cursor = factory.GetDefaultCursor(CursorType::kCustom);
|
||||
auto cursor = factory.GetDefaultCursor(CursorType::kCustom);
|
||||
// Custom cursors don't have a default platform cursor.
|
||||
EXPECT_EQ(cursor, nullptr);
|
||||
}
|
||||
|
36
ui/base/cursor/platform_cursor.h
Normal file
36
ui/base/cursor/platform_cursor.h
Normal file
@ -0,0 +1,36 @@
|
||||
// Copyright 2021 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_PLATFORM_CURSOR_H_
|
||||
#define UI_BASE_CURSOR_PLATFORM_CURSOR_H_
|
||||
|
||||
#include "base/component_export.h"
|
||||
#include "base/memory/ref_counted.h"
|
||||
|
||||
namespace ui {
|
||||
|
||||
// Ref-counted base class for platform-specific cursors.
|
||||
//
|
||||
// Sub-classes of PlatformCursor are expected to wrap platform-specific cursor
|
||||
// resources (e.g. HCURSOR on Windows). Those resources also have
|
||||
// platform-specific deletion methods that must only be called once the last
|
||||
// cursor is destroyed, thus requiring a ref-counted type.
|
||||
// While default cursors (all other than kCustom in
|
||||
// ui/base/cursor/cursor_type.mojom) are used often during any Chrome session
|
||||
// and could perhaps be kept alive for the duration of the program, custom
|
||||
// cursors might incur in high memory usage. Because of this, all types of
|
||||
// cursors are expected to be ref-counted.
|
||||
class COMPONENT_EXPORT(UI_BASE_CURSOR_BASE) PlatformCursor
|
||||
: public base::RefCounted<PlatformCursor> {
|
||||
public:
|
||||
REQUIRE_ADOPTION_FOR_REFCOUNTED_TYPE();
|
||||
|
||||
protected:
|
||||
friend class base::RefCounted<PlatformCursor>;
|
||||
virtual ~PlatformCursor() = default;
|
||||
};
|
||||
|
||||
} // namespace ui
|
||||
|
||||
#endif // UI_BASE_CURSOR_PLATFORM_CURSOR_H_
|
@ -6,14 +6,24 @@
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#include "base/memory/scoped_refptr.h"
|
||||
|
||||
namespace ui {
|
||||
|
||||
WinCursor::WinCursor(HCURSOR hcursor) {
|
||||
hcursor_ = hcursor;
|
||||
// static
|
||||
scoped_refptr<WinCursor> WinCursor::FromPlatformCursor(
|
||||
scoped_refptr<PlatformCursor> platform_cursor) {
|
||||
return base::WrapRefCounted(static_cast<WinCursor*>(platform_cursor.get()));
|
||||
}
|
||||
|
||||
WinCursor::WinCursor(HCURSOR hcursor, bool should_destroy)
|
||||
: should_destroy_(should_destroy), hcursor_(hcursor) {}
|
||||
|
||||
WinCursor::~WinCursor() {
|
||||
DestroyIcon(hcursor_);
|
||||
// DestroyIcon shouldn't be used to destroy a shared icon:
|
||||
// https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-destroyicon#remarks
|
||||
if (should_destroy_)
|
||||
DestroyIcon(hcursor_);
|
||||
}
|
||||
|
||||
} // namespace ui
|
||||
|
@ -6,17 +6,22 @@
|
||||
#define UI_BASE_CURSOR_WIN_WIN_CURSOR_H_
|
||||
|
||||
#include "base/component_export.h"
|
||||
#include "base/memory/ref_counted.h"
|
||||
#include "base/win/windows_types.h"
|
||||
#include "ui/base/cursor/platform_cursor.h"
|
||||
|
||||
template <class T>
|
||||
class scoped_refptr;
|
||||
|
||||
namespace ui {
|
||||
|
||||
// Ref counted class to hold a Windows cursor, i.e. an HCURSOR. Clears the
|
||||
// Ref counted class to hold a Windows cursor, i.e. an HCURSOR. Clears the
|
||||
// resources on destruction.
|
||||
class COMPONENT_EXPORT(UI_BASE_CURSOR) WinCursor
|
||||
: public base::RefCounted<WinCursor> {
|
||||
class COMPONENT_EXPORT(UI_BASE_CURSOR) WinCursor : public PlatformCursor {
|
||||
public:
|
||||
explicit WinCursor(HCURSOR hcursor = nullptr);
|
||||
static scoped_refptr<WinCursor> FromPlatformCursor(
|
||||
scoped_refptr<PlatformCursor> platform_cursor);
|
||||
|
||||
explicit WinCursor(HCURSOR hcursor = nullptr, bool should_destroy = false);
|
||||
WinCursor(const WinCursor&) = delete;
|
||||
WinCursor& operator=(const WinCursor&) = delete;
|
||||
|
||||
@ -24,9 +29,10 @@ class COMPONENT_EXPORT(UI_BASE_CURSOR) WinCursor
|
||||
|
||||
private:
|
||||
friend class base::RefCounted<WinCursor>;
|
||||
~WinCursor() override;
|
||||
|
||||
~WinCursor();
|
||||
|
||||
// Release the cursor on deletion. To be used by custom image cursors.
|
||||
bool should_destroy_;
|
||||
HCURSOR hcursor_;
|
||||
};
|
||||
|
||||
|
@ -12,8 +12,8 @@
|
||||
#include "base/notreached.h"
|
||||
#include "base/win/scoped_gdi_object.h"
|
||||
#include "base/win/windows_types.h"
|
||||
#include "ui/base/cursor/cursor.h"
|
||||
#include "ui/base/cursor/mojom/cursor_type.mojom.h"
|
||||
#include "ui/base/cursor/platform_cursor.h"
|
||||
#include "ui/base/resource/resource_bundle_win.h"
|
||||
#include "ui/gfx/icon_util.h"
|
||||
#include "ui/resources/grit/ui_unscaled_resources.h"
|
||||
@ -21,14 +21,6 @@
|
||||
namespace ui {
|
||||
namespace {
|
||||
|
||||
WinCursor* ToWinCursor(PlatformCursor cursor) {
|
||||
return static_cast<WinCursor*>(cursor);
|
||||
}
|
||||
|
||||
PlatformCursor ToPlatformCursor(WinCursor* cursor) {
|
||||
return static_cast<PlatformCursor>(cursor);
|
||||
}
|
||||
|
||||
const wchar_t* GetCursorId(mojom::CursorType type) {
|
||||
switch (type) {
|
||||
case mojom::CursorType::kNull:
|
||||
@ -135,7 +127,8 @@ WinCursorFactory::WinCursorFactory() = default;
|
||||
|
||||
WinCursorFactory::~WinCursorFactory() = default;
|
||||
|
||||
PlatformCursor WinCursorFactory::GetDefaultCursor(mojom::CursorType type) {
|
||||
scoped_refptr<PlatformCursor> WinCursorFactory::GetDefaultCursor(
|
||||
mojom::CursorType type) {
|
||||
if (!default_cursors_.count(type)) {
|
||||
// Using a dark 1x1 bit bmp for the kNone cursor may still cause DWM to do
|
||||
// composition work unnecessarily. Better to totally remove it from the
|
||||
@ -153,25 +146,16 @@ PlatformCursor WinCursorFactory::GetDefaultCursor(mojom::CursorType type) {
|
||||
default_cursors_[type] = base::MakeRefCounted<WinCursor>(hcursor);
|
||||
}
|
||||
|
||||
auto cursor = default_cursors_[type];
|
||||
return ToPlatformCursor(cursor.get());
|
||||
return default_cursors_[type];
|
||||
}
|
||||
|
||||
PlatformCursor WinCursorFactory::CreateImageCursor(mojom::CursorType type,
|
||||
const SkBitmap& bitmap,
|
||||
const gfx::Point& hotspot) {
|
||||
auto cursor = base::MakeRefCounted<WinCursor>(
|
||||
IconUtil::CreateCursorFromSkBitmap(bitmap, hotspot).release());
|
||||
cursor->AddRef();
|
||||
return ToPlatformCursor(cursor.get());
|
||||
}
|
||||
|
||||
void WinCursorFactory::RefImageCursor(PlatformCursor cursor) {
|
||||
ToWinCursor(cursor)->AddRef();
|
||||
}
|
||||
|
||||
void WinCursorFactory::UnrefImageCursor(PlatformCursor cursor) {
|
||||
ToWinCursor(cursor)->Release();
|
||||
scoped_refptr<PlatformCursor> WinCursorFactory::CreateImageCursor(
|
||||
mojom::CursorType type,
|
||||
const SkBitmap& bitmap,
|
||||
const gfx::Point& hotspot) {
|
||||
return base::MakeRefCounted<WinCursor>(
|
||||
IconUtil::CreateCursorFromSkBitmap(bitmap, hotspot).release(),
|
||||
/*should_destroy=*/true);
|
||||
}
|
||||
|
||||
} // namespace ui
|
||||
|
@ -29,12 +29,12 @@ class COMPONENT_EXPORT(UI_BASE_CURSOR) WinCursorFactory : public CursorFactory {
|
||||
~WinCursorFactory() override;
|
||||
|
||||
// CursorFactory:
|
||||
PlatformCursor GetDefaultCursor(mojom::CursorType type) override;
|
||||
PlatformCursor CreateImageCursor(mojom::CursorType type,
|
||||
const SkBitmap& bitmap,
|
||||
const gfx::Point& hotspot) override;
|
||||
void RefImageCursor(PlatformCursor cursor) override;
|
||||
void UnrefImageCursor(PlatformCursor cursor) override;
|
||||
scoped_refptr<PlatformCursor> GetDefaultCursor(
|
||||
mojom::CursorType type) override;
|
||||
scoped_refptr<PlatformCursor> CreateImageCursor(
|
||||
mojom::CursorType type,
|
||||
const SkBitmap& bitmap,
|
||||
const gfx::Point& hotspot) override;
|
||||
|
||||
private:
|
||||
std::map<mojom::CursorType, scoped_refptr<WinCursor>> default_cursors_;
|
||||
|
@ -68,7 +68,7 @@ component("x") {
|
||||
|
||||
defines = [ "IS_UI_BASE_X_IMPL" ]
|
||||
|
||||
public_deps = []
|
||||
public_deps = [ "//ui/base/cursor:cursor_base" ]
|
||||
deps = [
|
||||
"//base",
|
||||
"//base:i18n",
|
||||
@ -79,7 +79,6 @@ component("x") {
|
||||
"//ui/base:features",
|
||||
"//ui/base/clipboard:clipboard_types",
|
||||
"//ui/base/clipboard:file_info",
|
||||
"//ui/base/cursor:cursor_base",
|
||||
"//ui/base/cursor:theme_manager",
|
||||
"//ui/base/cursor/mojom:cursor_type",
|
||||
"//ui/display/util",
|
||||
|
@ -4,6 +4,7 @@
|
||||
|
||||
#include "ui/base/x/x11_cursor.h"
|
||||
|
||||
#include "base/memory/scoped_refptr.h"
|
||||
#include "ui/base/x/x11_cursor_loader.h"
|
||||
#include "ui/gfx/x/connection.h"
|
||||
#include "ui/gfx/x/future.h"
|
||||
@ -11,6 +12,12 @@
|
||||
|
||||
namespace ui {
|
||||
|
||||
// static
|
||||
scoped_refptr<X11Cursor> X11Cursor::FromPlatformCursor(
|
||||
scoped_refptr<PlatformCursor> platform_cursor) {
|
||||
return base::WrapRefCounted(static_cast<X11Cursor*>(platform_cursor.get()));
|
||||
}
|
||||
|
||||
X11Cursor::X11Cursor() = default;
|
||||
|
||||
X11Cursor::X11Cursor(x11::Cursor cursor) : loaded_(true), xcursor_(cursor) {}
|
||||
|
@ -9,20 +9,23 @@
|
||||
|
||||
#include "base/callback.h"
|
||||
#include "base/component_export.h"
|
||||
#include "base/memory/ref_counted.h"
|
||||
#include "ui/base/cursor/platform_cursor.h"
|
||||
#include "ui/gfx/x/xproto.h"
|
||||
|
||||
template <class T>
|
||||
class scoped_refptr;
|
||||
|
||||
namespace ui {
|
||||
|
||||
// Ref counted class to hold an X11 cursor resource. Clears the X11 resources
|
||||
// on destruction
|
||||
class COMPONENT_EXPORT(UI_BASE_X) X11Cursor
|
||||
: public base::RefCounted<X11Cursor> {
|
||||
class COMPONENT_EXPORT(UI_BASE_X) X11Cursor : public PlatformCursor {
|
||||
public:
|
||||
REQUIRE_ADOPTION_FOR_REFCOUNTED_TYPE();
|
||||
|
||||
using Callback = base::OnceCallback<void(x11::Cursor)>;
|
||||
|
||||
static scoped_refptr<X11Cursor> FromPlatformCursor(
|
||||
scoped_refptr<PlatformCursor> platform_cursor);
|
||||
|
||||
X11Cursor();
|
||||
explicit X11Cursor(x11::Cursor cursor);
|
||||
|
||||
@ -35,16 +38,16 @@ class COMPONENT_EXPORT(UI_BASE_X) X11Cursor
|
||||
x11::Cursor xcursor() const { return xcursor_; }
|
||||
|
||||
private:
|
||||
friend class base::RefCounted<X11Cursor>;
|
||||
friend class base::RefCounted<PlatformCursor>;
|
||||
friend class XCursorLoader;
|
||||
|
||||
~X11Cursor() override;
|
||||
|
||||
void SetCursor(x11::Cursor cursor);
|
||||
|
||||
// This cannot be named Release() since it conflicts with base::RefCounted.
|
||||
x11::Cursor ReleaseCursor();
|
||||
|
||||
~X11Cursor();
|
||||
|
||||
bool loaded_ = false;
|
||||
x11::Cursor xcursor_ = x11::Cursor::None;
|
||||
|
||||
|
@ -6,6 +6,7 @@
|
||||
|
||||
#include "third_party/skia/include/core/SkBitmap.h"
|
||||
#include "ui/base/cursor/mojom/cursor_type.mojom-shared.h"
|
||||
#include "ui/base/cursor/platform_cursor.h"
|
||||
#include "ui/base/x/x11_cursor.h"
|
||||
#include "ui/base/x/x11_cursor_loader.h"
|
||||
#include "ui/base/x/x11_util.h"
|
||||
@ -16,14 +17,6 @@ namespace ui {
|
||||
|
||||
namespace {
|
||||
|
||||
X11Cursor* ToX11Cursor(PlatformCursor cursor) {
|
||||
return static_cast<X11Cursor*>(cursor);
|
||||
}
|
||||
|
||||
PlatformCursor ToPlatformCursor(X11Cursor* cursor) {
|
||||
return static_cast<PlatformCursor>(cursor);
|
||||
}
|
||||
|
||||
scoped_refptr<X11Cursor> CreateInvisibleCursor(XCursorLoader* cursor_loader) {
|
||||
SkBitmap bitmap;
|
||||
bitmap.allocN32Pixels(1, 1);
|
||||
@ -37,28 +30,20 @@ X11CursorFactory::X11CursorFactory()
|
||||
|
||||
X11CursorFactory::~X11CursorFactory() = default;
|
||||
|
||||
PlatformCursor X11CursorFactory::CreateImageCursor(mojom::CursorType type,
|
||||
const SkBitmap& bitmap,
|
||||
const gfx::Point& hotspot) {
|
||||
scoped_refptr<PlatformCursor> X11CursorFactory::CreateImageCursor(
|
||||
mojom::CursorType type,
|
||||
const SkBitmap& bitmap,
|
||||
const gfx::Point& hotspot) {
|
||||
// There is a problem with custom cursors that have no custom data. The
|
||||
// resulting SkBitmap is empty and X crashes when creating a zero size cursor
|
||||
// image. Return invisible cursor here instead.
|
||||
if (bitmap.drawsNothing()) {
|
||||
// The result of `CreateImageCursor()` is owned by the caller, and will be
|
||||
// Unref()ed by code far away. (Usually in web_cursor.cc in content, among
|
||||
// others.) If we don't manually add another reference before we cast this
|
||||
// to a void*, we can end up with the cursor being freed out from under us.
|
||||
auto* invisible_cursor = GetDefaultCursor(mojom::CursorType::kNone);
|
||||
RefImageCursor(invisible_cursor);
|
||||
return invisible_cursor;
|
||||
}
|
||||
if (bitmap.drawsNothing())
|
||||
return GetDefaultCursor(mojom::CursorType::kNone);
|
||||
|
||||
auto cursor = cursor_loader_->CreateCursor(bitmap, hotspot);
|
||||
cursor->AddRef();
|
||||
return ToPlatformCursor(cursor.get());
|
||||
return cursor_loader_->CreateCursor(bitmap, hotspot);
|
||||
}
|
||||
|
||||
PlatformCursor X11CursorFactory::CreateAnimatedCursor(
|
||||
scoped_refptr<PlatformCursor> X11CursorFactory::CreateAnimatedCursor(
|
||||
mojom::CursorType type,
|
||||
const std::vector<SkBitmap>& bitmaps,
|
||||
const gfx::Point& hotspot,
|
||||
@ -67,17 +52,7 @@ PlatformCursor X11CursorFactory::CreateAnimatedCursor(
|
||||
images.reserve(bitmaps.size());
|
||||
for (const auto& bitmap : bitmaps)
|
||||
images.push_back(XCursorLoader::Image{bitmap, hotspot, frame_delay});
|
||||
auto cursor = cursor_loader_->CreateCursor(images);
|
||||
cursor->AddRef();
|
||||
return ToPlatformCursor(cursor.get());
|
||||
}
|
||||
|
||||
void X11CursorFactory::RefImageCursor(PlatformCursor cursor) {
|
||||
ToX11Cursor(cursor)->AddRef();
|
||||
}
|
||||
|
||||
void X11CursorFactory::UnrefImageCursor(PlatformCursor cursor) {
|
||||
ToX11Cursor(cursor)->Release();
|
||||
return cursor_loader_->CreateCursor(images);
|
||||
}
|
||||
|
||||
void X11CursorFactory::ObserveThemeChanges() {
|
||||
@ -95,7 +70,8 @@ void X11CursorFactory::OnCursorThemeSizeChanged(int cursor_theme_size) {
|
||||
ClearThemeCursors();
|
||||
}
|
||||
|
||||
PlatformCursor X11CursorFactory::GetDefaultCursor(mojom::CursorType type) {
|
||||
scoped_refptr<PlatformCursor> X11CursorFactory::GetDefaultCursor(
|
||||
mojom::CursorType type) {
|
||||
if (!default_cursors_.count(type)) {
|
||||
// Try to load a predefined X11 cursor.
|
||||
default_cursors_[type] =
|
||||
@ -104,8 +80,7 @@ PlatformCursor X11CursorFactory::GetDefaultCursor(mojom::CursorType type) {
|
||||
: cursor_loader_->LoadCursor(CursorNamesFromType(type));
|
||||
}
|
||||
|
||||
// Returns owned default cursor for this type.
|
||||
return default_cursors_[type].get();
|
||||
return default_cursors_[type];
|
||||
}
|
||||
|
||||
void X11CursorFactory::ClearThemeCursors() {
|
||||
|
@ -21,7 +21,7 @@ namespace ui {
|
||||
class X11Cursor;
|
||||
class XCursorLoader;
|
||||
|
||||
// CursorFactoryOzone implementation for X11 cursors.
|
||||
// CursorFactory implementation for X11 cursors.
|
||||
class COMPONENT_EXPORT(UI_BASE_X) X11CursorFactory
|
||||
: public CursorFactory,
|
||||
public CursorThemeManagerObserver {
|
||||
@ -32,16 +32,17 @@ class COMPONENT_EXPORT(UI_BASE_X) X11CursorFactory
|
||||
~X11CursorFactory() override;
|
||||
|
||||
// CursorFactory:
|
||||
PlatformCursor GetDefaultCursor(mojom::CursorType type) override;
|
||||
PlatformCursor CreateImageCursor(mojom::CursorType type,
|
||||
const SkBitmap& bitmap,
|
||||
const gfx::Point& hotspot) override;
|
||||
PlatformCursor CreateAnimatedCursor(mojom::CursorType type,
|
||||
const std::vector<SkBitmap>& bitmaps,
|
||||
const gfx::Point& hotspot,
|
||||
base::TimeDelta frame_delay) override;
|
||||
void RefImageCursor(PlatformCursor cursor) override;
|
||||
void UnrefImageCursor(PlatformCursor cursor) override;
|
||||
scoped_refptr<PlatformCursor> GetDefaultCursor(
|
||||
mojom::CursorType type) override;
|
||||
scoped_refptr<PlatformCursor> CreateImageCursor(
|
||||
mojom::CursorType type,
|
||||
const SkBitmap& bitmap,
|
||||
const gfx::Point& hotspot) override;
|
||||
scoped_refptr<PlatformCursor> CreateAnimatedCursor(
|
||||
mojom::CursorType type,
|
||||
const std::vector<SkBitmap>& bitmaps,
|
||||
const gfx::Point& hotspot,
|
||||
base::TimeDelta frame_delay) override;
|
||||
void ObserveThemeChanges() override;
|
||||
|
||||
private:
|
||||
|
@ -6,28 +6,24 @@
|
||||
|
||||
#include "testing/gtest/include/gtest/gtest.h"
|
||||
#include "third_party/skia/include/core/SkBitmap.h"
|
||||
#include "ui/base/cursor/mojom/cursor_type.mojom.h"
|
||||
#include "ui/base/cursor/platform_cursor.h"
|
||||
#include "ui/base/x/x11_cursor.h"
|
||||
#include "ui/gfx/geometry/point.h"
|
||||
|
||||
namespace ui {
|
||||
|
||||
TEST(X11CursorFactoryTest, InvisibleRefcount) {
|
||||
using mojom::CursorType;
|
||||
|
||||
TEST(X11CursorFactoryTest, InvisibleCursor) {
|
||||
X11CursorFactory factory;
|
||||
|
||||
// Building an image cursor with an invalid SkBitmap should return the
|
||||
// invisible cursor in X11. The invisible cursor instance should have more
|
||||
// than a single reference since the factory should hold a reference and
|
||||
// CreateImageCursor should return an incremented refcount.
|
||||
auto* invisible_cursor = static_cast<X11Cursor*>(
|
||||
factory.CreateImageCursor({}, SkBitmap(), gfx::Point()));
|
||||
// invisible cursor in X11.
|
||||
auto invisible_cursor =
|
||||
factory.CreateImageCursor({}, SkBitmap(), gfx::Point());
|
||||
ASSERT_NE(invisible_cursor, nullptr);
|
||||
ASSERT_FALSE(invisible_cursor->HasOneRef());
|
||||
|
||||
// Release our refcount on the cursor
|
||||
factory.UnrefImageCursor(invisible_cursor);
|
||||
|
||||
// The invisible cursor should still exist.
|
||||
EXPECT_TRUE(invisible_cursor->HasOneRef());
|
||||
EXPECT_EQ(invisible_cursor, factory.GetDefaultCursor(CursorType::kNone));
|
||||
}
|
||||
|
||||
} // namespace ui
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include "base/trace_event/trace_event.h"
|
||||
#include "build/chromeos_buildflags.h"
|
||||
#include "ui/base/cursor/mojom/cursor_type.mojom.h"
|
||||
#include "ui/base/cursor/ozone/bitmap_cursor_factory_ozone.h"
|
||||
#include "ui/gfx/geometry/point_conversions.h"
|
||||
#include "ui/ozone/platform/drm/host/drm_window_host.h"
|
||||
#include "ui/ozone/platform/drm/host/drm_window_host_manager.h"
|
||||
@ -75,21 +76,18 @@ gfx::Point DrmCursor::GetBitmapLocationLocked() {
|
||||
}
|
||||
|
||||
void DrmCursor::SetCursor(gfx::AcceleratedWidget window,
|
||||
PlatformCursor platform_cursor) {
|
||||
scoped_refptr<BitmapCursorOzone> platform_cursor) {
|
||||
TRACE_EVENT0("drmcursor", "DrmCursor::SetCursor");
|
||||
DCHECK(thread_checker_.CalledOnValidThread());
|
||||
DCHECK_NE(window, gfx::kNullAcceleratedWidget);
|
||||
DCHECK(platform_cursor);
|
||||
|
||||
scoped_refptr<BitmapCursorOzone> bitmap =
|
||||
BitmapCursorFactoryOzone::GetBitmapCursor(platform_cursor);
|
||||
|
||||
base::AutoLock lock(lock_);
|
||||
|
||||
if (window_ != window || bitmap_ == bitmap)
|
||||
if (window_ != window || bitmap_ == platform_cursor)
|
||||
return;
|
||||
|
||||
bitmap_ = bitmap;
|
||||
bitmap_ = platform_cursor;
|
||||
|
||||
SendCursorShowLocked();
|
||||
}
|
||||
|
@ -8,9 +8,9 @@
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#include "base/memory/scoped_refptr.h"
|
||||
#include "base/synchronization/lock.h"
|
||||
#include "base/threading/thread_checker.h"
|
||||
#include "ui/base/cursor/ozone/bitmap_cursor_factory_ozone.h"
|
||||
#include "ui/events/ozone/evdev/cursor_delegate_evdev.h"
|
||||
#include "ui/gfx/geometry/rect.h"
|
||||
|
||||
@ -53,8 +53,9 @@ class DrmCursor : public CursorDelegateEvdev {
|
||||
void SetDrmCursorProxy(std::unique_ptr<DrmCursorProxy> proxy);
|
||||
void ResetDrmCursorProxy();
|
||||
|
||||
// Change the cursor over the specifed window.
|
||||
void SetCursor(gfx::AcceleratedWidget window, PlatformCursor platform_cursor);
|
||||
// Change the cursor over the specified window.
|
||||
void SetCursor(gfx::AcceleratedWidget window,
|
||||
scoped_refptr<BitmapCursorOzone> platform_cursor);
|
||||
|
||||
// Handle window lifecycle.
|
||||
void OnWindowAdded(gfx::AcceleratedWidget window,
|
||||
|
@ -5,6 +5,9 @@
|
||||
#include "ui/ozone/platform/drm/host/drm_window_host.h"
|
||||
|
||||
#include "base/bind.h"
|
||||
#include "base/memory/scoped_refptr.h"
|
||||
#include "ui/base/cursor/ozone/bitmap_cursor_factory_ozone.h"
|
||||
#include "ui/base/cursor/platform_cursor.h"
|
||||
#include "ui/display/display.h"
|
||||
#include "ui/events/devices/device_data_manager.h"
|
||||
#include "ui/events/event.h"
|
||||
@ -125,8 +128,8 @@ bool DrmWindowHost::ShouldUseNativeFrame() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
void DrmWindowHost::SetCursor(PlatformCursor cursor) {
|
||||
cursor_->SetCursor(widget_, cursor);
|
||||
void DrmWindowHost::SetCursor(scoped_refptr<PlatformCursor> cursor) {
|
||||
cursor_->SetCursor(widget_, BitmapCursorOzone::FromPlatformCursor(cursor));
|
||||
}
|
||||
|
||||
void DrmWindowHost::MoveCursorTo(const gfx::Point& location) {
|
||||
|
@ -76,7 +76,7 @@ class DrmWindowHost : public PlatformWindow,
|
||||
void Deactivate() override;
|
||||
void SetUseNativeFrame(bool use_native_frame) override;
|
||||
bool ShouldUseNativeFrame() const override;
|
||||
void SetCursor(PlatformCursor cursor) override;
|
||||
void SetCursor(scoped_refptr<PlatformCursor> cursor) override;
|
||||
void MoveCursorTo(const gfx::Point& location) override;
|
||||
void ConfineCursorToBounds(const gfx::Rect& bounds) override;
|
||||
void SetRestoredBoundsInPixels(const gfx::Rect& bounds) override;
|
||||
|
@ -14,6 +14,8 @@
|
||||
|
||||
#include "base/fuchsia/fuchsia_logging.h"
|
||||
#include "base/fuchsia/process_context.h"
|
||||
#include "base/memory/scoped_refptr.h"
|
||||
#include "ui/base/cursor/platform_cursor.h"
|
||||
#include "ui/events/event.h"
|
||||
#include "ui/events/event_constants.h"
|
||||
#include "ui/events/keycodes/keyboard_code_conversion.h"
|
||||
@ -195,7 +197,7 @@ bool ScenicWindow::ShouldUseNativeFrame() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
void ScenicWindow::SetCursor(PlatformCursor cursor) {
|
||||
void ScenicWindow::SetCursor(scoped_refptr<PlatformCursor> cursor) {
|
||||
NOTIMPLEMENTED_LOG_ONCE();
|
||||
}
|
||||
|
||||
|
@ -81,7 +81,7 @@ class COMPONENT_EXPORT(OZONE) ScenicWindow : public PlatformWindow,
|
||||
void Deactivate() override;
|
||||
void SetUseNativeFrame(bool use_native_frame) override;
|
||||
bool ShouldUseNativeFrame() const override;
|
||||
void SetCursor(PlatformCursor cursor) override;
|
||||
void SetCursor(scoped_refptr<PlatformCursor> cursor) override;
|
||||
void MoveCursorTo(const gfx::Point& location) override;
|
||||
void ConfineCursorToBounds(const gfx::Rect& bounds) override;
|
||||
void SetRestoredBoundsInPixels(const gfx::Rect& bounds) override;
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include "base/task/thread_pool.h"
|
||||
#include "base/task/thread_pool/thread_pool_instance.h"
|
||||
#include "base/task_runner_util.h"
|
||||
#include "ui/base/cursor/platform_cursor.h"
|
||||
#include "ui/ozone/platform/wayland/host/wayland_connection.h"
|
||||
#include "ui/ozone/platform/wayland/host/wayland_shm.h"
|
||||
|
||||
@ -48,7 +49,8 @@ void WaylandCursorFactory::ObserveThemeChanges() {
|
||||
cursor_theme_observer_.Observe(cursor_theme_manager);
|
||||
}
|
||||
|
||||
PlatformCursor WaylandCursorFactory::GetDefaultCursor(mojom::CursorType type) {
|
||||
scoped_refptr<PlatformCursor> WaylandCursorFactory::GetDefaultCursor(
|
||||
mojom::CursorType type) {
|
||||
if (current_theme_->cache.count(type) == 0) {
|
||||
for (const std::string& name : CursorNamesFromType(type)) {
|
||||
wl_cursor* cursor = GetCursorFromTheme(name);
|
||||
@ -68,7 +70,7 @@ PlatformCursor WaylandCursorFactory::GetDefaultCursor(mojom::CursorType type) {
|
||||
if (current_theme_->cache[type].get() == nullptr)
|
||||
return BitmapCursorFactoryOzone::GetDefaultCursor(type);
|
||||
|
||||
return static_cast<PlatformCursor>(current_theme_->cache[type].get());
|
||||
return current_theme_->cache[type];
|
||||
}
|
||||
|
||||
void WaylandCursorFactory::SetDeviceScaleFactor(float scale) {
|
||||
|
@ -36,7 +36,8 @@ class WaylandCursorFactory : public BitmapCursorFactoryOzone,
|
||||
void ObserveThemeChanges() override;
|
||||
|
||||
// CursorFactory:
|
||||
PlatformCursor GetDefaultCursor(mojom::CursorType type) override;
|
||||
scoped_refptr<PlatformCursor> GetDefaultCursor(
|
||||
mojom::CursorType type) override;
|
||||
void SetDeviceScaleFactor(float scale) override;
|
||||
|
||||
protected:
|
||||
|
@ -8,6 +8,9 @@
|
||||
|
||||
#include "base/containers/flat_map.h"
|
||||
#include "base/gtest_prod_util.h"
|
||||
#include "base/memory/scoped_refptr.h"
|
||||
#include "ui/base/cursor/ozone/bitmap_cursor_factory_ozone.h"
|
||||
#include "ui/base/cursor/platform_cursor.h"
|
||||
#include "ui/ozone/platform/wayland/test/wayland_test.h"
|
||||
|
||||
namespace ui {
|
||||
@ -85,7 +88,7 @@ TEST_P(WaylandCursorFactoryTest, RetainOldThemeUntilNewBufferIsAttached) {
|
||||
// that theme.
|
||||
{
|
||||
auto* const current_theme = cursor_factory_->current_theme_.get();
|
||||
auto* const cursor =
|
||||
auto const cursor =
|
||||
cursor_factory_->GetDefaultCursor(mojom::CursorType::kPointer);
|
||||
EXPECT_NE(cursor, nullptr);
|
||||
EXPECT_GT(cursor_factory_->current_theme_->cache.size(), 0U);
|
||||
@ -105,19 +108,19 @@ TEST_P(WaylandCursorFactoryTest, RetainOldThemeUntilNewBufferIsAttached) {
|
||||
EXPECT_EQ(cursor_factory_->unloaded_theme_.get(), current_theme);
|
||||
|
||||
cursor_factory_->OnCursorBufferAttached(static_cast<wl_cursor*>(
|
||||
static_cast<BitmapCursorOzone*>(cursor)->platform_data()));
|
||||
BitmapCursorOzone::FromPlatformCursor(cursor)->platform_data()));
|
||||
EXPECT_EQ(cursor_factory_->unloaded_theme_.get(), current_theme);
|
||||
}
|
||||
|
||||
// Finally, tell the factory that we have attached a buffer from the current
|
||||
// theme. This time the old theme held since a while ago should be freed.
|
||||
{
|
||||
auto* const cursor =
|
||||
auto const cursor =
|
||||
cursor_factory_->GetDefaultCursor(mojom::CursorType::kPointer);
|
||||
EXPECT_NE(cursor, nullptr);
|
||||
|
||||
cursor_factory_->OnCursorBufferAttached(static_cast<wl_cursor*>(
|
||||
static_cast<BitmapCursorOzone*>(cursor)->platform_data()));
|
||||
BitmapCursorOzone::FromPlatformCursor(cursor)->platform_data()));
|
||||
|
||||
EXPECT_EQ(cursor_factory_->unloaded_theme_.get(), nullptr);
|
||||
}
|
||||
|
@ -8,10 +8,12 @@
|
||||
#include <cmath>
|
||||
#include <memory>
|
||||
|
||||
#include "base/memory/scoped_refptr.h"
|
||||
#include "testing/gmock/include/gmock/gmock.h"
|
||||
#include "testing/gtest/include/gtest/gtest.h"
|
||||
#include "ui/base/cursor/mojom/cursor_type.mojom-shared.h"
|
||||
#include "ui/base/cursor/ozone/bitmap_cursor_factory_ozone.h"
|
||||
#include "ui/base/cursor/platform_cursor.h"
|
||||
#include "ui/events/devices/device_data_manager.h"
|
||||
#include "ui/events/event.h"
|
||||
#include "ui/ozone/platform/wayland/host/wayland_cursor.h"
|
||||
@ -275,10 +277,8 @@ TEST_P(WaylandPointerTest, SetBitmapOnPointerFocus) {
|
||||
dummy_cursor.allocPixels(info, 10 * 4);
|
||||
|
||||
BitmapCursorFactoryOzone cursor_factory;
|
||||
PlatformCursor cursor = cursor_factory.CreateImageCursor(
|
||||
auto cursor = cursor_factory.CreateImageCursor(
|
||||
mojom::CursorType::kCustom, dummy_cursor, gfx::Point(5, 8));
|
||||
scoped_refptr<BitmapCursorOzone> bitmap =
|
||||
BitmapCursorFactoryOzone::GetBitmapCursor(cursor);
|
||||
|
||||
EXPECT_CALL(*pointer_, SetCursor(Ne(nullptr), 5, 8));
|
||||
window_->SetCursor(cursor);
|
||||
|
@ -14,6 +14,7 @@
|
||||
#include "build/chromeos_buildflags.h"
|
||||
#include "ui/base/cursor/mojom/cursor_type.mojom.h"
|
||||
#include "ui/base/cursor/ozone/bitmap_cursor_factory_ozone.h"
|
||||
#include "ui/base/cursor/platform_cursor.h"
|
||||
#include "ui/base/dragdrop/mojom/drag_drop_types.mojom.h"
|
||||
#include "ui/base/dragdrop/os_exchange_data.h"
|
||||
#include "ui/events/event.h"
|
||||
@ -316,49 +317,41 @@ bool WaylandWindow::ShouldUseNativeFrame() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
void WaylandWindow::SetCursor(PlatformCursor cursor) {
|
||||
DCHECK(cursor);
|
||||
void WaylandWindow::SetCursor(scoped_refptr<PlatformCursor> platform_cursor) {
|
||||
DCHECK(platform_cursor);
|
||||
|
||||
scoped_refptr<BitmapCursorOzone> bitmap =
|
||||
BitmapCursorFactoryOzone::GetBitmapCursor(cursor);
|
||||
if (bitmap_ == bitmap)
|
||||
if (bitmap_ == platform_cursor)
|
||||
return;
|
||||
|
||||
bitmap_ = bitmap;
|
||||
|
||||
if (bitmap_->type() == CursorType::kNone) {
|
||||
// Hide the cursor.
|
||||
auto cursor = BitmapCursorOzone::FromPlatformCursor(platform_cursor);
|
||||
base::Optional<int32_t> shape =
|
||||
WaylandZcrCursorShapes::ShapeFromType(cursor->type());
|
||||
if (cursor->type() == CursorType::kNone) { // Hide the cursor.
|
||||
connection_->SetCursorBitmap(std::vector<SkBitmap>(), gfx::Point(),
|
||||
buffer_scale());
|
||||
return;
|
||||
}
|
||||
// Check for theme-provided cursor.
|
||||
if (bitmap_->platform_data()) {
|
||||
} else if (cursor->platform_data()) { // Check for theme-provided cursor.
|
||||
connection_->SetPlatformCursor(
|
||||
reinterpret_cast<wl_cursor*>(bitmap_->platform_data()), buffer_scale());
|
||||
return;
|
||||
}
|
||||
// Check for Wayland server-side cursor support (e.g. exo for lacros).
|
||||
if (connection_->zcr_cursor_shapes()) {
|
||||
base::Optional<int32_t> shape =
|
||||
WaylandZcrCursorShapes::ShapeFromType(bitmap->type());
|
||||
// If the server supports this cursor type, use a server-side cursor.
|
||||
if (shape.has_value()) {
|
||||
reinterpret_cast<wl_cursor*>(cursor->platform_data()), buffer_scale());
|
||||
} else if (connection_->zcr_cursor_shapes() &&
|
||||
shape.has_value()) { // Check for Wayland server-side cursor
|
||||
// support (e.g. exo for lacros).
|
||||
#if BUILDFLAG(IS_CHROMEOS_LACROS)
|
||||
// Lacros should not load image assets for default cursors. See
|
||||
// BitmapCursorFactoryOzone::GetDefaultCursor().
|
||||
DCHECK(bitmap_->bitmaps().empty());
|
||||
// Lacros should not load image assets for default cursors. See
|
||||
// BitmapCursorFactoryOzone::GetDefaultCursor().
|
||||
DCHECK(cursor->bitmaps().empty());
|
||||
#endif // BUILDFLAG(IS_CHROMEOS_LACROS)
|
||||
connection_->zcr_cursor_shapes()->SetCursorShape(shape.value());
|
||||
return;
|
||||
}
|
||||
// Fall through to client-side bitmap cursors.
|
||||
connection_->zcr_cursor_shapes()->SetCursorShape(shape.value());
|
||||
} else { // Use client-side bitmap cursors as fallback.
|
||||
// Translate physical pixels to DIPs.
|
||||
gfx::Point hotspot_in_dips =
|
||||
gfx::ScaleToRoundedPoint(cursor->hotspot(), 1.0f / ui_scale_);
|
||||
connection_->SetCursorBitmap(cursor->bitmaps(), hotspot_in_dips,
|
||||
buffer_scale());
|
||||
}
|
||||
// Translate physical pixels to DIPs.
|
||||
gfx::Point hotspot_in_dips =
|
||||
gfx::ScaleToRoundedPoint(bitmap_->hotspot(), 1.0f / ui_scale_);
|
||||
connection_->SetCursorBitmap(bitmap_->bitmaps(), hotspot_in_dips,
|
||||
buffer_scale());
|
||||
|
||||
// The new cursor needs to be stored last to avoid deleting the old cursor
|
||||
// while it's still in use.
|
||||
bitmap_ = cursor;
|
||||
}
|
||||
|
||||
void WaylandWindow::MoveCursorTo(const gfx::Point& location) {
|
||||
|
@ -155,7 +155,7 @@ class WaylandWindow : public PlatformWindow,
|
||||
void Deactivate() override;
|
||||
void SetUseNativeFrame(bool use_native_frame) override;
|
||||
bool ShouldUseNativeFrame() const override;
|
||||
void SetCursor(PlatformCursor cursor) override;
|
||||
void SetCursor(scoped_refptr<PlatformCursor> cursor) override;
|
||||
void MoveCursorTo(const gfx::Point& location) override;
|
||||
void ConfineCursorToBounds(const gfx::Rect& bounds) override;
|
||||
void SetRestoredBoundsInPixels(const gfx::Rect& bounds) override;
|
||||
|
@ -14,6 +14,9 @@
|
||||
#include "ui/gfx/native_widget_types.h"
|
||||
#include "ui/platform_window/platform_window_delegate.h"
|
||||
|
||||
template <class T>
|
||||
class scoped_refptr;
|
||||
|
||||
namespace gfx {
|
||||
class ImageSkia;
|
||||
class Point;
|
||||
@ -23,7 +26,7 @@ class Transform;
|
||||
} // namespace gfx
|
||||
|
||||
namespace ui {
|
||||
using PlatformCursor = void*;
|
||||
class PlatformCursor;
|
||||
|
||||
// Generic PlatformWindow interface.
|
||||
class COMPONENT_EXPORT(PLATFORM_WINDOW) PlatformWindow
|
||||
@ -73,7 +76,12 @@ class COMPONENT_EXPORT(PLATFORM_WINDOW) PlatformWindow
|
||||
virtual void SetUseNativeFrame(bool use_native_frame) = 0;
|
||||
virtual bool ShouldUseNativeFrame() const = 0;
|
||||
|
||||
virtual void SetCursor(PlatformCursor cursor) = 0;
|
||||
// This method sets the current cursor to `cursor`. Note that the platform
|
||||
// window should keep a copy of `cursor` and also avoid replacing it until the
|
||||
// new value has been set if any kind of platform-specific resources are
|
||||
// managed by the platform cursor, e.g. HCURSOR on Windows, which are
|
||||
// destroyed once the last copy of the platform cursor goes out of scope.
|
||||
virtual void SetCursor(scoped_refptr<PlatformCursor> cursor) = 0;
|
||||
|
||||
// Moves the cursor to |location|. Location is in platform window coordinates.
|
||||
virtual void MoveCursorTo(const gfx::Point& location) = 0;
|
||||
|
@ -4,7 +4,9 @@
|
||||
|
||||
#include "ui/platform_window/stub/stub_window.h"
|
||||
|
||||
#include "base/memory/scoped_refptr.h"
|
||||
#include "base/notreached.h"
|
||||
#include "ui/base/cursor/platform_cursor.h"
|
||||
#include "ui/platform_window/platform_window_delegate.h"
|
||||
|
||||
namespace ui {
|
||||
@ -84,7 +86,7 @@ bool StubWindow::ShouldUseNativeFrame() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
void StubWindow::SetCursor(PlatformCursor cursor) {}
|
||||
void StubWindow::SetCursor(scoped_refptr<PlatformCursor> cursor) {}
|
||||
|
||||
void StubWindow::MoveCursorTo(const gfx::Point& location) {}
|
||||
|
||||
|
@ -48,7 +48,7 @@ class STUB_WINDOW_EXPORT StubWindow : public PlatformWindow {
|
||||
void Deactivate() override;
|
||||
void SetUseNativeFrame(bool use_native_frame) override;
|
||||
bool ShouldUseNativeFrame() const override;
|
||||
void SetCursor(PlatformCursor cursor) override;
|
||||
void SetCursor(scoped_refptr<PlatformCursor> cursor) override;
|
||||
void MoveCursorTo(const gfx::Point& location) override;
|
||||
void ConfineCursorToBounds(const gfx::Rect& bounds) override;
|
||||
void SetRestoredBoundsInPixels(const gfx::Rect& bounds) override;
|
||||
|
@ -4,20 +4,22 @@
|
||||
|
||||
#include "ui/platform_window/win/win_window.h"
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include "base/memory/scoped_refptr.h"
|
||||
#include "base/notreached.h"
|
||||
#include "base/strings/string_util_win.h"
|
||||
#include "ui/base/cursor/platform_cursor.h"
|
||||
#include "ui/base/cursor/win/win_cursor.h"
|
||||
#include "ui/base/win/shell.h"
|
||||
#include "ui/events/event.h"
|
||||
#include "ui/events/event_utils.h"
|
||||
#include "ui/gfx/win/msg_util.h"
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
namespace ui {
|
||||
|
||||
namespace {
|
||||
@ -147,9 +149,15 @@ bool WinWindow::ShouldUseNativeFrame() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
void WinWindow::SetCursor(PlatformCursor cursor) {
|
||||
DCHECK(cursor);
|
||||
::SetCursor(static_cast<WinCursor*>(cursor)->hcursor());
|
||||
void WinWindow::SetCursor(scoped_refptr<PlatformCursor> platform_cursor) {
|
||||
DCHECK(platform_cursor);
|
||||
|
||||
auto cursor = WinCursor::FromPlatformCursor(platform_cursor);
|
||||
::SetCursor(cursor->hcursor());
|
||||
|
||||
// The new cursor needs to be stored last to avoid deleting the old cursor
|
||||
// while it's still in use.
|
||||
cursor_ = cursor;
|
||||
}
|
||||
|
||||
void WinWindow::MoveCursorTo(const gfx::Point& location) {
|
||||
|
@ -7,6 +7,7 @@
|
||||
|
||||
#include "base/compiler_specific.h"
|
||||
#include "base/macros.h"
|
||||
#include "base/memory/scoped_refptr.h"
|
||||
#include "base/memory/weak_ptr.h"
|
||||
#include "ui/gfx/win/msg_util.h"
|
||||
#include "ui/gfx/win/window_impl.h"
|
||||
@ -17,6 +18,7 @@
|
||||
#include <windows.h>
|
||||
|
||||
namespace ui {
|
||||
class WinCursor;
|
||||
|
||||
class WIN_WINDOW_EXPORT WinWindow : public PlatformWindow,
|
||||
public gfx::WindowImpl {
|
||||
@ -48,7 +50,7 @@ class WIN_WINDOW_EXPORT WinWindow : public PlatformWindow,
|
||||
void Deactivate() override;
|
||||
void SetUseNativeFrame(bool use_native_frame) override;
|
||||
bool ShouldUseNativeFrame() const override;
|
||||
void SetCursor(PlatformCursor cursor) override;
|
||||
void SetCursor(scoped_refptr<PlatformCursor> cursor) override;
|
||||
void MoveCursorTo(const gfx::Point& location) override;
|
||||
void ConfineCursorToBounds(const gfx::Rect& bounds) override;
|
||||
void SetRestoredBoundsInPixels(const gfx::Rect& bounds) override;
|
||||
@ -105,6 +107,10 @@ class WIN_WINDOW_EXPORT WinWindow : public PlatformWindow,
|
||||
|
||||
PlatformWindowDelegate* delegate_;
|
||||
|
||||
// Keep a reference to the current cursor to make sure the wrapped HCURSOR
|
||||
// isn't destroyed after the call to SetCursor().
|
||||
scoped_refptr<WinCursor> cursor_;
|
||||
|
||||
CR_MSG_MAP_CLASS_DECLARATIONS(WinWindow)
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(WinWindow);
|
||||
|
@ -4,6 +4,7 @@
|
||||
|
||||
#include "ui/platform_window/x11/x11_window.h"
|
||||
|
||||
#include "base/memory/scoped_refptr.h"
|
||||
#include "base/strings/string_number_conversions.h"
|
||||
#include "base/threading/thread_task_runner_handle.h"
|
||||
#include "base/trace_event/trace_event.h"
|
||||
@ -12,6 +13,7 @@
|
||||
#include "third_party/skia/include/core/SkRegion.h"
|
||||
#include "ui/base/buildflags.h"
|
||||
#include "ui/base/cursor/cursor.h"
|
||||
#include "ui/base/cursor/platform_cursor.h"
|
||||
#include "ui/base/dragdrop/drag_drop_types.h"
|
||||
#include "ui/base/dragdrop/mojom/drag_drop_types.mojom.h"
|
||||
#include "ui/base/dragdrop/os_exchange_data.h"
|
||||
@ -760,10 +762,10 @@ bool X11Window::ShouldUseNativeFrame() const {
|
||||
return use_native_frame_;
|
||||
}
|
||||
|
||||
void X11Window::SetCursor(PlatformCursor cursor) {
|
||||
void X11Window::SetCursor(scoped_refptr<PlatformCursor> cursor) {
|
||||
DCHECK(cursor);
|
||||
|
||||
last_cursor_ = static_cast<X11Cursor*>(cursor);
|
||||
last_cursor_ = X11Cursor::FromPlatformCursor(cursor);
|
||||
on_cursor_loaded_.Reset(base::BindOnce(DefineCursor, xwindow_));
|
||||
last_cursor_->OnCursorLoaded(on_cursor_loaded_.callback());
|
||||
}
|
||||
|
@ -90,7 +90,7 @@ class X11_WINDOW_EXPORT X11Window
|
||||
void Deactivate() override;
|
||||
void SetUseNativeFrame(bool use_native_frame) override;
|
||||
bool ShouldUseNativeFrame() const override;
|
||||
void SetCursor(PlatformCursor cursor) override;
|
||||
void SetCursor(scoped_refptr<PlatformCursor> cursor) override;
|
||||
void MoveCursorTo(const gfx::Point& location) override;
|
||||
void ConfineCursorToBounds(const gfx::Rect& bounds) override;
|
||||
void SetRestoredBoundsInPixels(const gfx::Rect& bounds) override;
|
||||
|
@ -1362,7 +1362,10 @@ test("views_unittests") {
|
||||
"widget/desktop_aura/desktop_screen_x11_unittest.cc",
|
||||
"widget/desktop_aura/x11_drag_drop_client_unittest.cc",
|
||||
]
|
||||
deps += [ "//ui/base/x:test_support" ]
|
||||
deps += [
|
||||
"//ui/base/x",
|
||||
"//ui/base/x:test_support",
|
||||
]
|
||||
}
|
||||
if (is_linux || is_chromeos || is_fuchsia) {
|
||||
sources += [
|
||||
|
@ -9,12 +9,14 @@
|
||||
|
||||
#include "base/bind.h"
|
||||
#include "base/callback_helpers.h"
|
||||
#include "base/memory/scoped_refptr.h"
|
||||
#include "base/notreached.h"
|
||||
#include "base/strings/utf_string_conversions.h"
|
||||
#include "base/threading/thread_task_runner_handle.h"
|
||||
#include "ui/aura/client/drag_drop_delegate.h"
|
||||
#include "ui/aura/window.h"
|
||||
#include "ui/aura/window_tree_host.h"
|
||||
#include "ui/base/cursor/platform_cursor.h"
|
||||
#include "ui/base/data_transfer_policy/data_transfer_endpoint.h"
|
||||
#include "ui/base/dragdrop/drag_drop_types.h"
|
||||
#include "ui/base/dragdrop/mojom/drag_drop_types.mojom.h"
|
||||
@ -60,7 +62,7 @@ class FakePlatformWindow : public ui::PlatformWindow, public ui::WmDragHandler {
|
||||
}
|
||||
void Activate() override {}
|
||||
void Deactivate() override {}
|
||||
void SetCursor(ui::PlatformCursor cursor) override {}
|
||||
void SetCursor(scoped_refptr<ui::PlatformCursor> cursor) override {}
|
||||
void MoveCursorTo(const gfx::Point& location) override {}
|
||||
void ConfineCursorToBounds(const gfx::Rect& bounds) override {}
|
||||
void SetRestoredBoundsInPixels(const gfx::Rect& bounds) override {}
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include "base/bind.h"
|
||||
#include "base/containers/flat_set.h"
|
||||
#include "base/memory/ptr_util.h"
|
||||
#include "base/memory/scoped_refptr.h"
|
||||
#include "base/metrics/histogram_macros.h"
|
||||
#include "base/trace_event/trace_event.h"
|
||||
#include "base/win/win_util.h"
|
||||
@ -22,6 +23,8 @@
|
||||
#include "ui/aura/client/focus_client.h"
|
||||
#include "ui/aura/window_event_dispatcher.h"
|
||||
#include "ui/base/class_property.h"
|
||||
#include "ui/base/cursor/cursor.h"
|
||||
#include "ui/base/cursor/platform_cursor.h"
|
||||
#include "ui/base/cursor/win/win_cursor.h"
|
||||
#include "ui/base/ime/input_method.h"
|
||||
#include "ui/base/ui_base_features.h"
|
||||
@ -633,10 +636,8 @@ void DesktopWindowTreeHostWin::SetCursorNative(gfx::NativeCursor cursor) {
|
||||
TRACE_EVENT1("ui,input", "DesktopWindowTreeHostWin::SetCursorNative",
|
||||
"cursor", cursor.type());
|
||||
|
||||
ui::WinCursor* platform_cursor =
|
||||
static_cast<ui::WinCursor*>(cursor.platform());
|
||||
DCHECK(platform_cursor);
|
||||
message_handler_->SetCursor(platform_cursor->hcursor());
|
||||
message_handler_->SetCursor(
|
||||
ui::WinCursor::FromPlatformCursor(cursor.platform()));
|
||||
}
|
||||
|
||||
void DesktopWindowTreeHostWin::OnCursorVisibilityChangedNative(bool show) {
|
||||
|
@ -13,6 +13,7 @@
|
||||
#include "base/location.h"
|
||||
#include "base/macros.h"
|
||||
#include "base/memory/ptr_util.h"
|
||||
#include "base/memory/scoped_refptr.h"
|
||||
#include "base/run_loop.h"
|
||||
#include "base/single_thread_task_runner.h"
|
||||
#include "base/strings/utf_string_conversions.h"
|
||||
@ -22,9 +23,9 @@
|
||||
#include "ui/aura/test/test_screen.h"
|
||||
#include "ui/aura/window.h"
|
||||
#include "ui/aura/window_tree_host.h"
|
||||
#include "ui/base/cursor/cursor.h"
|
||||
#include "ui/base/cursor/cursor_loader.h"
|
||||
#include "ui/base/cursor/mojom/cursor_type.mojom.h"
|
||||
#include "ui/base/cursor/platform_cursor.h"
|
||||
#include "ui/base/dragdrop/drag_drop_types.h"
|
||||
#include "ui/base/dragdrop/mojom/drag_drop_types.mojom-shared.h"
|
||||
#include "ui/base/dragdrop/os_exchange_data.h"
|
||||
@ -323,10 +324,10 @@ DragOperation SimpleTestDragDropClient::StartDragAndDrop(
|
||||
ui::CursorLoader cursor_loader;
|
||||
ui::Cursor grabbing = ui::mojom::CursorType::kGrabbing;
|
||||
cursor_loader.SetPlatformCursor(&grabbing);
|
||||
auto* last_cursor = static_cast<ui::X11Cursor*>(
|
||||
source_window->GetHost()->last_cursor().platform());
|
||||
loop_->RunMoveLoop(!source_window->HasCapture(), last_cursor,
|
||||
static_cast<ui::X11Cursor*>(grabbing.platform()));
|
||||
auto last_cursor = source_window->GetHost()->last_cursor();
|
||||
loop_->RunMoveLoop(!source_window->HasCapture(),
|
||||
ui::X11Cursor::FromPlatformCursor(last_cursor.platform()),
|
||||
ui::X11Cursor::FromPlatformCursor(grabbing.platform()));
|
||||
|
||||
auto resulting_operation = negotiated_operation();
|
||||
CleanupDrag();
|
||||
|
@ -35,6 +35,7 @@
|
||||
#include "ui/accessibility/platform/ax_fragment_root_win.h"
|
||||
#include "ui/accessibility/platform/ax_platform_node_win.h"
|
||||
#include "ui/accessibility/platform/ax_system_caret_win.h"
|
||||
#include "ui/base/cursor/win/win_cursor.h"
|
||||
#include "ui/base/ime/text_input_client.h"
|
||||
#include "ui/base/ime/text_input_type.h"
|
||||
#include "ui/base/ui_base_features.h"
|
||||
@ -402,7 +403,7 @@ HWNDMessageHandler::HWNDMessageHandler(HWNDMessageHandlerDelegate* delegate,
|
||||
waiting_for_close_now_(false),
|
||||
use_system_default_icon_(false),
|
||||
restored_enabled_(false),
|
||||
current_cursor_(nullptr),
|
||||
current_cursor_(base::MakeRefCounted<ui::WinCursor>()),
|
||||
dpi_(0),
|
||||
called_enable_non_client_dpi_scaling_(false),
|
||||
active_mouse_tracking_flags_(0),
|
||||
@ -863,10 +864,12 @@ bool HWNDMessageHandler::SetTitle(const std::u16string& title) {
|
||||
return true;
|
||||
}
|
||||
|
||||
void HWNDMessageHandler::SetCursor(HCURSOR cursor) {
|
||||
void HWNDMessageHandler::SetCursor(scoped_refptr<ui::WinCursor> cursor) {
|
||||
DCHECK(cursor);
|
||||
|
||||
TRACE_EVENT1("ui,input", "HWNDMessageHandler::SetCursor", "cursor",
|
||||
static_cast<const void*>(cursor));
|
||||
::SetCursor(cursor);
|
||||
static_cast<const void*>(cursor->hcursor()));
|
||||
::SetCursor(cursor->hcursor());
|
||||
current_cursor_ = cursor;
|
||||
}
|
||||
|
||||
@ -2486,12 +2489,15 @@ LRESULT HWNDMessageHandler::OnSetCursor(UINT message,
|
||||
if (is_pen_active_in_client_area_)
|
||||
return 1;
|
||||
|
||||
// current_cursor_ must be a ui::WinCursor, so that custom image cursors are
|
||||
// properly ref-counted. cursor below is only used for system cursors and
|
||||
// doesn't replace the current cursor so an HCURSOR can be used directly.
|
||||
wchar_t* cursor = IDC_ARROW;
|
||||
// Reimplement the necessary default behavior here. Calling DefWindowProc can
|
||||
// trigger weird non-client painting for non-glass windows with custom frames.
|
||||
// Using a ScopedRedrawLock to prevent caption rendering artifacts may allow
|
||||
// content behind this window to incorrectly paint in front of this window.
|
||||
// Invalidating the window to paint over either set of artifacts is not ideal.
|
||||
wchar_t* cursor = IDC_ARROW;
|
||||
switch (LOWORD(l_param)) {
|
||||
case HTSIZE:
|
||||
cursor = IDC_SIZENWSE;
|
||||
|
@ -17,6 +17,7 @@
|
||||
#include "base/compiler_specific.h"
|
||||
#include "base/lazy_instance.h"
|
||||
#include "base/macros.h"
|
||||
#include "base/memory/scoped_refptr.h"
|
||||
#include "base/memory/weak_ptr.h"
|
||||
#include "base/scoped_observation.h"
|
||||
#include "base/win/scoped_gdi_object.h"
|
||||
@ -43,9 +44,10 @@ class Insets;
|
||||
namespace ui {
|
||||
class AXFragmentRootWin;
|
||||
class AXSystemCaretWin;
|
||||
class SessionChangeObserver;
|
||||
class TextInputClient;
|
||||
class ViewProp;
|
||||
class SessionChangeObserver;
|
||||
class WinCursor;
|
||||
} // namespace ui
|
||||
|
||||
namespace views {
|
||||
@ -159,7 +161,7 @@ class VIEWS_EXPORT HWNDMessageHandler : public gfx::WindowImpl,
|
||||
// Returns true if the title changed.
|
||||
bool SetTitle(const std::u16string& title);
|
||||
|
||||
void SetCursor(HCURSOR cursor);
|
||||
void SetCursor(scoped_refptr<ui::WinCursor> cursor);
|
||||
|
||||
void FrameTypeChanged();
|
||||
|
||||
@ -624,7 +626,7 @@ class VIEWS_EXPORT HWNDMessageHandler : public gfx::WindowImpl,
|
||||
bool restored_enabled_;
|
||||
|
||||
// The current cursor.
|
||||
HCURSOR current_cursor_;
|
||||
scoped_refptr<ui::WinCursor> current_cursor_;
|
||||
|
||||
// The icon created from the bitmap image of the window icon.
|
||||
base::win::ScopedHICON window_icon_;
|
||||
|
Reference in New Issue
Block a user