diff --git a/v3/UNRELEASED_CHANGELOG.md b/v3/UNRELEASED_CHANGELOG.md index 7fd94333899..d996434af59 100644 --- a/v3/UNRELEASED_CHANGELOG.md +++ b/v3/UNRELEASED_CHANGELOG.md @@ -23,6 +23,7 @@ After processing, the content will be moved to the main changelog and this file ## Fixed +- Prevent macOS applications from crashing when replacing the application menu from a Wails callback - macOS app activation now respects activation policy for regular apps only in [PR](https://github.com/wailsapp/wails/pull/5897) by @julianstorer - Guard uninitialized GTK windows in Linux builds in [PR](https://github.com/wailsapp/wails/pull/5898) by @julianstorer - Set explicit opaque background color for Linux WebKit windows before URL load in [PR](https://github.com/wailsapp/wails/pull/5899) by @julianstorer diff --git a/v3/pkg/application/application_darwin.go b/v3/pkg/application/application_darwin.go index ece33619e26..b9f6f361f8b 100644 --- a/v3/pkg/application/application_darwin.go +++ b/v3/pkg/application/application_darwin.go @@ -141,7 +141,19 @@ static void destroyApp(void) { // Set the application menu static void setApplicationMenu(void *menu) { NSMenu *nsMenu = (__bridge NSMenu *)menu; - [NSApp setMainMenu:menu]; + void (^apply)(void) = ^{ + [NSApp setMainMenu:nsMenu]; + }; + + // AppKit requires the main menu to be replaced on the main thread. Menu.Set + // may be called from Wails event listeners, which execute on worker + // goroutines, so marshal the update synchronously. Avoid dispatch_sync when + // already on the main thread because that would deadlock. + if ([NSThread isMainThread]) { + apply(); + } else { + dispatch_sync(dispatch_get_main_queue(), apply); + } } // Get the application name