From 6e7c885ae7b60bb8eff97cd973b5b07e22bb1a51 Mon Sep 17 00:00:00 2001 From: Saad Najmi Date: Tue, 28 Apr 2026 09:12:03 -0700 Subject: [PATCH] fix(macos): show React menu on right-click of Fabric root views The Fabric root view (`RCTSurfaceHostingProxyRootView`) does not override `menuForEvent:` like the old-architecture `RCTRootView` does, so secondary clicks on the React content do nothing on the new architecture. Add a `HostingViewController` whose `rightMouseDown` shows the React menu, and use it for the React content view in multi-app mode. Also ungate the existing `ViewController` handlers so single-app mode picks them up via the responder chain. Co-Authored-By: Claude Opus 4.7 (1M context) --- macos/ReactTestApp/AppDelegate.swift | 2 +- macos/ReactTestApp/ViewController.swift | 19 ++++++++++++++++--- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/macos/ReactTestApp/AppDelegate.swift b/macos/ReactTestApp/AppDelegate.swift index f15938601..aaba29e46 100644 --- a/macos/ReactTestApp/AppDelegate.swift +++ b/macos/ReactTestApp/AppDelegate.swift @@ -214,7 +214,7 @@ extension AppDelegate { return viewController } - let viewController = NSViewController(nibName: nil, bundle: nil) + let viewController = HostingViewController(nibName: nil, bundle: nil) viewController.title = title viewController.view = host.view( moduleName: component.appKey, diff --git a/macos/ReactTestApp/ViewController.swift b/macos/ReactTestApp/ViewController.swift index b4163779c..f787b9b14 100644 --- a/macos/ReactTestApp/ViewController.swift +++ b/macos/ReactTestApp/ViewController.swift @@ -33,6 +33,8 @@ final class ViewController: NSViewController { ) } + #endif // !ENABLE_SINGLE_APP_MODE + override func mouseDown(with event: NSEvent) { NSMenu.popUpReactMenu(with: event, for: view) } @@ -40,11 +42,20 @@ final class ViewController: NSViewController { override func rightMouseDown(with event: NSEvent) { NSMenu.popUpReactMenu(with: event, for: view) } - - #endif // !ENABLE_SINGLE_APP_MODE } -#if !ENABLE_SINGLE_APP_MODE +// Hosts a React Native root view. The Fabric root view does not implement +// `menuForEvent:`, so right-click events propagate up the responder chain to +// this controller, which presents the React menu as a context menu. +final class HostingViewController: NSViewController { + override func mouseDown(with event: NSEvent) { + NSMenu.popUpReactMenu(with: event, for: view) + } + + override func rightMouseDown(with event: NSEvent) { + NSMenu.popUpReactMenu(with: event, for: view) + } +} extension NSMenu { static func popUpReactMenu(with event: NSEvent, for view: NSView) { @@ -56,6 +67,8 @@ extension NSMenu { } } +#if !ENABLE_SINGLE_APP_MODE + final class Label: NSTextView { init(text: String) { super.init(frame: .zero)