Skip to content

Fix window close / quit safety races#1162

Open
georgeharker wants to merge 1 commit intomasterfrom
window-close-fixes
Open

Fix window close / quit safety races#1162
georgeharker wants to merge 1 commit intomasterfrom
window-close-fixes

Conversation

@georgeharker
Copy link
Copy Markdown
Collaborator

Fixes several independent race conditions and correctness issues in the window close / app quit path. All changes are in VimR/VimR/ with no dependencies on other in-flight work.
AppDelegate.swift — applicationShouldTerminate

Both cancel paths (blocked-windows alert dismiss and dirty-windows cancel) returned without calling reply(toApplicationShouldTerminate:). Since the function returns .terminateLater, this left the app permanently stuck in a pending-termination state — subsequent window closes or Cmd+Q would misbehave because macOS considered termination already in progress. Added reply(false) before each early return.

MainWindow+Actions.swift / MainWindow+Delegates.swift / MainWindow.swift — dead closeWindow flag
The closeWindow IBAction set a closeWindow = true flag before calling performClose, causing windowShouldClose to send :qa! (quit all tabs) instead of :q (close current tab). Cmd+W should only close the current tab. Removed the flag, the defer reset, and the entire :qa! branch. windowShouldClose now always takes the closeCurrentTab / :q path.
MainWindow+Delegates.swift — ipcBecameInvalid

Called windowController.close() directly, bypassing neoVimStopped() / prepareClosing(). This meant isClosing was never set, the CLI pipe was not closed, and the Redux .close action was never emitted — leaving the window's UUID permanently in app state. Routed through neoVimStopped() instead.
UiRoot.swift — subscriber early-return race

The guard if self.mainWindows.isEmpty { return } was intended for app startup but also fired when a rapid second state update arrived after the last window had already been removed — silently preventing afterLastWindowAction (quit/hide) from ever firing. Restructured to only trigger quit/hide when windows were actually removed in this update and the result is empty (guard !uuidsToRemove.isEmpty, self.mainWindows.isEmpty).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant