Tk Source Code

Changes On Branch core-9-0-branch
Login

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

Changes In Branch core-9-0-branch Excluding Merge-Ins

This is equivalent to a diff from 60200f7a0d to effef6c657

2025-04-07
15:02
Merge 9.0 Leaf check-in: 57e558bf98 user: jan.nijtmans tags: trunk, main
15:01
Remove OPTS=tk8 option: It was meant to be able to compile extesions witk Tk 8.7, which will never fly .... Leaf check-in: effef6c657 user: jan.nijtmans tags: core-9-0-branch
2025-04-03
16:23
Sync tcl.m4 with Tcl check-in: 83f32527c1 user: jan.nijtmans tags: core-9-0-branch
2025-03-11
14:36
Split off Tk 9.0. release check-in: 288254a97d user: jan.nijtmans tags: core-9-0-branch
14:33
version -> 9.1a0, start of Tk 9.1 development check-in: c191a71ce8 user: jan.nijtmans tags: trunk, main
11:58
Ticket [441c526c] MSWin: remove XP Style dialogs and old compiler compatibility check-in: 683c4bb9b3 user: oehhar tags: 441c526c-mswin-xpstyle-dialogs-removal
2025-03-10
23:05
Adjust event-9,19. The last commit must have changed some timing. check-in: 60200f7a0d user: culler tags: trunk, main
22:26
Fix [6328ce0301] Aqua menubar crashes and unclear menubar selection algorithm. check-in: e8768dc5c9 user: culler tags: trunk, main

Changes to README.md.
1
2
3
4
5
6
7
8

9
10
11
12
13
14
15
16




17
18
19
20
21
22
23
1
2
3
4
5
6
7

8
9
10
11
12




13
14
15
16
17
18
19
20
21
22
23







-
+




-
-
-
-
+
+
+
+







# README:  Tk

This is the **Tk 9.0.2** source distribution.

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

9.0 (production release, daily build)
9.1 (in development, daily build)
[![Build Status](https://github.com/tcltk/tk/actions/workflows/linux-build.yml/badge.svg?branch=main)](https://github.com/tcltk/tk/actions/workflows/linux-build.yml?query=branch%3Amain)
[![Build Status](https://github.com/tcltk/tk/actions/workflows/win-build.yml/badge.svg?branch=main)](https://github.com/tcltk/tk/actions/workflows/win-build.yml?query=branch%3Amain)
[![Build Status](https://github.com/tcltk/tk/actions/workflows/mac-build.yml/badge.svg?branch=main)](https://github.com/tcltk/tk/actions/workflows/mac-build.yml?query=branch%3Amain)
<br>
8.6 (legacy release, daily build)
[![Build Status](https://github.com/tcltk/tk/actions/workflows/linux-build.yml/badge.svg?branch=core-8-6-branch)](https://github.com/tcltk/tk/actions/workflows/linux-build.yml?query=branch%3Acore-8-6-branch)
[![Build Status](https://github.com/tcltk/tk/actions/workflows/win-build.yml/badge.svg?branch=core-8-6-branch)](https://github.com/tcltk/tk/actions/workflows/win-build.yml?query=branch%3Acore-8-6-branch)
[![Build Status](https://github.com/tcltk/tk/actions/workflows/mac-build.yml/badge.svg?branch=core-8-6-branch)](https://github.com/tcltk/tk/actions/workflows/mac-build.yml?query=branch%3Acore-8-6-branch)
9.0 (production release, daily build)
[![Build Status](https://github.com/tcltk/tk/actions/workflows/linux-build.yml/badge.svg?branch=core-9-0-branch)](https://github.com/tcltk/tk/actions/workflows/linux-build.yml?query=branch%3Acore-9-0-branch)
[![Build Status](https://github.com/tcltk/tk/actions/workflows/win-build.yml/badge.svg?branch=core-9-0-branch)](https://github.com/tcltk/tk/actions/workflows/win-build.yml?query=branch%3Acore-9-0-branch)
[![Build Status](https://github.com/tcltk/tk/actions/workflows/mac-build.yml/badge.svg?branch=core-9-0-branch)](https://github.com/tcltk/tk/actions/workflows/mac-build.yml?query=branch%3Acore-9-0-branch)

## <a id="intro">1.</a> Introduction

This directory contains the sources and documentation for Tk, a
cross-platform GUI toolkit implemented with the Tcl scripting language.

For details on features, incompatibilities, and potential problems with
Changes to changes.md.
22
23
24
25
26
27
28



29
30
31
32
33
34
35
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38







+
+
+







 - [wm iconbitmap does not correctly set the icon pixmap hint on macOS](https://core.tcl-lang.org/tk/tktview/13ac26)
 - [Backspace crashes 9.0 interpreter on FreeBSD](https://core.tcl-lang.org/tk/tktview/1da19a)
 - [Bug in the ttk::scale widget of the "default" theme](https://core.tcl-lang.org/tk/tktview/126d07)
 - [Wrong appearance of the ttk::menubutton indicator of the "xpnative" theme](https://core.tcl-lang.org/tk/tktview/525536)
 - [English shortcuts for Chinese locale](https://core.tcl-lang.org/tk/tktview/c99266)
 - [No grip element in ttk::panedwindow sashes of most built-in themes](https://core.tcl-lang.org/tk/tktview/9902d8)
 - [Tk_Get3DBorderColors broken by design](https://core.tcl-lang.org/tk/tktview/517165)
 - [MS-Win: Incorrect system menu entries for transient toplevels](https://core.tcl-lang.org/tk/tktview/159aa5)
 - [MS-Win: Withdrawn Tk transient windows can reappear in Windows taskbar preview](https://core.tcl-lang.org/tk/tktview/91d0e9)
 - [Aqua windows don't always move focus correctly](https://core.tcl-lang.org/tkview/28d33f)

Release Tk 9.0.1 arises from the check-in with tag `core-9-0-1`.

Tk 9.0.1 continues the Tk 9.0 series of releases.  The Tk 9.0 series
does not support Tcl 8.6.  The Tk 9.0 series extends the Tcl 9.0 series.
To make use of Tk 9.0.1, first a Tcl 9.0 release must be present.
As new Tk features are developed, expect them to appear in Tk 9, but not
Changes to generic/tkImage.c.
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
71
72
73
74
75
76
77



78
79
80
81
82
83
84







-
-
-







    TkWindow *winPtr;		/* Main window of interpreter (used to detect
				 * when the world is falling apart.) */
} ImageModel;

typedef struct {
    Tk_ImageType *imageTypeList;/* First in a list of all known image
				 * types. */
    Tk_ImageType *oldImageTypeList;
				/* First in a list of all known old-style
				 * image types. */
    int initialized;		/* Set to 1 if we've initialized the
				 * structure. */
} ThreadSpecificData;
static Tcl_ThreadDataKey dataKey;

/*
 * Prototypes for local functions:
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
109
110
111
112
113
114
115





116
117
118
119
120
121
122







-
-
-
-
-







ImageTypeThreadExitProc(
    TCL_UNUSED(void *))
{
    Tk_ImageType *freePtr;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    while (tsdPtr->oldImageTypeList != NULL) {
	freePtr = tsdPtr->oldImageTypeList;
	tsdPtr->oldImageTypeList = tsdPtr->oldImageTypeList->nextPtr;
	ckfree(freePtr);
    }
    while (tsdPtr->imageTypeList != NULL) {
	freePtr = tsdPtr->imageTypeList;
	tsdPtr->imageTypeList = tsdPtr->imageTypeList->nextPtr;
	ckfree(freePtr);
    }
}

222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
214
215
216
217
218
219
220

221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237










238
239
240
241
242
243
244







-

















-
-
-
-
-
-
-
-
-
-







    if (Tcl_GetIndexFromObjStruct(interp, objv[1], imageOptions,
	    sizeof(char *), "option", 0, &index) != TCL_OK) {
	return TCL_ERROR;
    }
    switch ((enum options) index) {
    case IMAGE_CREATE: {
	Tcl_Obj **args;
	int oldimage = 0;

	if (objc < 3) {
	    Tcl_WrongNumArgs(interp, 2, objv,
		    "type ?name? ?-option value ...?");
	    return TCL_ERROR;
	}

	/*
	 * Look up the image type.
	 */

	arg = Tcl_GetString(objv[2]);
	for (typePtr = tsdPtr->imageTypeList; typePtr != NULL;
		typePtr = typePtr->nextPtr) {
	    if ((*arg == typePtr->name[0])
		    && (strcmp(arg, typePtr->name) == 0)) {
		break;
	    }
	}
	if (typePtr == NULL) {
	    oldimage = 1;
	    for (typePtr = tsdPtr->oldImageTypeList; typePtr != NULL;
		    typePtr = typePtr->nextPtr) {
		if ((*arg == typePtr->name[0])
			&& (strcmp(arg, typePtr->name) == 0)) {
		    break;
		}
	    }
	}
	if (typePtr == NULL) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "image type \"%s\" does not exist", arg));
	    Tcl_SetErrorCode(interp, "TK", "LOOKUP", "IMAGE_TYPE", arg, (char *)NULL);
	    return TCL_ERROR;
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363

364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
322
323
324
325
326
327
328







329








330
331

332
333
334



335
336
337



338
339
340
341
342
343
344







-
-
-
-
-
-
-

-
-
-
-
-
-
-
-
+

-



-
-
-



-
-
-







	 * initialization, then re-"get" for any existing instances of the
	 * image.
	 */

	objv += firstOption;
	objc -= firstOption;
	args = (Tcl_Obj **) objv;
	if (oldimage) {
	    args = (Tcl_Obj **)ckalloc((objc+1) * sizeof(Tcl_Obj *));
	    for (i = 0; i < objc; i++) {
		args[i] = (Tcl_Obj *) Tcl_GetString(objv[i]);
	    }
	    args[objc] = NULL;
	}
	Tcl_Preserve(modelPtr);
	if (oldimage) {
	    typedef int (OldCreateProc)(Tcl_Interp*, char*, Tcl_Size, char**,
		Tk_ImageType*, Tk_ImageModel, void **);
	    i = ((OldCreateProc*)typePtr->createProc)(interp,
		(char*)name, objc, (char**)args, typePtr,
		(Tk_ImageModel)modelPtr, &modelPtr->modelData);
	} else {
	    i = typePtr->createProc(interp, name, objc, args, typePtr,
	i = typePtr->createProc(interp, name, objc, args, typePtr,
		(Tk_ImageModel)modelPtr, &modelPtr->modelData);
	}
	if (i != TCL_OK){
	    EventuallyDeleteImage(modelPtr, 0);
	    Tcl_Release(modelPtr);
	    if (oldimage) {
		ckfree(args);
	    }
	    return TCL_ERROR;
	}
	Tcl_Release(modelPtr);
	if (oldimage) {
	    ckfree(args);
	}
	modelPtr->typePtr = typePtr;
	for (imagePtr = modelPtr->instancePtr; imagePtr != NULL;
		imagePtr = imagePtr->nextPtr) {
	    imagePtr->instanceData = typePtr->getProc(imagePtr->tkwin,
		    modelPtr->modelData);
	}
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
380
381
382
383
384
385
386





387
388
389
390
391
392
393







-
-
-
-
-







	if (objc != 2) {
	    Tcl_WrongNumArgs(interp, 2, objv, NULL);
	    return TCL_ERROR;
	}
	resultObj = Tcl_NewObj();
	for (typePtr = tsdPtr->imageTypeList; typePtr != NULL;
		typePtr = typePtr->nextPtr) {
	    Tcl_ListObjAppendElement(NULL, resultObj, Tcl_NewStringObj(
		    typePtr->name, TCL_INDEX_NONE));
	}
	for (typePtr = tsdPtr->oldImageTypeList; typePtr != NULL;
		typePtr = typePtr->nextPtr) {
	    Tcl_ListObjAppendElement(NULL, resultObj, Tcl_NewStringObj(
		    typePtr->name, TCL_INDEX_NONE));
	}
	Tcl_SetObjResult(interp, resultObj);
	break;

    case IMAGE_HEIGHT:
Changes to generic/tkTextDisp.c.
4579
4580
4581
4582
4583
4584
4585
4586

4587
4588

4589
4590
4591
4592
4593
4594
4595
4579
4580
4581
4582
4583
4584
4585

4586
4587

4588
4589
4590
4591
4592
4593
4594
4595







-
+

-
+







			LOG("tk_textEmbWinDisplay", string);
		    }
#ifdef MAC_OSX_TK
		    /* We need to redisplay the entire DLine so that the
		     * background of the line will not contain artifacts left
		     * by the scrolling.
		     */
		    

		    DisplayDLine(textPtr, dlPtr, NULL, pixmap);
#else		   
#else
		    TkTextEmbWinDisplayProc(textPtr, chunkPtr, x,
			    0,
			    dlPtr->height-dlPtr->spaceAbove-dlPtr->spaceBelow,
			    dlPtr->baseline - dlPtr->spaceAbove,
			    NULL,
			    None,
			    dlPtr->y + dlPtr->spaceAbove);
Changes to library/bgerror.tcl.
177
178
179
180
181
182
183
184

185
186
187
188
189
190
191
177
178
179
180
181
182
183

184
185
186
187
188
189
190
191







-
+








    ttk::frame $dlg.bot
    ttk::frame $dlg.top
    pack $dlg.bot -side bottom -fill both
    pack $dlg.top -side top -fill both -expand 1

    set W [ttk::frame $dlg.top.info]
    text $W.text -setgrid false -height 10 -wrap char \
    text $W.text -setgrid 0 -height 10 -wrap char \
	-yscrollcommand [list $W.scroll set]
    if {$windowingsystem ne "aqua"} {
	$W.text configure -width 40
    }

    ttk::scrollbar $W.scroll -command [list $W.text yview]
    pack $W.scroll -side right -fill y
Changes to library/console.tcl.
141
142
143
144
145
146
147
148

149
150
151
152
153
154
155
141
142
143
144
145
146
147

148
149
150
151
152
153
154
155







-
+







    ::ttk::style layout ConsoleFrame {
	Entry.field -sticky news -border 1 -children {
	    ConsoleFrame.padding -sticky news
	}
    }
    ::ttk::frame .consoleframe -style ConsoleFrame

    set con [text .console -yscrollcommand [list .sb set] -setgrid true \
    set con [text .console -yscrollcommand [list .sb set] -setgrid 1 \
		 -borderwidth 0 -highlightthickness 0 -font TkConsoleFont]
    if {[tk windowingsystem] eq "aqua"} {
	scrollbar .sb -command [list $con yview]
    } else {
	::ttk::scrollbar .sb -command [list $con yview]
    }
    pack .sb  -in .consoleframe -fill both -side right -padx 1 -pady 1
Changes to library/demos/bind.tcl.
16
17
18
19
20
21
22
23

24
25
26
27
28
29
30
16
17
18
19
20
21
22

23
24
25
26
27
28
29
30







-
+







wm iconname $w "bind"
positionWindow $w

## See Code / Dismiss buttons
set btns [addSeeDismiss $w.buttons $w]
pack $btns -side bottom -fill x

text $w.text -yscrollcommand "$w.scroll set" -setgrid true \
text $w.text -yscrollcommand "$w.scroll set" -setgrid 1 \
	-width 60 -height 24 -font $font -wrap word
ttk::scrollbar $w.scroll -command "$w.text yview"
pack $w.scroll -side right -fill y
pack $w.text -expand yes -fill both

# Set up display styles.

Changes to library/demos/browse.
11
12
13
14
15
16
17
18

19
20
21
22
23
24
25
11
12
13
14
15
16
17

18
19
20
21
22
23
24
25







-
+








# Create a scrollbar on the right side of the main window and a listbox
# on the left side.

scrollbar .scroll -command ".list yview"
pack .scroll -side right -fill y
listbox .list -yscroll ".scroll set" -relief sunken -width 20 -height 20 \
	-setgrid yes
	-setgrid 1
pack .list -side left -fill both -expand yes
wm minsize . 1 1

# The procedure below is invoked to open a browser on a given file;  if the
# file is a directory then another instance of this program is invoked; if
# the file is a regular file then the Mx editor is invoked to display
# the file.
Changes to library/demos/rmt.
38
39
40
41
42
43
44
45

46
47
48
49
50
51
52
38
39
40
41
42
43
44

45
46
47
48
49
50
51
52







-
+







.menu add cascade  -label "File"  -underline 0  -menu .menu.file
.menu.file add cascade  -label "Select Application"  -underline 0 \
	-menu .menu.file.apps
.menu.file add command  -label "Quit"  -command "destroy ."  -underline 0

# Create text window and scrollbar.

text .t -yscrollcommand ".s set" -setgrid true
text .t -yscrollcommand ".s set" -setgrid 1
scrollbar .s -command ".t yview"
grid .t .s -sticky nsew
grid rowconfigure . 0 -weight 1
grid columnconfigure . 0 -weight 1

# Create a binding to forward commands to the target application,
# plus modify many of the built-in bindings so that only information
Changes to library/demos/search.tcl.
104
105
106
107
108
109
110
111

112
113
114
115
116
117
118
104
105
106
107
108
109
110

111
112
113
114
115
116
117
118







-
+







entry $w.string.entry -width 40 -textvariable searchString
button $w.string.button -text "Highlight" \
	-command "textSearch $w.text \$searchString search"
pack $w.string.label $w.string.entry -side left
pack $w.string.button -side left -pady 3p -padx 7.5p
bind $w.string.entry <Return> "textSearch $w.text \$searchString search"

text $w.text -yscrollcommand "$w.scroll set" -setgrid true
text $w.text -yscrollcommand "$w.scroll set" -setgrid 1
ttk::scrollbar $w.scroll -command "$w.text yview"
pack $w.file $w.string -side top -fill x
pack $w.scroll -side right -fill y
pack $w.text -expand yes -fill both

# Set up display styles for text highlighting.

Changes to library/demos/style.tcl.
20
21
22
23
24
25
26
27

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

27
28
29
30
31
32
33
34







-
+







set btns [addSeeDismiss $w.buttons $w]
pack $btns -side bottom -fill x

# Only set the font family in one place for simplicity and consistency

set family Courier

text $w.text -yscrollcommand "$w.scroll set" -setgrid true \
text $w.text -yscrollcommand "$w.scroll set" -setgrid 1 \
	-width 70 -height 32 -wrap word -font "$family 12"
ttk::scrollbar $w.scroll -command "$w.text yview"
pack $w.scroll -side right -fill y
pack $w.text -expand yes -fill both

# Set up display styles

Changes to library/demos/twind.tcl.
26
27
28
29
30
31
32
33

34
35
36
37
38
39
40
26
27
28
29
30
31
32

33
34
35
36
37
38
39
40







-
+








## See Code / Dismiss buttons
set btns [addSeeDismiss $w.buttons $w]
pack $btns -side bottom -fill x

frame $w.f -highlightthickness 1 -borderwidth 1 -relief sunken
set t $w.f.text
text $t -yscrollcommand "$w.scroll set" -setgrid true -font $font -width 70 \
text $t -yscrollcommand "$w.scroll set" -font $font -width 70 \
	-height 35 -wrap word -highlightthickness 0 -borderwidth 0
pack $t -expand  yes -fill both
ttk::scrollbar $w.scroll -command "$t yview"
pack $w.scroll -side right -fill y
panedwindow $w.pane
pack $w.pane -expand yes -fill both
$w.pane add $w.f -stretch always
Changes to macosx/tkMacOSXDialog.c.
1377
1378
1379
1380
1381
1382
1383
1384

1385
1386
1387
1388
1389
1390
1391
1377
1378
1379
1380
1381
1382
1383

1384
1385
1386
1387
1388
1389
1390
1391







-
+







 *
 *----------------------------------------------------------------------
 */

void
TkAboutDlg(void)
{
    [NSApp orderFrontStandardAboutPanel:nil];
    [NSApp orderFrontStandardAboutPanel:NSApp];
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXStandardAboutPanelObjCmd --
 *
1407
1408
1409
1410
1411
1412
1413
1414

1415
1416
1417
1418
1419
1420
1421
1407
1408
1409
1410
1411
1412
1413

1414
1415
1416
1417
1418
1419
1420
1421







-
+







    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    if (objc > 1) {
	Tcl_WrongNumArgs(interp, 1, objv, NULL);
	return TCL_ERROR;
    }
    [NSApp orderFrontStandardAboutPanel:nil];
    [NSApp orderFrontStandardAboutPanel:NSApp];
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_MessageBoxObjCmd --
Changes to macosx/tkMacOSXImage.c.
980
981
982
983
984
985
986
987
988


989
990
991
992
993
994
995
996
997
998

999
1000
1001
1002
1003
1004
1005
980
981
982
983
984
985
986


987
988
989
990
991
992
993
994
995
996
997

998
999
1000
1001
1002
1003
1004
1005







-
-
+
+









-
+







{
    Drawable drawable = Tk_WindowId(tkwin);
    HIShapeRef srcRgn, dstRgn;
    HIMutableShapeRef dmgRgn = HIShapeCreateMutable();
    NSRect srcRect, dstRect;
    int result = 0;
    NSView *view = TkMacOSXGetNSViewForDrawable(drawable);
    CGRect viewBounds = [view bounds];    
    
    CGRect viewBounds = [view bounds];

    /*
     * To compute the damage region correctly we need to clip the source and
     * destination rectangles to the NSView bounds in the same way that
     * XCopyArea does.
     */

    CGRect bounds = ClipCopyRects(viewBounds, viewBounds, x, y, width, height);
    unsigned int w = bounds.size.width;
    unsigned int h = bounds.size.height;
    

    if (XCopyArea(Tk_Display(tkwin), drawable, drawable, gc, x, y,
	     w, h, x + dx, y + dy) == Success) {

	/*
	 * Compute the damage region, using Tk coordinates (origin at top left).
	 */

1058
1059
1060
1061
1062
1063
1064
1065

1066
1067
1068
1069
1070
1071
1072
1058
1059
1060
1061
1062
1063
1064

1065
1066
1067
1068
1069
1070
1071
1072







-
+







    CGImageRef img = NULL;
    CGRect dstRect;

    // XXXX Need to deal with pixmaps!

    NSView *srcView = TkMacOSXGetNSViewForDrawable(src);
    NSView *dstView = TkMacOSXGetNSViewForDrawable(dst);
    CGRect srcBounds = [srcView bounds];    
    CGRect srcBounds = [srcView bounds];
    CGRect dstBounds = [dstView bounds];

    // To avoid distorting the image when it is drawn we must ensure that
    // the source and destination rectangles have the same size.  This is
    // tricky because each of those rectangles will be clipped to the
    // bounds of its containing NSView.  If the source gets clipped and
    // the destination does not, for example, then the shapes will differ.
Changes to macosx/tkMacOSXMenu.c.
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1156
1157
1158
1159
1160
1161
1162

1163
1164
1165
1166
1167
1168
1169







-








void
Tk_SetMainMenubar(
    Tcl_Interp *interp,		/* The interpreter of the application */
    Tk_Window tkwin,		/* The frame we are setting up */
    const char *menuName)	/* The name of the menu to put in front. */
{
    static Tcl_Interp *currentInterp = NULL;
    TKMenu *menu = nil;
    TkWindow *winPtr = (TkWindow *) tkwin;

    /*
     * We will be called when an embedded window receives an ActivationNotify
     * event, but we should not change the menubar in that case.
     */
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1200
1201
1202
1203
1204
1205
1206

1207
1208
1209
1210
1211
1212
1213







-







    }

    /*
     * If we couldn't find a menu this will install the default menubar.
     */

    [NSApp tkSetMainMenu:menu];
    currentInterp = interp;
}

/*
 *----------------------------------------------------------------------
 *
 * CheckForSpecialMenu --
 *
Changes to macosx/tkMacOSXMenus.c.
199
200
201
202
203
204
205
206

207
208
209
210
211
212
213
199
200
201
202
203
204
205

206
207
208
209
210
211
212
213







-
+








- (void) orderFrontStandardAboutPanel: (id) sender
{
    (void)sender;

    if (!_eventInterp || !Tcl_FindCommand(_eventInterp, "tkAboutDialog",
	    NULL, 0) || (GetCurrentEventKeyModifiers() & optionKey)) {
	[super orderFrontStandardAboutPanel:nil];
	[super orderFrontStandardAboutPanel:NSApp];
    } else {
	int code = Tcl_EvalEx(_eventInterp, "tkAboutDialog", TCL_INDEX_NONE,
		TCL_EVAL_GLOBAL);

	if (code != TCL_OK) {
	    Tcl_BackgroundException(_eventInterp, code);
	}
Changes to macosx/tkMacOSXPrivate.h.
290
291
292
293
294
295
296


297
298
299
300
301
302
303
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305







+
+







MODULE_SCOPE NSColor*   controlAccentColor(void);
MODULE_SCOPE void       Ttk_MacOSXInit(void);
MODULE_SCOPE unsigned long TkMacOSXClearPixel(void);
MODULE_SCOPE int MacSystrayInit(Tcl_Interp *);
MODULE_SCOPE int MacPrint_Init(Tcl_Interp *);
MODULE_SCOPE NSString*  TkMacOSXOSTypeToUTI(OSType ostype);
MODULE_SCOPE NSImage*   TkMacOSXIconForFileType(NSString *filetype);
MODULE_SCOPE void TkMacOSXAssignNewKeyWindow(Tcl_Interp *interp,
					     NSWindow *ignore);

#pragma mark Private Objective-C Classes

#define VISIBILITY_HIDDEN __attribute__((visibility("hidden")))

enum { tkMainMenu = 1, tkApplicationMenu, tkWindowsMenu, tkHelpMenu};

Changes to macosx/tkMacOSXSubwindows.c.
186
187
188
189
190
191
192

193
194
195
196
197
198
199
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200







+








	    TkMacOSXApplyWindowAttributes(winPtr, win);
	    [win setExcludedFromWindowsMenu:NO];
	    [NSApp activateIgnoringOtherApps:initialized];
	    if (initialized) {
		if ([win canBecomeKeyWindow]) {
		    [win makeKeyAndOrderFront:NSApp];
		    [NSApp setTkEventTarget:TkMacOSXGetTkWindow(win)];
		} else {
		    [win orderFrontRegardless];
		}

		/*
		 * Delay for up to 20 milliseconds until the toplevel has
		 * actually become the highest toplevel.  This is to ensure
356
357
358
359
360
361
362

363
364
365
366
367
368
369
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371







+







			continue;
		    }
		    wmInfoPtr = winPtr2->wmInfoPtr;
		    isOnScreen = (wmInfoPtr->hints.initial_state != IconicState &&
				  wmInfoPtr->hints.initial_state != WithdrawnState);
		    if (w != win && isOnScreen && [w canBecomeKeyWindow]) {
			[w makeKeyAndOrderFront:NSApp];
			[NSApp setTkEventTarget:TkMacOSXGetTkWindow(win)];
			break;
		    }
		}
	    }
	}
	TkMacOSXInvalClipRgns((Tk_Window)winPtr);
    } else {
Changes to macosx/tkMacOSXWindowEvent.c.
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
75
76
77
78
79
80
81













82
83
84
85
86
87
88
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
75
76
77
78
79
80
81
82
83
84
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







+




-








+
+
+
+
-
-
+
+

+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+

-
+

-
-
-
+
+
+

-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+







static int		GenerateActivateEvents(TkWindow *winPtr,
			    int activeFlag);

#pragma mark TKApplication(TKWindowEvent)

extern NSString *NSWindowDidOrderOnScreenNotification;
extern NSString *NSWindowWillOrderOnScreenNotification;
extern NSString *NSWindowWillCloseNotification;

#ifdef TK_MAC_DEBUG_NOTIFICATIONS
extern NSString *NSWindowDidOrderOffScreenNotification;
#endif


@implementation TKApplication(TKWindowEvent)

- (void) windowActivation: (NSNotification *) notification
{
#ifdef TK_MAC_DEBUG_NOTIFICATIONS
    TKLog(@"-[%@(%p) %s] %@", [self class], self, sel_getName(_cmd), notification);
#endif
    if ([NSApp tkWillExit]) {
	return;
    }
    static NSWindow *systemDialog = NULL;
    NSWindow *w = [notification object];
    TkWindow *winPtr = TkMacOSXGetTkWindow(w);
    NSWindow *win = [notification object];
    TkWindow *winPtr = TkMacOSXGetTkWindow(win);
    NSString *name = [notification name];
    if ([name isEqualToString:NSWindowDidResignKeyNotification]) {
	if (![NSApp keyWindow] && [NSApp isActive]) {
	    if (winPtr) {
		/*
		 * A Tk window lost focus and no window has focus anymore.
		 */

		TkMacOSXAssignNewKeyWindow(Tk_Interp((Tk_Window) winPtr), NULL);
	    } else {
		/*
		 * A system dialog, such as a standard About dialog, lost focus.
		 */

		TkMacOSXAssignNewKeyWindow(NULL, NULL);
	    }
	}
    }
    /*
     * On older systems the system dialogs do not send DidResignKey
     * but the do send WillClose.
     */

    if ([name isEqualToString:NSWindowWillCloseNotification]) {
	if (win == systemDialog) {
	    TkMacOSXAssignNewKeyWindow(NULL, NULL);
	}
    }
    Bool flag = [name isEqualToString:NSWindowDidBecomeKeyNotification];
    if (winPtr && flag) {
	NSPoint location = [NSEvent mouseLocation];
	int x = location.x;
	int y = floor(TkMacOSXZeroScreenHeight() - location.y);
	/*
	 * The Tk event target persists when there is no key window but
	 * gets reset when a new window becomes the key window.
	 */
    if ([name isEqualToString:NSWindowDidBecomeKeyNotification]) {
	if (winPtr) {
	    NSPoint location = [NSEvent mouseLocation];
	    int x = location.x;
	    int y = floor(TkMacOSXZeroScreenHeight() - location.y);
	    /*
	     * The Tk event target persists when there is no key window but
	     * gets reset when a new window becomes the key window.
	     */

	[NSApp setTkEventTarget: winPtr];
	    [NSApp setTkEventTarget: winPtr];

	/*
	 * Call Tk_UpdatePointer if the pointer is in the window.
	 */
	    /*
	     * Call Tk_UpdatePointer if the pointer is in the window.
	     */

	NSView *view = [w contentView];
	NSPoint viewLocation = [view convertPoint:location fromView:nil];
	if (NSPointInRect(viewLocation, NSInsetRect([view bounds], 2, 2))) {
	    Tk_UpdatePointer((Tk_Window) winPtr, x, y, [NSApp tkButtonState]);
	}
    }
    if (winPtr && Tk_IsMapped(winPtr)) {
	GenerateActivateEvents(winPtr, flag);
	    NSView *view = [win contentView];
	    NSPoint viewLocation = [view convertPoint:location fromView:nil];
	    if (NSPointInRect(viewLocation,
			      NSInsetRect([view bounds], 2, 2))) {
		Tk_UpdatePointer((Tk_Window) winPtr, x, y,
				 [NSApp tkButtonState]);
	    }
	} else {
	    systemDialog = win;
	}
	if (winPtr && Tk_IsMapped(winPtr)) {
	    GenerateActivateEvents(winPtr, true);
	}
    }
}

- (void) windowBoundsChanged: (NSNotification *) notification
{
#ifdef TK_MAC_DEBUG_NOTIFICATIONS
    TKLog(@"-[%@(%p) %s] %@", [self class], self, sel_getName(_cmd), notification);
132
133
134
135
136
137
138
139

140
141
142
143
144
145
146
168
169
170
171
172
173
174

175
176
177
178
179
180
181
182







-
+







#endif

    NSWindow *w = [notification object];
    TkWindow *winPtr = TkMacOSXGetTkWindow(w);
    if (winPtr && winPtr->wmInfoPtr->hints.initial_state == IconicState) {
	winPtr->wmInfoPtr->hints.initial_state =
		TkMacOSXIsWindowZoomed(winPtr) ? ZoomState : NormalState;
	TkWmUnmapWindow(winPtr);
	TkWmMapWindow(winPtr);

	/*
	 * NSWindowDidDeminiaturizeNotification is received after
	 * NSWindowDidBecomeKeyNotification, so activate manually
	 */

	GenerateActivateEvents(winPtr, 1);
299
300
301
302
303
304
305

306
307
308
309
310
311
312
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349







+







    NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];

#define observe(n, s) \
	[nc addObserver:self selector:@selector(s) name:(n) object:nil]

    observe(NSWindowDidBecomeKeyNotification, windowActivation:);
    observe(NSWindowDidResignKeyNotification, windowActivation:);
    observe(NSWindowWillCloseNotification, windowActivation:);
    observe(NSWindowDidMoveNotification, windowBoundsChanged:);
    observe(NSWindowDidResizeNotification, windowBoundsChanged:);
    observe(NSWindowDidDeminiaturizeNotification, windowExpanded:);
    observe(NSWindowDidMiniaturizeNotification, windowCollapsed:);
    observe(NSWindowWillOrderOnScreenNotification, windowMapped:);
    observe(NSWindowDidOrderOnScreenNotification, windowBecameVisible:);
    observe(NSWindowWillStartLiveResizeNotification, windowLiveResize:);
Changes to macosx/tkMacOSXWm.c.
833
834
835
836
837
838
839











































840
841
842
843
844
845
846
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889







+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+







		return NULL;
	    }
	}
    }
    return NULL;
}

void TkMacOSXAssignNewKeyWindow(
    Tcl_Interp *interp,
    NSWindow *ignore)
{
    TkWindow *winPtr;

    /*
     * Avoid bug 5692042764: set tkEventTarget to NULL if there is no window to
     * send Tk events to.
     */

    [NSApp setTkEventTarget: NULL];
    for (NSWindow *w in [NSApp orderedWindows]) {
	WmInfo *wmPtr;
	BOOL isOnScreen;
	winPtr = TkMacOSXGetTkWindow(w);
	if (!winPtr
	    || !winPtr->wmInfoPtr
	    || (winPtr->flags & TK_ALREADY_DEAD)) {
	    continue;
	}
	if (interp && interp != Tk_Interp((Tk_Window) winPtr)) {
	    continue;
	}
	wmPtr = winPtr->wmInfoPtr;
	isOnScreen = (wmPtr->hints.initial_state != IconicState &&
		      wmPtr->hints.initial_state != WithdrawnState);
	if (w != ignore && isOnScreen && [w canBecomeKeyWindow]) {
	    TKMenu *menu;
	    [w makeKeyAndOrderFront:NSApp];
	    /* Set the menubar for the new front window. */
	    if (winPtr->wmInfoPtr &&
		winPtr->wmInfoPtr->menuPtr &&
		winPtr->wmInfoPtr->menuPtr->mainMenuPtr) {
		menu = (TKMenu *) winPtr->wmInfoPtr->menuPtr->platformData;
		[NSApp tkSetMainMenu:menu];
		[NSApp setTkEventTarget: winPtr];
	    }
	    break;
	}
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TkWmNewWindow --
 *
 *	This procedure is invoked whenever a new top-level window is created.
 *	Its job is to initialize the WmInfo structure for the window.
1264
1265
1266
1267
1268
1269
1270
1271

1272
1273
1274
1275
1276
1277
1278

1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1307
1308
1309
1310
1311
1312
1313

1314







1315


















1316
1317
1318
1319
1320
1321
1322







-
+
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-







	 * there is no choice for a new key window.  Moreover, if the host
	 * computer has a TouchBar then the TouchBar holds a reference to the
	 * key window which prevents it from being deallocated until it stops
	 * being the key window.  On these systems the only option for
	 * preventing zombies is to set the key window to nil.
	 */


	TkMacOSXAssignNewKeyWindow(Tk_Interp((Tk_Window) winPtr),
	/*
	 * Fix bug 5692042764:
	 * set tkEventTarget to NULL when there is no window to send Tk events to.
	 */
	TkWindow *newTkEventTarget = NULL;
	winPtr2 = NULL;

				   deadNSWindow);
	for (w in [NSApp orderedWindows]) {
	    winPtr2 = TkMacOSXGetTkWindow(w);
	    BOOL isOnScreen;

	    if (!winPtr2 || !winPtr2->wmInfoPtr) {
		continue;
	    }
	    wmPtr2 = winPtr2->wmInfoPtr;
	    isOnScreen = (wmPtr2->hints.initial_state != IconicState &&
			  wmPtr2->hints.initial_state != WithdrawnState);
	    if (w != deadNSWindow && isOnScreen && [w canBecomeKeyWindow]) {
		[w makeKeyAndOrderFront:NSApp];
		newTkEventTarget = TkMacOSXGetTkWindow(w);
		break;
	    }
	}

	[NSApp setTkEventTarget:newTkEventTarget];

	/*
	 * Prevent zombies on systems with a TouchBar.
	 */

	if (deadNSWindow == [NSApp keyWindow]) {
	    [NSApp _setKeyWindow:nil];
7229
7230
7231
7232
7233
7234
7235
7236
7237
7238
7239
7240
7241
7242
7243
7248
7249
7250
7251
7252
7253
7254

7255
7256
7257
7258
7259
7260
7261







-







{
    if (!winPtr ||
	(winPtr->flags & TK_ALREADY_DEAD) ||
	!Tk_IsMapped(winPtr) ||
	winPtr->atts.override_redirect) {
	return 0;
    }

    if (Tk_IsTopLevel(winPtr) && !Tk_IsEmbedded(winPtr)) {
	NSWindow *win = TkMacOSXGetNSWindowForDrawable(winPtr->window);

	TkWmRestackToplevel(winPtr, Above, NULL);
	if (force) {
	    [NSApp activateIgnoringOtherApps:YES];
	}
Changes to tests/constraints.tcl.
242
243
244
245
246
247
248
249
250
251



252
253
254
255
256
257
258
242
243
244
245
246
247
248



249
250
251
252
253
254
255
256
257
258







-
-
-
+
+
+







	namespace export controlPointerWarpTiming

	# On macOS windows are not allowed to overlap the menubar at the top of the
	# screen or the dock.  So tests which move a window and then check whether it
	# got moved to the requested location should use a y coordinate larger than the
	# height of the menubar (normally 23 pixels) and an x coordinate larger than the
	# width of the dock, if it happens to be on the left.
	# testmenubarheight deals with this issue but may not be available from the test
	# environment, therefore provide a fallback here
	if {[llength [info procs testmenubarheight]] == 0} {
	# The C-level command "testmenubarheight" deals with this issue but it may
	# not be available on each platform. Therefore, provide a fallback here.
	if {[llength [info commands testmenubarheight]] == 0} {
	    if {[tk windowingsystem] ne "aqua"} {
		# Windows may overlap the menubar
		proc testmenubarheight {} {
		    return 0
		}
	    } else {
		# Windows may not overlap the menubar
Changes to tests/event.test.
1128
1129
1130
1131
1132
1133
1134


1135
1136
1137
1138
1139
1140
1141
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143







+
+







    bind all <Enter> {}
    destroy .one
    unset result
} -result {|<Enter> NotifyNonlinear .one|}

test event-9.19 {Successive destructions (pointer window + ancestors including its toplevel), destination is internal window, bypass root win} -setup {
    setup_win_mousepointer .one; # ensure the mouse pointer is where we want it to be (the .one toplevel is not itself used in this test)
    wm geometry . +500+500; # avoid an extraneous <Leave> event
    update idletasks
    destroy .one
    toplevel .two
    pack propagate .two 0
    wm geometry .two 300x300+100+100
    create_and_pack_frames .two
    wm deiconify .two
    update idletasks; # make sure two is there
Changes to tests/filebox.test.
278
279
280
281
282
283
284
285
286


287
288
289
290
291
292
293
278
279
280
281
282
283
284


285
286
287
288
289
290
291
292
293







-
-
+
+







	destroy .t1
	destroy .t2
    }

test fileDialog-2.7-$mode {"tk_getOpenFile: bad extension" -body {
    #ToPressButton $parent cancel
    set filename [tk_getOpenFile -filetypes {
        {"Invalid extension" {x.y}}
        {"All files" {*}}
	{"Invalid extension" {x.y}}
	{"All files" {*}}
     }]
     } -result {}
}

    foreach x [lsort -integer [array names filters]] {
	test filebox-3.$x-$mode "tk_getOpenFile command" nonUnixUserInteraction {
	    ToPressButton $parent ok
Changes to tests/focus.test.
1
2
3
4
5
6
7
8
9
10
11
12




13
14
15
16
17
18
19
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23












+
+
+
+







# This file is a Tcl script to test out the "focus" command and the
# other procedures in the file tkFocus.c.  It is organized in the
# standard fashion for Tcl tests.
#
# Copyright © 1994-1996 Sun Microsystems, Inc.
# Copyright © 1998-1999 Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
eval tcltest::configure $argv
tcltest::loadTestedCommands
namespace import -force tcltest::test
if {[tk windowingsystem] eq "aqua"} {
    interp create childInterp
    load {} Tk childInterp
}

testConstraint failsOnUbuntu [expr {![info exists ::env(CI)] || ![string match Linux $::tcl_platform(os)]}]
testConstraint failsOnXQuarz [expr {$tcl_platform(os) ne "Darwin" || [tk windowingsystem] ne "x11" }]

proc focusSetup {} {
    destroy .t
    toplevel .t
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
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
75







+
-
-
-
+
+
+
+
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+








# The following procedure ensures that there is no input focus
# in this application.  It does it by arranging for another
# application to grab the focus.  The "after" and "update" stuff
# is needed to wait long enough for pending actions to get through
# the X server and possibly also the window manager.

if {[tk windowingsystem] eq "aqua"} {
proc focusClear {} {
    dobg {after 200; focus -force .; update}
    after 400
    proc focusClear {} {
	childInterp eval {
	    focus -force .
	    set i 0
    if {[tk windowingsystem] eq "aqua"} {
	# In Aqua we need to explicitly wait until focus is cleared.
	while {[focus] != ""} {
	    after 100 {set y 1}
	    tkwait variable y
	}
    }

    update
	    while {[focus] != "."} {
		after 100
		incr i
		if {$i > 10} {
		    break
		}
	    }
	}
    }
} else {
    proc focusClear {} {
	dobg {after 200; focus -force .; update}
	after 400
	update
    }
}


# Button used in some tests in the whole test file
button .b -text .b -relief raised -bd 2
pack .b

153
154
155
156
157
158
159

160

161
162
163
164
165
166
167
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181







+

+







    unix
} -body {
    focus -displayof .lousy
} -returnCodes error -result {bad window path name ".lousy"}
test focus-1.12 {Tk_FocusCmd procedure, -displayof option} -constraints {
    unix
} -body {
    # Move focus to the root window in the child or bg interpreter.
    focusClear
    # The main application does not have focus, so this has no effect now.
    focus .t
    focus -displayof .t.b3
}  -result {}
test focus-1.13 {Tk_FocusCmd procedure, -displayof option} -constraints {
    unix
} -body {
    focusClear
785
786
787
788
789
790
791



792
799
800
801
802
803
804
805
806
807
808
809







+
+
+

    crashit
} -result {Reached}

deleteWindows

# cleanup
cleanupTests
if {[tk windowingsystem] eq "aqua"} {
    interp delete childInterp
}
return
Changes to tests/place.test.
292
293
294
295
296
297
298

299
300
301
302
303
304
305
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306







+







    place forget .t.f
} -body {
    place .t.f -x 0 -y 0 -width 200 -height 100
    place .t.f2 -in .t.f -relx 1.0 -rely 1.0 -anchor sw -width 50 -height 20
    update
    set result [winfo ismapped .t.f2]
    wm iconify .t
    update idletasks
    lappend result [winfo ismapped .t.f2]
    place .t.f2 -x 40 -y 30 -relx 0 -rely 0 -anchor nw
    update
    lappend result [winfo x .t.f2] [winfo y .t.f2] [winfo ismapped .t.f2]
    wm deiconify .t
    update
    lappend result [winfo ismapped .t.f2]
Changes to tests/textTag.test.
1505
1506
1507
1508
1509
1510
1511



1512
1513
1514
1515
1516
1517
1518
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521







+
+
+








test textTag-18.1 {TkTextPickCurrent tag bindings} -setup {
    destroy .t
    wm geometry . +200+200 ; update
    event generate {} <Motion> -warp 1 -x 5 -y 5
    controlPointerWarpTiming
} -body {
    # Move the cursor out of the way.
    event generate . <Motion> -warp 1 -x 800 -y 500
    controlPointerWarpTiming
    text .t -width 30 -height 4 -relief sunken -borderwidth 10 \
      -highlightthickness 10 -pady 2
    pack .t
    update ; # map the window, otherwise -warp can't be done

    .t insert end " Tag here " TAG " no tag here"
    .t tag configure TAG -borderwidth 4 -relief raised
Changes to unix/Makefile.in.
649
650
651
652
653
654
655
656

657
658
659
660
661
662
663
649
650
651
652
653
654
655

656
657
658
659
660
661
662
663







-
+







		cat ${TK_ZIP_FILE} >> ${LIB_FILE}; \
	    else $(MACHER) append ${LIB_FILE} ${TK_ZIP_FILE} /tmp/macher_output; \
		 mv /tmp/macher_output ${LIB_FILE}; chmod u+x ${LIB_FILE}; \
	    fi; \
	fi

${STUB_LIB_FILE}: ${STUB_LIB_OBJS}
	@if test "x${LIB_FILE}" = "xlibtcl9tk${MAJOR_VERSION}.${MINOR_VERSION}.dll"; then \
	@if test "x${LIB_FILE}" = "xcygtcl9tk${MAJOR_VERSION}.${MINOR_VERSION}.dll"; then \
	    (cd ${TOP_DIR}/win; ${MAKE} tcl9tk${MAJOR_VERSION}${MINOR_VERSION}.dll); \
	    cp "${TOP_DIR}/win/tcl9tk${MAJOR_VERSION}${MINOR_VERSION}.dll" .; \
	fi
	rm -f $@
	@MAKE_STUB_LIB@

# Build Aqua resource files
Changes to unix/configure.
4776
4777
4778
4779
4780
4781
4782
4783

4784
4785
4786
4787
4788
4789
4790
4776
4777
4778
4779
4780
4781
4782

4783
4784
4785
4786
4787
4788
4789
4790







-
+







	    DL_LIBS="-ldl"
	    LDFLAGS="$LDFLAGS -export-dynamic"
	    CC_SEARCH_FLAGS=""
	    LD_SEARCH_FLAGS=""
	    ;;
	CYGWIN_*|MINGW32_*|MSYS_*)
	    SHLIB_CFLAGS="-fno-common"
	    SHLIB_LD='${CC} -shared'
	    SHLIB_LD='${CC} -shared -Wl,--out-implib,$(patsubst cyg%.dll,lib%.dll,$@).a'
	    SHLIB_SUFFIX=".dll"
	    DL_OBJS="tclLoadDl.o"
	    PLAT_OBJS='${CYGWIN_OBJS}'
	    PLAT_SRCS='${CYGWIN_SRCS}'
	    DL_LIBS="-ldl"
	    CC_SEARCH_FLAGS=""
	    LD_SEARCH_FLAGS=""
8778
8779
8780
8781
8782
8783
8784






8785
8786

8787
8788

8789
8790
8791
8792
8793
8794
8795
8796
8797
8778
8779
8780
8781
8782
8783
8784
8785
8786
8787
8788
8789
8790
8791

8792
8793

8794
8795

8796
8797
8798
8799
8800
8801
8802







+
+
+
+
+
+

-
+

-
+

-







#	The statements below define a collection of symbols related to
#	building libtk as a shared library instead of a static library.
#--------------------------------------------------------------------

eval eval "TK_UNSHARED_LIB_SUFFIX=${UNSHARED_LIB_SUFFIX}"
eval eval "TK_SHARED_LIB_SUFFIX=${SHARED_LIB_SUFFIX}"
eval "TK_LIB_FILE_TCL8=libtk${LIB_SUFFIX}"
if test "$ac_cv_cygwin" = "yes" -a "$SHARED_BUILD" != "0"; then
eval "TK_LIB_FILE_TCL9=cygtcl9tk${LIB_SUFFIX}"
EXTRA_INSTALL_BINARIES='$(INSTALL_LIBRARY) $(patsubst cyg%.dll,lib%.dll.a,${LIB_FILE}) "$(LIB_INSTALL_DIR)"'
else
eval "TK_LIB_FILE_TCL9=libtcl9tk${LIB_SUFFIX}"
fi
if test ${TCL_MAJOR_VERSION} = 8 ; then
eval "TK_LIB_FILE=libtk${LIB_SUFFIX}"
eval "TK_LIB_FILE=${TK_LIB_FILE_TCL8}"
else
eval "TK_LIB_FILE=libtcl9tk${LIB_SUFFIX}"
eval "TK_LIB_FILE=${TK_LIB_FILE_TCL9}"
fi
eval "TK_LIB_FILE_TCL9=libtcl9tk${LIB_SUFFIX}"

# tkConfig.sh needs a version of the _LIB_SUFFIX that has been eval'ed
# since on some platforms TK_LIB_FILE contains shell escapes.

eval "TK_LIB_FILE=${TK_LIB_FILE}"

if test "${SHARED_BUILD}" = "1" -a "${SHLIB_SUFFIX}" != ""; then
Changes to unix/configure.ac.
538
539
540
541
542
543
544






545
546

547
548

549
550
551
552
553
554
555
556
557
538
539
540
541
542
543
544
545
546
547
548
549
550
551

552
553

554
555

556
557
558
559
560
561
562







+
+
+
+
+
+

-
+

-
+

-







#	The statements below define a collection of symbols related to
#	building libtk as a shared library instead of a static library.
#--------------------------------------------------------------------

eval eval "TK_UNSHARED_LIB_SUFFIX=${UNSHARED_LIB_SUFFIX}"
eval eval "TK_SHARED_LIB_SUFFIX=${SHARED_LIB_SUFFIX}"
eval "TK_LIB_FILE_TCL8=libtk${LIB_SUFFIX}"
if test "$ac_cv_cygwin" = "yes" -a "$SHARED_BUILD" != "0"; then
eval "TK_LIB_FILE_TCL9=cygtcl9tk${LIB_SUFFIX}"
EXTRA_INSTALL_BINARIES='$(INSTALL_LIBRARY) $(patsubst cyg%.dll,lib%.dll.a,${LIB_FILE}) "$(LIB_INSTALL_DIR)"'
else
eval "TK_LIB_FILE_TCL9=libtcl9tk${LIB_SUFFIX}"
fi
if test ${TCL_MAJOR_VERSION} = 8 ; then
eval "TK_LIB_FILE=libtk${LIB_SUFFIX}"
eval "TK_LIB_FILE=${TK_LIB_FILE_TCL8}"
else
eval "TK_LIB_FILE=libtcl9tk${LIB_SUFFIX}"
eval "TK_LIB_FILE=${TK_LIB_FILE_TCL9}"
fi
eval "TK_LIB_FILE_TCL9=libtcl9tk${LIB_SUFFIX}"

# tkConfig.sh needs a version of the _LIB_SUFFIX that has been eval'ed
# since on some platforms TK_LIB_FILE contains shell escapes.

eval "TK_LIB_FILE=${TK_LIB_FILE}"

if test "${SHARED_BUILD}" = "1" -a "${SHLIB_SUFFIX}" != ""; then
Changes to unix/tcl.m4.
1075
1076
1077
1078
1079
1080
1081
1082

1083
1084
1085
1086
1087
1088
1089
1075
1076
1077
1078
1079
1080
1081

1082
1083
1084
1085
1086
1087
1088
1089







-
+







	    DL_LIBS="-ldl"
	    LDFLAGS="$LDFLAGS -export-dynamic"
	    CC_SEARCH_FLAGS=""
	    LD_SEARCH_FLAGS=""
	    ;;
	CYGWIN_*|MINGW32_*|MSYS_*)
	    SHLIB_CFLAGS="-fno-common"
	    SHLIB_LD='${CC} -shared'
	    SHLIB_LD='${CC} -shared -Wl,--out-implib,$(patsubst cyg%.dll,lib%.dll,$[@]).a'
	    SHLIB_SUFFIX=".dll"
	    DL_OBJS="tclLoadDl.o"
	    PLAT_OBJS='${CYGWIN_OBJS}'
	    PLAT_SRCS='${CYGWIN_SRCS}'
	    DL_LIBS="-ldl"
	    CC_SEARCH_FLAGS=""
	    LD_SEARCH_FLAGS=""
2083
2084
2085
2086
2087
2088
2089
2090

2091
2092
2093
2094
2095
2096
2097
2083
2084
2085
2086
2087
2088
2089

2090
2091
2092
2093
2094
2095
2096
2097







-
+







#
#--------------------------------------------------------------------

AC_DEFUN([SC_TIME_HANDLER], [
    AC_CHECK_HEADERS(sys/time.h)
    AC_CHECK_HEADERS_ONCE([sys/time.h])

    AC_CHECK_FUNCS(gmtime_r localtime_r mktime)
    AC_CHECK_FUNCS(gmtime_r localtime_r)

    AC_CACHE_CHECK([tm_tzadj in struct tm], tcl_cv_member_tm_tzadj, [
	AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <time.h>]], [[struct tm tm; (void)tm.tm_tzadj;]])],
	    [tcl_cv_member_tm_tzadj=yes],
	    [tcl_cv_member_tm_tzadj=no])])
    if test $tcl_cv_member_tm_tzadj = yes ; then
	AC_DEFINE(HAVE_TM_TZADJ, 1, [Should we use the tm_tzadj field of struct tm?])
Changes to unix/tkUnixSysTray.c.
910
911
912
913
914
915
916
917

918
919
920
921
922
923
924
910
911
912
913
914
915
916

917
918
919
920
921
922
923
924







-
+







			Tcl_GetString(icon->imageObj), IgnoreImageChange, NULL);
		Tcl_RestoreInterpState(icon->interp,saved);
	    }
	    if (icon->photo && !icon->offscreenImage) {
		icon->offscreenImage = XGetImage(Tk_Display(icon->drawingWin),
			icon->offscreenPixmap, 0, 0, w, h, AllPlanes, ZPixmap);
	    }
	    if (icon->offscreenGC == None) {
	    if (icon->offscreenGC == NULL) {
		XGCValues gcv;
		gcv.function = GXcopy;
		gcv.plane_mask = AllPlanes;
		gcv.foreground = 0;
		gcv.background = 0;
		icon->offscreenGC = Tk_GetGC(icon->drawingWin,
			GCFunction|GCPlaneMask|GCForeground|GCBackground, &gcv);
Changes to win/rules.vc.
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
877
878
879
880
881
882
883




884
885
886
887
888
889
890







-
-
-
-







USE_THREAD_ALLOC= 0
!endif

!if [nmakehlp -f $(OPTS) "tcl8"]
!message *** Build for Tcl8
TCL_BUILD_FOR = 8
!endif
!if [nmakehlp -f $(OPTS) "tk8"]
!message *** Build for Tk8
TK_BUILD_FOR = 8
!endif

!if $(TCL_MAJOR_VERSION) == 8
!if [nmakehlp -f $(OPTS) "time64bit"]
!message *** Force 64-bit time_t
_USE_64BIT_TIME_T = 1
!endif
!endif
1450
1451
1452
1453
1454
1455
1456
1457

1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1446
1447
1448
1449
1450
1451
1452

1453



1454
1455
1456
1457
1458
1459
1460







-
+
-
-
-








!if $(TCL_MAJOR_VERSION) == 8
!if "$(_USE_64BIT_TIME_T)" == "1"
OPTDEFINES	= $(OPTDEFINES) /D_USE_64BIT_TIME_T=1
!endif
!endif
!if "$(TCL_BUILD_FOR)" == "8"
OPTDEFINES	= $(OPTDEFINES) /DTCL_MAJOR_VERSION=8
OPTDEFINES	= $(OPTDEFINES) /DTCL_MAJOR_VERSION=8 /DTK_MAJOR_VERSION=8
!endif
!if "$(TK_BUILD_FOR)" == "8"
OPTDEFINES	= $(OPTDEFINES) /DTK_MAJOR_VERSION=8
!endif

# Like the TEA system only set this non empty for non-Tk extensions
# Note: some extensions use PACKAGE_NAME and others use PACKAGE_TCLNAME
# so we pass both
!if !$(DOING_TCL) && !$(DOING_TK)
PKGNAMEFLAGS = /DPACKAGE_NAME="\"$(PRJ_PACKAGE_TCLNAME)\"" \
1585
1586
1587
1588
1589
1590
1591
1592

1593
1594
1595
1596
1597
1598
1599
1578
1579
1580
1581
1582
1583
1584

1585
1586
1587
1588
1589
1590
1591
1592







-
+







ldebug= $(ldebug) -profile
!endif

### Declarations common to all linker versions
lflags	= -nologo -machine:$(MACHINE) $(LINKERFLAGS) $(ldebug)

!if $(MSVCRT) && !($(DEBUG) && !$(UNCHECKED)) && $(VCVERSION) >= 1900
lflags	= $(lflags) -nodefaultlib:libucrt.lib
lflags	= $(lflags) -nodefaultlib:ucrt.lib
!endif

dlllflags = $(lflags) -dll
conlflags = $(lflags) -subsystem:console
guilflags = $(lflags) -subsystem:windows

# Libraries that are required for every image.
Changes to win/tkWinWm.c.
299
300
301
302
303
304
305






306

307
308
309
310
311
312
313
299
300
301
302
303
304
305
306
307
308
309
310
311

312
313
314
315
316
317
318
319







+
+
+
+
+
+
-
+







#define EX_FULLSCREEN_STYLE (WS_EX_APPWINDOW)

#define WM_TOPLEVEL_STYLE (WS_OVERLAPPEDWINDOW|WS_CLIPCHILDREN|CS_DBLCLKS)
#define EX_TOPLEVEL_STYLE (0)

#define WM_TRANSIENT_STYLE \
		(WS_POPUP|WS_CAPTION|WS_SYSMENU|WS_CLIPSIBLINGS|CS_DBLCLKS)
/*
 * Bug 159aa5eb: Removed extended style WS_EX_DLGMODALFRAME. This style has
 * the undocumented side effect to enable the unwanted system menu items
 * "Resize", "Minimize" and "Maximize". "Resise" menu item may be correctly
 * enabled by "wm resizable".
 */
#define EX_TRANSIENT_STYLE (WS_EX_DLGMODALFRAME)
#define EX_TRANSIENT_STYLE (0)

/*
 * The following structure is the official type record for geometry management
 * of top-level windows.
 */

static void		TopLevelReqProc(void *dummy, Tk_Window tkwin);
5343
5344
5345
5346
5347
5348
5349
5350
5351

5352
5353
5354
5355
5356
5357
5358
5349
5350
5351
5352
5353
5354
5355


5356
5357
5358
5359
5360
5361
5362
5363







-
-
+







			winPtr->pathName));
		Tcl_SetErrorCode(interp, "TK", "WM", "STATE", "TRANSIENT",
			NULL);
		return TCL_ERROR;
	    }
	    TkpWmSetState(winPtr, IconicState);
	} else if (index == OPT_WITHDRAWN) {
	    wmPtr->flags |= WM_WITHDRAWN;
	    TkpWmSetState(winPtr, WithdrawnState);
	    TkpWinToplevelWithDraw(winPtr);
	} else if (index == OPT_ZOOMED) {
	    TkpWmSetState(winPtr, ZoomState);
	} else {
	    Tcl_Panic("wm state not matched");
	}
    } else {
	const char *stateStr = "";
5628
5629
5630
5631
5632
5633
5634
5635
5636

5637
5638
5639
5640
5641
5642
5643
5633
5634
5635
5636
5637
5638
5639


5640
5641
5642
5643
5644
5645
5646
5647







-
-
+







	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "can't withdraw %s: the container does not support the request",
		    Tcl_GetString(objv[2])));
	    Tcl_SetErrorCode(interp, "TK", "WM", "COMMUNICATION", NULL);
	    return TCL_ERROR;
	}
    } else {
	wmPtr->flags |= WM_WITHDRAWN;
	TkpWmSetState(winPtr, WithdrawnState);
	TkpWinToplevelWithDraw(winPtr);
    }
    return TCL_OK;
}

/*
 * Invoked by those wm subcommands that affect geometry. Schedules a geometry
 * update.
8336
8337
8338
8339
8340
8341
8342


8343






















8344
8345
8346
8347







8348
8349
8350
8351
8352
8353
8354
8340
8341
8342
8343
8344
8345
8346
8347
8348
8349
8350
8351
8352
8353
8354
8355
8356
8357
8358
8359
8360
8361
8362
8363
8364
8365
8366
8367
8368
8369
8370
8371
8372
8373


8374
8375
8376
8377
8378
8379
8380
8381
8382
8383
8384
8385
8386
8387







+
+

+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+


-
-
+
+
+
+
+
+
+







 */

void
TkpWinToplevelWithDraw(
    TkWindow *winPtr)
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    int resetTempStyle = 0;
    LONG exStyle = 0;

    /*
     * Special handling of transient toplevels (wmPtr->containerPtr != NULL),
     * in order to work around a Windows 10 & 11 problem where withdrawn
     * transients still appear in the thumbnail preview of the parent window,
     * when hovering over it in the Windows taskbar.  Temporarily setting this
     * window style to include WS_EX_TOOLWINDOW prevents it being captured in
     * the Windows thumbnail preview.
     * See ticket 91d0e9d8.
     */

    if (!(wmPtr->flags & WM_WITHDRAWN)
	     && !(wmPtr->flags & TK_EMBEDDED)
	     && !(wmPtr->flags & WM_NEVER_MAPPED)
	     && (wmPtr->containerPtr != NULL)) {
	exStyle = GetWindowLongPtrW(wmPtr->wrapper, GWL_EXSTYLE);
	if ( !(exStyle & WS_EX_TOOLWINDOW) ) {
	    SetWindowLongPtrW(wmPtr->wrapper, GWL_EXSTYLE,
		     exStyle | WS_EX_TOOLWINDOW);
	    resetTempStyle=1;
	}
    }

    wmPtr->flags |= WM_WITHDRAWN;
    TkpWmSetState(winPtr, WithdrawnState);
}


    if (resetTempStyle) {
	SetWindowLongPtrW(wmPtr->wrapper, GWL_EXSTYLE,
		exStyle & ~WS_EX_TOOLWINDOW);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TkpWinToplevelIconify --
 *
 *	This function is to be used by a window manager to iconify a toplevel
 *	window.