diff --git a/Telegram/SourceFiles/dialogs/dialogs_indexed_list.cpp b/Telegram/SourceFiles/dialogs/dialogs_indexed_list.cpp index 2254346cf8..43636f81a8 100644 --- a/Telegram/SourceFiles/dialogs/dialogs_indexed_list.cpp +++ b/Telegram/SourceFiles/dialogs/dialogs_indexed_list.cpp @@ -194,6 +194,20 @@ void IndexedList::adjustNames( } } +void IndexedList::freeze() { + _list.freeze(); + for (auto &[ch, list] : _index) { + list.freeze(); + } +} + +void IndexedList::unfreeze() { + _list.unfreeze(); + for (auto &[ch, list] : _index) { + list.unfreeze(); + } +} + void IndexedList::remove(Key key, Row *replacedBy) { if (_list.remove(key, replacedBy)) { for (const auto &ch : key.entry()->chatListFirstLetters()) { diff --git a/Telegram/SourceFiles/dialogs/dialogs_indexed_list.h b/Telegram/SourceFiles/dialogs/dialogs_indexed_list.h index dfdf3b1de3..97cc709151 100644 --- a/Telegram/SourceFiles/dialogs/dialogs_indexed_list.h +++ b/Telegram/SourceFiles/dialogs/dialogs_indexed_list.h @@ -24,6 +24,8 @@ public: Row *addByName(Key key); void adjustByDate(const RowsByLetter &links); void moveToTop(Key key); + void freeze(); + void unfreeze(); bool updateHeight(Key key, float64 narrowRatio); bool updateHeights(float64 narrowRatio); diff --git a/Telegram/SourceFiles/dialogs/dialogs_inner_widget.cpp b/Telegram/SourceFiles/dialogs/dialogs_inner_widget.cpp index aa4dc87f85..7c13b16b78 100644 --- a/Telegram/SourceFiles/dialogs/dialogs_inner_widget.cpp +++ b/Telegram/SourceFiles/dialogs/dialogs_inner_widget.cpp @@ -95,6 +95,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL namespace Dialogs { namespace { +constexpr auto kFreezeTimeout = crl::time(5000); constexpr auto kHashtagResultsLimit = 5; constexpr auto kStartReorderThreshold = 30; constexpr auto kStartDragToFilterThresholdX = kStartReorderThreshold; @@ -291,7 +292,8 @@ InnerWidget::InnerWidget( , _narrowWidth(st::defaultDialogRow.padding.left() + st::defaultDialogRow.photoSize + st::defaultDialogRow.padding.left()) -, _childListShown(std::move(childListShown)) { +, _childListShown(std::move(childListShown)) +, _freezeTimer([=] { _shownList->unfreeze(); update(); }) { setAttribute(Qt::WA_OpaquePaintEvent, true); style::PaletteChanged( @@ -1678,6 +1680,13 @@ void InnerWidget::mouseMoveEvent(QMouseEvent *e) { return; } + if (_lastMousePosition && *_lastMousePosition != globalPosition) { + if (!_freezeTimer.isActive()) { + _shownList->freeze(); + } + _freezeTimer.callOnce(kFreezeTimeout); + } + if (_pressed && (e->buttons() & Qt::LeftButton)) { const auto local = e->pos(); const auto outside = _dragging ? false : true; @@ -3052,6 +3061,8 @@ void InnerWidget::updateDialogRow( void InnerWidget::enterEventHook(QEnterEvent *e) { setMouseTracking(true); + _shownList->freeze(); + _freezeTimer.callOnce(kFreezeTimeout); } Row *InnerWidget::shownRowByKey(Key key) { @@ -3134,6 +3145,7 @@ void InnerWidget::refreshShownList() { ? session().data().chatsFilters().chatsList(_filterId)->indexed() : session().data().chatsList(_openedFolder)->indexed(); if (_shownList != list) { + _shownList->unfreeze(); _shownList = list; _shownList->updateHeights(_narrowRatio); } @@ -3141,7 +3153,10 @@ void InnerWidget::refreshShownList() { void InnerWidget::leaveEventHook(QEvent *e) { setMouseTracking(false); + _freezeTimer.cancel(); + _shownList->unfreeze(); clearSelection(); + update(); } void InnerWidget::dragLeft() { diff --git a/Telegram/SourceFiles/dialogs/dialogs_inner_widget.h b/Telegram/SourceFiles/dialogs/dialogs_inner_widget.h index afd8dd3b15..ad6970454d 100644 --- a/Telegram/SourceFiles/dialogs/dialogs_inner_widget.h +++ b/Telegram/SourceFiles/dialogs/dialogs_inner_widget.h @@ -678,6 +678,7 @@ private: rpl::event_stream<> _touchCancelRequests; rpl::variable _childListShown; + base::Timer _freezeTimer; float64 _narrowRatio = 0.; bool _geometryInited = false; diff --git a/Telegram/SourceFiles/dialogs/dialogs_list.cpp b/Telegram/SourceFiles/dialogs/dialogs_list.cpp index e3c8044413..2a215176fe 100644 --- a/Telegram/SourceFiles/dialogs/dialogs_list.cpp +++ b/Telegram/SourceFiles/dialogs/dialogs_list.cpp @@ -84,6 +84,11 @@ void List::adjustByName(not_null row) { void List::adjustByDate(not_null row) { Expects(_sortMode == SortMode::Date); + if (_frozen) { + _pendingAdjust.emplace(row); + return; + } + const auto key = row->sortKey(_filterId); const auto index = row->index(); const auto i = _rows.begin() + index; @@ -103,6 +108,17 @@ void List::adjustByDate(not_null row) { } } +void List::freeze() { + _frozen = true; +} + +void List::unfreeze() { + _frozen = false; + for (const auto &row : base::take(_pendingAdjust)) { + adjustByDate(row); + } +} + bool List::updateHeight(Key key, float64 narrowRatio) { const auto i = _rowByKey.find(key); if (i == _rowByKey.cend()) { @@ -170,6 +186,7 @@ bool List::remove(Key key, Row *replacedBy) { } const auto row = i->second.get(); + _pendingAdjust.remove(row); row->entry()->owner().dialogsRowReplaced({ row, replacedBy }); auto top = row->top(); diff --git a/Telegram/SourceFiles/dialogs/dialogs_list.h b/Telegram/SourceFiles/dialogs/dialogs_list.h index 7b1bd84f24..e1d9057225 100644 --- a/Telegram/SourceFiles/dialogs/dialogs_list.h +++ b/Telegram/SourceFiles/dialogs/dialogs_list.h @@ -52,6 +52,8 @@ public: not_null addByName(Key key); bool moveToTop(Key key); void adjustByDate(not_null row); + void freeze(); + void unfreeze(); bool updateHeight(Key key, float64 narrowRatio); bool updateHeights(float64 narrowRatio); bool remove(Key key, Row *replacedBy = nullptr); @@ -82,8 +84,10 @@ private: SortMode _sortMode = SortMode(); FilterId _filterId = 0; float64 _narrowRatio = 0.; + bool _frozen = false; std::vector> _rows; std::map> _rowByKey; + base::flat_set> _pendingAdjust; };