Order macOS pointer events by the previous button state, scale the cursor position into framebuffer pixels, and escalate crash cleanup to SIGKILL

This commit is contained in:
Viktor Liu
2026-09-22 20:10:15 +02:00
parent a5c146ccda
commit 88dbac029e
4 changed files with 59 additions and 8 deletions
+33
View File
@@ -9,6 +9,7 @@ import (
"strconv"
"strings"
"syscall"
"time"
log "github.com/sirupsen/logrus"
)
@@ -61,6 +62,19 @@ func (s *ShutdownState) Cleanup() error {
if killErr := syscall.Kill(proc.PID, syscall.SIGKILL); killErr != nil {
log.Debugf("cleanup: kill pid %d (%s): group kill: %v, single kill: %v", proc.PID, desc, err, killErr)
}
continue
}
// An X server or a desktop process may catch or ignore TERM, and this
// record is discarded below either way, so nothing would come back for
// it. Escalate the way the ordinary virtual-session shutdown does
// rather than leaving it running against the next session.
if groupGone(proc.PID, cleanupGracePeriod) {
continue
}
log.Debugf("cleanup: pid %d (%s) survived SIGTERM, sending SIGKILL", proc.PID, desc)
if err := syscall.Kill(-proc.PID, syscall.SIGKILL); err != nil {
log.Debugf("cleanup: SIGKILL pid %d (%s): %v", proc.PID, desc, err)
}
}
@@ -68,6 +82,25 @@ func (s *ShutdownState) Cleanup() error {
return nil
}
// cleanupGracePeriod is how long a signalled process group gets to exit on its
// own before Cleanup escalates to SIGKILL.
const cleanupGracePeriod = 2 * time.Second
// groupGone polls the process group until it has exited or grace expires, and
// reports whether it is gone. Signal 0 only probes for existence.
func groupGone(pid int, grace time.Duration) bool {
deadline := time.Now().Add(grace)
for {
if err := syscall.Kill(-pid, 0); err != nil {
return true
}
if !time.Now().Before(deadline) {
return false
}
time.Sleep(50 * time.Millisecond)
}
}
// describeProcess captures the identity of a freshly started process so a later
// Cleanup can tell it apart from whatever inherits its PID.
func describeProcess(pid int) sessionProcess {