From e589429bd987d5b76789363380a7fa3a35b5826e Mon Sep 17 00:00:00 2001 From: BruebachL <44814898+BruebachL@users.noreply.github.com> Date: Tue, 25 Aug 2026 06:33:57 +0200 Subject: [PATCH] [Client] Pin user list header length to the viewport width (#7158) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * [Client] Pin user list header length to the viewport width The header stretch mode kept a resize section property, so after any column grew past the viewport the list carried an invisible horizontal pan range that scrolled rows sideways without visual feedback Drop the leftover property so displayed length always equals viewport width and horizontal panning is impossible * Show columns 1 and 2 Took 12 minutes Took 2 minutes --------- Co-authored-by: Lukas Brübach --- .../widgets/server/user/user_list_widget.cpp | 20 +++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/cockatrice/src/interface/widgets/server/user/user_list_widget.cpp b/cockatrice/src/interface/widgets/server/user/user_list_widget.cpp index c4b5d6af6..e7570ab26 100644 --- a/cockatrice/src/interface/widgets/server/user/user_list_widget.cpp +++ b/cockatrice/src/interface/widgets/server/user/user_list_widget.cpp @@ -613,7 +613,12 @@ UserListWidget::UserListWidget(TabSupervisor *_tabSupervisor, userTree->hideColumn(3); connect(userTree, &QTreeWidget::itemActivated, this, &UserListWidget::userClicked); userTree->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); - userTree->header()->setStretchLastSection(true); + // QTreeWidget enables stretchLastSection by default. Left on, the hidden + // last section absorbs viewport resizes, the Stretch sections never + // redistribute, and the header keeps a stale length past the viewport — + // an invisible horizontal pan range under ScrollBarAlwaysOff. Disable it + // so the explicit resize modes in applyDisplayMode() own the geometry. + userTree->header()->setStretchLastSection(false); // Always create timers so callers never segfault on a null deref; // showPopupForUser / hidePopup already guard against a null userInfoPopup. @@ -930,13 +935,24 @@ void UserListWidget::applyDisplayMode() { const bool styled = SettingsCache::instance().appearance().getStyleUserList(); + // Both modes must keep the header length at the viewport width: with + // ScrollBarAlwaysOff a nonzero horizontal range is invisible but still + // pans via trackpad gestures, which reads as janky random drift. if (styled) { userTree->header()->setSectionResizeMode(0, QHeaderView::Stretch); userTree->hideColumn(1); userTree->hideColumn(2); userTree->hideColumn(3); } else { - userTree->header()->setSectionResizeMode(QHeaderView::ResizeToContents); + // Bounded widths instead of ResizeToContents: content sizing measures + // the FULL text width while the delegate elides afterwards, so long + // names widened the header past the viewport. Fixed icon columns plus + // a stretched name column keep the range at zero, eliding trims. + userTree->header()->setSectionResizeMode(0, QHeaderView::Fixed); + userTree->header()->resizeSection(0, 24); + userTree->header()->setSectionResizeMode(1, QHeaderView::Fixed); + userTree->header()->resizeSection(1, 22); + userTree->header()->setSectionResizeMode(2, QHeaderView::Stretch); userTree->showColumn(1); userTree->showColumn(2); userTree->hideColumn(3);