Tk Source Code

Check-in [973b11e7]
Login
Bounty program for improvements to Tcl and certain Tcl packages.
Tcl 2019 Conference, Houston/TX, US, Nov 4-8
Send your abstracts to tclconference@googlegroups.com
or submit via the online form by Sep 9.

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Added a drawing procedure for dark RadioButtons and dealt with many slightly wrong ttk details.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | bug-0d63621b6c
Files: files | file ages | folders
SHA3-256:973b11e76aa85d3daa21251229bf836bf3af1ab3dcdc33b8dd24506e6e492f38
User & Date: culler 2019-03-15 02:42:39
Context
2019-03-15
21:14
Fix some conditional compilation misconfiguration. check-in: f1f399c4 user: culler tags: bug-0d63621b6c
02:42
Added a drawing procedure for dark RadioButtons and dealt with many slightly wrong ttk details. check-in: 973b11e7 user: culler tags: bug-0d63621b6c
2019-03-13
21:46
Added a drawing procedure for dark CheckBoxes. Added drawing primitives to make the code DRYer. check-in: e85ff3ff user: culler tags: bug-0d63621b6c
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to library/ttk/aquaTheme.tcl.

    27     27   
    28     28   	# Buttons
    29     29   	ttk::style configure TButton -anchor center -width -6 \
    30     30   	    -foreground systemControlTextColor
    31     31   	ttk::style map TButton \
    32     32   	    -foreground {
    33     33   		disabled systemDisabledControlTextColor}
    34         -	ttk::style configure Toolbutton -padding 4 -foreground black
           34  +	ttk::style map TCheckbutton \
           35  +	    -foreground {
           36  +		disabled systemDisabledControlTextColor}
           37  +	ttk::style map TRadiobutton \
           38  +	    -foreground {
           39  +		disabled systemDisabledControlTextColor}
           40  +	ttk::style configure Toolbutton -padding 4
           41  +#	ttk::style configure Toolbutton -padding 4 -foreground black
           42  +#	ttk::style map Toolbutton \
           43  +#	    -background {
           44  +#		background systemWindowBody}
           45  +
    35     46   	# Workaround for #1100117:
    36     47   	# Actually, on Aqua we probably shouldn't stipple images in
    37     48   	# disabled buttons even if it did work...
    38     49   	ttk::style configure . -stipple {}
    39     50   
    40     51   
    41     52   	# Notebook

Changes to macosx/ttkMacOSXTheme.c.

   108    108    * and must be used in order to have a background color which responds
   109    109    * to Dark Mode.  So we use this hard-wired RGBA color on the older systems
   110    110    * which don't support Dark Mode anyway.
   111    111    */
   112    112   
   113    113   static CGFloat windowBackground[4] = {235.0/255, 235.0/255, 235.0/255, 1.0};
   114    114   
   115         -static int MacOSXGetBoxColor(
          115  +static int GetBoxColor(
   116    116       CGContextRef context,
   117    117       Tk_Window tkwin,
   118    118       int depth,
   119    119       CGFloat *fill)
   120    120   {
   121    121       TkWindow *winPtr = (TkWindow *)tkwin;
   122    122       NSColorSpace *deviceRGB = [NSColorSpace deviceRGBColorSpace];
................................................................................
   159    159   	    fill[i] -= (depth*8.0)/255.0;
   160    160   	}
   161    161       }
   162    162       return depth;
   163    163   }
   164    164   
   165    165   /*
   166         - * MacOSXDrawGroupBox --
          166  + * DrawGroupBox --
   167    167    *
   168    168    *    This is a standalone drawing procedure which draws the contrasting
   169    169    *    rounded rectangular box for LabelFrames and Notebook panes.
   170    170    */
   171    171   
   172         -static void MacOSXDrawGroupBox(
          172  +static void DrawGroupBox(
   173    173       CGRect bounds,
   174    174       CGContextRef context,
   175    175       Tk_Window tkwin)
   176    176   {
   177    177       CGPathRef path;
   178    178       NSColorSpace *deviceRGB = [NSColorSpace deviceRGBColorSpace];
   179    179       NSColor *borderColor, *bgColor;
   180    180       static CGFloat border[4] = {1.0, 1.0, 1.0, 0.25};
   181    181       CGFloat fill[4];
   182         -    MacOSXGetBoxColor(context, tkwin, 1, fill);
          182  +    GetBoxColor(context, tkwin, 1, fill);
   183    183       bgColor = [NSColor colorWithColorSpace: deviceRGB components: fill
   184    184   				     count: 4];
   185    185       CGContextSetFillColorSpace(context, deviceRGB.CGColorSpace);
   186    186       CGContextSetFillColorWithColor(context, bgColor.CGColor);
   187    187       path = CGPathCreateWithRoundedRect(bounds, 4, 4, NULL);
   188    188       CGContextClipToRect(context, bounds);
   189    189       CGContextBeginPath(context);
................................................................................
   210    210    *
   211    211    *    The HIToolbox does not support Dark Mode, and apparently never will,
   212    212    *    so to make widgets look "native" we have to provide analogues of the
   213    213    *    HITheme drawing functions to be used in DarkAqua.  We continue to use
   214    214    *    HITheme in Aqua, since it understands earlier versions of the OS.
   215    215    */
   216    216   
          217  +/*
          218  + *  Colors and gradients used in Dark Mode.
          219  + */
   217    220   
   218    221   static CGFloat darkButtonFace[4] = {112.0/255, 113.0/255, 115.0/255, 1.0};
   219    222   static CGFloat darkDisabledButtonFace[4] = {86.0/255, 87.0/255, 89.0/255, 1.0};
   220    223   static CGFloat darkInactiveSelectedTab[4] = {159.0/255, 160.0/255, 161.0/255, 1.0};
   221    224   static CGFloat darkTabSeparator[4] = {0.0, 0.0, 0.0, 0.25};
   222    225   static CGFloat darkTopGradient[8] = {1.0, 1.0, 1.0, 0.3,
   223    226   				     1.0, 1.0, 1.0, 0.0};
   224    227   static CGFloat darkBackgroundGradient[8] = {0.0, 0.0, 0.0, 0.1,
   225    228   					    0.0, 0.0, 0.0, 0.25};
   226         -static CGFloat darkCheckGradient[8] = {89.0/255, 90.0/255, 93.0/255, 1.0,
          229  +static CGFloat darkInactiveGradient[8] = {89.0/255, 90.0/255, 93.0/255, 1.0,
   227    230   				       119.0/255, 120.0/255, 122.0/255, 1.0};
   228    231   static CGFloat darkSelectedGradient[8] = {23.0/255, 111.0/255, 232.0/255, 1.0,
   229    232   					  20.0/255, 94.0/255,  206.0/255, 1.0};
          233  +
          234  +/*
          235  + * NormalizeButtonBounds --
          236  + *
          237  + * Apple's Human Interface Guidelines only allow three specific heights for buttons:
          238  + * Regular, small and mini. We always use the regular size.  However, Ttk may
          239  + * provide an arbitrary bounding rectangle.  We always draw the button centered
          240  + * vertically on the rectangle, and having the same width as the rectangle.
          241  + * This function returns the actual bounding rectangle that will be used in
          242  + * drawing the button.
          243  + */
          244  +
          245  +static CGRect NormalizeButtonBounds(
          246  +    SInt32 heightMetric,
          247  +    CGRect bounds)
          248  +{
          249  +    SInt32 height;
          250  +    ChkErr(GetThemeMetric, heightMetric, &height);
          251  +    bounds.origin.y += (bounds.size.height - height)/2;
          252  +    bounds.size.height = height;
          253  +    return bounds;
          254  +}
   230    255   
   231    256   /* FillButtonBackground --
   232    257    *
   233    258    *    Fills a rounded rectangle with a transparent black gradient.
   234    259    */
   235    260   
   236    261   static void FillButtonBackground(
................................................................................
   325    350       CGContextClip(context);
   326    351       CGContextDrawLinearGradient(context, gradient, bounds.origin, end, 0);
   327    352       CFRelease(path);
   328    353       CFRelease(gradient);
   329    354   }
   330    355   
   331    356   /*
   332         - * MacOSXDrawDarkButton --
          357  + * DrawDarkButton --
   333    358    *
   334    359    *    This is a standalone drawing procedure which draws PushButtons and
   335    360    *    PopupButtons in the Dark Mode style.
   336    361    */
   337    362   
   338         -static void MacOSXDrawDarkButton(
          363  +static void DrawDarkButton(
   339    364       CGRect bounds,
   340    365       ThemeButtonKind kind,
   341    366       Ttk_State state,
   342    367       CGContextRef context)
   343    368   {
   344    369       NSColorSpace *deviceRGB = [NSColorSpace deviceRGBColorSpace];
   345    370       NSColor *faceColor;
   346    371   
   347         -    CGContextSetLineWidth(context, 1.0);
          372  +    /*
          373  +     * To match the appearance of Apple's buttons we need to increase the
          374  +     * height by 1 pixel.
          375  +     */
          376  +
          377  +    bounds.size.height += 1;
          378  +
   348    379       CGContextClipToRect(context, bounds);
   349    380       FillButtonBackground(context, bounds, 5);
   350    381   
   351    382       /*
   352    383        * Fill the button face with the appropriate color.
   353    384        */
   354    385   
................................................................................
   401    432   	CGContextRestoreGState(context);
   402    433       }
   403    434   
   404    435       HighlightButtonBorder(context, bounds);
   405    436   }
   406    437   
   407    438   /*
   408         - * MacOSXDrawDarkCheckBox --
          439  + * DrawDarkCheckBox --
   409    440    *
   410    441    *    This is a standalone drawing procedure which draws Checkboxes
   411    442    *    in the Dark Mode style.
   412    443    */
   413    444   
   414         -static void MacOSXDrawDarkCheckBox(
          445  +static void DrawDarkCheckBox(
   415    446       CGRect bounds,
   416    447       Ttk_State state,
   417    448       CGContextRef context)
   418    449   {
   419         -    CGRect checkbounds = {{2, 3},{16, 16}};
          450  +    CGRect checkbounds = {{0, bounds.size.height/2 - 8},{16, 16}};
   420    451       NSColorSpace *deviceRGB = [NSColorSpace deviceRGBColorSpace];
   421    452       NSColor *stroke;
   422    453       CGFloat x, y;
   423    454       bounds = CGRectOffset(checkbounds, bounds.origin.x, bounds.origin.y);
   424    455       x = bounds.origin.x;
   425    456       y = bounds.origin.y;
   426    457   
   427    458       CGContextClipToRect(context, bounds);
   428    459       FillButtonBackground(context, bounds, 4);
   429    460       bounds = CGRectInset(bounds, 1, 1);
   430         -    GradientFillButtonFace(context, bounds, 3, darkCheckGradient, 2);
          461  +    if (!(state & TTK_STATE_BACKGROUND) &&
          462  +	((state  & TTK_STATE_SELECTED) || (state & TTK_STATE_ALTERNATE))) {
          463  +	GradientFillButtonFace(context, bounds, 3, darkSelectedGradient, 2);
          464  +    } else {
          465  +	GradientFillButtonFace(context, bounds, 3, darkInactiveGradient, 2);
          466  +    }
   431    467       HighlightButtonBorder(context, bounds);
   432    468       if ((state  & TTK_STATE_SELECTED) || (state & TTK_STATE_ALTERNATE)) {
   433    469   	CGContextSetStrokeColorSpace(context, deviceRGB.CGColorSpace);
   434    470   	if (state & TTK_STATE_DISABLED) {
   435    471   	    stroke = [NSColor disabledControlTextColor];
   436    472   	} else {
   437    473   	    stroke = [NSColor controlTextColor];
   438    474   	}
   439    475   	CGContextSetStrokeColorWithColor(context, stroke.CGColor);
   440    476       }
   441    477       if (state & TTK_STATE_SELECTED) {
   442    478   	CGContextSetLineWidth(context, 1.5);
   443    479   	CGContextBeginPath(context);
   444         -	CGPoint check[3] = {{x+3, y+7}, {x+6.5, y+9.5}, {x+10, y+4}};
          480  +	CGPoint check[3] = {{x+4, y+8}, {x+7, y+11}, {x+11, y+4}};
   445    481   	CGContextAddLines(context, check, 3);
   446    482   	CGContextStrokePath(context);
   447    483       } else if (state & TTK_STATE_ALTERNATE) {
   448    484   	CGContextSetLineWidth(context, 2.0);
   449    485   	CGContextBeginPath(context);
   450         -	CGPoint check[2] = {{x+4, y+7}, {x+12, y+7}};
   451         -	CGContextAddLines(context, check, 2);
          486  +	CGPoint bar[2] = {{x+4, y+8}, {x+12, y+8}};
          487  +	CGContextAddLines(context, bar, 2);
   452    488   	CGContextStrokePath(context);
   453    489       }
   454    490   }
   455    491   
   456    492   /*
   457         - * MacOSXDrawDarkTab --
          493  + * DrawDarkRadioButton --
          494  + *
          495  + *    This is a standalone drawing procedure which draws RadioButtons
          496  + *    in the Dark Mode style.
          497  + */
          498  +
          499  +static void DrawDarkRadioButton(
          500  +    CGRect bounds,
          501  +    Ttk_State state,
          502  +    CGContextRef context)
          503  +{
          504  +    CGRect checkbounds = {{0, bounds.size.height/2 - 9},{18, 18}};
          505  +    NSColorSpace *deviceRGB = [NSColorSpace deviceRGBColorSpace];
          506  +    NSColor *fill;
          507  +    CGFloat x, y;
          508  +    bounds = CGRectOffset(checkbounds, bounds.origin.x, bounds.origin.y);
          509  +    x = bounds.origin.x;
          510  +    y = bounds.origin.y;
          511  +
          512  +    CGContextClipToRect(context, bounds);
          513  +    FillButtonBackground(context, bounds, 9);
          514  +    bounds = CGRectInset(bounds, 1, 1);
          515  +    if (!(state & TTK_STATE_BACKGROUND) &&
          516  +	((state  & TTK_STATE_SELECTED) || (state & TTK_STATE_ALTERNATE))) {
          517  +	GradientFillButtonFace(context, bounds, 8, darkSelectedGradient, 2);
          518  +    } else {
          519  +	GradientFillButtonFace(context, bounds, 8, darkInactiveGradient, 2);
          520  +    }
          521  +    HighlightButtonBorder(context, bounds);
          522  +    if ((state  & TTK_STATE_SELECTED) || (state & TTK_STATE_ALTERNATE)) {
          523  +	CGContextSetStrokeColorSpace(context, deviceRGB.CGColorSpace);
          524  +	if (state & TTK_STATE_DISABLED) {
          525  +	    fill = [NSColor disabledControlTextColor];
          526  +	} else {
          527  +	    fill = [NSColor controlTextColor];
          528  +	}
          529  +	CGContextSetFillColorWithColor(context, fill.CGColor);
          530  +    }
          531  +    if (state & TTK_STATE_SELECTED) {
          532  +	CGContextBeginPath(context);
          533  +	CGRect dot = {{x + 6, y + 6}, {6, 6}};
          534  +	CGContextAddEllipseInRect(context, dot);
          535  +	CGContextFillPath(context);
          536  +    } else if (state & TTK_STATE_ALTERNATE) {
          537  +	CGRect bar = {{x + 5, y + 8}, {8, 2}};
          538  +	CGContextFillRect(context, bar);
          539  +    }
          540  +}
          541  +
          542  +/*
          543  + * DrawDarkTab --
   458    544    *
   459    545    *    This is a standalone drawing procedure which draws Tabbed Pane
   460    546    *    Tabs in the Dark Mode style.
   461    547    */
   462    548   
   463         -static void MacOSXDrawDarkTab(
          549  +static void DrawDarkTab(
   464    550       CGRect bounds,
   465    551       Ttk_State state,
   466    552       CGContextRef context)
   467    553   {
   468    554       NSColorSpace *deviceRGB = [NSColorSpace deviceRGBColorSpace];
   469    555       NSColor *faceColor, *stroke;
   470    556       CGRect originalBounds= bounds;
................................................................................
   545    631   	    SolidFillButtonFace(context, bounds, 4, faceColor);
   546    632   	}
   547    633   	HighlightButtonBorder(context, bounds);
   548    634       }
   549    635   }
   550    636   
   551    637   /*
   552         - * MacOSXDrawDarkSeparator --
          638  + * DrawDarkSeparator --
   553    639    *
   554    640    *    This is a standalone drawing procedure which draws a separator widget
   555    641    *    in Dark Mode.
   556    642    */
   557    643   
   558         -static void MacOSXDrawDarkSeparator(
          644  +static void DrawDarkSeparator(
   559    645       CGRect bounds,
   560    646       CGContextRef context,
   561    647       Tk_Window tkwin)
   562    648   {
   563    649       static CGFloat fill[4] = {1.0, 1.0, 1.0, 0.3};
   564    650       NSColorSpace *deviceRGB = [NSColorSpace deviceRGBColorSpace];
   565    651       NSColor *fillColor = [NSColor colorWithColorSpace: deviceRGB
................................................................................
   571    657   
   572    658   #endif /* MAC_OS_X_VERSION_MIN_REQUIRED >101300 */
   573    659   
   574    660   /*----------------------------------------------------------------------
   575    661    * +++ Button element: Used for elements drawn with DrawThemeButton.
   576    662    */
   577    663   
   578         -/*
   579         - * Extra margins to account for drop shadow.
   580         - */
   581         -static Ttk_Padding ButtonMargins = {2, 2, 2, 2};
   582         -
   583    664   #define NoThemeMetric 0xFFFFFFFF
   584    665   
   585    666   typedef struct {
   586    667       ThemeButtonKind kind;
   587    668       ThemeMetric heightMetric;
   588    669   } ThemeButtonParams;
   589    670   
................................................................................
   615    696    * computeButtonDrawInfo --
   616    697    *    Fill in an appearance manager HIThemeButtonDrawInfo record.
   617    698    */
   618    699   
   619    700   static inline HIThemeButtonDrawInfo computeButtonDrawInfo(
   620    701       ThemeButtonParams *params, Ttk_State state)
   621    702   {
          703  +    /*
          704  +     *  See ButtonElementDraw for the explanation of why we always draw
          705  +     *  PushButtons in the active state.
          706  +     */
          707  +    
   622    708       const HIThemeButtonDrawInfo info = {
   623    709   	.version = 0,
   624         -	.state = Ttk_StateTableLookup(ThemeStateTable, state),
          710  +	.state = params && params->kind == kThemePushButton ?
          711  +	    kThemeStateActive : Ttk_StateTableLookup(ThemeStateTable, state),
   625    712   	.kind = params ? params->kind : 0,
   626    713   	.value = Ttk_StateTableLookup(ButtonValueTable, state),
   627    714   	.adornment = Ttk_StateTableLookup(ButtonAdornmentTable, state),
   628    715       };
   629    716       return info;
   630    717   }
   631    718   
................................................................................
   648    735       int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
   649    736   {
   650    737       ThemeButtonParams *params = clientData;
   651    738       const HIThemeButtonDrawInfo info = computeButtonDrawInfo(params, 0);
   652    739       static const CGRect scratchBounds = {{0, 0}, {100, 100}};
   653    740       CGRect contentBounds;
   654    741   
   655         -    ButtonElementSizeNoPadding(
   656         -	clientData, elementRecord, tkwin,
   657         -	widthPtr, heightPtr, paddingPtr);
          742  +    ButtonElementSizeNoPadding( clientData, elementRecord, tkwin,
          743  +    	widthPtr, heightPtr, paddingPtr);
   658    744   
   659    745       /*
   660    746        * To compute internal padding, query the appearance manager
   661    747        * for the content bounds of a dummy rectangle, then use
   662    748        * the difference as the padding.
   663    749        */
   664    750   
   665    751       ChkErr(HIThemeGetButtonContentBounds,
   666    752   	&scratchBounds, &info, &contentBounds);
   667    753   
   668    754       paddingPtr->left = CGRectGetMinX(contentBounds);
   669         -    paddingPtr->right = CGRectGetMaxX(scratchBounds) - CGRectGetMaxX(contentBounds) + 1;
   670         -    if (TkMacOSXInDarkMode(tkwin)) {
   671         -	paddingPtr->top = CGRectGetMinY(contentBounds) + 2;
   672         -	paddingPtr->bottom = CGRectGetMaxY(scratchBounds) - CGRectGetMaxY(contentBounds) + 3;
   673         -    } else {
   674         -	paddingPtr->top = CGRectGetMinY(contentBounds) + 3;
   675         -	paddingPtr->bottom = CGRectGetMaxY(scratchBounds) - CGRectGetMaxY(contentBounds) + 2;
   676         -    }
   677         -
   678         -    /*
   679         -     * Now add a little extra padding to account for drop shadows.
   680         -     * @@@ SHOULD: call GetThemeButtonBackgroundBounds() instead.
   681         -     */
   682         -
   683         -    *paddingPtr = Ttk_AddPadding(*paddingPtr, ButtonMargins);
   684         -    *widthPtr += Ttk_PaddingWidth(ButtonMargins);
   685         -    *heightPtr += Ttk_PaddingHeight(ButtonMargins);
          755  +    paddingPtr->right = CGRectGetMaxX(scratchBounds) - CGRectGetMaxX(contentBounds);
   686    756   }
   687         -
   688    757   
   689    758   static void ButtonElementDraw(
   690    759       void *clientData, void *elementRecord, Tk_Window tkwin,
   691    760       Drawable d, Ttk_Box b, Ttk_State state)
   692    761   {
   693    762       BEGIN_DRAWING(d)
   694    763       ThemeButtonParams *params = clientData;
   695         -    CGRect bounds = BoxToRect(d, Ttk_PadBox(b, ButtonMargins));
          764  +    CGRect bounds = BoxToRect(d, b);
   696    765       HIThemeButtonDrawInfo info = computeButtonDrawInfo(params, state);
          766  +    bounds = NormalizeButtonBounds(params->heightMetric, bounds);
   697    767   
   698         -#if MAC_OS_X_VERSION_MIN_REQUIRED > 101300
   699    768       if (TkMacOSXInDarkMode(tkwin)) {
          769  +#if MAC_OS_X_VERSION_MIN_REQUIRED > 101300
   700    770   	switch (info.kind) {
   701    771   	case kThemePushButton:
   702    772   	case kThemePopupButton:
   703         -	    MacOSXDrawDarkButton(bounds, info.kind, state, dc.context);
          773  +	    DrawDarkButton(bounds, info.kind, state, dc.context);
   704    774   	    break;
   705    775   	case kThemeCheckBox:
   706         -	    if (!(state & (TTK_STATE_SELECTED | TTK_STATE_ALTERNATE)) ||
   707         -		(state & TTK_STATE_BACKGROUND) ||
   708         -		(state & TTK_STATE_DISABLED)) {
   709         -		MacOSXDrawDarkCheckBox(bounds, state, dc.context);
   710         -		break;
   711         -	    }
          776  +	    DrawDarkCheckBox(bounds, state, dc.context);
          777  +	    break;
          778  +	case kThemeRadioButton:
          779  +	    DrawDarkRadioButton(bounds, state, dc.context);
          780  +	    break;
   712    781   	default:
   713    782   	    ChkErr(HIThemeDrawButton, &bounds, &info, dc.context, HIOrientation, NULL);
          783  +#endif
   714    784   	}
   715    785       } else {
          786  +	/*
          787  +	 *  Apple's PushButton and PopupButton do not change their (white) fill
          788  +	 *  color when the window is inactive although, except in 10.7 (Lion),
          789  +	 *  the color of the arrow button on a PopupButton does change.  For
          790  +	 *  some reason HITheme fills inactive buttons with a transparent color
          791  +	 *  that allows the window background to show through, leading to
          792  +	 *  inconsistent behavior.  We work around this by filling behind an
          793  +	 *  inactive PopupButton with a white color before asking HIToolbox to
          794  +	 *  draw it.  PopupButton.  For PushButtons, we simply draw them in the
          795  +	 *  active state.
          796  +	 */
          797  +	if (info.kind == kThemePopupButton && (state & TTK_STATE_BACKGROUND)) {
          798  +	    CGRect innerBounds = CGRectInset(bounds, 1, 1);
          799  +	    SolidFillButtonFace(dc.context, innerBounds, 4, [NSColor whiteColor]);
          800  +	}
   716    801   	ChkErr(HIThemeDrawButton, &bounds, &info, dc.context, HIOrientation, NULL);
   717    802       }
   718         -#else
   719         -    ChkErr(HIThemeDrawButton, &bounds, &info, dc.context, HIOrientation, NULL);
   720         -#endif
   721    803       END_DRAWING
   722    804   }
   723    805   
   724    806   static Ttk_ElementSpec ButtonElementSpec = {
   725    807       TK_STYLE_VERSION_2,
   726    808       sizeof(NullElement),
   727    809       TtkNullElementOptions,
................................................................................
   820    902   	.adornment = Ttk_StateTableLookup(TabAdornmentTable, state),
   821    903   	.kind = kHIThemeTabKindNormal,
   822    904   	.position = Ttk_StateTableLookup(TabPositionTable, state),
   823    905       };
   824    906       BEGIN_DRAWING(d)
   825    907   #if MAC_OS_X_VERSION_MIN_REQUIRED > 101300
   826    908       if (TkMacOSXInDarkMode(tkwin)) {
   827         -	MacOSXDrawDarkTab(bounds, state, dc.context);
          909  +	DrawDarkTab(bounds, state, dc.context);
   828    910       } else {
   829    911   	ChkErr(HIThemeDrawTab, &bounds, &info, dc.context, HIOrientation, NULL);
   830    912       }
   831    913   #else
   832    914       ChkErr(HIThemeDrawTab, &bounds, &info, dc.context, HIOrientation, NULL);
   833    915   #endif
   834    916       END_DRAWING
................................................................................
   860    942       TkWindow *winPtr = (TkWindow *)tkwin;
   861    943       MacDrawable *macWin = winPtr->privatePtr;
   862    944       CGRect bounds = BoxToRect(d, b);
   863    945       bounds.origin.y -= kThemeMetricTabFrameOverlap;
   864    946       bounds.size.height += kThemeMetricTabFrameOverlap;
   865    947       BEGIN_DRAWING(d)
   866    948   #if MAC_OS_X_VERSION_MIN_REQUIRED > 10800
   867         -    MacOSXDrawGroupBox(bounds, dc.context, tkwin);
          949  +    DrawGroupBox(bounds, dc.context, tkwin);
   868    950   #else
   869    951       HIThemeTabPaneDrawInfo info = {
   870    952   	.version = 1,
   871    953   	.state = Ttk_StateTableLookup(ThemeStateTable, state),
   872    954   	.direction = kThemeTabNorth,
   873    955   	.size = kHIThemeTabSizeNormal,
   874    956   	.kind = kHIThemeTabKindNormal,
................................................................................
   916    998       Drawable d, Ttk_Box b, Ttk_State state)
   917    999   {
   918   1000       TkWindow *winPtr = (TkWindow *)tkwin;
   919   1001       CGRect bounds = BoxToRect(d, b);
   920   1002   
   921   1003       BEGIN_DRAWING(d)
   922   1004   #if MAC_OS_X_VERSION_MIN_REQUIRED > 10800
   923         -    MacOSXDrawGroupBox(bounds, dc.context, tkwin);
         1005  +    DrawGroupBox(bounds, dc.context, tkwin);
   924   1006   #else
   925   1007       const HIThemeGroupBoxDrawInfo info = {
   926   1008   	.version = 0,
   927   1009   	.state = Ttk_StateTableLookup(ThemeStateTable, state),
   928   1010   	.kind = kHIThemeGroupBoxKindPrimaryOpaque,
   929   1011       };
   930   1012       ChkErr(HIThemeDrawGroupBox, &bounds, &info, dc.context, HIOrientation);
................................................................................
  1010   1092    *
  1011   1093    * NOTES:
  1012   1094    *    kThemeMetricComboBoxLargeDisclosureWidth -> 17
  1013   1095    *    Padding and margins guesstimated by trial-and-error.
  1014   1096    */
  1015   1097   
  1016   1098   static Ttk_Padding ComboboxPadding = { 2, 3, 17, 1 };
  1017         -static Ttk_Padding ComboboxMargins = { 3, 3, 4, 4 };
         1099  +static Ttk_Padding ComboboxMargins = { 3, 4, 4, 3 };
  1018   1100   
  1019   1101   static void ComboboxElementSize(
  1020   1102       void *clientData, void *elementRecord, Tk_Window tkwin,
  1021   1103       int *widthPtr, int *heightPtr, Ttk_Padding *paddingPtr)
  1022   1104   {
  1023   1105       *widthPtr = 0;
  1024   1106       *heightPtr = 0;
................................................................................
  1331   1413   	/* Separator only supports kThemeStateActive, kThemeStateInactive */
  1332   1414   	.state = Ttk_StateTableLookup(ThemeStateTable, state & TTK_STATE_BACKGROUND),
  1333   1415       };
  1334   1416   
  1335   1417       BEGIN_DRAWING(d)
  1336   1418   #if MAC_OS_X_VERSION_MIN_REQUIRED > 101300
  1337   1419       if (TkMacOSXInDarkMode(tkwin)) {
  1338         -	MacOSXDrawDarkSeparator(bounds, dc.context, tkwin);
         1420  +	DrawDarkSeparator(bounds, dc.context, tkwin);
  1339   1421       } else {
  1340   1422   	ChkErr(HIThemeDrawSeparator, &bounds, &info, dc.context, HIOrientation);
  1341   1423       }
  1342   1424   #else
  1343   1425       ChkErr(HIThemeDrawSeparator, &bounds, &info, dc.context, HIOrientation);
  1344   1426   #endif
  1345   1427       END_DRAWING
................................................................................
  1411   1493    *    Before drawing any ttk widget, its bounding rectangle is filled with a
  1412   1494    *    background color.  This color must match the background color of the
  1413   1495    *    containing widget to avoid looking ugly. The need for care when doing
  1414   1496    *    this is exacerbated by the fact that ttk enforces its "native look" by
  1415   1497    *    not allowing user control of the background or highlight colors of ttk
  1416   1498    *    widgets.
  1417   1499    *
  1418         - *    This job is made more complicated by the fact that the Appkit GroupBox
  1419         - *    (used for ttk LabelFrames) and TabbedPane (used for the Notebook widget)
  1420         - *    both place their content inside a rectangle with rounded corners that has
  1421         - *    a color which contrasts with the dialog background color.  Moreover,
  1422         - *    although the Apple human interface guidelines recommend against doing so,
  1423         - *    there are times when one wants to nest these widgets, for example having
  1424         - *    a GroupBox inside of a TabbedPane.  To have the right contrast, each
  1425         - *    level of nesting requires a different color.
         1500  + *    This job is made more complicated in recent versions of macOS by the fact
         1501  + *    that the Appkit GroupBox (used for ttk LabelFrames) and TabbedPane (used
         1502  + *    for the Notebook widget) both place their content inside a rectangle with
         1503  + *    rounded corners that has a color which contrasts with the dialog
         1504  + *    background color.  Moreover, although the Apple human interface
         1505  + *    guidelines recommend against doing so, there are times when one wants to
         1506  + *    nest these widgets, for example having a GroupBox inside of a TabbedPane.
         1507  + *    To have the right contrast, each level of nesting requires a different
         1508  + *    color.
  1426   1509    *
  1427         - *    Previous Tk releases used the HIThemeDrawGroupBox routine This meant that
  1428         - *    the best that could be done was to set the GroupBox to be of kind
  1429         - *    kHIThemeGroupBoxKindPrimaryOpaque, and set its fill color to be the
  1430         - *    system background color.  If widgets inside the box were drawn with the
  1431         - *    system background color the backgrounds would match.  But this produces a
  1432         - *    GroupBox with no contrast, so the only visual clue is a faint
  1433         - *    highlighting around the top of the GroupBox.  Moreover, the TabbedPane
  1434         - *    does not have an Opaque version, so while it is drawn inside a
  1435         - *    contrasting rounded rectangle, the widgets inside the pane needed to be
  1436         - *    enclosed in a frame with the system background color. This added a visual
  1437         - *    artifact since the frame's background color does not match the Pane's
  1438         - *    background color.  That code has been replaced with the standalone
  1439         - *    drawing procedure macOSXDrawGroupBox, which draws a rounded rectangle
  1440         - *    with an appropriate contrasting background color.
         1510  + *    Previous Tk releases used the HIThemeDrawGroupBox routine to draw
         1511  + *    GroupBoxes and TabbedPanes. This meant that the best that could be done
         1512  + *    was to set the GroupBox to be of kind kHIThemeGroupBoxKindPrimaryOpaque,
         1513  + *    and set its fill color to be the system background color.  If widgets
         1514  + *    inside the box were drawn with the system background color the
         1515  + *    backgrounds would match.  But this produces a GroupBox with no contrast,
         1516  + *    the only visual clue being a faint highlighting around the top of the
         1517  + *    GroupBox.  Moreover, the TabbedPane does not have an Opaque version, so
         1518  + *    while it is drawn inside a contrasting rounded rectangle, the widgets
         1519  + *    inside the pane needed to be enclosed in a frame with the system
         1520  + *    background color. This added a visual artifact since the frame's
         1521  + *    background color does not match the Pane's background color.  That code
         1522  + *    has now been replaced with the standalone drawing procedure
         1523  + *    macOSXDrawGroupBox, which draws a rounded rectangle with an appropriate
         1524  + *    contrasting background color.
  1441   1525    *
  1442   1526    *    Patterned backgrounds, which are now obsolete, should be aligned with the
  1443   1527    *    coordinate system of the top-level window.  Apparently failing to do this
  1444   1528    *    used to cause graphics anomalies when drawing into an off-screen graphics
  1445   1529    *    port.  The code for handling this is currently commented out.
  1446   1530    */
  1447   1531   
................................................................................
  1452   1536   {
  1453   1537       CGRect bounds = BoxToRect(d, b);
  1454   1538       BEGIN_DRAWING(d)
  1455   1539   #if MAC_OS_X_VERSION_MIN_REQUIRED > 10800
  1456   1540       NSColorSpace *deviceRGB = [NSColorSpace deviceRGBColorSpace];
  1457   1541       NSColor *bgColor;
  1458   1542       CGFloat fill[4];
  1459         -    MacOSXGetBoxColor(dc.context, tkwin, 0, fill);
         1543  +    GetBoxColor(dc.context, tkwin, 0, fill);
  1460   1544       bgColor = [NSColor colorWithColorSpace: deviceRGB components: fill
  1461   1545   				     count: 4];
  1462   1546       CGContextSetFillColorSpace(dc.context, deviceRGB.CGColorSpace);
  1463   1547       CGContextSetFillColorWithColor(dc.context, bgColor.CGColor);
  1464   1548       CGContextFillRect(dc.context, bounds);
  1465   1549   #else
  1466   1550       ThemeBrush brush = (state & TTK_STATE_BACKGROUND)