diff --git a/v3/UNRELEASED_CHANGELOG.md b/v3/UNRELEASED_CHANGELOG.md index 77bc7c3ec..1b4c4a647 100644 --- a/v3/UNRELEASED_CHANGELOG.md +++ b/v3/UNRELEASED_CHANGELOG.md @@ -28,6 +28,7 @@ After processing, the content will be moved to the main changelog and this file ## Fixed +- Fix "ghost windows" issue on macOS caused by not accessing AppKit APIs from the Main Thread in App.Window.Current() (#4947) by @wimaha - Fix HTML `` not working on macOS by implementing WKUIDelegate runOpenPanelWithParameters (#4862) - Fix native file drag-and-drop not working when using `@wailsio/runtime` npm module on macOS/Linux (#4953) by @leaanthony - Fix binding generation for cross-package type aliases (#4578) by @fbbdev diff --git a/v3/pkg/application/application_darwin.go b/v3/pkg/application/application_darwin.go index 1de18f632..287b66e84 100644 --- a/v3/pkg/application/application_darwin.go +++ b/v3/pkg/application/application_darwin.go @@ -146,10 +146,31 @@ static char* getAppName(void) { // get the current window ID static unsigned int getCurrentWindowID(void) { - NSWindow *window = [NSApp keyWindow]; - // Get the window delegate - WebviewWindowDelegate *delegate = (WebviewWindowDelegate*)[window delegate]; - return delegate.windowId; + // AppKit must be accessed on the main thread. This function may be called + // from arbitrary Go goroutines, so we hop to the main queue when needed. + __block unsigned int result = 0; + if (NSApp == nil) { + return result; + } + void (^resolve)(void) = ^{ + NSWindow *window = [NSApp keyWindow]; + if (window == nil) { + window = [NSApp mainWindow]; + } + if (window == nil) { + return; + } + WebviewWindowDelegate *delegate = (WebviewWindowDelegate*)[window delegate]; + if (delegate != nil) { + result = delegate.windowId; + } + }; + if ([NSThread isMainThread]) { + resolve(); + } else { + dispatch_sync(dispatch_get_main_queue(), resolve); + } + return result; } // Set the application icon