mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2026-07-25 06:54:43 +00:00
Freeze chat list order while mouse hovers over it
When subscribed to many active chats, the list reorders too quickly, causing misclicks. Freeze the visual order while the mouse is over the chat list and replay deferred reorderings when the mouse leaves or after 5 seconds of inactivity. Fixes #1504.
This commit is contained in:
@@ -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()) {
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -678,6 +678,7 @@ private:
|
||||
rpl::event_stream<> _touchCancelRequests;
|
||||
|
||||
rpl::variable<ChildListShown> _childListShown;
|
||||
base::Timer _freezeTimer;
|
||||
float64 _narrowRatio = 0.;
|
||||
bool _geometryInited = false;
|
||||
|
||||
|
||||
@@ -84,6 +84,11 @@ void List::adjustByName(not_null<Row*> row) {
|
||||
void List::adjustByDate(not_null<Row*> 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*> 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();
|
||||
|
||||
@@ -52,6 +52,8 @@ public:
|
||||
not_null<Row*> addByName(Key key);
|
||||
bool moveToTop(Key key);
|
||||
void adjustByDate(not_null<Row*> 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<not_null<Row*>> _rows;
|
||||
std::map<Key, std::unique_ptr<Row>> _rowByKey;
|
||||
base::flat_set<not_null<Row*>> _pendingAdjust;
|
||||
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user