diff options
| author | Danilo M. <danix@danix.xyz> | 2026-08-09 11:06:30 +0200 |
|---|---|---|
| committer | Danilo M. <danix@danix.xyz> | 2026-08-09 11:06:30 +0200 |
| commit | 751ca62940a21a9941e558de01f43e143c92492d (patch) | |
| tree | f861752c78304555e20c79cd389c8c0dcfa2b502 /src | |
| parent | 99709c65f674385d6fbe9da53fe91c5f6a715880 (diff) | |
| download | qtmaildir-751ca62940a21a9941e558de01f43e143c92492d.tar.gz qtmaildir-751ca62940a21a9941e558de01f43e143c92492d.zip | |
fix(ui): stop a restored splitter position collapsing the message pane
A splitter position is saved in pixels, so one saved in a wide window
does not fit a narrower one: QSplitter::restoreState() honours the first
pane's saved size verbatim and gives the second whatever is left. A real
1285/1252 split restored into a 1136px window left the message pane 29px
wide, a sliver of rendered mail beside a full-width thread list. The
wider the window ever was, the worse the next narrower session.
Fixed with a minimum width on the pane and setCollapsible(1, false),
which covers the restore and the equivalent drag. A restore-time repair
running from showEvent() was written first and deleted: with the floor
in place it was mutation-tested to be redundant, since the minimum width
constrains restoreState() as much as it constrains a drag.
The floor is 300px rather than a bare "visible" width, because it is
reached only when a position does not fit and should land somewhere mail
is readable; at 200 the placeholder's own text wraps every few words.
The test asserts against the pane's own minimumWidth() rather than a
repeated literal, with a guard on the floor itself so it cannot pass
against a lowered one.
Note for later work in test_mainwindow: the offscreen platform chooses
the window width itself and has been seen to choose differently between
two runs of the same binary (1181 and 779), and it ignores resize(),
setFixedWidth() and a resize of the splitter on a shown window. Any
assertion on a pane ratio, or on the second pane's pixels, is measuring
that choice rather than this code.
Backlog item 55, whose recorded cause blamed the thread view's size hint
and first-run layout. Measured, that hint is 256px, not the 886 the item
computed from the column widths, and a freshly built window splits
correctly; the entry has been corrected in place.
Diffstat (limited to 'src')
| -rw-r--r-- | src/mainwindow.cpp | 11 | ||||
| -rw-r--r-- | src/mainwindow.h | 8 |
2 files changed, 19 insertions, 0 deletions
diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index cb02652..11de1d4 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -585,6 +585,17 @@ void MainWindow::buildUi() m_splitter->addWidget(m_threadView); m_splitter->addWidget(m_messageView); m_splitter->setStretchFactor(1, 2); + // A splitter position is saved in PIXELS, so one saved in a wide window + // does not fit a narrower one: QSplitter restores the first pane's size + // verbatim and gives the second whatever is left. A real 1285/1252 split + // restored into a 1136px window left the message pane 29px wide, a sliver + // of rendered mail beside a full-width thread list. A floor on the pane + // covers that and the equivalent drag, and needs no restore-time repair. + // Only the message pane: a minimum on the thread view as well would leave + // a narrow window unable to satisfy either, the same fault from the other + // side. + m_splitter->setCollapsible(1, false); + m_messageView->setMinimumWidth(kMinMessagePaneWidth); layout->addWidget(m_splitter, 1); layout->addWidget(m_syncLogPane); diff --git a/src/mainwindow.h b/src/mainwindow.h index 490467f..d8401a3 100644 --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -211,6 +211,7 @@ private: /// Restores window geometry, splitter and thread-list header widths. /// A missing or rejected blob leaves the buildUi() defaults in place. void restoreUiState(); + void saveUiState() const; void registerActions(); @@ -415,6 +416,13 @@ private: /// menu bar does. QMenu *m_threadContextMenu = nullptr; QSplitter *m_splitter = nullptr; + + /// Below this the message pane shows a sliver of a rendered mail and is + /// not worth the space it occupies. This is a floor, reached only when a + /// restored position does not fit, so it is set at the width mail is + /// readable at rather than the width it is merely visible at: at 200 the + /// placeholder's own text wraps every couple of words. + static constexpr int kMinMessagePaneWidth = 300; QComboBox *m_accountBox = nullptr; QLabel *m_statusLabel = nullptr; |
