| 1 | package main |
| 2 | |
| 3 | import ( |
| 4 | "context" |
| 5 | goruntime "runtime" |
| 6 | "time" |
| 7 | |
| 8 | "github.com/wailsapp/wails/v2/pkg/runtime" |
| 9 | ) |
| 10 | |
| 11 | const windowsWebView2StartupFallbackDelay = 15 * time.Second |
| 12 | |
| 13 | const windowsWebView2StartupFallbackMessage = "The desktop interface did not become ready within 15 seconds. " + |
| 14 | "An unavailable Windows system proxy or a WebView2 failure may be blocking startup. " + |
| 15 | "Check the system proxy, then restart Reasonix. If the problem continues, repair Microsoft Edge WebView2 Runtime or reinstall Reasonix.\n\n" + |
| 16 | "桌面界面在 15 秒内未能就绪。不可用的 Windows 系统代理或 WebView2 故障可能阻塞了启动。" + |
| 17 | "请检查系统代理后重启 Reasonix;如果问题仍然存在,请修复 Microsoft Edge WebView2 Runtime 或重新安装 Reasonix。" |
| 18 | |
| 19 | // startWindowsWebView2StartupFallback prevents StartHidden from turning a slow |
| 20 | // or failed WebView2 navigation into an apparently missing application. Proxy |
| 21 | // isolation is the primary repair; this watchdog is the last-resort visible |
| 22 | // recovery path for policy-forced proxies and unrelated WebView2 failures. |
| 23 | func (a *App) startWindowsWebView2StartupFallback(ctx context.Context) { |
| 24 | if !shouldStartWindowsWebView2StartupFallback(goruntime.GOOS, a.remoteWindowTicket != "") { |
| 25 | return |
| 26 | } |
| 27 | go func() { |
| 28 | timer := time.NewTimer(windowsWebView2StartupFallbackDelay) |
| 29 | defer timer.Stop() |
| 30 | if !awaitStartupFallback(ctx, timer.C, a.startupReady.Load) { |
| 31 | return |
| 32 | } |
| 33 | |
| 34 | // Show the native shell first so a dialog failure can never leave the app |
| 35 | // completely invisible. The dark native background is already configured. |
| 36 | runtime.WindowShow(ctx) |
| 37 | if a.startupReady.Load() { |
| 38 | return |
| 39 | } |
| 40 | _, _ = runtime.MessageDialog(ctx, runtime.MessageDialogOptions{ |
| 41 | Type: runtime.WarningDialog, |
| 42 | Title: "Reasonix startup delayed / Reasonix 启动延迟", |
| 43 | Message: windowsWebView2StartupFallbackMessage, |
| 44 | Buttons: []string{"OK"}, |
| 45 | DefaultButton: "OK", |
| 46 | }) |
| 47 | }() |
| 48 | } |
| 49 | |
| 50 | func shouldStartWindowsWebView2StartupFallback(goos string, remoteWindow bool) bool { |
| 51 | return goos == "windows" && !remoteWindow |
| 52 | } |
| 53 | |
| 54 | func awaitStartupFallback(ctx context.Context, timeout <-chan time.Time, ready func() bool) bool { |
| 55 | select { |
| 56 | case <-ctx.Done(): |
| 57 | return false |
| 58 | case <-timeout: |
| 59 | return !ready() |
| 60 | } |
| 61 | } |
| 62 |