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;
if (universalPinnedId == hiddenId) {
if (_pinnedBar) {
_pinnedBar->setContent(rpl::single(Ui::MessageBarContent()));
_pinnedTracker->reset();
auto qobject = base::unique_qptr{
Ui::WrapAsQObject(this, std::move(_pinnedBar)).get()
};
auto destroyer = [this, object = std::move(qobject)]() mutable {
object = nullptr;
_pinnedBarHeight = 0;
updateHistoryGeometry();
updateControlsGeometry();
};
base::call_delayed(
st::defaultMessageBar.duration,
this,
std::move(destroyer));
_hidingPinnedBar = base::take(_pinnedBar);
const auto raw = _hidingPinnedBar.get();
base::call_delayed(st::defaultMessageBar.duration, this, [=] {
if (_hidingPinnedBar.get() == raw) {
clearHidingPinnedBar();
}
});
}
return;
}
@ -6214,6 +6209,7 @@ void HistoryWidget::checkPinnedBarState() {
return;
}
clearHidingPinnedBar();
_pinnedBar = std::make_unique<Ui::PinnedBar>(this, [=] {
return controller()->isGifPausedAtLeastFor(
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() {
if (!_peer || !_peer->messagesTTL()) {
if (_ttlInfo) {

View File

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

View File

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

View File

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