[go: nahoru, domu]

Unify Aura and Ozone X11 PlatformCursor

This CL ports Aura/X11 to use X11CursorFactoryOzone, renamed to
X11CursorFactory; and X11CursorOzone, renamed to X11Cursor.

It moves X11Cursor{Factory} to //ui/base/x, to allow access to the
factory from outside of //ui/ozone, in particular, to instantiate it in
aura::Env when not using Ozone.

As a result of these changes, the Aura/X11 code of WebCursor, ui::Cursor
and CursorLoaderX11 can be removed and replaced by the Ozone versions of
the code, that only depend on the generic CursorFactory.

Additionally, X11WindowOzone isn't needed anymore and X11Window is used
instead.

Fixed: 1029142
Change-Id: I438064f8723700d20de23a0d33819d593828c6a9
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2260642
Commit-Queue: Henrique Ferreiro <hferreiro@igalia.com>
Reviewed-by: Scott Violet <sky@chromium.org>
Cr-Commit-Position: refs/heads/master@{#782359}
diff --git a/content/common/BUILD.gn b/content/common/BUILD.gn
index e0263e297..e09f70a6 100644
--- a/content/common/BUILD.gn
+++ b/content/common/BUILD.gn
@@ -93,7 +93,6 @@
     "cursors/webcursor_android.cc",
     "cursors/webcursor_aura.cc",
     "cursors/webcursor_aurawin.cc",
-    "cursors/webcursor_aurax11.cc",
     "cursors/webcursor_mac.mm",
     "cursors/webcursor_ozone.cc",
     "drag_event_source_info.h",
@@ -342,7 +341,7 @@
     deps += [ "//ppapi/proxy:ipc_sources" ]
   }
 
-  if (!use_ozone) {
+  if (!use_x11 && !use_ozone) {
     sources -= [ "cursors/webcursor_ozone.cc" ]
   }
 
@@ -352,12 +351,6 @@
     sources -= [ "cursors/webcursor_aura.cc" ]
   }
 
-  if (!use_aura || !use_x11) {
-    sources -= [ "cursors/webcursor_aurax11.cc" ]
-  } else {
-    deps += [ "//ui/gfx/x" ]
-  }
-
   if (is_linux) {
     deps += [ "//third_party/fontconfig" ]
   }
diff --git a/content/common/cursors/webcursor_aurax11.cc b/content/common/cursors/webcursor_aurax11.cc
deleted file mode 100644
index 111207a..0000000
--- a/content/common/cursors/webcursor_aurax11.cc
+++ /dev/null
@@ -1,46 +0,0 @@
-// Copyright (c) 2012 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 "content/common/cursors/webcursor.h"
-
-#include "base/check_op.h"
-#include "ui/base/cursor/cursor.h"
-#include "ui/base/cursor/mojom/cursor_type.mojom-shared.h"
-#include "ui/base/x/x11_util.h"
-#include "ui/gfx/x/x11.h"
-
-namespace content {
-
-ui::PlatformCursor WebCursor::GetPlatformCursor(const ui::Cursor& cursor) {
-  // The other cursor types are set in CursorLoaderX11
-  DCHECK_EQ(cursor.type(), ui::mojom::CursorType::kCustom);
-
-  if (platform_cursor_)
-    return platform_cursor_;
-
-  XcursorImage* image = ui::SkBitmapToXcursorImage(cursor.custom_bitmap(),
-                                                   cursor.custom_hotspot());
-  platform_cursor_ = ui::CreateReffedCustomXCursor(image);
-  return platform_cursor_;
-}
-
-void WebCursor::CleanupPlatformData() {
-  if (platform_cursor_) {
-    ui::UnrefCustomXCursor(platform_cursor_);
-    platform_cursor_ = 0;
-  }
-  custom_cursor_.reset();
-}
-
-void WebCursor::CopyPlatformData(const WebCursor& other) {
-  if (platform_cursor_)
-    ui::UnrefCustomXCursor(platform_cursor_);
-  platform_cursor_ = other.platform_cursor_;
-  if (platform_cursor_)
-    ui::RefCustomXCursor(platform_cursor_);
-
-  device_scale_factor_ = other.device_scale_factor_;
-}
-
-}  // namespace content
diff --git a/content/common/cursors/webcursor_ozone.cc b/content/common/cursors/webcursor_ozone.cc
index 6667e0e..1663960 100644
--- a/content/common/cursors/webcursor_ozone.cc
+++ b/content/common/cursors/webcursor_ozone.cc
@@ -25,6 +25,7 @@
   return platform_cursor_;
 }
 
+#if defined(USE_OZONE)
 void WebCursor::SetDisplayInfo(const display::Display& display) {
   if (rotation_ == display.panel_rotation() &&
       device_scale_factor_ == display.device_scale_factor() &&
@@ -53,6 +54,7 @@
        static_cast<float>(maximum_cursor_size_.width()) / bitmap->width(),
        static_cast<float>(maximum_cursor_size_.height()) / bitmap->height()});
 }
+#endif
 
 void WebCursor::CleanupPlatformData() {
   if (platform_cursor_) {
@@ -70,7 +72,9 @@
     ui::CursorFactory::GetInstance()->RefImageCursor(platform_cursor_);
 
   device_scale_factor_ = other.device_scale_factor_;
+#if defined(USE_OZONE)
   maximum_cursor_size_ = other.maximum_cursor_size_;
+#endif
 }
 
 }  // namespace content
diff --git a/ui/aura/BUILD.gn b/ui/aura/BUILD.gn
index 9e80743..fd917270 100644
--- a/ui/aura/BUILD.gn
+++ b/ui/aura/BUILD.gn
@@ -127,6 +127,7 @@
     "//ui/events:events_base",
     "//ui/events/platform",
     "//ui/gfx",
+    "//ui/gfx:gfx_switches",
     "//ui/gfx/geometry",
     "//ui/gl",
     "//ui/platform_window",
@@ -140,6 +141,7 @@
   ]
 
   if (use_x11) {
+    public_deps += [ "//ui/base/x" ]
     deps += [
       "//ui/events/platform/x11",
       "//ui/platform_window/x11",
diff --git a/ui/aura/env.cc b/ui/aura/env.cc
index 56d2ef9..22b7aac6 100644
--- a/ui/aura/env.cc
+++ b/ui/aura/env.cc
@@ -25,6 +25,10 @@
 #include "ui/ozone/public/ozone_platform.h"
 #endif
 
+#if defined(USE_X11)
+#include "ui/gfx/switches.h"
+#endif
+
 namespace aura {
 
 namespace {
@@ -205,7 +209,15 @@
 Env::Env()
     : env_controller_(std::make_unique<EnvInputStateController>(this)),
       gesture_recognizer_(std::make_unique<ui::GestureRecognizerImpl>()),
-      input_state_lookup_(InputStateLookup::Create()) {}
+      input_state_lookup_(InputStateLookup::Create()) {
+#if defined(USE_X11)
+  // In Ozone/X11, the cursor factory is initialized by the platform
+  // initialization code.
+  if (!features::IsUsingOzonePlatform() &&
+      !base::CommandLine::ForCurrentProcess()->HasSwitch(switches::kHeadless))
+    cursor_factory_ = std::make_unique<ui::X11CursorFactory>();
+#endif
+}
 
 void Env::Init() {
 #if defined(USE_OZONE)
diff --git a/ui/aura/env.h b/ui/aura/env.h
index 893c1578a..12f91827 100644
--- a/ui/aura/env.h
+++ b/ui/aura/env.h
@@ -19,6 +19,10 @@
 #include "ui/events/types/event_type.h"
 #include "ui/gfx/geometry/point.h"
 
+#if defined(USE_X11)
+#include "ui/base/x/x11_cursor_factory.h"  // nogncheck
+#endif
+
 namespace ui {
 class ContextFactory;
 class EventObserver;
@@ -171,6 +175,10 @@
 
   std::unique_ptr<ui::GestureRecognizer> gesture_recognizer_;
 
+#if defined(USE_X11)
+  std::unique_ptr<ui::X11CursorFactory> cursor_factory_;
+#endif
+
   std::unique_ptr<InputStateLookup> input_state_lookup_;
   std::unique_ptr<ui::PlatformEventSource> event_source_;
 
diff --git a/ui/base/BUILD.gn b/ui/base/BUILD.gn
index 3241093..1179753 100644
--- a/ui/base/BUILD.gn
+++ b/ui/base/BUILD.gn
@@ -1079,6 +1079,7 @@
 
   if (use_x11) {
     deps += [
+      "//ui/base/x:unittests",
       "//ui/events/platform/x11",
       "//ui/gfx/x",
     ]
diff --git a/ui/base/cursor/BUILD.gn b/ui/base/cursor/BUILD.gn
index c5971c5..f16386ec 100644
--- a/ui/base/cursor/BUILD.gn
+++ b/ui/base/cursor/BUILD.gn
@@ -24,18 +24,22 @@
   ]
   deps = [ "//ui/gfx:geometry_skia" ]
 
-  if (use_x11) {
-    sources += [ "cursor_x11.cc" ]
-    deps += [ "//ui/base/x" ]
-  }
-
-  if (use_ozone) {
-    sources += [ "cursor_ozone.cc" ]
-  }
-
   if (is_win) {
     sources += [ "cursor_win.cc" ]
   }
+
+  if (use_x11 || use_ozone) {
+    sources += [ "cursor_ozone.cc" ]
+  }
+}
+
+source_set("theme_manager") {
+  sources = [
+    "cursor_theme_manager.cc",
+    "cursor_theme_manager.h",
+    "cursor_theme_manager_observer.h",
+  ]
+  deps = [ "//base" ]
 }
 
 if (use_aura) {
@@ -45,9 +49,6 @@
       "cursor_loader.h",
       "cursor_lookup.cc",
       "cursor_lookup.h",
-      "cursor_theme_manager.cc",
-      "cursor_theme_manager.h",
-      "cursor_theme_manager_observer.h",
       "cursor_util.cc",
       "cursor_util.h",
       "cursors_aura.cc",
@@ -80,21 +81,8 @@
       deps += [ "//ui/resources:ui_unscaled_resources_grd" ]
     }
 
-    if (use_x11) {
-      sources += [
-        "cursor_loader_x11.cc",
-        "cursor_loader_x11.h",
-      ]
-      public_deps += [
-        "//ui/base/x",
-        "//ui/gfx/x",
-      ]
-    }
-
     if (use_ozone) {
       sources += [
-        "cursor_loader_ozone.cc",
-        "cursor_loader_ozone.h",
         "ozone/bitmap_cursor_factory_ozone.cc",
         "ozone/bitmap_cursor_factory_ozone.h",
       ]
@@ -103,6 +91,13 @@
         "//ui/gfx/geometry",
       ]
     }
+
+    if (use_x11 || use_ozone) {
+      sources += [
+        "cursor_loader_ozone.cc",
+        "cursor_loader_ozone.h",
+      ]
+    }
   }
 }
 
diff --git a/ui/base/cursor/cursor.h b/ui/base/cursor/cursor.h
index 47d9b8b..835027a 100644
--- a/ui/base/cursor/cursor.h
+++ b/ui/base/cursor/cursor.h
@@ -21,8 +21,6 @@
 
 #if defined(OS_WIN)
 typedef ::HCURSOR PlatformCursor;
-#elif defined(USE_X11)
-typedef unsigned long PlatformCursor;
 #else
 typedef void* PlatformCursor;
 #endif
diff --git a/ui/base/cursor/cursor_factory.cc b/ui/base/cursor/cursor_factory.cc
index 45a4883..c1b79564 100644
--- a/ui/base/cursor/cursor_factory.cc
+++ b/ui/base/cursor/cursor_factory.cc
@@ -4,6 +4,8 @@
 
 #include "ui/base/cursor/cursor_factory.h"
 
+#include <ostream>
+
 #include "base/check.h"
 #include "base/check_op.h"
 #include "base/notreached.h"
diff --git a/ui/base/cursor/cursor_factory.h b/ui/base/cursor/cursor_factory.h
index 2ef7723c..1fff711 100644
--- a/ui/base/cursor/cursor_factory.h
+++ b/ui/base/cursor/cursor_factory.h
@@ -8,7 +8,6 @@
 #include <vector>
 
 #include "base/component_export.h"
-#include "ui/base/cursor/cursor.h"
 #include "ui/base/cursor/mojom/cursor_type.mojom-forward.h"
 
 class SkBitmap;
@@ -18,6 +17,7 @@
 }
 
 namespace ui {
+using PlatformCursor = void*;
 
 class COMPONENT_EXPORT(UI_BASE_CURSOR_BASE) CursorFactory {
  public:
diff --git a/ui/base/cursor/cursor_loader_x11.cc b/ui/base/cursor/cursor_loader_x11.cc
deleted file mode 100644
index 5b3cd3d8..0000000
--- a/ui/base/cursor/cursor_loader_x11.cc
+++ /dev/null
@@ -1,171 +0,0 @@
-// Copyright (c) 2012 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_loader_x11.h"
-
-#include <float.h>
-
-#include "base/check.h"
-#include "base/notreached.h"
-#include "ui/base/cursor/cursor.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"
-
-namespace ui {
-
-CursorLoader* CursorLoader::Create() {
-  return new CursorLoaderX11;
-}
-
-CursorLoaderX11::ImageCursor::ImageCursor(XcursorImage* x_image,
-                                          float scale,
-                                          display::Display::Rotation rotation)
-    : scale(scale), rotation(rotation) {
-  cursor = CreateReffedCustomXCursor(x_image);
-}
-
-CursorLoaderX11::ImageCursor::~ImageCursor() {
-  UnrefCustomXCursor(cursor);
-}
-
-CursorLoaderX11::CursorLoaderX11()
-    : display_(gfx::GetXDisplay()),
-      invisible_cursor_(CreateInvisibleCursor(), gfx::GetXDisplay()) {
-  auto* cursor_theme_manager = CursorThemeManager::GetInstance();
-  if (cursor_theme_manager)
-    cursor_theme_observer_.Add(cursor_theme_manager);
-}
-
-CursorLoaderX11::~CursorLoaderX11() {
-  UnloadAll();
-}
-
-void CursorLoaderX11::LoadImageCursor(mojom::CursorType id,
-                                      int resource_id,
-                                      const gfx::Point& hot) {
-  SkBitmap bitmap;
-  gfx::Point hotspot = hot;
-
-  GetImageCursorBitmap(resource_id, scale(), rotation(), &hotspot, &bitmap);
-  XcursorImage* x_image = SkBitmapToXcursorImage(bitmap, hotspot);
-  image_cursors_[id] =
-      std::make_unique<ImageCursor>(x_image, scale(), rotation());
-}
-
-void CursorLoaderX11::LoadAnimatedCursor(mojom::CursorType id,
-                                         int resource_id,
-                                         const gfx::Point& hot,
-                                         int frame_delay_ms) {
-  std::vector<SkBitmap> bitmaps;
-  gfx::Point hotspot = hot;
-
-  GetAnimatedCursorBitmaps(resource_id, scale(), rotation(), &hotspot,
-                           &bitmaps);
-
-  XcursorImages* x_images = XcursorImagesCreate(bitmaps.size());
-  x_images->nimage = bitmaps.size();
-
-  for (unsigned int frame = 0; frame < bitmaps.size(); ++frame) {
-    XcursorImage* x_image = SkBitmapToXcursorImage(bitmaps[frame], hotspot);
-    x_image->delay = frame_delay_ms;
-    x_images->images[frame] = x_image;
-  }
-
-  animated_cursors_[id] = std::make_pair(
-      XcursorImagesLoadCursor(gfx::GetXDisplay(), x_images), x_images);
-}
-
-void CursorLoaderX11::UnloadAll() {
-  image_cursors_.clear();
-
-  // Free animated cursors and images.
-  for (const auto& cursor : animated_cursors_) {
-    XcursorImagesDestroy(
-        cursor.second.second);  // also frees individual frames.
-    XFreeCursor(gfx::GetXDisplay(), cursor.second.first);
-  }
-}
-
-void CursorLoaderX11::SetPlatformCursor(gfx::NativeCursor* cursor) {
-  DCHECK(cursor);
-
-  if (*cursor == mojom::CursorType::kNone) {
-    cursor->SetPlatformCursor(invisible_cursor_.get());
-    return;
-  }
-
-  if (*cursor == mojom::CursorType::kCustom)
-    return;
-
-  cursor->set_image_scale_factor(scale());
-  cursor->SetPlatformCursor(CursorFromId(cursor->type()));
-}
-
-const XcursorImage* CursorLoaderX11::GetXcursorImageForTest(
-    mojom::CursorType id) {
-  return test::GetCachedXcursorImage(image_cursors_[id]->cursor);
-}
-
-void CursorLoaderX11::OnCursorThemeNameChanged(
-    const std::string& cursor_theme_name) {
-  XcursorSetTheme(display_, cursor_theme_name.c_str());
-  ClearThemeCursors();
-}
-
-void CursorLoaderX11::OnCursorThemeSizeChanged(int cursor_theme_size) {
-  XcursorSetDefaultSize(display_, cursor_theme_size);
-  ClearThemeCursors();
-}
-
-bool CursorLoaderX11::IsImageCursor(gfx::NativeCursor native_cursor) {
-  mojom::CursorType type = native_cursor.type();
-  return image_cursors_.count(type) || animated_cursors_.count(type);
-}
-
-::Cursor CursorLoaderX11::CursorFromId(mojom::CursorType id) {
-  auto font_it = font_cursors_.find(id);
-  if (font_it != font_cursors_.end())
-    return font_it->second;
-  auto image_it = image_cursors_.find(id);
-  if (image_it != image_cursors_.end()) {
-    if (image_it->second->scale == scale() &&
-        image_it->second->rotation == rotation()) {
-      return image_it->second->cursor;
-    } else {
-      image_cursors_.erase(image_it);
-    }
-  }
-
-  // First try to load the cursor directly.
-  ::Cursor cursor = LoadCursorFromType(id);
-  if (cursor != x11::None) {
-    font_cursors_[id] = cursor;
-    return cursor;
-  }
-
-  // If the theme is missing the desired cursor, use a chromium-supplied
-  // fallback icon.
-  int resource_id;
-  gfx::Point point;
-  if (ui::GetCursorDataFor(ui::CursorSize::kNormal, id, scale(), &resource_id,
-                           &point)) {
-    LoadImageCursor(id, resource_id, point);
-    return image_cursors_[id]->cursor;
-  }
-
-  // As a last resort, return a left pointer.
-  cursor = XCreateFontCursor(display_, XC_left_ptr);
-  DCHECK(cursor);
-  font_cursors_[id] = cursor;
-  return cursor;
-}
-
-void CursorLoaderX11::ClearThemeCursors() {
-  font_cursors_.clear();
-  image_cursors_.clear();
-}
-
-}  // namespace ui
diff --git a/ui/base/cursor/cursor_loader_x11.h b/ui/base/cursor/cursor_loader_x11.h
deleted file mode 100644
index 3f618ebc..0000000
--- a/ui/base/cursor/cursor_loader_x11.h
+++ /dev/null
@@ -1,97 +0,0 @@
-// Copyright (c) 2012 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_CURSOR_LOADER_X11_H_
-#define UI_BASE_CURSOR_CURSOR_LOADER_X11_H_
-
-#include <map>
-#include <memory>
-#include <string>
-#include <utility>
-
-#include "base/component_export.h"
-#include "base/macros.h"
-#include "base/scoped_observer.h"
-#include "ui/base/cursor/cursor_loader.h"
-#include "ui/base/cursor/cursor_theme_manager.h"
-#include "ui/base/cursor/cursor_theme_manager_observer.h"
-#include "ui/base/cursor/mojom/cursor_type.mojom-forward.h"
-#include "ui/base/x/x11_util.h"
-#include "ui/display/display.h"
-#include "ui/gfx/x/x11.h"
-#include "ui/gfx/x/x11_types.h"
-
-namespace ui {
-
-class COMPONENT_EXPORT(UI_BASE_CURSOR) CursorLoaderX11
-    : public CursorLoader,
-      public CursorThemeManagerObserver {
- public:
-  CursorLoaderX11();
-  ~CursorLoaderX11() 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;
-
-  const XcursorImage* GetXcursorImageForTest(mojom::CursorType id);
-
- protected:
-  // CursorThemeManager:
-  void OnCursorThemeNameChanged(const std::string& cursor_theme_name) override;
-  void OnCursorThemeSizeChanged(int cursor_theme_size) override;
-
- private:
-  struct ImageCursor {
-    ImageCursor(XcursorImage* x_image,
-                float scale,
-                display::Display::Rotation rotation);
-    ~ImageCursor();
-
-    ::Cursor cursor;
-    float scale;
-    display::Display::Rotation rotation;
-  };
-
-  // Returns true if we have an image resource loaded for the |native_cursor|.
-  bool IsImageCursor(gfx::NativeCursor native_cursor);
-
-  // Loads a new cursor corresponding to |id|.
-  ::Cursor CursorFromId(mojom::CursorType id);
-
-  void ClearThemeCursors();
-
-  XDisplay* display_;
-
-  // A map from a cursor native type to X cursor.
-  std::map<mojom::CursorType, ::Cursor> font_cursors_;
-
-  // A map to hold all image cursors. It maps the cursor ID to the X Cursor, the
-  // display's scale factor, and the display's rotation.
-  std::map<mojom::CursorType, std::unique_ptr<ImageCursor>> image_cursors_;
-
-  // A map to hold all animated cursors. It maps the cursor ID to the pair of
-  // the X Cursor and the corresponding XcursorImages. We need a pointer to the
-  // images so that we can free them on destruction.
-  std::map<mojom::CursorType, std::pair<::Cursor, XcursorImages*>>
-      animated_cursors_;
-
-  const XScopedCursor invisible_cursor_;
-
-  ScopedObserver<CursorThemeManager, CursorThemeManagerObserver>
-      cursor_theme_observer_{this};
-
-  DISALLOW_COPY_AND_ASSIGN(CursorLoaderX11);
-};
-
-}  // namespace ui
-
-#endif  // UI_BASE_CURSOR_CURSOR_LOADER_X11_H_
diff --git a/ui/base/cursor/cursor_theme_manager.h b/ui/base/cursor/cursor_theme_manager.h
index b1948d3e..a6d09f0 100644
--- a/ui/base/cursor/cursor_theme_manager.h
+++ b/ui/base/cursor/cursor_theme_manager.h
@@ -7,13 +7,12 @@
 
 #include <string>
 
-#include "base/component_export.h"
 #include "base/observer_list.h"
 #include "ui/base/cursor/cursor_theme_manager_observer.h"
 
 namespace ui {
 
-class COMPONENT_EXPORT(UI_BASE_CURSOR) CursorThemeManager {
+class CursorThemeManager {
  public:
   CursorThemeManager(const CursorThemeManager&) = delete;
   CursorThemeManager& operator=(const CursorThemeManager&) = delete;
diff --git a/ui/base/cursor/cursor_theme_manager_observer.h b/ui/base/cursor/cursor_theme_manager_observer.h
index 37409ea..028a8bb 100644
--- a/ui/base/cursor/cursor_theme_manager_observer.h
+++ b/ui/base/cursor/cursor_theme_manager_observer.h
@@ -7,13 +7,11 @@
 
 #include <string>
 
-#include "base/component_export.h"
 #include "base/observer_list_types.h"
 
 namespace ui {
 
-class COMPONENT_EXPORT(UI_BASE_CURSOR) CursorThemeManagerObserver
-    : public base::CheckedObserver {
+class CursorThemeManagerObserver : public base::CheckedObserver {
  public:
   // |cursor_theme_name| will be nonempty.
   virtual void OnCursorThemeNameChanged(
diff --git a/ui/base/cursor/cursor_x11.cc b/ui/base/cursor/cursor_x11.cc
deleted file mode 100644
index edf6c9bb..0000000
--- a/ui/base/cursor/cursor_x11.cc
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright (c) 2012 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/x/x11_util.h"
-
-namespace ui {
-
-void Cursor::RefCustomCursor() {
-  if (platform_cursor_)
-    ui::RefCustomXCursor(platform_cursor_);
-}
-
-void Cursor::UnrefCustomCursor() {
-  if (platform_cursor_)
-    ui::UnrefCustomXCursor(platform_cursor_);
-}
-
-}  // namespace ui
diff --git a/ui/base/x/BUILD.gn b/ui/base/x/BUILD.gn
index cfdae7fd3..96f59fb 100644
--- a/ui/base/x/BUILD.gn
+++ b/ui/base/x/BUILD.gn
@@ -15,6 +15,10 @@
   sources = [
     "selection_utils.cc",
     "selection_utils.h",
+    "x11_cursor.cc",
+    "x11_cursor.h",
+    "x11_cursor_factory.cc",
+    "x11_cursor_factory.h",
     "x11_desktop_window_move_client.cc",
     "x11_desktop_window_move_client.h",
     "x11_display_manager.cc",
@@ -74,6 +78,8 @@
     "//ui/base:hit_test",
     "//ui/base:wm_role_names",
     "//ui/base/clipboard:clipboard_types",
+    "//ui/base/cursor:cursor_base",
+    "//ui/base/cursor:theme_manager",
     "//ui/base/cursor/mojom:cursor_type",
     "//ui/base/dragdrop/file_info",
     "//ui/display/util",
@@ -83,6 +89,7 @@
     "//ui/events/platform/x11",
     "//ui/events/x:x",
     "//ui/gfx",
+    "//ui/gfx/geometry",
     "//ui/gfx/x",
     "//ui/platform_window/common",
   ]
@@ -118,3 +125,14 @@
     "//ui/gfx/x",
   ]
 }
+
+source_set("unittests") {
+  testonly = true
+  sources = [ "x11_cursor_factory_unittest.cc" ]
+  deps = [
+    ":x",
+    "//skia",
+    "//testing/gtest",
+    "//ui/gfx/geometry",
+  ]
+}
diff --git a/ui/ozone/platform/x11/x11_cursor_ozone.cc b/ui/base/x/x11_cursor.cc
similarity index 64%
rename from ui/ozone/platform/x11/x11_cursor_ozone.cc
rename to ui/base/x/x11_cursor.cc
index dca5fed1..9d55c5d 100644
--- a/ui/ozone/platform/x11/x11_cursor_ozone.cc
+++ b/ui/base/x/x11_cursor.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "ui/ozone/platform/x11/x11_cursor_ozone.h"
+#include "ui/base/x/x11_cursor.h"
 
 #include "base/check_op.h"
 #include "third_party/skia/include/core/SkBitmap.h"
@@ -11,16 +11,15 @@
 
 namespace ui {
 
-X11CursorOzone::X11CursorOzone(const SkBitmap& bitmap,
-                               const gfx::Point& hotspot) {
+X11Cursor::X11Cursor(const SkBitmap& bitmap, const gfx::Point& hotspot) {
   XcursorImage* image = SkBitmapToXcursorImage(bitmap, hotspot);
   xcursor_ = XcursorImageLoadCursor(gfx::GetXDisplay(), image);
   XcursorImageDestroy(image);
 }
 
-X11CursorOzone::X11CursorOzone(const std::vector<SkBitmap>& bitmaps,
-                               const gfx::Point& hotspot,
-                               int frame_delay_ms) {
+X11Cursor::X11Cursor(const std::vector<SkBitmap>& bitmaps,
+                     const gfx::Point& hotspot,
+                     int frame_delay_ms) {
   // Initialize an XCursorImage for each frame, store all of them in
   // XCursorImages and load the cursor from that.
   XcursorImages* images = XcursorImagesCreate(bitmaps.size());
@@ -35,14 +34,14 @@
   XcursorImagesDestroy(images);
 }
 
-X11CursorOzone::X11CursorOzone(::Cursor xcursor) : xcursor_(xcursor) {}
+X11Cursor::X11Cursor(::Cursor xcursor) : xcursor_(xcursor) {}
 
 // static
-scoped_refptr<X11CursorOzone> X11CursorOzone::CreateInvisible() {
-  return base::MakeRefCounted<X11CursorOzone>(CreateInvisibleCursor());
+scoped_refptr<X11Cursor> X11Cursor::CreateInvisible() {
+  return base::MakeRefCounted<X11Cursor>(CreateInvisibleCursor());
 }
 
-X11CursorOzone::~X11CursorOzone() {
+X11Cursor::~X11Cursor() {
   XFreeCursor(gfx::GetXDisplay(), xcursor_);
 }
 
diff --git a/ui/base/x/x11_cursor.h b/ui/base/x/x11_cursor.h
new file mode 100644
index 0000000..1711b94
--- /dev/null
+++ b/ui/base/x/x11_cursor.h
@@ -0,0 +1,55 @@
+// Copyright 2016 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_X_X11_CURSOR_H_
+#define UI_BASE_X_X11_CURSOR_H_
+
+#include <vector>
+
+#include "base/component_export.h"
+#include "base/memory/ref_counted.h"
+#include "base/memory/scoped_refptr.h"
+#include "ui/gfx/x/x11.h"
+
+class SkBitmap;
+
+namespace gfx {
+class Point;
+}
+
+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> {
+ public:
+  REQUIRE_ADOPTION_FOR_REFCOUNTED_TYPE();
+
+  // Handles creating X11 cursor resources from SkBitmap/hotspot.
+  X11Cursor(const SkBitmap& bitmap, const gfx::Point& hotspot);
+  X11Cursor(const X11Cursor&) = delete;
+  X11Cursor& operator=(const X11Cursor&) = delete;
+  X11Cursor(const std::vector<SkBitmap>& bitmaps,
+            const gfx::Point& hotspot,
+            int frame_delay_ms);
+  // Wraps an X11 cursor |xcursor|.
+  explicit X11Cursor(::Cursor xcursor);
+
+  // Creates a new cursor that is invisible.
+  static scoped_refptr<X11Cursor> CreateInvisible();
+
+  ::Cursor xcursor() const { return xcursor_; }
+
+ private:
+  friend class base::RefCounted<X11Cursor>;
+
+  ~X11Cursor();
+
+  ::Cursor xcursor_ = x11::None;
+};
+
+}  // namespace ui
+
+#endif  // UI_BASE_X_X11_CURSOR_H_
diff --git a/ui/base/x/x11_cursor_factory.cc b/ui/base/x/x11_cursor_factory.cc
new file mode 100644
index 0000000..f706072
--- /dev/null
+++ b/ui/base/x/x11_cursor_factory.cc
@@ -0,0 +1,114 @@
+// Copyright 2016 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/x/x11_cursor_factory.h"
+
+#include "third_party/skia/include/core/SkBitmap.h"
+#include "ui/base/cursor/mojom/cursor_type.mojom-shared.h"
+#include "ui/base/x/x11_cursor.h"
+#include "ui/base/x/x11_util.h"
+#include "ui/gfx/geometry/point.h"
+#include "ui/gfx/x/x11.h"
+
+namespace ui {
+
+namespace {
+
+X11Cursor* ToX11Cursor(PlatformCursor cursor) {
+  return static_cast<X11Cursor*>(cursor);
+}
+
+PlatformCursor ToPlatformCursor(X11Cursor* cursor) {
+  return static_cast<PlatformCursor>(cursor);
+}
+
+}  // namespace
+
+X11CursorFactory::X11CursorFactory()
+    : invisible_cursor_(X11Cursor::CreateInvisible()) {}
+
+X11CursorFactory::~X11CursorFactory() = default;
+
+PlatformCursor X11CursorFactory::GetDefaultCursor(mojom::CursorType type) {
+  return ToPlatformCursor(GetDefaultCursorInternal(type).get());
+}
+
+PlatformCursor X11CursorFactory::CreateImageCursor(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 |invisible_cursor_| 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 |invisible_cursor_| being freed out from
+    // under us.
+    invisible_cursor_->AddRef();
+    return ToPlatformCursor(invisible_cursor_.get());
+  }
+
+  auto cursor = base::MakeRefCounted<X11Cursor>(bitmap, hotspot);
+  cursor->AddRef();
+  return ToPlatformCursor(cursor.get());
+}
+
+PlatformCursor X11CursorFactory::CreateAnimatedCursor(
+    const std::vector<SkBitmap>& bitmaps,
+    const gfx::Point& hotspot,
+    int frame_delay_ms) {
+  auto cursor =
+      base::MakeRefCounted<X11Cursor>(bitmaps, hotspot, frame_delay_ms);
+  cursor->AddRef();
+  return ToPlatformCursor(cursor.get());
+}
+
+void X11CursorFactory::RefImageCursor(PlatformCursor cursor) {
+  ToX11Cursor(cursor)->AddRef();
+}
+
+void X11CursorFactory::UnrefImageCursor(PlatformCursor cursor) {
+  ToX11Cursor(cursor)->Release();
+}
+
+void X11CursorFactory::ObserveThemeChanges() {
+  auto* cursor_theme_manager = CursorThemeManager::GetInstance();
+  if (cursor_theme_manager)
+    cursor_theme_observer_.Add(cursor_theme_manager);
+}
+
+void X11CursorFactory::OnCursorThemeNameChanged(
+    const std::string& cursor_theme_name) {
+  XcursorSetTheme(gfx::GetXDisplay(), cursor_theme_name.c_str());
+  ClearThemeCursors();
+}
+
+void X11CursorFactory::OnCursorThemeSizeChanged(int cursor_theme_size) {
+  XcursorSetDefaultSize(gfx::GetXDisplay(), cursor_theme_size);
+  ClearThemeCursors();
+}
+
+scoped_refptr<X11Cursor> X11CursorFactory::GetDefaultCursorInternal(
+    mojom::CursorType type) {
+  if (type == mojom::CursorType::kNone)
+    return invisible_cursor_;
+
+  if (!default_cursors_.count(type)) {
+    // Try to load a predefined X11 cursor.
+    ::Cursor xcursor = LoadCursorFromType(type);
+    if (xcursor == x11::None)
+      return nullptr;
+    auto cursor = base::MakeRefCounted<X11Cursor>(xcursor);
+    default_cursors_[type] = cursor;
+  }
+
+  // Returns owned default cursor for this type.
+  return default_cursors_[type];
+}
+
+void X11CursorFactory::ClearThemeCursors() {
+  default_cursors_.clear();
+}
+
+}  // namespace ui
diff --git a/ui/ozone/platform/x11/x11_cursor_factory_ozone.h b/ui/base/x/x11_cursor_factory.h
similarity index 67%
rename from ui/ozone/platform/x11/x11_cursor_factory_ozone.h
rename to ui/base/x/x11_cursor_factory.h
index 355d794..e741147 100644
--- a/ui/ozone/platform/x11/x11_cursor_factory_ozone.h
+++ b/ui/base/x/x11_cursor_factory.h
@@ -2,31 +2,33 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef UI_OZONE_PLATFORM_X11_X11_CURSOR_FACTORY_OZONE_H_
-#define UI_OZONE_PLATFORM_X11_X11_CURSOR_FACTORY_OZONE_H_
+#ifndef UI_BASE_X_X11_CURSOR_FACTORY_H_
+#define UI_BASE_X_X11_CURSOR_FACTORY_H_
 
 #include <map>
-#include <memory>
+#include <string>
 #include <vector>
 
-#include "base/macros.h"
+#include "base/component_export.h"
+#include "base/memory/scoped_refptr.h"
 #include "base/scoped_observer.h"
-#include "ui/base/cursor/cursor.h"
 #include "ui/base/cursor/cursor_factory.h"
 #include "ui/base/cursor/cursor_theme_manager.h"
 #include "ui/base/cursor/cursor_theme_manager_observer.h"
 #include "ui/base/cursor/mojom/cursor_type.mojom-forward.h"
-#include "ui/gfx/x/x11.h"
 
 namespace ui {
-class X11CursorOzone;
+class X11Cursor;
 
 // CursorFactoryOzone implementation for X11 cursors.
-class X11CursorFactoryOzone : public CursorFactory,
-                              public CursorThemeManagerObserver {
+class COMPONENT_EXPORT(UI_BASE_X) X11CursorFactory
+    : public CursorFactory,
+      public CursorThemeManagerObserver {
  public:
-  X11CursorFactoryOzone();
-  ~X11CursorFactoryOzone() override;
+  X11CursorFactory();
+  X11CursorFactory(const X11CursorFactory&) = delete;
+  X11CursorFactory& operator=(const X11CursorFactory&) = delete;
+  ~X11CursorFactory() override;
 
   // CursorFactoryOzone:
   PlatformCursor GetDefaultCursor(mojom::CursorType type) override;
@@ -47,21 +49,18 @@
   void ClearThemeCursors();
 
   // Loads/caches default cursor or returns cached version.
-  scoped_refptr<X11CursorOzone> GetDefaultCursorInternal(
-      mojom::CursorType type);
+  scoped_refptr<X11Cursor> GetDefaultCursorInternal(mojom::CursorType type);
 
   // Holds a single instance of the invisible cursor. X11 has no way to hide
   // the cursor so an invisible cursor mimics that.
-  scoped_refptr<X11CursorOzone> invisible_cursor_;
+  scoped_refptr<X11Cursor> invisible_cursor_;
 
-  std::map<mojom::CursorType, scoped_refptr<X11CursorOzone>> default_cursors_;
+  std::map<mojom::CursorType, scoped_refptr<X11Cursor>> default_cursors_;
 
   ScopedObserver<CursorThemeManager, CursorThemeManagerObserver>
       cursor_theme_observer_{this};
-
-  DISALLOW_COPY_AND_ASSIGN(X11CursorFactoryOzone);
 };
 
 }  // namespace ui
 
-#endif  // UI_OZONE_PLATFORM_X11_X11_CURSOR_FACTORY_OZONE_H_
+#endif  // UI_BASE_X_X11_CURSOR_FACTORY_H_
diff --git a/ui/ozone/platform/x11/x11_cursor_factory_ozone_unittest.cc b/ui/base/x/x11_cursor_factory_unittest.cc
similarity index 77%
rename from ui/ozone/platform/x11/x11_cursor_factory_ozone_unittest.cc
rename to ui/base/x/x11_cursor_factory_unittest.cc
index 7cb63f1..8c317fba 100644
--- a/ui/ozone/platform/x11/x11_cursor_factory_ozone_unittest.cc
+++ b/ui/base/x/x11_cursor_factory_unittest.cc
@@ -2,23 +2,23 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "ui/ozone/platform/x11/x11_cursor_factory_ozone.h"
+#include "ui/base/x/x11_cursor_factory.h"
 
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/skia/include/core/SkBitmap.h"
+#include "ui/base/x/x11_cursor.h"
 #include "ui/gfx/geometry/point.h"
-#include "ui/ozone/platform/x11/x11_cursor_ozone.h"
 
 namespace ui {
 
-TEST(X11CursorFactoryOzoneTest, InvisibleRefcount) {
-  X11CursorFactoryOzone factory;
+TEST(X11CursorFactoryTest, InvisibleRefcount) {
+  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<X11CursorOzone*>(
+  auto* invisible_cursor = static_cast<X11Cursor*>(
       factory.CreateImageCursor(SkBitmap(), gfx::Point()));
   ASSERT_FALSE(invisible_cursor->HasOneRef());
 
diff --git a/ui/gtk/BUILD.gn b/ui/gtk/BUILD.gn
index d849743..02e12b9 100644
--- a/ui/gtk/BUILD.gn
+++ b/ui/gtk/BUILD.gn
@@ -76,6 +76,7 @@
     "//ui/aura",
     "//ui/base",
     "//ui/base:buildflags",
+    "//ui/base/cursor:theme_manager",
     "//ui/base/ime",
     "//ui/base/ime/linux",
     "//ui/display",
diff --git a/ui/ozone/platform/x11/BUILD.gn b/ui/ozone/platform/x11/BUILD.gn
index 7f03799..35b64eb 100644
--- a/ui/ozone/platform/x11/BUILD.gn
+++ b/ui/ozone/platform/x11/BUILD.gn
@@ -24,23 +24,12 @@
     "x11_canvas_surface.h",
     "x11_clipboard_ozone.cc",
     "x11_clipboard_ozone.h",
-    "x11_cursor_factory_ozone.cc",
-    "x11_cursor_factory_ozone.h",
-    "x11_cursor_ozone.cc",
-    "x11_cursor_ozone.h",
     "x11_screen_ozone.cc",
     "x11_screen_ozone.h",
     "x11_surface_factory.cc",
     "x11_surface_factory.h",
   ]
 
-  public_deps = [
-    "//ui/base/cursor",
-    "//ui/base/cursor:cursor_base",
-    "//ui/base/cursor/mojom:cursor_type",
-    "//ui/base/x",
-  ]
-
   deps = [
     "//base",
     "//build:chromecast_buildflags",
@@ -50,8 +39,9 @@
     "//ui/base:buildflags",
     "//ui/base:data_exchange",
     "//ui/base/clipboard:clipboard_types",
-    "//ui/base/cursor",
+    "//ui/base/cursor:cursor_base",
     "//ui/base/ime",
+    "//ui/base/x",
     "//ui/base/x:gl",
     "//ui/display/fake",
     "//ui/events",
@@ -73,17 +63,11 @@
   ]
 
   if (is_chromeos) {
-    sources += [
-      "x11_window_ozone_chromeos.cc",
-      "x11_window_ozone_chromeos.h",
-    ]
     deps += [ "//ui/base/ime/chromeos" ]
   } else {
     sources += [
       "x11_os_exchange_data_provider_ozone.cc",
       "x11_os_exchange_data_provider_ozone.h",
-      "x11_window_ozone.cc",
-      "x11_window_ozone.h",
     ]
     deps += [ "//ui/base/ime/linux" ]
   }
@@ -106,7 +90,6 @@
 source_set("x11_unittests") {
   testonly = true
   sources = [
-    "x11_cursor_factory_ozone_unittest.cc",
     "x11_screen_ozone_unittest.cc",
     "x11_window_ozone_unittest.cc",
   ]
diff --git a/ui/ozone/platform/x11/ozone_platform_x11.cc b/ui/ozone/platform/x11/ozone_platform_x11.cc
index a058a54c..394ef374c 100644
--- a/ui/ozone/platform/x11/ozone_platform_x11.cc
+++ b/ui/ozone/platform/x11/ozone_platform_x11.cc
@@ -14,6 +14,7 @@
 #include "ui/base/cursor/cursor_factory.h"
 #include "ui/base/dragdrop/os_exchange_data_provider_factory.h"
 #include "ui/base/dragdrop/os_exchange_data_provider_factory_ozone.h"
+#include "ui/base/x/x11_cursor_factory.h"
 #include "ui/base/x/x11_error_handler.h"
 #include "ui/base/x/x11_util.h"
 #include "ui/display/fake/fake_display_delegate.h"
@@ -26,16 +27,15 @@
 #include "ui/ozone/common/stub_overlay_manager.h"
 #include "ui/ozone/platform/x11/gl_egl_utility_x11.h"
 #include "ui/ozone/platform/x11/x11_clipboard_ozone.h"
-#include "ui/ozone/platform/x11/x11_cursor_factory_ozone.h"
 #include "ui/ozone/platform/x11/x11_screen_ozone.h"
 #include "ui/ozone/platform/x11/x11_surface_factory.h"
-#include "ui/ozone/platform/x11/x11_window_ozone.h"
 #include "ui/ozone/public/gpu_platform_support_host.h"
 #include "ui/ozone/public/input_controller.h"
 #include "ui/ozone/public/ozone_platform.h"
 #include "ui/ozone/public/system_input_injector.h"
 #include "ui/platform_window/platform_window.h"
 #include "ui/platform_window/platform_window_init_properties.h"
+#include "ui/platform_window/x11/x11_window.h"
 
 #if defined(OS_CHROMEOS)
 #include "ui/base/dragdrop/os_exchange_data_provider_non_backed.h"
@@ -107,8 +107,7 @@
   std::unique_ptr<PlatformWindow> CreatePlatformWindow(
       PlatformWindowDelegate* delegate,
       PlatformWindowInitProperties properties) override {
-    std::unique_ptr<X11WindowOzone> window =
-        std::make_unique<X11WindowOzone>(delegate);
+    auto window = std::make_unique<X11Window>(delegate);
     window->Initialize(std::move(properties));
     window->SetTitle(base::ASCIIToUTF16("Ozone X11"));
     return std::move(window);
@@ -167,7 +166,7 @@
     overlay_manager_ = std::make_unique<StubOverlayManager>();
     input_controller_ = CreateStubInputController();
     clipboard_ = std::make_unique<X11ClipboardOzone>();
-    cursor_factory_ = std::make_unique<X11CursorFactoryOzone>();
+    cursor_factory_ = std::make_unique<X11CursorFactory>();
     gpu_platform_support_host_.reset(CreateStubGpuPlatformSupportHost());
 
 #if BUILDFLAG(USE_XKBCOMMON)
diff --git a/ui/ozone/platform/x11/x11_cursor_factory_ozone.cc b/ui/ozone/platform/x11/x11_cursor_factory_ozone.cc
deleted file mode 100644
index 1850966e..0000000
--- a/ui/ozone/platform/x11/x11_cursor_factory_ozone.cc
+++ /dev/null
@@ -1,114 +0,0 @@
-// Copyright 2016 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/ozone/platform/x11/x11_cursor_factory_ozone.h"
-
-#include "third_party/skia/include/core/SkBitmap.h"
-#include "ui/base/cursor/mojom/cursor_type.mojom-shared.h"
-#include "ui/base/x/x11_util.h"
-#include "ui/gfx/geometry/point.h"
-#include "ui/gfx/x/x11.h"
-#include "ui/ozone/platform/x11/x11_cursor_ozone.h"
-
-namespace ui {
-
-namespace {
-
-X11CursorOzone* ToX11CursorOzone(PlatformCursor cursor) {
-  return static_cast<X11CursorOzone*>(cursor);
-}
-
-PlatformCursor ToPlatformCursor(X11CursorOzone* cursor) {
-  return static_cast<PlatformCursor>(cursor);
-}
-
-}  // namespace
-
-X11CursorFactoryOzone::X11CursorFactoryOzone()
-    : invisible_cursor_(X11CursorOzone::CreateInvisible()) {}
-
-X11CursorFactoryOzone::~X11CursorFactoryOzone() {}
-
-PlatformCursor X11CursorFactoryOzone::GetDefaultCursor(mojom::CursorType type) {
-  return ToPlatformCursor(GetDefaultCursorInternal(type).get());
-}
-
-PlatformCursor X11CursorFactoryOzone::CreateImageCursor(
-    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 |invisible_cursor_| 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 |invisible_cursor_| being freed out from
-    // under us.
-    invisible_cursor_->AddRef();
-    return ToPlatformCursor(invisible_cursor_.get());
-  }
-
-  X11CursorOzone* cursor = new X11CursorOzone(bitmap, hotspot);
-  cursor->AddRef();
-  return ToPlatformCursor(cursor);
-}
-
-PlatformCursor X11CursorFactoryOzone::CreateAnimatedCursor(
-    const std::vector<SkBitmap>& bitmaps,
-    const gfx::Point& hotspot,
-    int frame_delay_ms) {
-  X11CursorOzone* cursor = new X11CursorOzone(bitmaps, hotspot, frame_delay_ms);
-  cursor->AddRef();
-  return ToPlatformCursor(cursor);
-}
-
-void X11CursorFactoryOzone::RefImageCursor(PlatformCursor cursor) {
-  ToX11CursorOzone(cursor)->AddRef();
-}
-
-void X11CursorFactoryOzone::UnrefImageCursor(PlatformCursor cursor) {
-  ToX11CursorOzone(cursor)->Release();
-}
-
-void X11CursorFactoryOzone::ObserveThemeChanges() {
-  auto* cursor_theme_manager = CursorThemeManager::GetInstance();
-  if (cursor_theme_manager)
-    cursor_theme_observer_.Add(cursor_theme_manager);
-}
-
-void X11CursorFactoryOzone::OnCursorThemeNameChanged(
-    const std::string& cursor_theme_name) {
-  XcursorSetTheme(gfx::GetXDisplay(), cursor_theme_name.c_str());
-  ClearThemeCursors();
-}
-
-void X11CursorFactoryOzone::OnCursorThemeSizeChanged(int cursor_theme_size) {
-  XcursorSetDefaultSize(gfx::GetXDisplay(), cursor_theme_size);
-  ClearThemeCursors();
-}
-
-scoped_refptr<X11CursorOzone> X11CursorFactoryOzone::GetDefaultCursorInternal(
-    mojom::CursorType type) {
-  if (type == mojom::CursorType::kNone)
-    return invisible_cursor_;
-
-  if (!default_cursors_.count(type)) {
-    // Try to load a predefined X11 cursor.
-    ::Cursor xcursor = LoadCursorFromType(type);
-    if (xcursor == x11::None)
-      return nullptr;
-    auto cursor = base::MakeRefCounted<X11CursorOzone>(xcursor);
-    default_cursors_[type] = cursor;
-  }
-
-  // Returns owned default cursor for this type.
-  return default_cursors_[type];
-}
-
-void X11CursorFactoryOzone::ClearThemeCursors() {
-  default_cursors_.clear();
-}
-
-}  // namespace ui
diff --git a/ui/ozone/platform/x11/x11_cursor_ozone.h b/ui/ozone/platform/x11/x11_cursor_ozone.h
deleted file mode 100644
index fc4fddf..0000000
--- a/ui/ozone/platform/x11/x11_cursor_ozone.h
+++ /dev/null
@@ -1,53 +0,0 @@
-// Copyright 2016 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_X11_X11_CURSOR_OZONE_H_
-#define UI_OZONE_PLATFORM_X11_X11_CURSOR_OZONE_H_
-
-#include <vector>
-
-#include "base/macros.h"
-#include "base/memory/ref_counted.h"
-#include "base/memory/scoped_refptr.h"
-#include "ui/base/cursor/cursor.h"
-#include "ui/gfx/x/x11.h"
-
-class SkBitmap;
-
-namespace gfx {
-class Point;
-}
-
-namespace ui {
-
-// Ref counted class to hold an X11 cursor resource.  Clears the X11 resources
-// on destruction
-class X11CursorOzone : public base::RefCounted<X11CursorOzone> {
- public:
-  // Handles creating X11 cursor resources from SkBitmap/hotspot.
-  X11CursorOzone(const SkBitmap& bitmap, const gfx::Point& hotspot);
-  X11CursorOzone(const std::vector<SkBitmap>& bitmaps,
-                 const gfx::Point& hotspot,
-                 int frame_delay_ms);
-  // Wraps an X11 cursor |xcursor|.
-  explicit X11CursorOzone(::Cursor xcursor);
-
-  // Creates a new cursor that is invisible.
-  static scoped_refptr<X11CursorOzone> CreateInvisible();
-
-  ::Cursor xcursor() const { return xcursor_; }
-
- private:
-  friend class base::RefCounted<X11CursorOzone>;
-
-  ~X11CursorOzone();
-
-  ::Cursor xcursor_ = x11::None;
-
-  DISALLOW_COPY_AND_ASSIGN(X11CursorOzone);
-};
-
-}  // namespace ui
-
-#endif  // UI_OZONE_PLATFORM_X11_X11_CURSOR_OZONE_H_
diff --git a/ui/ozone/platform/x11/x11_screen_ozone.cc b/ui/ozone/platform/x11/x11_screen_ozone.cc
index 5e31ef8..76aeb9e 100644
--- a/ui/ozone/platform/x11/x11_screen_ozone.cc
+++ b/ui/ozone/platform/x11/x11_screen_ozone.cc
@@ -11,8 +11,8 @@
 #include "ui/gfx/font_render_params.h"
 #include "ui/gfx/geometry/dip_util.h"
 #include "ui/gfx/native_widget_types.h"
-#include "ui/ozone/platform/x11/x11_window_ozone.h"
 #include "ui/platform_window/x11/x11_topmost_window_finder.h"
+#include "ui/platform_window/x11/x11_window.h"
 #include "ui/platform_window/x11/x11_window_manager.h"
 
 namespace ui {
diff --git a/ui/ozone/platform/x11/x11_screen_ozone_unittest.cc b/ui/ozone/platform/x11/x11_screen_ozone_unittest.cc
index 121a6cc..5b2ac245 100644
--- a/ui/ozone/platform/x11/x11_screen_ozone_unittest.cc
+++ b/ui/ozone/platform/x11/x11_screen_ozone_unittest.cc
@@ -13,10 +13,10 @@
 #include "ui/display/display.h"
 #include "ui/display/display_observer.h"
 #include "ui/events/platform/x11/x11_event_source.h"
-#include "ui/ozone/platform/x11/x11_window_ozone.h"
 #include "ui/ozone/test/mock_platform_window_delegate.h"
 #include "ui/platform_window/platform_window_delegate.h"
 #include "ui/platform_window/platform_window_init_properties.h"
+#include "ui/platform_window/x11/x11_window.h"
 #include "ui/platform_window/x11/x11_window_manager.h"
 
 using ::testing::_;
@@ -95,14 +95,14 @@
                                                     manager->displays_);
   }
 
-  std::unique_ptr<X11WindowOzone> CreatePlatformWindow(
+  std::unique_ptr<X11Window> CreatePlatformWindow(
       MockPlatformWindowDelegate* delegate,
       const gfx::Rect& bounds,
       gfx::AcceleratedWidget* widget = nullptr) {
     EXPECT_CALL(*delegate, OnAcceleratedWidgetAvailable(_))
         .WillOnce(StoreWidget(widget));
     PlatformWindowInitProperties init_params(bounds);
-    auto window = std::make_unique<X11WindowOzone>(delegate);
+    auto window = std::make_unique<X11Window>(delegate);
     window->Initialize(std::move(init_params));
     return window;
   }
diff --git a/ui/ozone/platform/x11/x11_window_ozone.cc b/ui/ozone/platform/x11/x11_window_ozone.cc
deleted file mode 100644
index 99e323d6e..0000000
--- a/ui/ozone/platform/x11/x11_window_ozone.cc
+++ /dev/null
@@ -1,22 +0,0 @@
-// Copyright 2020 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/ozone/platform/x11/x11_window_ozone.h"
-
-#include "ui/ozone/platform/x11/x11_cursor_ozone.h"
-#include "ui/platform_window/platform_window_delegate.h"
-
-namespace ui {
-
-X11WindowOzone::X11WindowOzone(PlatformWindowDelegate* delegate)
-    : X11Window(delegate) {}
-
-X11WindowOzone::~X11WindowOzone() = default;
-
-void X11WindowOzone::SetCursor(PlatformCursor cursor) {
-  X11CursorOzone* cursor_ozone = static_cast<X11CursorOzone*>(cursor);
-  XWindow::SetCursor(cursor_ozone->xcursor());
-}
-
-}  // namespace ui
diff --git a/ui/ozone/platform/x11/x11_window_ozone.h b/ui/ozone/platform/x11/x11_window_ozone.h
deleted file mode 100644
index fcf4e67..0000000
--- a/ui/ozone/platform/x11/x11_window_ozone.h
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright 2020 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_X11_X11_WINDOW_OZONE_H_
-#define UI_OZONE_PLATFORM_X11_X11_WINDOW_OZONE_H_
-
-#include "ui/platform_window/x11/x11_window.h"
-
-namespace ui {
-
-class PlatformWindowDelegate;
-
-// PlatformWindow implementation for non-ChromeOS X11 Ozone.
-// PlatformEvents are ui::Events.
-class X11WindowOzone : public X11Window {
- public:
-  explicit X11WindowOzone(PlatformWindowDelegate* delegate);
-  ~X11WindowOzone() override;
-
-  X11WindowOzone(const X11WindowOzone&) = delete;
-  X11WindowOzone& operator=(const X11WindowOzone&) = delete;
-
-  // Overridden from PlatformWindow:
-  void SetCursor(PlatformCursor cursor) override;
-};
-
-}  // namespace ui
-
-#endif  // UI_OZONE_PLATFORM_X11_X11_WINDOW_OZONE_H_
diff --git a/ui/ozone/platform/x11/x11_window_ozone_chromeos.cc b/ui/ozone/platform/x11/x11_window_ozone_chromeos.cc
deleted file mode 100644
index d4f22451..0000000
--- a/ui/ozone/platform/x11/x11_window_ozone_chromeos.cc
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright 2016 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/ozone/platform/x11/x11_window_ozone_chromeos.h"
-
-#include "ui/events/event.h"
-#include "ui/ozone/platform/x11/x11_cursor_ozone.h"
-#include "ui/platform_window/platform_window_delegate.h"
-#include "ui/platform_window/x11/x11_window_manager.h"
-
-namespace ui {
-
-X11WindowOzone::X11WindowOzone(PlatformWindowDelegate* delegate)
-    : X11Window(delegate) {}
-
-X11WindowOzone::~X11WindowOzone() = default;
-
-void X11WindowOzone::SetCursor(PlatformCursor cursor) {
-  X11CursorOzone* cursor_ozone = static_cast<X11CursorOzone*>(cursor);
-  XWindow::SetCursor(cursor_ozone->xcursor());
-}
-
-void X11WindowOzone::Initialize(PlatformWindowInitProperties properties) {
-  X11Window::Initialize(std::move(properties));
-}
-
-}  // namespace ui
diff --git a/ui/ozone/platform/x11/x11_window_ozone_chromeos.h b/ui/ozone/platform/x11/x11_window_ozone_chromeos.h
deleted file mode 100644
index 3bcdec5..0000000
--- a/ui/ozone/platform/x11/x11_window_ozone_chromeos.h
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright 2016 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_X11_X11_WINDOW_OZONE_CHROMEOS_H_
-#define UI_OZONE_PLATFORM_X11_X11_WINDOW_OZONE_CHROMEOS_H_
-
-#include "base/macros.h"
-#include "ui/platform_window/x11/x11_window.h"
-
-namespace ui {
-
-class PlatformWindowDelegate;
-
-// PlatformWindow implementation for ChromeOS X11 Ozone.
-// PlatformEvents are ui::Events.
-class X11WindowOzone : public X11Window {
- public:
-  explicit X11WindowOzone(PlatformWindowDelegate* delegate);
-  ~X11WindowOzone() override;
-
-  // Overridden from PlatformWindow:
-  void SetCursor(PlatformCursor cursor) override;
-
-  // Overridden from X11Window:
-  void Initialize(PlatformWindowInitProperties properties) override;
-
-  DISALLOW_COPY_AND_ASSIGN(X11WindowOzone);
-};
-
-}  // namespace ui
-
-#endif  // UI_OZONE_PLATFORM_X11_X11_WINDOW_OZONE_CHROMEOS_H_
diff --git a/ui/ozone/platform/x11/x11_window_ozone_unittest.cc b/ui/ozone/platform/x11/x11_window_ozone_unittest.cc
index 0b415cde..ddf6448 100644
--- a/ui/ozone/platform/x11/x11_window_ozone_unittest.cc
+++ b/ui/ozone/platform/x11/x11_window_ozone_unittest.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "ui/ozone/platform/x11/x11_window_ozone.h"
+#include "ui/platform_window/x11/x11_window.h"
 
 #include <memory>
 #include <utility>
@@ -87,7 +87,7 @@
     EXPECT_CALL(*delegate, OnAcceleratedWidgetAvailable(_))
         .WillOnce(StoreWidget(widget));
     PlatformWindowInitProperties init_params(bounds);
-    auto window = std::make_unique<X11WindowOzone>(delegate);
+    auto window = std::make_unique<X11Window>(delegate);
     window->Initialize(std::move(init_params));
     return std::move(window);
   }
@@ -187,8 +187,8 @@
   EXPECT_EQ(gfx::Point(-277, 215), event->AsLocatedEvent()->location());
 }
 
-// This test case ensures window_manager properly provides X11WindowOzone
-// instances as they are created/destroyed.
+// This test case ensures window_manager properly provides X11Window instances
+// as they are created/destroyed.
 TEST_F(X11WindowOzoneTest, GetWindowFromAcceleratedWigets) {
   MockPlatformWindowDelegate delegate;
   gfx::Rect bounds(0, 0, 100, 100);
@@ -226,12 +226,12 @@
   auto window_2 = CreatePlatformWindow(&delegate_2, bounds_2, &widget_2);
 
   EXPECT_CALL(delegate_1, OnMouseEnter()).Times(1);
-  window_manager()->MouseOnWindow(static_cast<X11WindowOzone*>(window_1.get()));
+  window_manager()->MouseOnWindow(static_cast<X11Window*>(window_1.get()));
   // The mouse is already on window_1, and this should not call OnMouseEnter.
-  window_manager()->MouseOnWindow(static_cast<X11WindowOzone*>(window_1.get()));
+  window_manager()->MouseOnWindow(static_cast<X11Window*>(window_1.get()));
 
   EXPECT_CALL(delegate_2, OnMouseEnter()).Times(1);
-  window_manager()->MouseOnWindow(static_cast<X11WindowOzone*>(window_2.get()));
+  window_manager()->MouseOnWindow(static_cast<X11Window*>(window_2.get()));
 
   EXPECT_EQ(window_2.get(),
             window_manager()->window_mouse_currently_on_for_test());
diff --git a/ui/platform_window/x11/x11_window.cc b/ui/platform_window/x11/x11_window.cc
index 5490580..bc2c182 100644
--- a/ui/platform_window/x11/x11_window.cc
+++ b/ui/platform_window/x11/x11_window.cc
@@ -7,6 +7,7 @@
 #include "base/strings/string_number_conversions.h"
 #include "base/trace_event/trace_event.h"
 #include "ui/base/buildflags.h"
+#include "ui/base/x/x11_cursor.h"
 #include "ui/base/x/x11_desktop_window_move_client.h"
 #include "ui/base/x/x11_util.h"
 #include "ui/base/x/x11_util_internal.h"
@@ -389,11 +390,7 @@
 }
 
 void X11Window::SetCursor(PlatformCursor cursor) {
-  // X11PlatformWindowOzone has different type of PlatformCursor. Thus, use this
-  // only for X11 and Ozone will manage this by itself.
-#if defined(USE_X11)
-  XWindow::SetCursor(cursor);
-#endif
+  XWindow::SetCursor(static_cast<X11Cursor*>(cursor)->xcursor());
 }
 
 void X11Window::MoveCursorTo(const gfx::Point& location) {
diff --git a/ui/views/BUILD.gn b/ui/views/BUILD.gn
index e10dcb0..ae6aff3 100644
--- a/ui/views/BUILD.gn
+++ b/ui/views/BUILD.gn
@@ -529,7 +529,7 @@
 
   if (is_linux && !is_chromeos) {
     sources -= [ "window/window_button_order_provider.cc" ]
-    public_deps += [ "//ui/base/cursor" ]
+    public_deps += [ "//ui/base/cursor:theme_manager" ]
     deps += [
       "//ui/base/ime/linux",
       "//ui/shell_dialogs",
diff --git a/ui/views/widget/desktop_aura/desktop_drag_drop_client_aurax11.cc b/ui/views/widget/desktop_aura/desktop_drag_drop_client_aurax11.cc
index bb4c35fd..80090c4 100644
--- a/ui/views/widget/desktop_aura/desktop_drag_drop_client_aurax11.cc
+++ b/ui/views/widget/desktop_aura/desktop_drag_drop_client_aurax11.cc
@@ -23,6 +23,7 @@
 #include "ui/base/dragdrop/os_exchange_data_provider_x11.h"
 #include "ui/base/layout.h"
 #include "ui/base/x/selection_utils.h"
+#include "ui/base/x/x11_cursor.h"
 #include "ui/base/x/x11_drag_context.h"
 #include "ui/base/x/x11_util.h"
 #include "ui/base/x/x11_whole_screen_move_loop.h"
@@ -167,11 +168,16 @@
   // Windows has a specific method, DoDragDrop(), which performs the entire
   // drag. We have to emulate this, so we spin off a nested runloop which will
   // track all cursor movement and reroute events to a specific handler.
+  auto* last_cursor = static_cast<ui::X11Cursor*>(
+      source_window->GetHost()->last_cursor().platform());
   move_loop_->RunMoveLoop(
       !source_window->HasCapture(),
-      source_window->GetHost()->last_cursor().platform(),
-      cursor_manager_->GetInitializedCursor(ui::mojom::CursorType::kGrabbing)
-          .platform());
+      last_cursor ? last_cursor->xcursor() : x11::None,
+      static_cast<ui::X11Cursor*>(
+          cursor_manager_
+              ->GetInitializedCursor(ui::mojom::CursorType::kGrabbing)
+              .platform())
+          ->xcursor());
 
   if (alive) {
     auto resulting_operation = negotiated_operation();
@@ -349,7 +355,9 @@
       break;
   }
   move_loop_->UpdateCursor(
-      cursor_manager_->GetInitializedCursor(cursor_type).platform());
+      static_cast<ui::X11Cursor*>(
+          cursor_manager_->GetInitializedCursor(cursor_type).platform())
+          ->xcursor());
 }
 
 void DesktopDragDropClientAuraX11::OnBeginForeignDrag(x11::Window window) {
diff --git a/ui/views/widget/desktop_aura/x11_drag_drop_client_unittest.cc b/ui/views/widget/desktop_aura/x11_drag_drop_client_unittest.cc
index 67f745e3..c9946d29 100644
--- a/ui/views/widget/desktop_aura/x11_drag_drop_client_unittest.cc
+++ b/ui/views/widget/desktop_aura/x11_drag_drop_client_unittest.cc
@@ -23,6 +23,7 @@
 #include "ui/aura/window.h"
 #include "ui/aura/window_tree_host.h"
 #include "ui/base/dragdrop/os_exchange_data.h"
+#include "ui/base/x/x11_cursor.h"
 #include "ui/base/x/x11_move_loop.h"
 #include "ui/base/x/x11_move_loop_delegate.h"
 #include "ui/base/x/x11_os_exchange_data_provider.h"
@@ -317,11 +318,16 @@
   // drag. We have to emulate this, so we spin off a nested runloop which will
   // track all cursor movement and reroute events to a specific handler.
   auto cursor_manager_ = std::make_unique<DesktopNativeCursorManager>();
+  auto* last_cursor = static_cast<ui::X11Cursor*>(
+      source_window->GetHost()->last_cursor().platform());
   loop_->RunMoveLoop(
       !source_window->HasCapture(),
-      source_window->GetHost()->last_cursor().platform(),
-      cursor_manager_->GetInitializedCursor(ui::mojom::CursorType::kGrabbing)
-          .platform());
+      last_cursor ? last_cursor->xcursor() : x11::None,
+      static_cast<ui::X11Cursor*>(
+          cursor_manager_
+              ->GetInitializedCursor(ui::mojom::CursorType::kGrabbing)
+              .platform())
+          ->xcursor());
 
   auto resulting_operation = negotiated_operation();
   CleanupDrag();