From 0e09eaf43bcf3f7d46cd89415406bd128b0df675 Mon Sep 17 00:00:00 2001 From: "alexei.dolgolyov" Date: Wed, 8 Apr 2026 23:14:58 +0300 Subject: [PATCH] fix(launcher): set TCL_LIBRARY/TK_LIBRARY for embedded Python MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Embedded Python ships with tcl8.6/ and tk8.6/ next to python.exe, but Tcl's auto-detection searches /../lib/tcl8.6 — a path that doesn't exist in our layout. Without these env vars, tkinter.Tk() raises "Can't find a usable init.tcl", breaking the screen overlay (and any other tk-based UI) on installed builds. --- server/src/wled_controller/__main__.py | 31 +++++++++++++++++++++----- 1 file changed, 26 insertions(+), 5 deletions(-) diff --git a/server/src/wled_controller/__main__.py b/server/src/wled_controller/__main__.py index 16f4eb8..50474c2 100644 --- a/server/src/wled_controller/__main__.py +++ b/server/src/wled_controller/__main__.py @@ -13,12 +13,33 @@ import time import webbrowser from pathlib import Path -import uvicorn -from wled_controller.config import get_config -from wled_controller.server_ref import set_server, set_tray -from wled_controller.tray import PYSTRAY_AVAILABLE, TrayManager -from wled_controller.utils import setup_logging, get_logger +def _fix_embedded_tcl_paths() -> None: + """Point TCL_LIBRARY/TK_LIBRARY at the bundled tcl/tk dirs. + + The Windows installer ships embedded Python with tcl8.6/ and tk8.6/ + next to python.exe, but Tcl's auto-detection searches ``/../lib/tcl8.6`` + and similar paths that don't exist in our layout. Without these env vars, + ``tkinter.Tk()`` fails with "Can't find a usable init.tcl", which breaks + both the screen overlay and tray messageboxes. + """ + exe_dir = Path(sys.executable).parent + tcl_dir = exe_dir / "tcl8.6" + tk_dir = exe_dir / "tk8.6" + if (tcl_dir / "init.tcl").is_file(): + os.environ.setdefault("TCL_LIBRARY", str(tcl_dir)) + if (tk_dir / "tk.tcl").is_file(): + os.environ.setdefault("TK_LIBRARY", str(tk_dir)) + + +_fix_embedded_tcl_paths() + +import uvicorn # noqa: E402 + +from wled_controller.config import get_config # noqa: E402 +from wled_controller.server_ref import set_server, set_tray # noqa: E402 +from wled_controller.tray import PYSTRAY_AVAILABLE, TrayManager # noqa: E402 +from wled_controller.utils import setup_logging, get_logger # noqa: E402 setup_logging() logger = get_logger(__name__)