Index: generic/tkInt.h
==================================================================
--- generic/tkInt.h
+++ generic/tkInt.h
@@ -1090,14 +1090,15 @@
 #ifdef __cplusplus
 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
  * world:
  */

Index: generic/tkWindow.c
==================================================================
--- generic/tkWindow.c
+++ 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
==================================================================
--- generic/ttk/ttkTheme.c
+++ generic/ttk/ttkTheme.c
@@ -401,12 +401,10 @@
     Cleanup *cleanupList;		/* Cleanup records */
     Ttk_ResourceCache cache;		/* Resource cache */
     int themeChangePending;		/* scheduled ThemeChangedProc call? */
 } StylePackageData;
 
-static void ThemeChangedProc(void *);	/* Forward */
-
 /* Ttk_StylePkgFree --
  *	Cleanup procedure for StylePackageData.
  */
 static void Ttk_StylePkgFree(
     ClientData clientData,
@@ -415,17 +413,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) {
@@ -484,11 +475,11 @@
  *
  */
 void Ttk_RegisterCleanup(
     Tcl_Interp *interp, ClientData clientData, Ttk_CleanupProc *cleanupProc)
 {
-    StylePackageData *pkgPtr = (StylePackageData *)GetStylePackageData(interp);
+    StylePackageData *pkgPtr = GetStylePackageData(interp);
     Cleanup *cleanup = (Cleanup *)ckalloc(sizeof(*cleanup));
 
     cleanup->clientData = clientData;
     cleanup->cleanupProc = cleanupProc;
     cleanup->next = pkgPtr->cleanupList;
@@ -528,10 +519,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.
  *