diff --git a/src/app/nebula_controller.cpp b/src/app/nebula_controller.cpp index 4c0f649..dc04581 100644 --- a/src/app/nebula_controller.cpp +++ b/src/app/nebula_controller.cpp @@ -241,13 +241,12 @@ void NebulaController::OnWindowResized(const nebula::window::BrowserLayout& layo } void NebulaController::OnWindowCloseRequested() { -#if defined(_WIN32) if (!closing_ && !closing_tab_browsers_.empty()) { // CEF Alloy can bubble a child browser close as WM_CLOSE on the host - // window. Per-tab closes should not turn into full app shutdown. + // window (Windows) or performClose: on the host window (OS X). Per-tab + // closes should not turn into full app shutdown. return; } -#endif if (launch_options_.mode == AppMode::BigPicture && !closing_) { if (!SwitchToSiblingMode(AppMode::Desktop)) { diff --git a/src/platform/mac/startup_mac.mm b/src/platform/mac/startup_mac.mm index 9f2d5e9..fa177eb 100644 --- a/src/platform/mac/startup_mac.mm +++ b/src/platform/mac/startup_mac.mm @@ -8,9 +8,40 @@ #include #include +#include "include/cef_application_mac.h" #include "include/cef_command_line.h" #include "ui/paths.h" +// All CEF client applications must subclass NSApplication and implement the +// CefAppProtocol. CEF's message pump and window teardown code calls +// -[NSApplication isHandlingSendEvent:]/setHandlingSendEvent: (through +// CefScopedSendingEvent) while dispatching events. Against the plain +// NSApplication those selectors do not exist, so any code path that reaches +// them (for example closing a tab while a browser view is being torn down) +// raises "unrecognized selector sent to NSApplication" and crashes. +@interface NebulaApplication : NSApplication { + @private + BOOL handling_send_event_; +} +@end + +@implementation NebulaApplication + +- (BOOL)isHandlingSendEvent { + return handling_send_event_; +} + +- (void)setHandlingSendEvent:(BOOL)handlingSendEvent { + handling_send_event_ = handlingSendEvent; +} + +- (void)sendEvent:(NSEvent*)event { + CefScopedSendingEvent sending_event_scoper; + [super sendEvent:event]; +} + +@end + namespace nebula::platform { namespace { @@ -20,7 +51,10 @@ int g_single_instance_lock = -1; void PrepareApp() { @autoreleasepool { - [NSApplication sharedApplication]; + // Create the shared application as NebulaApplication (CefAppProtocol) + // before anything else touches NSApp so the CEF pipeline always sees + // the protocol methods it requires. + [NebulaApplication sharedApplication]; [NSApp setActivationPolicy:NSApplicationActivationPolicyRegular]; [NSApp finishLaunching]; }