From 247ce87fe7e782441676baaaccaaf3dea979dbcc Mon Sep 17 00:00:00 2001 From: Wilko Date: Tue, 3 Feb 2026 21:41:14 +0100 Subject: [PATCH] =?UTF-8?q?fix(v3):=20App=20Expos=C3=A9=20shows=20?= =?UTF-8?q?=E2=80=9Cghost=E2=80=9D=20window=20after=20calling=20App.Window?= =?UTF-8?q?.Current()=20(#4947)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix(macOS): run getCurrentWindowID on main thread and add nil checks AppKit must be used on the main thread. getCurrentWindowID could be called from arbitrary Go goroutines, so dispatch to the main queue when not already on the main thread. Also guard NSApp, window, and delegate with nil checks and fall back to mainWindow when keyWindow is nil to avoid wrong or missing window ID. * Update UNRELEASED_CHANGELOG.md * Update UNRELEASED_CHANGELOG.md * Update UNRELEASED_CHANGELOG.md * fix: consistent indentation and changelog formatting - Convert spaces to tabs in getCurrentWindowID() for codebase consistency - Move changelog entry below the comment Co-Authored-By: Claude Opus 4.5 --------- Co-authored-by: Lea Anthony Co-authored-by: Claude Opus 4.5 --- v3/UNRELEASED_CHANGELOG.md | 1 + v3/pkg/application/application_darwin.go | 29 ++++++++++++++++++++---- 2 files changed, 26 insertions(+), 4 deletions(-) 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