Tk Source Code

Check-in [52ea1fd5]
Login
EuroTcl/OpenACS 11 - 12 JULY 2024, VIENNA

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

Overview
Comment:Merge 9.0
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | revised_text | tip-466
Files: files | file ages | folders
SHA3-256: 52ea1fd538b9ccd53489027dba64e3a4442fb399eeb627d4992ce68a622bd741
User & Date: jan.nijtmans 2024-05-21 09:06:08
Context
2024-05-29
18:48
merge trunk check-in: aa78dc34 user: fvogel tags: revised_text, tip-466
2024-05-21
09:06
Merge 9.0 check-in: 52ea1fd5 user: jan.nijtmans tags: revised_text, tip-466
2024-05-20
20:14
b2 -> b3, as preparation for next release check-in: 2c8c1f0d user: jan.nijtmans tags: trunk, main
2024-05-16
14:07
Merge 9.0 check-in: b05736e1 user: jan.nijtmans tags: revised_text, tip-466
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to README.md.

1
2
3
4
5
6
7
8
9
10
# README:  Tk

This is the **Tk 9.0b2** source distribution.

You can get any source release of Tk from [our distribution
site](https://sourceforge.net/projects/tcl/files/Tcl/).

8.6 (production release, daily build)
[![Build Status](https://github.com/tcltk/tk/workflows/Linux/badge.svg?branch=core-8-6-branch)](https://github.com/tcltk/tk/actions?query=workflow%3A%22Linux%22+branch%3Acore-8-6-branch)
[![Build Status](https://github.com/tcltk/tk/workflows/Windows/badge.svg?branch=core-8-6-branch)](https://github.com/tcltk/tk/actions?query=workflow%3A%22Windows%22+branch%3Acore-8-6-branch)


|







1
2
3
4
5
6
7
8
9
10
# README:  Tk

This is the **Tk 9.0b3** source distribution.

You can get any source release of Tk from [our distribution
site](https://sourceforge.net/projects/tcl/files/Tcl/).

8.6 (production release, daily build)
[![Build Status](https://github.com/tcltk/tk/workflows/Linux/badge.svg?branch=core-8-6-branch)](https://github.com/tcltk/tk/actions?query=workflow%3A%22Linux%22+branch%3Acore-8-6-branch)
[![Build Status](https://github.com/tcltk/tk/workflows/Windows/badge.svg?branch=core-8-6-branch)](https://github.com/tcltk/tk/actions?query=workflow%3A%22Windows%22+branch%3Acore-8-6-branch)

Changes to changes.md.

1



































TODO



































|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36

The source code for Tk is managed by fossil.  Tk developers coordinate all
changes to the Tk source code at

> [Tk Source Code](https://core.tcl-lang.org/tk/)

Release Tk 9.0b3 arises from the check-in with tag core-9-0-b3.

Highlighted differences between Tk 9.0 and Tk 8.6 are summarized below,
with focus on changes important to programmers using the Tk library and
writing Tcl scripts containing Tk commands.

## Many improvements to use of platform features and conventions.
 - Built-in widgets and themes are scaling-aware.
 - Improved support of two-finger gestures, where available
 - The `tk windowingsystem` "aqua" needs macOS 10.10 or later

## New commands and options
 - `tk sysnotify`: access to the OS notifications system
 - `tk systray`: access to the OS tray facility
 - `tk print`: access to the OS printing facility

## Widget options
 - New `ttk::progressbar` option: **-text**
 - `$frame ... -backgroundimage $img -tile $bool`
 - `$menu id`, `$menu add|insert ... ?$id? ...`
 - `$image get ... -withalpha ...`
 - All indices now accept the forms **end**, **end-int**, **int+|-int**

## Improved widget appearance
 - `ttk::notebook` with nondefault tab positions

## Images
 - Partial SVG support
 - Read/write access to photo image metadata

Changes to doc/ttk_widget.n.

383
384
385
386
387
388
389


390
391
392
393
394
395
396
.IP \fBhover\fR
The mouse cursor is within the widget.
This is similar to the \fBactive\fP state;
it is used in some themes for widgets that
provide distinct visual feedback for
the active widget in addition to the active element
within the widget.


.PP
A \fIstate specification\fR or \fIstateSpec\fR is a list
of state names, optionally prefixed with an exclamation point (!)
indicating that the bit is off.
.SH EXAMPLES
.CS
set b [ttk::button .b]







>
>







383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
.IP \fBhover\fR
The mouse cursor is within the widget.
This is similar to the \fBactive\fP state;
it is used in some themes for widgets that
provide distinct visual feedback for
the active widget in addition to the active element
within the widget.
.IP \fBuser1\fR-\fBuser6\fR
Freely usable for other purposes
.PP
A \fIstate specification\fR or \fIstateSpec\fR is a list
of state names, optionally prefixed with an exclamation point (!)
indicating that the bit is off.
.SH EXAMPLES
.CS
set b [ttk::button .b]

Changes to generic/tk.h.

67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84

#ifndef TK_MAJOR_VERSION
#   define TK_MAJOR_VERSION 9
#endif
#if TK_MAJOR_VERSION == 9
#   define TK_MINOR_VERSION	0
#   define TK_RELEASE_LEVEL	TCL_BETA_RELEASE
#   define TK_RELEASE_SERIAL	2

#   define TK_VERSION		"9.0"
#   define TK_PATCH_LEVEL		"9.0b2"
#endif /* TK_MAJOR_VERSION */

/*
 * A special definition used to allow this header file to be included from
 * windows or mac resource files so that they can obtain version information.
 * RC_INVOKED is defined by default by the windows RC tool and manually set
 * for macintosh.







|


|







67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84

#ifndef TK_MAJOR_VERSION
#   define TK_MAJOR_VERSION 9
#endif
#if TK_MAJOR_VERSION == 9
#   define TK_MINOR_VERSION	0
#   define TK_RELEASE_LEVEL	TCL_BETA_RELEASE
#   define TK_RELEASE_SERIAL	3

#   define TK_VERSION		"9.0"
#   define TK_PATCH_LEVEL		"9.0b3"
#endif /* TK_MAJOR_VERSION */

/*
 * A special definition used to allow this header file to be included from
 * windows or mac resource files so that they can obtain version information.
 * RC_INVOKED is defined by default by the windows RC tool and manually set
 * for macintosh.

Changes to generic/ttk/ttkClamTheme.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/*
 * Copyright © 2004 Joe English
 *
 * "clam" theme; inspired by the XFCE family of Gnome themes.
 */

#include "tkInt.h"
#include "ttkTheme.h"

/*
 * Under windows, the Tk-provided XDrawLine and XDrawArc have an
 * off-by-one error in the end point. This is especially apparent with this
 * theme. Defining this macro as true handles this case.
 */
#if defined(_WIN32) && !defined(WIN32_XDRAWLINE_HACK)







|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/*
 * Copyright © 2004 Joe English
 *
 * "clam" theme; inspired by the XFCE family of Gnome themes.
 */

#include "tkInt.h"
#include "ttkThemeInt.h"

/*
 * Under windows, the Tk-provided XDrawLine and XDrawArc have an
 * off-by-one error in the end point. This is especially apparent with this
 * theme. Defining this macro as true handles this case.
 */
#if defined(_WIN32) && !defined(WIN32_XDRAWLINE_HACK)
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
    if (state & TTK_STATE_SELECTED) {
	delta = borderWidth;
    }

    switch (nbTabsStickBit) {
	default:
	case TTK_STICK_S:
	    if (state & TTK_STATE_USER2) {		/* rightmost tab */
		--b.width;
	    }

	    Tk_Fill3DRectangle(tkwin, d, border,
		b.x+2, b.y+2, b.width-1, b.height-2+delta,
		borderWidth, TK_RELIEF_FLAT);








|







1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
    if (state & TTK_STATE_SELECTED) {
	delta = borderWidth;
    }

    switch (nbTabsStickBit) {
	default:
	case TTK_STICK_S:
	    if (state & TTK_STATE_LAST) {		/* rightmost tab */
		--b.width;
	    }

	    Tk_Fill3DRectangle(tkwin, d, border,
		b.x+2, b.y+2, b.width-1, b.height-2+delta,
		borderWidth, TK_RELIEF_FLAT);

1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064

	    gc = Ttk_GCForColor(tkwin, tab->lightColorObj, d);
	    XDrawLine(display, d, gc, x1+1, y1+1, x1+1, y2+delta+w);
	    XDrawLine(display, d, gc, x1+1, y1+1, x2-1+w, y1+1);
	    break;

	case TTK_STICK_N:
	    if (state & TTK_STATE_USER2) {		/* rightmost tab */
		--b.width;
	    }

	    Tk_Fill3DRectangle(tkwin, d, border,
		b.x+2, b.y-delta, b.width-1, b.height-2+delta,
		borderWidth, TK_RELIEF_FLAT);








|







1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064

	    gc = Ttk_GCForColor(tkwin, tab->lightColorObj, d);
	    XDrawLine(display, d, gc, x1+1, y1+1, x1+1, y2+delta+w);
	    XDrawLine(display, d, gc, x1+1, y1+1, x2-1+w, y1+1);
	    break;

	case TTK_STICK_N:
	    if (state & TTK_STATE_LAST) {		/* rightmost tab */
		--b.width;
	    }

	    Tk_Fill3DRectangle(tkwin, d, border,
		b.x+2, b.y-delta, b.width-1, b.height-2+delta,
		borderWidth, TK_RELIEF_FLAT);

1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086

	    gc = Ttk_GCForColor(tkwin, tab->lightColorObj, d);
	    XDrawLine(display, d, gc, x1+1, y1-1, x1+1, y2-delta-w);
	    XDrawLine(display, d, gc, x1+1, y1-1, x2-1+w, y1-1);
	    break;

	case TTK_STICK_E:
	    if (state & TTK_STATE_USER2) {		/* bottommost tab */
		--b.height;
	    }

	    Tk_Fill3DRectangle(tkwin, d, border,
		b.x+2, b.y+2, b.width-2+delta, b.height-1,
		borderWidth, TK_RELIEF_FLAT);








|







1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086

	    gc = Ttk_GCForColor(tkwin, tab->lightColorObj, d);
	    XDrawLine(display, d, gc, x1+1, y1-1, x1+1, y2-delta-w);
	    XDrawLine(display, d, gc, x1+1, y1-1, x2-1+w, y1-1);
	    break;

	case TTK_STICK_E:
	    if (state & TTK_STATE_LAST) {		/* bottommost tab */
		--b.height;
	    }

	    Tk_Fill3DRectangle(tkwin, d, border,
		b.x+2, b.y+2, b.width-2+delta, b.height-1,
		borderWidth, TK_RELIEF_FLAT);

1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108

	    gc = Ttk_GCForColor(tkwin, tab->lightColorObj, d);
	    XDrawLine(display, d, gc, x1+1, y1+1, x1+1, y2-1+w);
	    XDrawLine(display, d, gc, x1+1, y1+1, x2+delta+w, y1+1);
	    break;

	case TTK_STICK_W:
	    if (state & TTK_STATE_USER2) {		/* bottommost tab */
		--b.height;
	    }

	    Tk_Fill3DRectangle(tkwin, d, border,
		b.x-delta, b.y+2, b.width-2+delta, b.height-1,
		borderWidth, TK_RELIEF_FLAT);








|







1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108

	    gc = Ttk_GCForColor(tkwin, tab->lightColorObj, d);
	    XDrawLine(display, d, gc, x1+1, y1+1, x1+1, y2-1+w);
	    XDrawLine(display, d, gc, x1+1, y1+1, x2+delta+w, y1+1);
	    break;

	case TTK_STICK_W:
	    if (state & TTK_STATE_LAST) {		/* bottommost tab */
		--b.height;
	    }

	    Tk_Fill3DRectangle(tkwin, d, border,
		b.x-delta, b.y+2, b.width-2+delta, b.height-1,
		borderWidth, TK_RELIEF_FLAT);

Changes to generic/ttk/ttkDefaultTheme.c.

1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
    SliderElementDraw
};

/*------------------------------------------------------------------------
 * +++ Tree indicator element.
 */

#define TTK_STATE_OPEN TTK_STATE_USER1		/* XREF: treeview.c */
#define TTK_STATE_LEAF TTK_STATE_USER2

typedef struct {
    Tcl_Obj *colorObj;
    Tcl_Obj *marginObj;
    Tcl_Obj *sizeObj;
} TreeitemIndicator;

static const Ttk_ElementOptionSpec TreeitemIndicatorOptions[] = {







<
<
<







1204
1205
1206
1207
1208
1209
1210



1211
1212
1213
1214
1215
1216
1217
    SliderElementDraw
};

/*------------------------------------------------------------------------
 * +++ Tree indicator element.
 */




typedef struct {
    Tcl_Obj *colorObj;
    Tcl_Obj *marginObj;
    Tcl_Obj *sizeObj;
} TreeitemIndicator;

static const Ttk_ElementOptionSpec TreeitemIndicatorOptions[] = {

Changes to generic/ttk/ttkNotebook.c.

313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
    }
    for (i = 0; i < Ttk_NumberContent(nb->notebook.mgr); ++i) {
	Tab *tab = (Tab *)Ttk_ContentData(nb->notebook.mgr, i);
	if (tab->state == TAB_STATE_HIDDEN) {
	    continue;
	}
	if (index == i) {
	    state |= TTK_STATE_USER1;
	}
	break;
    }
    for (i = Ttk_NumberContent(nb->notebook.mgr) - 1; i >= 0; --i) {
	Tab *tab = (Tab *)Ttk_ContentData(nb->notebook.mgr, i);
	if (tab->state == TAB_STATE_HIDDEN) {
	    continue;
	}
	if (index == i) {
	    state |= TTK_STATE_USER2;
	}
	break;
    }
    if (itab->state == TAB_STATE_DISABLED) {
	state |= TTK_STATE_DISABLED;
    }








|









|







313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
    }
    for (i = 0; i < Ttk_NumberContent(nb->notebook.mgr); ++i) {
	Tab *tab = (Tab *)Ttk_ContentData(nb->notebook.mgr, i);
	if (tab->state == TAB_STATE_HIDDEN) {
	    continue;
	}
	if (index == i) {
	    state |= TTK_STATE_FIRST;
	}
	break;
    }
    for (i = Ttk_NumberContent(nb->notebook.mgr) - 1; i >= 0; --i) {
	Tab *tab = (Tab *)Ttk_ContentData(nb->notebook.mgr, i);
	if (tab->state == TAB_STATE_HIDDEN) {
	    continue;
	}
	if (index == i) {
	    state |= TTK_STATE_LAST;
	}
	break;
    }
    if (itab->state == TAB_STATE_DISABLED) {
	state |= TTK_STATE_DISABLED;
    }

Changes to generic/ttk/ttkState.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16



17


18
19


20

21
22
23
24
25
26
27
28
29
30
31
32
33

34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57

58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
/*
 * Tk widget state utilities.
 *
 * Copyright © 2003 Joe English.  Freely redistributable.
 *
 */

#include "tkInt.h"
#include "ttkTheme.h"

/*
 * Table of state names.  Must be kept in sync with TTK_STATE_*
 * #defines in ttkTheme.h.
 */
static const char *const stateNames[] =
{



    "active",		/* Mouse cursor is over widget or element */


    "disabled",		/* Widget is disabled */
    "focus",		/* Widget has keyboard focus */


    "pressed",		/* Pressed or "armed" */

    "selected",		/* "on", "true", "current", etc. */
    "background",	/* Top-level window lost focus (Mac,Win "inactive") */
    "alternate",	/* Widget-specific alternate display style */
    "invalid",		/* Bad value */
    "readonly",		/* Editing/modification disabled */
    "hover",		/* Mouse cursor is over widget */
    "reserved1",	/* Reserved for future extension */
    "reserved2",	/* Reserved for future extension */
    "reserved3",	/* Reserved for future extension */
    "user3",		/* User-definable state */
    "user2",		/* User-definable state */
    "user1",		/* User-definable state */
    NULL

};

/*------------------------------------------------------------------------
 * +++ StateSpec object type:
 *
 * The string representation consists of a list of state names,
 * each optionally prefixed by an exclamation point (!).
 *
 * The internal representation uses the upper half of the longValue
 * to store the on bits and the lower half to store the off bits.
 * If we ever get more than 16 states, this will need to be reconsidered...
 */

static int  StateSpecSetFromAny(Tcl_Interp *interp, Tcl_Obj *obj);
/* static void StateSpecFreeIntRep(Tcl_Obj *); */
#define StateSpecFreeIntRep 0		/* not needed */
static void StateSpecDupIntRep(Tcl_Obj *, Tcl_Obj *);
static void StateSpecUpdateString(Tcl_Obj *);

static const
TkObjType StateSpecObjType =
{
    {"StateSpec",
    StateSpecFreeIntRep,

    StateSpecDupIntRep,
    StateSpecUpdateString,
    StateSpecSetFromAny,
    TCL_OBJTYPE_V0},
    0
};

static void StateSpecDupIntRep(Tcl_Obj *srcPtr, Tcl_Obj *copyPtr)
{
    copyPtr->internalRep.longValue = srcPtr->internalRep.longValue;
    copyPtr->typePtr = &StateSpecObjType.objType;
}

static int StateSpecSetFromAny(Tcl_Interp *interp, Tcl_Obj *objPtr)
{
    int status;
    Tcl_Size i, objc;











|
<

|
<
>
>
>
|
>
>
|
|
>
>
|
>
|
<
<
|
|
|
<
<
<
|
|
|
<
>








|

|



<
<







<
>









|







1
2
3
4
5
6
7
8
9
10
11
12

13
14

15
16
17
18
19
20
21
22
23
24
25
26
27


28
29
30



31
32
33

34
35
36
37
38
39
40
41
42
43
44
45
46
47
48


49
50
51
52
53
54
55

56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
/*
 * Tk widget state utilities.
 *
 * Copyright © 2003 Joe English.  Freely redistributable.
 *
 */

#include "tkInt.h"
#include "ttkTheme.h"

/*
 * Table of state names.

 */
static const struct {

    char name[12];
    int value;
} stateNames[] = {
    {"active", TTK_STATE_ACTIVE},		/* Mouse cursor is over widget or element */
    {"alternate", TTK_STATE_ALTERNATE},	/* Widget-specific alternate display style */
    {"background", TTK_STATE_BACKGROUND},	/* Top-level window lost focus (Mac,Win "inactive") */
    {"disabled", TTK_STATE_DISABLED},		/* Widget is disabled */
    {"focus", TTK_STATE_FOCUS},		/* Widget has keyboard focus */
    {"hover", TTK_STATE_HOVER},		/* Mouse cursor is over widget */
    {"invalid", TTK_STATE_INVALID},		/* Bad value */
    {"pressed", TTK_STATE_PRESSED},		/* Pressed or "armed" */
    {"readonly", TTK_STATE_READONLY},		/* Editing/modification disabled */
    {"selected", TTK_STATE_SELECTED},		/* "on", "true", "current", etc. */


    {"user1", TTK_STATE_USER1},		/* User-definable state */
    {"user2", TTK_STATE_USER2},		/* User-definable state */
    {"user3", TTK_STATE_USER3},		/* User-definable state */



    {"user4", TTK_STATE_USER4},		/* User-definable state */
    {"user5", TTK_STATE_USER5},		/* User-definable state */
    {"user6", TTK_STATE_USER6},		/* User-definable state */

    {"", 0}
};

/*------------------------------------------------------------------------
 * +++ StateSpec object type:
 *
 * The string representation consists of a list of state names,
 * each optionally prefixed by an exclamation point (!).
 *
 * The internal representation uses the upper half of the wideValue
 * to store the on bits and the lower half to store the off bits.
 * If we ever get more than 32 states, this will need to be reconsidered...
 */

static int  StateSpecSetFromAny(Tcl_Interp *interp, Tcl_Obj *obj);


static void StateSpecDupIntRep(Tcl_Obj *, Tcl_Obj *);
static void StateSpecUpdateString(Tcl_Obj *);

static const
TkObjType StateSpecObjType =
{
    {"StateSpec",

    0,
    StateSpecDupIntRep,
    StateSpecUpdateString,
    StateSpecSetFromAny,
    TCL_OBJTYPE_V0},
    0
};

static void StateSpecDupIntRep(Tcl_Obj *srcPtr, Tcl_Obj *copyPtr)
{
    copyPtr->internalRep.wideValue = srcPtr->internalRep.wideValue;
    copyPtr->typePtr = &StateSpecObjType.objType;
}

static int StateSpecSetFromAny(Tcl_Interp *interp, Tcl_Obj *objPtr)
{
    int status;
    Tcl_Size i, objc;
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140

141
142
143
144
145
146
147
148
	if (*stateName == '!') {
	    ++stateName;
	    on = 0;
	} else {
	    on = 1;
	}

	for (j = 0; stateNames[j] != 0; ++j) {
	    if (strcmp(stateName, stateNames[j]) == 0)
		break;
	}

    	if (stateNames[j] == 0) {
	    if (interp) {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"Invalid state name %s", stateName));
		Tcl_SetErrorCode(interp, "TTK", "VALUE", "STATE", NULL);
	    }
	    return TCL_ERROR;
	}

	if (on) {
	    onbits |= (1<<j);
	} else {
	    offbits |= (1<<j);
	}
    }

    /* Invalidate old intrep:
     */
    if (objPtr->typePtr && objPtr->typePtr->freeIntRepProc) {
	objPtr->typePtr->freeIntRepProc(objPtr);
    }

    objPtr->typePtr = &StateSpecObjType.objType;
    objPtr->internalRep.longValue = (onbits << 16) | offbits;

    return TCL_OK;
}

static void StateSpecUpdateString(Tcl_Obj *objPtr)
{
    unsigned int onbits = (objPtr->internalRep.longValue & 0xFFFF0000) >> 16;
    unsigned int offbits = objPtr->internalRep.longValue & 0x0000FFFF;
    unsigned int mask = onbits | offbits;
    Tcl_DString result;
    int i;
    int len;

    Tcl_DStringInit(&result);

    for (i=0; stateNames[i] != NULL; ++i) {
	if (mask & (1<<i)) {
	    if (offbits & (1<<i))
		Tcl_DStringAppend(&result, "!", 1);

	    Tcl_DStringAppend(&result, stateNames[i], TCL_INDEX_NONE);
	    Tcl_DStringAppend(&result, " ", 1);
	}
    }

    len = Tcl_DStringLength(&result);
    if (len) {
	/* 'len' includes extra trailing ' ' */







|
|



|









|

|










|






|
|







|
|
|

>
|







85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
	if (*stateName == '!') {
	    ++stateName;
	    on = 0;
	} else {
	    on = 1;
	}

	for (j = 0; stateNames[j].value; ++j) {
	    if (strcmp(stateName, stateNames[j].name) == 0)
		break;
	}

    	if (stateNames[j].value == 0) {
	    if (interp) {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"Invalid state name %s", stateName));
		Tcl_SetErrorCode(interp, "TTK", "VALUE", "STATE", NULL);
	    }
	    return TCL_ERROR;
	}

	if (on) {
	    onbits |= stateNames[j].value;
	} else {
	    offbits |= stateNames[j].value;
	}
    }

    /* Invalidate old intrep:
     */
    if (objPtr->typePtr && objPtr->typePtr->freeIntRepProc) {
	objPtr->typePtr->freeIntRepProc(objPtr);
    }

    objPtr->typePtr = &StateSpecObjType.objType;
    objPtr->internalRep.wideValue = ((Tcl_WideInt)onbits << 32) | offbits;

    return TCL_OK;
}

static void StateSpecUpdateString(Tcl_Obj *objPtr)
{
    unsigned int onbits = objPtr->internalRep.wideValue >> 32;
    unsigned int offbits = objPtr->internalRep.wideValue & 0xFFFFFFFFLL;
    unsigned int mask = onbits | offbits;
    Tcl_DString result;
    int i;
    int len;

    Tcl_DStringInit(&result);

    for (i=0; stateNames[i].value; ++i) {
	if (mask & stateNames[i].value) {
	    if (offbits & stateNames[i].value) {
		Tcl_DStringAppend(&result, "!", 1);
	    }
	    Tcl_DStringAppend(&result, stateNames[i].name, TCL_INDEX_NONE);
	    Tcl_DStringAppend(&result, " ", 1);
	}
    }

    len = Tcl_DStringLength(&result);
    if (len) {
	/* 'len' includes extra trailing ' ' */
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193

Tcl_Obj *Ttk_NewStateSpecObj(unsigned int onbits, unsigned int offbits)
{
    Tcl_Obj *objPtr = Tcl_NewObj();

    Tcl_InvalidateStringRep(objPtr);
    objPtr->typePtr = &StateSpecObjType.objType;
    objPtr->internalRep.longValue = (onbits << 16) | offbits;

    return objPtr;
}

int Ttk_GetStateSpecFromObj(
    Tcl_Interp *interp,
    Tcl_Obj *objPtr,
    Ttk_StateSpec *spec)
{
    if (objPtr->typePtr != &StateSpecObjType.objType) {
	int status = StateSpecSetFromAny(interp, objPtr);
	if (status != TCL_OK)
	    return status;
    }

    spec->onbits = (objPtr->internalRep.longValue & 0xFFFF0000) >> 16;
    spec->offbits = objPtr->internalRep.longValue & 0x0000FFFF;
    return TCL_OK;
}


/*
 * Tk_StateMapLookup --
 *







|















|
|







162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193

Tcl_Obj *Ttk_NewStateSpecObj(unsigned int onbits, unsigned int offbits)
{
    Tcl_Obj *objPtr = Tcl_NewObj();

    Tcl_InvalidateStringRep(objPtr);
    objPtr->typePtr = &StateSpecObjType.objType;
    objPtr->internalRep.wideValue = ((Tcl_WideInt)onbits << 32) | offbits;

    return objPtr;
}

int Ttk_GetStateSpecFromObj(
    Tcl_Interp *interp,
    Tcl_Obj *objPtr,
    Ttk_StateSpec *spec)
{
    if (objPtr->typePtr != &StateSpecObjType.objType) {
	int status = StateSpecSetFromAny(interp, objPtr);
	if (status != TCL_OK)
	    return status;
    }

    spec->onbits = objPtr->internalRep.wideValue >> 32;
    spec->offbits = objPtr->internalRep.wideValue & 0xFFFFFFFFLL;
    return TCL_OK;
}


/*
 * Tk_StateMapLookup --
 *

Changes to generic/ttk/ttkThemeInt.h.

1
2
3
4
5
6
7
8
9
10









11
12
13
14
15
16
17
/*
 * Theme engine: private definitions.
 *
 * Copyright © 2004 Joe English.  Freely redistributable.
 */

#ifndef _TTKTHEMEINT
#define _TTKTHEMEINT

#include "ttkTheme.h"










typedef struct Ttk_TemplateNode_ Ttk_TemplateNode, *Ttk_LayoutTemplate;

MODULE_SCOPE Ttk_ElementClass *Ttk_GetElement(Ttk_Theme, const char *name);
MODULE_SCOPE const char *Ttk_ElementClassName(Ttk_ElementClass *);

MODULE_SCOPE void Ttk_ElementSize(










>
>
>
>
>
>
>
>
>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
/*
 * Theme engine: private definitions.
 *
 * Copyright © 2004 Joe English.  Freely redistributable.
 */

#ifndef _TTKTHEMEINT
#define _TTKTHEMEINT

#include "ttkTheme.h"

/*------------------------------------------------------------------------
 * +++ Widget states (internal).
 */

#define TTK_STATE_OPEN		(1<<16)
#define TTK_STATE_LEAF		(1<<17)
#define TTK_STATE_FIRST		(1<<18)
#define TTK_STATE_LAST		(1<<19)

typedef struct Ttk_TemplateNode_ Ttk_TemplateNode, *Ttk_LayoutTemplate;

MODULE_SCOPE Ttk_ElementClass *Ttk_GetElement(Ttk_Theme, const char *name);
MODULE_SCOPE const char *Ttk_ElementClassName(Ttk_ElementClass *);

MODULE_SCOPE void Ttk_ElementSize(

Changes to generic/ttk/ttkTreeview.c.

19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#define DEF_COLWIDTH		"200"
#define DEF_MINWIDTH		"20"

static const Tk_Anchor DEFAULT_IMAGEANCHOR = TK_ANCHOR_W;
static const int DEFAULT_INDENT 	= 20;
static const int HALO   		= 4;	/* heading separator */

#define TTK_STATE_OPEN TTK_STATE_USER1
#define TTK_STATE_LEAF TTK_STATE_USER2

#define STATE_CHANGED	 	(0x100)	/* item state option changed */

#define MAX(a,b) (((a) > (b)) ? (a) : (b))

/*------------------------------------------------------------------------
 * +++ Tree items.
 *







<
<
<







19
20
21
22
23
24
25



26
27
28
29
30
31
32
#define DEF_COLWIDTH		"200"
#define DEF_MINWIDTH		"20"

static const Tk_Anchor DEFAULT_IMAGEANCHOR = TK_ANCHOR_W;
static const int DEFAULT_INDENT 	= 20;
static const int HALO   		= 4;	/* heading separator */




#define STATE_CHANGED	 	(0x100)	/* item state option changed */

#define MAX(a,b) (((a) > (b)) ? (a) : (b))

/*------------------------------------------------------------------------
 * +++ Tree items.
 *

Changes to library/tk.tcl.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# tk.tcl --
#
# Initialization script normally executed in the interpreter for each Tk-based
# application.  Arranges class bindings for widgets.
#
# Copyright © 1992-1994 The Regents of the University of California.
# Copyright © 1994-1996 Sun Microsystems, Inc.
# Copyright © 1998-2000 Ajuba Solutions.
#
# See the file "license.terms" for information on usage and redistribution of
# this file, and for a DISCLAIMER OF ALL WARRANTIES.

# Verify that we have Tk binary and script components from the same release
package require -exact tk  9.0b2

# Create a ::tk namespace
namespace eval ::tk {
    # Set up the msgcat commands
    namespace eval msgcat {
	namespace export mc mcmax
        if {[interp issafe] || [catch {package require msgcat}]} {













|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# tk.tcl --
#
# Initialization script normally executed in the interpreter for each Tk-based
# application.  Arranges class bindings for widgets.
#
# Copyright © 1992-1994 The Regents of the University of California.
# Copyright © 1994-1996 Sun Microsystems, Inc.
# Copyright © 1998-2000 Ajuba Solutions.
#
# See the file "license.terms" for information on usage and redistribution of
# this file, and for a DISCLAIMER OF ALL WARRANTIES.

# Verify that we have Tk binary and script components from the same release
package require -exact tk  9.0b3

# Create a ::tk namespace
namespace eval ::tk {
    # Set up the msgcat commands
    namespace eval msgcat {
	namespace export mc mcmax
        if {[interp issafe] || [catch {package require msgcat}]} {

Changes to macosx/ttkMacOSXTheme.c.

26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
 *      "prelight", or "hot-tracked".  Aqua doesn't use this kind of feedback.
 *
 *      The QuickDraw/Carbon coordinate system is relative to the top-level
 *      window, not to the Tk_Window.  BoxToRect() accounts for this.
 */

#include "tkMacOSXPrivate.h"
#include "ttk/ttkTheme.h"
#include "ttkMacOSXTheme.h"
#include "tkColor.h"
#include <math.h>

MODULE_SCOPE NSColor *controlAccentColor(void) {
    static int accentPixel = -1;
    if (accentPixel == -1) {







|







26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
 *      "prelight", or "hot-tracked".  Aqua doesn't use this kind of feedback.
 *
 *      The QuickDraw/Carbon coordinate system is relative to the top-level
 *      window, not to the Tk_Window.  BoxToRect() accounts for this.
 */

#include "tkMacOSXPrivate.h"
#include "ttk/ttkThemeInt.h"
#include "ttkMacOSXTheme.h"
#include "tkColor.h"
#include <math.h>

MODULE_SCOPE NSColor *controlAccentColor(void) {
    static int accentPixel = -1;
    if (accentPixel == -1) {
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
     * Extend the bounds to one or both sides so the rounded part will be
     * clipped off if the right of the left tab, the left of the right tab,
     * and both sides of the middle tabs.
     */

    CGContextClipToRect(context, bounds);
    if (OSVersion < 110000 || !(state & TTK_STATE_SELECTED)) {
	if (!(state & TTK_STATE_FIRST_TAB)) {
	    bounds.origin.x -= 10;
	    bounds.size.width += 10;
	}
	if (!(state & TTK_STATE_LAST_TAB)) {
	    bounds.size.width += 10;
	}
    }
    /*
     * Fill the tab face with the appropriate color or gradient.  Use a solid
     * color if the tab is not selected, otherwise use the accent color with
     * highlights
     */

    if (!(state & TTK_STATE_SELECTED)) {
	DrawGrayButton(context, bounds, &tabDesign, state, tkwin);

        /*
         * Draw a separator line on the left side of the tab if it
         * not first.
         */

	if (!(state & TTK_STATE_FIRST_TAB)) {
	    CGContextSaveGState(context);
	    strokeColor = CGColorFromGray(darkTabSeparator);
	    CGContextSetStrokeColorWithColor(context, strokeColor);
	    CGContextBeginPath(context);
	    CGContextMoveToPoint(context, originalBounds.origin.x,
		originalBounds.origin.y + 1);
	    CGContextAddLineToPoint(context, originalBounds.origin.x,
		originalBounds.origin.y + originalBounds.size.height - 1);
	    CGContextStrokePath(context);
	    CGContextRestoreGState(context);
	}
    } else {

	/*
	 * This is the selected tab; paint it with the current accent color.
	 * If it is first, cover up the separator line drawn by the second one.
	 * (The selected tab is always drawn last.)
	 */

	if ((state & TTK_STATE_FIRST_TAB) && !(state & TTK_STATE_LAST_TAB)) {
	    bounds.size.width += 1;
	}
	if (!(state & TTK_STATE_BACKGROUND)) {
	    DrawAccentedButton(context, bounds, &tabDesign, 0, 0);
	} else {
	    DrawGrayButton(context, bounds, &tabDesign, state, tkwin);
	}







|



|

















|



















|







1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
     * Extend the bounds to one or both sides so the rounded part will be
     * clipped off if the right of the left tab, the left of the right tab,
     * and both sides of the middle tabs.
     */

    CGContextClipToRect(context, bounds);
    if (OSVersion < 110000 || !(state & TTK_STATE_SELECTED)) {
	if (!(state & TTK_STATE_FIRST)) {
	    bounds.origin.x -= 10;
	    bounds.size.width += 10;
	}
	if (!(state & TTK_STATE_LAST)) {
	    bounds.size.width += 10;
	}
    }
    /*
     * Fill the tab face with the appropriate color or gradient.  Use a solid
     * color if the tab is not selected, otherwise use the accent color with
     * highlights
     */

    if (!(state & TTK_STATE_SELECTED)) {
	DrawGrayButton(context, bounds, &tabDesign, state, tkwin);

        /*
         * Draw a separator line on the left side of the tab if it
         * not first.
         */

	if (!(state & TTK_STATE_FIRST)) {
	    CGContextSaveGState(context);
	    strokeColor = CGColorFromGray(darkTabSeparator);
	    CGContextSetStrokeColorWithColor(context, strokeColor);
	    CGContextBeginPath(context);
	    CGContextMoveToPoint(context, originalBounds.origin.x,
		originalBounds.origin.y + 1);
	    CGContextAddLineToPoint(context, originalBounds.origin.x,
		originalBounds.origin.y + originalBounds.size.height - 1);
	    CGContextStrokePath(context);
	    CGContextRestoreGState(context);
	}
    } else {

	/*
	 * This is the selected tab; paint it with the current accent color.
	 * If it is first, cover up the separator line drawn by the second one.
	 * (The selected tab is always drawn last.)
	 */

	if ((state & TTK_STATE_FIRST) && !(state & TTK_STATE_LAST)) {
	    bounds.size.width += 1;
	}
	if (!(state & TTK_STATE_BACKGROUND)) {
	    DrawAccentedButton(context, bounds, &tabDesign, 0, 0);
	} else {
	    DrawGrayButton(context, bounds, &tabDesign, state, tkwin);
	}
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
	CGRect clipRect = bounds;
	/*
	 * Draw a segment of a Group Box as a background for non-selected tabs.
	 * Clip the Group Box so that the segments fit together to form a long
	 * rounded rectangle behind the entire tab bar.
	 */

	if (!(state & TTK_STATE_FIRST_TAB)) {
	    clipRect.origin.x -= 5;
	    bounds.origin.x -= 5;
	    bounds.size.width += 5;
	}
	if (!(state & TTK_STATE_LAST_TAB)) {
	    clipRect.size.width += 5;
	    bounds.size.width += 5;
	}
	CGContextSaveGState(context);
	CGContextClipToRect(context, clipRect);
	DrawGroupBox(bounds, context, tkwin, 3, NO);
	CGContextRestoreGState(context);







|




|







1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
	CGRect clipRect = bounds;
	/*
	 * Draw a segment of a Group Box as a background for non-selected tabs.
	 * Clip the Group Box so that the segments fit together to form a long
	 * rounded rectangle behind the entire tab bar.
	 */

	if (!(state & TTK_STATE_FIRST)) {
	    clipRect.origin.x -= 5;
	    bounds.origin.x -= 5;
	    bounds.size.width += 5;
	}
	if (!(state & TTK_STATE_LAST)) {
	    clipRect.size.width += 5;
	    bounds.size.width += 5;
	}
	CGContextSaveGState(context);
	CGContextClipToRect(context, clipRect);
	DrawGroupBox(bounds, context, tkwin, 3, NO);
	CGContextRestoreGState(context);
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
    {kThemeTabFrontUnavailable, TTK_STATE_DISABLED | TTK_STATE_SELECTED, 0},
    {kThemeTabNonFrontUnavailable, TTK_STATE_DISABLED, 0},
    {kThemeTabFront, TTK_STATE_SELECTED, 0},
    {kThemeTabNonFrontPressed, TTK_STATE_PRESSED, 0},
    {kThemeTabNonFront, 0, 0}
};
static const Ttk_StateTable TabAdornmentTable[] = {
    {kHIThemeTabAdornmentNone, TTK_STATE_FIRST_TAB | TTK_STATE_LAST_TAB, 0},
    {kHIThemeTabAdornmentTrailingSeparator, TTK_STATE_FIRST_TAB, 0},
    {kHIThemeTabAdornmentNone, TTK_STATE_LAST_TAB, 0},
    {kHIThemeTabAdornmentTrailingSeparator, 0, 0},
};
static const Ttk_StateTable TabPositionTable[] = {
    {kHIThemeTabPositionOnly, TTK_STATE_FIRST_TAB | TTK_STATE_LAST_TAB, 0},
    {kHIThemeTabPositionFirst, TTK_STATE_FIRST_TAB, 0},
    {kHIThemeTabPositionLast, TTK_STATE_LAST_TAB, 0},
    {kHIThemeTabPositionMiddle, 0, 0},
};

/*
 * Apple XHIG Tab View Specifications:
 *
 * Control sizes: Tab views are available in regular, small, and mini sizes.







|
|
|



|
|
|







1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
    {kThemeTabFrontUnavailable, TTK_STATE_DISABLED | TTK_STATE_SELECTED, 0},
    {kThemeTabNonFrontUnavailable, TTK_STATE_DISABLED, 0},
    {kThemeTabFront, TTK_STATE_SELECTED, 0},
    {kThemeTabNonFrontPressed, TTK_STATE_PRESSED, 0},
    {kThemeTabNonFront, 0, 0}
};
static const Ttk_StateTable TabAdornmentTable[] = {
    {kHIThemeTabAdornmentNone, TTK_STATE_FIRST | TTK_STATE_LAST, 0},
    {kHIThemeTabAdornmentTrailingSeparator, TTK_STATE_FIRST, 0},
    {kHIThemeTabAdornmentNone, TTK_STATE_LAST, 0},
    {kHIThemeTabAdornmentTrailingSeparator, 0, 0},
};
static const Ttk_StateTable TabPositionTable[] = {
    {kHIThemeTabPositionOnly, TTK_STATE_FIRST | TTK_STATE_LAST, 0},
    {kHIThemeTabPositionFirst, TTK_STATE_FIRST, 0},
    {kHIThemeTabPositionLast, TTK_STATE_LAST, 0},
    {kHIThemeTabPositionMiddle, 0, 0},
};

/*
 * Apple XHIG Tab View Specifications:
 *
 * Control sizes: Tab views are available in regular, small, and mini sizes.
3317
3318
3319
3320
3321
3322
3323
3324
3325
3326
3327
3328
3329
3330
3331
3332
3333
3334
    TreeHeaderElementDraw
};

/*----------------------------------------------------------------------
 * +++ Disclosure triangles --
 */

#define TTK_TREEVIEW_STATE_OPEN         TTK_STATE_USER1
#define TTK_TREEVIEW_STATE_LEAF         TTK_STATE_USER2
static const Ttk_StateTable DisclosureValueTable[] = {
    {kThemeDisclosureDown, TTK_TREEVIEW_STATE_OPEN, 0},
    {kThemeDisclosureRight, 0, 0},
};
static void DisclosureElementSize(
    TCL_UNUSED(void *),    /* clientData */
    TCL_UNUSED(void *),    /* elementRecord */
    TCL_UNUSED(Tk_Window), /* tkwin */
    int *minWidth,







<
<

|







3317
3318
3319
3320
3321
3322
3323


3324
3325
3326
3327
3328
3329
3330
3331
3332
    TreeHeaderElementDraw
};

/*----------------------------------------------------------------------
 * +++ Disclosure triangles --
 */



static const Ttk_StateTable DisclosureValueTable[] = {
    {kThemeDisclosureDown, TTK_STATE_OPEN, 0},
    {kThemeDisclosureRight, 0, 0},
};
static void DisclosureElementSize(
    TCL_UNUSED(void *),    /* clientData */
    TCL_UNUSED(void *),    /* elementRecord */
    TCL_UNUSED(Tk_Window), /* tkwin */
    int *minWidth,
3347
3348
3349
3350
3351
3352
3353
3354
3355
3356
3357
3358
3359
3360
3361
3362
3363
3364
3365
3366
3367
3368
3369
3370
3371
3372
3373
3374
3375
3376
3377
3378
3379
3380
    TCL_UNUSED(void *),    /* clientData */
    TCL_UNUSED(void *),    /* elementRecord */
    Tk_Window tkwin,
    Drawable d,
    Ttk_Box b,
    Ttk_State state)
{
    if (!(state & TTK_TREEVIEW_STATE_LEAF)) {
	int triangleState = TkMacOSXInDarkMode(tkwin) ?
	    kThemeStateInactive : kThemeStateActive;
	CGRect bounds = BoxToRect(d, b);
	const HIThemeButtonDrawInfo info = {
	    .version = 0,
	    .state = triangleState,
	    .kind = kThemeDisclosureTriangle,
	    .value = Ttk_StateTableLookup(DisclosureValueTable, state),
	    .adornment = kThemeAdornmentDrawIndicatorOnly,
	};

	BEGIN_DRAWING(d)
	if ([NSApp macOSVersion] >= 110000) {
	    CGFloat rgba[4];
	    NSColorSpace *deviceRGB = [NSColorSpace deviceRGBColorSpace];
	    NSColor *stroke = [[NSColor textColor]
		colorUsingColorSpace: deviceRGB];
	    [stroke getComponents: rgba];
	    if (state & TTK_TREEVIEW_STATE_OPEN) {
		DrawOpenDisclosure(dc.context, bounds, 2, 8, rgba);
	    } else {
		DrawClosedDisclosure(dc.context, bounds, 2, 12, rgba);
	    }
	} else {
	    ChkErr(HIThemeDrawButton, &bounds, &info, dc.context, HIOrientation,
	    NULL);







|


















|







3345
3346
3347
3348
3349
3350
3351
3352
3353
3354
3355
3356
3357
3358
3359
3360
3361
3362
3363
3364
3365
3366
3367
3368
3369
3370
3371
3372
3373
3374
3375
3376
3377
3378
    TCL_UNUSED(void *),    /* clientData */
    TCL_UNUSED(void *),    /* elementRecord */
    Tk_Window tkwin,
    Drawable d,
    Ttk_Box b,
    Ttk_State state)
{
    if (!(state & TTK_STATE_LEAF)) {
	int triangleState = TkMacOSXInDarkMode(tkwin) ?
	    kThemeStateInactive : kThemeStateActive;
	CGRect bounds = BoxToRect(d, b);
	const HIThemeButtonDrawInfo info = {
	    .version = 0,
	    .state = triangleState,
	    .kind = kThemeDisclosureTriangle,
	    .value = Ttk_StateTableLookup(DisclosureValueTable, state),
	    .adornment = kThemeAdornmentDrawIndicatorOnly,
	};

	BEGIN_DRAWING(d)
	if ([NSApp macOSVersion] >= 110000) {
	    CGFloat rgba[4];
	    NSColorSpace *deviceRGB = [NSColorSpace deviceRGBColorSpace];
	    NSColor *stroke = [[NSColor textColor]
		colorUsingColorSpace: deviceRGB];
	    [stroke getComponents: rgba];
	    if (state & TTK_STATE_OPEN) {
		DrawOpenDisclosure(dc.context, bounds, 2, 8, rgba);
	    } else {
		DrawClosedDisclosure(dc.context, bounds, 2, 12, rgba);
	    }
	} else {
	    ChkErr(HIThemeDrawButton, &bounds, &info, dc.context, HIOrientation,
	    NULL);

Changes to macosx/ttkMacOSXTheme.h.

34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49

#define RangeToFactor(max) ((double) (1073741824.0) / (max < 1.0 ? 1.0 : max))

/*
 * Meanings of Ttk states represented by User1 and User2.
 */

#define TTK_STATE_FIRST_TAB     TTK_STATE_USER1
#define TTK_STATE_LAST_TAB      TTK_STATE_USER2
#define TTK_STATE_IS_ACCENTED   TTK_STATE_USER2
#define TTK_TREEVIEW_STATE_SORTARROW    TTK_STATE_USER1

/*
 * Colors and gradients used when drawing buttons.
 */








<
<







34
35
36
37
38
39
40


41
42
43
44
45
46
47

#define RangeToFactor(max) ((double) (1073741824.0) / (max < 1.0 ? 1.0 : max))

/*
 * Meanings of Ttk states represented by User1 and User2.
 */



#define TTK_STATE_IS_ACCENTED   TTK_STATE_USER2
#define TTK_TREEVIEW_STATE_SORTARROW    TTK_STATE_USER1

/*
 * Colors and gradients used when drawing buttons.
 */

Changes to unix/configure.

2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613




TK_VERSION=9.0
TK_MAJOR_VERSION=9
TK_MINOR_VERSION=0
TK_PATCH_LEVEL="b2"
VERSION=${TK_VERSION}
LOCALES="cs da de el en en_gb eo es fr hu it nl pl pt ru sv"

#--------------------------------------------------------------------
# Find and load the tclConfig.sh file
#--------------------------------------------------------------------








|







2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613




TK_VERSION=9.0
TK_MAJOR_VERSION=9
TK_MINOR_VERSION=0
TK_PATCH_LEVEL="b3"
VERSION=${TK_VERSION}
LOCALES="cs da de el en en_gb eo es fr hu it nl pl pt ru sv"

#--------------------------------------------------------------------
# Find and load the tclConfig.sh file
#--------------------------------------------------------------------

Changes to unix/configure.ac.

22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
    /* override */ #undef PACKAGE_STRING
    #endif /* _TKCONFIG */])
])

TK_VERSION=9.0
TK_MAJOR_VERSION=9
TK_MINOR_VERSION=0
TK_PATCH_LEVEL="b2"
VERSION=${TK_VERSION}
LOCALES="cs da de el en en_gb eo es fr hu it nl pl pt ru sv"

#--------------------------------------------------------------------
# Find and load the tclConfig.sh file
#--------------------------------------------------------------------








|







22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
    /* override */ #undef PACKAGE_STRING
    #endif /* _TKCONFIG */])
])

TK_VERSION=9.0
TK_MAJOR_VERSION=9
TK_MINOR_VERSION=0
TK_PATCH_LEVEL="b3"
VERSION=${TK_VERSION}
LOCALES="cs da de el en en_gb eo es fr hu it nl pl pt ru sv"

#--------------------------------------------------------------------
# Find and load the tclConfig.sh file
#--------------------------------------------------------------------

Changes to unix/tk.spec.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# This file is the basis for a binary Tk Linux RPM.

%{!?directory:%define directory /usr/local}

Name:          tk
Summary:       Tk graphical toolkit for the Tcl scripting language.
Version:       9.0b2
Release:       2
License:       BSD
Group:         Development/Languages
Source:        http://prdownloads.sourceforge.net/tcl/tk%{version}-src.tar.gz
URL:           https://www.tcl-lang.org/
Buildroot:     /var/tmp/%{name}%{version}
Buildrequires: XFree86-devel tcl >= 8.7.0






|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
# This file is the basis for a binary Tk Linux RPM.

%{!?directory:%define directory /usr/local}

Name:          tk
Summary:       Tk graphical toolkit for the Tcl scripting language.
Version:       9.0b3
Release:       2
License:       BSD
Group:         Development/Languages
Source:        http://prdownloads.sourceforge.net/tcl/tk%{version}-src.tar.gz
URL:           https://www.tcl-lang.org/
Buildroot:     /var/tmp/%{name}%{version}
Buildrequires: XFree86-devel tcl >= 8.7.0

Changes to win/configure.

2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
# versions of autoconf incorrectly set SHELL to /bin/bash instead of
# /bin/sh. The bash shell seems to suffer from some strange failures.
SHELL=/bin/sh

TK_VERSION=9.0
TK_MAJOR_VERSION=9
TK_MINOR_VERSION=0
TK_PATCH_LEVEL="b2"
VER=$TK_MAJOR_VERSION$TK_MINOR_VERSION

#------------------------------------------------------------------------
# Handle the --prefix=... option
#------------------------------------------------------------------------

if test "${prefix}" = "NONE"; then







|







2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
# versions of autoconf incorrectly set SHELL to /bin/bash instead of
# /bin/sh. The bash shell seems to suffer from some strange failures.
SHELL=/bin/sh

TK_VERSION=9.0
TK_MAJOR_VERSION=9
TK_MINOR_VERSION=0
TK_PATCH_LEVEL="b3"
VER=$TK_MAJOR_VERSION$TK_MINOR_VERSION

#------------------------------------------------------------------------
# Handle the --prefix=... option
#------------------------------------------------------------------------

if test "${prefix}" = "NONE"; then

Changes to win/configure.ac.

11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# versions of autoconf incorrectly set SHELL to /bin/bash instead of
# /bin/sh. The bash shell seems to suffer from some strange failures.
SHELL=/bin/sh

TK_VERSION=9.0
TK_MAJOR_VERSION=9
TK_MINOR_VERSION=0
TK_PATCH_LEVEL="b2"
VER=$TK_MAJOR_VERSION$TK_MINOR_VERSION

#------------------------------------------------------------------------
# Handle the --prefix=... option
#------------------------------------------------------------------------

if test "${prefix}" = "NONE"; then







|







11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# versions of autoconf incorrectly set SHELL to /bin/bash instead of
# /bin/sh. The bash shell seems to suffer from some strange failures.
SHELL=/bin/sh

TK_VERSION=9.0
TK_MAJOR_VERSION=9
TK_MINOR_VERSION=0
TK_PATCH_LEVEL="b3"
VER=$TK_MAJOR_VERSION$TK_MINOR_VERSION

#------------------------------------------------------------------------
# Handle the --prefix=... option
#------------------------------------------------------------------------

if test "${prefix}" = "NONE"; then

Changes to win/ttkWinXPTheme.c.

15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
 *  	shellcc/platform/commctls/userex/refentry.asp >
 */

#include "tkWinInt.h"
#include <windows.h>
#include <uxtheme.h>
#include <vssym32.h>
#include "ttk/ttkTheme.h"

typedef HTHEME  (STDAPICALLTYPE OpenThemeDataProc)(HWND hwnd,
		 LPCWSTR pszClassList);
typedef HRESULT (STDAPICALLTYPE CloseThemeDataProc)(HTHEME hTheme);
typedef HRESULT (STDAPICALLTYPE DrawThemeBackgroundProc)(HTHEME hTheme,
                 HDC hdc, int iPartId, int iStateId, const RECT *pRect,
                 OPTIONAL const RECT *pClipRect);







|







15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
 *  	shellcc/platform/commctls/userex/refentry.asp >
 */

#include "tkWinInt.h"
#include <windows.h>
#include <uxtheme.h>
#include <vssym32.h>
#include "ttk/ttkThemeInt.h"

typedef HTHEME  (STDAPICALLTYPE OpenThemeDataProc)(HWND hwnd,
		 LPCWSTR pszClassList);
typedef HRESULT (STDAPICALLTYPE CloseThemeDataProc)(HTHEME hTheme);
typedef HRESULT (STDAPICALLTYPE DrawThemeBackgroundProc)(HTHEME hTheme,
                 HDC hdc, int iPartId, int iStateId, const RECT *pRect,
                 OPTIONAL const RECT *pClipRect);
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878

/*----------------------------------------------------------------------
 * +++  Tree indicator element.
 *
 *	Generic element, but don't display at all if TTK_STATE_LEAF (=USER2) set
 */

#define TTK_STATE_OPEN TTK_STATE_USER1
#define TTK_STATE_LEAF TTK_STATE_USER2

static const Ttk_StateTable header_statemap[] =
{
    { HIS_PRESSED, 	TTK_STATE_PRESSED, 0 },
    { HIS_HOT,  	TTK_STATE_ACTIVE, 0 },
    { HIS_NORMAL, 	0,0 },
};








<
<
<







862
863
864
865
866
867
868



869
870
871
872
873
874
875

/*----------------------------------------------------------------------
 * +++  Tree indicator element.
 *
 *	Generic element, but don't display at all if TTK_STATE_LEAF (=USER2) set
 */




static const Ttk_StateTable header_statemap[] =
{
    { HIS_PRESSED, 	TTK_STATE_PRESSED, 0 },
    { HIS_HOT,  	TTK_STATE_ACTIVE, 0 },
    { HIS_NORMAL, 	0,0 },
};