diff --git a/src/MacVim/MMAppController.m b/src/MacVim/MMAppController.m index 265ec677d2..c932be938b 100644 --- a/src/MacVim/MMAppController.m +++ b/src/MacVim/MMAppController.m @@ -769,6 +769,7 @@ fsEventCallback(ConstFSEventStreamRef streamRef, if (!screen) screen = [win screen]; + BOOL willSwitchScreens = screen != [win screen]; if (cascadeFrom) { // Do manual cascading instead of using // -[MMWindow cascadeTopLeftFromPoint:] since it is rather @@ -795,7 +796,14 @@ fsEventCallback(ConstFSEventStreamRef streamRef, ASLogNotice(@"Window not on screen, don't constrain position"); } - [win setFrameTopLeftPoint:topLeft]; + // setFrameTopLeftPoint will trigger a resize event if the window is + // moved across monitors; at this point such a resize would incorrectly + // constrain the window to the default vim dimensions, so a specialized + // method is used that will avoid that behavior. + if (willSwitchScreens) + [windowController moveWindowAcrossScreens:topLeft]; + else + [win setFrameTopLeftPoint:topLeft]; } if (1 == [vimControllers count]) { diff --git a/src/MacVim/MMWindowController.h b/src/MacVim/MMWindowController.h index a9603031bf..a200c16cdc 100644 --- a/src/MacVim/MMWindowController.h +++ b/src/MacVim/MMWindowController.h @@ -45,6 +45,7 @@ NSPoint userTopLeft; NSPoint defaultTopLeft; NSToolbar *toolbar; + BOOL resizingDueToMove; } - (id)initWithVimController:(MMVimController *)controller; @@ -55,6 +56,7 @@ - (void)cleanup; - (void)openWindow; - (BOOL)presentWindow:(id)unused; +- (void)moveWindowAcrossScreens:(NSPoint)origin; - (void)updateTabsWithData:(NSData *)data; - (void)selectTabWithIndex:(int)idx; - (void)setTextDimensionsWithRows:(int)rows columns:(int)cols isLive:(BOOL)live diff --git a/src/MacVim/MMWindowController.m b/src/MacVim/MMWindowController.m index 6fb25eba3a..ea15c23f99 100644 --- a/src/MacVim/MMWindowController.m +++ b/src/MacVim/MMWindowController.m @@ -150,6 +150,8 @@ self = [super initWithWindow:win]; if (!self) return nil; + resizingDueToMove = NO; + vimController = controller; decoratedWindow = [win retain]; @@ -347,6 +349,18 @@ return YES; } +- (void)moveWindowAcrossScreens:(NSPoint)topLeft +{ + // HACK! This method moves a window to a new origin and to a different + // screen. This is primarily useful to avoid a scenario where such a move + // will trigger a resize, even though the frame didn't actually change size. + // This method should not be called unless the new origin is definitely on + // a different screen, otherwise the next legitimate resize message will + // be skipped. + resizingDueToMove = YES; + [[self window] setFrameTopLeftPoint:topLeft]; +} + - (void)updateTabsWithData:(NSData *)data { [vimView updateTabsWithData:data]; @@ -993,7 +1007,13 @@ - (void)windowDidResize:(id)sender { - if (!setupDone || fullScreenEnabled || !windowPresented) return; + if (resizingDueToMove) + { + resizingDueToMove = NO; + return; + } + + if (!setupDone || fullScreenEnabled) return; // NOTE: Since we have no control over when the window may resize (Cocoa // may resize automatically) we simply set the view to fill the entire