Tk Source Code

Artifact [ddcd4ca9]
Login

Artifact ddcd4ca97a94c767ae97da6da92a7388cdb79fcd12faae2a12cd1db10c49e0c7:

Attachment "doubleclickbug.diff" to ticket [317643cf] added by anonymous 2019-07-23 08:12:44. (unpublished)
diff --git a/changes b/changes
index 81108a5a7..29e992a5d 100644
--- a/changes
+++ b/changes
@@ -7568,4 +7568,4 @@ Tk Cocoa 2.0: More drawing internals refinements (culler,walzer)
 
 2018-11-04 (bug)[6b22d4] [treeview] binding fix (ohagan)
 
-- Released 8.6.9, November 9, 2018 - http://core.tcl-lang.org/tk/ for details -
+- Released 8.6.9, November 16, 2018 - http://core.tcl-lang.org/tk/ for details -
diff --git a/generic/tkImgPhInstance.c b/generic/tkImgPhInstance.c
index ec9ee0438..fb106b17e 100644
--- a/generic/tkImgPhInstance.c
+++ b/generic/tkImgPhInstance.c
@@ -30,8 +30,10 @@ extern int		_XInitImageFuncPtrs(XImage *image);
  * Forward declarations
  */
 
+#ifndef MAC_OSX_TK
 static void		BlendComplexAlpha(XImage *bgImg, PhotoInstance *iPtr,
 			    int xOffset, int yOffset, int width, int height);
+#endif
 static int		IsValidPalette(PhotoInstance *instancePtr,
 			    const char *palette);
 static int		CountBits(pixel mask);
@@ -409,7 +411,7 @@ TkImgPhotoGet(
  *
  *----------------------------------------------------------------------
  */
-
+#ifndef MAC_OSX_TK
 #ifndef _WIN32
 #define GetRValue(rgb)	(UCHAR(((rgb) & red_mask) >> red_shift))
 #define GetGValue(rgb)	(UCHAR(((rgb) & green_mask) >> green_shift))
@@ -418,13 +420,6 @@ TkImgPhotoGet(
 	(UCHAR(r) << red_shift)   | \
 	(UCHAR(g) << green_shift) | \
 	(UCHAR(b) << blue_shift)  ))
-#ifdef MAC_OSX_TK
-#define RGBA(r, g, b, a) ((unsigned)( \
-	(UCHAR(r) << red_shift)   | \
-	(UCHAR(g) << green_shift) | \
-	(UCHAR(b) << blue_shift)  | \
-	(UCHAR(a) << alpha_shift) ))
-#endif
 #define RGB15(r, g, b)	((unsigned)( \
 	(((r) * red_mask / 255)   & red_mask)   | \
 	(((g) * green_mask / 255) & green_mask) | \
@@ -443,16 +438,7 @@ BlendComplexAlpha(
     unsigned long pixel;
     unsigned char r, g, b, alpha, unalpha, *masterPtr;
     unsigned char *alphaAr = iPtr->masterPtr->pix32;
-#if defined(MAC_OSX_TK)
-    /* Background "pixels" are actually 2^pp x 2^pp blocks of subpixels.  Each
-     * block gets blended with the color of one image pixel.  Since we iterate
-     * over the background subpixels, we reset the width and height to the
-     * subpixel dimensions of the background image we are using.
-     */
-    int pp = bgImg->pixelpower;
-    width = width << pp;
-    height = height << pp;
-#endif
+
     /*
      * This blending is an integer version of the Source-Over compositing rule
      * (see Porter&Duff, "Compositing Digital Images", proceedings of SIGGRAPH
@@ -492,13 +478,6 @@ BlendComplexAlpha(
     while ((0x0001 & (blue_mask >> blue_shift)) == 0) {
 	blue_shift++;
     }
-#ifdef MAC_OSX_TK
-    unsigned long alpha_mask = visual->alpha_mask;
-    unsigned long alpha_shift = 0;
-    while ((0x0001 & (alpha_mask >> alpha_shift)) == 0) {
-	alpha_shift++;
-    }
-#endif
 #endif /* !_WIN32 */
 
     /*
@@ -558,16 +537,9 @@ BlendComplexAlpha(
 #endif /* !_WIN32 && !MAC_OSX_TK */
 
     for (y = 0; y < height; y++) {
-# if !defined(MAC_OSX_TK)
 	line = (y + yOffset) * iPtr->masterPtr->width;
 	for (x = 0; x < width; x++) {
 	    masterPtr = alphaAr + ((line + x + xOffset) * 4);
-#else
-	/* Repeat each image row and column 2^pp times. */
-	line = ((y>>pp) + yOffset) * iPtr->masterPtr->width;
-	for (x = 0; x < width; x++) {
-	    masterPtr = alphaAr + ((line + (x>>pp) + xOffset) * 4);
-#endif
 	    alpha = masterPtr[3];
 
 	    /*
@@ -599,16 +571,13 @@ BlendComplexAlpha(
 		    g = ALPHA_BLEND(ga, g, alpha, unalpha);
 		    b = ALPHA_BLEND(ba, b, alpha, unalpha);
 		}
-#ifndef MAC_OSX_TK
 		XPutPixel(bgImg, x, y, RGB(r, g, b));
-#else
-		XPutPixel(bgImg, x, y, RGBA(r, g, b, alpha));
-#endif
 	    }
 	}
     }
 #undef ALPHA_BLEND
 }
+#endif /* MAC_OSX_TK */
 
 /*
  *----------------------------------------------------------------------
@@ -651,6 +620,24 @@ TkImgPhotoDisplay(
 	return;
     }
 
+#ifdef MAC_OSX_TK
+    /*
+     * The Mac version of TkPutImage handles RGBA images directly.  There is
+     * no need to call XGetImage or to do the Porter-Duff compositing by hand.
+     * We just let the CG graphics library do it, using the graphics hardware.
+     */
+    unsigned char *rgbaPixels = instancePtr->masterPtr->pix32;
+
+    XImage *photo = XCreateImage(display, NULL, 32, ZPixmap, 0, (char*)rgbaPixels,
+				 (unsigned int)instancePtr->width,
+				 (unsigned int)instancePtr->height,
+				 0, (unsigned int)(4 * instancePtr->width));
+    TkPutImage(NULL, 0, display, drawable, instancePtr->gc,
+	       photo, imageX, imageY, drawableX, drawableY,
+	       (unsigned int) width, (unsigned int) height);
+    photo->data = NULL;
+    XDestroyImage(photo);
+#else
     if ((instancePtr->masterPtr->flags & COMPLEX_ALPHA)
 	    && visInfo.depth >= 15
 	    && (visInfo.class == DirectColor || visInfo.class == TrueColor)) {
@@ -709,6 +696,7 @@ TkImgPhotoDisplay(
 	XSetClipOrigin(display, instancePtr->gc, 0, 0);
     }
     XFlush(display);
+#endif
 }
 
 /*
diff --git a/generic/tkOption.c b/generic/tkOption.c
index 24e7fb336..545a9b9b5 100644
--- a/generic/tkOption.c
+++ b/generic/tkOption.c
@@ -996,6 +996,9 @@ AddFromString(
 	while ((*src == ' ') || (*src == '\t')) {
 	    src++;
 	}
+	if (*src == '\\' && (src[1] == '\t' || src[1] == ' ')) {
+	    src++;
+	}
 	if (*src == '\0') {
 	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
 		    "missing value on line %d", lineNum));
@@ -1025,7 +1028,7 @@ AddFromString(
 		    src += 2;
 		    *dst++ = '\n';
 		    continue;
-		} else if (src[1] == '\t' || src[1] == ' ' || src[1] == '\\') {
+		} else if (src[1] == '\\') {
 		    ++src;
 		} else if (src[1] >= '0' && src[1] <= '3' && src[2] >= '0' &&
 			src[2] <= '9' && src[3] >= '0' && src[3] <= '9') {
diff --git a/generic/tkTest.c b/generic/tkTest.c
index 2dbd87724..560939130 100644
--- a/generic/tkTest.c
+++ b/generic/tkTest.c
@@ -31,6 +31,9 @@
 #if defined(MAC_OSX_TK)
 #include "tkMacOSXInt.h"
 #include "tkScrollbar.h"
+#define SIMULATE_DRAWING TkTestSimulateDrawing(true);
+#else
+#define SIMULATE_DRAWING
 #endif
 
 #ifdef __UNIX__
@@ -1550,16 +1553,35 @@ ImageDisplay(
     TImageInstance *instPtr = (TImageInstance *) clientData;
     char buffer[200 + TCL_INTEGER_SPACE * 6];
 
+    /*
+     * The purpose of the test image type is to track the calls to an image
+     * display proc and record the parameters passed in each call.  On macOS
+     * these tests will fail because of the asynchronous drawing.  The low
+     * level graphics calls below which are supposed to draw a rectangle will
+     * not draw anything to the screen because the idle task will not be
+     * processed inside of the drawRect method and hence will not be able to
+     * obtain a valid graphics context. Instead, the window will be marked as
+     * needing display, and will be redrawn during a future asynchronous call
+     * to drawRect.  This will generate an other call to this display proc,
+     * and the recorded data will show extra calls, causing the test to fail.
+     * To avoid this, we can set the [NSApp simulateDrawing] flag, which will
+     * cause all low level drawing routines to return immediately and not
+     * schedule the window for drawing later.  This flag is cleared by the
+     * next call to XSync, which is called by the update command.
+     */
+
     sprintf(buffer, "%s display %d %d %d %d",
 	    instPtr->masterPtr->imageName, imageX, imageY, width, height);
     Tcl_SetVar2(instPtr->masterPtr->interp, instPtr->masterPtr->varName, NULL,
-	    buffer, TCL_GLOBAL_ONLY|TCL_APPEND_VALUE|TCL_LIST_ELEMENT);
+		buffer, TCL_GLOBAL_ONLY|TCL_APPEND_VALUE|TCL_LIST_ELEMENT);
     if (width > (instPtr->masterPtr->width - imageX)) {
 	width = instPtr->masterPtr->width - imageX;
     }
     if (height > (instPtr->masterPtr->height - imageY)) {
 	height = instPtr->masterPtr->height - imageY;
     }
+
+    SIMULATE_DRAWING
     XDrawRectangle(display, drawable, instPtr->gc, drawableX, drawableY,
 	    (unsigned) (width-1), (unsigned) (height-1));
     XDrawLine(display, drawable, instPtr->gc, drawableX, drawableY,
diff --git a/macosx/tkMacOSXButton.c b/macosx/tkMacOSXButton.c
index 14b8872d3..ea78d435d 100644
--- a/macosx/tkMacOSXButton.c
+++ b/macosx/tkMacOSXButton.c
@@ -1201,3 +1201,11 @@ PulseDefaultButtonProc(ClientData clientData)
             PULSE_TIMER_MSECS, PulseDefaultButtonProc, clientData);
 }
 
+/*
+ * Local Variables:
+ * mode: objc
+ * c-basic-offset: 4
+ * fill-column: 79
+ * coding: utf-8
+ * End:
+ */
diff --git a/macosx/tkMacOSXConfig.c b/macosx/tkMacOSXConfig.c
index bdfcb6ec0..841fc54ed 100644
--- a/macosx/tkMacOSXConfig.c
+++ b/macosx/tkMacOSXConfig.c
@@ -41,3 +41,12 @@ TkpGetSystemDefault(
 {
     return NULL;
 }
+
+/*
+ * Local Variables:
+ * mode: objc
+ * c-basic-offset: 4
+ * fill-column: 79
+ * coding: utf-8
+ * End:
+ */
diff --git a/macosx/tkMacOSXConstants.h b/macosx/tkMacOSXConstants.h
index b160083ed..0badf1a8f 100644
--- a/macosx/tkMacOSXConstants.h
+++ b/macosx/tkMacOSXConstants.h
@@ -40,6 +40,7 @@
 
 #if MAC_OS_X_VERSION_MIN_REQUIRED >= 101200
 #define NSAppKitDefined NSEventTypeAppKitDefined
+#define NSApplicationDefined NSEventTypeApplicationDefined
 #define NSApplicationActivatedEventType NSEventSubtypeApplicationActivated
 #define NSApplicationDeactivatedEventType NSEventSubtypeApplicationDeactivated
 #define NSWindowExposedEventType NSEventSubtypeWindowExposed
@@ -92,6 +93,7 @@
 #define NSAlphaShiftKeyMask NSEventModifierFlagCapsLock
 #define NSShiftKeyMask NSEventModifierFlagShift
 #define NSAnyEventMask NSEventMaskAny
+#define NSApplicationDefinedMask NSEventMaskApplicationDefined
 #define NSTexturedBackgroundWindowMask NSWindowStyleMaskTexturedBackground
 #define NSUtilityWindowMask NSWindowStyleMaskUtilityWindow
 #define NSNonactivatingPanelMask NSWindowStyleMaskNonactivatingPanel
diff --git a/macosx/tkMacOSXDialog.c b/macosx/tkMacOSXDialog.c
index 8d20d4e90..f8453c77b 100644
--- a/macosx/tkMacOSXDialog.c
+++ b/macosx/tkMacOSXDialog.c
@@ -1198,36 +1198,42 @@ TkAboutDlg(void)
     NSString *year = [dateFormatter stringFromDate:[NSDate date]];
 
     [dateFormatter release];
-
-    NSMutableParagraphStyle *style =
-	    [[[NSParagraphStyle defaultParagraphStyle] mutableCopy]
-	    autorelease];
-
-    [style setAlignment:NSCenterTextAlignment];
-
-    NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
-	    @"Tcl & Tk", @"ApplicationName",
-	    @"Tcl " TCL_VERSION " & Tk " TK_VERSION, @"ApplicationVersion",
-	    @TK_PATCH_LEVEL, @"Version",
-	    image, @"ApplicationIcon",
-	    [NSString stringWithFormat:@"Copyright %1$C 1987-%2$@.", 0xA9,
-	    year], @"Copyright",
-	    [[[NSAttributedString alloc] initWithString:
-	    [NSString stringWithFormat:
-	    @"%1$C 1987-%2$@ Tcl Core Team." "\n\n"
-		"%1$C 1989-%2$@ Contributors." "\n\n"
-		"%1$C 2011-%2$@ Kevin Walzer/WordTech Communications LLC." "\n\n"
-		"%1$C 2014-%2$@ Marc Culler." "\n\n"
-		"%1$C 2002-%2$@ Daniel A. Steffen." "\n\n"
-		"%1$C 2001-2009 Apple Inc." "\n\n"
-		"%1$C 2001-2002 Jim Ingham & Ian Reid" "\n\n"
-		"%1$C 1998-2000 Jim Ingham & Ray Johnson" "\n\n"
-		"%1$C 1998-2000 Scriptics Inc." "\n\n"
-		"%1$C 1996-1997 Sun Microsystems Inc.", 0xA9, year] attributes:
-	    [NSDictionary dictionaryWithObject:style
-	    forKey:NSParagraphStyleAttributeName]] autorelease], @"Credits",
-	    nil];
-    [NSApp orderFrontStandardAboutPanelWithOptions:options];
+   
+    /*
+     * This replaces the old about dialog with a standard alert that displays
+     * correctly on 10.14.
+     */
+    
+    NSString *version =  @"Tcl " TCL_PATCH_LEVEL " & Tk " TCL_PATCH_LEVEL;
+    NSString *url =   @"www.tcl-lang.org";
+    NSTextView *credits = [[NSTextView alloc] initWithFrame:NSMakeRect(0,0,300,300)];
+    NSFont *font = [NSFont systemFontOfSize:[NSFont systemFontSize]];
+    NSDictionary *textAttributes = [NSDictionary dictionaryWithObject:font
+					        forKey:NSFontAttributeName];
+    [credits insertText: [[NSAttributedString alloc]
+		 initWithString:[NSString stringWithFormat: @"\n"
+		"Tcl and Tk are distributed under a modified BSD license: "
+		"www.tcl.tk/software/tcltk/license.html\n\n"
+		"%1$C 1987-%2$@ Tcl Core Team and Contributers.\n\n"
+		"%1$C 2011-%2$@ Kevin Walzer/WordTech Communications LLC.\n\n"
+		"%1$C 2014-%2$@ Marc Culler.\n\n"
+		"%1$C 2002-2012 Daniel A. Steffen.\n\n"
+		"%1$C 2001-2009 Apple Inc.\n\n"
+		"%1$C 2001-2002 Jim Ingham & Ian Reid\n\n"
+		"%1$C 1998-2000 Jim Ingham & Ray Johnson\n\n"
+		"%1$C 1998-2000 Scriptics Inc.\n\n"
+		"%1$C 1996-1997 Sun Microsystems Inc.", 0xA9, year]
+	     attributes:textAttributes]
+             replacementRange:NSMakeRange(0,0)];
+    [credits setDrawsBackground:NO];
+    [credits setEditable:NO];
+     NSAlert *about = [[NSAlert alloc] init];
+    [[about window] setTitle:@"About Tcl & Tk"];
+    [about setMessageText: version];
+    [about setInformativeText:url];
+    about.accessoryView = credits;
+    [about runModal];
+    [about release];
 }
 
 /*
@@ -1257,7 +1263,7 @@ TkMacOSXStandardAboutPanelObjCmd(
 	Tcl_WrongNumArgs(interp, 1, objv, NULL);
 	return TCL_ERROR;
     }
-    [NSApp orderFrontStandardAboutPanelWithOptions:[NSDictionary dictionary]];
+    TkAboutDlg();
     return TCL_OK;
 }
 
diff --git a/macosx/tkMacOSXDraw.c b/macosx/tkMacOSXDraw.c
index ce53a177e..984e2e57b 100644
--- a/macosx/tkMacOSXDraw.c
+++ b/macosx/tkMacOSXDraw.c
@@ -111,6 +111,25 @@ TkMacOSXInitCGDrawing(
  *
  *	Extract bitmap data from a MacOSX drawable as an NSBitmapImageRep.
  *
+ *      This is only used by XGetImage, which is never called.  And this
+ *      implementation does not work correctly.  Originally it relied on
+ *      [NSBitmapImageRep initWithFocusedViewRect:view_rect] which was
+ *      deprecated by Apple in OSX 10.14 and also required the use of other
+ *      deprecated functions such as [NSView lockFocus]. Apple's suggested
+ *      replacement is [NSView cacheDisplayInRect: toBitmapImageRep:] and that
+ *      is what is being used here.  However, that method only works when the
+ *      view has a valid CGContext, and a view is only guaranteed to have a
+ *      valid context during a call to [NSView drawRect].  To further
+ *      complicate matters, cacheDisplayInRect calls [NSView drawRect].
+ *      Essentially it is asking the view to draw a subrectangle of itself into
+ *      a special graphics context which is linked to the BitmapImageRep.  But
+ *      our implementation of [NSView drawRect] does not allow recursive calls.
+ *      If called recursively it returns immediately without doing any drawing.
+ *      So the bottom line is that this function either returns a NULL pointer
+ *      or a black image.  To make it useful would require a significant amount
+ *      of rewriting of the drawRect method.  Perhaps the next release of OSX
+ *      will include some more helpful ways of doing this.
+ *
  * Results:
  *	Returns an NSBitmapRep representing the image of the given
  *      rectangle of the given drawable.  This object is retained.
@@ -134,15 +153,16 @@ TkMacOSXBitmapRepFromDrawableRect(
 	unsigned int height)
 {
     MacDrawable *mac_drawable = (MacDrawable *) drawable;
-    CGContextRef cg_context=NULL;
-    CGImageRef cg_image=NULL, sub_cg_image=NULL;
-    NSBitmapImageRep *bitmap_rep=NULL;
+    CGContextRef cg_context = NULL;
+    CGImageRef cg_image=NULL, sub_cg_image = NULL;
+    NSBitmapImageRep *bitmap_rep = NULL;
     NSView *view=NULL;
     if ( mac_drawable->flags & TK_IS_PIXMAP ) {
+
 	/*
-	 * This means that the MacDrawable is functioning as a
-	 * Tk Pixmap, so its view field is NULL.
-	*/
+	 * This MacDrawable is a bitmap, so its view is NULL.
+	 */
+
 	cg_context = TkMacOSXGetCGContextForDrawable(drawable);
 	CGRect image_rect = CGRectMake(x, y, width, height);
 	cg_image = CGBitmapContextCreateImage( (CGContextRef) cg_context);
@@ -155,22 +175,32 @@ TkMacOSXBitmapRepFromDrawableRect(
 	    CGImageRelease(cg_image);
 	}
     } else if ( (view = TkMacOSXDrawableView(mac_drawable)) ) {
+
 	/*
 	 * Convert Tk top-left to NSView bottom-left coordinates.
 	 */
+
 	int view_height = [view bounds].size.height;
 	NSRect view_rect = NSMakeRect(x + mac_drawable->xOff,
 			       view_height - height - y - mac_drawable->yOff,
 			       width, height);
 
-	if ( [view lockFocusIfCanDraw] ) {
-	    bitmap_rep = [NSBitmapImageRep alloc];
-	    bitmap_rep = [bitmap_rep initWithFocusedViewRect:view_rect];
-	    [view unlockFocus];
+	/*
+	 * Attempt to copy from the view to a bitmapImageRep.  If the view does
+	 * not have a valid CGContext, doing this will silently corrupt memory
+	 * and make a big mess. So, in that case, we mark the view as needing
+	 * display and return NULL.
+	 */
+
+	if (view == [NSView focusView]) {
+	    bitmap_rep = [view bitmapImageRepForCachingDisplayInRect: view_rect];
+	    [bitmap_rep retain];
+	    [view cacheDisplayInRect:view_rect toBitmapImageRep:bitmap_rep];
 	} else {
-	    TkMacOSXDbgMsg("Could not lock focus on view.");
+	    TkMacOSXDbgMsg("No CGContext - cannot copy from screen to bitmap.");
+	    [view setNeedsDisplay:YES];
+	    return NULL;
 	}
-
     } else {
 	TkMacOSXDbgMsg("Invalid source drawable");
     }
@@ -211,26 +241,24 @@ XCopyArea(
     MacDrawable *srcDraw = (MacDrawable *) src;
     NSBitmapImageRep *bitmap_rep = NULL;
     CGImageRef img = NULL;
+    CGRect bounds, srcRect, dstRect;
 
     display->request++;
-
     if (!width || !height) {
-	/* This happens all the time.
-	TkMacOSXDbgMsg("Drawing of empty area requested");
-	*/
 	return;
     }
 
     if (!TkMacOSXSetupDrawingContext(dst, gc, 1, &dc)) {
 	return;
-	/*TkMacOSXDbgMsg("Failed to setup drawing context.");*/
+	TkMacOSXDbgMsg("Failed to setup drawing context.");
     }
 
     if ( dc.context ) {
 	if (srcDraw->flags & TK_IS_PIXMAP) {
 	    img = TkMacOSXCreateCGImageWithDrawable(src);
 	}else if (TkMacOSXDrawableWindow(src)) {
-	    bitmap_rep =  TkMacOSXBitmapRepFromDrawableRect(src, src_x, src_y, width, height);
+	    bitmap_rep =  TkMacOSXBitmapRepFromDrawableRect(src,
+				   src_x, src_y, width, height);
 	    if ( bitmap_rep ) {
 		img = [bitmap_rep CGImage];
 	    }
@@ -239,13 +267,12 @@ XCopyArea(
 	}
 
 	if (img) {
-	    TkMacOSXDrawCGImage(dst, gc, dc.context, img, gc->foreground, gc->background,
-			CGRectMake(0, 0, srcDraw->size.width, srcDraw->size.height),
-			CGRectMake(src_x, src_y, width, height),
-			CGRectMake(dest_x, dest_y, width, height));
+	    bounds = CGRectMake(0, 0, srcDraw->size.width, srcDraw->size.height);
+	    srcRect = CGRectMake(src_x, src_y, width, height);
+	    dstRect = CGRectMake(dest_x, dest_y, width, height);
+	    TkMacOSXDrawCGImage(dst, gc, dc.context, img,
+		     gc->foreground, gc->background, bounds, srcRect, dstRect);
 	    CFRelease(img);
-
-
 	} else {
 	    TkMacOSXDbgMsg("Failed to construct CGImage.");
 	}
@@ -294,7 +321,7 @@ XCopyPlane(
     TkMacOSXDrawingContext dc;
     MacDrawable *srcDraw = (MacDrawable *) src;
     MacDrawable *dstDraw = (MacDrawable *) dst;
-
+    CGRect bounds, srcRect, dstRect;
     display->request++;
     if (!width || !height) {
 	/* TkMacOSXDbgMsg("Drawing of empty area requested"); */
@@ -314,7 +341,7 @@ XCopyPlane(
 		TkpClipMask *clipPtr = (TkpClipMask *) gc->clip_mask;
 		unsigned long imageBackground  = gc->background;
                 if (clipPtr && clipPtr->type == TKP_CLIP_PIXMAP){
-		    CGRect srcRect = CGRectMake(src_x, src_y, width, height);
+		    srcRect = CGRectMake(src_x, src_y, width, height);
 		    CGImageRef mask = TkMacOSXCreateCGImageWithDrawable(clipPtr->value.pixmap);
 		    CGImageRef submask = CGImageCreateWithImageInRect(img, srcRect);
 		    CGRect rect = CGRectMake(dest_x, dest_y, width, height);
@@ -339,10 +366,11 @@ XCopyPlane(
 		    CGImageRelease(submask);
 		    CGImageRelease(subimage);
 		} else {
-		    TkMacOSXDrawCGImage(dst, gc, dc.context, img, gc->foreground, imageBackground,
-				CGRectMake(0, 0, srcDraw->size.width, srcDraw->size.height),
-				CGRectMake(src_x, src_y, width, height),
-				CGRectMake(dest_x, dest_y, width, height));
+		    bounds = CGRectMake(0, 0, srcDraw->size.width, srcDraw->size.height);
+		    srcRect = CGRectMake(src_x, src_y, width, height);
+		    dstRect = CGRectMake(dest_x, dest_y, width, height);
+		    TkMacOSXDrawCGImage(dst, gc, dc.context, img, gc->foreground,
+					imageBackground, bounds, srcRect, dstRect);
 		    CGImageRelease(img);
 		}
 	    } else { /* no image */
@@ -446,10 +474,8 @@ TkMacOSXGetNSImageWithTkImage(
     int height)
 {
     Pixmap pixmap = Tk_GetPixmap(display, None, width, height, 0);
-    MacDrawable *macDraw = (MacDrawable *) pixmap;
     NSImage *nsImage;
 
-    macDraw->flags |= TK_USE_XIMAGE_ALPHA;
     Tk_RedrawImage(image, 0, 0, width, height, pixmap, 0, 0);
     nsImage = CreateNSImageWithPixmap(pixmap, width, height);
     Tk_FreePixmap(display, pixmap);
@@ -602,11 +628,13 @@ TkMacOSXDrawCGImage(
 	    }
 	}
 	dstBounds = CGRectOffset(dstBounds, macDraw->xOff, macDraw->yOff);
-
 	if (CGImageIsMask(image)) {
-	    /*CGContextSaveGState(context);*/
 	    if (macDraw->flags & TK_IS_BW_PIXMAP) {
-		/* Set fill color to black, background comes from the context, or is transparent. */
+
+		/* Set fill color to black; background comes from the context,
+		 * or is transparent.
+		 */
+
 		if (imageBackground != TRANSPARENT_PIXEL << 24) {
 		    CGContextClearRect(context, dstBounds);
 		}
@@ -1454,7 +1482,7 @@ TkMacOSXSetUpGraphicsPort(
  *----------------------------------------------------------------------
  */
 
-int
+Bool
 TkMacOSXSetupDrawingContext(
     Drawable d,
     GC gc,
@@ -1462,38 +1490,69 @@ TkMacOSXSetupDrawingContext(
     TkMacOSXDrawingContext *dcPtr)
 {
     MacDrawable *macDraw = ((MacDrawable*)d);
-    int dontDraw = 0, isWin = 0;
+    Bool canDraw = true;
+    NSWindow *win = NULL;
     TkMacOSXDrawingContext dc = {};
     CGRect clipBounds;
 
-    dc.clipRgn = TkMacOSXGetClipRgn(d);
-    if (!dontDraw) {
-	ClipToGC(d, gc, &dc.clipRgn);
-	dontDraw = dc.clipRgn ? HIShapeIsEmpty(dc.clipRgn) : 0;
-    }
-    if (dontDraw) {
-	goto end;
+    /*
+     * If we are simulating drawing for tests, just return false.
+     */
+
+    if ([NSApp simulateDrawing]) {
+	return false;
     }
-    if (useCG) {
-	dc.context = TkMacOSXGetCGContextForDrawable(d);
+
+    /*
+     * If the drawable is not a pixmap and it has an associated
+     * NSWindow then we know we are drawing to a window.
+     */
+
+    if (!(macDraw->flags & TK_IS_PIXMAP)) {
+	win = TkMacOSXDrawableWindow(d);
     }
-    if (!dc.context || !(macDraw->flags & TK_IS_PIXMAP)) {
-	isWin = (TkMacOSXDrawableWindow(d) != nil);
+
+    /*
+     * Check that we have a non-empty clipping region.
+     */
+
+    dc.clipRgn = TkMacOSXGetClipRgn(d);
+    ClipToGC(d, gc, &dc.clipRgn);
+    if (dc.clipRgn && HIShapeIsEmpty(dc.clipRgn)) {
+	canDraw = false;
+	goto end;
     }
+
+    /*
+     * If we already have a CGContext, use it.  Otherwise, if we
+     * are drawing to a window then we can get one from the
+     * window.
+     */
+
+    dc.context = TkMacOSXGetCGContextForDrawable(d);
     if (dc.context) {
 	dc.portBounds = clipBounds = CGContextGetClipBoundingBox(dc.context);
-    } else if (isWin) {
+    } else if (win) {
 	NSView *view = TkMacOSXDrawableView(macDraw);
 	if (view) {
-	    if (view != [NSView focusView]) {
-		dc.focusLocked = [view lockFocusIfCanDraw];
-		dontDraw = !dc.focusLocked;
-	    } else {
-		dontDraw = ![view canDraw];
-	    }
-	    if (dontDraw) {
-		goto end;
-	    }
+
+	    /*
+	     * We can only draw into the view when the current CGContext is
+	     * valid and belongs to the view.  Validity can only be guaranteed
+	     * inside of a view's drawRect or setFrame methods.  The isDrawing
+	     * attribute tells us whether we are being called from one of those
+	     * methods.
+	     *
+	     * If the CGContext is not valid, or belongs to a different View,
+	     * then we mark our view as needing display and return failure.
+	     * It should get drawn in a later call to drawRect.
+	     */
+
+           if (view != [NSView focusView]) {
+	       [view setNeedsDisplay:YES];
+	       canDraw = false;
+	       goto end;
+	   }
 	    dc.view = view;
 	    dc.context = GET_CGCONTEXT;
 	    dc.portBounds = NSRectToCGRect([view bounds]);
@@ -1508,14 +1567,17 @@ TkMacOSXSetupDrawingContext(
 	Tcl_Panic("TkMacOSXSetupDrawingContext(): "
 		"no context to draw into !");
     }
+
+    /*
+     * Configure the drawing context.
+     */
+
     if (dc.context) {
 	CGAffineTransform t = { .a = 1, .b = 0, .c = 0, .d = -1, .tx = 0,
 		.ty = dc.portBounds.size.height};
 	dc.portBounds.origin.x += macDraw->xOff;
 	dc.portBounds.origin.y += macDraw->yOff;
-	if (!dc.focusLocked) {
-	    CGContextSaveGState(dc.context);
-	}
+	CGContextSaveGState(dc.context);
 	CGContextSetTextDrawingMode(dc.context, kCGTextFill);
 	CGContextConcatCTM(dc.context, t);
 	if (dc.clipRgn) {
@@ -1550,7 +1612,7 @@ TkMacOSXSetupDrawingContext(
 	    double w = gc->line_width;
 
 	    TkMacOSXSetColorInContext(gc, gc->foreground, dc.context);
-	    if (isWin) {
+	    if (win) {
 		CGContextSetPatternPhase(dc.context, CGSizeMake(
 			dc.portBounds.size.width, dc.portBounds.size.height));
 	    }
@@ -1588,13 +1650,21 @@ TkMacOSXSetupDrawingContext(
 	    }
 	}
     }
+
 end:
-    if (dontDraw && dc.clipRgn) {
+#ifdef TK_MAC_DEBUG_DRAWING
+    if (!canDraw && win != NULL) {
+	TkWindow *winPtr = TkMacOSXGetTkWindow(win);
+	if (winPtr) fprintf(stderr, "Cannot draw in %s - postponing.\n",
+			    Tk_PathName(winPtr));
+    }
+#endif
+    if (!canDraw && dc.clipRgn) {
 	CFRelease(dc.clipRgn);
 	dc.clipRgn = NULL;
     }
     *dcPtr = dc;
-    return !dontDraw;
+    return canDraw;
 }
 
 /*
@@ -1619,12 +1689,7 @@ TkMacOSXRestoreDrawingContext(
 {
     if (dcPtr->context) {
 	CGContextSynchronize(dcPtr->context);
-	[[dcPtr->view window] setViewsNeedDisplay:YES];
-	if (dcPtr->focusLocked) {
-	    [dcPtr->view unlockFocus];
-	} else {
-	    CGContextRestoreGState(dcPtr->context);
-	}
+	CGContextRestoreGState(dcPtr->context);
     }
     if (dcPtr->clipRgn) {
 	CFRelease(dcPtr->clipRgn);
@@ -1663,17 +1728,13 @@ TkMacOSXGetClipRgn(
 #ifdef TK_MAC_DEBUG_DRAWING
 	TkMacOSXDbgMsg("%s", macDraw->winPtr->pathName);
 	NSView *view = TkMacOSXDrawableView(macDraw);
-	if ([view lockFocusIfCanDraw]) {
-	    CGContextRef context = GET_CGCONTEXT;
-	    CGContextSaveGState(context);
-	    CGContextConcatCTM(context, CGAffineTransformMake(1.0, 0.0, 0.0,
-		    -1.0, 0.0, [view bounds].size.height));
-	    ChkErr(HIShapeReplacePathInCGContext, macDraw->visRgn, context);
-	    CGContextSetRGBFillColor(context, 0.0, 1.0, 0.0, 0.1);
-	    CGContextEOFillPath(context);
-	    CGContextRestoreGState(context);
-	    [view unlockFocus];
-	}
+	CGContextSaveGState(context);
+	CGContextConcatCTM(context, CGAffineTransformMake(1.0, 0.0, 0.0,
+	      -1.0, 0.0, [view bounds].size.height));
+	ChkErr(HIShapeReplacePathInCGContext, macDraw->visRgn, context);
+	CGContextSetRGBFillColor(context, 0.0, 1.0, 0.0, 0.1);
+	CGContextEOFillPath(context);
+	CGContextRestoreGState(context);
 #endif /* TK_MAC_DEBUG_DRAWING */
     }
 
@@ -1733,13 +1794,11 @@ TkpClipDrawableToRect(
     int width, int height)
 {
     MacDrawable *macDraw = (MacDrawable *) d;
-    NSView *view = TkMacOSXDrawableView(macDraw);
 
     if (macDraw->drawRgn) {
 	CFRelease(macDraw->drawRgn);
 	macDraw->drawRgn = NULL;
     }
-
     if (width >= 0 && height >= 0) {
 	CGRect clipRect = CGRectMake(x + macDraw->xOff, y + macDraw->yOff,
 		width, height);
@@ -1755,17 +1814,6 @@ TkpClipDrawableToRect(
 	} else {
 	    macDraw->drawRgn = drawRgn;
 	}
-	if (view && view != [NSView focusView] && [view lockFocusIfCanDraw]) {
-	    clipRect.origin.y = [view bounds].size.height -
-		    (clipRect.origin.y + clipRect.size.height);
-	    NSRectClip(NSRectFromCGRect(clipRect));
-	    macDraw->flags |= TK_FOCUSED_VIEW;
-	}
-    } else {
-	if (view && (macDraw->flags & TK_FOCUSED_VIEW)) {
-	    [view unlockFocus];
-	    macDraw->flags &= ~TK_FOCUSED_VIEW;
-	}
     }
 }
 
diff --git a/macosx/tkMacOSXEvent.c b/macosx/tkMacOSXEvent.c
index 25c0bea36..798c73ca0 100644
--- a/macosx/tkMacOSXEvent.c
+++ b/macosx/tkMacOSXEvent.c
@@ -112,11 +112,16 @@ enum {
  *
  * TkMacOSXFlushWindows --
  *
- *	This routine is a stub called by XSync, which is called during
- *      the Tk update command.  It calls displayIfNeeded on all visible
- *      windows.  This is necessary in order to insure that update will
- *      run all of the display procedures which have been registered as
- *      idle tasks.  The test suite assumes that this is the case.
+ *	This routine is a stub called by XSync, which is called during the Tk
+ *      update command.  The language specification does not require that the
+ *      update command be synchronous but many of the tests assume that is the
+ *      case.  It is not naturally the case on macOS since many idle tasks are
+ *      run inside of the drawRect method of a window's contentView, and that
+ *      method will not be called until after this function returns.  To make
+ *      the tests work, we attempt to force this to be synchronous by waiting
+ *      until drawRect has been called for each window.  The mechanism we use
+ *      for this is to have drawRect post an ApplicationDefined NSEvent on the
+ *      AppKit event queue when it finishes drawing, and wait for it here.
  *
  * Results:
  *	None.
@@ -132,13 +137,15 @@ MODULE_SCOPE void
 TkMacOSXFlushWindows(void)
 {
     NSArray *macWindows = [NSApp orderedWindows];
-
+    if ([NSApp simulateDrawing]) {
+	[NSApp setSimulateDrawing:NO];
+	return;
+    }
     for (NSWindow *w in macWindows) {
-	if (TkMacOSXGetXWindow(w)) {
-	    [w displayIfNeeded];
-	}
+    	if (TkMacOSXGetXWindow(w)) {
+    	    [w displayIfNeeded];
+    	}
     }
-
 }
 
 
diff --git a/macosx/tkMacOSXImage.c b/macosx/tkMacOSXImage.c
index 096faac71..a5c870adb 100644
--- a/macosx/tkMacOSXImage.c
+++ b/macosx/tkMacOSXImage.c
@@ -6,7 +6,7 @@
  * Copyright (c) 1995-1997 Sun Microsystems, Inc.
  * Copyright 2001-2009, Apple Inc.
  * Copyright (c) 2005-2009 Daniel A. Steffen <[email protected]>
- * Copyright 2017 Marc Culler.
+ * Copyright 2017-2018 Marc Culler.
  *
  * See the file "license.terms" for information on usage and redistribution
  * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
@@ -29,7 +29,8 @@ _XInitImageFuncPtrs(
  *
  * TkMacOSXCreateCGImageWithXImage --
  *
- *	Create CGImage from XImage, copying the image data.
+ *	Create CGImage from XImage, copying the image data.  Called
+ *      in Tk_PutImage and (currently) nowhere else.
  *
  * Results:
  *	CGImage, release after use.
@@ -46,8 +47,7 @@ static void ReleaseData(void *info, const void *data, size_t size) {
 
 CGImageRef
 TkMacOSXCreateCGImageWithXImage(
-    XImage *image,
-    int use_ximage_alpha)
+    XImage *image)
 {
     CGImageRef img = NULL;
     size_t bitsPerComponent, bitsPerPixel;
@@ -88,21 +88,17 @@ TkMacOSXCreateCGImageWithXImage(
 				    bitsPerPixel, image->bytes_per_line, provider, decode, 0);
 	}
     } else if (image->format == ZPixmap && image->bits_per_pixel == 32) {
+
 	/*
 	 * Color image
 	 */
 
 	CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceRGB();
-
 	bitsPerComponent = 8;
 	bitsPerPixel = 32;
 	bitmapInfo = (image->byte_order == MSBFirst ?
-		      kCGBitmapByteOrder32Big : kCGBitmapByteOrder32Little);
-	if (use_ximage_alpha) {
-	    bitmapInfo |= kCGImageAlphaPremultipliedFirst;
-	} else {
-	    bitmapInfo |= kCGImageAlphaNoneSkipFirst;
-	}
+		      kCGBitmapByteOrder32Little : kCGBitmapByteOrder32Big);
+	bitmapInfo |= kCGImageAlphaLast;
 	data = memcpy(ckalloc(len), image->data + image->xoffset, len);
 	if (data) {
 	    provider = CGDataProviderCreateWithData(data, data, len, releaseData);
@@ -128,7 +124,12 @@ TkMacOSXCreateCGImageWithXImage(
  *
  * XGetImage --
  *
- *	This function copies data from a pixmap or window into an XImage.
+ *	This function copies data from a pixmap or window into an XImage.  It
+ *      is essentially never used. At one time it was called by
+ *      pTkImgPhotoDisplay, but that is no longer the case. Currently it is
+ *      called two places, one of which is requesting an XY image which we do
+ *      not support.  It probably does not work correctly -- see the comments
+ *      for TkMacOSXBitmapRepFromDrawableRect.
  *
  * Results:
  *	Returns a newly allocated XImage containing the data from the given
@@ -165,7 +166,6 @@ XGetImage(
     unsigned int bytes_per_row, size, row, n, m;
     unsigned int scalefactor=1, scaled_height=height, scaled_width=width;
     NSWindow *win = TkMacOSXDrawableWindow(drawable);
-    MacDrawable *macDraw = ((MacDrawable*)drawable);
     static enum {unknown, no, yes} has_retina = unknown;
 
     if (win && has_retina == unknown) {
@@ -178,9 +178,11 @@ XGetImage(
     }
 
     if (has_retina == yes) {
+
 	/*
 	 * We only allow scale factors 1 or 2, as Apple currently does.
 	 */
+
 #ifdef __clang__
 	scalefactor = [win backingScaleFactor] == 2.0 ? 2 : 1;
 #endif
@@ -192,8 +194,9 @@ XGetImage(
 	if (width == 0 || height == 0) {
 	    return NULL;
 	}
+
 	bitmap_rep = TkMacOSXBitmapRepFromDrawableRect(drawable,
-		         x, y, width, height);
+			  x, y, width, height);
 	if (!bitmap_rep) {
 	    TkMacOSXDbgMsg("XGetImage: Failed to construct NSBitmapRep");
 	    return NULL;
@@ -206,39 +209,24 @@ XGetImage(
 	    (bitmap_fmt != 0 && bitmap_fmt != 1) ||
 	    [bitmap_rep samplesPerPixel] != 4    ||
 	    [bitmap_rep isPlanar] != 0           ||
-	    bytes_per_row != 4 * scaled_width    ||
+	    bytes_per_row < 4 * scaled_width    ||
 	    size != bytes_per_row*scaled_height  ) {
 	    TkMacOSXDbgMsg("XGetImage: Unrecognized bitmap format");
 	    CFRelease(bitmap_rep);
 	    return NULL;
 	}
-
-	if (macDraw->flags & TK_USE_XIMAGE_ALPHA) {
-	    /*
-	     * When called by TkImgPhotoDisplay we are being asked to return a
-	     * background image to be blended with the photoimage using its
-	     * alpha channel, if it has one.  Returning a black pixmap here
-	     * makes TkImgPhotoDisplay create an XImage with a premultiplied
-	     * alpha channel, as favored by Apple.  When TkImgPhotoDisplay
-	     * passes this XImage to TkPutImage, targeting a pixmap, it creates
-	     * an image with correct transparency.  This is used, for example,
-	     * when creating an iconphoto or a menu image from a PNG
-	     * photoimage.
-	     */
-	    bzero(bitmap, size);
-	} else {
-	    memcpy(bitmap, (char *)[bitmap_rep bitmapData], size);
-	}
+	memcpy(bitmap, (char *)[bitmap_rep bitmapData], size);
 	CFRelease(bitmap_rep);
 
 	/*
 	 * When Apple extracts a bitmap from an NSView, it may be in
 	 * either BGRA or ABGR format.  For an XImage we need RGBA.
 	 */
+
 	struct pixel_fmt pixel = bitmap_fmt == 0 ? bgra : abgr;
 
-	for (row=0, n=0; row<scaled_height; row++, n+=bytes_per_row) {
-	    for (m=n; m<n+bytes_per_row; m+=4) {
+	for (row = 0, n = 0; row < scaled_height; row++, n += bytes_per_row) {
+	    for (m = n; m < n + 4*scaled_width; m += 4) {
 		R = *(bitmap + m + pixel.r);
 		G = *(bitmap + m + pixel.g);
 		B = *(bitmap + m + pixel.b);
@@ -514,8 +502,9 @@ XCreateImage(
  *
  * TkPutImage --
  *
- *	Copies a subimage from an in-memory image to a rectangle of
- *	of the specified drawable.
+ *	Copies a rectangular subimage of an XImage into a drawable.
+ *      Currently this is only called by TkImgPhotoDisplay, using
+ *      a Window as the drawable.
  *
  * Results:
  *	None.
@@ -542,23 +531,38 @@ TkPutImage(
     unsigned int height)	/* distination and source. */
 {
     TkMacOSXDrawingContext dc;
-    MacDrawable *macDraw = ((MacDrawable*)drawable);
+    MacDrawable *macDraw = (MacDrawable *) drawable;
 
     display->request++;
     if (!TkMacOSXSetupDrawingContext(drawable, gc, 1, &dc)) {
 	return BadDrawable;
     }
     if (dc.context) {
-	CGImageRef img = TkMacOSXCreateCGImageWithXImage(image,
-			     macDraw->flags & TK_USE_XIMAGE_ALPHA);
+	CGRect bounds, srcRect, dstRect;
+	CGImageRef img = TkMacOSXCreateCGImageWithXImage(image);
+
+	/*
+	 * The CGContext for a pixmap is RGB only, with A = 0.
+	 */
+
+	if (!(macDraw->flags & TK_IS_PIXMAP)) {
+	    CGContextSetBlendMode(dc.context, kCGBlendModeSourceAtop);
+	}
 	if (img) {
-	    /* If the XImage has big pixels, rescale the source dimensions.*/
+
+	    /* If the XImage has big pixels, the source is rescaled to reflect
+	     * the actual pixel dimensions.  This is not currently used, but
+	     * could arise if the image were copied from a retina monitor and
+	     * redrawn on an ordinary monitor.
+	     */
+
 	    int pp = image->pixelpower;
+	    bounds = CGRectMake(0, 0, image->width, image->height);
+	    srcRect = CGRectMake(src_x<<pp, src_y<<pp, width<<pp, height<<pp);
+	    dstRect = CGRectMake(dest_x, dest_y, width, height);
 	    TkMacOSXDrawCGImage(drawable, gc, dc.context,
-		    img, gc->foreground, gc->background,
-		    CGRectMake(0, 0, image->width<<pp, image->height<<pp),
-		    CGRectMake(src_x<<pp, src_y<<pp, width<<pp, height<<pp),
-		    CGRectMake(dest_x, dest_y, width, height));
+				img, gc->foreground, gc->background,
+				bounds, srcRect, dstRect);
 	    CFRelease(img);
 	} else {
 	    TkMacOSXDbgMsg("Invalid source drawable");
diff --git a/macosx/tkMacOSXInit.c b/macosx/tkMacOSXInit.c
index 10ef87efc..8e9c60010 100644
--- a/macosx/tkMacOSXInit.c
+++ b/macosx/tkMacOSXInit.c
@@ -47,6 +47,7 @@ static char scriptPath[PATH_MAX + 1] = "";
 @synthesize poolLock = _poolLock;
 @synthesize macMinorVersion = _macMinorVersion;
 @synthesize isDrawing = _isDrawing;
+@synthesize simulateDrawing = _simulateDrawing;
 @end
 
 /*
@@ -162,13 +163,14 @@ static char scriptPath[PATH_MAX + 1] = "";
     systemVersion = [[NSProcessInfo processInfo] operatingSystemVersion];
     minorVersion = systemVersion.minorVersion;
 #endif
-    [NSApp setMacMinorVersion: minorVersion]; 
+    [NSApp setMacMinorVersion: minorVersion];
 
     /*
      * We are not drawing yet.
      */
 
-    [NSApp setIsDrawing: NO];
+    [NSApp setIsDrawing:NO];
+    [NSApp setSimulateDrawing:NO];
 
     /*
      * Be our own delegate.
@@ -178,6 +180,7 @@ static char scriptPath[PATH_MAX + 1] = "";
     /*
      * Make sure we are allowed to open windows.
      */
+
     [NSApp setActivationPolicy:NSApplicationActivationPolicyRegular];
 
     /*
diff --git a/macosx/tkMacOSXInt.h b/macosx/tkMacOSXInt.h
index f4859ff88..4e1e689b6 100644
--- a/macosx/tkMacOSXInt.h
+++ b/macosx/tkMacOSXInt.h
@@ -83,11 +83,10 @@ typedef struct TkWindowPrivate MacDrawable;
 #define TK_CLIP_INVALID		0x02
 #define TK_HOST_EXISTS		0x04
 #define TK_DRAWN_UNDER_MENU	0x08
-#define TK_FOCUSED_VIEW		0x10
-#define TK_IS_PIXMAP		0x20
-#define TK_IS_BW_PIXMAP		0x40
-#define TK_DO_NOT_DRAW          0x80
-#define TK_USE_XIMAGE_ALPHA     0x100
+#define TK_IS_PIXMAP		0x10
+#define TK_IS_BW_PIXMAP		0x20
+#define TK_DO_NOT_DRAW          0x40
+
 /*
  * I am reserving TK_EMBEDDED = 0x100 in the MacDrawable flags
  * This is defined in tk.h. We need to duplicate the TK_EMBEDDED flag in the
@@ -201,6 +200,7 @@ MODULE_SCOPE void TkpReleaseRegion(TkRegion r);
 MODULE_SCOPE void TkpShiftButton(NSButton *button, NSPoint delta);
 MODULE_SCOPE Bool TkpAppIsDrawing(void);
 MODULE_SCOPE void TkpDisplayWindow(Tk_Window tkwin);
+MODULE_SCOPE void TkTestSimulateDrawing(Bool);
 
 /*
  * Include the stubbed internal platform-specific API.
diff --git a/macosx/tkMacOSXKeyEvent.c b/macosx/tkMacOSXKeyEvent.c
index f79185e85..31fffa15a 100644
--- a/macosx/tkMacOSXKeyEvent.c
+++ b/macosx/tkMacOSXKeyEvent.c
@@ -68,15 +68,19 @@ unsigned short releaseCode;
         processingCompose = NO;
       }
 
+    w = [theEvent window];
+    TkWindow *winPtr = TkMacOSXGetTkWindow(w);
+    Tk_Window tkwin = (Tk_Window) winPtr;
+    XEvent xEvent;
+
+    if (!winPtr) {
+	return theEvent;
+    }
+
     switch (type) {
     case NSKeyUp:
-
 	/*Fix for bug #1ba71a86bb: key release firing on key press.*/
-	w = [theEvent window];
-	XEvent xEvent;
 	setupXEvent(&xEvent, w, 0);
-	TkWindow *winPtr = TkMacOSXGetTkWindow(w);
-	Tk_Window tkwin = (Tk_Window) winPtr;
 	xEvent.xany.type = KeyRelease;
 	xEvent.xkey.keycode = releaseCode;
 	xEvent.xany.serial = LastKnownRequestProcessed(Tk_Display(tkwin));
@@ -88,8 +92,7 @@ unsigned short releaseCode;
     case NSFlagsChanged:
 	modifiers = [theEvent modifierFlags];
 	keyCode = [theEvent keyCode];
-	//	w = [self windowWithWindowNumber:[theEvent windowNumber]];
-	w = [theEvent window];
+
 #if defined(TK_MAC_DEBUG_EVENTS) || NS_KEYLOG == 1
 	TKLog(@"-[%@(%p) %s] r=%d mods=%u '%@' '%@' code=%u c=%d %@ %d", [self class], self, _cmd, repeat, modifiers, characters, charactersIgnoringModifiers, keyCode,([charactersIgnoringModifiers length] == 0) ? 0 : [charactersIgnoringModifiers characterAtIndex: 0], w, type);
 #endif
@@ -431,6 +434,9 @@ setupXEvent(XEvent *xEvent, NSWindow *w, unsigned int state)
 {
     TkWindow *winPtr = TkMacOSXGetTkWindow(w);
     Tk_Window tkwin = (Tk_Window) winPtr;
+    if (!winPtr) {
+	return;
+    }
 
     memset(xEvent, 0, sizeof(XEvent));
     xEvent->xany.serial = LastKnownRequestProcessed(Tk_Display(tkwin));
diff --git a/macosx/tkMacOSXMenubutton.c b/macosx/tkMacOSXMenubutton.c
index a85e57273..1acefe51a 100644
--- a/macosx/tkMacOSXMenubutton.c
+++ b/macosx/tkMacOSXMenubutton.c
@@ -843,3 +843,11 @@ TkMacOSXComputeMenuButtonDrawParams(TkMenuButton * butPtr, DrawParams * dpPtr)
     return 1;
 }
 
+/*
+ * Local Variables:
+ * mode: objc
+ * c-basic-offset: 4
+ * fill-column: 79
+ * coding: utf-8
+ * End:
+ */
diff --git a/macosx/tkMacOSXMenus.c b/macosx/tkMacOSXMenus.c
index f8f00a62b..15dbad4f3 100644
--- a/macosx/tkMacOSXMenus.c
+++ b/macosx/tkMacOSXMenus.c
@@ -379,13 +379,13 @@ GenerateEditEvent(
     XVirtualEvent event;
     int x, y;
     TkWindow *winPtr = TkMacOSXGetTkWindow([NSApp keyWindow]);
-    Tk_Window tkwin = (Tk_Window) winPtr;
+    Tk_Window tkwin;
 
-    if (tkwin == NULL) {
+    if (!winPtr) {
 	return;
     }
     tkwin = (Tk_Window) winPtr->dispPtr->focusPtr;
-    if (tkwin == NULL) {
+    if (!tkwin) {
 	return;
     }
     bzero(&event, sizeof(XVirtualEvent));
diff --git a/macosx/tkMacOSXNotify.c b/macosx/tkMacOSXNotify.c
index e2769269d..7cbd24830 100644
--- a/macosx/tkMacOSXNotify.c
+++ b/macosx/tkMacOSXNotify.c
@@ -169,7 +169,7 @@ void DebugPrintQueue(void)
  *----------------------------------------------------------------------
  */
 
-static NSString *
+NSString *
 GetRunLoopMode(NSModalSession modalSession)
 {
     NSString *runLoopMode = nil;
diff --git a/macosx/tkMacOSXPrivate.h b/macosx/tkMacOSXPrivate.h
index 197879f1b..d804ca063 100644
--- a/macosx/tkMacOSXPrivate.h
+++ b/macosx/tkMacOSXPrivate.h
@@ -131,7 +131,6 @@ typedef struct TkMacOSXDrawingContext {
     NSView *view;
     HIShapeRef clipRgn;
     CGRect portBounds;
-    int focusLocked;
 } TkMacOSXDrawingContext;
 
 /*
@@ -190,8 +189,7 @@ MODULE_SCOPE int	TkGenerateButtonEventForXPointer(Window window);
 MODULE_SCOPE EventModifiers TkMacOSXModifierState(void);
 MODULE_SCOPE NSBitmapImageRep* TkMacOSXBitmapRepFromDrawableRect(Drawable drawable,
 			    int x, int y, unsigned int width, unsigned int height);
-MODULE_SCOPE CGImageRef TkMacOSXCreateCGImageWithXImage(XImage *image,
-			    int use_ximage_alpha);
+MODULE_SCOPE CGImageRef TkMacOSXCreateCGImageWithXImage(XImage *image);
 MODULE_SCOPE void       TkMacOSXDrawCGImage(Drawable d, GC gc, CGContextRef context,
 			    CGImageRef image, unsigned long imageForeground,
 			    unsigned long imageBackground, CGRect imageBounds,
@@ -267,11 +265,13 @@ VISIBILITY_HIDDEN
     int _poolLock;
     int _macMinorVersion;
     Bool _isDrawing;
+    Bool _simulateDrawing;
 #endif
 }
 @property int poolLock;
 @property int macMinorVersion;
 @property Bool isDrawing;
+@property Bool simulateDrawing;
 
 @end
 @interface TKApplication(TKInit)
@@ -333,9 +333,7 @@ VISIBILITY_HIDDEN
 
 @interface TKContentView(TKWindowEvent)
 - (void) drawRect: (NSRect) rect;
-- (void) generateExposeEvents: (HIShapeRef) shape;
-- (void) viewDidChangeEffectiveAppearance;
-- (void) updateAppearanceEvent;
+- (void) generateExposeEvents: (HIShapeRef) shape; 
 - (void) tkToolbarButton: (id) sender;
 - (BOOL) isOpaque;
 - (BOOL) wantsDefaultClipping;
diff --git a/macosx/tkMacOSXTest.c b/macosx/tkMacOSXTest.c
index 1882ce62e..5576c44af 100644
--- a/macosx/tkMacOSXTest.c
+++ b/macosx/tkMacOSXTest.c
@@ -79,6 +79,35 @@ DebuggerObjCmd(
     return TCL_OK;
 }
 
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkTestSimulateDrawing --
+ *
+ *      A test widget display procedure which records calls can use this to
+ *      avoid duplicate calls which would occur due to fact that no valid
+ *      graphics context is available to the idle task which is running the
+ *      display proc.  Note that no actual drawing to the screen will take
+ *      place when this flag is set.  This is just a wrapper for the NSApp
+ *      property.
+ *
+ *
+ * Results:
+ *      Calls to low level drawing routines will return without actually
+ *	drawing anything to the screen.
+ *
+ * Side effects:
+ *	None
+ *
+ *----------------------------------------------------------------------
+ */
+MODULE_SCOPE void
+TkTestSimulateDrawing(Bool yesno) {
+    [NSApp setSimulateDrawing:yesno];
+}
+
+
+
 /*
  * Local Variables:
  * mode: objc
diff --git a/macosx/tkMacOSXWindowEvent.c b/macosx/tkMacOSXWindowEvent.c
index 3e2231160..5bb42ae50 100644
--- a/macosx/tkMacOSXWindowEvent.c
+++ b/macosx/tkMacOSXWindowEvent.c
@@ -832,13 +832,20 @@ ConfigureRestrictProc(
 			Tk_PathName(winPtr));
 #endif
 
+    if ([NSApp simulateDrawing]) {
+    	return;
+    }
+
     /*
-     * We do not allow recursive calls to drawRect.
+     * We do not allow recursive calls to drawRect, but we only log
+     * them on OSX > 10.13, where they should never happen.
      */
-    if ([NSApp isDrawing]) {
+
+    if ([NSApp isDrawing] && [NSApp macMinorVersion] > 13) {
 	TKLog(@"WARNING: a recursive call to drawRect was aborted.");
 	return;
     }
+
     [NSApp setIsDrawing: YES];
 
     [self getRectsBeingDrawn:&rectsBeingDrawn count:&rectsBeingDrawnCount];
@@ -863,7 +870,6 @@ ConfigureRestrictProc(
 #ifdef TK_MAC_DEBUG_DRAWING
     fprintf(stderr, "drawRect: done.\n");
 #endif
-
 }
 
 -(void) setFrameSize: (NSSize)newsize
@@ -873,6 +879,12 @@ ConfigureRestrictProc(
     TkWindow *winPtr = TkMacOSXGetTkWindow(w);
     Tk_Window tkwin = (Tk_Window) winPtr;
     if (winPtr) {
+	/* On OSX versions below 10.14 setFrame calls drawRect.
+	 * On 10.14 it does its own drawing.
+	 */
+	if ([NSApp macMinorVersion] > 13) {
+	    [NSApp setIsDrawing:YES];
+	}
 	unsigned int width = (unsigned int)newsize.width;
 	unsigned int height=(unsigned int)newsize.height;
 	ClientData oldArg;
@@ -910,13 +922,18 @@ ConfigureRestrictProc(
 	TkMacOSXUpdateClipRgn(winPtr);
 
 	 /*
-	  * Finally, generate and process expose events to redraw the window.
+	  * Generate and process expose events to redraw the window.
 	  */
 
 	HIRect bounds = NSRectToCGRect([self bounds]);
 	HIShapeRef shape = HIShapeCreateWithRect(&bounds);
 	[self generateExposeEvents: shape];
 	[w displayIfNeeded];
+
+	/*
+	 * Finally, unlock the main autoreleasePool.
+	 */
+	
 	[NSApp _unlockAutoreleasePool];
     }
 }
@@ -973,34 +990,30 @@ ConfigureRestrictProc(
 	 *
 	 * Fortunately, Tk schedules all drawing to be done while Tcl is idle.
 	 * So we can do the drawing by processing all of the idle events that
-	 * were created when the expose events were processed. Unfortunately
-	 * this does not work in macOS 10.13.
+	 * were created when the expose events were processed.
 	 */
-	if ([NSApp macMinorVersion] > 13 || [self inLiveResize]) {
-	    while (Tcl_DoOneEvent(TCL_IDLE_EVENTS)) {}
-	}
+	while (Tcl_DoOneEvent(TCL_IDLE_EVENTS)) {}
     }
 }
 
-
 /*
- * These two methods allow Tk to register a virtual event which fires when the
- * appearance changes on 10.14.
+ * This method is called when a user changes between light and dark mode.
+ * The implementation here generates a Tk virtual event which can be bound
+ * to a function that redraws the window in an appropriate style.
  */
 
 - (void) viewDidChangeEffectiveAppearance
 {
-    [self updateAppearanceEvent];
-}
-
-- (void) updateAppearanceEvent
-{
+    XVirtualEvent event;
+    int x, y;
     NSString *osxMode = [[NSUserDefaults standardUserDefaults] stringForKey:@"AppleInterfaceStyle"];
     NSWindow *w = [self window];
     TkWindow *winPtr = TkMacOSXGetTkWindow(w);
-    XVirtualEvent event;
-    int x, y;
     Tk_Window tkwin = (Tk_Window) winPtr;
+
+    if (!winPtr) {
+	return;
+    }
     bzero(&event, sizeof(XVirtualEvent));
     event.type = VirtualEvent;
     event.serial = LastKnownRequestProcessed(Tk_Display(tkwin));
@@ -1040,6 +1053,9 @@ ConfigureRestrictProc(
     int x, y;
     TkWindow *winPtr = TkMacOSXGetTkWindow([self window]);
     Tk_Window tkwin = (Tk_Window) winPtr;
+    if (!winPtr){
+	return;
+    }
     bzero(&event, sizeof(XVirtualEvent));
     event.type = VirtualEvent;
     event.serial = LastKnownRequestProcessed(Tk_Display(tkwin));
diff --git a/macosx/tkMacOSXWm.c b/macosx/tkMacOSXWm.c
index 5dcc07586..9e45996cc 100644
--- a/macosx/tkMacOSXWm.c
+++ b/macosx/tkMacOSXWm.c
@@ -403,6 +403,9 @@ NSStatusItem *exitFullScreen;
 - (void)toggleFullScreen:(id)sender
 {
   TkWindow *winPtr = TkMacOSXGetTkWindow(self);
+  if (!winPtr) {
+      return;
+  }
   Tcl_Interp *interp = Tk_Interp((Tk_Window)winPtr);
   if ([NSApp macMinorVersion] > 12) {
       if (([self styleMask] & NSFullScreenWindowMask) == NSFullScreenWindowMask) {
@@ -415,13 +418,15 @@ NSStatusItem *exitFullScreen;
   }
 }
 
--(void)restoreOldScreen:(id)sender {
-
-  TkWindow *winPtr = TkMacOSXGetTkWindow(self);
-  Tcl_Interp *interp = Tk_Interp((Tk_Window)winPtr);
-
-  TkMacOSXMakeFullscreen(winPtr, self, 0, interp);
-  [[NSStatusBar systemStatusBar] removeStatusItem: exitFullScreen];
+-(void)restoreOldScreen:(id)sender
+{
+    TkWindow *winPtr = TkMacOSXGetTkWindow(self);
+    if (!winPtr) {
+	return;
+    }
+    Tcl_Interp *interp = Tk_Interp((Tk_Window)winPtr);
+    TkMacOSXMakeFullscreen(winPtr, self, 0, interp);
+    [[NSStatusBar systemStatusBar] removeStatusItem: exitFullScreen];
 }
 
 @end
@@ -431,14 +436,15 @@ NSStatusItem *exitFullScreen;
 - (BOOL) canBecomeKeyWindow
 {
     TkWindow *winPtr = TkMacOSXGetTkWindow(self);
-
-    return (winPtr && winPtr->wmInfoPtr && (winPtr->wmInfoPtr->macClass ==
-	    kHelpWindowClass || winPtr->wmInfoPtr->attributes &
-	    kWindowNoActivatesAttribute)) ? NO : YES;
+    if (!winPtr) {
+	return NO;
+    }
+    return (winPtr->wmInfoPtr &&
+	    (winPtr->wmInfoPtr->macClass == kHelpWindowClass ||
+	     winPtr->wmInfoPtr->attributes & kWindowNoActivatesAttribute)
+	    ) ? NO : YES;
 }
 
-
-
 #if DEBUG_ZOMBIES
 - (id) retain
 {
@@ -462,7 +468,8 @@ NSStatusItem *exitFullScreen;
 	title = "unnamed window";
     }
     if (DEBUG_ZOMBIES > 1){
-	printf("Autoreleased <%s>. Count is %lu\n", title, [self retainCount]);
+	fprintf(stderr, "Autoreleased <%s>. Count is %lu\n",
+		title, [self retainCount]);
     }
     return result;
 }
@@ -473,7 +480,8 @@ NSStatusItem *exitFullScreen;
 	title = "unnamed window";
     }
     if (DEBUG_ZOMBIES > 1){
-	printf("Releasing <%s>. Count is %lu\n", title, [self retainCount]);
+	fprintf(stderr, "Releasing <%s>. Count is %lu\n",
+		title, [self retainCount]);
     }
     [super release];
 }
@@ -484,7 +492,8 @@ NSStatusItem *exitFullScreen;
 	title = "unnamed window";
     }
     if (DEBUG_ZOMBIES > 0){
-	printf(">>>> Freeing <%s>. Count is %lu\n", title, [self retainCount]);
+	fprintf(stderr, ">>>> Freeing <%s>. Count is %lu\n",
+		title, [self retainCount]);
     }
     [super dealloc];
 }
@@ -605,15 +614,15 @@ FrontWindowAtPoint(
 {
     NSPoint p = NSMakePoint(x, tkMacOSXZeroScreenHeight - y);
     NSArray *windows = [NSApp orderedWindows];
-    TkWindow *front = NULL;
+    TkWindow *winPtr = NULL;
 
     for (NSWindow *w in windows) {
-	    if (w && NSMouseInRect(p, [w frame], NO)) {
-		front = TkMacOSXGetTkWindow(w);
-		break;
-	    }
+	winPtr = TkMacOSXGetTkWindow(w);
+	if (winPtr && NSMouseInRect(p, [w frame], NO)) {
+	    break;
 	}
-    return front;
+    }
+    return winPtr;
 }
 
 /*
@@ -741,7 +750,6 @@ TkWmMapWindow(
 				 * mapped. */
 {
     WmInfo *wmPtr = winPtr->wmInfoPtr;
-
     if (wmPtr->flags & WM_NEVER_MAPPED) {
 	/*
 	 * Create the underlying Mac window for this Tk window.
@@ -5677,7 +5685,7 @@ TkMacOSXMakeRealWindowExist(
     geometry.size.height += structureRect.size.height;
     geometry.origin.y = tkMacOSXZeroScreenHeight - (geometry.origin.y +
 	    geometry.size.height);
-    [window setFrame:geometry display:NO];
+    [window setFrame:geometry display:YES];
     TkMacOSXRegisterOffScreenWindow((Window) macWin, window);
     macWin->flags |= TK_HOST_EXISTS;
 }
diff --git a/macosx/tkMacOSXXStubs.c b/macosx/tkMacOSXXStubs.c
index 17cbc46b6..cc98e84a8 100644
--- a/macosx/tkMacOSXXStubs.c
+++ b/macosx/tkMacOSXXStubs.c
@@ -3,7 +3,7 @@
  *
  *	This file contains most of the X calls called by Tk. Many of these
  *	calls are just stubs and either don't make sense on the Macintosh or
- *	their implamentation just doesn't do anything. Other calls will
+ *	their implementation just doesn't do anything. Other calls will
  *	eventually be moved into other files.
  *
  * Copyright (c) 1995-1997 Sun Microsystems, Inc.
@@ -203,7 +203,6 @@ TkpOpenDisplay(
     screen->root_visual = ckalloc(sizeof(Visual));
     screen->root_visual->visualid     = 0;
     screen->root_visual->class	      = TrueColor;
-    screen->root_visual->alpha_mask   = 0xFF000000;
     screen->root_visual->red_mask     = 0x00FF0000;
     screen->root_visual->green_mask   = 0x0000FF00;
     screen->root_visual->blue_mask    = 0x000000FF;
diff --git a/tests/option.test b/tests/option.test
index ea5b5d115..c8e29da61 100644
--- a/tests/option.test
+++ b/tests/option.test
@@ -386,7 +386,7 @@ test option-15.6 {database files} -body {
 test option-15.7 {database files} -body {
     option read $option1
 	option get . x9 color
-} -result " \t\\A\n"
+} -result " \\\t\\A\n"
 test option-15.8 {database files} -body {
     option read $option1 widget foo
 } -returnCodes error -result {wrong # args: should be "option readfile fileName ?priority?"}
@@ -415,6 +415,22 @@ test option-16.1 {ReadOptionFile} -body {
     removeFile $option4
 } -result {true false}
 
+set opt162val {label {
+  foo bar
+}
+}
+set opt162list [split $opt162val \n]
+
+test option-16.2 {ticket 766ef52f3} {
+    set option5 [makeFile {} option.file4]
+    set file [open $option5 w]
+    fconfigure $file -translation crlf
+    puts $file "*notok: $opt162list"
+    close $file
+    option read $option5 userDefault
+    option get . notok notok
+} $opt162list
+
 deleteWindows
 
 # cleanup
diff --git a/xlib/X11/Xlib.h b/xlib/X11/Xlib.h
index b027e286c..8d8ec686b 100644
--- a/xlib/X11/Xlib.h
+++ b/xlib/X11/Xlib.h
@@ -203,9 +203,6 @@ typedef struct {
 	int class;		/* class of screen (monochrome, etc.) */
 #endif
 	unsigned long red_mask, green_mask, blue_mask;	/* mask values */
-#if defined(MAC_OSX_TK)
-        unsigned long alpha_mask;
-#endif
 	int bits_per_rgb;	/* log base 2 of distinct color values */
 	int map_entries;	/* color map entries */
 } Visual;
@@ -335,7 +332,6 @@ typedef struct _XImage {
     XPointer obdata;		/* hook for the object routines to hang on */
 #if defined(MAC_OSX_TK)
     int pixelpower;		/* n such that pixels are 2^n x 2^n blocks*/
-    unsigned long alpha_mask;
 #endif
     struct funcs {		/* image manipulation routines */
 	struct _XImage *(*create_image)();