1 /* vi:set ts=8 sts=4 sw=4 ft=objc:
3 * VIM - Vi IMproved by Bram Moolenaar
4 * MacVim GUI port by Bjorn Winckler
6 * Do ":help uganda" in Vim to read copying and usage conditions.
7 * Do ":help credits" in Vim to see a list of people who contributed.
8 * See README.txt for an overview of the Vim source code.
13 * Handles resizing of windows, acts as an mediator between MMVimView and
17 #import "MMWindowController.h"
18 #import <PSMTabBarControl.h>
19 #import "MMTextView.h"
20 #import "MMTextStorage.h"
21 #import "MMVimController.h"
23 #import "MMAppController.h"
24 #import "MMTypesetter.h"
25 #import "MMFullscreenWindow.h"
30 @interface MMWindowController (Private)
31 - (NSSize)contentSize;
32 - (NSRect)contentRectForFrameRect:(NSRect)frame;
33 - (NSRect)frameRectForContentRect:(NSRect)contentRect;
34 - (void)resizeWindowToFit:(id)sender;
35 - (NSRect)fitWindowToFrame:(NSRect)frame;
36 - (void)updateResizeIncrements;
37 - (NSTabViewItem *)addNewTabViewItem;
38 - (IBAction)vimMenuItemAction:(id)sender;
39 - (BOOL)askBackendForStarRegister:(NSPasteboard *)pb;
40 - (void)checkWindowNeedsResizing;
41 - (NSSize)resizeVimViewToFitSize:(NSSize)size;
47 NSString *buildMenuItemDescriptor(NSMenu *menu, NSString *tail)
49 return menu ? buildMenuItemDescriptor([menu supermenu], [[menu title]
50 stringByAppendingString:tail])
54 NSMutableArray *buildMenuAddress(NSMenu *menu)
58 addr = buildMenuAddress([menu supermenu]);
59 [addr addObject:[menu title]];
61 addr = [NSMutableArray array];
68 @interface NSWindow (NSWindowPrivate)
69 // Note: This hack allows us to set content shadowing separately from
70 // the window shadow. This is apparently what webkit and terminal do.
71 - (void)_setContentHasShadow:(BOOL)shadow; // new Tiger private method
73 // This is a private api that makes textured windows not have rounded corners.
74 // We want this on Leopard.
75 - (void)setBottomCornerRounded:(BOOL)rounded;
78 @interface NSWindow (NSLeopardOnly)
79 // Note: These functions are Leopard-only, use -[NSObject respondsToSelector:]
80 // before calling them to make sure everything works on Tiger too.
82 #ifndef CGFLOAT_DEFINED
83 // On Leopard, CGFloat is float on 32bit and double on 64bit. On Tiger,
84 // we can't use this anyways, so it's just here to keep the compiler happy.
85 // However, when we're compiling for Tiger and running on Leopard, we
86 // might need the correct typedef, so this piece is copied from ATSTypes.h
88 typedef double CGFloat;
90 typedef float CGFloat;
93 - (void)setAutorecalculatesContentBorderThickness:(BOOL)b forEdge:(NSRectEdge)e;
94 - (void)setContentBorderThickness:(CGFloat)b forEdge:(NSRectEdge)e;
100 @implementation MMWindowController
102 - (id)initWithVimController:(MMVimController *)controller
104 #ifndef NSAppKitVersionNumber10_4 // needed for non-10.5 sdk
105 # define NSAppKitVersionNumber10_4 824
107 unsigned styleMask = NSTitledWindowMask | NSClosableWindowMask
108 | NSMiniaturizableWindowMask | NSResizableWindowMask
109 | NSUnifiedTitleAndToolbarWindowMask;
111 // Use textured background on Leopard or later (skip the 'if' on Tiger for
112 // polished metal window).
113 if (floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_4)
114 styleMask |= NSTexturedBackgroundWindowMask;
116 // NOTE: The content rect is only used the very first time MacVim is
117 // started (or rather, when ~/Library/Preferences/org.vim.MacVim.plist does
118 // not exist). The chosen values will put the window somewhere near the
119 // top and in the middle of a 1024x768 screen.
120 NSWindow *win = [[NSWindow alloc]
121 initWithContentRect:NSMakeRect(242,364,480,360)
123 backing:NSBackingStoreBuffered
126 if ((self = [super initWithWindow:win])) {
127 vimController = controller;
129 // Window cascading is handled by MMAppController.
130 [self setShouldCascadeWindows:NO];
132 NSView *contentView = [win contentView];
133 vimView = [[MMVimView alloc] initWithFrame:[contentView frame]
134 vimController:vimController];
135 [contentView addSubview:vimView];
137 // Create the tabline separator (which may be visible when the tabline
138 // is hidden). See showTabBar: for circumstances when the separator
140 NSRect tabSepRect = [contentView frame];
141 tabSepRect.origin.y = NSMaxY(tabSepRect)-1;
142 tabSepRect.size.height = 1;
143 tablineSeparator = [[NSBox alloc] initWithFrame:tabSepRect];
145 [tablineSeparator setBoxType:NSBoxSeparator];
146 [tablineSeparator setHidden:NO];
147 [tablineSeparator setAutoresizingMask:NSViewWidthSizable
150 [contentView setAutoresizesSubviews:YES];
151 [contentView addSubview:tablineSeparator];
153 [win setDelegate:self];
154 [win setInitialFirstResponder:[vimView textView]];
156 if ([win styleMask] & NSTexturedBackgroundWindowMask) {
157 // On Leopard, we want to have a textured window to have nice
158 // looking tabs. But the textured window look implies rounded
159 // corners, which looks really weird -- disable them. This is a
160 // private api, though.
161 if ([win respondsToSelector:@selector(setBottomCornerRounded:)])
162 [win setBottomCornerRounded:NO];
164 // When the tab bar is toggled, it changes color for the fraction
165 // of a second, probably because vim sends us events in a strange
166 // order, confusing appkit's content border heuristic for a short
167 // while. This can be worked around with these two methods. There
168 // might be a better way, but it's good enough.
169 if ([win respondsToSelector:@selector(
170 setAutorecalculatesContentBorderThickness:forEdge:)])
171 [win setAutorecalculatesContentBorderThickness:NO
173 if ([win respondsToSelector:
174 @selector(setContentBorderThickness:forEdge:)])
175 [win setContentBorderThickness:0 forEdge:NSMaxYEdge];
178 // Make us safe on pre-tiger OSX
179 if ([win respondsToSelector:@selector(_setContentHasShadow:)])
180 [win _setContentHasShadow:NO];
190 //NSLog(@"%@ %s", [self className], _cmd);
192 [tablineSeparator release]; tablineSeparator = nil;
193 [windowAutosaveKey release]; windowAutosaveKey = nil;
194 [vimView release]; vimView = nil;
199 - (NSString *)description
202 @"%@ : setupDone=%d windowAutosaveKey=%@ vimController=%@";
203 return [NSString stringWithFormat:format,
204 [self className], setupDone, windowAutosaveKey, vimController];
207 - (MMVimController *)vimController
209 return vimController;
212 - (MMTextView *)textView
214 return [vimView textView];
217 - (MMTextStorage *)textStorage
219 return [vimView textStorage];
222 - (MMVimView *)vimView
227 - (NSString *)windowAutosaveKey
229 return windowAutosaveKey;
232 - (void)setWindowAutosaveKey:(NSString *)key
234 [windowAutosaveKey autorelease];
235 windowAutosaveKey = [key copy];
240 //NSLog(@"%@ %s", [self className], _cmd);
242 if (fullscreenWindow != nil) {
243 // if we are closed while still in fullscreen, end fullscreen mode,
244 // release ourselves (because this won't happen in MMWindowController)
245 // and perform close operation on the original window
246 [self leaveFullscreen];
252 [tablineSeparator removeFromSuperviewWithoutNeedingDisplay];
253 [vimView removeFromSuperviewWithoutNeedingDisplay];
254 [vimView cleanup]; // TODO: is this necessary?
256 [[self window] orderOut:self];
261 [[NSApp delegate] windowControllerWillOpen:self];
263 [self addNewTabViewItem];
267 [self updateResizeIncrements];
268 [self resizeWindowToFit:self];
269 [[self window] makeKeyAndOrderFront:self];
272 - (void)updateTabsWithData:(NSData *)data
274 [vimView updateTabsWithData:data];
277 - (void)selectTabWithIndex:(int)idx
279 [vimView selectTabWithIndex:idx];
282 - (void)setTextDimensionsWithRows:(int)rows columns:(int)cols
284 //NSLog(@"setTextDimensionsWithRows:%d columns:%d", rows, cols);
286 [vimView setActualRows:rows columns:cols];
288 if (setupDone && ![vimView inLiveResize])
289 shouldUpdateWindowSize = YES;
292 - (void)createScrollbarWithIdentifier:(long)ident type:(int)type
294 [vimView createScrollbarWithIdentifier:ident type:type];
297 - (void)destroyScrollbarWithIdentifier:(long)ident
299 [vimView destroyScrollbarWithIdentifier:ident];
300 [self checkWindowNeedsResizing];
303 - (void)showScrollbarWithIdentifier:(long)ident state:(BOOL)visible
305 [vimView showScrollbarWithIdentifier:ident state:visible];
306 [self checkWindowNeedsResizing];
309 - (void)setScrollbarPosition:(int)pos length:(int)len identifier:(long)ident
311 [vimView setScrollbarPosition:pos length:len identifier:ident];
314 - (void)setScrollbarThumbValue:(float)val proportion:(float)prop
315 identifier:(long)ident
317 [vimView setScrollbarThumbValue:val proportion:prop identifier:ident];
320 - (void)setDefaultColorsBackground:(NSColor *)back foreground:(NSColor *)fore
322 // NOTE: This is called when the transparency changes so set the opacity
323 // flag on the window here (should be faster if the window is opaque).
324 BOOL isOpaque = [back alphaComponent] == 1.0f;
325 [[self window] setOpaque:isOpaque];
327 [vimView setDefaultColorsBackground:back foreground:fore];
330 - (void)setFont:(NSFont *)font
332 [[NSFontManager sharedFontManager] setSelectedFont:font isMultiple:NO];
333 [[vimView textStorage] setFont:font];
334 [self updateResizeIncrements];
337 - (void)setWideFont:(NSFont *)font
339 [[vimView textStorage] setWideFont:font];
342 - (void)processCommandQueueDidFinish
344 // XXX: If not in live resize and vimview's desired size differs from actual
345 // size, resize ourselves
346 if (shouldUpdateWindowSize) {
347 shouldUpdateWindowSize = NO;
348 [vimView setShouldUpdateWindowSize:NO];
349 [self resizeWindowToFit:self];
353 - (void)popupMenu:(NSMenu *)menu atRow:(int)row column:(int)col
355 if (!setupDone) return;
358 if (row >= 0 && col >= 0) {
359 NSSize cellSize = [[vimView textStorage] cellSize];
360 NSPoint pt = { (col+1)*cellSize.width, (row+1)*cellSize.height };
361 pt = [[vimView textView] convertPoint:pt toView:nil];
363 event = [NSEvent mouseEventWithType:NSRightMouseDown
367 windowNumber:[[self window] windowNumber]
373 event = [[vimView textView] lastMouseDownEvent];
376 [NSMenu popUpContextMenu:menu withEvent:event forView:[vimView textView]];
379 - (void)showTabBar:(BOOL)on
381 [[vimView tabBarControl] setHidden:!on];
383 // Rules for when to show tabline separator:
385 // Tabline visible & Toolbar visible => Separator visible
386 // ================================================================
387 // NO & NO => NO (Tiger), YES (Leopard)
392 // XXX: This is ignored if called while in fullscreen mode
394 NSToolbar *toolbar = [[self window] toolbar];
395 if (([[self window] styleMask] & NSTexturedBackgroundWindowMask) == 0) {
396 [tablineSeparator setHidden:![toolbar isVisible]];
398 [tablineSeparator setHidden:NO];
401 if (([[self window] styleMask] & NSTexturedBackgroundWindowMask) == 0) {
402 [tablineSeparator setHidden:on];
404 [tablineSeparator setHidden:YES];
409 // shouldUpdateWindowSize = YES;
412 - (void)showToolbar:(BOOL)on size:(int)size mode:(int)mode
414 NSToolbar *toolbar = [[self window] toolbar];
415 if (!toolbar) return;
417 [toolbar setSizeMode:size];
418 [toolbar setDisplayMode:mode];
419 [toolbar setVisible:on];
421 // See showTabBar: for circumstances when the separator should be hidden.
422 if (([[self window] styleMask] & NSTexturedBackgroundWindowMask) == 0) {
424 [tablineSeparator setHidden:YES];
426 [tablineSeparator setHidden:![[vimView tabBarControl] isHidden]];
429 // Textured windows don't have a line below there title bar, so we
430 // need the separator in this case as well. In fact, the only case
431 // where we don't need the separator is when the tab bar control
432 // is visible (because it brings its own separator).
433 [tablineSeparator setHidden:![[vimView tabBarControl] isHidden]];
437 - (void)setMouseShape:(int)shape
439 // This switch should match mshape_names[] in misc2.c.
441 // TODO: Add missing cursor shapes.
443 case 2: [[NSCursor IBeamCursor] set]; break;
444 case 3: case 4: [[NSCursor resizeUpDownCursor] set]; break;
445 case 5: case 6: [[NSCursor resizeLeftRightCursor] set]; break;
446 case 9: [[NSCursor crosshairCursor] set]; break;
447 case 10: [[NSCursor pointingHandCursor] set]; break;
448 case 11: [[NSCursor openHandCursor] set]; break;
450 [[NSCursor arrowCursor] set]; break;
453 // Shape 1 indicates that the mouse cursor should be hidden.
455 [NSCursor setHiddenUntilMouseMoves:YES];
458 - (void)adjustLinespace:(int)linespace
460 if (vimView && [vimView textStorage]) {
461 [[vimView textStorage] setLinespace:(float)linespace];
462 shouldUpdateWindowSize = YES;
466 - (void)liveResizeWillStart
468 // Save the original title, if we haven't already.
469 if (lastSetTitle == nil) {
470 lastSetTitle = [[[self window] title] retain];
474 - (void)liveResizeDidEnd
476 if (!setupDone) return;
478 // NOTE: During live resize the window is not constrained to lie inside the
479 // screen (because we must not programmatically alter the window size
480 // during live resize or it will 'jitter'), so at the end of live resize we
481 // make sure a final SetTextDimensionsMsgID message is sent to ensure that
482 // resizeWindowToFit does get called. For this reason and also because we
483 // want to ensure that Vim and MacVim have consistent states, this resize
484 // message is sent synchronously. (If the states were inconsistent the
485 // text view may become too large or too small to fit the window.)
487 NSSize contentSize = [self contentSize];
490 [vimView getDesiredRows:&desiredSize[0] columns:&desiredSize[1]
491 forSize:contentSize];
493 NSData *data = [NSData dataWithBytes:desiredSize length:2*sizeof(int)];
495 BOOL resizeOk = [vimController sendMessageNow:SetTextDimensionsMsgID
500 // Force the window size to match the text view size otherwise Vim and
501 // MacVim will have inconsistent states.
502 [self resizeWindowToFit:self];
505 // If we saved the original title while resizing, restore it.
506 if (lastSetTitle != nil) {
507 [[self window] setTitle:lastSetTitle];
508 [lastSetTitle release];
515 if (!setupDone) return;
518 vimViewRect.origin = NSMakePoint(0, 0);
519 vimViewRect.size = [vimView getDesiredRows:NULL columns:NULL
520 forSize:[self contentSize]];
522 // HACK! If the window does resize, then windowDidResize is called which in
523 // turn calls placeViews. In case the computed new size of the window is
524 // no different from the current size, then we need to call placeViews
526 if (NSEqualRects(vimViewRect, [vimView frame])) {
527 [vimView placeViews];
529 [vimView setFrame:vimViewRect];
533 - (void)enterFullscreen
535 fullscreenWindow = [[MMFullscreenWindow alloc] initWithWindow:[self window]
537 [fullscreenWindow enterFullscreen];
539 [fullscreenWindow setDelegate:self];
542 - (void)leaveFullscreen
544 [fullscreenWindow leaveFullscreen];
545 [fullscreenWindow release];
546 fullscreenWindow = nil;
550 - (IBAction)addNewTab:(id)sender
552 [vimView addNewTab:sender];
555 - (IBAction)toggleToolbar:(id)sender
557 [vimController sendMessage:ToggleToolbarMsgID data:nil];
562 // -- NSWindow delegate ------------------------------------------------------
564 - (void)windowDidBecomeMain:(NSNotification *)notification
566 [vimController sendMessage:GotFocusMsgID data:nil];
568 if ([vimView textStorage]) {
569 NSFontManager *fontManager = [NSFontManager sharedFontManager];
570 [fontManager setSelectedFont:[[vimView textStorage] font]
575 - (void)windowDidResignMain:(NSNotification *)notification
577 [vimController sendMessage:LostFocusMsgID data:nil];
579 if ([vimView textView])
580 [[vimView textView] hideMarkedTextField];
583 - (BOOL)windowShouldClose:(id)sender
585 [vimController sendMessage:VimShouldCloseMsgID data:nil];
589 - (void)windowDidMove:(NSNotification *)notification
591 if (setupDone && windowAutosaveKey) {
592 NSRect frame = [[self window] frame];
593 NSPoint topLeft = { frame.origin.x, NSMaxY(frame) };
594 NSString *topLeftString = NSStringFromPoint(topLeft);
596 [[NSUserDefaults standardUserDefaults]
597 setObject:topLeftString forKey:windowAutosaveKey];
601 - (void)windowDidResize:(id)sender
603 if (!setupDone) return;
605 // Live resizing works as follows:
606 // VimView's size is changed immediatly, and a resize message to the
607 // remote vim instance is sent. The remote vim instance sends a
608 // "vim content size changed" right back, but in live resize mode this
609 // doesn't change the VimView (because we assume that it already has the
610 // correct size because we set the resize increments correctly). Afterward,
611 // the remote vim view sends a batch draw for the text visible in the
612 // resized text area.
614 NSSize contentSize = [self contentSize];
615 [self resizeVimViewToFitSize:contentSize];
618 frame.origin = NSMakePoint(0, 0);
619 frame.size = contentSize;
620 [vimView setFrame:frame];
623 - (NSRect)windowWillUseStandardFrame:(NSWindow *)win
624 defaultFrame:(NSRect)frame
626 // HACK! For some reason 'frame' is not always constrained to fit on the
627 // screen (e.g. it may overlap the menu bar), so first constrain it to the
628 // screen; otherwise the new frame we compute may be too large and this
629 // will mess up the display after the window resizes.
630 frame = [win constrainFrameRect:frame toScreen:[win screen]];
632 // HACK! If the top of 'frame' is lower than the current window frame,
633 // increase 'frame' so that their tops align. Really, 'frame' should
634 // already have its top at least as high as the current window frame, but
635 // for some reason this is not always the case.
636 // (See resizeWindowToFit: for a similar hack.)
637 NSRect cur = [win frame];
638 if (NSMaxY(cur) > NSMaxY(frame)) {
639 frame.size.height = cur.origin.y - frame.origin.y + cur.size.height;
642 frame = [self fitWindowToFrame:frame];
644 // Keep old width and horizontal position unless user clicked while the
645 // Command key is held down.
646 NSEvent *event = [NSApp currentEvent];
647 if (!([event type] == NSLeftMouseUp
648 && [event modifierFlags] & NSCommandKeyMask)) {
649 NSRect currentFrame = [win frame];
650 frame.size.width = currentFrame.size.width;
651 frame.origin.x = currentFrame.origin.x;
660 // -- Services menu delegate -------------------------------------------------
662 - (id)validRequestorForSendType:(NSString *)sendType
663 returnType:(NSString *)returnType
665 if ([sendType isEqual:NSStringPboardType]
666 && [self askBackendForStarRegister:nil])
669 return [super validRequestorForSendType:sendType returnType:returnType];
672 - (BOOL)writeSelectionToPasteboard:(NSPasteboard *)pboard
673 types:(NSArray *)types
675 if (![types containsObject:NSStringPboardType])
678 return [self askBackendForStarRegister:pboard];
681 @end // MMWindowController
685 @implementation MMWindowController (Private)
687 - (NSRect)contentRectForFrameRect:(NSRect)frame
689 NSRect result = [[self window] contentRectForFrameRect:frame];
690 if (![tablineSeparator isHidden])
691 --result.size.height;
695 - (NSRect)frameRectForContentRect:(NSRect)contentRect
697 if (![tablineSeparator isHidden])
698 ++contentRect.size.height;
699 return [[self window] frameRectForContentRect:contentRect];
702 - (NSSize)contentSize
704 return [self contentRectForFrameRect:[[self window] frame]].size;
707 - (void)resizeWindowToFit:(id)sender
709 // Makes the window large enough to contain the vim view, called after the
710 // vim view's size was changed. If the window had to become to big, the
711 // vim view is made smaller.
713 // NOTE: Be very careful when you call this method! Do not call while
714 // processing command queue, instead set 'shouldUpdateWindowSize' to YES.
715 // The only other place it is currently called is when live resize ends.
716 // This is done to ensure that the text view and window sizes match up
717 // (they may become out of sync if a SetTextDimensionsMsgID message to the
718 // backend is dropped).
720 if (!setupDone) return;
722 // Get size of text view, adapt window size to it
723 NSWindow *win = [self window];
724 NSRect frame = [win frame];
725 NSRect contentRect = [self contentRectForFrameRect:frame];
726 NSSize newSize = [vimView desiredSizeForActualRowsAndColumns];
728 // Keep top-left corner of the window fixed when resizing.
729 contentRect.origin.y -= newSize.height - contentRect.size.height;
730 contentRect.size = newSize;
732 frame = [self frameRectForContentRect:contentRect];
733 NSRect maxFrame = [win constrainFrameRect:frame toScreen:[win screen]];
735 // HACK! Assuming the window frame cannot already be placed too high,
736 // adjust 'maxFrame' so that it at least as high up as the current frame.
737 // The reason for doing this is that constrainFrameRect:toScreen: does not
738 // always seem to utilize as much area as possible.
739 if (NSMaxY(frame) > NSMaxY(maxFrame)) {
740 maxFrame.size.height = frame.origin.y - maxFrame.origin.y
744 if (!NSEqualRects(maxFrame, frame)) {
745 // The new window frame is too big to fit on the screen, so fit the
746 // text storage to the biggest frame which will fit on the screen.
747 //NSLog(@"Proposed window frame does not fit on the screen!");
748 frame = [self fitWindowToFrame:maxFrame];
749 [self resizeVimViewToFitSize:[self contentRectForFrameRect:frame].size];
752 // NSLog(@"%s %@", _cmd, NSStringFromRect(frame));
754 // HACK! If the window does resize, then windowDidResize is called which in
755 // turn calls placeViews. In case the computed new size of the window is
756 // no different from the current size, then we need to call placeViews
758 if (NSEqualRects(frame, [win frame])) {
761 [win setFrame:frame display:YES];
765 - (NSRect)fitWindowToFrame:(NSRect)frame
767 if (!setupDone) return frame;
769 NSRect contentRect = [self contentRectForFrameRect:frame];
770 NSSize size = [vimView getDesiredRows:NULL columns:NULL
771 forSize:contentRect.size];
773 // Keep top-left corner of 'frame' fixed.
774 contentRect.origin.y -= size.height - contentRect.size.height;
775 contentRect.size = size;
777 return [self frameRectForContentRect:contentRect];
780 - (void)updateResizeIncrements
782 if (!setupDone) return;
784 NSSize size = [[vimView textStorage] cellSize];
785 [[self window] setContentResizeIncrements:size];
788 - (NSTabViewItem *)addNewTabViewItem
790 return [vimView addNewTabViewItem];
793 - (IBAction)vimMenuItemAction:(id)sender
795 int tag = [sender tag];
797 NSMutableData *data = [NSMutableData data];
798 [data appendBytes:&tag length:sizeof(int)];
800 [vimController sendMessage:ExecuteMenuMsgID data:data];
803 - (BOOL)askBackendForStarRegister:(NSPasteboard *)pb
806 id backendProxy = [vimController backendProxy];
810 reply = [backendProxy starRegisterToPasteboard:pb];
812 @catch (NSException *e) {
813 NSLog(@"WARNING: Caught exception in %s: \"%@\"", _cmd, e);
820 - (void)checkWindowNeedsResizing
822 shouldUpdateWindowSize =
823 shouldUpdateWindowSize || [vimView shouldUpdateWindowSize];
826 - (NSSize)resizeVimViewToFitSize:(NSSize)size
828 // If our optimal (rows,cols) do not match our current (rows,cols), resize
829 // ourselves and tell the Vim process to sync up.
831 NSSize newSize = [vimView getDesiredRows:&desired[0] columns:&desired[1]
835 [vimView getActualRows:&rows columns:&columns];
837 if (desired[0] != rows || desired[1] != columns) {
838 // NSLog(@"Notify Vim that text storage dimensions changed from %dx%d "
839 // @"to %dx%d", columns, rows, desired[0], desired[1]);
840 NSData *data = [NSData dataWithBytes:desired length:2*sizeof(int)];
842 [vimController sendMessage:SetTextDimensionsMsgID data:data];
844 // We only want to set the window title if this resize came from
845 // a live-resize, not (for example) setting 'columns' or 'lines'.
846 if ([[self textView] inLiveResize]) {
847 [[self window] setTitle:[NSString stringWithFormat:@"%dx%d",
848 desired[1], desired[0]]];
856 @end // MMWindowController (Private)