Repository: electron/electron
Pull request: fix: `screen.getCursorScreenPoint()` crash on Wayland

#### Description of Change

Closes #50079.

require a Window to exist before calling Screen::getCursorScreenPoint()

CC @codebytere @mitchchn 

`ui::WaylandScreen::GetCursorScreenPoint()` [requires](https://chromium.googlesource.com/chromium/src/+/d08503f709a3419689bfcbedb181535e596d6959/ui/ozone/platform/wayland/host/wayland_screen.cc#371) at least one window to exist or it can DCHECK / dereference a nullptr. We used to work around this with #35503 but that approach no longer works. This PR is similar in spirit to 35503 but instead checks that `!WindowList.IsEmpty()` to confirm that at least one window exists.

#### Checklist

- [x] PR description included
- [x] I have built and tested this PR
- [ ] `npm test` passes
- [x] [PR release notes](https://github.com/electron/clerk/blob/main/README.md) describe the change in a way relevant to app developers, and are [capitalized, punctuated, and past tense](https://github.com/electron/clerk/blob/main/README.md#examples).

#### Release Notes

Notes: Fixed an issue where `screen.getCursorScreenPoint()` crashed on Wayland when it was called before a `BrowserWindow` had been created

Changed files:
filename: docs/api/screen.md
patch: @@ -110,6 +110,8 @@ Returns [`Point`](structures/point.md)
 
 The current absolute position of the mouse pointer.
 
+Not supported on Wayland (Linux).
+
 > [!NOTE]
 > The return value is a DIP point, not a screen physical point.
 

filename: shell/browser/api/electron_api_screen.cc
patch: @@ -32,10 +32,6 @@
 #include "shell/browser/linux/x11_util.h"
 #endif
 
-#if defined(USE_OZONE)
-#include "ui/ozone/public/ozone_platform.h"
-#endif
-
 namespace electron::api {
 
 const gin::WrapperInfo Screen::kWrapperInfo = {{gin::kEmbedderNativeGin},
@@ -94,16 +90,9 @@ Screen::~Screen() {
 }
 
 gfx::Point Screen::GetCursorScreenPoint(v8::Isolate* isolate) {
-#if defined(USE_OZONE)
-  // Wayland will crash unless a window is created prior to calling
-  // GetCursorScreenPoint.
-  if (!ui::OzonePlatform::IsInitialized()) {
-    gin_helper::ErrorThrower thrower(isolate);
-    thrower.ThrowError(
-        "screen.getCursorScreenPoint() cannot be called before a window has "
-        "been created.");
+#if BUILDFLAG(IS_LINUX)
+  if (x11_util::IsWayland())
     return {};
-  }
 #endif
   auto* screen = GetDisplayScreen();
   return screen ? screen->GetCursorScreenPoint() : gfx::Point{};

filename: shell/browser/linux/x11_util.cc
patch: @@ -4,13 +4,27 @@
 
 #include "shell/browser/linux/x11_util.h"
 
+#include "build/build_config.h"
 #include "ui/ozone/platform_selection.h"  // nogncheck
 
 namespace x11_util {
 
 bool IsX11() {
-  static const bool is_x11 = ui::GetOzonePlatformId() == ui::kPlatformX11;
-  return is_x11;
+#if BUILDFLAG(IS_LINUX)
+  static const bool is = ui::GetOzonePlatformId() == ui::kPlatformX11;
+  return is;
+#else
+  return false;
+#endif
+}
+
+bool IsWayland() {
+#if BUILDFLAG(IS_LINUX)
+  static const bool is = ui::GetOzonePlatformId() == ui::kPlatformWayland;
+  return is;
+#else
+  return false;
+#endif
 }
 
 }  // namespace x11_util

filename: shell/browser/linux/x11_util.h
patch: @@ -7,7 +7,8 @@
 
 namespace x11_util {
 
-bool IsX11();
+[[nodiscard]] bool IsX11();
+[[nodiscard]] bool IsWayland();
 
 }  // namespace x11_util