Fix possible crash in pinned bar destruction.

This commit is contained in:
John Preston 2022-11-09 10:18:55 +04:00
parent 66435d5269
commit 7e2a49c1f9
4 changed files with 44 additions and 25 deletions

View file

@ -6193,20 +6193,15 @@ void HistoryWidget::checkPinnedBarState() {
: currentPinnedId.msg; : currentPinnedId.msg;
if (universalPinnedId == hiddenId) { if (universalPinnedId == hiddenId) {
if (_pinnedBar) { if (_pinnedBar) {
_pinnedBar->setContent(rpl::single(Ui::MessageBarContent()));
_pinnedTracker->reset(); _pinnedTracker->reset();
auto qobject = base::unique_qptr{ _hidingPinnedBar = base::take(_pinnedBar);
Ui::WrapAsQObject(this, std::move(_pinnedBar)).get() const auto raw = _hidingPinnedBar.get();
}; base::call_delayed(st::defaultMessageBar.duration, this, [=] {
auto destroyer = [this, object = std::move(qobject)]() mutable { if (_hidingPinnedBar.get() == raw) {
object = nullptr; clearHidingPinnedBar();
_pinnedBarHeight = 0; }
updateHistoryGeometry(); });
updateControlsGeometry();
};
base::call_delayed(
st::defaultMessageBar.duration,
this,
std::move(destroyer));
} }
return; return;
} }
@ -6214,6 +6209,7 @@ void HistoryWidget::checkPinnedBarState() {
return; return;
} }
clearHidingPinnedBar();
_pinnedBar = std::make_unique<Ui::PinnedBar>(this, [=] { _pinnedBar = std::make_unique<Ui::PinnedBar>(this, [=] {
return controller()->isGifPausedAtLeastFor( return controller()->isGifPausedAtLeastFor(
Window::GifPauseReason::Any); Window::GifPauseReason::Any);
@ -6300,6 +6296,17 @@ void HistoryWidget::checkPinnedBarState() {
} }
} }
void HistoryWidget::clearHidingPinnedBar() {
if (!_hidingPinnedBar) {
return;
}
if (const auto delta = -_pinnedBarHeight) {
_pinnedBarHeight = 0;
setGeometryWithTopMoved(geometry(), delta);
}
_hidingPinnedBar = nullptr;
}
void HistoryWidget::checkMessagesTTL() { void HistoryWidget::checkMessagesTTL() {
if (!_peer || !_peer->messagesTTL()) { if (!_peer || !_peer->messagesTTL()) {
if (_ttlInfo) { if (_ttlInfo) {

View file

@ -487,6 +487,7 @@ private:
void updatePinnedViewer(); void updatePinnedViewer();
void setupPinnedTracker(); void setupPinnedTracker();
void checkPinnedBarState(); void checkPinnedBarState();
void clearHidingPinnedBar();
void refreshPinnedBarButton(bool many, HistoryItem *item); void refreshPinnedBarButton(bool many, HistoryItem *item);
void checkLastPinnedClickedIdReset( void checkLastPinnedClickedIdReset(
int wasScrollTop, int wasScrollTop,
@ -628,6 +629,7 @@ private:
std::unique_ptr<HistoryView::PinnedTracker> _pinnedTracker; std::unique_ptr<HistoryView::PinnedTracker> _pinnedTracker;
std::unique_ptr<Ui::PinnedBar> _pinnedBar; std::unique_ptr<Ui::PinnedBar> _pinnedBar;
std::unique_ptr<Ui::PinnedBar> _hidingPinnedBar;
int _pinnedBarHeight = 0; int _pinnedBarHeight = 0;
FullMsgId _pinnedClickedId; FullMsgId _pinnedClickedId;
std::optional<FullMsgId> _minPinnedId; std::optional<FullMsgId> _minPinnedId;

View file

@ -1569,19 +1569,15 @@ void RepliesWidget::checkPinnedBarState() {
: currentPinnedId.msg; : currentPinnedId.msg;
if (universalPinnedId == hiddenId) { if (universalPinnedId == hiddenId) {
if (_pinnedBar) { if (_pinnedBar) {
_pinnedBar->setContent(rpl::single(Ui::MessageBarContent()));
_pinnedTracker->reset(); _pinnedTracker->reset();
auto qobject = base::unique_qptr{ _hidingPinnedBar = base::take(_pinnedBar);
Ui::WrapAsQObject(this, std::move(_pinnedBar)).get() const auto raw = _hidingPinnedBar.get();
}; base::call_delayed(st::defaultMessageBar.duration, this, [=] {
auto destroyer = [this, object = std::move(qobject)]() mutable { if (_hidingPinnedBar.get() == raw) {
object = nullptr; clearHidingPinnedBar();
_pinnedBarHeight = 0; }
updateControlsGeometry(); });
};
base::call_delayed(
st::defaultMessageBar.duration,
this,
std::move(destroyer));
} }
return; return;
} }
@ -1589,6 +1585,7 @@ void RepliesWidget::checkPinnedBarState() {
return; return;
} }
clearHidingPinnedBar();
_pinnedBar = std::make_unique<Ui::PinnedBar>(this, [=] { _pinnedBar = std::make_unique<Ui::PinnedBar>(this, [=] {
return controller()->isGifPausedAtLeastFor( return controller()->isGifPausedAtLeastFor(
Window::GifPauseReason::Any); Window::GifPauseReason::Any);
@ -1671,6 +1668,17 @@ void RepliesWidget::checkPinnedBarState() {
} }
} }
void RepliesWidget::clearHidingPinnedBar() {
if (!_hidingPinnedBar) {
return;
}
if (const auto delta = -_pinnedBarHeight) {
_pinnedBarHeight = 0;
setGeometryWithTopMoved(geometry(), delta);
}
_hidingPinnedBar = nullptr;
}
void RepliesWidget::refreshPinnedBarButton(bool many, HistoryItem *item) { void RepliesWidget::refreshPinnedBarButton(bool many, HistoryItem *item) {
if (!_pinnedBar) { if (!_pinnedBar) {
return; // It can be in process of hiding. return; // It can be in process of hiding.

View file

@ -256,6 +256,7 @@ private:
void updatePinnedViewer(); void updatePinnedViewer();
void setupPinnedTracker(); void setupPinnedTracker();
void checkPinnedBarState(); void checkPinnedBarState();
void clearHidingPinnedBar();
void refreshPinnedBarButton(bool many, HistoryItem *item); void refreshPinnedBarButton(bool many, HistoryItem *item);
void checkLastPinnedClickedIdReset( void checkLastPinnedClickedIdReset(
int wasScrollTop, int wasScrollTop,
@ -332,6 +333,7 @@ private:
std::unique_ptr<PinnedTracker> _pinnedTracker; std::unique_ptr<PinnedTracker> _pinnedTracker;
std::unique_ptr<Ui::PinnedBar> _pinnedBar; std::unique_ptr<Ui::PinnedBar> _pinnedBar;
std::unique_ptr<Ui::PinnedBar> _hidingPinnedBar;
int _pinnedBarHeight = 0; int _pinnedBarHeight = 0;
FullMsgId _pinnedClickedId; FullMsgId _pinnedClickedId;
std::optional<FullMsgId> _minPinnedId; std::optional<FullMsgId> _minPinnedId;