@@ -132,6 +132,8 @@ - (id)initWithFrame:(NSRect)frame
132132 if (!(self = [super initWithFrame: frame]))
133133 return nil ;
134134
135+ cgLayerLock = [NSLock new ];
136+
135137 // NOTE! It does not matter which font is set here, Vim will set its
136138 // own font on startup anyway. Just set some bogus values.
137139 font = [[NSFont userFixedPitchFontOfSize: 0 ] retain ];
@@ -586,18 +588,12 @@ - (void)drawRect:(NSRect)rect
586588 NSGraphicsContext *context = [NSGraphicsContext currentContext ];
587589 [context setShouldAntialias: antialias];
588590
589- id data;
590- NSEnumerator *e = [drawData objectEnumerator ];
591- while ((data = [e nextObject ]))
592- [self batchDrawData: data];
593-
594- [drawData removeAllObjects ];
595-
596- if (cgLayerEnabled) {
591+ if (cgLayerEnabled && drawData.count == 0 ) {
597592 // during a live resize, we will have around a stale layer until the
598593 // refresh messages travel back from the vim process. We push the old
599594 // layer in at an offset to get rid of jitter due to lines changing
600595 // position.
596+ [cgLayerLock lock ];
601597 CGLayerRef l = [self getCGLayer ];
602598 CGSize cgLayerSize = CGLayerGetSize (l);
603599 CGSize frameSize = [self frame ].size ;
@@ -608,22 +604,45 @@ - (void)drawRect:(NSRect)rect
608604 cgLayerSize.height );
609605
610606 CGContextRef cgContext = [context graphicsPort ];
611- CGContextSaveGState (cgContext);
612- CGContextSetBlendMode (cgContext, kCGBlendModeCopy );
613- CGContextDrawLayerInRect (cgContext, drawRect, l);
614- CGContextRestoreGState (cgContext);
607+
608+ const NSRect *rects;
609+ long count;
610+ [self getRectsBeingDrawn: &rects count: &count];
611+
612+ int i;
613+ for (i = 0 ; i < count; i++) {
614+ CGContextSaveGState (cgContext);
615+ CGContextClipToRect (cgContext, rects[i]);
616+ CGContextSetBlendMode (cgContext, kCGBlendModeCopy );
617+ CGContextDrawLayerInRect (cgContext, drawRect, l);
618+ CGContextRestoreGState (cgContext);
619+ }
620+ [cgLayerLock unlock ];
621+ } else {
622+ id data;
623+ NSEnumerator *e = [drawData objectEnumerator ];
624+ while ((data = [e nextObject ]))
625+ [self batchDrawData: data];
626+
627+ [drawData removeAllObjects ];
615628 }
616629}
617630
618631- (void )performBatchDrawWithData : (NSData *)data
619632{
620- [drawData addObject: data];
621- [self setNeedsDisplay: YES ];
633+ if (cgLayerEnabled && drawData.count == 0 && [self getCGContext ]) {
634+ [cgLayerLock lock ];
635+ [self batchDrawData: data];
636+ [cgLayerLock unlock ];
637+ } else {
638+ [drawData addObject: data];
639+ [self setNeedsDisplay: YES ];
622640
623- // NOTE: During resizing, Cocoa only sends draw messages before Vim's rows
624- // and columns are changed (due to ipc delays). Force a redraw here.
625- if ([self inLiveResize ])
626- [self display ];
641+ // NOTE: During resizing, Cocoa only sends draw messages before Vim's rows
642+ // and columns are changed (due to ipc delays). Force a redraw here.
643+ if ([self inLiveResize ])
644+ [self display ];
645+ }
627646}
628647
629648- (void )setCGLayerEnabled : (BOOL )enabled
@@ -646,11 +665,12 @@ - (void)releaseCGLayer
646665- (CGLayerRef)getCGLayer
647666{
648667 NSParameterAssert (cgLayerEnabled);
649- if (!cgLayer) {
668+ if (!cgLayer && [ self lockFocusIfCanDraw ] ) {
650669 NSGraphicsContext *context = [NSGraphicsContext currentContext ];
651670 NSRect frame = [self frame ];
652671 cgLayer = CGLayerCreateWithContext (
653672 [context graphicsPort ], frame.size , NULL );
673+ [self unlockFocus ];
654674 }
655675 return cgLayer;
656676}
@@ -982,6 +1002,7 @@ - (void)batchDrawData:(NSData *)data
9821002 operation: NSCompositingOperationSourceOver
9831003 fraction: 1.0 ];
9841004 }
1005+ [self setNeedsDisplayInRect: r];
9851006 } else if (DrawStringDrawType == type) {
9861007 int bg = *((int *)bytes); bytes += sizeof (int );
9871008 int fg = *((int *)bytes); bytes += sizeof (int );
@@ -1478,6 +1499,8 @@ - (void)drawString:(const UniChar *)chars length:(UniCharCount)length
14781499 if (thinStrokes)
14791500 CGContextSetFontSmoothingStyle (context, originalFontSmoothingStyle);
14801501 CGContextRestoreGState (context);
1502+
1503+ [self setNeedsDisplayInRect: clipRect];
14811504}
14821505
14831506- (void )scrollRect : (NSRect )rect lineCount : (int )count
@@ -1495,6 +1518,7 @@ - (void)scrollRect:(NSRect)rect lineCount:(int)count
14951518 CGContextDrawLayerAtPoint (
14961519 context, CGPointMake (0 , -yOffset), [self getCGLayer ]);
14971520 CGContextRestoreGState (context);
1521+ [self setNeedsDisplayInRect: clipRect];
14981522 } else {
14991523 NSSize delta={0 , -count * cellSize.height };
15001524 [self scrollRect: rect by: delta];
@@ -1549,6 +1573,7 @@ - (void)clearBlockFromRow:(int)row1 column:(int)col1 toRow:(int)row2
15491573 CGContextSetBlendMode (context, kCGBlendModeCopy );
15501574 CGContextFillRect (context, *(CGRect*)&rect);
15511575 CGContextSetBlendMode (context, kCGBlendModeNormal );
1576+ [self setNeedsDisplayInRect: rect];
15521577}
15531578
15541579- (void )clearAll
@@ -1565,6 +1590,8 @@ - (void)clearAll
15651590 CGContextSetRGBFillColor (context, r, g, b, a);
15661591 CGContextFillRect (context, *(CGRect*)&rect);
15671592 CGContextSetBlendMode (context, kCGBlendModeNormal );
1593+
1594+ [self setNeedsDisplay: YES ];
15681595}
15691596
15701597- (void )drawInsertionPointAtRow : (int )row column : (int )col shape : (int )shape
@@ -1612,6 +1639,7 @@ - (void)drawInsertionPointAtRow:(int)row column:(int)col shape:(int)shape
16121639 CGContextFillRect (context, *(CGRect*)&rect);
16131640 }
16141641
1642+ [self setNeedsDisplayInRect: rect];
16151643 CGContextRestoreGState (context);
16161644}
16171645
@@ -1628,6 +1656,7 @@ - (void)drawInvertedRectAtRow:(int)row column:(int)col numRows:(int)nrows
16281656 numColumns: ncols];
16291657 CGContextFillRect (cgctx, *(CGRect*)&rect);
16301658
1659+ [self setNeedsDisplayInRect: rect];
16311660 CGContextRestoreGState (cgctx);
16321661}
16331662
0 commit comments