@@ -54,6 +54,10 @@ Copyright (C) 1994 Steen Lumholt.
5454# include <tk.h>
5555#endif
5656
57+ #if defined(MS_WINDOWS ) && TK_MAJOR_VERSION >= 9
58+ # include <tkPlatDecls.h>
59+ #endif
60+
5761#include "tkinter.h"
5862
5963#if TK_HEX_VERSION < 0x0805020c
@@ -199,6 +203,57 @@ _get_tcl_lib_path(void)
199203}
200204#endif /* MS_WINDOWS */
201205
206+ #if defined(MS_WINDOWS ) && TK_MAJOR_VERSION >= 9
207+ static void
208+ mount_tk_dll_zip (void )
209+ {
210+ HINSTANCE tk_module = Tk_GetHINSTANCE ();
211+ wchar_t * tk_path = NULL ;
212+ DWORD path_len = 0 ;
213+ for (DWORD buffer_len = 256 ;
214+ tk_path == NULL && buffer_len < (1024 * 1024 );
215+ buffer_len *= 2 )
216+ {
217+ tk_path = (wchar_t * )PyMem_RawMalloc (
218+ buffer_len * sizeof (* tk_path ));
219+ if (tk_path != NULL ) {
220+ path_len = GetModuleFileNameW (tk_module , tk_path , buffer_len );
221+ if (path_len == buffer_len ) {
222+ PyMem_RawFree (tk_path );
223+ tk_path = NULL ;
224+ }
225+ }
226+ }
227+
228+ if (tk_path == NULL || path_len == 0 ) {
229+ PyMem_RawFree (tk_path );
230+ return ;
231+ }
232+
233+ Tcl_DString utf8_path ;
234+
235+ Tcl_DStringInit (& utf8_path );
236+ Tcl_WCharToUtfDString (tk_path , path_len , & utf8_path );
237+ /* Failure is harmless if the DLL has no embedded ZIP or if another
238+ interpreter has already mounted it. */
239+ (void ) TclZipfs_Mount (NULL , Tcl_DStringValue (& utf8_path ),
240+ "//zipfs:/lib/tk" , NULL );
241+ Tcl_DStringFree (& utf8_path );
242+ PyMem_RawFree (tk_path );
243+ }
244+ #endif
245+
246+ int
247+ Tkinter_TkInit (Tcl_Interp * interp )
248+ {
249+ #if defined(MS_WINDOWS ) && TK_MAJOR_VERSION >= 9
250+ /* Tcl/Tk 9 may embed the tk_library in the Tk DLL which tcl_findLibrary
251+ does not search. Mount the DLL using Zipfs if possible. */
252+ mount_tk_dll_zip ();
253+ #endif
254+ return Tk_Init (interp );
255+ }
256+
202257/* The threading situation is complicated. Tcl is not thread-safe, except
203258 when configured with --enable-threads.
204259
@@ -569,7 +624,7 @@ Tcl_AppInit(Tcl_Interp *interp)
569624 return TCL_OK ;
570625 }
571626
572- if (Tk_Init (interp ) == TCL_ERROR ) {
627+ if (Tkinter_TkInit (interp ) == TCL_ERROR ) {
573628 PySys_WriteStderr ("Tk_Init error: %s\n" , Tcl_GetStringResult (interp ));
574629 return TCL_ERROR ;
575630 }
@@ -3013,7 +3068,7 @@ _tkinter_tkapp_loadtk_impl(TkappObject *self)
30133068 return NULL ;
30143069 }
30153070 if (_tk_exists == NULL || strcmp (_tk_exists , "1" ) != 0 ) {
3016- if (Tk_Init (interp ) == TCL_ERROR ) {
3071+ if (Tkinter_TkInit (interp ) == TCL_ERROR ) {
30173072 Tkinter_Error (self );
30183073 return NULL ;
30193074 }
0 commit comments