From f033d01527852268435dd8ab24ce875b4b0e5828 Mon Sep 17 00:00:00 2001 From: Christopher Chavez Date: Sat, 2 Sep 2023 03:53:36 -0500 Subject: [PATCH] gh-71383: add upstream fix Adapted from https://core.tcl-lang.org/tk/info/b1876b9ebc4b --- generic/tkInt.h | 3 ++- generic/tkWindow.c | 1 + generic/ttk/ttkTheme.c | 26 +++++++++++++++++++------- 3 files changed, 22 insertions(+), 8 deletions(-) diff --git a/generic/tkInt.h b/generic/tkInt.h index 35b7e67380..7568585fad 100644 --- a/generic/tkInt.h +++ b/generic/tkInt.h @@ -1092,10 +1092,11 @@ extern "C" { #endif /* - * Themed widget set init function: + * Themed widget set init function, and handler called when Tk is destroyed. */ 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 diff --git a/generic/tkWindow.c b/generic/tkWindow.c index fa2555354d..59c12433dd 100644 --- a/generic/tkWindow.c +++ b/generic/tkWindow.c @@ -1621,6 +1621,7 @@ Tk_DestroyWindow( TkFontPkgFree(winPtr->mainPtr); TkFocusFree(winPtr->mainPtr); TkStylePkgFree(winPtr->mainPtr); + Ttk_TkDestroyedHandler(winPtr->mainPtr->interp); /* * When embedding Tk into other applications, make sure that all diff --git a/generic/ttk/ttkTheme.c b/generic/ttk/ttkTheme.c index 711c4107f8..09c7b15ebe 100644 --- a/generic/ttk/ttkTheme.c +++ b/generic/ttk/ttkTheme.c @@ -417,13 +417,6 @@ static void Ttk_StylePkgFree( Tcl_HashEntry *entryPtr; Cleanup *cleanup; - /* - * Cancel any pending ThemeChanged calls: - */ - if (pkgPtr->themeChangePending) { - Tcl_CancelIdleCall(ThemeChangedProc, pkgPtr); - } - /* * Free themes. */ @@ -531,6 +524,25 @@ static void ThemeChanged(StylePackageData *pkgPtr) } } +/* 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.