Fix crash in session destruction.

Also use rpl::event_stream for downloaderTaskFinished.
This commit is contained in:
John Preston 2020-07-01 12:03:34 +04:00
parent 0981335ca7
commit eb1845e33b
38 changed files with 129 additions and 78 deletions

View file

@ -1364,7 +1364,10 @@ void RevokePublicLinkBox::prepare() {
addButton(tr::lng_cancel(), [=] { closeBox(); });
subscribe(_session->downloaderTaskFinished(), [=] { update(); });
_session->downloaderTaskFinished(
) | rpl::start_with_next([=] {
update();
}, lifetime());
_inner->resizeToWidth(st::boxWideWidth);
setDimensions(st::boxWideWidth, _innerTop + _inner->height());

View file

@ -203,7 +203,10 @@ BackgroundBox::Inner::Inner(
}
requestPapers();
subscribe(_session->downloaderTaskFinished(), [=] { update(); });
_session->downloaderTaskFinished(
) | rpl::start_with_next([=] {
update();
}, lifetime());
using Update = Window::Theme::BackgroundUpdate;
subscribe(Window::Theme::Background(), [=](const Update &update) {
if (update.paletteChanged()) {

View file

@ -419,9 +419,10 @@ BackgroundPreviewBox::BackgroundPreviewBox(
if (_media) {
_media->thumbnailWanted(_paper.fileOrigin());
}
subscribe(_controller->session().downloaderTaskFinished(), [=] {
_controller->session().downloaderTaskFinished(
) | rpl::start_with_next([=] {
update();
});
}, lifetime());
}
not_null<HistoryView::ElementDelegate*> BackgroundPreviewBox::delegate() {

View file

@ -891,9 +891,10 @@ ConfirmInviteBox::ConfirmInviteBox(
_photo = photo->createMediaView();
_photo->wanted(Data::PhotoSize::Small, Data::FileOrigin());
if (!_photo->image(Data::PhotoSize::Small)) {
subscribe(_session->downloaderTaskFinished(), [=] {
_session->downloaderTaskFinished(
) | rpl::start_with_next([=] {
update();
});
}, lifetime());
}
} else {
_photoEmpty = std::make_unique<Ui::EmptyUserpic>(

View file

@ -291,7 +291,8 @@ EditCaptionBox::EditCaptionBox(
Assert(_thumbnailImageLoaded || _refreshThumbnail);
if (!_thumbnailImageLoaded) {
subscribe(_controller->session().downloaderTaskFinished(), [=] {
_controller->session().downloaderTaskFinished(
) | rpl::start_with_next([=] {
if (_thumbnailImageLoaded
|| (_photoMedia && !_photoMedia->image(PhotoSize::Large))
|| (_documentMedia && !_documentMedia->thumbnail())) {
@ -299,7 +300,7 @@ EditCaptionBox::EditCaptionBox(
}
_refreshThumbnail();
update();
});
}, lifetime());
}
_field.create(
this,

View file

@ -662,9 +662,10 @@ PeerListContent::PeerListContent(
, _st(st)
, _controller(controller)
, _rowHeight(_st.item.height) {
subscribe(_controller->session().downloaderTaskFinished(), [=] {
_controller->session().downloaderTaskFinished(
) | rpl::start_with_next([=] {
update();
});
}, lifetime());
using UpdateFlag = Data::PeerUpdate::Flag;
_controller->session().changes().peerUpdates(

View file

@ -570,9 +570,10 @@ ShareBox::Inner::Inner(
update.oldFirstLetters);
}, lifetime());
subscribe(_navigation->session().downloaderTaskFinished(), [=] {
_navigation->session().downloaderTaskFinished(
) | rpl::start_with_next([=] {
update();
});
}, lifetime());
subscribe(Window::Theme::Background(), [this](const Window::Theme::BackgroundUpdate &update) {
if (update.paletteChanged()) {

View file

@ -254,7 +254,10 @@ StickerSetBox::Inner::Inner(
_controller->session().api().updateStickers();
subscribe(_controller->session().downloaderTaskFinished(), [this] { update(); });
_controller->session().downloaderTaskFinished(
) | rpl::start_with_next([=] {
update();
}, lifetime());
setMouseTracking(true);
}

View file

@ -1002,10 +1002,12 @@ Main::Session &StickersBox::Inner::session() const {
}
void StickersBox::Inner::setup() {
subscribe(session().downloaderTaskFinished(), [this] {
session().downloaderTaskFinished(
) | rpl::start_with_next([=] {
update();
readVisibleSets();
});
}, lifetime());
setMouseTracking(true);
}

View file

@ -446,9 +446,10 @@ void Panel::initLayout() {
}, lifetime());
processUserPhoto();
subscribe(_user->session().downloaderTaskFinished(), [=] {
_user->session().downloaderTaskFinished(
) | rpl::start_with_next([=] {
refreshUserPhoto();
});
}, lifetime());
createDefaultCacheImage();
Ui::Platform::InitOnTopPanel(this);

View file

@ -604,9 +604,10 @@ FieldAutocompleteInner::FieldAutocompleteInner(
, _brows(brows)
, _srows(srows)
, _previewTimer([=] { showPreview(); }) {
subscribe(
controller->session().downloaderTaskFinished(),
[=] { update(); });
controller->session().downloaderTaskFinished(
) | rpl::start_with_next([=] {
update();
}, lifetime());
}
void FieldAutocompleteInner::paintEvent(QPaintEvent *e) {

View file

@ -153,9 +153,10 @@ GifsListWidget::GifsListWidget(
refreshSavedGifs();
}, lifetime());
subscribe(controller->session().downloaderTaskFinished(), [this] {
controller->session().downloaderTaskFinished(
) | rpl::start_with_next([=] {
update();
});
}, lifetime());
subscribe(controller->gifPauseLevelChanged(), [=] {
if (!controller->isGifPausedAtLeastFor(

View file

@ -198,7 +198,7 @@ std::shared_ptr<LargeEmojiImage> EmojiPack::image(EmojiPtr emoji) {
if (!strong->image) {
strong->load = nullptr;
strong->image.emplace(std::move(image));
_session->downloaderTaskFinished().notify();
_session->notifyDownloaderTaskFinished();
}
}
}

View file

@ -105,9 +105,7 @@ struct StickerIcon {
};
class StickersListWidget::Footer
: public TabbedSelector::InnerFooter
, private base::Subscriber {
class StickersListWidget::Footer : public TabbedSelector::InnerFooter {
public:
explicit Footer(not_null<StickersListWidget*> parent);
@ -132,7 +130,7 @@ protected:
void mousePressEvent(QMouseEvent *e) override;
void mouseMoveEvent(QMouseEvent *e) override;
void mouseReleaseEvent(QMouseEvent *e) override;
bool event(QEvent *e) override;
bool eventHook(QEvent *e) override;
void processHideFinished() override;
@ -249,9 +247,10 @@ StickersListWidget::Footer::Footer(not_null<StickersListWidget*> parent)
_iconsLeft = _iconsRight = st::emojiCategorySkip + st::stickerIconWidth;
subscribe(_pan->session().downloaderTaskFinished(), [=] {
_pan->session().downloaderTaskFinished(
) | rpl::start_with_next([=] {
update();
});
}, lifetime());
}
void StickersListWidget::Footer::clearHeavyData() {
@ -600,7 +599,7 @@ void StickersListWidget::Footer::finishDragging() {
updateSelected();
}
bool StickersListWidget::Footer::event(QEvent *e) {
bool StickersListWidget::Footer::eventHook(QEvent *e) {
if (e->type() == QEvent::TouchBegin) {
} else if (e->type() == QEvent::Wheel) {
if (!_icons.empty()
@ -609,7 +608,7 @@ bool StickersListWidget::Footer::event(QEvent *e) {
scrollByWheelEvent(static_cast<QWheelEvent*>(e));
}
}
return InnerFooter::event(e);
return InnerFooter::eventHook(e);
}
void StickersListWidget::Footer::scrollByWheelEvent(
@ -890,12 +889,13 @@ StickersListWidget::StickersListWidget(
Box<StickersBox>(controller, StickersBox::Section::Installed));
});
subscribe(session().downloaderTaskFinished(), [=] {
session().downloaderTaskFinished(
) | rpl::start_with_next([=] {
if (isVisible()) {
update();
readVisibleFeatured(getVisibleTop(), getVisibleBottom());
}
});
}, lifetime());
session().changes().peerUpdates(
Data::PeerUpdate::Flag::StickersSet

View file

@ -938,7 +938,7 @@ void TabbedSelector::Inner::panelHideFinished() {
}
TabbedSelector::InnerFooter::InnerFooter(QWidget *parent)
: TWidget(parent) {
: RpWidget(parent) {
resize(st::emojiPanWidth, st::emojiFooterHeight);
}

View file

@ -276,7 +276,7 @@ private:
};
class TabbedSelector::InnerFooter : public TWidget {
class TabbedSelector::InnerFooter : public Ui::RpWidget {
public:
InnerFooter(QWidget *parent);

View file

@ -26,7 +26,7 @@ void CloudImageView::set(
not_null<Main::Session*> session,
QImage image) {
_image.emplace(std::move(image));
session->downloaderTaskFinished().notify();
session->notifyDownloaderTaskFinished();
}
CloudImage::CloudImage() = default;

View file

@ -222,8 +222,7 @@ void CloudThemes::loadDocumentAndInvoke(
return;
}
if (!alreadyWaiting) {
base::ObservableViewer(
_session->downloaderTaskFinished()
_session->downloaderTaskFinished(
) | rpl::filter([=, &value] {
return value.documentMedia->loaded();
}) | rpl::start_with_next([=, &value] {

View file

@ -168,7 +168,7 @@ void DocumentMedia::setGoodThumbnail(QImage thumbnail) {
return;
}
_goodThumbnail = std::make_unique<Image>(std::move(thumbnail));
_owner->session().downloaderTaskFinished().notify();
_owner->session().notifyDownloaderTaskFinished();
}
Image *DocumentMedia::thumbnailInline() const {
@ -206,7 +206,7 @@ QSize DocumentMedia::thumbnailSize() const {
void DocumentMedia::setThumbnail(QImage thumbnail) {
_thumbnail = std::make_unique<Image>(std::move(thumbnail));
_owner->session().downloaderTaskFinished().notify();
_owner->session().notifyDownloaderTaskFinished();
}
QByteArray DocumentMedia::videoThumbnailContent() const {

View file

@ -82,7 +82,7 @@ void PhotoMedia::set(PhotoSize size, QImage image) {
Qt::SmoothTransformation);
}
_images[index] = std::make_unique<Image>(std::move(image));
_owner->session().downloaderTaskFinished().notify();
_owner->session().notifyDownloaderTaskFinished();
}
bool PhotoMedia::loaded() const {

View file

@ -34,7 +34,7 @@ void StickersSetThumbnailView::set(
} else {
_image = std::make_unique<Image>(std::move(image));
}
session->downloaderTaskFinished().notify();
session->notifyDownloaderTaskFinished();
}
Image *StickersSetThumbnailView::image() const {

View file

@ -132,7 +132,10 @@ InnerWidget::InnerWidget(
});
_cancelSearchFromUser->hide();
subscribe(session().downloaderTaskFinished(), [=] { update(); });
session().downloaderTaskFinished(
) | rpl::start_with_next([=] {
update();
}, lifetime());
subscribe(Core::App().notifications().settingsChanged(), [=](
Window::Notifications::ChangeType change) {

View file

@ -305,7 +305,11 @@ HistoryWidget::HistoryWidget(
, _topShadow(this) {
setAcceptDrops(true);
subscribe(session().downloaderTaskFinished(), [=] { update(); });
session().downloaderTaskFinished(
) | rpl::start_with_next([=] {
update();
}, lifetime());
connect(_scroll, SIGNAL(scrolled()), this, SLOT(onScroll()));
_historyDown->addClickHandler([=] { historyDownClicked(); });
_unreadMentions->addClickHandler([=] { showNextUnreadMention(); });

View file

@ -585,21 +585,27 @@ void ListWidget::start() {
invalidatePaletteCache();
}
}, lifetime());
ObservableViewer(
session().downloaderTaskFinished()
) | rpl::start_with_next([this] { update(); }, lifetime());
session().downloaderTaskFinished(
) | rpl::start_with_next([=] {
update();
}, lifetime());
session().data().itemLayoutChanged(
) | rpl::start_with_next([this](auto item) {
itemLayoutChanged(item);
}, lifetime());
session().data().itemRemoved(
) | rpl::start_with_next([this](auto item) {
itemRemoved(item);
}, lifetime());
session().data().itemRepaintRequest(
) | rpl::start_with_next([this](auto item) {
repaintItem(item);
}, lifetime());
_controller->mediaSourceQueryValue(
) | rpl::start_with_next([this]{
restart();

View file

@ -58,9 +58,11 @@ Inner::Inner(
setMouseTracking(true);
setAttribute(Qt::WA_OpaquePaintEvent);
subscribe(_controller->session().downloaderTaskFinished(), [this] {
_controller->session().downloaderTaskFinished(
) | rpl::start_with_next([=] {
update();
});
}, lifetime());
subscribe(controller->gifPauseLevelChanged(), [this] {
if (!_controller->isGifPausedAtLeastFor(Window::GifPauseReason::InlineResults)) {
update();

View file

@ -181,7 +181,11 @@ Storage::Domain &Session::domainLocal() const {
return _account->domainLocal();
}
base::Observable<void> &Session::downloaderTaskFinished() {
void Session::notifyDownloaderTaskFinished() {
downloader().notifyTaskFinished();
}
rpl::producer<> Session::downloaderTaskFinished() const {
return downloader().taskFinished();
}

View file

@ -121,7 +121,8 @@ public:
-> const base::flat_set<not_null<Window::SessionController*>> &;
// Shortcuts.
[[nodiscard]] base::Observable<void> &downloaderTaskFinished();
void notifyDownloaderTaskFinished();
[[nodiscard]] rpl::producer<> downloaderTaskFinished() const;
[[nodiscard]] MTP::DcId mainDcId() const;
[[nodiscard]] MTP::Instance &mtp() const;
[[nodiscard]] const MTP::ConfigFields &serverConfig() const;

View file

@ -3530,8 +3530,7 @@ void OverlayWidget::setSession(not_null<Main::Session*> session) {
_session = session;
setWindowIcon(Window::CreateIcon(session));
base::ObservableViewer(
session->downloaderTaskFinished()
session->downloaderTaskFinished(
) | rpl::start_with_next([=] {
if (!isHidden()) {
updateControls();

View file

@ -812,8 +812,7 @@ void AppendEmojiPacks(
[self setNeedsDisplayInRect:PeerRectByIndex(userpicIndex)];
};
const auto listenToDownloaderFinished = [=] {
base::ObservableViewer(
_session->downloaderTaskFinished()
_session->downloaderTaskFinished(
) | rpl::start_with_next([=] {
const auto all = ranges::all_of(_pins, [=](const auto &pin) {
return (!pin->peer->hasUserpic())
@ -1193,8 +1192,7 @@ void AppendEmojiPacks(
[self updateImage];
return;
}
base::ObservableViewer(
document->session().downloaderTaskFinished()
document->session().downloaderTaskFinished(
) | rpl::start_with_next([=] {
_image = _media->getStickerSmall();
if (_image) {

View file

@ -33,7 +33,11 @@ PeerListWidget::PeerListWidget(
, _removeText(removeText)
, _removeWidth(st::normalFont->width(_removeText)) {
setMouseTracking(true);
subscribe(peer->session().downloaderTaskFinished(), [=] { update(); });
peer->session().downloaderTaskFinished(
) | rpl::start_with_next([=] {
update();
}, lifetime());
}
int PeerListWidget::resizeGetHeight(int newWidth) {

View file

@ -38,8 +38,11 @@ public:
void enqueue(not_null<Task*> task, int priority);
void remove(not_null<Task*> task);
[[nodiscard]] base::Observable<void> &taskFinished() {
return _taskFinishedObservable;
void notifyTaskFinished() {
_taskFinished.fire({});
}
[[nodiscard]] rpl::producer<> taskFinished() const {
return _taskFinished.events();
}
int changeRequestedAmount(MTP::DcId dcId, int index, int delta);
@ -101,7 +104,7 @@ private:
const not_null<ApiWrap*> _api;
base::Observable<void> _taskFinishedObservable;
rpl::event_stream<> _taskFinished;
base::flat_map<MTP::DcId, DcBalanceData> _balanceData;
base::Timer _resetGenerationTimer;

View file

@ -140,7 +140,7 @@ void FileLoader::finishWithBytes(const QByteArray &data) {
Platform::File::PostprocessDownloaded(
QFileInfo(_file).absoluteFilePath());
}
_session->downloaderTaskFinished().notify();
_session->notifyDownloaderTaskFinished();
_updates.fire_done();
}
@ -440,7 +440,7 @@ bool FileLoader::finalizeResult() {
_cacheTag));
}
}
_session->downloaderTaskFinished().notify();
_session->notifyDownloaderTaskFinished();
_updates.fire_done();
return true;
}

View file

@ -639,8 +639,7 @@ void UserpicButton::setupPeerViewers() {
update();
}, lifetime());
base::ObservableViewer(
_peer->session().downloaderTaskFinished()
_peer->session().downloaderTaskFinished(
) | rpl::filter([=] {
return _waiting;
}) | rpl::start_with_next([=] {

View file

@ -21,6 +21,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "window/themes/window_theme.h"
#include "storage/file_download.h"
#include "main/main_session.h"
#include "main/main_account.h"
#include "history/history.h"
#include "history/history_item.h"
#include "platform/platform_specific.h"
@ -229,14 +230,16 @@ void Manager::showNextFromQueue() {
void Manager::subscribeToSession(not_null<Main::Session*> session) {
auto i = _subscriptions.find(session);
if (i == _subscriptions.end()) {
i = _subscriptions.emplace(session, base::Subscription()).first;
session->lifetime().add([=] {
i = _subscriptions.emplace(session).first;
session->account().sessionChanges(
) | rpl::start_with_next([=] {
_subscriptions.remove(session);
});
} else if (i->second) {
}, i->second.lifetime);
} else if (i->second.subscription) {
return;
}
i->second = session->downloaderTaskFinished().add_subscription([=] {
session->downloaderTaskFinished(
) | rpl::start_with_next([=] {
auto found = false;
for (const auto &notification : _notifications) {
if (const auto history = notification->maybeHistory()) {
@ -247,9 +250,9 @@ void Manager::subscribeToSession(not_null<Main::Session*> session) {
}
}
if (!found) {
_subscriptions[session].destroy();
_subscriptions[session].subscription.destroy();
}
});
}, i->second.subscription);
}
void Manager::moveWidgets() {

View file

@ -56,6 +56,10 @@ private:
friend class internal::Widget;
using Notification = internal::Notification;
using HideAllButton = internal::HideAllButton;
struct SessionSubscription {
rpl::lifetime subscription;
rpl::lifetime lifetime;
};
[[nodiscard]] QPixmap hiddenUserpicPlaceholder() const;
@ -91,7 +95,7 @@ private:
std::vector<std::unique_ptr<Notification>> _notifications;
base::flat_map<
not_null<Main::Session*>,
base::Subscription> _subscriptions;
SessionSubscription> _subscriptions;
std::unique_ptr<HideAllButton> _hideAll;

View file

@ -666,8 +666,7 @@ void CloudList::subscribeToDownloadFinished() {
if (_downloadFinishedLifetime) {
return;
}
base::ObservableViewer(
_window->session().downloaderTaskFinished()
_window->session().downloaderTaskFinished(
) | rpl::start_with_next([=] {
auto &&waiting = _elements | ranges::view::filter(&Element::waiting);
const auto still = ranges::count_if(waiting, [&](Element &element) {

View file

@ -580,7 +580,10 @@ MainMenu::MainMenu(
_version->setLink(1, std::make_shared<UrlClickHandler>(qsl("https://desktop.telegram.org/changelog")));
_version->setLink(2, std::make_shared<LambdaClickHandler>([] { Ui::show(Box<AboutBox>()); }));
subscribe(_controller->session().downloaderTaskFinished(), [=] { update(); });
_controller->session().downloaderTaskFinished(
) | rpl::start_with_next([=] {
update();
}, lifetime());
_controller->session().changes().peerUpdates(
_controller->session().user(),

View file

@ -36,9 +36,10 @@ MediaPreviewWidget::MediaPreviewWidget(
, _controller(controller)
, _emojiSize(Ui::Emoji::GetSizeLarge() / cIntRetinaFactor()) {
setAttribute(Qt::WA_TransparentForMouseEvents);
subscribe(_controller->session().downloaderTaskFinished(), [=] {
_controller->session().downloaderTaskFinished(
) | rpl::start_with_next([=] {
update();
});
}, lifetime());
}
QRect MediaPreviewWidget::updateArea() const {