| Adapted from https://core.tcl-lang.org/tk/info/b1876b9ebc4b |
| |
| Index: generic/tkInt.h |
| ================================================================== |
| --- a/generic/tkInt.h.orig |
| +++ b/generic/tkInt.h |
| @@ -1094,10 +1094,11 @@ |
| /* |
| * Themed widget set init function: |
| */ |
| |
| MODULE_SCOPE int Ttk_Init(Tcl_Interp *interp); |
| +MODULE_SCOPE void Ttk_TkDestroyedHandler(Tcl_Interp *interp); |
| |
| /* |
| * Internal functions shared among Tk modules but not exported to the outside |
| * world: |
| */ |
| |
| Index: generic/tkWindow.c |
| ================================================================== |
| --- a/generic/tkWindow.c.orig |
| +++ b/generic/tkWindow.c |
| @@ -1619,10 +1619,11 @@ |
| TkBindFree(winPtr->mainPtr); |
| TkDeleteAllImages(winPtr->mainPtr); |
| TkFontPkgFree(winPtr->mainPtr); |
| TkFocusFree(winPtr->mainPtr); |
| TkStylePkgFree(winPtr->mainPtr); |
| + Ttk_TkDestroyedHandler(winPtr->mainPtr->interp); |
| |
| /* |
| * When embedding Tk into other applications, make sure that all |
| * destroy events reach the server. Otherwise the embedding |
| * application may also attempt to destroy the windows, resulting |
| |
| Index: generic/ttk/ttkTheme.c |
| ================================================================== |
| --- a/generic/ttk/ttkTheme.c.orig |
| +++ b/generic/ttk/ttkTheme.c |
| @@ -415,17 +415,10 @@ |
| StylePackageData *pkgPtr = (StylePackageData *)clientData; |
| Tcl_HashSearch search; |
| Tcl_HashEntry *entryPtr; |
| Cleanup *cleanup; |
| |
| - /* |
| - * Cancel any pending ThemeChanged calls: |
| - */ |
| - if (pkgPtr->themeChangePending) { |
| - Tcl_CancelIdleCall(ThemeChangedProc, pkgPtr); |
| - } |
| - |
| /* |
| * Free themes. |
| */ |
| entryPtr = Tcl_FirstHashEntry(&pkgPtr->themeTable, &search); |
| while (entryPtr != NULL) { |
| @@ -528,10 +521,29 @@ |
| if (!pkgPtr->themeChangePending) { |
| Tcl_DoWhenIdle(ThemeChangedProc, pkgPtr); |
| pkgPtr->themeChangePending = 1; |
| } |
| } |
| + |
| +/* Ttk_TkDestroyedHandler -- |
| + * See bug [310c74ecf440]: idle calls to ThemeChangedProc() |
| + * need to be canceled when Tk is destroyed, since the interp |
| + * may still be active afterward; canceling them from |
| + * Ttk_StylePkgFree() would be too late. |
| + */ |
| +void Ttk_TkDestroyedHandler( |
| + Tcl_Interp* interp) |
| +{ |
| + StylePackageData* pkgPtr = GetStylePackageData(interp); |
| + |
| + /* |
| + * Cancel any pending ThemeChanged calls: |
| + */ |
| + if (pkgPtr->themeChangePending) { |
| + Tcl_CancelIdleCall(ThemeChangedProc, pkgPtr); |
| + } |
| +} |
| |
| /* |
| * Ttk_CreateTheme -- |
| * Create a new theme and register it in the global theme table. |
| * |
| |