|
9 | 9 | import webbrowser |
10 | 10 | from datetime import datetime |
11 | 11 | from opensak.utils.constants import LOG_COLOURS |
12 | | -from PySide6.QtCore import Qt, QUrl, Signal, QDate, QLocale, QEvent |
| 12 | +from PySide6.QtCore import Qt, QUrl, Signal, QDate, QLocale, QEvent, QSize |
13 | 13 | from PySide6.QtWidgets import ( |
14 | 14 | QWidget, QVBoxLayout, QHBoxLayout, QLabel, |
15 | 15 | QTextBrowser, QTabWidget, QFrame, QSizePolicy, |
@@ -88,6 +88,39 @@ def acceptNavigationRequest(self, url: QUrl | str, nav_type, is_main_frame: bool |
88 | 88 | return False |
89 | 89 |
|
90 | 90 |
|
| 91 | +class _TabWidget(QTabWidget): |
| 92 | + """QTabWidget whose minimumSizeHint doesn't propagate the largest tab |
| 93 | + page's minimum height up into the parent layout. |
| 94 | +
|
| 95 | + Issue #755: QTabWidget.minimumSizeHint() normally reports the size |
| 96 | + needed to fit whichever tab page has the largest minimum size (since any |
| 97 | + tab could be switched to at any time). That propagated straight up into |
| 98 | + CacheDetailPanel's — and therefore the whole bottom_splitter's — minimum |
| 99 | + height, which made the main vertical splitter refuse to shrink the |
| 100 | + bottom panel much past that content's natural minimum. |
| 101 | +
|
| 102 | + v1.17.1 "fixed" this by setting the widget's vertical QSizePolicy to |
| 103 | + Ignored instead of overriding this method. That was a regression |
| 104 | + (reported by Mike, see follow-up issue): QSizePolicy.Ignored does not |
| 105 | + carry the ExpandFlag that Expanding does, so the tabs stopped being the |
| 106 | + preferred recipient of any leftover vertical space in the panel's |
| 107 | + QVBoxLayout. With no widget left flagged as expansive, Qt's box-layout |
| 108 | + algorithm instead spread that leftover space across ALL rows in the |
| 109 | + layout — including the compact header/meta rows — producing large empty |
| 110 | + grey padding around them that grew worse the taller the panel was |
| 111 | + dragged. |
| 112 | + Overriding minimumSizeHint() here fixes the original #755 problem |
| 113 | + directly, without touching the size *policy* — the tabs keep their |
| 114 | + normal Expanding policy, so they still get first claim on extra space, |
| 115 | + exactly as before v1.17.1. Each tab's own content (QTextBrowser/log |
| 116 | + list/etc.) already scrolls internally when squeezed, so nothing becomes |
| 117 | + unreachable when the splitter is dragged small. |
| 118 | + """ |
| 119 | + |
| 120 | + def minimumSizeHint(self) -> QSize: |
| 121 | + return QSize(0, 0) |
| 122 | + |
| 123 | + |
91 | 124 | class CacheDetailPanel(QWidget): |
92 | 125 | """Displays full details for a single selected cache.""" |
93 | 126 |
|
@@ -249,7 +282,7 @@ def _setup_ui(self) -> None: |
249 | 282 | layout.addWidget(self._placed_lbl) |
250 | 283 |
|
251 | 284 | # ── Tabs: Description | Hint | Logs ─────────────────────────────────── |
252 | | - self._tabs = QTabWidget() |
| 285 | + self._tabs = _TabWidget() # see _TabWidget docstring — issue #755 |
253 | 286 | self._tabs.setDocumentMode(True) |
254 | 287 |
|
255 | 288 | # Beskrivelse — QWebEngineView så eksterne billeder og CJK-fonte virker. |
@@ -345,27 +378,6 @@ def _setup_ui(self) -> None: |
345 | 378 | note_layout.addWidget(self._note_editor) |
346 | 379 | self._tabs.addTab(note_widget, tr("detail_tab_notes")) |
347 | 380 |
|
348 | | - # Issue #755: QTabWidget reports its own minimumSizeHint as the |
349 | | - # LARGEST of its tab pages' minimums (since any tab could be |
350 | | - # switched to at any time), and that propagates straight up into |
351 | | - # this panel's — and therefore the whole bottom_splitter's — |
352 | | - # minimum height, which is what made the main vertical splitter |
353 | | - # refuse to shrink the bottom panel much past its content's |
354 | | - # natural minimum ("stuck around the middle of the window"). |
355 | | - # |
356 | | - # QSizePolicy.Policy.Ignored on the vertical component tells Qt's |
357 | | - # layout system to disregard this widget's height hint entirely |
358 | | - # when computing the *minimum* size for this panel — the splitter |
359 | | - # can then be dragged freely down to a small size. It still grows |
360 | | - # to fill available space normally when there's room (Ignored only |
361 | | - # affects the minimum/hint contribution, not actual sizing), and |
362 | | - # each tab's own content already scrolls internally when squeezed |
363 | | - # (QTextBrowser/log list/etc. all have their own scrollbars), so |
364 | | - # nothing becomes unreachable — content just scrolls instead of |
365 | | - # ever blocking the splitter. |
366 | | - size_policy = self._tabs.sizePolicy() |
367 | | - size_policy.setVerticalPolicy(QSizePolicy.Policy.Ignored) |
368 | | - self._tabs.setSizePolicy(size_policy) |
369 | 381 | layout.addWidget(self._tabs) |
370 | 382 | self._tabs.currentChanged.connect(self._on_tab_changed) |
371 | 383 |
|
|
0 commit comments