Force process exit when the main window closes (#12172)#12198
Merged
Conversation
With ShutdownMode.OnLastWindowClose a single stray window keeps the app alive as an invisible background process - e.g. a leaked non-taskbar "please wait" progress window or an undocked video/audio window. Such a lingering process holds file/current-directory handles and locks the folder it was working in, so the user can't delete or move it. Hook the main window's Closed event and Environment.Exit(0) there. By the time Closed fires the main window's OnClosing has already saved settings and run CleanUp(); Closed never fires on a cancelled (unsaved-changes) close, so this is safe and guarantees shutdown regardless of any window, native thread, or child handle still lingering. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Addresses #12172
Problem
A user reported that after closing SubtitleEdit, a
SubtitleEdit.exeprocess kept running as a background process (~113 MB, invisible — not in the taskbar), and this locked the folder it had been working in (needed a third-party unlocker to release it).Root cause
The app runs with
ShutdownMode.OnLastWindowClose(Program.cs), so the process only exits when the last AvaloniaWindowcloses. Any single stray window keeps it alive:PleaseWaitWindow(ShowInTaskbar = false) whoseClose()was skipped on some path, orAllowCloseis set, and are only closed byMainViewModel.CleanUp()).While the process lingers it still holds OS handles — an open video file handle, or the process current directory (libmpv temporarily sets it) — and on Windows that locks the folder. Nothing inside the app releases those; only process exit does. So the folder lock is a symptom of the process never terminating.
Fix
Hook the main window's
Closedevent and forceEnvironment.Exit(0).Why this is the right trigger:
lifetime.Start()returning — a leaked window preventsOnLastWindowClosefrom ever firing, soStart()would never return.Closedfires, the main window'sOnClosinghas already saved settings and runCleanUp()(which closes the undocked windows).Closednever fires on a cancelled close (unsaved-changes prompt setse.Cancel = true), so we never exit prematurely.This guarantees shutdown regardless of any stray window, native thread, or child handle still lingering. Applies to both the normal main window and the standalone Batch Convert window (both set
lifetime.MainWindow).Notes
The exact leak that stranded the window in the original report couldn't be reproduced from the bug (no repro steps, filed against the older v5.0.0.0). This is a defensive backstop for the whole class of "lingering background process" bugs rather than a fix for one specific leak. Builds clean (0 warnings / 0 errors).
🤖 Generated with Claude Code