Clear timeline widgets when they exceed a certain limit (#158)

That's a fix to deal with long running sessions which will end
up taking more & more memory given enough time.
This commit is contained in:
Konstantinos Sideris 2018-07-21 12:09:23 +03:00
parent e8cb2cee0c
commit 9d718fccf4
2 changed files with 45 additions and 2 deletions

View file

@ -38,6 +38,10 @@
using TimelineEvent = mtx::events::collections::TimelineEvents;
//! Maximum number of widgets to keep in the timeline layout.
constexpr int MAX_RETAINED_WIDGETS = 100;
constexpr int MIN_SCROLLBAR_HANDLE = 60;
//! Retrieve the timestamp of the event represented by the given widget.
QDateTime
getDate(QWidget *widget)
@ -481,8 +485,7 @@ TimelineView::addEvents(const mtx::responses::Timeline &timeline)
void
TimelineView::init()
{
QSettings settings;
local_user_ = settings.value("auth/user_id").toString();
local_user_ = utils::localUser();
QIcon icon;
icon.addFile(":/icons/icons/ui/angle-arrow-down.png");
@ -965,6 +968,19 @@ TimelineView::showEvent(QShowEvent *event)
QWidget::showEvent(event);
}
void
TimelineView::hideEvent(QHideEvent *event)
{
const auto handleHeight = scroll_area_->verticalScrollBar()->sizeHint().height();
const auto widgetsNum = scroll_layout_->count();
// Remove widgets from the timeline to reduce the memory footprint.
if (handleHeight < MIN_SCROLLBAR_HANDLE && widgetsNum > MAX_RETAINED_WIDGETS)
clearTimeline();
QWidget::hideEvent(event);
}
bool
TimelineView::event(QEvent *event)
{
@ -974,6 +990,30 @@ TimelineView::event(QEvent *event)
return QWidget::event(event);
}
void
TimelineView::clearTimeline()
{
// Delete all widgets.
QLayoutItem *item;
while ((item = scroll_layout_->takeAt(0)) != nullptr) {
delete item->widget();
delete item;
}
// The next call to /messages will be without a prev token.
prev_batch_token_.clear();
eventIds_.clear();
// Clear queues with pending messages to be rendered.
bottomMessages_.clear();
topMessages_.clear();
firstSender_.clear();
lastSender_.clear();
scroll_layout_->addStretch(1);
}
void
TimelineView::toggleScrollDownButton()
{

View file

@ -161,6 +161,7 @@ signals:
protected:
void paintEvent(QPaintEvent *event) override;
void showEvent(QShowEvent *event) override;
void hideEvent(QHideEvent *event) override;
bool event(QEvent *event) override;
private:
@ -271,6 +272,8 @@ private:
//! Store the event id associated with the given widget.
void saveEventId(QWidget *widget);
//! Remove all widgets from the timeline layout.
void clearTimeline();
QVBoxLayout *top_layout_;
QVBoxLayout *scroll_layout_;