#ifndef UI_WM_CORE_CURSOR_MANAGER_H_
#define UI_WM_CORE_CURSOR_MANAGER_H_
#include <memory>
#include "base/component_export.h"
#include "base/memory/raw_ptr.h"
#include "base/observer_list.h"
#include "third_party/skia/include/core/SkColor.h"
#include "ui/aura/client/cursor_client.h"
#include "ui/display/display.h"
#include "ui/gfx/geometry/point.h"
#include "ui/gfx/native_ui_types.h"
#include "ui/wm/core/native_cursor_manager_delegate.h"
namespace ui {
class KeyEvent;
class TouchEvent;
enum class CursorSize;
}
namespace wm {
namespace internal {
class CursorState;
}
class NativeCursorManager;
class COMPONENT_EXPORT(UI_WM) CursorManager
: public aura::client::CursorClient,
public NativeCursorManagerDelegate {
public:
explicit CursorManager(std::unique_ptr<NativeCursorManager> delegate);
CursorManager(const CursorManager&) = delete;
CursorManager& operator=(const CursorManager&) = delete;
~CursorManager() override;
static void ResetCursorVisibilityStateForTest();
void SetCursor(gfx::NativeCursor) override;
gfx::NativeCursor GetCursor() const override;
void SetCursorForced(gfx::NativeCursor) override;
void ShowCursor() override;
void HideCursor() override;
bool IsCursorVisible() const override;
void SetCursorSize(ui::CursorSize cursor_size) override;
ui::CursorSize GetCursorSize() const override;
void SetLargeCursorSizeInDip(int large_cursor_size_in_dip) override;
int GetLargeCursorSizeInDip() const override;
void SetCursorColor(SkColor color) override;
SkColor GetCursorColor() const override;
void EnableMouseEvents() override;
void DisableMouseEvents() override;
bool IsMouseEventsEnabled() const override;
void SetDisplay(const display::Display& display) override;
const display::Display& GetDisplay() const override;
void LockCursor() override;
void UnlockCursor() override;
bool IsCursorLocked() const override;
void AddObserver(aura::client::CursorClientObserver* observer) override;
void RemoveObserver(aura::client::CursorClientObserver* observer) override;
bool ShouldHideCursorOnKeyEvent(const ui::KeyEvent& event) const override;
bool ShouldHideCursorOnTouchEvent(const ui::TouchEvent& event) const override;
gfx::Size GetSystemCursorSize() const override;
#if BUILDFLAG(IS_WIN)
void UpdateSystemCursorVisibilityForTest(bool visible) override;
#endif
private:
void CommitCursor(gfx::NativeCursor cursor) override;
void CommitVisibility(bool visible) override;
void CommitCursorSize(ui::CursorSize cursor_size) override;
void CommitLargeCursorSizeInDip(int large_cursor_size_in_dip) override;
void CommitCursorColor(SkColor color) override;
void CommitMouseEventsEnabled(bool enabled) override;
void CommitSystemCursorSize(const gfx::Size& cursor_size) override;
void CommitSystemCursorVisibility(bool visible) override;
void SetCursorImpl(gfx::NativeCursor cursor, bool forced);
void UpdateSystemCursorVisibility(bool visible);
class ScopedCursorLock {
public:
explicit ScopedCursorLock(CursorManager* cursor_manager);
~ScopedCursorLock();
private:
raw_ptr<CursorManager> cursor_manager_;
};
std::unique_ptr<NativeCursorManager> delegate_;
display::Display display_;
int cursor_lock_count_;
std::unique_ptr<internal::CursorState> current_state_;
std::unique_ptr<internal::CursorState> state_on_unlock_;
base::ObserverList<aura::client::CursorClientObserver>::
UncheckedAndDanglingUntriaged observers_;
std::optional<ScopedCursorLock> scoped_cursor_lock_;
static bool last_cursor_visibility_state_;
};
}
#endif