From 71f340d9b5bedf193253fa796edb1efe8e1baf0e Mon Sep 17 00:00:00 2001 From: John Preston Date: Thu, 11 Apr 2019 10:15:47 +0400 Subject: [PATCH] Revert "Don't restart animations timer." This reverts commit 392d90dc1d9e321fe8aaf8702e0fabc94fed92ce. Otherwise scrolling while typing animates lags terribly on macOS. --- .../SourceFiles/ui/effects/animations.cpp | 94 ++++++++++--------- Telegram/SourceFiles/ui/effects/animations.h | 15 +-- 2 files changed, 56 insertions(+), 53 deletions(-) diff --git a/Telegram/SourceFiles/ui/effects/animations.cpp b/Telegram/SourceFiles/ui/effects/animations.cpp index de450743a..982f60ecb 100644 --- a/Telegram/SourceFiles/ui/effects/animations.cpp +++ b/Telegram/SourceFiles/ui/effects/animations.cpp @@ -53,22 +53,21 @@ void Basic::markStopped() { Manager::Manager() { Core::Sandbox::Instance().widgetUpdateRequests( - /*) | rpl::filter([=] { + ) | rpl::filter([=] { return (_lastUpdateTime + kIgnoreUpdatesTimeout < crl::now()); - }*/) | rpl::start_with_next([=] { - update(UpdateSource::RepaintRequest); + }) | rpl::start_with_next([=] { + update(); }, _lifetime); } void Manager::start(not_null animation) { - _forceUpdateProcessing = true; + _forceImmediateUpdate = true; if (_updating) { _starting.emplace_back(animation.get()); - return; + } else { + schedule(); + _active.emplace_back(animation.get()); } - _active.emplace_back(animation.get()); - startTimer(); - updateQueued(); } void Manager::stop(not_null animation) { @@ -90,16 +89,15 @@ void Manager::stop(not_null animation) { } } -void Manager::update(UpdateSource source) { - if (_active.empty() || _updating) { +void Manager::update() { + if (_active.empty() || _updating || _scheduled) { return; } const auto now = crl::now(); - if (_forceUpdateProcessing) { - _forceUpdateProcessing = false; - } else if (now < _lastUpdateTime + kIgnoreUpdatesTimeout) { - return; + if (_forceImmediateUpdate) { + _forceImmediateUpdate = false; } + schedule(); _updating = true; const auto guard = gsl::finally([&] { _updating = false; }); @@ -110,30 +108,48 @@ void Manager::update(UpdateSource source) { }; _active.erase(ranges::remove_if(_active, isFinished), end(_active)); - if (empty(_starting)) { - if (empty(_active)) { - stopTimer(); - } - return; - } - _active.insert( - end(_active), - std::make_move_iterator(begin(_starting)), - std::make_move_iterator(end(_starting))); - _starting.clear(); - if (_forceUpdateProcessing) { - updateQueued(); + if (!empty(_starting)) { + _active.insert( + end(_active), + std::make_move_iterator(begin(_starting)), + std::make_move_iterator(end(_starting))); + _starting.clear(); } } void Manager::updateQueued() { - if (_queued) { + Expects(_timerId == 0); + + _timerId = -1; + crl::on_main(delayedCallGuard(), [=] { + Expects(_timerId < 0); + + _timerId = 0; + update(); + }); +} + +void Manager::schedule() { + if (_scheduled || _timerId < 0) { return; } - _queued = true; - crl::on_main(delayedCallGuard(), [=] { - _queued = false; - update(UpdateSource::Queued); + stopTimer(); + + _scheduled = true; + Ui::PostponeCall(delayedCallGuard(), [=] { + _scheduled = false; + if (_forceImmediateUpdate) { + _forceImmediateUpdate = false; + updateQueued(); + } else { + const auto next = _lastUpdateTime + kAnimationTimeout; + const auto now = crl::now(); + if (now < next) { + _timerId = startTimer(next - now, Qt::PreciseTimer); + } else { + updateQueued(); + } + } }); } @@ -141,22 +157,14 @@ not_null Manager::delayedCallGuard() const { return static_cast(this); } -void Manager::startTimer() { - if (_timerId) { - return; - } - _timerId = QObject::startTimer(kAnimationTick, Qt::PreciseTimer); -} - void Manager::stopTimer() { - if (!_timerId) { - return; + if (_timerId > 0) { + killTimer(base::take(_timerId)); } - killTimer(base::take(_timerId)); } void Manager::timerEvent(QTimerEvent *e) { - update(UpdateSource::TimerEvent); + update(); } } // namespace Animations diff --git a/Telegram/SourceFiles/ui/effects/animations.h b/Telegram/SourceFiles/ui/effects/animations.h index 56bbc5976..c5dee8b6d 100644 --- a/Telegram/SourceFiles/ui/effects/animations.h +++ b/Telegram/SourceFiles/ui/effects/animations.h @@ -101,13 +101,9 @@ class Manager final : private QObject { public: Manager(); -private: - enum class UpdateSource { - Queued, - TimerEvent, - RepaintRequest, - }; + void update(); +private: class ActiveBasicPointer { public: ActiveBasicPointer(Basic *value = nullptr) : _value(value) { @@ -155,21 +151,20 @@ private: friend class Basic; void timerEvent(QTimerEvent *e) override; - void update(UpdateSource source); void start(not_null animation); void stop(not_null animation); + void schedule(); void updateQueued(); - void startTimer(); void stopTimer(); not_null delayedCallGuard() const; crl::time _lastUpdateTime = 0; int _timerId = 0; bool _updating = false; - bool _queued = false; - bool _forceUpdateProcessing = false; + bool _scheduled = false; + bool _forceImmediateUpdate = false; std::vector _active; std::vector _starting; rpl::lifetime _lifetime;