summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorDanilo M. <danix@danix.xyz>2026-08-09 11:06:30 +0200
committerDanilo M. <danix@danix.xyz>2026-08-09 11:06:30 +0200
commit751ca62940a21a9941e558de01f43e143c92492d (patch)
treef861752c78304555e20c79cd389c8c0dcfa2b502 /src
parent99709c65f674385d6fbe9da53fe91c5f6a715880 (diff)
downloadqtmaildir-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.cpp11
-rw-r--r--src/mainwindow.h8
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;