Improve maximize behaviour on multi-monitor setups
This commit is contained in:
parent
27c0e55711
commit
50b9aa723c
|
|
@ -446,11 +446,6 @@ class UIBuilderMixin:
|
|||
max_btn.bind("<Leave>", lambda _e: max_btn.configure(bg=bar_bg))
|
||||
self._max_button = max_btn
|
||||
|
||||
min_btn = tk.Button(title_bar, text="—", command=self._minimize_window, **btn_kwargs)
|
||||
min_btn.pack(side=tk.RIGHT, padx=0, pady=4)
|
||||
min_btn.bind("<Enter>", lambda _e: min_btn.configure(bg="#2c2c32"))
|
||||
min_btn.bind("<Leave>", lambda _e: min_btn.configure(bg=bar_bg))
|
||||
|
||||
for widget in (title_bar, title_label):
|
||||
widget.bind("<ButtonPress-1>", self._start_window_drag)
|
||||
widget.bind("<B1-Motion>", self._perform_window_drag)
|
||||
|
|
@ -491,11 +486,54 @@ class UIBuilderMixin:
|
|||
except Exception:
|
||||
pass
|
||||
|
||||
def _monitor_work_area(self) -> tuple[int, int, int, int] | None:
|
||||
try:
|
||||
import ctypes
|
||||
from ctypes import wintypes
|
||||
|
||||
user32 = ctypes.windll.user32 # type: ignore[attr-defined]
|
||||
root_x = self.root.winfo_rootx()
|
||||
root_y = self.root.winfo_rooty()
|
||||
width = max(self.root.winfo_width(), 1)
|
||||
height = max(self.root.winfo_height(), 1)
|
||||
center_x = root_x + width // 2
|
||||
center_y = root_y + height // 2
|
||||
|
||||
class MONITORINFO(ctypes.Structure):
|
||||
_fields_ = [
|
||||
("cbSize", wintypes.DWORD),
|
||||
("rcMonitor", wintypes.RECT),
|
||||
("rcWork", wintypes.RECT),
|
||||
("dwFlags", wintypes.DWORD),
|
||||
]
|
||||
|
||||
monitor = user32.MonitorFromPoint(
|
||||
wintypes.POINT(center_x, center_y), 2 # MONITOR_DEFAULTTONEAREST
|
||||
)
|
||||
info = MONITORINFO()
|
||||
info.cbSize = ctypes.sizeof(MONITORINFO)
|
||||
if not user32.GetMonitorInfoW(monitor, ctypes.byref(info)):
|
||||
return None
|
||||
work = info.rcWork
|
||||
return work.left, work.top, work.right, work.bottom
|
||||
except Exception:
|
||||
return None
|
||||
|
||||
def _maximize_window(self) -> None:
|
||||
self._remember_window_geometry()
|
||||
screen_width = self.root.winfo_screenwidth()
|
||||
screen_height = self.root.winfo_screenheight()
|
||||
self.root.geometry(f"{screen_width}x{screen_height}+0+0")
|
||||
work_area = self._monitor_work_area()
|
||||
if work_area is None:
|
||||
screen_width = self.root.winfo_screenwidth()
|
||||
screen_height = self.root.winfo_screenheight()
|
||||
left = 0
|
||||
top = 0
|
||||
width = screen_width
|
||||
height = screen_height
|
||||
else:
|
||||
left, top, right, bottom = work_area
|
||||
width = max(1, right - left)
|
||||
height = max(1, bottom - top)
|
||||
self.root.geometry(f"{width}x{height}+{left}+{top}")
|
||||
self._is_maximized = True
|
||||
self._update_maximize_button()
|
||||
|
||||
|
|
@ -520,14 +558,6 @@ class UIBuilderMixin:
|
|||
else:
|
||||
self._restore_window()
|
||||
|
||||
def _minimize_window(self) -> None:
|
||||
try:
|
||||
self.root.overrideredirect(False)
|
||||
self.root.iconify()
|
||||
self.root.after(50, lambda: self.root.overrideredirect(True))
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
def _update_maximize_button(self) -> None:
|
||||
button = getattr(self, "_max_button", None)
|
||||
if button is None:
|
||||
|
|
|
|||
Loading…
Reference in New Issue