From b4beb6abed67da3d2397df17e7785f4863c278a7 Mon Sep 17 00:00:00 2001 From: John Preston Date: Fri, 20 Sep 2019 13:10:23 +0300 Subject: [PATCH] Fix toast notification destruction. --- ui/toast/toast.h | 4 +-- ui/toast/toast_manager.cpp | 59 +++++++++++++++++++++----------------- ui/toast/toast_manager.h | 8 +++--- 3 files changed, 39 insertions(+), 32 deletions(-) diff --git a/ui/toast/toast.h b/ui/toast/toast.h index 3ea36cc..6ced4e9 100644 --- a/ui/toast/toast.h +++ b/ui/toast/toast.h @@ -16,11 +16,11 @@ class Manager; class Widget; } // namespace internal -static constexpr const int DefaultDuration = 1500; +inline constexpr auto kDefaultDuration = crl::time(1500); struct Config { QString text; QMargins padding; - int durationMs = DefaultDuration; + crl::time durationMs = kDefaultDuration; int minWidth = 0; int maxWidth = 0; int maxLines = 16; diff --git a/ui/toast/toast_manager.cpp b/ui/toast/toast_manager.cpp index 03eb810..adbac76 100644 --- a/ui/toast/toast_manager.cpp +++ b/ui/toast/toast_manager.cpp @@ -25,8 +25,8 @@ Manager::Manager(not_null parent, const CreateTag &) bool Manager::eventFilter(QObject *o, QEvent *e) { if (e->type() == QEvent::Resize) { for (auto i = _toastByWidget.cbegin(), e = _toastByWidget.cend(); i != e; ++i) { - if (i.key()->parentWidget() == o) { - i.key()->onParentResized(); + if (i->first->parentWidget() == o) { + i->first->onParentResized(); } } } @@ -45,13 +45,13 @@ not_null Manager::instance(not_null parent) { } void Manager::addToast(std::unique_ptr &&toast) { - _toasts.push_back(toast.release()); - Instance *t = _toasts.back(); - Widget *widget = t->_widget.get(); + _toasts.push_back(std::move(toast)); + const auto t = _toasts.back().get(); + const auto widget = t->_widget.get(); - _toastByWidget.insert(widget, t); + _toastByWidget.emplace(widget, t); connect(widget, SIGNAL(destroyed(QObject*)), this, SLOT(onToastWidgetDestroyed(QObject*))); - if (auto parent = widget->parentWidget()) { + if (const auto parent = widget->parentWidget()) { auto found = false; for (auto i = _toastParents.begin(); i != _toastParents.cend();) { if (*i == parent) { @@ -64,14 +64,16 @@ void Manager::addToast(std::unique_ptr &&toast) { } } if (!found) { - _toastParents.insert(parent); + _toastParents.push_back(parent); parent->installEventFilter(this); } } - auto oldHideNearestMs = _toastByHideTime.isEmpty() ? 0LL : _toastByHideTime.firstKey(); - _toastByHideTime.insert(t->_hideAtMs, t); - if (!oldHideNearestMs || _toastByHideTime.firstKey() < oldHideNearestMs) { + const auto nearestHide = _toastByHideTime.empty() + ? 0LL + : _toastByHideTime.begin()->first; + _toastByHideTime.emplace(t->_hideAtMs, t); + if (!nearestHide || _toastByHideTime.begin()->first < nearestHide) { startNextHideTimer(); } } @@ -79,8 +81,8 @@ void Manager::addToast(std::unique_ptr &&toast) { void Manager::hideByTimer() { auto now = crl::now(); for (auto i = _toastByHideTime.begin(); i != _toastByHideTime.cend();) { - if (i.key() <= now) { - auto toast = i.value(); + if (i->first <= now) { + const auto toast = i->second; i = _toastByHideTime.erase(i); toast->hideAnimated(); } else { @@ -91,35 +93,40 @@ void Manager::hideByTimer() { } void Manager::onToastWidgetDestroyed(QObject *widget) { - auto i = _toastByWidget.find(static_cast(widget)); - if (i != _toastByWidget.cend()) { - auto toast = i.value(); - _toastByWidget.erase(i); - toast->_widget.release(); + const auto i = _toastByWidget.find(static_cast(widget)); + if (i == _toastByWidget.cend()) { + return; + } + const auto toast = i->second; + _toastByWidget.erase(i); + toast->_widget.release(); - int index = _toasts.indexOf(toast); - if (index >= 0) { - _toasts.removeAt(index); - delete toast; - } + const auto j = ranges::find( + _toasts, + toast.get(), + &std::unique_ptr::get); + if (j != end(_toasts)) { + _toasts.erase(j); } } void Manager::startNextHideTimer() { - if (_toastByHideTime.isEmpty()) return; + if (_toastByHideTime.empty()) return; auto ms = crl::now(); - if (ms >= _toastByHideTime.firstKey()) { + if (ms >= _toastByHideTime.begin()->first) { crl::on_main(this, [=] { hideByTimer(); }); } else { - _hideTimer.callOnce(_toastByHideTime.firstKey() - ms); + _hideTimer.callOnce(_toastByHideTime.begin()->first - ms); } } Manager::~Manager() { ManagersMap.remove(parent()); + _toastByWidget.clear(); + _toasts.clear(); } } // namespace internal diff --git a/ui/toast/toast_manager.h b/ui/toast/toast_manager.h index 8c35efd..c094260 100644 --- a/ui/toast/toast_manager.h +++ b/ui/toast/toast_manager.h @@ -43,10 +43,10 @@ private: base::Timer _hideTimer; crl::time _nextHide = 0; - QMultiMap _toastByHideTime; - QMap _toastByWidget; - QList _toasts; - OrderedSet> _toastParents; + base::flat_multi_map> _toastByHideTime; + base::flat_map, not_null> _toastByWidget; + std::vector> _toasts; + std::vector> _toastParents; };