Tk Source Code

Artifact [30cdf92b]
Login

Artifact 30cdf92b83ce816b4d5e98370341910cba2e137ace10dd202cbd680e7eb2b085:

Attachment "needsToDrawRect-patch.diff" to ticket [06d8246b] added by chrstphrchvz 2020-03-22 08:46:04.
diff --git macosx/tkMacOSXDraw.c macosx/tkMacOSXDraw.c
index 1bf257202..8a793495f 100644
--- macosx/tkMacOSXDraw.c
+++ macosx/tkMacOSXDraw.c
@@ -1634,33 +1634,41 @@ TkMacOSXSetupDrawingContext(
 	 * 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.
+	 * The region to be drawn into must also intersect with the area
+	 * for the current drawRect call.
 	 *
 	 * If the CGContext is not valid then we mark our view as needing
 	 * display in the bounding rectangle of the clipping region and
 	 * return failure.  That rectangle should get drawn in a later call
 	 * to drawRect.
-	 *
-	 * As an exception to the above, if mouse buttons are pressed at the
-	 * moment when we fail to obtain a valid context we schedule the entire
-	 * view for a redraw rather than just the clipping region.  The purpose
-	 * of this is to make sure that scrollbars get updated correctly.
 	 */
 
-	if (![NSApp isDrawing] || view != [NSView focusView]) {
-	    NSRect bounds = [view bounds];
-	    NSRect dirtyNS = bounds;
-	    if ([NSEvent pressedMouseButtons]) {
-		[view setNeedsDisplay:YES];
-	    } else {
-		CGAffineTransform t = { .a = 1, .b = 0, .c = 0, .d = -1, .tx = 0,
-					.ty = dirtyNS.size.height};
-		if (dc.clipRgn) {
-		    CGRect dirtyCG = NSRectToCGRect(dirtyNS);
-		    HIShapeGetBounds(dc.clipRgn, &dirtyCG);
-		    dirtyNS = NSRectToCGRect(CGRectApplyAffineTransform(dirtyCG, t));
-		}
-		[view setNeedsDisplayInRect:dirtyNS];
-	    }
+	NSRect bounds = [view bounds];
+	NSRect dirtyNS = bounds;
+	if (dc.clipRgn) {
+	    // Don't bother initializing; will be overwritten with dc.clipRgn
+	    //CGRect dirtyCG = NSRectToCGRect(dirtyNS);
+	    CGRect dirtyCG;
+	    HIShapeGetBounds(dc.clipRgn, &dirtyCG);
+	    CGAffineTransform t = {
+		.a = 1, .b = 0, .c = 0, .d = -1, .tx = 0,
+		.ty = dirtyNS.size.height
+	    };
+	    dirtyNS = NSRectToCGRect(CGRectApplyAffineTransform(dirtyCG, t));
+	}
+	if (![NSApp isDrawing] || view != [NSView focusView] ||
+		![view needsToDrawRect:dirtyNS]) {
+	    /*
+	     * Unresolved issue: setNeedsDisplayInRect, which is preferred
+	     * for performance over setNeedsDisplay:YES, won't always trigger
+	     * a new call to drawRect before handing control back over
+	     * to the Tcl event loop. One effect of this is that scrollbars
+	     * can fail to redraw after every other MouseWheel event
+	     * for the scrolled widget (e.g. listbox or canvas).
+	     * See ticket 06d8246baf
+	     */
+	    //[view setNeedsDisplayInRect:dirtyNS];
+	    [view setNeedsDisplay:YES];
 	    canDraw = false;
 	    goto end;
 	}