@@ -28,6 +28,7 @@ final class UiRoot: UiComponent {
2828 context. subscribe ( uuid: self . uuid) { state in
2929 let uuidsInState = Set ( state. mainWindows. keys)
3030
31+ // Open any new windows that appeared in state.
3132 uuidsInState
3233 . subtracting ( self . mainWindows. keys)
3334 . compactMap { state. mainWindows [ $0] }
@@ -36,25 +37,22 @@ final class UiRoot: UiComponent {
3637 mainWindow. show ( )
3738 }
3839
39- if self . mainWindows. isEmpty {
40- // We exit here if there are no main windows open.
41- // Otherwise, when hide/quit after last main window is active,
42- // you have to be really quick to open a new window
43- // when re-activating VimR w/o automatic new main window.
44- return
45- }
46-
47- self . mainWindows. keys
48- . filter { !uuidsInState. contains ( $0) }
49- . forEach ( self . removeMainWindow)
40+ // Remove windows that are no longer in state.
41+ let uuidsToRemove = self . mainWindows. keys. filter { !uuidsInState. contains ( $0) }
42+ uuidsToRemove. forEach ( self . removeMainWindow)
5043
5144 if self . activateAsciiImInInsertMode != state. activateAsciiImInNormalMode {
5245 self . activateAsciiImInInsertMode = state. activateAsciiImInNormalMode
5346 self . mainWindows. values
5447 . forEach { $0. activateAsciiImInInsertMode = self . activateAsciiImInInsertMode }
5548 }
5649
57- guard self . mainWindows. isEmpty else { return }
50+ // Only trigger the after-last-window action if we actually removed something
51+ // in this update and the result is that no windows remain. Guarding on
52+ // `!uuidsToRemove.isEmpty` prevents a rapid second state update (where
53+ // self.mainWindows is already empty at entry) from erroneously skipping or
54+ // double-firing the quit/hide action.
55+ guard !uuidsToRemove. isEmpty, self . mainWindows. isEmpty else { return }
5856
5957 switch state. afterLastWindowAction {
6058 case . doNothing: return
0 commit comments