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;
}