diff options
author | marc_culler <marc.culler@gmail.com> | 2020-10-20 20:30:41 (GMT) |
---|---|---|
committer | marc_culler <marc.culler@gmail.com> | 2020-10-20 20:30:41 (GMT) |
commit | 5b13ba033904738041f29eb71237d5de772f8cb5 (patch) | |
tree | 2e544116c87c76ed8588596163312bb48d393cd6 | |
parent | 0df4224575b6a68df0c2c85d97d30c1c9f4317cf (diff) | |
parent | 4746f7a4ce8af735167adf0718f799d6dcfac83e (diff) | |
download | tk-5b13ba033904738041f29eb71237d5de772f8cb5.zip tk-5b13ba033904738041f29eb71237d5de772f8cb5.tar.gz tk-5b13ba033904738041f29eb71237d5de772f8cb5.tar.bz2 |
Merge 8.6 and edit comments
-rw-r--r-- | macosx/tkMacOSXHLEvents.c | 7 | ||||
-rw-r--r-- | macosx/tkMacOSXInit.c | 81 | ||||
-rw-r--r-- | macosx/tkMacOSXPort.h | 8 | ||||
-rw-r--r-- | unix/tkAppInit.c | 8 |
4 files changed, 100 insertions, 4 deletions
diff --git a/macosx/tkMacOSXHLEvents.c b/macosx/tkMacOSXHLEvents.c index f1489dd..f405a53 100644 --- a/macosx/tkMacOSXHLEvents.c +++ b/macosx/tkMacOSXHLEvents.c @@ -596,9 +596,14 @@ ReallyKillMe( { Tcl_Interp *interp = ((KillEvent *) eventPtr)->interp; int quit = Tcl_FindCommand(interp, "::tk::mac::Quit", NULL, 0)!=NULL; - int code = Tcl_EvalEx(interp, quit ? "::tk::mac::Quit" : "exit", -1, TCL_EVAL_GLOBAL); + if (!quit) { + Tcl_Exit(0); + } + + int code = Tcl_EvalEx(interp, "::tk::mac::Quit", -1, TCL_EVAL_GLOBAL); if (code != TCL_OK) { + /* * Should be never reached... */ diff --git a/macosx/tkMacOSXInit.c b/macosx/tkMacOSXInit.c index d49422b..ca3dec4 100644 --- a/macosx/tkMacOSXInit.c +++ b/macosx/tkMacOSXInit.c @@ -113,6 +113,7 @@ static int TkMacOSXGetAppPathCmd(ClientData cd, Tcl_Interp *ip, /* * Initialize event processing. */ + TkMacOSXInitAppleEvents(_eventInterp); /* @@ -271,6 +272,65 @@ static int TkMacOSXGetAppPathCmd(ClientData cd, Tcl_Interp *ip, */ /* + * Helper function which closes the shared NSFontPanel and NSColorPanel. + */ + +static void closePanels( + void) +{ + if ([NSFontPanel sharedFontPanelExists]) { + [[NSFontPanel sharedFontPanel] orderOut:nil]; + } + if ([NSColorPanel sharedColorPanelExists]) { + [[NSColorPanel sharedColorPanel] orderOut:nil]; + } +} + +/* + * This custom exit procedure is called by Tcl_Exit in place of the exit + * function from the C runtime. It calls the terminate method of the + * NSApplication class (superTerminate for a TKApplication). The purpose of + * doing this is to ensure that the NSFontPanel and the NSColorPanel are closed + * before the process exits, and that the application state is recorded + * correctly for all termination scenarios. + * + * TkpWantsExitProc tells Tcl_AppInit whether to install our custom exit proc, + * which terminates the process by calling [NSApplication terminate]. This + * does not work correctly if the process is part of an exec pipeline, so it is + * only done if the process was launched by the launcher or if both stdin and + * stdout are ttys. To disable using the custom exit proc altogether, undefine + * USE_CUSTOM_EXIT_PROC. + */ + +#if defined(USE_CUSTOM_EXIT_PROC) +static Bool doCleanupFromExit = NO; + +int TkpWantsExitProc(void) { + return doCleanupFromExit == YES; +} + +TCL_NORETURN void TkpExitProc( + void *clientdata) +{ + Bool doCleanup = doCleanupFromExit; + if (doCleanupFromExit) { + doCleanupFromExit = NO; /* prevent possible recursive call. */ + closePanels(); + } + + /* + * Tcl_Exit does not call Tcl_Finalize if there is an exit proc installed. + */ + + Tcl_Finalize(); + if (doCleanup == YES) { + [(TKApplication *)NSApp superTerminate:nil]; /* Should not return. */ + } + exit((long)clientdata); /* Convince the compiler that we don't return. */ +} +#endif + +/* * This signal handler is installed for the SIGINT, SIGHUP and SIGTERM signals * so that normal finalization occurs when a Tk app is killed by one of these * signals (e.g when ^C is pressed while running Wish in the shell). It calls @@ -281,6 +341,8 @@ static int TkMacOSXGetAppPathCmd(ClientData cd, Tcl_Interp *ip, */ static void TkMacOSXSignalHandler(TCL_UNUSED(int)) { + (void)signal; + Tcl_Exit(1); } @@ -298,7 +360,6 @@ TkpInit( if (!initialized) { struct stat st; Bool shouldOpenConsole = NO; - Bool isLaunched = NO; Bool stdinIsNullish = (!isatty(0) && (fstat(0, &st) || (S_ISCHR(st.st_mode) && st.st_blocks == 0))); @@ -398,7 +459,11 @@ TkpInit( Tcl_SetVar2(interp, "tcl_interactive", NULL, "1", TCL_GLOBAL_ONLY); } - isLaunched = YES; + +#if defined(USE_CUSTOM_EXIT_PROC) + doCleanupFromExit = YES; +#endif + shouldOpenConsole = YES; } if (shouldOpenConsole) { @@ -421,7 +486,9 @@ TkpInit( FILE *null = fopen("/dev/null", "w"); dup2(fileno(null), STDOUT_FILENO); dup2(fileno(null), STDERR_FILENO); - isLaunched = YES; +#if defined(USE_CUSTOM_EXIT_PROC) + doCleanupFromExit = YES; +#endif } /* @@ -458,6 +525,14 @@ TkpInit( } } +# if defined(USE_CUSTOM_EXIT_PROC) + + if ((isatty(0) && isatty(1))) { + doCleanupFromExit = YES; + } + +# endif + /* * Install a signal handler for SIGINT, SIGHUP and SIGTERM which uses * Tcl_Exit instead of exit so that normal cleanup takes place if a TK diff --git a/macosx/tkMacOSXPort.h b/macosx/tkMacOSXPort.h index 61c0d0d..d875873 100644 --- a/macosx/tkMacOSXPort.h +++ b/macosx/tkMacOSXPort.h @@ -157,4 +157,12 @@ MODULE_SCOPE void TkMacOSXHandleMapOrUnmap(Tk_Window tkwin, XEvent *event); #define TkpHandleMapOrUnmap(tkwin, event) TkMacOSXHandleMapOrUnmap(tkwin, event) +/* + * Used by tkAppInit + */ + +#define USE_CUSTOM_EXIT_PROC +EXTERN int TkpWantsExitProc(void); +EXTERN TCL_NORETURN void TkpExitProc(void *); + #endif /* _TKMACPORT */ diff --git a/unix/tkAppInit.c b/unix/tkAppInit.c index 9e6c112..db44bb7 100644 --- a/unix/tkAppInit.c +++ b/unix/tkAppInit.c @@ -15,6 +15,7 @@ #undef BUILD_tk #undef STATIC_BUILD #include "tk.h" +#include "tkPort.h" #ifdef TK_TEST #ifdef __cplusplus @@ -120,6 +121,13 @@ Tcl_AppInit( } Tcl_StaticPackage(interp, "Tk", Tk_Init, Tk_SafeInit); +#if defined(USE_CUSTOM_EXIT_PROC) + if (TkpWantsExitProc()) { + /* The cast below avoids warnings from old gcc compilers. */ + Tcl_SetExitProc((void *)TkpExitProc); + } +#endif + #ifdef TK_TEST if (Tktest_Init(interp) == TCL_ERROR) { return TCL_ERROR; |