Skip to content

Commit be8318b

Browse files
authored
bpo-44828: Avoid tkinter file dialog failure on macOS 12 Monterey (pythonGH-29276)
when using the Tk 8.6.11 provided by python.org macOS installers. Patch by Marc Culler of the Tk project.
1 parent cdc7a58 commit be8318b

File tree

3 files changed

+206
-1
lines changed

3 files changed

+206
-1
lines changed
Lines changed: 202 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,202 @@
1+
--- tk8.6.11/macosx/tkMacOSXDialog.c 2020-12-31 01:46:07.000000000 +0000
2+
+++ tk8.6.11-patched/macosx/tkMacOSXDialog.c 2021-10-28 15:13:03.000000000 +0000
3+
@@ -221,7 +221,7 @@
4+
returnCode: (NSModalResponse) returnCode
5+
contextInfo: (void *) contextInfo
6+
{
7+
- FilePanelCallbackInfo *callbackInfo = contextInfo;
8+
+ FilePanelCallbackInfo *callbackInfo = (FilePanelCallbackInfo *)contextInfo;
9+
10+
if (returnCode == modalOK) {
11+
Tcl_Obj *resultObj;
12+
@@ -266,7 +266,7 @@
13+
- (void) tkAlertDidEnd: (NSAlert *) alert returnCode: (NSInteger) returnCode
14+
contextInfo: (void *) contextInfo
15+
{
16+
- AlertCallbackInfo *callbackInfo = contextInfo;
17+
+ AlertCallbackInfo *callbackInfo = (AlertCallbackInfo *)contextInfo;
18+
19+
if (returnCode >= NSAlertFirstButtonReturn) {
20+
Tcl_Obj *resultObj = Tcl_NewStringObj(alertButtonStrings[
21+
@@ -350,49 +350,41 @@
22+
FilePanelCallbackInfo *callbackInfo)
23+
{
24+
NSInteger modalReturnCode;
25+
+ int OSVersion = [NSApp macOSVersion];
26+
27+
- if (parent && ![parent attachedSheet]) {
28+
- [panel beginSheetModalForWindow:parent
29+
- completionHandler:^(NSModalResponse returnCode) {
30+
- [NSApp tkFilePanelDidEnd:panel
31+
- returnCode:returnCode
32+
- contextInfo:callbackInfo ];
33+
- }];
34+
-
35+
- /*
36+
- * The sheet has been prepared, so now we have to run it as a modal
37+
- * window. Using [NSApp runModalForWindow:] on macOS 10.15 or later
38+
- * generates warnings on stderr. But using [NSOpenPanel runModal] or
39+
- * [NSSavePanel runModal] on 10.14 or earler does not cause the
40+
- * completion handler to run when the panel is closed.
41+
- */
42+
+ /*
43+
+ * Use a sheet if -parent is specified (unless there is already a sheet).
44+
+ */
45+
46+
- if ([NSApp macOSVersion] > 101400) {
47+
- modalReturnCode = [panel runModal];
48+
- } else {
49+
+ if (parent && ![parent attachedSheet]) {
50+
+ if (OSVersion < 101500) {
51+
+ [panel beginSheetModalForWindow:parent
52+
+ completionHandler:^(NSModalResponse returnCode) {
53+
+ [NSApp tkFilePanelDidEnd:panel
54+
+ returnCode:returnCode
55+
+ contextInfo:callbackInfo ];
56+
+ }];
57+
modalReturnCode = [NSApp runModalForWindow:panel];
58+
- }
59+
- } else {
60+
-
61+
- /*
62+
- * For the standalone file dialog, completion handlers do not work
63+
- * at all on macOS 10.14 and earlier.
64+
- */
65+
-
66+
- if ([NSApp macOSVersion] > 101400) {
67+
- [panel beginWithCompletionHandler:^(NSModalResponse returnCode) {
68+
+ } else if (OSVersion < 110000) {
69+
+ [panel beginSheetModalForWindow:parent
70+
+ completionHandler:^(NSModalResponse returnCode) {
71+
[NSApp tkFilePanelDidEnd:panel
72+
- returnCode:returnCode
73+
- contextInfo:callbackInfo ];
74+
- }];
75+
+ returnCode:returnCode
76+
+ contextInfo:callbackInfo ];
77+
+ }];
78+
modalReturnCode = [panel runModal];
79+
} else {
80+
+ [parent beginSheet: panel completionHandler:nil];
81+
modalReturnCode = [panel runModal];
82+
[NSApp tkFilePanelDidEnd:panel
83+
- returnCode:modalReturnCode
84+
- contextInfo:callbackInfo ];
85+
- [panel close];
86+
+ returnCode:modalReturnCode
87+
+ contextInfo:callbackInfo ];
88+
}
89+
+ } else {
90+
+ modalReturnCode = [panel runModal];
91+
+ [NSApp tkFilePanelDidEnd:panel
92+
+ returnCode:modalReturnCode
93+
+ contextInfo:callbackInfo ];
94+
}
95+
return callbackInfo->cmdObj ? modalOther : modalReturnCode;
96+
}
97+
@@ -422,7 +414,7 @@
98+
Tcl_Obj *const objv[]) /* Argument objects. */
99+
{
100+
int result = TCL_ERROR;
101+
- Tk_Window parent, tkwin = clientData;
102+
+ Tk_Window parent, tkwin = (Tk_Window)clientData;
103+
const char *title = NULL;
104+
int i;
105+
NSColor *color = nil, *initialColor = nil;
106+
@@ -677,7 +669,7 @@
107+
int objc, /* Number of arguments. */
108+
Tcl_Obj *const objv[]) /* Argument objects. */
109+
{
110+
- Tk_Window tkwin = clientData;
111+
+ Tk_Window tkwin = (Tk_Window)clientData;
112+
char *str;
113+
int i, result = TCL_ERROR, haveParentOption = 0;
114+
int index, len, multiple = 0;
115+
@@ -1679,10 +1671,10 @@
116+
if (!fontchooserInterp) {
117+
return;
118+
}
119+
- fcdPtr = Tcl_GetAssocData(fontchooserInterp, "::tk::fontchooser", NULL);
120+
+ fcdPtr = (FontchooserData *)Tcl_GetAssocData(fontchooserInterp, "::tk::fontchooser", NULL);
121+
switch (kind) {
122+
case FontchooserClosed:
123+
- if (fcdPtr->parent != None) {
124+
+ if (fcdPtr->parent != NULL) {
125+
TkSendVirtualEvent(fcdPtr->parent, "TkFontchooserVisibility", NULL);
126+
fontchooserInterp = NULL;
127+
}
128+
@@ -1738,7 +1730,7 @@
129+
130+
switch(optionIndex) {
131+
case FontchooserParent:
132+
- if (fcdPtr->parent != None) {
133+
+ if (fcdPtr->parent != NULL) {
134+
resObj = Tcl_NewStringObj(
135+
((TkWindow *)fcdPtr->parent)->pathName, -1);
136+
} else {
137+
@@ -1801,7 +1793,7 @@
138+
Tcl_Obj *const objv[])
139+
{
140+
Tk_Window tkwin = (Tk_Window)clientData;
141+
- FontchooserData *fcdPtr = Tcl_GetAssocData(interp, "::tk::fontchooser",
142+
+ FontchooserData *fcdPtr = (FontchooserData *)Tcl_GetAssocData(interp, "::tk::fontchooser",
143+
NULL);
144+
int i, r = TCL_OK;
145+
146+
@@ -1858,7 +1850,7 @@
147+
Tk_Window parent = Tk_NameToWindow(interp,
148+
Tcl_GetString(objv[i+1]), tkwin);
149+
150+
- if (parent == None) {
151+
+ if (parent == NULL) {
152+
return TCL_ERROR;
153+
}
154+
if (fcdPtr->parent) {
155+
@@ -1885,7 +1877,7 @@
156+
fcdPtr->titleObj = NULL;
157+
}
158+
break;
159+
- case FontchooserFont:
160+
+ case FontchooserFont: {
161+
Tcl_GetStringFromObj(objv[i+1], &len);
162+
if (len) {
163+
Tk_Font f = Tk_AllocFontFromObj(interp, tkwin, objv[i+1]);
164+
@@ -1919,6 +1911,7 @@
165+
"TkFontchooserFontChanged", NULL);
166+
}
167+
break;
168+
+ }
169+
case FontchooserCmd:
170+
if (fcdPtr->cmdObj) {
171+
Tcl_DecrRefCount(fcdPtr->cmdObj);
172+
@@ -1964,10 +1957,10 @@
173+
TCL_UNUSED(int),
174+
TCL_UNUSED(Tcl_Obj *const *))
175+
{
176+
- FontchooserData *fcdPtr = Tcl_GetAssocData(interp, "::tk::fontchooser",
177+
+ FontchooserData *fcdPtr = (FontchooserData *)Tcl_GetAssocData(interp, "::tk::fontchooser",
178+
NULL);
179+
180+
- if (fcdPtr->parent == None) {
181+
+ if (fcdPtr->parent == NULL) {
182+
fcdPtr->parent = (Tk_Window)clientData;
183+
Tk_CreateEventHandler(fcdPtr->parent, StructureNotifyMask,
184+
FontchooserParentEventHandler, fcdPtr);
185+
@@ -2042,7 +2035,7 @@
186+
ClientData clientData,
187+
XEvent *eventPtr)
188+
{
189+
- FontchooserData *fcdPtr = clientData;
190+
+ FontchooserData *fcdPtr = (FontchooserData *)clientData;
191+
192+
if (eventPtr->type == DestroyNotify) {
193+
Tk_DeleteEventHandler(fcdPtr->parent, StructureNotifyMask,
194+
@@ -2074,7 +2067,7 @@
195+
ClientData clientData,
196+
Tcl_Interp *interp)
197+
{
198+
- FontchooserData *fcdPtr = clientData;
199+
+ FontchooserData *fcdPtr = (FontchooserData *)clientData;
200+
201+
if (fcdPtr->titleObj) {
202+
Tcl_DecrRefCount(fcdPtr->titleObj);

Mac/BuildScript/build-installer.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -269,7 +269,7 @@ def library_recipes():
269269
tcl_checksum='8a4c004f48984a03a7747e9ba06e4da4'
270270

271271
tk_checksum='c7ee71a2d05bba78dfffd76528dc17c6'
272-
tk_patches = [ ]
272+
tk_patches = ['bpo-44828-filedialog-crash-monterey.patch']
273273

274274

275275
result.extend([
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Avoid tkinter file dialog failure on macOS 12 Monterey when using the Tk
2+
8.6.11 provided by python.org macOS installers. Patch by Marc Culler of the
3+
Tk project.

0 commit comments

Comments
 (0)