From 423b0ae36f245b340d14ab4ed3ec0fdf15dc71cc Mon Sep 17 00:00:00 2001 From: culler Date: Tue, 20 Apr 2021 21:44:01 +0000 Subject: fix [cde766f911]: scrollbars do not update correctly for treeview widgets. --- macosx/tkMacOSXDraw.c | 72 +++++++++++++++++++++++++++--------------------- macosx/tkMacOSXPrivate.h | 3 +- macosx/tkMacOSXRegion.c | 49 ++++++++++++++++++++++++++++++++ macosx/ttkMacOSXTheme.c | 24 ++++++++++++---- 4 files changed, 109 insertions(+), 39 deletions(-) diff --git a/macosx/tkMacOSXDraw.c b/macosx/tkMacOSXDraw.c index ac5c721..63decb7 100644 --- a/macosx/tkMacOSXDraw.c +++ b/macosx/tkMacOSXDraw.c @@ -513,7 +513,7 @@ XDrawSegments( * * XFillPolygon -- * - * Draws a filled polygon. + * Draws a filled polygon using the even-odd fill algorithm, * * Results: * None. @@ -531,7 +531,7 @@ XFillPolygon( GC gc, /* Use this GC. */ XPoint *points, /* Array of points. */ int npoints, /* Number of points. */ - TCL_UNUSED(int), /* Shape to draw. */ + TCL_UNUSED(int), /* Shape to draw. */ int mode) /* Drawing mode. */ { MacDrawable *macWin = (MacDrawable *)d; @@ -1300,7 +1300,6 @@ TkMacOSXSetupDrawingContext( dc.portBounds = CGContextGetClipBoundingBox(dc.context); } else { NSRect drawingBounds, currentBounds; - dc.view = view; dc.context = GET_CGCONTEXT; dc.portBounds = NSRectToCGRect([view bounds]); @@ -1355,37 +1354,46 @@ TkMacOSXSetupDrawingContext( * Finish configuring the drawing context. */ - { - CGAffineTransform t = { - .a = 1, .b = 0, - .c = 0, .d = -1, - .tx = 0, - .ty = dc.portBounds.size.height - }; + 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; - CGContextSaveGState(dc.context); - CGContextSetTextDrawingMode(dc.context, kCGTextFill); - CGContextConcatCTM(dc.context, t); - if (dc.clipRgn) { + dc.portBounds.origin.x += macDraw->xOff; + dc.portBounds.origin.y += macDraw->yOff; + CGContextSaveGState(dc.context); + CGContextSetTextDrawingMode(dc.context, kCGTextFill); + CGContextConcatCTM(dc.context, t); + if (dc.clipRgn) { #ifdef TK_MAC_DEBUG_DRAWING - CGContextSaveGState(dc.context); - ChkErr(HIShapeReplacePathInCGContext, dc.clipRgn, dc.context); - CGContextSetRGBFillColor(dc.context, 1.0, 0.0, 0.0, 0.1); - CGContextEOFillPath(dc.context); - CGContextRestoreGState(dc.context); + CGContextSaveGState(dc.context); + ChkErr(HIShapeReplacePathInCGContext, dc.clipRgn, dc.context); + CGContextSetRGBFillColor(dc.context, 1.0, 0.0, 0.0, 0.1); + CGContextEOFillPath(dc.context); + CGContextRestoreGState(dc.context); #endif /* TK_MAC_DEBUG_DRAWING */ + if (!HIShapeIsRectangular(dc.clipRgn)) { + + /* + * We expect the clipping path dc.clipRgn to consist of the + * bounding rectangle of the drawable window, together with + * disjoint smaller rectangles inside of it which bound its + * geometric children. In that case the even-odd rule will + * clip to the region inside the large rectangle and outside + * of the smaller rectangles. + */ + + ChkErr(HIShapeReplacePathInCGContext, dc.clipRgn, dc.context); + CGContextEOClip(dc.context); + } + else { CGRect r; - CGRect b = CGRectApplyAffineTransform( - CGContextGetClipBoundingBox(dc.context), t); - if (!HIShapeIsRectangular(dc.clipRgn) || - !CGRectContainsRect(*HIShapeGetBounds(dc.clipRgn, &r), b)) { - ChkErr(HIShapeReplacePathInCGContext, dc.clipRgn, dc.context); - CGContextEOClip(dc.context); - } + HIShapeGetBounds(dc.clipRgn, &r); + CGContextClipToRect(dc.context, r); } } if (gc) { @@ -1405,8 +1413,8 @@ TkMacOSXSetupDrawingContext( TkMacOSXSetColorInContext(gc, gc->foreground, dc.context); if (view) { - CGContextSetPatternPhase(dc.context, CGSizeMake( - dc.portBounds.size.width, dc.portBounds.size.height)); + CGContextSetPatternPhase(dc.context, + CGSizeMake(dc.portBounds.size.width, dc.portBounds.size.height)); } if (gc->function != GXcopy) { TkMacOSXDbgMsg("Logical functions other than GXcopy are " @@ -1446,8 +1454,8 @@ TkMacOSXSetupDrawingContext( end: #ifdef TK_MAC_DEBUG_DRAWING - if (!canDraw && win != NULL) { - TkWindow *winPtr = TkMacOSXGetTkWindow(win); + if (!canDraw && macDraw->winPtr != NULL) { + TkWindow *winPtr = macDraw->winPtr; if (winPtr) { fprintf(stderr, "Cannot draw in %s - postponing.\n", diff --git a/macosx/tkMacOSXPrivate.h b/macosx/tkMacOSXPrivate.h index ed24255..0bd46c6 100644 --- a/macosx/tkMacOSXPrivate.h +++ b/macosx/tkMacOSXPrivate.h @@ -231,7 +231,8 @@ MODULE_SCOPE OSStatus TkMacOSHIShapeUnionWithRect(HIMutableShapeRef inShape, const CGRect *inRect); MODULE_SCOPE OSStatus TkMacOSHIShapeUnion(HIShapeRef inShape1, HIShapeRef inShape2, HIMutableShapeRef outResult); - +MODULE_SCOPE int TkMacOSXCountRectsInRegion(HIShapeRef shape); +MODULE_SCOPE void TkMacOSXPrintRectsInRegion(HIShapeRef shape); /* * Prototypes of TkAqua internal procs. */ diff --git a/macosx/tkMacOSXRegion.c b/macosx/tkMacOSXRegion.c index 6c70a63..3c168f1 100644 --- a/macosx/tkMacOSXRegion.c +++ b/macosx/tkMacOSXRegion.c @@ -555,6 +555,55 @@ TkMacOSHIShapeUnion( return result; } +static OSStatus +rectCounter( + int msg, + TCL_UNUSED(HIShapeRef), + const CGRect *rect, + void *ref) +{ + int *count = (int *)ref; + (*count)++; + return noErr; +} + +static OSStatus +rectPrinter( + int msg, + TCL_UNUSED(HIShapeRef), + const CGRect *rect, + void *ref) +{ + if (rect) { + printf(" %s\n", NSStringFromRect(*rect).UTF8String); + } + return noErr; +} + +int +TkMacOSXCountRectsInRegion( + HIShapeRef shape) +{ + int rect_count = 0; + if (!HIShapeIsEmpty(shape)) { + ChkErr(HIShapeEnumerate, shape, + kHIShapeParseFromBottom|kHIShapeParseFromLeft, + rectCounter, &rect_count); + } + return rect_count; +} + +void +TkMacOSXPrintRectsInRegion( + HIShapeRef shape) +{ + if (!HIShapeIsEmpty(shape)) { + ChkErr(HIShapeEnumerate, shape, + kHIShapeParseFromBottom|kHIShapeParseFromLeft, + rectPrinter, NULL); + } +} + /* * Local Variables: * mode: objc diff --git a/macosx/ttkMacOSXTheme.c b/macosx/ttkMacOSXTheme.c index 92c5156..c4e1f33 100644 --- a/macosx/ttkMacOSXTheme.c +++ b/macosx/ttkMacOSXTheme.c @@ -36,10 +36,22 @@ * Macros for handling drawing contexts. */ -#define BEGIN_DRAWING(d) { \ - TkMacOSXDrawingContext dc; \ - if (!TkMacOSXSetupDrawingContext((d), NULL, &dc)) {return;} -#define END_DRAWING \ +#define BEGIN_DRAWING(d) { \ + TkMacOSXDrawingContext dc; \ + if (!TkMacOSXSetupDrawingContext((d), NULL, &dc)) { \ + return; \ + } \ + +#define BEGIN_DRAWING_OR_REDRAW(d) { \ + TkMacOSXDrawingContext dc; \ + if (!TkMacOSXSetupDrawingContext((d), NULL, &dc)) { \ + NSView *view = TkMacOSXGetNSViewForDrawable(d); \ + while (Tcl_DoOneEvent(TCL_IDLE_EVENTS)) {} \ + [(TKContentView *)view addTkDirtyRect:[view bounds]]; \ + return; \ + } \ + +#define END_DRAWING \ TkMacOSXRestoreDrawingContext(&dc);} #define HIOrientation kHIThemeOrientationNormal @@ -1602,7 +1614,7 @@ static void TabElementDraw( .position = Ttk_StateTableLookup(TabPositionTable, state), }; - BEGIN_DRAWING(d) + BEGIN_DRAWING_OR_REDRAW(d) if (TkMacOSXInDarkMode(tkwin)) { DrawDarkTab(bounds, state, dc.context); } else { @@ -2794,7 +2806,7 @@ static void FillElementDraw( NSColorSpace *deviceRGB = [NSColorSpace deviceRGBColorSpace]; NSColor *bgColor; CGFloat fill[4]; - BEGIN_DRAWING(d) + BEGIN_DRAWING_OR_REDRAW(d) GetBackgroundColor(dc.context, tkwin, 0, fill); bgColor = [NSColor colorWithColorSpace: deviceRGB components: fill count: 4]; -- cgit v0.12