diff --git a/app/app.py b/app/app.py index 78a37b4..bc7eb6f 100644 --- a/app/app.py +++ b/app/app.py @@ -84,7 +84,58 @@ class ICRAApp( self._is_maximized = True self.root.geometry(f"{screen_width}x{screen_height}+0+0") self.root.configure(bg="#f2f2f7") - self.root.bind("", lambda _e: self.root.overrideredirect(True)) + self.root.bind("", self._restore_borderless) + self.root.after(0, self._ensure_taskbar_entry) + + def _restore_borderless(self, _event=None) -> None: + try: + self.root.overrideredirect(True) + self._ensure_taskbar_entry() + except Exception: + pass + + def _ensure_taskbar_entry(self) -> None: + """Force the borderless window to show up in the Windows taskbar.""" + try: + import platform + + if platform.system() != "Windows": + return + + import ctypes + hwnd = self.root.winfo_id() + if not hwnd: + return + + GWL_EXSTYLE = -20 + WS_EX_TOOLWINDOW = 0x00000080 + WS_EX_APPWINDOW = 0x00040000 + SWP_NOSIZE = 0x0001 + SWP_NOMOVE = 0x0002 + SWP_NOZORDER = 0x0004 + SWP_FRAMECHANGED = 0x0020 + + user32 = ctypes.windll.user32 # type: ignore[attr-defined] + shell32 = ctypes.windll.shell32 # type: ignore[attr-defined] + + style = user32.GetWindowLongW(hwnd, GWL_EXSTYLE) + new_style = (style & ~WS_EX_TOOLWINDOW) | WS_EX_APPWINDOW + if new_style != style: + user32.SetWindowLongW(hwnd, GWL_EXSTYLE, new_style) + user32.SetWindowPos( + hwnd, + 0, + 0, + 0, + 0, + 0, + SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED, + ) + + app_id = ctypes.c_wchar_p("ICRA.App") + shell32.SetCurrentProcessExplicitAppUserModelID(app_id) + except Exception: + pass def start_app() -> None: