From 81fb89344542fe22e936d2e39cc4b8e766113172 Mon Sep 17 00:00:00 2001 From: Nico Weber Date: Tue, 30 Oct 2007 21:44:23 +0100 Subject: [PATCH] Vim view refactoring. This fixes the ':set lines=1000000' problem in fu mode. Furthermore, this fixes a regression that the tab sizes weren't adjusted when changing the window size. --- src/MacVim/MMFullscreenWindow.m | 35 +++--- src/MacVim/MMTextStorage.m | 1 + src/MacVim/MMVimView.h | 31 ++---- src/MacVim/MMVimView.m | 115 ++++++++++++++++++-- src/MacVim/MMWindowController.h | 3 - src/MacVim/MMWindowController.m | 229 ++++++++++++++++++++-------------------- 6 files changed, 242 insertions(+), 172 deletions(-) diff --git a/src/MacVim/MMFullscreenWindow.m b/src/MacVim/MMFullscreenWindow.m index ed0dab90..9ebc2d59 100644 --- a/src/MacVim/MMFullscreenWindow.m +++ b/src/MacVim/MMFullscreenWindow.m @@ -103,21 +103,19 @@ [self setTitle:[target title]]; [self setOpaque:[target isOpaque]]; - // make us visible and target invisible - [target orderOut:self]; - [self makeKeyAndOrderFront:self]; - // don't set this sooner, so we don't get an additional // focus gained message [self setDelegate:delegate]; // update bottom right corner scrollbar (no resize handle in fu mode) - [[self windowController] placeViews]; - - // the call above moves the text view in the lower left corner, fix that - // XXX: still required? + [view placeViews]; + + // move vim view to the window's center [self centerView]; - [self display]; + + // make us visible and target invisible + [target orderOut:self]; + [self makeKeyAndOrderFront:self]; // fade back in if (didBlend) { @@ -142,7 +140,6 @@ [self retain]; // NSWindowController releases us once [[self windowController] setWindow:target]; - [[view tabBarControl] setStyleNamed:oldTabBarStyle]; // fix delegate @@ -163,12 +160,8 @@ // sooner [target setDelegate:delegate]; - // update bottom right corner scrollbar (resize handle reappears) - // XXX: Doesn't work? - [[self windowController] placeViews]; - [view placeScrollbars]; - + [view placeViews]; // fade back in if (didBlend) { @@ -243,10 +236,14 @@ { //return [target contentRectForFrameRect:rect]; - // EVIL HACK: this is always called with [[self window] frame] as argument - // from MMWindowController. We can't let frame return the frame of target, - // so "fix" this here. - return [target contentRectForFrameRect:[target frame]]; + // EVIL HACK: if this is always called with [[self window] frame] as + // argument from MMWindowController, we can't let frame return the frame + // of target so "fix" this here. + if (NSEqualRects([self frame], rect)) { + return [target contentRectForFrameRect:[target frame]]; + } else { + return [target contentRectForFrameRect:rect]; + } } - (NSRect)frameRectForContentRect:(NSRect)contentRect diff --git a/src/MacVim/MMTextStorage.m b/src/MacVim/MMTextStorage.m index f8c717bf..21bb5181 100644 --- a/src/MacVim/MMTextStorage.m +++ b/src/MacVim/MMTextStorage.m @@ -603,6 +603,7 @@ return (unsigned)(col + row*(maxColumns+1)); } +// XXX: unused at the moment - (BOOL)resizeToFitSize:(NSSize)size { int rows = maxRows, cols = maxColumns; diff --git a/src/MacVim/MMVimView.h b/src/MacVim/MMVimView.h index be006671..8f2e3d90 100644 --- a/src/MacVim/MMVimView.h +++ b/src/MacVim/MMVimView.h @@ -29,7 +29,7 @@ MMTextStorage *textStorage; NSMutableArray *scrollbars; - // This is temporary to make the refactoring easier + // This is temporary to make the refactoring easier (XXX) BOOL shouldUpdateWindowSize; } @@ -41,25 +41,23 @@ - (BOOL)inLiveResize; - (void)cleanup; +- (NSSize)desiredSizeForActualRowsAndColumns; +- (NSSize)getDesiredRows:(int *)r columns:(int *)c forSize:(NSSize)size; +- (void)getActualRows:(int *)r columns:(int *)c; +- (void)setActualRows:(int)r columns:(int)c; - (PSMTabBarControl *)tabBarControl; -- (NSTabView *)tabView; - (IBAction)addNewTab:(id)sender; - (void)updateTabsWithData:(NSData *)data; - (void)selectTabWithIndex:(int)idx; -- (int)representedIndexOfTabViewItem:(NSTabViewItem *)tvi; - (NSTabViewItem *)addNewTabViewItem; -- (BOOL)bottomScrollbarVisible; -- (BOOL)leftScrollbarVisible; -- (BOOL)rightScrollbarVisible; -- (void)placeScrollbars; - (void)createScrollbarWithIdentifier:(long)ident type:(int)type; - (void)destroyScrollbarWithIdentifier:(long)ident; - (void)showScrollbarWithIdentifier:(long)ident state:(BOOL)visible; - (void)setScrollbarThumbValue:(float)val proportion:(float)prop identifier:(long)ident; -- (MMScroller *)scrollbarForIdentifier:(long)ident index:(unsigned *)idx; +- (void)setScrollbarPosition:(int)pos length:(int)len identifier:(long)ident; - (void)setDefaultColorsBackground:(NSColor *)back foreground:(NSColor *)fore; @@ -67,21 +65,6 @@ - (NSRect)textViewRectForContentSize:(NSSize)contentSize; - (void)setShouldUpdateWindowSize:(BOOL)b; +- (void)placeViews; // XXX: this should probably not be public -- (NSSize)contentSizeForTextStorageSize:(NSSize)textViewSize; -- (NSSize)textStorageSizeForTextViewSize:(NSSize)textViewSize; @end - -// TODO: Move! -@interface MMScroller : NSScroller { - long identifier; - int type; - NSRange range; -} -- (id)initWithIdentifier:(long)ident type:(int)type; -- (long)identifier; -- (int)type; -- (NSRange)range; -- (void)setRange:(NSRange)newRange; -@end - diff --git a/src/MacVim/MMVimView.m b/src/MacVim/MMVimView.m index a175f897..d5a1fb10 100644 --- a/src/MacVim/MMVimView.m +++ b/src/MacVim/MMVimView.m @@ -32,16 +32,44 @@ enum { @end +// TODO: Move! +@interface MMScroller : NSScroller { + long identifier; + int type; + NSRange range; +} +- (id)initWithIdentifier:(long)ident type:(int)type; +- (long)identifier; +- (int)type; +- (NSRange)range; +- (void)setRange:(NSRange)newRange; +@end + + @interface MMVimView (Private) - (BOOL)bottomScrollbarVisible; - (BOOL)leftScrollbarVisible; - (BOOL)rightScrollbarVisible; - (void)placeScrollbars; +- (int)representedIndexOfTabViewItem:(NSTabViewItem *)tvi; +- (MMScroller *)scrollbarForIdentifier:(long)ident index:(unsigned *)idx; +- (NSSize)contentSizeForTextStorageSize:(NSSize)textViewSize; +- (NSSize)textStorageSizeForTextViewSize:(NSSize)textViewSize; +- (NSTabView *)tabView; @end @implementation MMVimView +- (NSRect)tabBarFrameForFrame:(NSRect)frame +{ + NSRect tabFrame = { + { 0, frame.size.height - 22 }, + { frame.size.width, 22 } + }; + return tabFrame; +} + - (MMVimView *)initWithFrame:(NSRect)frame vimController:(MMVimController *)controller { if (![super initWithFrame:frame]) @@ -96,9 +124,7 @@ enum { // Create the tab bar control (which is responsible for actually // drawing the tabline and tabs). - NSRect tabFrame = frame; - tabFrame.origin.y = NSMaxY(tabFrame) - 22; - tabFrame.size.height = 22; + NSRect tabFrame = [self tabBarFrameForFrame:frame]; tabBarControl = [[PSMTabBarControl alloc] initWithFrame:tabFrame]; [tabView setDelegate:tabBarControl]; @@ -106,7 +132,6 @@ enum { [tabBarControl setTabView:tabView]; [tabBarControl setDelegate:self]; [tabBarControl setHidden:YES]; - [tabBarControl setAutoresizingMask:NSViewWidthSizable|NSViewMinYMargin]; [tabBarControl setCellMinWidth:[ud integerForKey:MMTabMinWidthKey]]; [tabBarControl setCellMaxWidth:[ud integerForKey:MMTabMaxWidthKey]]; [tabBarControl setCellOptimumWidth: @@ -118,8 +143,18 @@ enum { [tabBarControl setPartnerView:[self textView]]; + // tab bar resizing only works if awakeFromNib is called (that's where + // the NSViewFrameDidChangeNotification callback is installed). Sounds like + // a PSMTabBarControl bug, let's live with it for now. + [tabBarControl awakeFromNib]; + [self addSubview:tabBarControl]; + [self setPostsFrameChangedNotifications:YES]; + [[NSNotificationCenter defaultCenter] + addObserver:self selector:@selector(placeViews) + name:NSViewFrameDidChangeNotification object:self]; + return self; } @@ -182,6 +217,8 @@ enum { // removed as an observer, so remove it here (else lots of evil nasty bugs // will come and gnaw at your feet while you are sleeping). [[NSNotificationCenter defaultCenter] removeObserver:tabBarControl]; + + [[NSNotificationCenter defaultCenter] removeObserver:self]; [tabBarControl removeFromSuperviewWithoutNeedingDisplay]; [textView removeFromSuperviewWithoutNeedingDisplay]; @@ -195,6 +232,29 @@ enum { [tabView removeAllTabViewItems]; } +- (NSSize)desiredSizeForActualRowsAndColumns +{ + return [self contentSizeForTextStorageSize:[[self textStorage] size]]; +} + +- (NSSize)getDesiredRows:(int *)r columns:(int *)c forSize:(NSSize)size +{ + NSSize textViewSize = [self textViewRectForContentSize:size].size; + NSSize textStorageSize = [self textStorageSizeForTextViewSize:textViewSize]; + NSSize newSize = [textStorage fitToSize:textStorageSize rows:r columns:c]; + return [self contentSizeForTextStorageSize:newSize]; +} + +- (void)getActualRows:(int *)r columns:(int *)c +{ + [textStorage getMaxRows:r columns:c]; +} + +- (void)setActualRows:(int)r columns:(int)c +{ + [textStorage setMaxRows:r columns:c]; +} + - (IBAction)addNewTab:(id)sender { // NOTE! This can get called a lot if the user holds down the key @@ -271,6 +331,9 @@ enum { vimTaskSelectedTab = YES; [[self tabView] selectTabViewItem:tvi]; vimTaskSelectedTab = NO; + + // we might need to change the scrollbars that are visible + [self placeScrollbars]; } } @@ -547,6 +610,36 @@ enum { return nil; } +- (void)setScrollbarPosition:(int)pos length:(int)len identifier:(long)ident +{ + MMScroller *scroller = [self scrollbarForIdentifier:ident index:NULL]; + NSRange range = NSMakeRange(pos, len); + if (!NSEqualRanges(range, [scroller range])) { + //NSLog(@"Set range %@ for scroller %d", + // NSStringFromRange(range), ident); + [scroller setRange:range]; + // TODO! Should only do this once per update. + + // This could be sent because a text window was created or closed, so + // we might need to update which scrollbars are visible. + [self placeScrollbars]; + } +} + +- (void)placeViews +{ + NSRect textViewRect = [self textViewRectForContentSize:[self frame].size]; + + // Give all superfluous space to the text view. It might be smaller or + // larger than it wants to be, but this is needed during life resizing + [[self textView] setFrame:textViewRect]; + + // for some reason, autoresizing doesn't work...set tab size manually + [tabBarControl setFrame:[self tabBarFrameForFrame:[self frame]]]; + + [self placeScrollbars]; +} + - (void)setDefaultColorsBackground:(NSColor *)back foreground:(NSColor *)fore { [textStorage setDefaultColorsBackground:back foreground:fore]; @@ -567,13 +660,6 @@ enum { { NSSize size = textViewSize; - NSUserDefaults *ud = [NSUserDefaults standardUserDefaults]; - int right = [ud integerForKey:MMTextInsetRightKey]; - int bot = [ud integerForKey:MMTextInsetBottomKey]; - - size.width += [[self textView] textContainerOrigin].x + right; - size.height += [[self textView] textContainerOrigin].y + bot; - if (![[self tabBarControl] isHidden]) size.height += [[self tabBarControl] frame].size.height; @@ -584,6 +670,13 @@ enum { if ([self rightScrollbarVisible]) size.width += [NSScroller scrollerWidth]; + NSUserDefaults *ud = [NSUserDefaults standardUserDefaults]; + int right = [ud integerForKey:MMTextInsetRightKey]; + int bot = [ud integerForKey:MMTextInsetBottomKey]; + + size.width += [[self textView] textContainerOrigin].x + right; + size.height += [[self textView] textContainerOrigin].y + bot; + return size; } diff --git a/src/MacVim/MMWindowController.h b/src/MacVim/MMWindowController.h index ff1bcd8d..782bc588 100644 --- a/src/MacVim/MMWindowController.h +++ b/src/MacVim/MMWindowController.h @@ -20,7 +20,6 @@ @interface MMWindowController : NSWindowController { NSBox *tablineSeparator; - MMVimController *vimController; MMVimView *vimView; BOOL setupDone; @@ -67,5 +66,3 @@ - (IBAction)toggleToolbar:(id)sender; @end - -// vim: set ft=objc: diff --git a/src/MacVim/MMWindowController.m b/src/MacVim/MMWindowController.m index 96f20904..5a5740fa 100644 --- a/src/MacVim/MMWindowController.m +++ b/src/MacVim/MMWindowController.m @@ -22,18 +22,17 @@ @interface MMWindowController (Private) -- (NSSize)contentSizeForTextStorageSize:(NSSize)textViewSize; -- (NSRect)textViewRectForContentSize:(NSSize)contentSize; -- (NSSize)textStorageSizeForTextViewSize:(NSSize)textViewSize; +- (NSSize)contentSize; +- (NSRect)contentRectForFrameRect:(NSRect)frame; +- (NSRect)frameRectForContentRect:(NSRect)contentRect; - (void)resizeWindowToFit:(id)sender; - (NSRect)fitWindowToFrame:(NSRect)frame; - (void)updateResizeIncrements; - (NSTabViewItem *)addNewTabViewItem; -- (int)representedIndexOfTabViewItem:(NSTabViewItem *)tvi; - (IBAction)vimMenuItemAction:(id)sender; -- (MMScroller *)scrollbarForIdentifier:(long)ident index:(unsigned *)idx; - (BOOL)askBackendForStarRegister:(NSPasteboard *)pb; - (void)checkWindowNeedsResizing; +- (NSSize)resizeVimViewToFitSize:(NSSize)size; @end @@ -82,9 +81,9 @@ NSMutableArray *buildMenuAddress(NSMenu *menu) vimView = [[MMVimView alloc] initWithFrame:[contentView frame] vimController:vimController]; [contentView addSubview:vimView]; - //[vimView translateOriginToPoint: - // NSMakePoint([contentView frame].size.width, 0)]; - //[vimView rotateByAngle:45.f]; + // [vimView translateOriginToPoint: + // NSMakePoint([contentView frame].size.width, 0)]; + // [vimView rotateByAngle:45.f]; // Create the tabline separator (which may be visible when the tabline // is hidden). @@ -125,7 +124,10 @@ NSMutableArray *buildMenuAddress(NSMenu *menu) - (NSString *)description { - return [NSString stringWithFormat:@"%@ : setupDone=%d windowAutosaveKey=%@ vimController=%@", [self className], setupDone, windowAutosaveKey, vimController]; + NSString *format = + @"%@ : setupDone=%d windowAutosaveKey=%@ vimController=%@"; + return [NSString stringWithFormat:format, + [self className], setupDone, windowAutosaveKey, vimController]; } - (MMVimController *)vimController @@ -208,7 +210,7 @@ NSMutableArray *buildMenuAddress(NSMenu *menu) { //NSLog(@"setTextDimensionsWithRows:%d columns:%d", rows, cols); - [[vimView textStorage] setMaxRows:rows columns:cols]; + [vimView setActualRows:rows columns:cols]; if (setupDone && ![vimView inLiveResize]) shouldUpdateWindowSize = YES; @@ -233,17 +235,7 @@ NSMutableArray *buildMenuAddress(NSMenu *menu) - (void)setScrollbarPosition:(int)pos length:(int)len identifier:(long)ident { - MMScroller *scroller = [self scrollbarForIdentifier:ident index:NULL]; - NSRange range = NSMakeRange(pos, len); - if (!NSEqualRanges(range, [scroller range])) { - //NSLog(@"Set range %@ for scroller %d", - // NSStringFromRange(range), ident); - [scroller setRange:range]; - // TODO! Should only do this once per update. - - if (setupDone) // TODO: probably not necessary - [vimView placeScrollbars]; - } + [vimView setScrollbarPosition:pos length:len identifier:ident]; } - (void)setScrollbarThumbValue:(float)val proportion:(float)prop @@ -271,6 +263,8 @@ NSMutableArray *buildMenuAddress(NSMenu *menu) - (void)processCommandQueueDidFinish { + // XXX: If not in live resize and vimview's desired size differs from actual + // size, resize ourselves if (shouldUpdateWindowSize) { shouldUpdateWindowSize = NO; [vimView setShouldUpdateWindowSize:NO]; @@ -374,25 +368,30 @@ NSMutableArray *buildMenuAddress(NSMenu *menu) - (void)liveResizeDidEnd { - // TODO: Don't duplicate code from placeViews. - if (!setupDone) return; + // At the end of an resize, check if vim view size and number of + // columns / rows agree (the first is set while resizing, the second by + // messages sent from vim). If not, send a synchronous (!) message to vim + // to set columns / rows to the value belonging to the view size. If the + // message couldn't be sent, change the view size to fit columns / rows. + // NOTE! It is assumed that the window has been resized so that it will // exactly fit the text storage (possibly after resizing it). If this is // not the case the display might be messed up. BOOL resizeFailed = NO; - NSWindow *win = [self window]; - NSRect contentRect = [win contentRectForFrameRect:[win frame]]; - NSRect textViewRect = [self textViewRectForContentSize:contentRect.size]; - NSSize tsSize = [self textStorageSizeForTextViewSize:textViewRect.size]; + NSSize contentSize = [self contentSize]; + + int desiredSize[2]; + [vimView getDesiredRows:&desiredSize[0] columns:&desiredSize[1] + forSize:contentSize]; + + int rows, columns; + [vimView getActualRows:&rows columns:&columns]; - int dim[2], rows, cols; - [[vimView textStorage] getMaxRows:&rows columns:&cols]; - [[vimView textStorage] fitToSize:tsSize rows:&dim[0] columns:&dim[1]]; + if (desiredSize[0] != rows || desiredSize[1] != columns) { - if (dim[0] != rows || dim[1] != cols) { - NSData *data = [NSData dataWithBytes:dim length:2*sizeof(int)]; + NSData *data = [NSData dataWithBytes:desiredSize length:2*sizeof(int)]; // NOTE: Since we're at the end of a live resize we want to make sure // that the SetTextDimensionsMsgID message reaches Vim, else Vim and @@ -405,10 +404,6 @@ NSMutableArray *buildMenuAddress(NSMenu *menu) timeout:.5]; } - [[vimView textView] setFrame:textViewRect]; - - [vimView placeScrollbars]; - if (resizeFailed) { // Force the window size to match the text view size otherwise Vim and // MacVim will have inconsistent states. @@ -427,52 +422,20 @@ NSMutableArray *buildMenuAddress(NSMenu *menu) { if (!setupDone) return; - // NOTE! It is assumed that the window has been resized so that it will - // exactly fit the text storage (possibly after resizing it). If this is - // not the case the display might be messed up. - NSWindow *win = [self window]; - NSRect contentRect = [win contentRectForFrameRect:[win frame]]; - NSRect textViewRect = [self textViewRectForContentSize:contentRect.size]; - NSSize tsSize = [self textStorageSizeForTextViewSize:textViewRect.size]; - - // If our optimal (rows,cols) do not match our current (rows,cols), resize - // ourselves and tell the Vim process to sync up. - int dim[2], rows, cols; - [[vimView textStorage] getMaxRows:&rows columns:&cols]; - [[vimView textStorage] fitToSize:tsSize rows:&dim[0] columns:&dim[1]]; - - if (dim[0] != rows || dim[1] != cols) { - //NSLog(@"Notify Vim that text storage dimensions changed " - // @"from %dx%d to %dx%d", cols, rows, dim[1], dim[0]); - NSData *data = [NSData dataWithBytes:dim length:2*sizeof(int)]; - - [vimController sendMessage:SetTextDimensionsMsgID data:data]; - - // We only want to set the window title if this resize came from - // a live-resize, not (for example) setting 'columns' or 'lines'. - if ([[self textView] inLiveResize]) { - [win setTitle:[NSString stringWithFormat:@"%dx%d", - dim[1], dim[0]]]; - } - } - - // XXX: put vimView resizing logic in vimView - [[vimView textView] setFrame:textViewRect]; - - NSRect vimViewRect = textViewRect; + NSRect vimViewRect; vimViewRect.origin = NSMakePoint(0, 0); - if (![[vimView tabBarControl] isHidden]) - vimViewRect.size.height += [[vimView tabBarControl] frame].size.height; - if ([vimView bottomScrollbarVisible]) - vimViewRect.size.height += [NSScroller scrollerWidth]; - if ([vimView leftScrollbarVisible]) - vimViewRect.size.width += [NSScroller scrollerWidth]; - if ([vimView rightScrollbarVisible]) - vimViewRect.size.width += [NSScroller scrollerWidth]; - - [vimView setFrame:vimViewRect]; + vimViewRect.size = [vimView getDesiredRows:NULL columns:NULL + forSize:[self contentSize]]; - [vimView placeScrollbars]; + // HACK! If the window does resize, then windowDidResize is called which in + // turn calls placeViews. In case the computed new size of the window is + // no different from the current size, then we need to call placeViews + // manually. + if (NSEqualRects(vimViewRect, [vimView frame])) { + [vimView placeViews]; + } else { + [vimView setFrame:vimViewRect]; + } } - (void)enterFullscreen @@ -546,7 +509,23 @@ NSMutableArray *buildMenuAddress(NSMenu *menu) - (void)windowDidResize:(id)sender { if (!setupDone) return; - [self placeViews]; + + // Live resizing works as follows: + // VimView's size is changed immediatly, and a resize message to the + // remote vim instance is sent. The remote vim instance sends a + // "vim content size changed" right back, but in live resize mode this + // doesn't change the VimView (because we assume that it already has the + // correct size because we set the resize increments correctly). Afterward, + // the remote vim view sends a batch draw for the text visible in the + // resized text area. + + NSSize contentSize = [self contentSize]; + [self resizeVimViewToFitSize:contentSize]; + + NSRect frame; + frame.origin = NSMakePoint(0, 0); + frame.size = contentSize; + [vimView setFrame:frame]; } - (NSRect)windowWillUseStandardFrame:(NSWindow *)win @@ -570,7 +549,7 @@ NSMutableArray *buildMenuAddress(NSMenu *menu) frame = [self fitWindowToFrame:frame]; - // Keep old width and horizontal position unless user clicked with the + // Keep old width and horizontal position unless user clicked while the // Command key is held down. NSEvent *event = [NSApp currentEvent]; if (!([event type] == NSLeftMouseUp @@ -613,30 +592,32 @@ NSMutableArray *buildMenuAddress(NSMenu *menu) @implementation MMWindowController (Private) -- (NSSize)contentSizeForTextStorageSize:(NSSize)textViewSize +- (NSRect)contentRectForFrameRect:(NSRect)frame { - NSSize size = [vimView contentSizeForTextStorageSize:textViewSize]; + NSRect result = [[self window] contentRectForFrameRect:frame]; if (![tablineSeparator isHidden]) - ++size.height; - return size; + --result.size.height; + return result; } -- (NSRect)textViewRectForContentSize:(NSSize)contentSize +- (NSRect)frameRectForContentRect:(NSRect)contentRect { - NSSize size = { contentSize.width, contentSize.height }; if (![tablineSeparator isHidden]) - --size.height; - - return [vimView textViewRectForContentSize:size]; + ++contentRect.size.height; + return [[self window] frameRectForContentRect:contentRect]; } -- (NSSize)textStorageSizeForTextViewSize:(NSSize)textViewSize +- (NSSize)contentSize { - return [vimView textStorageSizeForTextViewSize:textViewSize]; + return [self contentRectForFrameRect:[[self window] frame]].size; } - (void)resizeWindowToFit:(id)sender { + // Makes the window large enough to contain the vim view, called after the + // vim view's size was changed. If the window had to become to big, the + // vim view is made smaller. + // NOTE: Be very careful when you call this method! Do not call while // processing command queue, instead set 'shouldUpdateWindowSize' to YES. // The only other place it is currently called is when live resize ends. @@ -646,17 +627,17 @@ NSMutableArray *buildMenuAddress(NSMenu *menu) if (!setupDone) return; + // Get size of text view, adapt window size to it NSWindow *win = [self window]; NSRect frame = [win frame]; - NSRect contentRect = [win contentRectForFrameRect:frame]; - NSSize textStorageSize = [[vimView textStorage] size]; - NSSize newSize = [self contentSizeForTextStorageSize:textStorageSize]; + NSRect contentRect = [self contentRectForFrameRect:frame]; + NSSize newSize = [vimView desiredSizeForActualRowsAndColumns]; // Keep top-left corner of the window fixed when resizing. contentRect.origin.y -= newSize.height - contentRect.size.height; contentRect.size = newSize; - frame = [win frameRectForContentRect:contentRect]; + frame = [self frameRectForContentRect:contentRect]; NSRect maxFrame = [win constrainFrameRect:frame toScreen:[win screen]]; // HACK! Assuming the window frame cannot already be placed too high, @@ -673,9 +654,10 @@ NSMutableArray *buildMenuAddress(NSMenu *menu) // text storage to the biggest frame which will fit on the screen. //NSLog(@"Proposed window frame does not fit on the screen!"); frame = [self fitWindowToFrame:maxFrame]; + [self resizeVimViewToFitSize:[self contentRectForFrameRect:frame].size]; } - //NSLog(@"%s %@", _cmd, NSStringFromRect(frame)); + // NSLog(@"%s %@", _cmd, NSStringFromRect(frame)); // HACK! If the window does resize, then windowDidResize is called which in // turn calls placeViews. In case the computed new size of the window is @@ -692,18 +674,15 @@ NSMutableArray *buildMenuAddress(NSMenu *menu) { if (!setupDone) return frame; - NSWindow *win = [self window]; - NSRect contentRect = [win contentRectForFrameRect:frame]; - NSSize size = [self textViewRectForContentSize:contentRect.size].size; - size = [self textStorageSizeForTextViewSize:size]; - size = [[vimView textStorage] fitToSize:size]; - size = [self contentSizeForTextStorageSize:size]; + NSRect contentRect = [self contentRectForFrameRect:frame]; + NSSize size = [vimView getDesiredRows:NULL columns:NULL + forSize:contentRect.size]; // Keep top-left corner of 'frame' fixed. contentRect.origin.y -= size.height - contentRect.size.height; contentRect.size = size; - return [win frameRectForContentRect:contentRect]; + return [self frameRectForContentRect:contentRect]; } - (void)updateResizeIncrements @@ -719,11 +698,6 @@ NSMutableArray *buildMenuAddress(NSMenu *menu) return [vimView addNewTabViewItem]; } -- (int)representedIndexOfTabViewItem:(NSTabViewItem *)tvi -{ - return [vimView representedIndexOfTabViewItem:tvi]; -} - - (IBAction)vimMenuItemAction:(id)sender { int tag = [sender tag]; @@ -734,11 +708,6 @@ NSMutableArray *buildMenuAddress(NSMenu *menu) [vimController sendMessage:ExecuteMenuMsgID data:data]; } -- (MMScroller *)scrollbarForIdentifier:(long)ident index:(unsigned *)idx -{ - return [vimView scrollbarForIdentifier:ident index:idx]; -} - - (BOOL)askBackendForStarRegister:(NSPasteboard *)pb { BOOL reply = NO; @@ -762,4 +731,34 @@ NSMutableArray *buildMenuAddress(NSMenu *menu) shouldUpdateWindowSize || [vimView shouldUpdateWindowSize]; } +- (NSSize)resizeVimViewToFitSize:(NSSize)size +{ + // If our optimal (rows,cols) do not match our current (rows,cols), resize + // ourselves and tell the Vim process to sync up. + int desired[2]; + NSSize newSize = [vimView getDesiredRows:&desired[0] columns:&desired[1] + forSize:size]; + + int rows, columns; + [vimView getActualRows:&rows columns:&columns]; + + if (desired[0] != rows || desired[1] != columns) { + // NSLog(@"Notify Vim that text storage dimensions changed from %dx%d " + // @"to %dx%d", columns, rows, desired[0], desired[1]); + NSData *data = [NSData dataWithBytes:desired length:2*sizeof(int)]; + + [vimController sendMessage:SetTextDimensionsMsgID data:data]; + + // We only want to set the window title if this resize came from + // a live-resize, not (for example) setting 'columns' or 'lines'. + if ([[self textView] inLiveResize]) { + [[self window] setTitle:[NSString stringWithFormat:@"%dx%d", + desired[1], desired[0]]]; + } + } + + return newSize; +} + + @end // MMWindowController (Private) -- 2.11.4.GIT