Merged changes from hunter. Attempt to fix cthulhu announcing modifiers when suspended for xterm.

This commit is contained in:
Storm Dragon committed 2026-10-31 16:07:29 -04:00
1 parent 27867a48cb
commit f2cc47c8a0
24 files changed
+679 -67

No files matched your search

+49 -28
View File
@@ -21,24 +21,28 @@ const managedKey = "CTHULHU_WINE_ACCESS_MANAGED"
type prefix struct {
path, loader string
environment map[string]string
programs map[string]bool
}
type process struct {
cmd *exec.Cmd
done chan struct{}
started time.Time
seen time.Time
failures int
next time.Time
stopping atomic.Bool
cmd *exec.Cmd
done chan struct{}
started time.Time
seen time.Time
failures int
next time.Time
stopping atomic.Bool
controllerOnly bool
}
type Manager struct {
logger *slog.Logger
helper string
procRoot string
cancel context.CancelFunc
done chan struct{}
logger *slog.Logger
helper string
procRoot string
cancel context.CancelFunc
done chan struct{}
ControllerOnly bool
ExcludedPrograms []string
}
func New(logger *slog.Logger) *Manager {
@@ -151,7 +155,11 @@ func (manager *Manager) poll(active map[string]*process) {
child.next = now.Add(backoff(child.failures))
child.cmd = nil
default:
continue
if manager.controller_only(source) && !child.controllerOnly {
stop(child)
} else {
continue
}
}
}
if now.Before(child.next) {
@@ -179,7 +187,13 @@ func backoff(failures int) time.Duration {
}
func (manager *Manager) launch(child *process, source prefix, now time.Time) error {
cmd := exec.Command(manager.helper)
helper, err := stage_helper(manager.helper, source.environment)
if err != nil {
return err
}
controllerOnly := child.controllerOnly || manager.controller_only(source)
arguments := manager.helper_arguments(controllerOnly)
cmd := exec.Command(helper, arguments...)
diagnostics := newHelperDiagnostics()
cmd.Stdin = nil
cmd.Stdout = nil
@@ -187,11 +201,17 @@ func (manager *Manager) launch(child *process, source prefix, now time.Time) err
// Bound stderr draining if a Wine descendant retains the inherited pipe.
cmd.WaitDelay = 200 * time.Millisecond
cmd.SysProcAttr = &syscall.SysProcAttr{Setsid: true}
environment := os.Environ()
environment := make([]string, 0, len(os.Environ())+8)
for _, entry := range os.Environ() {
key, _, _ := strings.Cut(entry, "=")
if key != "WINEESYNC" && key != "WINEFSYNC" {
environment = append(environment, entry)
}
}
// 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"} {
for _, key := range []string{"DISPLAY", "WAYLAND_DISPLAY", "XAUTHORITY", "XDG_RUNTIME_DIR", "WINEESYNC", "WINEFSYNC"} {
if value := source.environment[key]; value != "" {
environment = append(environment, key+"="+value)
}
@@ -206,6 +226,7 @@ func (manager *Manager) launch(child *process, source prefix, now time.Time) err
}
child.cmd, child.done, child.started = cmd, make(chan struct{}), now
child.stopping.Store(false)
child.controllerOnly = controllerOnly
logger := manager.logger.With("helper_pid", cmd.Process.Pid)
logger.Info("Wine accessibility helper started")
logger.Debug("Wine accessibility helper launch configuration", "executable", cmd.Path,
@@ -317,17 +338,13 @@ func discover(root string, uid uint32) map[string]prefix {
if !filepath.IsAbs(path) {
continue
}
loader := environment["WINELOADER"]
if !executable(loader) {
loader = exe
if strings.HasSuffix(name, "-preloader") {
loader = strings.TrimSuffix(exe, "-preloader")
}
if !executable(loader) {
loader = ""
}
loader := wine_loader(exe, environment["WINELOADER"])
programs := map[string]bool{program_name(string(commandLine)): true}
if previous, ok := result[path]; ok {
previous.programs[program_name(string(commandLine))] = true
continue
}
result[path] = prefix{path: path, loader: loader, environment: environment}
result[path] = prefix{path: path, loader: loader, environment: environment, programs: programs}
}
return result
}
@@ -341,9 +358,13 @@ func applicationProcess(commandLine string) bool {
if program == "" {
return false
}
program = filepath.Base(strings.ReplaceAll(program, "\\", "/"))
normalized := strings.ReplaceAll(program, "\\", "/")
if strings.HasSuffix(normalized, "/windows/system32/steam.exe") || strings.HasSuffix(normalized, "/windows/syswow64/steam.exe") {
return false
}
program = filepath.Base(normalized)
switch program {
case "", "services.exe", "winedevice.exe", "svchost.exe", "plugplay.exe", "rpcss.exe", "lsass.exe", "wineboot.exe", "winemenubuilder.exe":
case "", "xalia.exe", "conhost.exe", "tabtip.exe", "start.exe", "services.exe", "winedevice.exe", "svchost.exe", "plugplay.exe", "rpcss.exe", "lsass.exe", "wineboot.exe", "winemenubuilder.exe":
return false
case "explorer.exe":
// Ordinary Explorer windows are applications; its desktop host is not.