I am using a standard AppKit NSPersistentDocument document base application and would like a document's window to remember its location and open in the same position it was last closed in.
Note that setting the autosavename in IB on the Window will result in all documents opening in the same position. I want a document to remember its position based on the documents filename.
I have subclassed NSPersistentDocument and currently set the autosave name in the windowControllerDidLoadNib:
function. This almost works fine, except that if I open and close the same document repeatedly without closing the App then each time its window's height is increased a small amount (26 pixels), almost like its doing the cascade thing. However if I close the App completely and reopen it then the document remembers its previous position exactly. Am I doing something wrong or is this a bug. Is there some cleanup I should be doing perhaps to ensure that the window is not being resized each time its re-opened.
// NSPersistentDocument subclass
- (void)windowControllerDidLoadNib:(NSWindowController *)aController
{
LOG(@"windowControllerDidLoadNib called...");
[super windowControllerDidLoadNib:aController];
if ([self autoSaveName] != nil) {
[aController setWindowFrameAutosaveName:[self autoSaveName]];
}
[aController setShouldCascadeWindows:NO];
}
- (NSString*)autoSaveName
{
return [[self fileURL] lastPathComponent];
}
If I add the following code to add 22 pixels to its height
- (NSRect)windowPositionPreference {
LOG(@"printUserDefaults called");
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSString *autosaveNameKey = [NSString stringWithFormat:@"NSWindow Frame %@", [self autoSaveName]];
NSString *frameString = [defaults objectForKey:autosaveNameKey];
NSArray *array = [frameString componentsSeparatedByString:@" "];
CGFloat x = [[array objectAtIndex:0] floatValue];
CGFloat y = [[array objectAtIndex:1] floatValue];
CGFloat width = [[array objectAtIndex:2] floatValue];
CGFloat height = [[array objectAtIndex:3] floatValue];
NSRect rect = CGRectMake(x, y, width, height+22);
FLOG(@" window frame = %fx, %fy, %fw, %fh", x, y, width, height);
return rect;
}
and then set the frame like so in - (void)windowControllerDidLoadNib:(NSWindowController *)aController
NSRect rect = [self windowPositionPreference];
[aController.window setFrame:rect display:YES];
The position seems to be retained exactly. Surely autosavename is just meant to work.