@@ -40,6 +40,16 @@ - (NSMutableArray*)vimControllers {
40
40
}
41
41
@end
42
42
43
+ static BOOL forceInLiveResize = NO ;
44
+ @implementation MMVimView (testWindowResize)
45
+ - (BOOL )inLiveResize {
46
+ // Mock NSView's inLiveResize functionality
47
+ if (forceInLiveResize)
48
+ return YES ;
49
+ return [super inLiveResize ];
50
+ }
51
+ @end
52
+
43
53
@interface MacVimTests : XCTestCase
44
54
45
55
@end
@@ -583,4 +593,144 @@ - (void) testTitlebarDocumentIcon {
583
593
[self waitForVimClose ];
584
594
}
585
595
596
+ // / Test resizing the MacVim window properly resizes Vim
597
+ - (void ) testWindowResize {
598
+ MMAppController *app = MMAppController.sharedInstance ;
599
+
600
+ [app openNewWindow: NewWindowClean activate: YES ];
601
+ [self waitForVimOpenAndMessages ];
602
+
603
+ NSWindow *win = [[[app keyVimController ] windowController ] window ];
604
+ MMVimView *vimView = [[[app keyVimController ] windowController ] vimView ];
605
+ MMTextView *textView = [[[[app keyVimController ] windowController ] vimView ] textView ];
606
+
607
+ // Set a default 30,80 base size for the entire test
608
+ [self sendStringToVim: @" :set lines=30 columns=80\n " withMods: 0 ];
609
+ [self waitForEventHandlingAndVimProcess ];
610
+ XCTAssertEqual (30 , textView.maxRows );
611
+ XCTAssertEqual (80 , textView.maxColumns );
612
+
613
+ const NSRect winFrame = win.frame ;
614
+
615
+ {
616
+ // Test basic resizing functionality. Make sure text view is updated properly
617
+ NSRect newFrame = winFrame;
618
+ newFrame.size .width -= textView.cellSize .width ;
619
+ newFrame.size .height -= textView.cellSize .height ;
620
+
621
+ [win setFrame: newFrame display: YES ];
622
+ XCTAssertEqual (30 , textView.maxRows );
623
+ XCTAssertEqual (80 , textView.maxColumns );
624
+ [self waitForVimProcess ];
625
+ XCTAssertEqual (29 , textView.maxRows );
626
+ XCTAssertEqual (79 , textView.maxColumns );
627
+
628
+ [win setFrame: winFrame display: YES ];
629
+ [self waitForVimProcess ];
630
+ XCTAssertEqual (30 , textView.maxRows );
631
+ XCTAssertEqual (80 , textView.maxColumns );
632
+ }
633
+
634
+ {
635
+ // Test rapid resizing where we resize faster than Vim can handle. We
636
+ // should be updating a pending size indicating what we expect Vim's
637
+ // size should be and use that as the cache. Previously we had a bug
638
+ // we we used the outdated size as cache instead leading to rapid
639
+ // resizing sometimes leading to stale sizes.
640
+
641
+ // This kind of situation coudl occur if say Vim is stalled for a bit
642
+ // and we resized the window multiple times. We don't rate limit unlike
643
+ // live resizing since usually it's not needed.
644
+ NSRect newFrame = winFrame;
645
+ newFrame.size .width -= textView.cellSize .width ;
646
+ newFrame.size .height -= textView.cellSize .height ;
647
+
648
+ [win setFrame: newFrame display: YES ];
649
+ XCTAssertEqual (30 , textView.maxRows );
650
+ XCTAssertEqual (80 , textView.maxColumns );
651
+ XCTAssertEqual (29 , textView.pendingMaxRows );
652
+ XCTAssertEqual (79 , textView.pendingMaxColumns );
653
+
654
+ [win setFrame: winFrame display: YES ];
655
+ XCTAssertEqual (30 , textView.maxRows );
656
+ XCTAssertEqual (80 , textView.maxColumns );
657
+ XCTAssertEqual (30 , textView.pendingMaxRows );
658
+ XCTAssertEqual (80 , textView.pendingMaxColumns );
659
+
660
+ [self waitForVimProcess ];
661
+ XCTAssertEqual (30 , textView.maxRows );
662
+ XCTAssertEqual (80 , textView.maxColumns );
663
+ }
664
+
665
+ {
666
+ // Test rapid resizing again, but this time we don't resize back to the
667
+ // original size, but instead incremented multiple times. Just to make
668
+ // sure we actually get set to the final size.
669
+ NSRect newFrame = winFrame;
670
+ for (int i = 0 ; i < 5 ; i++) {
671
+ newFrame.size .width += textView.cellSize .width ;
672
+ newFrame.size .height += textView.cellSize .height ;
673
+ [win setFrame: newFrame display: YES ];
674
+ }
675
+ XCTAssertEqual (30 , textView.maxRows );
676
+ XCTAssertEqual (80 , textView.maxColumns );
677
+ XCTAssertEqual (35 , textView.pendingMaxRows );
678
+ XCTAssertEqual (85 , textView.pendingMaxColumns );
679
+
680
+ [self waitForVimProcess ];
681
+ XCTAssertEqual (35 , textView.maxRows );
682
+ XCTAssertEqual (85 , textView.maxColumns );
683
+
684
+ [win setFrame: winFrame display: YES ]; // reset back to original size
685
+ [self waitForVimProcess ];
686
+ XCTAssertEqual (30 , textView.maxRows );
687
+ XCTAssertEqual (80 , textView.maxColumns );
688
+ }
689
+
690
+ {
691
+ // Test live resizing (e.g. when user drags the window edge to resize).
692
+ // We rate limit the number of messages we send to Vim so if there are
693
+ // multiple resize events they will be sequenced to avoid overloading Vim.
694
+ forceInLiveResize = YES ; // simulate live resizing which can only be initiated by a user
695
+ [vimView viewWillStartLiveResize ];
696
+
697
+ NSRect newFrame = winFrame;
698
+ for (int i = 0 ; i < 5 ; i++) {
699
+ newFrame.size .width += textView.cellSize .width ;
700
+ newFrame.size .height += textView.cellSize .height ;
701
+ [win setFrame: newFrame display: YES ];
702
+ }
703
+
704
+ // The first time Vim processes this it should have only received the first message
705
+ // due to rate limiting.
706
+ XCTAssertEqual (30 , textView.maxRows );
707
+ XCTAssertEqual (80 , textView.maxColumns );
708
+ XCTAssertEqual (31 , textView.pendingMaxRows );
709
+ XCTAssertEqual (81 , textView.pendingMaxColumns );
710
+
711
+ // After Vim has processed the messages it should now have the final size
712
+ [self waitForVimProcess ]; // first wait for Vim to respond it processed the first message, where we send off the second one
713
+ [self waitForVimProcess ]; // Vim should now have processed the last message
714
+ XCTAssertEqual (35 , textView.maxRows );
715
+ XCTAssertEqual (85 , textView.maxColumns );
716
+ XCTAssertEqual (35 , textView.pendingMaxRows );
717
+ XCTAssertEqual (85 , textView.pendingMaxColumns );
718
+
719
+ forceInLiveResize = NO ;
720
+ [vimView viewDidEndLiveResize ];
721
+ [self waitForVimProcess ];
722
+ XCTAssertEqual (35 , textView.maxRows );
723
+ XCTAssertEqual (85 , textView.maxColumns );
724
+
725
+ [win setFrame: winFrame display: YES ]; // reset back to original size
726
+ [self waitForEventHandlingAndVimProcess ];
727
+ XCTAssertEqual (30 , textView.maxRows );
728
+ XCTAssertEqual (80 , textView.maxColumns );
729
+ }
730
+
731
+ // Clean up
732
+ [[app keyVimController ] sendMessage: VimShouldCloseMsgID data: nil ];
733
+ [self waitForVimClose ];
734
+ }
735
+
586
736
@end
0 commit comments