From 77257c0f79171da4fd01a11664615679bf3ea959 Mon Sep 17 00:00:00 2001 From: culler Date: Wed, 27 Oct 2021 15:01:09 +0000 Subject: The standalone file dialog needs the same fix as the sheet --- macosx/tkMacOSXDialog.c | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/macosx/tkMacOSXDialog.c b/macosx/tkMacOSXDialog.c index 08998bc..717c17d 100644 --- a/macosx/tkMacOSXDialog.c +++ b/macosx/tkMacOSXDialog.c @@ -350,9 +350,9 @@ static NSInteger showOpenSavePanel( FilePanelCallbackInfo *callbackInfo) { NSInteger modalReturnCode; + int osVersion = [NSApp macOSVersion]; if (parent && ![parent attachedSheet]) { - int osVersion = [NSApp macOSVersion]; [panel beginSheetModalForWindow:parent completionHandler:^(NSModalResponse returnCode) { [NSApp tkFilePanelDidEnd:panel @@ -385,20 +385,15 @@ static NSInteger showOpenSavePanel( * at all on macOS 10.14 and earlier. */ - if ([NSApp macOSVersion] > 101400) { - [panel beginWithCompletionHandler:^(NSModalResponse returnCode) { - [NSApp tkFilePanelDidEnd:panel - returnCode:returnCode - contextInfo:callbackInfo ]; - }]; + if ( osVersion > 101400 && osVersion < 120000) { modalReturnCode = [panel runModal]; } else { - modalReturnCode = [panel runModal]; - [NSApp tkFilePanelDidEnd:panel - returnCode:modalReturnCode - contextInfo:callbackInfo ]; - [panel close]; + modalReturnCode = [NSApp runModalForWindow:panel]; } + [NSApp tkFilePanelDidEnd:panel + returnCode:modalReturnCode + contextInfo:callbackInfo ]; + [panel close]; } return callbackInfo->cmdObj ? modalOther : modalReturnCode; } -- cgit v0.12 From bc47200f0cf1837c15042210beffdb5f7912301e Mon Sep 17 00:00:00 2001 From: culler Date: Wed, 27 Oct 2021 18:17:21 +0000 Subject: Some cleanup without resolving other (minor) 12.0 bugs --- macosx/tkMacOSXDialog.c | 43 +++++++++++++++++++++++++------------------ 1 file changed, 25 insertions(+), 18 deletions(-) diff --git a/macosx/tkMacOSXDialog.c b/macosx/tkMacOSXDialog.c index 717c17d..2ba35e0 100644 --- a/macosx/tkMacOSXDialog.c +++ b/macosx/tkMacOSXDialog.c @@ -362,7 +362,7 @@ static NSInteger showOpenSavePanel( /* * The sheet has been prepared, so now we have to run it as a modal - * window. Using [NSApp runModalForWindow:] on macOS 10.15 or later + * window. Using [NSApp runModalForWindow:] on macOS 10.15 or 11.0 * generates warnings on stderr. But using [NSOpenPanel runModal] or * [NSSavePanel runModal] on 10.14 or earler does not cause the * completion handler to run when the panel is closed. Apple apparently @@ -370,7 +370,12 @@ static NSInteger showOpenSavePanel( * macOS 12.0. The warnings do not appear in that OS, and using * runModal produces an error dialog that says "The open file operation * failed to connect to the open and save panel service." along with an - * assertion error. + * assertion error. Unfortunately, 10.12 introduced other bugs. When + * displaying the panel as a sheet it is first shown as a separate + * window for an instant and then attached to the parent as a sheet. + * Also, the filename input field is not focused when the dialog opens, + * either as a sheet or a separate window. No workaround is currently + * known for these. */ if ( osVersion > 101400 && osVersion < 120000) { @@ -393,7 +398,6 @@ static NSInteger showOpenSavePanel( [NSApp tkFilePanelDidEnd:panel returnCode:modalReturnCode contextInfo:callbackInfo ]; - [panel close]; } return callbackInfo->cmdObj ? modalOther : modalReturnCode; } @@ -688,10 +692,11 @@ Tk_GetOpenFileObjCmd( NSString *directory = nil, *filename = nil; NSString *message = nil, *title = nil; NSWindow *parent; - openpanel = [NSOpenPanel openPanel]; NSInteger modalReturnCode = modalError; BOOL parentIsKey = NO; + openpanel = [NSOpenPanel openPanel]; + for (i = 1; i < objc; i += 2) { if (Tcl_GetIndexFromObjStruct(interp, objv[i], openOptionStrings, sizeof(char *), "option", TCL_EXACT, &index) != TCL_OK) { @@ -754,7 +759,6 @@ Tk_GetOpenFileObjCmd( } } if (title) { - [openpanel setTitle:title]; /* * From OSX 10.11, the title string is silently ignored in the open @@ -771,6 +775,8 @@ Tk_GetOpenFileObjCmd( } else { message = title; } + } else { + [openpanel setTitle:title]; } } @@ -961,10 +967,10 @@ Tk_GetSaveFileObjCmd( NSString *directory = nil, *filename = nil, *defaultType = nil; NSString *message = nil, *title = nil; NSWindow *parent; - savepanel = [NSSavePanel savePanel]; NSInteger modalReturnCode = modalError; BOOL parentIsKey = NO; + savepanel = [NSSavePanel savePanel]; for (i = 1; i < objc; i += 2) { if (Tcl_GetIndexFromObjStruct(interp, objv[i], saveOptionStrings, sizeof(char *), "option", TCL_EXACT, &index) != TCL_OK) { @@ -1037,25 +1043,26 @@ Tk_GetSaveFileObjCmd( } if (title) { - [savepanel setTitle:title]; /* * From OSX 10.11, the title string is silently ignored, if the save * panel is a sheet. Prepend the title to the message in this case. - * NOTE: should be conditional on OSX version, but -mmacosx-version-min - * does not revert this behaviour. */ - if (haveParentOption) { - if (message) { - NSString *fullmessage = - [[NSString alloc] initWithFormat:@"%@\n%@",title,message]; - [message release]; - [title release]; - message = fullmessage; - } else { - message = title; + if ([NSApp macOSVersion] > 101000) { + if (haveParentOption) { + if (message) { + NSString *fullmessage = + [[NSString alloc] initWithFormat:@"%@\n%@",title,message]; + [message release]; + [title release]; + message = fullmessage; + } else { + message = title; + } } + } else { + [savepanel setTitle:title]; } } -- cgit v0.12 From e8b212de5ca61695a8ce7172649b90d9eb80defa Mon Sep 17 00:00:00 2001 From: culler Date: Wed, 27 Oct 2021 22:09:06 +0000 Subject: The real fix, at least for Big Sur and Monterey. --- macosx/tkMacOSXDialog.c | 61 ++++++++++++++++--------------------------------- 1 file changed, 20 insertions(+), 41 deletions(-) diff --git a/macosx/tkMacOSXDialog.c b/macosx/tkMacOSXDialog.c index 2ba35e0..09adaad 100644 --- a/macosx/tkMacOSXDialog.c +++ b/macosx/tkMacOSXDialog.c @@ -353,52 +353,28 @@ static NSInteger showOpenSavePanel( int osVersion = [NSApp macOSVersion]; if (parent && ![parent attachedSheet]) { - [panel beginSheetModalForWindow:parent - completionHandler:^(NSModalResponse returnCode) { - [NSApp tkFilePanelDidEnd:panel - returnCode:returnCode - contextInfo:callbackInfo ]; - }]; /* - * The sheet has been prepared, so now we have to run it as a modal - * window. Using [NSApp runModalForWindow:] on macOS 10.15 or 11.0 - * generates warnings on stderr. But using [NSOpenPanel runModal] or - * [NSSavePanel runModal] on 10.14 or earler does not cause the - * completion handler to run when the panel is closed. Apple apparently - * decided to go back to using runModalForWindow with the release of - * macOS 12.0. The warnings do not appear in that OS, and using - * runModal produces an error dialog that says "The open file operation - * failed to connect to the open and save panel service." along with an - * assertion error. Unfortunately, 10.12 introduced other bugs. When - * displaying the panel as a sheet it is first shown as a separate - * window for an instant and then attached to the parent as a sheet. - * Also, the filename input field is not focused when the dialog opens, - * either as a sheet or a separate window. No workaround is currently - * known for these. + * On most version of macOS the completion handler does not get + * run at all. So we ignore it. */ + + [parent beginSheet: panel completionHandler:nil]; - if ( osVersion > 101400 && osVersion < 120000) { - modalReturnCode = [panel runModal]; - } else { - modalReturnCode = [NSApp runModalForWindow:panel]; - } + } + /* + * On macOS 10.15 and higher, calling runModalForWindow generates + * warnings on stderr. + */ + + if ( osVersion > 101400) { + modalReturnCode = [panel runModal]; } else { - - /* - * For the standalone file dialog, completion handlers do not work - * at all on macOS 10.14 and earlier. - */ - - if ( osVersion > 101400 && osVersion < 120000) { - modalReturnCode = [panel runModal]; - } else { - modalReturnCode = [NSApp runModalForWindow:panel]; - } - [NSApp tkFilePanelDidEnd:panel - returnCode:modalReturnCode - contextInfo:callbackInfo ]; + modalReturnCode = [NSApp runModalForWindow:panel]; } + [NSApp tkFilePanelDidEnd:panel + returnCode:modalReturnCode + contextInfo:callbackInfo ]; return callbackInfo->cmdObj ? modalOther : modalReturnCode; } @@ -970,7 +946,10 @@ Tk_GetSaveFileObjCmd( NSInteger modalReturnCode = modalError; BOOL parentIsKey = NO; - savepanel = [NSSavePanel savePanel]; + if (savepanel == nil) { + savepanel = [NSSavePanel savePanel]; + [savepanel setDelegate:NSApp]; + } for (i = 1; i < objc; i += 2) { if (Tcl_GetIndexFromObjStruct(interp, objv[i], saveOptionStrings, sizeof(char *), "option", TCL_EXACT, &index) != TCL_OK) { -- cgit v0.12 From b073b90aa63190350a96903dcac16bbc701c4204 Mon Sep 17 00:00:00 2001 From: marc_culler Date: Wed, 27 Oct 2021 22:54:37 +0000 Subject: Catalina is a special case. --- macosx/tkMacOSXDialog.c | 26 +++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/macosx/tkMacOSXDialog.c b/macosx/tkMacOSXDialog.c index 09adaad..afb57fb 100644 --- a/macosx/tkMacOSXDialog.c +++ b/macosx/tkMacOSXDialog.c @@ -355,11 +355,20 @@ static NSInteger showOpenSavePanel( if (parent && ![parent attachedSheet]) { /* - * On most version of macOS the completion handler does not get - * run at all. So we ignore it. + * A completion handler is not needed except on macOS 10.15, where we + * have to start the sheet differently. */ - - [parent beginSheet: panel completionHandler:nil]; + + if (osVersion >= 101500 && osVersion < 110000 ) { + [panel beginSheetModalForWindow:parent + completionHandler:^(NSModalResponse returnCode) { + [NSApp tkFilePanelDidEnd:panel + returnCode:returnCode + contextInfo:callbackInfo ]; + }]; + } else { + [parent beginSheet: panel completionHandler:nil]; + } } /* @@ -372,9 +381,12 @@ static NSInteger showOpenSavePanel( } else { modalReturnCode = [NSApp runModalForWindow:panel]; } - [NSApp tkFilePanelDidEnd:panel - returnCode:modalReturnCode - contextInfo:callbackInfo ]; + + if (osVersion < 101500 || osVersion >= 110000 ) { + [NSApp tkFilePanelDidEnd:panel + returnCode:modalReturnCode + contextInfo:callbackInfo ]; + } return callbackInfo->cmdObj ? modalOther : modalReturnCode; } -- cgit v0.12 From 554073edbdc9a4d3ac707404b7b78f76eb5e46ba Mon Sep 17 00:00:00 2001 From: culler Date: Thu, 28 Oct 2021 13:33:03 +0000 Subject: One more round - thanks to Ned Deily for testing with IDLE. --- macosx/tkMacOSXDialog.c | 77 ++++++++++++++++++++++--------------------------- 1 file changed, 35 insertions(+), 42 deletions(-) diff --git a/macosx/tkMacOSXDialog.c b/macosx/tkMacOSXDialog.c index afb57fb..b6f4503 100644 --- a/macosx/tkMacOSXDialog.c +++ b/macosx/tkMacOSXDialog.c @@ -350,39 +350,38 @@ static NSInteger showOpenSavePanel( FilePanelCallbackInfo *callbackInfo) { NSInteger modalReturnCode; - int osVersion = [NSApp macOSVersion]; + int OSVersion = [NSApp macOSVersion]; - if (parent && ![parent attachedSheet]) { - - /* - * A completion handler is not needed except on macOS 10.15, where we - * have to start the sheet differently. - */ + /* + * Use a sheet if -parent is specified (unless there is already a sheet). + */ - if (osVersion >= 101500 && osVersion < 110000 ) { + if (parent && ![parent attachedSheet]) { + if (OSVersion < 101500) { [panel beginSheetModalForWindow:parent completionHandler:^(NSModalResponse returnCode) { [NSApp tkFilePanelDidEnd:panel returnCode:returnCode contextInfo:callbackInfo ]; }]; + modalReturnCode = [NSApp runModalForWindow:panel]; + } else if (OSVersion < 110000) { + [panel beginSheetModalForWindow:parent + completionHandler:^(NSModalResponse returnCode) { + [NSApp tkFilePanelDidEnd:panel + returnCode:returnCode + contextInfo:callbackInfo ]; + }]; + modalReturnCode = [panel runModal]; } else { [parent beginSheet: panel completionHandler:nil]; + modalReturnCode = [panel runModal]; + [NSApp tkFilePanelDidEnd:panel + returnCode:modalReturnCode + contextInfo:callbackInfo ]; } - - } - /* - * On macOS 10.15 and higher, calling runModalForWindow generates - * warnings on stderr. - */ - - if ( osVersion > 101400) { - modalReturnCode = [panel runModal]; } else { - modalReturnCode = [NSApp runModalForWindow:panel]; - } - - if (osVersion < 101500 || osVersion >= 110000 ) { + modalReturnCode = [panel runModal]; [NSApp tkFilePanelDidEnd:panel returnCode:modalReturnCode contextInfo:callbackInfo ]; @@ -680,11 +679,10 @@ Tk_GetOpenFileObjCmd( NSString *directory = nil, *filename = nil; NSString *message = nil, *title = nil; NSWindow *parent; + openpanel = [NSOpenPanel openPanel]; NSInteger modalReturnCode = modalError; BOOL parentIsKey = NO; - openpanel = [NSOpenPanel openPanel]; - for (i = 1; i < objc; i += 2) { if (Tcl_GetIndexFromObjStruct(interp, objv[i], openOptionStrings, sizeof(char *), "option", TCL_EXACT, &index) != TCL_OK) { @@ -747,6 +745,7 @@ Tk_GetOpenFileObjCmd( } } if (title) { + [openpanel setTitle:title]; /* * From OSX 10.11, the title string is silently ignored in the open @@ -763,8 +762,6 @@ Tk_GetOpenFileObjCmd( } else { message = title; } - } else { - [openpanel setTitle:title]; } } @@ -955,13 +952,10 @@ Tk_GetSaveFileObjCmd( NSString *directory = nil, *filename = nil, *defaultType = nil; NSString *message = nil, *title = nil; NSWindow *parent; + savepanel = [NSSavePanel savePanel]; NSInteger modalReturnCode = modalError; BOOL parentIsKey = NO; - if (savepanel == nil) { - savepanel = [NSSavePanel savePanel]; - [savepanel setDelegate:NSApp]; - } for (i = 1; i < objc; i += 2) { if (Tcl_GetIndexFromObjStruct(interp, objv[i], saveOptionStrings, sizeof(char *), "option", TCL_EXACT, &index) != TCL_OK) { @@ -1034,26 +1028,25 @@ Tk_GetSaveFileObjCmd( } if (title) { + [savepanel setTitle:title]; /* * From OSX 10.11, the title string is silently ignored, if the save * panel is a sheet. Prepend the title to the message in this case. + * NOTE: should be conditional on OSX version, but -mmacosx-version-min + * does not revert this behaviour. */ - if ([NSApp macOSVersion] > 101000) { - if (haveParentOption) { - if (message) { - NSString *fullmessage = - [[NSString alloc] initWithFormat:@"%@\n%@",title,message]; - [message release]; - [title release]; - message = fullmessage; - } else { - message = title; - } + if (haveParentOption) { + if (message) { + NSString *fullmessage = + [[NSString alloc] initWithFormat:@"%@\n%@",title,message]; + [message release]; + [title release]; + message = fullmessage; + } else { + message = title; } - } else { - [savepanel setTitle:title]; } } -- cgit v0.12