From d33960ddf3a2545b2eec385b0eee85ce5b725700 Mon Sep 17 00:00:00 2001 From: Angus Kola Date: Sun, 25 Oct 2026 15:48:28 -0400 Subject: [PATCH 1/2] bumped version to 2026.10.25 --- internal/version/version.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/version/version.go b/internal/version/version.go index 26e507a..1093261 100644 --- a/internal/version/version.go +++ b/internal/version/version.go @@ -21,7 +21,7 @@ import "strings" const Name = "Cthulhu" -const Version = "2026.10.24" +const Version = "2026.10.25" const Channel = "testing" var Build = Version From 17383f732e53c437c020e40d99e49f3421be7ed9 Mon Sep 17 00:00:00 2001 From: deedra Date: Sun, 25 Oct 2026 14:56:36 -0700 Subject: [PATCH 2/2] Keep Wine accessibility helpers on the reader's session bus A Wine application can inherit a different D-Bus session address from the running Cthulhu instance. The helper manager previously copied that address from the application's environment, redirecting accessibility requests to a bus where the supervising reader was unavailable. This left foobar2000 and its Preferences dialog silent despite working native control support. Retain the reader's inherited DBUS_SESSION_BUS_ADDRESS when launching a helper. Continue taking the application's display, runtime directory, Wine prefix and loader so hooks still attach to the correct Wine session. The manager remains responsible for helper startup and shutdown. Extend the existing manager lifecycle regression to supply conflicting application and reader bus addresses. Assert that the helper receives the reader's bus, the application's display, the expected prefix and the managed-helper marker, while retaining the shutdown checks. The regression failed against the original implementation before the fix. Validation: - GOPROXY=off go test ./internal/wine -count=1 - GOPROXY=off go test -race ./internal/wine -count=1 - GOPROXY=off go vet ./internal/wine - Built and installed the reader; configuration validation passed. - After reload, both the default-prefix and Bard helpers used the reader's bus. Foobar2000 Preferences opened on workspace 3 without settings changes. - The user subsequently confirmed that the installed changes look good. --- internal/wine/manager.go | 5 ++++- internal/wine/manager_test.go | 7 ++++--- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/internal/wine/manager.go b/internal/wine/manager.go index 5e2f6d1..573072f 100644 --- a/internal/wine/manager.go +++ b/internal/wine/manager.go @@ -188,7 +188,10 @@ func (manager *Manager) launch(child *process, source prefix, now time.Time) err cmd.WaitDelay = 200 * time.Millisecond cmd.SysProcAttr = &syscall.SysProcAttr{Setsid: true} environment := os.Environ() - for _, key := range []string{"DISPLAY", "WAYLAND_DISPLAY", "XDG_RUNTIME_DIR", "DBUS_SESSION_BUS_ADDRESS"} { + // Hooks need the application's display, but D-Bus requests go to this + // reader's session. Applications launched from another session bus must + // not redirect the helper away from the service supervising it. + for _, key := range []string{"DISPLAY", "WAYLAND_DISPLAY", "XDG_RUNTIME_DIR"} { if value := source.environment[key]; value != "" { environment = append(environment, key+"="+value) } diff --git a/internal/wine/manager_test.go b/internal/wine/manager_test.go index 06049b2..438fe26 100644 --- a/internal/wine/manager_test.go +++ b/internal/wine/manager_test.go @@ -219,13 +219,14 @@ func TestManagerLaunchesAndStopsHelperForActivePrefix(t *testing.T) { if err := os.WriteFile(filepath.Join(proc, "cmdline"), []byte("application.exe\x00"), 0600); err != nil { t.Fatal(err) } - if err := os.WriteFile(filepath.Join(proc, "environ"), []byte("WINEPREFIX="+prefixPath+"\x00WINELOADER="+loader+"\x00"), 0600); err != nil { + if err := os.WriteFile(filepath.Join(proc, "environ"), []byte("WINEPREFIX="+prefixPath+"\x00WINELOADER="+loader+"\x00DBUS_SESSION_BUS_ADDRESS=unix:path=/application-bus\x00DISPLAY=:7\x00"), 0600); err != nil { t.Fatal(err) } output := filepath.Join(root, "helper-output") t.Setenv("CTHULHU_TEST_WINE_OUTPUT", output) + t.Setenv("DBUS_SESSION_BUS_ADDRESS", "unix:path=/reader-bus") helper := filepath.Join(root, "helper") - script := "#!/bin/sh\nprintf '%s\\n' \"$WINEPREFIX\" \"$CTHULHU_WINE_ACCESS_MANAGED\" > \"$CTHULHU_TEST_WINE_OUTPUT\"\nexec sleep 30\n" + script := "#!/bin/sh\nprintf '%s\\n' \"$WINEPREFIX\" \"$CTHULHU_WINE_ACCESS_MANAGED\" \"$DBUS_SESSION_BUS_ADDRESS\" \"$DISPLAY\" > \"$CTHULHU_TEST_WINE_OUTPUT\"\nexec sleep 30\n" if err := os.WriteFile(helper, []byte(script), 0700); err != nil { t.Fatal(err) } @@ -243,7 +244,7 @@ func TestManagerLaunchesAndStopsHelperForActivePrefix(t *testing.T) { } time.Sleep(10 * time.Millisecond) } - if string(contents) != prefixPath+"\n1\n" { + if string(contents) != prefixPath+"\n1\nunix:path=/reader-bus\n:7\n" { t.Fatalf("helper environment = %q", contents) } stopCtx, cancel := context.WithTimeout(context.Background(), time.Second)