Revert "Restore native title bar with theme-aware styling"
This reverts commit 07d7679889.
			
			
This commit is contained in:
		
							parent
							
								
									07d7679889
								
							
						
					
					
						commit
						183b769000
					
				
							
								
								
									
										82
									
								
								app/app.py
								
								
								
								
							
							
						
						
									
										82
									
								
								app/app.py
								
								
								
								
							|  | @ -5,6 +5,7 @@ from __future__ import annotations | |||
| import ctypes | ||||
| import platform | ||||
| import tkinter as tk | ||||
| from ctypes import wintypes | ||||
| from importlib import resources | ||||
| 
 | ||||
| from .gui import ColorPickerMixin, ExclusionMixin, ThemeMixin, UIBuilderMixin | ||||
|  | @ -76,9 +77,6 @@ class ICRAApp( | |||
|         self.bring_to_front() | ||||
| 
 | ||||
|     def _setup_window(self) -> None: | ||||
|         system = platform.system() | ||||
|         self.use_native_titlebar = system == "Windows" | ||||
| 
 | ||||
|         screen_width = self.root.winfo_screenwidth() | ||||
|         screen_height = self.root.winfo_screenheight() | ||||
|         default_width = int(screen_width * 0.8) | ||||
|  | @ -86,13 +84,6 @@ class ICRAApp( | |||
|         default_x = (screen_width - default_width) // 2 | ||||
|         default_y = (screen_height - default_height) // 4 | ||||
|         self._window_geometry = f"{default_width}x{default_height}+{default_x}+{default_y}" | ||||
| 
 | ||||
|         if self.use_native_titlebar: | ||||
|             self._is_maximized = False | ||||
|             self.root.geometry(self._window_geometry) | ||||
|             self.root.after(0, lambda: self.root.state("zoomed")) | ||||
|         else: | ||||
|             self.root.overrideredirect(True) | ||||
|         self._is_maximized = True | ||||
|         self.root.geometry(f"{screen_width}x{screen_height}+0+0") | ||||
|         self.root.configure(bg="#f2f2f7") | ||||
|  | @ -151,57 +142,74 @@ class ICRAApp( | |||
|             self._window_icon_ref = None | ||||
| 
 | ||||
|     def _init_window_chrome(self) -> None: | ||||
|         """Configure window chrome based on platform.""" | ||||
|         """Configure a borderless window while retaining a taskbar entry.""" | ||||
|         try: | ||||
|             if self.use_native_titlebar: | ||||
|                 if platform.system() == "Windows": | ||||
|             system = platform.system() | ||||
|             if system == "Windows": | ||||
|                 self.root.after(0, self._apply_windows_borderless_style) | ||||
|                 self.root.after(0, self._ensure_taskbar_entry) | ||||
|                     initial_mode = getattr(self, "theme", "light") | ||||
|                     self.root.after(0, lambda: self._apply_os_titlebar_theme(initial_mode)) | ||||
|                     self.root.bind( | ||||
|                         "<Map>", | ||||
|                         lambda _e: self._apply_os_titlebar_theme(getattr(self, "theme", "light")), | ||||
|                         add="+", | ||||
|                     ) | ||||
|                 self.root.bind("<Map>", lambda _e: self._apply_windows_borderless_style(), add="+") | ||||
|                 self.root.bind("<Map>", lambda _e: self._ensure_taskbar_entry(), add="+") | ||||
|             else: | ||||
|                 self.root.bind("<Map>", self._restore_borderless) | ||||
|                 self.root.after(0, self._restore_borderless) | ||||
|                 self.root.after(0, self._ensure_taskbar_entry) | ||||
|                 self.root.overrideredirect(True) | ||||
|         except Exception: | ||||
|             self.root.overrideredirect(True) | ||||
| 
 | ||||
|     def _restore_borderless(self, _event=None) -> None: | ||||
|         try: | ||||
|             self.root.overrideredirect(True) | ||||
|         except Exception: | ||||
|             pass | ||||
| 
 | ||||
|     def _apply_os_titlebar_theme(self, mode: str | None = None) -> None: | ||||
|     def _apply_windows_borderless_style(self) -> None: | ||||
|         try: | ||||
|             if platform.system() != "Windows": | ||||
|                 return | ||||
| 
 | ||||
|             hwnd = self.root.winfo_id() | ||||
|             if not hwnd: | ||||
|                 self.root.after(50, lambda: self._apply_os_titlebar_theme(mode)) | ||||
|                 self.root.after(50, self._apply_windows_borderless_style) | ||||
|                 return | ||||
| 
 | ||||
|             user32 = ctypes.windll.user32  # type: ignore[attr-defined] | ||||
|             GWL_STYLE = -16 | ||||
|             WS_CAPTION = 0x00C00000 | ||||
|             WS_THICKFRAME = 0x00040000 | ||||
|             WS_BORDER = 0x00800000 | ||||
|             SWP_NOSIZE = 0x0001 | ||||
|             SWP_NOMOVE = 0x0002 | ||||
|             SWP_NOZORDER = 0x0004 | ||||
|             SWP_FRAMECHANGED = 0x0020 | ||||
| 
 | ||||
|             set_window_long = getattr(user32, "SetWindowLongPtrW", user32.SetWindowLongW) | ||||
|             get_window_long = getattr(user32, "GetWindowLongPtrW", user32.GetWindowLongW) | ||||
|             ptr_type = ctypes.c_longlong if ctypes.sizeof(ctypes.c_void_p) == 8 else ctypes.c_long | ||||
|             get_window_long.restype = ptr_type  # type: ignore[attr-defined] | ||||
|             get_window_long.argtypes = [wintypes.HWND, ctypes.c_int]  # type: ignore[attr-defined] | ||||
|             set_window_long.restype = ptr_type  # type: ignore[attr-defined] | ||||
|             set_window_long.argtypes = [wintypes.HWND, ctypes.c_int, ptr_type]  # type: ignore[attr-defined] | ||||
| 
 | ||||
|             style = get_window_long(hwnd, GWL_STYLE) | ||||
|             new_style = style & ~(WS_CAPTION | WS_THICKFRAME | WS_BORDER) | ||||
|             if new_style != style: | ||||
|                 set_window_long(hwnd, GWL_STYLE, ptr_type(new_style)) | ||||
|                 user32.SetWindowPos( | ||||
|                     hwnd, | ||||
|                     0, | ||||
|                     0, | ||||
|                     0, | ||||
|                     0, | ||||
|                     0, | ||||
|                     SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED, | ||||
|                 ) | ||||
|             try: | ||||
|                 dwmapi = ctypes.windll.dwmapi  # type: ignore[attr-defined] | ||||
|             except Exception: | ||||
|                 return | ||||
| 
 | ||||
|             attribute = ctypes.c_uint(20)  # DWMWA_USE_IMMERSIVE_DARK_MODE | ||||
|             value = ctypes.c_int(1 if (mode or self.theme) == "dark" else 0) | ||||
|                 DWMWA_USE_IMMERSIVE_DARK_MODE = 20 | ||||
|                 value = ctypes.c_int(1) | ||||
|                 dwmapi.DwmSetWindowAttribute( | ||||
|                     hwnd, | ||||
|                 attribute, | ||||
|                     ctypes.c_uint(DWMWA_USE_IMMERSIVE_DARK_MODE), | ||||
|                     ctypes.byref(value), | ||||
|                     ctypes.sizeof(value), | ||||
|                 ) | ||||
|             except Exception: | ||||
|                 pass | ||||
|         except Exception: | ||||
|             pass | ||||
| 
 | ||||
| 
 | ||||
| def start_app() -> None: | ||||
|  |  | |||
|  | @ -71,10 +71,6 @@ class ThemeMixin: | |||
|         if callable(canvas_refresher): | ||||
|             canvas_refresher() | ||||
| 
 | ||||
|         os_theme_hook = getattr(self, "_apply_os_titlebar_theme", None) | ||||
|         if callable(os_theme_hook): | ||||
|             os_theme_hook(self.theme) | ||||
| 
 | ||||
|     def detect_system_theme(self) -> str: | ||||
|         """Best-effort detection of the OS theme preference.""" | ||||
|         try: | ||||
|  |  | |||
|  | @ -12,8 +12,6 @@ class UIBuilderMixin: | |||
|     """Constructs the Tkinter UI and common widgets.""" | ||||
| 
 | ||||
|     def setup_ui(self) -> None: | ||||
|         self._custom_titlebar = not getattr(self, "use_native_titlebar", False) | ||||
|         if self._custom_titlebar: | ||||
|         self._create_titlebar() | ||||
| 
 | ||||
|         toolbar = ttk.Frame(self.root) | ||||
|  | @ -467,8 +465,6 @@ class UIBuilderMixin: | |||
|             pass | ||||
| 
 | ||||
|     def _start_window_drag(self, event) -> None: | ||||
|         if not getattr(self, "_custom_titlebar", True): | ||||
|             return | ||||
|         if getattr(self, "_is_maximized", False): | ||||
|             cursor_x, cursor_y = event.x_root, event.y_root | ||||
|             self._toggle_maximize_window(force_state=False) | ||||
|  | @ -480,8 +476,6 @@ class UIBuilderMixin: | |||
|         self._drag_offset = (event.x_root - self.root.winfo_rootx(), event.y_root - self.root.winfo_rooty()) | ||||
| 
 | ||||
|     def _perform_window_drag(self, event) -> None: | ||||
|         if not getattr(self, "_custom_titlebar", True): | ||||
|             return | ||||
|         offset = getattr(self, "_drag_offset", None) | ||||
|         if offset is None: | ||||
|             return | ||||
|  | @ -531,8 +525,6 @@ class UIBuilderMixin: | |||
|             return None | ||||
| 
 | ||||
|     def _maximize_window(self) -> None: | ||||
|         if not getattr(self, "_custom_titlebar", True): | ||||
|             return | ||||
|         self._remember_window_geometry() | ||||
|         work_area = self._monitor_work_area() | ||||
|         if work_area is None: | ||||
|  | @ -551,8 +543,6 @@ class UIBuilderMixin: | |||
|         self._update_maximize_button() | ||||
| 
 | ||||
|     def _restore_window(self) -> None: | ||||
|         if not getattr(self, "_custom_titlebar", True): | ||||
|             return | ||||
|         geometry = getattr(self, "_window_geometry", None) | ||||
|         if not geometry: | ||||
|             screen_width = self.root.winfo_screenwidth() | ||||
|  | @ -567,8 +557,6 @@ class UIBuilderMixin: | |||
|         self._update_maximize_button() | ||||
| 
 | ||||
|     def _toggle_maximize_window(self, force_state: bool | None = None) -> None: | ||||
|         if not getattr(self, "_custom_titlebar", True): | ||||
|             return | ||||
|         desired = force_state if force_state is not None else not getattr(self, "_is_maximized", False) | ||||
|         if desired: | ||||
|             self._maximize_window() | ||||
|  | @ -576,8 +564,6 @@ class UIBuilderMixin: | |||
|             self._restore_window() | ||||
| 
 | ||||
|     def _minimize_window(self) -> None: | ||||
|         if not getattr(self, "_custom_titlebar", True): | ||||
|             return | ||||
|         try: | ||||
|             self._remember_window_geometry() | ||||
|             self.root.iconify() | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue