diff --git a/cmd/gogio/windows_test.go b/cmd/gogio/windows_test.go index 6c26ed50..86fa48e1 100644 --- a/cmd/gogio/windows_test.go +++ b/cmd/gogio/windows_test.go @@ -5,6 +5,7 @@ package main_test import ( "context" "image" + "io" "os" "os/exec" "path/filepath" @@ -69,29 +70,46 @@ func (d *WineTestDriver) Start(path string) { // to reuse a previously set up wineprefix. wineprefix := filepath.Join(cacheDir, "gio-e2e-wine") - // First, run a headless winecfg to make sure the wineprefix is - // set up. If Wine encounters any issue setting up, we can also - // report it early. This can easily take 5s the first time. The - // "/?" parameter is just to not try to open the winecfg GUI. - // TODO(mvdan): Why does this take ~2s when run with a terminal - // (pty), but it takes ~6s when run here? + // First, ensure that wineprefix is up to date with wineboot. + // Wait for this separately from the first frame, as setting up + // a new prefix might take 5s on its own. + env := []string{ + "DISPLAY=" + d.display, + "WINEDEBUG=fixme-all", // hide "fixme" noise + "WINEPREFIX=" + wineprefix, + + // Disable wine-gecko (Explorer) and wine-mono (.NET). + // Otherwise, if not installed, wineboot will get stuck + // with a prompt to install them on the virtual X + // display. Moreover, Gio doesn't need either, and wine + // is faster without them. + "WINEDLLOVERRIDES=mscoree,mshtml=", + } { start := time.Now() - cmd := exec.Command("wine", "winecfg", "/?") - cmd.Env = []string{"WINEPREFIX=" + wineprefix} - if out, err := cmd.CombinedOutput(); err != nil { - d.Fatalf("%v: %s", err, out) + cmd := exec.Command("wine", "wineboot", "-i") + cmd.Env = env + // Use a combined output pipe instead of CombinedOutput, + // so that we only wait for the child process to exit, + // and we don't need to wait for all of wine's + // grandchildren to exit and stop writing. This is + // relevant as wine leaves "wineserver" lingering for + // three seconds by default, to be reused later. + stdout, err := cmd.StdoutPipe() + if err != nil { + d.Fatal(err) + } + cmd.Stderr = cmd.Stdout + if err := cmd.Run(); err != nil { + io.Copy(os.Stderr, stdout) + d.Fatal(err) } d.Logf("set up WINEPREFIX in %s", time.Since(start)) } ctx, cancel := context.WithCancel(context.Background()) cmd := exec.CommandContext(ctx, "wine", bin) - cmd.Env = []string{ - "DISPLAY=" + d.display, - "WINEDEBUG=-all", // hide warnings and other noise - "WINEPREFIX=" + wineprefix, - } + cmd.Env = env output, err := cmd.StdoutPipe() if err != nil { d.Fatal(err)