aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAlan Third2020-04-11 14:18:39 +0100
committerAlan Third2020-04-16 19:11:05 +0100
commitc019f03e38850b3ba3a2bcbcc84960d5b8d9663f (patch)
tree7f1ab25650ae0aa954d6079a827ef7d5c7552bbe /src
parent24cb6908d70c14792c686679cb08091447b9c3b1 (diff)
downloademacs-c019f03e38850b3ba3a2bcbcc84960d5b8d9663f.tar.gz
emacs-c019f03e38850b3ba3a2bcbcc84960d5b8d9663f.zip
Allow dynamic choice of drawing path on NS (bug#39883)
* src/nsterm.h (NS_DRAW_TO_BUFFER): Let this be enabled on versions older than 10.14. * src/nsterm.m (ns_update_begin): (ns_update_end): (ns_focus): (ns_unfocus): ([EmacsView viewDidResize:]): ([EmacsView createDrawingBuffer]): ([EmacsView windowDidChangeBackingProperties:]): ([EmacsView copyRect:to:]): ([EmacsView wantsUpdateLayer]): Dynamically switch between drawing to a buffer and drawing to the screen, depending on the version of AppKit in use. ([EmacsView dealloc]): We can't release the context unless NS_DRAW_TO_BUFFER is defined.
Diffstat (limited to 'src')
-rw-r--r--src/nsterm.h10
-rw-r--r--src/nsterm.m229
2 files changed, 167 insertions, 72 deletions
diff --git a/src/nsterm.h b/src/nsterm.h
index e142dbd4f07..f5d3c32b8b3 100644
--- a/src/nsterm.h
+++ b/src/nsterm.h
@@ -343,14 +343,8 @@ typedef id instancetype;
343 therefore we draw to an offscreen buffer and swap it in when the 343 therefore we draw to an offscreen buffer and swap it in when the
344 toolkit wants to draw the frame. GNUstep and macOS 10.7 and below 344 toolkit wants to draw the frame. GNUstep and macOS 10.7 and below
345 do not support this method, so we revert to drawing directly to the 345 do not support this method, so we revert to drawing directly to the
346 glass. 346 glass. */
347 347#if defined (NS_IMPL_COCOA) && MAC_OS_X_VERSION_MAX_ALLOWED >= 101400
348 FIXME: Should we make this macOS 10.8+, or macOS 10.14+? I'm
349 inclined to go with 10.14+ as there have been some reports of funny
350 behaviour on 10.13 and below. It may be worth adding a variable to
351 allow people in the overlapping region to switch between drawing
352 paths. */
353#if defined (NS_IMPL_COCOA) && defined (MAC_OS_X_VERSION_10_14)
354#define NS_DRAW_TO_BUFFER 1 348#define NS_DRAW_TO_BUFFER 1
355#endif 349#endif
356 350
diff --git a/src/nsterm.m b/src/nsterm.m
index a75c3ef4dba..9cd1c9d8602 100644
--- a/src/nsterm.m
+++ b/src/nsterm.m
@@ -1144,10 +1144,25 @@ ns_update_begin (struct frame *f)
1144 1144
1145 ns_updating_frame = f; 1145 ns_updating_frame = f;
1146#ifdef NS_DRAW_TO_BUFFER 1146#ifdef NS_DRAW_TO_BUFFER
1147 [view focusOnDrawingBuffer]; 1147#if MAC_OS_X_VERSION_MIN_REQUIRED < 101400
1148#else 1148 if ([FRAME_NS_VIEW (f) wantsUpdateLayer])
1149 [view lockFocus]; 1149 {
1150#endif 1150#endif
1151 [view focusOnDrawingBuffer];
1152#if MAC_OS_X_VERSION_MIN_REQUIRED < 101400
1153 }
1154 else
1155 {
1156#endif
1157#endif /* NS_DRAW_TO_BUFFER */
1158
1159#if !defined (NS_DRAW_TO_BUFFER) || MAC_OS_X_VERSION_MIN_REQUIRED < 101400
1160 [view lockFocus];
1161#endif
1162#if defined (NS_DRAW_TO_BUFFER) && MAC_OS_X_VERSION_MIN_REQUIRED < 101400
1163 }
1164#endif
1165
1151} 1166}
1152 1167
1153 1168
@@ -1166,15 +1181,29 @@ ns_update_end (struct frame *f)
1166 MOUSE_HL_INFO (f)->mouse_face_defer = 0; 1181 MOUSE_HL_INFO (f)->mouse_face_defer = 0;
1167 1182
1168#ifdef NS_DRAW_TO_BUFFER 1183#ifdef NS_DRAW_TO_BUFFER
1169 [NSGraphicsContext setCurrentContext:nil]; 1184#if MAC_OS_X_VERSION_MIN_REQUIRED < 101400
1170 [view setNeedsDisplay:YES]; 1185 if ([FRAME_NS_VIEW (f) wantsUpdateLayer])
1171#else 1186 {
1172 block_input (); 1187#endif
1188 [NSGraphicsContext setCurrentContext:nil];
1189 [view setNeedsDisplay:YES];
1190#if MAC_OS_X_VERSION_MIN_REQUIRED < 101400
1191 }
1192 else
1193 {
1194#endif
1195#endif /* NS_DRAW_TO_BUFFER */
1173 1196
1174 [view unlockFocus]; 1197#if !defined (NS_DRAW_TO_BUFFER) || MAC_OS_X_VERSION_MIN_REQUIRED < 101400
1175 [[view window] flushWindow]; 1198 block_input ();
1176 1199
1177 unblock_input (); 1200 [view unlockFocus];
1201 [[view window] flushWindow];
1202
1203 unblock_input ();
1204#endif
1205#if defined (NS_DRAW_TO_BUFFER) && MAC_OS_X_VERSION_MIN_REQUIRED < 101400
1206 }
1178#endif 1207#endif
1179 ns_updating_frame = NULL; 1208 ns_updating_frame = NULL;
1180} 1209}
@@ -1199,24 +1228,39 @@ ns_focus (struct frame *f, NSRect *r, int n)
1199 } 1228 }
1200 1229
1201 if (f != ns_updating_frame) 1230 if (f != ns_updating_frame)
1202#ifdef NS_DRAW_TO_BUFFER
1203 [view focusOnDrawingBuffer];
1204#else
1205 { 1231 {
1206 if (view != focus_view) 1232#ifdef NS_DRAW_TO_BUFFER
1233#if MAC_OS_X_VERSION_MIN_REQUIRED < 101400
1234 if ([FRAME_NS_VIEW (f) wantsUpdateLayer])
1207 { 1235 {
1208 if (focus_view != NULL) 1236#endif
1237 [view focusOnDrawingBuffer];
1238#if MAC_OS_X_VERSION_MIN_REQUIRED < 101400
1239 }
1240 else
1241 {
1242#endif
1243#endif /* NS_DRAW_TO_BUFFER */
1244
1245#if !defined (NS_DRAW_TO_BUFFER) || MAC_OS_X_VERSION_MIN_REQUIRED < 101400
1246 if (view != focus_view)
1209 { 1247 {
1210 [focus_view unlockFocus]; 1248 if (focus_view != NULL)
1211 [[focus_view window] flushWindow]; 1249 {
1212 } 1250 [focus_view unlockFocus];
1251 [[focus_view window] flushWindow];
1252 }
1213 1253
1214 if (view) 1254 if (view)
1215 [view lockFocus]; 1255 [view lockFocus];
1216 focus_view = view; 1256 focus_view = view;
1257 }
1258#endif
1259#if defined (NS_DRAW_TO_BUFFER) && MAC_OS_X_VERSION_MIN_REQUIRED < 101400
1217 } 1260 }
1218 }
1219#endif 1261#endif
1262 }
1263
1220 1264
1221 /* clipping */ 1265 /* clipping */
1222 if (r) 1266 if (r)
@@ -1246,16 +1290,30 @@ ns_unfocus (struct frame *f)
1246 } 1290 }
1247 1291
1248#ifdef NS_DRAW_TO_BUFFER 1292#ifdef NS_DRAW_TO_BUFFER
1249 [FRAME_NS_VIEW (f) setNeedsDisplay:YES]; 1293 #if MAC_OS_X_VERSION_MIN_REQUIRED < 101400
1250#else 1294 if ([FRAME_NS_VIEW (f) wantsUpdateLayer])
1251 if (f != ns_updating_frame) 1295 {
1296#endif
1297 [FRAME_NS_VIEW (f) setNeedsDisplay:YES];
1298#if MAC_OS_X_VERSION_MIN_REQUIRED < 101400
1299 }
1300 else
1252 { 1301 {
1253 if (focus_view != NULL) 1302#endif
1303#endif /* NS_DRAW_TO_BUFFER */
1304
1305#if !defined (NS_DRAW_TO_BUFFER) || MAC_OS_X_VERSION_MIN_REQUIRED < 101400
1306 if (f != ns_updating_frame)
1254 { 1307 {
1255 [focus_view unlockFocus]; 1308 if (focus_view != NULL)
1256 [[focus_view window] flushWindow]; 1309 {
1257 focus_view = NULL; 1310 [focus_view unlockFocus];
1311 [[focus_view window] flushWindow];
1312 focus_view = NULL;
1313 }
1258 } 1314 }
1315#endif
1316#if defined (NS_DRAW_TO_BUFFER) && MAC_OS_X_VERSION_MIN_REQUIRED < 101400
1259 } 1317 }
1260#endif 1318#endif
1261} 1319}
@@ -6254,7 +6312,9 @@ not_in_argv (NSString *arg)
6254 name:NSViewFrameDidChangeNotification 6312 name:NSViewFrameDidChangeNotification
6255 object:nil]; 6313 object:nil];
6256 6314
6315#ifdef NS_DRAW_TO_BUFFER
6257 CGContextRelease (drawingBuffer); 6316 CGContextRelease (drawingBuffer);
6317#endif
6258 6318
6259 [toolbar release]; 6319 [toolbar release];
6260 if (fs_state == FULLSCREEN_BOTH) 6320 if (fs_state == FULLSCREEN_BOTH)
@@ -7268,13 +7328,27 @@ not_in_argv (NSString *arg)
7268 return; 7328 return;
7269 7329
7270#ifdef NS_DRAW_TO_BUFFER 7330#ifdef NS_DRAW_TO_BUFFER
7271 CGFloat scale = [[self window] backingScaleFactor]; 7331#if MAC_OS_X_VERSION_MIN_REQUIRED < 101400
7272 oldw = (CGFloat)CGBitmapContextGetWidth (drawingBuffer) / scale; 7332 if ([self wantsUpdateLayer])
7273 oldh = (CGFloat)CGBitmapContextGetHeight (drawingBuffer) / scale; 7333 {
7274#else 7334#endif
7275 oldw = FRAME_PIXEL_WIDTH (emacsframe); 7335 CGFloat scale = [[self window] backingScaleFactor];
7276 oldh = FRAME_PIXEL_HEIGHT (emacsframe); 7336 oldw = (CGFloat)CGBitmapContextGetWidth (drawingBuffer) / scale;
7337 oldh = (CGFloat)CGBitmapContextGetHeight (drawingBuffer) / scale;
7338#if MAC_OS_X_VERSION_MIN_REQUIRED < 101400
7339 }
7340 else
7341 {
7277#endif 7342#endif
7343#endif /* NS_DRAW_TO_BUFFER */
7344#if !defined (NS_DRAW_TO_BUFFER) || MAC_OS_X_VERSION_MIN_REQUIRED < 101400
7345 oldw = FRAME_PIXEL_WIDTH (emacsframe);
7346 oldh = FRAME_PIXEL_HEIGHT (emacsframe);
7347#endif
7348#if defined (NS_DRAW_TO_BUFFER) && MAC_OS_X_VERSION_MIN_REQUIRED < 101400
7349 }
7350#endif
7351
7278 neww = (int)NSWidth (frame); 7352 neww = (int)NSWidth (frame);
7279 newh = (int)NSHeight (frame); 7353 newh = (int)NSHeight (frame);
7280 7354
@@ -8304,6 +8378,9 @@ not_in_argv (NSString *arg)
8304{ 8378{
8305 NSTRACE ("EmacsView createDrawingBuffer]"); 8379 NSTRACE ("EmacsView createDrawingBuffer]");
8306 8380
8381 if (! [self wantsUpdateLayer])
8382 return;
8383
8307 NSGraphicsContext *screen; 8384 NSGraphicsContext *screen;
8308 CGColorSpaceRef colorSpace = [[[self window] colorSpace] CGColorSpace]; 8385 CGColorSpaceRef colorSpace = [[[self window] colorSpace] CGColorSpace];
8309 CGFloat scale = [[self window] backingScaleFactor]; 8386 CGFloat scale = [[self window] backingScaleFactor];
@@ -8339,6 +8416,9 @@ not_in_argv (NSString *arg)
8339{ 8416{
8340 NSTRACE ("EmacsView windowDidChangeBackingProperties:]"); 8417 NSTRACE ("EmacsView windowDidChangeBackingProperties:]");
8341 8418
8419 if (! [self wantsUpdateLayer])
8420 return;
8421
8342 CGFloat old = [[[notification userInfo] 8422 CGFloat old = [[[notification userInfo]
8343 objectForKey:@"NSBackingPropertyOldScaleFactorKey"] 8423 objectForKey:@"NSBackingPropertyOldScaleFactorKey"]
8344 doubleValue]; 8424 doubleValue];
@@ -8362,41 +8442,56 @@ not_in_argv (NSString *arg)
8362 NSTRACE_RECT ("Destination", dstRect); 8442 NSTRACE_RECT ("Destination", dstRect);
8363 8443
8364#ifdef NS_DRAW_TO_BUFFER 8444#ifdef NS_DRAW_TO_BUFFER
8365 CGImageRef copy; 8445#if MAC_OS_X_VERSION_MIN_REQUIRED < 101400
8366 NSRect frame = [self frame]; 8446 if ([self wantsUpdateLayer])
8367 NSAffineTransform *setOrigin = [NSAffineTransform transform]; 8447 {
8448#endif
8449 CGImageRef copy;
8450 NSRect frame = [self frame];
8451 NSAffineTransform *setOrigin = [NSAffineTransform transform];
8368 8452
8369 [[NSGraphicsContext currentContext] saveGraphicsState]; 8453 [[NSGraphicsContext currentContext] saveGraphicsState];
8370 8454
8371 /* Set the clipping before messing with the buffer's 8455 /* Set the clipping before messing with the buffer's
8372 orientation. */ 8456 orientation. */
8373 NSRectClip (dstRect); 8457 NSRectClip (dstRect);
8374 8458
8375 /* Unflip the buffer as the copied image will be unflipped, and 8459 /* Unflip the buffer as the copied image will be unflipped, and
8376 offset the top left so when we draw back into the buffer the 8460 offset the top left so when we draw back into the buffer the
8377 correct part of the image is drawn. */ 8461 correct part of the image is drawn. */
8378 CGContextScaleCTM(drawingBuffer, 1, -1); 8462 CGContextScaleCTM(drawingBuffer, 1, -1);
8379 CGContextTranslateCTM(drawingBuffer, 8463 CGContextTranslateCTM(drawingBuffer,
8380 NSMinX (dstRect) - NSMinX (srcRect), 8464 NSMinX (dstRect) - NSMinX (srcRect),
8381 -NSHeight (frame) - (NSMinY (dstRect) - NSMinY (srcRect))); 8465 -NSHeight (frame) - (NSMinY (dstRect) - NSMinY (srcRect)));
8382 8466
8383 /* Take a copy of the buffer and then draw it back to the buffer, 8467 /* Take a copy of the buffer and then draw it back to the buffer,
8384 limited by the clipping rectangle. */ 8468 limited by the clipping rectangle. */
8385 copy = CGBitmapContextCreateImage (drawingBuffer); 8469 copy = CGBitmapContextCreateImage (drawingBuffer);
8386 CGContextDrawImage (drawingBuffer, frame, copy); 8470 CGContextDrawImage (drawingBuffer, frame, copy);
8387 8471
8388 CGImageRelease (copy); 8472 CGImageRelease (copy);
8389 8473
8390 [[NSGraphicsContext currentContext] restoreGraphicsState]; 8474 [[NSGraphicsContext currentContext] restoreGraphicsState];
8391 [self setNeedsDisplayInRect:dstRect]; 8475 [self setNeedsDisplayInRect:dstRect];
8392#else
8393 hide_bell(); // Ensure the bell image isn't scrolled.
8394 8476
8395 ns_focus (emacsframe, &dstRect, 1); 8477#if MAC_OS_X_VERSION_MIN_REQUIRED < 101400
8396 [self scrollRect: srcRect 8478 }
8397 by: NSMakeSize (dstRect.origin.x - srcRect.origin.x, 8479 else
8398 dstRect.origin.y - srcRect.origin.y)]; 8480 {
8399 ns_unfocus (emacsframe); 8481#endif
8482#endif /* NS_DRAW_TO_BUFFER */
8483
8484#if !defined (NS_DRAW_TO_BUFFER) || MAC_OS_X_VERSION_MIN_REQUIRED < 101400
8485 hide_bell(); // Ensure the bell image isn't scrolled.
8486
8487 ns_focus (emacsframe, &dstRect, 1);
8488 [self scrollRect: srcRect
8489 by: NSMakeSize (dstRect.origin.x - srcRect.origin.x,
8490 dstRect.origin.y - srcRect.origin.y)];
8491 ns_unfocus (emacsframe);
8492#endif
8493#if defined (NS_DRAW_TO_BUFFER) && MAC_OS_X_VERSION_MIN_REQUIRED < 101400
8494 }
8400#endif 8495#endif
8401} 8496}
8402 8497
@@ -8404,7 +8499,13 @@ not_in_argv (NSString *arg)
8404#ifdef NS_DRAW_TO_BUFFER 8499#ifdef NS_DRAW_TO_BUFFER
8405- (BOOL)wantsUpdateLayer 8500- (BOOL)wantsUpdateLayer
8406{ 8501{
8407 return YES; 8502#if MAC_OS_X_VERSION_MIN_REQUIRED < 101400
8503 if (NSAppKitVersionNumber < 1671)
8504 return NO;
8505#endif
8506
8507 /* Running on macOS 10.14 or above. */
8508 return YES;
8408} 8509}
8409 8510
8410 8511