Skip to content

Commit f6ba7dd

Browse files
committed
Fix bad interaction with never opening window + terminate on last window
Previously, if you configure MacVim to never open an untitled window on launch, *and* terminate MacVim on last window closing, you could get an odd behavior where MacVim will close itself soon after launch, usually when you fiddle with "About MacVim" or the preference pane. This isn't too big a deal but could potentially make it hard to change the preference back, and it's hard to know if a future macOS update will further break this behavior causing MacVim to keep terminating itself on launch (the termination behavior relies on the `applicationShouldTerminateAfterLastWindowClosed` API which is controlled by the OS). To fix this, simply make it so that the preference pane doesn't allow both settings to be set at once. If the user is trying to do so, set the other setting to be something sane. Also, in the `applicationShouldTerminateAfterLastWindowClosed` behavior, make sure we add additional protection so that it will not return true when we are set to never open untitled window (this should only be the case if the user manually set it using `defaults` because we are now already protecting against this in the preference pane logic). This should be fine because these two setting don't really make sense for the user anyway. It doesn't seem to make a lot of sense for the user to want this behavior. Note that I'm doing manual checking in preference UI instead of using some sort of key-value listening of NSUserDefaults because I'm afraid of some unintentional infinite recursion going on where the settings keep setting each other back and forth. By only doing this at preference pane changes this should not happen. Fix #1257
1 parent aeafa39 commit f6ba7dd

File tree

3 files changed

+45
-2
lines changed

3 files changed

+45
-2
lines changed

src/MacVim/Base.lproj/Preferences.xib

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
<?xml version="1.0" encoding="UTF-8"?>
2-
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="17701" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
2+
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="20037" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
33
<dependencies>
44
<deployment version="1090" identifier="macosx"/>
5-
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="17701"/>
5+
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="20037"/>
66
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
77
</dependencies>
88
<objects>
@@ -63,6 +63,7 @@
6363
</column>
6464
</cells>
6565
<connections>
66+
<action selector="openUntitledWindowChanged:" target="-2" id="S8l-uX-tEl"/>
6667
<binding destination="58" name="selectedTag" keyPath="values.MMUntitledWindow" id="171"/>
6768
</connections>
6869
</matrix>
@@ -175,6 +176,7 @@
175176
</menu>
176177
</popUpButtonCell>
177178
<connections>
179+
<action selector="lastWindowClosedChanged:" target="-2" id="IcT-7v-gxr"/>
178180
<binding destination="58" name="selectedIndex" keyPath="values.MMLastWindowClosedBehavior" id="968"/>
179181
</connections>
180182
</popUpButton>

src/MacVim/MMAppController.m

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -529,6 +529,17 @@ - (void)application:(NSApplication *)sender openFiles:(NSArray *)filenames
529529

530530
- (BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)sender
531531
{
532+
if (MMUntitledWindowNever ==
533+
[[NSUserDefaults standardUserDefaults]
534+
integerForKey:MMUntitledWindowKey]) {
535+
// Sanity protection: If we never open a new window on application launch, there could
536+
// be an issue here where we immediately terminate MacVim. Because of that, we always
537+
// return false regardless of what MMLastWindowClosedBehavior is. Note that the user
538+
// should not be able to set these two conflicting options together in the preference pane
539+
// but it's possible to do so in the terminal by calling "defaults" manually.
540+
return false;
541+
}
542+
532543
return (MMTerminateWhenLastWindowClosed ==
533544
[[NSUserDefaults standardUserDefaults]
534545
integerForKey:MMLastWindowClosedBehaviorKey]);

src/MacVim/MMPreferenceController.m

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,4 +133,34 @@ - (IBAction)fontPropertiesChanged:(id)sender
133133
[[MMAppController sharedInstance] refreshAllFonts];
134134
}
135135

136+
-(IBAction)lastWindowClosedChanged:(id)sender
137+
{
138+
// Sanity checking for terminate when last window closed + not opening an untitled window.
139+
// This results in a potentially awkward situation wehre MacVim will close itself since it
140+
// doesn't have any window opened when launched.
141+
// Note that the potentially bad behavior is already protected against for in applicationShouldTerminateAfterLastWindowClosed:,
142+
// but this sanity checking is to make sure the user can see that in an explicit fashion.
143+
NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults];
144+
if ([defaults integerForKey:MMLastWindowClosedBehaviorKey] == MMTerminateWhenLastWindowClosed) {
145+
if ([defaults integerForKey:MMUntitledWindowKey] == MMUntitledWindowNever) {
146+
[defaults setInteger:MMUntitledWindowOnOpen forKey:MMUntitledWindowKey];
147+
}
148+
}
149+
}
150+
151+
-(IBAction)openUntitledWindowChanged:(id)sender
152+
{
153+
// Sanity checking for terminate when last window closed + not opening an untitled window.
154+
// This results in a potentially awkward situation wehre MacVim will close itself since it
155+
// doesn't have any window opened when launched.
156+
// Note that the potentially bad behavior is already protected against for in applicationShouldTerminateAfterLastWindowClosed:,
157+
// but this sanity checking is to make sure the user can see that in an explicit fashion.
158+
NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults];
159+
if ([defaults integerForKey:MMLastWindowClosedBehaviorKey] == MMTerminateWhenLastWindowClosed) {
160+
if ([defaults integerForKey:MMUntitledWindowKey] == MMUntitledWindowNever) {
161+
[defaults setInteger:MMHideWhenLastWindowClosed forKey:MMLastWindowClosedBehaviorKey];
162+
}
163+
}
164+
}
165+
136166
@end

0 commit comments

Comments
 (0)