summaryrefslogtreecommitdiff
path: root/chromium/ui/ozone/platform/wayland/host/wayland_cursor_factory.h
blob: 9542bf4d6561d9cdd464ac1df86d58d108aff250 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
// 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_OZONE_PLATFORM_WAYLAND_HOST_WAYLAND_CURSOR_FACTORY_H_
#define UI_OZONE_PLATFORM_WAYLAND_HOST_WAYLAND_CURSOR_FACTORY_H_

#include <string>

#include "base/containers/flat_map.h"
#include "base/gtest_prod_util.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/scoped_refptr.h"
#include "base/scoped_observation.h"
#include "ui/linux/cursor_theme_manager_observer.h"
#include "ui/linux/linux_ui.h"
#include "ui/ozone/common/bitmap_cursor_factory.h"
#include "ui/ozone/platform/wayland/common/wayland_object.h"
#include "ui/ozone/platform/wayland/host/wayland_cursor.h"

struct wl_cursor_theme;

namespace ui {

class BitmapCursor;
class WaylandConnection;

// CursorFactory implementation for Wayland.
class WaylandCursorFactory : public BitmapCursorFactory,
                             public CursorThemeManagerObserver,
                             public WaylandCursorBufferListener {
 public:
  explicit WaylandCursorFactory(WaylandConnection* connection);
  WaylandCursorFactory(const WaylandCursorFactory&) = delete;
  WaylandCursorFactory& operator=(const WaylandCursorFactory&) = delete;
  ~WaylandCursorFactory() override;

  // CursorFactory:
  void ObserveThemeChanges() override;

  // CursorFactory:
  scoped_refptr<PlatformCursor> GetDefaultCursor(
      mojom::CursorType type) override;
  void SetDeviceScaleFactor(float scale) override;

 protected:
  // Returns the actual wl_cursor record from the currently loaded theme.
  // Virtual for tests where themes can be empty.
  virtual wl_cursor* GetCursorFromTheme(const std::string& name);

 private:
  FRIEND_TEST_ALL_PREFIXES(WaylandCursorFactoryTest,
                           RetainOldThemeUntilNewBufferIsAttached);

  struct ThemeData {
    ThemeData();
    ~ThemeData();
    wl::Object<wl_cursor_theme> theme;
    base::flat_map<mojom::CursorType, scoped_refptr<BitmapCursor>> cache;
  };

  // CusorThemeManagerObserver:
  void OnCursorThemeNameChanged(const std::string& cursor_theme_name) override;
  void OnCursorThemeSizeChanged(int cursor_theme_size) override;

  // WaylandCursorBufferListener:
  void OnCursorBufferAttached(wl_cursor* cursor_data) override;

  void ReloadThemeCursors();
  void OnThemeLoaded(const std::string& loaded_theme_name,
                     int loaded_theme_size,
                     wl_cursor_theme* loaded_theme);

  const raw_ptr<WaylandConnection> connection_;

  base::ScopedObservation<LinuxUi,
                          CursorThemeManagerObserver,
                          &LinuxUi::AddCursorThemeObserver,
                          &LinuxUi::RemoveCursorThemeObserver>
      cursor_theme_observer_{this};

  // Name of the current theme.
  std::string name_;
  // Current size of cursors
  int size_ = 24;

  // The current scale of the mouse cursor icon.
  float scale_ = 1.0f;

  std::unique_ptr<ThemeData> current_theme_;
  // Holds the reference on the unloaded theme until the cursor is released.
  std::unique_ptr<ThemeData> unloaded_theme_;

  base::WeakPtrFactory<WaylandCursorFactory> weak_factory_{this};
};

}  // namespace ui

#endif  // UI_OZONE_PLATFORM_WAYLAND_HOST_WAYLAND_CURSOR_FACTORY_H_