@@ -70,16 +70,26 @@ void DelayEmitWithMetrics(Screen* screen,
7070 screen->Emit (name, display, metrics);
7171}
7272
73+ // Calls the one-liner `display::Screen::Get()` to get ui's global screen.
74+ // NOTE: during shutdown, that screen can be destroyed before us. This means:
75+ // 1. Call this instead of keeping a possibly-dangling raw_ptr in api::Screen.
76+ // 2. Always check this function's return value for nullptr before use.
77+ [[nodiscard]] auto * GetDisplayScreen () {
78+ return display::Screen::Get ();
79+ }
80+
81+ [[nodiscard]] auto GetFallbackDisplay () {
82+ return display::Display::GetDefaultDisplay ();
83+ }
7384} // namespace
7485
75- Screen::Screen (display::Screen* screen) : screen_{screen} {
76- screen_->AddObserver (this );
86+ Screen::Screen () {
87+ if (auto * screen = GetDisplayScreen ())
88+ screen->AddObserver (this );
7789}
7890
7991Screen::~Screen () {
80- // Use `display::Screen::Get()` here, not our cached `screen_`:
81- // during shutdown, it can get torn down before us.
82- if (auto * screen = display::Screen::Get ())
92+ if (auto * screen = GetDisplayScreen ())
8393 screen->RemoveObserver (this );
8494}
8595
@@ -95,7 +105,33 @@ gfx::Point Screen::GetCursorScreenPoint(v8::Isolate* isolate) {
95105 return {};
96106 }
97107#endif
98- return screen_->GetCursorScreenPoint ();
108+ auto * screen = GetDisplayScreen ();
109+ return screen ? screen->GetCursorScreenPoint () : gfx::Point{};
110+ }
111+
112+ display::Display Screen::GetPrimaryDisplay () const {
113+ const auto * screen = GetDisplayScreen ();
114+ return screen ? screen->GetPrimaryDisplay () : GetFallbackDisplay ();
115+ }
116+
117+ std::vector<display::Display> Screen::GetAllDisplays () const {
118+ if (const auto * screen = GetDisplayScreen ())
119+ return screen->GetAllDisplays ();
120+
121+ // Even though this is only reached during shutdown by Screen::Get() failing,
122+ // display::Screen::GetAllDisplays() is guaranteed to return >= 1 display.
123+ // For consistency with that API, let's return a nonempty vector here.
124+ return {GetFallbackDisplay ()};
125+ }
126+
127+ display::Display Screen::GetDisplayNearestPoint (const gfx::Point& point) const {
128+ const auto * screen = GetDisplayScreen ();
129+ return screen ? screen->GetDisplayNearestPoint (point) : GetFallbackDisplay ();
130+ }
131+
132+ display::Display Screen::GetDisplayMatching (const gfx::Rect& match_rect) const {
133+ const auto * screen = GetDisplayScreen ();
134+ return screen ? screen->GetDisplayMatching (match_rect) : GetFallbackDisplay ();
99135}
100136
101137#if BUILDFLAG(IS_WIN)
@@ -182,14 +218,14 @@ Screen* Screen::Create(gin_helper::ErrorThrower error_thrower) {
182218 return {};
183219 }
184220
185- display::Screen* screen = display::Screen::Get ();
221+ display::Screen* screen = GetDisplayScreen ();
186222 if (!screen) {
187223 error_thrower.ThrowError (" Failed to get screen information" );
188224 return {};
189225 }
190226
191227 return cppgc::MakeGarbageCollected<Screen>(
192- error_thrower.isolate ()->GetCppHeap ()->GetAllocationHandle (), screen );
228+ error_thrower.isolate ()->GetCppHeap ()->GetAllocationHandle ());
193229}
194230
195231gin::ObjectTemplateBuilder Screen::GetObjectTemplateBuilder (
@@ -218,7 +254,6 @@ const gin::WrapperInfo* Screen::wrapper_info() const {
218254const char * Screen::GetHumanReadableName () const {
219255 return " Electron / Screen" ;
220256}
221-
222257} // namespace electron::api
223258
224259namespace {
0 commit comments