Repository: electron/electron
Pull request: fix: handle missing `NativeWindowMac` in `ElectronNSWindow`

Backport of #47751

See that PR for details.


Notes: Fixed an issue where certain operations performed in a window close callback could trigger a crash.


Changed files:
filename: shell/browser/ui/cocoa/electron_ns_window.mm
patch: @@ -176,18 +176,16 @@ - (void)cleanup {
 }
 
 - (id)accessibilityFocusedUIElement {
-  views::Widget* widget = shell_->widget();
-  id superFocus = [super accessibilityFocusedUIElement];
-  if (!widget || shell_->IsFocused())
-    return superFocus;
+  if (!shell_ || !shell_->widget() || shell_->IsFocused())
+    return [super accessibilityFocusedUIElement];
   return nil;
 }
 - (NSRect)originalContentRectForFrameRect:(NSRect)frameRect {
   return [super contentRectForFrameRect:frameRect];
 }
 
 - (NSTouchBar*)makeTouchBar {
-  if (shell_->touch_bar())
+  if (shell_ && shell_->touch_bar())
     return [shell_->touch_bar() makeTouchBar];
   else
     return nil;
@@ -217,7 +215,8 @@ - (void)sendEvent:(NSEvent*)event {
 }
 
 - (void)rotateWithEvent:(NSEvent*)event {
-  shell_->NotifyWindowRotateGesture(event.rotation);
+  if (shell_)
+    shell_->NotifyWindowRotateGesture(event.rotation);
 }
 
 - (NSRect)contentRectForFrameRect:(NSRect)frameRect {
@@ -241,7 +240,7 @@ - (NSRect)constrainFrameRect:(NSRect)frameRect toScreen:(NSScreen*)screen {
     //
     // If there's no frame, put the window wherever the developer
     // wanted it to go
-    if (shell_->has_frame()) {
+    if (shell_ && shell_->has_frame()) {
       result.size = frameRect.size;
     } else {
       result = frameRect;
@@ -288,7 +287,7 @@ - (id)accessibilityAttributeValue:(NSString*)attribute {
 }
 
 - (NSString*)accessibilityTitle {
-  return base::SysUTF8ToNSString(shell_->GetTitle());
+  return base::SysUTF8ToNSString(shell_ ? shell_->GetTitle() : "");
 }
 
 - (BOOL)canBecomeMainWindow {
@@ -308,7 +307,7 @@ - (BOOL)validateUserInterfaceItem:(id<NSValidatedUserInterfaceItem>)item {
   // support closing a window without title we need to manually do menu item
   // validation. This code path is used by the "roundedCorners" option.
   if ([item action] == @selector(performClose:))
-    return shell_->IsClosable();
+    return shell_ && shell_->IsClosable();
   return [super validateUserInterfaceItem:item];
 }
 
@@ -328,7 +327,8 @@ - (void)disableHeadlessMode {
     // shown, but we don't want the headless behavior of allowing the window to
     // be placed unconstrained.
     self.isHeadless = false;
-    shell_->widget()->DisableHeadlessMode();
+    if (shell_->widget())
+      shell_->widget()->DisableHeadlessMode();
   }
 }
 
@@ -378,6 +378,9 @@ - (void)performClose:(id)sender {
 }
 
 - (BOOL)toggleFullScreenMode:(id)sender {
+  if (!shell_)
+    return NO;
+
   bool is_simple_fs = shell_->IsSimpleFullScreen();
   bool always_simple_fs = shell_->always_simple_fullscreen();
 
@@ -411,11 +414,13 @@ - (BOOL)toggleFullScreenMode:(id)sender {
 }
 
 - (void)performMiniaturize:(id)sender {
-  if (shell_->title_bar_style() ==
-      electron::NativeWindowMac::TitleBarStyle::kCustomButtonsOnHover)
+  if (shell_ &&
+      shell_->title_bar_style() ==
+          electron::NativeWindowMac::TitleBarStyle::kCustomButtonsOnHover) {
     [self miniaturize:self];
-  else
+  } else {
     [super performMiniaturize:sender];
+  }
 }
 
 @end