diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 91dd900..149772b 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -51,7 +51,7 @@ jobs: run: python scripts/prepare_remote_fallbacks.py - name: Syntax check - run: python -m py_compile setup_tool.py setup_tool_dynamic.py remote_packages.py tests/test_safety.py scripts/prepare_remote_fallbacks.py + run: python -m py_compile setup_tool.py setup_tool_dynamic.py setup_tool_responsive.py remote_packages.py tests/test_safety.py scripts/prepare_remote_fallbacks.py - name: Unit safety tests run: python -m unittest discover -s tests -v @@ -66,7 +66,7 @@ jobs: --add-data "Payload;Payload" --add-data "vanilla-tweaks.exe;." --name "WoW_Modernization_Tool" - setup_tool_dynamic.py + setup_tool_responsive.py - name: Verify EXE exists shell: pwsh diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index 4eaf5e0..5e42c85 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -21,6 +21,7 @@ This update focuses on **better compatibility, safer WoW.exe patching and improv ## 🛡️ Reliability - DXVK exclusive fullscreen is now disabled by default to avoid black screens during Alt+Tab on Windows. +- The Tool window now adapts better to Windows display scaling and smaller screens, keeping **Apply Setup & Tweaks** accessible. - Expanded automated tests for installation ordering, recovery and executable patching. - Improved rollback behavior to reduce the risk of partial installations. diff --git a/setup_tool_responsive.py b/setup_tool_responsive.py new file mode 100644 index 0000000..68fcfa8 --- /dev/null +++ b/setup_tool_responsive.py @@ -0,0 +1,51 @@ +import tkinter as tk +from tkinter import ttk + +import setup_tool_dynamic + + +class ResponsiveModernWowSetupTool(setup_tool_dynamic.ModernWowSetupTool): + """Production entry point with DPI/display-scaling-safe window behavior.""" + + def __init__(self, root): + super().__init__(root) + + # Preserve all existing installer behavior and only change how the + # top-level Tk window allocates and exposes its controls. + root.resizable(True, True) + + # Reserve the bottom action button before the expandable notebook so + # Windows DPI/text scaling cannot push Apply outside the visible area. + notebook = next( + (child for child in root.winfo_children() if isinstance(child, ttk.Notebook)), + None, + ) + apply_button = getattr(self, "apply_button", None) + if notebook is not None and apply_button is not None: + notebook.pack_forget() + apply_button.pack_forget() + apply_button.pack(side="bottom", pady=10, fill="x", padx=20) + notebook.pack(fill="both", expand=True, padx=10, pady=(5, 10)) + + root.update_idletasks() + + # Prefer the widgets' requested size when the monitor has room, while + # keeping a margin so the window remains reachable on smaller screens. + screen_width = max(1, root.winfo_screenwidth()) + screen_height = max(1, root.winfo_screenheight()) + max_width = max(640, screen_width - 80) + max_height = max(520, screen_height - 80) + + requested_width = max(680, root.winfo_reqwidth()) + requested_height = max(660, root.winfo_reqheight()) + width = min(requested_width, max_width) + height = min(requested_height, max_height) + + root.geometry(f"{width}x{height}") + root.minsize(min(640, max_width), min(520, max_height)) + + +if __name__ == "__main__": + root = tk.Tk() + app = ResponsiveModernWowSetupTool(root) + root.mainloop()