Fix stack overflow crash in emoji panel hiding.

A call to hideChildren before setting _hiding to the desired value
could lead through leaveEvent to a recursive call to hideAnimated.
This commit is contained in:
John Preston 2019-04-30 12:56:21 +04:00
parent 5c3f93eee1
commit c9552390e7
2 changed files with 16 additions and 8 deletions

View File

@ -255,15 +255,21 @@ void TabbedPanel::hideByTimerOrLeave() {
hideAnimated(); hideAnimated();
} }
void TabbedPanel::prepareCache() { void TabbedPanel::prepareCacheFor(bool hiding) {
if (_a_opacity.animating()) return; if (_a_opacity.animating()) {
return;
}
auto showAnimation = base::take(_a_show); auto showAnimation = base::take(_a_show);
auto showAnimationData = base::take(_showAnimation); auto showAnimationData = base::take(_showAnimation);
_hiding = false;
showChildren(); showChildren();
_cache = Ui::GrabWidget(this); _cache = Ui::GrabWidget(this);
_showAnimation = base::take(showAnimationData);
_a_show = base::take(showAnimation); _a_show = base::take(showAnimation);
_showAnimation = base::take(showAnimationData);
_hiding = hiding;
if (_a_show.animating()) { if (_a_show.animating()) {
hideChildren(); hideChildren();
} }
@ -273,11 +279,13 @@ void TabbedPanel::startOpacityAnimation(bool hiding) {
if (_selector && !_selector->isHidden()) { if (_selector && !_selector->isHidden()) {
_selector->beforeHiding(); _selector->beforeHiding();
} }
_hiding = false; prepareCacheFor(hiding);
prepareCache();
_hiding = hiding;
hideChildren(); hideChildren();
_a_opacity.start([this] { opacityAnimationCallback(); }, _hiding ? 1. : 0., _hiding ? 0. : 1., st::emojiPanDuration); _a_opacity.start(
[=] { opacityAnimationCallback(); },
_hiding ? 1. : 0.,
_hiding ? 0. : 1.,
st::emojiPanDuration);
} }
void TabbedPanel::startShowAnimation() { void TabbedPanel::startShowAnimation() {

View File

@ -77,7 +77,7 @@ private:
QImage grabForAnimation(); QImage grabForAnimation();
void startShowAnimation(); void startShowAnimation();
void startOpacityAnimation(bool hiding); void startOpacityAnimation(bool hiding);
void prepareCache(); void prepareCacheFor(bool hiding);
void opacityAnimationCallback(); void opacityAnimationCallback();