From a8f11dcd5333a1dfe8c9ae61c1b1a66cb651ebb7 Mon Sep 17 00:00:00 2001 From: tomasalias Date: Thu, 8 Oct 2026 22:06:42 +0200 Subject: [PATCH] fix(gui): set titlebar icon directly on root HWND and remove iconphoto conflict on Windows --- patcher/patcher_gui.py | 42 +++++++++++++++++++++++++++++++++--------- 1 file changed, 33 insertions(+), 9 deletions(-) diff --git a/patcher/patcher_gui.py b/patcher/patcher_gui.py index 8ce1daf..6590823 100644 --- a/patcher/patcher_gui.py +++ b/patcher/patcher_gui.py @@ -103,21 +103,45 @@ class BetterCFApp: ico_path = find_asset("icon.ico") if ico_path and os.name == "nt": try: + self.root.iconbitmap(str(ico_path.resolve())) self.root.iconbitmap(default=str(ico_path.resolve())) except Exception: pass - png_path = find_asset("icon_512.png") or find_asset("icon.png") - if png_path: try: - if HAS_PIL: - im = Image.open(png_path) - self._icon_photo = ImageTk.PhotoImage(im.resize((64, 64), Image.Resampling.LANCZOS)) - self.root.iconphoto(True, self._icon_photo) - else: - self._icon_photo = tk.PhotoImage(file=str(png_path)) - self.root.iconphoto(True, self._icon_photo) + import ctypes + user32 = ctypes.windll.user32 + GA_ROOT = 2 + WM_SETICON = 0x0080 + IMAGE_ICON = 1 + LR_LOADFROMFILE = 0x0010 + + self.root.update_idletasks() + inner_hwnd = self.root.winfo_id() + root_hwnd = user32.GetAncestor(inner_hwnd, GA_ROOT) or inner_hwnd + + self._win32_icon_sm = user32.LoadImageW(None, str(ico_path.resolve()), IMAGE_ICON, 16, 16, LR_LOADFROMFILE) + self._win32_icon_bg = user32.LoadImageW(None, str(ico_path.resolve()), IMAGE_ICON, 32, 32, LR_LOADFROMFILE) + + for h in (inner_hwnd, root_hwnd): + if self._win32_icon_sm: + user32.SendMessageW(h, WM_SETICON, 0, self._win32_icon_sm) + if self._win32_icon_bg: + user32.SendMessageW(h, WM_SETICON, 1, self._win32_icon_bg) except Exception: pass + elif os.name != "nt": + png_path = find_asset("icon_512.png") or find_asset("icon.png") + if png_path: + try: + if HAS_PIL: + im = Image.open(png_path) + self._icon_photo = ImageTk.PhotoImage(im.resize((64, 64), Image.Resampling.LANCZOS)) + self.root.iconphoto(True, self._icon_photo) + else: + self._icon_photo = tk.PhotoImage(file=str(png_path)) + self.root.iconphoto(True, self._icon_photo) + except Exception: + pass def _configure_styles(self): style = ttk.Style()