diff --git a/MMAppController.h b/MMAppController.h index abf9a69bf0..d73becf36b 100644 --- a/MMAppController.h +++ b/MMAppController.h @@ -28,13 +28,15 @@ extern NSString *MMCellWidthMultiplierKey; extern NSString *MMBaselineOffsetKey; +@class MMWindowController; -@interface MMAppController : NSObject -{ + +@interface MMAppController : NSObject { NSMutableArray *vimControllers; } - (void)removeVimController:(id)controller; +- (void)windowControllerWillOpen:(MMWindowController *)windowController; - (IBAction)newVimWindow:(id)sender; - (IBAction)selectNextWindow:(id)sender; - (IBAction)selectPreviousWindow:(id)sender; diff --git a/MMAppController.m b/MMAppController.m index 220cec88db..82bb04934c 100644 --- a/MMAppController.m +++ b/MMAppController.m @@ -10,6 +10,7 @@ #import "MMAppController.h" #import "MMVimController.h" +#import "MMWindowController.h" @@ -30,6 +31,10 @@ NSString *MMCellWidthMultiplierKey = @"cellwidthmultiplier"; NSString *MMBaselineOffsetKey = @"baselineoffset"; +// Key in user defaults for autosave data. +NSString *MMAutosaveKey = @"DefaultWindow"; + + @interface MMAppController (MMServices) - (void)openSelection:(NSPasteboard *)pboard userData:(NSString *)userData @@ -249,6 +254,42 @@ NSString *MMBaselineOffsetKey = @"baselineoffset"; } } +- (void)windowControllerWillOpen:(MMWindowController *)windowController +{ + NSPoint topLeft = NSZeroPoint; + NSWindow *keyWin = [NSApp keyWindow]; + NSWindow *win = [windowController window]; + + if (!win) return; + + // If there is a key window, cascade from it, otherwise use the autosaved + // window position (if any). + if (keyWin) { + NSRect frame = [keyWin frame]; + topLeft = NSMakePoint(frame.origin.x, NSMaxY(frame)); + } else { + NSDictionary *dict = [[NSUserDefaults standardUserDefaults] + dictionaryForKey:MMAutosaveKey]; + if (dict) { + id x = [dict objectForKey:@"x"]; + id y = [dict objectForKey:@"y"]; + + if (x && [x isKindOfClass:[NSNumber class]] && + y && [y isKindOfClass:[NSNumber class]]) { + topLeft.x = [x floatValue]; + topLeft.y = [y floatValue]; + } + } + } + + if (!NSEqualPoints(topLeft, NSZeroPoint)) { + if (keyWin) + topLeft = [win cascadeTopLeftFromPoint:topLeft]; + + [win setFrameTopLeftPoint:topLeft]; + } +} + - (IBAction)newVimWindow:(id)sender { NSMutableArray *args = [NSMutableArray arrayWithObject:@"-g"]; @@ -311,15 +352,23 @@ NSString *MMBaselineOffsetKey = @"baselineoffset"; [(NSDistantObject*)backend setProtocolForProxy:@protocol(MMBackendProtocol)]; - MMVimController *wc = [[[MMVimController alloc] initWithBackend:backend] + MMVimController *vc = [[[MMVimController alloc] initWithBackend:backend] autorelease]; - [vimControllers addObject:wc]; + + if (![vimControllers count]) { + // The first window autosaves its position. (The autosaving features + // of Cocoa are not used because we need more control over what is + // autosaved and when it is restored.) + [[vc windowController] setWindowAutosaveKey:MMAutosaveKey]; + } + + [vimControllers addObject:vc]; // HACK! MacVim does not get activated if it is launched from the // terminal, so we forcibly activate here. [NSApp activateIgnoringOtherApps:YES]; - return wc; + return vc; } @end // MMAppController diff --git a/MMBackend.h b/MMBackend.h index 7742a499af..f4a8499520 100644 --- a/MMBackend.h +++ b/MMBackend.h @@ -13,8 +13,7 @@ -@interface MMBackend : NSObject -{ +@interface MMBackend : NSObject { NSMutableArray *queue; NSMutableData *drawData; NSConnection *connection; diff --git a/MMWindowController.h b/MMWindowController.h index 144c2f43a2..39c8c8515a 100644 --- a/MMWindowController.h +++ b/MMWindowController.h @@ -16,8 +16,7 @@ @class MMVimController; -@interface MMWindowController : NSWindowController -{ +@interface MMWindowController : NSWindowController { IBOutlet PSMTabBarControl *tabBarControl; IBOutlet NSTabView *tabView; IBOutlet NSTextField *statusTextField; @@ -32,12 +31,15 @@ NSMutableArray *scrollbars; BOOL setupDone; BOOL shouldUpdateWindowSize; + NSString *windowAutosaveKey; } - (id)initWithVimController:(MMVimController *)controller; - (MMVimController *)vimController; - (MMTextView *)textView; - (MMTextStorage *)textStorage; +- (NSString *)windowAutosaveKey; +- (void)setWindowAutosaveKey:(NSString *)key; - (void)openWindow; - (void)updateTabsWithData:(NSData *)data; - (void)selectTabWithIndex:(int)idx; diff --git a/MMWindowController.m b/MMWindowController.m index 6660df839b..bc33cc0911 100644 --- a/MMWindowController.m +++ b/MMWindowController.m @@ -67,6 +67,7 @@ static float StatusLineHeight = 16.0f; - (void)placeScrollbars; - (void)scroll:(id)sender; - (void)placeViews; +- (NSDictionary *)windowAutosaveDict; @end @@ -102,6 +103,9 @@ NSMutableArray *buildMenuAddress(NSMenu *menu) vimController = controller; scrollbars = [[NSMutableArray alloc] init]; + // Window cascading is handled by MMAppController. + [self setShouldCascadeWindows:NO]; + // Setup a complete text system. textStorage = [[MMTextStorage alloc] init]; NSLayoutManager *lm = [[NSLayoutManager alloc] init]; @@ -220,8 +224,21 @@ NSMutableArray *buildMenuAddress(NSMenu *menu) return textStorage; } +- (NSString *)windowAutosaveKey +{ + return windowAutosaveKey; +} + +- (void)setWindowAutosaveKey:(NSString *)key +{ + [windowAutosaveKey autorelease]; + windowAutosaveKey = [key copy]; +} + - (void)openWindow { + [[NSApp delegate] windowControllerWillOpen:self]; + [self addNewTabViewItem]; // NOTE! This flag is set once the entire text system is set up. @@ -229,7 +246,6 @@ NSMutableArray *buildMenuAddress(NSMenu *menu) [self updateResizeIncrements]; [self resizeWindowToFit:self]; - [[self window] makeKeyAndOrderFront:self]; BOOL statusOff = [[NSUserDefaults standardUserDefaults] @@ -541,6 +557,16 @@ NSMutableArray *buildMenuAddress(NSMenu *menu) [tabBarControl setDelegate:nil]; } +- (void)windowDidMove:(NSNotification *)notification +{ + if (windowAutosaveKey) { + NSDictionary *dict = [self windowAutosaveDict]; + if (dict) + [[NSUserDefaults standardUserDefaults] + setObject:dict forKey:windowAutosaveKey]; + } +} + - (void)windowDidResize:(id)sender { if (!setupDone) return; @@ -1039,6 +1065,30 @@ NSMutableArray *buildMenuAddress(NSMenu *menu) [self placeScrollbars]; } +- (NSDictionary *)windowAutosaveDict +{ + if (!setupDone) + return nil; + + int rows = 0, cols = 0; + if (textStorage) + [textStorage getMaxRows:&rows columns:&cols]; + + NSPoint origin = NSZeroPoint; + if (setupDone) { + NSRect frame = [[self window] frame]; + origin = NSMakePoint(frame.origin.x, NSMaxY(frame)); + } + + NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys: + [NSNumber numberWithInt:rows], @"Rows", + [NSNumber numberWithInt:cols], @"Columns", + [NSNumber numberWithFloat:origin.x], @"x", + [NSNumber numberWithFloat:origin.y], @"y", nil]; + + return dict; +} + @end // MMWindowController (Private)