From 283ede86ad14d19e075c9329241471299f717e1b Mon Sep 17 00:00:00 2001 From: nerix Date: Sun, 10 Sep 2023 17:08:13 +0200 Subject: [PATCH] Only layout visible `ChannelView`s (#4811) --- CHANGELOG.md | 1 + src/widgets/helper/ChannelView.cpp | 58 ++++++++++++++++++------------ src/widgets/helper/ChannelView.hpp | 11 +++--- 3 files changed, 42 insertions(+), 28 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c8a25d80a..8af8f78a2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ - Dev: Do a pretty major refactor of the Settings classes. List settings (e.g. highlights) are most heavily modified, and should have an extra eye kept on them. (#4775) - Dev: Remove `boost::noncopyable` use & `boost_random` dependency. (#4776) - Dev: Fix clang-tidy `cppcoreguidelines-pro-type-member-init` warnings. (#4426) +- Dev: Immediate layout for invisible `ChannelView`s is skipped. (#4811) ## 2.4.5 diff --git a/src/widgets/helper/ChannelView.cpp b/src/widgets/helper/ChannelView.cpp index 0dcd55260..c8abae676 100644 --- a/src/widgets/helper/ChannelView.cpp +++ b/src/widgets/helper/ChannelView.cpp @@ -228,8 +228,15 @@ void ChannelView::initializeLayout() void ChannelView::initializeScrollbar() { this->scrollBar_->getCurrentValueChanged().connect([this] { - this->performLayout(true); - this->queueUpdate(); + if (this->isVisible()) + { + this->performLayout(true); + this->queueUpdate(); + } + else + { + this->layoutQueued_ = true; + } }); } @@ -413,33 +420,35 @@ void ChannelView::scaleChangedEvent(float scale) void ChannelView::queueUpdate() { - // if (this->updateTimer.isActive()) { - // this->updateQueued = true; - // return; - // } - - // this->repaint(); - this->update(); - - // this->updateTimer.start(); } void ChannelView::queueLayout() { - // if (!this->layoutCooldown->isActive()) { - this->performLayout(); - - // this->layoutCooldown->start(); - // } else { - // this->layoutQueued = true; - // } + if (this->isVisible()) + { + this->performLayout(); + } + else + { + this->layoutQueued_ = true; + } } -void ChannelView::performLayout(bool causedByScrollbar) +void ChannelView::showEvent(QShowEvent * /*event*/) +{ + if (this->layoutQueued_) + { + this->performLayout(false, true); + } +} + +void ChannelView::performLayout(bool causedByScrollbar, bool causedByShow) { // BenchmarkGuard benchmark("layout"); + this->layoutQueued_ = false; + /// Get messages and check if there are at least 1 const auto &messages = this->getMessagesSnapshot(); @@ -451,7 +460,7 @@ void ChannelView::performLayout(bool causedByScrollbar) this->layoutVisibleMessages(messages); /// Update scrollbar - this->updateScrollbar(messages, causedByScrollbar); + this->updateScrollbar(messages, causedByScrollbar, causedByShow); this->goToBottom_->setVisible(this->enableScrollingToBottom_ && this->scrollBar_->isVisible() && @@ -490,7 +499,7 @@ void ChannelView::layoutVisibleMessages( void ChannelView::updateScrollbar( const LimitedQueueSnapshot &messages, - bool causedByScrollbar) + bool causedByScrollbar, bool causedByShow) { if (messages.size() == 0) { @@ -539,6 +548,7 @@ void ChannelView::updateScrollbar( showScrollbar && !causedByScrollbar) { this->scrollBar_->scrollToBottom( + !causedByShow && getSettings()->enableSmoothScrollingNewMessages.getValue()); } } @@ -799,7 +809,7 @@ void ChannelView::setChannel(ChannelPtr underlyingChannel) this->underlyingChannel_ = underlyingChannel; - this->queueLayout(); + this->performLayout(); this->queueUpdate(); // Notifications @@ -903,6 +913,10 @@ void ChannelView::messageAppended(MessagePtr &message, else { this->scrollBar_->offsetMinimum(1); + if (this->showingLatestMessages_ && !this->isVisible()) + { + this->scrollBar_->scrollToBottom(false); + } this->selection_.shiftMessageIndex(1); } } diff --git a/src/widgets/helper/ChannelView.hpp b/src/widgets/helper/ChannelView.hpp index f28abf408..1fb4c3941 100644 --- a/src/widgets/helper/ChannelView.hpp +++ b/src/widgets/helper/ChannelView.hpp @@ -181,6 +181,7 @@ protected: void mouseDoubleClickEvent(QMouseEvent *event) override; void hideEvent(QHideEvent *) override; + void showEvent(QShowEvent *event) override; void handleLinkClick(QMouseEvent *event, const Link &link, MessageLayout *layout); @@ -200,11 +201,12 @@ private: void messageReplaced(size_t index, MessagePtr &replacement); void messagesUpdated(); - void performLayout(bool causedByScrollbar = false); + void performLayout(bool causedByScrollbar = false, + bool causedByShow = false); void layoutVisibleMessages( const LimitedQueueSnapshot &messages); void updateScrollbar(const LimitedQueueSnapshot &messages, - bool causedByScrollbar); + bool causedByScrollbar, bool causedByShow); void drawMessages(QPainter &painter); void setSelection(const SelectionItem &start, const SelectionItem &end); @@ -256,11 +258,8 @@ private: void showReplyThreadPopup(const MessagePtr &message); bool canReplyToMessages() const; - QTimer *layoutCooldown_{}; - bool layoutQueued_{}; + bool layoutQueued_ = false; - QTimer updateTimer_; - bool updateQueued_ = false; bool lastMessageHasAlternateBackground_ = false; bool lastMessageHasAlternateBackgroundReverse_ = true;